More small fixes made reading the rest of the docs and the tutorials.
| | |
| | | for action in resolveConflicts(self.actions): |
| | | File "zope/configuration/config.py", line 1507, in resolveConflicts |
| | | raise ConfigurationConflictError(conflicts) |
| | | zope.configuration.config.ConfigurationConflictError: |
| | | zope.configuration.config.ConfigurationConflictError: |
| | | Conflicting configuration actions |
| | | For: ('view', None, '', None, <InterfaceClass pyramid.interfaces.IView>, |
| | | For: ('view', None, '', None, <InterfaceClass pyramid.interfaces.IView>, |
| | | None, None, None, None, None, False, None, None, None) |
| | | ('app.py', 14, '<module>', 'config.add_view(hello_world)') |
| | | ('app.py', 17, '<module>', 'config.add_view(hello_world)') |
| | |
| | | :meth:`~pyramid.config.Configurator.add_route`, |
| | | :meth:`~pyramid.config.Configurator.add_renderer`, |
| | | :meth:`~pyramid.config.Configurator.set_request_factory`, |
| | | :meth:`~pyramid.config.Configurator.set_renderer_globals_factory` |
| | | :meth:`~pyramid.config.Configurator.set_renderer_globals_factory`, |
| | | :meth:`~pyramid.config.Configurator.set_locale_negotiator` and |
| | | :meth:`~pyramid.config.Configurator.set_default_permission`. |
| | | |
| | |
| | | |
| | | if __name__ == '__main__': |
| | | config = Configurator() |
| | | config.add_directive('add_newrequest_subscriber', |
| | | config.add_directive('add_newrequest_subscriber', |
| | | add_newrequest_subscriber) |
| | | |
| | | Once :meth:`~pyramid.config.Configurator.add_directive` is called, a user can |
| | |
| | | :linenos: |
| | | |
| | | def includeme(config) |
| | | config.add_directive('add_newrequest_subscriber', |
| | | config.add_directive('add_newrequest_subscriber', |
| | | add_newrequest_subscriber) |
| | | |
| | | The user of the add-on package ``pyramid_subscriberhelpers`` would then be |
| | |
| | | single: environment variables |
| | | single: ini file settings |
| | | single: PasteDeploy settings |
| | | |
| | | |
| | | .. _environment_chapter: |
| | | |
| | | Environment Variables and ``.ini`` File Settings |
| | |
| | | | ``PYRAMID_DEBUG_AUTHORIZATION`` | ``debug_authorization`` | |
| | | | | | |
| | | | | | |
| | | | | | |
| | | | | | |
| | | +---------------------------------+-----------------------------+ |
| | | |
| | | Debugging Not Found Errors |
| | |
| | | Mako Import |
| | | +++++++++++ |
| | | |
| | | String list of Python statements, typically individual “import” lines, which |
| | | String list of Python statements, typically individual "import" lines, which |
| | | will be placed into the module level preamble of all generated Python modules. |
| | | |
| | | |
| | |
| | | ``reload_templates``. |
| | | |
| | | If you want to turn all ``reload`` settings (every setting that starts |
| | | with ``reload_``). on in one fell swoop, you can use |
| | | with ``reload_``) on in one fell swoop, you can use |
| | | ``PYRAMID_RELOAD_ALL=1`` as an environment variable setting or you may use |
| | | ``reload_all=true`` in the config file. Note that this does not |
| | | affect settings that do not start with ``reload_*`` such as |
| | |
| | | most useful during development, where you may wish to augment or |
| | | override the more permanent settings in the configuration file. |
| | | This is useful because many of the reload and debug settings may |
| | | have performance or security (i.e., disclosure) implications |
| | | have performance or security (i.e., disclosure) implications |
| | | that make them undesirable in a production environment. |
| | | |
| | | .. index:: |
| | | .. index:: |
| | | single: reload_templates |
| | | single: reload_assets |
| | | |
| | |
| | | registry = pyramid.threadlocal.get_current_registry() |
| | | settings = registry.settings |
| | | debug_frobnosticator = settings['debug_frobnosticator'] |
| | | |
| | | |
| | | |
| | | |
| | | |
| | | |
| | |
| | | method. Assets are files that are |
| | | accessed by :app:`Pyramid` using the :term:`pkg_resources` API such as static |
| | | files and templates via a :term:`asset specification`. Other directives and |
| | | configurator methods also deal in routes, views, and assets. For example, |
| | | configurator methods also deal in routes, views, and assets. For example, the |
| | | ``add_handler`` directive of the ``pyramid_handlers`` package adds a single |
| | | route, and some number of views. |
| | | |
| | |
| | | if __name__ == '__main__': |
| | | config.scan('someotherpackage') |
| | | config.commit() |
| | | config.add_view('mypackage.views.myview', name='myview' |
| | | config.add_view('mypackage.views.myview', name='myview') |
| | | |
| | | Once this is done, you should be able to extend or override the application |
| | | like any other (see :ref:`extending_the_application`). |
| | |
| | | application (e.g. ``python setup.py develop`` or ``python setup.py |
| | | install``). |
| | | |
| | | - Change the ``main`` function in the new package's ``__init__py`` to include |
| | | - Change the ``main`` function in the new package's ``__init__.py`` to include |
| | | the original :app:`Pyramid` application's configuration functions via |
| | | :meth:`pyramid.config.Configurator.include` statements or a :term:`scan`. |
| | | |
| | |
| | | the view which generates it can be overridden as necessary. |
| | | |
| | | The :term:`forbidden view` callable is a view callable like any other. The |
| | | :term:`view configuration` which causes it to be a "not found" view consists |
| | | :term:`view configuration` which causes it to be a "forbidden" view consists |
| | | only of naming the :exc:`pyramid.exceptions.Forbidden` class as the |
| | | ``context`` of the view configuration. |
| | | |
| | |
| | | ----------------------- |
| | | |
| | | Whenever :app:`Pyramid` handles a request to perform a rendering (after a |
| | | view with a ``renderer=`` configuration attribute is invoked, or when the any |
| | | view with a ``renderer=`` configuration attribute is invoked, or when any |
| | | of the methods beginning with ``render`` within the :mod:`pyramid.renderers` |
| | | module are called), *renderer globals* can be injected into the *system* |
| | | values sent to the renderer. By default, no renderer globals are injected, |
| | |
| | | :linenos: |
| | | |
| | | def renderer_globals_factory(system): |
| | | return {'a':1} |
| | | return {'a': 1} |
| | | |
| | | config = Configurator( |
| | | renderer_globals_factory=renderer_globals_factory) |
| | |
| | | from pyramid.config import Configurator |
| | | |
| | | def renderer_globals_factory(system): |
| | | return {'a':1} |
| | | return {'a': 1} |
| | | |
| | | config = Configurator() |
| | | config.set_renderer_globals_factory(renderer_globals_factory) |
| | |
| | | ----------------------------- |
| | | |
| | | Subscribers to the :class:`pyramid.events.BeforeRender` event may introspect |
| | | the and modify the set of :term:`renderer globals` before they are passed to |
| | | a :term:`renderer`. This event object iself has a dictionary-like interface |
| | | and modify the set of :term:`renderer globals` before they are passed to a |
| | | :term:`renderer`. This event object iself has a dictionary-like interface |
| | | that can be used for this purpose. For example: |
| | | |
| | | .. code-block:: python |
| | |
| | | from myapp.traversal import URLGenerator |
| | | from myapp.resources import MyRoot |
| | | |
| | | config.registry.registerAdapter(URLGenerator, (MyRoot, Interface), |
| | | config.registry.registerAdapter(URLGenerator, (MyRoot, Interface), |
| | | IContextURL) |
| | | |
| | | In the above example, the ``myapp.traversal.URLGenerator`` class will be used |
| | |
| | | |
| | | The default calling conventions for view callables are documented in the |
| | | :ref:`views_chapter` chapter. You can change the way users define view |
| | | callbles by employing a :term:`view mapper`. |
| | | callables by employing a :term:`view mapper`. |
| | | |
| | | A view mapper is an object that accepts a set of keyword arguments and which |
| | | returns a callable. The returned callable is called with the :term:`view |
| | |
| | | :linenos: |
| | | |
| | | import venusian |
| | | from pyramid.threadlocal import get_current_registry |
| | | from mypackage.interfaces import IMyUtility |
| | | |
| | | |
| | | class registerFunction(object): |
| | | |
| | | |
| | | def __init__(self, path): |
| | | self.path = path |
| | | |
| | | def register(self, scanner, name, wrapped): |
| | | registry = scanner.config.registry |
| | | registry.getUtility(IMyUtility).register( |
| | | self.path, wrapped |
| | | ) |
| | | |
| | | self.path, wrapped) |
| | | |
| | | def __call__(self, wrapped): |
| | | venusian.attach(wrapped, self.register) |
| | | return wrapped |
| | | |
| | | |
| | | This decorator could then be used to register functions throughout |
| | | your code: |
| | | |
| | |
| | | |
| | | from paste.httpserver import serve |
| | | from pyramid.config import Configurator |
| | | from mypackage.interfaces import IMyUtility |
| | | |
| | | class UtilityImplementation: |
| | | |
| | | implements(ISomething) |
| | | implements(IMyUtility) |
| | | |
| | | def __init__(self): |
| | | self.registrations = {} |
| | | |
| | | def register(self,path,callable_): |
| | | self.registrations[path]=callable_ |
| | | def register(self, path, callable_): |
| | | self.registrations[path] = callable_ |
| | | |
| | | if __name__ == '__main__': |
| | | config = Configurator() |
| | |
| | | :linenos: |
| | | |
| | | from pyramid.i18n import TranslationString |
| | | ts = TranslationString('Add ${number}', mapping={'number':1}, |
| | | ts = TranslationString('Add ${number}', mapping={'number':1}, |
| | | domain='form') |
| | | |
| | | The above translation string named a domain of ``form``. A |
| | |
| | | :linenos: |
| | | |
| | | from pyramid.i18n import TranslationString as _ |
| | | ts = _('Add ${number}', msgid='add-number', mapping={'number':1}, |
| | | ts = _('Add ${number}', msgid='add-number', mapping={'number':1}, |
| | | domain='pyramid') |
| | | |
| | | You can set up your own translation string factory much like the one |
| | |
| | | |
| | | A ``.pot`` file is created by a program which searches through your |
| | | project's source code and which picks out every :term:`message |
| | | identifier` passed to one of the '``_()`` functions |
| | | identifier` passed to one of the ``_()`` functions |
| | | (eg. :term:`translation string` constructions). The list of all |
| | | message identifiers is placed into a ``.pot`` file, which serves as |
| | | a template for creating ``.po`` files. |
| | |
| | | .. code-block:: text |
| | | |
| | | C> cd \my\virtualenv |
| | | C> bin\easy_install Babel lingua |
| | | C> Scripts\easy_install Babel lingua |
| | | |
| | | .. index:: |
| | | single: Babel; message extractors |
| | |
| | | from pyramid.i18n import get_localizer |
| | | from pyramid.i18n import TranslationString |
| | | |
| | | ts = TranslationString('Add ${number}', mapping={'number':1}, |
| | | ts = TranslationString('Add ${number}', mapping={'number':1}, |
| | | domain='pyramid') |
| | | |
| | | def aview(request): |
| | |
| | | |
| | | .. code-block:: python |
| | | :linenos: |
| | | |
| | | |
| | | from pyramid.threadlocal import get_current_registry |
| | | settings = get_current_registry().settings |
| | | languages = settings['available_languages'].split() |
| | |
| | | :linenos: |
| | | |
| | | from pyramid.config import Configurator |
| | | config.add_translation_dirs('my.application:locale/', |
| | | config.add_translation_dirs('my.application:locale/', |
| | | 'another.application:locale/') |
| | | |
| | | A message catalog in a translation directory added via |
| | |
| | | While the ZCA is an excellent tool with which to build a *framework* |
| | | such as :app:`Pyramid`, it is not always the best tool with which |
| | | to build an *application* due to the opacity of the ``zope.component`` |
| | | APIs. Accordingly, :app:`Pyramid` tends to hide the the presence |
| | | of the ZCA from application developers. You needn't understand the |
| | | ZCA to create a :app:`Pyramid` application; its use is effectively |
| | | only a framework implementation detail. |
| | | APIs. Accordingly, :app:`Pyramid` tends to hide the presence of the |
| | | ZCA from application developers. You needn't understand the ZCA to |
| | | create a :app:`Pyramid` application; its use is effectively only a |
| | | framework implementation detail. |
| | | |
| | | However, developers who are already used to writing :term:`Zope` |
| | | applications often still wish to use the ZCA while building a |
| | |
| | | ~~~~~~~~~~~~~~~~~~~~~~ |
| | | |
| | | Add a ``security.py`` module within your package (in the same |
| | | directory as ``__init__.py``, ``views.py``, etc) with the following |
| | | directory as ``__init__.py``, ``views.py``, etc.) with the following |
| | | content: |
| | | |
| | | .. literalinclude:: src/authorization/tutorial/security.py |
| | |
| | | logged_in = authenticated_userid(request) |
| | | |
| | | We'll then change the return value of each view that has an associated |
| | | ``renderer`` to pass the `resulting `logged_in`` value to the |
| | | ``renderer`` to pass the resulting ``logged_in`` value to the |
| | | template. For example: |
| | | |
| | | .. ignore-next-block |
| | |
| | | credentials with the username ``editor``, password ``editor`` will |
| | | show the edit page form being displayed. |
| | | |
| | | - After logging in (as a result of hitting an edit or add page and |
| | | - After logging in (as a result of hitting an edit or add page and |
| | | submitting the login form with the ``editor`` credentials), we'll see |
| | | a Logout link in the upper right hand corner. When we click it, |
| | | we're logged out, and redirected back to the front page. |
| | |
| | | the request as a single argument, you can obtain it via |
| | | ``request.context``. |
| | | |
| | | We're going to define several :term:`view callable` functions then wire them |
| | | We're going to define several :term:`view callable` functions, then wire them |
| | | into :app:`Pyramid` using some :term:`view configuration`. |
| | | |
| | | The source code for this tutorial stage can be browsed via |
| | |
| | | |
| | | If the view execution is *not* a result of a form submission (if the |
| | | expression ``'form.submitted' in request.params`` is ``False``), the view |
| | | simply renders the edit form, passing the request, the page resource, and a |
| | | save_url which will be used as the action of the generated form. |
| | | simply renders the edit form, passing the page resource, and a ``save_url`` |
| | | which will be used as the action of the generated form. |
| | | |
| | | If the view execution *is* a result of a form submission (if the expression |
| | | ``'form.submitted' in request.params`` is ``True``), the view grabs the |
| | |
| | | |
| | | For cut and paste purposes, the source code for all stages of this |
| | | tutorial can be browsed at |
| | | `http://github.com/Pylons/pyramid/tree/master/docs/tutorials/wiki |
| | | <http://github.com/Pylons/pyramid/tree/master/docs/tutorials/wiki>`_. |
| | | `http://github.com/Pylons/pyramid/tree/master/docs/tutorials/wiki/src/ |
| | | <http://github.com/Pylons/pyramid/tree/master/docs/tutorials/wiki/src/>`_. |
| | | |
| | | .. toctree:: |
| | | :maxdepth: 2 |
| | |
| | | |
| | | .. code-block:: text |
| | | |
| | | c:\pyramidtut> Scripts\easy_install docutils repoze.tm2 \ |
| | | c:\pyramidtut> Scripts\easy_install docutils repoze.tm2 ^ |
| | | repoze.zodbconn nose coverage |
| | | |
| | | .. _making_a_project: |
| | |
| | | |
| | | .. code-block:: text |
| | | |
| | | c:\pyramidtut\tutorial> ..\Scripts\nosetests --cover-package=tutorial \ |
| | | c:\pyramidtut\tutorial> ..\Scripts\nosetests --cover-package=tutorial ^ |
| | | --cover-erase --with-coverage |
| | | |
| | | Looks like the code in the ``pyramid_zodb`` scaffold for ZODB projects is |
| | |
| | | :meth:`pyramid.config.Configurator.add_route` for more info. |
| | | |
| | | We'll pass the ``RootFactory`` we created in the step above in as the |
| | | ``root_factory`` argument to a :term:`Configurator`. |
| | | ``root_factory`` argument to a :term:`Configurator`. |
| | | |
| | | Configuring an Authorization Policy |
| | | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ |
| | |
| | | :term:`view callable`. This is also known as a :term:`forbidden view`: |
| | | |
| | | .. literalinclude:: src/authorization/tutorial/__init__.py |
| | | :lines: 41-43 |
| | | :lines: 25,41-43 |
| | | :linenos: |
| | | :language: python |
| | | |
| | |
| | | ---------------------- |
| | | |
| | | Add a ``security.py`` module within your package (in the same directory as |
| | | :file:`__init__.py`, :file:`views.py`, etc) with the following content: |
| | | :file:`__init__.py`, :file:`views.py`, etc.) with the following content: |
| | | |
| | | .. literalinclude:: src/authorization/tutorial/security.py |
| | | :linenos: |
| | |
| | | register views for the routes, mapping your patterns to code: |
| | | |
| | | .. literalinclude:: src/basiclayout/tutorial/__init__.py |
| | | :lines: 14 |
| | | :lines: 14-15 |
| | | :language: py |
| | | |
| | | The first positional ``add_view`` argument ``tutorial.views.my_view`` is the |
| | |
| | | ``renderer``, which is a template which lives in the ``templates`` |
| | | subdirectory of the package. When the ``tutorial.views.my_view`` view |
| | | returns a dictionary, a :term:`renderer` will use this template to create a |
| | | response. This |
| | | response. |
| | | |
| | | Finally, we use the :meth:`pyramid.config.Configurator.make_wsgi_app` |
| | | method to return a :term:`WSGI` application: |
| | |
| | | :linenos: |
| | | :language: py |
| | | |
| | | Next we set up a SQLAlchemy "DBSession" object: |
| | | Next we set up a SQLAlchemy "DBSession" object: |
| | | |
| | | .. literalinclude:: src/basiclayout/tutorial/models.py |
| | | :lines: 15-16 |
| | |
| | | :language: python |
| | | |
| | | As you can see, our ``Page`` class has a class level attribute |
| | | ``__tablename__`` which equals the string ``pages``. This means that |
| | | ``__tablename__`` which equals the string ``'pages'``. This means that |
| | | SQLAlchemy will store our wiki data in a SQL table named ``pages``. Our Page |
| | | class will also have class-level attributes named ``id``, ``name`` and |
| | | ``data`` (all instances of :class:`sqlalchemy.Column`). These will map to |
| | |
| | | largely the same as the ``initialize_sql`` in the paster-generated |
| | | ``models.py``. |
| | | |
| | | Our DBSession assignment stays the same as the original generated |
| | | Our ``DBSession`` assignment stays the same as the original generated |
| | | ``models.py``. |
| | | |
| | | Looking at the Result of all Our Edits to ``models.py`` |
| | |
| | | into the URL by the ``pattern`` of a ``route`` statement. For instance, if a |
| | | call to :meth:`pyramid.config.Configurator.add_route` in ``__init__.py`` had |
| | | the pattern ``{one}/{two}``, and the URL at ``http://example.com/foo/bar`` |
| | | was invoked, matching this pattern, the matchdict dictionary attached to the |
| | | request passed to the view would have a ``one`` key with the value ``foo`` |
| | | and a ``two`` key with the value ``bar``. |
| | | was invoked, matching this pattern, the ``matchdict`` dictionary attached to |
| | | the request passed to the view would have a ``'one'`` key with the value |
| | | ``'foo'`` and a ``'two'`` key with the value ``'bar'``. |
| | | |
| | | The source code for this tutorial stage can be browsed at |
| | | `http://github.com/Pylons/pyramid/tree/master/docs/tutorials/wiki2/src/views/ |
| | |
| | | The ``view_wiki`` view function |
| | | ------------------------------- |
| | | |
| | | The ``view_wiki`` function will respond as the :term:`default view` of a |
| | | ``Wiki`` model object. It always redirects to a URL which represents the |
| | | path to our "FrontPage". |
| | | The ``view_wiki`` function is the :term:`default view` that will be called |
| | | when a request is made to the root URL of our wiki. It always redirects to |
| | | a URL which represents the path to our "FrontPage". |
| | | |
| | | .. literalinclude:: src/views/tutorial/views.py |
| | | :pyobject: view_wiki |
| | |
| | | The ``view_page`` view function |
| | | ------------------------------- |
| | | |
| | | The ``view_page`` function will respond as the :term:`default view` of |
| | | a ``Page`` object. The ``view_page`` function renders the |
| | | :term:`ReStructuredText` body of a page (stored as the ``data`` |
| | | attribute of a Page object) as HTML. Then it substitutes an HTML |
| | | anchor for each *WikiWord* reference in the rendered HTML using a |
| | | The ``view_page`` function will be used to show a single page of our |
| | | wiki. It renders the :term:`ReStructuredText` body of a page (stored as |
| | | the ``data`` attribute of a Page object) as HTML. Then it substitutes an |
| | | HTML anchor for each *WikiWord* reference in the rendered HTML using a |
| | | compiled regular expression. |
| | | |
| | | .. literalinclude:: src/views/tutorial/views.py |
| | |
| | | :linenos: |
| | | :language: python |
| | | |
| | | The matchdict will have a ``pagename`` key that matches the name of the page |
| | | we'd like to add. If our add view is invoked via, |
| | | e.g. ``http://localhost:6543/add_page/SomeName``, the ``pagename`` value in |
| | | the matchdict will be ``SomeName``. |
| | | The ``matchdict`` will have a ``'pagename'`` key that matches the name of |
| | | the page we'd like to add. If our add view is invoked via, |
| | | e.g. ``http://localhost:6543/add_page/SomeName``, the value for |
| | | ``'pagename'`` in the ``matchdict`` will be ``'SomeName'``. |
| | | |
| | | If the view execution is *not* a result of a form submission (if the |
| | | expression ``'form.submitted' in request.params`` is ``False``), the view |
| | | callable renders a template. To do so, it generates a "save url" which the |
| | | template use as the form post URL during rendering. We're lazy here, so |
| | | template uses as the form post URL during rendering. We're lazy here, so |
| | | we're trying to use the same template (``templates/edit.pt``) for the add |
| | | view as well as the page edit view, so we create a dummy Page object in order |
| | | to satisfy the edit form's desire to have *some* page object exposed as |
| | |
| | | |
| | | If the view execution *is* a result of a form submission (if the expression |
| | | ``'form.submitted' in request.params`` is ``True``), we scrape the page body |
| | | from the form data, create a Page object using the name in the matchdict |
| | | ``pagename``, and obtain the page body from the request, and save it into the |
| | | database using ``session.add``. We then redirect back to the ``view_page`` |
| | | view (the :term:`default view` for a Page) for the newly created page. |
| | | from the form data, create a Page object with this page body and the name |
| | | taken from ``matchdict['pagename']``, and save it into the database using |
| | | ``session.add``. We then redirect back to the ``view_page`` view for the |
| | | newly created page. |
| | | |
| | | The ``edit_page`` view function |
| | | ------------------------------- |
| | |
| | | The ``edit_page`` function will be invoked when a user clicks the "Edit this |
| | | Page" button on the view form. It renders an edit form but it also acts as |
| | | the handler for the form it renders. The ``matchdict`` attribute of the |
| | | request passed to the ``edit_page`` view will have a ``pagename`` key |
| | | request passed to the ``edit_page`` view will have a ``'pagename'`` key |
| | | matching the name of the page the user wants to edit. |
| | | |
| | | .. literalinclude:: src/views/tutorial/views.py |
| | |
| | | |
| | | If the view execution is *not* a result of a form submission (if the |
| | | expression ``'form.submitted' in request.params`` is ``False``), the view |
| | | simply renders the edit form, passing the request, the page object, and a |
| | | save_url which will be used as the action of the generated form. |
| | | simply renders the edit form, passing the page object and a ``save_url`` |
| | | which will be used as the action of the generated form. |
| | | |
| | | If the view execution *is* a result of a form submission (if the expression |
| | | ``'form.submitted' in request.params`` is ``True``), the view grabs the |
| | | ``body`` element of the request parameter and sets it as the ``data`` |
| | | attribute of the page object. It then redirects to the default view of the |
| | | wiki page, which will always be the ``view_page`` view. |
| | | ``body`` element of the request parameters and sets it as the ``data`` |
| | | attribute of the page object. It then redirects to the ``view_page`` view |
| | | of the wiki page. |
| | | |
| | | Viewing the Result of all Our Edits to ``views.py`` |
| | | =================================================== |
| | |
| | | The ``__init__.py`` file contains |
| | | :meth:`pyramid.config.Configurator.add_view` calls which serve to map |
| | | routes via :term:`url dispatch` to views. First, we’ll get rid of the |
| | | existing route created by the template using the name ``home``. It’s only an |
| | | existing route created by the template using the name ``'home'``. It’s only an |
| | | example and isn’t relevant to our application. |
| | | |
| | | We then need to add four calls to ``add_route``. Note that the *ordering* of |
| | |
| | | the order they're found in the ``__init__.py`` file. |
| | | |
| | | #. Add a declaration which maps the pattern ``/`` (signifying the root URL) |
| | | to the route named ``view_wiki``. |
| | | to the route named ``view_wiki``. |
| | | |
| | | #. Add a declaration which maps the pattern ``/{pagename}`` to the route named |
| | | ``view_page``. This is the regular view for a page. |
| | |
| | | writing top-level names to tutorial.egg-info/top_level.txt |
| | | writing dependency_links to tutorial.egg-info/dependency_links.txt |
| | | writing entry points to tutorial.egg-info/entry_points.txt |
| | | unrecognized .svn/entries format in |
| | | unrecognized .svn/entries format in |
| | | reading manifest file 'tutorial.egg-info/SOURCES.txt' |
| | | writing manifest file 'tutorial.egg-info/SOURCES.txt' |
| | | running build_ext |
| | |
| | | |
| | | |
| | | |
| | | |
| | | |
| | |
| | | |
| | | For cut and paste purposes, the source code for all stages of this |
| | | tutorial can be browsed at |
| | | `http://github.com/Pylons/pyramid/tree/master/docs/tutorials/wiki2/ |
| | | <http://github.com/Pylons/pyramid/tree/master/docs/tutorials/wiki2/>`_. |
| | | `http://github.com/Pylons/pyramid/tree/master/docs/tutorials/wiki2/src/ |
| | | <http://github.com/Pylons/pyramid/tree/master/docs/tutorials/wiki2/src/>`_. |
| | | |
| | | .. toctree:: |
| | | :maxdepth: 2 |
| | |
| | | |
| | | .. code-block:: text |
| | | |
| | | c:\pyramidtut> Scripts\easy_install docutils \ |
| | | c:\pyramidtut> Scripts\easy_install docutils ^ |
| | | nose coverage zope.sqlalchemy SQLAlchemy repoze.tm2 |
| | | |
| | | |
| | |
| | | |
| | | .. code-block:: text |
| | | |
| | | c:\pyramidtut\tutorial> ..\Scripts\nosetests --cover-package=tutorial \ |
| | | c:\pyramidtut\tutorial> ..\Scripts\nosetests --cover-package=tutorial ^ |
| | | --cover-erase --with-coverage |
| | | |
| | | Looks like our package's ``models`` module doesn't quite have 100% |
| | |
| | | data = Column(Text) |
| | | |
| | | def __init__(self, name, data): |
| | | self.name = name |
| | | self.data = data |
| | | self.name = name |
| | | self.data = data |
| | | |
| | | def initialize_sql(engine): |
| | | DBSession.configure(bind=engine) |
| | |
| | | data = Column(Text) |
| | | |
| | | def __init__(self, name, data): |
| | | self.name = name |
| | | self.data = data |
| | | self.name = name |
| | | self.data = data |
| | | |
| | | def initialize_sql(engine): |
| | | DBSession.configure(bind=engine) |
| | |
| | | data = Column(Text) |
| | | |
| | | def __init__(self, name, data): |
| | | self.name = name |
| | | self.data = data |
| | | self.name = name |
| | | self.data = data |
| | | |
| | | def initialize_sql(engine): |
| | | DBSession.configure(bind=engine) |