From d559afa1b3fabe2733e97c64df4370cc12f33ce0 Mon Sep 17 00:00:00 2001 From: Paul Everitt Date: Tue, 6 Aug 2013 15:23:51 -0400 Subject: Up through JSON. --- docs/designdefense.rst | 3 + docs/getting_started/index.rst | 5 + docs/getting_started/quick_glance.rst | 291 +++++++++++++-------- docs/getting_started/quick_glance/jinja2/app.py | 12 +- .../quick_glance/jinja2/hello_world.jinja2 | 1 - docs/getting_started/quick_glance/jinja2/views.py | 8 + docs/getting_started/quick_glance/json/app.py | 15 +- .../quick_glance/json/hello_world.jinja2 | 10 + .../quick_glance/json/hello_world.pt | 17 ++ docs/getting_started/quick_glance/json/views.py | 13 + docs/getting_started/quick_glance/requests/app.py | 10 +- docs/getting_started/quick_glance/routing/app.py | 14 +- docs/getting_started/quick_glance/routing/views.py | 10 + docs/getting_started/quick_glance/static/app.css | 4 - .../quick_glance/static_assets/app.py | 14 + .../quick_glance/static_assets/hello_world.jinja2 | 10 + .../quick_glance/static_assets/hello_world.pt | 17 ++ .../quick_glance/static_assets/static/app.css | 4 + .../quick_glance/static_assets/views.py | 6 + .../getting_started/quick_glance/templating/app.py | 10 + .../quick_glance/templating/hello_world.pt | 8 + .../quick_glance/templating/views.py | 8 + .../quick_glance/view_classes/app.py | 2 +- docs/getting_started/quick_glance/views/app.py | 5 +- docs/getting_started/quick_glance/views/views.py | 26 +- docs/getting_started/static_assets/app.py | 19 -- .../static_assets/hello_world.jinja2 | 10 - docs/glossary.rst | 4 + 28 files changed, 369 insertions(+), 187 deletions(-) create mode 100644 docs/getting_started/quick_glance/jinja2/views.py create mode 100644 docs/getting_started/quick_glance/json/hello_world.jinja2 create mode 100644 docs/getting_started/quick_glance/json/hello_world.pt create mode 100644 docs/getting_started/quick_glance/json/views.py create mode 100644 docs/getting_started/quick_glance/routing/views.py delete mode 100644 docs/getting_started/quick_glance/static/app.css create mode 100644 docs/getting_started/quick_glance/static_assets/app.py create mode 100644 docs/getting_started/quick_glance/static_assets/hello_world.jinja2 create mode 100644 docs/getting_started/quick_glance/static_assets/hello_world.pt create mode 100644 docs/getting_started/quick_glance/static_assets/static/app.css create mode 100644 docs/getting_started/quick_glance/static_assets/views.py create mode 100644 docs/getting_started/quick_glance/templating/app.py create mode 100644 docs/getting_started/quick_glance/templating/hello_world.pt create mode 100644 docs/getting_started/quick_glance/templating/views.py delete mode 100644 docs/getting_started/static_assets/app.py delete mode 100644 docs/getting_started/static_assets/hello_world.jinja2 diff --git a/docs/designdefense.rst b/docs/designdefense.rst index ea46053a0..22570c23d 100644 --- a/docs/designdefense.rst +++ b/docs/designdefense.rst @@ -1295,6 +1295,9 @@ predictability. a registry in another module. This has the effect that double-registrations will never be performed. + +.. _routes_need_ordering: + Routes Need Relative Ordering +++++++++++++++++++++++++++++ diff --git a/docs/getting_started/index.rst b/docs/getting_started/index.rst index 61964056e..06baf20ca 100644 --- a/docs/getting_started/index.rst +++ b/docs/getting_started/index.rst @@ -24,6 +24,11 @@ This guide is part of the official documentation. If you find a bug, you can report it using the same facilities as the described in the software's :ref:`support-and-development`. +Notes +===== + +- Cover static urls and asset specifications, resolving, replacing + Contents ======== diff --git a/docs/getting_started/quick_glance.rst b/docs/getting_started/quick_glance.rst index d58303e29..b04baeec8 100644 --- a/docs/getting_started/quick_glance.rst +++ b/docs/getting_started/quick_glance.rst @@ -67,7 +67,7 @@ browser and you will see the ``Hello World!`` message. New to Python web programming? If so, some lines in module merit explanation: -#. *Line 10*. ``if __name__ == '__main__':`` is Python's way of +#. *Line 10*. The ``if __name__ == '__main__':`` is Python's way of saying "Start here when running from the command line". #. *Lines 11-13*. Use Pyramid's :term:`configurator` to connect @@ -78,8 +78,13 @@ explanation: #. *Lines 14-16*. Publish a :term:`WSGI` app using an HTTP server. -Handling Web Requests With webob -================================ +As shown in this example, the :term:`configurator` plays a central role +in Pyramid development. Building an application from loosely-coupled +parts via :doc:`../narr/configuration` is a central idea in Pyramid, +one that we will revisit regurlarly in this *Getting Started* document. + +Handling Web Requests and Responses +=================================== Developing for the web means processing web requests. As this is a critical part of a web application, web developers need a robust, @@ -98,86 +103,144 @@ Let's see some features of requests and responses in action: .. literalinclude:: quick_glance/requests/app.py :pyobject: hello_world +In this Pyramid view, we get the URL being visited from ``request.url``. +Also, if you visited ``http://localhost:6543/?name=alice``, +the name is included in the body of the response:: + + URL http://localhost:6543/?name=alice with name: alice +Finally, we set the response's content type and return the Response. Views ===== -In the example above, the ``hello_world`` function is a "view" (or more -specifically, a :term:`view callable`. Views are the primary way to -accept web requests and return responses. +For the examples above, the ``hello_world`` function is a "view". In +Pyramid, views are the primary way to accept web requests and return +responses. + +So far our examples place everything in one file: + +- the view function -So far the view, its registration with the configuration, and the route -to map it to a URL are all in the same Python module as the WSGI -application launching. Let's move the views out to their own ``views -.py`` module and change the ``app.py`` to scan that module looking for -decorators that setup the views. First, our revised ``app.py``: +- its registration with the configurator + +- the route to map it to a URL + +- the WSGI application launcher + +Let's move the views out to their own ``views.py`` module and change +the ``app.py`` to scan that module, looking for decorators that setup +the views. First, our revised ``app.py``: .. literalinclude:: quick_glance/views/app.py :linenos: We added some more routes, but we also removed the view code. Our views, and their registrations (via decorators) are now in a module -``views.py`` which is scanned via: - -.. code-block:: python - - config.scan('views') +``views.py`` which is scanned via ``config.scan('views')``. -Our ``views.py`` is now more self-contained: +We now have a ``views.py`` module that is focused on handling requests +and responses: .. literalinclude:: quick_glance/views/views.py :linenos: +We have 4 views, each leading to the other. If you start at +``http://localhost:6543/``, you get a response with a link to the next +view. The ``hello_view`` (available at the URL ``/howdy``) has a link +to the ``redirect_view``, which shows issuing a redirect to the final +view. +.. note:: -- Raise exception, redirect -- Change header -- request object -- "callable" + We're focusing on one topic at a time, thus we are leaving out + handling errors, logging, restarting, etc. These will be covered in + sections of the *Getting Started* guide. -Routing With Decorators and Matchdicts -====================================== -Let's repeat the smallest step, but make it a little more functional -and elegant by adding: +Routing +======= -- Echo back a name sent in via the URL +Writing web applications usually means sophisticated URL design. We +just saw some Pyramid machinery for requests and views. Let's look at +features that help in routing. -- The URL is below the top of the site +Above we saw the basics of routing URLs to views in Pyramid: -- Use a decorator to register the view +- Your project's "setup" code registers a route name to be used when + matching part of the URL -Let's make update our ``app.py`` module: +- Elsewhere, a view is configured to be called for that route name + +.. note:: + + Why do this twice? Other systems don't make us repeat this! As + illustrated in :ref:`routes_need_ordering`, multiple routes might + match the same URL pattern. Rather than provide ways to help guess, + Pyramid lets you be explicit in ordering. Pyramid also gives + facilities to avoid the problem. + +What if we want part of the URL to be available as data in my view? This +route declaration: .. literalinclude:: quick_glance/routing/app.py - :linenos: + :start-after: Start Route 1 + :end-before: End Route 1 -When you run ``python ./app.py`` and visit a URL such as -``http://localhost:6543/hello/amy``, the response includes ``amy`` in -the HTML. +With this, URLs such as ``/howdy/amy/smith`` will assign ``amy`` to +``first`` and ``smith`` to ``last``. We can then use this data in our +view: -This module, while small, starts to show how many Pyramid applications -are composed: +.. literalinclude:: quick_glance/routing/views.py + :start-after: Start Route 1 + :end-before: End Route 1 -#. *Line 7*. Pyramid's configuration supports - :term:`imperative configuration`, such as the ``config.add_view`` in - the previous example. You can also use - :term:`declarative configuration`, in which a Python - :term:`decorator` is placed on the line above the view. +``request.matchdict`` contains values from the URL that match the +"replacement patterns" (the curly braces) in the route declaration. +This information can then be used in your view. -#. *Line 14*. When setting up the route, mark off a section of the URL - to be data available to the view's :term:`matchdict`. +As you might imagine, Pyramid provides +:doc:`many more features in routing <../narr/urldispatch>` +(route factories, custom predicates, security statements, +etc.) We will see more features later in *Geting Started*. -#. *Line 15*. Tell the configurator to go look for decorators. +Templating +========== +Ouch. We have been making our own ``Response`` and filling the response +body with HTML. You usually won't embed an HTML string directly in +Python, but instead, will use a templating language. -Templates -========= +Pyramid doesn't mandate a particular database system, form library, +etc. It encourages replaceability. This applies equally to templating, +which is fortunate: developers have strong views about template +languages. That said, Pyramid bundles Chameleon and Mako, +so in this step, let's use Chameleon as an example: + +.. literalinclude:: quick_glance/templating/views.py + :start-after: Start View 1 + :end-before: End View 1 + +Ahh, that looks better. We have a view that is focused on Python code. +Our ``@view_config`` decorator specifies a :term:`renderer` that points +our template file. Our view then simply returns data which is then +supplied to our template: -You usually won't embed an HTML string directly in Python, but instead, -will use a templating language. Pyramid comes bundled with Chameleon -and Mako, but Jinja2 is popular. Let's install it: +.. literalinclude:: quick_glance/templating/hello_world.pt + :language: html + +Since our view returned ``dict(name=request.matchdict['name'])``, +we can use ``name`` as a variable in our template via +``${name}``. + +Templating With ``jinja2`` +========================== + +We just said Pyramid doesn't prefer one templating language over +another. Time to prove it. Jinja2 is a popular templating system, +modelled after Django's templates. Let's add ``pyramid_jinja2``, +a Pyramid :term:`add-on` which enables Jinja2 as a :term:`renderer` in +our Pyramid applications: .. code-block:: bash @@ -190,28 +253,28 @@ our configuration: config.include('pyramid_jinja2') -Our view changes. We only return Python data and let the ``renderer`` -argument tell Pyramid to pass the response through Jinja2: +The only change in our view...point the renderer at the ``.jinja2`` file: -.. code-block:: python +.. literalinclude:: quick_glance/jinja2/views.py + :start-after: Start View 1 + :end-before: End View 1 - @view_config(route_name='hello', renderer="hello_world.jinja2") - def hello_world(request): - return dict(name=request.matchdict['name']) +Our Jinja2 template is very similar to our previous template: -Our template is HTML-oriented with a little logic in the ``

