summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--docs/designdefense.rst3
-rw-r--r--docs/getting_started/index.rst5
-rw-r--r--docs/getting_started/quick_glance.rst291
-rw-r--r--docs/getting_started/quick_glance/jinja2/app.py12
-rw-r--r--docs/getting_started/quick_glance/jinja2/hello_world.jinja21
-rw-r--r--docs/getting_started/quick_glance/jinja2/views.py8
-rw-r--r--docs/getting_started/quick_glance/json/app.py15
-rw-r--r--docs/getting_started/quick_glance/json/hello_world.jinja2 (renamed from docs/getting_started/static_assets/hello_world.jinja2)0
-rw-r--r--docs/getting_started/quick_glance/json/hello_world.pt17
-rw-r--r--docs/getting_started/quick_glance/json/views.py13
-rw-r--r--docs/getting_started/quick_glance/requests/app.py10
-rw-r--r--docs/getting_started/quick_glance/routing/app.py14
-rw-r--r--docs/getting_started/quick_glance/routing/views.py10
-rw-r--r--docs/getting_started/quick_glance/static_assets/app.py (renamed from docs/getting_started/static_assets/app.py)13
-rw-r--r--docs/getting_started/quick_glance/static_assets/hello_world.jinja210
-rw-r--r--docs/getting_started/quick_glance/static_assets/hello_world.pt17
-rw-r--r--docs/getting_started/quick_glance/static_assets/static/app.css (renamed from docs/getting_started/quick_glance/static/app.css)0
-rw-r--r--docs/getting_started/quick_glance/static_assets/views.py6
-rw-r--r--docs/getting_started/quick_glance/templating/app.py10
-rw-r--r--docs/getting_started/quick_glance/templating/hello_world.pt8
-rw-r--r--docs/getting_started/quick_glance/templating/views.py8
-rw-r--r--docs/getting_started/quick_glance/view_classes/app.py2
-rw-r--r--docs/getting_started/quick_glance/views/app.py5
-rw-r--r--docs/getting_started/quick_glance/views/views.py26
-rw-r--r--docs/glossary.rst4
25 files changed, 345 insertions, 163 deletions
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 ``<h1>``:
+.. 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.
- <html lang="en">
- <html xmlns="http://www.w3.org/1999/xhtml">
- <head>
- <title>Quick Glance</title>
- </head>
- <body>
- <h1>Hello {{ name }}!</h1>
- </body>
- </html>
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 ``<head>`` 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:
- <link rel="stylesheet" href="/static/app.css" />
+.. 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 @@
-<html lang="en">
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
<title>Quick Glance</title>
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/static_assets/hello_world.jinja2 b/docs/getting_started/quick_glance/json/hello_world.jinja2
index 3d0f28c1f..3d0f28c1f 100644
--- a/docs/getting_started/static_assets/hello_world.jinja2
+++ b/docs/getting_started/quick_glance/json/hello_world.jinja2
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 @@
+<html lang="en">
+<html xmlns="http://www.w3.org/1999/xhtml">
+<head>
+ <title>Quick Glance</title>
+ <!-- Start Link 1 -->
+ <link rel="stylesheet" href="/static/app.css" />
+ <!-- End Link 1 -->
+ <!-- Start Link 2 -->
+ <link rel="stylesheet"
+ href="${request.static_url('static/app.css')}"
+ />
+ <!-- End Link 2 -->
+</head>
+<body>
+<h1>Hello ${name}!</h1>
+</body>
+</html> \ 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('<h1>Hello World!</h1>')
+ # 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('<h1>Hello %(name)s!</h1>' % 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 = '<h1>Hi %(first)s %(last)s!</h1>' % request.matchdict
+ return Response(body)
+ # End Route 1 \ No newline at end of file
diff --git a/docs/getting_started/static_assets/app.py b/docs/getting_started/quick_glance/static_assets/app.py
index a0c967c47..9c808972f 100644
--- a/docs/getting_started/static_assets/app.py
+++ b/docs/getting_started/quick_glance/static_assets/app.py
@@ -1,19 +1,14 @@
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_route('hello', '/howdy/{name}')
+ # Start Static 1
config.add_static_view(name='static', path='static')
+ # End Static 1
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/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 @@
+<html lang="en">
+<html xmlns="http://www.w3.org/1999/xhtml">
+<head>
+ <title>Quick Glance</title>
+ <link rel="stylesheet" href="/static/app.css" />
+</head>
+<body>
+<h1>Hello {{ name }}!</h1>
+</body>
+</html> \ 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 @@
+<html lang="en">
+<html xmlns="http://www.w3.org/1999/xhtml">
+<head>
+ <title>Quick Glance</title>
+ <!-- Start Link 1 -->
+ <link rel="stylesheet" href="/static/app.css" />
+ <!-- End Link 1 -->
+ <!-- Start Link 2 -->
+ <link rel="stylesheet"
+ href="${request.static_url('static/app.css')}"
+ />
+ <!-- End Link 2 -->
+</head>
+<body>
+<h1>Hello ${name}!</h1>
+</body>
+</html> \ No newline at end of file
diff --git a/docs/getting_started/quick_glance/static/app.css b/docs/getting_started/quick_glance/static_assets/static/app.css
index f8acf3164..f8acf3164 100644
--- a/docs/getting_started/quick_glance/static/app.css
+++ b/docs/getting_started/quick_glance/static_assets/static/app.css
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 @@
+<html lang="en">
+<head>
+ <title>Quick Glance</title>
+</head>
+<body>
+<h1>Hello ${name}</h1>
+</body>
+</html> \ 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('<p>Visit <a href="/howdy?name=lisa">hello</a></p>')
+
+
+# /howdy?name=alice which links to the next view
@view_config(route_name='hello')
-def hello_world(request):
- return Response('<h1>Hello %(name)s!</h1>' % request.matchdict)
+def hello_view(request):
+ name = request.params.get('name', 'No Name')
+ body = '<p>Hi %s, this <a href="/goto">redirects</a></p>'
+ 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/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