From 02d863cc63a688a3bd9fb66874a273db0b710a0a Mon Sep 17 00:00:00 2001 From: Tshepang Lekhonkhobe Date: Thu, 28 Feb 2013 00:42:42 +0200 Subject: [PATCH 01/21] improve the look of the videos chapter --- misc/videos.rst | 68 ++++++++++++++++++++----------------------------- 1 file changed, 27 insertions(+), 41 deletions(-) diff --git a/misc/videos.rst b/misc/videos.rst index ec470e1..2153b96 100644 --- a/misc/videos.rst +++ b/misc/videos.rst @@ -1,57 +1,43 @@ Pyramid Tutorial/Informational Videos ------------------------------------- -Six Feet Up's "Intro to Basic Pyramid": +* Six Feet Up's `Intro to Basic Pyramid + `_. -http://www.sixfeetup.com/blog/intro-to-the-python-framework-pyramid-and-a-sample-app +* Daniel Nouri's "Writing A Pyramid Application" (long, 3+ hours), from + EuroPython 2012: -Daniel Nouri's "Writing A Pyramid Application" (long, 3+ hours), from -EuroPython 2012: + - `Part 1 `_ -Part 1: http://www.youtube.com/watch?v=dKZjbm_qLUM + - `Part 2 `_ -Part 2: http://www.youtube.com/watch?v=vNvMAOko6ME + See also the related `blog post `_. -See also: http://danielnouri.org/notes/2012/08/16/pyramid-europython-tutorial-video/ +* Carlos de la Guardia's `Writing a Pyramid Application + `_ + tutorial from PyCon 2012 (long, 3+ hours). -Carlos de la Guardia's "Writing a Pyramid Application" tutorial from PyCon -2012 (long, 3+ hours): +* Dylan Jay's `Pyramid: Lighter, faster, better web apps + `_ from PyCon AU 2011 (~37 mins). -http://www.youtube.com/watch?v=NBSosX8xiRk +* Carlos de la Guardia's `Patterns for building large Pyramid applications + `_" (~25 minutes). -Dylan Jay's "Pyramid: Lighter, faster, better web apps" from PyCon AU 2011: +* Eric Bieschke's `Pyramid Turbo Start Tutorial + `_" (very short, 2 mins, 2011). -http://www.youtube.com/watch?v=DBV0MsRu72M +* Chris McDonough `presentation + `_ + to Helsinki Python User's Group about Pyramid (2012), about 30 mins. -Carlos de la Guardia's "Patterns for building large Pyramid applications" (~25 -minutes): +* Chris McDonough at DjangoCon 2012, `About Django from the Pyramid Guy + `_ (about 30 mins). -http://www.youtube.com/watch?v=NUQMr5R3dlk +* Chris McDonough and Mark Ramm: `FLOSS Weekly 151: The Pylons Project + `_ (about 40 mins, 2010). -Eric Bieschke's "Pyramid Turbo Start Tutorial" (very short, 2 mins, 2011): +* Kevin Gill's `What is Pyramid and where is it with respect to Django + `_" (~43 mins) via Python Ireland May 2011. -http://www.youtube.com/watch?v=PscYR_4sQCU - -Chris McDonough presentation to Helsinki Python User's Group about Pyramid -(2012), about 30 mins: - -http://www.youtube.com/watch?v=XKYuKWqr_do&feature=youtu.be - -Chris McDonough at DjangoCon 2012, "About Django from the Pyramid Guy" (about -30 mins): - -http://www.youtube.com/watch?v=eN7h6ZbzMy0" - -Chris McDonough and Mark Ramm on FLOSS Weekly (2010) about the Pylons Project, -about 40 mins: - -http://www.youtube.com/watch?v=_A8kDHozPoM - -Kevin Gill: "What is Pyramid and where is it with respect to Django" (~43 mins) -via Python Ireland May 2011: - -http://vimeo.com/23771511 - -Saiju M's "Create Pyramid Application With SQLAlchemy" (~ 17 mins): - -http://www.youtube.com/watch?v=L2KSsqwwH9M +* Saiju M's `Create Pyramid Application With SQLAlchemy + `_ (~ 17 mins). From 841f63455c89cef408a69a66aee348967653e7ba Mon Sep 17 00:00:00 2001 From: Chris Davies Date: Sun, 3 Mar 2013 14:06:44 -0500 Subject: [PATCH 02/21] * Fixed apex URL * fixed grammer as per issue #64 --- auth/index.rst | 8 ++++---- configuration/whirlwind_tour.rst | 2 +- 2 files changed, 5 insertions(+), 5 deletions(-) diff --git a/auth/index.rst b/auth/index.rst index b378a67..4038be3 100644 --- a/auth/index.rst +++ b/auth/index.rst @@ -22,16 +22,16 @@ Pyramid Auth with Akhet and SQLAlchemy Learn how to set up Pyramid authorization using Akhet and SQLAlchemy at http://pyramid.chromaticleaves.com/simpleauth/. -Google, Facebook, Tweeter, and any OpenID Authentication +Google, Facebook, Twitter, and any OpenID Authentication ======================================================== See `Wayne Witzel III's blog post `_ about using Velruse and Pyramid together to do Google OAuth authentication. -See Matthew Housden and Chris Davies pyramid_apex project for any basic and openid -authentication such as Google, Facebook, Tweeter and more at -https://github.com/cd34/pyramid_apex. +See Matthew Housden and Chris Davies apex project for any basic and +openid authentication such as Google, Facebook, Tweeter and more at +https://github.com/cd34/apex. Integration with Enterprise Systems =================================== diff --git a/configuration/whirlwind_tour.rst b/configuration/whirlwind_tour.rst index d07bbbd..920472e 100644 --- a/configuration/whirlwind_tour.rst +++ b/configuration/whirlwind_tour.rst @@ -350,7 +350,7 @@ the pending configuration action impled by the first call to ``add_view`` by calling ``config.commit()`` explicitly. When we called the ``add_view`` the second time, the discriminator of the first call to ``add_view`` was no longer in the pending actions list to conflict with. The conflict was -resolved because conflict the actions list got flushed. Why do we see ``Hi +resolved because the pending actions list got flushed. Why do we see ``Hi world!`` in our browser instead of ``Hello world!``? Because the call to ``config.make_wsgi_app()`` implies a second commit. The second commit caused the second ``add_view`` configuration callback to be called, and this From 645e00f06645ffd98f4ede85989a87a6a6439bcd Mon Sep 17 00:00:00 2001 From: cd34 Date: Sun, 3 Mar 2013 15:27:12 -0500 Subject: [PATCH 03/21] Update index.rst Fixed second occurrence of Tweeter. --- auth/index.rst | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/auth/index.rst b/auth/index.rst index 4038be3..fa3cbcc 100644 --- a/auth/index.rst +++ b/auth/index.rst @@ -30,7 +30,7 @@ See `Wayne Witzel III's blog post about using Velruse and Pyramid together to do Google OAuth authentication. See Matthew Housden and Chris Davies apex project for any basic and -openid authentication such as Google, Facebook, Tweeter and more at +openid authentication such as Google, Facebook, Twitter and more at https://github.com/cd34/apex. Integration with Enterprise Systems From d744da735fd2d51695df0230d70a67c00b17448e Mon Sep 17 00:00:00 2001 From: Tim Freund Date: Wed, 6 Mar 2013 22:31:01 -0500 Subject: [PATCH 04/21] Fixed spelling of HTTPInternalServerError --- pylons/exceptions.rst | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pylons/exceptions.rst b/pylons/exceptions.rst index b1ca9aa..2f42b47 100644 --- a/pylons/exceptions.rst +++ b/pylons/exceptions.rst @@ -22,7 +22,7 @@ Here's how to send redirects and HTTP errors in Pyramid compared to Pylons:: return exc.HTTPNotFound() # Same thing raise exc.HTTPForbidden() raise exc.HTTPBadRequest() - raise exc.HTTPInernalServerError() + raise exc.HTTPInternalServerError() raise exc.HTTPFound(request.route_url("section1")) # Redirect The ``pyramid.httpexceptions`` module has classes for all official HTTP From 85eb8707858b88eeef6b5e647644f66f0f7b27d8 Mon Sep 17 00:00:00 2001 From: Tshepang Lekhonkhobe Date: Mon, 18 Mar 2013 19:18:41 +0200 Subject: [PATCH 05/21] add intersphinx_mapping to CPython docs --- conf.py | 6 +++++- index.rst | 2 +- 2 files changed, 6 insertions(+), 2 deletions(-) diff --git a/conf.py b/conf.py index f6819aa..485a993 100644 --- a/conf.py +++ b/conf.py @@ -34,7 +34,11 @@ 'sphinx.ext.intersphinx' ] -intersphinx_mapping = {'http://docs.pylonsproject.org/projects/pyramid/en/latest/': None} +intersphinx_mapping = { + 'python': ('http://docs.python.org', None), + 'python3': ('http://docs.python.org/3', None), + 'pyramid': ('http://docs.pylonsproject.org/projects/pyramid/en/latest', None), +} # Add any paths that contain templates here, relative to this directory. templates_path = ['_templates'] diff --git a/index.rst b/index.rst index dca7128..055c79d 100644 --- a/index.rst +++ b/index.rst @@ -26,7 +26,7 @@ It supplements the `main documentation misc/index todo -:ref:`Pyramid Glossary ` +:ref:`Pyramid Glossary ` Indices and tables ================== From d36597410c7d7a011530a50e0c947ae30117444c Mon Sep 17 00:00:00 2001 From: reeedo Date: Mon, 18 Mar 2013 16:16:07 -0700 Subject: [PATCH 06/21] Documentation updates: add reference links, minor reorganization. --- auth/akhet_sqlalchemy.rst | 6 ++ auth/auth_tutorial.rst | 7 +++ auth/enterprise.rst | 26 ++++++++ auth/index.rst | 63 +++---------------- auth/open_id_auth.rst | 11 ++++ configuration/index.rst | 10 ++- deployment/deployment.rst | 5 +- deployment/gevent.rst | 2 + deployment/nginx.rst | 4 +- index.rst | 1 - logging/index.rst | 4 ++ routing/index.rst | 14 +++++ .../traversal_in_views.rst | 0 static_assets/index.rst | 5 ++ templates/index.rst | 8 +++ testing/index.rst | 9 +++ todo.rst | 5 ++ views/index.rst | 4 ++ 18 files changed, 126 insertions(+), 58 deletions(-) create mode 100644 auth/akhet_sqlalchemy.rst create mode 100644 auth/auth_tutorial.rst create mode 100644 auth/enterprise.rst create mode 100644 auth/open_id_auth.rst rename traversal_in_views.rst => routing/traversal_in_views.rst (100%) diff --git a/auth/akhet_sqlalchemy.rst b/auth/akhet_sqlalchemy.rst new file mode 100644 index 0000000..75eb128 --- /dev/null +++ b/auth/akhet_sqlalchemy.rst @@ -0,0 +1,6 @@ +Pyramid Auth with Akhet and SQLAlchemy +====================================== + +Learn how to set up Pyramid authorization using Akhet and SQLAlchemy at +http://pyramid.chromaticleaves.com/simpleauth/. + diff --git a/auth/auth_tutorial.rst b/auth/auth_tutorial.rst new file mode 100644 index 0000000..5ffc4b2 --- /dev/null +++ b/auth/auth_tutorial.rst @@ -0,0 +1,7 @@ +Auth Tutorial +============= + +See Michael Merickel's authentication/authorization tutorial at +http://michael.merickel.org/projects/pyramid_auth_demo/ with code on Github at +https://github.com/mmerickel/pyramid_auth_demo. + diff --git a/auth/enterprise.rst b/auth/enterprise.rst new file mode 100644 index 0000000..139d126 --- /dev/null +++ b/auth/enterprise.rst @@ -0,0 +1,26 @@ +Integration with Enterprise Systems +=================================== + +When using Pyramid within an "enterprise" (or an intranet), it is often desirable to +integrate with existing authentication and authorization (entitlement) systems. +For example, in Microsoft Network environments, the user database is typically +maintained in Active Directory. At present, there is no ready-to-use recipe, but we +are listing places that may be worth looking at for ideas when developing one: + +Authentication +-------------- + +* `adpasswd project on pypi `_ +* `Tim Golden's Active Directory Cookbook `_ +* `python-ad `_ +* `python-ldap.org `_ +* `python-ntmlm `_ +* `Blog post on managing AD from Python in Linux `_ + +Authorization +------------- + +* `Microsoft Authorization Manager `_ +* `Fundamentals of WCF Security `_ +* `Calling WCF Services from C++ using gSOAP `_ + diff --git a/auth/index.rst b/auth/index.rst index fa3cbcc..efe7f9e 100644 --- a/auth/index.rst +++ b/auth/index.rst @@ -1,61 +1,18 @@ Authentication and Authorization %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% - .. toctree:: :maxdepth: 1 - user_object - custom basic + custom + user_object wiki2_auth - -Auth Tutorial -============= - -See Michael Merickel's authentication/authorization tutorial at -http://michael.merickel.org/projects/pyramid_auth_demo/ with code on Github at -https://github.com/mmerickel/pyramid_auth_demo. - -Pyramid Auth with Akhet and SQLAlchemy -====================================== - -Learn how to set up Pyramid authorization using Akhet and SQLAlchemy at -http://pyramid.chromaticleaves.com/simpleauth/. - -Google, Facebook, Twitter, and any OpenID Authentication -======================================================== - -See `Wayne Witzel III's blog post -`_ -about using Velruse and Pyramid together to do Google OAuth authentication. - -See Matthew Housden and Chris Davies apex project for any basic and -openid authentication such as Google, Facebook, Twitter and more at -https://github.com/cd34/apex. - -Integration with Enterprise Systems -=================================== - -When using Pyramid within an "enterprise" (or an intranet), it is often desirable to -integrate with existing authentication and authorization (entitlement) systems. -For example, in Microsoft Network environments, the user database is typically -maintained in Active Directory. At present, there is no ready-to-use recipe, but we -are listing places that may be worth looking at for ideas when developing one: - -Authentication --------------- - -* `adpasswd project on pypi `_ -* `Tim Golden's Active Directory Cookbook `_ -* `python-ad `_ -* `python-ldap.org `_ -* `python-ntmlm `_ -* `Blog post on managing AD from Python in Linux `_ - -Authorization -------------- - -* `Microsoft Authorization Manager `_ -* `Fundamentals of WCF Security `_ -* `Calling WCF Services from C++ using gSOAP `_ + auth_tutorial + akhet_sqlalchemy + open_id_auth + enterprise + +For basic information on authentication and authorization, see the +`security `_ +section of the Pyramid documentation. diff --git a/auth/open_id_auth.rst b/auth/open_id_auth.rst new file mode 100644 index 0000000..42059ae --- /dev/null +++ b/auth/open_id_auth.rst @@ -0,0 +1,11 @@ +Google, Facebook, Twitter, and any OpenID Authentication +======================================================== + +See `Wayne Witzel III's blog post +`_ +about using Velruse and Pyramid together to do Google OAuth authentication. + +See Matthew Housden and Chris Davies apex project for any basic and +openid authentication such as Google, Facebook, Twitter and more at +https://github.com/cd34/apex. + diff --git a/configuration/index.rst b/configuration/index.rst index 0c4aa58..94a6392 100644 --- a/configuration/index.rst +++ b/configuration/index.rst @@ -3,6 +3,14 @@ Configuration .. toctree:: :maxdepth: 2 - + whirlwind_tour django_settings + +For more information on configuration see the following sections of the Pyramid documentation: + +- `basic configuration `_ +- `advanced configuration `_ +- `configuration introspection `_ +- `extending configuration `_ +- `PasteDeploy configuration `_ diff --git a/deployment/deployment.rst b/deployment/deployment.rst index 1cc8769..5d73c81 100644 --- a/deployment/deployment.rst +++ b/deployment/deployment.rst @@ -30,7 +30,8 @@ different projects in production with much success, but never verbatim. What is WSGI? +++++++++++++ -WSGI is a Python standard dictating the interface between a server and an +WSGI is a `Python standard `_ +dictating the interface between a server and an application. The entry point to your pyramid application is an object implementing the WSGI interface. Thus, your application can be served by any server supporting WSGI. @@ -47,3 +48,5 @@ A short list includes: + ``gevent`` + ``mod_wsgi`` + +For more information on WSGI, see the `WSGI home `_ diff --git a/deployment/gevent.rst b/deployment/gevent.rst index dccb5b8..6482140 100644 --- a/deployment/gevent.rst +++ b/deployment/gevent.rst @@ -14,3 +14,5 @@ gevent + long polling http://michael.merickel.org/2011/6/21/tictactoe-and-long-polling-with-pyramid/ https://github.com/mmerickel/tictactoe + +For more information on gevent see the `gevent home page `_ diff --git a/deployment/nginx.rst b/deployment/nginx.rst index 53650bd..1e654ac 100644 --- a/deployment/nginx.rst +++ b/deployment/nginx.rst @@ -6,8 +6,8 @@ of traffic. The advantage in deployment is that by using ``paster``, it is not unlike the basic development environment you're probably using on your local machine. -Nginx is a highly optimized HTTP server, very capable of serving static -content as well as acting as a proxy between other applications and the +`Nginx `_ is a highly optimized HTTP server, very capable of serving +static content as well as acting as a proxy between other applications and the outside world. As a proxy, it also has good support for basic load balancing between multiple instances of an application. diff --git a/index.rst b/index.rst index dca7128..bd39a5e 100644 --- a/index.rst +++ b/index.rst @@ -21,7 +21,6 @@ It supplements the `main documentation static_assets/index templates/index testing/index - traversal_in_views views/index misc/index todo diff --git a/logging/index.rst b/logging/index.rst index 6a6c804..06766ad 100644 --- a/logging/index.rst +++ b/logging/index.rst @@ -5,3 +5,7 @@ Logging :maxdepth: 2 sqlalchemy_logger + +For more information on logging, see the `Logging +`_ +section of the Pyramid documentation. \ No newline at end of file diff --git a/routing/index.rst b/routing/index.rst index 81824e1..883cf52 100644 --- a/routing/index.rst +++ b/routing/index.rst @@ -5,4 +5,18 @@ Traversal and URL dispatch :maxdepth: 2 combining + traversal_in_views traversal_sqlalchemy + +For more information on URL dispatch, see the `URL Dispatch +`_ +section of the Pyramid documentation. + +For more information traversal, see the following sections of the Pyramid +documentation: + +- `Hello Traversal `_ +- `Much Ado about Traversal `_ +- `Traversal `_ +- `Hybrid Dispatching `_ +- `Virtual Hosting `_ diff --git a/traversal_in_views.rst b/routing/traversal_in_views.rst similarity index 100% rename from traversal_in_views.rst rename to routing/traversal_in_views.rst diff --git a/static_assets/index.rst b/static_assets/index.rst index b86e5bd..033db4b 100644 --- a/static_assets/index.rst +++ b/static_assets/index.rst @@ -5,3 +5,8 @@ Static Assets (Static Files) :maxdepth: 2 files + + +For more information on static assets, see the `Static Assets +`_ +section of the Pyramid documentation. \ No newline at end of file diff --git a/templates/index.rst b/templates/index.rst index a134876..6efa1ae 100644 --- a/templates/index.rst +++ b/templates/index.rst @@ -7,3 +7,11 @@ Templates and Renderers templates mako_i18n chameleon_i18n + +For more information on Templates and Renderers, see the following sections +of the Pyramid documentation: + +- `Templates `_ +- `Renderers `_ +- `Internationalization and Localization + `_ \ No newline at end of file diff --git a/testing/index.rst b/testing/index.rst index fff3337..2c9f4cf 100644 --- a/testing/index.rst +++ b/testing/index.rst @@ -5,3 +5,12 @@ Testing :maxdepth: 2 testing_post_curl + +For more information on testing see the `Testing +`_ +section of the Pyramid documentation. + +For additional information on other testing packages see: + +- `WebTest `_ +- `nose `_ diff --git a/todo.rst b/todo.rst index d7496dc..fe8272b 100644 --- a/todo.rst +++ b/todo.rst @@ -62,3 +62,8 @@ TODO - Outgrowing Pyramid Handlers: http://michael.merickel.org/2011/8/23/outgrowing-pyramid-handlers/ - Incorporate Google Analytics into a Pyramid Application: http://russell.ballestrini.net/incorporate-google-analytics-into-a-pyramid-application/ + +- Cookbook docs reorg + + - Add reference links to main documentation + - Move tutorials/overviews to tutorial project and replace with links diff --git a/views/index.rst b/views/index.rst index d6e1a49..8723ce9 100644 --- a/views/index.rst +++ b/views/index.rst @@ -7,3 +7,7 @@ Views chaining_decorators params_mapper +For more information on views, see the `Views +`_ +section of the Pyramid documentation. + From d71ee7934048a81ae9b92bcce9bc5b142daba023 Mon Sep 17 00:00:00 2001 From: reeedo Date: Tue, 19 Mar 2013 11:09:40 -0700 Subject: [PATCH 07/21] Minor format fixes --- logging/index.rst | 2 +- static_assets/index.rst | 2 +- templates/index.rst | 2 +- todo.rst | 1 - 4 files changed, 3 insertions(+), 4 deletions(-) diff --git a/logging/index.rst b/logging/index.rst index 06766ad..6a773c8 100644 --- a/logging/index.rst +++ b/logging/index.rst @@ -8,4 +8,4 @@ Logging For more information on logging, see the `Logging `_ -section of the Pyramid documentation. \ No newline at end of file +section of the Pyramid documentation. diff --git a/static_assets/index.rst b/static_assets/index.rst index 033db4b..c609f88 100644 --- a/static_assets/index.rst +++ b/static_assets/index.rst @@ -9,4 +9,4 @@ Static Assets (Static Files) For more information on static assets, see the `Static Assets `_ -section of the Pyramid documentation. \ No newline at end of file +section of the Pyramid documentation. diff --git a/templates/index.rst b/templates/index.rst index 6efa1ae..d465fa2 100644 --- a/templates/index.rst +++ b/templates/index.rst @@ -14,4 +14,4 @@ of the Pyramid documentation: - `Templates `_ - `Renderers `_ - `Internationalization and Localization - `_ \ No newline at end of file + `_ diff --git a/todo.rst b/todo.rst index fe8272b..4e170b1 100644 --- a/todo.rst +++ b/todo.rst @@ -65,5 +65,4 @@ TODO - Cookbook docs reorg - - Add reference links to main documentation - Move tutorials/overviews to tutorial project and replace with links From e217312a8bcfdbfced89d707d13e9d51c734800d Mon Sep 17 00:00:00 2001 From: reeedo Date: Tue, 19 Mar 2013 11:39:43 -0700 Subject: [PATCH 08/21] move debugging doc into hierarchy and reorg for clarity --- .../debugging_pyramid.rst | 31 ------------------- debugging/index.rst | 9 ++++++ debugging/using_pdb.rst | 26 ++++++++++++++++ index.rst | 2 +- 4 files changed, 36 insertions(+), 32 deletions(-) rename debugging.rst => debugging/debugging_pyramid.rst (76%) create mode 100644 debugging/index.rst create mode 100644 debugging/using_pdb.rst diff --git a/debugging.rst b/debugging/debugging_pyramid.rst similarity index 76% rename from debugging.rst rename to debugging/debugging_pyramid.rst index a267a7b..40bfad8 100644 --- a/debugging.rst +++ b/debugging/debugging_pyramid.rst @@ -1,34 +1,3 @@ -Debugging -========= - -Using PDB to Debug Your Application -+++++++++++++++++++++++++++++++++++ - -``pdb`` is an interactive tool that comes with Python, which allows you to -break your program at an arbitrary point, examine values, and step through -code. It's often much more useful than print statements or logging -statements to examine program state. You can place a ``pdb.set_trace()`` -statement in your Pyramid application at a place where you'd like to examine -program state. When you issue a request to the application, and that point -in your code is reached, you will be dropped into the ``pdb`` debugging -console within the terminal that you used to start your application. - -There are lots of great resources that can help you learn PDB. - -- Doug Hellmann's PyMOTW blog entry entitled "pdb - Interactive Debugger" at - http://blog.doughellmann.com/2010/09/pymotw-pdb-interactive-debugger.html - is the canonical text resource to learning PDB. - -- The PyCon video presentation by Chris McDonough entitled "Introduction to - PDB" at http://pyvideo.org/video/644/introduction-to-pdb is a good place to - start learning PDB. - -- The video at http://marakana.com/forums/python/python/423.html shows you - how to start how to start to using pdb. The video describes using ``pdb`` - in a command-line program. - -Below is a debugging scenario using PDB to debug Pyramid. - Debugging Pyramid +++++++++++++++++ diff --git a/debugging/index.rst b/debugging/index.rst new file mode 100644 index 0000000..7bc6d72 --- /dev/null +++ b/debugging/index.rst @@ -0,0 +1,9 @@ +Debugging +%%%%%%%%% + +.. toctree:: + :maxdepth: 2 + + using_pdb + debugging_pyramid + diff --git a/debugging/using_pdb.rst b/debugging/using_pdb.rst new file mode 100644 index 0000000..b262e6e --- /dev/null +++ b/debugging/using_pdb.rst @@ -0,0 +1,26 @@ +Using PDB to Debug Your Application ++++++++++++++++++++++++++++++++++++ + +``pdb`` is an interactive tool that comes with Python, which allows you to +break your program at an arbitrary point, examine values, and step through +code. It's often much more useful than print statements or logging +statements to examine program state. You can place a ``pdb.set_trace()`` +statement in your Pyramid application at a place where you'd like to examine +program state. When you issue a request to the application, and that point +in your code is reached, you will be dropped into the ``pdb`` debugging +console within the terminal that you used to start your application. + +There are lots of great resources that can help you learn PDB. + +- Doug Hellmann's PyMOTW blog entry entitled "pdb - Interactive Debugger" at + http://blog.doughellmann.com/2010/09/pymotw-pdb-interactive-debugger.html + is the canonical text resource to learning PDB. + +- The PyCon video presentation by Chris McDonough entitled "Introduction to + PDB" at http://pyvideo.org/video/644/introduction-to-pdb is a good place to + start learning PDB. + +- The video at http://marakana.com/forums/python/python/423.html shows you + how to start how to start to using pdb. The video describes using ``pdb`` + in a command-line program. + diff --git a/index.rst b/index.rst index bd39a5e..bde8b62 100644 --- a/index.rst +++ b/index.rst @@ -11,7 +11,7 @@ It supplements the `main documentation auth/index configuration/index database/index - debugging + debugging/index deployment/index forms/index logging/index From b85523b1400f85a7532cea4e55ae32d3142d7f6e Mon Sep 17 00:00:00 2001 From: reeedo Date: Wed, 20 Mar 2013 10:19:24 -0700 Subject: [PATCH 09/21] update debugging/index --- debugging/index.rst | 1 + 1 file changed, 1 insertion(+) diff --git a/debugging/index.rst b/debugging/index.rst index 7bc6d72..fb9d1bc 100644 --- a/debugging/index.rst +++ b/debugging/index.rst @@ -6,4 +6,5 @@ Debugging using_pdb debugging_pyramid + pydev From c3b680b930a87b9be6fb1aa026c29fbd2576e001 Mon Sep 17 00:00:00 2001 From: reeedo Date: Wed, 20 Mar 2013 10:58:50 -0700 Subject: [PATCH 10/21] Add the pydev doc --- debugging/pydev.rst | 74 +++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 74 insertions(+) create mode 100644 debugging/pydev.rst diff --git a/debugging/pydev.rst b/debugging/pydev.rst new file mode 100644 index 0000000..7e2056d --- /dev/null +++ b/debugging/pydev.rst @@ -0,0 +1,74 @@ +Debugging with PyDev +++++++++++++++++++++ + +``pdb`` is a great tool for debugging python scripts, but it has some +limitations to its usefulness. For example, you must modify your code +to insert breakpoints, and its command line interface can be somewhat obtuse. + +Many developers use custom text editors that that allow them to add wrappers +to the basic command line environment, with support for git and other +development tools. In many cases, however, debugging support basically +ends up being simply a wrapper around basic ``pdb`` functionality. + +`PyDev `_ is an `Eclipse `_ plugin +for the Python language, providing an integrated development environment +that includes a built in python interpreter, Git support, integration with +task management, and other useful development functionality. + +The PyDev debugger allows you to execute code without modifying the source +to set breakpoints, and has a gui interface that allows you to inspect +and modify internal state. + +Lars Vogella has provided a clear `tutorial +`_ +on setting up pydev and getting started with the PyDev debugger. Full +documentation on using the PyDev debugger may be found `here +`_. You can also debug +programs not running under Eclipse using the `Remote Debugging +`_ feature. + +PyDev allows you to configure the system to use any python intepreter you +have installed on your machine, and with proper configuration you can support +both 2.x and 3.x syntax. + +Configuring PyDev for a virtualenv +---------------------------------- + +Most of the time you want to be running your code in a virtualenv in order +to be sure that your code is isolated and all the right versions of your +package dependencies are available. You can pip install virtualenv if you like, +but I recommend `virtualenvwrapper +`_ +which eliminates much of the busywork of setting up virtualenvs. + +PyDev will look through all the libraries on your ``PYTHONPATH`` to resolve all +your external references, such as imports, etc. So you will want the virtualenv +libraries on your ``PYTHONPATH`` to avoid unnecessary name-resolution problems. + +To use PyDev with virtualenv takes some additional configuration that isn't +covered in the above tutorial. Basically, you just need to make sure your +virtualenv libraries are in the ``PYTHONPATH``. + +First, open the project properties by right clicking over the project name +and selecting *Properties*. + +In the Properties dialog, select *PyDev - Interpreter/Grammar*, and click +on the *Click here to configure an interpreter not listed* link. The +*Preferences* dialog will come up with *Python Interpreter* selected. +Click on the *New* button. + +Enter a name (e.g. ``pytest_python``) and browse to your virtualenv bin +directory (e.g. ``~/.virtual_envs/pytest/bin/python``) to select +the python interpreter in that location, then select *OK*. + +A dialog will then appear asking you to choose the libraries that should +be on the ``PYTHONPATH``. Most of the necessary libraries should be automatically +selected. [Note: on the Mac, the System libraries are not selected. Select +them all.]. Hit *OK*, and your virtualenv python is now configured. + +You will finally be back on the dialog for configuring your project python +interpreter/grammar. Choose the interpreter you just configured and click +*OK*. + +At this point, formerly unresolved references to libraries installed in your +virtualenv should no longer be called out as errors. From 846df709fe7225309eaf1e0b4361d11ab998d864 Mon Sep 17 00:00:00 2001 From: reeedo Date: Wed, 20 Mar 2013 12:11:22 -0700 Subject: [PATCH 11/21] Update format and validate all steps --- debugging/pydev.rst | 32 ++++++++++++++++++++++++-------- 1 file changed, 24 insertions(+), 8 deletions(-) diff --git a/debugging/pydev.rst b/debugging/pydev.rst index 7e2056d..7f6ca03 100644 --- a/debugging/pydev.rst +++ b/debugging/pydev.rst @@ -36,8 +36,8 @@ Configuring PyDev for a virtualenv Most of the time you want to be running your code in a virtualenv in order to be sure that your code is isolated and all the right versions of your -package dependencies are available. You can pip install virtualenv if you like, -but I recommend `virtualenvwrapper +package dependencies are available. You can ``pip install virtualenv`` if +you like, but I recommend `virtualenvwrapper `_ which eliminates much of the busywork of setting up virtualenvs. @@ -49,13 +49,23 @@ To use PyDev with virtualenv takes some additional configuration that isn't covered in the above tutorial. Basically, you just need to make sure your virtualenv libraries are in the ``PYTHONPATH``. +[Note: If you have never configured a python interpreter for your workspace, +you will not be able to create a project without doing so. You should follow +the steps below to configure python, but you should NOT include any +virtualenv libraries for it. Then you will be able to create projects using +this primary python interpreter. After you create your project, you should +then follow the steps below to configure a new interpreter specifically for +your project which does include the virtualenv libraries. This way, each +project can be related to a specific virtualenv without confusion.] + First, open the project properties by right clicking over the project name and selecting *Properties*. -In the Properties dialog, select *PyDev - Interpreter/Grammar*, and click -on the *Click here to configure an interpreter not listed* link. The -*Preferences* dialog will come up with *Python Interpreter* selected. -Click on the *New* button. +In the Properties dialog, select *PyDev - Interpreter/Grammar*, and make +sure that the project type *Python* is selected. Click on the "Click here +to configure an interpreter not listed" link. The *Preferences* dialog will +come up with *Python Interpreters* page, and your current interpreter +selected. Click on the *New...* button. Enter a name (e.g. ``pytest_python``) and browse to your virtualenv bin directory (e.g. ``~/.virtual_envs/pytest/bin/python``) to select @@ -68,7 +78,13 @@ them all.]. Hit *OK*, and your virtualenv python is now configured. You will finally be back on the dialog for configuring your project python interpreter/grammar. Choose the interpreter you just configured and click -*OK*. +*OK*. You may also choose the grammar level (2.7, 3.0, etc.) at this time. At this point, formerly unresolved references to libraries installed in your -virtualenv should no longer be called out as errors. +virtualenv should no longer be called out as errors. (You will have to +close and reopen any python modules before the new interpreter will take +effect.) + +Remember also when using the PyDev console, to choose the interpreter +associated with the project so that references in the console will +be properly resolved. From ea0f3273d686a104ac8b52177ae09b1e8e75b482 Mon Sep 17 00:00:00 2001 From: reeedo Date: Wed, 20 Mar 2013 12:19:12 -0700 Subject: [PATCH 12/21] Reformat notes --- debugging/pydev.rst | 25 +++++++++++++++---------- 1 file changed, 15 insertions(+), 10 deletions(-) diff --git a/debugging/pydev.rst b/debugging/pydev.rst index 7f6ca03..507c115 100644 --- a/debugging/pydev.rst +++ b/debugging/pydev.rst @@ -49,14 +49,16 @@ To use PyDev with virtualenv takes some additional configuration that isn't covered in the above tutorial. Basically, you just need to make sure your virtualenv libraries are in the ``PYTHONPATH``. -[Note: If you have never configured a python interpreter for your workspace, -you will not be able to create a project without doing so. You should follow -the steps below to configure python, but you should NOT include any -virtualenv libraries for it. Then you will be able to create projects using -this primary python interpreter. After you create your project, you should -then follow the steps below to configure a new interpreter specifically for -your project which does include the virtualenv libraries. This way, each -project can be related to a specific virtualenv without confusion.] +.. note:: + + If you have never configured a python interpreter for your workspace, + you will not be able to create a project without doing so. You should follow + the steps below to configure python, but you should NOT include any + virtualenv libraries for it. Then you will be able to create projects using + this primary python interpreter. After you create your project, you should + then follow the steps below to configure a new interpreter specifically for + your project which does include the virtualenv libraries. This way, each + project can be related to a specific virtualenv without confusion. First, open the project properties by right clicking over the project name and selecting *Properties*. @@ -73,8 +75,11 @@ the python interpreter in that location, then select *OK*. A dialog will then appear asking you to choose the libraries that should be on the ``PYTHONPATH``. Most of the necessary libraries should be automatically -selected. [Note: on the Mac, the System libraries are not selected. Select -them all.]. Hit *OK*, and your virtualenv python is now configured. +selected. Hit *OK*, and your virtualenv python is now configured. + +.. note:: + + On the Mac, the system libraries are not selected. Select them all. You will finally be back on the dialog for configuring your project python interpreter/grammar. Choose the interpreter you just configured and click From 17d572725d367b42bcc416c059a9bbb111e969c7 Mon Sep 17 00:00:00 2001 From: reeedo Date: Wed, 20 Mar 2013 14:51:31 -0700 Subject: [PATCH 13/21] Add section on running Pyramid in PyDev. --- debugging/pydev.rst | 71 +++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 71 insertions(+) diff --git a/debugging/pydev.rst b/debugging/pydev.rst index 507c115..ad318ab 100644 --- a/debugging/pydev.rst +++ b/debugging/pydev.rst @@ -93,3 +93,74 @@ effect.) Remember also when using the PyDev console, to choose the interpreter associated with the project so that references in the console will be properly resolved. + +Running Pyramid under Pydev +---------------------------------- + +(Thanks to Michael Wilson for much of this - see `Setting up Eclipse +(PyDev) for Pyramid +`_) + +.. note:: + + This section assumes you have created a virtualenv with Pyramid installed, + and have configured your PyDev as above for this virtualenv. + We further assume you are using ``virtualenvwrapper`` (see above) so that + ``$WORKON_HOME`` is the location of your ``.virtualenvs`` directory + and ``proj_venv`` is the name of your virtualenv. + ``$WORKSPACE`` is the name of the PyDev workspace containing your project + + To create a working example, copy the `pyramid tutorial step03 + `_ + code into $WORKSPACE/tutorial. + + After copying the code, cd to ``$WORKSPACE/tutorial`` and run + ``python setup.py develop`` + + You should now be ready to setup PyDev to run the tutorial step03 code. + +We will set up PyDev to run pserve as part of a run or debug configuration. + +First, copy ``pserve.py`` from your virtualenv to a location outside of your +project library path:: + + cp $WORKON_HOME/proj_venv/bin/pserve.py $WORKSPACE + +.. note:: + + IMPORTANT: Do not put this in your project library path! + +Now we need to have PyDev run this by default. To create a new run +configuration, right click on the project and select +*Run As -> Run Configurations...*. Select *Python Run* as your +configuration type, and click on the new configuration icon. Add your +project name (or browse to it), in this case "tutorial". + +Add these values to the *Main* tab:: + + Project: RunPyramid + Main Module: ${workspace_loc}/pserve.py + +Add these values to the *Arguments* tab:: + + Program arguments: ${workspace_loc:tutorial/development.ini} --reload + +.. note:: + + Do not add ``--reload`` if you are trying to debug with + Eclipse. It has been reported that this causes problems. + +On the *Common* tab:: + + Uncheck "Launch in background" + In the box labeled "Display in favorites menu", click "Run" + +Hit *Run* to run your configuration immediately, or *Apply* to create the +configuration without running it. + +You can now run your configuration at any time by selecting the *Run/Play -> +RunPyramid* button. + +The console should show that the server has started. To verify, open +your browser to 127.0.0.1:6547. You should see the hello world text. + From dc6ca7831a70badeb6a4464191180d5993dbd9d5 Mon Sep 17 00:00:00 2001 From: reeedo Date: Wed, 20 Mar 2013 15:06:37 -0700 Subject: [PATCH 14/21] Final validation updates, and add comments about Debug configuration. --- debugging/pydev.rst | 24 +++++++++++++++++------- 1 file changed, 17 insertions(+), 7 deletions(-) diff --git a/debugging/pydev.rst b/debugging/pydev.rst index ad318ab..1d7d9de 100644 --- a/debugging/pydev.rst +++ b/debugging/pydev.rst @@ -94,8 +94,8 @@ Remember also when using the PyDev console, to choose the interpreter associated with the project so that references in the console will be properly resolved. -Running Pyramid under Pydev ----------------------------------- +Running/Debugging Pyramid under Pydev +------------------------------------- (Thanks to Michael Wilson for much of this - see `Setting up Eclipse (PyDev) for Pyramid @@ -149,18 +149,28 @@ Add these values to the *Arguments* tab:: Do not add ``--reload`` if you are trying to debug with Eclipse. It has been reported that this causes problems. + + We recommend you create a separate debug configuration + without the ``--reload``, and instead of checking "Run" + in the "Display in favorites menu", check "Debug". On the *Common* tab:: Uncheck "Launch in background" - In the box labeled "Display in favorites menu", click "Run" + In the box labeled "Display in favorites menu", check "Run" -Hit *Run* to run your configuration immediately, or *Apply* to create the -configuration without running it. +Hit *Run* (*Debug*) to run (debug) your configuration immediately, +or *Apply* to create the configuration without running it. -You can now run your configuration at any time by selecting the *Run/Play -> -RunPyramid* button. +You can now run your application at any time by selecting the *Run/Play* +button and selecting the *RunPyramid* command. Similarly, you can +debug your application by selecting the *Debug* button and selecting +the *DebugPyramid* command (or whatever you called it!). The console should show that the server has started. To verify, open your browser to 127.0.0.1:6547. You should see the hello world text. +Note that when debugging, breakpoints can be set as with ordinary code, +but they will only be hit when the view containing the breakpoint +is served. + From d4d9b589e317d60c0915662581cb648edc9e6554 Mon Sep 17 00:00:00 2001 From: reeedo Date: Wed, 20 Mar 2013 16:15:46 -0700 Subject: [PATCH 15/21] added myself to CONTRIBUTORS --- CONTRIBUTORS.txt | 1 + 1 file changed, 1 insertion(+) diff --git a/CONTRIBUTORS.txt b/CONTRIBUTORS.txt index bdd9122..6504fd0 100644 --- a/CONTRIBUTORS.txt +++ b/CONTRIBUTORS.txt @@ -111,3 +111,4 @@ Paul Winkler, 1/30/2012 Doug Morgan, 03/12/2012 Josh Finnie, 03/13/2012 Tom Willis, 03/22/2012 +Larry Reed, 03/20/2013 From e8e8ed05209c766c152bd7016c6e5e1e5a06306d Mon Sep 17 00:00:00 2001 From: oneadvent Date: Sat, 23 Mar 2013 19:35:29 -0500 Subject: [PATCH 16/21] add mako requirement of context and an example of how to use it when checking if someone is authorized to view a template. --- templates/templates.rst | 21 +++++++++++++++++++++ 1 file changed, 21 insertions(+) diff --git a/templates/templates.rst b/templates/templates.rst index d3c6fbf..478bbb1 100644 --- a/templates/templates.rst +++ b/templates/templates.rst @@ -58,6 +58,27 @@ The value inserted into the template as the result of this statement will be You can add more imports and functions to ``helpers.py`` as necessary to make features available in your templates. +Usage in Mako Templating: +If you wanted to change templates using %inherit based on if a user was logged +in you could do the following:: + + @subscriber(BeforeRender) + def add_base_template(event): + request = event.get('request') + if request.user: + base = 'blaster:templates/logged_in_layout.mako' + event.update({'base': base}) + else: + base = 'blaster:templates/layout.mako' + event.update({'base': base}) + +and then in your mako file you can call %inherit like so:: + + <%inherit file="${context['base']}" /> + +Important note: you must call the variable this way because of the way Mako works +it will not know about any other variable until after %inherit is called. + Using a BeforeRender Event to Expose Chameleon ``base`` Template ---------------------------------------------------------------- From a76ac83f6486aecccee0d530c4abfb39d86f9869 Mon Sep 17 00:00:00 2001 From: oneadvent Date: Sun, 24 Mar 2013 18:57:03 -0500 Subject: [PATCH 17/21] using correct styling MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit via http://sphinx-doc.org/markup/para.html --- templates/templates.rst | 29 +++++++++++++++++------------ 1 file changed, 17 insertions(+), 12 deletions(-) diff --git a/templates/templates.rst b/templates/templates.rst index 478bbb1..68f39b6 100644 --- a/templates/templates.rst +++ b/templates/templates.rst @@ -60,24 +60,29 @@ features available in your templates. Usage in Mako Templating: If you wanted to change templates using %inherit based on if a user was logged -in you could do the following:: +in you could do the following: + +.. code-block:: python @subscriber(BeforeRender) - def add_base_template(event): - request = event.get('request') - if request.user: - base = 'blaster:templates/logged_in_layout.mako' - event.update({'base': base}) - else: - base = 'blaster:templates/layout.mako' - event.update({'base': base}) + def add_base_template(event): + request = event.get('request') + if request.user: + base = 'blaster:templates/logged_in_layout.mako' + event.update({'base': base}) + else: + base = 'blaster:templates/layout.mako' + event.update({'base': base}) + +and then in your mako file you can call %inherit like so -and then in your mako file you can call %inherit like so:: +.. code-block:: python <%inherit file="${context['base']}" /> -Important note: you must call the variable this way because of the way Mako works -it will not know about any other variable until after %inherit is called. +.. note:: +You must call the variable this way because of the way Mako works. +It will not know about any other variable until after %inherit is called. Using a BeforeRender Event to Expose Chameleon ``base`` Template From eb393b4a40a82b109c7d31361ed25402ed5d568b Mon Sep 17 00:00:00 2001 From: oneadvent Date: Sun, 24 Mar 2013 19:02:12 -0500 Subject: [PATCH 18/21] tabbing issue --- templates/templates.rst | 16 ++++++++-------- 1 file changed, 8 insertions(+), 8 deletions(-) diff --git a/templates/templates.rst b/templates/templates.rst index 68f39b6..455f375 100644 --- a/templates/templates.rst +++ b/templates/templates.rst @@ -65,14 +65,14 @@ in you could do the following: .. code-block:: python @subscriber(BeforeRender) - def add_base_template(event): - request = event.get('request') - if request.user: - base = 'blaster:templates/logged_in_layout.mako' - event.update({'base': base}) - else: - base = 'blaster:templates/layout.mako' - event.update({'base': base}) + def add_base_template(event): + request = event.get('request') + if request.user: + base = 'blaster:templates/logged_in_layout.mako' + event.update({'base': base}) + else: + base = 'blaster:templates/layout.mako' + event.update({'base': base}) and then in your mako file you can call %inherit like so From bad1d5e3f74ef643866214227792ae4195b7df48 Mon Sep 17 00:00:00 2001 From: Michael Merickel Date: Sun, 24 Mar 2013 23:04:40 -0500 Subject: [PATCH 19/21] fixed up Mako BeforeRender example --- templates/templates.rst | 38 ++++++++++++++++++++------------------ 1 file changed, 20 insertions(+), 18 deletions(-) diff --git a/templates/templates.rst b/templates/templates.rst index 455f375..2de2668 100644 --- a/templates/templates.rst +++ b/templates/templates.rst @@ -58,31 +58,33 @@ The value inserted into the template as the result of this statement will be You can add more imports and functions to ``helpers.py`` as necessary to make features available in your templates. -Usage in Mako Templating: -If you wanted to change templates using %inherit based on if a user was logged -in you could do the following: +Using a BeforeRender Event to Expose a Mako ``base`` Template +------------------------------------------------------------- -.. code-block:: python +If you wanted to change templates using ``%inherit`` based on if a user was +logged in you could do the following: - @subscriber(BeforeRender) - def add_base_template(event): - request = event.get('request') - if request.user: - base = 'blaster:templates/logged_in_layout.mako' - event.update({'base': base}) - else: - base = 'blaster:templates/layout.mako' - event.update({'base': base}) +.. code-block:: python -and then in your mako file you can call %inherit like so + @subscriber(BeforeRender) + def add_base_template(event): + request = event.get('request') + if request.user: + base = 'myapp:templates/logged_in_layout.mako' + event.update({'base': base}) + else: + base = 'myapp:templates/layout.mako' + event.update({'base': base}) -.. code-block:: python +And then in your mako file you can call %inherit like so:: <%inherit file="${context['base']}" /> -.. note:: -You must call the variable this way because of the way Mako works. -It will not know about any other variable until after %inherit is called. +You **must** call the variable this way because of the way Mako works. +It will not know about any other variable other than ``context`` until after +``%inherit`` is called. Be aware that ``context`` here is not the Pyramid +context in the traversal sense (which is stored in ``request.context``) but +rather the Mako rendering context. Using a BeforeRender Event to Expose Chameleon ``base`` Template From f1df45911aafbdfa190aad166daba4ebe3e037fc Mon Sep 17 00:00:00 2001 From: Philip Jenvey Date: Wed, 3 Apr 2013 12:45:39 -0700 Subject: [PATCH 20/21] simplify w/ shutil.copyfileobj, reword --- static_assets/files.rst | 22 +++++++--------------- 1 file changed, 7 insertions(+), 15 deletions(-) diff --git a/static_assets/files.rst b/static_assets/files.rst index 0040cc9..a5c7275 100644 --- a/static_assets/files.rst +++ b/static_assets/files.rst @@ -157,36 +157,28 @@ request object as a ``cgi.FieldStorage`` object accessible through the ``file`` and ``filename`` and we'll use those to write the file to disk:: import os + import shutil + from pyramid.response import Response def store_mp3_view(request): # ``filename`` contains the name of the file in string format. # - # WARNING: this example does not deal with the fact that IE sends an - # absolute file *path* as the filename. This example is naive; it - # trusts user input. - + # WARNING: Internet Explorer is known to send an absolute file + # *path* as the filename. This example is naive; it trusts + # user input. filename = request.POST['mp3'].filename # ``input_file`` contains the actual file data which needs to be # stored somewhere. - input_file = request.POST['mp3'].file # Using the filename like this without cleaning it is very # insecure so please keep that in mind when writing your own # file handling. file_path = os.path.join('/tmp', filename) - output_file = open(file_path, 'wb') - - # Finally write the data to the output file - input_file.seek(0) - while 1: - data = input_file.read(2<<16) - if not data: - break - output_file.write(data) - output_file.close() + with open(file_path, 'wb') as output_file: + shutil.copyfileobj(input_file, output_file) return Response('OK') From 1693870f89cc293bb6f357a2b2b057fa0dd78349 Mon Sep 17 00:00:00 2001 From: Tshepang Lekhonkhobe Date: Sat, 6 Apr 2013 23:44:30 +0200 Subject: [PATCH 21/21] add cross-ref target --- index.rst | 2 ++ 1 file changed, 2 insertions(+) diff --git a/index.rst b/index.rst index 19a0f0b..2cbb601 100644 --- a/index.rst +++ b/index.rst @@ -1,3 +1,5 @@ +.. _pyramid-cookbook: + Pyramid Cookbook ================