``: +.. literalinclude:: quick_glance/jinja2/hello_world.jinja2 + :language: html -.. code-block:: html +Pyramid's templating add-ons register a new kind of renderer into your +application. The renderer registration maps to different kinds of +filename extensions. In this case, changing the extension from ``.pt`` +to ``.jinja2`` passed the view response through the ``pyramid_jinja2`` +renderer. + +.. note:: + + At the time of this writing, Jinja2 had not released a version + compatible with Python 3.3. - - - - Quick Glance - - -

Hello {{ name }}!

- - Static Assets ============= @@ -219,11 +282,11 @@ Static Assets Of course the Web is more than just markup. You need static assets: CSS, JS, and images. Let's point our web app at a directory where Pyramid will serve some static assets. First, another call to the -``Configurator``: - -.. code-block:: python +:term:`configurator`: - config.add_static_view(name='static', path='static') +.. literalinclude:: quick_glance/static_assets/app.py + :start-after: Start Static 1 + :end-before: End Static 1 This tells our WSGI application to map requests under ``http://localhost:6543/static/`` to files and directories inside a @@ -231,45 +294,45 @@ This tells our WSGI application to map requests under Next, make a directory ``static`` and place ``app.css`` inside: -.. code-block:: css - - body { - margin: 2em; - font-family: sans-serif; - } +.. literalinclude:: quick_glance/static_assets/static/app.css + :language: css All we need to do now is point to it in the ```` of our Jinja2 template: -.. code-block:: html +.. literalinclude:: quick_glance/static_assets/hello_world.pt + :language: html + :start-after: Start Link 1 + :end-before: End Link 1 + +This link presumes that our CSS is at a URL starting with ``/static/``. +What if the site is later moved under ``/somesite/static/``? Or perhaps +web developer changes the arrangement on disk? Pyramid gives a helper +that provides flexibility on URL generation: - +.. literalinclude:: quick_glance/static_assets/hello_world.pt + :language: html + :start-after: Start Link 2 + :end-before: End Link 2 + +By using ``request.static_url`` to generate the full URL to the static +assets, you both ensure you stay in sync with the configuration and +gain refactoring flexibility later. Returning JSON ============== Modern web apps are more than rendered HTML. Dynamic pages now use -JavaScript update the UI in the browser by requesting server data as -JSON. +JavaScript to update the UI in the browser by requesting server data as +JSON. Pyramid supports this with a JSON renderer: -Pyramid supports this with a JSON renderer: - -.. code-block:: python - - @view_config(route_name='hello_json', renderer='json') - def hello_json(request): - return [1, 2, 3] +.. literalinclude:: quick_glance/json/views.py + :start-after: Start View 1 + :end-before: End View 2 This wires up a view that returns some data through the JSON -"renderer", which calls Python's JSON support to serialize the data -into JSON, set the appropriate HTTP headers, and more. - -The view needs a route added to the ``Configurator``: - -.. code-block:: python - - config.add_route('hello_json', 'hello.json') - +:term:`renderer`, which calls Python's JSON support to serialize the data +into JSON and set the appropriate HTTP headers. View Classes ============ @@ -301,6 +364,24 @@ Let's re-organize our two views into methods on a view class: Everything else remains the same. + +Configuration +============= + + +#. *Line 7*. Pyramid's configuration supports + :term:`imperative configuration`, such as the ``config.add_view`` in + the previous example. You can also use + :term:`declarative configuration`, in which a Python + :term:`decorator` is placed on the line above the view. + +#. *Line 15*. Tell the configurator to go look for decorators. + +- Move route declarations into views, with prefix thingy + +Packages +======== + Quick Project Startup with Scaffolds ==================================== @@ -768,23 +849,3 @@ Authorization ============= -Notes - -- See also, interlinking, teasers or "3 Extras" at the end of each - section, links to a downloadable version of the Python module - -- Read "pyramid for humans" and getting started as an attempt to kill - those - -- Do a better job at the "why" - -- Explain imperative vs. declarative configuration and link to "why - configuration" - -- For see also, point also to Getting Started sections - -- Debugging - -- Explain and link to WSGI, Python Packages - -- Richer routing diff --git a/docs/getting_started/quick_glance/jinja2/app.py b/docs/getting_started/quick_glance/jinja2/app.py index bee50373b..83af219db 100644 --- a/docs/getting_started/quick_glance/jinja2/app.py +++ b/docs/getting_started/quick_glance/jinja2/app.py @@ -1,19 +1,11 @@ from wsgiref.simple_server import make_server from pyramid.config import Configurator -from pyramid.response import Response -from pyramid.view import view_config - - -@view_config(route_name='hello', renderer='app3.jinja2') -def hello_world(request): - return dict(name=request.matchdict['name']) - if __name__ == '__main__': config = Configurator() - config.add_route('hello', '/hello/{name}') + config.add_route('hello', '/howdy/{name}') config.include('pyramid_jinja2') - config.scan() + config.scan('views') app = config.make_wsgi_app() server = make_server('0.0.0.0', 6543, app) server.serve_forever() \ No newline at end of file diff --git a/docs/getting_started/quick_glance/jinja2/hello_world.jinja2 b/docs/getting_started/quick_glance/jinja2/hello_world.jinja2 index 6d9f0cd5f..5fc1fc9bf 100644 --- a/docs/getting_started/quick_glance/jinja2/hello_world.jinja2 +++ b/docs/getting_started/quick_glance/jinja2/hello_world.jinja2 @@ -1,4 +1,3 @@ - Quick Glance diff --git a/docs/getting_started/quick_glance/jinja2/views.py b/docs/getting_started/quick_glance/jinja2/views.py new file mode 100644 index 000000000..916cdc720 --- /dev/null +++ b/docs/getting_started/quick_glance/jinja2/views.py @@ -0,0 +1,8 @@ +from pyramid.view import view_config + + +# Start View 1 +@view_config(route_name='hello', renderer='hello_world.jinja2') +# End View 1 +def hello_world(request): + return dict(name=request.matchdict['name']) diff --git a/docs/getting_started/quick_glance/json/app.py b/docs/getting_started/quick_glance/json/app.py index 9b47fdeaf..950cb478f 100644 --- a/docs/getting_started/quick_glance/json/app.py +++ b/docs/getting_started/quick_glance/json/app.py @@ -1,26 +1,15 @@ from wsgiref.simple_server import make_server from pyramid.config import Configurator -from pyramid.view import view_config - - -@view_config(route_name='hello', renderer='app4.jinja2') -def hello_world(request): - return dict(name=request.matchdict['name']) - - -@view_config(route_name='hello_json', renderer='json') -def hello_json(request): - return [1, 2, 3] if __name__ == '__main__': config = Configurator() - config.add_route('hello', '/hello/{name}') + config.add_route('hello', '/howdy/{name}') config.add_route('hello_json', 'hello.json') config.add_static_view(name='static', path='static') config.include('pyramid_jinja2') - config.scan() + config.scan('views') app = config.make_wsgi_app() server = make_server('0.0.0.0', 6543, app) server.serve_forever() \ No newline at end of file diff --git a/docs/getting_started/quick_glance/json/hello_world.jinja2 b/docs/getting_started/quick_glance/json/hello_world.jinja2 new file mode 100644 index 000000000..3d0f28c1f --- /dev/null +++ b/docs/getting_started/quick_glance/json/hello_world.jinja2 @@ -0,0 +1,10 @@ + + + + Quick Glance + + + +

Hello {{ name }}!

+ + \ No newline at end of file diff --git a/docs/getting_started/quick_glance/json/hello_world.pt b/docs/getting_started/quick_glance/json/hello_world.pt new file mode 100644 index 000000000..0cf20d076 --- /dev/null +++ b/docs/getting_started/quick_glance/json/hello_world.pt @@ -0,0 +1,17 @@ + + + + Quick Glance + + + + + + + + +

Hello ${name}!

+ + \ No newline at end of file diff --git a/docs/getting_started/quick_glance/json/views.py b/docs/getting_started/quick_glance/json/views.py new file mode 100644 index 000000000..583e220c7 --- /dev/null +++ b/docs/getting_started/quick_glance/json/views.py @@ -0,0 +1,13 @@ +from pyramid.view import view_config + + +@view_config(route_name='hello', renderer='hello_world.pt') +def hello_world(request): + return dict(name=request.matchdict['name']) + + +# Start View 1 +@view_config(route_name='hello_json', renderer='json') +def hello_json(request): + return [1, 2, 3] + # End View 1 \ No newline at end of file diff --git a/docs/getting_started/quick_glance/requests/app.py b/docs/getting_started/quick_glance/requests/app.py index df5a6cf18..7ac81eb50 100644 --- a/docs/getting_started/quick_glance/requests/app.py +++ b/docs/getting_started/quick_glance/requests/app.py @@ -4,7 +4,15 @@ from pyramid.response import Response def hello_world(request): - return Response('

Hello World!

') + # Some parameters from a request such as /?name=lisa + url = request.url + name = request.params.get('name', 'No Name Provided') + + body = 'URL %s with name: %s' % (url, name) + return Response( + content_type="text/plain", + body=body + ) if __name__ == '__main__': diff --git a/docs/getting_started/quick_glance/routing/app.py b/docs/getting_started/quick_glance/routing/app.py index bbae35b07..04a8a6344 100644 --- a/docs/getting_started/quick_glance/routing/app.py +++ b/docs/getting_started/quick_glance/routing/app.py @@ -1,18 +1,12 @@ from wsgiref.simple_server import make_server from pyramid.config import Configurator -from pyramid.response import Response -from pyramid.view import view_config - - -@view_config(route_name='hello') -def hello_world(request): - return Response('

Hello %(name)s!

' % request.matchdict) - if __name__ == '__main__': config = Configurator() - config.add_route('hello', '/hello/{name}') - config.scan() + # Start Route 1 + config.add_route('hello', '/howdy/{first}/{last}') + # End Route 1 + config.scan('views') app = config.make_wsgi_app() server = make_server('0.0.0.0', 6543, app) server.serve_forever() \ No newline at end of file diff --git a/docs/getting_started/quick_glance/routing/views.py b/docs/getting_started/quick_glance/routing/views.py new file mode 100644 index 000000000..8cb8d3780 --- /dev/null +++ b/docs/getting_started/quick_glance/routing/views.py @@ -0,0 +1,10 @@ +from pyramid.response import Response +from pyramid.view import view_config + + +# Start Route 1 +@view_config(route_name='hello') +def hello_world(request): + body = '

Hi %(first)s %(last)s!

' % request.matchdict + return Response(body) + # End Route 1 \ No newline at end of file diff --git a/docs/getting_started/quick_glance/static/app.css b/docs/getting_started/quick_glance/static/app.css deleted file mode 100644 index f8acf3164..000000000 --- a/docs/getting_started/quick_glance/static/app.css +++ /dev/null @@ -1,4 +0,0 @@ -body { - margin: 2em; - font-family: sans-serif; -} \ No newline at end of file diff --git a/docs/getting_started/quick_glance/static_assets/app.py b/docs/getting_started/quick_glance/static_assets/app.py new file mode 100644 index 000000000..9c808972f --- /dev/null +++ b/docs/getting_started/quick_glance/static_assets/app.py @@ -0,0 +1,14 @@ +from wsgiref.simple_server import make_server +from pyramid.config import Configurator + +if __name__ == '__main__': + config = Configurator() + config.add_route('hello', '/howdy/{name}') + # Start Static 1 + config.add_static_view(name='static', path='static') + # End Static 1 + config.include('pyramid_jinja2') + config.scan('views') + app = config.make_wsgi_app() + server = make_server('0.0.0.0', 6543, app) + server.serve_forever() \ No newline at end of file diff --git a/docs/getting_started/quick_glance/static_assets/hello_world.jinja2 b/docs/getting_started/quick_glance/static_assets/hello_world.jinja2 new file mode 100644 index 000000000..3d0f28c1f --- /dev/null +++ b/docs/getting_started/quick_glance/static_assets/hello_world.jinja2 @@ -0,0 +1,10 @@ + + + + Quick Glance + + + +

Hello {{ name }}!

+ + \ No newline at end of file diff --git a/docs/getting_started/quick_glance/static_assets/hello_world.pt b/docs/getting_started/quick_glance/static_assets/hello_world.pt new file mode 100644 index 000000000..0cf20d076 --- /dev/null +++ b/docs/getting_started/quick_glance/static_assets/hello_world.pt @@ -0,0 +1,17 @@ + + + + Quick Glance + + + + + + + + +

Hello ${name}!

+ + \ No newline at end of file diff --git a/docs/getting_started/quick_glance/static_assets/static/app.css b/docs/getting_started/quick_glance/static_assets/static/app.css new file mode 100644 index 000000000..f8acf3164 --- /dev/null +++ b/docs/getting_started/quick_glance/static_assets/static/app.css @@ -0,0 +1,4 @@ +body { + margin: 2em; + font-family: sans-serif; +} \ No newline at end of file diff --git a/docs/getting_started/quick_glance/static_assets/views.py b/docs/getting_started/quick_glance/static_assets/views.py new file mode 100644 index 000000000..90730ae32 --- /dev/null +++ b/docs/getting_started/quick_glance/static_assets/views.py @@ -0,0 +1,6 @@ +from pyramid.view import view_config + + +@view_config(route_name='hello', renderer='hello_world.pt') +def hello_world(request): + return dict(name=request.matchdict['name']) diff --git a/docs/getting_started/quick_glance/templating/app.py b/docs/getting_started/quick_glance/templating/app.py new file mode 100644 index 000000000..6d1a29f4e --- /dev/null +++ b/docs/getting_started/quick_glance/templating/app.py @@ -0,0 +1,10 @@ +from wsgiref.simple_server import make_server +from pyramid.config import Configurator + +if __name__ == '__main__': + config = Configurator() + config.add_route('hello', '/howdy/{name}') + config.scan('views') + app = config.make_wsgi_app() + server = make_server('0.0.0.0', 6543, app) + server.serve_forever() \ No newline at end of file diff --git a/docs/getting_started/quick_glance/templating/hello_world.pt b/docs/getting_started/quick_glance/templating/hello_world.pt new file mode 100644 index 000000000..8860df26a --- /dev/null +++ b/docs/getting_started/quick_glance/templating/hello_world.pt @@ -0,0 +1,8 @@ + + + Quick Glance + + +

