From b7bc0262cc51546cf0219520ef5aedee9b754971 Mon Sep 17 00:00:00 2001 From: Chris McDonough Date: Mon, 22 Nov 2010 23:55:03 -0500 Subject: fix project section name doc bug --- docs/narr/project.rst | 11 ++++++----- 1 file changed, 6 insertions(+), 5 deletions(-) diff --git a/docs/narr/project.rst b/docs/narr/project.rst index 6e466b284..aef134ff7 100644 --- a/docs/narr/project.rst +++ b/docs/narr/project.rst @@ -316,12 +316,13 @@ Python interpreter shell unconditionally. [pipeline:main] pipeline = egg:WebError#evalerror - myapp + MyProject - If you use ``main`` as the section name argument instead of ``myapp`` - against the above ``.ini`` file, an error will occur. Use the most - specific reference to your application within the ``.ini`` file possible - as the section name argument. + Use ``MyProject`` instead of ``main`` as the section name argument to + ``pshell`` against the above ``.ini`` file (e.g. ``paster pshell + development.ini MyProject``). If you use ``main`` instead, an error will + occur. Use the most specific reference to your application within the + ``.ini`` file possible as the section name argument. Press ``Ctrl-D`` to exit the interactive shell (or ``Ctrl-Z`` on Windows). -- cgit v1.2.3 From efbb06c2d2813f23f8fad68cf09123f1ab75d96d Mon Sep 17 00:00:00 2001 From: Chris McDonough Date: Mon, 22 Nov 2010 23:57:38 -0500 Subject: fix wrong egg reference --- docs/narr/startup.rst | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/docs/narr/startup.rst b/docs/narr/startup.rst index c57525f4c..427acc319 100644 --- a/docs/narr/startup.rst +++ b/docs/narr/startup.rst @@ -86,9 +86,9 @@ press ``return`` after running ``paster serve development.ini``. :linenos: In this case, the ``myproject.run:app`` function referred to by the entry - point URI ``egg:MyProject#app`` (see :ref:`MyProject_ini` for more - information about entry point URIs, and how they relate to callables), - will receive the key/value pairs ``{'reload_templates':'true', + point URI ``egg:MyProject`` (see :ref:`MyProject_ini` for more information + about entry point URIs, and how they relate to callables), will receive + the key/value pairs ``{'reload_templates':'true', 'debug_authorization':'false', 'debug_notfound':'false', 'debug_templates':'true', 'default_locale_name':'en'}``. -- cgit v1.2.3 From 344ed58d2aa9f42ed64142d92ae5d79bf3a9f4e7 Mon Sep 17 00:00:00 2001 From: Chris McDonough Date: Tue, 23 Nov 2010 00:00:22 -0500 Subject: fix quoting --- docs/narr/urldispatch.rst | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/docs/narr/urldispatch.rst b/docs/narr/urldispatch.rst index a86041e55..df7d592f9 100644 --- a/docs/narr/urldispatch.rst +++ b/docs/narr/urldispatch.rst @@ -349,7 +349,8 @@ also capture the remainder of the URL, for example: foo/{baz}/{bar}{fizzle:.*} -The above pattern will match these URLs, generating the following matchdicts: +The above pattern will match these URLs, generating the following +matchdicts:: foo/1/2/ -> {'baz':'1', 'bar':'2', 'fizzle':()} foo/abc/def/a/b/c -> {'baz':'abc', 'bar':'def', 'fizzle': 'a/b/c')} -- cgit v1.2.3 From b22d1fed835897c28b0136253ae428d28e19e07c Mon Sep 17 00:00:00 2001 From: Chris McDonough Date: Tue, 23 Nov 2010 00:03:39 -0500 Subject: gardening --- TODO.txt | 2 ++ 1 file changed, 2 insertions(+) diff --git a/TODO.txt b/TODO.txt index 4319e3cca..c5584d3cc 100644 --- a/TODO.txt +++ b/TODO.txt @@ -108,3 +108,5 @@ Nice-to-Have - Add functionality that mocks the behavior of ``repoze.browserid``. +- One way to split up views chapter: views with renderers / views without + renderers. -- cgit v1.2.3 From 3f61fa08ae42860dde823e610134e4cc2b7ec991 Mon Sep 17 00:00:00 2001 From: Chris McDonough Date: Tue, 23 Nov 2010 00:12:16 -0500 Subject: correct typo: ! -> ~ --- docs/narr/handlers.rst | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/docs/narr/handlers.rst b/docs/narr/handlers.rst index 022f27115..d82f42bdb 100644 --- a/docs/narr/handlers.rst +++ b/docs/narr/handlers.rst @@ -168,8 +168,8 @@ information on the handler method which is used by configuration. All keyword arguments are recorded, and passed to -:meth:`!pyramid.configuration.Configurator.add_view`. Any valid keyword -arguments for :meth:`!pyramid.configuration.Configurator.add_view` can thus be +:meth:`~pyramid.configuration.Configurator.add_view`. Any valid keyword +arguments for :meth:`~pyramid.configuration.Configurator.add_view` can thus be used with the :class:`~pyramid.view.action` decorator to further restrict when the view will be called. -- cgit v1.2.3 From bc414e504a11e91da9e6aa3fdd7e3aea724104f9 Mon Sep 17 00:00:00 2001 From: Igor Sobreira Date: Tue, 23 Nov 2010 09:08:21 -0200 Subject: fixing typo in deprecation warning --- pyramid/settings.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pyramid/settings.py b/pyramid/settings.py index 64b108421..928dd1915 100644 --- a/pyramid/settings.py +++ b/pyramid/settings.py @@ -88,7 +88,7 @@ def get_settings(): deprecated( 'get_settings', '(pyramid.settings.get_settings is deprecated as of Pyramid 1.0. Use' - '``pyramid.threadlocals.get_current_registry().settings`` instead or use ' + '``pyramid.threadlocal.get_current_registry().settings`` instead or use ' 'the ``settings`` attribute of the registry available from the request ' '(``request.registry.settings``)).') -- cgit v1.2.3 From e880a42099f1e3df1bd628058ba9e3a38a5ef0c8 Mon Sep 17 00:00:00 2001 From: Chris McDonough Date: Wed, 24 Nov 2010 03:15:22 -0500 Subject: - Add support for json on GAE by catching NotImplementedError and importing simplejson from django.utils. --- CHANGES.txt | 3 +++ pyramid/compat/__init__.py | 7 ++++++- 2 files changed, 9 insertions(+), 1 deletion(-) diff --git a/CHANGES.txt b/CHANGES.txt index 2ea0ac448..b8c3a847f 100644 --- a/CHANGES.txt +++ b/CHANGES.txt @@ -13,6 +13,9 @@ Features - ``pyramid.testig.DummyRequest`` now has a class variable, ``query_string``, which defaults to the empty string. +- Add support for json on GAE by catching NotImplementedError and importing + simplejson from django.utils. + Bug Fixes --------- diff --git a/pyramid/compat/__init__.py b/pyramid/compat/__init__.py index 205175132..8bbf79703 100644 --- a/pyramid/compat/__init__.py +++ b/pyramid/compat/__init__.py @@ -133,7 +133,12 @@ except NameError: # pragma: no cover try: import json except ImportError: # pragma: no cover - import simplejson as json + try: + import simplejson as json + except NotImplementedError: + from django.utils import simplejson as json # GAE + + try: from hashlib import md5 -- cgit v1.2.3 From a9f17c8b3a7fc935b70e87f2a1fb8728deb16f85 Mon Sep 17 00:00:00 2001 From: Chris McDonough Date: Wed, 24 Nov 2010 18:42:35 -0500 Subject: - The Mako renderer did not properly turn the ``mako.imports``, ``mako.default_filters``, and ``mako.imports`` settings into lists. - The Mako renderer did not properly convert the ``mako.error_handler`` setting from a dotted name to a callable. - The Mako renderer now accepts a resource specification for ``mako.module_directory``. --- CHANGES.txt | 9 ++ pyramid/configuration.py | 141 +-------------------------- pyramid/mako_templating.py | 19 +++- pyramid/tests/test_configuration.py | 175 --------------------------------- pyramid/tests/test_mako_templating.py | 92 +++++++++++++++++- pyramid/tests/test_util.py | 177 ++++++++++++++++++++++++++++++++++ pyramid/util.py | 144 +++++++++++++++++++++++++++ 7 files changed, 437 insertions(+), 320 deletions(-) create mode 100644 pyramid/tests/test_util.py create mode 100644 pyramid/util.py diff --git a/CHANGES.txt b/CHANGES.txt index b8c3a847f..547a7254a 100644 --- a/CHANGES.txt +++ b/CHANGES.txt @@ -16,6 +16,9 @@ Features - Add support for json on GAE by catching NotImplementedError and importing simplejson from django.utils. +- The Mako renderer now accepts a resource specification for + ``mako.module_directory``. + Bug Fixes --------- @@ -25,6 +28,12 @@ Bug Fixes - Make default renderer work (renderer factory registered with no name, which is active for every view unless the view names a specific renderer). +- The Mako renderer did not properly turn the ``mako.imports``, + ``mako.default_filters``, and ``mako.imports`` settings into lists. + +- The Mako renderer did not properly convert the ``mako.error_handler`` + setting from a dotted name to a callable. + Documentation ------------- diff --git a/pyramid/configuration.py b/pyramid/configuration.py index 6ebb56ec3..29a322c7f 100644 --- a/pyramid/configuration.py +++ b/pyramid/configuration.py @@ -3,7 +3,6 @@ import re import sys import threading import inspect -import pkg_resources import venusian @@ -67,7 +66,6 @@ from pyramid.i18n import get_localizer from pyramid.log import make_stream_logger from pyramid.mako_templating import renderer_factory as mako_renderer_factory from pyramid.path import caller_package -from pyramid.path import package_of from pyramid.path import package_path from pyramid.registry import Registry from pyramid.renderers import RendererHelper @@ -83,6 +81,7 @@ from pyramid.traversal import DefaultRootFactory from pyramid.traversal import find_interface from pyramid.traversal import traversal_path from pyramid.urldispatch import RoutesMapper +from pyramid.util import DottedNameResolver from pyramid.view import default_exceptionresponse_view from pyramid.view import render_view_to_response @@ -2727,144 +2726,6 @@ def make_app(root_factory, package=None, filename='configure.zcml', config.end() return config.make_wsgi_app() -class DottedNameResolver(object): - """ This class resolves dotted name references to 'global' Python - objects (objects which can be imported) to those objects. - - Two dotted name styles are supported during deserialization: - - - ``pkg_resources``-style dotted names where non-module attributes - of a package are separated from the rest of the path using a ':' - e.g. ``package.module:attr``. - - - ``zope.dottedname``-style dotted names where non-module - attributes of a package are separated from the rest of the path - using a '.' e.g. ``package.module.attr``. - - These styles can be used interchangeably. If the serialization - contains a ``:`` (colon), the ``pkg_resources`` resolution - mechanism will be chosen, otherwise the ``zope.dottedname`` - resolution mechanism will be chosen. - - The constructor accepts a single argument named ``package`` which - should be a one of: - - - a Python module or package object - - - A fully qualified (not relative) dotted name to a module or package - - - The value ``None`` - - The ``package`` is used when relative dotted names are supplied to - the resolver's ``resolve`` and ``maybe_resolve`` methods. A - dotted name which has a ``.`` (dot) or ``:`` (colon) as its first - character is treated as relative. - - If the value ``None`` is supplied as the package name, the - resolver will only be able to resolve fully qualified (not - relative) names. Any attempt to resolve a relative name when the - ``package`` is ``None`` will result in an - :exc:`pyramid.configuration.ConfigurationError` exception. - - If a *module* or *module name* (as opposed to a package or package - name) is supplied as ``package``, its containing package is - computed and this package used to derive the package name (all - names are resolved relative to packages, never to modules). For - example, if the ``package`` argument to this type was passed the - string ``xml.dom.expatbuilder``, and ``.mindom`` is supplied to - the ``resolve`` method, the resulting import would be for - ``xml.minidom``, because ``xml.dom.expatbuilder`` is a module - object, not a package object. - - If a *package* or *package name* (as opposed to a module or module - name) is supplied as ``package``, this package will be used to - relative compute dotted names. For example, if the ``package`` - argument to this type was passed the string ``xml.dom``, and - ``.minidom`` is supplied to the ``resolve`` method, the resulting - import would be for ``xml.minidom``. - - When a dotted name cannot be resolved, a - :class:`pyramid.exceptions.ConfigurationError` error is raised. - """ - def __init__(self, package): - if package is None: - self.package_name = None - self.package = None - else: - if isinstance(package, basestring): - try: - __import__(package) - except ImportError: - raise ConfigurationError( - 'The dotted name %r cannot be imported' % (package,)) - package = sys.modules[package] - self.package = package_of(package) - self.package_name = self.package.__name__ - - def _pkg_resources_style(self, value): - """ package.module:attr style """ - if value.startswith('.') or value.startswith(':'): - if not self.package_name: - raise ConfigurationError( - 'relative name %r irresolveable without ' - 'package_name' % (value,)) - if value in ['.', ':']: - value = self.package_name - else: - value = self.package_name + value - return pkg_resources.EntryPoint.parse( - 'x=%s' % value).load(False) - - def _zope_dottedname_style(self, value): - """ package.module.attr style """ - module = self.package_name and self.package_name or None - if value == '.': - if self.package_name is None: - raise ConfigurationError( - 'relative name %r irresolveable without package' % (value,) - ) - name = module.split('.') - else: - name = value.split('.') - if not name[0]: - if module is None: - raise ConfigurationError( - 'relative name %r irresolveable without ' - 'package' % (value,) - ) - module = module.split('.') - name.pop(0) - while not name[0]: - module.pop() - name.pop(0) - name = module + name - - used = name.pop(0) - found = __import__(used) - for n in name: - used += '.' + n - try: - found = getattr(found, n) - except AttributeError: - __import__(used) - found = getattr(found, n) # pragma: no cover - - return found - - def resolve(self, dotted): - if not isinstance(dotted, basestring): - raise ConfigurationError('%r is not a string' % (dotted,)) - return self.maybe_resolve(dotted) - - def maybe_resolve(self, dotted): - if isinstance(dotted, basestring): - if ':' in dotted: - return self._pkg_resources_style(dotted) - else: - return self._zope_dottedname_style(dotted) - return dotted - - class ActionPredicate(object): action_name = 'action' def __init__(self, action): diff --git a/pyramid/mako_templating.py b/pyramid/mako_templating.py index 6356e0db4..c9c041edb 100644 --- a/pyramid/mako_templating.py +++ b/pyramid/mako_templating.py @@ -8,6 +8,7 @@ from pyramid.interfaces import ITemplateRenderer from pyramid.exceptions import ConfigurationError from pyramid.resource import resolve_resource_spec from pyramid.resource import abspath_from_resource_spec +from pyramid.util import DottedNameResolver from mako.lookup import TemplateLookup from mako import exceptions @@ -61,17 +62,27 @@ def renderer_factory(info): lookup = registry.queryUtility(IMakoLookup) if lookup is None: reload_templates = settings.get('reload_templates', False) - directories = settings.get('mako.directories') - module_directory = settings.get('mako.module_directory') + directories = settings.get('mako.directories', None) + module_directory = settings.get('mako.module_directory', None) input_encoding = settings.get('mako.input_encoding', 'utf-8') error_handler = settings.get('mako.error_handler', None) default_filters = settings.get('mako.default_filters', None) - imports = settings.get('mako.imports', []) + imports = settings.get('mako.imports', None) if directories is None: raise ConfigurationError( 'Mako template used without a ``mako.directories`` setting') - directories = directories.splitlines() + directories = filter(None, directories.splitlines()) directories = [ abspath_from_resource_spec(d) for d in directories ] + if module_directory is not None: + module_directory = abspath_from_resource_spec(module_directory) + if error_handler is not None: + dotted = DottedNameResolver(info.package) + error_handler = dotted.maybe_resolve(error_handler) + if default_filters is not None: + default_filters = filter(None, default_filters.splitlines()) + if imports: + imports = filter(None, imports.splitlines()) + lookup = PkgResourceTemplateLookup(directories=directories, module_directory=module_directory, input_encoding=input_encoding, diff --git a/pyramid/tests/test_configuration.py b/pyramid/tests/test_configuration.py index 5113d1f4e..938db3c31 100644 --- a/pyramid/tests/test_configuration.py +++ b/pyramid/tests/test_configuration.py @@ -4286,181 +4286,6 @@ class TestMakeApp(unittest.TestCase): Configurator=DummyConfigurator) self.assertEqual(app.zcml_file, '2.zcml') -class TestDottedNameResolver(unittest.TestCase): - def _makeOne(self, package=None): - from pyramid.configuration import DottedNameResolver - return DottedNameResolver(package) - - def config_exc(self, func, *arg, **kw): - from pyramid.exceptions import ConfigurationError - try: - func(*arg, **kw) - except ConfigurationError, e: - return e - else: - raise AssertionError('Invalid not raised') # pragma: no cover - - def test_zope_dottedname_style_resolve_absolute(self): - typ = self._makeOne() - result = typ._zope_dottedname_style( - 'pyramid.tests.test_configuration.TestDottedNameResolver') - self.assertEqual(result, self.__class__) - - def test_zope_dottedname_style_irrresolveable_absolute(self): - typ = self._makeOne() - self.assertRaises(ImportError, typ._zope_dottedname_style, - 'pyramid.test_configuration.nonexisting_name') - - def test__zope_dottedname_style_resolve_relative(self): - import pyramid.tests - typ = self._makeOne(package=pyramid.tests) - result = typ._zope_dottedname_style( - '.test_configuration.TestDottedNameResolver') - self.assertEqual(result, self.__class__) - - def test__zope_dottedname_style_resolve_relative_leading_dots(self): - import pyramid.tests.test_configuration - typ = self._makeOne(package=pyramid.tests) - result = typ._zope_dottedname_style( - '..tests.test_configuration.TestDottedNameResolver') - self.assertEqual(result, self.__class__) - - def test__zope_dottedname_style_resolve_relative_is_dot(self): - import pyramid.tests - typ = self._makeOne(package=pyramid.tests) - result = typ._zope_dottedname_style('.') - self.assertEqual(result, pyramid.tests) - - def test__zope_dottedname_style_irresolveable_relative_is_dot(self): - typ = self._makeOne() - e = self.config_exc(typ._zope_dottedname_style, '.') - self.assertEqual( - e.args[0], - "relative name '.' irresolveable without package") - - def test_zope_dottedname_style_resolve_relative_nocurrentpackage(self): - typ = self._makeOne() - e = self.config_exc(typ._zope_dottedname_style, '.whatever') - self.assertEqual( - e.args[0], - "relative name '.whatever' irresolveable without package") - - def test_zope_dottedname_style_irrresolveable_relative(self): - import pyramid.tests - typ = self._makeOne(package=pyramid.tests) - self.assertRaises(ImportError, typ._zope_dottedname_style, - '.notexisting') - - def test__zope_dottedname_style_resolveable_relative(self): - import pyramid - typ = self._makeOne(package=pyramid) - result = typ._zope_dottedname_style('.tests') - from pyramid import tests - self.assertEqual(result, tests) - - def test__zope_dottedname_style_irresolveable_absolute(self): - typ = self._makeOne() - self.assertRaises( - ImportError, - typ._zope_dottedname_style, 'pyramid.fudge.bar') - - def test__zope_dottedname_style_resolveable_absolute(self): - typ = self._makeOne() - result = typ._zope_dottedname_style( - 'pyramid.tests.test_configuration.TestDottedNameResolver') - self.assertEqual(result, self.__class__) - - def test__pkg_resources_style_resolve_absolute(self): - typ = self._makeOne() - result = typ._pkg_resources_style( - 'pyramid.tests.test_configuration:TestDottedNameResolver') - self.assertEqual(result, self.__class__) - - def test__pkg_resources_style_irrresolveable_absolute(self): - typ = self._makeOne() - self.assertRaises(ImportError, typ._pkg_resources_style, - 'pyramid.tests:nonexisting') - - def test__pkg_resources_style_resolve_relative(self): - import pyramid.tests - typ = self._makeOne(package=pyramid.tests) - result = typ._pkg_resources_style( - '.test_configuration:TestDottedNameResolver') - self.assertEqual(result, self.__class__) - - def test__pkg_resources_style_resolve_relative_is_dot(self): - import pyramid.tests - typ = self._makeOne(package=pyramid.tests) - result = typ._pkg_resources_style('.') - self.assertEqual(result, pyramid.tests) - - def test__pkg_resources_style_resolve_relative_nocurrentpackage(self): - typ = self._makeOne() - from pyramid.exceptions import ConfigurationError - self.assertRaises(ConfigurationError, typ._pkg_resources_style, - '.whatever') - - def test__pkg_resources_style_irrresolveable_relative(self): - import pyramid - typ = self._makeOne(package=pyramid) - self.assertRaises(ImportError, typ._pkg_resources_style, - ':notexisting') - - def test_resolve_not_a_string(self): - typ = self._makeOne() - e = self.config_exc(typ.resolve, None) - self.assertEqual(e.args[0], 'None is not a string') - - def test_resolve_using_pkgresources_style(self): - typ = self._makeOne() - result = typ.resolve( - 'pyramid.tests.test_configuration:TestDottedNameResolver') - self.assertEqual(result, self.__class__) - - def test_resolve_using_zope_dottedname_style(self): - typ = self._makeOne() - result = typ.resolve( - 'pyramid.tests.test_configuration:TestDottedNameResolver') - self.assertEqual(result, self.__class__) - - def test_resolve_missing_raises(self): - typ = self._makeOne() - self.assertRaises(ImportError, typ.resolve, 'cant.be.found') - - def test_ctor_string_module_resolveable(self): - import pyramid.tests - typ = self._makeOne('pyramid.tests.test_configuration') - self.assertEqual(typ.package, pyramid.tests) - self.assertEqual(typ.package_name, 'pyramid.tests') - - def test_ctor_string_package_resolveable(self): - import pyramid.tests - typ = self._makeOne('pyramid.tests') - self.assertEqual(typ.package, pyramid.tests) - self.assertEqual(typ.package_name, 'pyramid.tests') - - def test_ctor_string_irresolveable(self): - from pyramid.configuration import ConfigurationError - self.assertRaises(ConfigurationError, self._makeOne, 'cant.be.found') - - def test_ctor_module(self): - import pyramid.tests - import pyramid.tests.test_configuration - typ = self._makeOne(pyramid.tests.test_configuration) - self.assertEqual(typ.package, pyramid.tests) - self.assertEqual(typ.package_name, 'pyramid.tests') - - def test_ctor_package(self): - import pyramid.tests - typ = self._makeOne(pyramid.tests) - self.assertEqual(typ.package, pyramid.tests) - self.assertEqual(typ.package_name, 'pyramid.tests') - - def test_ctor_None(self): - typ = self._makeOne(None) - self.assertEqual(typ.package, None) - self.assertEqual(typ.package_name, None) - class Test_isexception(unittest.TestCase): def _callFUT(self, ob): from pyramid.configuration import isexception diff --git a/pyramid/tests/test_mako_templating.py b/pyramid/tests/test_mako_templating.py index e0c02550b..cfb54b902 100644 --- a/pyramid/tests/test_mako_templating.py +++ b/pyramid/tests/test_mako_templating.py @@ -47,7 +47,7 @@ class Test_renderer_factory(Base, unittest.TestCase): def test_composite_directories_path(self): from pyramid.mako_templating import IMakoLookup - twice = self.templates_dir + '\n' + self.templates_dir + twice = '\n' + self.templates_dir + '\n' + self.templates_dir + '\n' settings = {'mako.directories':twice} info = DummyRendererInfo({ 'name':'helloworld.mak', @@ -59,6 +59,96 @@ class Test_renderer_factory(Base, unittest.TestCase): lookup = self.config.registry.getUtility(IMakoLookup) self.assertEqual(lookup.directories, [self.templates_dir]*2) + def test_with_module_directory_resource_spec(self): + import os + from pyramid.mako_templating import IMakoLookup + module_directory = 'pyramid.tests:fixtures' + settings = {'mako.directories':self.templates_dir, + 'mako.module_directory':module_directory} + info = DummyRendererInfo({ + 'name':'helloworld.mak', + 'package':None, + 'registry':self.config.registry, + 'settings':settings, + }) + self._callFUT(info) + lookup = self.config.registry.getUtility(IMakoLookup) + fixtures = os.path.join(os.path.dirname(__file__), 'fixtures') + self.assertEqual(lookup.module_directory, fixtures) + + def test_with_module_directory_resource_abspath(self): + import os + from pyramid.mako_templating import IMakoLookup + fixtures = os.path.join(os.path.dirname(__file__), 'fixtures') + settings = {'mako.directories':self.templates_dir, + 'mako.module_directory':fixtures} + info = DummyRendererInfo({ + 'name':'helloworld.mak', + 'package':None, + 'registry':self.config.registry, + 'settings':settings, + }) + self._callFUT(info) + lookup = self.config.registry.getUtility(IMakoLookup) + self.assertEqual(lookup.module_directory, fixtures) + + def test_with_input_encoding(self): + from pyramid.mako_templating import IMakoLookup + settings = {'mako.directories':self.templates_dir, + 'mako.input_encoding':'utf-16'} + info = DummyRendererInfo({ + 'name':'helloworld.mak', + 'package':None, + 'registry':self.config.registry, + 'settings':settings, + }) + self._callFUT(info) + lookup = self.config.registry.getUtility(IMakoLookup) + self.assertEqual(lookup.template_args['input_encoding'], 'utf-16') + + def test_with_error_handler(self): + from pyramid.mako_templating import IMakoLookup + settings = {'mako.directories':self.templates_dir, + 'mako.error_handler':'pyramid.tests'} + import pyramid.tests + info = DummyRendererInfo({ + 'name':'helloworld.mak', + 'package':None, + 'registry':self.config.registry, + 'settings':settings, + }) + self._callFUT(info) + lookup = self.config.registry.getUtility(IMakoLookup) + self.assertEqual(lookup.template_args['error_handler'], pyramid.tests) + + def test_with_default_filters(self): + from pyramid.mako_templating import IMakoLookup + settings = {'mako.directories':self.templates_dir, + 'mako.default_filters':'\nh\ng\n\n'} + info = DummyRendererInfo({ + 'name':'helloworld.mak', + 'package':None, + 'registry':self.config.registry, + 'settings':settings, + }) + self._callFUT(info) + lookup = self.config.registry.getUtility(IMakoLookup) + self.assertEqual(lookup.template_args['default_filters'], ['h', 'g']) + + def test_with_imports(self): + from pyramid.mako_templating import IMakoLookup + settings = {'mako.directories':self.templates_dir, + 'mako.imports':'\none\ntwo\n\n'} + info = DummyRendererInfo({ + 'name':'helloworld.mak', + 'package':None, + 'registry':self.config.registry, + 'settings':settings, + }) + self._callFUT(info) + lookup = self.config.registry.getUtility(IMakoLookup) + self.assertEqual(lookup.template_args['imports'], ['one', 'two']) + def test_with_lookup(self): from pyramid.mako_templating import IMakoLookup lookup = dict() diff --git a/pyramid/tests/test_util.py b/pyramid/tests/test_util.py new file mode 100644 index 000000000..2929f888f --- /dev/null +++ b/pyramid/tests/test_util.py @@ -0,0 +1,177 @@ +import unittest + +class TestDottedNameResolver(unittest.TestCase): + def _makeOne(self, package=None): + from pyramid.util import DottedNameResolver + return DottedNameResolver(package) + + def config_exc(self, func, *arg, **kw): + from pyramid.exceptions import ConfigurationError + try: + func(*arg, **kw) + except ConfigurationError, e: + return e + else: + raise AssertionError('Invalid not raised') # pragma: no cover + + def test_zope_dottedname_style_resolve_absolute(self): + typ = self._makeOne() + result = typ._zope_dottedname_style( + 'pyramid.tests.test_util.TestDottedNameResolver') + self.assertEqual(result, self.__class__) + + def test_zope_dottedname_style_irrresolveable_absolute(self): + typ = self._makeOne() + self.assertRaises(ImportError, typ._zope_dottedname_style, + 'pyramid.test_util.nonexisting_name') + + def test__zope_dottedname_style_resolve_relative(self): + import pyramid.tests + typ = self._makeOne(package=pyramid.tests) + result = typ._zope_dottedname_style( + '.test_util.TestDottedNameResolver') + self.assertEqual(result, self.__class__) + + def test__zope_dottedname_style_resolve_relative_leading_dots(self): + import pyramid.tests.test_configuration + typ = self._makeOne(package=pyramid.tests) + result = typ._zope_dottedname_style( + '..tests.test_util.TestDottedNameResolver') + self.assertEqual(result, self.__class__) + + def test__zope_dottedname_style_resolve_relative_is_dot(self): + import pyramid.tests + typ = self._makeOne(package=pyramid.tests) + result = typ._zope_dottedname_style('.') + self.assertEqual(result, pyramid.tests) + + def test__zope_dottedname_style_irresolveable_relative_is_dot(self): + typ = self._makeOne() + e = self.config_exc(typ._zope_dottedname_style, '.') + self.assertEqual( + e.args[0], + "relative name '.' irresolveable without package") + + def test_zope_dottedname_style_resolve_relative_nocurrentpackage(self): + typ = self._makeOne() + e = self.config_exc(typ._zope_dottedname_style, '.whatever') + self.assertEqual( + e.args[0], + "relative name '.whatever' irresolveable without package") + + def test_zope_dottedname_style_irrresolveable_relative(self): + import pyramid.tests + typ = self._makeOne(package=pyramid.tests) + self.assertRaises(ImportError, typ._zope_dottedname_style, + '.notexisting') + + def test__zope_dottedname_style_resolveable_relative(self): + import pyramid + typ = self._makeOne(package=pyramid) + result = typ._zope_dottedname_style('.tests') + from pyramid import tests + self.assertEqual(result, tests) + + def test__zope_dottedname_style_irresolveable_absolute(self): + typ = self._makeOne() + self.assertRaises( + ImportError, + typ._zope_dottedname_style, 'pyramid.fudge.bar') + + def test__zope_dottedname_style_resolveable_absolute(self): + typ = self._makeOne() + result = typ._zope_dottedname_style( + 'pyramid.tests.test_util.TestDottedNameResolver') + self.assertEqual(result, self.__class__) + + def test__pkg_resources_style_resolve_absolute(self): + typ = self._makeOne() + result = typ._pkg_resources_style( + 'pyramid.tests.test_util:TestDottedNameResolver') + self.assertEqual(result, self.__class__) + + def test__pkg_resources_style_irrresolveable_absolute(self): + typ = self._makeOne() + self.assertRaises(ImportError, typ._pkg_resources_style, + 'pyramid.tests:nonexisting') + + def test__pkg_resources_style_resolve_relative(self): + import pyramid.tests + typ = self._makeOne(package=pyramid.tests) + result = typ._pkg_resources_style( + '.test_util:TestDottedNameResolver') + self.assertEqual(result, self.__class__) + + def test__pkg_resources_style_resolve_relative_is_dot(self): + import pyramid.tests + typ = self._makeOne(package=pyramid.tests) + result = typ._pkg_resources_style('.') + self.assertEqual(result, pyramid.tests) + + def test__pkg_resources_style_resolve_relative_nocurrentpackage(self): + typ = self._makeOne() + from pyramid.exceptions import ConfigurationError + self.assertRaises(ConfigurationError, typ._pkg_resources_style, + '.whatever') + + def test__pkg_resources_style_irrresolveable_relative(self): + import pyramid + typ = self._makeOne(package=pyramid) + self.assertRaises(ImportError, typ._pkg_resources_style, + ':notexisting') + + def test_resolve_not_a_string(self): + typ = self._makeOne() + e = self.config_exc(typ.resolve, None) + self.assertEqual(e.args[0], 'None is not a string') + + def test_resolve_using_pkgresources_style(self): + typ = self._makeOne() + result = typ.resolve( + 'pyramid.tests.test_util:TestDottedNameResolver') + self.assertEqual(result, self.__class__) + + def test_resolve_using_zope_dottedname_style(self): + typ = self._makeOne() + result = typ.resolve( + 'pyramid.tests.test_util:TestDottedNameResolver') + self.assertEqual(result, self.__class__) + + def test_resolve_missing_raises(self): + typ = self._makeOne() + self.assertRaises(ImportError, typ.resolve, 'cant.be.found') + + def test_ctor_string_module_resolveable(self): + import pyramid.tests + typ = self._makeOne('pyramid.tests.test_util') + self.assertEqual(typ.package, pyramid.tests) + self.assertEqual(typ.package_name, 'pyramid.tests') + + def test_ctor_string_package_resolveable(self): + import pyramid.tests + typ = self._makeOne('pyramid.tests') + self.assertEqual(typ.package, pyramid.tests) + self.assertEqual(typ.package_name, 'pyramid.tests') + + def test_ctor_string_irresolveable(self): + from pyramid.configuration import ConfigurationError + self.assertRaises(ConfigurationError, self._makeOne, 'cant.be.found') + + def test_ctor_module(self): + import pyramid.tests + import pyramid.tests.test_util + typ = self._makeOne(pyramid.tests.test_util) + self.assertEqual(typ.package, pyramid.tests) + self.assertEqual(typ.package_name, 'pyramid.tests') + + def test_ctor_package(self): + import pyramid.tests + typ = self._makeOne(pyramid.tests) + self.assertEqual(typ.package, pyramid.tests) + self.assertEqual(typ.package_name, 'pyramid.tests') + + def test_ctor_None(self): + typ = self._makeOne(None) + self.assertEqual(typ.package, None) + self.assertEqual(typ.package_name, None) + diff --git a/pyramid/util.py b/pyramid/util.py new file mode 100644 index 000000000..84a23bb23 --- /dev/null +++ b/pyramid/util.py @@ -0,0 +1,144 @@ +import pkg_resources +import sys + +from pyramid.exceptions import ConfigurationError +from pyramid.path import package_of + +class DottedNameResolver(object): + """ This class resolves dotted name references to 'global' Python + objects (objects which can be imported) to those objects. + + Two dotted name styles are supported during deserialization: + + - ``pkg_resources``-style dotted names where non-module attributes + of a package are separated from the rest of the path using a ':' + e.g. ``package.module:attr``. + + - ``zope.dottedname``-style dotted names where non-module + attributes of a package are separated from the rest of the path + using a '.' e.g. ``package.module.attr``. + + These styles can be used interchangeably. If the serialization + contains a ``:`` (colon), the ``pkg_resources`` resolution + mechanism will be chosen, otherwise the ``zope.dottedname`` + resolution mechanism will be chosen. + + The constructor accepts a single argument named ``package`` which + should be a one of: + + - a Python module or package object + + - A fully qualified (not relative) dotted name to a module or package + + - The value ``None`` + + The ``package`` is used when relative dotted names are supplied to + the resolver's ``resolve`` and ``maybe_resolve`` methods. A + dotted name which has a ``.`` (dot) or ``:`` (colon) as its first + character is treated as relative. + + If the value ``None`` is supplied as the package name, the + resolver will only be able to resolve fully qualified (not + relative) names. Any attempt to resolve a relative name when the + ``package`` is ``None`` will result in an + :exc:`pyramid.configuration.ConfigurationError` exception. + + If a *module* or *module name* (as opposed to a package or package + name) is supplied as ``package``, its containing package is + computed and this package used to derive the package name (all + names are resolved relative to packages, never to modules). For + example, if the ``package`` argument to this type was passed the + string ``xml.dom.expatbuilder``, and ``.mindom`` is supplied to + the ``resolve`` method, the resulting import would be for + ``xml.minidom``, because ``xml.dom.expatbuilder`` is a module + object, not a package object. + + If a *package* or *package name* (as opposed to a module or module + name) is supplied as ``package``, this package will be used to + relative compute dotted names. For example, if the ``package`` + argument to this type was passed the string ``xml.dom``, and + ``.minidom`` is supplied to the ``resolve`` method, the resulting + import would be for ``xml.minidom``. + + When a dotted name cannot be resolved, a + :class:`pyramid.exceptions.ConfigurationError` error is raised. + """ + def __init__(self, package): + if package is None: + self.package_name = None + self.package = None + else: + if isinstance(package, basestring): + try: + __import__(package) + except ImportError: + raise ConfigurationError( + 'The dotted name %r cannot be imported' % (package,)) + package = sys.modules[package] + self.package = package_of(package) + self.package_name = self.package.__name__ + + def _pkg_resources_style(self, value): + """ package.module:attr style """ + if value.startswith('.') or value.startswith(':'): + if not self.package_name: + raise ConfigurationError( + 'relative name %r irresolveable without ' + 'package_name' % (value,)) + if value in ['.', ':']: + value = self.package_name + else: + value = self.package_name + value + return pkg_resources.EntryPoint.parse( + 'x=%s' % value).load(False) + + def _zope_dottedname_style(self, value): + """ package.module.attr style """ + module = self.package_name and self.package_name or None + if value == '.': + if self.package_name is None: + raise ConfigurationError( + 'relative name %r irresolveable without package' % (value,) + ) + name = module.split('.') + else: + name = value.split('.') + if not name[0]: + if module is None: + raise ConfigurationError( + 'relative name %r irresolveable without ' + 'package' % (value,) + ) + module = module.split('.') + name.pop(0) + while not name[0]: + module.pop() + name.pop(0) + name = module + name + + used = name.pop(0) + found = __import__(used) + for n in name: + used += '.' + n + try: + found = getattr(found, n) + except AttributeError: + __import__(used) + found = getattr(found, n) # pragma: no cover + + return found + + def resolve(self, dotted): + if not isinstance(dotted, basestring): + raise ConfigurationError('%r is not a string' % (dotted,)) + return self.maybe_resolve(dotted) + + def maybe_resolve(self, dotted): + if isinstance(dotted, basestring): + if ':' in dotted: + return self._pkg_resources_style(dotted) + else: + return self._zope_dottedname_style(dotted) + return dotted + + -- cgit v1.2.3 From 0cb7acf94d429a6019871308469a98bafecac923 Mon Sep 17 00:00:00 2001 From: Chris McDonough Date: Wed, 24 Nov 2010 18:50:30 -0500 Subject: typo fix --- CHANGES.txt | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/CHANGES.txt b/CHANGES.txt index 547a7254a..3c6b8e010 100644 --- a/CHANGES.txt +++ b/CHANGES.txt @@ -10,8 +10,8 @@ Features templates now use idiomatic SQLAlchemy configuration in their respective ``.ini`` files and Python code. -- ``pyramid.testig.DummyRequest`` now has a class variable, ``query_string``, - which defaults to the empty string. +- ``pyramid.testing.DummyRequest`` now has a class variable, + ``query_string``, which defaults to the empty string. - Add support for json on GAE by catching NotImplementedError and importing simplejson from django.utils. -- cgit v1.2.3 From b64d22c7e5692e10434eec83f6e2c64a4fed6a9e Mon Sep 17 00:00:00 2001 From: Chris McDonough Date: Wed, 24 Nov 2010 19:01:49 -0500 Subject: allow imports, directories, and default_filters to be lists in settings --- pyramid/mako_templating.py | 11 ++++++---- pyramid/tests/test_mako_templating.py | 41 +++++++++++++++++++++++++++++++++++ 2 files changed, 48 insertions(+), 4 deletions(-) diff --git a/pyramid/mako_templating.py b/pyramid/mako_templating.py index c9c041edb..3ef2868a5 100644 --- a/pyramid/mako_templating.py +++ b/pyramid/mako_templating.py @@ -71,7 +71,8 @@ def renderer_factory(info): if directories is None: raise ConfigurationError( 'Mako template used without a ``mako.directories`` setting') - directories = filter(None, directories.splitlines()) + if not hasattr(directories, '__iter__'): + directories = filter(None, directories.splitlines()) directories = [ abspath_from_resource_spec(d) for d in directories ] if module_directory is not None: module_directory = abspath_from_resource_spec(module_directory) @@ -79,9 +80,11 @@ def renderer_factory(info): dotted = DottedNameResolver(info.package) error_handler = dotted.maybe_resolve(error_handler) if default_filters is not None: - default_filters = filter(None, default_filters.splitlines()) - if imports: - imports = filter(None, imports.splitlines()) + if not hasattr(default_filters, '__iter__'): + default_filters = filter(None, default_filters.splitlines()) + if imports is not None: + if not hasattr(imports, '__iter__'): + imports = filter(None, imports.splitlines()) lookup = PkgResourceTemplateLookup(directories=directories, module_directory=module_directory, diff --git a/pyramid/tests/test_mako_templating.py b/pyramid/tests/test_mako_templating.py index cfb54b902..4b75e1a28 100644 --- a/pyramid/tests/test_mako_templating.py +++ b/pyramid/tests/test_mako_templating.py @@ -59,6 +59,19 @@ class Test_renderer_factory(Base, unittest.TestCase): lookup = self.config.registry.getUtility(IMakoLookup) self.assertEqual(lookup.directories, [self.templates_dir]*2) + def test_directories_list(self): + from pyramid.mako_templating import IMakoLookup + settings = {'mako.directories':['a', 'b']} + info = DummyRendererInfo({ + 'name':'helloworld.mak', + 'package':None, + 'registry':self.config.registry, + 'settings':settings, + }) + self._callFUT(info) + lookup = self.config.registry.getUtility(IMakoLookup) + self.assertEqual(lookup.directories, ['a', 'b']) + def test_with_module_directory_resource_spec(self): import os from pyramid.mako_templating import IMakoLookup @@ -135,6 +148,20 @@ class Test_renderer_factory(Base, unittest.TestCase): lookup = self.config.registry.getUtility(IMakoLookup) self.assertEqual(lookup.template_args['default_filters'], ['h', 'g']) + def test_with_default_filters_list(self): + from pyramid.mako_templating import IMakoLookup + settings = {'mako.directories':self.templates_dir, + 'mako.default_filters':['h', 'g']} + info = DummyRendererInfo({ + 'name':'helloworld.mak', + 'package':None, + 'registry':self.config.registry, + 'settings':settings, + }) + self._callFUT(info) + lookup = self.config.registry.getUtility(IMakoLookup) + self.assertEqual(lookup.template_args['default_filters'], ['h', 'g']) + def test_with_imports(self): from pyramid.mako_templating import IMakoLookup settings = {'mako.directories':self.templates_dir, @@ -149,6 +176,20 @@ class Test_renderer_factory(Base, unittest.TestCase): lookup = self.config.registry.getUtility(IMakoLookup) self.assertEqual(lookup.template_args['imports'], ['one', 'two']) + def test_with_imports_list(self): + from pyramid.mako_templating import IMakoLookup + settings = {'mako.directories':self.templates_dir, + 'mako.imports':['one', 'two']} + info = DummyRendererInfo({ + 'name':'helloworld.mak', + 'package':None, + 'registry':self.config.registry, + 'settings':settings, + }) + self._callFUT(info) + lookup = self.config.registry.getUtility(IMakoLookup) + self.assertEqual(lookup.template_args['imports'], ['one', 'two']) + def test_with_lookup(self): from pyramid.mako_templating import IMakoLookup lookup = dict() -- cgit v1.2.3 From 81e648ffded9caa9480c0053c11a0bc15afbc39a Mon Sep 17 00:00:00 2001 From: Chris McDonough Date: Wed, 24 Nov 2010 23:07:58 -0500 Subject: - New boolean Mako settings variable ``mako.strict_undefined``. See `Mako Context Variables `_ for its meaning. - Depend on Mako 0.3.6+ (we now require the ``strict_undefined`` feature). --- CHANGES.txt | 10 ++++++++++ TODO.txt | 2 -- docs/narr/environment.rst | 18 ++++++++++++++++++ pyramid/mako_templating.py | 6 +++++- pyramid/tests/test_mako_templating.py | 31 ++++++++++++++++++++++++++++++- setup.py | 2 +- 6 files changed, 64 insertions(+), 5 deletions(-) diff --git a/CHANGES.txt b/CHANGES.txt index 3c6b8e010..1675ab9fc 100644 --- a/CHANGES.txt +++ b/CHANGES.txt @@ -19,6 +19,16 @@ Features - The Mako renderer now accepts a resource specification for ``mako.module_directory``. +- New boolean Mako settings variable ``mako.strict_undefined``. See `Mako + Context Variables + `_ for + its meaning. + +Dependencies +------------ + +- Depend on Mako 0.3.6+ (we now require the ``strict_undefined`` feature). + Bug Fixes --------- diff --git a/TODO.txt b/TODO.txt index c5584d3cc..0033eb3b3 100644 --- a/TODO.txt +++ b/TODO.txt @@ -20,8 +20,6 @@ Should-Have - Add docs for httpexceptions module for each webob.exc class that inherits from WSGIHTTPException. -- Create a ``docs`` directory for each paster template. - - Remove "BFG" from Pyramid-specific environ variables. - translationdir ZCML directive use of ``path_spec`` should maybe die. diff --git a/docs/narr/environment.rst b/docs/narr/environment.rst index ecf85e464..c3fe401ec 100644 --- a/docs/narr/environment.rst +++ b/docs/narr/environment.rst @@ -249,6 +249,24 @@ will be placed into the module level preamble of all generated Python modules. | | +-----------------------------+ + +Mako Strict Undefined ++++++++++++++++++++++ + +``true`` or ``false``, representing the "strict undefined" behavior of Mako +(see `Mako Context Variables +`_). By +default, this is ``false``. + ++-----------------------------+ +| Config File Setting Name | ++=============================+ +| ``mako.strict_undefined`` | +| | +| | +| | ++-----------------------------+ + Examples -------- diff --git a/pyramid/mako_templating.py b/pyramid/mako_templating.py index 3ef2868a5..a5f9b0f68 100644 --- a/pyramid/mako_templating.py +++ b/pyramid/mako_templating.py @@ -8,6 +8,7 @@ from pyramid.interfaces import ITemplateRenderer from pyramid.exceptions import ConfigurationError from pyramid.resource import resolve_resource_spec from pyramid.resource import abspath_from_resource_spec +from pyramid.settings import asbool from pyramid.util import DottedNameResolver from mako.lookup import TemplateLookup @@ -68,6 +69,7 @@ def renderer_factory(info): error_handler = settings.get('mako.error_handler', None) default_filters = settings.get('mako.default_filters', None) imports = settings.get('mako.imports', None) + strict_undefined = settings.get('mako.strict_undefined', 'false') if directories is None: raise ConfigurationError( 'Mako template used without a ``mako.directories`` setting') @@ -85,6 +87,7 @@ def renderer_factory(info): if imports is not None: if not hasattr(imports, '__iter__'): imports = filter(None, imports.splitlines()) + strict_undefined = asbool(strict_undefined) lookup = PkgResourceTemplateLookup(directories=directories, module_directory=module_directory, @@ -92,7 +95,8 @@ def renderer_factory(info): error_handler=error_handler, default_filters=default_filters, imports=imports, - filesystem_checks=reload_templates) + filesystem_checks=reload_templates, + strict_undefined=strict_undefined) registry_lock.acquire() try: registry.registerUtility(lookup, IMakoLookup) diff --git a/pyramid/tests/test_mako_templating.py b/pyramid/tests/test_mako_templating.py index 4b75e1a28..506dc18cd 100644 --- a/pyramid/tests/test_mako_templating.py +++ b/pyramid/tests/test_mako_templating.py @@ -190,6 +190,34 @@ class Test_renderer_factory(Base, unittest.TestCase): lookup = self.config.registry.getUtility(IMakoLookup) self.assertEqual(lookup.template_args['imports'], ['one', 'two']) + def test_with_strict_undefined_true(self): + from pyramid.mako_templating import IMakoLookup + settings = {'mako.directories':self.templates_dir, + 'mako.strict_undefined':'true'} + info = DummyRendererInfo({ + 'name':'helloworld.mak', + 'package':None, + 'registry':self.config.registry, + 'settings':settings, + }) + self._callFUT(info) + lookup = self.config.registry.getUtility(IMakoLookup) + self.assertEqual(lookup.template_args['strict_undefined'], True) + + def test_with_strict_undefined_false(self): + from pyramid.mako_templating import IMakoLookup + settings = {'mako.directories':self.templates_dir, + 'mako.strict_undefined':'false'} + info = DummyRendererInfo({ + 'name':'helloworld.mak', + 'package':None, + 'registry':self.config.registry, + 'settings':settings, + }) + self._callFUT(info) + lookup = self.config.registry.getUtility(IMakoLookup) + self.assertEqual(lookup.template_args['strict_undefined'], False) + def test_with_lookup(self): from pyramid.mako_templating import IMakoLookup lookup = dict() @@ -301,7 +329,8 @@ class TestIntegration(unittest.TestCase): def test_render_to_response_pkg_spec(self): from pyramid.renderers import render_to_response - result = render_to_response('pyramid.tests:fixtures/helloworld.mak', {'a':1}) + result = render_to_response('pyramid.tests:fixtures/helloworld.mak', + {'a':1}) self.assertEqual(result.ubody, u'\nHello föö\n') def test_render_with_abs_path(self): diff --git a/setup.py b/setup.py index c1939f73c..75f5b13dd 100644 --- a/setup.py +++ b/setup.py @@ -29,7 +29,7 @@ except IOError: install_requires=[ 'Chameleon >= 1.2.3', - 'Mako', + 'Mako >= 0.3.6', # strict_undefined 'Paste > 1.7', # temp version pin to prevent PyPi install failure :-( 'PasteDeploy', 'PasteScript', -- cgit v1.2.3 From 8add482cbd7353542b9bac61e8c13deecbe8825e Mon Sep 17 00:00:00 2001 From: Blaise Laflamme Date: Fri, 26 Nov 2010 15:26:36 -0500 Subject: Updated starter template with new theme --- .../starter/+package+/static/footerbg.png | Bin 0 -> 333 bytes .../starter/+package+/static/headerbg.png | Bin 0 -> 203 bytes .../starter/+package+/static/ie6.css | 8 ++++++ .../starter/+package+/static/logo.png | Bin 6641 -> 0 bytes .../starter/+package+/static/middlebg.png | Bin 0 -> 2797 bytes .../starter/+package+/static/pylons.css | 30 +++++++++++---------- .../starter/+package+/static/pyramid.png | Bin 0 -> 33055 bytes .../starter/+package+/static/transparent.gif | Bin 0 -> 49 bytes .../starter/+package+/templates/mytemplate.pt | 25 ++++++++--------- 9 files changed, 35 insertions(+), 28 deletions(-) create mode 100644 pyramid/paster_templates/starter/+package+/static/footerbg.png create mode 100644 pyramid/paster_templates/starter/+package+/static/headerbg.png create mode 100644 pyramid/paster_templates/starter/+package+/static/ie6.css delete mode 100644 pyramid/paster_templates/starter/+package+/static/logo.png create mode 100644 pyramid/paster_templates/starter/+package+/static/middlebg.png create mode 100644 pyramid/paster_templates/starter/+package+/static/pyramid.png create mode 100644 pyramid/paster_templates/starter/+package+/static/transparent.gif diff --git a/pyramid/paster_templates/starter/+package+/static/footerbg.png b/pyramid/paster_templates/starter/+package+/static/footerbg.png new file mode 100644 index 000000000..1fbc873da Binary files /dev/null and b/pyramid/paster_templates/starter/+package+/static/footerbg.png differ diff --git a/pyramid/paster_templates/starter/+package+/static/headerbg.png b/pyramid/paster_templates/starter/+package+/static/headerbg.png new file mode 100644 index 000000000..0596f2020 Binary files /dev/null and b/pyramid/paster_templates/starter/+package+/static/headerbg.png differ diff --git a/pyramid/paster_templates/starter/+package+/static/ie6.css b/pyramid/paster_templates/starter/+package+/static/ie6.css new file mode 100644 index 000000000..b7c8493d8 --- /dev/null +++ b/pyramid/paster_templates/starter/+package+/static/ie6.css @@ -0,0 +1,8 @@ +* html img, +* html .png{position:relative;behavior:expression((this.runtimeStyle.behavior="none")&&(this.pngSet?this.pngSet=true:(this.nodeName == "IMG" && this.src.toLowerCase().indexOf('.png')>-1?(this.runtimeStyle.backgroundImage = "none", +this.runtimeStyle.filter = "progid:DXImageTransform.Microsoft.AlphaImageLoader(src='" + this.src + "',sizingMethod='image')", +this.src = "static/transparent.gif"):(this.origBg = this.origBg? this.origBg :this.currentStyle.backgroundImage.toString().replace('url("','').replace('")',''), +this.runtimeStyle.filter = "progid:DXImageTransform.Microsoft.AlphaImageLoader(src='" + this.origBg + "',sizingMethod='crop')", +this.runtimeStyle.backgroundImage = "none")),this.pngSet=true) +);} +#wrap{display:table;height:100%} diff --git a/pyramid/paster_templates/starter/+package+/static/logo.png b/pyramid/paster_templates/starter/+package+/static/logo.png deleted file mode 100644 index 88f5d9865..000000000 Binary files a/pyramid/paster_templates/starter/+package+/static/logo.png and /dev/null differ diff --git a/pyramid/paster_templates/starter/+package+/static/middlebg.png b/pyramid/paster_templates/starter/+package+/static/middlebg.png new file mode 100644 index 000000000..2369cfb7d Binary files /dev/null and b/pyramid/paster_templates/starter/+package+/static/middlebg.png differ diff --git a/pyramid/paster_templates/starter/+package+/static/pylons.css b/pyramid/paster_templates/starter/+package+/static/pylons.css index c153be07f..ba73a28f3 100644 --- a/pyramid/paster_templates/starter/+package+/static/pylons.css +++ b/pyramid/paster_templates/starter/+package+/static/pylons.css @@ -42,23 +42,25 @@ body h2, body h3, body h4, body h5, -body h6{font-family:"Nobile","Lucida Grande",Lucida,Verdana,sans-serif;font-weight:normal;color:#144fb2;font-style:normal;} -#wrap {min-height: 100%;} -#header,#footer{width:100%;color:#ffffff;height:40px;position:absolute;text-align:center;line-height:40px;overflow:hidden;font-size:12px;} -#header{background-color:#e88f00;top:0;font-size:14px;} -#footer{background-color:#000000;bottom:0;position: relative;margin-top:-40px;clear:both;} -.header,.footer{width:700px;margin-right:auto;margin-left:auto;} +body h6{font-family:"Neuton","Lucida Grande",Lucida,Verdana,sans-serif;font-weight:normal;color:#373839;font-style:normal;} +#wrap{min-height:100%;} +#header,#footer{width:100%;color:#ffffff;height:40px;position:absolute;text-align:center;line-height:40px;overflow:hidden;font-size:12px;vertical-align:middle;} +#header{background:#000000;top:0;font-size:14px;} +#footer{bottom:0;background:#000000 url(footerbg.png) repeat-x 0 top;position:relative;margin-top:-40px;clear:both;} +.header,.footer{width:750px;margin-right:auto;margin-left:auto;} .wrapper{width:100%} #top,#bottom{width:100%;} -#top{color:#888;background-color:#eee;height:300px;border-bottom:2px solid #ddd;} -#bottom{color:#222;background-color:#ffffff;overflow:hidden;padding-bottom:80px;} -.top,.bottom{width:700px;margin-right:auto;margin-left:auto;} -.top{padding-top:100px;} +#top{color:#000000;height:230px;/*border-bottom:1px solid #f19e00;*/ +background:#ffffff url(headerbg.png) repeat-x 0 top;position:relative;/*border-top:5px solid #000000;*/} +#bottom{color:#222;background-color:#ffffff;} +.top,.middle,.bottom{width:750px;margin-right:auto;margin-left:auto;} +.top{padding-top:40px;} +#middle{width:100%;height:100px;background:url(middlebg.png) repeat-x;border-top:2px solid #ffffff;border-bottom:2px solid #b2b2b2;} .app-welcome{margin-top:25px;} .app-name{color:#000000;font-weight:bold;} .bottom{padding-top:50px;} -#left{width:325px;float:left;padding-right:25px;} -#right{width:325px;float:right;padding-left:25px;} +#left{width:350px;float:left;padding-right:25px;} +#right{width:350px;float:right;padding-left:25px;} .align-left{text-align:left;} .align-right{text-align:right;} .align-center{text-align:center;} @@ -67,7 +69,7 @@ ul.links li{list-style-type:none;font-size:14px;} form{border-style:none;} fieldset{border-style:none;} input{color:#222;border:1px solid #ccc;font-family:sans-serif;font-size:12px;line-height:16px;} -input[type=text]{} +input[type=text]{width:205px;} input[type=submit]{background-color:#ddd;font-weight:bold;} /*Opera Fix*/ -body:before {content:"";height:100%;float:left;width:0;margin-top:-32767px;} +body:before{content:"";height:100%;float:left;width:0;margin-top:-32767px;} diff --git a/pyramid/paster_templates/starter/+package+/static/pyramid.png b/pyramid/paster_templates/starter/+package+/static/pyramid.png new file mode 100644 index 000000000..347e05549 Binary files /dev/null and b/pyramid/paster_templates/starter/+package+/static/pyramid.png differ diff --git a/pyramid/paster_templates/starter/+package+/static/transparent.gif b/pyramid/paster_templates/starter/+package+/static/transparent.gif new file mode 100644 index 000000000..0341802e5 Binary files /dev/null and b/pyramid/paster_templates/starter/+package+/static/transparent.gif differ diff --git a/pyramid/paster_templates/starter/+package+/templates/mytemplate.pt b/pyramid/paster_templates/starter/+package+/templates/mytemplate.pt index 6ad23d44f..02fc00eeb 100644 --- a/pyramid/paster_templates/starter/+package+/templates/mytemplate.pt +++ b/pyramid/paster_templates/starter/+package+/templates/mytemplate.pt @@ -7,21 +7,21 @@ + -
-
- +
pyramid
+
+
+
+

Welcome to ${project}, an application generated by
the Pyramid web application development framework. @@ -31,21 +31,18 @@

-

Search Pyramid documentation

+

Search documentation

- +