diff options
222 files changed, 3501 insertions, 2904 deletions
diff --git a/CHANGES.txt b/CHANGES.txt index 04f5a7d05..b7be0aea0 100644 --- a/CHANGES.txt +++ b/CHANGES.txt @@ -9,23 +9,85 @@ Bug Fixes Instead of trying to resolve the view, if it cannot, it will now just print ``<unknown>``. +- The `self` argument was included in new methods of the ``ISession`` interface + signature, causing ``pyramid_beaker`` tests to fail (jkrebs). + +- Readd ``pyramid.traversal.model_path_tuple`` as an alias for + ``pyramid.traversal.resource_path_tuple`` for backwards compatibility. + Features -------- +- Add a new API ``pyramid.url.current_route_url``, which computes a URL based + on the "current" route (if any) and its matchdict values. + - ``config.add_view`` now accepts a ``decorator`` keyword argument, a callable which will decorate the view callable before it is added to the registry. -- ``config.add_view`` now accepts a ``view_mapper`` keyword argument, which - should be a class which implements the new - ``pyramid.interfaces.IViewMapperFactory`` interface. Use of an alternate - view mapper allows objects that are meant to be used as view callables to - have an arbitrary argument list and an arbitrary result. This feature will - be used by Pyramid extension developers, not by "civilians". - -- If a handler class provides an __action_decorator__ attribute (usually a - classmethod or staticmethod), use that as the decorator for each view +- If a handler class provides an ``__action_decorator__`` attribute (usually + a classmethod or staticmethod), use that as the decorator for each view registration for that handler. +- The ``pyramid.interfaces.IAuthenticationPolicy`` interface now specifies an + ``unauthenticated_userid`` method. This method supports an important + optimization required by people who are using persistent storages which do + not support object caching and whom want to create a "user object" as a + request attribute. + +- A new API has been added to the ``pyramid.security`` module named + ``unauthenticated_userid``. This API function calls the + ``unauthenticated_userid`` method of the effective security policy. + +- An ``unauthenticated_userid`` method has been added to the dummy + authentication policy returned by + ``pyramid.config.Configurator.testing_securitypolicy``. It returns the + same thing as that the dummy authentication policy's + ``authenticated_userid`` method. + +- The class ``pyramid.authentication.AuthTktCookieHelper`` is now an API. + This class can be used by third-party authentication policy developers to + help in the mechanics of authentication cookie-setting. + +- New constructor argument to Configurator: ``default_view_mapper``. Useful + to create systems that have alternate view calling conventions. A view + mapper allows objects that are meant to be used as view callables to have + an arbitrary argument list and an arbitrary result. The object passed as + ``default_view_mapper`` should implement the + ``pyramid.interfaces.IViewMapperFactory`` interface. + +- add a ``set_view_mapper`` API to Configurator. Has + the same result as passing ``default_view_mapper`` to the Configurator + constructor. + +- ``config.add_view`` now accepts a ``mapper`` keyword argument, which should + either be ``None``, a string representing a Python dotted name, or an + object which is an ``IViewMapperFactory``. This feature is not useful for + "civilians", only for extension writers. + +- Allow static renderer provided during view registration to be overridden at + request time via a request attribute named ``override_renderer``, which + should be the name of a previously registered renderer. Useful to provide + "omnipresent" RPC using existing rendered views. + +- Instances of ``pyramid.testing.DummyRequest`` now have a ``session`` + object, which is mostly a dictionary, but also implements the other session + API methods for flash and CSRF. + +Backwards Incompatibilities +--------------------------- + +- Since the ``pyramid.interfaces.IAuthenticationPolicy`` interface now + specifies that a policy implementation must implement an + ``unauthenticated_userid`` method, all third-party custom authentication + policies now must implement this method. It, however, will only be called + when the global function named ``pyramid.security.unauthenticated_userid`` + is invoked, so if you're not invoking that, you will not notice any issues. + +- ``pyramid.interfaces.ISession.get_csrf_token`` now mandates that an + implementation should return a *new* token if one doesn't already exist in + the session (previously it would return None). The internal sessioning + implementation has been changed. + Documentation ------------- @@ -33,24 +95,44 @@ Documentation removed from the tutorials section. It was moved to the ``pyramid_tutorials`` Github repository. +- The "Resource Location and View Lookup" chapter has been replaced with a + variant of Rob Miller's "Much Ado About Traversal" (originally published at + http://blog.nonsequitarian.org/2010/much-ado-about-traversal/). + +- Many minor wording tweaks and refactorings (merged Casey Duncan's docs + fork, in which he is working on general editing). + +- Added (weak) description of new view mapper feature to Hooks narrative + chapter. + Internals --------- - The "view derivation" code is now factored into a set of classes rather than a large number of standalone functions (a side effect of the - ``view_mapper`` refactoring). + view mapper refactoring). - The ``pyramid.renderer.RendererHelper`` class has grown a ``render_view`` method, which is used by the default view mapper (a side effect of the - ``view_mapper`` refactoring). + view mapper refactoring). - The object passed as ``renderer`` to the "view deriver" is now an instance of ``pyramid.renderers.RendererHelper`` rather than a dictionary (a side - effect of ``view_mapper`` refactoring). + effect of view mapper refactoring). - The class used as the "page template" in ``pyramid.chameleon_text`` was removed, in preference to using a Chameleon-inbuilt version. +- A view callable wrapper registered in the registry now contains an + ``__original_view__`` attribute which references the original view callable + (or class). + +- The (non-API) method of all internal authentication policy implementations + previously named ``_get_userid`` is now named ``unauthenticated_userid``, + promoted to an API method. If you were overriding this method, you'll now + need to override it as ``unauthenticated_userid`` instead. + +- Remove (non-API) function of config.py named _map_view. 1.0a8 (2010-12-27) ================== diff --git a/CONTRIBUTORS.txt b/CONTRIBUTORS.txt index 7b0364b6d..ec9042f08 100644 --- a/CONTRIBUTORS.txt +++ b/CONTRIBUTORS.txt @@ -120,3 +120,5 @@ Contributors - Rob Miller, 2010/12/28 - Marius Gedminas, 2010/12/31 + +- Marcin Lulek, 2011/01/02
\ No newline at end of file diff --git a/COPYRIGHT.txt b/COPYRIGHT.txt index aa870dc84..51c76455e 100644 --- a/COPYRIGHT.txt +++ b/COPYRIGHT.txt @@ -1,4 +1,4 @@ -Copyright (c) 2008-2010 Agendaless Consulting and Contributors. +Copyright (c) 2008-2011 Agendaless Consulting and Contributors. (http://www.agendaless.com), All Rights Reserved Portions (c) Django Project (http://djangoproject.com/). @@ -11,14 +11,25 @@ Must-Have (before 1.0) - Re-make testing.setUp() and testing.tearDown() the canonical APIs for test configuration. -- Document ``decorator=`` and ``view_mapper`` parameters to add_view. +- API docs for ``pyramid.views.action``. -- Allow ``decorator=`` and ``view_mapper=`` to be passed via ZCML and the - ``view_config`` decorator. +- Use a commit veto when configuring repoze.tm2 in paster templates for + non-1X, 2X, or 3X responses. + +- Consider passing two callables to CallbackAuthenticationPolicy: one for + validating/obtaining the userid, the other for returning groups. + +- Add docs for ``__action_decorator__`` attr of handler. Should-Have ----------- +- Add a session attribute to DummyRequest. + +- Convert paster template and tutorial HTML templates to use + ``request.static_url('{{package}}:static/foo.css')`` rather than + ``${request.application_url}/static/foo.css``. + - Add notes about renderer response attrs to request docs. - Add an example of using a cascade to serve static assets from the root. diff --git a/docs/Makefile b/docs/Makefile index 3d706d17e..1d032cf45 100644 --- a/docs/Makefile +++ b/docs/Makefile @@ -25,7 +25,7 @@ help: clean: -rm -rf _build/* -html: _themes/ +html: _themes mkdir -p _build/html _build/doctrees $(SPHINXBUILD) -b html $(ALLSPHINXOPTS) _build/html @echo diff --git a/docs/api/authentication.rst b/docs/api/authentication.rst index 54db77417..a6d4c1e18 100644 --- a/docs/api/authentication.rst +++ b/docs/api/authentication.rst @@ -3,6 +3,9 @@ :mod:`pyramid.authentication` -------------------------------- +Authentication Policies +~~~~~~~~~~~~~~~~~~~~~~~ + .. automodule:: pyramid.authentication .. autoclass:: AuthTktAuthenticationPolicy @@ -11,3 +14,10 @@ .. autoclass:: RemoteUserAuthenticationPolicy +Helper Classes +~~~~~~~~~~~~~~ + + .. autoclass:: AuthTktCookieHelper + + + diff --git a/docs/api/security.rst b/docs/api/security.rst index 4acf5fe4d..de249355d 100644 --- a/docs/api/security.rst +++ b/docs/api/security.rst @@ -10,6 +10,8 @@ Authentication API Functions .. autofunction:: authenticated_userid +.. autofunction:: unauthenticated_userid + .. autofunction:: effective_principals .. autofunction:: forget diff --git a/docs/api/url.rst b/docs/api/url.rst index 1aa3082b7..01be76283 100644 --- a/docs/api/url.rst +++ b/docs/api/url.rst @@ -9,6 +9,8 @@ .. autofunction:: route_url + .. autofunction:: current_route_url + .. autofunction:: route_path .. autofunction:: static_url diff --git a/docs/conf.py b/docs/conf.py index 8c238cecd..2f4c5227a 100644 --- a/docs/conf.py +++ b/docs/conf.py @@ -13,6 +13,7 @@ import sys, os import datetime +import inspect import warnings warnings.simplefilter('ignore', DeprecationWarning) @@ -407,6 +408,18 @@ def setup(app): app.add_directive('frontmatter', frontmatter, 1, (0, 0, 0)) app.add_directive('mainmatter', mainmatter, 1, (0, 0, 0)) app.add_directive('backmatter', backmatter, 1, (0, 0, 0)) + app.connect('autodoc-process-signature', resig) + +def resig(app, what, name, obj, options, signature, return_annotation): + """ Allow for preservation of ``@action_method`` decorated methods + in configurator """ + docobj = getattr(obj, '__docobj__', None) + if docobj is not None: + argspec = inspect.getargspec(docobj) + if argspec[0] and argspec[0][0] in ('cls', 'self'): + del argspec[0][0] + signature = inspect.formatargspec(*argspec) + return signature, return_annotation # turn off all line numbers in latex formatting @@ -426,7 +439,7 @@ def setup(app): epub_title = 'The Pyramid Web Application Development Framework, Version 1.0' epub_author = 'Chris McDonough' epub_publisher = 'Agendaless Consulting' -epub_copyright = '2008-2010' +epub_copyright = '2008-2011' # The language of the text. It defaults to the language option # or en if the language is not set. diff --git a/docs/copyright.rst b/docs/copyright.rst index 691080ba7..9ef093d0c 100644 --- a/docs/copyright.rst +++ b/docs/copyright.rst @@ -7,7 +7,7 @@ by Chris McDonough .. |copy| unicode:: U+000A9 .. COPYRIGHT SIGN -Copyright |copy| 2008-2010, Agendaless Consulting. +Copyright |copy| 2008-2011, Agendaless Consulting. .. ISBN-10: 0615345379 @@ -48,9 +48,15 @@ with respect to the use of the information contained herein. Attributions ------------ +Editor: + Casey Duncan + Contributors: - Ben Bangert, Blaise Laflamme, Carlos de la Guardia, Paul Everitt, - Marius Gedminas, Casey Duncan + + Ben Bangert, Blaise Laflamme, Rob Miller, Mike Orr, Carlos de la Guardia, + Paul Everitt, Tres Seaver, Marius Gedminas, Chris Rossi, Joachim Krebs, + Xavier Spriet, Reed O'Brien, William Chambers, Charlie Choiniere, Jamaludin + Ahmad. .. Cover Designer: .. Nat Hardwick of `Electrosoup <http://www.electrosoup.co.uk>`_. diff --git a/docs/designdefense.rst b/docs/designdefense.rst index 1d6941283..df14fb440 100644 --- a/docs/designdefense.rst +++ b/docs/designdefense.rst @@ -895,9 +895,9 @@ Pyramid Applications are Extensible; I Don't Believe In Application Extensibilit Any :app:`Pyramid` application written obeying certain constraints is *extensible*. This feature is discussed in the :app:`Pyramid` documentation -chapters named :ref:`extending_chapter` and :ref:`advconf_narr`. It is made -possible by the use of the :term:`Zope Component Architecture` and within -:app:`Pyramid`. +chapters named :ref:`extending_chapter` and :ref:`advconfig_narr`. It is +made possible by the use of the :term:`Zope Component Architecture` and +within :app:`Pyramid`. "Extensible", in this context, means: @@ -1018,7 +1018,7 @@ Challenge :app:`Pyramid` performs automatic authorization checks only at :term:`view` execution time. Zope 3 wraps context objects with a `security proxy -<http://wiki.zope.org/zope3/WhatAreSecurityProxies>`, which causes Zope 3 to +<http://wiki.zope.org/zope3/WhatAreSecurityProxies>`_, which causes Zope 3 to do also security checks during attribute access. I like this, because it means: diff --git a/docs/glossary.rst b/docs/glossary.rst index 7090b5f93..a7e3a7884 100644 --- a/docs/glossary.rst +++ b/docs/glossary.rst @@ -112,15 +112,14 @@ Glossary about :app:`Pyramid` view callables. view configuration - View configuration is the act of associating a :term:`view - callable` with configuration information. This configuration - information helps map a given :term:`request` to a particular view - callable and it can influence the response of a view callable. - :app:`Pyramid` views can be configured via :term:`imperative - configuration`, :term:`ZCML` or by a special ``@view_config`` - decorator coupled with a :term:`scan`. See - :ref:`view_config_chapter` for more information about view - configuration. + View configuration is the act of associating a :term:`view callable` + with configuration information. This configuration information helps + map a given :term:`request` to a particular view callable and it can + influence the response of a view callable. :app:`Pyramid` views can be + configured via :term:`imperative configuration`, :term:`ZCML` or by a + special ``@view_config`` decorator coupled with a :term:`scan`. See + :ref:`view_config_chapter` for more information about view + configuration. view name The "URL name" of a view, e.g ``index.html``. If a view is @@ -835,7 +834,7 @@ Glossary :meth:`pyramid.config.Configurator.add_route` and :meth:`pyramid.config.Configurator.add_view` to make it more convenient to register a collection of views as a single class when - using :term:`url dispatch`. See also :ref:`handlers_chapter`. + using :term:`url dispatch`. See also :ref:`views_chapter`. Deployment settings Deployment settings are settings passed to the :term:`Configurator` as a @@ -851,6 +850,15 @@ Glossary WSGI middleware which can display debuggable traceback information in the browser when an exception is raised by a Pyramid application. See http://pypi.python.org/pypi/WebError . - - + view mapper + A view mapper is a class which implements the + :class:`pyramid.interfaces.IViewMapperFactory` interface, which performs + view argument and return value mapping. This is a plug point for + extension builders, not normally used by "civilians". + + matchdict + The dictionary attached to the :term:`request` object as + ``request.matchdict`` when a :term:`URL dispatch` route has been matched. + Its keys are names as identified within the route pattern; its values are + the values matched by each pattern name. diff --git a/docs/narr/forms.rst b/docs/narr/forms.rst index 9ba862022..080f02159 100644 --- a/docs/narr/forms.rst +++ b/docs/narr/forms.rst @@ -1,5 +1,10 @@ .. _forms_chapter: +.. index:: + single: unicode, views, and forms + single: forms, views, and unicode + single: views, forms, and unicode + Form Handling ============= diff --git a/docs/narr/hooks.rst b/docs/narr/hooks.rst index 2917b5254..cf3f56e87 100644 --- a/docs/narr/hooks.rst +++ b/docs/narr/hooks.rst @@ -541,6 +541,94 @@ The default context URL generator is available for perusal as the class :term:`Pylons` GitHub Pyramid repository. .. index:: + single: view mapper + +Using a View Mapper +------------------- + +The default calling conventions for view callables are documented in the +:ref:`views_chapter`. You can change the way users define view callbles by +employing a :term:`view mapper`. + +A view mapper is an object that accepts a set of keyword arguments and which +returns a callable. The returned callable is called with the :term:`view +callable` object. The returned callable should itself return another +callable which can be called with the "internal calling protocol" ``(context, +request)``. + +You can use a view mapper in a number of ways: + +- by setting a ``__view_mapper__`` attribute (which is the view mapper + object) on the view callable itself + +- by passing the mapper object to + :meth:`pyramid.config.Configurator.add_view` (or its declarative/decorator + equivalents) as the ``mapper`` argument. + +- by registering a *default* view mapper. + +Here's an example of a view mapper that emulates (somewhat) a Pylons +"controller". The mapper is initialized with some keyword arguments. Its +``__call__`` method accepts the view object (which will be a class). It uses +the ``attr`` keyword argument it is passed to determine which attribute +should be used as an action method. The wrapper method it returns accepts +``(context, request)`` and returns the result of calling the action method +with keyword arguments implied by the :term:`matchdict` after popping the +``action`` out of it. This somewhat emulates the Pylons style of calling +action methods with routing parameters pulled out of the route matching dict +as keyword arguments. + +.. code-block:: python + :linenos: + + # framework + + class PylonsControllerViewMapper(object): + def __init__(self, **kw): + self.kw = kw + + def __call__(self, view): + attr = self.kw['attr'] + def wrapper(context, request): + matchdict = request.matchdict.copy() + matchdict.pop('action', None) + inst = view() + meth = getattr(inst, attr) + return meth(**matchdict) + return wrapper + + class BaseController(object): + __view_mapper__ = PylonsControllerViewMapper + +A user might make use of these framework components like so: + +.. code-block:: python + :linenos: + + # user application + + from webob import Response + from pyramid.config import Configurator + from paste.httpserver import serve + + class MyController(BaseController): + def index(self, id): + return Response(id) + + if __name__ == '__main__': + config = Configurator() + config.add_handler('one', '/{id}', MyController, action='index') + config.add_handler('two', '/{action}/{id}', MyController) + serve(config.make_wsgi_app()) + +The :meth:`pyramid.config.Configurator.set_default_mapper` method can be used +to set a *default* view mapper (overriding the superdefault view mapper used +by Pyramid itself). + +A *single* view registration can use a view mapper by passing the mapper as +the ``mapper`` argument to :meth:`pyramid.config.Configuration.add_view`. + +.. index:: single: configuration decorator .. _registering_configuration_decorators: @@ -581,7 +669,7 @@ follows: self.path = path def register(self, scanner, name, wrapped): - registry = get_current_registry() + registry = scanner.config.registry registry.getUtility(IMyUtility).register( self.path, wrapped ) diff --git a/docs/narr/muchadoabouttraversal.rst b/docs/narr/muchadoabouttraversal.rst index 9bd829754..bc1b48462 100644 --- a/docs/narr/muchadoabouttraversal.rst +++ b/docs/narr/muchadoabouttraversal.rst @@ -4,285 +4,307 @@ Much Ado About Traversal ======================== -A lot of folks who have been using Pylons (and, therefore, Routes-based -URL matching) are being exposed for the first time, via :app:`Pyramid`, -to new ideas such as ":term:`traversal`" and ":term:`view lookup`" as a -way to route incoming HTTP requests to callable code. This has caused a -bit of consternation in some circles. Many think that traversal is hard -to understand. Others question its usefulness; URL matching has worked -for them so far, why should they even consider dealing with another -approach, one which doesn't fit their brain and which doesn't provide -any immediately obvious value? - -This chapter is an attempt to counter these opinions. Traversal and -view lookup *are* useful. There are some straightforward, real-world -use cases that are much more easily served by a traversal-based approach -than by a pattern-matching mechanism. Even if you haven't yet hit one -of these use cases yourself, understanding these new ideas is worth the -effort for any web developer so you know when you might want to use -them. Especially because (WARNING: Bold Assertion Ahead) these ideas -are *not* particularly hard to understand. In fact, :term:`traversal` -is a straightforward metaphor easily comprehended by anyone who's ever -used a run-of-the-mill file system with folders and files. +.. note:: This chapter was adapted, with permission, from a blog post by `Rob + Miller <http://blog.nonsequitarian.org/>`_, originally published at + `http://blog.nonsequitarian.org/2010/much-ado-about-traversal/ + <http://blog.nonsequitarian.org/2010/much-ado-about-traversal/>`_. + +Traversal is an alternative to :term:`URL dispatch` which allows +:app:`Pyramid` applications to map URLs to code. .. note:: - Those of you who are already familiar with traversal and view lookup - conceptually, may want to skip directly to the - :ref:`traversal_chapter` chapter, which discusses the technical - details. + Ex-Zope users whom are already familiar with traversal and view lookup + conceptually may want to skip directly to the :ref:`traversal_chapter` + chapter, which discusses technical details. This chapter is mostly aimed + at people who have previous :term:`Pylons` experience or experience in + another framework which does not provide traversal, and need an + introduction to the "why" of traversal. + +Some folks who have been using Pylons and its Routes-based URL matching for a +long time are being exposed for the first time, via :app:`Pyramid`, to new +ideas such as ":term:`traversal`" and ":term:`view lookup`" as a way to route +incoming HTTP requests to callable code. Some of the same folks believe that +traversal is hard to understand. Others question its usefulness; URL +matching has worked for them so far, why should they even consider dealing +with another approach, one which doesn't fit their brain and which doesn't +provide any immediately obvious value? + +You can be assured that if you don't want to understand traversal, you don't +have to. You can happily build :app:`Pyramid` applications with only +:term:`URL dispatch`. However, there are some straightforward, real-world +use cases that are much more easily served by a traversal-based approach than +by a pattern-matching mechanism. Even if you haven't yet hit one of these +use cases yourself, understanding these new ideas is worth the effort for any +web developer so you know when you might want to use them. :term:`Traversal` +is actually a straightforward metaphor easily comprehended by anyone who's +ever used a run-of-the-mill file system with folders and files. URL Dispatch ------------ -Let's take a step back. The problem we're trying to solve is -simple. We have an HTTP request for a particular path that -has been routed to our web application. The requested path will -possibly invoke a specific callable function defined somewhere in our -app, or it may point to nothing in which case a 404 response should be -generated. What we're trying to do is figure out is which callable -function, if any, should be invoked for a given requested path. - -URL matching (or :term:`URL dispatch` in :app:`Pyramid` parlance) -approaches this problem by parsing the URL path and comparing the -results to a set of registered "patterns", defined by a set of regular -expressions, or some other URL path templating syntax. Each pattern is -mapped to a callable function somewhere; if the request path matches a -specific pattern, the associated function is called. If the request -path matches more than one pattern, some conflict resolution scheme is -used, usually a simple order precedence so that the first match will -take priority over any subsequent matches. If a request path doesn't -match any of the defined patterns, we've got a 404. - -Just in case it's not crystal clear, we'll give an example. Using -:app:`Pyramid`'s syntax, we might have a match pattern such as -``/{userid}/photos/{photoid}``, mapped to a ``photo_view()`` function -defined somewhere in our code. Then a request for a path such as +Let's step back and consider the problem we're trying to solve, which is +simple. An HTTP request for a particular path has been routed to our web +application. The requested path will possibly invoke a specific :term:`view +callable` function defined somewhere in our app. We're trying to determine +*which* callable function, if any, should be invoked for a given requested +URL. + +Many systems, including Pyramid, offer a simple solution. They offer the +concept of "URL matching". URL matching approaches this problem by parsing +the URL path and comparing the results to a set of registered "patterns", +defined by a set of regular expressions, or some other URL path templating +syntax. Each pattern is mapped to a callable function somewhere; if the +request path matches a specific pattern, the associated function is called. +If the request path matches more than one pattern, some conflict resolution +scheme is used, usually a simple order precedence so that the first match +will take priority over any subsequent matches. If a request path doesn't +match any of the defined patterns, :app:`Pyramid` a "404 Not Found" response +is returned. + +In Pyramid, we offer an implementation of URL mapping which we call +:term:`URL dispatch`. Using :app:`Pyramid` syntax, we might have a match +pattern such as ``/{userid}/photos/{photoid}``, mapped to a ``photo_view()`` +function defined somewhere in our code. Then a request for a path such as ``/joeschmoe/photos/photo1`` would be a match, and the ``photo_view()`` function would be invoked to handle the request. Similarly, ``/{userid}/blog/{year}/{month}/{postid}`` might map to a -``blog_post_view()`` function, so -``/joeschmoe/blog/2010/12/urlmatching`` would trigger the function, -which presumably would know how to find and render the ``urlmatching`` -blog post. +``blog_post_view()`` function, so ``/joeschmoe/blog/2010/12/urlmatching`` +would trigger the function, which presumably would know how to find and +render the ``urlmatching`` blog post. Historical Refresher -------------------- -Okay, we've got :term:`URL dispatch` out of the way, soon we'll dig in -to the supposedly "harder to understand" idea of traversal. Before we -do, though, let's take a trip down memory lane. If you've been doing -web work for a while, you may remember a time when we didn't have these -fancy web frameworks. Instead, we had general purpose HTTP servers that -primarily served files off of a file system. The "root" of a given site -mapped to a particular folder somewhere on the file system. Each -segment of the request path represented a subdirectory. The final path -segment would be either a directory or a file, and once the server found -the right file it would package it up in an HTTP response and send it -back to the client. So serving up a request for -``/joeschmoe/photos/photo1`` literally meant that there was a -``joeschmoe`` folder somewhere, which contained a ``photos`` folder, -which in turn contained a ``photo1`` file. If at any point along the -way we find that there is not a folder or file matching the requested -path, we return a 404 response. - -As the web grew more dynamic, however, a little bit of extra -complexity was added. Technologies such as CGI and HTTP server -modules were developed. Files were still looked up on the file -system, but if the file ended with (for example) ``.cgi`` or ``.php``, -or if it lived in a special folder, instead of simply sending the file -to the client the server would read the file, execute it using an -interpreter of some sort, and then send the output from this process -to the client as the final result. The server configuration specified -which files would trigger some dynamic code, with the default case -being to just serve the static file. +Now that we've refreshed our understanding of :term:`URL dispatch`, we'll dig +in to the idea of traversal. Before we do, though, let's take a trip down +memory lane. If you've been doing web work for a while, you may remember a +time when we didn't have fancy web frameworks like :term:`Pylons` and +:app:`Pyramid`. Instead, we had general purpose HTTP servers that primarily +served files off of a file system. The "root" of a given site mapped to a +particular folder somewhere on the file system. Each segment of the request +URL path represented a subdirectory. The final path segment would be either +a directory or a file, and once the server found the right file it would +package it up in an HTTP response and send it back to the client. So serving +up a request for ``/joeschmoe/photos/photo1`` literally meant that there was +a ``joeschmoe`` folder somewhere, which contained a ``photos`` folder, which +in turn contained a ``photo1`` file. If at any point along the way we find +that there is not a folder or file matching the requested path, we return a +404 response. + +As the web grew more dynamic, however, a little bit of extra complexity was +added. Technologies such as CGI and HTTP server modules were developed. +Files were still looked up on the file system, but if the file ended with +(for example) ``.cgi`` or ``.php``, or if it lived in a special folder, +instead of simply sending the file to the client the server would read the +file, execute it using an interpreter of some sort, and then send the output +from this process to the client as the final result. The server +configuration specified which files would trigger some dynamic code, with the +default case being to just serve the static file. Traversal (aka Resource Location) --------------------------------- -You with me so far? Good. Because if you understand how serving -files from a file system works, then you pretty much understand -traversal. And if you understand that a server might do something -different based on what type of file a given request specifies, then -you pretty much understand view lookup. - -Wait... what!?! - .. index:: single: traversal overview -The only difference between file system lookup and traversal is that a -file system lookup is stepping through nested directories and files in -a file system tree, while traversal is stepping through nested -dictionary-type objects in an object tree. Let's take a detailed look -at one of our example paths, so we can see what I mean: - -With ``/joeschmoe/photos/photo1``, we've got 4 segments: ``/``, -``joeschmoe/``, ``photos/`` and ``photo1``. With file system -lookup we have a root folder (``/``) containing a nested folder -(``joeschmoe``), which contains ANOTHER nested folder (``photos``), -which finally contains a JPG file ("photo1"). With traversal, we -have a dictionary-like root object. Asking for the ``joeschmoe`` key -gives us another dictionary-like object. Asking this in turn for the -``photos`` key gives us yet another mapping object, which finally -(hopefully) contains the resource that we're looking for within its -values, referenced by the ``photo1`` key. +Believe it or not, if you understand how serving files from a file system +works,you understand traversal. And if you understand that a server might do +something different based on what type of file a given request specifies, +then you understand view lookup. + +The major difference between file system lookup and traversal is that a file +system lookup steps through nested directories and files in a file system +tree, while traversal steps through nested dictionary-type objects in an +:term:`resource tree`. Let's take a detailed look at one of our example +paths, so we can see what I mean: + +The path ``/joeschmoe/photos/photo1``, has four segments: ``/``, +``joeschmoe``, ``photos`` and ``photo1``. With file system lookup we might +have a root folder (``/``) containing a nested folder (``joeschmoe``), which +contains another nested folder (``photos``), which finally contains a JPG +file ("photo1"). With traversal, we instead have a dictionary-like root +object. Asking for the ``joeschmoe`` key gives us another dictionary-like +object. Asking this in turn for the ``photos`` key gives us yet another +mapping object, which finally (hopefully) contains the resource that we're +looking for within its values, referenced by the ``photo1`` key. In pure Python terms, then, the traversal or "resource location" portion of satisfying the ``/joeschmoe/photos/photo1`` request -will look like this:: +will look something like this pseudocode:: get_root()['joeschmoe']['photos']['photo1'] -Where ``get_root()`` is some function that returns our root traversal -resource. If all of the specified keys exist, then the returned object -will be the resource that is being requested, analogous to the JPG file -that was retrieved in the file system example. If a :exc:`KeyError` is -generated anywhere along the way, we get a 404. (Well, this isn't -precisely true, as you'll see when we learn about view lookup below, but -the basic idea holds.) +``get_root()`` is some function that returns a root traversal +:term:`resource`. If all of the specified keys exist, then the returned +object will be the resource that is being requested, analogous to the JPG +file that was retrieved in the file system example. If a :exc:`KeyError` is +generated anywhere along the way, :app:`Pyramid` will return 404. (This +isn't precisely true, as you'll see when we learn about view lookup below, +but the basic idea holds.) -What is a "resource"? +What Is a "Resource"? --------------------- -Okay, okay... files on a file system I understand, you might say. But -what are these nested dictionary things? Where do these objects, these -"resources", live? What *are* they? - -Well, since :app:`Pyramid` is not a highly opinionated framework, there -is no restriction on how a resource is implemented; the developer can do -whatever they want. One common pattern is to persist all of the -resources, including the root, in a database. The root object stores -the ids of all of its subresources, and provides a ``__getitem__`` -implementation that fetches them. So ``get_root()`` fetches the unique -root object, while ``get_root()['joeschmoe']`` returns a different -object, also stored in the database, which in turn has its own -subresources and ``__getitem__`` implementation, etc. These resources -could be persisted in a relational database, one of the many "NoSQL" -solutions that are becoming popular these days, or anywhere else, it -doesn't matter. As long as the returned objects provide the -dictionary-like API (i.e. as long as they have an appropriately +"Files on a file system I understand", you might say. "But what are these +nested dictionary things? Where do these objects, these 'resources', live? +What *are* they?" + +Since :app:`Pyramid` is not a highly opinionated framework, it makes no +restriction on how a :term:`resource` is implemented; a developer can +implement them as he wishes. One common pattern used is to persist all of +the resources, including the root, in a database as a graph. The root object +is a dictionarylike object. Dictionarylike objects in Python supply a +``__getitem__`` method which is called when key lookup is done. Under the +hood, when ``adict`` is a dictionarylike object, Python translates +``adict['a']`` to ``adict.__getitem__('a')``. Try doing this in a Python +interpreter prompt if you don't believe us: + +.. code-block:: text + :linenos: + + Python 2.4.6 (#2, Apr 29 2010, 00:31:48) + [GCC 4.4.3] on linux2 + Type "help", "copyright", "credits" or "license" for more information. + >>> adict = {} + >>> adict['a'] = 1 + >>> adict['a'] + 1 + >>> adict.__getitem__('a') + 1 + + +The dictionarylike root object stores the ids of all of its subresources as +keys, and provides a ``__getitem__`` implementation that fetches them. So +``get_root()`` fetches the unique root object, while +``get_root()['joeschmoe']`` returns a different object, also stored in the +database, which in turn has its own subresources and ``__getitem__`` +implementation, etc. These resources might be persisted in a relational +database, one of the many "NoSQL" solutions that are becoming popular these +days, or anywhere else, it doesn't matter. As long as the returned objects +provide the dictionary-like API (i.e. as long as they have an appropriately implemented ``__getitem__`` method) then traversal will work. -In fact, you don't need a "database" at all. You could trivially -implement a set of objects with ``__getitem__`` methods that search -for files in specific directories, and thus precisely recreate the -older mechanism of having the URL path mapped directly to a folder -structure on the file system. Traversal is in fact a superset of file +In fact, you don't need a "database" at all. You could trivially implement a +set of objects with ``__getitem__`` methods that search for files in specific +directories, and thus precisely recreate the older mechanism of having the +URL path mapped directly to a folder structure on the file system. Or you +could use plain dictionaries too. Traversal is in fact a superset of file system lookup. +.. note:: See the chapter entitled :ref:`resources_chapter` for a more + technical overview of resources. + View Lookup ----------- -At this point we're nearly there. We've covered traversal, which is -the process by which a specific resource is retrieved according to a -specific URL path. But what is this "view lookup" business? - -View lookup comes from a simple realization, namely, that there is more -than one possible action that you might want to take for a single -resource. With our photo example, for instance, you might want to view -the photo in a page, but you might also want to provide a way for the -user to edit the photo and any associated metadata. We'll call the -former the ``view`` view, and the latter will be the ``edit`` view -(Original, I know.) :app:`Pyramid` has a centralized view registry -where named views can be associated with specific resource types. So in -our example, we'll assume that we've registered ``view`` and ``edit`` -views for photo objects, and that we've specified the ``view`` view as -the default, so that ``/joeschmoe/photos/photo1/view`` and -``/joeschmoe/photos/photo1`` are equivalent. The edit view would -sensibly be provided by a request for ``/joeschmoe/photos/photo1/edit``. - -Hopefully it's clear that the first portion of the edit view's URL path -is going to resolve to the same resource as the non-edit version, -specifically the resource returned by -``get_root()['joeschmoe']['photos']['photo1']``. But traveral ends -there; the ``photo1`` resource doesn't have an ``edit`` key. In fact, -it might not even be a dictionary-like object, in which case -``photo1['edit']`` would be meaningless. When :app:`Pyramid`'s resource -location has resolved to a *leaf* resource but the entire request path -has not yet been expended, the next path segment is treated as a view -name. The registry is then checked to see if a view of the given name -has been specified for a resource of the given type. If so, the view -callable is invoked, with the resource passed in as the ``context`` -object; if not, we 404. - -This is a slight simplification, but to summarize you can think of a -request for ``/joeschmoe/photos/photo1/edit`` as ultimately converted -into the following piece of Python:: +At this point we're nearly there. We've covered traversal, which is the +process by which a specific resource is retrieved according to a specific URL +path. But what is "view lookup"? + +The need for view lookup is simple: there is more than one possible action +that you might want to take after finding a :term:`resource`. With our photo +example, for instance, you might want to view the photo in a page, but you +might also want to provide a way for the user to edit the photo and any +associated metadata. We'll call the former the ``view`` view, and the latter +will be the ``edit`` view (Original, I know.) :app:`Pyramid` has a +centralized view registry where named views can be associated with specific +resource types. So in our example, we'll assume that we've registered +``view`` and ``edit`` views for photo objects, and that we've specified the +``view`` view as the default, so that ``/joeschmoe/photos/photo1/view`` and +``/joeschmoe/photos/photo1`` are equivalent. The edit view would sensibly be +provided by a request for ``/joeschmoe/photos/photo1/edit``. + +Hopefully it's clear that the first portion of the edit view's URL path is +going to resolve to the same resource as the non-edit version, specifically +the resource returned by ``get_root()['joeschmoe']['photos']['photo1']``. +But traveral ends there; the ``photo1`` resource doesn't have an ``edit`` +key. In fact, it might not even be a dictionary-like object, in which case +``photo1['edit']`` would be meaningless. When the :app:`Pyramid` resource +location has been resolved to a *leaf* resource, but the entire request path +has not yet been expended, the *very next* path segment is treated as a +:term:`view name`. The registry is then checked to see if a view of the +given name has been specified for a resource of the given type. If so, the +view callable is invoked, with the resource passed in as the related +``context`` object (also available as ``request.context``). If a view +callable could not be found, :app:`Pyramid` will return a "404 Not Found" +response. + +You might conceptualize a request for ``/joeschmoe/photos/photo1/edit`` as +ultimately converted into the following piece of Pythonic pseudocode:: context = get_root()['joeschmoe']['photos']['photo1'] - view_callable = registry.get_view(context, 'edit') - view_callable(context, request) + view_callable = get_view(context, 'edit') + request.context = context + view_callable(request) -That's not too hard to conceptualize, is it? +The ``get_root`` and ``get_view`` functions don't really exist. Internally, +:app:`Pyramid` does something more complicated. But the example above is a +reasonable approximation of the view lookup algorithm in pseudocode. Use Cases --------- -Let's come back around to look at why we even care. Yes, maybe -traversal and view lookup isn't mind-bending rocket science. But URL -matching is easier to explain, and it's good enough, right? +Why should we care about traversal? URL matching is easier to explain, and +it's good enough, right? -In some cases, yes, but certainly not in all cases. So far we've had -very structured URLs, where our paths have had a specific, small -number of pieces, like this:: +In some cases, yes, but certainly not in all cases. So far we've had very +structured URLs, where our paths have had a specific, small number of pieces, +like this:: /{userid}/{typename}/{objectid}[/{view_name}] In all of the examples thus far, we've hard coded the typename value, -assuming that we'd know at development time what names were going to -be used ("photos", "blog", etc.). But what if we don't know what -these names will be? Or, worse yet, what if we don't know *anything* -about the structure of the URLs inside a user's folder? We could be -writing a CMS where we want the end user to be able to arbitrarily add -content and other folders inside his folder. He might decide to nest -folders dozens of layers deep. How would you construct matching -patterns that could account for every possible combination of paths -that might develop? - -It may be possible, but it's tricky at best. And your matching -patterns are going to become quite complex very quickly as you try -to handle all of the edge cases. - -With traversal, however, it's straightforward. You want 20 layers of -nesting? No problem, :app:`Pyramid` will happily call ``__getitem__`` -as long as it needs to, until it runs out of path segments or until it -gets a :exc:`KeyError`. Each resource only needs to know how to fetch -its immediate children, the traversal algorithm takes care of the rest. - -The key advantage of traversal here is that the structure of the -resource tree can live in the database, and not in the code. It's -simple to let users modify the tree at runtime to set up their own -personalized directory structures. - -Another use case in which traversal shines is when there is a need to -support a context-dependent security policy. One example might be a -document management infrastructure for a large corporation, where -members of different departments have varying access levels to the -various other departments' files. Reasonably, even specific files -might need to be made available to specific individuals. Traversal -does well here because the idea of a resource context is baked right -into the code resolution and calling process. Resource objects can -store ACLs, which can be inherited and/or overridden by the -subresources. - -If each resource can thus generate a context-based ACL, then whenever -view code is attempting to perform a sensitive action, it can check -against that ACL to see whether the current user should be allowed to -perform the action. In this way you achieve so called "instance based" -or "row level" security which is considerably harder to model using a -traditional tabular approach. :app:`Pyramid` actively supports such a -scheme, and in fact if you register your views with guard permissions -and use an authorization policy, :app:`Pyramid` can check against a -resource's ACL when deciding whether or not the view itself is available -to the current user. - -In summary, there are entire classes of problems that are more easily -served by traversal and view lookup than by :term:`URL dispatch`. If -your problems aren't of this nature, great, stick with :term:`URL -dispatch`. But if you're using :app:`Pyramid` and you ever find that -you *do* need to support one of these use cases, you'll be glad you have -traversal in your toolkit. +assuming that we'd know at development time what names were going to be used +("photos", "blog", etc.). But what if we don't know what these names will +be? Or, worse yet, what if we don't know *anything* about the structure of +the URLs inside a user's folder? We could be writing a CMS where we want the +end user to be able to arbitrarily add content and other folders inside his +folder. He might decide to nest folders dozens of layers deep. How will you +construct matching patterns that could account for every possible combination +of paths that might develop? + +It's possible, but it will make for some somewhat ugly URLs. And the +matching patterns are going to become complex quickly as you try to handle +all of the edge cases. + +With traversal, however, it's straightforward. If you want 20 layers of +nesting, it's no problem. :app:`Pyramid` will happily call ``__getitem__`` +as many times as it needs to, until it runs out of path segments or until a +resource raises a :exc:`KeyError`. Each resource only needs to know how to +fetch its immediate children, the traversal algorithm takes care of the rest. + +One of the key advantages of traversal is that the structure of the resource +tree can live in the database, and not in the code. It's simple to let users +modify the tree at runtime to set up their own personalized directory +structures. + +Another use case in which traversal shines is when there is a need to support +a context-dependent security policy. One example might be a document +management infrastructure for a large corporation, where members of different +departments have varying access levels to the various other departments' +files. Reasonably, even specific files might need to be made available to +specific individuals. Traversal does well here if your resources actually +represent the data objects related to your documents, because the idea of a +resource authorization is baked right into the code resolution and calling +process. Resource objects can store ACLs, which can be inherited and/or +overridden by the subresources. + +If each resource can thus generate a context-based ACL, then whenever view +code is attempting to perform a sensitive action, it can check against that +ACL to see whether the current user should be allowed to perform the action. +In this way you achieve so called "instance based" or "row level" security +which is considerably harder to model using a traditional tabular approach. +:app:`Pyramid` actively supports such a scheme, and in fact if you register +your views with guard permissions and use an authorization policy, +:app:`Pyramid` can check against a resource's ACL when deciding whether or +not the view itself is available to the current user. + +In summary, there are entire classes of problems that are more easily served +by traversal and view lookup than by :term:`URL dispatch`. If your problems +don't require it, great: stick with :term:`URL dispatch`. But if you're +using :app:`Pyramid` and you ever find that you *do* need to support one of +these use cases, you'll be glad you have traversal in your toolkit. .. note:: It is even possible to mix and match :term:`traversal` with diff --git a/docs/narr/project.rst b/docs/narr/project.rst index 55a2711f3..c1017b5c1 100644 --- a/docs/narr/project.rst +++ b/docs/narr/project.rst @@ -180,7 +180,7 @@ Installing your Newly Created Project for Development To install a newly created project for development, you should ``cd`` to the newly created project directory and use the Python interpreter from the :term:`virtualenv` you created during :ref:`installing_chapter` to invoke the -command ``python setup.py develop.py`` +command ``python setup.py develop`` The file named ``setup.py`` will be in the root of the paster-generated project directory. The ``python`` you're invoking should be the one that @@ -910,6 +910,8 @@ example. See :ref:`testing_chapter` for more information about writing :app:`Pyramid` unit tests. +.. _modifying_package_structure: + Modifying Package Structure ---------------------------- @@ -958,12 +960,14 @@ To this: .. code-block:: python :linenos: - config.add_view('myproject.views.blogs.my_view', + config.add_view('myproject.views.blog.my_view', renderer='myproject:templates/mytemplate.pt') You can then continue to add files to the ``views`` directory, and refer to views or handler classes/functions within those files via the dotted name -passed as the first argument to ``add_view``. For example: +passed as the first argument to ``add_view``. For example, if you added a +file named ``anothermodule.py`` to the ``views`` subdirectory, and added a +view callable named ``my_view`` to it: .. code-block:: python :linenos: diff --git a/docs/narr/resources.rst b/docs/narr/resources.rst index b892cf3cd..cf13f8c8d 100644 --- a/docs/narr/resources.rst +++ b/docs/narr/resources.rst @@ -1,3 +1,5 @@ +.. _resources_chapter: + Resources ========= diff --git a/docs/narr/templates.rst b/docs/narr/templates.rst index 437b823e9..7ef8e1923 100644 --- a/docs/narr/templates.rst +++ b/docs/narr/templates.rst @@ -628,7 +628,7 @@ application's configuration section, e.g.: .. code-block:: ini :linenos: - [app:main] + [app:MyProject] use = egg:MyProject#app debug_templates = true diff --git a/docs/narr/viewconfig.rst b/docs/narr/viewconfig.rst index 372e520b4..f8b3fdb24 100644 --- a/docs/narr/viewconfig.rst +++ b/docs/narr/viewconfig.rst @@ -181,6 +181,22 @@ Non-Predicate Arguments If ``wrapper`` is not supplied, no wrapper view is used. +``decorator`` + A :term:`dotted Python name` to function (or the function itself) which + will be used to decorate the registered :term:`view callable`. The + decorator function will be called with the view callable as a single + argument. The view callable it is passed will accept ``(context, + request)``. The decorator must return a replacement view callable which + also accepts ``(context, request)``. + +``mapper`` + A Python object or :term:`dotted Python name` which refers to a :term:`view + mapper`, or ``None``. By default it is ``None``, which indicates that the + view should use the default view mapper. This plug-point is useful for + Pyramid extension developers, but it's not very useful for 'civilians' who + are just developing stock Pyramid applications. Pay no attention to the man + behind the curtain. + Predicate Arguments +++++++++++++++++++ diff --git a/docs/narr/views.rst b/docs/narr/views.rst index 48bb7f829..e8cf2f83c 100644 --- a/docs/narr/views.rst +++ b/docs/narr/views.rst @@ -408,8 +408,3 @@ exception views which have a name will be ignored. Exception views can be configured with any view registration mechanism: ``@view_config`` decorator, ZCML, or imperative ``add_view`` styles. -.. index:: - single: unicode, views, and forms - single: forms, views, and unicode - single: views, forms, and unicode - diff --git a/docs/tutorials/wiki/authorization.rst b/docs/tutorials/wiki/authorization.rst index 1b66ace96..ee86eb543 100644 --- a/docs/tutorials/wiki/authorization.rst +++ b/docs/tutorials/wiki/authorization.rst @@ -136,7 +136,6 @@ Add a ``login.pt`` template to your templates directory. It's referred to within the login view we just added to ``login.py``. .. literalinclude:: src/authorization/tutorial/templates/login.pt - :linenos: :language: xml Change ``view.pt`` and ``edit.pt`` @@ -146,11 +145,10 @@ We'll also need to change our ``edit.pt`` and ``view.pt`` templates to display a "Logout" link if someone is logged in. This link will invoke the logout view. -To do so we'll add this to both templates within the ``<div -class="main_content">`` div: +To do so we'll add this to both templates within the ``<div id="right" +class="app-welcome align-right">`` div: .. code-block:: xml - :linenos: <span tal:condition="logged_in"> <a href="${request.application_url}/logout">Logout</a> diff --git a/docs/tutorials/wiki/basiclayout.rst b/docs/tutorials/wiki/basiclayout.rst index f6e1f800a..4017d7af8 100644 --- a/docs/tutorials/wiki/basiclayout.rst +++ b/docs/tutorials/wiki/basiclayout.rst @@ -169,7 +169,6 @@ The ``development.ini`` (in the tutorial :term:`project` directory, as opposed to the tutorial :term:`package` directory) looks like this: .. literalinclude:: src/views/development.ini - :linenos: :language: ini diff --git a/docs/tutorials/wiki/definingmodels.rst b/docs/tutorials/wiki/definingmodels.rst index f201f6dc7..5e4b8fb22 100644 --- a/docs/tutorials/wiki/definingmodels.rst +++ b/docs/tutorials/wiki/definingmodels.rst @@ -163,7 +163,7 @@ On Windows: .. code-block:: text - c:\bigfntut\tutorial> ..\Scripts\python setup.py test -q + c:\pyramidtut\tutorial> ..\Scripts\python setup.py test -q The expected output is something like this: diff --git a/docs/tutorials/wiki/definingviews.rst b/docs/tutorials/wiki/definingviews.rst index 5b0e5dca1..90768f320 100644 --- a/docs/tutorials/wiki/definingviews.rst +++ b/docs/tutorials/wiki/definingviews.rst @@ -230,7 +230,6 @@ Once we're done with the ``view.pt`` template, it will look a lot like the below: .. literalinclude:: src/views/tutorial/templates/view.pt - :linenos: :language: xml .. note:: The names available for our use in a template are always those that @@ -257,23 +256,24 @@ Once we're done with the ``edit.pt`` template, it will look a lot like the below: .. literalinclude:: src/views/tutorial/templates/edit.pt - :linenos: :language: xml Static Assets ------------- -Our templates name a single static asset named ``style.css``. We need to -create this and place it in a file named ``style.css`` within our package's -``static`` directory. This file is a little too long to replicate within the -body of this guide, however it is available `online -<http://github.com/Pylons/pyramid/blob/master/docs/tutorials/wiki/src/views/tutorial/static/style.css>`_. +Our templates name a single static asset named ``pylons.css``. We don't need +to create this file within our package's ``static`` directory because it was +provided at the time we created the project. This file is a little too long to +replicate within the body of this guide, however it is available `online +<http://github.com/Pylons/pyramid/blob/master/docs/tutorials/wiki/src/views/tutorial/static/pylons.css>`_. This CSS file will be accessed via -e.g. ``http://localhost:6543/static/style.css`` by virtue of the call to +e.g. ``http://localhost:6543/static/pylons.css`` by virtue of the call to ``add_static_view`` directive we've made in the ``__init__`` file. Any number and type of static assets can be placed in this directory (or -subdirectories) and are just referred to by URL within templates. +subdirectories) and are just referred to by URL or by using the convenience +method ``static_url`` e.g. ``request.static_url('{{package}}:static/foo.css')`` +within templates. Testing the Views ================= @@ -308,7 +308,7 @@ On Windows: .. code-block:: text - c:\bigfntut\tutorial> ..\Scripts\python setup.py test -q + c:\pyramidtut\tutorial> ..\Scripts\python setup.py test -q The expected result looks something like: diff --git a/docs/tutorials/wiki/distributing.rst b/docs/tutorials/wiki/distributing.rst index ad717e72a..855d54eab 100644 --- a/docs/tutorials/wiki/distributing.rst +++ b/docs/tutorials/wiki/distributing.rst @@ -18,7 +18,7 @@ On Windows: .. code-block:: text - c:\bigfntut> ..\Scripts\python setup.py sdist + c:\pyramidtut> ..\Scripts\python setup.py sdist .. warning:: If your project files are not checked in to a version control repository (such as Subversion), the dist tarball will diff --git a/docs/tutorials/wiki/installation.rst b/docs/tutorials/wiki/installation.rst index 82265170d..95bc7a03e 100644 --- a/docs/tutorials/wiki/installation.rst +++ b/docs/tutorials/wiki/installation.rst @@ -26,28 +26,28 @@ Preparation, UNIX <http://peak.telecommunity.com/dist/ez_setup.py>`_ and run it using the ``python`` interpreter of your Python 2.6 installation: - .. code-block:: bash + .. code-block:: text $ /path/to/my/Python-2.6/bin/python ez_setup.py #. Use that Python's `bin/easy_install` to install `virtualenv`: - .. code-block:: bash + .. code-block:: text $ /path/to/my/Python-2.6/bin/easy_install virtualenv #. Use that Python's virtualenv to make a workspace: - .. code-block:: bash + .. code-block:: text $ path/to/my/Python-2.6/bin/virtualenv --no-site-packages \ - bigfntut + pyramidtut -#. Switch to the ``bigfntut`` directory: +#. Switch to the ``pyramidtut`` directory: - .. code-block:: bash + .. code-block:: text - $ cd bigfntut + $ cd pyramidtut #. (Optional) Consider using ``source bin/activate`` to make your shell environment wired to use the virtualenv. @@ -55,14 +55,14 @@ Preparation, UNIX #. Use ``easy_install`` to get :app:`Pyramid` and its direct dependencies installed: - .. code-block:: bash + .. code-block:: text $ bin/easy_install pyramid #. Use ``easy_install`` to install ``docutils``, ``repoze.tm``, ``repoze.zodbconn``, ``nose`` and ``coverage``: - .. code-block:: bash + .. code-block:: text $ bin/easy_install docutils repoze.tm repoze.zodbconn \ nose coverage @@ -79,27 +79,27 @@ Preparation, Windows the ``python`` interpreter of your Python 2.6 installation using a command prompt: - .. code-block:: bat + .. code-block:: text c:\> c:\Python26\python ez_setup.py #. Use that Python's `bin/easy_install` to install `virtualenv`: - .. code-block:: bat + .. code-block:: text c:\> c:\Python26\Scripts\easy_install virtualenv #. Use that Python's virtualenv to make a workspace: - .. code-block:: bat + .. code-block:: text - c:\> c:\Python26\Scripts\virtualenv --no-site-packages bigfntut + c:\> c:\Python26\Scripts\virtualenv --no-site-packages pyramidtut -#. Switch to the ``bigfntut`` directory: +#. Switch to the ``pyramidtut`` directory: - .. code-block:: bat + .. code-block:: text - c:\> cd bigfntut + c:\> cd pyramidtut #. (Optional) Consider using ``bin\activate.bat`` to make your shell environment wired to use the virtualenv. @@ -107,16 +107,16 @@ Preparation, Windows #. Use ``easy_install`` to get :app:`Pyramid` and its direct dependencies installed: - .. code-block:: bat + .. code-block:: text - c:\bigfntut> Scripts\easy_install pyramid + c:\pyramidtut> Scripts\easy_install pyramid #. Use ``easy_install`` to install ``docutils``, ``repoze.tm``, ``repoze.zodbconn``, ``nose`` and ``coverage``: - .. code-block:: bat + .. code-block:: text - c:\bigfntut> Scripts\easy_install docutils repoze.tm \ + c:\pyramidtut> Scripts\easy_install docutils repoze.tm \ repoze.zodbconn nose coverage .. _making_a_project: @@ -129,19 +129,19 @@ variety of templates to generate sample projects. For this tutorial, we will use the :term:`ZODB` -oriented template named ``pyramid_zodb``. The below instructions assume your current working directory is the -"virtualenv" named "bigfntut". +"virtualenv" named "pyramidtut". On UNIX: -.. code-block:: bash +.. code-block:: text $ bin/paster create -t pyramid_zodb tutorial On Windows: -.. code-block:: bat +.. code-block:: text - c:\bigfntut> Scripts\paster create -t pyramid_zodb tutorial + c:\pyramidtut> Scripts\paster create -t pyramid_zodb tutorial .. note:: If you are using Windows, the ``pyramid_zodb`` Paster template doesn't currently deal gracefully with installation into a location @@ -160,17 +160,17 @@ directory you created in :ref:`making_a_project`, and run the On UNIX: -.. code-block:: bash +.. code-block:: text $ cd tutorial $ ../bin/python setup.py develop On Windows: -.. code-block:: bat +.. code-block:: text - C:\bigfntut> cd tutorial - C:\bigfntut\tutorial> ..\Scripts\python setup.py develop + C:\pyramidtut> cd tutorial + C:\pyramidtut\tutorial> ..\Scripts\python setup.py develop .. _running_tests: @@ -182,15 +182,15 @@ the tests for the project. On UNIX: -.. code-block:: bash +.. code-block:: text $ ../bin/python setup.py test -q On Windows: -.. code-block:: bat +.. code-block:: text - c:\bigfntut\tutorial> ..\Scripts\python setup.py test -q + c:\pyramidtut\tutorial> ..\Scripts\python setup.py test -q Starting the Application ======================== @@ -199,15 +199,15 @@ Start the application. On UNIX: -.. code-block:: bash +.. code-block:: text $ ../bin/paster serve development.ini --reload On Windows: -.. code-block:: bat +.. code-block:: text - c:\bifgfntut\tutorial> ..\Scripts\paster serve development.ini --reload + c:\pyramidtut\tutorial> ..\Scripts\paster serve development.ini --reload Exposing Test Coverage Information ================================== @@ -220,15 +220,15 @@ tests. On UNIX: -.. code-block:: bash +.. code-block:: text $ ../bin/nosetests --cover-package=tutorial --cover-erase --with-coverage On Windows: -.. code-block:: bat +.. code-block:: text - c:\bigfntut\tutorial> ..\Scripts\nosetests --cover-package=tutorial \ + c:\pyramidtut\tutorial> ..\Scripts\nosetests --cover-package=tutorial \ --cover-erase --with-coverage Looks like the code in the ``pyramid_zodb`` template for ZODB projects is diff --git a/docs/tutorials/wiki/src/authorization/tutorial/static/footerbg.png b/docs/tutorials/wiki/src/authorization/tutorial/static/footerbg.png Binary files differnew file mode 100644 index 000000000..1fbc873da --- /dev/null +++ b/docs/tutorials/wiki/src/authorization/tutorial/static/footerbg.png diff --git a/docs/tutorials/wiki/src/authorization/tutorial/static/headerbg.png b/docs/tutorials/wiki/src/authorization/tutorial/static/headerbg.png Binary files differnew file mode 100644 index 000000000..0596f2020 --- /dev/null +++ b/docs/tutorials/wiki/src/authorization/tutorial/static/headerbg.png diff --git a/docs/tutorials/wiki/src/authorization/tutorial/static/ie6.css b/docs/tutorials/wiki/src/authorization/tutorial/static/ie6.css new file mode 100644 index 000000000..b7c8493d8 --- /dev/null +++ b/docs/tutorials/wiki/src/authorization/tutorial/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/docs/tutorials/wiki/src/authorization/tutorial/static/logo.png b/docs/tutorials/wiki/src/authorization/tutorial/static/logo.png Binary files differdeleted file mode 100644 index 88f5d9865..000000000 --- a/docs/tutorials/wiki/src/authorization/tutorial/static/logo.png +++ /dev/null diff --git a/docs/tutorials/wiki/src/authorization/tutorial/static/middlebg.png b/docs/tutorials/wiki/src/authorization/tutorial/static/middlebg.png Binary files differnew file mode 100644 index 000000000..2369cfb7d --- /dev/null +++ b/docs/tutorials/wiki/src/authorization/tutorial/static/middlebg.png diff --git a/docs/tutorials/wiki/src/authorization/tutorial/static/pylons.css b/docs/tutorials/wiki/src/authorization/tutorial/static/pylons.css index c153be07f..fd1914d8d 100644 --- a/docs/tutorials/wiki/src/authorization/tutorial/static/pylons.css +++ b/docs/tutorials/wiki/src/authorization/tutorial/static/pylons.css @@ -4,34 +4,23 @@ body{line-height:1;} ol,ul{list-style:none;} blockquote,q{quotes:none;} blockquote:before,blockquote:after,q:before,q:after{content:'';content:none;} -/* remember to define focus styles! */ :focus{outline:0;} -/* remember to highlight inserts somehow! */ ins{text-decoration:none;} del{text-decoration:line-through;} -/* tables still need 'cellspacing="0"' in the markup */ table{border-collapse:collapse;border-spacing:0;} -/* restyling */ sub{vertical-align:sub;font-size:smaller;line-height:normal;} sup{vertical-align:super;font-size:smaller;line-height:normal;} -/* lists */ ul,menu,dir{display:block;list-style-type:disc;margin:1em 0;padding-left:40px;} ol{display:block;list-style-type:decimal-leading-zero;margin:1em 0;padding-left:40px;} li{display:list-item;} -/* nested lists have no top/bottom margins */ ul ul,ul ol,ul dir,ul menu,ul dl,ol ul,ol ol,ol dir,ol menu,ol dl,dir ul,dir ol,dir dir,dir menu,dir dl,menu ul,menu ol,menu dir,menu menu,menu dl,dl ul,dl ol,dl dir,dl menu,dl dl{margin-top:0;margin-bottom:0;} -/* 2 deep unordered lists use a circle */ ol ul,ul ul,menu ul,dir ul,ol menu,ul menu,menu menu,dir menu,ol dir,ul dir,menu dir,dir dir{list-style-type:circle;} -/* 3 deep (or more) unordered lists use a square */ ol ol ul,ol ul ul,ol menu ul,ol dir ul,ol ol menu,ol ul menu,ol menu menu,ol dir menu,ol ol dir,ol ul dir,ol menu dir,ol dir dir,ul ol ul,ul ul ul,ul menu ul,ul dir ul,ul ol menu,ul ul menu,ul menu menu,ul dir menu,ul ol dir,ul ul dir,ul menu dir,ul dir dir,menu ol ul,menu ul ul,menu menu ul,menu dir ul,menu ol menu,menu ul menu,menu menu menu,menu dir menu,menu ol dir,menu ul dir,menu menu dir,menu dir dir,dir ol ul,dir ul ul,dir menu ul,dir dir ul,dir ol menu,dir ul menu,dir menu menu,dir dir menu,dir ol dir,dir ul dir,dir menu dir,dir dir dir{list-style-type:square;} .hidden{display:none;} p{line-height:1.5em;} -h1{font-size:1.75em;/* 28px */ -line-height:1.7em;font-family:helvetica,verdana;} -h2{font-size:1.5em;/* 24px */ -line-height:1.7em;font-family:helvetica,verdana;} -h3{font-size:1.25em;/* 20px */ -line-height:1.7em;font-family:helvetica,verdana;} +h1{font-size:1.75em;line-height:1.7em;font-family:helvetica,verdana;} +h2{font-size:1.5em;line-height:1.7em;font-family:helvetica,verdana;} +h3{font-size:1.25em;line-height:1.7em;font-family:helvetica,verdana;} h4{font-size:1em;line-height:1.7em;font-family:helvetica,verdana;} html,body{width:100%;height:100%;} body{margin:0;padding:0;background-color:#ffffff;position:relative;font:16px/24px "Nobile","Lucida Grande",Lucida,Verdana,sans-serif;} @@ -42,23 +31,26 @@ 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,#top-small,#bottom{width:100%;} +#top{color:#000000;height:230px;background:#ffffff url(headerbg.png) repeat-x 0 top;position:relative;} +#top-small{color:#000000;height:60px;background:#ffffff url(headerbg.png) repeat-x 0 top;position:relative;} +#bottom{color:#222;background-color:#ffffff;} +.top,.top-small,.middle,.bottom{width:750px;margin-right:auto;margin-left:auto;} +.top{padding-top:40px;} +.top-small{padding-top:10px;} +#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 +59,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],input[type=password]{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/docs/tutorials/wiki/src/authorization/tutorial/static/pyramid-small.png b/docs/tutorials/wiki/src/authorization/tutorial/static/pyramid-small.png Binary files differnew file mode 100644 index 000000000..a5bc0ade7 --- /dev/null +++ b/docs/tutorials/wiki/src/authorization/tutorial/static/pyramid-small.png diff --git a/docs/tutorials/wiki/src/authorization/tutorial/static/pyramid.png b/docs/tutorials/wiki/src/authorization/tutorial/static/pyramid.png Binary files differnew file mode 100644 index 000000000..347e05549 --- /dev/null +++ b/docs/tutorials/wiki/src/authorization/tutorial/static/pyramid.png diff --git a/docs/tutorials/wiki/src/authorization/tutorial/static/style.css b/docs/tutorials/wiki/src/authorization/tutorial/static/style.css deleted file mode 100644 index cad87e0d4..000000000 --- a/docs/tutorials/wiki/src/authorization/tutorial/static/style.css +++ /dev/null @@ -1,109 +0,0 @@ -html, body { - color: black; - background-color: #ddd; - font: x-small "Lucida Grande", "Lucida Sans Unicode", geneva, sans-serif; - margin: 0; - padding: 0; -} - -td, th {padding:3px;border:none;} -tr th {text-align:left;background-color:#f0f0f0;color:#333;} -tr.odd td {background-color:#edf3fe;} -tr.even td {background-color:#fff;} - -#header { - height: 80px; - width: 777px; - background: blue URL('../images/header_inner.png') no-repeat; - border-left: 1px solid #aaa; - border-right: 1px solid #aaa; - margin: 0 auto 0 auto; -} - -a.link, a, a.active { - color: #369; -} - - -#main_content { - color: black; - font-size: 127%; - background-color: white; - width: 757px; - margin: 0 auto 0 auto; - border-left: 1px solid #aaa; - border-right: 1px solid #aaa; - padding: 10px; -} - -#sidebar { - border: 1px solid #aaa; - background-color: #eee; - margin: 0.5em; - padding: 1em; - float: right; - width: 200px; - font-size: 88%; -} - -#sidebar h2 { - margin-top: 0; -} - -#sidebar ul { - margin-left: 1.5em; - padding-left: 0; -} - -h1,h2,h3,h4,h5,h6,#getting_started_steps { - font-family: "Century Schoolbook L", Georgia, serif; - font-weight: bold; -} - -h2 { - font-size: 150%; -} - -#footer { - border: 1px solid #aaa; - border-top: 0px none; - color: #999; - background-color: white; - padding: 10px; - font-size: 80%; - text-align: center; - width: 757px; - margin: 0 auto 1em auto; -} - -.code { - font-family: monospace; -} - -span.code { - font-weight: bold; - background: #eee; -} - -#status_block { - margin: 0 auto 0.5em auto; - padding: 15px 10px 15px 55px; - background: #cec URL('../images/ok.png') left center no-repeat; - border: 1px solid #9c9; - width: 450px; - font-size: 120%; - font-weight: bolder; -} - -.notice { - margin: 0.5em auto 0.5em auto; - padding: 15px 10px 15px 55px; - width: 450px; - background: #eef URL('../images/info.png') left center no-repeat; - border: 1px solid #cce; -} - -.fielderror { - color: red; - font-weight: bold; -} diff --git a/docs/tutorials/wiki/src/authorization/tutorial/static/transparent.gif b/docs/tutorials/wiki/src/authorization/tutorial/static/transparent.gif Binary files differnew file mode 100644 index 000000000..0341802e5 --- /dev/null +++ b/docs/tutorials/wiki/src/authorization/tutorial/static/transparent.gif diff --git a/docs/tutorials/wiki/src/authorization/tutorial/templates/edit.pt b/docs/tutorials/wiki/src/authorization/tutorial/templates/edit.pt index 5f8b22207..0e5858d3b 100644 --- a/docs/tutorials/wiki/src/authorization/tutorial/templates/edit.pt +++ b/docs/tutorials/wiki/src/authorization/tutorial/templates/edit.pt @@ -1,34 +1,51 @@ -<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" - "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"> -<html - xmlns="http://www.w3.org/1999/xhtml" - xmlns:tal="http://xml.zope.org/namespaces/tal"> - +<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd"> +<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en" xmlns:tal="http://xml.zope.org/namespaces/tal"> <head> - <meta content="text/html; charset=utf-8" http-equiv="Content-Type"/> - <title>Pyramid tutorial wiki (based on TurboGears 20-Minute Wiki) - Editing: ${page.__name__}</title> - <link rel="stylesheet" type="text/css" - href="${request.application_url}/static/style.css" /> + <title>${page.__name__} - Pyramid tutorial wiki (based on TurboGears 20-Minute Wiki)</title> + <meta http-equiv="Content-Type" content="text/html;charset=UTF-8"/> + <meta name="keywords" content="python web application" /> + <meta name="description" content="pyramid web application" /> + <link rel="shortcut icon" href="${request.static_url('tutorial:static/favicon.ico')}" /> + <link rel="stylesheet" href="${request.static_url('tutorial:static/pylons.css')}" type="text/css" media="screen" charset="utf-8" /> + <link rel="stylesheet" href="http://fonts.googleapis.com/css?family=Neuton&subset=latin" type="text/css" media="screen" charset="utf-8" /> + <link rel="stylesheet" href="http://fonts.googleapis.com/css?family=Nobile:regular,italic,bold,bolditalic&subset=latin" type="text/css" media="screen" charset="utf-8" /> + <!--[if lte IE 6]> + <link rel="stylesheet" href="${request.static_url('tutorial:static/ie6.css')}" type="text/css" media="screen" charset="utf-8" /> + <![endif]--> </head> - <body> - -<div class="main_content"> - <div style="float:right; width: 10em;"> Viewing - <span tal:replace="page.__name__">Page Name Goes Here</span> <br/> - You can return to the <a href="${request.application_url}" - >FrontPage</a>. - <span tal:condition="logged_in"><a - href="${request.application_url}/logout">Logout</a></span> - </div> - - <div> - <form action="${save_url}" method="post"> - <textarea name="body" tal:content="page.data" rows="10" cols="60"/> - <input type="submit" name="form.submitted" value="Save"/> - </form> - </div> -</div> + <div id="wrap"> + <div id="top-small"> + <div class="top-small align-center"> + <div> + <img src="${request.static_url('tutorial:static/pyramid-small.png')}" width="220" height="50" alt="pyramid" /> + </div> + </div> + </div> + <div id="middle"> + <div class="middle align-right"> + <div id="left" class="app-welcome align-left"> + Editing <b><span tal:replace="page.__name__">Page Name Goes Here</span></b><br/> + You can return to the <a href="${request.application_url}">FrontPage</a>.<br/> + </div> + <div id="right" class="app-welcome align-right"> + <span tal:condition="logged_in"> + <a href="${request.application_url}/logout">Logout</a> + </span> + </div> + </div> + </div> + <div id="bottom"> + <div class="bottom"> + <form action="${save_url}" method="post"> + <textarea name="body" tal:content="page.data" rows="10" cols="60"/><br/> + <input type="submit" name="form.submitted" value="Save"/> + </form> + </div> + </div> + </div> + <div id="footer"> + <div class="footer">© Copyright 2008-2011, Agendaless Consulting.</div> + </div> </body> -</html> +</html>
\ No newline at end of file diff --git a/docs/tutorials/wiki/src/authorization/tutorial/templates/login.pt b/docs/tutorials/wiki/src/authorization/tutorial/templates/login.pt index c56983d64..974e22f37 100644 --- a/docs/tutorials/wiki/src/authorization/tutorial/templates/login.pt +++ b/docs/tutorials/wiki/src/authorization/tutorial/templates/login.pt @@ -1,32 +1,49 @@ -<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" - "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"> -<html - xmlns="http://www.w3.org/1999/xhtml" - xmlns:tal="http://xml.zope.org/namespaces/tal"> - +<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd"> +<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en" xmlns:tal="http://xml.zope.org/namespaces/tal"> <head> - <meta content="text/html; charset=utf-8" http-equiv="Content-Type"/> - <title>Pyramid tutorial wiki (based on TurboGears 20-Minute Wiki)</title> - <link rel="stylesheet" type="text/css" - href="${request.application_url}/static/style.css" /> + <title>Login - Pyramid tutorial wiki (based on TurboGears 20-Minute Wiki)</title> + <meta http-equiv="Content-Type" content="text/html;charset=UTF-8"/> + <meta name="keywords" content="python web application" /> + <meta name="description" content="pyramid web application" /> + <link rel="shortcut icon" href="${request.static_url('tutorial:static/favicon.ico')}" /> + <link rel="stylesheet" href="${request.static_url('tutorial:static/pylons.css')}" type="text/css" media="screen" charset="utf-8" /> + <link rel="stylesheet" href="http://fonts.googleapis.com/css?family=Neuton&subset=latin" type="text/css" media="screen" charset="utf-8" /> + <link rel="stylesheet" href="http://fonts.googleapis.com/css?family=Nobile:regular,italic,bold,bolditalic&subset=latin" type="text/css" media="screen" charset="utf-8" /> + <!--[if lte IE 6]> + <link rel="stylesheet" href="${request.static_url('tutorial:static/ie6.css')}" type="text/css" media="screen" charset="utf-8" /> + <![endif]--> </head> - <body> - -<h1>Log In</h1> - -<div tal:replace="message"/> - -<div class="main_content"> - <form action="${url}" method="post"> - <input type="hidden" name="came_from" value="${came_from}"/> - <input type="text" name="login" value="${login}"/> - <br/> - <input type="password" name="password" value="${password}"/> - <br/> - <input type="submit" name="form.submitted" value="Log In"/> - </form> -</div> - + <div id="wrap"> + <div id="top-small"> + <div class="top-small align-center"> + <div> + <img src="${request.static_url('tutorial:static/pyramid-small.png')}" width="220" height="50" alt="pyramid" /> + </div> + </div> + </div> + <div id="middle"> + <div class="middle align-right"> + <div id="left" class="app-welcome align-left"> + <b>Login</b><br/> + <span tal:replace="message"/> + </div> + <div id="right" class="app-welcome align-right"></div> + </div> + </div> + <div id="bottom"> + <div class="bottom"> + <form action="${url}" method="post"> + <input type="hidden" name="came_from" value="${came_from}"/> + <input type="text" name="login" value="${login}"/><br/> + <input type="password" name="password" value="${password}"/><br/> + <input type="submit" name="form.submitted" value="Log In"/> + </form> + </div> + </div> + </div> + <div id="footer"> + <div class="footer">© Copyright 2008-2011, Agendaless Consulting.</div> + </div> </body> -</html> +</html>
\ No newline at end of file diff --git a/docs/tutorials/wiki/src/authorization/tutorial/templates/mytemplate.pt b/docs/tutorials/wiki/src/authorization/tutorial/templates/mytemplate.pt index a5a0dd214..cac9ccaa7 100644 --- a/docs/tutorials/wiki/src/authorization/tutorial/templates/mytemplate.pt +++ b/docs/tutorials/wiki/src/authorization/tutorial/templates/mytemplate.pt @@ -5,65 +5,72 @@ <meta http-equiv="Content-Type" content="text/html;charset=UTF-8"/> <meta name="keywords" content="python web application" /> <meta name="description" content="pyramid web application" /> - <link rel="shortcut icon" href="${request.application_url}/static/favicon.ico" /> - <link rel="stylesheet" href="${request.application_url}/static/pylons.css" type="text/css" media="screen" charset="utf-8" /> + <link rel="shortcut icon" href="${request.static_url('tutorial:static/favicon.ico')}" /> + <link rel="stylesheet" href="${request.static_url('tutorial:static/pylons.css')}" type="text/css" media="screen" charset="utf-8" /> + <link rel="stylesheet" href="http://fonts.googleapis.com/css?family=Neuton&subset=latin" type="text/css" media="screen" charset="utf-8" /> <link rel="stylesheet" href="http://fonts.googleapis.com/css?family=Nobile:regular,italic,bold,bolditalic&subset=latin" type="text/css" media="screen" charset="utf-8" /> + <!--[if lte IE 6]> + <link rel="stylesheet" href="${request.static_url('tutorial:static/ie6.css')}" type="text/css" media="screen" charset="utf-8" /> + <![endif]--> </head> <body> - <div id="header"> - <div class="header">The Pyramid Web Application Development Framework</div> - </div> - <div id="top"> - <div class="top align-center"> - <img src="${request.application_url}/static/logo.png" width="300" height="80"/> - <p class="app-welcome"> - Welcome to <span class="app-name">${project}</span>, an application generated by<br/> - the Pyramid web application development framework. - </p> + <div id="wrap"> + <div id="top"> + <div class="top align-center"> + <div><img src="${request.static_url('tutorial:static/pyramid.png')}" width="750" height="169" alt="pyramid"/></div> + </div> </div> - </div> - <div id="bottom"> - <div class="bottom"> - <div id="left" class="align-right"> - <h3>Search Pyramid documentation</h3> - <form method="get" action="http://docs.pylonshq.com/pyramid/dev/search.html"> - <input type="text" id="q" name="q" value="" /> - <input type="submit" id="x" value="Search" /> - </form> + <div id="middle"> + <div class="middle align-center"> + <p class="app-welcome"> + Welcome to <span class="app-name">${project}</span>, an application generated by<br/> + the Pyramid web application development framework. + </p> </div> - <div id="right" class="align-left"> - <h3>Pyramid links</h3> - <ul class="links"> - <li> - <a href="http://pylonshq.com">Pylons Website</a> - </li> - <li> - <a href="http://docs.pylonshq.com/pyramid/dev/#narrative-documentation">Narrative Documentation</a> - </li> - <li> - <a href="http://docs.pylonshq.com/pyramid/dev/#api-documentation">API Documentation</a> - </li> - <li> - <a href="http://docs.pylonshq.com/pyramid/dev/#tutorials">Tutorials</a> - </li> - <li> - <a href="http://docs.pylonshq.com/pyramid/dev/#change-history">Change History</a> - </li> - <li> - <a href="http://docs.pylonshq.com/pyramid/dev/#sample-applications">Sample Applications</a> - </li> - <li> - <a href="http://docs.pylonshq.com/pyramid/dev/#support-and-development">Support and Development</a> - </li> - <li> - <a href="irc://irc.freenode.net#pyramid">IRC Channel</a> - </li> - </ul> + </div> + <div id="bottom"> + <div class="bottom"> + <div id="left" class="align-right"> + <h2>Search documentation</h2> + <form method="get" action="http://docs.pylonshq.com/pyramid/dev/search.html"> + <input type="text" id="q" name="q" value="" /> + <input type="submit" id="x" value="Go" /> + </form> + </div> + <div id="right" class="align-left"> + <h2>Pyramid links</h2> + <ul class="links"> + <li> + <a href="http://pylonshq.com">Pylons Website</a> + </li> + <li> + <a href="http://docs.pylonshq.com/pyramid/dev/#narrative-documentation">Narrative Documentation</a> + </li> + <li> + <a href="http://docs.pylonshq.com/pyramid/dev/#api-documentation">API Documentation</a> + </li> + <li> + <a href="http://docs.pylonshq.com/pyramid/dev/#tutorials">Tutorials</a> + </li> + <li> + <a href="http://docs.pylonshq.com/pyramid/dev/#change-history">Change History</a> + </li> + <li> + <a href="http://docs.pylonshq.com/pyramid/dev/#sample-applications">Sample Applications</a> + </li> + <li> + <a href="http://docs.pylonshq.com/pyramid/dev/#support-and-development">Support and Development</a> + </li> + <li> + <a href="irc://irc.freenode.net#pyramid">IRC Channel</a> + </li> + </ul> + </div> </div> </div> </div> <div id="footer"> - <div class="footer">© Copyright 2008-2010, Agendaless Consulting.</div> + <div class="footer">© Copyright 2008-2011, Agendaless Consulting.</div> </div> </body> </html>
\ No newline at end of file diff --git a/docs/tutorials/wiki/src/authorization/tutorial/templates/view.pt b/docs/tutorials/wiki/src/authorization/tutorial/templates/view.pt index f957176f1..3fd709338 100644 --- a/docs/tutorials/wiki/src/authorization/tutorial/templates/view.pt +++ b/docs/tutorials/wiki/src/authorization/tutorial/templates/view.pt @@ -1,31 +1,55 @@ -<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" - "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"> -<html - xmlns="http://www.w3.org/1999/xhtml" - xmlns:tal="http://xml.zope.org/namespaces/tal"> - +<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd"> +<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en" xmlns:tal="http://xml.zope.org/namespaces/tal"> <head> - <meta content="text/html; charset=utf-8" http-equiv="Content-Type"/> - <title>${page.__name__} - Pyramid tutorial wiki - (based on TurboGears 20-Minute Wiki) - </title> - <link rel="stylesheet" type="text/css" - href="${request.application_url}/static/style.css" /> + <title>${page.__name__} - Pyramid tutorial wiki (based on TurboGears 20-Minute Wiki)</title> + <meta http-equiv="Content-Type" content="text/html;charset=UTF-8"/> + <meta name="keywords" content="python web application" /> + <meta name="description" content="pyramid web application" /> + <link rel="shortcut icon" href="${request.static_url('tutorial:static/favicon.ico')}" /> + <link rel="stylesheet" href="${request.static_url('tutorial:static/pylons.css')}" type="text/css" media="screen" charset="utf-8" /> + <link rel="stylesheet" href="http://fonts.googleapis.com/css?family=Neuton&subset=latin" type="text/css" media="screen" charset="utf-8" /> + <link rel="stylesheet" href="http://fonts.googleapis.com/css?family=Nobile:regular,italic,bold,bolditalic&subset=latin" type="text/css" media="screen" charset="utf-8" /> + <!--[if lte IE 6]> + <link rel="stylesheet" href="${request.static_url('tutorial:static/ie6.css')}" type="text/css" media="screen" charset="utf-8" /> + <![endif]--> </head> - <body> - -<div class="main_content"> -<div style="float:right; width: 10em;"> Viewing -<span tal:replace="page.__name__">Page Name Goes Here</span> <br/> -You can return to the <a href="${request.application_url}">FrontPage</a>. -<span tal:condition="logged_in"> - <a href="${request.application_url}/logout">Logout</a> -</span> -</div> - -<div tal:replace="structure content">Page text goes here.</div> -<p><a tal:attributes="href edit_url" href="">Edit this page</a></p> -</div> - -</body></html> + <div id="wrap"> + <div id="top-small"> + <div class="top-small align-center"> + <div> + <img src="${request.static_url('tutorial:static/pyramid-small.png')}" width="220" height="50" alt="pyramid" /> + </div> + </div> + </div> + <div id="middle"> + <div class="middle align-right"> + <div id="left" class="app-welcome align-left"> + Viewing <b><span tal:replace="page.__name__">Page Name Goes Here</span></b><br/> + You can return to the <a href="${request.application_url}">FrontPage</a>.<br/> + </div> + <div id="right" class="app-welcome align-right"> + <span tal:condition="logged_in"> + <a href="${request.application_url}/logout">Logout</a> + </span> + </div> + </div> + </div> + <div id="bottom"> + <div class="bottom"> + <div tal:replace="structure content"> + Page text goes here. + </div> + <p> + <a tal:attributes="href edit_url" href=""> + Edit this page + </a> + </p> + </div> + </div> + </div> + <div id="footer"> + <div class="footer">© Copyright 2008-2011, Agendaless Consulting.</div> + </div> +</body> +</html>
\ No newline at end of file diff --git a/docs/tutorials/wiki/src/basiclayout/tutorial/static/footerbg.png b/docs/tutorials/wiki/src/basiclayout/tutorial/static/footerbg.png Binary files differnew file mode 100644 index 000000000..1fbc873da --- /dev/null +++ b/docs/tutorials/wiki/src/basiclayout/tutorial/static/footerbg.png diff --git a/docs/tutorials/wiki/src/basiclayout/tutorial/static/headerbg.png b/docs/tutorials/wiki/src/basiclayout/tutorial/static/headerbg.png Binary files differnew file mode 100644 index 000000000..0596f2020 --- /dev/null +++ b/docs/tutorials/wiki/src/basiclayout/tutorial/static/headerbg.png diff --git a/docs/tutorials/wiki/src/basiclayout/tutorial/static/ie6.css b/docs/tutorials/wiki/src/basiclayout/tutorial/static/ie6.css new file mode 100644 index 000000000..b7c8493d8 --- /dev/null +++ b/docs/tutorials/wiki/src/basiclayout/tutorial/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/docs/tutorials/wiki/src/basiclayout/tutorial/static/logo.png b/docs/tutorials/wiki/src/basiclayout/tutorial/static/logo.png Binary files differdeleted file mode 100644 index 88f5d9865..000000000 --- a/docs/tutorials/wiki/src/basiclayout/tutorial/static/logo.png +++ /dev/null diff --git a/docs/tutorials/wiki/src/basiclayout/tutorial/static/middlebg.png b/docs/tutorials/wiki/src/basiclayout/tutorial/static/middlebg.png Binary files differnew file mode 100644 index 000000000..2369cfb7d --- /dev/null +++ b/docs/tutorials/wiki/src/basiclayout/tutorial/static/middlebg.png diff --git a/docs/tutorials/wiki/src/basiclayout/tutorial/static/pylons.css b/docs/tutorials/wiki/src/basiclayout/tutorial/static/pylons.css index c153be07f..fd1914d8d 100644 --- a/docs/tutorials/wiki/src/basiclayout/tutorial/static/pylons.css +++ b/docs/tutorials/wiki/src/basiclayout/tutorial/static/pylons.css @@ -4,34 +4,23 @@ body{line-height:1;} ol,ul{list-style:none;} blockquote,q{quotes:none;} blockquote:before,blockquote:after,q:before,q:after{content:'';content:none;} -/* remember to define focus styles! */ :focus{outline:0;} -/* remember to highlight inserts somehow! */ ins{text-decoration:none;} del{text-decoration:line-through;} -/* tables still need 'cellspacing="0"' in the markup */ table{border-collapse:collapse;border-spacing:0;} -/* restyling */ sub{vertical-align:sub;font-size:smaller;line-height:normal;} sup{vertical-align:super;font-size:smaller;line-height:normal;} -/* lists */ ul,menu,dir{display:block;list-style-type:disc;margin:1em 0;padding-left:40px;} ol{display:block;list-style-type:decimal-leading-zero;margin:1em 0;padding-left:40px;} li{display:list-item;} -/* nested lists have no top/bottom margins */ ul ul,ul ol,ul dir,ul menu,ul dl,ol ul,ol ol,ol dir,ol menu,ol dl,dir ul,dir ol,dir dir,dir menu,dir dl,menu ul,menu ol,menu dir,menu menu,menu dl,dl ul,dl ol,dl dir,dl menu,dl dl{margin-top:0;margin-bottom:0;} -/* 2 deep unordered lists use a circle */ ol ul,ul ul,menu ul,dir ul,ol menu,ul menu,menu menu,dir menu,ol dir,ul dir,menu dir,dir dir{list-style-type:circle;} -/* 3 deep (or more) unordered lists use a square */ ol ol ul,ol ul ul,ol menu ul,ol dir ul,ol ol menu,ol ul menu,ol menu menu,ol dir menu,ol ol dir,ol ul dir,ol menu dir,ol dir dir,ul ol ul,ul ul ul,ul menu ul,ul dir ul,ul ol menu,ul ul menu,ul menu menu,ul dir menu,ul ol dir,ul ul dir,ul menu dir,ul dir dir,menu ol ul,menu ul ul,menu menu ul,menu dir ul,menu ol menu,menu ul menu,menu menu menu,menu dir menu,menu ol dir,menu ul dir,menu menu dir,menu dir dir,dir ol ul,dir ul ul,dir menu ul,dir dir ul,dir ol menu,dir ul menu,dir menu menu,dir dir menu,dir ol dir,dir ul dir,dir menu dir,dir dir dir{list-style-type:square;} .hidden{display:none;} p{line-height:1.5em;} -h1{font-size:1.75em;/* 28px */ -line-height:1.7em;font-family:helvetica,verdana;} -h2{font-size:1.5em;/* 24px */ -line-height:1.7em;font-family:helvetica,verdana;} -h3{font-size:1.25em;/* 20px */ -line-height:1.7em;font-family:helvetica,verdana;} +h1{font-size:1.75em;line-height:1.7em;font-family:helvetica,verdana;} +h2{font-size:1.5em;line-height:1.7em;font-family:helvetica,verdana;} +h3{font-size:1.25em;line-height:1.7em;font-family:helvetica,verdana;} h4{font-size:1em;line-height:1.7em;font-family:helvetica,verdana;} html,body{width:100%;height:100%;} body{margin:0;padding:0;background-color:#ffffff;position:relative;font:16px/24px "Nobile","Lucida Grande",Lucida,Verdana,sans-serif;} @@ -42,23 +31,26 @@ 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,#top-small,#bottom{width:100%;} +#top{color:#000000;height:230px;background:#ffffff url(headerbg.png) repeat-x 0 top;position:relative;} +#top-small{color:#000000;height:60px;background:#ffffff url(headerbg.png) repeat-x 0 top;position:relative;} +#bottom{color:#222;background-color:#ffffff;} +.top,.top-small,.middle,.bottom{width:750px;margin-right:auto;margin-left:auto;} +.top{padding-top:40px;} +.top-small{padding-top:10px;} +#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 +59,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],input[type=password]{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/docs/tutorials/wiki/src/basiclayout/tutorial/static/pyramid-small.png b/docs/tutorials/wiki/src/basiclayout/tutorial/static/pyramid-small.png Binary files differnew file mode 100644 index 000000000..a5bc0ade7 --- /dev/null +++ b/docs/tutorials/wiki/src/basiclayout/tutorial/static/pyramid-small.png diff --git a/docs/tutorials/wiki/src/basiclayout/tutorial/static/pyramid.png b/docs/tutorials/wiki/src/basiclayout/tutorial/static/pyramid.png Binary files differnew file mode 100644 index 000000000..347e05549 --- /dev/null +++ b/docs/tutorials/wiki/src/basiclayout/tutorial/static/pyramid.png diff --git a/docs/tutorials/wiki/src/basiclayout/tutorial/static/transparent.gif b/docs/tutorials/wiki/src/basiclayout/tutorial/static/transparent.gif Binary files differnew file mode 100644 index 000000000..0341802e5 --- /dev/null +++ b/docs/tutorials/wiki/src/basiclayout/tutorial/static/transparent.gif diff --git a/docs/tutorials/wiki/src/basiclayout/tutorial/templates/mytemplate.pt b/docs/tutorials/wiki/src/basiclayout/tutorial/templates/mytemplate.pt index 6ad23d44f..cac9ccaa7 100644 --- a/docs/tutorials/wiki/src/basiclayout/tutorial/templates/mytemplate.pt +++ b/docs/tutorials/wiki/src/basiclayout/tutorial/templates/mytemplate.pt @@ -5,23 +5,23 @@ <meta http-equiv="Content-Type" content="text/html;charset=UTF-8"/> <meta name="keywords" content="python web application" /> <meta name="description" content="pyramid web application" /> - <link rel="shortcut icon" href="${request.application_url}/static/favicon.ico" /> - <link rel="stylesheet" href="${request.application_url}/static/pylons.css" type="text/css" media="screen" charset="utf-8" /> + <link rel="shortcut icon" href="${request.static_url('tutorial:static/favicon.ico')}" /> + <link rel="stylesheet" href="${request.static_url('tutorial:static/pylons.css')}" type="text/css" media="screen" charset="utf-8" /> + <link rel="stylesheet" href="http://fonts.googleapis.com/css?family=Neuton&subset=latin" type="text/css" media="screen" charset="utf-8" /> <link rel="stylesheet" href="http://fonts.googleapis.com/css?family=Nobile:regular,italic,bold,bolditalic&subset=latin" type="text/css" media="screen" charset="utf-8" /> - <!--[if !IE 7]> - <style type="text/css"> - #wrap {display:table;height:100%} - </style> + <!--[if lte IE 6]> + <link rel="stylesheet" href="${request.static_url('tutorial:static/ie6.css')}" type="text/css" media="screen" charset="utf-8" /> <![endif]--> </head> <body> <div id="wrap"> - <div id="header"> - <div class="header">The Pyramid Web Application Development Framework</div> - </div> <div id="top"> <div class="top align-center"> - <img src="${request.application_url}/static/logo.png" width="300" height="80"/> + <div><img src="${request.static_url('tutorial:static/pyramid.png')}" width="750" height="169" alt="pyramid"/></div> + </div> + </div> + <div id="middle"> + <div class="middle align-center"> <p class="app-welcome"> Welcome to <span class="app-name">${project}</span>, an application generated by<br/> the Pyramid web application development framework. @@ -31,22 +31,19 @@ <div id="bottom"> <div class="bottom"> <div id="left" class="align-right"> - <h3>Search Pyramid documentation</h3> + <h2>Search documentation</h2> <form method="get" action="http://docs.pylonshq.com/pyramid/dev/search.html"> <input type="text" id="q" name="q" value="" /> - <input type="submit" id="x" value="Search" /> + <input type="submit" id="x" value="Go" /> </form> </div> <div id="right" class="align-left"> - <h3>Pyramid links</h3> + <h2>Pyramid links</h2> <ul class="links"> <li> <a href="http://pylonshq.com">Pylons Website</a> </li> <li> - <a href="http://docs.pylonshq.com/">The Pylons Project Documentation</a> - </li> - <li> <a href="http://docs.pylonshq.com/pyramid/dev/#narrative-documentation">Narrative Documentation</a> </li> <li> @@ -73,7 +70,7 @@ </div> </div> <div id="footer"> - <div class="footer">© Copyright 2008-2010, Agendaless Consulting.</div> + <div class="footer">© Copyright 2008-2011, Agendaless Consulting.</div> </div> </body> </html>
\ No newline at end of file diff --git a/docs/tutorials/wiki/src/models/tutorial/static/footerbg.png b/docs/tutorials/wiki/src/models/tutorial/static/footerbg.png Binary files differnew file mode 100644 index 000000000..1fbc873da --- /dev/null +++ b/docs/tutorials/wiki/src/models/tutorial/static/footerbg.png diff --git a/docs/tutorials/wiki/src/models/tutorial/static/headerbg.png b/docs/tutorials/wiki/src/models/tutorial/static/headerbg.png Binary files differnew file mode 100644 index 000000000..0596f2020 --- /dev/null +++ b/docs/tutorials/wiki/src/models/tutorial/static/headerbg.png diff --git a/docs/tutorials/wiki/src/models/tutorial/static/ie6.css b/docs/tutorials/wiki/src/models/tutorial/static/ie6.css new file mode 100644 index 000000000..b7c8493d8 --- /dev/null +++ b/docs/tutorials/wiki/src/models/tutorial/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/docs/tutorials/wiki/src/models/tutorial/static/logo.png b/docs/tutorials/wiki/src/models/tutorial/static/logo.png Binary files differdeleted file mode 100644 index 88f5d9865..000000000 --- a/docs/tutorials/wiki/src/models/tutorial/static/logo.png +++ /dev/null diff --git a/docs/tutorials/wiki/src/models/tutorial/static/middlebg.png b/docs/tutorials/wiki/src/models/tutorial/static/middlebg.png Binary files differnew file mode 100644 index 000000000..2369cfb7d --- /dev/null +++ b/docs/tutorials/wiki/src/models/tutorial/static/middlebg.png diff --git a/docs/tutorials/wiki/src/models/tutorial/static/pylons.css b/docs/tutorials/wiki/src/models/tutorial/static/pylons.css index c153be07f..a9f49cc85 100644 --- a/docs/tutorials/wiki/src/models/tutorial/static/pylons.css +++ b/docs/tutorials/wiki/src/models/tutorial/static/pylons.css @@ -4,34 +4,23 @@ body{line-height:1;} ol,ul{list-style:none;} blockquote,q{quotes:none;} blockquote:before,blockquote:after,q:before,q:after{content:'';content:none;} -/* remember to define focus styles! */ :focus{outline:0;} -/* remember to highlight inserts somehow! */ ins{text-decoration:none;} del{text-decoration:line-through;} -/* tables still need 'cellspacing="0"' in the markup */ table{border-collapse:collapse;border-spacing:0;} -/* restyling */ sub{vertical-align:sub;font-size:smaller;line-height:normal;} sup{vertical-align:super;font-size:smaller;line-height:normal;} -/* lists */ ul,menu,dir{display:block;list-style-type:disc;margin:1em 0;padding-left:40px;} ol{display:block;list-style-type:decimal-leading-zero;margin:1em 0;padding-left:40px;} li{display:list-item;} -/* nested lists have no top/bottom margins */ ul ul,ul ol,ul dir,ul menu,ul dl,ol ul,ol ol,ol dir,ol menu,ol dl,dir ul,dir ol,dir dir,dir menu,dir dl,menu ul,menu ol,menu dir,menu menu,menu dl,dl ul,dl ol,dl dir,dl menu,dl dl{margin-top:0;margin-bottom:0;} -/* 2 deep unordered lists use a circle */ ol ul,ul ul,menu ul,dir ul,ol menu,ul menu,menu menu,dir menu,ol dir,ul dir,menu dir,dir dir{list-style-type:circle;} -/* 3 deep (or more) unordered lists use a square */ ol ol ul,ol ul ul,ol menu ul,ol dir ul,ol ol menu,ol ul menu,ol menu menu,ol dir menu,ol ol dir,ol ul dir,ol menu dir,ol dir dir,ul ol ul,ul ul ul,ul menu ul,ul dir ul,ul ol menu,ul ul menu,ul menu menu,ul dir menu,ul ol dir,ul ul dir,ul menu dir,ul dir dir,menu ol ul,menu ul ul,menu menu ul,menu dir ul,menu ol menu,menu ul menu,menu menu menu,menu dir menu,menu ol dir,menu ul dir,menu menu dir,menu dir dir,dir ol ul,dir ul ul,dir menu ul,dir dir ul,dir ol menu,dir ul menu,dir menu menu,dir dir menu,dir ol dir,dir ul dir,dir menu dir,dir dir dir{list-style-type:square;} .hidden{display:none;} p{line-height:1.5em;} -h1{font-size:1.75em;/* 28px */ -line-height:1.7em;font-family:helvetica,verdana;} -h2{font-size:1.5em;/* 24px */ -line-height:1.7em;font-family:helvetica,verdana;} -h3{font-size:1.25em;/* 20px */ -line-height:1.7em;font-family:helvetica,verdana;} +h1{font-size:1.75em;line-height:1.7em;font-family:helvetica,verdana;} +h2{font-size:1.5em;line-height:1.7em;font-family:helvetica,verdana;} +h3{font-size:1.25em;line-height:1.7em;font-family:helvetica,verdana;} h4{font-size:1em;line-height:1.7em;font-family:helvetica,verdana;} html,body{width:100%;height:100%;} body{margin:0;padding:0;background-color:#ffffff;position:relative;font:16px/24px "Nobile","Lucida Grande",Lucida,Verdana,sans-serif;} @@ -42,23 +31,26 @@ 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,#top-small,#bottom{width:100%;} +#top{color:#000000;height:230px;background:#ffffff url(headerbg.png) repeat-x 0 top;position:relative;} +#top-small{color:#000000;height:60px;background:#ffffff url(headerbg.png) repeat-x 0 top;position:relative;} +#bottom{color:#222;background-color:#ffffff;} +.top,.top-snall,.middle,.bottom{width:750px;margin-right:auto;margin-left:auto;} +.top{padding-top:40px;} +.top-small{padding-top:10px;} +#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 +59,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],input[type=password]{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/docs/tutorials/wiki/src/models/tutorial/static/pyramid-small.png b/docs/tutorials/wiki/src/models/tutorial/static/pyramid-small.png Binary files differnew file mode 100644 index 000000000..a5bc0ade7 --- /dev/null +++ b/docs/tutorials/wiki/src/models/tutorial/static/pyramid-small.png diff --git a/docs/tutorials/wiki/src/models/tutorial/static/pyramid.png b/docs/tutorials/wiki/src/models/tutorial/static/pyramid.png Binary files differnew file mode 100644 index 000000000..347e05549 --- /dev/null +++ b/docs/tutorials/wiki/src/models/tutorial/static/pyramid.png diff --git a/docs/tutorials/wiki/src/models/tutorial/static/transparent.gif b/docs/tutorials/wiki/src/models/tutorial/static/transparent.gif Binary files differnew file mode 100644 index 000000000..0341802e5 --- /dev/null +++ b/docs/tutorials/wiki/src/models/tutorial/static/transparent.gif diff --git a/docs/tutorials/wiki/src/models/tutorial/templates/mytemplate.pt b/docs/tutorials/wiki/src/models/tutorial/templates/mytemplate.pt index a5a0dd214..cac9ccaa7 100644 --- a/docs/tutorials/wiki/src/models/tutorial/templates/mytemplate.pt +++ b/docs/tutorials/wiki/src/models/tutorial/templates/mytemplate.pt @@ -5,65 +5,72 @@ <meta http-equiv="Content-Type" content="text/html;charset=UTF-8"/> <meta name="keywords" content="python web application" /> <meta name="description" content="pyramid web application" /> - <link rel="shortcut icon" href="${request.application_url}/static/favicon.ico" /> - <link rel="stylesheet" href="${request.application_url}/static/pylons.css" type="text/css" media="screen" charset="utf-8" /> + <link rel="shortcut icon" href="${request.static_url('tutorial:static/favicon.ico')}" /> + <link rel="stylesheet" href="${request.static_url('tutorial:static/pylons.css')}" type="text/css" media="screen" charset="utf-8" /> + <link rel="stylesheet" href="http://fonts.googleapis.com/css?family=Neuton&subset=latin" type="text/css" media="screen" charset="utf-8" /> <link rel="stylesheet" href="http://fonts.googleapis.com/css?family=Nobile:regular,italic,bold,bolditalic&subset=latin" type="text/css" media="screen" charset="utf-8" /> + <!--[if lte IE 6]> + <link rel="stylesheet" href="${request.static_url('tutorial:static/ie6.css')}" type="text/css" media="screen" charset="utf-8" /> + <![endif]--> </head> <body> - <div id="header"> - <div class="header">The Pyramid Web Application Development Framework</div> - </div> - <div id="top"> - <div class="top align-center"> - <img src="${request.application_url}/static/logo.png" width="300" height="80"/> - <p class="app-welcome"> - Welcome to <span class="app-name">${project}</span>, an application generated by<br/> - the Pyramid web application development framework. - </p> + <div id="wrap"> + <div id="top"> + <div class="top align-center"> + <div><img src="${request.static_url('tutorial:static/pyramid.png')}" width="750" height="169" alt="pyramid"/></div> + </div> </div> - </div> - <div id="bottom"> - <div class="bottom"> - <div id="left" class="align-right"> - <h3>Search Pyramid documentation</h3> - <form method="get" action="http://docs.pylonshq.com/pyramid/dev/search.html"> - <input type="text" id="q" name="q" value="" /> - <input type="submit" id="x" value="Search" /> - </form> + <div id="middle"> + <div class="middle align-center"> + <p class="app-welcome"> + Welcome to <span class="app-name">${project}</span>, an application generated by<br/> + the Pyramid web application development framework. + </p> </div> - <div id="right" class="align-left"> - <h3>Pyramid links</h3> - <ul class="links"> - <li> - <a href="http://pylonshq.com">Pylons Website</a> - </li> - <li> - <a href="http://docs.pylonshq.com/pyramid/dev/#narrative-documentation">Narrative Documentation</a> - </li> - <li> - <a href="http://docs.pylonshq.com/pyramid/dev/#api-documentation">API Documentation</a> - </li> - <li> - <a href="http://docs.pylonshq.com/pyramid/dev/#tutorials">Tutorials</a> - </li> - <li> - <a href="http://docs.pylonshq.com/pyramid/dev/#change-history">Change History</a> - </li> - <li> - <a href="http://docs.pylonshq.com/pyramid/dev/#sample-applications">Sample Applications</a> - </li> - <li> - <a href="http://docs.pylonshq.com/pyramid/dev/#support-and-development">Support and Development</a> - </li> - <li> - <a href="irc://irc.freenode.net#pyramid">IRC Channel</a> - </li> - </ul> + </div> + <div id="bottom"> + <div class="bottom"> + <div id="left" class="align-right"> + <h2>Search documentation</h2> + <form method="get" action="http://docs.pylonshq.com/pyramid/dev/search.html"> + <input type="text" id="q" name="q" value="" /> + <input type="submit" id="x" value="Go" /> + </form> + </div> + <div id="right" class="align-left"> + <h2>Pyramid links</h2> + <ul class="links"> + <li> + <a href="http://pylonshq.com">Pylons Website</a> + </li> + <li> + <a href="http://docs.pylonshq.com/pyramid/dev/#narrative-documentation">Narrative Documentation</a> + </li> + <li> + <a href="http://docs.pylonshq.com/pyramid/dev/#api-documentation">API Documentation</a> + </li> + <li> + <a href="http://docs.pylonshq.com/pyramid/dev/#tutorials">Tutorials</a> + </li> + <li> + <a href="http://docs.pylonshq.com/pyramid/dev/#change-history">Change History</a> + </li> + <li> + <a href="http://docs.pylonshq.com/pyramid/dev/#sample-applications">Sample Applications</a> + </li> + <li> + <a href="http://docs.pylonshq.com/pyramid/dev/#support-and-development">Support and Development</a> + </li> + <li> + <a href="irc://irc.freenode.net#pyramid">IRC Channel</a> + </li> + </ul> + </div> </div> </div> </div> <div id="footer"> - <div class="footer">© Copyright 2008-2010, Agendaless Consulting.</div> + <div class="footer">© Copyright 2008-2011, Agendaless Consulting.</div> </div> </body> </html>
\ No newline at end of file diff --git a/docs/tutorials/wiki/src/views/tutorial/static/footerbg.png b/docs/tutorials/wiki/src/views/tutorial/static/footerbg.png Binary files differnew file mode 100644 index 000000000..1fbc873da --- /dev/null +++ b/docs/tutorials/wiki/src/views/tutorial/static/footerbg.png diff --git a/docs/tutorials/wiki/src/views/tutorial/static/headerbg.png b/docs/tutorials/wiki/src/views/tutorial/static/headerbg.png Binary files differnew file mode 100644 index 000000000..0596f2020 --- /dev/null +++ b/docs/tutorials/wiki/src/views/tutorial/static/headerbg.png diff --git a/docs/tutorials/wiki/src/views/tutorial/static/ie6.css b/docs/tutorials/wiki/src/views/tutorial/static/ie6.css new file mode 100644 index 000000000..b7c8493d8 --- /dev/null +++ b/docs/tutorials/wiki/src/views/tutorial/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/docs/tutorials/wiki/src/views/tutorial/static/logo.png b/docs/tutorials/wiki/src/views/tutorial/static/logo.png Binary files differdeleted file mode 100644 index 88f5d9865..000000000 --- a/docs/tutorials/wiki/src/views/tutorial/static/logo.png +++ /dev/null diff --git a/docs/tutorials/wiki/src/views/tutorial/static/middlebg.png b/docs/tutorials/wiki/src/views/tutorial/static/middlebg.png Binary files differnew file mode 100644 index 000000000..2369cfb7d --- /dev/null +++ b/docs/tutorials/wiki/src/views/tutorial/static/middlebg.png diff --git a/docs/tutorials/wiki/src/views/tutorial/static/pylons.css b/docs/tutorials/wiki/src/views/tutorial/static/pylons.css index c153be07f..fd1914d8d 100644 --- a/docs/tutorials/wiki/src/views/tutorial/static/pylons.css +++ b/docs/tutorials/wiki/src/views/tutorial/static/pylons.css @@ -4,34 +4,23 @@ body{line-height:1;} ol,ul{list-style:none;} blockquote,q{quotes:none;} blockquote:before,blockquote:after,q:before,q:after{content:'';content:none;} -/* remember to define focus styles! */ :focus{outline:0;} -/* remember to highlight inserts somehow! */ ins{text-decoration:none;} del{text-decoration:line-through;} -/* tables still need 'cellspacing="0"' in the markup */ table{border-collapse:collapse;border-spacing:0;} -/* restyling */ sub{vertical-align:sub;font-size:smaller;line-height:normal;} sup{vertical-align:super;font-size:smaller;line-height:normal;} -/* lists */ ul,menu,dir{display:block;list-style-type:disc;margin:1em 0;padding-left:40px;} ol{display:block;list-style-type:decimal-leading-zero;margin:1em 0;padding-left:40px;} li{display:list-item;} -/* nested lists have no top/bottom margins */ ul ul,ul ol,ul dir,ul menu,ul dl,ol ul,ol ol,ol dir,ol menu,ol dl,dir ul,dir ol,dir dir,dir menu,dir dl,menu ul,menu ol,menu dir,menu menu,menu dl,dl ul,dl ol,dl dir,dl menu,dl dl{margin-top:0;margin-bottom:0;} -/* 2 deep unordered lists use a circle */ ol ul,ul ul,menu ul,dir ul,ol menu,ul menu,menu menu,dir menu,ol dir,ul dir,menu dir,dir dir{list-style-type:circle;} -/* 3 deep (or more) unordered lists use a square */ ol ol ul,ol ul ul,ol menu ul,ol dir ul,ol ol menu,ol ul menu,ol menu menu,ol dir menu,ol ol dir,ol ul dir,ol menu dir,ol dir dir,ul ol ul,ul ul ul,ul menu ul,ul dir ul,ul ol menu,ul ul menu,ul menu menu,ul dir menu,ul ol dir,ul ul dir,ul menu dir,ul dir dir,menu ol ul,menu ul ul,menu menu ul,menu dir ul,menu ol menu,menu ul menu,menu menu menu,menu dir menu,menu ol dir,menu ul dir,menu menu dir,menu dir dir,dir ol ul,dir ul ul,dir menu ul,dir dir ul,dir ol menu,dir ul menu,dir menu menu,dir dir menu,dir ol dir,dir ul dir,dir menu dir,dir dir dir{list-style-type:square;} .hidden{display:none;} p{line-height:1.5em;} -h1{font-size:1.75em;/* 28px */ -line-height:1.7em;font-family:helvetica,verdana;} -h2{font-size:1.5em;/* 24px */ -line-height:1.7em;font-family:helvetica,verdana;} -h3{font-size:1.25em;/* 20px */ -line-height:1.7em;font-family:helvetica,verdana;} +h1{font-size:1.75em;line-height:1.7em;font-family:helvetica,verdana;} +h2{font-size:1.5em;line-height:1.7em;font-family:helvetica,verdana;} +h3{font-size:1.25em;line-height:1.7em;font-family:helvetica,verdana;} h4{font-size:1em;line-height:1.7em;font-family:helvetica,verdana;} html,body{width:100%;height:100%;} body{margin:0;padding:0;background-color:#ffffff;position:relative;font:16px/24px "Nobile","Lucida Grande",Lucida,Verdana,sans-serif;} @@ -42,23 +31,26 @@ 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,#top-small,#bottom{width:100%;} +#top{color:#000000;height:230px;background:#ffffff url(headerbg.png) repeat-x 0 top;position:relative;} +#top-small{color:#000000;height:60px;background:#ffffff url(headerbg.png) repeat-x 0 top;position:relative;} +#bottom{color:#222;background-color:#ffffff;} +.top,.top-small,.middle,.bottom{width:750px;margin-right:auto;margin-left:auto;} +.top{padding-top:40px;} +.top-small{padding-top:10px;} +#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 +59,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],input[type=password]{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/docs/tutorials/wiki/src/views/tutorial/static/pyramid-small.png b/docs/tutorials/wiki/src/views/tutorial/static/pyramid-small.png Binary files differnew file mode 100644 index 000000000..a5bc0ade7 --- /dev/null +++ b/docs/tutorials/wiki/src/views/tutorial/static/pyramid-small.png diff --git a/docs/tutorials/wiki/src/views/tutorial/static/pyramid.png b/docs/tutorials/wiki/src/views/tutorial/static/pyramid.png Binary files differnew file mode 100644 index 000000000..347e05549 --- /dev/null +++ b/docs/tutorials/wiki/src/views/tutorial/static/pyramid.png diff --git a/docs/tutorials/wiki/src/views/tutorial/static/style.css b/docs/tutorials/wiki/src/views/tutorial/static/style.css deleted file mode 100644 index cad87e0d4..000000000 --- a/docs/tutorials/wiki/src/views/tutorial/static/style.css +++ /dev/null @@ -1,109 +0,0 @@ -html, body { - color: black; - background-color: #ddd; - font: x-small "Lucida Grande", "Lucida Sans Unicode", geneva, sans-serif; - margin: 0; - padding: 0; -} - -td, th {padding:3px;border:none;} -tr th {text-align:left;background-color:#f0f0f0;color:#333;} -tr.odd td {background-color:#edf3fe;} -tr.even td {background-color:#fff;} - -#header { - height: 80px; - width: 777px; - background: blue URL('../images/header_inner.png') no-repeat; - border-left: 1px solid #aaa; - border-right: 1px solid #aaa; - margin: 0 auto 0 auto; -} - -a.link, a, a.active { - color: #369; -} - - -#main_content { - color: black; - font-size: 127%; - background-color: white; - width: 757px; - margin: 0 auto 0 auto; - border-left: 1px solid #aaa; - border-right: 1px solid #aaa; - padding: 10px; -} - -#sidebar { - border: 1px solid #aaa; - background-color: #eee; - margin: 0.5em; - padding: 1em; - float: right; - width: 200px; - font-size: 88%; -} - -#sidebar h2 { - margin-top: 0; -} - -#sidebar ul { - margin-left: 1.5em; - padding-left: 0; -} - -h1,h2,h3,h4,h5,h6,#getting_started_steps { - font-family: "Century Schoolbook L", Georgia, serif; - font-weight: bold; -} - -h2 { - font-size: 150%; -} - -#footer { - border: 1px solid #aaa; - border-top: 0px none; - color: #999; - background-color: white; - padding: 10px; - font-size: 80%; - text-align: center; - width: 757px; - margin: 0 auto 1em auto; -} - -.code { - font-family: monospace; -} - -span.code { - font-weight: bold; - background: #eee; -} - -#status_block { - margin: 0 auto 0.5em auto; - padding: 15px 10px 15px 55px; - background: #cec URL('../images/ok.png') left center no-repeat; - border: 1px solid #9c9; - width: 450px; - font-size: 120%; - font-weight: bolder; -} - -.notice { - margin: 0.5em auto 0.5em auto; - padding: 15px 10px 15px 55px; - width: 450px; - background: #eef URL('../images/info.png') left center no-repeat; - border: 1px solid #cce; -} - -.fielderror { - color: red; - font-weight: bold; -} diff --git a/docs/tutorials/wiki/src/views/tutorial/static/transparent.gif b/docs/tutorials/wiki/src/views/tutorial/static/transparent.gif Binary files differnew file mode 100644 index 000000000..0341802e5 --- /dev/null +++ b/docs/tutorials/wiki/src/views/tutorial/static/transparent.gif diff --git a/docs/tutorials/wiki/src/views/tutorial/templates/edit.pt b/docs/tutorials/wiki/src/views/tutorial/templates/edit.pt index 1d40f526d..077a0dcb7 100644 --- a/docs/tutorials/wiki/src/views/tutorial/templates/edit.pt +++ b/docs/tutorials/wiki/src/views/tutorial/templates/edit.pt @@ -1,32 +1,47 @@ -<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" - "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"> -<html - xmlns="http://www.w3.org/1999/xhtml" - xmlns:tal="http://xml.zope.org/namespaces/tal"> - +<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd"> +<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en" xmlns:tal="http://xml.zope.org/namespaces/tal"> <head> - <meta content="text/html; charset=utf-8" http-equiv="Content-Type"/> - <title>Pyramid tutorial wiki (based on TurboGears 20-Minute Wiki) - Editing: ${page.__name__}</title> - <link rel="stylesheet" type="text/css" - href="${request.application_url}/static/style.css" /> + <title>${page.__name__} - Pyramid tutorial wiki (based on TurboGears 20-Minute Wiki)</title> + <meta http-equiv="Content-Type" content="text/html;charset=UTF-8"/> + <meta name="keywords" content="python web application" /> + <meta name="description" content="pyramid web application" /> + <link rel="shortcut icon" href="${request.static_url('tutorial:static/favicon.ico')}" /> + <link rel="stylesheet" href="${request.static_url('tutorial:static/pylons.css')}" type="text/css" media="screen" charset="utf-8" /> + <link rel="stylesheet" href="http://fonts.googleapis.com/css?family=Neuton&subset=latin" type="text/css" media="screen" charset="utf-8" /> + <link rel="stylesheet" href="http://fonts.googleapis.com/css?family=Nobile:regular,italic,bold,bolditalic&subset=latin" type="text/css" media="screen" charset="utf-8" /> + <!--[if lte IE 6]> + <link rel="stylesheet" href="${request.static_url('tutorial:static/ie6.css')}" type="text/css" media="screen" charset="utf-8" /> + <![endif]--> </head> - <body> - -<div class="main_content"> - <div style="float:right; width: 10em;"> Viewing - <span tal:replace="page.__name__">Page Name Goes Here</span> <br/> - You can return to the <a href="${request.application_url}" - >FrontPage</a>. - </div> - - <div> - <form action="${save_url}" method="post"> - <textarea name="body" tal:content="page.data" rows="10" cols="60"/> - <input type="submit" name="form.submitted" value="Save"/> - </form> - </div> -</div> + <div id="wrap"> + <div id="top-small"> + <div class="top-small align-center"> + <div> + <img src="${request.static_url('tutorial:static/pyramid-small.png')}" width="220" height="50" alt="pyramid" /> + </div> + </div> + </div> + <div id="middle"> + <div class="middle align-right"> + <div id="left" class="app-welcome align-left"> + Editing <b><span tal:replace="page.__name__">Page Name Goes Here</span></b><br/> + You can return to the <a href="${request.application_url}">FrontPage</a>.<br/> + </div> + <div id="right" class="app-welcome align-right"></div> + </div> + </div> + <div id="bottom"> + <div class="bottom"> + <form action="${save_url}" method="post"> + <textarea name="body" tal:content="page.data" rows="10" cols="60"/><br/> + <input type="submit" name="form.submitted" value="Save"/> + </form> + </div> + </div> + </div> + <div id="footer"> + <div class="footer">© Copyright 2008-2011, Agendaless Consulting.</div> + </div> </body> -</html> +</html>
\ No newline at end of file diff --git a/docs/tutorials/wiki/src/views/tutorial/templates/mytemplate.pt b/docs/tutorials/wiki/src/views/tutorial/templates/mytemplate.pt index a5a0dd214..cac9ccaa7 100644 --- a/docs/tutorials/wiki/src/views/tutorial/templates/mytemplate.pt +++ b/docs/tutorials/wiki/src/views/tutorial/templates/mytemplate.pt @@ -5,65 +5,72 @@ <meta http-equiv="Content-Type" content="text/html;charset=UTF-8"/> <meta name="keywords" content="python web application" /> <meta name="description" content="pyramid web application" /> - <link rel="shortcut icon" href="${request.application_url}/static/favicon.ico" /> - <link rel="stylesheet" href="${request.application_url}/static/pylons.css" type="text/css" media="screen" charset="utf-8" /> + <link rel="shortcut icon" href="${request.static_url('tutorial:static/favicon.ico')}" /> + <link rel="stylesheet" href="${request.static_url('tutorial:static/pylons.css')}" type="text/css" media="screen" charset="utf-8" /> + <link rel="stylesheet" href="http://fonts.googleapis.com/css?family=Neuton&subset=latin" type="text/css" media="screen" charset="utf-8" /> <link rel="stylesheet" href="http://fonts.googleapis.com/css?family=Nobile:regular,italic,bold,bolditalic&subset=latin" type="text/css" media="screen" charset="utf-8" /> + <!--[if lte IE 6]> + <link rel="stylesheet" href="${request.static_url('tutorial:static/ie6.css')}" type="text/css" media="screen" charset="utf-8" /> + <![endif]--> </head> <body> - <div id="header"> - <div class="header">The Pyramid Web Application Development Framework</div> - </div> - <div id="top"> - <div class="top align-center"> - <img src="${request.application_url}/static/logo.png" width="300" height="80"/> - <p class="app-welcome"> - Welcome to <span class="app-name">${project}</span>, an application generated by<br/> - the Pyramid web application development framework. - </p> + <div id="wrap"> + <div id="top"> + <div class="top align-center"> + <div><img src="${request.static_url('tutorial:static/pyramid.png')}" width="750" height="169" alt="pyramid"/></div> + </div> </div> - </div> - <div id="bottom"> - <div class="bottom"> - <div id="left" class="align-right"> - <h3>Search Pyramid documentation</h3> - <form method="get" action="http://docs.pylonshq.com/pyramid/dev/search.html"> - <input type="text" id="q" name="q" value="" /> - <input type="submit" id="x" value="Search" /> - </form> + <div id="middle"> + <div class="middle align-center"> + <p class="app-welcome"> + Welcome to <span class="app-name">${project}</span>, an application generated by<br/> + the Pyramid web application development framework. + </p> </div> - <div id="right" class="align-left"> - <h3>Pyramid links</h3> - <ul class="links"> - <li> - <a href="http://pylonshq.com">Pylons Website</a> - </li> - <li> - <a href="http://docs.pylonshq.com/pyramid/dev/#narrative-documentation">Narrative Documentation</a> - </li> - <li> - <a href="http://docs.pylonshq.com/pyramid/dev/#api-documentation">API Documentation</a> - </li> - <li> - <a href="http://docs.pylonshq.com/pyramid/dev/#tutorials">Tutorials</a> - </li> - <li> - <a href="http://docs.pylonshq.com/pyramid/dev/#change-history">Change History</a> - </li> - <li> - <a href="http://docs.pylonshq.com/pyramid/dev/#sample-applications">Sample Applications</a> - </li> - <li> - <a href="http://docs.pylonshq.com/pyramid/dev/#support-and-development">Support and Development</a> - </li> - <li> - <a href="irc://irc.freenode.net#pyramid">IRC Channel</a> - </li> - </ul> + </div> + <div id="bottom"> + <div class="bottom"> + <div id="left" class="align-right"> + <h2>Search documentation</h2> + <form method="get" action="http://docs.pylonshq.com/pyramid/dev/search.html"> + <input type="text" id="q" name="q" value="" /> + <input type="submit" id="x" value="Go" /> + </form> + </div> + <div id="right" class="align-left"> + <h2>Pyramid links</h2> + <ul class="links"> + <li> + <a href="http://pylonshq.com">Pylons Website</a> + </li> + <li> + <a href="http://docs.pylonshq.com/pyramid/dev/#narrative-documentation">Narrative Documentation</a> + </li> + <li> + <a href="http://docs.pylonshq.com/pyramid/dev/#api-documentation">API Documentation</a> + </li> + <li> + <a href="http://docs.pylonshq.com/pyramid/dev/#tutorials">Tutorials</a> + </li> + <li> + <a href="http://docs.pylonshq.com/pyramid/dev/#change-history">Change History</a> + </li> + <li> + <a href="http://docs.pylonshq.com/pyramid/dev/#sample-applications">Sample Applications</a> + </li> + <li> + <a href="http://docs.pylonshq.com/pyramid/dev/#support-and-development">Support and Development</a> + </li> + <li> + <a href="irc://irc.freenode.net#pyramid">IRC Channel</a> + </li> + </ul> + </div> </div> </div> </div> <div id="footer"> - <div class="footer">© Copyright 2008-2010, Agendaless Consulting.</div> + <div class="footer">© Copyright 2008-2011, Agendaless Consulting.</div> </div> </body> </html>
\ No newline at end of file diff --git a/docs/tutorials/wiki/src/views/tutorial/templates/view.pt b/docs/tutorials/wiki/src/views/tutorial/templates/view.pt index 50719f9e9..f676c1d25 100644 --- a/docs/tutorials/wiki/src/views/tutorial/templates/view.pt +++ b/docs/tutorials/wiki/src/views/tutorial/templates/view.pt @@ -1,29 +1,51 @@ -<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" - "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"> -<html - xmlns="http://www.w3.org/1999/xhtml" - xmlns:tal="http://xml.zope.org/namespaces/tal"> - +<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd"> +<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en" xmlns:tal="http://xml.zope.org/namespaces/tal"> <head> - <meta content="text/html; charset=utf-8" http-equiv="Content-Type"/> - <title>${page.__name__} - Pyramid tutorial wiki - (based on TurboGears 20-Minute Wiki) - </title> - <link rel="stylesheet" type="text/css" - href="${request.application_url}/static/style.css" /> + <title>${page.__name__} - Pyramid tutorial wiki (based on TurboGears 20-Minute Wiki)</title> + <meta http-equiv="Content-Type" content="text/html;charset=UTF-8"/> + <meta name="keywords" content="python web application" /> + <meta name="description" content="pyramid web application" /> + <link rel="shortcut icon" href="${request.static_url('tutorial:static/favicon.ico')}" /> + <link rel="stylesheet" href="${request.static_url('tutorial:static/pylons.css')}" type="text/css" media="screen" charset="utf-8" /> + <link rel="stylesheet" href="http://fonts.googleapis.com/css?family=Neuton&subset=latin" type="text/css" media="screen" charset="utf-8" /> + <link rel="stylesheet" href="http://fonts.googleapis.com/css?family=Nobile:regular,italic,bold,bolditalic&subset=latin" type="text/css" media="screen" charset="utf-8" /> + <!--[if lte IE 6]> + <link rel="stylesheet" href="${request.static_url('tutorial:static/ie6.css')}" type="text/css" media="screen" charset="utf-8" /> + <![endif]--> </head> - <body> - -<div class="main_content"> -<div style="float:right; width: 10em;"> Viewing -<span tal:replace="page.__name__">Page Name Goes Here</span> <br/> -You can return to the -<a href="${request.application_url}">FrontPage</a>. -</div> - -<div tal:replace="structure content">Page text goes here.</div> -<p><a tal:attributes="href edit_url" href="">Edit this page</a></p> -</div> - -</body></html> + <div id="wrap"> + <div id="top-small"> + <div class="top-small align-center"> + <div> + <img src="${request.static_url('tutorial:static/pyramid-small.png')}" width="220" height="50" alt="pyramid" /> + </div> + </div> + </div> + <div id="middle"> + <div class="middle align-right"> + <div id="left" class="app-welcome align-left"> + Viewing <b><span tal:replace="page.__name__">Page Name Goes Here</span></b><br/> + You can return to the <a href="${request.application_url}">FrontPage</a>.<br/> + </div> + <div id="right" class="app-welcome align-right"></div> + </div> + </div> + <div id="bottom"> + <div class="bottom"> + <div tal:replace="structure content"> + Page text goes here. + </div> + <p> + <a tal:attributes="href edit_url" href=""> + Edit this page + </a> + </p> + </div> + </div> + </div> + <div id="footer"> + <div class="footer">© Copyright 2008-2011, Agendaless Consulting.</div> + </div> +</body> +</html>
\ No newline at end of file diff --git a/docs/tutorials/wiki2/authorization.rst b/docs/tutorials/wiki2/authorization.rst index 8d30ab807..5b07fe788 100644 --- a/docs/tutorials/wiki2/authorization.rst +++ b/docs/tutorials/wiki2/authorization.rst @@ -202,7 +202,6 @@ Add a ``login.pt`` template to your templates directory. It's referred to within the login view we just added to ``login.py``. .. literalinclude:: src/authorization/tutorial/templates/login.pt - :linenos: :language: xml Change ``view.pt`` and ``edit.pt`` @@ -212,11 +211,10 @@ We'll also need to change our ``edit.pt`` and ``view.pt`` templates to display a "Logout" link if someone is logged in. This link will invoke the logout view. -To do so we'll add this to both templates within the ``<div -class="main_content">`` div: +To do so we'll add this to both templates within the ``<div id="right" +class="app-welcome align-right">`` div: .. code-block:: xml - :linenos: <span tal:condition="logged_in"> <a href="${request.application_url}/logout">Logout</a> @@ -261,13 +259,11 @@ Our ``views.py`` module will look something like this when we're done: Our ``edit.pt`` template will look something like this when we're done: .. literalinclude:: src/authorization/tutorial/templates/edit.pt - :linenos: :language: xml Our ``view.pt`` template will look something like this when we're done: .. literalinclude:: src/authorization/tutorial/templates/view.pt - :linenos: :language: xml Revisiting the Application diff --git a/docs/tutorials/wiki2/definingviews.rst b/docs/tutorials/wiki2/definingviews.rst index e3d611136..d4417ed0b 100644 --- a/docs/tutorials/wiki2/definingviews.rst +++ b/docs/tutorials/wiki2/definingviews.rst @@ -212,7 +212,6 @@ Once we're done with the ``view.pt`` template, it will look a lot like the below: .. literalinclude:: src/views/tutorial/templates/view.pt - :linenos: :language: xml .. note:: The names available for our use in a template are always @@ -240,25 +239,24 @@ Once we're done with the ``edit.pt`` template, it will look a lot like the below: .. literalinclude:: src/views/tutorial/templates/edit.pt - :linenos: :language: xml -Static Resources ----------------- - -Our templates name a single static resource named ``style.css``. We need to -create this and place it in a file named ``style.css`` within our package's -``static`` directory. This file is a little too long to replicate within the -body of this guide, however it is available `online -<http://github.com/Pylons/pyramid/blob/master/docs/tutorials/wiki2/src/views/tutorial/static/style.css>`_. +Static Assets +------------- +Our templates name a single static asset named ``pylons.css``. We don't need +to create this file within our package's ``static`` directory because it was +provided at the time we created the project. This file is a little too long to +replicate within the body of this guide, however it is available `online +<http://github.com/Pylons/pyramid/blob/master/docs/tutorials/wiki2/src/views/tutorial/static/pylons.css>`_. This CSS file will be accessed via -e.g. ``http://localhost:6543/static/style.css`` by virtue of the call we've -made to :meth:`pyramid.config.Configurator.add_static_view` within our -``__init__.py`` file. Any number and type of static resources can be placed -in this directory (or subdirectories) and are just referred to by URL within -templates. +e.g. ``http://localhost:6543/static/pylons.css`` by virtue of the call to +``add_static_view`` directive we've made in the ``__init__`` file. Any +number and type of static assets can be placed in this directory (or +subdirectories) and are just referred to by URL or by using the convenience +method ``static_url`` e.g. ``request.static_url('{{package}}:static/foo.css')`` +within templates. Mapping Views to URLs in ``__init__.py`` ======================================== diff --git a/docs/tutorials/wiki2/distributing.rst b/docs/tutorials/wiki2/distributing.rst index f4421e145..9f5db19ae 100644 --- a/docs/tutorials/wiki2/distributing.rst +++ b/docs/tutorials/wiki2/distributing.rst @@ -18,7 +18,7 @@ On Windows: .. code-block:: text - c:\bigfntut> ..\Scripts\python setup.py sdist + c:\pyramidtut> ..\Scripts\python setup.py sdist .. warning:: If your project files are not checked in to a version control repository (such as Subversion), the dist tarball will diff --git a/docs/tutorials/wiki2/installation.rst b/docs/tutorials/wiki2/installation.rst index e6fd5e6b9..c957f641e 100644 --- a/docs/tutorials/wiki2/installation.rst +++ b/docs/tutorials/wiki2/installation.rst @@ -45,13 +45,13 @@ Preparation, UNIX .. code-block:: text - $ path/to/my/Python-2.6/bin/virtualenv --no-site-packages bigfntut + $ path/to/my/Python-2.6/bin/virtualenv --no-site-packages pyramidtut -#. Switch to the ``bigfntut`` directory: +#. Switch to the ``pyramidtut`` directory: .. code-block:: text - $ cd bigfntut + $ cd pyramidtut #. (Optional) Consider using ``source bin/activate`` to make your shell environment wired to use the virtualenv. @@ -96,13 +96,13 @@ Preparation, Windows .. code-block:: text - c:\> c:\Python26\Scripts\virtualenv --no-site-packages bigfntut + c:\> c:\Python26\Scripts\virtualenv --no-site-packages pyramidtut -#. Switch to the ``bigfntut`` directory: +#. Switch to the ``pyramidtut`` directory: .. code-block:: text - c:\> cd bigfntut + c:\> cd pyramidtut #. (Optional) Consider using ``bin\activate.bat`` to make your shell environment wired to use the virtualenv. @@ -112,13 +112,13 @@ Preparation, Windows .. code-block:: text - c:\bigfntut> Scripts\easy_install pyramid + c:\pyramidtut> Scripts\easy_install pyramid #. Use ``easy_install`` to install various packages from PyPI. .. code-block:: text - c:\bigfntut> Scripts\easy_install -i docutils \ + c:\pyramidtut> Scripts\easy_install -i docutils \ nose coverage zope.sqlalchemy SQLAlchemy repoze.tm2 @@ -133,7 +133,7 @@ variety of templates to generate sample projects. We will use the that uses :term:`SQLAlchemy` and :term:`URL dispatch`. The below instructions assume your current working directory is the -"virtualenv" named "bigfntut". +"virtualenv" named "pyramidtut". On UNIX: @@ -145,7 +145,7 @@ On Windows: .. code-block:: text - c:\bigfntut> Scripts\paster create -t pyramid_routesalchemy tutorial + c:\pyramidtut> Scripts\paster create -t pyramid_routesalchemy tutorial .. note:: If you are using Windows, the ``pyramid_routesalchemy`` Paster template may not deal gracefully with installation into a @@ -173,8 +173,8 @@ On Windows: .. code-block:: text - c:\bigfntut> cd tutorial - c:\bigfntut\tutorial> ..\Scripts\python setup.py develop + c:\pyramidtut> cd tutorial + c:\pyramidtut\tutorial> ..\Scripts\python setup.py develop .. _sql_running_tests: @@ -194,7 +194,7 @@ On Windows: .. code-block:: text - c:\bigfntut\tutorial> ..\Scripts\python setup.py test -q + c:\pyramidtut\tutorial> ..\Scripts\python setup.py test -q Starting the Application ======================== @@ -211,7 +211,7 @@ On Windows: .. code-block:: text - c:\bifgfntut\tutorial> ..\Scripts\paster serve development.ini --reload + c:\pyramidtut\tutorial> ..\Scripts\paster serve development.ini --reload Exposing Test Coverage Information ================================== @@ -235,7 +235,7 @@ On Windows: .. code-block:: text - c:\bigfntut\tutorial> ..\Scripts\easy_install nose coverage + c:\pyramidtut\tutorial> ..\Scripts\easy_install nose coverage Once ``nose`` and ``coverage`` are installed, we can actually run the coverage tests. @@ -250,7 +250,7 @@ On Windows: .. code-block:: text - c:\bigfntut\tutorial> ..\Scripts\nosetests --cover-package=tutorial \ + c:\pyramidtut\tutorial> ..\Scripts\nosetests --cover-package=tutorial \ --cover-erase --with-coverage Looks like our package's ``models`` module doesn't quite have 100% diff --git a/docs/tutorials/wiki2/src/authorization/tutorial/static/footerbg.png b/docs/tutorials/wiki2/src/authorization/tutorial/static/footerbg.png Binary files differnew file mode 100644 index 000000000..1fbc873da --- /dev/null +++ b/docs/tutorials/wiki2/src/authorization/tutorial/static/footerbg.png diff --git a/docs/tutorials/wiki2/src/authorization/tutorial/static/headerbg.png b/docs/tutorials/wiki2/src/authorization/tutorial/static/headerbg.png Binary files differnew file mode 100644 index 000000000..0596f2020 --- /dev/null +++ b/docs/tutorials/wiki2/src/authorization/tutorial/static/headerbg.png diff --git a/docs/tutorials/wiki2/src/authorization/tutorial/static/ie6.css b/docs/tutorials/wiki2/src/authorization/tutorial/static/ie6.css new file mode 100644 index 000000000..b7c8493d8 --- /dev/null +++ b/docs/tutorials/wiki2/src/authorization/tutorial/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/docs/tutorials/wiki2/src/authorization/tutorial/static/logo.png b/docs/tutorials/wiki2/src/authorization/tutorial/static/logo.png Binary files differdeleted file mode 100644 index 88f5d9865..000000000 --- a/docs/tutorials/wiki2/src/authorization/tutorial/static/logo.png +++ /dev/null diff --git a/docs/tutorials/wiki2/src/authorization/tutorial/static/middlebg.png b/docs/tutorials/wiki2/src/authorization/tutorial/static/middlebg.png Binary files differnew file mode 100644 index 000000000..2369cfb7d --- /dev/null +++ b/docs/tutorials/wiki2/src/authorization/tutorial/static/middlebg.png diff --git a/docs/tutorials/wiki2/src/authorization/tutorial/static/pylons.css b/docs/tutorials/wiki2/src/authorization/tutorial/static/pylons.css index c153be07f..fd1914d8d 100644 --- a/docs/tutorials/wiki2/src/authorization/tutorial/static/pylons.css +++ b/docs/tutorials/wiki2/src/authorization/tutorial/static/pylons.css @@ -4,34 +4,23 @@ body{line-height:1;} ol,ul{list-style:none;} blockquote,q{quotes:none;} blockquote:before,blockquote:after,q:before,q:after{content:'';content:none;} -/* remember to define focus styles! */ :focus{outline:0;} -/* remember to highlight inserts somehow! */ ins{text-decoration:none;} del{text-decoration:line-through;} -/* tables still need 'cellspacing="0"' in the markup */ table{border-collapse:collapse;border-spacing:0;} -/* restyling */ sub{vertical-align:sub;font-size:smaller;line-height:normal;} sup{vertical-align:super;font-size:smaller;line-height:normal;} -/* lists */ ul,menu,dir{display:block;list-style-type:disc;margin:1em 0;padding-left:40px;} ol{display:block;list-style-type:decimal-leading-zero;margin:1em 0;padding-left:40px;} li{display:list-item;} -/* nested lists have no top/bottom margins */ ul ul,ul ol,ul dir,ul menu,ul dl,ol ul,ol ol,ol dir,ol menu,ol dl,dir ul,dir ol,dir dir,dir menu,dir dl,menu ul,menu ol,menu dir,menu menu,menu dl,dl ul,dl ol,dl dir,dl menu,dl dl{margin-top:0;margin-bottom:0;} -/* 2 deep unordered lists use a circle */ ol ul,ul ul,menu ul,dir ul,ol menu,ul menu,menu menu,dir menu,ol dir,ul dir,menu dir,dir dir{list-style-type:circle;} -/* 3 deep (or more) unordered lists use a square */ ol ol ul,ol ul ul,ol menu ul,ol dir ul,ol ol menu,ol ul menu,ol menu menu,ol dir menu,ol ol dir,ol ul dir,ol menu dir,ol dir dir,ul ol ul,ul ul ul,ul menu ul,ul dir ul,ul ol menu,ul ul menu,ul menu menu,ul dir menu,ul ol dir,ul ul dir,ul menu dir,ul dir dir,menu ol ul,menu ul ul,menu menu ul,menu dir ul,menu ol menu,menu ul menu,menu menu menu,menu dir menu,menu ol dir,menu ul dir,menu menu dir,menu dir dir,dir ol ul,dir ul ul,dir menu ul,dir dir ul,dir ol menu,dir ul menu,dir menu menu,dir dir menu,dir ol dir,dir ul dir,dir menu dir,dir dir dir{list-style-type:square;} .hidden{display:none;} p{line-height:1.5em;} -h1{font-size:1.75em;/* 28px */ -line-height:1.7em;font-family:helvetica,verdana;} -h2{font-size:1.5em;/* 24px */ -line-height:1.7em;font-family:helvetica,verdana;} -h3{font-size:1.25em;/* 20px */ -line-height:1.7em;font-family:helvetica,verdana;} +h1{font-size:1.75em;line-height:1.7em;font-family:helvetica,verdana;} +h2{font-size:1.5em;line-height:1.7em;font-family:helvetica,verdana;} +h3{font-size:1.25em;line-height:1.7em;font-family:helvetica,verdana;} h4{font-size:1em;line-height:1.7em;font-family:helvetica,verdana;} html,body{width:100%;height:100%;} body{margin:0;padding:0;background-color:#ffffff;position:relative;font:16px/24px "Nobile","Lucida Grande",Lucida,Verdana,sans-serif;} @@ -42,23 +31,26 @@ 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,#top-small,#bottom{width:100%;} +#top{color:#000000;height:230px;background:#ffffff url(headerbg.png) repeat-x 0 top;position:relative;} +#top-small{color:#000000;height:60px;background:#ffffff url(headerbg.png) repeat-x 0 top;position:relative;} +#bottom{color:#222;background-color:#ffffff;} +.top,.top-small,.middle,.bottom{width:750px;margin-right:auto;margin-left:auto;} +.top{padding-top:40px;} +.top-small{padding-top:10px;} +#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 +59,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],input[type=password]{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/docs/tutorials/wiki2/src/authorization/tutorial/static/pyramid-small.png b/docs/tutorials/wiki2/src/authorization/tutorial/static/pyramid-small.png Binary files differnew file mode 100644 index 000000000..a5bc0ade7 --- /dev/null +++ b/docs/tutorials/wiki2/src/authorization/tutorial/static/pyramid-small.png diff --git a/docs/tutorials/wiki2/src/authorization/tutorial/static/pyramid.png b/docs/tutorials/wiki2/src/authorization/tutorial/static/pyramid.png Binary files differnew file mode 100644 index 000000000..347e05549 --- /dev/null +++ b/docs/tutorials/wiki2/src/authorization/tutorial/static/pyramid.png diff --git a/docs/tutorials/wiki2/src/authorization/tutorial/static/style.css b/docs/tutorials/wiki2/src/authorization/tutorial/static/style.css deleted file mode 100644 index cad87e0d4..000000000 --- a/docs/tutorials/wiki2/src/authorization/tutorial/static/style.css +++ /dev/null @@ -1,109 +0,0 @@ -html, body { - color: black; - background-color: #ddd; - font: x-small "Lucida Grande", "Lucida Sans Unicode", geneva, sans-serif; - margin: 0; - padding: 0; -} - -td, th {padding:3px;border:none;} -tr th {text-align:left;background-color:#f0f0f0;color:#333;} -tr.odd td {background-color:#edf3fe;} -tr.even td {background-color:#fff;} - -#header { - height: 80px; - width: 777px; - background: blue URL('../images/header_inner.png') no-repeat; - border-left: 1px solid #aaa; - border-right: 1px solid #aaa; - margin: 0 auto 0 auto; -} - -a.link, a, a.active { - color: #369; -} - - -#main_content { - color: black; - font-size: 127%; - background-color: white; - width: 757px; - margin: 0 auto 0 auto; - border-left: 1px solid #aaa; - border-right: 1px solid #aaa; - padding: 10px; -} - -#sidebar { - border: 1px solid #aaa; - background-color: #eee; - margin: 0.5em; - padding: 1em; - float: right; - width: 200px; - font-size: 88%; -} - -#sidebar h2 { - margin-top: 0; -} - -#sidebar ul { - margin-left: 1.5em; - padding-left: 0; -} - -h1,h2,h3,h4,h5,h6,#getting_started_steps { - font-family: "Century Schoolbook L", Georgia, serif; - font-weight: bold; -} - -h2 { - font-size: 150%; -} - -#footer { - border: 1px solid #aaa; - border-top: 0px none; - color: #999; - background-color: white; - padding: 10px; - font-size: 80%; - text-align: center; - width: 757px; - margin: 0 auto 1em auto; -} - -.code { - font-family: monospace; -} - -span.code { - font-weight: bold; - background: #eee; -} - -#status_block { - margin: 0 auto 0.5em auto; - padding: 15px 10px 15px 55px; - background: #cec URL('../images/ok.png') left center no-repeat; - border: 1px solid #9c9; - width: 450px; - font-size: 120%; - font-weight: bolder; -} - -.notice { - margin: 0.5em auto 0.5em auto; - padding: 15px 10px 15px 55px; - width: 450px; - background: #eef URL('../images/info.png') left center no-repeat; - border: 1px solid #cce; -} - -.fielderror { - color: red; - font-weight: bold; -} diff --git a/docs/tutorials/wiki2/src/authorization/tutorial/static/transparent.gif b/docs/tutorials/wiki2/src/authorization/tutorial/static/transparent.gif Binary files differnew file mode 100644 index 000000000..0341802e5 --- /dev/null +++ b/docs/tutorials/wiki2/src/authorization/tutorial/static/transparent.gif diff --git a/docs/tutorials/wiki2/src/authorization/tutorial/templates/edit.pt b/docs/tutorials/wiki2/src/authorization/tutorial/templates/edit.pt index 05e2ecd76..e8c59eb10 100644 --- a/docs/tutorials/wiki2/src/authorization/tutorial/templates/edit.pt +++ b/docs/tutorials/wiki2/src/authorization/tutorial/templates/edit.pt @@ -1,35 +1,51 @@ -<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" - "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"> -<html - xmlns="http://www.w3.org/1999/xhtml" - xmlns:tal="http://xml.zope.org/namespaces/tal"> - +<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd"> +<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en" xmlns:tal="http://xml.zope.org/namespaces/tal"> <head> - <meta content="text/html; charset=utf-8" http-equiv="Content-Type"/> - <title>Pyramid tutorial wiki (based on TurboGears 20-Minute Wiki) - Editing: ${page.name}</title> - <link rel="stylesheet" type="text/css" - href="${request.application_url}/static/style.css" /> + <title>${page.name} - Pyramid tutorial wiki (based on TurboGears 20-Minute Wiki)</title> + <meta http-equiv="Content-Type" content="text/html;charset=UTF-8"/> + <meta name="keywords" content="python web application" /> + <meta name="description" content="pyramid web application" /> + <link rel="shortcut icon" href="${request.static_url('tutorial:static/favicon.ico')}" /> + <link rel="stylesheet" href="${request.static_url('tutorial:static/pylons.css')}" type="text/css" media="screen" charset="utf-8" /> + <link rel="stylesheet" href="http://fonts.googleapis.com/css?family=Neuton&subset=latin" type="text/css" media="screen" charset="utf-8" /> + <link rel="stylesheet" href="http://fonts.googleapis.com/css?family=Nobile:regular,italic,bold,bolditalic&subset=latin" type="text/css" media="screen" charset="utf-8" /> + <!--[if lte IE 6]> + <link rel="stylesheet" href="${request.static_url('tutorial:static/ie6.css')}" type="text/css" media="screen" charset="utf-8" /> + <![endif]--> </head> - <body> - -<div class="main_content"> - <div style="float:right; width: 10em;"> Viewing - <span tal:replace="page.name">Page Name Goes Here</span> <br/> - You can return to the <a href="${request.application_url}" - >FrontPage</a>. - <span tal:condition="logged_in"> - <a href="${request.application_url}/logout">Logout</a> - </span> - </div> - - <div> - <form action="${save_url}" method="post"> - <textarea name="body" tal:content="page.data" rows="10" cols="60"/> - <input type="submit" name="form.submitted" value="Save"/> - </form> - </div> -</div> + <div id="wrap"> + <div id="top-small"> + <div class="top-small align-center"> + <div> + <img src="${request.static_url('tutorial:static/pyramid-small.png')}" width="220" height="50" alt="pyramid" /> + </div> + </div> + </div> + <div id="middle"> + <div class="middle align-right"> + <div id="left" class="app-welcome align-left"> + Editing <b><span tal:replace="page.name">Page Name Goes Here</span></b><br/> + You can return to the <a href="${request.application_url}">FrontPage</a>.<br/> + </div> + <div id="right" class="app-welcome align-right"> + <span tal:condition="logged_in"> + <a href="${request.application_url}/logout">Logout</a> + </span> + </div> + </div> + </div> + <div id="bottom"> + <div class="bottom"> + <form action="${save_url}" method="post"> + <textarea name="body" tal:content="page.data" rows="10" cols="60"/><br/> + <input type="submit" name="form.submitted" value="Save"/> + </form> + </div> + </div> + </div> + <div id="footer"> + <div class="footer">© Copyright 2008-2011, Agendaless Consulting.</div> + </div> </body> -</html> +</html>
\ No newline at end of file diff --git a/docs/tutorials/wiki2/src/authorization/tutorial/templates/login.pt b/docs/tutorials/wiki2/src/authorization/tutorial/templates/login.pt index c56983d64..974e22f37 100644 --- a/docs/tutorials/wiki2/src/authorization/tutorial/templates/login.pt +++ b/docs/tutorials/wiki2/src/authorization/tutorial/templates/login.pt @@ -1,32 +1,49 @@ -<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" - "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"> -<html - xmlns="http://www.w3.org/1999/xhtml" - xmlns:tal="http://xml.zope.org/namespaces/tal"> - +<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd"> +<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en" xmlns:tal="http://xml.zope.org/namespaces/tal"> <head> - <meta content="text/html; charset=utf-8" http-equiv="Content-Type"/> - <title>Pyramid tutorial wiki (based on TurboGears 20-Minute Wiki)</title> - <link rel="stylesheet" type="text/css" - href="${request.application_url}/static/style.css" /> + <title>Login - Pyramid tutorial wiki (based on TurboGears 20-Minute Wiki)</title> + <meta http-equiv="Content-Type" content="text/html;charset=UTF-8"/> + <meta name="keywords" content="python web application" /> + <meta name="description" content="pyramid web application" /> + <link rel="shortcut icon" href="${request.static_url('tutorial:static/favicon.ico')}" /> + <link rel="stylesheet" href="${request.static_url('tutorial:static/pylons.css')}" type="text/css" media="screen" charset="utf-8" /> + <link rel="stylesheet" href="http://fonts.googleapis.com/css?family=Neuton&subset=latin" type="text/css" media="screen" charset="utf-8" /> + <link rel="stylesheet" href="http://fonts.googleapis.com/css?family=Nobile:regular,italic,bold,bolditalic&subset=latin" type="text/css" media="screen" charset="utf-8" /> + <!--[if lte IE 6]> + <link rel="stylesheet" href="${request.static_url('tutorial:static/ie6.css')}" type="text/css" media="screen" charset="utf-8" /> + <![endif]--> </head> - <body> - -<h1>Log In</h1> - -<div tal:replace="message"/> - -<div class="main_content"> - <form action="${url}" method="post"> - <input type="hidden" name="came_from" value="${came_from}"/> - <input type="text" name="login" value="${login}"/> - <br/> - <input type="password" name="password" value="${password}"/> - <br/> - <input type="submit" name="form.submitted" value="Log In"/> - </form> -</div> - + <div id="wrap"> + <div id="top-small"> + <div class="top-small align-center"> + <div> + <img src="${request.static_url('tutorial:static/pyramid-small.png')}" width="220" height="50" alt="pyramid" /> + </div> + </div> + </div> + <div id="middle"> + <div class="middle align-right"> + <div id="left" class="app-welcome align-left"> + <b>Login</b><br/> + <span tal:replace="message"/> + </div> + <div id="right" class="app-welcome align-right"></div> + </div> + </div> + <div id="bottom"> + <div class="bottom"> + <form action="${url}" method="post"> + <input type="hidden" name="came_from" value="${came_from}"/> + <input type="text" name="login" value="${login}"/><br/> + <input type="password" name="password" value="${password}"/><br/> + <input type="submit" name="form.submitted" value="Log In"/> + </form> + </div> + </div> + </div> + <div id="footer"> + <div class="footer">© Copyright 2008-2011, Agendaless Consulting.</div> + </div> </body> -</html> +</html>
\ No newline at end of file diff --git a/docs/tutorials/wiki2/src/authorization/tutorial/templates/mytemplate.pt b/docs/tutorials/wiki2/src/authorization/tutorial/templates/mytemplate.pt index 6ad23d44f..cac9ccaa7 100644 --- a/docs/tutorials/wiki2/src/authorization/tutorial/templates/mytemplate.pt +++ b/docs/tutorials/wiki2/src/authorization/tutorial/templates/mytemplate.pt @@ -5,23 +5,23 @@ <meta http-equiv="Content-Type" content="text/html;charset=UTF-8"/> <meta name="keywords" content="python web application" /> <meta name="description" content="pyramid web application" /> - <link rel="shortcut icon" href="${request.application_url}/static/favicon.ico" /> - <link rel="stylesheet" href="${request.application_url}/static/pylons.css" type="text/css" media="screen" charset="utf-8" /> + <link rel="shortcut icon" href="${request.static_url('tutorial:static/favicon.ico')}" /> + <link rel="stylesheet" href="${request.static_url('tutorial:static/pylons.css')}" type="text/css" media="screen" charset="utf-8" /> + <link rel="stylesheet" href="http://fonts.googleapis.com/css?family=Neuton&subset=latin" type="text/css" media="screen" charset="utf-8" /> <link rel="stylesheet" href="http://fonts.googleapis.com/css?family=Nobile:regular,italic,bold,bolditalic&subset=latin" type="text/css" media="screen" charset="utf-8" /> - <!--[if !IE 7]> - <style type="text/css"> - #wrap {display:table;height:100%} - </style> + <!--[if lte IE 6]> + <link rel="stylesheet" href="${request.static_url('tutorial:static/ie6.css')}" type="text/css" media="screen" charset="utf-8" /> <![endif]--> </head> <body> <div id="wrap"> - <div id="header"> - <div class="header">The Pyramid Web Application Development Framework</div> - </div> <div id="top"> <div class="top align-center"> - <img src="${request.application_url}/static/logo.png" width="300" height="80"/> + <div><img src="${request.static_url('tutorial:static/pyramid.png')}" width="750" height="169" alt="pyramid"/></div> + </div> + </div> + <div id="middle"> + <div class="middle align-center"> <p class="app-welcome"> Welcome to <span class="app-name">${project}</span>, an application generated by<br/> the Pyramid web application development framework. @@ -31,22 +31,19 @@ <div id="bottom"> <div class="bottom"> <div id="left" class="align-right"> - <h3>Search Pyramid documentation</h3> + <h2>Search documentation</h2> <form method="get" action="http://docs.pylonshq.com/pyramid/dev/search.html"> <input type="text" id="q" name="q" value="" /> - <input type="submit" id="x" value="Search" /> + <input type="submit" id="x" value="Go" /> </form> </div> <div id="right" class="align-left"> - <h3>Pyramid links</h3> + <h2>Pyramid links</h2> <ul class="links"> <li> <a href="http://pylonshq.com">Pylons Website</a> </li> <li> - <a href="http://docs.pylonshq.com/">The Pylons Project Documentation</a> - </li> - <li> <a href="http://docs.pylonshq.com/pyramid/dev/#narrative-documentation">Narrative Documentation</a> </li> <li> @@ -73,7 +70,7 @@ </div> </div> <div id="footer"> - <div class="footer">© Copyright 2008-2010, Agendaless Consulting.</div> + <div class="footer">© Copyright 2008-2011, Agendaless Consulting.</div> </div> </body> </html>
\ No newline at end of file diff --git a/docs/tutorials/wiki2/src/authorization/tutorial/templates/view.pt b/docs/tutorials/wiki2/src/authorization/tutorial/templates/view.pt index 0c654250a..d0360429c 100644 --- a/docs/tutorials/wiki2/src/authorization/tutorial/templates/view.pt +++ b/docs/tutorials/wiki2/src/authorization/tutorial/templates/view.pt @@ -1,31 +1,55 @@ -<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" - "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"> -<html - xmlns="http://www.w3.org/1999/xhtml" - xmlns:tal="http://xml.zope.org/namespaces/tal"> - +<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd"> +<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en" xmlns:tal="http://xml.zope.org/namespaces/tal"> <head> - <meta content="text/html; charset=utf-8" http-equiv="Content-Type"/> - <title>${page.name} - Pyramid tutorial wiki - (based on TurboGears 20-Minute Wiki)</title> - <link rel="stylesheet" type="text/css" - href="${request.application_url}/static/style.css" /> + <title>${page.name} - Pyramid tutorial wiki (based on TurboGears 20-Minute Wiki)</title> + <meta http-equiv="Content-Type" content="text/html;charset=UTF-8"/> + <meta name="keywords" content="python web application" /> + <meta name="description" content="pyramid web application" /> + <link rel="shortcut icon" href="${request.static_url('tutorial:static/favicon.ico')}" /> + <link rel="stylesheet" href="${request.static_url('tutorial:static/pylons.css')}" type="text/css" media="screen" charset="utf-8" /> + <link rel="stylesheet" href="http://fonts.googleapis.com/css?family=Neuton&subset=latin" type="text/css" media="screen" charset="utf-8" /> + <link rel="stylesheet" href="http://fonts.googleapis.com/css?family=Nobile:regular,italic,bold,bolditalic&subset=latin" type="text/css" media="screen" charset="utf-8" /> + <!--[if lte IE 6]> + <link rel="stylesheet" href="${request.static_url('tutorial:static/ie6.css')}" type="text/css" media="screen" charset="utf-8" /> + <![endif]--> </head> - <body> - -<div class="main_content"> -<div style="float:right; width: 10em;"> Viewing -<span tal:replace="page.name">Page Name Goes Here</span> <br/> -You can return to the <a href="${request.application_url}">FrontPage</a>. -<span tal:condition="logged_in"> - <a href="${request.application_url}/logout">Logout</a> -</span> -</div> - -<div tal:replace="structure content">Page text goes here.</div> -<p><a tal:attributes="href edit_url" href="">Edit this page</a></p> -</div> - + <div id="wrap"> + <div id="top-small"> + <div class="top-small align-center"> + <div> + <img src="${request.static_url('tutorial:static/pyramid-small.png')}" width="220" height="50" alt="pyramid" /> + </div> + </div> + </div> + <div id="middle"> + <div class="middle align-right"> + <div id="left" class="app-welcome align-left"> + Viewing <b><span tal:replace="page.name">Page Name Goes Here</span></b><br/> + You can return to the <a href="${request.application_url}">FrontPage</a>.<br/> + </div> + <div id="right" class="app-welcome align-right"> + <span tal:condition="logged_in"> + <a href="${request.application_url}/logout">Logout</a> + </span> + </div> + </div> + </div> + <div id="bottom"> + <div class="bottom"> + <div tal:replace="structure content"> + Page text goes here. + </div> + <p> + <a tal:attributes="href edit_url" href=""> + Edit this page + </a> + </p> + </div> + </div> + </div> + <div id="footer"> + <div class="footer">© Copyright 2008-2011, Agendaless Consulting.</div> + </div> </body> -</html> +</html>
\ No newline at end of file diff --git a/docs/tutorials/wiki2/src/basiclayout/tutorial/static/footerbg.png b/docs/tutorials/wiki2/src/basiclayout/tutorial/static/footerbg.png Binary files differnew file mode 100644 index 000000000..1fbc873da --- /dev/null +++ b/docs/tutorials/wiki2/src/basiclayout/tutorial/static/footerbg.png diff --git a/docs/tutorials/wiki2/src/basiclayout/tutorial/static/headerbg.png b/docs/tutorials/wiki2/src/basiclayout/tutorial/static/headerbg.png Binary files differnew file mode 100644 index 000000000..0596f2020 --- /dev/null +++ b/docs/tutorials/wiki2/src/basiclayout/tutorial/static/headerbg.png diff --git a/docs/tutorials/wiki2/src/basiclayout/tutorial/static/ie6.css b/docs/tutorials/wiki2/src/basiclayout/tutorial/static/ie6.css new file mode 100644 index 000000000..b7c8493d8 --- /dev/null +++ b/docs/tutorials/wiki2/src/basiclayout/tutorial/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/docs/tutorials/wiki2/src/basiclayout/tutorial/static/logo.png b/docs/tutorials/wiki2/src/basiclayout/tutorial/static/logo.png Binary files differdeleted file mode 100644 index 88f5d9865..000000000 --- a/docs/tutorials/wiki2/src/basiclayout/tutorial/static/logo.png +++ /dev/null diff --git a/docs/tutorials/wiki2/src/basiclayout/tutorial/static/middlebg.png b/docs/tutorials/wiki2/src/basiclayout/tutorial/static/middlebg.png Binary files differnew file mode 100644 index 000000000..2369cfb7d --- /dev/null +++ b/docs/tutorials/wiki2/src/basiclayout/tutorial/static/middlebg.png diff --git a/docs/tutorials/wiki2/src/basiclayout/tutorial/static/pylons.css b/docs/tutorials/wiki2/src/basiclayout/tutorial/static/pylons.css index c153be07f..fd1914d8d 100644 --- a/docs/tutorials/wiki2/src/basiclayout/tutorial/static/pylons.css +++ b/docs/tutorials/wiki2/src/basiclayout/tutorial/static/pylons.css @@ -4,34 +4,23 @@ body{line-height:1;} ol,ul{list-style:none;} blockquote,q{quotes:none;} blockquote:before,blockquote:after,q:before,q:after{content:'';content:none;} -/* remember to define focus styles! */ :focus{outline:0;} -/* remember to highlight inserts somehow! */ ins{text-decoration:none;} del{text-decoration:line-through;} -/* tables still need 'cellspacing="0"' in the markup */ table{border-collapse:collapse;border-spacing:0;} -/* restyling */ sub{vertical-align:sub;font-size:smaller;line-height:normal;} sup{vertical-align:super;font-size:smaller;line-height:normal;} -/* lists */ ul,menu,dir{display:block;list-style-type:disc;margin:1em 0;padding-left:40px;} ol{display:block;list-style-type:decimal-leading-zero;margin:1em 0;padding-left:40px;} li{display:list-item;} -/* nested lists have no top/bottom margins */ ul ul,ul ol,ul dir,ul menu,ul dl,ol ul,ol ol,ol dir,ol menu,ol dl,dir ul,dir ol,dir dir,dir menu,dir dl,menu ul,menu ol,menu dir,menu menu,menu dl,dl ul,dl ol,dl dir,dl menu,dl dl{margin-top:0;margin-bottom:0;} -/* 2 deep unordered lists use a circle */ ol ul,ul ul,menu ul,dir ul,ol menu,ul menu,menu menu,dir menu,ol dir,ul dir,menu dir,dir dir{list-style-type:circle;} -/* 3 deep (or more) unordered lists use a square */ ol ol ul,ol ul ul,ol menu ul,ol dir ul,ol ol menu,ol ul menu,ol menu menu,ol dir menu,ol ol dir,ol ul dir,ol menu dir,ol dir dir,ul ol ul,ul ul ul,ul menu ul,ul dir ul,ul ol menu,ul ul menu,ul menu menu,ul dir menu,ul ol dir,ul ul dir,ul menu dir,ul dir dir,menu ol ul,menu ul ul,menu menu ul,menu dir ul,menu ol menu,menu ul menu,menu menu menu,menu dir menu,menu ol dir,menu ul dir,menu menu dir,menu dir dir,dir ol ul,dir ul ul,dir menu ul,dir dir ul,dir ol menu,dir ul menu,dir menu menu,dir dir menu,dir ol dir,dir ul dir,dir menu dir,dir dir dir{list-style-type:square;} .hidden{display:none;} p{line-height:1.5em;} -h1{font-size:1.75em;/* 28px */ -line-height:1.7em;font-family:helvetica,verdana;} -h2{font-size:1.5em;/* 24px */ -line-height:1.7em;font-family:helvetica,verdana;} -h3{font-size:1.25em;/* 20px */ -line-height:1.7em;font-family:helvetica,verdana;} +h1{font-size:1.75em;line-height:1.7em;font-family:helvetica,verdana;} +h2{font-size:1.5em;line-height:1.7em;font-family:helvetica,verdana;} +h3{font-size:1.25em;line-height:1.7em;font-family:helvetica,verdana;} h4{font-size:1em;line-height:1.7em;font-family:helvetica,verdana;} html,body{width:100%;height:100%;} body{margin:0;padding:0;background-color:#ffffff;position:relative;font:16px/24px "Nobile","Lucida Grande",Lucida,Verdana,sans-serif;} @@ -42,23 +31,26 @@ 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,#top-small,#bottom{width:100%;} +#top{color:#000000;height:230px;background:#ffffff url(headerbg.png) repeat-x 0 top;position:relative;} +#top-small{color:#000000;height:60px;background:#ffffff url(headerbg.png) repeat-x 0 top;position:relative;} +#bottom{color:#222;background-color:#ffffff;} +.top,.top-small,.middle,.bottom{width:750px;margin-right:auto;margin-left:auto;} +.top{padding-top:40px;} +.top-small{padding-top:10px;} +#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 +59,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],input[type=password]{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/docs/tutorials/wiki2/src/basiclayout/tutorial/static/pyramid-small.png b/docs/tutorials/wiki2/src/basiclayout/tutorial/static/pyramid-small.png Binary files differnew file mode 100644 index 000000000..a5bc0ade7 --- /dev/null +++ b/docs/tutorials/wiki2/src/basiclayout/tutorial/static/pyramid-small.png diff --git a/docs/tutorials/wiki2/src/basiclayout/tutorial/static/pyramid.png b/docs/tutorials/wiki2/src/basiclayout/tutorial/static/pyramid.png Binary files differnew file mode 100644 index 000000000..347e05549 --- /dev/null +++ b/docs/tutorials/wiki2/src/basiclayout/tutorial/static/pyramid.png diff --git a/docs/tutorials/wiki2/src/basiclayout/tutorial/static/transparent.gif b/docs/tutorials/wiki2/src/basiclayout/tutorial/static/transparent.gif Binary files differnew file mode 100644 index 000000000..0341802e5 --- /dev/null +++ b/docs/tutorials/wiki2/src/basiclayout/tutorial/static/transparent.gif diff --git a/docs/tutorials/wiki2/src/basiclayout/tutorial/templates/mytemplate.pt b/docs/tutorials/wiki2/src/basiclayout/tutorial/templates/mytemplate.pt index 6ad23d44f..cac9ccaa7 100644 --- a/docs/tutorials/wiki2/src/basiclayout/tutorial/templates/mytemplate.pt +++ b/docs/tutorials/wiki2/src/basiclayout/tutorial/templates/mytemplate.pt @@ -5,23 +5,23 @@ <meta http-equiv="Content-Type" content="text/html;charset=UTF-8"/> <meta name="keywords" content="python web application" /> <meta name="description" content="pyramid web application" /> - <link rel="shortcut icon" href="${request.application_url}/static/favicon.ico" /> - <link rel="stylesheet" href="${request.application_url}/static/pylons.css" type="text/css" media="screen" charset="utf-8" /> + <link rel="shortcut icon" href="${request.static_url('tutorial:static/favicon.ico')}" /> + <link rel="stylesheet" href="${request.static_url('tutorial:static/pylons.css')}" type="text/css" media="screen" charset="utf-8" /> + <link rel="stylesheet" href="http://fonts.googleapis.com/css?family=Neuton&subset=latin" type="text/css" media="screen" charset="utf-8" /> <link rel="stylesheet" href="http://fonts.googleapis.com/css?family=Nobile:regular,italic,bold,bolditalic&subset=latin" type="text/css" media="screen" charset="utf-8" /> - <!--[if !IE 7]> - <style type="text/css"> - #wrap {display:table;height:100%} - </style> + <!--[if lte IE 6]> + <link rel="stylesheet" href="${request.static_url('tutorial:static/ie6.css')}" type="text/css" media="screen" charset="utf-8" /> <![endif]--> </head> <body> <div id="wrap"> - <div id="header"> - <div class="header">The Pyramid Web Application Development Framework</div> - </div> <div id="top"> <div class="top align-center"> - <img src="${request.application_url}/static/logo.png" width="300" height="80"/> + <div><img src="${request.static_url('tutorial:static/pyramid.png')}" width="750" height="169" alt="pyramid"/></div> + </div> + </div> + <div id="middle"> + <div class="middle align-center"> <p class="app-welcome"> Welcome to <span class="app-name">${project}</span>, an application generated by<br/> the Pyramid web application development framework. @@ -31,22 +31,19 @@ <div id="bottom"> <div class="bottom"> <div id="left" class="align-right"> - <h3>Search Pyramid documentation</h3> + <h2>Search documentation</h2> <form method="get" action="http://docs.pylonshq.com/pyramid/dev/search.html"> <input type="text" id="q" name="q" value="" /> - <input type="submit" id="x" value="Search" /> + <input type="submit" id="x" value="Go" /> </form> </div> <div id="right" class="align-left"> - <h3>Pyramid links</h3> + <h2>Pyramid links</h2> <ul class="links"> <li> <a href="http://pylonshq.com">Pylons Website</a> </li> <li> - <a href="http://docs.pylonshq.com/">The Pylons Project Documentation</a> - </li> - <li> <a href="http://docs.pylonshq.com/pyramid/dev/#narrative-documentation">Narrative Documentation</a> </li> <li> @@ -73,7 +70,7 @@ </div> </div> <div id="footer"> - <div class="footer">© Copyright 2008-2010, Agendaless Consulting.</div> + <div class="footer">© Copyright 2008-2011, Agendaless Consulting.</div> </div> </body> </html>
\ No newline at end of file diff --git a/docs/tutorials/wiki2/src/models/tutorial/static/footerbg.png b/docs/tutorials/wiki2/src/models/tutorial/static/footerbg.png Binary files differnew file mode 100644 index 000000000..1fbc873da --- /dev/null +++ b/docs/tutorials/wiki2/src/models/tutorial/static/footerbg.png diff --git a/docs/tutorials/wiki2/src/models/tutorial/static/headerbg.png b/docs/tutorials/wiki2/src/models/tutorial/static/headerbg.png Binary files differnew file mode 100644 index 000000000..0596f2020 --- /dev/null +++ b/docs/tutorials/wiki2/src/models/tutorial/static/headerbg.png diff --git a/docs/tutorials/wiki2/src/models/tutorial/static/ie6.css b/docs/tutorials/wiki2/src/models/tutorial/static/ie6.css new file mode 100644 index 000000000..b7c8493d8 --- /dev/null +++ b/docs/tutorials/wiki2/src/models/tutorial/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/docs/tutorials/wiki2/src/models/tutorial/static/logo.png b/docs/tutorials/wiki2/src/models/tutorial/static/logo.png Binary files differdeleted file mode 100644 index 88f5d9865..000000000 --- a/docs/tutorials/wiki2/src/models/tutorial/static/logo.png +++ /dev/null diff --git a/docs/tutorials/wiki2/src/models/tutorial/static/middlebg.png b/docs/tutorials/wiki2/src/models/tutorial/static/middlebg.png Binary files differnew file mode 100644 index 000000000..2369cfb7d --- /dev/null +++ b/docs/tutorials/wiki2/src/models/tutorial/static/middlebg.png diff --git a/docs/tutorials/wiki2/src/models/tutorial/static/pylons.css b/docs/tutorials/wiki2/src/models/tutorial/static/pylons.css index c153be07f..fd1914d8d 100644 --- a/docs/tutorials/wiki2/src/models/tutorial/static/pylons.css +++ b/docs/tutorials/wiki2/src/models/tutorial/static/pylons.css @@ -4,34 +4,23 @@ body{line-height:1;} ol,ul{list-style:none;} blockquote,q{quotes:none;} blockquote:before,blockquote:after,q:before,q:after{content:'';content:none;} -/* remember to define focus styles! */ :focus{outline:0;} -/* remember to highlight inserts somehow! */ ins{text-decoration:none;} del{text-decoration:line-through;} -/* tables still need 'cellspacing="0"' in the markup */ table{border-collapse:collapse;border-spacing:0;} -/* restyling */ sub{vertical-align:sub;font-size:smaller;line-height:normal;} sup{vertical-align:super;font-size:smaller;line-height:normal;} -/* lists */ ul,menu,dir{display:block;list-style-type:disc;margin:1em 0;padding-left:40px;} ol{display:block;list-style-type:decimal-leading-zero;margin:1em 0;padding-left:40px;} li{display:list-item;} -/* nested lists have no top/bottom margins */ ul ul,ul ol,ul dir,ul menu,ul dl,ol ul,ol ol,ol dir,ol menu,ol dl,dir ul,dir ol,dir dir,dir menu,dir dl,menu ul,menu ol,menu dir,menu menu,menu dl,dl ul,dl ol,dl dir,dl menu,dl dl{margin-top:0;margin-bottom:0;} -/* 2 deep unordered lists use a circle */ ol ul,ul ul,menu ul,dir ul,ol menu,ul menu,menu menu,dir menu,ol dir,ul dir,menu dir,dir dir{list-style-type:circle;} -/* 3 deep (or more) unordered lists use a square */ ol ol ul,ol ul ul,ol menu ul,ol dir ul,ol ol menu,ol ul menu,ol menu menu,ol dir menu,ol ol dir,ol ul dir,ol menu dir,ol dir dir,ul ol ul,ul ul ul,ul menu ul,ul dir ul,ul ol menu,ul ul menu,ul menu menu,ul dir menu,ul ol dir,ul ul dir,ul menu dir,ul dir dir,menu ol ul,menu ul ul,menu menu ul,menu dir ul,menu ol menu,menu ul menu,menu menu menu,menu dir menu,menu ol dir,menu ul dir,menu menu dir,menu dir dir,dir ol ul,dir ul ul,dir menu ul,dir dir ul,dir ol menu,dir ul menu,dir menu menu,dir dir menu,dir ol dir,dir ul dir,dir menu dir,dir dir dir{list-style-type:square;} .hidden{display:none;} p{line-height:1.5em;} -h1{font-size:1.75em;/* 28px */ -line-height:1.7em;font-family:helvetica,verdana;} -h2{font-size:1.5em;/* 24px */ -line-height:1.7em;font-family:helvetica,verdana;} -h3{font-size:1.25em;/* 20px */ -line-height:1.7em;font-family:helvetica,verdana;} +h1{font-size:1.75em;line-height:1.7em;font-family:helvetica,verdana;} +h2{font-size:1.5em;line-height:1.7em;font-family:helvetica,verdana;} +h3{font-size:1.25em;line-height:1.7em;font-family:helvetica,verdana;} h4{font-size:1em;line-height:1.7em;font-family:helvetica,verdana;} html,body{width:100%;height:100%;} body{margin:0;padding:0;background-color:#ffffff;position:relative;font:16px/24px "Nobile","Lucida Grande",Lucida,Verdana,sans-serif;} @@ -42,23 +31,26 @@ 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,#top-small,#bottom{width:100%;} +#top{color:#000000;height:230px;background:#ffffff url(headerbg.png) repeat-x 0 top;position:relative;} +#top-small{color:#000000;height:60px;background:#ffffff url(headerbg.png) repeat-x 0 top;position:relative;} +#bottom{color:#222;background-color:#ffffff;} +.top,.top-small,.middle,.bottom{width:750px;margin-right:auto;margin-left:auto;} +.top{padding-top:40px;} +.top-small{padding-top:10px;} +#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 +59,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],input[type=password]{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/docs/tutorials/wiki2/src/models/tutorial/static/pyramid-small.png b/docs/tutorials/wiki2/src/models/tutorial/static/pyramid-small.png Binary files differnew file mode 100644 index 000000000..a5bc0ade7 --- /dev/null +++ b/docs/tutorials/wiki2/src/models/tutorial/static/pyramid-small.png diff --git a/docs/tutorials/wiki2/src/models/tutorial/static/pyramid.png b/docs/tutorials/wiki2/src/models/tutorial/static/pyramid.png Binary files differnew file mode 100644 index 000000000..347e05549 --- /dev/null +++ b/docs/tutorials/wiki2/src/models/tutorial/static/pyramid.png diff --git a/docs/tutorials/wiki2/src/models/tutorial/static/transparent.gif b/docs/tutorials/wiki2/src/models/tutorial/static/transparent.gif Binary files differnew file mode 100644 index 000000000..0341802e5 --- /dev/null +++ b/docs/tutorials/wiki2/src/models/tutorial/static/transparent.gif diff --git a/docs/tutorials/wiki2/src/models/tutorial/templates/mytemplate.pt b/docs/tutorials/wiki2/src/models/tutorial/templates/mytemplate.pt index 6ad23d44f..cac9ccaa7 100644 --- a/docs/tutorials/wiki2/src/models/tutorial/templates/mytemplate.pt +++ b/docs/tutorials/wiki2/src/models/tutorial/templates/mytemplate.pt @@ -5,23 +5,23 @@ <meta http-equiv="Content-Type" content="text/html;charset=UTF-8"/> <meta name="keywords" content="python web application" /> <meta name="description" content="pyramid web application" /> - <link rel="shortcut icon" href="${request.application_url}/static/favicon.ico" /> - <link rel="stylesheet" href="${request.application_url}/static/pylons.css" type="text/css" media="screen" charset="utf-8" /> + <link rel="shortcut icon" href="${request.static_url('tutorial:static/favicon.ico')}" /> + <link rel="stylesheet" href="${request.static_url('tutorial:static/pylons.css')}" type="text/css" media="screen" charset="utf-8" /> + <link rel="stylesheet" href="http://fonts.googleapis.com/css?family=Neuton&subset=latin" type="text/css" media="screen" charset="utf-8" /> <link rel="stylesheet" href="http://fonts.googleapis.com/css?family=Nobile:regular,italic,bold,bolditalic&subset=latin" type="text/css" media="screen" charset="utf-8" /> - <!--[if !IE 7]> - <style type="text/css"> - #wrap {display:table;height:100%} - </style> + <!--[if lte IE 6]> + <link rel="stylesheet" href="${request.static_url('tutorial:static/ie6.css')}" type="text/css" media="screen" charset="utf-8" /> <![endif]--> </head> <body> <div id="wrap"> - <div id="header"> - <div class="header">The Pyramid Web Application Development Framework</div> - </div> <div id="top"> <div class="top align-center"> - <img src="${request.application_url}/static/logo.png" width="300" height="80"/> + <div><img src="${request.static_url('tutorial:static/pyramid.png')}" width="750" height="169" alt="pyramid"/></div> + </div> + </div> + <div id="middle"> + <div class="middle align-center"> <p class="app-welcome"> Welcome to <span class="app-name">${project}</span>, an application generated by<br/> the Pyramid web application development framework. @@ -31,22 +31,19 @@ <div id="bottom"> <div class="bottom"> <div id="left" class="align-right"> - <h3>Search Pyramid documentation</h3> + <h2>Search documentation</h2> <form method="get" action="http://docs.pylonshq.com/pyramid/dev/search.html"> <input type="text" id="q" name="q" value="" /> - <input type="submit" id="x" value="Search" /> + <input type="submit" id="x" value="Go" /> </form> </div> <div id="right" class="align-left"> - <h3>Pyramid links</h3> + <h2>Pyramid links</h2> <ul class="links"> <li> <a href="http://pylonshq.com">Pylons Website</a> </li> <li> - <a href="http://docs.pylonshq.com/">The Pylons Project Documentation</a> - </li> - <li> <a href="http://docs.pylonshq.com/pyramid/dev/#narrative-documentation">Narrative Documentation</a> </li> <li> @@ -73,7 +70,7 @@ </div> </div> <div id="footer"> - <div class="footer">© Copyright 2008-2010, Agendaless Consulting.</div> + <div class="footer">© Copyright 2008-2011, Agendaless Consulting.</div> </div> </body> </html>
\ No newline at end of file diff --git a/docs/tutorials/wiki2/src/views/tutorial/__init__.py b/docs/tutorials/wiki2/src/views/tutorial/__init__.py index 334fde814..1a8d24499 100644 --- a/docs/tutorials/wiki2/src/views/tutorial/__init__.py +++ b/docs/tutorials/wiki2/src/views/tutorial/__init__.py @@ -10,7 +10,7 @@ def main(global_config, **settings): initialize_sql(engine) config = Configurator(settings=settings) config.add_static_view('static', 'tutorial:static') - config.add_route('home', '/', view='tutorial.views.view_wiki') + config.add_route('view_wiki', '/', view='tutorial.views.view_wiki') config.add_route('view_page', '/{pagename}', view='tutorial.views.view_page', view_renderer='tutorial:templates/view.pt') diff --git a/docs/tutorials/wiki2/src/views/tutorial/static/footerbg.png b/docs/tutorials/wiki2/src/views/tutorial/static/footerbg.png Binary files differnew file mode 100644 index 000000000..1fbc873da --- /dev/null +++ b/docs/tutorials/wiki2/src/views/tutorial/static/footerbg.png diff --git a/docs/tutorials/wiki2/src/views/tutorial/static/headerbg.png b/docs/tutorials/wiki2/src/views/tutorial/static/headerbg.png Binary files differnew file mode 100644 index 000000000..0596f2020 --- /dev/null +++ b/docs/tutorials/wiki2/src/views/tutorial/static/headerbg.png diff --git a/docs/tutorials/wiki2/src/views/tutorial/static/ie6.css b/docs/tutorials/wiki2/src/views/tutorial/static/ie6.css new file mode 100644 index 000000000..b7c8493d8 --- /dev/null +++ b/docs/tutorials/wiki2/src/views/tutorial/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/docs/tutorials/wiki2/src/views/tutorial/static/logo.png b/docs/tutorials/wiki2/src/views/tutorial/static/logo.png Binary files differdeleted file mode 100644 index 88f5d9865..000000000 --- a/docs/tutorials/wiki2/src/views/tutorial/static/logo.png +++ /dev/null diff --git a/docs/tutorials/wiki2/src/views/tutorial/static/middlebg.png b/docs/tutorials/wiki2/src/views/tutorial/static/middlebg.png Binary files differnew file mode 100644 index 000000000..2369cfb7d --- /dev/null +++ b/docs/tutorials/wiki2/src/views/tutorial/static/middlebg.png diff --git a/docs/tutorials/wiki2/src/views/tutorial/static/pylons.css b/docs/tutorials/wiki2/src/views/tutorial/static/pylons.css index c153be07f..fd1914d8d 100644 --- a/docs/tutorials/wiki2/src/views/tutorial/static/pylons.css +++ b/docs/tutorials/wiki2/src/views/tutorial/static/pylons.css @@ -4,34 +4,23 @@ body{line-height:1;} ol,ul{list-style:none;} blockquote,q{quotes:none;} blockquote:before,blockquote:after,q:before,q:after{content:'';content:none;} -/* remember to define focus styles! */ :focus{outline:0;} -/* remember to highlight inserts somehow! */ ins{text-decoration:none;} del{text-decoration:line-through;} -/* tables still need 'cellspacing="0"' in the markup */ table{border-collapse:collapse;border-spacing:0;} -/* restyling */ sub{vertical-align:sub;font-size:smaller;line-height:normal;} sup{vertical-align:super;font-size:smaller;line-height:normal;} -/* lists */ ul,menu,dir{display:block;list-style-type:disc;margin:1em 0;padding-left:40px;} ol{display:block;list-style-type:decimal-leading-zero;margin:1em 0;padding-left:40px;} li{display:list-item;} -/* nested lists have no top/bottom margins */ ul ul,ul ol,ul dir,ul menu,ul dl,ol ul,ol ol,ol dir,ol menu,ol dl,dir ul,dir ol,dir dir,dir menu,dir dl,menu ul,menu ol,menu dir,menu menu,menu dl,dl ul,dl ol,dl dir,dl menu,dl dl{margin-top:0;margin-bottom:0;} -/* 2 deep unordered lists use a circle */ ol ul,ul ul,menu ul,dir ul,ol menu,ul menu,menu menu,dir menu,ol dir,ul dir,menu dir,dir dir{list-style-type:circle;} -/* 3 deep (or more) unordered lists use a square */ ol ol ul,ol ul ul,ol menu ul,ol dir ul,ol ol menu,ol ul menu,ol menu menu,ol dir menu,ol ol dir,ol ul dir,ol menu dir,ol dir dir,ul ol ul,ul ul ul,ul menu ul,ul dir ul,ul ol menu,ul ul menu,ul menu menu,ul dir menu,ul ol dir,ul ul dir,ul menu dir,ul dir dir,menu ol ul,menu ul ul,menu menu ul,menu dir ul,menu ol menu,menu ul menu,menu menu menu,menu dir menu,menu ol dir,menu ul dir,menu menu dir,menu dir dir,dir ol ul,dir ul ul,dir menu ul,dir dir ul,dir ol menu,dir ul menu,dir menu menu,dir dir menu,dir ol dir,dir ul dir,dir menu dir,dir dir dir{list-style-type:square;} .hidden{display:none;} p{line-height:1.5em;} -h1{font-size:1.75em;/* 28px */ -line-height:1.7em;font-family:helvetica,verdana;} -h2{font-size:1.5em;/* 24px */ -line-height:1.7em;font-family:helvetica,verdana;} -h3{font-size:1.25em;/* 20px */ -line-height:1.7em;font-family:helvetica,verdana;} +h1{font-size:1.75em;line-height:1.7em;font-family:helvetica,verdana;} +h2{font-size:1.5em;line-height:1.7em;font-family:helvetica,verdana;} +h3{font-size:1.25em;line-height:1.7em;font-family:helvetica,verdana;} h4{font-size:1em;line-height:1.7em;font-family:helvetica,verdana;} html,body{width:100%;height:100%;} body{margin:0;padding:0;background-color:#ffffff;position:relative;font:16px/24px "Nobile","Lucida Grande",Lucida,Verdana,sans-serif;} @@ -42,23 +31,26 @@ 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,#top-small,#bottom{width:100%;} +#top{color:#000000;height:230px;background:#ffffff url(headerbg.png) repeat-x 0 top;position:relative;} +#top-small{color:#000000;height:60px;background:#ffffff url(headerbg.png) repeat-x 0 top;position:relative;} +#bottom{color:#222;background-color:#ffffff;} +.top,.top-small,.middle,.bottom{width:750px;margin-right:auto;margin-left:auto;} +.top{padding-top:40px;} +.top-small{padding-top:10px;} +#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 +59,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],input[type=password]{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/docs/tutorials/wiki2/src/views/tutorial/static/pyramid-small.png b/docs/tutorials/wiki2/src/views/tutorial/static/pyramid-small.png Binary files differnew file mode 100644 index 000000000..a5bc0ade7 --- /dev/null +++ b/docs/tutorials/wiki2/src/views/tutorial/static/pyramid-small.png diff --git a/docs/tutorials/wiki2/src/views/tutorial/static/pyramid.png b/docs/tutorials/wiki2/src/views/tutorial/static/pyramid.png Binary files differnew file mode 100644 index 000000000..347e05549 --- /dev/null +++ b/docs/tutorials/wiki2/src/views/tutorial/static/pyramid.png diff --git a/docs/tutorials/wiki2/src/views/tutorial/static/style.css b/docs/tutorials/wiki2/src/views/tutorial/static/style.css deleted file mode 100644 index cad87e0d4..000000000 --- a/docs/tutorials/wiki2/src/views/tutorial/static/style.css +++ /dev/null @@ -1,109 +0,0 @@ -html, body { - color: black; - background-color: #ddd; - font: x-small "Lucida Grande", "Lucida Sans Unicode", geneva, sans-serif; - margin: 0; - padding: 0; -} - -td, th {padding:3px;border:none;} -tr th {text-align:left;background-color:#f0f0f0;color:#333;} -tr.odd td {background-color:#edf3fe;} -tr.even td {background-color:#fff;} - -#header { - height: 80px; - width: 777px; - background: blue URL('../images/header_inner.png') no-repeat; - border-left: 1px solid #aaa; - border-right: 1px solid #aaa; - margin: 0 auto 0 auto; -} - -a.link, a, a.active { - color: #369; -} - - -#main_content { - color: black; - font-size: 127%; - background-color: white; - width: 757px; - margin: 0 auto 0 auto; - border-left: 1px solid #aaa; - border-right: 1px solid #aaa; - padding: 10px; -} - -#sidebar { - border: 1px solid #aaa; - background-color: #eee; - margin: 0.5em; - padding: 1em; - float: right; - width: 200px; - font-size: 88%; -} - -#sidebar h2 { - margin-top: 0; -} - -#sidebar ul { - margin-left: 1.5em; - padding-left: 0; -} - -h1,h2,h3,h4,h5,h6,#getting_started_steps { - font-family: "Century Schoolbook L", Georgia, serif; - font-weight: bold; -} - -h2 { - font-size: 150%; -} - -#footer { - border: 1px solid #aaa; - border-top: 0px none; - color: #999; - background-color: white; - padding: 10px; - font-size: 80%; - text-align: center; - width: 757px; - margin: 0 auto 1em auto; -} - -.code { - font-family: monospace; -} - -span.code { - font-weight: bold; - background: #eee; -} - -#status_block { - margin: 0 auto 0.5em auto; - padding: 15px 10px 15px 55px; - background: #cec URL('../images/ok.png') left center no-repeat; - border: 1px solid #9c9; - width: 450px; - font-size: 120%; - font-weight: bolder; -} - -.notice { - margin: 0.5em auto 0.5em auto; - padding: 15px 10px 15px 55px; - width: 450px; - background: #eef URL('../images/info.png') left center no-repeat; - border: 1px solid #cce; -} - -.fielderror { - color: red; - font-weight: bold; -} diff --git a/docs/tutorials/wiki2/src/views/tutorial/static/transparent.gif b/docs/tutorials/wiki2/src/views/tutorial/static/transparent.gif Binary files differnew file mode 100644 index 000000000..0341802e5 --- /dev/null +++ b/docs/tutorials/wiki2/src/views/tutorial/static/transparent.gif diff --git a/docs/tutorials/wiki2/src/views/tutorial/templates/edit.pt b/docs/tutorials/wiki2/src/views/tutorial/templates/edit.pt index 047a64eb3..b45cea3c6 100644 --- a/docs/tutorials/wiki2/src/views/tutorial/templates/edit.pt +++ b/docs/tutorials/wiki2/src/views/tutorial/templates/edit.pt @@ -1,32 +1,47 @@ -<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" - "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"> -<html - xmlns="http://www.w3.org/1999/xhtml" - xmlns:tal="http://xml.zope.org/namespaces/tal"> - +<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd"> +<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en" xmlns:tal="http://xml.zope.org/namespaces/tal"> <head> - <meta content="text/html; charset=utf-8" http-equiv="Content-Type"/> - <title>Pyramid tutorial wiki (based on TurboGears 20-Minute Wiki) - Editing: ${page.name}</title> - <link rel="stylesheet" type="text/css" - href="${request.application_url}/static/style.css" /> + <title>${page.name} - Pyramid tutorial wiki (based on TurboGears 20-Minute Wiki)</title> + <meta http-equiv="Content-Type" content="text/html;charset=UTF-8"/> + <meta name="keywords" content="python web application" /> + <meta name="description" content="pyramid web application" /> + <link rel="shortcut icon" href="${request.static_url('tutorial:static/favicon.ico')}" /> + <link rel="stylesheet" href="${request.static_url('tutorial:static/pylons.css')}" type="text/css" media="screen" charset="utf-8" /> + <link rel="stylesheet" href="http://fonts.googleapis.com/css?family=Neuton&subset=latin" type="text/css" media="screen" charset="utf-8" /> + <link rel="stylesheet" href="http://fonts.googleapis.com/css?family=Nobile:regular,italic,bold,bolditalic&subset=latin" type="text/css" media="screen" charset="utf-8" /> + <!--[if lte IE 6]> + <link rel="stylesheet" href="${request.static_url('tutorial:static/ie6.css')}" type="text/css" media="screen" charset="utf-8" /> + <![endif]--> </head> - <body> - -<div class="main_content"> - <div style="float:right; width: 10em;"> Viewing - <span tal:replace="page.name">Page Name Goes Here</span> <br/> - You can return to the <a href="${request.application_url}" - >FrontPage</a>. - </div> - - <div> - <form action="${save_url}" method="post"> - <textarea name="body" tal:content="page.data" rows="10" cols="60"/> - <input type="submit" name="form.submitted" value="Save"/> - </form> - </div> -</div> + <div id="wrap"> + <div id="top-small"> + <div class="top-small align-center"> + <div> + <img src="${request.static_url('tutorial:static/pyramid-small.png')}" width="220" height="50" alt="pyramid" /> + </div> + </div> + </div> + <div id="middle"> + <div class="middle align-right"> + <div id="left" class="app-welcome align-left"> + Editing <b><span tal:replace="page.name">Page Name Goes Here</span></b><br/> + You can return to the <a href="${request.application_url}">FrontPage</a>.<br/> + </div> + <div id="right" class="app-welcome align-right"></div> + </div> + </div> + <div id="bottom"> + <div class="bottom"> + <form action="${save_url}" method="post"> + <textarea name="body" tal:content="page.data" rows="10" cols="60"/><br/> + <input type="submit" name="form.submitted" value="Save"/> + </form> + </div> + </div> + </div> + <div id="footer"> + <div class="footer">© Copyright 2008-2011, Agendaless Consulting.</div> + </div> </body> -</html> +</html>
\ No newline at end of file diff --git a/docs/tutorials/wiki2/src/views/tutorial/templates/mytemplate.pt b/docs/tutorials/wiki2/src/views/tutorial/templates/mytemplate.pt index 6ad23d44f..cac9ccaa7 100644 --- a/docs/tutorials/wiki2/src/views/tutorial/templates/mytemplate.pt +++ b/docs/tutorials/wiki2/src/views/tutorial/templates/mytemplate.pt @@ -5,23 +5,23 @@ <meta http-equiv="Content-Type" content="text/html;charset=UTF-8"/> <meta name="keywords" content="python web application" /> <meta name="description" content="pyramid web application" /> - <link rel="shortcut icon" href="${request.application_url}/static/favicon.ico" /> - <link rel="stylesheet" href="${request.application_url}/static/pylons.css" type="text/css" media="screen" charset="utf-8" /> + <link rel="shortcut icon" href="${request.static_url('tutorial:static/favicon.ico')}" /> + <link rel="stylesheet" href="${request.static_url('tutorial:static/pylons.css')}" type="text/css" media="screen" charset="utf-8" /> + <link rel="stylesheet" href="http://fonts.googleapis.com/css?family=Neuton&subset=latin" type="text/css" media="screen" charset="utf-8" /> <link rel="stylesheet" href="http://fonts.googleapis.com/css?family=Nobile:regular,italic,bold,bolditalic&subset=latin" type="text/css" media="screen" charset="utf-8" /> - <!--[if !IE 7]> - <style type="text/css"> - #wrap {display:table;height:100%} - </style> + <!--[if lte IE 6]> + <link rel="stylesheet" href="${request.static_url('tutorial:static/ie6.css')}" type="text/css" media="screen" charset="utf-8" /> <![endif]--> </head> <body> <div id="wrap"> - <div id="header"> - <div class="header">The Pyramid Web Application Development Framework</div> - </div> <div id="top"> <div class="top align-center"> - <img src="${request.application_url}/static/logo.png" width="300" height="80"/> + <div><img src="${request.static_url('tutorial:static/pyramid.png')}" width="750" height="169" alt="pyramid"/></div> + </div> + </div> + <div id="middle"> + <div class="middle align-center"> <p class="app-welcome"> Welcome to <span class="app-name">${project}</span>, an application generated by<br/> the Pyramid web application development framework. @@ -31,22 +31,19 @@ <div id="bottom"> <div class="bottom"> <div id="left" class="align-right"> - <h3>Search Pyramid documentation</h3> + <h2>Search documentation</h2> <form method="get" action="http://docs.pylonshq.com/pyramid/dev/search.html"> <input type="text" id="q" name="q" value="" /> - <input type="submit" id="x" value="Search" /> + <input type="submit" id="x" value="Go" /> </form> </div> <div id="right" class="align-left"> - <h3>Pyramid links</h3> + <h2>Pyramid links</h2> <ul class="links"> <li> <a href="http://pylonshq.com">Pylons Website</a> </li> <li> - <a href="http://docs.pylonshq.com/">The Pylons Project Documentation</a> - </li> - <li> <a href="http://docs.pylonshq.com/pyramid/dev/#narrative-documentation">Narrative Documentation</a> </li> <li> @@ -73,7 +70,7 @@ </div> </div> <div id="footer"> - <div class="footer">© Copyright 2008-2010, Agendaless Consulting.</div> + <div class="footer">© Copyright 2008-2011, Agendaless Consulting.</div> </div> </body> </html>
\ No newline at end of file diff --git a/docs/tutorials/wiki2/src/views/tutorial/templates/view.pt b/docs/tutorials/wiki2/src/views/tutorial/templates/view.pt index 86fcc914e..cacb58788 100644 --- a/docs/tutorials/wiki2/src/views/tutorial/templates/view.pt +++ b/docs/tutorials/wiki2/src/views/tutorial/templates/view.pt @@ -1,28 +1,51 @@ -<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" - "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"> -<html - xmlns="http://www.w3.org/1999/xhtml" - xmlns:tal="http://xml.zope.org/namespaces/tal"> - +<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd"> +<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en" xmlns:tal="http://xml.zope.org/namespaces/tal"> <head> - <meta content="text/html; charset=utf-8" http-equiv="Content-Type"/> - <title>${page.name} - Pyramid tutorial wiki - (based on TurboGears 20-Minute Wiki)</title> - <link rel="stylesheet" type="text/css" - href="${request.application_url}/static/style.css" /> + <title>${page.name} - Pyramid tutorial wiki (based on TurboGears 20-Minute Wiki)</title> + <meta http-equiv="Content-Type" content="text/html;charset=UTF-8"/> + <meta name="keywords" content="python web application" /> + <meta name="description" content="pyramid web application" /> + <link rel="shortcut icon" href="${request.static_url('tutorial:static/favicon.ico')}" /> + <link rel="stylesheet" href="${request.static_url('tutorial:static/pylons.css')}" type="text/css" media="screen" charset="utf-8" /> + <link rel="stylesheet" href="http://fonts.googleapis.com/css?family=Neuton&subset=latin" type="text/css" media="screen" charset="utf-8" /> + <link rel="stylesheet" href="http://fonts.googleapis.com/css?family=Nobile:regular,italic,bold,bolditalic&subset=latin" type="text/css" media="screen" charset="utf-8" /> + <!--[if lte IE 6]> + <link rel="stylesheet" href="${request.static_url('tutorial:static/ie6.css')}" type="text/css" media="screen" charset="utf-8" /> + <![endif]--> </head> - <body> - -<div class="main_content"> -<div style="float:right; width: 10em;"> Viewing -<span tal:replace="page.name">Page Name Goes Here</span> <br/> -You can return to the <a href="${request.application_url}">FrontPage</a>. -</div> - -<div tal:replace="structure content">Page text goes here.</div> -<p><a tal:attributes="href edit_url" href="">Edit this page</a></p> -</div> - + <div id="wrap"> + <div id="top-small"> + <div class="top-small align-center"> + <div> + <img src="${request.static_url('tutorial:static/pyramid-small.png')}" width="220" height="50" alt="pyramid" /> + </div> + </div> + </div> + <div id="middle"> + <div class="middle align-right"> + <div id="left" class="app-welcome align-left"> + Viewing <b><span tal:replace="page.name">Page Name Goes Here</span></b><br/> + You can return to the <a href="${request.application_url}">FrontPage</a>.<br/> + </div> + <div id="right" class="app-welcome align-right"></div> + </div> + </div> + <div id="bottom"> + <div class="bottom"> + <div tal:replace="structure content"> + Page text goes here. + </div> + <p> + <a tal:attributes="href edit_url" href=""> + Edit this page + </a> + </p> + </div> + </div> + </div> + <div id="footer"> + <div class="footer">© Copyright 2008-2011, Agendaless Consulting.</div> + </div> </body> -</html> +</html>
\ No newline at end of file diff --git a/docs/zcml/handler.rst b/docs/zcml/handler.rst index 01d442ab6..64aac7e78 100644 --- a/docs/zcml/handler.rst +++ b/docs/zcml/handler.rst @@ -155,4 +155,4 @@ You can also add a :term:`route configuration` via: See Also ~~~~~~~~ -See also :ref:`handlers_chapter`. +See also :ref:`views_chapter`. diff --git a/docs/zcml/view.rst b/docs/zcml/view.rst index b4fabdc2c..ba5c7bf23 100644 --- a/docs/zcml/view.rst +++ b/docs/zcml/view.rst @@ -213,6 +213,20 @@ Predicate Attributes associated view callable will be considered viable for a given request. +``decorator`` + A :term:`dotted Python name` to a function that will be used to decorate + the registered :term:`view callable`. The decorator function will be + called with the view callable as a single argument. The view callable it + is passed will accept ``(context, request)``. The decorator must return a + replacement view callable which also accepts ``(context, request)``. + +``mapper`` + A :term:`dotted Python name` which refers to a :term:`view mapper`, or + ``None``. By default it is ``None``, which indicates that the view should + use the default view mapper. This plug-point is useful for Pyramid + extension developers, but it's not very useful for 'civilians' who are just + developing stock Pyramid applications. + Examples ~~~~~~~~ diff --git a/pyramid/authentication.py b/pyramid/authentication.py index 86d725bcf..9de306b80 100644 --- a/pyramid/authentication.py +++ b/pyramid/authentication.py @@ -17,7 +17,7 @@ from pyramid.security import Everyone class CallbackAuthenticationPolicy(object): """ Abstract class """ def authenticated_userid(self, request): - userid = self._get_userid(request) + userid = self.unauthenticated_userid(request) if userid is None: return None if self.callback is None: @@ -27,7 +27,7 @@ class CallbackAuthenticationPolicy(object): def effective_principals(self, request): effective_principals = [Everyone] - userid = self._get_userid(request) + userid = self.unauthenticated_userid(request) if userid is None: return effective_principals if self.callback is None: @@ -89,6 +89,12 @@ class RepozeWho1AuthenticationPolicy(CallbackAuthenticationPolicy): if self.callback(identity, request) is not None: # is not None! return identity['repoze.who.userid'] + def unauthenticated_userid(self, request): + identity = self._get_identity(request) + if identity is None: + return None + return identity['repoze.who.userid'] + def effective_principals(self, request): effective_principals = [Everyone] identity = self._get_identity(request) @@ -147,7 +153,7 @@ class RemoteUserAuthenticationPolicy(CallbackAuthenticationPolicy): self.environ_key = environ_key self.callback = callback - def _get_userid(self, request): + def unauthenticated_userid(self, request): return request.environ.get(self.environ_key) def remember(self, request, principal, **kw): @@ -264,7 +270,7 @@ class AuthTktAuthenticationPolicy(CallbackAuthenticationPolicy): ) self.callback = callback - def _get_userid(self, request): + def unauthenticated_userid(self, request): result = self.cookie.identify(request) if result: return result['userid'] @@ -285,6 +291,12 @@ def b64decode(v): EXPIRE = object() class AuthTktCookieHelper(object): + """ + A helper class for use in third-party authentication policy + implementations. See + :class:`pyramid.authentication.AuthTktAuthenticationPolicy` for the + meanings of the constructor arguments. + """ auth_tkt = auth_tkt # for tests now = None # for tests @@ -356,6 +368,8 @@ class AuthTktCookieHelper(object): return cookies def identify(self, request): + """ Return a dictionary with authentication information, or ``None`` + if no valid auth_tkt is attached to ``request``""" environ = request.environ cookies = get_cookies(environ) cookie = cookies.get(self.cookie_name) @@ -411,11 +425,14 @@ class AuthTktCookieHelper(object): return identity def forget(self, request): - # return a set of expires Set-Cookie headers + """ Return a set of expires Set-Cookie headers, which will destroy + any existing auth_tkt cookie when attached to a response""" environ = request.environ return self._get_cookies(environ, '', max_age=EXPIRE) def remember(self, request, userid, max_age=None): + """ Return a set of Set-Cookie headers; when set into a response, + these headers will represent a valid authentication ticket.""" max_age = max_age or self.max_age environ = request.environ diff --git a/pyramid/config.py b/pyramid/config.py index ee34adae1..ff5d51fc4 100644 --- a/pyramid/config.py +++ b/pyramid/config.py @@ -125,6 +125,7 @@ def action_method(wrapped): return result wrapper.__name__ = wrapped.__name__ wrapper.__doc__ = wrapped.__doc__ + wrapper.__docobj__ = wrapped # for sphinx return wrapper class Configurator(object): @@ -246,7 +247,13 @@ class Configurator(object): ``autocommit`` is ``True``. If a conflict is detected a ``ConfigurationConflictError`` will be raised. Calling :meth:`pyramid.config.Configurator.make_wsgi_app` always implies a final - commit.""" + commit. + + If ``default_view_mapper`` is passed, it will be used as the default + :term:`view mapper` factory for view configurations that don't otherwise + specify one (see :class:`pyramid.interfaces.IViewMapperFactory`). If a + default_view_mapper is not passed, a superdefault view mapper will be + used. """ manager = manager # for testing injection venusian = venusian # for testing injection @@ -267,6 +274,7 @@ class Configurator(object): renderer_globals_factory=None, default_permission=None, session_factory=None, + default_view_mapper=None, autocommit=False, ): if package is None: @@ -292,6 +300,7 @@ class Configurator(object): renderer_globals_factory=renderer_globals_factory, default_permission=default_permission, session_factory=session_factory, + default_view_mapper=default_view_mapper, ) def _set_settings(self, mapping): @@ -343,8 +352,10 @@ class Configurator(object): def _derive_view(self, view, permission=None, predicates=(), attr=None, renderer=None, wrapper_viewname=None, viewname=None, accept=None, order=MAX_ORDER, - phash=DEFAULT_PHASH): + phash=DEFAULT_PHASH, decorator=None, + mapper=None): view = self.maybe_dotted(view) + mapper = self.maybe_dotted(mapper) if isinstance(renderer, basestring): renderer = RendererHelper(name=renderer, package=self.package, registry = self.registry) @@ -354,18 +365,21 @@ class Configurator(object): renderer = RendererHelper(name=None, package=self.package, registry=self.registry) - deriver = ViewDeriver( - registry=self.registry, - permission=permission, - predicates=predicates, - attr=attr, - renderer=renderer, - wrapper_viewname=wrapper_viewname, - viewname=viewname, - accept=accept, - order=order, - phash=phash, - package=self.package) + + deriver = ViewDeriver(registry=self.registry, + permission=permission, + predicates=predicates, + attr=attr, + renderer=renderer, + wrapper_viewname=wrapper_viewname, + viewname=viewname, + accept=accept, + order=order, + phash=phash, + package=self.package, + mapper=mapper, + decorator=decorator) + return deriver(view) def _override(self, package, path, override_package, override_prefix, @@ -422,8 +436,8 @@ class Configurator(object): immediately if ``autocommit`` is ``True``). .. note:: This method is typically only used by :app:`Pyramid` - framework extension authors, not by :app:`Pyramid` application - developers. + framework extension authors, not by :app:`Pyramid` application + developers. The ``discriminator`` uniquely identifies the action. It must be given, but it can be ``None``, to indicate that the action never @@ -596,9 +610,8 @@ class Configurator(object): authentication_policy=None, authorization_policy=None, renderers=DEFAULT_RENDERERS, debug_logger=None, locale_negotiator=None, request_factory=None, - renderer_globals_factory=None, - default_permission=None, - session_factory=None): + renderer_globals_factory=None, default_permission=None, + session_factory=None, default_view_mapper=None): """ When you pass a non-``None`` ``registry`` argument to the :term:`Configurator` constructor, no initial 'setup' is performed against the registry. This is because the registry you pass in may @@ -644,7 +657,13 @@ class Configurator(object): self.set_default_permission(default_permission) if session_factory is not None: self.set_session_factory(session_factory) + # commit before adding default_view_mapper, as the + # default_exceptionresponse_view above requires the superdefault view + # mapper self.commit() + if default_view_mapper is not None: + self.set_view_mapper(default_view_mapper) + self.commit() # getSiteManager is a unit testing dep injection def hook_zca(self, getSiteManager=None): @@ -925,7 +944,7 @@ class Configurator(object): Any extra keyword arguments are passed along to ``add_route``. - See :ref:`handlers_chapter` for more explanatory documentation. + See :ref:`views_chapter` for more explanatory documentation. This method returns the result of add_route.""" handler = self.maybe_dotted(handler) @@ -1028,7 +1047,7 @@ class Configurator(object): request_param=None, containment=None, attr=None, renderer=None, wrapper=None, xhr=False, accept=None, header=None, path_info=None, custom_predicates=(), - context=None, decorator=None, view_mapper=None): + context=None, decorator=None, mapper=None): """ Add a :term:`view configuration` to the current configuration state. Arguments to ``add_view`` are broken down below into *predicate* arguments and *non-predicate* @@ -1139,12 +1158,22 @@ class Configurator(object): decorator - A function which will be used to decorate the registered - :term:`view callable`. The decorator function will be - called with the view callable as a single argument, and it - must return a replacement view callable which accepts the - same arguments and returns the same type of values as the - original function. + A :term:`dotted Python name` to function (or the function itself) + which will be used to decorate the registered :term:`view + callable`. The decorator function will be called with the view + callable as a single argument. The view callable it is passed will + accept ``(context, request)``. The decorator must return a + replacement view callable which also accepts ``(context, + request)``. + + mapper + + A Python object or :term:`dotted Python name` which refers to a + :term:`view mapper`, or ``None``. By default it is ``None``, which + indicates that the view should use the default view mapper. This + plug-point is useful for Pyramid extension developers, but it's not + very useful for 'civilians' who are just developing stock Pyramid + applications. Pay no attention to the man behind the curtain. Predicate Arguments @@ -1283,22 +1312,13 @@ class Configurator(object): ``True``, the associated view callable will be considered viable for a given request. - view_mapper - - A class implementing the - :class:`pyramid.interfaces.IViewMapperFactory` interface, which - performs view argument and response mapping. By default it is - ``None``, which indicates that the view should use the default view - mapper. This plug-point is useful for Pyramid extension - developers, but it's not very useful for 'civilians' who are - just developing stock Pyramid applications. Pay no attention to - the man behind the curtain. - """ view = self.maybe_dotted(view) context = self.maybe_dotted(context) for_ = self.maybe_dotted(for_) containment = self.maybe_dotted(containment) + mapper = self.maybe_dotted(mapper) + decorator = self.maybe_dotted(decorator) if not view: if renderer: @@ -1332,7 +1352,7 @@ class Configurator(object): renderer=renderer, wrapper=wrapper, xhr=xhr, accept=accept, header=header, path_info=path_info, custom_predicates=custom_predicates, context=context, - view_mapper = view_mapper, + mapper = mapper, ) view_info = deferred_views.setdefault(route_name, []) view_info.append(info) @@ -1369,19 +1389,21 @@ class Configurator(object): # intent: will be None if no default permission is registered permission = self.registry.queryUtility(IDefaultPermission) - # NO_PERMISSION_REQUIRED handled by _secure_view - derived_view = ViewDeriver(registry=self.registry, - permission=permission, - predicates=predicates, - attr=attr, - renderer=renderer, - wrapper_viewname=wrapper, - viewname=name, - accept=accept, - order=order, - phash=phash, - decorator=decorator, - view_mapper=view_mapper)(view) + # __no_permission_required__ handled by _secure_view + deriver = ViewDeriver(registry=self.registry, + permission=permission, + predicates=predicates, + attr=attr, + renderer=renderer, + wrapper_viewname=wrapper, + viewname=name, + accept=accept, + order=order, + phash=phash, + package=self.package, + mapper=mapper, + decorator=decorator) + derived_view = deriver(view) registered = self.registry.adapters.registered @@ -2163,6 +2185,29 @@ class Configurator(object): self.action(IDefaultPermission, None) @action_method + def set_view_mapper(self, mapper): + """ + Setting a :term:`view mapper` makes it possible to make use of + :term:`view callable` objects which implement different call + signatures than the ones supported by :app:`Pyramid` as described in + its narrative documentation. + + The ``mapper`` should argument be an object implementing + :class:`pyramid.interfaces.IViewMapperFactory` or a :term:`dotted + Python name` to such an object. + + The provided ``mapper`` will become the default view mapper to be + used by all subsequent :term:`view configuration` registrations, as + if you had passed a ``default_view_mapper`` argument to the + :class:`pyramid.config.Configurator` constructor. + + See also :ref:`using_an_alternate_view_mapper`. + """ + mapper = self.maybe_dotted(mapper) + self.registry.registerUtility(mapper, IViewMapperFactory) + self.action(IViewMapperFactory, None) + + @action_method def set_session_factory(self, session_factory): """ Configure the application with a :term:`session factory`. If @@ -2695,6 +2740,10 @@ def wraps_view(wrapped): def preserve_view_attrs(view, wrapped_view): if wrapped_view is view: return view + original_view = getattr(view, '__original_view__', None) + if original_view is None: + original_view = view + wrapped_view.__original_view__ = original_view wrapped_view.__module__ = view.__module__ wrapped_view.__doc__ = view.__doc__ try: @@ -2734,19 +2783,30 @@ class ViewDeriver(object): self.logger = self.registry.queryUtility(IDebugLogger) def __call__(self, view): - mapper = self.kw.get('view_mapper') - if mapper is None: - mapper = DefaultViewMapper - view = mapper(**self.kw)(view) return self.attr_wrapped_view( self.predicated_view( self.authdebug_view( self.secured_view( - self.owrap_view( - view))))) + self.owrapped_view( + self.decorated_view( + self.rendered_view( + self.mapped_view(view)))))))) + + @wraps_view + def mapped_view(self, view): + mapper = self.kw.get('mapper') + if mapper is None: + mapper = getattr(view, '__view_mapper__', None) + if mapper is None: + mapper = self.registry.queryUtility(IViewMapperFactory) + if mapper is None: + mapper = DefaultViewMapper + + mapped_view = mapper(**self.kw)(view) + return mapped_view @wraps_view - def owrap_view(self, view): + def owrapped_view(self, view): wrapper_viewname = self.kw.get('wrapper_viewname') viewname = self.kw.get('viewname') if not wrapper_viewname: @@ -2860,29 +2920,64 @@ class ViewDeriver(object): attr_view.__phash__ = phash return attr_view + @wraps_view + def rendered_view(self, view): + wrapped_view = view + static_renderer = self.kw.get('renderer') + if static_renderer is None: + # register a default renderer if you want super-dynamic + # rendering. registering a default renderer will also allow + # override_renderer to work if a renderer is left unspecified for + # a view registration. + return view + + def _rendered_view(context, request): + renderer = static_renderer + response = wrapped_view(context, request) + if not is_response(response): + attrs = getattr(request, '__dict__', {}) + if 'override_renderer' in attrs: + # renderer overridden by newrequest event or other + renderer_name = attrs.pop('override_renderer') + renderer = RendererHelper(name=renderer_name, + package=self.kw.get('package'), + registry = self.kw['registry']) + if '__view__' in attrs: + view_inst = attrs.pop('__view__') + else: + view_inst = getattr(wrapped_view, '__original_view__', + wrapped_view) + return renderer.render_view(request, response, view_inst, + context) + return response + + return _rendered_view + + @wraps_view + def decorated_view(self, view): + decorator = self.kw.get('decorator') + if decorator is None: + return view + return decorator(view) + class DefaultViewMapper(object): implements(IViewMapperFactory) def __init__(self, **kw): - self.renderer = kw.get('renderer') self.attr = kw.get('attr') - self.decorator = kw.get('decorator') def __call__(self, view): - decorator = self.decorator if inspect.isclass(view): - view = preserve_view_attrs(view, self.map_class(view)) + view = self.map_class(view) else: - view = preserve_view_attrs(view, self.map_nonclass(view)) - if decorator is not None: - view = preserve_view_attrs(view, decorator(view)) + view = self.map_nonclass(view) return view def map_class(self, view): - ronly = self.requestonly(view) + ronly = requestonly(view, self.attr) if ronly: - mapped_view = self._map_class_requestonly(view) + mapped_view = self.map_class_requestonly(view) else: - mapped_view = self._map_class_native(view) + mapped_view = self.map_class_native(view) return mapped_view def map_nonclass(self, view): @@ -2890,47 +2985,41 @@ class DefaultViewMapper(object): # view unless it actually requires wrapping (to avoid function call # overhead). mapped_view = view - ronly = self.requestonly(view) + ronly = requestonly(view, self.attr) if ronly: - mapped_view = self._map_nonclass_requestonly(view) + mapped_view = self.map_nonclass_requestonly(view) elif self.attr: - mapped_view = self._map_nonclass_attr(view) - elif self.renderer is not None: - mapped_view = self._map_nonclass_rendered(view) + mapped_view = self.map_nonclass_attr(view) return mapped_view - def _map_class_requestonly(self, view): + def map_class_requestonly(self, view): # its a class that has an __init__ which only accepts request attr = self.attr def _class_requestonly_view(context, request): inst = view(request) + request.__view__ = inst if attr is None: response = inst() else: response = getattr(inst, attr)() - if self.renderer is not None and not is_response(response): - response = self.renderer.render_view(request, response, view, - context) return response return _class_requestonly_view - def _map_class_native(self, view): + def map_class_native(self, view): # its a class that has an __init__ which accepts both context and # request attr = self.attr def _class_view(context, request): inst = view(context, request) + request.__view__ = inst if attr is None: response = inst() else: response = getattr(inst, attr)() - if self.renderer is not None and not is_response(response): - response = self.renderer.render_view(request, response, view, - context) return response return _class_view - def _map_nonclass_requestonly(self, view): + def map_nonclass_requestonly(self, view): # its a function that has a __call__ which accepts only a single # request argument attr = self.attr @@ -2939,86 +3028,58 @@ class DefaultViewMapper(object): response = view(request) else: response = getattr(view, attr)(request) - if self.renderer is not None and not is_response(response): - response = self.renderer.render_view(request, response, view, - context) return response return _requestonly_view - def _map_nonclass_attr(self, view): + def map_nonclass_attr(self, view): # its a function that has a __call__ which accepts both context and # request, but still has an attr - attr = self.attr def _attr_view(context, request): - response = getattr(view, attr)(context, request) - if self.renderer is not None and not is_response(response): - response = self.renderer.render_view(request, response, view, - context) + response = getattr(view, self.attr)(context, request) return response return _attr_view - def _map_nonclass_rendered(self, view): - # it's a function that has a __call__ that accepts both context and - # request, but requires rendering - def _rendered_view(context, request): - response = view(context, request) - if self.renderer is not None and not is_response(response): - response = self.renderer.render_view(request, response, view, - context) - return response - return _rendered_view - - def requestonly(self, view): - attr = self.attr - if attr is None: - attr = '__call__' - if inspect.isfunction(view): - fn = view - elif inspect.isclass(view): - try: - fn = view.__init__ - except AttributeError: - return False - else: - try: - fn = getattr(view, attr) - except AttributeError: - return False - +def requestonly(view, attr=None): + if attr is None: + attr = '__call__' + if inspect.isfunction(view): + fn = view + elif inspect.isclass(view): try: - argspec = inspect.getargspec(fn) - except TypeError: + fn = view.__init__ + except AttributeError: return False - - args = argspec[0] - defaults = argspec[3] - - if hasattr(fn, 'im_func'): - # it's an instance method - if not args: - return False - args = args[1:] - if not args: + else: + try: + fn = getattr(view, attr) + except AttributeError: return False - if len(args) == 1: - return True + try: + argspec = inspect.getargspec(fn) + except TypeError: + return False - elif args[0] == 'request': - if len(args) - len(defaults) == 1: - return True + args = argspec[0] + defaults = argspec[3] + if hasattr(fn, 'im_func'): + # it's an instance method + if not args: + return False + args = args[1:] + if not args: return False + if len(args) == 1: + return True -def isexception(o): - if IInterface.providedBy(o): - if IException.isEqualOrExtendedBy(o): + elif args[0] == 'request': + if len(args) - len(defaults) == 1: return True - return ( - isinstance(o, Exception) or - (inspect.isclass(o) and (issubclass(o, Exception))) - ) + + return False + class ActionPredicate(object): action_name = 'action' @@ -3065,20 +3126,18 @@ def translator(msg): localizer = get_localizer(request) return localizer.translate(msg) -# b/c -def _map_view(view, registry, attr=None, renderer=None): - return DefaultViewMapper(registry=registry, attr=attr, - renderer=renderer)(view) - -# b/c -def requestonly(view, attr=None): - """ Return true of the class or callable accepts only a request argument, - as opposed to something that accepts context, request """ - return DefaultViewMapper(attr=attr).requestonly(view) - def is_response(ob): if ( hasattr(ob, 'app_iter') and hasattr(ob, 'headerlist') and hasattr(ob, 'status') ): return True return False +def isexception(o): + if IInterface.providedBy(o): + if IException.isEqualOrExtendedBy(o): + return True + return ( + isinstance(o, Exception) or + (inspect.isclass(o) and (issubclass(o, Exception))) + ) + diff --git a/pyramid/interfaces.py b/pyramid/interfaces.py index 10a324b28..14ff100b1 100644 --- a/pyramid/interfaces.py +++ b/pyramid/interfaces.py @@ -155,8 +155,19 @@ class IRouteRequest(Interface): class IAuthenticationPolicy(Interface): """ An object representing a Pyramid authentication policy. """ def authenticated_userid(request): - """ Return the authenticated userid or ``None`` if no - authenticated userid can be found. """ + """ Return the authenticated userid or ``None`` if no authenticated + userid can be found. This method of the policy should ensure that a + record exists in whatever persistent store is used related to the + user (the user should not have been deleted); if a record associated + with the current id does not exist in a persistent store, it should + return ``None``.""" + + def unauthenticated_userid(request): + """ Return the *unauthenticated* userid. This method performs the + same duty as ``authenticated_userid`` but is permitted to return the + userid based only on data present in the request; it neednt (and + shouldn't) check any persistent store to ensure that the user record + related to the request userid exists.""" def effective_principals(request): """ Return a sequence representing the effective principals @@ -501,14 +512,17 @@ class ISession(Interface): :meth:`pyramid.interfaces.ISesssion.flash` """ - def new_csrf_token(self): + def new_csrf_token(): """ Create and set into the session a new, random cross-site request forgery protection token. Return the token. It will be a string.""" - def get_csrf_token(self): - """ Get the CSRF token previously added to the session via - ``new_csrf_token``, and return the token. If no CSRF token exists, - the value returned will be ``None``. + def get_csrf_token(): + """ Return a random cross-site request forgery protection token. It + will be a string. If a token was previously added to the session via + ``new_csrf_token``, that token will be returned. If no CSRF token + was previously set into the session, ``new_csrf_token`` will be + called, which will create and set a token, and this token will be + returned. """ # mapping methods diff --git a/pyramid/paster.py b/pyramid/paster.py index 5efbae51c..5ac043c19 100644 --- a/pyramid/paster.py +++ b/pyramid/paster.py @@ -179,12 +179,10 @@ class PRoutesCommand(PCommand): print msg def command(self): - from pyramid.request import Request from pyramid.interfaces import IRouteRequest from pyramid.interfaces import IViewClassifier from pyramid.interfaces import IView from zope.interface import Interface - from zope.interface import providedBy config_file, section_name = self.args app = self.get_app(config_file, section_name, loadapp=self.loadapp[0]) registry = app.registry diff --git a/pyramid/paster_templates/alchemy/+package+/static/footerbg.png b/pyramid/paster_templates/alchemy/+package+/static/footerbg.png Binary files differnew file mode 100644 index 000000000..1fbc873da --- /dev/null +++ b/pyramid/paster_templates/alchemy/+package+/static/footerbg.png diff --git a/pyramid/paster_templates/alchemy/+package+/static/headerbg.png b/pyramid/paster_templates/alchemy/+package+/static/headerbg.png Binary files differnew file mode 100644 index 000000000..0596f2020 --- /dev/null +++ b/pyramid/paster_templates/alchemy/+package+/static/headerbg.png diff --git a/pyramid/paster_templates/alchemy/+package+/static/ie6.css b/pyramid/paster_templates/alchemy/+package+/static/ie6.css new file mode 100644 index 000000000..b7c8493d8 --- /dev/null +++ b/pyramid/paster_templates/alchemy/+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/alchemy/+package+/static/logo.png b/pyramid/paster_templates/alchemy/+package+/static/logo.png Binary files differdeleted file mode 100644 index 88f5d9865..000000000 --- a/pyramid/paster_templates/alchemy/+package+/static/logo.png +++ /dev/null diff --git a/pyramid/paster_templates/alchemy/+package+/static/middlebg.png b/pyramid/paster_templates/alchemy/+package+/static/middlebg.png Binary files differnew file mode 100644 index 000000000..2369cfb7d --- /dev/null +++ b/pyramid/paster_templates/alchemy/+package+/static/middlebg.png diff --git a/pyramid/paster_templates/alchemy/+package+/static/pylons.css b/pyramid/paster_templates/alchemy/+package+/static/pylons.css index c153be07f..fd1914d8d 100644 --- a/pyramid/paster_templates/alchemy/+package+/static/pylons.css +++ b/pyramid/paster_templates/alchemy/+package+/static/pylons.css @@ -4,34 +4,23 @@ body{line-height:1;} ol,ul{list-style:none;} blockquote,q{quotes:none;} blockquote:before,blockquote:after,q:before,q:after{content:'';content:none;} -/* remember to define focus styles! */ :focus{outline:0;} -/* remember to highlight inserts somehow! */ ins{text-decoration:none;} del{text-decoration:line-through;} -/* tables still need 'cellspacing="0"' in the markup */ table{border-collapse:collapse;border-spacing:0;} -/* restyling */ sub{vertical-align:sub;font-size:smaller;line-height:normal;} sup{vertical-align:super;font-size:smaller;line-height:normal;} -/* lists */ ul,menu,dir{display:block;list-style-type:disc;margin:1em 0;padding-left:40px;} ol{display:block;list-style-type:decimal-leading-zero;margin:1em 0;padding-left:40px;} li{display:list-item;} -/* nested lists have no top/bottom margins */ ul ul,ul ol,ul dir,ul menu,ul dl,ol ul,ol ol,ol dir,ol menu,ol dl,dir ul,dir ol,dir dir,dir menu,dir dl,menu ul,menu ol,menu dir,menu menu,menu dl,dl ul,dl ol,dl dir,dl menu,dl dl{margin-top:0;margin-bottom:0;} -/* 2 deep unordered lists use a circle */ ol ul,ul ul,menu ul,dir ul,ol menu,ul menu,menu menu,dir menu,ol dir,ul dir,menu dir,dir dir{list-style-type:circle;} -/* 3 deep (or more) unordered lists use a square */ ol ol ul,ol ul ul,ol menu ul,ol dir ul,ol ol menu,ol ul menu,ol menu menu,ol dir menu,ol ol dir,ol ul dir,ol menu dir,ol dir dir,ul ol ul,ul ul ul,ul menu ul,ul dir ul,ul ol menu,ul ul menu,ul menu menu,ul dir menu,ul ol dir,ul ul dir,ul menu dir,ul dir dir,menu ol ul,menu ul ul,menu menu ul,menu dir ul,menu ol menu,menu ul menu,menu menu menu,menu dir menu,menu ol dir,menu ul dir,menu menu dir,menu dir dir,dir ol ul,dir ul ul,dir menu ul,dir dir ul,dir ol menu,dir ul menu,dir menu menu,dir dir menu,dir ol dir,dir ul dir,dir menu dir,dir dir dir{list-style-type:square;} .hidden{display:none;} p{line-height:1.5em;} -h1{font-size:1.75em;/* 28px */ -line-height:1.7em;font-family:helvetica,verdana;} -h2{font-size:1.5em;/* 24px */ -line-height:1.7em;font-family:helvetica,verdana;} -h3{font-size:1.25em;/* 20px */ -line-height:1.7em;font-family:helvetica,verdana;} +h1{font-size:1.75em;line-height:1.7em;font-family:helvetica,verdana;} +h2{font-size:1.5em;line-height:1.7em;font-family:helvetica,verdana;} +h3{font-size:1.25em;line-height:1.7em;font-family:helvetica,verdana;} h4{font-size:1em;line-height:1.7em;font-family:helvetica,verdana;} html,body{width:100%;height:100%;} body{margin:0;padding:0;background-color:#ffffff;position:relative;font:16px/24px "Nobile","Lucida Grande",Lucida,Verdana,sans-serif;} @@ -42,23 +31,26 @@ 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,#top-small,#bottom{width:100%;} +#top{color:#000000;height:230px;background:#ffffff url(headerbg.png) repeat-x 0 top;position:relative;} +#top-small{color:#000000;height:60px;background:#ffffff url(headerbg.png) repeat-x 0 top;position:relative;} +#bottom{color:#222;background-color:#ffffff;} +.top,.top-small,.middle,.bottom{width:750px;margin-right:auto;margin-left:auto;} +.top{padding-top:40px;} +.top-small{padding-top:10px;} +#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 +59,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],input[type=password]{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/alchemy/+package+/static/pyramid-small.png b/pyramid/paster_templates/alchemy/+package+/static/pyramid-small.png Binary files differnew file mode 100644 index 000000000..a5bc0ade7 --- /dev/null +++ b/pyramid/paster_templates/alchemy/+package+/static/pyramid-small.png diff --git a/pyramid/paster_templates/alchemy/+package+/static/pyramid.png b/pyramid/paster_templates/alchemy/+package+/static/pyramid.png Binary files differnew file mode 100644 index 000000000..347e05549 --- /dev/null +++ b/pyramid/paster_templates/alchemy/+package+/static/pyramid.png diff --git a/pyramid/paster_templates/alchemy/+package+/static/transparent.gif b/pyramid/paster_templates/alchemy/+package+/static/transparent.gif Binary files differnew file mode 100644 index 000000000..0341802e5 --- /dev/null +++ b/pyramid/paster_templates/alchemy/+package+/static/transparent.gif diff --git a/pyramid/paster_templates/alchemy/+package+/templates/model.pt b/pyramid/paster_templates/alchemy/+package+/templates/model.pt_tmpl index 2d54d969e..1fd3c0b20 100644 --- a/pyramid/paster_templates/alchemy/+package+/templates/model.pt +++ b/pyramid/paster_templates/alchemy/+package+/templates/model.pt_tmpl @@ -5,23 +5,23 @@ <meta http-equiv="Content-Type" content="text/html;charset=UTF-8"/> <meta name="keywords" content="python web application" /> <meta name="description" content="pyramid web application" /> - <link rel="shortcut icon" href="${request.application_url}/static/favicon.ico" /> - <link rel="stylesheet" href="${request.application_url}/static/pylons.css" type="text/css" media="screen" charset="utf-8" /> + <link rel="shortcut icon" href="${request.static_url('{{package}}:static/favicon.ico')}" /> + <link rel="stylesheet" href="${request.static_url('{{package}}:static/pylons.css')}" type="text/css" media="screen" charset="utf-8" /> + <link rel="stylesheet" href="http://fonts.googleapis.com/css?family=Neuton&subset=latin" type="text/css" media="screen" charset="utf-8" /> <link rel="stylesheet" href="http://fonts.googleapis.com/css?family=Nobile:regular,italic,bold,bolditalic&subset=latin" type="text/css" media="screen" charset="utf-8" /> - <!--[if !IE 7]> - <style type="text/css"> - #wrap {display:table;height:100%} - </style> + <!--[if lte IE 6]> + <link rel="stylesheet" href="${request.static_url('{{package}}:static/ie6.css')}" type="text/css" media="screen" charset="utf-8" /> <![endif]--> </head> <body> <div id="wrap"> - <div id="header"> - <div class="header">The Pyramid Web Application Development Framework</div> - </div> <div id="top"> <div class="top align-center"> - <img src="${request.application_url}/static/logo.png" width="300" height="80"/> + <div><img src="${request.static_url('{{package}}:static/pyramid.png')}" width="750" height="169" alt="pyramid"/></div> + </div> + </div> + <div id="middle"> + <div class="middle align-center"> <p class="app-welcome"> Welcome to <span class="app-name">${project}</span>, an application generated by<br/> the Pyramid web application development framework. @@ -31,10 +31,10 @@ <div id="bottom"> <div class="bottom"> <div id="left" class="align-right"> - <h3>Search Pyramid documentation</h3> + <h2>Search documentation</h2> <form method="get" action="http://docs.pylonshq.com/pyramid/dev/search.html"> <input type="text" id="q" name="q" value="" /> - <input type="submit" id="x" value="Search" /> + <input type="submit" id="x" value="Go" /> </form> <br/> <p> @@ -44,15 +44,12 @@ </p> </div> <div id="right" class="align-left"> - <h3>Pyramid links</h3> + <h2>Pyramid links</h2> <ul class="links"> <li> <a href="http://pylonshq.com">Pylons Website</a> </li> <li> - <a href="http://docs.pylonshq.com/">The Pylons Project Documentation</a> - </li> - <li> <a href="http://docs.pylonshq.com/pyramid/dev/#narrative-documentation">Narrative Documentation</a> </li> <li> @@ -79,7 +76,7 @@ </div> </div> <div id="footer"> - <div class="footer">© Copyright 2008-2010, Agendaless Consulting.</div> + <div class="footer">© Copyright 2008-2011, Agendaless Consulting.</div> </div> </body> </html>
\ No newline at end of file diff --git a/pyramid/paster_templates/alchemy/+package+/templates/root.pt b/pyramid/paster_templates/alchemy/+package+/templates/root.pt_tmpl index 7dda6a033..ca05896ae 100644 --- a/pyramid/paster_templates/alchemy/+package+/templates/root.pt +++ b/pyramid/paster_templates/alchemy/+package+/templates/root.pt_tmpl @@ -5,23 +5,23 @@ <meta http-equiv="Content-Type" content="text/html;charset=UTF-8"/> <meta name="keywords" content="python web application" /> <meta name="description" content="pyramid web application" /> - <link rel="shortcut icon" href="${request.application_url}/static/favicon.ico" /> - <link rel="stylesheet" href="${request.application_url}/static/pylons.css" type="text/css" media="screen" charset="utf-8" /> + <link rel="shortcut icon" href="${request.static_url('{{package}}:static/favicon.ico')}" /> + <link rel="stylesheet" href="${request.static_url('{{package}}:static/pylons.css')}" type="text/css" media="screen" charset="utf-8" /> + <link rel="stylesheet" href="http://fonts.googleapis.com/css?family=Neuton&subset=latin" type="text/css" media="screen" charset="utf-8" /> <link rel="stylesheet" href="http://fonts.googleapis.com/css?family=Nobile:regular,italic,bold,bolditalic&subset=latin" type="text/css" media="screen" charset="utf-8" /> - <!--[if !IE 7]> - <style type="text/css"> - #wrap {display:table;height:100%} - </style> + <!--[if lte IE 6]> + <link rel="stylesheet" href="${request.static_url('{{package}}:static/ie6.css')}" type="text/css" media="screen" charset="utf-8" /> <![endif]--> </head> <body> <div id="wrap"> - <div id="header"> - <div class="header">The Pyramid Web Application Development Framework</div> - </div> <div id="top"> <div class="top align-center"> - <img src="${request.application_url}/static/logo.png" width="300" height="80"/> + <div><img src="${request.static_url('{{package}}:static/pyramid.png')}" width="750" height="169" alt="pyramid"/></div> + </div> + </div> + <div id="middle"> + <div class="middle align-center"> <p class="app-welcome"> Welcome to <span class="app-name">${project}</span>, an application generated by<br/> the Pyramid web application development framework. @@ -31,10 +31,10 @@ <div id="bottom"> <div class="bottom"> <div id="left" class="align-right"> - <h3>Search Pyramid documentation</h3> + <h2>Search documentation</h2> <form method="get" action="http://docs.pylonshq.com/pyramid/dev/search.html"> <input type="text" id="q" name="q" value="" /> - <input type="submit" id="x" value="Search" /> + <input type="submit" id="x" value="Go" /> </form> <br/> <p tal:repeat="item items"> @@ -42,15 +42,12 @@ </p> </div> <div id="right" class="align-left"> - <h3>Pyramid links</h3> + <h2>Pyramid links</h2> <ul class="links"> <li> <a href="http://pylonshq.com">Pylons Website</a> </li> <li> - <a href="http://docs.pylonshq.com/">The Pylons Project Documentation</a> - </li> - <li> <a href="http://docs.pylonshq.com/pyramid/dev/#narrative-documentation">Narrative Documentation</a> </li> <li> @@ -77,7 +74,7 @@ </div> </div> <div id="footer"> - <div class="footer">© Copyright 2008-2010, Agendaless Consulting.</div> + <div class="footer">© Copyright 2008-2011, Agendaless Consulting.</div> </div> </body> </html>
\ No newline at end of file diff --git a/pyramid/paster_templates/pylons_basic/+package+/static/footerbg.png b/pyramid/paster_templates/pylons_basic/+package+/static/footerbg.png Binary files differnew file mode 100644 index 000000000..1fbc873da --- /dev/null +++ b/pyramid/paster_templates/pylons_basic/+package+/static/footerbg.png diff --git a/pyramid/paster_templates/pylons_basic/+package+/static/headerbg.png b/pyramid/paster_templates/pylons_basic/+package+/static/headerbg.png Binary files differnew file mode 100644 index 000000000..0596f2020 --- /dev/null +++ b/pyramid/paster_templates/pylons_basic/+package+/static/headerbg.png diff --git a/pyramid/paster_templates/pylons_basic/+package+/static/ie6.css b/pyramid/paster_templates/pylons_basic/+package+/static/ie6.css new file mode 100644 index 000000000..b7c8493d8 --- /dev/null +++ b/pyramid/paster_templates/pylons_basic/+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/pylons_basic/+package+/static/logo.png b/pyramid/paster_templates/pylons_basic/+package+/static/logo.png Binary files differdeleted file mode 100644 index 88f5d9865..000000000 --- a/pyramid/paster_templates/pylons_basic/+package+/static/logo.png +++ /dev/null diff --git a/pyramid/paster_templates/pylons_basic/+package+/static/middlebg.png b/pyramid/paster_templates/pylons_basic/+package+/static/middlebg.png Binary files differnew file mode 100644 index 000000000..2369cfb7d --- /dev/null +++ b/pyramid/paster_templates/pylons_basic/+package+/static/middlebg.png diff --git a/pyramid/paster_templates/pylons_basic/+package+/static/pylons.css b/pyramid/paster_templates/pylons_basic/+package+/static/pylons.css index c153be07f..fd1914d8d 100644 --- a/pyramid/paster_templates/pylons_basic/+package+/static/pylons.css +++ b/pyramid/paster_templates/pylons_basic/+package+/static/pylons.css @@ -4,34 +4,23 @@ body{line-height:1;} ol,ul{list-style:none;} blockquote,q{quotes:none;} blockquote:before,blockquote:after,q:before,q:after{content:'';content:none;} -/* remember to define focus styles! */ :focus{outline:0;} -/* remember to highlight inserts somehow! */ ins{text-decoration:none;} del{text-decoration:line-through;} -/* tables still need 'cellspacing="0"' in the markup */ table{border-collapse:collapse;border-spacing:0;} -/* restyling */ sub{vertical-align:sub;font-size:smaller;line-height:normal;} sup{vertical-align:super;font-size:smaller;line-height:normal;} -/* lists */ ul,menu,dir{display:block;list-style-type:disc;margin:1em 0;padding-left:40px;} ol{display:block;list-style-type:decimal-leading-zero;margin:1em 0;padding-left:40px;} li{display:list-item;} -/* nested lists have no top/bottom margins */ ul ul,ul ol,ul dir,ul menu,ul dl,ol ul,ol ol,ol dir,ol menu,ol dl,dir ul,dir ol,dir dir,dir menu,dir dl,menu ul,menu ol,menu dir,menu menu,menu dl,dl ul,dl ol,dl dir,dl menu,dl dl{margin-top:0;margin-bottom:0;} -/* 2 deep unordered lists use a circle */ ol ul,ul ul,menu ul,dir ul,ol menu,ul menu,menu menu,dir menu,ol dir,ul dir,menu dir,dir dir{list-style-type:circle;} -/* 3 deep (or more) unordered lists use a square */ ol ol ul,ol ul ul,ol menu ul,ol dir ul,ol ol menu,ol ul menu,ol menu menu,ol dir menu,ol ol dir,ol ul dir,ol menu dir,ol dir dir,ul ol ul,ul ul ul,ul menu ul,ul dir ul,ul ol menu,ul ul menu,ul menu menu,ul dir menu,ul ol dir,ul ul dir,ul menu dir,ul dir dir,menu ol ul,menu ul ul,menu menu ul,menu dir ul,menu ol menu,menu ul menu,menu menu menu,menu dir menu,menu ol dir,menu ul dir,menu menu dir,menu dir dir,dir ol ul,dir ul ul,dir menu ul,dir dir ul,dir ol menu,dir ul menu,dir menu menu,dir dir menu,dir ol dir,dir ul dir,dir menu dir,dir dir dir{list-style-type:square;} .hidden{display:none;} p{line-height:1.5em;} -h1{font-size:1.75em;/* 28px */ -line-height:1.7em;font-family:helvetica,verdana;} -h2{font-size:1.5em;/* 24px */ -line-height:1.7em;font-family:helvetica,verdana;} -h3{font-size:1.25em;/* 20px */ -line-height:1.7em;font-family:helvetica,verdana;} +h1{font-size:1.75em;line-height:1.7em;font-family:helvetica,verdana;} +h2{font-size:1.5em;line-height:1.7em;font-family:helvetica,verdana;} +h3{font-size:1.25em;line-height:1.7em;font-family:helvetica,verdana;} h4{font-size:1em;line-height:1.7em;font-family:helvetica,verdana;} html,body{width:100%;height:100%;} body{margin:0;padding:0;background-color:#ffffff;position:relative;font:16px/24px "Nobile","Lucida Grande",Lucida,Verdana,sans-serif;} @@ -42,23 +31,26 @@ 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,#top-small,#bottom{width:100%;} +#top{color:#000000;height:230px;background:#ffffff url(headerbg.png) repeat-x 0 top;position:relative;} +#top-small{color:#000000;height:60px;background:#ffffff url(headerbg.png) repeat-x 0 top;position:relative;} +#bottom{color:#222;background-color:#ffffff;} +.top,.top-small,.middle,.bottom{width:750px;margin-right:auto;margin-left:auto;} +.top{padding-top:40px;} +.top-small{padding-top:10px;} +#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 +59,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],input[type=password]{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/pylons_basic/+package+/static/pyramid-small.png b/pyramid/paster_templates/pylons_basic/+package+/static/pyramid-small.png Binary files differnew file mode 100644 index 000000000..a5bc0ade7 --- /dev/null +++ b/pyramid/paster_templates/pylons_basic/+package+/static/pyramid-small.png diff --git a/pyramid/paster_templates/pylons_basic/+package+/static/pyramid.png b/pyramid/paster_templates/pylons_basic/+package+/static/pyramid.png Binary files differnew file mode 100644 index 000000000..347e05549 --- /dev/null +++ b/pyramid/paster_templates/pylons_basic/+package+/static/pyramid.png diff --git a/pyramid/paster_templates/pylons_basic/+package+/static/transparent.gif b/pyramid/paster_templates/pylons_basic/+package+/static/transparent.gif Binary files differnew file mode 100644 index 000000000..0341802e5 --- /dev/null +++ b/pyramid/paster_templates/pylons_basic/+package+/static/transparent.gif diff --git a/pyramid/paster_templates/starter/+package+/templates/mytemplate.pt b/pyramid/paster_templates/pylons_basic/+package+/templates/mytemplate.mako_tmpl index 02fc00eeb..a658ee2c9 100644 --- a/pyramid/paster_templates/starter/+package+/templates/mytemplate.pt +++ b/pyramid/paster_templates/pylons_basic/+package+/templates/mytemplate.mako_tmpl @@ -5,19 +5,19 @@ <meta http-equiv="Content-Type" content="text/html;charset=UTF-8"/> <meta name="keywords" content="python web application" /> <meta name="description" content="pyramid web application" /> - <link rel="shortcut icon" href="${request.application_url}/static/favicon.ico" /> - <link rel="stylesheet" href="${request.application_url}/static/pylons.css" type="text/css" media="screen" charset="utf-8" /> - <link href="http://fonts.googleapis.com/css?family=Neuton&subset=latin" rel="stylesheet" type="text/css" media="screen" charset="utf-8" /> + <link rel="shortcut icon" href="${request.static_url('{{package}}:static/favicon.ico')}" /> + <link rel="stylesheet" href="${request.static_url('{{package}}:static/pylons.css')}" type="text/css" media="screen" charset="utf-8" /> + <link rel="stylesheet" href="http://fonts.googleapis.com/css?family=Neuton&subset=latin" type="text/css" media="screen" charset="utf-8" /> <link rel="stylesheet" href="http://fonts.googleapis.com/css?family=Nobile:regular,italic,bold,bolditalic&subset=latin" type="text/css" media="screen" charset="utf-8" /> <!--[if lte IE 6]> - <link rel="stylesheet" href="${request.application_url}/static/ie6.css" type="text/css" media="screen" charset="utf-8" /> + <link rel="stylesheet" href="${request.static_url('{{package}}:static/ie6.css')}" type="text/css" media="screen" charset="utf-8" /> <![endif]--> </head> <body> <div id="wrap"> <div id="top"> <div class="top align-center"> - <div><img src="${request.application_url}/static/pyramid.png" width="750" height="169" alt="pyramid"/></div> + <div><img src="${request.static_url('{{package}}:static/pyramid.png')}" width="750" height="169" alt="pyramid"/></div> </div> </div> <div id="middle"> @@ -70,7 +70,7 @@ </div> </div> <div id="footer"> - <div class="footer">© Copyright 2008-2010, Agendaless Consulting.</div> + <div class="footer">© Copyright 2008-2011, Agendaless Consulting.</div> </div> </body> </html>
\ No newline at end of file diff --git a/pyramid/paster_templates/pylons_minimal/+package+/static/footerbg.png b/pyramid/paster_templates/pylons_minimal/+package+/static/footerbg.png Binary files differnew file mode 100644 index 000000000..1fbc873da --- /dev/null +++ b/pyramid/paster_templates/pylons_minimal/+package+/static/footerbg.png diff --git a/pyramid/paster_templates/pylons_minimal/+package+/static/headerbg.png b/pyramid/paster_templates/pylons_minimal/+package+/static/headerbg.png Binary files differnew file mode 100644 index 000000000..0596f2020 --- /dev/null +++ b/pyramid/paster_templates/pylons_minimal/+package+/static/headerbg.png diff --git a/pyramid/paster_templates/pylons_minimal/+package+/static/ie6.css b/pyramid/paster_templates/pylons_minimal/+package+/static/ie6.css new file mode 100644 index 000000000..b7c8493d8 --- /dev/null +++ b/pyramid/paster_templates/pylons_minimal/+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/pylons_minimal/+package+/static/logo.png b/pyramid/paster_templates/pylons_minimal/+package+/static/logo.png Binary files differdeleted file mode 100644 index 88f5d9865..000000000 --- a/pyramid/paster_templates/pylons_minimal/+package+/static/logo.png +++ /dev/null diff --git a/pyramid/paster_templates/pylons_minimal/+package+/static/middlebg.png b/pyramid/paster_templates/pylons_minimal/+package+/static/middlebg.png Binary files differnew file mode 100644 index 000000000..2369cfb7d --- /dev/null +++ b/pyramid/paster_templates/pylons_minimal/+package+/static/middlebg.png diff --git a/pyramid/paster_templates/pylons_minimal/+package+/static/pylons.css b/pyramid/paster_templates/pylons_minimal/+package+/static/pylons.css index c153be07f..fd1914d8d 100644 --- a/pyramid/paster_templates/pylons_minimal/+package+/static/pylons.css +++ b/pyramid/paster_templates/pylons_minimal/+package+/static/pylons.css @@ -4,34 +4,23 @@ body{line-height:1;} ol,ul{list-style:none;} blockquote,q{quotes:none;} blockquote:before,blockquote:after,q:before,q:after{content:'';content:none;} -/* remember to define focus styles! */ :focus{outline:0;} -/* remember to highlight inserts somehow! */ ins{text-decoration:none;} del{text-decoration:line-through;} -/* tables still need 'cellspacing="0"' in the markup */ table{border-collapse:collapse;border-spacing:0;} -/* restyling */ sub{vertical-align:sub;font-size:smaller;line-height:normal;} sup{vertical-align:super;font-size:smaller;line-height:normal;} -/* lists */ ul,menu,dir{display:block;list-style-type:disc;margin:1em 0;padding-left:40px;} ol{display:block;list-style-type:decimal-leading-zero;margin:1em 0;padding-left:40px;} li{display:list-item;} -/* nested lists have no top/bottom margins */ ul ul,ul ol,ul dir,ul menu,ul dl,ol ul,ol ol,ol dir,ol menu,ol dl,dir ul,dir ol,dir dir,dir menu,dir dl,menu ul,menu ol,menu dir,menu menu,menu dl,dl ul,dl ol,dl dir,dl menu,dl dl{margin-top:0;margin-bottom:0;} -/* 2 deep unordered lists use a circle */ ol ul,ul ul,menu ul,dir ul,ol menu,ul menu,menu menu,dir menu,ol dir,ul dir,menu dir,dir dir{list-style-type:circle;} -/* 3 deep (or more) unordered lists use a square */ ol ol ul,ol ul ul,ol menu ul,ol dir ul,ol ol menu,ol ul menu,ol menu menu,ol dir menu,ol ol dir,ol ul dir,ol menu dir,ol dir dir,ul ol ul,ul ul ul,ul menu ul,ul dir ul,ul ol menu,ul ul menu,ul menu menu,ul dir menu,ul ol dir,ul ul dir,ul menu dir,ul dir dir,menu ol ul,menu ul ul,menu menu ul,menu dir ul,menu ol menu,menu ul menu,menu menu menu,menu dir menu,menu ol dir,menu ul dir,menu menu dir,menu dir dir,dir ol ul,dir ul ul,dir menu ul,dir dir ul,dir ol menu,dir ul menu,dir menu menu,dir dir menu,dir ol dir,dir ul dir,dir menu dir,dir dir dir{list-style-type:square;} .hidden{display:none;} p{line-height:1.5em;} -h1{font-size:1.75em;/* 28px */ -line-height:1.7em;font-family:helvetica,verdana;} -h2{font-size:1.5em;/* 24px */ -line-height:1.7em;font-family:helvetica,verdana;} -h3{font-size:1.25em;/* 20px */ -line-height:1.7em;font-family:helvetica,verdana;} +h1{font-size:1.75em;line-height:1.7em;font-family:helvetica,verdana;} +h2{font-size:1.5em;line-height:1.7em;font-family:helvetica,verdana;} +h3{font-size:1.25em;line-height:1.7em;font-family:helvetica,verdana;} h4{font-size:1em;line-height:1.7em;font-family:helvetica,verdana;} html,body{width:100%;height:100%;} body{margin:0;padding:0;background-color:#ffffff;position:relative;font:16px/24px "Nobile","Lucida Grande",Lucida,Verdana,sans-serif;} @@ -42,23 +31,26 @@ 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,#top-small,#bottom{width:100%;} +#top{color:#000000;height:230px;background:#ffffff url(headerbg.png) repeat-x 0 top;position:relative;} +#top-small{color:#000000;height:60px;background:#ffffff url(headerbg.png) repeat-x 0 top;position:relative;} +#bottom{color:#222;background-color:#ffffff;} +.top,.top-small,.middle,.bottom{width:750px;margin-right:auto;margin-left:auto;} +.top{padding-top:40px;} +.top-small{padding-top:10px;} +#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 +59,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],input[type=password]{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/pylons_minimal/+package+/static/pyramid-small.png b/pyramid/paster_templates/pylons_minimal/+package+/static/pyramid-small.png Binary files differnew file mode 100644 index 000000000..a5bc0ade7 --- /dev/null +++ b/pyramid/paster_templates/pylons_minimal/+package+/static/pyramid-small.png diff --git a/pyramid/paster_templates/pylons_minimal/+package+/static/pyramid.png b/pyramid/paster_templates/pylons_minimal/+package+/static/pyramid.png Binary files differnew file mode 100644 index 000000000..347e05549 --- /dev/null +++ b/pyramid/paster_templates/pylons_minimal/+package+/static/pyramid.png diff --git a/pyramid/paster_templates/pylons_minimal/+package+/static/transparent.gif b/pyramid/paster_templates/pylons_minimal/+package+/static/transparent.gif Binary files differnew file mode 100644 index 000000000..0341802e5 --- /dev/null +++ b/pyramid/paster_templates/pylons_minimal/+package+/static/transparent.gif diff --git a/pyramid/paster_templates/pylons_basic/+package+/templates/mytemplate.mako b/pyramid/paster_templates/pylons_minimal/+package+/templates/mytemplate.mako_tmpl index 63ec0172a..a658ee2c9 100644 --- a/pyramid/paster_templates/pylons_basic/+package+/templates/mytemplate.mako +++ b/pyramid/paster_templates/pylons_minimal/+package+/templates/mytemplate.mako_tmpl @@ -5,23 +5,23 @@ <meta http-equiv="Content-Type" content="text/html;charset=UTF-8"/> <meta name="keywords" content="python web application" /> <meta name="description" content="pyramid web application" /> - <link rel="shortcut icon" href="${request.application_url}/static/favicon.ico" /> - <link rel="stylesheet" href="${request.application_url}/static/pylons.css" type="text/css" media="screen" charset="utf-8" /> + <link rel="shortcut icon" href="${request.static_url('{{package}}:static/favicon.ico')}" /> + <link rel="stylesheet" href="${request.static_url('{{package}}:static/pylons.css')}" type="text/css" media="screen" charset="utf-8" /> + <link rel="stylesheet" href="http://fonts.googleapis.com/css?family=Neuton&subset=latin" type="text/css" media="screen" charset="utf-8" /> <link rel="stylesheet" href="http://fonts.googleapis.com/css?family=Nobile:regular,italic,bold,bolditalic&subset=latin" type="text/css" media="screen" charset="utf-8" /> - <!--[if !IE 7]> - <style type="text/css"> - #wrap {display:table;height:100%} - </style> + <!--[if lte IE 6]> + <link rel="stylesheet" href="${request.static_url('{{package}}:static/ie6.css')}" type="text/css" media="screen" charset="utf-8" /> <![endif]--> </head> <body> <div id="wrap"> - <div id="header"> - <div class="header">The Pyramid Web Application Development Framework</div> - </div> <div id="top"> <div class="top align-center"> - <img src="${request.application_url}/static/logo.png" width="300" height="80"/> + <div><img src="${request.static_url('{{package}}:static/pyramid.png')}" width="750" height="169" alt="pyramid"/></div> + </div> + </div> + <div id="middle"> + <div class="middle align-center"> <p class="app-welcome"> Welcome to <span class="app-name">${project}</span>, an application generated by<br/> the Pyramid web application development framework. @@ -31,14 +31,14 @@ <div id="bottom"> <div class="bottom"> <div id="left" class="align-right"> - <h3>Search Pyramid documentation</h3> + <h2>Search documentation</h2> <form method="get" action="http://docs.pylonshq.com/pyramid/dev/search.html"> <input type="text" id="q" name="q" value="" /> - <input type="submit" id="x" value="Search" /> + <input type="submit" id="x" value="Go" /> </form> </div> <div id="right" class="align-left"> - <h3>Pyramid links</h3> + <h2>Pyramid links</h2> <ul class="links"> <li> <a href="http://pylonshq.com">Pylons Website</a> @@ -47,9 +47,6 @@ <a href="http://docs.pylonshq.com/pyramid/dev/#narrative-documentation">Narrative Documentation</a> </li> <li> - <a href="http://docs.pylonshq.com/pyramid/dev/#narrative-documentation">Narrative Documentation</a> - </li> - <li> <a href="http://docs.pylonshq.com/pyramid/dev/#api-documentation">API Documentation</a> </li> <li> @@ -73,7 +70,7 @@ </div> </div> <div id="footer"> - <div class="footer">© Copyright 2008-2010, Agendaless Consulting.</div> + <div class="footer">© Copyright 2008-2011, Agendaless Consulting.</div> </div> </body> </html>
\ No newline at end of file diff --git a/pyramid/paster_templates/pylons_sqla/+package+/static/footerbg.png b/pyramid/paster_templates/pylons_sqla/+package+/static/footerbg.png Binary files differnew file mode 100644 index 000000000..1fbc873da --- /dev/null +++ b/pyramid/paster_templates/pylons_sqla/+package+/static/footerbg.png diff --git a/pyramid/paster_templates/pylons_sqla/+package+/static/headerbg.png b/pyramid/paster_templates/pylons_sqla/+package+/static/headerbg.png Binary files differnew file mode 100644 index 000000000..0596f2020 --- /dev/null +++ b/pyramid/paster_templates/pylons_sqla/+package+/static/headerbg.png diff --git a/pyramid/paster_templates/pylons_sqla/+package+/static/ie6.css b/pyramid/paster_templates/pylons_sqla/+package+/static/ie6.css new file mode 100644 index 000000000..b7c8493d8 --- /dev/null +++ b/pyramid/paster_templates/pylons_sqla/+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/pylons_sqla/+package+/static/logo.png b/pyramid/paster_templates/pylons_sqla/+package+/static/logo.png Binary files differdeleted file mode 100644 index 88f5d9865..000000000 --- a/pyramid/paster_templates/pylons_sqla/+package+/static/logo.png +++ /dev/null diff --git a/pyramid/paster_templates/pylons_sqla/+package+/static/middlebg.png b/pyramid/paster_templates/pylons_sqla/+package+/static/middlebg.png Binary files differnew file mode 100644 index 000000000..2369cfb7d --- /dev/null +++ b/pyramid/paster_templates/pylons_sqla/+package+/static/middlebg.png diff --git a/pyramid/paster_templates/pylons_sqla/+package+/static/pylons.css b/pyramid/paster_templates/pylons_sqla/+package+/static/pylons.css index c153be07f..fd1914d8d 100644 --- a/pyramid/paster_templates/pylons_sqla/+package+/static/pylons.css +++ b/pyramid/paster_templates/pylons_sqla/+package+/static/pylons.css @@ -4,34 +4,23 @@ body{line-height:1;} ol,ul{list-style:none;} blockquote,q{quotes:none;} blockquote:before,blockquote:after,q:before,q:after{content:'';content:none;} -/* remember to define focus styles! */ :focus{outline:0;} -/* remember to highlight inserts somehow! */ ins{text-decoration:none;} del{text-decoration:line-through;} -/* tables still need 'cellspacing="0"' in the markup */ table{border-collapse:collapse;border-spacing:0;} -/* restyling */ sub{vertical-align:sub;font-size:smaller;line-height:normal;} sup{vertical-align:super;font-size:smaller;line-height:normal;} -/* lists */ ul,menu,dir{display:block;list-style-type:disc;margin:1em 0;padding-left:40px;} ol{display:block;list-style-type:decimal-leading-zero;margin:1em 0;padding-left:40px;} li{display:list-item;} -/* nested lists have no top/bottom margins */ ul ul,ul ol,ul dir,ul menu,ul dl,ol ul,ol ol,ol dir,ol menu,ol dl,dir ul,dir ol,dir dir,dir menu,dir dl,menu ul,menu ol,menu dir,menu menu,menu dl,dl ul,dl ol,dl dir,dl menu,dl dl{margin-top:0;margin-bottom:0;} -/* 2 deep unordered lists use a circle */ ol ul,ul ul,menu ul,dir ul,ol menu,ul menu,menu menu,dir menu,ol dir,ul dir,menu dir,dir dir{list-style-type:circle;} -/* 3 deep (or more) unordered lists use a square */ ol ol ul,ol ul ul,ol menu ul,ol dir ul,ol ol menu,ol ul menu,ol menu menu,ol dir menu,ol ol dir,ol ul dir,ol menu dir,ol dir dir,ul ol ul,ul ul ul,ul menu ul,ul dir ul,ul ol menu,ul ul menu,ul menu menu,ul dir menu,ul ol dir,ul ul dir,ul menu dir,ul dir dir,menu ol ul,menu ul ul,menu menu ul,menu dir ul,menu ol menu,menu ul menu,menu menu menu,menu dir menu,menu ol dir,menu ul dir,menu menu dir,menu dir dir,dir ol ul,dir ul ul,dir menu ul,dir dir ul,dir ol menu,dir ul menu,dir menu menu,dir dir menu,dir ol dir,dir ul dir,dir menu dir,dir dir dir{list-style-type:square;} .hidden{display:none;} p{line-height:1.5em;} -h1{font-size:1.75em;/* 28px */ -line-height:1.7em;font-family:helvetica,verdana;} -h2{font-size:1.5em;/* 24px */ -line-height:1.7em;font-family:helvetica,verdana;} -h3{font-size:1.25em;/* 20px */ -line-height:1.7em;font-family:helvetica,verdana;} +h1{font-size:1.75em;line-height:1.7em;font-family:helvetica,verdana;} +h2{font-size:1.5em;line-height:1.7em;font-family:helvetica,verdana;} +h3{font-size:1.25em;line-height:1.7em;font-family:helvetica,verdana;} h4{font-size:1em;line-height:1.7em;font-family:helvetica,verdana;} html,body{width:100%;height:100%;} body{margin:0;padding:0;background-color:#ffffff;position:relative;font:16px/24px "Nobile","Lucida Grande",Lucida,Verdana,sans-serif;} @@ -42,23 +31,26 @@ 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,#top-small,#bottom{width:100%;} +#top{color:#000000;height:230px;background:#ffffff url(headerbg.png) repeat-x 0 top;position:relative;} +#top-small{color:#000000;height:60px;background:#ffffff url(headerbg.png) repeat-x 0 top;position:relative;} +#bottom{color:#222;background-color:#ffffff;} +.top,.top-small,.middle,.bottom{width:750px;margin-right:auto;margin-left:auto;} +.top{padding-top:40px;} +.top-small{padding-top:10px;} +#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 +59,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],input[type=password]{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/pylons_sqla/+package+/static/pyramid-small.png b/pyramid/paster_templates/pylons_sqla/+package+/static/pyramid-small.png Binary files differnew file mode 100644 index 000000000..a5bc0ade7 --- /dev/null +++ b/pyramid/paster_templates/pylons_sqla/+package+/static/pyramid-small.png diff --git a/pyramid/paster_templates/pylons_sqla/+package+/static/pyramid.png b/pyramid/paster_templates/pylons_sqla/+package+/static/pyramid.png Binary files differnew file mode 100644 index 000000000..347e05549 --- /dev/null +++ b/pyramid/paster_templates/pylons_sqla/+package+/static/pyramid.png diff --git a/pyramid/paster_templates/pylons_sqla/+package+/static/transparent.gif b/pyramid/paster_templates/pylons_sqla/+package+/static/transparent.gif Binary files differnew file mode 100644 index 000000000..0341802e5 --- /dev/null +++ b/pyramid/paster_templates/pylons_sqla/+package+/static/transparent.gif diff --git a/pyramid/paster_templates/pylons_sqla/+package+/templates/mytemplate.mako b/pyramid/paster_templates/pylons_sqla/+package+/templates/mytemplate.mako_tmpl index 8b65d6a2b..9130f6da8 100644 --- a/pyramid/paster_templates/pylons_sqla/+package+/templates/mytemplate.mako +++ b/pyramid/paster_templates/pylons_sqla/+package+/templates/mytemplate.mako_tmpl @@ -5,23 +5,23 @@ <meta http-equiv="Content-Type" content="text/html;charset=UTF-8"/> <meta name="keywords" content="python web application" /> <meta name="description" content="pyramid web application" /> - <link rel="shortcut icon" href="${request.application_url}/static/favicon.ico" /> - <link rel="stylesheet" href="${request.application_url}/static/pylons.css" type="text/css" media="screen" charset="utf-8" /> + <link rel="shortcut icon" href="${request.static_url('{{package}}:static/favicon.ico')}" /> + <link rel="stylesheet" href="${request.static_url('{{package}}:static/pylons.css')}" type="text/css" media="screen" charset="utf-8" /> + <link rel="stylesheet" href="http://fonts.googleapis.com/css?family=Neuton&subset=latin" type="text/css" media="screen" charset="utf-8" /> <link rel="stylesheet" href="http://fonts.googleapis.com/css?family=Nobile:regular,italic,bold,bolditalic&subset=latin" type="text/css" media="screen" charset="utf-8" /> - <!--[if !IE 7]> - <style type="text/css"> - #wrap {display:table;height:100%} - </style> + <!--[if lte IE 6]> + <link rel="stylesheet" href="${request.static_url('{{package}}:static/ie6.css')}" type="text/css" media="screen" charset="utf-8" /> <![endif]--> </head> <body> <div id="wrap"> - <div id="header"> - <div class="header">The Pyramid Web Application Development Framework</div> - </div> <div id="top"> <div class="top align-center"> - <img src="${request.application_url}/static/logo.png" width="300" height="80"/> + <div><img src="${request.static_url('{{package}}:static/pyramid.png')}" width="750" height="169" alt="pyramid"/></div> + </div> + </div> + <div id="middle"> + <div class="middle align-center"> <p class="app-welcome"> Welcome to <span class="app-name">${project}</span>, an application generated by<br/> the Pyramid web application development framework. @@ -31,24 +31,21 @@ <div id="bottom"> <div class="bottom"> <div id="left" class="align-right"> - <h3>Search Pyramid documentation</h3> + <h2>Search documentation</h2> <form method="get" action="http://docs.pylonshq.com/pyramid/dev/search.html"> <input type="text" id="q" name="q" value="" /> - <input type="submit" id="x" value="Search" /> + <input type="submit" id="x" value="Go" /> </form> <br/> <p>The root object's name is "${root.name}"</p> </div> <div id="right" class="align-left"> - <h3>Pyramid links</h3> + <h2>Pyramid links</h2> <ul class="links"> <li> <a href="http://pylonshq.com">Pylons Website</a> </li> <li> - <a href="http://docs.pylonshq.com/">The Pylons Project Documentation</a> - </li> - <li> <a href="http://docs.pylonshq.com/pyramid/dev/#narrative-documentation">Narrative Documentation</a> </li> <li> @@ -75,7 +72,7 @@ </div> </div> <div id="footer"> - <div class="footer">© Copyright 2008-2010, Agendaless Consulting.</div> + <div class="footer">© Copyright 2008-2011, Agendaless Consulting.</div> </div> </body> </html>
\ No newline at end of file diff --git a/pyramid/paster_templates/routesalchemy/+package+/static/footerbg.png b/pyramid/paster_templates/routesalchemy/+package+/static/footerbg.png Binary files differnew file mode 100644 index 000000000..1fbc873da --- /dev/null +++ b/pyramid/paster_templates/routesalchemy/+package+/static/footerbg.png diff --git a/pyramid/paster_templates/routesalchemy/+package+/static/headerbg.png b/pyramid/paster_templates/routesalchemy/+package+/static/headerbg.png Binary files differnew file mode 100644 index 000000000..0596f2020 --- /dev/null +++ b/pyramid/paster_templates/routesalchemy/+package+/static/headerbg.png diff --git a/pyramid/paster_templates/routesalchemy/+package+/static/ie6.css b/pyramid/paster_templates/routesalchemy/+package+/static/ie6.css new file mode 100644 index 000000000..b7c8493d8 --- /dev/null +++ b/pyramid/paster_templates/routesalchemy/+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/routesalchemy/+package+/static/logo.png b/pyramid/paster_templates/routesalchemy/+package+/static/logo.png Binary files differdeleted file mode 100644 index 88f5d9865..000000000 --- a/pyramid/paster_templates/routesalchemy/+package+/static/logo.png +++ /dev/null diff --git a/pyramid/paster_templates/routesalchemy/+package+/static/middlebg.png b/pyramid/paster_templates/routesalchemy/+package+/static/middlebg.png Binary files differnew file mode 100644 index 000000000..2369cfb7d --- /dev/null +++ b/pyramid/paster_templates/routesalchemy/+package+/static/middlebg.png diff --git a/pyramid/paster_templates/routesalchemy/+package+/static/pylons.css b/pyramid/paster_templates/routesalchemy/+package+/static/pylons.css index c153be07f..fd1914d8d 100644 --- a/pyramid/paster_templates/routesalchemy/+package+/static/pylons.css +++ b/pyramid/paster_templates/routesalchemy/+package+/static/pylons.css @@ -4,34 +4,23 @@ body{line-height:1;} ol,ul{list-style:none;} blockquote,q{quotes:none;} blockquote:before,blockquote:after,q:before,q:after{content:'';content:none;} -/* remember to define focus styles! */ :focus{outline:0;} -/* remember to highlight inserts somehow! */ ins{text-decoration:none;} del{text-decoration:line-through;} -/* tables still need 'cellspacing="0"' in the markup */ table{border-collapse:collapse;border-spacing:0;} -/* restyling */ sub{vertical-align:sub;font-size:smaller;line-height:normal;} sup{vertical-align:super;font-size:smaller;line-height:normal;} -/* lists */ ul,menu,dir{display:block;list-style-type:disc;margin:1em 0;padding-left:40px;} ol{display:block;list-style-type:decimal-leading-zero;margin:1em 0;padding-left:40px;} li{display:list-item;} -/* nested lists have no top/bottom margins */ ul ul,ul ol,ul dir,ul menu,ul dl,ol ul,ol ol,ol dir,ol menu,ol dl,dir ul,dir ol,dir dir,dir menu,dir dl,menu ul,menu ol,menu dir,menu menu,menu dl,dl ul,dl ol,dl dir,dl menu,dl dl{margin-top:0;margin-bottom:0;} -/* 2 deep unordered lists use a circle */ ol ul,ul ul,menu ul,dir ul,ol menu,ul menu,menu menu,dir menu,ol dir,ul dir,menu dir,dir dir{list-style-type:circle;} -/* 3 deep (or more) unordered lists use a square */ ol ol ul,ol ul ul,ol menu ul,ol dir ul,ol ol menu,ol ul menu,ol menu menu,ol dir menu,ol ol dir,ol ul dir,ol menu dir,ol dir dir,ul ol ul,ul ul ul,ul menu ul,ul dir ul,ul ol menu,ul ul menu,ul menu menu,ul dir menu,ul ol dir,ul ul dir,ul menu dir,ul dir dir,menu ol ul,menu ul ul,menu menu ul,menu dir ul,menu ol menu,menu ul menu,menu menu menu,menu dir menu,menu ol dir,menu ul dir,menu menu dir,menu dir dir,dir ol ul,dir ul ul,dir menu ul,dir dir ul,dir ol menu,dir ul menu,dir menu menu,dir dir menu,dir ol dir,dir ul dir,dir menu dir,dir dir dir{list-style-type:square;} .hidden{display:none;} p{line-height:1.5em;} -h1{font-size:1.75em;/* 28px */ -line-height:1.7em;font-family:helvetica,verdana;} -h2{font-size:1.5em;/* 24px */ -line-height:1.7em;font-family:helvetica,verdana;} -h3{font-size:1.25em;/* 20px */ -line-height:1.7em;font-family:helvetica,verdana;} +h1{font-size:1.75em;line-height:1.7em;font-family:helvetica,verdana;} +h2{font-size:1.5em;line-height:1.7em;font-family:helvetica,verdana;} +h3{font-size:1.25em;line-height:1.7em;font-family:helvetica,verdana;} h4{font-size:1em;line-height:1.7em;font-family:helvetica,verdana;} html,body{width:100%;height:100%;} body{margin:0;padding:0;background-color:#ffffff;position:relative;font:16px/24px "Nobile","Lucida Grande",Lucida,Verdana,sans-serif;} @@ -42,23 +31,26 @@ 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,#top-small,#bottom{width:100%;} +#top{color:#000000;height:230px;background:#ffffff url(headerbg.png) repeat-x 0 top;position:relative;} +#top-small{color:#000000;height:60px;background:#ffffff url(headerbg.png) repeat-x 0 top;position:relative;} +#bottom{color:#222;background-color:#ffffff;} +.top,.top-small,.middle,.bottom{width:750px;margin-right:auto;margin-left:auto;} +.top{padding-top:40px;} +.top-small{padding-top:10px;} +#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 +59,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],input[type=password]{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/routesalchemy/+package+/static/pyramid-small.png b/pyramid/paster_templates/routesalchemy/+package+/static/pyramid-small.png Binary files differnew file mode 100644 index 000000000..a5bc0ade7 --- /dev/null +++ b/pyramid/paster_templates/routesalchemy/+package+/static/pyramid-small.png diff --git a/pyramid/paster_templates/routesalchemy/+package+/static/pyramid.png b/pyramid/paster_templates/routesalchemy/+package+/static/pyramid.png Binary files differnew file mode 100644 index 000000000..347e05549 --- /dev/null +++ b/pyramid/paster_templates/routesalchemy/+package+/static/pyramid.png diff --git a/pyramid/paster_templates/routesalchemy/+package+/static/transparent.gif b/pyramid/paster_templates/routesalchemy/+package+/static/transparent.gif Binary files differnew file mode 100644 index 000000000..0341802e5 --- /dev/null +++ b/pyramid/paster_templates/routesalchemy/+package+/static/transparent.gif diff --git a/pyramid/paster_templates/routesalchemy/+package+/templates/mytemplate.pt b/pyramid/paster_templates/routesalchemy/+package+/templates/mytemplate.pt deleted file mode 100644 index 6ad23d44f..000000000 --- a/pyramid/paster_templates/routesalchemy/+package+/templates/mytemplate.pt +++ /dev/null @@ -1,79 +0,0 @@ -<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd"> -<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en" xmlns:tal="http://xml.zope.org/namespaces/tal"> -<head> - <title>The Pyramid Web Application Development Framework</title> - <meta http-equiv="Content-Type" content="text/html;charset=UTF-8"/> - <meta name="keywords" content="python web application" /> - <meta name="description" content="pyramid web application" /> - <link rel="shortcut icon" href="${request.application_url}/static/favicon.ico" /> - <link rel="stylesheet" href="${request.application_url}/static/pylons.css" type="text/css" media="screen" charset="utf-8" /> - <link rel="stylesheet" href="http://fonts.googleapis.com/css?family=Nobile:regular,italic,bold,bolditalic&subset=latin" type="text/css" media="screen" charset="utf-8" /> - <!--[if !IE 7]> - <style type="text/css"> - #wrap {display:table;height:100%} - </style> - <![endif]--> -</head> -<body> - <div id="wrap"> - <div id="header"> - <div class="header">The Pyramid Web Application Development Framework</div> - </div> - <div id="top"> - <div class="top align-center"> - <img src="${request.application_url}/static/logo.png" width="300" height="80"/> - <p class="app-welcome"> - Welcome to <span class="app-name">${project}</span>, an application generated by<br/> - the Pyramid web application development framework. - </p> - </div> - </div> - <div id="bottom"> - <div class="bottom"> - <div id="left" class="align-right"> - <h3>Search Pyramid documentation</h3> - <form method="get" action="http://docs.pylonshq.com/pyramid/dev/search.html"> - <input type="text" id="q" name="q" value="" /> - <input type="submit" id="x" value="Search" /> - </form> - </div> - <div id="right" class="align-left"> - <h3>Pyramid links</h3> - <ul class="links"> - <li> - <a href="http://pylonshq.com">Pylons Website</a> - </li> - <li> - <a href="http://docs.pylonshq.com/">The Pylons Project Documentation</a> - </li> - <li> - <a href="http://docs.pylonshq.com/pyramid/dev/#narrative-documentation">Narrative Documentation</a> - </li> - <li> - <a href="http://docs.pylonshq.com/pyramid/dev/#api-documentation">API Documentation</a> - </li> - <li> - <a href="http://docs.pylonshq.com/pyramid/dev/#tutorials">Tutorials</a> - </li> - <li> - <a href="http://docs.pylonshq.com/pyramid/dev/#change-history">Change History</a> - </li> - <li> - <a href="http://docs.pylonshq.com/pyramid/dev/#sample-applications">Sample Applications</a> - </li> - <li> - <a href="http://docs.pylonshq.com/pyramid/dev/#support-and-development">Support and Development</a> - </li> - <li> - <a href="irc://irc.freenode.net#pyramid">IRC Channel</a> - </li> - </ul> - </div> - </div> - </div> - </div> - <div id="footer"> - <div class="footer">© Copyright 2008-2010, Agendaless Consulting.</div> - </div> -</body> -</html>
\ No newline at end of file diff --git a/pyramid/paster_templates/pylons_minimal/+package+/templates/mytemplate.mako b/pyramid/paster_templates/routesalchemy/+package+/templates/mytemplate.pt_tmpl index 6ad23d44f..a658ee2c9 100644 --- a/pyramid/paster_templates/pylons_minimal/+package+/templates/mytemplate.mako +++ b/pyramid/paster_templates/routesalchemy/+package+/templates/mytemplate.pt_tmpl @@ -5,23 +5,23 @@ <meta http-equiv="Content-Type" content="text/html;charset=UTF-8"/> <meta name="keywords" content="python web application" /> <meta name="description" content="pyramid web application" /> - <link rel="shortcut icon" href="${request.application_url}/static/favicon.ico" /> - <link rel="stylesheet" href="${request.application_url}/static/pylons.css" type="text/css" media="screen" charset="utf-8" /> + <link rel="shortcut icon" href="${request.static_url('{{package}}:static/favicon.ico')}" /> + <link rel="stylesheet" href="${request.static_url('{{package}}:static/pylons.css')}" type="text/css" media="screen" charset="utf-8" /> + <link rel="stylesheet" href="http://fonts.googleapis.com/css?family=Neuton&subset=latin" type="text/css" media="screen" charset="utf-8" /> <link rel="stylesheet" href="http://fonts.googleapis.com/css?family=Nobile:regular,italic,bold,bolditalic&subset=latin" type="text/css" media="screen" charset="utf-8" /> - <!--[if !IE 7]> - <style type="text/css"> - #wrap {display:table;height:100%} - </style> + <!--[if lte IE 6]> + <link rel="stylesheet" href="${request.static_url('{{package}}:static/ie6.css')}" type="text/css" media="screen" charset="utf-8" /> <![endif]--> </head> <body> <div id="wrap"> - <div id="header"> - <div class="header">The Pyramid Web Application Development Framework</div> - </div> <div id="top"> <div class="top align-center"> - <img src="${request.application_url}/static/logo.png" width="300" height="80"/> + <div><img src="${request.static_url('{{package}}:static/pyramid.png')}" width="750" height="169" alt="pyramid"/></div> + </div> + </div> + <div id="middle"> + <div class="middle align-center"> <p class="app-welcome"> Welcome to <span class="app-name">${project}</span>, an application generated by<br/> the Pyramid web application development framework. @@ -31,22 +31,19 @@ <div id="bottom"> <div class="bottom"> <div id="left" class="align-right"> - <h3>Search Pyramid documentation</h3> + <h2>Search documentation</h2> <form method="get" action="http://docs.pylonshq.com/pyramid/dev/search.html"> <input type="text" id="q" name="q" value="" /> - <input type="submit" id="x" value="Search" /> + <input type="submit" id="x" value="Go" /> </form> </div> <div id="right" class="align-left"> - <h3>Pyramid links</h3> + <h2>Pyramid links</h2> <ul class="links"> <li> <a href="http://pylonshq.com">Pylons Website</a> </li> <li> - <a href="http://docs.pylonshq.com/">The Pylons Project Documentation</a> - </li> - <li> <a href="http://docs.pylonshq.com/pyramid/dev/#narrative-documentation">Narrative Documentation</a> </li> <li> @@ -73,7 +70,7 @@ </div> </div> <div id="footer"> - <div class="footer">© Copyright 2008-2010, Agendaless Consulting.</div> + <div class="footer">© Copyright 2008-2011, Agendaless Consulting.</div> </div> </body> </html>
\ No newline at end of file diff --git a/pyramid/paster_templates/starter/+package+/static/pylons.css b/pyramid/paster_templates/starter/+package+/static/pylons.css index 33b21ac1a..fd1914d8d 100644 --- a/pyramid/paster_templates/starter/+package+/static/pylons.css +++ b/pyramid/paster_templates/starter/+package+/static/pylons.css @@ -38,12 +38,13 @@ body h6{font-family:"Neuton","Lucida Grande",Lucida,Verdana,sans-serif;font-weig #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:#000000;height:230px; -background:#ffffff url(headerbg.png) repeat-x 0 top;position:relative;} +#top,#top-small,#bottom{width:100%;} +#top{color:#000000;height:230px;background:#ffffff url(headerbg.png) repeat-x 0 top;position:relative;} +#top-small{color:#000000;height:60px;background:#ffffff url(headerbg.png) repeat-x 0 top;position:relative;} #bottom{color:#222;background-color:#ffffff;} -.top,.middle,.bottom{width:750px;margin-right:auto;margin-left:auto;} +.top,.top-small,.middle,.bottom{width:750px;margin-right:auto;margin-left:auto;} .top{padding-top:40px;} +.top-small{padding-top:10px;} #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;} @@ -58,7 +59,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]{width:205px;} +input[type=text],input[type=password]{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;} diff --git a/pyramid/paster_templates/starter/+package+/static/pyramid-small.png b/pyramid/paster_templates/starter/+package+/static/pyramid-small.png Binary files differnew file mode 100644 index 000000000..a5bc0ade7 --- /dev/null +++ b/pyramid/paster_templates/starter/+package+/static/pyramid-small.png diff --git a/pyramid/paster_templates/starter/+package+/templates/mytemplate.pt_tmpl b/pyramid/paster_templates/starter/+package+/templates/mytemplate.pt_tmpl new file mode 100644 index 000000000..a658ee2c9 --- /dev/null +++ b/pyramid/paster_templates/starter/+package+/templates/mytemplate.pt_tmpl @@ -0,0 +1,76 @@ +<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd"> +<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en" xmlns:tal="http://xml.zope.org/namespaces/tal"> +<head> + <title>The Pyramid Web Application Development Framework</title> + <meta http-equiv="Content-Type" content="text/html;charset=UTF-8"/> + <meta name="keywords" content="python web application" /> + <meta name="description" content="pyramid web application" /> + <link rel="shortcut icon" href="${request.static_url('{{package}}:static/favicon.ico')}" /> + <link rel="stylesheet" href="${request.static_url('{{package}}:static/pylons.css')}" type="text/css" media="screen" charset="utf-8" /> + <link rel="stylesheet" href="http://fonts.googleapis.com/css?family=Neuton&subset=latin" type="text/css" media="screen" charset="utf-8" /> + <link rel="stylesheet" href="http://fonts.googleapis.com/css?family=Nobile:regular,italic,bold,bolditalic&subset=latin" type="text/css" media="screen" charset="utf-8" /> + <!--[if lte IE 6]> + <link rel="stylesheet" href="${request.static_url('{{package}}:static/ie6.css')}" type="text/css" media="screen" charset="utf-8" /> + <![endif]--> +</head> +<body> + <div id="wrap"> + <div id="top"> + <div class="top align-center"> + <div><img src="${request.static_url('{{package}}:static/pyramid.png')}" width="750" height="169" alt="pyramid"/></div> + </div> + </div> + <div id="middle"> + <div class="middle align-center"> + <p class="app-welcome"> + Welcome to <span class="app-name">${project}</span>, an application generated by<br/> + the Pyramid web application development framework. + </p> + </div> + </div> + <div id="bottom"> + <div class="bottom"> + <div id="left" class="align-right"> + <h2>Search documentation</h2> + <form method="get" action="http://docs.pylonshq.com/pyramid/dev/search.html"> + <input type="text" id="q" name="q" value="" /> + <input type="submit" id="x" value="Go" /> + </form> + </div> + <div id="right" class="align-left"> + <h2>Pyramid links</h2> + <ul class="links"> + <li> + <a href="http://pylonshq.com">Pylons Website</a> + </li> + <li> + <a href="http://docs.pylonshq.com/pyramid/dev/#narrative-documentation">Narrative Documentation</a> + </li> + <li> + <a href="http://docs.pylonshq.com/pyramid/dev/#api-documentation">API Documentation</a> + </li> + <li> + <a href="http://docs.pylonshq.com/pyramid/dev/#tutorials">Tutorials</a> + </li> + <li> + <a href="http://docs.pylonshq.com/pyramid/dev/#change-history">Change History</a> + </li> + <li> + <a href="http://docs.pylonshq.com/pyramid/dev/#sample-applications">Sample Applications</a> + </li> + <li> + <a href="http://docs.pylonshq.com/pyramid/dev/#support-and-development">Support and Development</a> + </li> + <li> + <a href="irc://irc.freenode.net#pyramid">IRC Channel</a> + </li> + </ul> + </div> + </div> + </div> + </div> + <div id="footer"> + <div class="footer">© Copyright 2008-2011, Agendaless Consulting.</div> + </div> +</body> +</html>
\ No newline at end of file diff --git a/pyramid/paster_templates/starter_zcml/+package+/static/footerbg.png b/pyramid/paster_templates/starter_zcml/+package+/static/footerbg.png Binary files differnew file mode 100644 index 000000000..1fbc873da --- /dev/null +++ b/pyramid/paster_templates/starter_zcml/+package+/static/footerbg.png diff --git a/pyramid/paster_templates/starter_zcml/+package+/static/headerbg.png b/pyramid/paster_templates/starter_zcml/+package+/static/headerbg.png Binary files differnew file mode 100644 index 000000000..0596f2020 --- /dev/null +++ b/pyramid/paster_templates/starter_zcml/+package+/static/headerbg.png diff --git a/pyramid/paster_templates/starter_zcml/+package+/static/ie6.css b/pyramid/paster_templates/starter_zcml/+package+/static/ie6.css new file mode 100644 index 000000000..b7c8493d8 --- /dev/null +++ b/pyramid/paster_templates/starter_zcml/+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_zcml/+package+/static/logo.png b/pyramid/paster_templates/starter_zcml/+package+/static/logo.png Binary files differdeleted file mode 100644 index 88f5d9865..000000000 --- a/pyramid/paster_templates/starter_zcml/+package+/static/logo.png +++ /dev/null diff --git a/pyramid/paster_templates/starter_zcml/+package+/static/middlebg.png b/pyramid/paster_templates/starter_zcml/+package+/static/middlebg.png Binary files differnew file mode 100644 index 000000000..2369cfb7d --- /dev/null +++ b/pyramid/paster_templates/starter_zcml/+package+/static/middlebg.png diff --git a/pyramid/paster_templates/starter_zcml/+package+/static/pylons.css b/pyramid/paster_templates/starter_zcml/+package+/static/pylons.css index c153be07f..fd1914d8d 100644 --- a/pyramid/paster_templates/starter_zcml/+package+/static/pylons.css +++ b/pyramid/paster_templates/starter_zcml/+package+/static/pylons.css @@ -4,34 +4,23 @@ body{line-height:1;} ol,ul{list-style:none;} blockquote,q{quotes:none;} blockquote:before,blockquote:after,q:before,q:after{content:'';content:none;} -/* remember to define focus styles! */ :focus{outline:0;} -/* remember to highlight inserts somehow! */ ins{text-decoration:none;} del{text-decoration:line-through;} -/* tables still need 'cellspacing="0"' in the markup */ table{border-collapse:collapse;border-spacing:0;} -/* restyling */ sub{vertical-align:sub;font-size:smaller;line-height:normal;} sup{vertical-align:super;font-size:smaller;line-height:normal;} -/* lists */ ul,menu,dir{display:block;list-style-type:disc;margin:1em 0;padding-left:40px;} ol{display:block;list-style-type:decimal-leading-zero;margin:1em 0;padding-left:40px;} li{display:list-item;} -/* nested lists have no top/bottom margins */ ul ul,ul ol,ul dir,ul menu,ul dl,ol ul,ol ol,ol dir,ol menu,ol dl,dir ul,dir ol,dir dir,dir menu,dir dl,menu ul,menu ol,menu dir,menu menu,menu dl,dl ul,dl ol,dl dir,dl menu,dl dl{margin-top:0;margin-bottom:0;} -/* 2 deep unordered lists use a circle */ ol ul,ul ul,menu ul,dir ul,ol menu,ul menu,menu menu,dir menu,ol dir,ul dir,menu dir,dir dir{list-style-type:circle;} -/* 3 deep (or more) unordered lists use a square */ ol ol ul,ol ul ul,ol menu ul,ol dir ul,ol ol menu,ol ul menu,ol menu menu,ol dir menu,ol ol dir,ol ul dir,ol menu dir,ol dir dir,ul ol ul,ul ul ul,ul menu ul,ul dir ul,ul ol menu,ul ul menu,ul menu menu,ul dir menu,ul ol dir,ul ul dir,ul menu dir,ul dir dir,menu ol ul,menu ul ul,menu menu ul,menu dir ul,menu ol menu,menu ul menu,menu menu menu,menu dir menu,menu ol dir,menu ul dir,menu menu dir,menu dir dir,dir ol ul,dir ul ul,dir menu ul,dir dir ul,dir ol menu,dir ul menu,dir menu menu,dir dir menu,dir ol dir,dir ul dir,dir menu dir,dir dir dir{list-style-type:square;} .hidden{display:none;} p{line-height:1.5em;} -h1{font-size:1.75em;/* 28px */ -line-height:1.7em;font-family:helvetica,verdana;} -h2{font-size:1.5em;/* 24px */ -line-height:1.7em;font-family:helvetica,verdana;} -h3{font-size:1.25em;/* 20px */ -line-height:1.7em;font-family:helvetica,verdana;} +h1{font-size:1.75em;line-height:1.7em;font-family:helvetica,verdana;} +h2{font-size:1.5em;line-height:1.7em;font-family:helvetica,verdana;} +h3{font-size:1.25em;line-height:1.7em;font-family:helvetica,verdana;} h4{font-size:1em;line-height:1.7em;font-family:helvetica,verdana;} html,body{width:100%;height:100%;} body{margin:0;padding:0;background-color:#ffffff;position:relative;font:16px/24px "Nobile","Lucida Grande",Lucida,Verdana,sans-serif;} @@ -42,23 +31,26 @@ 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,#top-small,#bottom{width:100%;} +#top{color:#000000;height:230px;background:#ffffff url(headerbg.png) repeat-x 0 top;position:relative;} +#top-small{color:#000000;height:60px;background:#ffffff url(headerbg.png) repeat-x 0 top;position:relative;} +#bottom{color:#222;background-color:#ffffff;} +.top,.top-small,.middle,.bottom{width:750px;margin-right:auto;margin-left:auto;} +.top{padding-top:40px;} +.top-small{padding-top:10px;} +#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 +59,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],input[type=password]{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_zcml/+package+/static/pyramid-small.png b/pyramid/paster_templates/starter_zcml/+package+/static/pyramid-small.png Binary files differnew file mode 100644 index 000000000..a5bc0ade7 --- /dev/null +++ b/pyramid/paster_templates/starter_zcml/+package+/static/pyramid-small.png diff --git a/pyramid/paster_templates/starter_zcml/+package+/static/pyramid.png b/pyramid/paster_templates/starter_zcml/+package+/static/pyramid.png Binary files differnew file mode 100644 index 000000000..347e05549 --- /dev/null +++ b/pyramid/paster_templates/starter_zcml/+package+/static/pyramid.png diff --git a/pyramid/paster_templates/starter_zcml/+package+/static/transparent.gif b/pyramid/paster_templates/starter_zcml/+package+/static/transparent.gif Binary files differnew file mode 100644 index 000000000..0341802e5 --- /dev/null +++ b/pyramid/paster_templates/starter_zcml/+package+/static/transparent.gif diff --git a/pyramid/paster_templates/starter_zcml/+package+/templates/mytemplate.pt b/pyramid/paster_templates/starter_zcml/+package+/templates/mytemplate.pt deleted file mode 100644 index 6ad23d44f..000000000 --- a/pyramid/paster_templates/starter_zcml/+package+/templates/mytemplate.pt +++ /dev/null @@ -1,79 +0,0 @@ -<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd"> -<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en" xmlns:tal="http://xml.zope.org/namespaces/tal"> -<head> - <title>The Pyramid Web Application Development Framework</title> - <meta http-equiv="Content-Type" content="text/html;charset=UTF-8"/> - <meta name="keywords" content="python web application" /> - <meta name="description" content="pyramid web application" /> - <link rel="shortcut icon" href="${request.application_url}/static/favicon.ico" /> - <link rel="stylesheet" href="${request.application_url}/static/pylons.css" type="text/css" media="screen" charset="utf-8" /> - <link rel="stylesheet" href="http://fonts.googleapis.com/css?family=Nobile:regular,italic,bold,bolditalic&subset=latin" type="text/css" media="screen" charset="utf-8" /> - <!--[if !IE 7]> - <style type="text/css"> - #wrap {display:table;height:100%} - </style> - <![endif]--> -</head> -<body> - <div id="wrap"> - <div id="header"> - <div class="header">The Pyramid Web Application Development Framework</div> - </div> - <div id="top"> - <div class="top align-center"> - <img src="${request.application_url}/static/logo.png" width="300" height="80"/> - <p class="app-welcome"> - Welcome to <span class="app-name">${project}</span>, an application generated by<br/> - the Pyramid web application development framework. - </p> - </div> - </div> - <div id="bottom"> - <div class="bottom"> - <div id="left" class="align-right"> - <h3>Search Pyramid documentation</h3> - <form method="get" action="http://docs.pylonshq.com/pyramid/dev/search.html"> - <input type="text" id="q" name="q" value="" /> - <input type="submit" id="x" value="Search" /> - </form> - </div> - <div id="right" class="align-left"> - <h3>Pyramid links</h3> - <ul class="links"> - <li> - <a href="http://pylonshq.com">Pylons Website</a> - </li> - <li> - <a href="http://docs.pylonshq.com/">The Pylons Project Documentation</a> - </li> - <li> - <a href="http://docs.pylonshq.com/pyramid/dev/#narrative-documentation">Narrative Documentation</a> - </li> - <li> - <a href="http://docs.pylonshq.com/pyramid/dev/#api-documentation">API Documentation</a> - </li> - <li> - <a href="http://docs.pylonshq.com/pyramid/dev/#tutorials">Tutorials</a> - </li> - <li> - <a href="http://docs.pylonshq.com/pyramid/dev/#change-history">Change History</a> - </li> - <li> - <a href="http://docs.pylonshq.com/pyramid/dev/#sample-applications">Sample Applications</a> - </li> - <li> - <a href="http://docs.pylonshq.com/pyramid/dev/#support-and-development">Support and Development</a> - </li> - <li> - <a href="irc://irc.freenode.net#pyramid">IRC Channel</a> - </li> - </ul> - </div> - </div> - </div> - </div> - <div id="footer"> - <div class="footer">© Copyright 2008-2010, Agendaless Consulting.</div> - </div> -</body> -</html>
\ No newline at end of file diff --git a/pyramid/paster_templates/starter_zcml/+package+/templates/mytemplate.pt_tmpl b/pyramid/paster_templates/starter_zcml/+package+/templates/mytemplate.pt_tmpl new file mode 100644 index 000000000..a658ee2c9 --- /dev/null +++ b/pyramid/paster_templates/starter_zcml/+package+/templates/mytemplate.pt_tmpl @@ -0,0 +1,76 @@ +<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd"> +<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en" xmlns:tal="http://xml.zope.org/namespaces/tal"> +<head> + <title>The Pyramid Web Application Development Framework</title> + <meta http-equiv="Content-Type" content="text/html;charset=UTF-8"/> + <meta name="keywords" content="python web application" /> + <meta name="description" content="pyramid web application" /> + <link rel="shortcut icon" href="${request.static_url('{{package}}:static/favicon.ico')}" /> + <link rel="stylesheet" href="${request.static_url('{{package}}:static/pylons.css')}" type="text/css" media="screen" charset="utf-8" /> + <link rel="stylesheet" href="http://fonts.googleapis.com/css?family=Neuton&subset=latin" type="text/css" media="screen" charset="utf-8" /> + <link rel="stylesheet" href="http://fonts.googleapis.com/css?family=Nobile:regular,italic,bold,bolditalic&subset=latin" type="text/css" media="screen" charset="utf-8" /> + <!--[if lte IE 6]> + <link rel="stylesheet" href="${request.static_url('{{package}}:static/ie6.css')}" type="text/css" media="screen" charset="utf-8" /> + <![endif]--> +</head> +<body> + <div id="wrap"> + <div id="top"> + <div class="top align-center"> + <div><img src="${request.static_url('{{package}}:static/pyramid.png')}" width="750" height="169" alt="pyramid"/></div> + </div> + </div> + <div id="middle"> + <div class="middle align-center"> + <p class="app-welcome"> + Welcome to <span class="app-name">${project}</span>, an application generated by<br/> + the Pyramid web application development framework. + </p> + </div> + </div> + <div id="bottom"> + <div class="bottom"> + <div id="left" class="align-right"> + <h2>Search documentation</h2> + <form method="get" action="http://docs.pylonshq.com/pyramid/dev/search.html"> + <input type="text" id="q" name="q" value="" /> + <input type="submit" id="x" value="Go" /> + </form> + </div> + <div id="right" class="align-left"> + <h2>Pyramid links</h2> + <ul class="links"> + <li> + <a href="http://pylonshq.com">Pylons Website</a> + </li> + <li> + <a href="http://docs.pylonshq.com/pyramid/dev/#narrative-documentation">Narrative Documentation</a> + </li> + <li> + <a href="http://docs.pylonshq.com/pyramid/dev/#api-documentation">API Documentation</a> + </li> + <li> + <a href="http://docs.pylonshq.com/pyramid/dev/#tutorials">Tutorials</a> + </li> + <li> + <a href="http://docs.pylonshq.com/pyramid/dev/#change-history">Change History</a> + </li> + <li> + <a href="http://docs.pylonshq.com/pyramid/dev/#sample-applications">Sample Applications</a> + </li> + <li> + <a href="http://docs.pylonshq.com/pyramid/dev/#support-and-development">Support and Development</a> + </li> + <li> + <a href="irc://irc.freenode.net#pyramid">IRC Channel</a> + </li> + </ul> + </div> + </div> + </div> + </div> + <div id="footer"> + <div class="footer">© Copyright 2008-2011, Agendaless Consulting.</div> + </div> +</body> +</html>
\ No newline at end of file diff --git a/pyramid/paster_templates/zodb/+package+/static/footerbg.png b/pyramid/paster_templates/zodb/+package+/static/footerbg.png Binary files differnew file mode 100644 index 000000000..1fbc873da --- /dev/null +++ b/pyramid/paster_templates/zodb/+package+/static/footerbg.png diff --git a/pyramid/paster_templates/zodb/+package+/static/headerbg.png b/pyramid/paster_templates/zodb/+package+/static/headerbg.png Binary files differnew file mode 100644 index 000000000..0596f2020 --- /dev/null +++ b/pyramid/paster_templates/zodb/+package+/static/headerbg.png diff --git a/pyramid/paster_templates/zodb/+package+/static/ie6.css b/pyramid/paster_templates/zodb/+package+/static/ie6.css new file mode 100644 index 000000000..b7c8493d8 --- /dev/null +++ b/pyramid/paster_templates/zodb/+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/zodb/+package+/static/logo.png b/pyramid/paster_templates/zodb/+package+/static/logo.png Binary files differdeleted file mode 100644 index 88f5d9865..000000000 --- a/pyramid/paster_templates/zodb/+package+/static/logo.png +++ /dev/null diff --git a/pyramid/paster_templates/zodb/+package+/static/middlebg.png b/pyramid/paster_templates/zodb/+package+/static/middlebg.png Binary files differnew file mode 100644 index 000000000..2369cfb7d --- /dev/null +++ b/pyramid/paster_templates/zodb/+package+/static/middlebg.png diff --git a/pyramid/paster_templates/zodb/+package+/static/pylons.css b/pyramid/paster_templates/zodb/+package+/static/pylons.css index c153be07f..fd1914d8d 100644 --- a/pyramid/paster_templates/zodb/+package+/static/pylons.css +++ b/pyramid/paster_templates/zodb/+package+/static/pylons.css @@ -4,34 +4,23 @@ body{line-height:1;} ol,ul{list-style:none;} blockquote,q{quotes:none;} blockquote:before,blockquote:after,q:before,q:after{content:'';content:none;} -/* remember to define focus styles! */ :focus{outline:0;} -/* remember to highlight inserts somehow! */ ins{text-decoration:none;} del{text-decoration:line-through;} -/* tables still need 'cellspacing="0"' in the markup */ table{border-collapse:collapse;border-spacing:0;} -/* restyling */ sub{vertical-align:sub;font-size:smaller;line-height:normal;} sup{vertical-align:super;font-size:smaller;line-height:normal;} -/* lists */ ul,menu,dir{display:block;list-style-type:disc;margin:1em 0;padding-left:40px;} ol{display:block;list-style-type:decimal-leading-zero;margin:1em 0;padding-left:40px;} li{display:list-item;} -/* nested lists have no top/bottom margins */ ul ul,ul ol,ul dir,ul menu,ul dl,ol ul,ol ol,ol dir,ol menu,ol dl,dir ul,dir ol,dir dir,dir menu,dir dl,menu ul,menu ol,menu dir,menu menu,menu dl,dl ul,dl ol,dl dir,dl menu,dl dl{margin-top:0;margin-bottom:0;} -/* 2 deep unordered lists use a circle */ ol ul,ul ul,menu ul,dir ul,ol menu,ul menu,menu menu,dir menu,ol dir,ul dir,menu dir,dir dir{list-style-type:circle;} -/* 3 deep (or more) unordered lists use a square */ ol ol ul,ol ul ul,ol menu ul,ol dir ul,ol ol menu,ol ul menu,ol menu menu,ol dir menu,ol ol dir,ol ul dir,ol menu dir,ol dir dir,ul ol ul,ul ul ul,ul menu ul,ul dir ul,ul ol menu,ul ul menu,ul menu menu,ul dir menu,ul ol dir,ul ul dir,ul menu dir,ul dir dir,menu ol ul,menu ul ul,menu menu ul,menu dir ul,menu ol menu,menu ul menu,menu menu menu,menu dir menu,menu ol dir,menu ul dir,menu menu dir,menu dir dir,dir ol ul,dir ul ul,dir menu ul,dir dir ul,dir ol menu,dir ul menu,dir menu menu,dir dir menu,dir ol dir,dir ul dir,dir menu dir,dir dir dir{list-style-type:square;} .hidden{display:none;} p{line-height:1.5em;} -h1{font-size:1.75em;/* 28px */ -line-height:1.7em;font-family:helvetica,verdana;} -h2{font-size:1.5em;/* 24px */ -line-height:1.7em;font-family:helvetica,verdana;} -h3{font-size:1.25em;/* 20px */ -line-height:1.7em;font-family:helvetica,verdana;} +h1{font-size:1.75em;line-height:1.7em;font-family:helvetica,verdana;} +h2{font-size:1.5em;line-height:1.7em;font-family:helvetica,verdana;} +h3{font-size:1.25em;line-height:1.7em;font-family:helvetica,verdana;} h4{font-size:1em;line-height:1.7em;font-family:helvetica,verdana;} html,body{width:100%;height:100%;} body{margin:0;padding:0;background-color:#ffffff;position:relative;font:16px/24px "Nobile","Lucida Grande",Lucida,Verdana,sans-serif;} @@ -42,23 +31,26 @@ 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,#top-small,#bottom{width:100%;} +#top{color:#000000;height:230px;background:#ffffff url(headerbg.png) repeat-x 0 top;position:relative;} +#top-small{color:#000000;height:60px;background:#ffffff url(headerbg.png) repeat-x 0 top;position:relative;} +#bottom{color:#222;background-color:#ffffff;} +.top,.top-small,.middle,.bottom{width:750px;margin-right:auto;margin-left:auto;} +.top{padding-top:40px;} +.top-small{padding-top:10px;} +#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 +59,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],input[type=password]{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/zodb/+package+/static/pyramid-small.png b/pyramid/paster_templates/zodb/+package+/static/pyramid-small.png Binary files differnew file mode 100644 index 000000000..a5bc0ade7 --- /dev/null +++ b/pyramid/paster_templates/zodb/+package+/static/pyramid-small.png diff --git a/pyramid/paster_templates/zodb/+package+/static/pyramid.png b/pyramid/paster_templates/zodb/+package+/static/pyramid.png Binary files differnew file mode 100644 index 000000000..347e05549 --- /dev/null +++ b/pyramid/paster_templates/zodb/+package+/static/pyramid.png diff --git a/pyramid/paster_templates/zodb/+package+/static/transparent.gif b/pyramid/paster_templates/zodb/+package+/static/transparent.gif Binary files differnew file mode 100644 index 000000000..0341802e5 --- /dev/null +++ b/pyramid/paster_templates/zodb/+package+/static/transparent.gif diff --git a/pyramid/paster_templates/zodb/+package+/templates/mytemplate.pt b/pyramid/paster_templates/zodb/+package+/templates/mytemplate.pt deleted file mode 100644 index 6ad23d44f..000000000 --- a/pyramid/paster_templates/zodb/+package+/templates/mytemplate.pt +++ /dev/null @@ -1,79 +0,0 @@ -<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd"> -<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en" xmlns:tal="http://xml.zope.org/namespaces/tal"> -<head> - <title>The Pyramid Web Application Development Framework</title> - <meta http-equiv="Content-Type" content="text/html;charset=UTF-8"/> - <meta name="keywords" content="python web application" /> - <meta name="description" content="pyramid web application" /> - <link rel="shortcut icon" href="${request.application_url}/static/favicon.ico" /> - <link rel="stylesheet" href="${request.application_url}/static/pylons.css" type="text/css" media="screen" charset="utf-8" /> - <link rel="stylesheet" href="http://fonts.googleapis.com/css?family=Nobile:regular,italic,bold,bolditalic&subset=latin" type="text/css" media="screen" charset="utf-8" /> - <!--[if !IE 7]> - <style type="text/css"> - #wrap {display:table;height:100%} - </style> - <![endif]--> -</head> -<body> - <div id="wrap"> - <div id="header"> - <div class="header">The Pyramid Web Application Development Framework</div> - </div> - <div id="top"> - <div class="top align-center"> - <img src="${request.application_url}/static/logo.png" width="300" height="80"/> - <p class="app-welcome"> - Welcome to <span class="app-name">${project}</span>, an application generated by<br/> - the Pyramid web application development framework. - </p> - </div> - </div> - <div id="bottom"> - <div class="bottom"> - <div id="left" class="align-right"> - <h3>Search Pyramid documentation</h3> - <form method="get" action="http://docs.pylonshq.com/pyramid/dev/search.html"> - <input type="text" id="q" name="q" value="" /> - <input type="submit" id="x" value="Search" /> - </form> - </div> - <div id="right" class="align-left"> - <h3>Pyramid links</h3> - <ul class="links"> - <li> - <a href="http://pylonshq.com">Pylons Website</a> - </li> - <li> - <a href="http://docs.pylonshq.com/">The Pylons Project Documentation</a> - </li> - <li> - <a href="http://docs.pylonshq.com/pyramid/dev/#narrative-documentation">Narrative Documentation</a> - </li> - <li> - <a href="http://docs.pylonshq.com/pyramid/dev/#api-documentation">API Documentation</a> - </li> - <li> - <a href="http://docs.pylonshq.com/pyramid/dev/#tutorials">Tutorials</a> - </li> - <li> - <a href="http://docs.pylonshq.com/pyramid/dev/#change-history">Change History</a> - </li> - <li> - <a href="http://docs.pylonshq.com/pyramid/dev/#sample-applications">Sample Applications</a> - </li> - <li> - <a href="http://docs.pylonshq.com/pyramid/dev/#support-and-development">Support and Development</a> - </li> - <li> - <a href="irc://irc.freenode.net#pyramid">IRC Channel</a> - </li> - </ul> - </div> - </div> - </div> - </div> - <div id="footer"> - <div class="footer">© Copyright 2008-2010, Agendaless Consulting.</div> - </div> -</body> -</html>
\ No newline at end of file diff --git a/pyramid/paster_templates/zodb/+package+/templates/mytemplate.pt_tmpl b/pyramid/paster_templates/zodb/+package+/templates/mytemplate.pt_tmpl new file mode 100644 index 000000000..a658ee2c9 --- /dev/null +++ b/pyramid/paster_templates/zodb/+package+/templates/mytemplate.pt_tmpl @@ -0,0 +1,76 @@ +<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd"> +<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en" xmlns:tal="http://xml.zope.org/namespaces/tal"> +<head> + <title>The Pyramid Web Application Development Framework</title> + <meta http-equiv="Content-Type" content="text/html;charset=UTF-8"/> + <meta name="keywords" content="python web application" /> + <meta name="description" content="pyramid web application" /> + <link rel="shortcut icon" href="${request.static_url('{{package}}:static/favicon.ico')}" /> + <link rel="stylesheet" href="${request.static_url('{{package}}:static/pylons.css')}" type="text/css" media="screen" charset="utf-8" /> + <link rel="stylesheet" href="http://fonts.googleapis.com/css?family=Neuton&subset=latin" type="text/css" media="screen" charset="utf-8" /> + <link rel="stylesheet" href="http://fonts.googleapis.com/css?family=Nobile:regular,italic,bold,bolditalic&subset=latin" type="text/css" media="screen" charset="utf-8" /> + <!--[if lte IE 6]> + <link rel="stylesheet" href="${request.static_url('{{package}}:static/ie6.css')}" type="text/css" media="screen" charset="utf-8" /> + <![endif]--> +</head> +<body> + <div id="wrap"> + <div id="top"> + <div class="top align-center"> + <div><img src="${request.static_url('{{package}}:static/pyramid.png')}" width="750" height="169" alt="pyramid"/></div> + </div> + </div> + <div id="middle"> + <div class="middle align-center"> + <p class="app-welcome"> + Welcome to <span class="app-name">${project}</span>, an application generated by<br/> + the Pyramid web application development framework. + </p> + </div> + </div> + <div id="bottom"> + <div class="bottom"> + <div id="left" class="align-right"> + <h2>Search documentation</h2> + <form method="get" action="http://docs.pylonshq.com/pyramid/dev/search.html"> + <input type="text" id="q" name="q" value="" /> + <input type="submit" id="x" value="Go" /> + </form> + </div> + <div id="right" class="align-left"> + <h2>Pyramid links</h2> + <ul class="links"> + <li> + <a href="http://pylonshq.com">Pylons Website</a> + </li> + <li> + <a href="http://docs.pylonshq.com/pyramid/dev/#narrative-documentation">Narrative Documentation</a> + </li> + <li> + <a href="http://docs.pylonshq.com/pyramid/dev/#api-documentation">API Documentation</a> + </li> + <li> + <a href="http://docs.pylonshq.com/pyramid/dev/#tutorials">Tutorials</a> + </li> + <li> + <a href="http://docs.pylonshq.com/pyramid/dev/#change-history">Change History</a> + </li> + <li> + <a href="http://docs.pylonshq.com/pyramid/dev/#sample-applications">Sample Applications</a> + </li> + <li> + <a href="http://docs.pylonshq.com/pyramid/dev/#support-and-development">Support and Development</a> + </li> + <li> + <a href="irc://irc.freenode.net#pyramid">IRC Channel</a> + </li> + </ul> + </div> + </div> + </div> + </div> + <div id="footer"> + <div class="footer">© Copyright 2008-2011, Agendaless Consulting.</div> + </div> +</body> +</html>
\ No newline at end of file diff --git a/pyramid/security.py b/pyramid/security.py index 723e87a87..51c0802d5 100644 --- a/pyramid/security.py +++ b/pyramid/security.py @@ -64,6 +64,24 @@ def authenticated_userid(request): return None return policy.authenticated_userid(request) +def unauthenticated_userid(request): + """ Return an object which represents the *claimed* (not verified) user + id of the credentials present in the request. ``None`` if there is no + :term:`authentication policy` in effect or there is no user data + associated with the current request. This differs from + :func:`~pyramid.security.authenticated_userid`, because the effective + authentication policy will not ensure that a record associated with the + userid exists in persistent storage.""" + try: + reg = request.registry + except AttributeError: + reg = get_current_registry() # b/c + + policy = reg.queryUtility(IAuthenticationPolicy) + if policy is None: + return None + return policy.unauthenticated_userid(request) + def effective_principals(request): """ Return the list of 'effective' :term:`principal` identifiers for the ``request``. This will include the userid of the diff --git a/pyramid/session.py b/pyramid/session.py index 516815d99..9fbb79bf7 100644 --- a/pyramid/session.py +++ b/pyramid/session.py @@ -194,7 +194,10 @@ def UnencryptedCookieSessionFactoryConfig( @manage_accessed def get_csrf_token(self): - return self.get('_csrft_', None) + token = self.get('_csrft_', None) + if token is None: + token = self.new_csrf_token() + return token # non-API methods def _set_cookie(self, response): diff --git a/pyramid/testing.py b/pyramid/testing.py index 61bb1843a..96388b709 100644 --- a/pyramid/testing.py +++ b/pyramid/testing.py @@ -11,6 +11,7 @@ from pyramid.interfaces import IRequest from pyramid.interfaces import ISecuredView from pyramid.interfaces import IView from pyramid.interfaces import IViewClassifier +from pyramid.interfaces import ISession from pyramid.config import Configurator from pyramid.exceptions import Forbidden @@ -44,9 +45,10 @@ def registerDummySecurityPolicy(userid=None, groupids=(), permissive=True): :func:`pyramid.security.authenticated_userid` or :func:`pyramid.security.effective_principals` APIs are used. - This function is most useful when testing code that uses the APIs - named :func:`pyramid.security.has_permission`, + This function is most useful when testing code that uses the APIs named + :func:`pyramid.security.has_permission`, :func:`pyramid.security.authenticated_userid`, + :func:`pyramid.security.unauthenticated_userid`, :func:`pyramid.security.effective_principals`, and :func:`pyramid.security.principals_allowed_by_permission`. @@ -332,6 +334,9 @@ class DummySecurityPolicy(object): def authenticated_userid(self, request): return self.userid + def unauthenticated_userid(self, request): + return self.userid + def effective_principals(self, request): effective_principals = [Everyone] if self.userid: @@ -429,7 +434,12 @@ class DummyResource: that will be attached to the resulting resource via :func:`zope.interface.alsoProvides`. Any extra keywords passed in the ``kw`` argumnent will be set as direct attributes of - the resource object.""" + the resource object. + + .. note:: For backwards compatibility purposes, this class can also + be imported as :class:`pyramid.testing.DummyModel`. + + """ self.__name__ = __name__ self.__parent__ = __parent__ if __provides__ is not None: @@ -502,6 +512,37 @@ class DummyResource: DummyModel = DummyResource # b/w compat (forever) +class DummySession(dict): + implements(ISession) + created = None + new = True + def changed(self): + pass + + def invalidate(self): + self.clear() + + def flash(self, msg, queue='', allow_duplicate=True): + storage = self.setdefault('_f_' + queue, []) + if allow_duplicate or (msg not in storage): + storage.append(msg) + + def pop_flash(self, queue=''): + storage = self.pop('_f_' + queue, []) + return storage + + def peek_flash(self, queue=''): + storage = self.get('_f_' + queue, []) + return storage + + def new_csrf_token(self): + token = 'csrft' + self['_csrft_'] = token + return token + + def get_csrf_token(self): + return self.get('_csrft_', None) + class DummyRequest(object): """ A dummy request object (imitates a :term:`request` object). @@ -517,8 +558,6 @@ class DummyRequest(object): Extra keyword arguments are assigned as attributes of the request itself. - .. note:: For backwards compatibility purposes, this class can also be - imported as :class:`pyramid.testing.DummyModel`. """ implements(IRequest) method = 'GET' @@ -565,6 +604,7 @@ class DummyRequest(object): self.virtual_root = None self.marshalled = params # repoze.monty self.registry = get_current_registry() + self.session = DummySession() self.__dict__.update(kw) def add_response_callback(self, callback): diff --git a/pyramid/tests/test_authentication.py b/pyramid/tests/test_authentication.py index d9d0c2c97..49d655466 100644 --- a/pyramid/tests/test_authentication.py +++ b/pyramid/tests/test_authentication.py @@ -18,11 +18,22 @@ class TestRepozeWho1AuthenticationPolicy(unittest.TestCase): from pyramid.interfaces import IAuthenticationPolicy verifyObject(IAuthenticationPolicy, self._makeOne()) + def test_unauthenticated_userid_returns_None(self): + request = DummyRequest({}) + policy = self._makeOne() + self.assertEqual(policy.unauthenticated_userid(request), None) + + def test_unauthenticated_userid(self): + request = DummyRequest( + {'repoze.who.identity':{'repoze.who.userid':'fred'}}) + policy = self._makeOne() + self.assertEqual(policy.unauthenticated_userid(request), 'fred') + def test_authenticated_userid_None(self): request = DummyRequest({}) policy = self._makeOne() self.assertEqual(policy.authenticated_userid(request), None) - + def test_authenticated_userid(self): request = DummyRequest( {'repoze.who.identity':{'repoze.who.userid':'fred'}}) @@ -132,6 +143,16 @@ class TestRemoteUserAuthenticationPolicy(unittest.TestCase): from pyramid.interfaces import IAuthenticationPolicy verifyObject(IAuthenticationPolicy, self._makeOne()) + def test_unauthenticated_userid_returns_None(self): + request = DummyRequest({}) + policy = self._makeOne() + self.assertEqual(policy.unauthenticated_userid(request), None) + + def test_unauthenticated_userid(self): + request = DummyRequest({'REMOTE_USER':'fred'}) + policy = self._makeOne() + self.assertEqual(policy.unauthenticated_userid(request), 'fred') + def test_authenticated_userid_None(self): request = DummyRequest({}) policy = self._makeOne() @@ -196,6 +217,16 @@ class TestAutkTktAuthenticationPolicy(unittest.TestCase): from pyramid.interfaces import IAuthenticationPolicy verifyObject(IAuthenticationPolicy, self._makeOne(None, None)) + def test_unauthenticated_userid_returns_None(self): + request = DummyRequest({}) + policy = self._makeOne(None, None) + self.assertEqual(policy.unauthenticated_userid(request), None) + + def test_unauthenticated_userid(self): + request = DummyRequest({'REMOTE_USER':'fred'}) + policy = self._makeOne(None, {'userid':'fred'}) + self.assertEqual(policy.unauthenticated_userid(request), 'fred') + def test_authenticated_userid_no_cookie_identity(self): request = DummyRequest({}) policy = self._makeOne(None, None) diff --git a/pyramid/tests/test_config.py b/pyramid/tests/test_config.py index b2fa0e329..ac459d7e3 100644 --- a/pyramid/tests/test_config.py +++ b/pyramid/tests/test_config.py @@ -63,27 +63,11 @@ class ConfiguratorTests(unittest.TestCase): config.registry.registerHandler(subscriber, (event_iface,)) return L - def _registerLogger(self, config): - from pyramid.interfaces import IDebugLogger - logger = DummyLogger() - config.registry.registerUtility(logger, IDebugLogger) - return logger - def _makeRequest(self, config): request = DummyRequest() request.registry = config.registry return request - def _registerSecurityPolicy(self, config, permissive): - from pyramid.interfaces import IAuthenticationPolicy - from pyramid.interfaces import IAuthorizationPolicy - policy = DummySecurityPolicy(permissive) - config.registry.registerUtility(policy, IAuthenticationPolicy) - config.registry.registerUtility(policy, IAuthorizationPolicy) - - def _registerSettings(self, config, **settings): - config.registry.settings = settings - def test_ctor_no_registry(self): import sys from pyramid.interfaces import ISettings @@ -196,6 +180,13 @@ class ConfiguratorTests(unittest.TestCase): config = self._makeOne(session_factory='factory') self.assertEqual(config.registry.getUtility(ISessionFactory), 'factory') + def test_ctor_default_view_mapper(self): + from pyramid.interfaces import IViewMapperFactory + mapper = object() + config = self._makeOne(default_view_mapper=mapper) + self.assertEqual(config.registry.getUtility(IViewMapperFactory), + mapper) + def test_with_package_module(self): from pyramid.tests import test_configuration import pyramid.tests @@ -790,8 +781,10 @@ class ConfiguratorTests(unittest.TestCase): config = self._makeOne(autocommit=True) config.add_view(view=view) wrapper = self._getViewCallable(config) - result = wrapper(None, None) + request = self._makeRequest(config) + result = wrapper(None, request) self.assertEqual(result, 'OK') + self.assertEqual(request.__view__.__class__, view) def test_add_view_as_oldstyle_class_requestonly(self): class view: @@ -803,8 +796,11 @@ class ConfiguratorTests(unittest.TestCase): config = self._makeOne(autocommit=True) config.add_view(view=view) wrapper = self._getViewCallable(config) - result = wrapper(None, None) + + request = self._makeRequest(config) + result = wrapper(None, request) self.assertEqual(result, 'OK') + self.assertEqual(request.__view__.__class__, view) def test_add_view_context_as_class(self): from zope.interface import implementedBy @@ -1427,8 +1423,6 @@ class ConfiguratorTests(unittest.TestCase): self.assertEqual(result.settings, settings) def test_add_view_with_default_renderer(self): - import pyramid.tests - from pyramid.interfaces import ISettings class view(object): def __init__(self, context, request): self.request = request @@ -2340,7 +2334,8 @@ class ConfiguratorTests(unittest.TestCase): request_type = self._getRouteRequestIface(config, 'name') wrapper = self._getViewCallable(config, None, request_type) self._assertRoute(config, 'name', 'path') - self.assertEqual(wrapper(None, None), 'OK') + request = self._makeRequest(config) + self.assertEqual(wrapper(None, request), 'OK') def test_add_route_with_view_renderer_alias(self): config = self._makeOne(autocommit=True) @@ -2437,6 +2432,52 @@ class ConfiguratorTests(unittest.TestCase): else: # pragma: no cover raise AssertionError + def test_derive_view_function(self): + def view(request): + return 'OK' + config = self._makeOne() + result = config.derive_view(view) + self.failIf(result is view) + self.assertEqual(result(None, None), 'OK') + + def test_derive_view_dottedname(self): + config = self._makeOne() + result = config.derive_view( + 'pyramid.tests.test_config.dummy_view') + self.failIf(result is dummy_view) + self.assertEqual(result(None, None), 'OK') + + def test_derive_view_with_default_renderer_no_explicit_renderer(self): + config = self._makeOne() + class moo(object): + def __init__(self, view): + pass + def __call__(self, *arg, **kw): + return 'moo' + config.add_renderer(None, moo) + def view(request): + return 'OK' + result = config.derive_view(view) + self.failIf(result is view) + self.assertEqual(result(None, None).body, 'moo') + + def test_derive_view_with_default_renderer_with_explicit_renderer(self): + class moo(object): pass + class foo(object): + def __init__(self, view): + pass + def __call__(self, *arg, **kw): + return 'foo' + def view(request): + return 'OK' + config = self._makeOne() + config.add_renderer(None, moo) + config.add_renderer('foo', foo) + result = config.derive_view(view, renderer='foo') + self.failIf(result is view) + request = self._makeRequest(config) + self.assertEqual(result(None, request).body, 'foo') + def test__override_not_yet_registered(self): from pyramid.interfaces import IPackageOverrides package = DummyPackage('package') @@ -2633,6 +2674,22 @@ class ConfiguratorTests(unittest.TestCase): self.assertEqual(config.registry.getUtility(IDefaultPermission), 'view') + def test_add_view_mapper(self): + from pyramid.interfaces import IViewMapperFactory + config = self._makeOne(autocommit=True) + mapper = object() + config.set_view_mapper(mapper) + result = config.registry.getUtility(IViewMapperFactory) + self.assertEqual(result, mapper) + + def test_add_view_mapper_dottedname(self): + from pyramid.interfaces import IViewMapperFactory + config = self._makeOne(autocommit=True) + config.set_view_mapper('pyramid.tests.test_config') + result = config.registry.getUtility(IViewMapperFactory) + from pyramid.tests import test_config + self.assertEqual(result, test_config) + def test_set_session_factory(self): from pyramid.interfaces import ISessionFactory config = self._makeOne(autocommit=True) @@ -2680,404 +2737,6 @@ class ConfiguratorTests(unittest.TestCase): self.assertEqual(config.registry.getUtility(ITranslationDirectories), [locale]) - def test_derive_view_function(self): - def view(request): - return 'OK' - config = self._makeOne() - result = config.derive_view(view) - self.failIf(result is view) - self.assertEqual(result(None, None), 'OK') - - def test_derive_view_dottedname(self): - config = self._makeOne() - result = config.derive_view( - 'pyramid.tests.test_config.dummy_view') - self.failIf(result is dummy_view) - self.assertEqual(result(None, None), 'OK') - - def test_derive_view_with_renderer(self): - def view(request): - return 'OK' - config = self._makeOne(autocommit=True) - class moo(object): - def __init__(self, *arg, **kw): - pass - def __call__(self, *arg, **kw): - return 'moo' - config.add_renderer('moo', moo) - result = config.derive_view(view, renderer='moo') - self.failIf(result is view) - self.assertEqual(result(None, None).body, 'moo') - - def test_derive_view_with_default_renderer_no_explicit_renderer(self): - def view(request): - return 'OK' - config = self._makeOne(autocommit=True) - class moo(object): - def __init__(self, *arg, **kw): - pass - def __call__(self, *arg, **kw): - return 'moo' - config.add_renderer(None, moo) - result = config.derive_view(view) - self.failIf(result is view) - self.assertEqual(result(None, None).body, 'moo') - - def test_derive_view_with_default_renderer_with_explicit_renderer(self): - def view(request): - return 'OK' - config = self._makeOne(autocommit=True) - class moo(object): pass - class foo(object): - def __init__(self, *arg, **kw): - pass - def __call__(self, *arg, **kw): - return 'foo' - config.add_renderer(None, moo) - config.add_renderer('foo', foo) - result = config.derive_view(view, renderer='foo') - self.failIf(result is view) - self.assertEqual(result(None, None).body, 'foo') - - def test_derive_view_class_without_attr(self): - class View(object): - def __init__(self, request): - pass - def __call__(self): - return 'OK' - config = self._makeOne() - result = config.derive_view(View) - self.assertEqual(result(None, None), 'OK') - - def test_derive_view_class_with_attr(self): - class View(object): - def __init__(self, request): - pass - def another(self): - return 'OK' - config = self._makeOne() - result = config.derive_view(View, attr='another') - self.assertEqual(result(None, None), 'OK') - - def test__derive_view_as_function_context_and_request(self): - def view(context, request): - return 'OK' - config = self._makeOne() - result = config._derive_view(view) - self.failUnless(result is view) - self.failIf(hasattr(result, '__call_permissive__')) - self.assertEqual(view(None, None), 'OK') - - def test__derive_view_as_function_requestonly(self): - def view(request): - return 'OK' - config = self._makeOne() - result = config._derive_view(view) - self.failIf(result is view) - self.assertEqual(view.__module__, result.__module__) - self.assertEqual(view.__doc__, result.__doc__) - self.assertEqual(view.__name__, result.__name__) - self.failIf(hasattr(result, '__call_permissive__')) - self.assertEqual(result(None, None), 'OK') - - def test__derive_view_as_newstyle_class_context_and_request(self): - class view(object): - def __init__(self, context, request): - pass - def __call__(self): - return 'OK' - config = self._makeOne() - result = config._derive_view(view) - self.failIf(result is view) - self.assertEqual(view.__module__, result.__module__) - self.assertEqual(view.__doc__, result.__doc__) - self.assertEqual(view.__name__, result.__name__) - self.failIf(hasattr(result, '__call_permissive__')) - self.assertEqual(result(None, None), 'OK') - - def test__derive_view_as_newstyle_class_requestonly(self): - class view(object): - def __init__(self, context, request): - pass - def __call__(self): - return 'OK' - config = self._makeOne() - result = config._derive_view(view) - self.failIf(result is view) - self.assertEqual(view.__module__, result.__module__) - self.assertEqual(view.__doc__, result.__doc__) - self.assertEqual(view.__name__, result.__name__) - self.failIf(hasattr(result, '__call_permissive__')) - self.assertEqual(result(None, None), 'OK') - - def test__derive_view_as_oldstyle_class_context_and_request(self): - class view: - def __init__(self, context, request): - pass - def __call__(self): - return 'OK' - config = self._makeOne() - result = config._derive_view(view) - self.failIf(result is view) - self.assertEqual(view.__module__, result.__module__) - self.assertEqual(view.__doc__, result.__doc__) - self.assertEqual(view.__name__, result.__name__) - self.failIf(hasattr(result, '__call_permissive__')) - self.assertEqual(result(None, None), 'OK') - - def test__derive_view_as_oldstyle_class_requestonly(self): - class view: - def __init__(self, context, request): - pass - def __call__(self): - return 'OK' - config = self._makeOne() - result = config._derive_view(view) - self.failIf(result is view) - self.assertEqual(view.__module__, result.__module__) - self.assertEqual(view.__doc__, result.__doc__) - self.assertEqual(view.__name__, result.__name__) - self.failIf(hasattr(result, '__call_permissive__')) - self.assertEqual(result(None, None), 'OK') - - def test__derive_view_as_instance_context_and_request(self): - class View: - def __call__(self, context, request): - return 'OK' - view = View() - config = self._makeOne() - result = config._derive_view(view) - self.failUnless(result is view) - self.failIf(hasattr(result, '__call_permissive__')) - self.assertEqual(result(None, None), 'OK') - - def test__derive_view_as_instance_requestonly(self): - class View: - def __call__(self, request): - return 'OK' - view = View() - config = self._makeOne() - result = config._derive_view(view) - self.failIf(result is view) - self.assertEqual(view.__module__, result.__module__) - self.assertEqual(view.__doc__, result.__doc__) - self.failUnless('instance' in result.__name__) - self.failIf(hasattr(result, '__call_permissive__')) - self.assertEqual(result(None, None), 'OK') - - def test__derive_view_with_debug_authorization_no_authpol(self): - view = lambda *arg: 'OK' - config = self._makeOne() - self._registerSettings(config, - debug_authorization=True, reload_templates=True) - logger = self._registerLogger(config) - result = config._derive_view(view, permission='view') - self.assertEqual(view.__module__, result.__module__) - self.assertEqual(view.__doc__, result.__doc__) - self.assertEqual(view.__name__, result.__name__) - self.failIf(hasattr(result, '__call_permissive__')) - request = self._makeRequest(config) - request.view_name = 'view_name' - request.url = 'url' - self.assertEqual(result(None, request), 'OK') - self.assertEqual(len(logger.messages), 1) - self.assertEqual(logger.messages[0], - "debug_authorization of url url (view name " - "'view_name' against context None): Allowed " - "(no authorization policy in use)") - - def test__derive_view_with_debug_authorization_no_permission(self): - view = lambda *arg: 'OK' - config = self._makeOne() - self._registerSettings(config, - debug_authorization=True, reload_templates=True) - self._registerSecurityPolicy(config, True) - logger = self._registerLogger(config) - result = config._derive_view(view) - self.assertEqual(view.__module__, result.__module__) - self.assertEqual(view.__doc__, result.__doc__) - self.assertEqual(view.__name__, result.__name__) - self.failIf(hasattr(result, '__call_permissive__')) - request = self._makeRequest(config) - request.view_name = 'view_name' - request.url = 'url' - self.assertEqual(result(None, request), 'OK') - self.assertEqual(len(logger.messages), 1) - self.assertEqual(logger.messages[0], - "debug_authorization of url url (view name " - "'view_name' against context None): Allowed (" - "no permission registered)") - - def test__derive_view_debug_auth_permission_authpol_permitted(self): - view = lambda *arg: 'OK' - config = self._makeOne() - self._registerSettings(config, debug_authorization=True, - reload_templates=True) - logger = self._registerLogger(config) - self._registerSecurityPolicy(config, True) - result = config._derive_view(view, permission='view') - self.assertEqual(view.__module__, result.__module__) - self.assertEqual(view.__doc__, result.__doc__) - self.assertEqual(view.__name__, result.__name__) - self.assertEqual(result.__call_permissive__, view) - request = self._makeRequest(config) - request.view_name = 'view_name' - request.url = 'url' - self.assertEqual(result(None, request), 'OK') - self.assertEqual(len(logger.messages), 1) - self.assertEqual(logger.messages[0], - "debug_authorization of url url (view name " - "'view_name' against context None): True") - - def test__derive_view_debug_auth_permission_authpol_denied(self): - from pyramid.exceptions import Forbidden - view = lambda *arg: 'OK' - config = self._makeOne() - self._registerSettings(config, - debug_authorization=True, reload_templates=True) - logger = self._registerLogger(config) - self._registerSecurityPolicy(config, False) - result = config._derive_view(view, permission='view') - self.assertEqual(view.__module__, result.__module__) - self.assertEqual(view.__doc__, result.__doc__) - self.assertEqual(view.__name__, result.__name__) - self.assertEqual(result.__call_permissive__, view) - request = self._makeRequest(config) - request.view_name = 'view_name' - request.url = 'url' - self.assertRaises(Forbidden, result, None, request) - self.assertEqual(len(logger.messages), 1) - self.assertEqual(logger.messages[0], - "debug_authorization of url url (view name " - "'view_name' against context None): False") - - def test__derive_view_debug_auth_permission_authpol_denied2(self): - view = lambda *arg: 'OK' - config = self._makeOne() - self._registerSettings(config, - debug_authorization=True, reload_templates=True) - self._registerLogger(config) - self._registerSecurityPolicy(config, False) - result = config._derive_view(view, permission='view') - self.assertEqual(view.__module__, result.__module__) - self.assertEqual(view.__doc__, result.__doc__) - self.assertEqual(view.__name__, result.__name__) - request = self._makeRequest(config) - request.view_name = 'view_name' - request.url = 'url' - permitted = result.__permitted__(None, None) - self.assertEqual(permitted, False) - - def test__derive_view_debug_auth_permission_authpol_overridden(self): - view = lambda *arg: 'OK' - config = self._makeOne() - self._registerSettings(config, - debug_authorization=True, reload_templates=True) - logger = self._registerLogger(config) - self._registerSecurityPolicy(config, False) - result = config._derive_view(view, - permission='__no_permission_required__') - self.assertEqual(view.__module__, result.__module__) - self.assertEqual(view.__doc__, result.__doc__) - self.assertEqual(view.__name__, result.__name__) - self.failIf(hasattr(result, '__call_permissive__')) - request = self._makeRequest(config) - request.view_name = 'view_name' - request.url = 'url' - self.assertEqual(result(None, request), 'OK') - self.assertEqual(len(logger.messages), 1) - self.assertEqual(logger.messages[0], - "debug_authorization of url url (view name " - "'view_name' against context None): False") - - def test__derive_view_with_predicates_all(self): - view = lambda *arg: 'OK' - predicates = [] - def predicate1(context, request): - predicates.append(True) - return True - def predicate2(context, request): - predicates.append(True) - return True - config = self._makeOne() - result = config._derive_view(view, predicates=[predicate1, predicate2]) - request = self._makeRequest(config) - request.method = 'POST' - next = result(None, None) - self.assertEqual(next, 'OK') - self.assertEqual(predicates, [True, True]) - - def test__derive_view_with_predicates_checker(self): - view = lambda *arg: 'OK' - predicates = [] - def predicate1(context, request): - predicates.append(True) - return True - def predicate2(context, request): - predicates.append(True) - return True - config = self._makeOne() - result = config._derive_view(view, predicates=[predicate1, predicate2]) - request = self._makeRequest(config) - request.method = 'POST' - next = result.__predicated__(None, None) - self.assertEqual(next, True) - self.assertEqual(predicates, [True, True]) - - def test__derive_view_with_predicates_notall(self): - from pyramid.exceptions import NotFound - view = lambda *arg: 'OK' - predicates = [] - def predicate1(context, request): - predicates.append(True) - return True - def predicate2(context, request): - predicates.append(True) - return False - config = self._makeOne() - result = config._derive_view(view, predicates=[predicate1, predicate2]) - request = self._makeRequest(config) - request.method = 'POST' - self.assertRaises(NotFound, result, None, None) - self.assertEqual(predicates, [True, True]) - - def test__derive_view_with_wrapper_viewname(self): - from webob import Response - from pyramid.interfaces import IView - from pyramid.interfaces import IViewClassifier - inner_response = Response('OK') - def inner_view(context, request): - return inner_response - def outer_view(context, request): - self.assertEqual(request.wrapped_response, inner_response) - self.assertEqual(request.wrapped_body, inner_response.body) - self.assertEqual(request.wrapped_view, inner_view) - return Response('outer ' + request.wrapped_body) - config = self._makeOne() - config.registry.registerAdapter( - outer_view, (IViewClassifier, None, None), IView, 'owrap') - result = config._derive_view(inner_view, viewname='inner', - wrapper_viewname='owrap') - self.failIf(result is inner_view) - self.assertEqual(inner_view.__module__, result.__module__) - self.assertEqual(inner_view.__doc__, result.__doc__) - request = self._makeRequest(config) - request.registry = config.registry - response = result(None, request) - self.assertEqual(response.body, 'outer OK') - - def test__derive_view_with_wrapper_viewname_notfound(self): - from webob import Response - inner_response = Response('OK') - def inner_view(context, request): - return inner_response - config = self._makeOne() - request = self._makeRequest(config) - request.registry = config.registry - wrapped = config._derive_view( - inner_view, viewname='inner', wrapper_viewname='owrap') - self.assertRaises(ValueError, wrapped, None, request) - def test_override_asset_samename(self): from pyramid.exceptions import ConfigurationError config = self._makeOne() @@ -3557,348 +3216,838 @@ class ConfiguratorTests(unittest.TestCase): for confinst in conflict: yield confinst[2] -class Test__map_view(unittest.TestCase): +class TestViewDeriver(unittest.TestCase): def setUp(self): - from pyramid.registry import Registry - self.registry = Registry() - testing.setUp(registry=self.registry) + self.config = testing.setUp() def tearDown(self): - del self.registry - testing.tearDown() - - def _registerRenderer(self, typ='.txt'): - from pyramid.interfaces import IRendererFactory - from pyramid.interfaces import ITemplateRenderer - from pyramid.renderers import RendererHelper - from zope.interface import implements - class DummyRenderer: - implements(ITemplateRenderer) - def __init__(self, path): - self.__class__.path = path - def __call__(self, *arg): - return 'Hello!' - self.registry.registerUtility(DummyRenderer, IRendererFactory, name=typ) - renderer = RendererHelper(name='abc' + typ, registry=self.registry) - return renderer - + self.config = None + + def _makeOne(self, **kw): + kw['registry'] = self.config.registry + from pyramid.config import ViewDeriver + return ViewDeriver(**kw) + def _makeRequest(self): request = DummyRequest() - request.registry = self.registry + request.registry = self.config.registry return request - def _callFUT(self, view, **kw): - from pyramid.config import _map_view - return _map_view(view, self.registry, **kw) + def _registerLogger(self): + from pyramid.interfaces import IDebugLogger + logger = DummyLogger() + self.config.registry.registerUtility(logger, IDebugLogger) + return logger - def test__map_view_as_function_context_and_request(self): - def view(context, request): + def _registerSecurityPolicy(self, permissive): + from pyramid.interfaces import IAuthenticationPolicy + from pyramid.interfaces import IAuthorizationPolicy + policy = DummySecurityPolicy(permissive) + self.config.registry.registerUtility(policy, IAuthenticationPolicy) + self.config.registry.registerUtility(policy, IAuthorizationPolicy) + + def test_requestonly_function(self): + def view(request): return 'OK' - result = self._callFUT(view) - self.failUnless(result is view) + deriver = self._makeOne() + result = deriver(view) + self.failIf(result is view) self.assertEqual(result(None, None), 'OK') - def test__map_view_as_function_with_attr(self): - def view(context, request): - """ """ - result = self._callFUT(view, attr='__name__') + def test_requestonly_function_with_renderer(self): + class moo(object): + def render_view(inself, req, resp, view_inst, ctx): + self.assertEqual(req, request) + self.assertEqual(resp, 'OK') + self.assertEqual(view_inst, view) + self.assertEqual(ctx, context) + return 'moo' + def view(request): + return 'OK' + deriver = self._makeOne(renderer=moo()) + result = deriver(view) self.failIf(result is view) - self.assertRaises(TypeError, result, None, None) - - def test__map_view_as_function_with_attr_and_renderer(self): - renderer = self._registerRenderer() - view = lambda *arg: 'OK' - result = self._callFUT(view, attr='__name__', renderer=renderer) + request = self._makeRequest() + context = testing.DummyResource() + self.assertEqual(result(context, request), 'moo') + + def test_requestonly_function_with_renderer_request_override(self): + def moo(info): + def inner(value, system): + self.assertEqual(value, 'OK') + self.assertEqual(system['request'], request) + self.assertEqual(system['context'], context) + return 'moo' + return inner + def view(request): + return 'OK' + self.config.add_renderer('moo', moo) + deriver = self._makeOne(renderer='string') + result = deriver(view) self.failIf(result is view) - self.assertRaises(TypeError, result, None, None) + request = self._makeRequest() + request.override_renderer = 'moo' + context = testing.DummyResource() + self.assertEqual(result(context, request).body, 'moo') - def test__map_view_as_function_requestonly(self): + def test_requestonly_function_with_renderer_request_has_view(self): + class moo(object): + def render_view(inself, req, resp, view_inst, ctx): + self.assertEqual(req, request) + self.assertEqual(resp, 'OK') + self.assertEqual(view_inst, 'view') + self.assertEqual(ctx, context) + return 'moo' def view(request): return 'OK' - result = self._callFUT(view) + deriver = self._makeOne(renderer=moo()) + result = deriver(view) self.failIf(result is view) - self.assertEqual(view.__module__, result.__module__) - self.assertEqual(view.__doc__, result.__doc__) - self.assertEqual(view.__name__, result.__name__) - self.assertEqual(result(None, None), 'OK') + request = self._makeRequest() + request.__view__ = 'view' + context = testing.DummyResource() + self.assertEqual(result(context, request), 'moo') + self.failIf(hasattr(request, '__view__')) + + def test_class_without_attr(self): + class View(object): + def __init__(self, request): + pass + def __call__(self): + return 'OK' + deriver = self._makeOne() + result = deriver(View) + request = self._makeRequest() + self.assertEqual(result(None, request), 'OK') + self.assertEqual(request.__view__.__class__, View) + + def test_class_with_attr(self): + class View(object): + def __init__(self, request): + pass + def another(self): + return 'OK' + deriver = self._makeOne(attr='another') + result = deriver(View) + request = self._makeRequest() + self.assertEqual(result(None, request), 'OK') + self.assertEqual(request.__view__.__class__, View) + + def test_as_function_context_and_request(self): + def view(context, request): + return 'OK' + deriver = self._makeOne() + result = deriver(view) + self.failUnless(result is view) + self.failIf(hasattr(result, '__call_permissive__')) + self.assertEqual(view(None, None), 'OK') - def test__map_view_as_function_requestonly_with_attr(self): + def test_as_function_requestonly(self): def view(request): - """ """ - result = self._callFUT(view, attr='__name__') + return 'OK' + deriver = self._makeOne() + result = deriver(view) self.failIf(result is view) self.assertEqual(view.__module__, result.__module__) self.assertEqual(view.__doc__, result.__doc__) self.assertEqual(view.__name__, result.__name__) - self.assertRaises(TypeError, result, None, None) + self.failIf(hasattr(result, '__call_permissive__')) + self.assertEqual(result(None, None), 'OK') - def test__map_view_as_newstyle_class_context_and_request(self): + def test_as_newstyle_class_context_and_request(self): class view(object): def __init__(self, context, request): pass def __call__(self): return 'OK' - result = self._callFUT(view) + deriver = self._makeOne() + result = deriver(view) self.failIf(result is view) self.assertEqual(view.__module__, result.__module__) self.assertEqual(view.__doc__, result.__doc__) self.assertEqual(view.__name__, result.__name__) - self.assertEqual(result(None, None), 'OK') + self.failIf(hasattr(result, '__call_permissive__')) + request = self._makeRequest() + self.assertEqual(result(None, request), 'OK') + self.assertEqual(request.__view__.__class__, view) - def test__map_view_as_newstyle_class_context_and_request_with_attr(self): + def test_as_newstyle_class_requestonly(self): class view(object): def __init__(self, context, request): pass - def index(self): + def __call__(self): return 'OK' - result = self._callFUT(view, attr='index') + deriver = self._makeOne() + result = deriver(view) self.failIf(result is view) self.assertEqual(view.__module__, result.__module__) self.assertEqual(view.__doc__, result.__doc__) self.assertEqual(view.__name__, result.__name__) - self.assertEqual(result(None, None), 'OK') + self.failIf(hasattr(result, '__call_permissive__')) + request = self._makeRequest() + self.assertEqual(result(None, request), 'OK') + self.assertEqual(request.__view__.__class__, view) - def test__map_view_as_newstyle_class_context_and_request_attr_and_renderer( - self): - renderer = self._registerRenderer() - class view(object): + def test_as_oldstyle_class_context_and_request(self): + class view: def __init__(self, context, request): pass - def index(self): - return {'a':'1'} - result = self._callFUT(view, attr='index', renderer=renderer) + def __call__(self): + return 'OK' + deriver = self._makeOne() + result = deriver(view) self.failIf(result is view) self.assertEqual(view.__module__, result.__module__) self.assertEqual(view.__doc__, result.__doc__) self.assertEqual(view.__name__, result.__name__) + self.failIf(hasattr(result, '__call_permissive__')) request = self._makeRequest() - self.assertEqual(result(None, request).body, 'Hello!') + self.assertEqual(result(None, request), 'OK') + self.assertEqual(request.__view__.__class__, view) - def test__map_view_as_newstyle_class_requestonly(self): - class view(object): - def __init__(self, request): + def test_as_oldstyle_class_requestonly(self): + class view: + def __init__(self, context, request): pass def __call__(self): return 'OK' - result = self._callFUT(view) + deriver = self._makeOne() + result = deriver(view) self.failIf(result is view) self.assertEqual(view.__module__, result.__module__) self.assertEqual(view.__doc__, result.__doc__) self.assertEqual(view.__name__, result.__name__) + self.failIf(hasattr(result, '__call_permissive__')) + request = self._makeRequest() + self.assertEqual(result(None, request), 'OK') + self.assertEqual(request.__view__.__class__, view) + + def test_as_instance_context_and_request(self): + class View: + def __call__(self, context, request): + return 'OK' + view = View() + deriver = self._makeOne() + result = deriver(view) + self.failUnless(result is view) + self.failIf(hasattr(result, '__call_permissive__')) self.assertEqual(result(None, None), 'OK') - def test__map_view_as_newstyle_class_requestonly_with_attr(self): - class view(object): - def __init__(self, request): - pass - def index(self): + def test_as_instance_requestonly(self): + class View: + def __call__(self, request): return 'OK' - result = self._callFUT(view, attr='index') + view = View() + deriver = self._makeOne() + result = deriver(view) self.failIf(result is view) self.assertEqual(view.__module__, result.__module__) self.assertEqual(view.__doc__, result.__doc__) - self.assertEqual(view.__name__, result.__name__) + self.failUnless('instance' in result.__name__) + self.failIf(hasattr(result, '__call_permissive__')) self.assertEqual(result(None, None), 'OK') - def test__map_view_as_newstyle_class_requestonly_attr_and_renderer(self): - renderer = self._registerRenderer() - class view(object): + def test_with_debug_authorization_no_authpol(self): + view = lambda *arg: 'OK' + self.config.registry.settings = dict( + debug_authorization=True, reload_templates=True) + logger = self._registerLogger() + deriver = self._makeOne(permission='view') + result = deriver(view) + self.assertEqual(view.__module__, result.__module__) + self.assertEqual(view.__doc__, result.__doc__) + self.assertEqual(view.__name__, result.__name__) + self.failIf(hasattr(result, '__call_permissive__')) + request = self._makeRequest() + request.view_name = 'view_name' + request.url = 'url' + self.assertEqual(result(None, request), 'OK') + self.assertEqual(len(logger.messages), 1) + self.assertEqual(logger.messages[0], + "debug_authorization of url url (view name " + "'view_name' against context None): Allowed " + "(no authorization policy in use)") + + def test_with_debug_authorization_no_permission(self): + view = lambda *arg: 'OK' + self.config.registry.settings = dict( + debug_authorization=True, reload_templates=True) + self._registerSecurityPolicy(True) + logger = self._registerLogger() + deriver = self._makeOne() + result = deriver(view) + self.assertEqual(view.__module__, result.__module__) + self.assertEqual(view.__doc__, result.__doc__) + self.assertEqual(view.__name__, result.__name__) + self.failIf(hasattr(result, '__call_permissive__')) + request = self._makeRequest() + request.view_name = 'view_name' + request.url = 'url' + self.assertEqual(result(None, request), 'OK') + self.assertEqual(len(logger.messages), 1) + self.assertEqual(logger.messages[0], + "debug_authorization of url url (view name " + "'view_name' against context None): Allowed (" + "no permission registered)") + + def test_debug_auth_permission_authpol_permitted(self): + view = lambda *arg: 'OK' + self.config.registry.settings = dict( + debug_authorization=True, reload_templates=True) + logger = self._registerLogger() + self._registerSecurityPolicy(True) + deriver = self._makeOne(permission='view') + result = deriver(view) + self.assertEqual(view.__module__, result.__module__) + self.assertEqual(view.__doc__, result.__doc__) + self.assertEqual(view.__name__, result.__name__) + self.assertEqual(result.__call_permissive__, view) + request = self._makeRequest() + request.view_name = 'view_name' + request.url = 'url' + self.assertEqual(result(None, request), 'OK') + self.assertEqual(len(logger.messages), 1) + self.assertEqual(logger.messages[0], + "debug_authorization of url url (view name " + "'view_name' against context None): True") + + def test_debug_auth_permission_authpol_denied(self): + from pyramid.exceptions import Forbidden + view = lambda *arg: 'OK' + self.config.registry.settings = dict( + debug_authorization=True, reload_templates=True) + logger = self._registerLogger() + self._registerSecurityPolicy(False) + deriver = self._makeOne(permission='view') + result = deriver(view) + self.assertEqual(view.__module__, result.__module__) + self.assertEqual(view.__doc__, result.__doc__) + self.assertEqual(view.__name__, result.__name__) + self.assertEqual(result.__call_permissive__, view) + request = self._makeRequest() + request.view_name = 'view_name' + request.url = 'url' + self.assertRaises(Forbidden, result, None, request) + self.assertEqual(len(logger.messages), 1) + self.assertEqual(logger.messages[0], + "debug_authorization of url url (view name " + "'view_name' against context None): False") + + def test_debug_auth_permission_authpol_denied2(self): + view = lambda *arg: 'OK' + self.config.registry.settings = dict( + debug_authorization=True, reload_templates=True) + self._registerLogger() + self._registerSecurityPolicy(False) + deriver = self._makeOne(permission='view') + result = deriver(view) + self.assertEqual(view.__module__, result.__module__) + self.assertEqual(view.__doc__, result.__doc__) + self.assertEqual(view.__name__, result.__name__) + request = self._makeRequest() + request.view_name = 'view_name' + request.url = 'url' + permitted = result.__permitted__(None, None) + self.assertEqual(permitted, False) + + def test_debug_auth_permission_authpol_overridden(self): + view = lambda *arg: 'OK' + self.config.registry.settings = dict( + debug_authorization=True, reload_templates=True) + logger = self._registerLogger() + self._registerSecurityPolicy(False) + deriver = self._makeOne(permission='__no_permission_required__') + result = deriver(view) + self.assertEqual(view.__module__, result.__module__) + self.assertEqual(view.__doc__, result.__doc__) + self.assertEqual(view.__name__, result.__name__) + self.failIf(hasattr(result, '__call_permissive__')) + request = self._makeRequest() + request.view_name = 'view_name' + request.url = 'url' + self.assertEqual(result(None, request), 'OK') + self.assertEqual(len(logger.messages), 1) + self.assertEqual(logger.messages[0], + "debug_authorization of url url (view name " + "'view_name' against context None): False") + + def test_with_predicates_all(self): + view = lambda *arg: 'OK' + predicates = [] + def predicate1(context, request): + predicates.append(True) + return True + def predicate2(context, request): + predicates.append(True) + return True + deriver = self._makeOne(predicates=[predicate1, predicate2]) + result = deriver(view) + request = self._makeRequest() + request.method = 'POST' + next = result(None, None) + self.assertEqual(next, 'OK') + self.assertEqual(predicates, [True, True]) + + def test_with_predicates_checker(self): + view = lambda *arg: 'OK' + predicates = [] + def predicate1(context, request): + predicates.append(True) + return True + def predicate2(context, request): + predicates.append(True) + return True + deriver = self._makeOne(predicates=[predicate1, predicate2]) + result = deriver(view) + request = self._makeRequest() + request.method = 'POST' + next = result.__predicated__(None, None) + self.assertEqual(next, True) + self.assertEqual(predicates, [True, True]) + + def test_with_predicates_notall(self): + from pyramid.exceptions import NotFound + view = lambda *arg: 'OK' + predicates = [] + def predicate1(context, request): + predicates.append(True) + return True + def predicate2(context, request): + predicates.append(True) + return False + deriver = self._makeOne(predicates=[predicate1, predicate2]) + result = deriver(view) + request = self._makeRequest() + request.method = 'POST' + self.assertRaises(NotFound, result, None, None) + self.assertEqual(predicates, [True, True]) + + def test_with_wrapper_viewname(self): + from webob import Response + from pyramid.interfaces import IView + from pyramid.interfaces import IViewClassifier + inner_response = Response('OK') + def inner_view(context, request): + return inner_response + def outer_view(context, request): + self.assertEqual(request.wrapped_response, inner_response) + self.assertEqual(request.wrapped_body, inner_response.body) + self.assertEqual(request.wrapped_view, inner_view) + return Response('outer ' + request.wrapped_body) + self.config.registry.registerAdapter( + outer_view, (IViewClassifier, None, None), IView, 'owrap') + deriver = self._makeOne(viewname='inner', + wrapper_viewname='owrap') + result = deriver(inner_view) + self.failIf(result is inner_view) + self.assertEqual(inner_view.__module__, result.__module__) + self.assertEqual(inner_view.__doc__, result.__doc__) + request = self._makeRequest() + response = result(None, request) + self.assertEqual(response.body, 'outer OK') + + def test_with_wrapper_viewname_notfound(self): + from webob import Response + inner_response = Response('OK') + def inner_view(context, request): + return inner_response + deriver = self._makeOne(viewname='inner', wrapper_viewname='owrap') + wrapped = deriver(inner_view) + request = self._makeRequest() + self.assertRaises(ValueError, wrapped, None, request) + + def test_as_newstyle_class_context_and_request_attr_and_renderer(self): + class renderer(object): + def render_view(inself, req, resp, view_inst, ctx): + self.assertEqual(req, request) + self.assertEqual(resp, {'a':'1'}) + self.assertEqual(view_inst.__class__, View) + self.assertEqual(ctx, context) + return resp + class View(object): + def __init__(self, context, request): + pass + def index(self): + return {'a':'1'} + deriver = self._makeOne(renderer=renderer(), attr='index') + result = deriver(View) + self.failIf(result is View) + self.assertEqual(result.__module__, View.__module__) + self.assertEqual(result.__doc__, View.__doc__) + self.assertEqual(result.__name__, View.__name__) + request = self._makeRequest() + context = testing.DummyResource() + self.assertEqual(result(context, request), {'a':'1'}) + + def test_as_newstyle_class_requestonly_attr_and_renderer(self): + class renderer(object): + def render_view(inself, req, resp, view_inst, ctx): + self.assertEqual(req, request) + self.assertEqual(resp, {'a':'1'}) + self.assertEqual(view_inst.__class__, View) + self.assertEqual(ctx, context) + return resp + class View(object): def __init__(self, request): pass def index(self): return {'a':'1'} - result = self._callFUT(view, attr='index', renderer=renderer) + deriver = self._makeOne(renderer=renderer(), attr='index') + result = deriver(View) + self.failIf(result is View) + self.assertEqual(result.__module__, View.__module__) + self.assertEqual(result.__doc__, View.__doc__) + self.assertEqual(result.__name__, View.__name__) + request = self._makeRequest() + context = testing.DummyResource() + self.assertEqual(result(context, request), {'a':'1'}) + + def test_as_oldstyle_cls_context_request_attr_and_renderer(self): + class renderer(object): + def render_view(inself, req, resp, view_inst, ctx): + self.assertEqual(req, request) + self.assertEqual(resp, {'a':'1'}) + self.assertEqual(view_inst.__class__, View) + self.assertEqual(ctx, context) + return resp + class View: + def __init__(self, context, request): + pass + def index(self): + return {'a':'1'} + deriver = self._makeOne(renderer=renderer(), attr='index') + result = deriver(View) + self.failIf(result is View) + self.assertEqual(result.__module__, View.__module__) + self.assertEqual(result.__doc__, View.__doc__) + self.assertEqual(result.__name__, View.__name__) + request = self._makeRequest() + context = testing.DummyResource() + self.assertEqual(result(context, request), {'a':'1'}) + + def test_as_oldstyle_cls_requestonly_attr_and_renderer(self): + class renderer(object): + def render_view(inself, req, resp, view_inst, ctx): + self.assertEqual(req, request) + self.assertEqual(resp, {'a':'1'}) + self.assertEqual(view_inst.__class__, View) + self.assertEqual(ctx, context) + return resp + class View: + def __init__(self, request): + pass + def index(self): + return {'a':'1'} + deriver = self._makeOne(renderer=renderer(), attr='index') + result = deriver(View) + self.failIf(result is View) + self.assertEqual(result.__module__, View.__module__) + self.assertEqual(result.__doc__, View.__doc__) + self.assertEqual(result.__name__, View.__name__) + request = self._makeRequest() + context = testing.DummyResource() + self.assertEqual(result(context, request), {'a':'1'}) + + def test_as_instance_context_and_request_attr_and_renderer(self): + class renderer(object): + def render_view(inself, req, resp, view_inst, ctx): + self.assertEqual(req, request) + self.assertEqual(resp, {'a':'1'}) + self.assertEqual(view_inst, view) + self.assertEqual(ctx, context) + return resp + class View: + def index(self, context, request): + return {'a':'1'} + deriver = self._makeOne(renderer=renderer(), attr='index') + view = View() + result = deriver(view) + self.failIf(result is view) + self.assertEqual(result.__module__, view.__module__) + self.assertEqual(result.__doc__, view.__doc__) + request = self._makeRequest() + context = testing.DummyResource() + self.assertEqual(result(context, request), {'a':'1'}) + + def test_as_instance_requestonly_attr_and_renderer(self): + class renderer(object): + def render_view(inself, req, resp, view_inst, ctx): + self.assertEqual(req, request) + self.assertEqual(resp, {'a':'1'}) + self.assertEqual(view_inst, view) + self.assertEqual(ctx, context) + return resp + class View: + def index(self, request): + return {'a':'1'} + deriver = self._makeOne(renderer=renderer(), attr='index') + view = View() + result = deriver(view) + self.failIf(result is view) + self.assertEqual(result.__module__, view.__module__) + self.assertEqual(result.__doc__, view.__doc__) + request = self._makeRequest() + context = testing.DummyResource() + self.assertEqual(result(context, request), {'a':'1'}) + + def test_with_view_mapper_config_specified(self): + class mapper(object): + def __init__(self, **kw): + self.kw = kw + def __call__(self, view): + def wrapped(context, request): + return 'OK' + return wrapped + def view(context, request): return 'NOTOK' + deriver = self._makeOne(mapper=mapper) + result = deriver(view) + self.failIf(result is view) + self.assertEqual(result(None, None), 'OK') + + def test_with_view_mapper_view_specified(self): + def mapper(**kw): + def inner(view): + def superinner(context, request): + self.assertEqual(request, None) + return 'OK' + return superinner + return inner + def view(context, request): return 'NOTOK' + view.__view_mapper__ = mapper + deriver = self._makeOne() + result = deriver(view) + self.failIf(result is view) + self.assertEqual(result(None, None), 'OK') + + def test_with_view_mapper_default_mapper_specified(self): + def mapper(**kw): + def inner(view): + def superinner(context, request): + self.assertEqual(request, None) + return 'OK' + return superinner + return inner + self.config.set_view_mapper(mapper) + def view(context, request): return 'NOTOK' + deriver = self._makeOne() + result = deriver(view) + self.failIf(result is view) + self.assertEqual(result(None, None), 'OK') + +class TestDefaultViewMapper(unittest.TestCase): + def setUp(self): + self.config = testing.setUp() + self.registry = self.config.registry + + def tearDown(self): + del self.registry + testing.tearDown() + + def _makeOne(self, **kw): + from pyramid.config import DefaultViewMapper + kw['registry'] = self.registry + return DefaultViewMapper(**kw) + + def _makeRequest(self): + request = DummyRequest() + request.registry = self.registry + return request + + def test_view_as_function_context_and_request(self): + def view(context, request): + return 'OK' + mapper = self._makeOne() + result = mapper(view) + self.failUnless(result is view) + request = self._makeRequest() + self.assertEqual(result(None, request), 'OK') + + def test__view_as_function_with_attr(self): + def view(context, request): + """ """ + mapper = self._makeOne(attr='__name__') + result = mapper(view) self.failIf(result is view) - self.assertEqual(view.__module__, result.__module__) - self.assertEqual(view.__doc__, result.__doc__) - self.assertEqual(view.__name__, result.__name__) request = self._makeRequest() - self.assertEqual(result(None, request).body, 'Hello!') + self.assertRaises(TypeError, result, None, request) - def test__map_view_as_oldstyle_class_context_and_request(self): - class view: + def test_view_as_function_requestonly(self): + def view(request): + return 'OK' + mapper = self._makeOne() + result = mapper(view) + self.failIf(result is view) + request = self._makeRequest() + self.assertEqual(result(None, request), 'OK') + + def test_view_as_function_requestonly_with_attr(self): + def view(request): + """ """ + mapper = self._makeOne(attr='__name__') + result = mapper(view) + self.failIf(result is view) + request = self._makeRequest() + self.assertRaises(TypeError, result, None, request) + + def test_view_as_newstyle_class_context_and_request(self): + class view(object): def __init__(self, context, request): pass def __call__(self): return 'OK' - result = self._callFUT(view) + mapper = self._makeOne() + result = mapper(view) self.failIf(result is view) - self.assertEqual(view.__module__, result.__module__) - self.assertEqual(view.__doc__, result.__doc__) - self.assertEqual(view.__name__, result.__name__) - self.assertEqual(result(None, None), 'OK') + request = self._makeRequest() + self.assertEqual(result(None, request), 'OK') - def test__map_view_as_oldstyle_class_context_and_request_with_attr(self): - class view: + def test_view_as_newstyle_class_context_and_request_with_attr(self): + class view(object): def __init__(self, context, request): pass def index(self): return 'OK' - result = self._callFUT(view, attr='index') + mapper = self._makeOne(attr='index') + result = mapper(view) self.failIf(result is view) - self.assertEqual(view.__module__, result.__module__) - self.assertEqual(view.__doc__, result.__doc__) - self.assertEqual(view.__name__, result.__name__) - self.assertEqual(result(None, None), 'OK') + request = self._makeRequest() + self.assertEqual(result(None, request), 'OK') - def test__map_view_as_oldstyle_cls_context_request_attr_and_renderer(self): - renderer = self._registerRenderer() - class view: - def __init__(self, context, request): + def test_view_as_newstyle_class_requestonly(self): + class view(object): + def __init__(self, request): + pass + def __call__(self): + return 'OK' + mapper = self._makeOne() + result = mapper(view) + self.failIf(result is view) + request = self._makeRequest() + self.assertEqual(result(None, request), 'OK') + + def test_view_as_newstyle_class_requestonly_with_attr(self): + class view(object): + def __init__(self, request): pass def index(self): - return {'a':'1'} - result = self._callFUT(view, attr='index', renderer=renderer) + return 'OK' + mapper = self._makeOne(attr='index') + result = mapper(view) self.failIf(result is view) - self.assertEqual(view.__module__, result.__module__) - self.assertEqual(view.__doc__, result.__doc__) - self.assertEqual(view.__name__, result.__name__) request = self._makeRequest() - self.assertEqual(result(None, request).body, 'Hello!') + self.assertEqual(result(None, request), 'OK') - def test__map_view_as_oldstyle_class_requestonly(self): + def test_view_as_oldstyle_class_context_and_request(self): class view: - def __init__(self, request): + def __init__(self, context, request): pass def __call__(self): return 'OK' - result = self._callFUT(view) + mapper = self._makeOne() + result = mapper(view) self.failIf(result is view) - self.assertEqual(view.__module__, result.__module__) - self.assertEqual(view.__doc__, result.__doc__) - self.assertEqual(view.__name__, result.__name__) - self.assertEqual(result(None, None), 'OK') + request = self._makeRequest() + self.assertEqual(result(None, request), 'OK') - def test__map_view_as_oldstyle_class_requestonly_with_attr(self): + def test_view_as_oldstyle_class_context_and_request_with_attr(self): class view: - def __init__(self, request): + def __init__(self, context, request): pass def index(self): return 'OK' - result = self._callFUT(view, attr='index') + mapper = self._makeOne(attr='index') + result = mapper(view) self.failIf(result is view) - self.assertEqual(view.__module__, result.__module__) - self.assertEqual(view.__doc__, result.__doc__) - self.assertEqual(view.__name__, result.__name__) - self.assertEqual(result(None, None), 'OK') + request = self._makeRequest() + self.assertEqual(result(None, request), 'OK') - def test__map_view_as_oldstyle_class_requestonly_attr_and_renderer(self): - renderer = self._registerRenderer() + def test_view_as_oldstyle_class_requestonly(self): + class view: + def __init__(self, request): + pass + def __call__(self): + return 'OK' + mapper = self._makeOne() + result = mapper(view) + self.failIf(result is view) + request = self._makeRequest() + self.assertEqual(result(None, request), 'OK') + + def test_view_as_oldstyle_class_requestonly_with_attr(self): class view: def __init__(self, request): pass def index(self): - return {'a':'1'} - result = self._callFUT(view, attr='index', renderer=renderer) + return 'OK' + mapper = self._makeOne(attr='index') + result = mapper(view) self.failIf(result is view) - self.assertEqual(view.__module__, result.__module__) - self.assertEqual(view.__doc__, result.__doc__) - self.assertEqual(view.__name__, result.__name__) request = self._makeRequest() - self.assertEqual(result(None, request).body, 'Hello!') + self.assertEqual(result(None, request), 'OK') - def test__map_view_as_instance_context_and_request(self): + def test_view_as_instance_context_and_request(self): class View: def __call__(self, context, request): return 'OK' view = View() - result = self._callFUT(view) + mapper = self._makeOne() + result = mapper(view) self.failUnless(result is view) - self.assertEqual(result(None, None), 'OK') + request = self._makeRequest() + self.assertEqual(result(None, request), 'OK') - def test__map_view_as_instance_context_and_request_and_attr(self): + def test_view_as_instance_context_and_request_and_attr(self): class View: def index(self, context, request): return 'OK' view = View() - result = self._callFUT(view, attr='index') - self.failIf(result is view) - self.assertEqual(result(None, None), 'OK') - - def test__map_view_as_instance_context_and_request_attr_and_renderer(self): - renderer = self._registerRenderer() - class View: - def index(self, context, request): - return {'a':'1'} - view = View() - result = self._callFUT(view, attr='index', renderer=renderer) + mapper = self._makeOne(attr='index') + result = mapper(view) self.failIf(result is view) request = self._makeRequest() - self.assertEqual(result(None, request).body, 'Hello!') + self.assertEqual(result(None, request), 'OK') - def test__map_view_as_instance_requestonly(self): + def test_view_as_instance_requestonly(self): class View: def __call__(self, request): return 'OK' view = View() - result = self._callFUT(view) + mapper = self._makeOne() + result = mapper(view) self.failIf(result is view) - self.assertEqual(view.__module__, result.__module__) - self.assertEqual(view.__doc__, result.__doc__) - self.failUnless('instance' in result.__name__) - self.assertEqual(result(None, None), 'OK') + request = self._makeRequest() + self.assertEqual(result(None, request), 'OK') - def test__map_view_as_instance_requestonly_with_attr(self): + def test_view_as_instance_requestonly_with_attr(self): class View: def index(self, request): return 'OK' view = View() - result = self._callFUT(view, attr='index') - self.failIf(result is view) - self.assertEqual(view.__module__, result.__module__) - self.assertEqual(view.__doc__, result.__doc__) - self.failUnless('instance' in result.__name__) - self.assertEqual(result(None, None), 'OK') - - def test__map_view_as_instance_requestonly_with_attr_and_renderer(self): - renderer = self._registerRenderer() - class View: - def index(self, request): - return {'a':'1'} - view = View() - result = self._callFUT(view, attr='index', renderer=renderer) - self.failIf(result is view) - self.assertEqual(view.__module__, result.__module__) - self.assertEqual(view.__doc__, result.__doc__) - self.failUnless('instance' in result.__name__) - request = self._makeRequest() - self.assertEqual(result(None, request).body, 'Hello!') - - def test__map_view_rendereronly(self): - renderer = self._registerRenderer() - def view(context, request): - return {'a':'1'} - result = self._callFUT(view, renderer=renderer) + mapper = self._makeOne(attr='index') + result = mapper(view) self.failIf(result is view) - self.assertEqual(view.__module__, result.__module__) - self.assertEqual(view.__doc__, result.__doc__) request = self._makeRequest() - self.assertEqual(result(None, request).body, 'Hello!') - - def test__map_view_with_registry(self): - renderer = self._registerRenderer() - def view(context, request): - return {'a':'1'} - result = self._callFUT(view, renderer=renderer) - self.failIf(result is view) - self.assertEqual(view.__module__, result.__module__) - self.assertEqual(view.__doc__, result.__doc__) - request = self._makeRequest() - self.assertEqual(result(None, request).body, 'Hello!') + self.assertEqual(result(None, request), 'OK') -class Test_wraps_view(unittest.TestCase): - def _callFUT(self, fn, view): - from pyramid.config import wraps_view - return wraps_view(fn)(None, view) +class Test_preserve_view_attrs(unittest.TestCase): + def _callFUT(self, view, wrapped_view): + from pyramid.config import preserve_view_attrs + return preserve_view_attrs(view, wrapped_view) def test_it_same(self): def view(context, request): """ """ - def afunc(self, view): - return view - result = self._callFUT(afunc, view) + result = self._callFUT(view, view) self.failUnless(result is view) + def test_it_different_with_existing_original_view(self): + def view1(context, request): pass + view1.__original_view__ = 'abc' + def view2(context, request): pass + result = self._callFUT(view1, view2) + self.assertEqual(result.__original_view__, 'abc') + self.failIf(result is view1) + def test_it_different(self): class DummyView1: """ 1 """ @@ -3906,9 +4055,9 @@ class Test_wraps_view(unittest.TestCase): __module__ = '1' def __call__(self, context, request): """ """ - def __call_permissive__(self, context, reuqest): + def __call_permissive__(self, context, request): """ """ - def __predicated__(self, context, reuqest): + def __predicated__(self, context, request): """ """ def __permitted__(self, context, request): """ """ @@ -3918,18 +4067,17 @@ class Test_wraps_view(unittest.TestCase): __module__ = '2' def __call__(self, context, request): """ """ - def __call_permissive__(self, context, reuqest): + def __call_permissive__(self, context, request): """ """ - def __predicated__(self, context, reuqest): + def __predicated__(self, context, request): """ """ def __permitted__(self, context, request): """ """ view1 = DummyView1() view2 = DummyView2() - def afunc(self, view): - return view1 - result = self._callFUT(afunc, view2) + result = self._callFUT(view2, view1) self.assertEqual(result, view1) + self.failUnless(view1.__original_view__ is view2) self.failUnless(view1.__doc__ is view2.__doc__) self.failUnless(view1.__module__ is view2.__module__) self.failUnless(view1.__name__ is view2.__name__) @@ -4395,24 +4543,23 @@ class TestMultiView(unittest.TestCase): response = mv(context, request) self.assertEqual(response, expected_response) - -class TestRequestOnly(unittest.TestCase): - def _callFUT(self, arg): +class Test_requestonly(unittest.TestCase): + def _callFUT(self, view, attr=None): from pyramid.config import requestonly - return requestonly(arg) + return requestonly(view, attr) - def test_newstyle_class_no_init(self): + def test_requestonly_newstyle_class_no_init(self): class foo(object): """ """ self.assertFalse(self._callFUT(foo)) - def test_newstyle_class_init_toomanyargs(self): + def test_requestonly_newstyle_class_init_toomanyargs(self): class foo(object): def __init__(self, context, request): """ """ self.assertFalse(self._callFUT(foo)) - def test_newstyle_class_init_onearg_named_request(self): + def test_requestonly_newstyle_class_init_onearg_named_request(self): class foo(object): def __init__(self, request): """ """ @@ -4488,6 +4635,22 @@ class TestRequestOnly(unittest.TestCase): """ """ self.assertFalse(self._callFUT(foo)) + def test_function_with_attr_false(self): + def bar(context, request): + """ """ + def foo(context, request): + """ """ + foo.bar = bar + self.assertFalse(self._callFUT(foo, 'bar')) + + def test_function_with_attr_true(self): + def bar(context, request): + """ """ + def foo(request): + """ """ + foo.bar = bar + self.assertTrue(self._callFUT(foo, 'bar')) + def test_function_onearg_named_request(self): def foo(request): """ """ diff --git a/pyramid/tests/test_security.py b/pyramid/tests/test_security.py index dd9d48f45..94cefa642 100644 --- a/pyramid/tests/test_security.py +++ b/pyramid/tests/test_security.py @@ -224,6 +224,36 @@ class TestAuthenticatedUserId(unittest.TestCase): result = self._callFUT(request) self.assertEqual(result, 'yo') +class TestUnauthenticatedUserId(unittest.TestCase): + def setUp(self): + cleanUp() + + def tearDown(self): + cleanUp() + + def _callFUT(self, request): + from pyramid.security import unauthenticated_userid + return unauthenticated_userid(request) + + def test_no_authentication_policy(self): + request = _makeRequest() + result = self._callFUT(request) + self.assertEqual(result, None) + + def test_with_authentication_policy(self): + request = _makeRequest() + _registerAuthenticationPolicy(request.registry, 'yo') + result = self._callFUT(request) + self.assertEqual(result, 'yo') + + def test_with_authentication_policy_no_reg_on_request(self): + from pyramid.threadlocal import get_current_registry + request = DummyRequest({}) + registry = get_current_registry() + _registerAuthenticationPolicy(registry, 'yo') + result = self._callFUT(request) + self.assertEqual(result, 'yo') + class TestEffectivePrincipals(unittest.TestCase): def setUp(self): cleanUp() @@ -355,6 +385,9 @@ class DummyAuthenticationPolicy: def effective_principals(self, request): return self.result + def unauthenticated_userid(self, request): + return self.result + def authenticated_userid(self, request): return self.result diff --git a/pyramid/tests/test_session.py b/pyramid/tests/test_session.py index 0e88b28cd..251d92c23 100644 --- a/pyramid/tests/test_session.py +++ b/pyramid/tests/test_session.py @@ -178,6 +178,13 @@ class TestUnencryptedCookieSession(unittest.TestCase): self.assertEqual(token, 'token') self.failUnless('_csrft_' in session) + def test_get_csrf_token_new(self): + request = testing.DummyRequest() + session = self._makeOne(request) + token = session.get_csrf_token() + self.failUnless(token) + self.failUnless('_csrft_' in session) + class Test_manage_accessed(unittest.TestCase): def _makeOne(self, wrapped): from pyramid.session import manage_accessed diff --git a/pyramid/tests/test_testing.py b/pyramid/tests/test_testing.py index ec6fdac5f..eaaad6aef 100644 --- a/pyramid/tests/test_testing.py +++ b/pyramid/tests/test_testing.py @@ -297,7 +297,11 @@ class TestDummySecurityPolicy(unittest.TestCase): def test_authenticated_userid(self): policy = self._makeOne('user') self.assertEqual(policy.authenticated_userid(None), 'user') - + + def test_unauthenticated_userid(self): + policy = self._makeOne('user') + self.assertEqual(policy.unauthenticated_userid(None), 'user') + def test_effective_principals_userid(self): policy = self._makeOne('user', ('group1',)) from pyramid.security import Everyone @@ -409,6 +413,7 @@ class TestDummyRequest(unittest.TestCase): def test_defaults(self): from pyramid.threadlocal import get_current_registry + from pyramid.testing import DummySession request = self._makeOne() self.assertEqual(request.method, 'GET') self.assertEqual(request.application_url, 'http://example.com') @@ -434,6 +439,7 @@ class TestDummyRequest(unittest.TestCase): self.assertEqual(request.virtual_root, None) self.assertEqual(request.virtual_root_path, ()) self.assertEqual(request.registry, get_current_registry()) + self.assertEqual(request.session.__class__, DummySession) def test_params_explicit(self): request = self._makeOne(params = {'foo':'bar'}) @@ -719,6 +725,86 @@ class Test_skip_on(unittest.TestCase): decorated = self._callFUT('ok')(foo) self.assertEqual(decorated(), True) +class TestDummySession(unittest.TestCase): + def _makeOne(self): + from pyramid.testing import DummySession + return DummySession() + + def test_instance_conforms(self): + from zope.interface.verify import verifyObject + from pyramid.interfaces import ISession + session = self._makeOne() + verifyObject(ISession, session) + + def test_changed(self): + session = self._makeOne() + self.assertEqual(session.changed(), None) + + def test_invalidate(self): + session = self._makeOne() + session['a'] = 1 + self.assertEqual(session.invalidate(), None) + self.failIf('a' in session) + + def test_flash_default(self): + session = self._makeOne() + session.flash('msg1') + session.flash('msg2') + self.assertEqual(session['_f_'], ['msg1', 'msg2']) + + def test_flash_mixed(self): + session = self._makeOne() + session.flash('warn1', 'warn') + session.flash('warn2', 'warn') + session.flash('err1', 'error') + session.flash('err2', 'error') + self.assertEqual(session['_f_warn'], ['warn1', 'warn2']) + + def test_pop_flash_default_queue(self): + session = self._makeOne() + queue = ['one', 'two'] + session['_f_'] = queue + result = session.pop_flash() + self.assertEqual(result, queue) + self.assertEqual(session.get('_f_'), None) + + def test_pop_flash_nodefault_queue(self): + session = self._makeOne() + queue = ['one', 'two'] + session['_f_error'] = queue + result = session.pop_flash('error') + self.assertEqual(result, queue) + self.assertEqual(session.get('_f_error'), None) + + def test_peek_flash_default_queue(self): + session = self._makeOne() + queue = ['one', 'two'] + session['_f_'] = queue + result = session.peek_flash() + self.assertEqual(result, queue) + self.assertEqual(session.get('_f_'), queue) + + def test_peek_flash_nodefault_queue(self): + session = self._makeOne() + queue = ['one', 'two'] + session['_f_error'] = queue + result = session.peek_flash('error') + self.assertEqual(result, queue) + self.assertEqual(session.get('_f_error'), queue) + + def test_new_csrf_token(self): + session = self._makeOne() + token = session.new_csrf_token() + self.assertEqual(token, session['_csrft_']) + + def test_get_csrf_token(self): + session = self._makeOne() + session['_csrft_'] = 'token' + token = session.get_csrf_token() + self.assertEqual(token, 'token') + self.failUnless('_csrft_' in session) + + from zope.interface import Interface from zope.interface import implements diff --git a/pyramid/tests/test_url.py b/pyramid/tests/test_url.py index f11d36aca..a40727e9b 100644 --- a/pyramid/tests/test_url.py +++ b/pyramid/tests/test_url.py @@ -209,6 +209,47 @@ class TestRouteUrl(unittest.TestCase): self.assertEqual(result, 'http://example2.com/1/2/3/a') self.assertEqual(route.kw, {}) # shouldnt have anchor/query +class TestCurrentRouteUrl(unittest.TestCase): + def setUp(self): + cleanUp() + + def tearDown(self): + cleanUp() + + def _callFUT(self, *arg, **kw): + from pyramid.url import current_route_url + return current_route_url(*arg, **kw) + + def test_current_request_has_no_route(self): + request = _makeRequest() + self.assertRaises(ValueError, self._callFUT, request) + + def test_with_elements_query_and_anchor(self): + from pyramid.interfaces import IRoutesMapper + request = _makeRequest() + route = DummyRoute('/1/2/3') + mapper = DummyRoutesMapper(route=route) + request.matched_route = route + request.matchdict = {} + request.registry.registerUtility(mapper, IRoutesMapper) + result = self._callFUT(request, 'extra1', 'extra2', _query={'a':1}, + _anchor=u"foo") + self.assertEqual(result, + 'http://example.com:5432/1/2/3/extra1/extra2?a=1#foo') + + def test_with__route_name(self): + from pyramid.interfaces import IRoutesMapper + request = _makeRequest() + route = DummyRoute('/1/2/3') + mapper = DummyRoutesMapper(route=route) + request.matched_route = route + request.matchdict = {} + request.registry.registerUtility(mapper, IRoutesMapper) + result = self._callFUT(request, 'extra1', 'extra2', _query={'a':1}, + _anchor=u"foo", _route_name='bar') + self.assertEqual(result, + 'http://example.com:5432/1/2/3/extra1/extra2?a=1#foo') + class TestRoutePath(unittest.TestCase): def setUp(self): cleanUp() @@ -302,6 +343,7 @@ class DummyRoutesMapper: class DummyRoute: pregenerator = None + name = 'route' def __init__(self, result='/1/2/3'): self.result = result diff --git a/pyramid/tests/test_view.py b/pyramid/tests/test_view.py index 7fc066319..204547cf2 100644 --- a/pyramid/tests/test_view.py +++ b/pyramid/tests/test_view.py @@ -229,11 +229,14 @@ class TestViewConfigDecorator(unittest.TestCase): def test_create_nondefaults(self): decorator = self._makeOne(name=None, request_type=None, for_=None, - permission='foo') + permission='foo', mapper='mapper', + decorator='decorator') self.assertEqual(decorator.name, None) self.assertEqual(decorator.request_type, None) self.assertEqual(decorator.context, None) self.assertEqual(decorator.permission, 'foo') + self.assertEqual(decorator.mapper, 'mapper') + self.assertEqual(decorator.decorator, 'decorator') def test_call_function(self): decorator = self._makeOne() diff --git a/pyramid/traversal.py b/pyramid/traversal.py index f3377b0d0..f32b43493 100644 --- a/pyramid/traversal.py +++ b/pyramid/traversal.py @@ -352,6 +352,9 @@ def resource_path_tuple(resource, *elements): """ return tuple(_resource_path_list(resource, *elements)) +model_path_tuple = resource_path_tuple # b/w compat + + def _resource_path_list(resource, *elements): """ Implementation detail shared by resource_path and resource_path_tuple""" path = [loc.__name__ or '' for loc in lineage(resource)] diff --git a/pyramid/url.py b/pyramid/url.py index ac569eecb..3126ad26c 100644 --- a/pyramid/url.py +++ b/pyramid/url.py @@ -32,7 +32,7 @@ def route_url(route_name, request, *elements, **kw): enough arguments, for example). For example, if you've defined a route named "foobar" with the path - ``:foo/{bar}/*traverse``:: + ``{foo}/{bar}/*traverse``:: route_url('foobar', request, foo='1') => <KeyError exception> route_url('foobar', request, foo='1', bar='2') => <KeyError exception> @@ -366,6 +366,60 @@ def static_url(path, request, **kw): return info.generate(path, request, **kw) +def current_route_url(request, *elements, **kw): + """Generates a fully qualified URL for a named :app:`Pyramid` + :term:`route configuration` based on the 'current route'. + + This function supplements :func:`pyramid.url.route_url`. It presents an + easy way to generate a URL for the 'current route' (defined as the route + which matched when the request was generated). + + The arguments to this function have the same meaning as those with the + same names passed to :func:`pyramid.url.route_url`. It also understands + an extra argument which ``route_url`` does not named ``_route_name``. + + The route name used to generate a URL is taken from either the + ``_route_name`` keyword argument or the name of the route which is + currently associated with the request if ``_route_name`` was not passed. + Keys and values from the current request :term:`matchdict` are combined + with the ``kw`` arguments to form a set of defaults named ``newkw``. + Then ``route_url(route_name, request, *elements, **newkw)`` is called, + returning a URL. + + Examples follow. + + If the 'current route' has the route pattern ``/foo/{page}`` and the + current url path is ``/foo/1`` , the matchdict will be ``{'page':'1'}``. + The result of ``current_route_url(request)`` in this situation will be + ``/foo/1``. + + If the 'current route' has the route pattern ``/foo/{page}`` and the + current current url path is ``/foo/1``, the matchdict will be + ``{'page':'1'}``. The result of ``current_route_url(request, page='2')`` + in this situation will be ``/foo/2``. + + Usage of the ``_route_name`` keyword argument: if our routing table + defines routes ``/foo/{action}`` named 'foo' and ``/foo/{action}/{page}`` + named ``fooaction``, and the current url pattern is ``/foo/view`` (which + has matched the ``/foo/{action}`` route), we may want to use the + matchdict args to generate a URL to the ``fooaction`` route. In this + scenario, ``current_url(request, _route_name='fooaction', page='5')`` + Will return string like: ``/foo/view/5``. + """ + + if '_route_name' in kw: + route_name = kw.pop('_route_name') + else: + route = getattr(request, 'matched_route', None) + route_name = getattr(route, 'name', None) + if route_name is None: + raise ValueError('Current request matches no route') + + newkw = {} + newkw.update(request.matchdict) + newkw.update(kw) + return route_url(route_name, request, *elements, **newkw) + @lru_cache(1000) def _join_elements(elements): return '/'.join([quote_path_segment(s) for s in elements]) diff --git a/pyramid/view.py b/pyramid/view.py index 776185d8b..26f64d5fc 100644 --- a/pyramid/view.py +++ b/pyramid/view.py @@ -17,7 +17,6 @@ from zope.interface import providedBy from pyramid.interfaces import IRoutesMapper from pyramid.interfaces import IView from pyramid.interfaces import IViewClassifier -from pyramid.interfaces import IRendererFactory from pyramid.httpexceptions import HTTPFound from pyramid.renderers import RendererHelper @@ -277,6 +276,9 @@ class view_config(object): ``False``). The view will only be invoked if all custom predicates return ``True``. + See the :meth:`pyramid.config.Configurator.add_view`` method for + descriptions of the ``decorator`` and ``mapper`` arguments. + Any individual or all parameters can be omitted. The simplest :class:`pyramid.view.view_config` declaration is:: @@ -384,7 +386,8 @@ class view_config(object): route_name=None, request_method=None, request_param=None, containment=None, attr=None, renderer=None, wrapper=None, xhr=False, accept=None, header=None, path_info=None, - custom_predicates=(), context=None): + custom_predicates=(), context=None, decorator=None, + mapper=None): self.name = name self.request_type = request_type self.context = context or for_ @@ -401,6 +404,8 @@ class view_config(object): self.header = header self.path_info = path_info self.custom_predicates = custom_predicates + self.decorator = decorator + self.mapper = mapper def __call__(self, wrapped): settings = self.__dict__.copy() diff --git a/pyramid/zcml.py b/pyramid/zcml.py index a2088e505..298086912 100644 --- a/pyramid/zcml.py +++ b/pyramid/zcml.py @@ -128,6 +128,14 @@ class IViewDirective(Interface): description=(u'Accepts a regular expression.'), required = False) + decorator = GlobalObject( + title = u'View decorator', + required = False) + + mapper = GlobalObject( + title = u'View mapper', + required = False) + custom_predicates = Tokens( title=u"One or more custom dotted names to custom predicate callables", description=(u"A list of dotted name references to callables that " @@ -156,6 +164,8 @@ def view( header=None, path_info=None, traverse=None, + decorator=None, + mapper=None, custom_predicates=(), context=None, cacheable=True, # not used, here for b/w compat < 0.8 @@ -169,7 +179,8 @@ def view( request_method=request_method, request_param=request_param, containment=containment, attr=attr, renderer=renderer, wrapper=wrapper, xhr=xhr, accept=accept, header=header, - path_info=path_info, custom_predicates=custom_predicates) + path_info=path_info, custom_predicates=custom_predicates, + decorator=decorator, mapper=mapper) _view = view # for directives that take a view arg |