Hello ${name}

+ + \ No newline at end of file diff --git a/docs/getting_started/quick_glance/templating/views.py b/docs/getting_started/quick_glance/templating/views.py new file mode 100644 index 000000000..6c7846efa --- /dev/null +++ b/docs/getting_started/quick_glance/templating/views.py @@ -0,0 +1,8 @@ +from pyramid.view import view_config + + +# Start View 1 +@view_config(route_name='hello', renderer='hello_world.pt') +def hello_world(request): + return dict(name=request.matchdict['name']) + # End View 1 \ No newline at end of file diff --git a/docs/getting_started/quick_glance/view_classes/app.py b/docs/getting_started/quick_glance/view_classes/app.py index 90978344b..c29311aa5 100644 --- a/docs/getting_started/quick_glance/view_classes/app.py +++ b/docs/getting_started/quick_glance/view_classes/app.py @@ -20,7 +20,7 @@ class HelloWorldViews: if __name__ == '__main__': config = Configurator() - config.add_route('hello', '/hello/{name}') + config.add_route('hello', '/howdy/{name}') config.add_route('hello_json', 'hello.json') config.add_static_view(name='static', path='static') config.include('pyramid_jinja2') diff --git a/docs/getting_started/quick_glance/views/app.py b/docs/getting_started/quick_glance/views/app.py index 1e12b6581..54dc9ed4b 100644 --- a/docs/getting_started/quick_glance/views/app.py +++ b/docs/getting_started/quick_glance/views/app.py @@ -3,7 +3,10 @@ from pyramid.config import Configurator if __name__ == '__main__': config = Configurator() - config.add_route('hello', '/hello/{name}') + config.add_route('home', '/') + config.add_route('hello', '/howdy') + config.add_route('redirect', '/goto') + config.add_route('exception', '/problem') config.scan('views') app = config.make_wsgi_app() server = make_server('0.0.0.0', 6543, app) diff --git a/docs/getting_started/quick_glance/views/views.py b/docs/getting_started/quick_glance/views/views.py index 53a6a273a..9dc795f14 100644 --- a/docs/getting_started/quick_glance/views/views.py +++ b/docs/getting_started/quick_glance/views/views.py @@ -1,7 +1,29 @@ +from pyramid.httpexceptions import HTTPFound from pyramid.response import Response from pyramid.view import view_config +# First view, available at http://localhost:6543/ +@view_config(route_name='home') +def home_view(request): + return Response('

Visit hello

') + + +# /howdy?name=alice which links to the next view @view_config(route_name='hello') -def hello_world(request): - return Response('

Hello %(name)s!

' % request.matchdict) +def hello_view(request): + name = request.params.get('name', 'No Name') + body = '

Hi %s, this redirects

' + return Response(body % name) + + +# /goto which issues HTTP redirect to the last view +@view_config(route_name='redirect') +def redirect_view(request): + return HTTPFound(location="/problem") + + +# /problem which causes an site error +@view_config(route_name='exception') +def exception_view(request): + raise Exception() diff --git a/docs/getting_started/static_assets/app.py b/docs/getting_started/static_assets/app.py deleted file mode 100644 index a0c967c47..000000000 --- a/docs/getting_started/static_assets/app.py +++ /dev/null @@ -1,19 +0,0 @@ -from wsgiref.simple_server import make_server -from pyramid.config import Configurator -from pyramid.view import view_config - - -@view_config(route_name='hello', renderer='app4.jinja2') -def hello_world(request): - return dict(name=request.matchdict['name']) - - -if __name__ == '__main__': - config = Configurator() - config.add_route('hello', '/hello/{name}') - config.add_static_view(name='static', path='static') - config.include('pyramid_jinja2') - config.scan() - app = config.make_wsgi_app() - server = make_server('0.0.0.0', 6543, app) - server.serve_forever() \ No newline at end of file diff --git a/docs/getting_started/static_assets/hello_world.jinja2 b/docs/getting_started/static_assets/hello_world.jinja2 deleted file mode 100644 index 3d0f28c1f..000000000 --- a/docs/getting_started/static_assets/hello_world.jinja2 +++ /dev/null @@ -1,10 +0,0 @@ - - - - Quick Glance - - - -

Hello {{ name }}!

- - \ No newline at end of file diff --git a/docs/glossary.rst b/docs/glossary.rst index abc37c7f8..8ade889a3 100644 --- a/docs/glossary.rst +++ b/docs/glossary.rst @@ -1018,3 +1018,7 @@ Glossary system. See :ref:`registering_thirdparty_predicates` for more information. + add-on + A Python :term:`distribution` that uses Pyramid's extensibility + to plug into a Pyramid application and provide extra, + configurable services. \ No newline at end of file -- cgit v1.2.3