diff options
| author | Chris McDonough <chrism@plope.com> | 2011-09-09 04:20:46 -0400 |
|---|---|---|
| committer | Chris McDonough <chrism@plope.com> | 2011-09-09 04:20:46 -0400 |
| commit | 82dcba5bf8d6d024f42ded1565d30c314b8e8b4b (patch) | |
| tree | 8ba820897cd81a58dada152e13617788a340e5b2 /docs | |
| parent | d3aae87e4e167ab8ff7a0c54fee4197d9a8b8763 (diff) | |
| download | pyramid-82dcba5bf8d6d024f42ded1565d30c314b8e8b4b.tar.gz pyramid-82dcba5bf8d6d024f42ded1565d30c314b8e8b4b.tar.bz2 pyramid-82dcba5bf8d6d024f42ded1565d30c314b8e8b4b.zip | |
reorder
Diffstat (limited to 'docs')
| -rw-r--r-- | docs/narr/introduction.rst | 448 |
1 files changed, 224 insertions, 224 deletions
diff --git a/docs/narr/introduction.rst b/docs/narr/introduction.rst index 8a7c724a1..8694556b2 100644 --- a/docs/narr/introduction.rst +++ b/docs/narr/introduction.rst @@ -269,6 +269,47 @@ Here's a few views defined as methods of a class instead: See also :ref:`view_config_placement`. +.. _intro_asset_specs: + +Asset specifications +~~~~~~~~~~~~~~~~~~~~ + +Asset specifications are strings that contain both a Python package name and +a file or directory name, e.g. ``MyPackage:static/index.html``. Use of these +specifications is omnipresent in Pyramid. An asset specification can refer +to a template, a translation directory, or any other package-bound static +resource. This makes a system built on Pyramid extensible, because you don't +have to rely on globals ("*the* static directory") or lookup schemes ("*the* +ordered set of template directories") to address your files. You can move +files around as necessary, and include other packages that may not share your +system's templates or static files without encountering conflicts. + +Because asset specifications are used heavily in Pyramid, we've also provided +a way to allow users to override assets. Say you love a system that someone +else has created with Pyramid but you just need to change "that one template" +to make it all better. No need to fork the application. Just override the +asset specification for that template with your own inside a wrapper, and +you're good to go. + +Examples: :ref:`asset_specifications` and :ref:`overriding_assets_section`. + +Extensible templating +~~~~~~~~~~~~~~~~~~~~~ + +Pyramid has a structured API that allows for pluggability of "renderers". +Templating systems such as Mako, Genshi, Chameleon, and Jinja2 can be treated +as renderers. Renderer bindings for all of these templating systems already +exist for use in Pyramid. But if you'd rather use another, it's not a big +deal. Just copy the code from an existing renderer package, and plug in your +favorite templating system. You'll then be able to use that templating +system from within Pyramid just as you'd use one of the "built-in" templating +systems. + +Pyramid does not make you use a single templating system exclusively. You +can use multiple templating systems, even in the same project. + +Example: :ref:`templates_used_directly`. + Rendered views can return dictionaries ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ @@ -313,150 +354,6 @@ Python package. Asset specifications are omnipresent in Pyramid: see Example: :ref:`renderers_chapter`. -Extensible templating -~~~~~~~~~~~~~~~~~~~~~ - -Pyramid has a structured API that allows for pluggability of "renderers". -Templating systems such as Mako, Genshi, Chameleon, and Jinja2 can be treated -as renderers. Renderer bindings for all of these templating systems already -exist for use in Pyramid. But if you'd rather use another, it's not a big -deal. Just copy the code from an existing renderer package, and plug in your -favorite templating system. You'll then be able to use that templating -system from within Pyramid just as you'd use one of the "built-in" templating -systems. - -Pyramid does not make you use a single templating system exclusively. You -can use multiple templating systems, even in the same project. - -Example: :ref:`templates_used_directly`. - -View response adapters -~~~~~~~~~~~~~~~~~~~~~~ - -A lot is made of the aesthetics of what *kinds* of objects you're allowed to -return from view callables in various frameworks. In a previous section in -this document we showed you that, if you use a :term:`renderer`, you can -usually return a dictionary from a view callable instead of a full-on -:term:`Response` object. But some frameworks allow you return strings or -tuples from view callables. When frameworks allow for this, code looks -slightly prettier, because fewer imports need to be done, and there is less -code. For example, compare this: - -.. code-block:: python - :linenos: - - def aview(request): - return "Hello world!" - -To this: - -.. code-block:: python - :linenos: - - from pyramid.response import Response - - def aview(request): - return Response("Hello world!") - -The former is "prettier", right? - -Out of the box, if you define the former view callable (the one that simply -returns a string) in Pyramid, when it is executed, Pyramid will raise an -exception. This is because "explicit is better than implicit", in most -cases, and by default, Pyramid wants you to return a :term:`Response` object -from a view callable. This is because there's usually a heck of a lot more -to a response object than just its body. But if you're the kind of person -who values such aesthetics, we have an easy way to allow for this sort of -thing: - -.. code-block:: python - :linenos: - - from pyramid.config import Configurator - from pyramid.response import Response - - def string_response_adapter(s): - response = Response(s) - response.content_type = 'text/html' - return response - - if __name__ == '__main__': - config = Configurator() - config.add_response_adapter(string_response_adapter, basestring) - -Do that once in your Pyramid application at startup. Now you can return -strings from any of your view callables, e.g.: - -.. code-block:: python - :linenos: - - def helloview(request): - return "Hello world!" - - def goodbyeview(request): - return "Goodbye world!" - -Oh noes! What if you want to indicate a custom content type? And a custom -status code? No fear: - -.. code-block:: python - :linenos: - - from pyramid.config import Configurator - - def tuple_response_adapter(val): - status_int, content_type, body = val - response = Response(body) - response.content_type = content_type - response.status_int = status_int - return response - - def string_response_adapter(body): - response = Response(body) - response.content_type = 'text/html' - response.status_int = 200 - return response - - if __name__ == '__main__': - config = Configurator() - config.add_response_adapter(string_response_adapter, basestring) - config.add_response_adapter(tuple_response_adapter, tuple) - -Once this is done, both of these view callables will work: - -.. code-block:: python - :linenos: - - def aview(request): - return "Hello world!" - - def anotherview(request): - return (403, 'text/plain', "Forbidden") - -Pyramid defaults to explicit behavior, because it's the most generally -useful, but provide hooks that allow you to adapt the framework to localized -aesthetic desires. - -See also :ref:`using_iresponse`. - -"Global" response object -~~~~~~~~~~~~~~~~~~~~~~~~ - -"Constructing these response objects in my view callables is such a chore! -And I'm way too lazy to register a response adapter, as per the prior -section," you say. Fine. Be that way: - -.. code-block:: python - :linenos: - - def aview(request): - response = request.response - response.body = 'Hello world!' - response.content_type = 'text/plain' - return response - -See also :ref:`request_response_attr`. - Event system ~~~~~~~~~~~~ @@ -477,6 +374,47 @@ they'd subscribe to the events that are normally sent by Pyramid itself. Example: :ref:`events_chapter` and :ref:`event_types`. +Built-in internationalization +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + +Pyramid ships with internalization-related features in its core: +localization, pluralization, and creating message catalogs from source files +and templates. Pyramid allows for a plurality of message catalog via the use +of translation domains: you can create a system that has its own translations +without conflict with other translations in other domains. + +Example: :ref:`i18n_chapter`. + +HTTP caching +~~~~~~~~~~~~ + +Pyramid provides an easy way to associate views with HTTP caching policies. +You can just tell Pyramid to configure your view with an ``http_cache`` +statement, and it will take care of the rest:: + + @view_config(http_cache=3600) # 60 minutes + def myview(request): .... + +Pyramid will add appropriate ``Cache-Control`` and ``Expires`` headers to +responses generated when this view is invoked. + +See the :meth:`~pyramid.config.Configurator.add_view` method's +``http_cache`` documentation for more information. + +Sessions +~~~~~~~~ + +Pyramid has built-in HTTP sessioning. This allows you to associate data with +otherwise anonymous users between requests. Lots of systems do this. But +Pyramid also allows you to plug in your own sessioning system by creating +some code that adheres to a documented interface. Currently there is a +binding package for the third-party Beaker sessioning system that does exactly +this. But if you have a specialized need (perhaps you want to store your +session data in MongoDB), you can. You can even switch between +implementations without changing your application code. + +Example: :ref:`sessions_chapter`. + Speed ~~~~~ @@ -494,19 +432,23 @@ than Python will be a bottleneck. Example: http://blog.curiasolutions.com/the-great-web-framework-shootout/ -Sessions -~~~~~~~~ +Exception views +~~~~~~~~~~~~~~~ -Pyramid has built-in HTTP sessioning. This allows you to associate data with -otherwise anonymous users between requests. Lots of systems do this. But -Pyramid also allows you to plug in your own sessioning system by creating -some code that adheres to a documented interface. Currently there is a -binding package for the third-party Beaker sessioning system that does exactly -this. But if you have a specialized need (perhaps you want to store your -session data in MongoDB), you can. You can even switch between -implementations without changing your application code. +Exceptions happen. Rather than deal with exceptions that might present +themselves to a user in production in an ad-hoc way, Pyramid allows you to +register an :term:`exception view`. Exception views are like regular Pyramid +views, but they're only invoked when an exception "bubbles up" to Pyramid +itself. For example, you might register an exception view for the +:exc:`Exception` exception, which will catch *all* exceptions, and present a +pretty "well, this is embarrassing" page. Or you might choose to register an +exception view for only specific kinds of application-specific exceptions, +such as an exception that happens when a file is not found, or an exception +that happens when an action cannot be performed because the user doesn't have +permission to do something. In the former case, you can show a pretty "Not +Found" page; in the latter case you might show a login form. -Example: :ref:`sessions_chapter`. +Example: :ref:`exception_views`. No singletons ~~~~~~~~~~~~~ @@ -542,48 +484,6 @@ be easier to test. Example: :ref:`view_configuration_parameters`. -Exception views -~~~~~~~~~~~~~~~ - -Exceptions happen. Rather than deal with exceptions that might present -themselves to a user in production in an ad-hoc way, Pyramid allows you to -register an :term:`exception view`. Exception views are like regular Pyramid -views, but they're only invoked when an exception "bubbles up" to Pyramid -itself. For example, you might register an exception view for the -:exc:`Exception` exception, which will catch *all* exceptions, and present a -pretty "well, this is embarrassing" page. Or you might choose to register an -exception view for only specific kinds of application-specific exceptions, -such as an exception that happens when a file is not found, or an exception -that happens when an action cannot be performed because the user doesn't have -permission to do something. In the former case, you can show a pretty "Not -Found" page; in the latter case you might show a login form. - -Example: :ref:`exception_views`. - -.. _intro_asset_specs: - -Asset specifications -~~~~~~~~~~~~~~~~~~~~ - -Asset specifications are strings that contain both a Python package name and -a file or directory name, e.g. ``MyPackage:static/index.html``. Use of these -specifications is omnipresent in Pyramid. An asset specification can refer -to a template, a translation directory, or any other package-bound static -resource. This makes a system built on Pyramid extensible, because you don't -have to rely on globals ("*the* static directory") or lookup schemes ("*the* -ordered set of template directories") to address your files. You can move -files around as necessary, and include other packages that may not share your -system's templates or static files without encountering conflicts. - -Because asset specifications are used heavily in Pyramid, we've also provided -a way to allow users to override assets. Say you love a system that someone -else has created with Pyramid but you just need to change "that one template" -to make it all better. No need to fork the application. Just override the -asset specification for that template with your own inside a wrapper, and -you're good to go. - -Examples: :ref:`asset_specifications` and :ref:`overriding_assets_section`. - Transaction management ~~~~~~~~~~~~~~~~~~~~~~ @@ -679,17 +579,6 @@ system. Example: :ref:`enabling_authorization_policy`. -Built-in internationalization -~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ - -Pyramid ships with internalization-related features in its core: -localization, pluralization, and creating message catalogs from source files -and templates. Pyramid allows for a plurality of message catalog via the use -of translation domains: you can create a system that has its own translations -without conflict with other translations in other domains. - -Example: :ref:`i18n_chapter`. - Traversal ~~~~~~~~~ @@ -710,22 +599,6 @@ as opposed to "Bob can edit documents"). Example: :ref:`much_ado_about_traversal_chapter`. -HTTP caching -~~~~~~~~~~~~ - -Pyramid provides an easy way to associate views with HTTP caching policies. -You can just tell Pyramid to configure your view with an ``http_cache`` -statement, and it will take care of the rest:: - - @view_config(http_cache=3600) # 60 minutes - def myview(request): .... - -Pyramid will add appropriate ``Cache-Control`` and ``Expires`` headers to -responses generated when this view is invoked. - -See the :meth:`~pyramid.config.Configurator.add_view` method's -``http_cache`` documentation for more information. - Tweens ~~~~~~ @@ -738,6 +611,133 @@ Pyramid itself, meaning you have access to templates and other renderers, a Example: :ref:`registering_tweens`. +View response adapters +~~~~~~~~~~~~~~~~~~~~~~ + +A lot is made of the aesthetics of what *kinds* of objects you're allowed to +return from view callables in various frameworks. In a previous section in +this document we showed you that, if you use a :term:`renderer`, you can +usually return a dictionary from a view callable instead of a full-on +:term:`Response` object. But some frameworks allow you return strings or +tuples from view callables. When frameworks allow for this, code looks +slightly prettier, because fewer imports need to be done, and there is less +code. For example, compare this: + +.. code-block:: python + :linenos: + + def aview(request): + return "Hello world!" + +To this: + +.. code-block:: python + :linenos: + + from pyramid.response import Response + + def aview(request): + return Response("Hello world!") + +The former is "prettier", right? + +Out of the box, if you define the former view callable (the one that simply +returns a string) in Pyramid, when it is executed, Pyramid will raise an +exception. This is because "explicit is better than implicit", in most +cases, and by default, Pyramid wants you to return a :term:`Response` object +from a view callable. This is because there's usually a heck of a lot more +to a response object than just its body. But if you're the kind of person +who values such aesthetics, we have an easy way to allow for this sort of +thing: + +.. code-block:: python + :linenos: + + from pyramid.config import Configurator + from pyramid.response import Response + + def string_response_adapter(s): + response = Response(s) + response.content_type = 'text/html' + return response + + if __name__ == '__main__': + config = Configurator() + config.add_response_adapter(string_response_adapter, basestring) + +Do that once in your Pyramid application at startup. Now you can return +strings from any of your view callables, e.g.: + +.. code-block:: python + :linenos: + + def helloview(request): + return "Hello world!" + + def goodbyeview(request): + return "Goodbye world!" + +Oh noes! What if you want to indicate a custom content type? And a custom +status code? No fear: + +.. code-block:: python + :linenos: + + from pyramid.config import Configurator + + def tuple_response_adapter(val): + status_int, content_type, body = val + response = Response(body) + response.content_type = content_type + response.status_int = status_int + return response + + def string_response_adapter(body): + response = Response(body) + response.content_type = 'text/html' + response.status_int = 200 + return response + + if __name__ == '__main__': + config = Configurator() + config.add_response_adapter(string_response_adapter, basestring) + config.add_response_adapter(tuple_response_adapter, tuple) + +Once this is done, both of these view callables will work: + +.. code-block:: python + :linenos: + + def aview(request): + return "Hello world!" + + def anotherview(request): + return (403, 'text/plain', "Forbidden") + +Pyramid defaults to explicit behavior, because it's the most generally +useful, but provide hooks that allow you to adapt the framework to localized +aesthetic desires. + +See also :ref:`using_iresponse`. + +"Global" response object +~~~~~~~~~~~~~~~~~~~~~~~~ + +"Constructing these response objects in my view callables is such a chore! +And I'm way too lazy to register a response adapter, as per the prior +section," you say. Fine. Be that way: + +.. code-block:: python + :linenos: + + def aview(request): + response = request.response + response.body = 'Hello world!' + response.content_type = 'text/plain' + return response + +See also :ref:`request_response_attr`. + Automating repetitive configuration ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ |
