summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorBen Bangert <ben@groovie.org>2010-10-29 11:14:41 -0700
committerBen Bangert <ben@groovie.org>2010-10-29 11:14:41 -0700
commit17e70c8db9140c0b4062f46ef5eb4527d678b793 (patch)
tree38b6b8de2a57db4debec477bc4fda27db82c4c5a
parentd39e99e1f6f06a02a275a8a30f154e0f292d7dff (diff)
parent5038994ea9e053b16fca74ea8fa022871e630883 (diff)
downloadpyramid-17e70c8db9140c0b4062f46ef5eb4527d678b793.tar.gz
pyramid-17e70c8db9140c0b4062f46ef5eb4527d678b793.tar.bz2
pyramid-17e70c8db9140c0b4062f46ef5eb4527d678b793.zip
Merge branch 'master' of github.com:Pylons/pyramid
-rw-r--r--CHANGES.txt17
-rw-r--r--HACKING.txt50
-rw-r--r--TODO.txt14
-rw-r--r--docs/api.rst1
-rw-r--r--docs/api/personality.rst9
-rw-r--r--docs/api/request.rst5
-rw-r--r--docs/api/view.rst2
-rw-r--r--docs/designdefense.rst36
-rw-r--r--docs/glossary.rst146
-rw-r--r--docs/narr/configuration.rst20
-rw-r--r--docs/narr/extending.rst6
-rw-r--r--docs/narr/hooks.rst2
-rw-r--r--docs/narr/project.rst15
-rw-r--r--docs/narr/security.rst6
-rw-r--r--docs/narr/sessions.rst22
-rw-r--r--docs/narr/templates.rst24
-rw-r--r--docs/narr/views.rst104
-rw-r--r--docs/narr/webob.rst6
-rw-r--r--docs/tutorials/catalog/index.rst10
-rw-r--r--docs/tutorials/modwsgi/index.rst2
-rw-r--r--docs/tutorials/wiki/authorization.rst14
-rw-r--r--docs/tutorials/wiki/src/authorization/tutorial/login.py6
-rw-r--r--docs/tutorials/wiki/src/authorization/tutorial/views.py14
-rw-r--r--docs/tutorials/wiki/src/viewdecorators/tutorial/views.py10
-rw-r--r--docs/tutorials/wiki/viewdecorators.rst31
-rw-r--r--docs/zcml/forbidden.rst2
-rw-r--r--docs/zcml/notfound.rst4
-rw-r--r--docs/zcml/view.rst4
-rw-r--r--pyramid/configuration.py20
-rw-r--r--pyramid/interfaces.py4
-rw-r--r--pyramid/paster.py16
-rw-r--r--pyramid/paster_templates/pylons_basic/+package+/__init__.py_tmpl22
-rw-r--r--pyramid/paster_templates/pylons_basic/+package+/handlers/__init__.py1
-rw-r--r--pyramid/paster_templates/pylons_basic/+package+/handlers/hello.py_tmpl9
-rw-r--r--pyramid/paster_templates/pylons_basic/+package+/lib/__init__.py1
-rw-r--r--pyramid/paster_templates/pylons_basic/+package+/lib/helpers.py7
-rw-r--r--pyramid/paster_templates/pylons_basic/+package+/static/default.css380
-rw-r--r--pyramid/paster_templates/pylons_basic/+package+/static/images/img01.gifbin0 -> 3840 bytes
-rw-r--r--pyramid/paster_templates/pylons_basic/+package+/static/images/img02.gifbin0 -> 4689 bytes
-rw-r--r--pyramid/paster_templates/pylons_basic/+package+/static/images/img03.gifbin0 -> 229 bytes
-rw-r--r--pyramid/paster_templates/pylons_basic/+package+/static/images/img04.gifbin0 -> 92 bytes
-rw-r--r--pyramid/paster_templates/pylons_basic/+package+/static/images/spacer.gifbin0 -> 43 bytes
-rw-r--r--pyramid/paster_templates/pylons_basic/+package+/static/templatelicense.txt243
-rw-r--r--pyramid/paster_templates/pylons_basic/+package+/templates/mytemplate.mak49
-rw-r--r--pyramid/paster_templates/pylons_basic/+package+/tests.py_tmpl24
-rw-r--r--pyramid/paster_templates/pylons_basic/CHANGES.txt_tmpl4
-rw-r--r--pyramid/paster_templates/pylons_basic/README.txt_tmpl4
-rw-r--r--pyramid/paster_templates/pylons_basic/development.ini_tmpl28
-rw-r--r--pyramid/paster_templates/pylons_basic/setup.cfg_tmpl27
-rw-r--r--pyramid/paster_templates/pylons_basic/setup.py_tmpl36
-rw-r--r--pyramid/paster_templates/pylons_minimal/+package+/__init__.py_tmpl21
-rw-r--r--pyramid/paster_templates/pylons_minimal/+package+/handlers.py_tmpl9
-rw-r--r--pyramid/paster_templates/pylons_minimal/+package+/static/default.css380
-rw-r--r--pyramid/paster_templates/pylons_minimal/+package+/static/images/img01.gifbin0 -> 3840 bytes
-rw-r--r--pyramid/paster_templates/pylons_minimal/+package+/static/images/img02.gifbin0 -> 4689 bytes
-rw-r--r--pyramid/paster_templates/pylons_minimal/+package+/static/images/img03.gifbin0 -> 229 bytes
-rw-r--r--pyramid/paster_templates/pylons_minimal/+package+/static/images/img04.gifbin0 -> 92 bytes
-rw-r--r--pyramid/paster_templates/pylons_minimal/+package+/static/images/spacer.gifbin0 -> 43 bytes
-rw-r--r--pyramid/paster_templates/pylons_minimal/+package+/static/templatelicense.txt243
-rw-r--r--pyramid/paster_templates/pylons_minimal/+package+/templates/mytemplate.mak49
-rw-r--r--pyramid/paster_templates/pylons_minimal/+package+/tests.py_tmpl24
-rw-r--r--pyramid/paster_templates/pylons_minimal/CHANGES.txt_tmpl4
-rw-r--r--pyramid/paster_templates/pylons_minimal/README.txt_tmpl4
-rw-r--r--pyramid/paster_templates/pylons_minimal/development.ini_tmpl28
-rw-r--r--pyramid/paster_templates/pylons_minimal/setup.cfg_tmpl27
-rw-r--r--pyramid/paster_templates/pylons_minimal/setup.py_tmpl36
-rw-r--r--pyramid/paster_templates/pylons_sqla/+package+/__init__.py_tmpl38
-rw-r--r--pyramid/paster_templates/pylons_sqla/+package+/handlers.py_tmpl12
-rw-r--r--pyramid/paster_templates/pylons_sqla/+package+/models.py47
-rw-r--r--pyramid/paster_templates/pylons_sqla/+package+/static/default.css380
-rw-r--r--pyramid/paster_templates/pylons_sqla/+package+/static/images/img01.gifbin0 -> 3840 bytes
-rw-r--r--pyramid/paster_templates/pylons_sqla/+package+/static/images/img02.gifbin0 -> 4689 bytes
-rw-r--r--pyramid/paster_templates/pylons_sqla/+package+/static/images/img03.gifbin0 -> 229 bytes
-rw-r--r--pyramid/paster_templates/pylons_sqla/+package+/static/images/img04.gifbin0 -> 92 bytes
-rw-r--r--pyramid/paster_templates/pylons_sqla/+package+/static/images/spacer.gifbin0 -> 43 bytes
-rw-r--r--pyramid/paster_templates/pylons_sqla/+package+/static/templatelicense.txt243
-rw-r--r--pyramid/paster_templates/pylons_sqla/+package+/templates/mytemplate.mak50
-rw-r--r--pyramid/paster_templates/pylons_sqla/+package+/tests.py_tmpl26
-rw-r--r--pyramid/paster_templates/pylons_sqla/CHANGES.txt_tmpl4
-rw-r--r--pyramid/paster_templates/pylons_sqla/README.txt_tmpl4
-rw-r--r--pyramid/paster_templates/pylons_sqla/development.ini_tmpl32
-rw-r--r--pyramid/paster_templates/pylons_sqla/setup.cfg_tmpl27
-rw-r--r--pyramid/paster_templates/pylons_sqla/setup.py_tmpl48
-rw-r--r--pyramid/personality/__init__.py1
-rw-r--r--pyramid/personality/pylons.py24
-rw-r--r--pyramid/request.py8
-rw-r--r--pyramid/session.py30
-rw-r--r--pyramid/testing.py2
-rw-r--r--pyramid/tests/defpermbugapp/__init__.py8
-rw-r--r--pyramid/tests/grokkedapp/__init__.py30
-rw-r--r--pyramid/tests/grokkedapp/another.py21
-rw-r--r--pyramid/tests/grokkedapp/pod/notinit.py4
-rw-r--r--pyramid/tests/grokkedapp/subpackage/__init__.py4
-rw-r--r--pyramid/tests/grokkedapp/subpackage/notinit.py4
-rw-r--r--pyramid/tests/grokkedapp/subpackage/subsubpackage/__init__.py4
-rw-r--r--pyramid/tests/test_docs.py2
-rw-r--r--pyramid/tests/test_integration.py4
-rw-r--r--pyramid/tests/test_pylons_personality.py54
-rw-r--r--pyramid/tests/test_request.py6
-rw-r--r--pyramid/tests/test_session.py17
-rw-r--r--pyramid/tests/test_view.py6
-rw-r--r--pyramid/tests/viewdecoratorapp/views/views.py10
-rw-r--r--pyramid/view.py53
-rw-r--r--setup.py3
104 files changed, 3120 insertions, 368 deletions
diff --git a/CHANGES.txt b/CHANGES.txt
index 1e4d73c6c..8d3bfe3a0 100644
--- a/CHANGES.txt
+++ b/CHANGES.txt
@@ -31,11 +31,28 @@ Features (delta from BFG 1.3.X)
- Using ``request.session`` now returns a (dictionary-like) session
object if a session factory has been configured.
+- New module: ``pyramid.personality.pylons``: contains Pylons-specific
+ features.
+
+- The request now has a new attribute: ``tmpl_context`` for benefit of
+ Pylons users.
+
+- The decorator previously known as ``pyramid.view.bfg_view`` is now
+ known most formally as ``pyramid.view.view_config`` in docs and
+ paster templates. An import of ``pyramid.view.bfg_view``, however,
+ will continue to work "forever".
+
Documentation (delta from BFG 1.3)
-----------------------------------
- Added a ``pyramid.httpexceptions`` API documentation chapter.
+- Added a ``pyramid.session`` API documentation chapter.
+
+- Added a ``Session Objects`` narrative documentation chapter.
+
+- Added an API chapter for the ``pyramid.personality`` module.
+
Backwards Incompatibilities (with BFG 1.3.X)
--------------------------------------------
diff --git a/HACKING.txt b/HACKING.txt
index 7de34bed6..464b653c1 100644
--- a/HACKING.txt
+++ b/HACKING.txt
@@ -1,7 +1,15 @@
-In order to add a feature to this package:
+Hacking on Pyramid
+==================
+
+Here are some guidelines about hacking on Pyramid.
+
+Adding Features
+---------------
+
+In order to add a feature to Pyramid:
- The feature must be documented in both the API and narrative
- documentation (in docs/).
+ documentation (in ``docs/``).
- The feature must work fully on the following CPython versions: 2.4,
2.5, 2.6, and 2.7 on both UNIX and Windows.
@@ -19,6 +27,38 @@ In order to add a feature to this package:
be discussed).
The above requirements are relaxed for paster template dependencies.
-If a paster template has a dependency on something that doesn't work
-on a particular platform, that caveat should be spelled out clearly in
-*its* documentation (within docs/).
+If a paster template has an install-time dependency on something that
+doesn't work on a particular platform, that caveat should be spelled
+out clearly in *its* documentation (within its ``docs/`` directory).
+
+Coding Style
+------------
+
+- PEP8 compliance. Whitespace rules are relaxed: not necessary to put
+ 2 newlines between classes. But 80-column lines, in particular, are
+ mandatory.
+
+Test Coverage
+-------------
+
+- The codebase *must* have 100% test statement coverage after each
+ commit. You can test coverage via ``python setup.py nosetests
+ --with-coverage`` (requires the ``nose`` and ``coverage`` packages).
+
+Documentation Coverage
+----------------------
+
+- If you fix a bug, and the bug requires an API or behavior
+ modification, all documentation in this package which references
+ that API or behavior must change to reflect the bug fix, ideally in
+ the same commit that fixes the bug or adds the feature.
+
+Change Log
+----------
+
+- Feature additions and bugfixes must be added to the ``CHANGES.txt``
+ file in the prevailing style. Changelog entries should be long and
+ descriptive, not cryptic. Other developers should be able to know
+ what your changelog entry means.
+
+
diff --git a/TODO.txt b/TODO.txt
index ccb046faa..463b0e1d5 100644
--- a/TODO.txt
+++ b/TODO.txt
@@ -62,13 +62,9 @@
- Update App engine chapter.
-- Add SessionFactory interface
+- Browser id?
-- Create session interface (flash() is part of it, figure out granularity)
-
-- Add CacheFactory interface
-
-- Browser id
+- .flash API on session.
- Signed_signature method of the request and response from pylons2.
@@ -84,10 +80,12 @@
- ``handler`` ZCML directive.
-- ``bfg_view`` alias.
-
- ``repoze.bfg.message`` alias.
- Try to get rid of Mako Beaker dependency.
- Maybe make renderer globals lookup send an event?
+
+- bfgshell
+
+- ``docs`` directory for each paster template.
diff --git a/docs/api.rst b/docs/api.rst
index 8e7c0c283..e457d28f0 100644
--- a/docs/api.rst
+++ b/docs/api.rst
@@ -20,6 +20,7 @@ documentation is organized alphabetically by module name.
api/interfaces
api/location
api/paster
+ api/personality
api/renderers
api/request
api/router
diff --git a/docs/api/personality.rst b/docs/api/personality.rst
new file mode 100644
index 000000000..7eb964e76
--- /dev/null
+++ b/docs/api/personality.rst
@@ -0,0 +1,9 @@
+.. _personality_module:
+
+:mod:`pyramid.personality.pylons`
+---------------------------------
+
+.. module:: pyramid.personality.pylons
+
+.. function:: renderer_globals_factory_config
+
diff --git a/docs/api/request.rst b/docs/api/request.rst
index 9e851ba8d..97b164428 100644
--- a/docs/api/request.rst
+++ b/docs/api/request.rst
@@ -93,3 +93,8 @@
``request.session`` attribute will cause a
:class:`pyramid.exceptions.ConfigurationError` to be raised.
+ .. attribute:: tmpl_context
+
+ The template context for Pylons-style applications.
+
+
diff --git a/docs/api/view.rst b/docs/api/view.rst
index 5e884656c..0057cca4a 100644
--- a/docs/api/view.rst
+++ b/docs/api/view.rst
@@ -13,7 +13,7 @@
.. autofunction:: is_response
- .. autoclass:: bfg_view
+ .. autoclass:: view_config
:members:
.. autoclass:: static
diff --git a/docs/designdefense.rst b/docs/designdefense.rst
index 0e4784c66..c437f18d9 100644
--- a/docs/designdefense.rst
+++ b/docs/designdefense.rst
@@ -374,14 +374,14 @@ which don't use interfaces. Instead, each predicate uses a
domain-specific string as a match value.
For example, to write a view configuration which matches only requests
-with the ``POST`` HTTP request method, you might write a ``@bfg_view``
+with the ``POST`` HTTP request method, you might write a ``@view_config``
decorator which mentioned the ``request_method`` predicate:
.. code-block:: python
:linenos:
- from pyramid.view import bfg_view
- @bfg_view(name='post_view', request_method='POST', renderer='json')
+ from pyramid.view import view_config
+ @view_config(name='post_view', request_method='POST', renderer='json')
def post_view(request):
return 'POSTed'
@@ -392,8 +392,8 @@ response:
.. code-block:: python
:linenos:
- from pyramid.view import bfg_view
- @bfg_view(name='post_view', request_method='POST', accept='application/json',
+ from pyramid.view import view_config
+ @view_config(name='post_view', request_method='POST', accept='application/json',
renderer='json')
def post_view(request):
return 'POSTed'
@@ -417,13 +417,13 @@ acommodate this by allowing people to define "custom" view predicates:
.. code-block:: python
:linenos:
- from pyramid.view import bfg_view
+ from pyramid.view import view_config
from webob import Response
def subpath(context, request):
return request.subpath and request.subpath[0] == 'abc'
- @bfg_view(custom_predicates=(subpath,))
+ @view_config(custom_predicates=(subpath,))
def aview(request):
return Response('OK')
@@ -760,7 +760,7 @@ code.
Pyramid Is Too Big
------------------
-"The :mod:`pyramid` compressed tarball is 1MB. It must be
+"The :mod:`pyramid` compressed tarball is almost 2MB. It must be
enormous!"
No. We just ship it with test code and helper templates. Here's a
@@ -768,26 +768,26 @@ breakdown of what's included in subdirectories of the package tree:
docs/
- 2.2MB
+ 3.0MB
-repoze/bfg/tests
+pyramid/tests/
- 580KB
+ 1.1MB
-repoze/bfg/paster_templates
+pyramid/paster_templates/
- 372KB
+ 804KB
-repoze/bfg (except for ``repoze/bfg/tests and repoze/bfg/paster_templates``)
+pyramid/ (except for ``pyramd/tests and pyramid/paster_templates``)
- 316K
+ 539K
-The actual :mod:`pyramid` runtime code is about 10% of the total
-size of the tarball omitting docs, helper templates used for package
+The actual :mod:`pyramid` runtime code is about 10% of the total size
+of the tarball omitting docs, helper templates used for package
generation, and test code. Of the approximately 13K lines of Python
code in the package, the code that actually has a chance of executing
during normal operation, excluding tests and paster template Python
-files, accounts for approximately 3K lines of Python code. This is
+files, accounts for approximately 5K lines of Python code. This is
comparable to Pylons, which ships with a little over 2K lines of
Python code, excluding tests.
diff --git a/docs/glossary.rst b/docs/glossary.rst
index 93d86b664..9259fed0a 100644
--- a/docs/glossary.rst
+++ b/docs/glossary.rst
@@ -97,20 +97,20 @@ Glossary
which will be an instance of a :term:`request` object. An
alternate calling convention allows a view to be defined as a
callable which accepts a pair of arguments: ``context`` and
- ``request``: this calling convention is useful for traversal-based
- applications in which a :term:`context` is always very important. A
- view callable is the primary mechanism by which a developer writes
- user interface code within :mod:`repoze.bfg`. See
- :ref:`views_chapter` for more information about :mod:`repoze.bfg`
- view callables.
+ ``request``: this calling convention is useful for
+ traversal-based applications in which a :term:`context` is always
+ very important. A view callable is the primary mechanism by
+ which a developer writes user interface code within
+ :mod:`pyramid`. See :ref:`views_chapter` for more information
+ about :mod:`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.
- :mod:`repoze.bfg` views can be configured via :term:`imperative
- configuration`, :term:`ZCML` or by a special ``@bfg_view``
+ :mod:`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:`views_chapter`
for more information about view configuration.
@@ -138,12 +138,12 @@ Glossary
:term:`context` of a :term:`view`. If :mod:`url dispatch` is
used, a single :term:`context` is generated for each request and
is used as the context of a view: this object is also technically
- a "model" in :mod:`repoze.bfg` terms, although this terminology
+ a "model" in :mod:`pyramid` terms, although this terminology
can be a bit confusing: see :ref:`model_traversal_confusion`.
traversal
The act of descending "down" a graph of model objects from a root
- model in order to find a :term:`context`. The :mod:`repoze.bfg`
+ model in order to find a :term:`context`. The :mod:`pyramid`
:term:`router` performs traversal of model objects when a
:term:`root factory` is specified. See the
:ref:`traversal_chapter` chapter for more information. Traversal
@@ -153,15 +153,15 @@ Glossary
router
The :term:`WSGI` application created when you start a
- :mod:`repoze.bfg` application. The router intercepts requests,
+ :mod:`pyramid` application. The router intercepts requests,
invokes traversal and/or URL dispatch, calls view functions, and
returns responses to the WSGI server on behalf of your
- :mod:`repoze.bfg` application.
+ :mod:`pyramid` application.
URL dispatch
An alternative to graph traversal as a mechanism for locating a
:term:`context` for a :term:`view`. When you use a :term:`route`
- in your :mod:`repoze.bfg` application via a :term:`route
+ in your :mod:`pyramid` application via a :term:`route
configuration`, you are using URL dispatch. See the
:ref:`urldispatch_chapter` for more information.
@@ -178,10 +178,10 @@ Glossary
application registry
A registry of configuration information consulted by
- :mod:`repoze.bfg` while servicing an application. An application
+ :mod:`pyramid` while servicing an application. An application
registry maps model types to views, as well as housing other
application-specific component registrations. Every
- :mod:`repoze.bfg` application has one (and only one) application
+ :mod:`pyramid` application has one (and only one) application
registry.
template
@@ -235,7 +235,7 @@ Glossary
authentication
The act of determining that the credentials a user presents
during a particular request are "good". Authentication in
- :mod:`repoze.bfg` is performed via an :term:`authentication
+ :mod:`pyramid` is performed via an :term:`authentication
policy`.
authorization
@@ -243,7 +243,7 @@ Glossary
action. In bfg terms, this means determining whether, for a given
context, any :term:`principal` (or principals) associated with the
request have the requisite :term:`permission` to allow the request
- to continue. Authorization in :mod:`repoze.bfg` is performed via
+ to continue. Authorization in :mod:`pyramid` is performed via
its :term:`authorization policy`.
principal
@@ -256,21 +256,21 @@ Glossary
"group foo" and "group bar".
authorization policy
- An authorization policy in :mod:`repoze.bfg` terms is a bit of
+ An authorization policy in :mod:`pyramid` terms is a bit of
code which has an API which determines whether or not the
principals associated with the request can perform an action
associated with a permission, based on the information found on the
:term:`context`.
authentication policy
- An authentication policy in :mod:`repoze.bfg` terms is a bit of
+ An authentication policy in :mod:`pyramid` terms is a bit of
code which has an API which determines the current
:term:`principal` (or principals) associated with a request.
WSGI
`Web Server Gateway Interface <http://wsgi.org/>`_. This is a
Python standard for connecting web applications to web servers,
- similar to the concept of Java Servlets. ``repoze.bfg`` requires
+ similar to the concept of Java Servlets. ``pyramid`` requires
that your application be served as a WSGI application.
middleware
@@ -318,7 +318,7 @@ Glossary
PasteDeploy
`PasteDeploy <http://pythonpaste.org>`_ is a library used by
- :mod:`repoze.bfg` which makes it possible to configure
+ :mod:`pyramid` which makes it possible to configure
:term:`WSGI` components together declaratively within an ``.ini``
file. It was developed by Ian Bicking as part of :term:`Paste`.
@@ -329,7 +329,7 @@ Glossary
maintained by Malthe Borch. It has several extensions, such as
the ability to use bracketed (Genshi-style) ``${name}`` syntax,
even within ZPT. It is also much faster than the reference
- implementations of both ZPT and Genshi. :mod:`repoze.bfg` offers
+ implementations of both ZPT and Genshi. :mod:`pyramid` offers
Chameleon templating out of the box in ZPT and text flavors.
ZPT
@@ -352,7 +352,7 @@ Glossary
Routes
A `system by Ben Bangert <http://routes.groovie.org/>`_ which
parses URLs and compares them against a number of user defined
- mappings. The URL pattern matching syntax in :mod:`repoze.bfg` is
+ mappings. The URL pattern matching syntax in :mod:`pyramid` is
inspired by the Routes syntax (which was inspired by Ruby On
Rails pattern syntax).
@@ -372,11 +372,11 @@ Glossary
ZCML
`Zope Configuration Markup Language
<http://www.muthukadan.net/docs/zca.html#zcml>`_, an XML dialect
- used by Zope and :mod:`repoze.bfg` for configuration tasks. ZCML
+ used by Zope and :mod:`pyramid` for configuration tasks. ZCML
is capable of performing different types of :term:`configuration
- declaration`, but its primary purpose in :mod:`repoze.bfg` is to
+ declaration`, but its primary purpose in :mod:`pyramid` is to
perform :term:`view configuration` and :term:`route configuration`
- within the ``configure.zcml`` file in a :mod:`repoze.bfg`
+ within the ``configure.zcml`` file in a :mod:`pyramid`
application. You can use ZCML as an alternative to
:term:`imperative configuration`.
@@ -391,7 +391,7 @@ Glossary
<http://www.muthukadan.net/docs/zca.html>`_ (aka ZCA) is a system
which allows for application pluggability and complex dispatching
based on objects which implement an :term:`interface`.
- :mod:`repoze.bfg` uses the ZCA "under the hood" to perform view
+ :mod:`pyramid` uses the ZCA "under the hood" to perform view
dispatching and other application configuration tasks.
reStructuredText
@@ -402,7 +402,7 @@ Glossary
root
The object at which :term:`traversal` begins when
- :mod:`repoze.bfg` searches for a :term:`context` (for :term:`URL
+ :mod:`pyramid` searches for a :term:`context` (for :term:`URL
Dispatch`, the root is *always* the context).
subpath
@@ -415,26 +415,26 @@ Glossary
interface
A `Zope interface <http://pypi.python.org/pypi/zope.interface>`_
- object. In :mod:`repoze.bfg`, an interface may be attached to a
+ object. In :mod:`pyramid`, an interface may be attached to a
:term:`model` object or a :term:`request` object in order to
identify that the object is "of a type". Interfaces are used
- internally by :mod:`repoze.bfg` to perform view lookups and other
+ internally by :mod:`pyramid` to perform view lookups and other
policy lookups. The ability to make use of an interface is
exposed to an application programmers during :term:`view
configuration` via the ``context`` argument, the ``request_type``
argument and the ``containment`` argument. Interfaces are also
exposed to application developers when they make use of the
- :term:`event` system. Fundamentally, :mod:`repoze.bfg`
+ :term:`event` system. Fundamentally, :mod:`pyramid`
programmers can think of an interface as something that they can
attach to an object that stamps it with a "type" unrelated to its
underlying Python type. Interfaces can also be used to describe
the behavior of an object (its methods and attributes), but
- unless they choose to, :mod:`repoze.bfg` programmers do not need
+ unless they choose to, :mod:`pyramid` programmers do not need
to understand or use this feature of interfaces.
event
An object broadcast to zero or more :term:`subscriber` callables
- during normal :mod:`repoze.bfg` system operations during the
+ during normal :mod:`pyramid` system operations during the
lifetime of an application. Application code can subscribe to
these events by using the subscriber functionality described in
:ref:`events_chapter`.
@@ -448,32 +448,32 @@ Glossary
request type
An attribute of a :term:`request` that allows for specialization
of view invocation based on arbitrary categorization. The every
- :term:`request` object that :mod:`repoze.bfg` generates and
+ :term:`request` object that :mod:`pyramid` generates and
manipulates has one or more :term:`interface` objects attached to
it. The default interface attached to a request object is
- ``repoze.bfg.interfaces.IRequest``.
+ ``pyramid.interfaces.IRequest``.
repoze.lemonade
Zope2 CMF-like `data structures and helper facilities
<http://docs.repoze.org/lemonade>`_ for CA-and-ZODB-based
- applications useful within :mod:`repoze.bfg` applications.
+ applications useful within :mod:`pyramid` applications.
repoze.catalog
An indexing and search facility (fielded and full-text) based on
`zope.index <http://pypi.python.org/pypi/zope.index>`_. See `the
documentation <http://docs.repoze.org/catalog>`_ for more
- information. A tutorial for its usage in :mod:`repoze.bfg`
+ information. A tutorial for its usage in :mod:`pyramid`
exists in :ref:`catalog_tutorial`.
repoze.who
`Authentication middleware <http://docs.repoze.org/who>`_ for
- :term:`WSGI` applications. It can be used by :mod:`repoze.bfg` to
+ :term:`WSGI` applications. It can be used by :mod:`pyramid` to
provide authentication information.
repoze.workflow
`Barebones workflow for Python apps
<http://docs.repoze.org/workflow>`_ . It can be used by
- :mod:`repoze.bfg` to form a workflow system.
+ :mod:`pyramid` to form a workflow system.
virtual root
A model object representing the "virtual" root of a request; this
@@ -490,11 +490,11 @@ Glossary
object in a lineage is available as its ``__parent__`` attribute.
root factory
- The "root factory" of an :mod:`repoze.bfg` application is called
+ The "root factory" of an :mod:`pyramid` application is called
on every request sent to the application. The root factory
returns the traversal root of an application. It is
conventionally named ``get_root``. An application may supply a
- root factory to :mod:`repoze.bfg` during the construction of a
+ root factory to :mod:`pyramid` during the construction of a
:term:`Configurator`. If a root factory is not supplied, the
application uses a default root object. Use of the default root
object is useful in application which use :term:`URL dispatch` for
@@ -524,7 +524,7 @@ Glossary
`mod_wsgi <http://code.google.com/p/modwsgi/>`_ is an Apache
module developed by Graham Dumpleton. It allows :term:`WSGI`
applications (such as applications developed using
- :mod:`repoze.bfg`) to be served using the Apache web server.
+ :mod:`pyramid`) to be served using the Apache web server.
view predicate
An argument to a :term:`view configuration` which evaluates to
@@ -548,7 +548,7 @@ Glossary
predicate
A test which returns ``True`` or ``False``. Two different types
- of predicates exist in :mod:`repoze.bfg`: a :term:`view predicate`
+ of predicates exist in :mod:`pyramid`: a :term:`view predicate`
and a :term:`route predicate`. View predicates are attached to
:term:`view configuration` and route predicates are attached to
:term:`route configuration`.
@@ -556,13 +556,13 @@ Glossary
decorator
A wrapper around a Python function or class which accepts the
function or class as its first argument and which returns an
- arbitrary object. :mod:`repoze.bfg` provides several decorators,
+ arbitrary object. :mod:`pyramid` provides several decorators,
used for configuration and return value modification purposes. See
also `PEP 318 <http://www.python.org/dev/peps/pep-0318/>`_.
configuration declaration
An individual method call made to an instance of a
- :mod:`repoze.bfg` :term:`Configurator` object which performs an
+ :mod:`pyramid` :term:`Configurator` object which performs an
arbitrary action, such as registering a :term:`view configuration`
(via the ``view`` method of the configurator) or :term:`route
configuration` (via the ``route`` method of the configurator). A
@@ -572,19 +572,21 @@ Glossary
of code in a package.
configuration decoration
+
Metadata implying one or more :term:`configuration declaration`
invocations. Often set by configuration Python :term:`decorator`
- attributes, such as ``repoze.bfg.view.bfg_view``, aka ``@bfg_view``.
+ attributes, such as :class:`pyramid.view.view_config`, aka
+ ``@view_config``.
scan
- The term used by :mod:`repoze.bfg` to define the process of
+ The term used by :mod:`pyramid` to define the process of
importing and examining all code in a Python package or module for
:term:`configuration decoration`.
configurator
An object used to do :term:`configuration declaration` within an
application. The most common configurator is an instance of the
- ``repoze.bfg.configuration.Configurator`` class.
+ ``pyramid.configuration.Configurator`` class.
imperative configuration
The configuration mode in which you use Python to call methods on
@@ -596,28 +598,28 @@ Glossary
a set of :term:`configuration declaration` statements.
Not Found view
- An :term:`exception view` invoked by :mod:`repoze.bfg` when the
- developer explicitly raises a ``repoze.bfg.exceptions.NotFound``
+ An :term:`exception view` invoked by :mod:`pyramid` when the
+ developer explicitly raises a ``pyramid.exceptions.NotFound``
exception from within :term:`view` code or :term:`root factory`
code, or when the current request doesn't match any :term:`view
- configuration`. :mod:`repoze.bfg` provides a default
+ configuration`. :mod:`pyramid` provides a default
implementation of a not found view; it can be overridden. See
:ref:`changing_the_notfound_view`.
Forbidden view
- An :term:`exception view` invoked by :mod:`repoze.bfg` when the
+ An :term:`exception view` invoked by :mod:`pyramid` when the
developer explicitly raises a
- ``repoze.bfg.exceptions.Forbidden`` exception from within
+ ``pyramid.exceptions.Forbidden`` exception from within
:term:`view` code or :term:`root factory` code, or when the
:term:`view configuration` and :term:`authorization policy`
found for a request disallows a particular view invocation.
- :mod:`repoze.bfg` provides a default implementation of a
+ :mod:`pyramid` provides a default implementation of a
forbidden view; it can be overridden. See
:ref:`changing_the_forbidden_view`.
Exception view
An exception view is a :term:`view callable` which may be
- invoked by :mod:`repoze.bfg` when an exception is raised during
+ invoked by :mod:`pyramid` when an exception is raised during
request processing. See :ref:`exception_views` for more
information.
@@ -627,7 +629,7 @@ Glossary
each `thread
<http://en.wikipedia.org/wiki/Thread_(computer_science)>` used by
the application may have a different value for this same "global"
- variable. :mod:`repoze.bfg` uses a small number of thread local
+ variable. :mod:`pyramid` uses a small number of thread local
variables, as described in :ref:`threadlocals_chapter`. See also
the `threading.local documentation
<http://docs.python.org/library/threading.html#threading.local>`
@@ -653,7 +655,7 @@ Glossary
Python
The `programming language <http://python.org>` in which
- :mod:`repoze.bfg` is written.
+ :mod:`pyramid` is written.
CPython
The C implementation of the Python language. This is the
@@ -671,7 +673,7 @@ Glossary
The act of locating a :term:`context` and a :term:`view name`
given a :term:`request`. :term:`Traversal` and :term:`URL
dispatch` are the context finding subsystems used by
- :mod:`repoze.bfg`.
+ :mod:`pyramid`.
Triad
The three bits of information used by :term:`view lookup` to find
@@ -681,18 +683,18 @@ Glossary
Google App Engine
`Google App Engine <http://code.google.com/appengine/>`_ (aka
"GAE") is a Python application hosting service offered by Google.
- :mod:`repoze.bfg` runs on GAE.
+ :mod:`pyramid` runs on GAE.
Venusian
`Venusian <http://docs.repoze.org/venusian>`_ is a library which
allows framework authors to defer decorator actions. Instead of
taking actions when a function (or class) decorator is executed
at import time, the action usually taken by the decorator is
- deferred until a separate "scan" phase. :mod:`repoze.bfg` relies
+ deferred until a separate "scan" phase. :mod:`pyramid` relies
on Venusian to provide a basis for its :term:`scan` feature.
Translation String
- An instance of :class:`repoze.bfg.i18n.TranslationString`, which
+ An instance of :class:`pyramid.i18n.TranslationString`, which
is a class that behaves like a Unicode string, but has several
extra attributes such as ``domain``, ``msgid``, and ``mapping``
for use during translation. Translation strings are usually
@@ -712,7 +714,7 @@ Glossary
A callable which receives a :term:`translation string` and
returns a translated Unicode object for the purposes of
internationalization. A :term:`localizer` supplies a
- translator to a :mod:`repoze.bfg` application accessible via its
+ translator to a :mod:`pyramid` application accessible via its
``translate`` method.
Translation Directory
@@ -724,10 +726,10 @@ Glossary
(minus the .mo extension) is the translation domain name.
Localizer
- An instance of the class :class:`repoze.bfg.i18n.Localizer` which
+ An instance of the class :class:`pyramid.i18n.Localizer` which
provides translation and pluralization services to an
application. It is retrieved via the
- :func:`repoze.bfg.i18n.get_localizer` function.
+ :func:`pyramid.i18n.get_localizer` function.
Locale Name
A string like ``en``, ``en_US``, ``de``, or ``de_AT`` which
@@ -740,19 +742,19 @@ Glossary
Locale Negotiator
An object supplying a policy determining which :term:`locale
name` best represents a given :term:`request`. It is used by the
- :func:`repoze.bfg.i18n.get_locale_name`, and
- :func:`repoze.bfg.i18n.negotiate_locale_name` functions, and
- indirectly by :func:`repoze.bfg.i18n.get_localizer`. The
- :func:`repoze.bfg.i18n.default_locale_negotiator` function
+ :func:`pyramid.i18n.get_locale_name`, and
+ :func:`pyramid.i18n.negotiate_locale_name` functions, and
+ indirectly by :func:`pyramid.i18n.get_localizer`. The
+ :func:`pyramid.i18n.default_locale_negotiator` function
is an example of a locale negotiator.
Gettext
The GNU `gettext <http://www.gnu.org/software/gettext/>`_
- library, used by the :mod:`repoze.bfg` translation machinery.
+ library, used by the :mod:`pyramid` translation machinery.
Babel
A `collection of tools <http://babel.edgewall.org/>`_ for
- internationalizing Python applications. :mod:`repoze.bfg` does
+ internationalizing Python applications. :mod:`pyramid` does
not depend on Babel to operate, but if Babel is installed,
additional locale functionality becomes available to your
application.
@@ -797,11 +799,11 @@ Glossary
pregenerator
A pregenerator is a function associated by a developer with a
- :term:`route`. It is called by :func:`repoze.bfg.url.route_url`
+ :term:`route`. It is called by :func:`pyramid.url.route_url`
in order to adjust the set of arguments passed to it by the user
for special purposes. It will influence the URL returned by
``route_url``. See
- :class:`repoze.bfg.interfaces.IRoutePregenerator` for more
+ :class:`pyramid.interfaces.IRoutePregenerator` for more
information.
session
diff --git a/docs/narr/configuration.rst b/docs/narr/configuration.rst
index fe55705bb..a62cf76ff 100644
--- a/docs/narr/configuration.rst
+++ b/docs/narr/configuration.rst
@@ -254,7 +254,7 @@ application. This error will contain information about which tags
might have conflicted.
.. index::
- single: bfg_view
+ single: view_config
single: ZCML view directive
single: configuration decoration
single: code scanning
@@ -277,10 +277,10 @@ referred to by the declaration itself. For example:
.. code-block:: python
:linenos:
- from pyramid.view import bfg_view
+ from pyramid.view import view_config
from webob import Response
- @bfg_view(name='hello', request_method='GET')
+ @view_config(name='hello', request_method='GET')
def hello(request):
return Response('Hello')
@@ -290,7 +290,7 @@ the configuration of a :mod:`pyramid` application, a configuration
decoration within application code must be found through a process
known as a :term:`scan`.
-The :class:`pyramid.view.bfg_view` decorator above adds an
+The :class:`pyramid.view.view_config` decorator above adds an
attribute to the ``hello`` function, making it available for a
:term:`scan` to find it later.
@@ -306,10 +306,10 @@ and its subpackages. For example:
:linenos:
from paste.httpserver import serve
- from pyramid.view import bfg_view
+ from pyramid.view import view_config
from webob import Response
- @bfg_view()
+ @view_config()
def hello(request):
return Response('Hello')
@@ -334,10 +334,10 @@ directive, the package the ZCML file points to is scanned.
# helloworld.py
from paste.httpserver import serve
- from pyramid.view import bfg_view
+ from pyramid.view import view_config
from webob import Response
- @bfg_view()
+ @view_config()
def hello(request):
return Response('Hello')
@@ -366,7 +366,7 @@ The scanning machinery imports each module and subpackage in a package
or module recursively, looking for special attributes attached to
objects defined within a module. These special attributes are
typically attached to code via the use of a :term:`decorator`. For
-example, the :class:`pyramid.view.bfg_view` decorator can be
+example, the :class:`pyramid.view.view_config` decorator can be
attached to a function or instance method.
Once scanning is invoked, and :term:`configuration decoration` is
@@ -375,7 +375,7 @@ found by the scanner, a set of calls are made to a
the intent of the configuration decoration.
In the example above, this is best represented as the scanner
-translating the arguments to :class:`pyramid.view.bfg_view` into a
+translating the arguments to :class:`pyramid.view.view_config` into a
call to the :meth:`pyramid.configuration.Configurator.add_view`
method, effectively:
diff --git a/docs/narr/extending.rst b/docs/narr/extending.rst
index 490d0733f..88b42eabf 100644
--- a/docs/narr/extending.rst
+++ b/docs/narr/extending.rst
@@ -39,7 +39,7 @@ The fundamental "plug points" of an application developed using
:mod:`pyramid` are *routes*, *views*, and *resources*. Routes are
declarations made using the ZCML ``<route>`` directive. Views are
declarations made using the ZCML ``<view>`` directive (or the
-``@bfg_view`` decorator). Resources are files that are accessed by
+``@view_config`` decorator). Resources are files that are accessed by
:mod:`pyramid` using the :term:`pkg_resources` API such as static
files and templates.
@@ -89,7 +89,7 @@ Extending an Application Which Possesses Configuration Decorators Or Which Does
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
If you've inherited a :mod:`pyramid` application which uses
-:class:`pyramid.view.bfg_view` decorators or which performs
+:class:`pyramid.view.view_config` decorators or which performs
configuration imperatively, one of two things may be true:
- If you just want to *extend* the application, you can write
@@ -101,7 +101,7 @@ configuration imperatively, one of two things may be true:
*may* need to change the source code of the original application.
If the only source of trouble is the existence of
- :class:`pyramid.view.bfg_view` decorators, you can just prevent a
+ :class:`pyramid.view.view_config` decorators, you can just prevent a
:term:`scan` from happening (by omitting the ``<scan>`` declaration
from ZCML or omitting any call to the
:meth:`pyramid.configuration.Configurator.scan` method). This
diff --git a/docs/narr/hooks.rst b/docs/narr/hooks.rst
index db933c525..12c1cd0aa 100644
--- a/docs/narr/hooks.rst
+++ b/docs/narr/hooks.rst
@@ -556,7 +556,7 @@ subscriber of a :class:`pyramid.interfaces.INewRequest` event).
Registering Configuration Decorators
------------------------------------
-Decorators such as :class:`pyramid.view.bfg_view` don't change the
+Decorators such as :class:`pyramid.view.view_config` don't change the
behavior of the functions or classes they're decorating. Instead,
when a :term:`scan` is performed, a modified version of the function
or class is registered with :mod:`pyramid`.
diff --git a/docs/narr/project.rst b/docs/narr/project.rst
index 0e18f0924..f88496fcc 100644
--- a/docs/narr/project.rst
+++ b/docs/narr/project.rst
@@ -21,6 +21,9 @@ templates".
single: pyramid_zodb paster template
single: pyramid_alchemy paster template
single: pyramid_routesalchemy paster template
+ single: pylons_minimal paster template
+ single: pylons_basic paster template
+ single: pylons_sqla paster template
.. _additional_paster_templates:
@@ -52,6 +55,18 @@ The included templates are these:
URL mapping via :term:`traversal` and persistence via
:term:`SQLAlchemy`
+``pylons_minimal``
+ URL mapping via :term:`URL dispatch` and Pylons-style view handlers,
+ minimal setup.
+
+``pylons_basic``
+ URL mapping via :term:`URL dispatch` and Pylons-style view handlers,
+ and some extra functionality.
+
+``pylons_sqla``
+ URL mapping via :term:`URL dispatch` and Pylons-style view handlers,
+ some extra functionality, and SQLAlchemy set up.
+
Each of these project templates uses :term:`ZCML` instead of
:term:`imperative configuration`. Each also makes the assumption that
you want your code to live in a Python :term:`package`. Even if your
diff --git a/docs/narr/security.rst b/docs/narr/security.rst
index 5782837aa..63d1cad25 100644
--- a/docs/narr/security.rst
+++ b/docs/narr/security.rst
@@ -181,16 +181,16 @@ For example, the following declaration protects the view named
/>
The equivalent view registration including the ``add`` permission name
-may be performed via the ``@bfg_view`` decorator:
+may be performed via the ``@view_config`` decorator:
.. ignore-next-block
.. code-block:: python
:linenos:
- from pyramid.view import bfg_view
+ from pyramid.view import view_config
from models import Blog
- @bfg_view(context=Blog, name='add_entry.html', permission='add')
+ @view_config(context=Blog, name='add_entry.html', permission='add')
def blog_entry_add_view(request):
""" Add blog entry code goes here """
pass
diff --git a/docs/narr/sessions.rst b/docs/narr/sessions.rst
index e460e2d74..df164e684 100644
--- a/docs/narr/sessions.rst
+++ b/docs/narr/sessions.rst
@@ -88,9 +88,6 @@ two extra methods.
Extra attributes:
-``modified``
- An integer timestamp indicating the last time the session was modified.
-
``created``
An integer timestamp indicating the time that this session was created.
@@ -130,13 +127,24 @@ Some gotchas:
When in doubt, call ``changed()`` after you've changed sessioning
data.
+.. index::
+ single: pyramid_beaker
+ single: Beaker
+
Using Alternate Session Factories
---------------------------------
-At the time of this writing, alternate session factories don't yet
-exist. It is our intent that we will soon provide at least one other
-session factory which will be easily installable: one that uses the
-`Beaker <http://beaker.groovie.org/>`_ library as a backend.
+At the time of this writing, exactly one alternate session factory
+implementation exists, named ``pyramid_beaker``. This is a session
+factory that uses the `Beaker <http://beaker.groovie.org/>`_ library
+as a backend. Beaker has support for file-based sessions, database
+based sessions, and encrypted cookie-based sessions. See
+`http://github.com/Pylons/pyramid_beaker
+<http://github.com/Pylons/pyramid_beaker>`_ for more information about
+``pyramid_beaker``.
+
+.. index::
+ single: session factory
Creating Your Own Session Factory
---------------------------------
diff --git a/docs/narr/templates.rst b/docs/narr/templates.rst
index 0650480af..57d1bc3b9 100644
--- a/docs/narr/templates.rst
+++ b/docs/narr/templates.rst
@@ -285,16 +285,16 @@ The association of a template as a renderer for a :term:`view
configuration` makes it possible to replace code within a :term:`view
callable` that handles the rendering of a template.
-Here's an example of using a :class:`pyramid.view.bfg_view`
+Here's an example of using a :class:`pyramid.view.view_config`
decorator to specify a :term:`view configuration` that names a
template renderer:
.. code-block:: python
:linenos:
- from pyramid.view import bfg_view
+ from pyramid.view import view_config
- @bfg_view(renderer='templates/foo.pt')
+ @view_config(renderer='templates/foo.pt')
def my_view(request):
return {'foo':1, 'bar':2}
@@ -310,7 +310,7 @@ Similar renderer configuration can be done imperatively and via
:term:`ZCML`. See :ref:`views_which_use_a_renderer`. See also
:ref:`built_in_renderers`.
-The ``renderer`` argument to the ``@bfg_view`` configuration decorator
+The ``renderer`` argument to the ``@view_config`` configuration decorator
shown above is the template *path*. In the example above, the path
``templates/foo.pt`` is *relative*. Relative to what, you ask?
Relative to the directory in which the file which defines the view
@@ -347,7 +347,7 @@ of :term:`Jinja2` templates as renderers. See
configuration typically return a dictionary, and making assertions
about the information is almost always more direct than needing to
parse HTML. Specifying a renderer from within :term:`ZCML` (as
- opposed to imperatively or via a ``bfg_view`` decorator, or using a
+ opposed to imperatively or via a ``view_config`` decorator, or using a
template directly from within a view callable) also makes it
possible for someone to modify the template used to render a view
without needing to fork your code to do so. See
@@ -401,9 +401,9 @@ the template as a :term:`renderer` like so:
.. code-block:: python
:linenos:
- from pyramid.view import bfg_view
+ from pyramid.view import view_config
- @bfg_view(renderer='templates/foo.pt')
+ @view_config(renderer='templates/foo.pt')
def my_view(request):
return {'foo':1, 'bar':2}
@@ -467,16 +467,16 @@ the macro itself) *into* the rendered template. To make a macro
available to the rendered template, you can retrieve a different
template using the :func:`pyramid.renderers.get_renderer` API,
and pass it in to the template being rendered. For example, using a
-:term:`view configuration` via a :class:`pyramid.view.bfg_view`
+:term:`view configuration` via a :class:`pyramid.view.view_config`
decorator that uses a :term:`renderer`:
.. code-block:: python
:linenos:
from pyramid.renderers import get_renderer
- from pyramid.view import bfg_view
+ from pyramid.view import view_config
- @bfg_view(renderer='templates/mytemplate.pt')
+ @view_config(renderer='templates/mytemplate.pt')
def my_view(request):
main = get_renderer('templates/master.pt').implementation()
return {'main':main}
@@ -534,9 +534,9 @@ which renders this template:
.. code-block:: python
:linenos:
- from pyramid.view import bfg_view
+ from pyramid.view import view_config
- @bfg_view(renderer='templates/mytemplate.txt')
+ @view_config(renderer='templates/mytemplate.txt')
def my_view(request):
return {'name':'world'}
diff --git a/docs/narr/views.rst b/docs/narr/views.rst
index 2969487d3..39115a493 100644
--- a/docs/narr/views.rst
+++ b/docs/narr/views.rst
@@ -255,9 +255,9 @@ Response interface, :mod:`pyramid` will attempt to use a
:linenos:
from webob import Response
- from pyramid.view import bfg_view
+ from pyramid.view import view_config
- @bfg_view(renderer='json')
+ @view_config(renderer='json')
def hello_world(request):
return {'content':'Hello!'}
@@ -266,7 +266,7 @@ dictionary does not implement the :term:`WebOb` response interface, so
you might believe that this example would fail. However, since a
``renderer`` is associated with the view callable through its
:term:`view configuration` (in this case, using a ``renderer``
-argument passed to :func:`pyramid.view.bfg_view`), if the view does
+argument passed to :func:`pyramid.view.view_config`), if the view does
*not* return a Response object, the renderer will attempt to convert
the result of the view to a response on the developer's behalf. Of
course, if no renderer is associated with a view's configuration,
@@ -411,9 +411,9 @@ representation of the dictionary:
:linenos:
from webob import Response
- from pyramid.view import bfg_view
+ from pyramid.view import view_config
- @bfg_view(renderer='string')
+ @view_config(renderer='string')
def hello_world(request):
return {'content':'Hello!'}
@@ -450,9 +450,9 @@ view will render the returned dictionary to a JSON serialization:
:linenos:
from webob import Response
- from pyramid.view import bfg_view
+ from pyramid.view import view_config
- @bfg_view(renderer='json')
+ @view_config(renderer='json')
def hello_world(request):
return {'content':'Hello!'}
@@ -610,9 +610,9 @@ attribute to the request before returning a result:
.. code-block:: python
:linenos:
- from pyramid.view import bfg_view
+ from pyramid.view import view_config
- @bfg_view(name='gone', renderer='templates/gone.pt')
+ @view_config(name='gone', renderer='templates/gone.pt')
def myview(request):
request.response_status = '404 Not Found'
return {'URL':request.URL}
@@ -737,9 +737,9 @@ attribute of a :term:`view configuration`:
.. code-block:: python
:linenos:
- from pyramid.view import bfg_view
+ from pyramid.view import view_config
- @bfg_view(renderer='amf')
+ @view_config(renderer='amf')
def myview(request):
return {'Hello':'world'}
@@ -771,9 +771,9 @@ configuration`:
.. code-block:: python
:linenos:
- from pyramid.view import bfg_view
+ from pyramid.view import view_config
- @bfg_view(renderer='templates/mytemplate.jinja2')
+ @view_config(renderer='templates/mytemplate.jinja2')
def myview(request):
return {'Hello':'world'}
@@ -928,7 +928,7 @@ code raises a ``hellworld.exceptions.ValidationFailure`` exception:
from helloworld.exceptions import ValidationFailure
- @bfg_view(context=ValidationFailure)
+ @view_config(context=ValidationFailure)
def failed_validation(exc, request):
response = Response('Failed validation: %s' % exc.msg)
response.status_int = 500
@@ -946,11 +946,11 @@ exception view registration:
.. code-block:: python
:linenos:
- from pyramid.view import bfg_view
+ from pyramid.view import view_config
from pyramid.exceptions import NotFound
from webob.exc import HTTPNotFound
- @bfg_view(context=NotFound, route_name='home')
+ @view_config(context=NotFound, route_name='home')
def notfound_view(request):
return HTTPNotFound()
@@ -976,7 +976,7 @@ registered as exception views which have a name will be ignored.
normal view.
The feature can be used with any view registration mechanism
-(``@bfg_view`` decorator, ZCML, or imperative ``add_view`` styles).
+(``@view_config`` decorator, ZCML, or imperative ``add_view`` styles).
.. index::
single: unicode, views, and forms
@@ -1120,8 +1120,8 @@ View configuration is performed in one of three ways:
:ref:`view_directive`.
- by running a :term:`scan` against application source code which has
- a :class:`pyramid.view.bfg_view` decorator attached to a Python
- object as per :class:`pyramid.view.bfg_view` and
+ a :class:`pyramid.view.view_config` decorator attached to a Python
+ object as per :class:`pyramid.view.view_config` and
:ref:`mapping_views_using_a_decorator_section`.
- by using the :meth:`pyramid.configuration.Configurator.add_view`
@@ -1497,15 +1497,15 @@ apply for the class which is named.
See :ref:`view_directive` for complete ZCML directive documentation.
.. index::
- single: bfg_view decorator
+ single: view_config decorator
.. _mapping_views_using_a_decorator_section:
-View Configuration Using the ``@bfg_view`` Decorator
+View Configuration Using the ``@view_config`` Decorator
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
For better locality of reference, you may use the
-:class:`pyramid.view.bfg_view` decorator to associate your view
+:class:`pyramid.view.view_config` decorator to associate your view
functions with URLs instead of using :term:`ZCML` or imperative
configuration for the same purpose.
@@ -1520,15 +1520,15 @@ configuration for the same purpose.
See :ref:`extending_chapter` for more information about building
extensible applications.
-Usage of the ``bfg_view`` decorator is a form of :term:`declarative
+Usage of the ``view_config`` decorator is a form of :term:`declarative
configuration`, like ZCML, but in decorator form.
-:class:`pyramid.view.bfg_view` can be used to associate :term:`view
+:class:`pyramid.view.view_config` can be used to associate :term:`view
configuration` information -- as done via the equivalent ZCML -- with
a function that acts as a :mod:`pyramid` view callable. All ZCML
:ref:`view_directive` attributes (save for the ``view`` attribute) are
available in decorator form and mean precisely the same thing.
-An example of the :class:`pyramid.view.bfg_view` decorator might
+An example of the :class:`pyramid.view.view_config` decorator might
reside in a :mod:`pyramid` application module ``views.py``:
.. ignore-next-block
@@ -1536,10 +1536,10 @@ reside in a :mod:`pyramid` application module ``views.py``:
:linenos:
from models import MyModel
- from pyramid.view import bfg_view
+ from pyramid.view import view_config
from pyramid.chameleon_zpt import render_template_to_response
- @bfg_view(name='my_view', request_method='POST', context=MyModel,
+ @view_config(name='my_view', request_method='POST', context=MyModel,
permission='read', renderer='templates/my.pt')
def my_view(request):
return {'a':1}
@@ -1567,15 +1567,15 @@ Or replaces the need to add this imperative configuration stanza:
config.add_view('.views.my_view', name='my_view', request_method='POST',
context=MyModel, permission='read')
-All arguments to ``bfg_view`` may be omitted. For example:
+All arguments to ``view_config`` may be omitted. For example:
.. code-block:: python
:linenos:
from webob import Response
- from pyramid.view import bfg_view
+ from pyramid.view import view_config
- @bfg_view()
+ @view_config()
def my_view(request):
""" My view """
return Response()
@@ -1586,9 +1586,9 @@ matches any model type, using no permission, registered against
requests with any request method / request type / request param /
route name / containment.
-The mere existence of a ``@bfg_view`` decorator doesn't suffice to
+The mere existence of a ``@view_config`` decorator doesn't suffice to
perform view configuration. To make :mod:`pyramid` process your
-:class:`pyramid.view.bfg_view` declarations, you *must* do one of
+:class:`pyramid.view.view_config` declarations, you *must* do one of
the following:
- If you are using :term:`ZCML`, insert the following boilerplate into
@@ -1610,7 +1610,7 @@ the following:
Please see :ref:`decorations_and_code_scanning` for detailed
information about what happens when code is scanned for configuration
declarations resulting from use of decorators like
-:class:`pyramid.view.bfg_view`.
+:class:`pyramid.view.view_config`.
See :ref:`configuration_module` for additional API arguments to the
:meth:`pyramid.configuration.Configurator.scan` method. For
@@ -1619,10 +1619,10 @@ better control exactly *which* code will be scanned. This is the same
value implied by the ``package`` attribute of the ZCML ``<scan>``
directive (see :ref:`scan_directive`).
-``@bfg_view`` Placement
-+++++++++++++++++++++++
+``@view_config`` Placement
+++++++++++++++++++++++++++
-A :class:`pyramid.view.bfg_view` decorator can be placed in various
+A :class:`pyramid.view.view_config` decorator can be placed in various
points in your application.
If your view callable is a function, it may be used as a function
@@ -1631,10 +1631,10 @@ decorator:
.. code-block:: python
:linenos:
- from pyramid.view import bfg_view
+ from pyramid.view import view_config
from webob import Response
- @bfg_view(name='edit')
+ @view_config(name='edit')
def edit(request):
return Response('edited!')
@@ -1648,9 +1648,9 @@ function. For example:
:linenos:
from webob import Response
- from pyramid.view import bfg_view
+ from pyramid.view import view_config
- @bfg_view()
+ @view_config()
class MyView(object):
def __init__(self, request):
self.request = request
@@ -1658,7 +1658,7 @@ function. For example:
def __call__(self):
return Response('hello')
-You can use the :class:`pyramid.view.bfg_view` decorator as a
+You can use the :class:`pyramid.view.view_config` decorator as a
simple callable to manually decorate classes in Python 2.5 and below
without the decorator syntactic sugar, if you wish:
@@ -1666,7 +1666,7 @@ without the decorator syntactic sugar, if you wish:
:linenos:
from webob import Response
- from pyramid.view import bfg_view
+ from pyramid.view import view_config
class MyView(object):
def __init__(self, request):
@@ -1675,20 +1675,20 @@ without the decorator syntactic sugar, if you wish:
def __call__(self):
return Response('hello')
- my_view = bfg_view()(MyView)
+ my_view = view_config()(MyView)
-More than one :class:`pyramid.view.bfg_view` decorator can be
+More than one :class:`pyramid.view.view_config` decorator can be
stacked on top of any number of others. Each decorator creates a
separate view registration. For example:
.. code-block:: python
:linenos:
- from pyramid.view import bfg_view
+ from pyramid.view import view_config
from webob import Response
- @bfg_view(name='edit')
- @bfg_view(name='change')
+ @view_config(name='edit')
+ @view_config(name='change')
def edit(request):
return Response('edited!')
@@ -1700,13 +1700,13 @@ The decorator can also be used against class methods:
:linenos:
from webob import Response
- from pyramid.view import bfg_view
+ from pyramid.view import view_config
class MyView(object):
def __init__(self, request):
self.request = request
- @bfg_view(name='hello')
+ @view_config(name='hello')
def amethod(self):
return Response('hello')
@@ -1729,9 +1729,9 @@ equivalently as the below:
:linenos:
from webob import Response
- from pyramid.view import bfg_view
+ from pyramid.view import view_config
- @bfg_view(attr='amethod', name='hello')
+ @view_config(attr='amethod', name='hello')
class MyView(object):
def __init__(self, request):
self.request = request
@@ -1750,7 +1750,7 @@ View Configuration Using the ``add_view`` Method of a Configurator
The :meth:`pyramid.configuration.Configurator.add_view` method
within :ref:`configuration_module` is used to configure a view
imperatively. The arguments to this method are very similar to the
-arguments that you provide to the ``@bfg_view`` decorator. For
+arguments that you provide to the ``@view_config`` decorator. For
example:
.. code-block:: python
diff --git a/docs/narr/webob.rst b/docs/narr/webob.rst
index 15f8da9cf..b41979a1f 100644
--- a/docs/narr/webob.rst
+++ b/docs/narr/webob.rst
@@ -112,9 +112,9 @@ Special Attributes Added to the Request by :mod:`pyramid`
In addition to the standard :term:`WebOb` attributes, :mod:`pyramid`
adds special attributes to every request: ``context``, ``registry``,
``root``, ``subpath``, ``traversed``, ``view_name``, ``virtual_root``
-, ``virtual_root_path``, and ``session``. These attributes are
-documented further within the :class:`pyramid.request.Request` API
-documentation.
+, ``virtual_root_path``, ``session``, and ``tmpl_context``. These
+attributes are documented further within the
+:class:`pyramid.request.Request` API documentation.
.. index::
single: request URLs
diff --git a/docs/tutorials/catalog/index.rst b/docs/tutorials/catalog/index.rst
index 9a5bbfb2f..424286bd9 100644
--- a/docs/tutorials/catalog/index.rst
+++ b/docs/tutorials/catalog/index.rst
@@ -1,7 +1,7 @@
.. _catalog_tutorial:
-Using :mod:`repoze.catalog` Within :mod:`repoze.bfg`
-====================================================
+Using :mod:`repoze.catalog` Within :mod:`pyramid`
+=================================================
:mod:`repoze.catalog` is a ZODB-based system that can be used to index
Python objects. It also offers a query interface for retrieving
@@ -83,12 +83,12 @@ want the application to be based on :term:`traversal`.
.. code-block:: text
- [chrism@snowpro sess]$ ../bin/paster --plugin=repoze.bfg bfgshell \
+ [chrism@snowpro sess]$ ../bin/paster --plugin=pyramid bfgshell \
myapp.ini myapp
Python 2.5.4 (r254:67916, Sep 4 2009, 02:12:16)
[GCC 4.2.1 (Apple Inc. build 5646)] on darwin
Type "help" for more information. "root" is the BFG app root object.
- >>> from repoze.bfg.traversal import model_path
+ >>> from pyramid.traversal import model_path
>>> from myapp.models import Document
>>> root['name'] = Document('title')
>>> doc = root['name']
@@ -107,7 +107,7 @@ or from within a ``bfgshell`` session to update the set of indexes
used by your application.
In :term:`view` code, you should be able to get a hold of the root
-object via the :func:`repoze.bfg.traversal.find_root` API. The
+object via the :func:`pyramid.traversal.find_root` API. The
``catalog`` attribute of that root object will represent the catalog
previously added.
diff --git a/docs/tutorials/modwsgi/index.rst b/docs/tutorials/modwsgi/index.rst
index 5572e300b..8b429a0c8 100644
--- a/docs/tutorials/modwsgi/index.rst
+++ b/docs/tutorials/modwsgi/index.rst
@@ -54,7 +54,7 @@ commands and files.
.. code-block:: text
$ cd ~/modwsgi/env
- $ bin/easy_install repoze.bfg
+ $ bin/easy_install pyramid
#. Create and install your :mod:`pyramid` application. For the
purposes of this tutorial, we'll just be using the ``bfg_starter``
diff --git a/docs/tutorials/wiki/authorization.rst b/docs/tutorials/wiki/authorization.rst
index 0d135f5e2..189401a45 100644
--- a/docs/tutorials/wiki/authorization.rst
+++ b/docs/tutorials/wiki/authorization.rst
@@ -182,12 +182,12 @@ Our resulting ``models.py`` file will now look like so:
:linenos:
:language: python
-Adding ``permission`` Declarations to our ``bfg_view`` Decorators
------------------------------------------------------------------
+Adding ``permission`` Declarations to our ``view_config`` Decorators
+--------------------------------------------------------------------
To protect each of our views with a particular permission, we need to
pass a ``permission`` argument to each of our
-:class:`pyramid.view.bfg_view` decorators. To do so, within
+:class:`pyramid.view.view_config` decorators. To do so, within
``views.py``:
- We add ``permission='view'`` to the decorator attached to the
@@ -220,10 +220,10 @@ pass a ``permission`` argument to each of our
consults the ``GROUPS`` data structure. This means that the
``editor`` user can add pages.
-- We add ``permission='edit'`` to the ``bfg_view`` decorator attached
- to the ``edit_page`` view function. This makes the assertion that
- only users who possess the effective ``edit`` permission at the time
- of the request may invoke this view. We've granted the
+- We add ``permission='edit'`` to the decorator attached to the
+ ``edit_page`` view function. This makes the assertion that only
+ users who possess the effective ``edit`` permission at the time of
+ the request may invoke this view. We've granted the
``group:editors`` principal the ``edit`` permission at the root
model via its ACL, so only the a user whom is a member of the group
named ``group:editors`` will able to invoke the ``edit_page`` view.
diff --git a/docs/tutorials/wiki/src/authorization/tutorial/login.py b/docs/tutorials/wiki/src/authorization/tutorial/login.py
index ee67d9a5e..60e69fddf 100644
--- a/docs/tutorials/wiki/src/authorization/tutorial/login.py
+++ b/docs/tutorials/wiki/src/authorization/tutorial/login.py
@@ -1,6 +1,6 @@
from pyramid.httpexceptions import HTTPFound
-from pyramid.view import bfg_view
+from pyramid.view import view_config
from pyramid.url import model_url
from pyramid.security import remember
@@ -9,7 +9,7 @@ from pyramid.security import forget
from tutorial.models import Wiki
from tutorial.security import USERS
-@bfg_view(context=Wiki, name='login', renderer='templates/login.pt')
+@view_config(context=Wiki, name='login', renderer='templates/login.pt')
def login(request):
login_url = model_url(request.context, request, 'login')
referrer = request.url
@@ -36,7 +36,7 @@ def login(request):
password = password,
)
-@bfg_view(context=Wiki, name='logout')
+@view_config(context=Wiki, name='logout')
def logout(request):
headers = forget(request)
return HTTPFound(location = model_url(request.context, request),
diff --git a/docs/tutorials/wiki/src/authorization/tutorial/views.py b/docs/tutorials/wiki/src/authorization/tutorial/views.py
index 8c35afcd6..48e4e2b43 100644
--- a/docs/tutorials/wiki/src/authorization/tutorial/views.py
+++ b/docs/tutorials/wiki/src/authorization/tutorial/views.py
@@ -6,7 +6,7 @@ from pyramid.url import model_url
from pyramid.security import authenticated_userid
-from pyramid.view import bfg_view
+from pyramid.view import view_config
from tutorial.models import Page
from tutorial.models import Wiki
@@ -14,11 +14,11 @@ from tutorial.models import Wiki
# regular expression used to find WikiWords
wikiwords = re.compile(r"\b([A-Z]\w+[A-Z]+\w+)")
-@bfg_view(context=Wiki, permission='view')
+@view_config(context=Wiki, permission='view')
def view_wiki(context, request):
return HTTPFound(location = model_url(context, request, 'FrontPage'))
-@bfg_view(context=Page, renderer='templates/view.pt', permission='view')
+@view_config(context=Page, renderer='templates/view.pt', permission='view')
def view_page(context, request):
wiki = context.__parent__
@@ -41,8 +41,8 @@ def view_page(context, request):
return dict(page = context, content = content, edit_url = edit_url,
logged_in = logged_in)
-@bfg_view(context=Wiki, name='add_page', renderer='templates/edit.pt',
- permission='edit')
+@view_config(context=Wiki, name='add_page', renderer='templates/edit.pt',
+ permission='edit')
def add_page(context, request):
name = request.subpath[0]
if 'form.submitted' in request.params:
@@ -61,8 +61,8 @@ def add_page(context, request):
return dict(page = page, save_url = save_url, logged_in = logged_in)
-@bfg_view(context=Page, name='edit_page', renderer='templates/edit.pt',
- permission='edit')
+@view_config(context=Page, name='edit_page', renderer='templates/edit.pt',
+ permission='edit')
def edit_page(context, request):
if 'form.submitted' in request.params:
context.data = request.params['body']
diff --git a/docs/tutorials/wiki/src/viewdecorators/tutorial/views.py b/docs/tutorials/wiki/src/viewdecorators/tutorial/views.py
index 937a67344..168965db2 100644
--- a/docs/tutorials/wiki/src/viewdecorators/tutorial/views.py
+++ b/docs/tutorials/wiki/src/viewdecorators/tutorial/views.py
@@ -3,7 +3,7 @@ import re
from pyramid.httpexceptions import HTTPFound
from pyramid.url import model_url
-from pyramid.view import bfg_view
+from pyramid.view import view_config
from tutorial.models import Page
from tutorial.models import Wiki
@@ -11,11 +11,11 @@ from tutorial.models import Wiki
# regular expression used to find WikiWords
wikiwords = re.compile(r"\b([A-Z]\w+[A-Z]+\w+)")
-@bfg_view(context=Wiki)
+@view_config(context=Wiki)
def view_wiki(context, request):
return HTTPFound(location = model_url(context, request, 'FrontPage'))
-@bfg_view(context=Page, renderer='templates/view.pt')
+@view_config(context=Page, renderer='templates/view.pt')
def view_page(context, request):
wiki = context.__parent__
@@ -34,7 +34,7 @@ def view_page(context, request):
edit_url = model_url(context, request, 'edit_page')
return dict(page = context, content = content, edit_url = edit_url)
-@bfg_view(context=Wiki, name='add_page', renderer='templates/edit.pt')
+@view_config(context=Wiki, name='add_page', renderer='templates/edit.pt')
def add_page(context, request):
name = request.subpath[0]
if 'form.submitted' in request.params:
@@ -50,7 +50,7 @@ def add_page(context, request):
page.__parent__ = context
return dict(page = page, save_url = save_url)
-@bfg_view(context=Page, name='edit_page', renderer='templates/edit.pt')
+@view_config(context=Page, name='edit_page', renderer='templates/edit.pt')
def edit_page(context, request):
if 'form.submitted' in request.params:
context.data = request.params['body']
diff --git a/docs/tutorials/wiki/viewdecorators.rst b/docs/tutorials/wiki/viewdecorators.rst
index 7d202ee6d..2d58890e4 100644
--- a/docs/tutorials/wiki/viewdecorators.rst
+++ b/docs/tutorials/wiki/viewdecorators.rst
@@ -3,25 +3,26 @@ Using View Decorators Rather than ZCML ``view`` directives
==========================================================
So far we've been using :term:`ZCML` to map model types to views.
-It's often easier to use the ``bfg_view`` view decorator to do this
-mapping. Using view decorators provides better locality of reference
-for the mapping, because you can see which model types and view names
-the view will serve right next to the view function itself. In this
-mode, however, you lose the ability for some views to be overridden
-"from the outside" (by someone using your application as a framework,
-as explained in the :ref:`extending_chapter`). Since this application
-is not meant to be a framework, it makes sense for us to switch over
-to using view decorators.
+It's often easier to use the :class:`pyramid.view.view_config` view
+decorator to do this mapping. Using view decorators provides better
+locality of reference for the mapping, because you can see which model
+types and view names the view will serve right next to the view
+function itself. In this mode, however, you lose the ability for some
+views to be overridden "from the outside" (by someone using your
+application as a framework, as explained in the
+:ref:`extending_chapter`). Since this application is not meant to be
+a framework, it makes sense for us to switch over to using view
+decorators.
Adding View Decorators
======================
-We're going to import the :class:`pyramid.view.bfg_view` callable.
+We're going to import the :class:`pyramid.view.view_config` callable.
This callable can be used as a function, class, or method decorator.
We'll use it to decorate our ``view_wiki``, ``view_page``,
``add_page`` and ``edit_page`` view functions.
-The :class:`pyramid.view.bfg_view` callable accepts a number of
+The :class:`pyramid.view.view_config` callable accepts a number of
arguments:
``context``
@@ -50,7 +51,7 @@ The decorator above the ``view_wiki`` function will be:
.. code-block:: python
:linenos:
- @bfg_view(context=Wiki)
+ @view_config(context=Wiki)
This indicates that the view is for the Wiki class and has the *empty*
view_name (indicating the :term:`default view` for the Wiki class).
@@ -76,7 +77,7 @@ The decorator above the ``view_page`` function will be:
.. code-block:: python
:linenos:
- @bfg_view(context=Page, renderer='templates/view.pt')
+ @view_config(context=Page, renderer='templates/view.pt')
This indicates that the view is for the Page class and has the *empty*
view_name (indicating the :term:`default view` for the Page class).
@@ -103,7 +104,7 @@ The decorator above the ``add_page`` function will be:
.. code-block:: python
:linenos:
- @bfg_view(context=Wiki, name='add_page', renderer='templates/edit.pt')
+ @view_config(context=Wiki, name='add_page', renderer='templates/edit.pt')
This indicates that the view is for the Wiki class and has the
``add_page`` view_name. After injecting this decorator, we can now
@@ -130,7 +131,7 @@ The decorator above the ``edit_page`` function will be:
.. code-block:: python
:linenos:
- @bfg_view(context=Page, name='edit_page', renderer='templates/edit.pt')
+ @view_config(context=Page, name='edit_page', renderer='templates/edit.pt')
This indicates that the view is for the Page class and has the
``edit_page`` view_name. After injecting this decorator, we can now
diff --git a/docs/zcml/forbidden.rst b/docs/zcml/forbidden.rst
index ca5b2cca1..330df3c2e 100644
--- a/docs/zcml/forbidden.rst
+++ b/docs/zcml/forbidden.rst
@@ -43,7 +43,7 @@ Attributes
``wrapper``
The :term:`view name` (*not* an object dotted name) of another view
- declared elsewhere in ZCML (or via the ``@bfg_view`` decorator)
+ declared elsewhere in ZCML (or via the ``@view_config`` decorator)
which will receive the response body of this view as the
``request.wrapped_body`` attribute of its own request, and the
response returned by this view as the ``request.wrapped_response``
diff --git a/docs/zcml/notfound.rst b/docs/zcml/notfound.rst
index 59263db34..0e1652708 100644
--- a/docs/zcml/notfound.rst
+++ b/docs/zcml/notfound.rst
@@ -6,7 +6,7 @@
.. warning::
The ``notfound`` ZCML directive is deprecated in :mod:`pyramid`
- version 1.3. Instead, you should use the :ref:`view_directive`
+ version 1.0. Instead, you should use the :ref:`view_directive`
directive with a ``context`` that names the
:exc:`pyramid.exceptions.NotFound` class. See
:ref:`changing_the_notfound_view` form more information.
@@ -42,7 +42,7 @@ Attributes
``wrapper``
The :term:`view name` (*not* an object dotted name) of another view
- declared elsewhere in ZCML (or via the ``@bfg_view`` decorator)
+ declared elsewhere in ZCML (or via the ``@view_config`` decorator)
which will receive the response body of this view as the
``request.wrapped_body`` attribute of its own request, and the
response returned by this view as the ``request.wrapped_response``
diff --git a/docs/zcml/view.rst b/docs/zcml/view.rst
index 041e35af5..392e84430 100644
--- a/docs/zcml/view.rst
+++ b/docs/zcml/view.rst
@@ -83,7 +83,7 @@ Non-Predicate Attributes
``wrapper``
The :term:`view name` (*not* an object dotted name) of another view
- declared elsewhere in ZCML (or via the ``@bfg_view`` decorator)
+ declared elsewhere in ZCML (or via the ``@view_config`` decorator)
which will receive the response body of this view as the
``request.wrapped_body`` attribute of its own request, and the
response returned by this view as the ``request.wrapped_response``
@@ -246,7 +246,7 @@ Alternatives
You can also add a :term:`view configuration` via:
-- Using the :class:`pyramid.view.bfg_view` class as a decorator.
+- Using the :class:`pyramid.view.view_config` class as a decorator.
- Using the :meth:`pyramid.configuration.Configurator.add_view` method.
diff --git a/pyramid/configuration.py b/pyramid/configuration.py
index f159a342f..b877441ec 100644
--- a/pyramid/configuration.py
+++ b/pyramid/configuration.py
@@ -1557,7 +1557,7 @@ class Configurator(object):
def scan(self, package=None, categories=None, _info=u''):
""" Scan a Python package and any of its subpackages for
objects marked with :term:`configuration decoration` such as
- :class:`pyramid.view.bfg_view`. Any decorated object found
+ :class:`pyramid.view.view_config`. Any decorated object found
will influence the current configuration state.
The ``package`` argument should be a Python :term:`package` or
@@ -1572,15 +1572,15 @@ class Configurator(object):
By default, ``categories`` is ``None`` which will execute
*all* Venusian decorator callbacks including
- :mod:`pyramid`-related decorators such as ``bfg_view``. If
- this is not desirable because the codebase has other
- Venusian-using decorators that aren't meant to be invoked
- during a particular scan, use ``('bfg',)`` as a ``categories``
- value to limit the execution of decorator callbacks to only
- those registered by :mod:`pyramid` itself. Or pass a
- sequence of Venusian scan categories as necessary
- (e.g. ``('bfg', 'myframework')``) to limit the decorators
- called to the set of categories required.
+ :mod:`pyramid`-related decorators such as
+ :class:`pyramid.view.view_config``. If this is not desirable
+ because the codebase has other Venusian-using decorators that
+ aren't meant to be invoked during a particular scan, use
+ ``('bfg',)`` as a ``categories`` value to limit the execution
+ of decorator callbacks to only those registered by
+ :mod:`pyramid` itself. Or pass a sequence of Venusian scan
+ categories as necessary (e.g. ``('bfg', 'myframework')``) to
+ limit the decorators called to the set of categories required.
"""
package = self.maybe_dotted(package)
if package is None: # pragma: no cover
diff --git a/pyramid/interfaces.py b/pyramid/interfaces.py
index e1d7491b5..56486307a 100644
--- a/pyramid/interfaces.py
+++ b/pyramid/interfaces.py
@@ -392,10 +392,6 @@ class ISession(Interface):
# attributes
created = Attribute('Integer representing Epoch time when created.')
- modified = Attribute(
- 'Integer representing Epoch time of last modification. If the '
- 'session has not yet been modified (it is new), this time will '
- 'be the created time.')
new = Attribute('Boolean attribute. If ``True``, the session is new.')
# special methods
diff --git a/pyramid/paster.py b/pyramid/paster.py
index 0b7a4f7c7..1a0e3f6cb 100644
--- a/pyramid/paster.py
+++ b/pyramid/paster.py
@@ -9,7 +9,6 @@ from paste.util.template import paste_script_template_renderer
from pyramid.scripting import get_root
-
class StarterProjectTemplate(Template):
_template_dir = 'paster_templates/starter'
summary = 'pyramid starter project'
@@ -30,6 +29,21 @@ class AlchemyProjectTemplate(Template):
summary = 'pyramid SQLAlchemy project using traversal'
template_renderer = staticmethod(paste_script_template_renderer)
+class PylonsBasicProjectTemplate(Template):
+ _template_dir = 'paster_templates/pylons_basic'
+ summary = 'Pylons basic project'
+ template_renderer = staticmethod(paste_script_template_renderer)
+
+class PylonsMinimalProjectTemplate(Template):
+ _template_dir = 'paster_templates/pylons_minimal'
+ summary = 'Pylons minimal project'
+ template_renderer = staticmethod(paste_script_template_renderer)
+
+class PylonsSQLAlchemyProjectTemplate(Template):
+ _template_dir = 'paster_templates/pylons_sqla'
+ summary = 'Pylons SQLAlchemy project'
+ template_renderer = staticmethod(paste_script_template_renderer)
+
def get_app(config_file, name, loadapp=loadapp):
""" Return the WSGI application named ``name`` in the PasteDeploy
config file ``config_file``"""
diff --git a/pyramid/paster_templates/pylons_basic/+package+/__init__.py_tmpl b/pyramid/paster_templates/pylons_basic/+package+/__init__.py_tmpl
new file mode 100644
index 000000000..b8f5219a7
--- /dev/null
+++ b/pyramid/paster_templates/pylons_basic/+package+/__init__.py_tmpl
@@ -0,0 +1,22 @@
+from pyramid_beaker import session_factory_from_settings
+from pyramid.personality.pylons import renderer_globals_factory_config
+from {{package}}.lib import helpers
+
+def main(global_config, **settings):
+ """ This function returns a Pyramid WSGI application.
+ """
+ from pyramid.configuration import Configurator
+ config = Configurator(settings=settings)
+ config.begin()
+ session_factory = session_factory_from_settings(settings)
+ config.set_session_factory(session_factory)
+ globals_factory = renderer_globals_factory_config(helpers)
+ config.set_renderer_globals_factory(globals_factory)
+ # XXX add caching setup
+ config.add_static_view('static', '{{package}}:static/')
+ config.add_handler('action', '/{action}',
+ '{{package}}.handlers.hello:HelloHandler')
+ config.add_handler('home', '/', '{{package}}.handlers.hello:HelloHandler',
+ action='index')
+ config.end()
+ return config.make_wsgi_app()
diff --git a/pyramid/paster_templates/pylons_basic/+package+/handlers/__init__.py b/pyramid/paster_templates/pylons_basic/+package+/handlers/__init__.py
new file mode 100644
index 000000000..5bb534f79
--- /dev/null
+++ b/pyramid/paster_templates/pylons_basic/+package+/handlers/__init__.py
@@ -0,0 +1 @@
+# package
diff --git a/pyramid/paster_templates/pylons_basic/+package+/handlers/hello.py_tmpl b/pyramid/paster_templates/pylons_basic/+package+/handlers/hello.py_tmpl
new file mode 100644
index 000000000..696772798
--- /dev/null
+++ b/pyramid/paster_templates/pylons_basic/+package+/handlers/hello.py_tmpl
@@ -0,0 +1,9 @@
+from pyramid.view import action
+
+class HelloHandler(object):
+ def __init__(self, request):
+ self.request = request
+
+ @action(renderer='mytemplate.mak')
+ def index(self):
+ return {'project':'{{project}}'}
diff --git a/pyramid/paster_templates/pylons_basic/+package+/lib/__init__.py b/pyramid/paster_templates/pylons_basic/+package+/lib/__init__.py
new file mode 100644
index 000000000..4287ca861
--- /dev/null
+++ b/pyramid/paster_templates/pylons_basic/+package+/lib/__init__.py
@@ -0,0 +1 @@
+# \ No newline at end of file
diff --git a/pyramid/paster_templates/pylons_basic/+package+/lib/helpers.py b/pyramid/paster_templates/pylons_basic/+package+/lib/helpers.py
new file mode 100644
index 000000000..878b8882f
--- /dev/null
+++ b/pyramid/paster_templates/pylons_basic/+package+/lib/helpers.py
@@ -0,0 +1,7 @@
+"""Helper functions
+
+Consists of functions to typically be used within templates, but also
+available to Controllers. This module is available to templates as 'h'.
+"""
+# Import helpers as desired, or define your own, ie:
+#from webhelpers.html.tags import checkbox, password
diff --git a/pyramid/paster_templates/pylons_basic/+package+/static/default.css b/pyramid/paster_templates/pylons_basic/+package+/static/default.css
new file mode 100644
index 000000000..41b3debde
--- /dev/null
+++ b/pyramid/paster_templates/pylons_basic/+package+/static/default.css
@@ -0,0 +1,380 @@
+/*
+Design by Free CSS Templates
+http://www.freecsstemplates.org
+Released for free under a Creative Commons Attribution 2.5 License
+*/
+
+body {
+ margin: 0;
+ padding: 0;
+ background: url(images/img01.gif) repeat-x left top;
+ font-size: 13px;
+ font-family: "Trebuchet MS", Georgia, "Times New Roman", Times, serif;
+ text-align: justify;
+ color: #FFFFFF;
+}
+
+h1, h2, h3 {
+ margin: 0;
+ text-transform: lowercase;
+ font-weight: normal;
+ color: #FFFFFF;
+}
+
+h1 {
+ letter-spacing: -1px;
+ font-size: 32px;
+}
+
+h2 {
+ font-size: 23px;
+}
+
+p, ul, ol {
+ margin: 0 0 2em 0;
+ text-align: justify;
+ line-height: 26px;
+}
+
+a:link {
+ color: #8BD80E;
+}
+
+a:hover, a:active {
+ text-decoration: none;
+ color: #8BD80E;
+}
+
+a:visited {
+ color: #8BD80E;
+}
+
+img {
+ border: none;
+}
+
+img.left {
+ float: left;
+ margin-right: 15px;
+}
+
+img.right {
+ float: right;
+ margin-left: 15px;
+}
+
+/* Form */
+
+form {
+ margin: 0;
+ padding: 0;
+}
+
+fieldset {
+ margin: 0;
+ padding: 0;
+ border: none;
+}
+
+legend {
+ display: none;
+}
+
+input, textarea, select {
+ font-family: "Trebuchet MS", Arial, Helvetica, sans-serif;
+ font-size: 13px;
+ color: #333333;
+}
+
+#wrapper {
+ margin: 0;
+ padding: 0;
+ background: #000000;
+}
+
+/* Header */
+
+#header {
+ width: 713px;
+ margin: 0 auto;
+ height: 42px;
+}
+
+/* Menu */
+
+#menu {
+ float: left;
+ width: 713px;
+ height: 50px;
+ background: url(images/img02.gif) no-repeat left top;
+}
+
+#menu ul {
+ margin: 0;
+ padding: 0px 0 0 10px;
+ list-style: none;
+ line-height: normal;
+}
+
+#menu li {
+ display: block;
+ float: left;
+}
+
+#menu a {
+ display: block;
+ float: left;
+ background: url(images/img04.gif) no-repeat right 55%;
+ margin-top: 5px;
+ margin-right: 3px;
+ padding: 8px 17px;
+ text-decoration: none;
+ font-size: 13px;
+ color: #000000;
+}
+
+#menu a:hover {
+ color: #000000;
+}
+
+#menu .current_page_item a {
+ color: #000000;
+}
+
+/** LOGO */
+
+#logo {
+ width: 713px;
+ height: 80px;
+ margin: 0 auto;
+}
+
+#logo h1, #logo h2 {
+ float: left;
+ margin: 0;
+ padding: 30px 0 0 0px;
+ line-height: normal;
+}
+
+#logo h1 {
+ font-family: Georgia, "Times New Roman", Times, serif;
+ font-size:40px;
+}
+
+#logo h1 a {
+ text-decoration: none;
+ color: #4C4C4C;
+}
+
+#logo h1 a:hover { text-decoration: underline; }
+
+#logo h2 {
+ float: left;
+ padding: 45px 0 0 18px;
+ font: 18px Georgia, "Times New Roman", Times, serif;
+ color: #8BD80E;
+}
+
+#logo p a {
+ text-decoration: none;
+ color: #8BD80E;
+}
+
+#logo p a:hover { text-decoration: underline; }
+
+
+
+/* Page */
+
+#page {
+ width: 663px;
+ margin: 0 auto;
+ background: #4C4C4C url(images/img03.gif) no-repeat left bottom;
+ padding: 0 25px;
+}
+
+/* Content */
+
+#content {
+ float: left;
+ width: 410px;
+
+}
+
+/* Post */
+
+.post {
+ padding: 15px 0px;
+ margin-bottom: 20px;
+}
+
+.post .title {
+ margin-bottom: 20px;
+ padding-bottom: 5px;
+}
+
+.post h1 {
+ padding: 0px 0 0 0px;
+ background: url(images/img08.jpg) no-repeat left top;
+ font-size: 24px;
+ color: #FFFFFF;
+}
+
+.post h2 {
+ padding: 0px 0 0 0px;
+ font-size: 22px;
+ color: #FFFFFF;
+}
+
+.post .entry {
+}
+
+.post .meta {
+ padding: 15px 15px 30px 0px;
+ font-family: Arial, Helvetica, sans-serif;
+ font-size: 11px;
+}
+
+.post .meta p {
+ margin: 0;
+ padding-top: 15px;
+ line-height: normal;
+ color: #FFFFFF;
+}
+
+.post .meta .byline {
+ float: left;
+}
+
+.post .meta .links {
+ float: right;
+}
+
+.post .meta .more {
+ padding: 0 10px 0 18px;
+}
+
+.post .meta .comments {
+}
+
+.post .meta b {
+ display: none;
+}
+
+
+/* Sidebar */
+
+#sidebar {
+ width: 210px;
+ float: right;
+ margin: 0;
+ padding: 0;
+}
+
+#sidebar ul {
+ margin: 0;
+ padding: 0;
+ list-style: none;
+}
+
+#sidebar li {
+ margin-bottom: 40px;
+}
+
+#sidebar li ul {
+}
+
+#sidebar li li {
+ margin: 0;
+}
+
+#sidebar h2 {
+ width: 250px;
+ padding: 8px 0 0 0px;
+ margin-bottom: 10px;
+ background: url(images/img07.jpg) no-repeat left top;
+ font-size: 20px;
+ color: #FFFFFF;
+}
+
+/* Search */
+
+#search {
+
+}
+
+#search h2 {
+ margin-bottom: 20px;
+}
+
+#s {
+ width: 140px;
+ margin-right: 5px;
+ padding: 3px;
+ border: 1px solid #BED99C;
+}
+
+#x {
+ padding: 3px;
+ border: none;
+ background: #8BD80E;
+ text-transform: lowercase;
+ font-size: 11px;
+ color: #FFFFFF;
+}
+
+/* Boxes */
+
+.box1 {
+ padding: 20px;
+}
+
+.box2 {
+ color: #BABABA;
+}
+
+.box2 h2 {
+ margin-bottom: 15px;
+ font-size: 16px;
+ color: #FFFFFF;
+}
+
+.box2 ul {
+ margin: 0;
+ padding: 0;
+ list-style: none;
+}
+
+.box2 a:link, .box2 a:hover, .box2 a:active, .box2 a:visited {
+ color: #EDEDED;
+}
+
+/* Footer */
+#footer-wrap {
+}
+
+#footer {
+ margin: 0 auto;
+ padding: 20px 0 10px 0;
+ background: #000000;
+}
+
+html>body #footer {
+ height: auto;
+}
+
+#footer p {
+ font-size: 11px;
+}
+
+#legal {
+ clear: both;
+ padding-top: 17px;
+ text-align: center;
+ color: #FFFFFF;
+}
+
+#legal a {
+ font-weight: normal;
+ color: #FFFFFF;
+}
diff --git a/pyramid/paster_templates/pylons_basic/+package+/static/images/img01.gif b/pyramid/paster_templates/pylons_basic/+package+/static/images/img01.gif
new file mode 100644
index 000000000..5f082bd99
--- /dev/null
+++ b/pyramid/paster_templates/pylons_basic/+package+/static/images/img01.gif
Binary files differ
diff --git a/pyramid/paster_templates/pylons_basic/+package+/static/images/img02.gif b/pyramid/paster_templates/pylons_basic/+package+/static/images/img02.gif
new file mode 100644
index 000000000..45a3ae976
--- /dev/null
+++ b/pyramid/paster_templates/pylons_basic/+package+/static/images/img02.gif
Binary files differ
diff --git a/pyramid/paster_templates/pylons_basic/+package+/static/images/img03.gif b/pyramid/paster_templates/pylons_basic/+package+/static/images/img03.gif
new file mode 100644
index 000000000..d92ea38f9
--- /dev/null
+++ b/pyramid/paster_templates/pylons_basic/+package+/static/images/img03.gif
Binary files differ
diff --git a/pyramid/paster_templates/pylons_basic/+package+/static/images/img04.gif b/pyramid/paster_templates/pylons_basic/+package+/static/images/img04.gif
new file mode 100644
index 000000000..950c4af9d
--- /dev/null
+++ b/pyramid/paster_templates/pylons_basic/+package+/static/images/img04.gif
Binary files differ
diff --git a/pyramid/paster_templates/pylons_basic/+package+/static/images/spacer.gif b/pyramid/paster_templates/pylons_basic/+package+/static/images/spacer.gif
new file mode 100644
index 000000000..5bfd67a2d
--- /dev/null
+++ b/pyramid/paster_templates/pylons_basic/+package+/static/images/spacer.gif
Binary files differ
diff --git a/pyramid/paster_templates/pylons_basic/+package+/static/templatelicense.txt b/pyramid/paster_templates/pylons_basic/+package+/static/templatelicense.txt
new file mode 100644
index 000000000..ccb6b06ab
--- /dev/null
+++ b/pyramid/paster_templates/pylons_basic/+package+/static/templatelicense.txt
@@ -0,0 +1,243 @@
+Creative Commons </>
+
+Creative Commons Legal Code
+
+*Attribution 2.5*
+
+CREATIVE COMMONS CORPORATION IS NOT A LAW FIRM AND DOES NOT PROVIDE
+LEGAL SERVICES. DISTRIBUTION OF THIS LICENSE DOES NOT CREATE AN
+ATTORNEY-CLIENT RELATIONSHIP. CREATIVE COMMONS PROVIDES THIS INFORMATION
+ON AN "AS-IS" BASIS. CREATIVE COMMONS MAKES NO WARRANTIES REGARDING THE
+INFORMATION PROVIDED, AND DISCLAIMS LIABILITY FOR DAMAGES RESULTING FROM
+ITS USE.
+
+/License/
+
+THE WORK (AS DEFINED BELOW) IS PROVIDED UNDER THE TERMS OF THIS CREATIVE
+COMMONS PUBLIC LICENSE ("CCPL" OR "LICENSE"). THE WORK IS PROTECTED BY
+COPYRIGHT AND/OR OTHER APPLICABLE LAW. ANY USE OF THE WORK OTHER THAN AS
+AUTHORIZED UNDER THIS LICENSE OR COPYRIGHT LAW IS PROHIBITED.
+
+BY EXERCISING ANY RIGHTS TO THE WORK PROVIDED HERE, YOU ACCEPT AND AGREE
+TO BE BOUND BY THE TERMS OF THIS LICENSE. THE LICENSOR GRANTS YOU THE
+RIGHTS CONTAINED HERE IN CONSIDERATION OF YOUR ACCEPTANCE OF SUCH TERMS
+AND CONDITIONS.
+
+*1. Definitions*
+
+ 1. *"Collective Work"* means a work, such as a periodical issue,
+ anthology or encyclopedia, in which the Work in its entirety in
+ unmodified form, along with a number of other contributions,
+ constituting separate and independent works in themselves, are
+ assembled into a collective whole. A work that constitutes a
+ Collective Work will not be considered a Derivative Work (as
+ defined below) for the purposes of this License.
+ 2. *"Derivative Work"* means a work based upon the Work or upon the
+ Work and other pre-existing works, such as a translation, musical
+ arrangement, dramatization, fictionalization, motion picture
+ version, sound recording, art reproduction, abridgment,
+ condensation, or any other form in which the Work may be recast,
+ transformed, or adapted, except that a work that constitutes a
+ Collective Work will not be considered a Derivative Work for the
+ purpose of this License. For the avoidance of doubt, where the
+ Work is a musical composition or sound recording, the
+ synchronization of the Work in timed-relation with a moving image
+ ("synching") will be considered a Derivative Work for the purpose
+ of this License.
+ 3. *"Licensor"* means the individual or entity that offers the Work
+ under the terms of this License.
+ 4. *"Original Author"* means the individual or entity who created the
+ Work.
+ 5. *"Work"* means the copyrightable work of authorship offered under
+ the terms of this License.
+ 6. *"You"* means an individual or entity exercising rights under this
+ License who has not previously violated the terms of this License
+ with respect to the Work, or who has received express permission
+ from the Licensor to exercise rights under this License despite a
+ previous violation.
+
+*2. Fair Use Rights.* Nothing in this license is intended to reduce,
+limit, or restrict any rights arising from fair use, first sale or other
+limitations on the exclusive rights of the copyright owner under
+copyright law or other applicable laws.
+
+*3. License Grant.* Subject to the terms and conditions of this License,
+Licensor hereby grants You a worldwide, royalty-free, non-exclusive,
+perpetual (for the duration of the applicable copyright) license to
+exercise the rights in the Work as stated below:
+
+ 1. to reproduce the Work, to incorporate the Work into one or more
+ Collective Works, and to reproduce the Work as incorporated in the
+ Collective Works;
+ 2. to create and reproduce Derivative Works;
+ 3. to distribute copies or phonorecords of, display publicly, perform
+ publicly, and perform publicly by means of a digital audio
+ transmission the Work including as incorporated in Collective Works;
+ 4. to distribute copies or phonorecords of, display publicly, perform
+ publicly, and perform publicly by means of a digital audio
+ transmission Derivative Works.
+ 5.
+
+ For the avoidance of doubt, where the work is a musical composition:
+
+ 1. *Performance Royalties Under Blanket Licenses*. Licensor
+ waives the exclusive right to collect, whether individually
+ or via a performance rights society (e.g. ASCAP, BMI,
+ SESAC), royalties for the public performance or public
+ digital performance (e.g. webcast) of the Work.
+ 2. *Mechanical Rights and Statutory Royalties*. Licensor waives
+ the exclusive right to collect, whether individually or via
+ a music rights agency or designated agent (e.g. Harry Fox
+ Agency), royalties for any phonorecord You create from the
+ Work ("cover version") and distribute, subject to the
+ compulsory license created by 17 USC Section 115 of the US
+ Copyright Act (or the equivalent in other jurisdictions).
+ 6. *Webcasting Rights and Statutory Royalties*. For the avoidance of
+ doubt, where the Work is a sound recording, Licensor waives the
+ exclusive right to collect, whether individually or via a
+ performance-rights society (e.g. SoundExchange), royalties for the
+ public digital performance (e.g. webcast) of the Work, subject to
+ the compulsory license created by 17 USC Section 114 of the US
+ Copyright Act (or the equivalent in other jurisdictions).
+
+The above rights may be exercised in all media and formats whether now
+known or hereafter devised. The above rights include the right to make
+such modifications as are technically necessary to exercise the rights
+in other media and formats. All rights not expressly granted by Licensor
+are hereby reserved.
+
+*4. Restrictions.*The license granted in Section 3 above is expressly
+made subject to and limited by the following restrictions:
+
+ 1. You may distribute, publicly display, publicly perform, or
+ publicly digitally perform the Work only under the terms of this
+ License, and You must include a copy of, or the Uniform Resource
+ Identifier for, this License with every copy or phonorecord of the
+ Work You distribute, publicly display, publicly perform, or
+ publicly digitally perform. You may not offer or impose any terms
+ on the Work that alter or restrict the terms of this License or
+ the recipients' exercise of the rights granted hereunder. You may
+ not sublicense the Work. You must keep intact all notices that
+ refer to this License and to the disclaimer of warranties. You may
+ not distribute, publicly display, publicly perform, or publicly
+ digitally perform the Work with any technological measures that
+ control access or use of the Work in a manner inconsistent with
+ the terms of this License Agreement. The above applies to the Work
+ as incorporated in a Collective Work, but this does not require
+ the Collective Work apart from the Work itself to be made subject
+ to the terms of this License. If You create a Collective Work,
+ upon notice from any Licensor You must, to the extent practicable,
+ remove from the Collective Work any credit as required by clause
+ 4(b), as requested. If You create a Derivative Work, upon notice
+ from any Licensor You must, to the extent practicable, remove from
+ the Derivative Work any credit as required by clause 4(b), as
+ requested.
+ 2. If you distribute, publicly display, publicly perform, or publicly
+ digitally perform the Work or any Derivative Works or Collective
+ Works, You must keep intact all copyright notices for the Work and
+ provide, reasonable to the medium or means You are utilizing: (i)
+ the name of the Original Author (or pseudonym, if applicable) if
+ supplied, and/or (ii) if the Original Author and/or Licensor
+ designate another party or parties (e.g. a sponsor institute,
+ publishing entity, journal) for attribution in Licensor's
+ copyright notice, terms of service or by other reasonable means,
+ the name of such party or parties; the title of the Work if
+ supplied; to the extent reasonably practicable, the Uniform
+ Resource Identifier, if any, that Licensor specifies to be
+ associated with the Work, unless such URI does not refer to the
+ copyright notice or licensing information for the Work; and in the
+ case of a Derivative Work, a credit identifying the use of the
+ Work in the Derivative Work (e.g., "French translation of the Work
+ by Original Author," or "Screenplay based on original Work by
+ Original Author"). Such credit may be implemented in any
+ reasonable manner; provided, however, that in the case of a
+ Derivative Work or Collective Work, at a minimum such credit will
+ appear where any other comparable authorship credit appears and in
+ a manner at least as prominent as such other comparable authorship
+ credit.
+
+*5. Representations, Warranties and Disclaimer*
+
+UNLESS OTHERWISE MUTUALLY AGREED TO BY THE PARTIES IN WRITING, LICENSOR
+OFFERS THE WORK AS-IS AND MAKES NO REPRESENTATIONS OR WARRANTIES OF ANY
+KIND CONCERNING THE WORK, EXPRESS, IMPLIED, STATUTORY OR OTHERWISE,
+INCLUDING, WITHOUT LIMITATION, WARRANTIES OF TITLE, MERCHANTIBILITY,
+FITNESS FOR A PARTICULAR PURPOSE, NONINFRINGEMENT, OR THE ABSENCE OF
+LATENT OR OTHER DEFECTS, ACCURACY, OR THE PRESENCE OF ABSENCE OF ERRORS,
+WHETHER OR NOT DISCOVERABLE. SOME JURISDICTIONS DO NOT ALLOW THE
+EXCLUSION OF IMPLIED WARRANTIES, SO SUCH EXCLUSION MAY NOT APPLY TO YOU.
+
+*6. Limitation on Liability.* EXCEPT TO THE EXTENT REQUIRED BY
+APPLICABLE LAW, IN NO EVENT WILL LICENSOR BE LIABLE TO YOU ON ANY LEGAL
+THEORY FOR ANY SPECIAL, INCIDENTAL, CONSEQUENTIAL, PUNITIVE OR EXEMPLARY
+DAMAGES ARISING OUT OF THIS LICENSE OR THE USE OF THE WORK, EVEN IF
+LICENSOR HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGES.
+
+*7. Termination*
+
+ 1. This License and the rights granted hereunder will terminate
+ automatically upon any breach by You of the terms of this License.
+ Individuals or entities who have received Derivative Works or
+ Collective Works from You under this License, however, will not
+ have their licenses terminated provided such individuals or
+ entities remain in full compliance with those licenses. Sections
+ 1, 2, 5, 6, 7, and 8 will survive any termination of this License.
+ 2. Subject to the above terms and conditions, the license granted
+ here is perpetual (for the duration of the applicable copyright in
+ the Work). Notwithstanding the above, Licensor reserves the right
+ to release the Work under different license terms or to stop
+ distributing the Work at any time; provided, however that any such
+ election will not serve to withdraw this License (or any other
+ license that has been, or is required to be, granted under the
+ terms of this License), and this License will continue in full
+ force and effect unless terminated as stated above.
+
+*8. Miscellaneous*
+
+ 1. Each time You distribute or publicly digitally perform the Work or
+ a Collective Work, the Licensor offers to the recipient a license
+ to the Work on the same terms and conditions as the license
+ granted to You under this License.
+ 2. Each time You distribute or publicly digitally perform a
+ Derivative Work, Licensor offers to the recipient a license to the
+ original Work on the same terms and conditions as the license
+ granted to You under this License.
+ 3. If any provision of this License is invalid or unenforceable under
+ applicable law, it shall not affect the validity or enforceability
+ of the remainder of the terms of this License, and without further
+ action by the parties to this agreement, such provision shall be
+ reformed to the minimum extent necessary to make such provision
+ valid and enforceable.
+ 4. No term or provision of this License shall be deemed waived and no
+ breach consented to unless such waiver or consent shall be in
+ writing and signed by the party to be charged with such waiver or
+ consent.
+ 5. This License constitutes the entire agreement between the parties
+ with respect to the Work licensed here. There are no
+ understandings, agreements or representations with respect to the
+ Work not specified here. Licensor shall not be bound by any
+ additional provisions that may appear in any communication from
+ You. This License may not be modified without the mutual written
+ agreement of the Licensor and You.
+
+Creative Commons is not a party to this License, and makes no warranty
+whatsoever in connection with the Work. Creative Commons will not be
+liable to You or any party on any legal theory for any damages
+whatsoever, including without limitation any general, special,
+incidental or consequential damages arising in connection to this
+license. Notwithstanding the foregoing two (2) sentences, if Creative
+Commons has expressly identified itself as the Licensor hereunder, it
+shall have all rights and obligations of Licensor.
+
+Except for the limited purpose of indicating to the public that the Work
+is licensed under the CCPL, neither party will use the trademark
+"Creative Commons" or any related trademark or logo of Creative Commons
+without the prior written consent of Creative Commons. Any permitted use
+will be in compliance with Creative Commons' then-current trademark
+usage guidelines, as may be published on its website or otherwise made
+available upon request from time to time.
+
+Creative Commons may be contacted at http://creativecommons.org/
+<http://creativecommons.org>.
+
+« Back to Commons Deed <./>
diff --git a/pyramid/paster_templates/pylons_basic/+package+/templates/mytemplate.mak b/pyramid/paster_templates/pylons_basic/+package+/templates/mytemplate.mak
new file mode 100644
index 000000000..035cc2f78
--- /dev/null
+++ b/pyramid/paster_templates/pylons_basic/+package+/templates/mytemplate.mak
@@ -0,0 +1,49 @@
+<!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"
+ xmlns:tal="http://xml.zope.org/namespaces/tal">
+<head>
+<meta http-equiv="content-type" content="text/html; charset=utf-8" />
+<title>${project} Application</title>
+<meta name="keywords" content="python web application" />
+<meta name="description" content="Pylons web application" />
+<link href="${request.application_url}/static/default.css" rel="stylesheet" type="text/css" />
+</head>
+<body>
+<!-- start header -->
+<div id="logo">
+ <h2><code>${project}</code>, a <code>Pylons</code> application</h2>
+</div>
+<div id="header">
+ <div id="menu">
+ </div>
+</div>
+<!-- end header -->
+<div id="wrapper">
+ <!-- start page -->
+ <div id="page">
+ <!-- start content -->
+ <div id="content">
+ <div class="post">
+ <h1 class="title">Welcome to <code>${project}</code>, an
+ application generated by the <a
+ href="http://pylonshq.com">Pylons</a> web
+ application framework.</h1>
+ </div>
+ </div>
+ <!-- end content -->
+ <!-- start sidebar -->
+ <div id="sidebar"></div>
+ <!-- end sidebar -->
+ <div style="clear: both;">&nbsp;</div>
+ </div>
+</div>
+<!-- end page -->
+<!-- start footer -->
+<div id="footer">
+ <p id="legal">( c ) 2008. All Rights Reserved. Template design
+ by <a href="http://www.freecsstemplates.org/">Free CSS
+ Templates</a>.</p>
+</div>
+<!-- end footer -->
+</body>
+</html>
diff --git a/pyramid/paster_templates/pylons_basic/+package+/tests.py_tmpl b/pyramid/paster_templates/pylons_basic/+package+/tests.py_tmpl
new file mode 100644
index 000000000..d98bee355
--- /dev/null
+++ b/pyramid/paster_templates/pylons_basic/+package+/tests.py_tmpl
@@ -0,0 +1,24 @@
+import unittest
+
+from pyramid.configuration import Configurator
+
+class MyControllerTests(unittest.TestCase):
+ def setUp(self):
+ self.config = Configurator()
+ self.config.begin()
+
+ def tearDown(self):
+ self.config.end()
+
+ def _makeOne(self, request):
+ from {{package}}.handlers import MyHandler
+ return MyHandler(request)
+
+ def test_index(self):
+ request = DummyRequest()
+ controller = self._makeOne(request)
+ info = controller.index()
+ self.assertEqual(info['project'], '{{project}}')
+
+class DummyRequest(object):
+ pass
diff --git a/pyramid/paster_templates/pylons_basic/CHANGES.txt_tmpl b/pyramid/paster_templates/pylons_basic/CHANGES.txt_tmpl
new file mode 100644
index 000000000..35a34f332
--- /dev/null
+++ b/pyramid/paster_templates/pylons_basic/CHANGES.txt_tmpl
@@ -0,0 +1,4 @@
+0.0
+---
+
+- Initial version
diff --git a/pyramid/paster_templates/pylons_basic/README.txt_tmpl b/pyramid/paster_templates/pylons_basic/README.txt_tmpl
new file mode 100644
index 000000000..0ddebfc3e
--- /dev/null
+++ b/pyramid/paster_templates/pylons_basic/README.txt_tmpl
@@ -0,0 +1,4 @@
+{{project}} README
+
+
+
diff --git a/pyramid/paster_templates/pylons_basic/development.ini_tmpl b/pyramid/paster_templates/pylons_basic/development.ini_tmpl
new file mode 100644
index 000000000..d3c8b57c9
--- /dev/null
+++ b/pyramid/paster_templates/pylons_basic/development.ini_tmpl
@@ -0,0 +1,28 @@
+[app:{{project}}]
+use = egg:{{project}}
+reload_templates = true
+mako.directories = {{package}}:templates
+debug_authorization = false
+debug_notfound = false
+debug_templates = true
+default_locale_name = en
+session.type = file
+session.data_dir = %(here)s/data/sessions/data
+session.lock_dir = %(here)s/data/sessions/lock
+session.key = {{project}}
+session.secret = your_app_secret_string
+cache.regions = default_term, second, short_term, long_term
+cache.type = memory
+cache.second.expire = 1
+cache.short_term.expire = 60
+cache.default_term.expire = 300
+cache.long_term.expire = 3600
+
+[pipeline:main]
+pipeline = egg:WebError#evalerror
+ {{project}}
+
+[server:main]
+use = egg:Paste#http
+host = 0.0.0.0
+port = 5000
diff --git a/pyramid/paster_templates/pylons_basic/setup.cfg_tmpl b/pyramid/paster_templates/pylons_basic/setup.cfg_tmpl
new file mode 100644
index 000000000..5bec29823
--- /dev/null
+++ b/pyramid/paster_templates/pylons_basic/setup.cfg_tmpl
@@ -0,0 +1,27 @@
+[nosetests]
+match=^test
+nocapture=1
+cover-package={{package}}
+with-coverage=1
+cover-erase=1
+
+[compile_catalog]
+directory = {{package}}/locale
+domain = {{project}}
+statistics = true
+
+[extract_messages]
+add_comments = TRANSLATORS:
+output_file = {{package}}/locale/{{project}}.pot
+width = 80
+
+[init_catalog]
+domain = {{project}}
+input_file = {{package}}/locale/{{project}}.pot
+output_dir = {{package}}/locale
+
+[update_catalog]
+domain = {{project}}
+input_file = {{package}}/locale/{{project}}.pot
+output_dir = {{package}}/locale
+previous = true
diff --git a/pyramid/paster_templates/pylons_basic/setup.py_tmpl b/pyramid/paster_templates/pylons_basic/setup.py_tmpl
new file mode 100644
index 000000000..baa57aa4e
--- /dev/null
+++ b/pyramid/paster_templates/pylons_basic/setup.py_tmpl
@@ -0,0 +1,36 @@
+import os
+
+from setuptools import setup, find_packages
+
+here = os.path.abspath(os.path.dirname(__file__))
+README = open(os.path.join(here, 'README.txt')).read()
+CHANGES = open(os.path.join(here, 'CHANGES.txt')).read()
+
+requires = ['pyramid', 'pyramid_beaker', 'WebError']
+
+setup(name='{{project}}',
+ version='0.0',
+ description='{{project}}',
+ long_description=README + '\n\n' + CHANGES,
+ classifiers=[
+ "Programming Language :: Python",
+ "Framework :: Pylons",
+ "Topic :: Internet :: WWW/HTTP",
+ "Topic :: Internet :: WWW/HTTP :: WSGI :: Application",
+ ],
+ author='',
+ author_email='',
+ url='',
+ keywords='web pylons',
+ packages=find_packages(),
+ include_package_data=True,
+ zip_safe=False,
+ install_requires=requires,
+ tests_require=requires,
+ test_suite="{{package}}",
+ entry_points = """\
+ [paste.app_factory]
+ main = {{package}}:main
+ """
+ )
+
diff --git a/pyramid/paster_templates/pylons_minimal/+package+/__init__.py_tmpl b/pyramid/paster_templates/pylons_minimal/+package+/__init__.py_tmpl
new file mode 100644
index 000000000..f47060997
--- /dev/null
+++ b/pyramid/paster_templates/pylons_minimal/+package+/__init__.py_tmpl
@@ -0,0 +1,21 @@
+from pyramid_beaker import session_factory_from_settings
+from pyramid.personality.pylons import renderer_globals_factory_config
+
+def main(global_config, **settings):
+ """ This function returns a Pyramid WSGI application.
+ """
+ from pyramid.configuration import Configurator
+ config = Configurator(settings=settings)
+ config.begin()
+ session_factory = session_factory_from_settings(settings)
+ config.set_session_factory(session_factory)
+ # XXX add caching setup
+ globals_factory = renderer_globals_factory_config(None)
+ config.set_renderer_globals_factory(globals_factory)
+ config.add_static_view('static', '{{package}}:static/')
+ config.add_handler('action', '/{action}', '{{package}}.handlers:MyHandler')
+ config.add_handler('home', '/', '{{package}}.handlers:MyHandler',
+ action='index')
+ config.end()
+ return config.make_wsgi_app()
+
diff --git a/pyramid/paster_templates/pylons_minimal/+package+/handlers.py_tmpl b/pyramid/paster_templates/pylons_minimal/+package+/handlers.py_tmpl
new file mode 100644
index 000000000..be1202551
--- /dev/null
+++ b/pyramid/paster_templates/pylons_minimal/+package+/handlers.py_tmpl
@@ -0,0 +1,9 @@
+from pyramid.view import action
+
+class MyHandler(object):
+ def __init__(self, request):
+ self.request = request
+
+ @action(renderer='mytemplate.mak')
+ def index(self):
+ return {'project':'{{project}}'}
diff --git a/pyramid/paster_templates/pylons_minimal/+package+/static/default.css b/pyramid/paster_templates/pylons_minimal/+package+/static/default.css
new file mode 100644
index 000000000..41b3debde
--- /dev/null
+++ b/pyramid/paster_templates/pylons_minimal/+package+/static/default.css
@@ -0,0 +1,380 @@
+/*
+Design by Free CSS Templates
+http://www.freecsstemplates.org
+Released for free under a Creative Commons Attribution 2.5 License
+*/
+
+body {
+ margin: 0;
+ padding: 0;
+ background: url(images/img01.gif) repeat-x left top;
+ font-size: 13px;
+ font-family: "Trebuchet MS", Georgia, "Times New Roman", Times, serif;
+ text-align: justify;
+ color: #FFFFFF;
+}
+
+h1, h2, h3 {
+ margin: 0;
+ text-transform: lowercase;
+ font-weight: normal;
+ color: #FFFFFF;
+}
+
+h1 {
+ letter-spacing: -1px;
+ font-size: 32px;
+}
+
+h2 {
+ font-size: 23px;
+}
+
+p, ul, ol {
+ margin: 0 0 2em 0;
+ text-align: justify;
+ line-height: 26px;
+}
+
+a:link {
+ color: #8BD80E;
+}
+
+a:hover, a:active {
+ text-decoration: none;
+ color: #8BD80E;
+}
+
+a:visited {
+ color: #8BD80E;
+}
+
+img {
+ border: none;
+}
+
+img.left {
+ float: left;
+ margin-right: 15px;
+}
+
+img.right {
+ float: right;
+ margin-left: 15px;
+}
+
+/* Form */
+
+form {
+ margin: 0;
+ padding: 0;
+}
+
+fieldset {
+ margin: 0;
+ padding: 0;
+ border: none;
+}
+
+legend {
+ display: none;
+}
+
+input, textarea, select {
+ font-family: "Trebuchet MS", Arial, Helvetica, sans-serif;
+ font-size: 13px;
+ color: #333333;
+}
+
+#wrapper {
+ margin: 0;
+ padding: 0;
+ background: #000000;
+}
+
+/* Header */
+
+#header {
+ width: 713px;
+ margin: 0 auto;
+ height: 42px;
+}
+
+/* Menu */
+
+#menu {
+ float: left;
+ width: 713px;
+ height: 50px;
+ background: url(images/img02.gif) no-repeat left top;
+}
+
+#menu ul {
+ margin: 0;
+ padding: 0px 0 0 10px;
+ list-style: none;
+ line-height: normal;
+}
+
+#menu li {
+ display: block;
+ float: left;
+}
+
+#menu a {
+ display: block;
+ float: left;
+ background: url(images/img04.gif) no-repeat right 55%;
+ margin-top: 5px;
+ margin-right: 3px;
+ padding: 8px 17px;
+ text-decoration: none;
+ font-size: 13px;
+ color: #000000;
+}
+
+#menu a:hover {
+ color: #000000;
+}
+
+#menu .current_page_item a {
+ color: #000000;
+}
+
+/** LOGO */
+
+#logo {
+ width: 713px;
+ height: 80px;
+ margin: 0 auto;
+}
+
+#logo h1, #logo h2 {
+ float: left;
+ margin: 0;
+ padding: 30px 0 0 0px;
+ line-height: normal;
+}
+
+#logo h1 {
+ font-family: Georgia, "Times New Roman", Times, serif;
+ font-size:40px;
+}
+
+#logo h1 a {
+ text-decoration: none;
+ color: #4C4C4C;
+}
+
+#logo h1 a:hover { text-decoration: underline; }
+
+#logo h2 {
+ float: left;
+ padding: 45px 0 0 18px;
+ font: 18px Georgia, "Times New Roman", Times, serif;
+ color: #8BD80E;
+}
+
+#logo p a {
+ text-decoration: none;
+ color: #8BD80E;
+}
+
+#logo p a:hover { text-decoration: underline; }
+
+
+
+/* Page */
+
+#page {
+ width: 663px;
+ margin: 0 auto;
+ background: #4C4C4C url(images/img03.gif) no-repeat left bottom;
+ padding: 0 25px;
+}
+
+/* Content */
+
+#content {
+ float: left;
+ width: 410px;
+
+}
+
+/* Post */
+
+.post {
+ padding: 15px 0px;
+ margin-bottom: 20px;
+}
+
+.post .title {
+ margin-bottom: 20px;
+ padding-bottom: 5px;
+}
+
+.post h1 {
+ padding: 0px 0 0 0px;
+ background: url(images/img08.jpg) no-repeat left top;
+ font-size: 24px;
+ color: #FFFFFF;
+}
+
+.post h2 {
+ padding: 0px 0 0 0px;
+ font-size: 22px;
+ color: #FFFFFF;
+}
+
+.post .entry {
+}
+
+.post .meta {
+ padding: 15px 15px 30px 0px;
+ font-family: Arial, Helvetica, sans-serif;
+ font-size: 11px;
+}
+
+.post .meta p {
+ margin: 0;
+ padding-top: 15px;
+ line-height: normal;
+ color: #FFFFFF;
+}
+
+.post .meta .byline {
+ float: left;
+}
+
+.post .meta .links {
+ float: right;
+}
+
+.post .meta .more {
+ padding: 0 10px 0 18px;
+}
+
+.post .meta .comments {
+}
+
+.post .meta b {
+ display: none;
+}
+
+
+/* Sidebar */
+
+#sidebar {
+ width: 210px;
+ float: right;
+ margin: 0;
+ padding: 0;
+}
+
+#sidebar ul {
+ margin: 0;
+ padding: 0;
+ list-style: none;
+}
+
+#sidebar li {
+ margin-bottom: 40px;
+}
+
+#sidebar li ul {
+}
+
+#sidebar li li {
+ margin: 0;
+}
+
+#sidebar h2 {
+ width: 250px;
+ padding: 8px 0 0 0px;
+ margin-bottom: 10px;
+ background: url(images/img07.jpg) no-repeat left top;
+ font-size: 20px;
+ color: #FFFFFF;
+}
+
+/* Search */
+
+#search {
+
+}
+
+#search h2 {
+ margin-bottom: 20px;
+}
+
+#s {
+ width: 140px;
+ margin-right: 5px;
+ padding: 3px;
+ border: 1px solid #BED99C;
+}
+
+#x {
+ padding: 3px;
+ border: none;
+ background: #8BD80E;
+ text-transform: lowercase;
+ font-size: 11px;
+ color: #FFFFFF;
+}
+
+/* Boxes */
+
+.box1 {
+ padding: 20px;
+}
+
+.box2 {
+ color: #BABABA;
+}
+
+.box2 h2 {
+ margin-bottom: 15px;
+ font-size: 16px;
+ color: #FFFFFF;
+}
+
+.box2 ul {
+ margin: 0;
+ padding: 0;
+ list-style: none;
+}
+
+.box2 a:link, .box2 a:hover, .box2 a:active, .box2 a:visited {
+ color: #EDEDED;
+}
+
+/* Footer */
+#footer-wrap {
+}
+
+#footer {
+ margin: 0 auto;
+ padding: 20px 0 10px 0;
+ background: #000000;
+}
+
+html>body #footer {
+ height: auto;
+}
+
+#footer p {
+ font-size: 11px;
+}
+
+#legal {
+ clear: both;
+ padding-top: 17px;
+ text-align: center;
+ color: #FFFFFF;
+}
+
+#legal a {
+ font-weight: normal;
+ color: #FFFFFF;
+}
diff --git a/pyramid/paster_templates/pylons_minimal/+package+/static/images/img01.gif b/pyramid/paster_templates/pylons_minimal/+package+/static/images/img01.gif
new file mode 100644
index 000000000..5f082bd99
--- /dev/null
+++ b/pyramid/paster_templates/pylons_minimal/+package+/static/images/img01.gif
Binary files differ
diff --git a/pyramid/paster_templates/pylons_minimal/+package+/static/images/img02.gif b/pyramid/paster_templates/pylons_minimal/+package+/static/images/img02.gif
new file mode 100644
index 000000000..45a3ae976
--- /dev/null
+++ b/pyramid/paster_templates/pylons_minimal/+package+/static/images/img02.gif
Binary files differ
diff --git a/pyramid/paster_templates/pylons_minimal/+package+/static/images/img03.gif b/pyramid/paster_templates/pylons_minimal/+package+/static/images/img03.gif
new file mode 100644
index 000000000..d92ea38f9
--- /dev/null
+++ b/pyramid/paster_templates/pylons_minimal/+package+/static/images/img03.gif
Binary files differ
diff --git a/pyramid/paster_templates/pylons_minimal/+package+/static/images/img04.gif b/pyramid/paster_templates/pylons_minimal/+package+/static/images/img04.gif
new file mode 100644
index 000000000..950c4af9d
--- /dev/null
+++ b/pyramid/paster_templates/pylons_minimal/+package+/static/images/img04.gif
Binary files differ
diff --git a/pyramid/paster_templates/pylons_minimal/+package+/static/images/spacer.gif b/pyramid/paster_templates/pylons_minimal/+package+/static/images/spacer.gif
new file mode 100644
index 000000000..5bfd67a2d
--- /dev/null
+++ b/pyramid/paster_templates/pylons_minimal/+package+/static/images/spacer.gif
Binary files differ
diff --git a/pyramid/paster_templates/pylons_minimal/+package+/static/templatelicense.txt b/pyramid/paster_templates/pylons_minimal/+package+/static/templatelicense.txt
new file mode 100644
index 000000000..ccb6b06ab
--- /dev/null
+++ b/pyramid/paster_templates/pylons_minimal/+package+/static/templatelicense.txt
@@ -0,0 +1,243 @@
+Creative Commons </>
+
+Creative Commons Legal Code
+
+*Attribution 2.5*
+
+CREATIVE COMMONS CORPORATION IS NOT A LAW FIRM AND DOES NOT PROVIDE
+LEGAL SERVICES. DISTRIBUTION OF THIS LICENSE DOES NOT CREATE AN
+ATTORNEY-CLIENT RELATIONSHIP. CREATIVE COMMONS PROVIDES THIS INFORMATION
+ON AN "AS-IS" BASIS. CREATIVE COMMONS MAKES NO WARRANTIES REGARDING THE
+INFORMATION PROVIDED, AND DISCLAIMS LIABILITY FOR DAMAGES RESULTING FROM
+ITS USE.
+
+/License/
+
+THE WORK (AS DEFINED BELOW) IS PROVIDED UNDER THE TERMS OF THIS CREATIVE
+COMMONS PUBLIC LICENSE ("CCPL" OR "LICENSE"). THE WORK IS PROTECTED BY
+COPYRIGHT AND/OR OTHER APPLICABLE LAW. ANY USE OF THE WORK OTHER THAN AS
+AUTHORIZED UNDER THIS LICENSE OR COPYRIGHT LAW IS PROHIBITED.
+
+BY EXERCISING ANY RIGHTS TO THE WORK PROVIDED HERE, YOU ACCEPT AND AGREE
+TO BE BOUND BY THE TERMS OF THIS LICENSE. THE LICENSOR GRANTS YOU THE
+RIGHTS CONTAINED HERE IN CONSIDERATION OF YOUR ACCEPTANCE OF SUCH TERMS
+AND CONDITIONS.
+
+*1. Definitions*
+
+ 1. *"Collective Work"* means a work, such as a periodical issue,
+ anthology or encyclopedia, in which the Work in its entirety in
+ unmodified form, along with a number of other contributions,
+ constituting separate and independent works in themselves, are
+ assembled into a collective whole. A work that constitutes a
+ Collective Work will not be considered a Derivative Work (as
+ defined below) for the purposes of this License.
+ 2. *"Derivative Work"* means a work based upon the Work or upon the
+ Work and other pre-existing works, such as a translation, musical
+ arrangement, dramatization, fictionalization, motion picture
+ version, sound recording, art reproduction, abridgment,
+ condensation, or any other form in which the Work may be recast,
+ transformed, or adapted, except that a work that constitutes a
+ Collective Work will not be considered a Derivative Work for the
+ purpose of this License. For the avoidance of doubt, where the
+ Work is a musical composition or sound recording, the
+ synchronization of the Work in timed-relation with a moving image
+ ("synching") will be considered a Derivative Work for the purpose
+ of this License.
+ 3. *"Licensor"* means the individual or entity that offers the Work
+ under the terms of this License.
+ 4. *"Original Author"* means the individual or entity who created the
+ Work.
+ 5. *"Work"* means the copyrightable work of authorship offered under
+ the terms of this License.
+ 6. *"You"* means an individual or entity exercising rights under this
+ License who has not previously violated the terms of this License
+ with respect to the Work, or who has received express permission
+ from the Licensor to exercise rights under this License despite a
+ previous violation.
+
+*2. Fair Use Rights.* Nothing in this license is intended to reduce,
+limit, or restrict any rights arising from fair use, first sale or other
+limitations on the exclusive rights of the copyright owner under
+copyright law or other applicable laws.
+
+*3. License Grant.* Subject to the terms and conditions of this License,
+Licensor hereby grants You a worldwide, royalty-free, non-exclusive,
+perpetual (for the duration of the applicable copyright) license to
+exercise the rights in the Work as stated below:
+
+ 1. to reproduce the Work, to incorporate the Work into one or more
+ Collective Works, and to reproduce the Work as incorporated in the
+ Collective Works;
+ 2. to create and reproduce Derivative Works;
+ 3. to distribute copies or phonorecords of, display publicly, perform
+ publicly, and perform publicly by means of a digital audio
+ transmission the Work including as incorporated in Collective Works;
+ 4. to distribute copies or phonorecords of, display publicly, perform
+ publicly, and perform publicly by means of a digital audio
+ transmission Derivative Works.
+ 5.
+
+ For the avoidance of doubt, where the work is a musical composition:
+
+ 1. *Performance Royalties Under Blanket Licenses*. Licensor
+ waives the exclusive right to collect, whether individually
+ or via a performance rights society (e.g. ASCAP, BMI,
+ SESAC), royalties for the public performance or public
+ digital performance (e.g. webcast) of the Work.
+ 2. *Mechanical Rights and Statutory Royalties*. Licensor waives
+ the exclusive right to collect, whether individually or via
+ a music rights agency or designated agent (e.g. Harry Fox
+ Agency), royalties for any phonorecord You create from the
+ Work ("cover version") and distribute, subject to the
+ compulsory license created by 17 USC Section 115 of the US
+ Copyright Act (or the equivalent in other jurisdictions).
+ 6. *Webcasting Rights and Statutory Royalties*. For the avoidance of
+ doubt, where the Work is a sound recording, Licensor waives the
+ exclusive right to collect, whether individually or via a
+ performance-rights society (e.g. SoundExchange), royalties for the
+ public digital performance (e.g. webcast) of the Work, subject to
+ the compulsory license created by 17 USC Section 114 of the US
+ Copyright Act (or the equivalent in other jurisdictions).
+
+The above rights may be exercised in all media and formats whether now
+known or hereafter devised. The above rights include the right to make
+such modifications as are technically necessary to exercise the rights
+in other media and formats. All rights not expressly granted by Licensor
+are hereby reserved.
+
+*4. Restrictions.*The license granted in Section 3 above is expressly
+made subject to and limited by the following restrictions:
+
+ 1. You may distribute, publicly display, publicly perform, or
+ publicly digitally perform the Work only under the terms of this
+ License, and You must include a copy of, or the Uniform Resource
+ Identifier for, this License with every copy or phonorecord of the
+ Work You distribute, publicly display, publicly perform, or
+ publicly digitally perform. You may not offer or impose any terms
+ on the Work that alter or restrict the terms of this License or
+ the recipients' exercise of the rights granted hereunder. You may
+ not sublicense the Work. You must keep intact all notices that
+ refer to this License and to the disclaimer of warranties. You may
+ not distribute, publicly display, publicly perform, or publicly
+ digitally perform the Work with any technological measures that
+ control access or use of the Work in a manner inconsistent with
+ the terms of this License Agreement. The above applies to the Work
+ as incorporated in a Collective Work, but this does not require
+ the Collective Work apart from the Work itself to be made subject
+ to the terms of this License. If You create a Collective Work,
+ upon notice from any Licensor You must, to the extent practicable,
+ remove from the Collective Work any credit as required by clause
+ 4(b), as requested. If You create a Derivative Work, upon notice
+ from any Licensor You must, to the extent practicable, remove from
+ the Derivative Work any credit as required by clause 4(b), as
+ requested.
+ 2. If you distribute, publicly display, publicly perform, or publicly
+ digitally perform the Work or any Derivative Works or Collective
+ Works, You must keep intact all copyright notices for the Work and
+ provide, reasonable to the medium or means You are utilizing: (i)
+ the name of the Original Author (or pseudonym, if applicable) if
+ supplied, and/or (ii) if the Original Author and/or Licensor
+ designate another party or parties (e.g. a sponsor institute,
+ publishing entity, journal) for attribution in Licensor's
+ copyright notice, terms of service or by other reasonable means,
+ the name of such party or parties; the title of the Work if
+ supplied; to the extent reasonably practicable, the Uniform
+ Resource Identifier, if any, that Licensor specifies to be
+ associated with the Work, unless such URI does not refer to the
+ copyright notice or licensing information for the Work; and in the
+ case of a Derivative Work, a credit identifying the use of the
+ Work in the Derivative Work (e.g., "French translation of the Work
+ by Original Author," or "Screenplay based on original Work by
+ Original Author"). Such credit may be implemented in any
+ reasonable manner; provided, however, that in the case of a
+ Derivative Work or Collective Work, at a minimum such credit will
+ appear where any other comparable authorship credit appears and in
+ a manner at least as prominent as such other comparable authorship
+ credit.
+
+*5. Representations, Warranties and Disclaimer*
+
+UNLESS OTHERWISE MUTUALLY AGREED TO BY THE PARTIES IN WRITING, LICENSOR
+OFFERS THE WORK AS-IS AND MAKES NO REPRESENTATIONS OR WARRANTIES OF ANY
+KIND CONCERNING THE WORK, EXPRESS, IMPLIED, STATUTORY OR OTHERWISE,
+INCLUDING, WITHOUT LIMITATION, WARRANTIES OF TITLE, MERCHANTIBILITY,
+FITNESS FOR A PARTICULAR PURPOSE, NONINFRINGEMENT, OR THE ABSENCE OF
+LATENT OR OTHER DEFECTS, ACCURACY, OR THE PRESENCE OF ABSENCE OF ERRORS,
+WHETHER OR NOT DISCOVERABLE. SOME JURISDICTIONS DO NOT ALLOW THE
+EXCLUSION OF IMPLIED WARRANTIES, SO SUCH EXCLUSION MAY NOT APPLY TO YOU.
+
+*6. Limitation on Liability.* EXCEPT TO THE EXTENT REQUIRED BY
+APPLICABLE LAW, IN NO EVENT WILL LICENSOR BE LIABLE TO YOU ON ANY LEGAL
+THEORY FOR ANY SPECIAL, INCIDENTAL, CONSEQUENTIAL, PUNITIVE OR EXEMPLARY
+DAMAGES ARISING OUT OF THIS LICENSE OR THE USE OF THE WORK, EVEN IF
+LICENSOR HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGES.
+
+*7. Termination*
+
+ 1. This License and the rights granted hereunder will terminate
+ automatically upon any breach by You of the terms of this License.
+ Individuals or entities who have received Derivative Works or
+ Collective Works from You under this License, however, will not
+ have their licenses terminated provided such individuals or
+ entities remain in full compliance with those licenses. Sections
+ 1, 2, 5, 6, 7, and 8 will survive any termination of this License.
+ 2. Subject to the above terms and conditions, the license granted
+ here is perpetual (for the duration of the applicable copyright in
+ the Work). Notwithstanding the above, Licensor reserves the right
+ to release the Work under different license terms or to stop
+ distributing the Work at any time; provided, however that any such
+ election will not serve to withdraw this License (or any other
+ license that has been, or is required to be, granted under the
+ terms of this License), and this License will continue in full
+ force and effect unless terminated as stated above.
+
+*8. Miscellaneous*
+
+ 1. Each time You distribute or publicly digitally perform the Work or
+ a Collective Work, the Licensor offers to the recipient a license
+ to the Work on the same terms and conditions as the license
+ granted to You under this License.
+ 2. Each time You distribute or publicly digitally perform a
+ Derivative Work, Licensor offers to the recipient a license to the
+ original Work on the same terms and conditions as the license
+ granted to You under this License.
+ 3. If any provision of this License is invalid or unenforceable under
+ applicable law, it shall not affect the validity or enforceability
+ of the remainder of the terms of this License, and without further
+ action by the parties to this agreement, such provision shall be
+ reformed to the minimum extent necessary to make such provision
+ valid and enforceable.
+ 4. No term or provision of this License shall be deemed waived and no
+ breach consented to unless such waiver or consent shall be in
+ writing and signed by the party to be charged with such waiver or
+ consent.
+ 5. This License constitutes the entire agreement between the parties
+ with respect to the Work licensed here. There are no
+ understandings, agreements or representations with respect to the
+ Work not specified here. Licensor shall not be bound by any
+ additional provisions that may appear in any communication from
+ You. This License may not be modified without the mutual written
+ agreement of the Licensor and You.
+
+Creative Commons is not a party to this License, and makes no warranty
+whatsoever in connection with the Work. Creative Commons will not be
+liable to You or any party on any legal theory for any damages
+whatsoever, including without limitation any general, special,
+incidental or consequential damages arising in connection to this
+license. Notwithstanding the foregoing two (2) sentences, if Creative
+Commons has expressly identified itself as the Licensor hereunder, it
+shall have all rights and obligations of Licensor.
+
+Except for the limited purpose of indicating to the public that the Work
+is licensed under the CCPL, neither party will use the trademark
+"Creative Commons" or any related trademark or logo of Creative Commons
+without the prior written consent of Creative Commons. Any permitted use
+will be in compliance with Creative Commons' then-current trademark
+usage guidelines, as may be published on its website or otherwise made
+available upon request from time to time.
+
+Creative Commons may be contacted at http://creativecommons.org/
+<http://creativecommons.org>.
+
+« Back to Commons Deed <./>
diff --git a/pyramid/paster_templates/pylons_minimal/+package+/templates/mytemplate.mak b/pyramid/paster_templates/pylons_minimal/+package+/templates/mytemplate.mak
new file mode 100644
index 000000000..035cc2f78
--- /dev/null
+++ b/pyramid/paster_templates/pylons_minimal/+package+/templates/mytemplate.mak
@@ -0,0 +1,49 @@
+<!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"
+ xmlns:tal="http://xml.zope.org/namespaces/tal">
+<head>
+<meta http-equiv="content-type" content="text/html; charset=utf-8" />
+<title>${project} Application</title>
+<meta name="keywords" content="python web application" />
+<meta name="description" content="Pylons web application" />
+<link href="${request.application_url}/static/default.css" rel="stylesheet" type="text/css" />
+</head>
+<body>
+<!-- start header -->
+<div id="logo">
+ <h2><code>${project}</code>, a <code>Pylons</code> application</h2>
+</div>
+<div id="header">
+ <div id="menu">
+ </div>
+</div>
+<!-- end header -->
+<div id="wrapper">
+ <!-- start page -->
+ <div id="page">
+ <!-- start content -->
+ <div id="content">
+ <div class="post">
+ <h1 class="title">Welcome to <code>${project}</code>, an
+ application generated by the <a
+ href="http://pylonshq.com">Pylons</a> web
+ application framework.</h1>
+ </div>
+ </div>
+ <!-- end content -->
+ <!-- start sidebar -->
+ <div id="sidebar"></div>
+ <!-- end sidebar -->
+ <div style="clear: both;">&nbsp;</div>
+ </div>
+</div>
+<!-- end page -->
+<!-- start footer -->
+<div id="footer">
+ <p id="legal">( c ) 2008. All Rights Reserved. Template design
+ by <a href="http://www.freecsstemplates.org/">Free CSS
+ Templates</a>.</p>
+</div>
+<!-- end footer -->
+</body>
+</html>
diff --git a/pyramid/paster_templates/pylons_minimal/+package+/tests.py_tmpl b/pyramid/paster_templates/pylons_minimal/+package+/tests.py_tmpl
new file mode 100644
index 000000000..d98bee355
--- /dev/null
+++ b/pyramid/paster_templates/pylons_minimal/+package+/tests.py_tmpl
@@ -0,0 +1,24 @@
+import unittest
+
+from pyramid.configuration import Configurator
+
+class MyControllerTests(unittest.TestCase):
+ def setUp(self):
+ self.config = Configurator()
+ self.config.begin()
+
+ def tearDown(self):
+ self.config.end()
+
+ def _makeOne(self, request):
+ from {{package}}.handlers import MyHandler
+ return MyHandler(request)
+
+ def test_index(self):
+ request = DummyRequest()
+ controller = self._makeOne(request)
+ info = controller.index()
+ self.assertEqual(info['project'], '{{project}}')
+
+class DummyRequest(object):
+ pass
diff --git a/pyramid/paster_templates/pylons_minimal/CHANGES.txt_tmpl b/pyramid/paster_templates/pylons_minimal/CHANGES.txt_tmpl
new file mode 100644
index 000000000..35a34f332
--- /dev/null
+++ b/pyramid/paster_templates/pylons_minimal/CHANGES.txt_tmpl
@@ -0,0 +1,4 @@
+0.0
+---
+
+- Initial version
diff --git a/pyramid/paster_templates/pylons_minimal/README.txt_tmpl b/pyramid/paster_templates/pylons_minimal/README.txt_tmpl
new file mode 100644
index 000000000..0ddebfc3e
--- /dev/null
+++ b/pyramid/paster_templates/pylons_minimal/README.txt_tmpl
@@ -0,0 +1,4 @@
+{{project}} README
+
+
+
diff --git a/pyramid/paster_templates/pylons_minimal/development.ini_tmpl b/pyramid/paster_templates/pylons_minimal/development.ini_tmpl
new file mode 100644
index 000000000..d3c8b57c9
--- /dev/null
+++ b/pyramid/paster_templates/pylons_minimal/development.ini_tmpl
@@ -0,0 +1,28 @@
+[app:{{project}}]
+use = egg:{{project}}
+reload_templates = true
+mako.directories = {{package}}:templates
+debug_authorization = false
+debug_notfound = false
+debug_templates = true
+default_locale_name = en
+session.type = file
+session.data_dir = %(here)s/data/sessions/data
+session.lock_dir = %(here)s/data/sessions/lock
+session.key = {{project}}
+session.secret = your_app_secret_string
+cache.regions = default_term, second, short_term, long_term
+cache.type = memory
+cache.second.expire = 1
+cache.short_term.expire = 60
+cache.default_term.expire = 300
+cache.long_term.expire = 3600
+
+[pipeline:main]
+pipeline = egg:WebError#evalerror
+ {{project}}
+
+[server:main]
+use = egg:Paste#http
+host = 0.0.0.0
+port = 5000
diff --git a/pyramid/paster_templates/pylons_minimal/setup.cfg_tmpl b/pyramid/paster_templates/pylons_minimal/setup.cfg_tmpl
new file mode 100644
index 000000000..5bec29823
--- /dev/null
+++ b/pyramid/paster_templates/pylons_minimal/setup.cfg_tmpl
@@ -0,0 +1,27 @@
+[nosetests]
+match=^test
+nocapture=1
+cover-package={{package}}
+with-coverage=1
+cover-erase=1
+
+[compile_catalog]
+directory = {{package}}/locale
+domain = {{project}}
+statistics = true
+
+[extract_messages]
+add_comments = TRANSLATORS:
+output_file = {{package}}/locale/{{project}}.pot
+width = 80
+
+[init_catalog]
+domain = {{project}}
+input_file = {{package}}/locale/{{project}}.pot
+output_dir = {{package}}/locale
+
+[update_catalog]
+domain = {{project}}
+input_file = {{package}}/locale/{{project}}.pot
+output_dir = {{package}}/locale
+previous = true
diff --git a/pyramid/paster_templates/pylons_minimal/setup.py_tmpl b/pyramid/paster_templates/pylons_minimal/setup.py_tmpl
new file mode 100644
index 000000000..baa57aa4e
--- /dev/null
+++ b/pyramid/paster_templates/pylons_minimal/setup.py_tmpl
@@ -0,0 +1,36 @@
+import os
+
+from setuptools import setup, find_packages
+
+here = os.path.abspath(os.path.dirname(__file__))
+README = open(os.path.join(here, 'README.txt')).read()
+CHANGES = open(os.path.join(here, 'CHANGES.txt')).read()
+
+requires = ['pyramid', 'pyramid_beaker', 'WebError']
+
+setup(name='{{project}}',
+ version='0.0',
+ description='{{project}}',
+ long_description=README + '\n\n' + CHANGES,
+ classifiers=[
+ "Programming Language :: Python",
+ "Framework :: Pylons",
+ "Topic :: Internet :: WWW/HTTP",
+ "Topic :: Internet :: WWW/HTTP :: WSGI :: Application",
+ ],
+ author='',
+ author_email='',
+ url='',
+ keywords='web pylons',
+ packages=find_packages(),
+ include_package_data=True,
+ zip_safe=False,
+ install_requires=requires,
+ tests_require=requires,
+ test_suite="{{package}}",
+ entry_points = """\
+ [paste.app_factory]
+ main = {{package}}:main
+ """
+ )
+
diff --git a/pyramid/paster_templates/pylons_sqla/+package+/__init__.py_tmpl b/pyramid/paster_templates/pylons_sqla/+package+/__init__.py_tmpl
new file mode 100644
index 000000000..cf26cd0ea
--- /dev/null
+++ b/pyramid/paster_templates/pylons_sqla/+package+/__init__.py_tmpl
@@ -0,0 +1,38 @@
+from pyramid_beaker import session_factory_from_settings
+from pyramid.personality.pylons import renderer_globals_factory_config
+
+def main(global_config, **settings):
+ """ This function returns a Pylons WSGI application.
+ """
+ from paste.deploy.converters import asbool
+ from pyramid.configuration import Configurator
+ from {{package}}.models import initialize_sql
+ db_string = settings.get('db_string')
+ if db_string is None:
+ raise ValueError("No 'db_string' value in application "
+ "configuration.")
+ initialize_sql(db_string, asbool(settings.get('db_echo')))
+ config = Configurator(settings=settings)
+ config.begin()
+ session_factory = session_factory_from_settings(settings)
+ config.set_session_factory(session_factory)
+ # XXX add caching setup
+ globals_factory = renderer_globals_factory_config(None)
+ config.set_renderer_globals_factory(globals_factory)
+ config.add_static_view(
+ 'static',
+ '{{package}}:static/'
+ )
+ config.add_handler(
+ 'main',
+ '/{action}',
+ '{{package}}.handlers:MyHandler',
+ )
+ config.add_handler(
+ 'home',
+ '/',
+ '{{package}}.handlers:MyHandler',
+ action='index'
+ )
+ config.end()
+ return config.make_wsgi_app()
diff --git a/pyramid/paster_templates/pylons_sqla/+package+/handlers.py_tmpl b/pyramid/paster_templates/pylons_sqla/+package+/handlers.py_tmpl
new file mode 100644
index 000000000..ce30a635e
--- /dev/null
+++ b/pyramid/paster_templates/pylons_sqla/+package+/handlers.py_tmpl
@@ -0,0 +1,12 @@
+from pyramid.view import action
+
+from {{package}}.models import MyModel
+
+class MyHandler(object):
+ def __init__(self, request):
+ self.request = request
+
+ @action(renderer='mytemplate.mak')
+ def index(self):
+ root = MyModel.by_name('root')
+ return {'root':root, 'project':'{{package}}'}
diff --git a/pyramid/paster_templates/pylons_sqla/+package+/models.py b/pyramid/paster_templates/pylons_sqla/+package+/models.py
new file mode 100644
index 000000000..092166902
--- /dev/null
+++ b/pyramid/paster_templates/pylons_sqla/+package+/models.py
@@ -0,0 +1,47 @@
+import transaction
+
+from sqlalchemy import create_engine
+from sqlalchemy import Column
+from sqlalchemy import Integer
+from sqlalchemy import Unicode
+
+from sqlalchemy.exc import IntegrityError
+from sqlalchemy.ext.declarative import declarative_base
+
+from sqlalchemy.orm import scoped_session
+from sqlalchemy.orm import sessionmaker
+
+from zope.sqlalchemy import ZopeTransactionExtension
+
+DBSession = scoped_session(sessionmaker(extension=ZopeTransactionExtension()))
+Base = declarative_base()
+
+class MyModel(Base):
+ __tablename__ = 'models'
+ id = Column(Integer, primary_key=True)
+ name = Column(Unicode(255), unique=True)
+ value = Column(Integer)
+
+ def __init__(self, name, value):
+ self.name = name
+ self.value = value
+
+ @classmethod
+ def by_name(cls, name=None):
+ return DBSession.query(cls).filter(cls.name == name).first()
+
+def populate():
+ model = MyModel(name=u'root', value=55)
+ DBSession.add(model)
+ DBSession.flush()
+ transaction.commit()
+
+def initialize_sql(db_string, db_echo=False):
+ engine = create_engine(db_string, echo=db_echo)
+ DBSession.configure(bind=engine)
+ Base.metadata.bind = engine
+ Base.metadata.create_all(engine)
+ try:
+ populate()
+ except IntegrityError:
+ pass
diff --git a/pyramid/paster_templates/pylons_sqla/+package+/static/default.css b/pyramid/paster_templates/pylons_sqla/+package+/static/default.css
new file mode 100644
index 000000000..41b3debde
--- /dev/null
+++ b/pyramid/paster_templates/pylons_sqla/+package+/static/default.css
@@ -0,0 +1,380 @@
+/*
+Design by Free CSS Templates
+http://www.freecsstemplates.org
+Released for free under a Creative Commons Attribution 2.5 License
+*/
+
+body {
+ margin: 0;
+ padding: 0;
+ background: url(images/img01.gif) repeat-x left top;
+ font-size: 13px;
+ font-family: "Trebuchet MS", Georgia, "Times New Roman", Times, serif;
+ text-align: justify;
+ color: #FFFFFF;
+}
+
+h1, h2, h3 {
+ margin: 0;
+ text-transform: lowercase;
+ font-weight: normal;
+ color: #FFFFFF;
+}
+
+h1 {
+ letter-spacing: -1px;
+ font-size: 32px;
+}
+
+h2 {
+ font-size: 23px;
+}
+
+p, ul, ol {
+ margin: 0 0 2em 0;
+ text-align: justify;
+ line-height: 26px;
+}
+
+a:link {
+ color: #8BD80E;
+}
+
+a:hover, a:active {
+ text-decoration: none;
+ color: #8BD80E;
+}
+
+a:visited {
+ color: #8BD80E;
+}
+
+img {
+ border: none;
+}
+
+img.left {
+ float: left;
+ margin-right: 15px;
+}
+
+img.right {
+ float: right;
+ margin-left: 15px;
+}
+
+/* Form */
+
+form {
+ margin: 0;
+ padding: 0;
+}
+
+fieldset {
+ margin: 0;
+ padding: 0;
+ border: none;
+}
+
+legend {
+ display: none;
+}
+
+input, textarea, select {
+ font-family: "Trebuchet MS", Arial, Helvetica, sans-serif;
+ font-size: 13px;
+ color: #333333;
+}
+
+#wrapper {
+ margin: 0;
+ padding: 0;
+ background: #000000;
+}
+
+/* Header */
+
+#header {
+ width: 713px;
+ margin: 0 auto;
+ height: 42px;
+}
+
+/* Menu */
+
+#menu {
+ float: left;
+ width: 713px;
+ height: 50px;
+ background: url(images/img02.gif) no-repeat left top;
+}
+
+#menu ul {
+ margin: 0;
+ padding: 0px 0 0 10px;
+ list-style: none;
+ line-height: normal;
+}
+
+#menu li {
+ display: block;
+ float: left;
+}
+
+#menu a {
+ display: block;
+ float: left;
+ background: url(images/img04.gif) no-repeat right 55%;
+ margin-top: 5px;
+ margin-right: 3px;
+ padding: 8px 17px;
+ text-decoration: none;
+ font-size: 13px;
+ color: #000000;
+}
+
+#menu a:hover {
+ color: #000000;
+}
+
+#menu .current_page_item a {
+ color: #000000;
+}
+
+/** LOGO */
+
+#logo {
+ width: 713px;
+ height: 80px;
+ margin: 0 auto;
+}
+
+#logo h1, #logo h2 {
+ float: left;
+ margin: 0;
+ padding: 30px 0 0 0px;
+ line-height: normal;
+}
+
+#logo h1 {
+ font-family: Georgia, "Times New Roman", Times, serif;
+ font-size:40px;
+}
+
+#logo h1 a {
+ text-decoration: none;
+ color: #4C4C4C;
+}
+
+#logo h1 a:hover { text-decoration: underline; }
+
+#logo h2 {
+ float: left;
+ padding: 45px 0 0 18px;
+ font: 18px Georgia, "Times New Roman", Times, serif;
+ color: #8BD80E;
+}
+
+#logo p a {
+ text-decoration: none;
+ color: #8BD80E;
+}
+
+#logo p a:hover { text-decoration: underline; }
+
+
+
+/* Page */
+
+#page {
+ width: 663px;
+ margin: 0 auto;
+ background: #4C4C4C url(images/img03.gif) no-repeat left bottom;
+ padding: 0 25px;
+}
+
+/* Content */
+
+#content {
+ float: left;
+ width: 410px;
+
+}
+
+/* Post */
+
+.post {
+ padding: 15px 0px;
+ margin-bottom: 20px;
+}
+
+.post .title {
+ margin-bottom: 20px;
+ padding-bottom: 5px;
+}
+
+.post h1 {
+ padding: 0px 0 0 0px;
+ background: url(images/img08.jpg) no-repeat left top;
+ font-size: 24px;
+ color: #FFFFFF;
+}
+
+.post h2 {
+ padding: 0px 0 0 0px;
+ font-size: 22px;
+ color: #FFFFFF;
+}
+
+.post .entry {
+}
+
+.post .meta {
+ padding: 15px 15px 30px 0px;
+ font-family: Arial, Helvetica, sans-serif;
+ font-size: 11px;
+}
+
+.post .meta p {
+ margin: 0;
+ padding-top: 15px;
+ line-height: normal;
+ color: #FFFFFF;
+}
+
+.post .meta .byline {
+ float: left;
+}
+
+.post .meta .links {
+ float: right;
+}
+
+.post .meta .more {
+ padding: 0 10px 0 18px;
+}
+
+.post .meta .comments {
+}
+
+.post .meta b {
+ display: none;
+}
+
+
+/* Sidebar */
+
+#sidebar {
+ width: 210px;
+ float: right;
+ margin: 0;
+ padding: 0;
+}
+
+#sidebar ul {
+ margin: 0;
+ padding: 0;
+ list-style: none;
+}
+
+#sidebar li {
+ margin-bottom: 40px;
+}
+
+#sidebar li ul {
+}
+
+#sidebar li li {
+ margin: 0;
+}
+
+#sidebar h2 {
+ width: 250px;
+ padding: 8px 0 0 0px;
+ margin-bottom: 10px;
+ background: url(images/img07.jpg) no-repeat left top;
+ font-size: 20px;
+ color: #FFFFFF;
+}
+
+/* Search */
+
+#search {
+
+}
+
+#search h2 {
+ margin-bottom: 20px;
+}
+
+#s {
+ width: 140px;
+ margin-right: 5px;
+ padding: 3px;
+ border: 1px solid #BED99C;
+}
+
+#x {
+ padding: 3px;
+ border: none;
+ background: #8BD80E;
+ text-transform: lowercase;
+ font-size: 11px;
+ color: #FFFFFF;
+}
+
+/* Boxes */
+
+.box1 {
+ padding: 20px;
+}
+
+.box2 {
+ color: #BABABA;
+}
+
+.box2 h2 {
+ margin-bottom: 15px;
+ font-size: 16px;
+ color: #FFFFFF;
+}
+
+.box2 ul {
+ margin: 0;
+ padding: 0;
+ list-style: none;
+}
+
+.box2 a:link, .box2 a:hover, .box2 a:active, .box2 a:visited {
+ color: #EDEDED;
+}
+
+/* Footer */
+#footer-wrap {
+}
+
+#footer {
+ margin: 0 auto;
+ padding: 20px 0 10px 0;
+ background: #000000;
+}
+
+html>body #footer {
+ height: auto;
+}
+
+#footer p {
+ font-size: 11px;
+}
+
+#legal {
+ clear: both;
+ padding-top: 17px;
+ text-align: center;
+ color: #FFFFFF;
+}
+
+#legal a {
+ font-weight: normal;
+ color: #FFFFFF;
+}
diff --git a/pyramid/paster_templates/pylons_sqla/+package+/static/images/img01.gif b/pyramid/paster_templates/pylons_sqla/+package+/static/images/img01.gif
new file mode 100644
index 000000000..5f082bd99
--- /dev/null
+++ b/pyramid/paster_templates/pylons_sqla/+package+/static/images/img01.gif
Binary files differ
diff --git a/pyramid/paster_templates/pylons_sqla/+package+/static/images/img02.gif b/pyramid/paster_templates/pylons_sqla/+package+/static/images/img02.gif
new file mode 100644
index 000000000..45a3ae976
--- /dev/null
+++ b/pyramid/paster_templates/pylons_sqla/+package+/static/images/img02.gif
Binary files differ
diff --git a/pyramid/paster_templates/pylons_sqla/+package+/static/images/img03.gif b/pyramid/paster_templates/pylons_sqla/+package+/static/images/img03.gif
new file mode 100644
index 000000000..d92ea38f9
--- /dev/null
+++ b/pyramid/paster_templates/pylons_sqla/+package+/static/images/img03.gif
Binary files differ
diff --git a/pyramid/paster_templates/pylons_sqla/+package+/static/images/img04.gif b/pyramid/paster_templates/pylons_sqla/+package+/static/images/img04.gif
new file mode 100644
index 000000000..950c4af9d
--- /dev/null
+++ b/pyramid/paster_templates/pylons_sqla/+package+/static/images/img04.gif
Binary files differ
diff --git a/pyramid/paster_templates/pylons_sqla/+package+/static/images/spacer.gif b/pyramid/paster_templates/pylons_sqla/+package+/static/images/spacer.gif
new file mode 100644
index 000000000..5bfd67a2d
--- /dev/null
+++ b/pyramid/paster_templates/pylons_sqla/+package+/static/images/spacer.gif
Binary files differ
diff --git a/pyramid/paster_templates/pylons_sqla/+package+/static/templatelicense.txt b/pyramid/paster_templates/pylons_sqla/+package+/static/templatelicense.txt
new file mode 100644
index 000000000..ccb6b06ab
--- /dev/null
+++ b/pyramid/paster_templates/pylons_sqla/+package+/static/templatelicense.txt
@@ -0,0 +1,243 @@
+Creative Commons </>
+
+Creative Commons Legal Code
+
+*Attribution 2.5*
+
+CREATIVE COMMONS CORPORATION IS NOT A LAW FIRM AND DOES NOT PROVIDE
+LEGAL SERVICES. DISTRIBUTION OF THIS LICENSE DOES NOT CREATE AN
+ATTORNEY-CLIENT RELATIONSHIP. CREATIVE COMMONS PROVIDES THIS INFORMATION
+ON AN "AS-IS" BASIS. CREATIVE COMMONS MAKES NO WARRANTIES REGARDING THE
+INFORMATION PROVIDED, AND DISCLAIMS LIABILITY FOR DAMAGES RESULTING FROM
+ITS USE.
+
+/License/
+
+THE WORK (AS DEFINED BELOW) IS PROVIDED UNDER THE TERMS OF THIS CREATIVE
+COMMONS PUBLIC LICENSE ("CCPL" OR "LICENSE"). THE WORK IS PROTECTED BY
+COPYRIGHT AND/OR OTHER APPLICABLE LAW. ANY USE OF THE WORK OTHER THAN AS
+AUTHORIZED UNDER THIS LICENSE OR COPYRIGHT LAW IS PROHIBITED.
+
+BY EXERCISING ANY RIGHTS TO THE WORK PROVIDED HERE, YOU ACCEPT AND AGREE
+TO BE BOUND BY THE TERMS OF THIS LICENSE. THE LICENSOR GRANTS YOU THE
+RIGHTS CONTAINED HERE IN CONSIDERATION OF YOUR ACCEPTANCE OF SUCH TERMS
+AND CONDITIONS.
+
+*1. Definitions*
+
+ 1. *"Collective Work"* means a work, such as a periodical issue,
+ anthology or encyclopedia, in which the Work in its entirety in
+ unmodified form, along with a number of other contributions,
+ constituting separate and independent works in themselves, are
+ assembled into a collective whole. A work that constitutes a
+ Collective Work will not be considered a Derivative Work (as
+ defined below) for the purposes of this License.
+ 2. *"Derivative Work"* means a work based upon the Work or upon the
+ Work and other pre-existing works, such as a translation, musical
+ arrangement, dramatization, fictionalization, motion picture
+ version, sound recording, art reproduction, abridgment,
+ condensation, or any other form in which the Work may be recast,
+ transformed, or adapted, except that a work that constitutes a
+ Collective Work will not be considered a Derivative Work for the
+ purpose of this License. For the avoidance of doubt, where the
+ Work is a musical composition or sound recording, the
+ synchronization of the Work in timed-relation with a moving image
+ ("synching") will be considered a Derivative Work for the purpose
+ of this License.
+ 3. *"Licensor"* means the individual or entity that offers the Work
+ under the terms of this License.
+ 4. *"Original Author"* means the individual or entity who created the
+ Work.
+ 5. *"Work"* means the copyrightable work of authorship offered under
+ the terms of this License.
+ 6. *"You"* means an individual or entity exercising rights under this
+ License who has not previously violated the terms of this License
+ with respect to the Work, or who has received express permission
+ from the Licensor to exercise rights under this License despite a
+ previous violation.
+
+*2. Fair Use Rights.* Nothing in this license is intended to reduce,
+limit, or restrict any rights arising from fair use, first sale or other
+limitations on the exclusive rights of the copyright owner under
+copyright law or other applicable laws.
+
+*3. License Grant.* Subject to the terms and conditions of this License,
+Licensor hereby grants You a worldwide, royalty-free, non-exclusive,
+perpetual (for the duration of the applicable copyright) license to
+exercise the rights in the Work as stated below:
+
+ 1. to reproduce the Work, to incorporate the Work into one or more
+ Collective Works, and to reproduce the Work as incorporated in the
+ Collective Works;
+ 2. to create and reproduce Derivative Works;
+ 3. to distribute copies or phonorecords of, display publicly, perform
+ publicly, and perform publicly by means of a digital audio
+ transmission the Work including as incorporated in Collective Works;
+ 4. to distribute copies or phonorecords of, display publicly, perform
+ publicly, and perform publicly by means of a digital audio
+ transmission Derivative Works.
+ 5.
+
+ For the avoidance of doubt, where the work is a musical composition:
+
+ 1. *Performance Royalties Under Blanket Licenses*. Licensor
+ waives the exclusive right to collect, whether individually
+ or via a performance rights society (e.g. ASCAP, BMI,
+ SESAC), royalties for the public performance or public
+ digital performance (e.g. webcast) of the Work.
+ 2. *Mechanical Rights and Statutory Royalties*. Licensor waives
+ the exclusive right to collect, whether individually or via
+ a music rights agency or designated agent (e.g. Harry Fox
+ Agency), royalties for any phonorecord You create from the
+ Work ("cover version") and distribute, subject to the
+ compulsory license created by 17 USC Section 115 of the US
+ Copyright Act (or the equivalent in other jurisdictions).
+ 6. *Webcasting Rights and Statutory Royalties*. For the avoidance of
+ doubt, where the Work is a sound recording, Licensor waives the
+ exclusive right to collect, whether individually or via a
+ performance-rights society (e.g. SoundExchange), royalties for the
+ public digital performance (e.g. webcast) of the Work, subject to
+ the compulsory license created by 17 USC Section 114 of the US
+ Copyright Act (or the equivalent in other jurisdictions).
+
+The above rights may be exercised in all media and formats whether now
+known or hereafter devised. The above rights include the right to make
+such modifications as are technically necessary to exercise the rights
+in other media and formats. All rights not expressly granted by Licensor
+are hereby reserved.
+
+*4. Restrictions.*The license granted in Section 3 above is expressly
+made subject to and limited by the following restrictions:
+
+ 1. You may distribute, publicly display, publicly perform, or
+ publicly digitally perform the Work only under the terms of this
+ License, and You must include a copy of, or the Uniform Resource
+ Identifier for, this License with every copy or phonorecord of the
+ Work You distribute, publicly display, publicly perform, or
+ publicly digitally perform. You may not offer or impose any terms
+ on the Work that alter or restrict the terms of this License or
+ the recipients' exercise of the rights granted hereunder. You may
+ not sublicense the Work. You must keep intact all notices that
+ refer to this License and to the disclaimer of warranties. You may
+ not distribute, publicly display, publicly perform, or publicly
+ digitally perform the Work with any technological measures that
+ control access or use of the Work in a manner inconsistent with
+ the terms of this License Agreement. The above applies to the Work
+ as incorporated in a Collective Work, but this does not require
+ the Collective Work apart from the Work itself to be made subject
+ to the terms of this License. If You create a Collective Work,
+ upon notice from any Licensor You must, to the extent practicable,
+ remove from the Collective Work any credit as required by clause
+ 4(b), as requested. If You create a Derivative Work, upon notice
+ from any Licensor You must, to the extent practicable, remove from
+ the Derivative Work any credit as required by clause 4(b), as
+ requested.
+ 2. If you distribute, publicly display, publicly perform, or publicly
+ digitally perform the Work or any Derivative Works or Collective
+ Works, You must keep intact all copyright notices for the Work and
+ provide, reasonable to the medium or means You are utilizing: (i)
+ the name of the Original Author (or pseudonym, if applicable) if
+ supplied, and/or (ii) if the Original Author and/or Licensor
+ designate another party or parties (e.g. a sponsor institute,
+ publishing entity, journal) for attribution in Licensor's
+ copyright notice, terms of service or by other reasonable means,
+ the name of such party or parties; the title of the Work if
+ supplied; to the extent reasonably practicable, the Uniform
+ Resource Identifier, if any, that Licensor specifies to be
+ associated with the Work, unless such URI does not refer to the
+ copyright notice or licensing information for the Work; and in the
+ case of a Derivative Work, a credit identifying the use of the
+ Work in the Derivative Work (e.g., "French translation of the Work
+ by Original Author," or "Screenplay based on original Work by
+ Original Author"). Such credit may be implemented in any
+ reasonable manner; provided, however, that in the case of a
+ Derivative Work or Collective Work, at a minimum such credit will
+ appear where any other comparable authorship credit appears and in
+ a manner at least as prominent as such other comparable authorship
+ credit.
+
+*5. Representations, Warranties and Disclaimer*
+
+UNLESS OTHERWISE MUTUALLY AGREED TO BY THE PARTIES IN WRITING, LICENSOR
+OFFERS THE WORK AS-IS AND MAKES NO REPRESENTATIONS OR WARRANTIES OF ANY
+KIND CONCERNING THE WORK, EXPRESS, IMPLIED, STATUTORY OR OTHERWISE,
+INCLUDING, WITHOUT LIMITATION, WARRANTIES OF TITLE, MERCHANTIBILITY,
+FITNESS FOR A PARTICULAR PURPOSE, NONINFRINGEMENT, OR THE ABSENCE OF
+LATENT OR OTHER DEFECTS, ACCURACY, OR THE PRESENCE OF ABSENCE OF ERRORS,
+WHETHER OR NOT DISCOVERABLE. SOME JURISDICTIONS DO NOT ALLOW THE
+EXCLUSION OF IMPLIED WARRANTIES, SO SUCH EXCLUSION MAY NOT APPLY TO YOU.
+
+*6. Limitation on Liability.* EXCEPT TO THE EXTENT REQUIRED BY
+APPLICABLE LAW, IN NO EVENT WILL LICENSOR BE LIABLE TO YOU ON ANY LEGAL
+THEORY FOR ANY SPECIAL, INCIDENTAL, CONSEQUENTIAL, PUNITIVE OR EXEMPLARY
+DAMAGES ARISING OUT OF THIS LICENSE OR THE USE OF THE WORK, EVEN IF
+LICENSOR HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGES.
+
+*7. Termination*
+
+ 1. This License and the rights granted hereunder will terminate
+ automatically upon any breach by You of the terms of this License.
+ Individuals or entities who have received Derivative Works or
+ Collective Works from You under this License, however, will not
+ have their licenses terminated provided such individuals or
+ entities remain in full compliance with those licenses. Sections
+ 1, 2, 5, 6, 7, and 8 will survive any termination of this License.
+ 2. Subject to the above terms and conditions, the license granted
+ here is perpetual (for the duration of the applicable copyright in
+ the Work). Notwithstanding the above, Licensor reserves the right
+ to release the Work under different license terms or to stop
+ distributing the Work at any time; provided, however that any such
+ election will not serve to withdraw this License (or any other
+ license that has been, or is required to be, granted under the
+ terms of this License), and this License will continue in full
+ force and effect unless terminated as stated above.
+
+*8. Miscellaneous*
+
+ 1. Each time You distribute or publicly digitally perform the Work or
+ a Collective Work, the Licensor offers to the recipient a license
+ to the Work on the same terms and conditions as the license
+ granted to You under this License.
+ 2. Each time You distribute or publicly digitally perform a
+ Derivative Work, Licensor offers to the recipient a license to the
+ original Work on the same terms and conditions as the license
+ granted to You under this License.
+ 3. If any provision of this License is invalid or unenforceable under
+ applicable law, it shall not affect the validity or enforceability
+ of the remainder of the terms of this License, and without further
+ action by the parties to this agreement, such provision shall be
+ reformed to the minimum extent necessary to make such provision
+ valid and enforceable.
+ 4. No term or provision of this License shall be deemed waived and no
+ breach consented to unless such waiver or consent shall be in
+ writing and signed by the party to be charged with such waiver or
+ consent.
+ 5. This License constitutes the entire agreement between the parties
+ with respect to the Work licensed here. There are no
+ understandings, agreements or representations with respect to the
+ Work not specified here. Licensor shall not be bound by any
+ additional provisions that may appear in any communication from
+ You. This License may not be modified without the mutual written
+ agreement of the Licensor and You.
+
+Creative Commons is not a party to this License, and makes no warranty
+whatsoever in connection with the Work. Creative Commons will not be
+liable to You or any party on any legal theory for any damages
+whatsoever, including without limitation any general, special,
+incidental or consequential damages arising in connection to this
+license. Notwithstanding the foregoing two (2) sentences, if Creative
+Commons has expressly identified itself as the Licensor hereunder, it
+shall have all rights and obligations of Licensor.
+
+Except for the limited purpose of indicating to the public that the Work
+is licensed under the CCPL, neither party will use the trademark
+"Creative Commons" or any related trademark or logo of Creative Commons
+without the prior written consent of Creative Commons. Any permitted use
+will be in compliance with Creative Commons' then-current trademark
+usage guidelines, as may be published on its website or otherwise made
+available upon request from time to time.
+
+Creative Commons may be contacted at http://creativecommons.org/
+<http://creativecommons.org>.
+
+« Back to Commons Deed <./>
diff --git a/pyramid/paster_templates/pylons_sqla/+package+/templates/mytemplate.mak b/pyramid/paster_templates/pylons_sqla/+package+/templates/mytemplate.mak
new file mode 100644
index 000000000..42c61bc4d
--- /dev/null
+++ b/pyramid/paster_templates/pylons_sqla/+package+/templates/mytemplate.mak
@@ -0,0 +1,50 @@
+<!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"
+ xmlns:tal="http://xml.zope.org/namespaces/tal">
+<head>
+<meta http-equiv="content-type" content="text/html; charset=utf-8" />
+<title>${project} Application</title>
+<meta name="keywords" content="python web application" />
+<meta name="description" content="Pylons web application" />
+<link href="${request.application_url}/static/default.css" rel="stylesheet" type="text/css" />
+</head>
+<body>
+<!-- start header -->
+<div id="logo">
+ <h2><code>${project}</code>, a <code>Pylons</code> application</h2>
+</div>
+<div id="header">
+ <div id="menu">
+ </div>
+</div>
+<!-- end header -->
+<div id="wrapper">
+ <!-- start page -->
+ <div id="page">
+ <!-- start content -->
+ <div id="content">
+ <div class="post">
+ <h1 class="title">Welcome to <code>${project}</code>, an
+ application generated by the <a
+ href="http://pylonshq.com">Pylons</a> web
+ application framework.</h1>
+ </div>
+ <div>The root object's name is "${root.name}"</div>
+ </div>
+ <!-- end content -->
+ <!-- start sidebar -->
+ <div id="sidebar"></div>
+ <!-- end sidebar -->
+ <div style="clear: both;">&nbsp;</div>
+ </div>
+</div>
+<!-- end page -->
+<!-- start footer -->
+<div id="footer">
+ <p id="legal">( c ) 2008. All Rights Reserved. Template design
+ by <a href="http://www.freecsstemplates.org/">Free CSS
+ Templates</a>.</p>
+</div>
+<!-- end footer -->
+</body>
+</html>
diff --git a/pyramid/paster_templates/pylons_sqla/+package+/tests.py_tmpl b/pyramid/paster_templates/pylons_sqla/+package+/tests.py_tmpl
new file mode 100644
index 000000000..099df47bd
--- /dev/null
+++ b/pyramid/paster_templates/pylons_sqla/+package+/tests.py_tmpl
@@ -0,0 +1,26 @@
+import unittest
+
+class MyHandlerTests(unittest.TestCase):
+ def setUp(self):
+ from pyramid.configuration import Configurator
+ from {{package}}.models import initialize_sql
+ self.session = initialize_sql('sqlite://')
+ self.config = Configurator()
+ self.config.begin()
+
+ def tearDown(self):
+ self.config.end()
+
+ def _makeOne(self, request):
+ from {{package}}.handlers import MyHandler
+ return MyHandler(request)
+
+ def test_index(self):
+ request = DummyRequest()
+ handler = self._makeOne(request)
+ info = handler.index()
+ self.assertEqual(info['project'], '{{package}}')
+ self.assertEqual(info['root'].name, 'root')
+
+class DummyRequest(object):
+ pass
diff --git a/pyramid/paster_templates/pylons_sqla/CHANGES.txt_tmpl b/pyramid/paster_templates/pylons_sqla/CHANGES.txt_tmpl
new file mode 100644
index 000000000..35a34f332
--- /dev/null
+++ b/pyramid/paster_templates/pylons_sqla/CHANGES.txt_tmpl
@@ -0,0 +1,4 @@
+0.0
+---
+
+- Initial version
diff --git a/pyramid/paster_templates/pylons_sqla/README.txt_tmpl b/pyramid/paster_templates/pylons_sqla/README.txt_tmpl
new file mode 100644
index 000000000..0ddebfc3e
--- /dev/null
+++ b/pyramid/paster_templates/pylons_sqla/README.txt_tmpl
@@ -0,0 +1,4 @@
+{{project}} README
+
+
+
diff --git a/pyramid/paster_templates/pylons_sqla/development.ini_tmpl b/pyramid/paster_templates/pylons_sqla/development.ini_tmpl
new file mode 100644
index 000000000..f1f1e28f2
--- /dev/null
+++ b/pyramid/paster_templates/pylons_sqla/development.ini_tmpl
@@ -0,0 +1,32 @@
+[app:{{project}}]
+use = egg:{{project}}
+reload_templates = true
+mako.directories = {{package}}:templates
+debug_authorization = false
+debug_notfound = false
+debug_templates = true
+default_locale_name = en
+db_string = sqlite:///%(here)s/tutorial.db
+db_echo = true
+session.type = file
+session.data_dir = %(here)s/data/sessions/data
+session.lock_dir = %(here)s/data/sessions/lock
+session.key = {{project}}
+session.secret = your_app_secret_string
+cache.regions = default_term, second, short_term, long_term
+cache.type = memory
+cache.second.expire = 1
+cache.short_term.expire = 60
+cache.default_term.expire = 300
+cache.long_term.expire = 3600
+
+[pipeline:main]
+pipeline =
+ egg:WebError#evalerror
+ egg:repoze.tm2#tm
+ {{project}}
+
+[server:main]
+use = egg:Paste#http
+host = 0.0.0.0
+port = 5000
diff --git a/pyramid/paster_templates/pylons_sqla/setup.cfg_tmpl b/pyramid/paster_templates/pylons_sqla/setup.cfg_tmpl
new file mode 100644
index 000000000..5bec29823
--- /dev/null
+++ b/pyramid/paster_templates/pylons_sqla/setup.cfg_tmpl
@@ -0,0 +1,27 @@
+[nosetests]
+match=^test
+nocapture=1
+cover-package={{package}}
+with-coverage=1
+cover-erase=1
+
+[compile_catalog]
+directory = {{package}}/locale
+domain = {{project}}
+statistics = true
+
+[extract_messages]
+add_comments = TRANSLATORS:
+output_file = {{package}}/locale/{{project}}.pot
+width = 80
+
+[init_catalog]
+domain = {{project}}
+input_file = {{package}}/locale/{{project}}.pot
+output_dir = {{package}}/locale
+
+[update_catalog]
+domain = {{project}}
+input_file = {{package}}/locale/{{project}}.pot
+output_dir = {{package}}/locale
+previous = true
diff --git a/pyramid/paster_templates/pylons_sqla/setup.py_tmpl b/pyramid/paster_templates/pylons_sqla/setup.py_tmpl
new file mode 100644
index 000000000..38881367a
--- /dev/null
+++ b/pyramid/paster_templates/pylons_sqla/setup.py_tmpl
@@ -0,0 +1,48 @@
+import os
+import sys
+
+from setuptools import setup, find_packages
+
+here = os.path.abspath(os.path.dirname(__file__))
+README = open(os.path.join(here, 'README.txt')).read()
+CHANGES = open(os.path.join(here, 'CHANGES.txt')).read()
+
+requires = [
+ 'pyramid',
+ 'pyramid_beaker',
+ 'SQLAlchemy',
+ 'transaction',
+ 'repoze.tm2',
+ 'zope.sqlalchemy',
+ 'WebError',
+]
+
+if sys.version_info[:3] < (2,5,0):
+ requires.append('pysqlite')
+
+setup(name='{{project}}',
+ version='0.0',
+ description='{{project}}',
+ long_description=README + '\n\n' + CHANGES,
+ classifiers=[
+ "Programming Language :: Python",
+ "Framework :: Pylons",
+ "Topic :: Internet :: WWW/HTTP",
+ "Topic :: Internet :: WWW/HTTP :: WSGI :: Application",
+ ],
+ author='',
+ author_email='',
+ url='',
+ keywords='web pylons',
+ packages=find_packages(),
+ include_package_data=True,
+ zip_safe=False,
+ install_requires=requires,
+ tests_require=requires,
+ test_suite="{{package}}",
+ entry_points = """\
+ [paste.app_factory]
+ main = {{package}}:main
+ """
+ )
+
diff --git a/pyramid/personality/__init__.py b/pyramid/personality/__init__.py
new file mode 100644
index 000000000..5bb534f79
--- /dev/null
+++ b/pyramid/personality/__init__.py
@@ -0,0 +1 @@
+# package
diff --git a/pyramid/personality/pylons.py b/pyramid/personality/pylons.py
new file mode 100644
index 000000000..2e7984fd9
--- /dev/null
+++ b/pyramid/personality/pylons.py
@@ -0,0 +1,24 @@
+from pyramid.threadlocal import get_current_request
+from pyramid.url import route_url
+
+def renderer_globals_factory_config(helpers):
+ """ Return a Pylons renderer globals factory using ``helpers`` as
+ a helpers key."""
+ def renderer_globals_factory(system):
+ req = system['request']
+ if req is None:
+ req = get_current_request()
+ renderer_globals = {
+ 'url': route_url,
+ 'h': helpers,
+ 'request':req,
+ }
+ if req is not None:
+ tmpl_context = req.tmpl_context
+ renderer_globals['c'] = tmpl_context
+ renderer_globals['tmpl_context'] = tmpl_context
+ if 'session' in req.__dict__:
+ renderer_globals['session'] = req.session
+ return renderer_globals
+ return renderer_globals_factory
+
diff --git a/pyramid/request.py b/pyramid/request.py
index 7ffdb7495..76fff37a8 100644
--- a/pyramid/request.py
+++ b/pyramid/request.py
@@ -9,6 +9,9 @@ from pyramid.interfaces import ISessionFactory
from pyramid.exceptions import ConfigurationError
from pyramid.decorator import reify
+class TemplateContext(object):
+ pass
+
class Request(WebobRequest):
"""
A subclass of the :term:`WebOb` Request class. An instance of
@@ -36,6 +39,11 @@ class Request(WebobRequest):
finished_callbacks = ()
exception = None
+ @reify
+ def tmpl_context(self):
+ """ Template context (for Pylons apps) """
+ return TemplateContext()
+
def add_response_callback(self, callback):
"""
Add a callback to the set of callbacks to be called by the
diff --git a/pyramid/session.py b/pyramid/session.py
index 50f071398..158468152 100644
--- a/pyramid/session.py
+++ b/pyramid/session.py
@@ -30,14 +30,6 @@ def manage_accessed(wrapped):
accessed.__doc__ = wrapped.__doc__
return accessed
-def manage_modified(wrapped):
- accessed = manage_accessed(wrapped)
- def modified(session, *arg, **kw):
- session.modified = int(time.time())
- return accessed(session, *arg, **kw)
- modified.__doc__ = accessed.__doc__
- return modified
-
def InsecureCookieSessionFactoryConfig(
secret,
timeout=1200,
@@ -116,20 +108,19 @@ def InsecureCookieSessionFactoryConfig(
def __init__(self, request):
self.request = request
now = time.time()
- created = accessed = modified = now
+ created = accessed = now
new = True
cookieval = request.cookies.get(self._cookie_name)
value = deserialize(cookieval, self._secret)
state = {}
if value is not None:
- accessed, created, modified, state = value
+ accessed, created, state = value
new = False
if now - accessed > self._timeout:
state = {}
self.created = created
self.accessed = accessed
- self.modified = modified
self.new = new
dict.__init__(self, state)
@@ -157,13 +148,13 @@ def InsecureCookieSessionFactoryConfig(
__iter__ = manage_accessed(dict.__iter__)
# modifying dictionary methods
- clear = manage_modified(dict.clear)
- update = manage_modified(dict.update)
- setdefault = manage_modified(dict.setdefault)
- pop = manage_modified(dict.pop)
- popitem = manage_modified(dict.popitem)
- __setitem__ = manage_modified(dict.__setitem__)
- __delitem__ = manage_modified(dict.__delitem__)
+ clear = manage_accessed(dict.clear)
+ update = manage_accessed(dict.update)
+ setdefault = manage_accessed(dict.setdefault)
+ pop = manage_accessed(dict.pop)
+ popitem = manage_accessed(dict.popitem)
+ __setitem__ = manage_accessed(dict.__setitem__)
+ __delitem__ = manage_accessed(dict.__delitem__)
# non-API methods
def _set_cookie(self, response):
@@ -172,8 +163,7 @@ def InsecureCookieSessionFactoryConfig(
if exception is not None: # dont set a cookie during exceptions
return False
cookieval = serialize(
- (self.accessed, self.created, self.modified, dict(self)),
- self._secret
+ (self.accessed, self.created, dict(self)), self._secret
)
if len(cookieval) > 4064:
raise ValueError(
diff --git a/pyramid/testing.py b/pyramid/testing.py
index 5d54af9e9..188485635 100644
--- a/pyramid/testing.py
+++ b/pyramid/testing.py
@@ -55,7 +55,7 @@ def registerDummySecurityPolicy(userid=None, groupids=(), permissive=True):
.. warning:: This API is deprecated as of :mod:`pyramid` 1.0.
Instead use the
- :meth:`repoze.bfg.configuration.Configurator.testing_securitypolicy`
+ :meth:`pyramid.configuration.Configurator.testing_securitypolicy`
method in your unit and integration tests.
"""
registry = get_current_registry()
diff --git a/pyramid/tests/defpermbugapp/__init__.py b/pyramid/tests/defpermbugapp/__init__.py
index b56c1c71d..82a189b9e 100644
--- a/pyramid/tests/defpermbugapp/__init__.py
+++ b/pyramid/tests/defpermbugapp/__init__.py
@@ -1,14 +1,14 @@
from webob import Response
-from pyramid.view import bfg_view
+from pyramid.view import view_config
-@bfg_view(name='x')
+@view_config(name='x')
def x_view(request): # pragma: no cover
return Response('this is private!')
-@bfg_view(name='y', permission='private2')
+@view_config(name='y', permission='private2')
def y_view(request): # pragma: no cover
return Response('this is private too!')
-@bfg_view(name='z', permission='__no_permission_required__')
+@view_config(name='z', permission='__no_permission_required__')
def z_view(request):
return Response('this is public')
diff --git a/pyramid/tests/grokkedapp/__init__.py b/pyramid/tests/grokkedapp/__init__.py
index 547987d8b..1411e4c49 100644
--- a/pyramid/tests/grokkedapp/__init__.py
+++ b/pyramid/tests/grokkedapp/__init__.py
@@ -1,15 +1,15 @@
-from pyramid.view import bfg_view
+from pyramid.view import view_config
-@bfg_view()
+@view_config()
def grokked(context, request):
return 'grokked'
-@bfg_view(request_method='POST')
+@view_config(request_method='POST')
def grokked_post(context, request):
return 'grokked_post'
-@bfg_view(name='stacked2')
-@bfg_view(name='stacked1')
+@view_config(name='stacked2')
+@view_config(name='stacked1')
def stacked(context, request):
return 'stacked'
@@ -21,8 +21,8 @@ class stacked_class(object):
def __call__(self):
return 'stacked_class'
-stacked_class = bfg_view(name='stacked_class1')(stacked_class)
-stacked_class = bfg_view(name='stacked_class2')(stacked_class)
+stacked_class = view_config(name='stacked_class1')(stacked_class)
+stacked_class = view_config(name='stacked_class2')(stacked_class)
class oldstyle_grokked_class:
def __init__(self, context, request):
@@ -32,7 +32,7 @@ class oldstyle_grokked_class:
def __call__(self):
return 'oldstyle_grokked_class'
-oldstyle_grokked_class = bfg_view(name='oldstyle_grokked_class')(
+oldstyle_grokked_class = view_config(name='oldstyle_grokked_class')(
oldstyle_grokked_class)
class grokked_class(object):
@@ -43,17 +43,17 @@ class grokked_class(object):
def __call__(self):
return 'grokked_class'
-grokked_class = bfg_view(name='grokked_class')(grokked_class)
+grokked_class = view_config(name='grokked_class')(grokked_class)
class Foo(object):
def __call__(self, context, request):
return 'grokked_instance'
grokked_instance = Foo()
-grokked_instance = bfg_view(name='grokked_instance')(grokked_instance)
+grokked_instance = view_config(name='grokked_instance')(grokked_instance)
class Base(object):
- @bfg_view(name='basemethod')
+ @view_config(name='basemethod')
def basemethod(self):
""" """
@@ -62,16 +62,16 @@ class MethodViews(Base):
self.context = context
self.request = request
- @bfg_view(name='method1')
+ @view_config(name='method1')
def method1(self):
return 'method1'
- @bfg_view(name='method2')
+ @view_config(name='method2')
def method2(self):
return 'method2'
- @bfg_view(name='stacked_method2')
- @bfg_view(name='stacked_method1')
+ @view_config(name='stacked_method2')
+ @view_config(name='stacked_method1')
def stacked(self):
return 'stacked_method'
diff --git a/pyramid/tests/grokkedapp/another.py b/pyramid/tests/grokkedapp/another.py
index 872eaf103..48fe81798 100644
--- a/pyramid/tests/grokkedapp/another.py
+++ b/pyramid/tests/grokkedapp/another.py
@@ -1,15 +1,15 @@
-from pyramid.view import bfg_view
+from pyramid.view import view_config
-@bfg_view(name='another')
+@view_config(name='another')
def grokked(context, request):
return 'another_grokked'
-@bfg_view(request_method='POST', name='another')
+@view_config(request_method='POST', name='another')
def grokked_post(context, request):
return 'another_grokked_post'
-@bfg_view(name='another_stacked2')
-@bfg_view(name='another_stacked1')
+@view_config(name='another_stacked2')
+@view_config(name='another_stacked1')
def stacked(context, request):
return 'another_stacked'
@@ -21,8 +21,8 @@ class stacked_class(object):
def __call__(self):
return 'another_stacked_class'
-stacked_class = bfg_view(name='another_stacked_class1')(stacked_class)
-stacked_class = bfg_view(name='another_stacked_class2')(stacked_class)
+stacked_class = view_config(name='another_stacked_class1')(stacked_class)
+stacked_class = view_config(name='another_stacked_class2')(stacked_class)
class oldstyle_grokked_class:
def __init__(self, context, request):
@@ -32,7 +32,7 @@ class oldstyle_grokked_class:
def __call__(self):
return 'another_oldstyle_grokked_class'
-oldstyle_grokked_class = bfg_view(name='another_oldstyle_grokked_class')(
+oldstyle_grokked_class = view_config(name='another_oldstyle_grokked_class')(
oldstyle_grokked_class)
class grokked_class(object):
@@ -43,14 +43,15 @@ class grokked_class(object):
def __call__(self):
return 'another_grokked_class'
-grokked_class = bfg_view(name='another_grokked_class')(grokked_class)
+grokked_class = view_config(name='another_grokked_class')(grokked_class)
class Foo(object):
def __call__(self, context, request):
return 'another_grokked_instance'
grokked_instance = Foo()
-grokked_instance = bfg_view(name='another_grokked_instance')(grokked_instance)
+grokked_instance = view_config(name='another_grokked_instance')(
+ grokked_instance)
# ungrokkable
diff --git a/pyramid/tests/grokkedapp/pod/notinit.py b/pyramid/tests/grokkedapp/pod/notinit.py
index 9c033eaef..3d01f92d5 100644
--- a/pyramid/tests/grokkedapp/pod/notinit.py
+++ b/pyramid/tests/grokkedapp/pod/notinit.py
@@ -1,5 +1,5 @@
-from pyramid.view import bfg_view
+from pyramid.view import view_config
-@bfg_view(name='pod_notinit')
+@view_config(name='pod_notinit')
def subpackage_notinit(context, request):
return 'pod_notinit'
diff --git a/pyramid/tests/grokkedapp/subpackage/__init__.py b/pyramid/tests/grokkedapp/subpackage/__init__.py
index 7f93f0f16..3e332913a 100644
--- a/pyramid/tests/grokkedapp/subpackage/__init__.py
+++ b/pyramid/tests/grokkedapp/subpackage/__init__.py
@@ -1,5 +1,5 @@
-from pyramid.view import bfg_view
+from pyramid.view import view_config
-@bfg_view(name='subpackage_init')
+@view_config(name='subpackage_init')
def subpackage_init(context, request):
return 'subpackage_init'
diff --git a/pyramid/tests/grokkedapp/subpackage/notinit.py b/pyramid/tests/grokkedapp/subpackage/notinit.py
index 3f26180b3..41f0c5ea8 100644
--- a/pyramid/tests/grokkedapp/subpackage/notinit.py
+++ b/pyramid/tests/grokkedapp/subpackage/notinit.py
@@ -1,5 +1,5 @@
-from pyramid.view import bfg_view
+from pyramid.view import view_config
-@bfg_view(name='subpackage_notinit')
+@view_config(name='subpackage_notinit')
def subpackage_notinit(context, request):
return 'subpackage_notinit'
diff --git a/pyramid/tests/grokkedapp/subpackage/subsubpackage/__init__.py b/pyramid/tests/grokkedapp/subpackage/subsubpackage/__init__.py
index d380226ab..ade9644ec 100644
--- a/pyramid/tests/grokkedapp/subpackage/subsubpackage/__init__.py
+++ b/pyramid/tests/grokkedapp/subpackage/subsubpackage/__init__.py
@@ -1,5 +1,5 @@
-from pyramid.view import bfg_view
+from pyramid.view import view_config
-@bfg_view(name='subsubpackage_init')
+@view_config(name='subsubpackage_init')
def subpackage_init(context, request):
return 'subsubpackage_init'
diff --git a/pyramid/tests/test_docs.py b/pyramid/tests/test_docs.py
index a00171842..bf06c7ca6 100644
--- a/pyramid/tests/test_docs.py
+++ b/pyramid/tests/test_docs.py
@@ -20,7 +20,7 @@ if 0:
m += manuel.capture.Manuel()
docs = []
- egg_path = pkg_resources.get_distribution('repoze.bfg').location
+ egg_path = pkg_resources.get_distribution('pyramid').location
path = os.path.join(egg_path, 'docs')
for root, dirs, files in os.walk(path):
for ignore in ('.svn', '.build', '.hg', '.git', 'CVS'):
diff --git a/pyramid/tests/test_integration.py b/pyramid/tests/test_integration.py
index fffd8c03e..872f50cd4 100644
--- a/pyramid/tests/test_integration.py
+++ b/pyramid/tests/test_integration.py
@@ -2,7 +2,7 @@ import os
import unittest
from pyramid.wsgi import wsgiapp
-from pyramid.view import bfg_view
+from pyramid.view import view_config
from pyramid.view import static
from zope.interface import Interface
@@ -12,7 +12,7 @@ from pyramid import testing
class INothing(Interface):
pass
-@bfg_view(for_=INothing)
+@view_config(for_=INothing)
@wsgiapp
def wsgiapptest(environ, start_response):
""" """
diff --git a/pyramid/tests/test_pylons_personality.py b/pyramid/tests/test_pylons_personality.py
new file mode 100644
index 000000000..570fcba5b
--- /dev/null
+++ b/pyramid/tests/test_pylons_personality.py
@@ -0,0 +1,54 @@
+import unittest
+
+
+class Test_pylons_renderer_globals_factory_config(unittest.TestCase):
+ def setUp(self):
+ from pyramid.configuration import Configurator
+ self.config = Configurator()
+ request = DummyRequest()
+ self.config.begin(request)
+
+ def tearDown(self):
+ self.config.end()
+
+ def _makeOne(self, helpers):
+ from pyramid.personality import pylons
+ return pylons.renderer_globals_factory_config(helpers)
+
+ def test_with_request(self):
+ request = DummyRequest()
+ from pyramid.url import route_url
+ system = {'request':request}
+ factory = self._makeOne('helpers')
+ result = factory(system)
+ self.assertEqual(result['url'], route_url)
+ self.assertEqual(result['h'], 'helpers')
+ self.assertEqual(result['c'], request.tmpl_context)
+ self.assertEqual(result['tmpl_context'], request.tmpl_context)
+
+ def test_without_request(self):
+ from pyramid.url import route_url
+ from pyramid.threadlocal import get_current_request
+ system = {'request':None}
+ factory = self._makeOne('helpers')
+ result = factory(system)
+ self.assertEqual(result['url'], route_url)
+ self.assertEqual(result['h'], 'helpers')
+ request = get_current_request()
+ self.assertEqual(result['c'], request.tmpl_context)
+ self.assertEqual(result['tmpl_context'], request.tmpl_context)
+ self.assertEqual(result['request'], request)
+
+ def test_with_session(self):
+ request = DummyRequest()
+ request.session = 'session'
+ system = {'request':request}
+ factory = self._makeOne('helpers')
+ result = factory(system)
+ self.assertEqual(result['session'], 'session')
+
+class DummyRequest(object):
+ def __init__(self):
+ self.tmpl_context = object()
+
+
diff --git a/pyramid/tests/test_request.py b/pyramid/tests/test_request.py
index 93cbb9691..775c41731 100644
--- a/pyramid/tests/test_request.py
+++ b/pyramid/tests/test_request.py
@@ -43,6 +43,12 @@ class TestRequest(unittest.TestCase):
inst = self._makeOne({})
self.assertTrue(IRequest.providedBy(inst))
+ def test_tmpl_context(self):
+ from pyramid.request import TemplateContext
+ inst = self._makeOne({})
+ result = inst.tmpl_context
+ self.assertEqual(result.__class__, TemplateContext)
+
def test_session_configured(self):
from pyramid.interfaces import ISessionFactory
inst = self._makeOne({})
diff --git a/pyramid/tests/test_session.py b/pyramid/tests/test_session.py
index d8c1b2c00..12f70bab9 100644
--- a/pyramid/tests/test_session.py
+++ b/pyramid/tests/test_session.py
@@ -13,7 +13,7 @@ class TestInsecureCookieSession(unittest.TestCase):
def _serialize(self, accessed, state, secret='secret'):
from pyramid.session import serialize
- return serialize((accessed, accessed, accessed, state), secret)
+ return serialize((accessed, accessed, state), secret)
def test_ctor_with_cookie_still_valid(self):
import time
@@ -155,21 +155,6 @@ class Test_manage_accessed(unittest.TestCase):
self.assertEqual(result, None)
self.assertEqual(session.response, response)
-class Test_manage_modified(Test_manage_accessed):
- def _makeOne(self, wrapped):
- from pyramid.session import manage_modified
- return manage_modified(wrapped)
-
- def test_modified_set(self):
- request = testing.DummyRequest()
- session = DummySessionFactory(request)
- session.modified = None
- session.accessed = None
- wrapper = self._makeOne(session.__class__.__setitem__)
- wrapper(session, 'a', 1)
- self.assertNotEqual(session.accessed, None)
- self.assertNotEqual(session.modified, None)
-
def serialize(data, secret):
try:
from hashlib import sha1
diff --git a/pyramid/tests/test_view.py b/pyramid/tests/test_view.py
index 62d09358b..fc725379e 100644
--- a/pyramid/tests/test_view.py
+++ b/pyramid/tests/test_view.py
@@ -206,7 +206,7 @@ class TestIsResponse(unittest.TestCase):
response.status = None
self.assertEqual(self._callFUT(response), False)
-class TestBFGViewDecorator(unittest.TestCase):
+class TestViewConfigDecorator(unittest.TestCase):
def setUp(self):
cleanUp()
@@ -214,8 +214,8 @@ class TestBFGViewDecorator(unittest.TestCase):
cleanUp()
def _getTargetClass(self):
- from pyramid.view import bfg_view
- return bfg_view
+ from pyramid.view import view_config
+ return view_config
def _makeOne(self, *arg, **kw):
return self._getTargetClass()(*arg, **kw)
diff --git a/pyramid/tests/viewdecoratorapp/views/views.py b/pyramid/tests/viewdecoratorapp/views/views.py
index 15b3e63c3..c59bc87ed 100644
--- a/pyramid/tests/viewdecoratorapp/views/views.py
+++ b/pyramid/tests/viewdecoratorapp/views/views.py
@@ -1,17 +1,17 @@
import os
-from pyramid.view import bfg_view
+from pyramid.view import view_config
-@bfg_view(renderer='templates/foo.pt', name='first')
+@view_config(renderer='templates/foo.pt', name='first')
def first(request):
return {'result':'OK1'}
-@bfg_view(renderer='pyramid.tests.viewdecoratorapp.views:templates/foo.pt',
- name='second')
+@view_config(renderer='pyramid.tests.viewdecoratorapp.views:templates/foo.pt',
+ name='second')
def second(request):
return {'result':'OK2'}
here = os.path.normpath(os.path.dirname(os.path.abspath(__file__)))
foo = os.path.join(here, 'templates', 'foo.pt')
-@bfg_view(renderer=foo, name='third')
+@view_config(renderer=foo, name='third')
def third(request):
return {'result':'OK3'}
diff --git a/pyramid/view.py b/pyramid/view.py
index bcd4cd0b7..bd9d52a24 100644
--- a/pyramid/view.py
+++ b/pyramid/view.py
@@ -143,7 +143,7 @@ def is_response(ob):
return True
return False
-class bfg_view(object):
+class view_config(object):
""" A function, class or method :term:`decorator` which allows a
developer to create view registrations nearer to a :term:`view
callable` definition than use of :term:`ZCML` or :term:`imperative
@@ -153,8 +153,8 @@ class bfg_view(object):
from models import MyModel
- @bfg_view(name='my_view', context=MyModel, permission='read',
- route_name='site1')
+ @view_config(name='my_view', context=MyModel, permission='read',
+ route_name='site1')
def my_view(context, request):
return 'OK'
@@ -176,9 +176,13 @@ class bfg_view(object):
route_name='site1'
/>
+ .. note: :class:`pyramid.view.view_config` is also importable, for
+ backwards compatibility purposes, as the name
+ :class:`pyramid.view.bfg_view`.
+
The following arguments are supported as arguments to
- ``bfg_view``: ``context``, ``permission``, ``name``,
- ``request_type``, ``route_name``, ``request_method``,
+ :class:`pyramid.view.view_config``: ``context``, ``permission``,
+ ``name``, ``request_type``, ``route_name``, ``request_method``,
``request_param``, ``containment``, ``xhr``, ``accept``,
``header`` and ``path_info``.
@@ -274,9 +278,9 @@ class bfg_view(object):
predicates return ``True``.
Any individual or all parameters can be omitted. The simplest
- ``bfg_view`` declaration is::
+ :class:`pyramid.view.view_config` declaration is::
- @bfg_view()
+ @view_config()
def my_view(...):
...
@@ -286,14 +290,14 @@ class bfg_view(object):
requests, with any ``REQUEST_METHOD``, any set of request.params
values, without respect to any object in the :term:`lineage`.
- The ``bfg_view`` decorator can also be used as a class decorator
+ The ``view_config`` decorator can also be used as a class decorator
in Python 2.6 and better (Python 2.5 and below do not support
class decorators)::
from webob import Response
- from pyramid.view import bfg_view
+ from pyramid.view import view_config
- @bfg_view()
+ @view_config()
class MyView(object):
def __init__(self, context, request):
self.context = context
@@ -301,11 +305,11 @@ class bfg_view(object):
def __call__(self):
return Response('hello from %s!' % self.context)
- In Python 2.5 and below, the ``bfg_view`` decorator can still be
+ In Python 2.5 and below, the ``view_config`` decorator can still be
used against a class, although not in decorator form::
from webob import Response
- from pyramid.view import bfg_view
+ from pyramid.view import view_config
class MyView(object):
def __init__(self, context, request):
@@ -314,7 +318,7 @@ class bfg_view(object):
def __call__(self):
return Response('hello from %s!' % self.context)
- MyView = bfg_view()(MyView)
+ MyView = view_config()(MyView)
.. note:: When a view is a class, the calling semantics are
different than when it is a function or another
@@ -323,22 +327,23 @@ class bfg_view(object):
.. warning:: Using a class as a view is a new feature in 0.8.1+.
- The bfg_view decorator can also be used against a class method::
+ The ``view_config`` decorator can also be used against a class
+ method::
from webob import Response
- from pyramid.view import bfg_view
+ from pyramid.view import view_config
class MyView(object):
def __init__(self, context, request):
self.context = context
self.request = request
- @bfg_view(name='hello')
+ @view_config(name='hello')
def amethod(self):
return Response('hello from %s!' % self.context)
- When the ``bfg_view`` decorator is used against a class method, a
- view is registered for the *class* (as described above), so the
+ When the ``view_config`` decorator is used against a class method,
+ a view is registered for the *class* (as described above), so the
class constructor must accept either ``request`` or ``context,
request``. The method which is decorated must return a response
(or rely on a :term:`renderer` to generate one). Using the
@@ -349,9 +354,9 @@ class bfg_view(object):
spelled equivalently as::
from webob import Response
- from pyramid.view import bfg_view
+ from pyramid.view import view_config
- @bfg_view(attr='amethod', name='hello')
+ @view_config(attr='amethod', name='hello')
class MyView(object):
def __init__(self, context, request):
self.context = context
@@ -360,11 +365,7 @@ class bfg_view(object):
def amethod(self):
return Response('hello from %s!' % self.context)
- .. warning:: The ability to use the ``bfg_view`` decorator as a
- method decorator is new in :mod:`pyramid` version
- 1.1.
-
- To make use of any ``bfg_view`` declaration, you must perform a
+ To make use of any ``view_config`` declaration, you must perform a
:term:`scan`. To do so, either insert the following boilerplate
into your application registry's ZCML::
@@ -431,6 +432,8 @@ class bfg_view(object):
return wrapped
+bfg_view = view_config # permanent b/c
+
def default_exceptionresponse_view(context, request):
if not isinstance(context, Exception):
# backwards compat for an exception response view registered via
diff --git a/setup.py b/setup.py
index 44fc10058..d7c549c03 100644
--- a/setup.py
+++ b/setup.py
@@ -82,6 +82,9 @@ setup(name='pyramid',
pyramid_zodb=pyramid.paster:ZODBProjectTemplate
pyramid_routesalchemy=pyramid.paster:RoutesAlchemyProjectTemplate
pyramid_alchemy=pyramid.paster:AlchemyProjectTemplate
+ pylons_basic=pyramid.paster:PylonsBasicProjectTemplate
+ pylons_minimal=pyramid.paster:PylonsMinimalProjectTemplate
+ pylons_sqla=pyramid.paster:PylonsSQLAlchemyProjectTemplate
[paste.paster_command]
pyramid_shell=pyramid.paster:BFGShellCommand
[console_scripts]