diff options
| author | Alexandre Bourget <alexandre.bourget@savoirfairelinux.com> | 2011-03-24 12:07:09 -0400 |
|---|---|---|
| committer | Alexandre Bourget <alexandre.bourget@savoirfairelinux.com> | 2011-03-24 12:07:09 -0400 |
| commit | 95e799d074de2e81914d513b4c331df1e738c00e (patch) | |
| tree | b3039037533610d8c86d82bb28f139d8a3777013 /docs/tutorials/wiki2 | |
| parent | 22d3253a26767501827d86b56db3a9b79bef6c4e (diff) | |
| parent | b596e1812627c359908759d7a8d83c339f08e385 (diff) | |
| download | pyramid-95e799d074de2e81914d513b4c331df1e738c00e.tar.gz pyramid-95e799d074de2e81914d513b4c331df1e738c00e.tar.bz2 pyramid-95e799d074de2e81914d513b4c331df1e738c00e.zip | |
Merge remote branch 'source/master'
Conflicts:
docs/narr/hooks.rst
Diffstat (limited to 'docs/tutorials/wiki2')
77 files changed, 1454 insertions, 1179 deletions
diff --git a/docs/tutorials/wiki2/authorization.rst b/docs/tutorials/wiki2/authorization.rst index 8d30ab807..64cab30db 100644 --- a/docs/tutorials/wiki2/authorization.rst +++ b/docs/tutorials/wiki2/authorization.rst @@ -27,43 +27,35 @@ Adding A Root Factory ~~~~~~~~~~~~~~~~~~~~~ We're going to start to use a custom :term:`root factory` within our -``__init__.py`` file. The objects generated by the root factory will be -used as the :term:`context` of each request to our application. In -order for :app:`Pyramid` declarative security to work properly, the -context object generated during a request must be decorated with -security declarations; when we begin to use a custom root factory to -generate our contexts, we can begin to make use of the declarative -security features of :app:`Pyramid`. +``__init__.py`` file. The objects generated by the root factory will be used +as the :term:`context` of each request to our application. We do this to +allow :app:`Pyramid` declarative security to work properly. The context +object generated by the root factory during a request will be decorated with +security declarations. When we begin to use a custom root factory to generate +our contexts, we can begin to make use of the declarative security features +of :app:`Pyramid`. We'll modify our ``__init__.py``, passing in a :term:`root factory` to our :term:`Configurator` constructor. We'll point it at a new class we create inside our ``models.py`` file. Add the following statements to your ``models.py`` file: -.. code-block:: python +.. literalinclude:: src/authorization/tutorial/models.py + :lines: 3-4,45-49 + :linenos: + :language: python - from pyramid.security import Allow - from pyramid.security import Everyone - - class RootFactory(object): - __acl__ = [ (Allow, Everyone, 'view'), - (Allow, 'group:editors', 'edit') ] - def __init__(self, request): - pass - -The ``RootFactory`` class we've just added will be used by -:app:`Pyramid` to construct a ``context`` object. The context is -attached to the request object passed to our view callables as the -``context`` attribute. - -All of our context objects will possess an ``__acl__`` attribute that -allows :data:`pyramid.security.Everyone` (a special principal) to -view all pages, while allowing only a :term:`principal` named -``group:editors`` to edit and add pages. The ``__acl__`` attribute -attached to a context is interpreted specially by :app:`Pyramid` as -an access control list during view callable execution. See -:ref:`assigning_acls` for more information about what an :term:`ACL` -represents. +The ``RootFactory`` class we've just added will be used by :app:`Pyramid` to +construct a ``context`` object. The context is attached to the request +object passed to our view callables as the ``context`` attribute. + +The context object generated by our root factory will possess an ``__acl__`` +attribute that allows :data:`pyramid.security.Everyone` (a special principal) +to view all pages, while allowing only a :term:`principal` named +``group:editors`` to edit and add pages. The ``__acl__`` attribute attached +to a context is interpreted specially by :app:`Pyramid` as an access control +list during view callable execution. See :ref:`assigning_acls` for more +information about what an :term:`ACL` represents. .. note: Although we don't use the functionality here, the ``factory`` used to create route contexts may differ per-route as opposed to globally. See @@ -84,30 +76,10 @@ For any :app:`Pyramid` application to perform authorization, we need to add a We'll change our ``__init__.py`` file to enable an ``AuthTktAuthenticationPolicy`` and an ``ACLAuthorizationPolicy`` to enable -declarative security checking. We'll also change ``__init__.py`` to add a -:meth:`pyramid.config.Configurator.add_view` call to points at our -``login`` :term:`view callable`, also known as a :term:`forbidden view`. -This configures our newly created login view to show up when :app:`Pyramid` -detects that a view invocation can not be authorized. Also, we'll add -``view_permission`` arguments with the value ``edit`` to the ``edit_page`` -and ``add_page`` routes. This indicates that the view callables which these -routes reference cannot be invoked without the authenticated user possessing -the ``edit`` permission with respect to the current context. - -This makes the assertion that only users who possess the effective ``edit`` -permission at the time of the request may invoke those two views. We've -granted the ``group:editors`` principal the ``edit`` permission at the root -model via its ACL, so only the a user whom is a member of the group named -``group:editors`` will able to invoke the views associated with the -``add_page`` or ``edit_page`` routes. - -Viewing Your Changes -~~~~~~~~~~~~~~~~~~~~ - -When we're done configuring a root factory, adding an authorization policy, -and adding views, your application's ``__init__.py`` will look like this: +declarative security checking. .. literalinclude:: src/authorization/tutorial/__init__.py + :lines: 15-21 :linenos: :language: python @@ -120,12 +92,52 @@ representing a :term:`dotted Python name`, which points at the ``groupfinder`` function in the current directory's ``security.py`` file. We haven't added that module yet, but we're about to. +We'll also change ``__init__.py``, adding a call to +:meth:`pyramid.config.Configurator.add_view` that points at our ``login`` +:term:`view callable`. This is also known as a :term:`forbidden view`: + +.. literalinclude:: src/authorization/tutorial/__init__.py + :lines: 24-26 + :linenos: + :language: python + +A forbidden view configures our newly created login view to show up when +:app:`Pyramid` detects that a view invocation can not be authorized. + +We'll also add ``view_permission`` arguments with the value ``edit`` to the +``edit_page`` and ``add_page`` routes. This indicates that the view +callables which these routes reference cannot be invoked without the +authenticated user possessing the ``edit`` permission with respect to the +current context. + +.. literalinclude:: src/authorization/tutorial/__init__.py + :lines: 32-39 + :linenos: + :language: python + +Adding these ``view_permission`` arguments causes Pyramid to make the +assertion that only users who possess the effective ``edit`` permission at +the time of the request may invoke those two views. We've granted the +``group:editors`` principal the ``edit`` permission at the root model via its +ACL, so only the a user whom is a member of the group named ``group:editors`` +will able to invoke the views associated with the ``add_page`` or +``edit_page`` routes. + +Viewing Your Changes +~~~~~~~~~~~~~~~~~~~~ + +When we're done configuring a root factory, adding an authorization policy, +and adding views, your application's ``__init__.py`` will look like this: + +.. literalinclude:: src/authorization/tutorial/__init__.py + :linenos: + :language: python Adding ``security.py`` ~~~~~~~~~~~~~~~~~~~~~~ Add a ``security.py`` module within your package (in the same directory as -"__init__.py", "views.py", etc) with the following content: +:file:`__init__.py`, :file:`views.py`, etc) with the following content: .. literalinclude:: src/authorization/tutorial/security.py :linenos: @@ -161,7 +173,7 @@ provide a link to it. This view will clear the credentials of the logged in user and redirect back to the front page. We'll add a different file (for presentation convenience) to add login -and logout view callables. Add a file named ``login.py`` to your +and the logout view callables. Add a file named ``login.py`` to your application (in the same directory as ``views.py``) with the following content: @@ -173,8 +185,8 @@ Changing Existing Views ~~~~~~~~~~~~~~~~~~~~~~~ Then we need to change each of our ``view_page``, ``edit_page`` and -``add_page`` views in ``views.py`` to pass a "logged in" parameter to -its template. We'll add something like this to each view body: +``add_page`` views in ``views.py`` to pass a "logged in" parameter to its +template. We'll add something like this to each view body: .. ignore-next-block .. code-block:: python @@ -183,8 +195,8 @@ its template. We'll add something like this to each view body: from pyramid.security import authenticated_userid logged_in = authenticated_userid(request) -We'll then change the return value of these views to pass the -`resulting `logged_in`` value to the template, e.g.: +We'll then change the return value of these views to pass the `resulting +`logged_in`` value to the template, e.g.: .. ignore-next-block .. code-block:: python @@ -202,7 +214,6 @@ Add a ``login.pt`` template to your templates directory. It's referred to within the login view we just added to ``login.py``. .. literalinclude:: src/authorization/tutorial/templates/login.pt - :linenos: :language: xml Change ``view.pt`` and ``edit.pt`` @@ -212,11 +223,10 @@ We'll also need to change our ``edit.pt`` and ``view.pt`` templates to display a "Logout" link if someone is logged in. This link will invoke the logout view. -To do so we'll add this to both templates within the ``<div -class="main_content">`` div: +To do so we'll add this to both templates within the ``<div id="right" +class="app-welcome align-right">`` div: .. code-block:: xml - :linenos: <span tal:condition="logged_in"> <a href="${request.application_url}/logout">Logout</a> @@ -261,13 +271,11 @@ Our ``views.py`` module will look something like this when we're done: Our ``edit.pt`` template will look something like this when we're done: .. literalinclude:: src/authorization/tutorial/templates/edit.pt - :linenos: :language: xml Our ``view.pt`` template will look something like this when we're done: .. literalinclude:: src/authorization/tutorial/templates/view.pt - :linenos: :language: xml Revisiting the Application @@ -279,5 +287,3 @@ of hitting an edit or add page and submitting the login form with the hand corner. When we click it, we're logged out, and redirected back to the front page. - - diff --git a/docs/tutorials/wiki2/basiclayout.rst b/docs/tutorials/wiki2/basiclayout.rst index 565bd0e96..4d3496788 100644 --- a/docs/tutorials/wiki2/basiclayout.rst +++ b/docs/tutorials/wiki2/basiclayout.rst @@ -2,10 +2,9 @@ Basic Layout ============ -The starter files generated by the ``pyramid_routesalchemy`` template -are basic, but they provide a good orientation for the high-level -patterns common to most :term:`url dispatch` -based :app:`Pyramid` -projects. +The starter files generated by the ``pyramid_routesalchemy`` template are +basic, but they provide a good orientation for the high-level patterns common +to most :term:`url dispatch` -based :app:`Pyramid` projects. The source code for this tutorial stage can be browsed at `http://github.com/Pylons/pyramid/tree/master/docs/tutorials/wiki2/src/basiclayout/ @@ -23,58 +22,94 @@ The generated ``development.ini`` file is read by ``paster`` which looks for the application module in the ``use`` variable of the ``app:tutorial`` section. The *entry point* is defined in the Setuptools configuration of this module, specifically in the ``setup.py`` file. For this tutorial, the *entry -point* is defined as ``tutorial:main`` and points to the following ``main`` -function: +point* is defined as ``tutorial:main`` and points to a function named ``main``. + +First we need some imports to support later code: + + .. literalinclude:: src/basiclayout/tutorial/__init__.py + :end-before: main + :linenos: + :language: py + +Next we define the main function and create a SQLAlchemy database engine from +the ``sqlalchemy.`` prefixed settings in the ``development.ini`` file's +``[app:tutorial]`` section. This will be a URI (something like +``sqlite://``): .. literalinclude:: src/basiclayout/tutorial/__init__.py + :lines: 6-9 :linenos: :language: py -#. *Lines 1-4*. Imports to support later code. - -#. *Line 9*. Create a SQLAlchemy database engine from the ``sqlalchemy.`` - prefixed settings in the ``development.ini`` file's ``[app:tutorial]`` - section. This will be a URI (something like ``sqlite://``). - -#. *Line 10*. We initialize our SQL database using SQLAlchemy, passing - it the engine - -#. *Line 11*. We construct a :term:`Configurator`. ``settings`` is - passed as a keyword argument with the dictionary values passed by - PasteDeploy as the ``settings`` argument. This will be a - dictionary of settings parsed by PasteDeploy, which contains - deployment-related values such as ``reload_templates``, - ``db_string``, etc. - -#. *Line 12*. We call - :meth:`pyramid.config.Configurator.add_static_view` with the - arguments ``static`` (the name), and ``tutorial:static`` (the path). This - registers a static resource view which will match any URL that starts with - ``/static/``. This will serve up static resources for us from within the - ``static`` directory of our ``tutorial`` package, in this case, - via ``http://localhost:6543/static/`` and below. With this declaration, - we're saying that any URL that starts with ``/static`` should go to the - static view; any remainder of its path (e.g. the ``/foo`` in - ``/static/foo``) will be used to compose a path to a static file resource, - such as a CSS file. - -#. *Lines 13-14*. Register a :term:`route configuration` via the - :meth:`pyramid.config.Configurator.add_route` method that will be - used when the URL is ``/``. Since this route has an ``pattern`` equalling - ``/`` it is the "default" route. The argument named ``view`` with the - value ``tutorial.views.my_view`` is the dotted name to a *function* we - write (generated by the ``pyramid_routesalchemy`` template) that is given - a ``request`` object and which returns a response or a dictionary. You - will use :meth:`pyramid.config.Configurator.add_route` statements - in a :term:`URL dispatch` based application to map URLs to code. This - route also names a ``view_renderer``, which is a template which lives in - the ``templates`` subdirectory of the package. When the - ``tutorial.views.my_view`` view returns a dictionary, a :term:`renderer` - will use this template to create a response. - -#. *Line 15*. We use the - :meth:`pyramid.config.Configurator.make_wsgi_app` method to return - a :term:`WSGI` application. +We then initialize our SQL database using SQLAlchemy, passing +it the engine: + + .. literalinclude:: src/basiclayout/tutorial/__init__.py + :lines: 10 + :language: py + +The next step is to construct a :term:`Configurator`: + + .. literalinclude:: src/basiclayout/tutorial/__init__.py + :lines: 11 + :language: py + +``settings`` is passed to the Configurator as a keyword argument with the +dictionary values passed by PasteDeploy as the ``**settings`` argument. This +will be a dictionary of settings parsed from the ``.ini`` file, which +contains deployment-related values such as ``reload_templates``, +``db_string``, etc. + +We now can call :meth:`pyramid.config.Configurator.add_static_view` with the +arguments ``static`` (the name), and ``tutorial:static`` (the path): + + .. literalinclude:: src/basiclayout/tutorial/__init__.py + :lines: 12 + :language: py + +This registers a static resource view which will match any URL that starts with +``/static/``. This will serve up static resources for us from within the +``static`` directory of our ``tutorial`` package, in this case, +via ``http://localhost:6543/static/`` and below. With this declaration, +we're saying that any URL that starts with ``/static`` should go to the +static view; any remainder of its path (e.g. the ``/foo`` in +``/static/foo``) will be used to compose a path to a static file resource, +such as a CSS file. + +Using the configurator we can also register a :term:`route configuration` +via the :meth:`pyramid.config.Configurator.add_route` method that will be +used when the URL is ``/``: + + .. literalinclude:: src/basiclayout/tutorial/__init__.py + :lines: 13-14 + :language: py + +Since this route has a ``pattern`` equalling ``/`` it is the route that will +be called when the URL ``/`` is visted, e.g. ``http://localhost:6543/``. The +argument named ``view`` with the value ``tutorial.views.my_view`` is the +dotted name to a *function* we write (generated by the +``pyramid_routesalchemy`` template) that is given a ``request`` object and +which returns a response or a dictionary. + +You will use :meth:`pyramid.config.Configurator.add_route` statements in a +:term:`URL dispatch` based application to map URLs to code. This route also +names a ``view_renderer``, which is a template which lives in the +``templates`` subdirectory of the package. When the +``tutorial.views.my_view`` view returns a dictionary, a :term:`renderer` will +use this template to create a response. + +Fimnally, we use the :meth:`pyramid.config.Configurator.make_wsgi_app` +method to return a :term:`WSGI` application: + + .. literalinclude:: src/basiclayout/tutorial/__init__.py + :lines: 15 + :language: py + +Our final ``__init__.py`` file will look like this: + + .. literalinclude:: src/basiclayout/tutorial/__init__.py + :linenos: + :language: py Content Models with ``models.py`` --------------------------------- @@ -85,34 +120,64 @@ SQLAlchemy is an "object relational mapper" (an ORM). The ``models.py`` file is where the ``pyramid_routesalchemy`` Paster template put the classes that implement our models. -Here is the source for ``models.py``: +Let's take a look. First, we need some imports to support later code. .. literalinclude:: src/basiclayout/tutorial/models.py + :end-before: DBSession :linenos: :language: py -#. *Lines 1-13*. Imports to support later code. +Next we set up a SQLAlchemy "DBSession" object: + + .. literalinclude:: src/basiclayout/tutorial/models.py + :lines: 15-16 + :linenos: + :language: py -#. *Line 15*. We set up a SQLAlchemy "DBSession" object here. We - specify that we'd like to use the "ZopeTransactionExtension". This - extension is an extension which allows us to use a *transaction - manager* instead of controlling commits and aborts to database - operations by hand. +We also need to create a declarative ``Base`` object to use as a +base class for our model: -#. *Line 16*. We create a declarative ``Base`` object to use as a - base class for our model. + .. literalinclude:: src/basiclayout/tutorial/models.py + :lines: 17 + :language: py + +To give a simple example of a model class, we define one named ``MyModel``: + + .. literalinclude:: src/basiclayout/tutorial/models.py + :pyobject: MyModel + :linenos: + :language: py -#. *Lines 18-26*. A model class named ``MyModel``. It has an - ``__init__`` that takes a two arguments (``name``, and ``value``). - It stores these values as ``self.name`` and ``self.value`` within - the ``__init__`` function itself. The ``MyModel`` class also has a - ``__tablename__`` attribute. This informs SQLAlchemy which table - to use to store the data representing instances of this class. +Our sample model has an ``__init__`` that takes a two arguments (``name``, +and ``value``). It stores these values as ``self.name`` and ``self.value`` +within the ``__init__`` function itself. The ``MyModel`` class also has a +``__tablename__`` attribute. This informs SQLAlchemy which table to use to +store the data representing instances of this class. -#. *Lines 28-33*. A function named ``populate`` which adds a single - model instance into our SQL storage and commits a transaction. +Next we define a function named ``populate`` which adds a single +model instance into our SQL storage and commits a transaction: -#. *Lines 35-42*. A function named ``initialize_sql`` which receives a SQL - database engine and binds it to our SQLAlchemy DBSession object. It also - calls the ``populate`` function, to do initial database population. + .. literalinclude:: src/basiclayout/tutorial/models.py + :pyobject: populate + :linenos: + :language: py + +The function doesn't do a lot in this case, but it's there to illustrate +how an application requiring many objects to be set up could work. + +Lastly we have a function named ``initialize_sql`` which receives a SQL +database engine and binds it to our SQLAlchemy DBSession object. It also +calls the ``populate`` function, to do initial database population. This +is the initialization function that is called from __init__.py above. + + .. literalinclude:: src/basiclayout/tutorial/models.py + :pyobject: initialize_sql + :linenos: + :language: py + +Here is the complete source for ``models.py``: + + .. literalinclude:: src/basiclayout/tutorial/models.py + :linenos: + :language: py diff --git a/docs/tutorials/wiki2/definingmodels.rst b/docs/tutorials/wiki2/definingmodels.rst index 09e1f26c3..7e8555190 100644 --- a/docs/tutorials/wiki2/definingmodels.rst +++ b/docs/tutorials/wiki2/definingmodels.rst @@ -31,28 +31,39 @@ application, this class should inherit from an instance of :class:`sqlalchemy.ext.declarative.declarative_base`. Declarative SQLAlchemy models are easier to use than directly-mapped ones. -Our ``Page`` class will have a class level attribute ``__tablename__`` which -equals the string ``pages``. This means that SQLAlchemy will store our wiki -data in a SQL table named ``pages``. Our Page class will also have -class-level attributes named ``id``, ``pagename`` and ``data`` (all instances -of :class:`sqlalchemy.Column`). These will map to columns in the ``pages`` -table. The ``id`` attribute will be the primary key in the table. The -``name`` attribute will be a text attribute, each value of which needs to be -unique within the column. The ``data`` attribute is a text attribute that -will hold the body of each page. - -We'll also remove our ``populate`` function. We'll inline the -populate step into ``initialize_sql``, changing our ``initialize_sql`` -function to add a FrontPage object to our database at startup time. -We're also going to use slightly different binding syntax. It will -will otherwise largely be the same as the ``initialize_sql`` in the -paster-generated ``models.py``. +.. literalinclude:: src/models/tutorial/models.py + :pyobject: Page + :linenos: + :language: python + +As you can see, our ``Page`` class has a class level attribute +``__tablename__`` which equals the string ``pages``. This means that +SQLAlchemy will store our wiki data in a SQL table named ``pages``. Our Page +class will also have class-level attributes named ``id``, ``pagename`` and +``data`` (all instances of :class:`sqlalchemy.Column`). These will map to +columns in the ``pages`` table. The ``id`` attribute will be the primary key +in the table. The ``name`` attribute will be a text attribute, each value of +which needs to be unique within the column. The ``data`` attribute is a text +attribute that will hold the body of each page. + +We'll also remove our ``populate`` function. We'll inline the populate step +into ``initialize_sql``, changing our ``initialize_sql`` function to add a +FrontPage object to our database at startup time. + +.. literalinclude:: src/models/tutorial/models.py + :pyobject: initialize_sql + :linenos: + :language: python + +Here, we're using a slightly different binding syntax. It is otherwise +largely the same as the ``initialize_sql`` in the paster-generated +``models.py``. Our DBSession assignment stays the same as the original generated ``models.py``. -Looking at the Result of Our Edits to ``models.py`` ---------------------------------------------------- +Looking at the Result of all Our Edits to ``models.py`` +------------------------------------------------------- The result of all of our edits to ``models.py`` will end up looking something like this: @@ -64,11 +75,10 @@ something like this: Viewing the Application in a Browser ------------------------------------ -We can't. At this point, our system is in a "non-runnable" state; -we'll need to change view-related files in the next chapter to be able -to start the application successfully. If you try to start the -application, you'll wind up with a Python traceback on your console -that ends with this exception: +We can't. At this point, our system is in a "non-runnable" state; we'll need +to change view-related files in the next chapter to be able to start the +application successfully. If you try to start the application, you'll wind +up with a Python traceback on your console that ends with this exception: .. code-block:: text diff --git a/docs/tutorials/wiki2/definingviews.rst b/docs/tutorials/wiki2/definingviews.rst index e3d611136..874c49d4c 100644 --- a/docs/tutorials/wiki2/definingviews.rst +++ b/docs/tutorials/wiki2/definingviews.rst @@ -2,10 +2,10 @@ Defining Views ============== -A :term:`view callable` in a :term:`url dispatch` -based -:app:`Pyramid` application is typically a simple Python function that -accepts a single parameter named :term:`request`. A view callable is -assumed to return a :term:`response` object. +A :term:`view callable` in a :term:`url dispatch` -based :app:`Pyramid` +application is typically a simple Python function that accepts a single +parameter named :term:`request`. A view callable is assumed to return a +:term:`response` object. .. note:: A :app:`Pyramid` view can also be defined as callable which accepts *two* arguments: a :term:`context` and a @@ -23,11 +23,11 @@ assumed to return a :term:`response` object. The request passed to every view that is called as the result of a route match has an attribute named ``matchdict`` that contains the elements placed into the URL by the ``pattern`` of a ``route`` statement. For instance, if a -call to :meth:`pyramid.config.Configurator.add_route` in -``__init__.py`` had the pattern ``{one}/{two}``, and the URL at -``http://example.com/foo/bar`` was invoked, matching this pattern, the -matchdict dictionary attached to the request passed to the view would have a -``one`` key with the value ``foo`` and a ``two`` key with the value ``bar``. +call to :meth:`pyramid.config.Configurator.add_route` in ``__init__.py`` had +the pattern ``{one}/{two}``, and the URL at ``http://example.com/foo/bar`` +was invoked, matching this pattern, the matchdict dictionary attached to the +request passed to the view would have a ``one`` key with the value ``foo`` +and a ``two`` key with the value ``bar``. The source code for this tutorial stage can be browsed at `http://github.com/Pylons/pyramid/tree/master/docs/tutorials/wiki2/src/views/ @@ -36,13 +36,13 @@ The source code for this tutorial stage can be browsed at Declaring Dependencies in Our ``setup.py`` File =============================================== -The view code in our application will depend on a package which is not -a dependency of the original "tutorial" application. The original -"tutorial" application was generated by the ``paster create`` command; -it doesn't know about our custom application requirements. We need to -add a dependency on the ``docutils`` package to our ``tutorial`` -package's ``setup.py`` file by assigning this dependency to the -``install_requires`` parameter in the ``setup`` function. +The view code in our application will depend on a package which is not a +dependency of the original "tutorial" application. The original "tutorial" +application was generated by the ``paster create`` command; it doesn't know +about our custom application requirements. We need to add a dependency on +the ``docutils`` package to our ``tutorial`` package's ``setup.py`` file by +assigning this dependency to the ``install_requires`` parameter in the +``setup`` function. Our resulting ``setup.py`` should look like so: @@ -58,38 +58,43 @@ Our resulting ``setup.py`` should look like so: Adding View Functions ===================== -We'll get rid of our ``my_view`` view function in our ``views.py`` -file. It's only an example and isn't relevant to our application. +We'll get rid of our ``my_view`` view function in our ``views.py`` file. +It's only an example and isn't relevant to our application. Then we're going to add four :term:`view callable` functions to our -``views.py`` module. One view callable (named ``view_wiki``) will -display the wiki itself (it will answer on the root URL), another -named ``view_page`` will display an individual page, another named -``add_page`` will allow a page to be added, and a final view callable -named ``edit_page`` will allow a page to be edited. We'll describe -each one briefly and show the resulting ``views.py`` file afterward. +``views.py`` module. One view callable (named ``view_wiki``) will display +the wiki itself (it will answer on the root URL), another named ``view_page`` +will display an individual page, another named ``add_page`` will allow a page +to be added, and a final view callable named ``edit_page`` will allow a page +to be edited. We'll describe each one briefly and show the resulting +``views.py`` file afterward. .. note:: - There is nothing special about the filename ``views.py``. A project - may have many view callables throughout its codebase in - arbitrarily-named files. Files implementing view callables often - have ``view`` in their filenames (or may live in a Python subpackage - of your application package named ``views``), but this is only by - convention. + There is nothing special about the filename ``views.py``. A project may + have many view callables throughout its codebase in arbitrarily-named + files. Files implementing view callables often have ``view`` in their + filenames (or may live in a Python subpackage of your application package + named ``views``), but this is only by convention. The ``view_wiki`` view function ------------------------------- -The ``view_wiki`` function will respond as the :term:`default view` of -a ``Wiki`` model object. It always redirects to a URL which -represents the path to our "FrontPage". It returns an instance of the -:class:`pyramid.httpexceptions.HTTPFound` class (instances of which -implement the WebOb :term:`response` interface), It will use the -:func:`pyramid.url.route_url` API to construct a URL to the -``FrontPage`` page (e.g. ``http://localhost:6543/FrontPage``), and -will use it as the "location" of the HTTPFound response, forming an -HTTP redirect. +The ``view_wiki`` function will respond as the :term:`default view` of a +``Wiki`` model object. It always redirects to a URL which represents the +path to our "FrontPage". + +.. literalinclude:: src/views/tutorial/views.py + :pyobject: view_wiki + :linenos: + :language: python + +The ``view_wiki`` function returns an instance of the +:class:`pyramid.httpexceptions.HTTPFound` class (instances of which implement +the WebOb :term:`response` interface), It will use the +:func:`pyramid.url.route_url` API to construct a URL to the ``FrontPage`` +page (e.g. ``http://localhost:6543/FrontPage``), and will use it as the +"location" of the HTTPFound response, forming an HTTP redirect. The ``view_page`` view function ------------------------------- @@ -101,88 +106,95 @@ attribute of a Page object) as HTML. Then it substitutes an HTML anchor for each *WikiWord* reference in the rendered HTML using a compiled regular expression. +.. literalinclude:: src/views/tutorial/views.py + :pyobject: view_page + :linenos: + :language: python + The curried function named ``check`` is used as the first argument to -``wikiwords.sub``, indicating that it should be called to provide a -value for each WikiWord match found in the content. If the wiki -already contains a page with the matched WikiWord name, the ``check`` -function generates a view link to be used as the substitution value -and returns it. If the wiki does not already contain a page with with -the matched WikiWord name, the function generates an "add" link as the -substitution value and returns it. - -As a result, the ``content`` variable is now a fully formed bit of -HTML containing various view and add links for WikiWords based on the -content of our current page object. - -We then generate an edit URL (because it's easier to do here than in -the template), and we return a dictionary with a number of arguments. -The fact that this view returns a dictionary (as opposed to a -:term:`response` object) is a cue to :app:`Pyramid` that it should -try to use a :term:`renderer` associated with the view configuration -to render a template. In our case, the template which will be -rendered will be the ``templates/view.pt`` template, as per the -configuration put into effect in ``__init__.py``. +``wikiwords.sub``, indicating that it should be called to provide a value for +each WikiWord match found in the content. If the wiki already contains a +page with the matched WikiWord name, the ``check`` function generates a view +link to be used as the substitution value and returns it. If the wiki does +not already contain a page with with the matched WikiWord name, the function +generates an "add" link as the substitution value and returns it. + +As a result, the ``content`` variable is now a fully formed bit of HTML +containing various view and add links for WikiWords based on the content of +our current page object. + +We then generate an edit URL (because it's easier to do here than in the +template), and we return a dictionary with a number of arguments. The fact +that this view returns a dictionary (as opposed to a :term:`response` object) +is a cue to :app:`Pyramid` that it should try to use a :term:`renderer` +associated with the view configuration to render a template. In our case, +the template which will be rendered will be the ``templates/view.pt`` +template, as per the configuration put into effect in ``__init__.py``. The ``add_page`` view function ------------------------------ -The ``add_page`` function will be invoked when a user clicks on a -*WikiWord* which isn't yet represented as a page in the system. The -``check`` function within the ``view_page`` view generates URLs to -this view. It also acts as a handler for the form that is generated -when we want to add a page object. The ``matchdict`` attribute of the -request passed to the ``add_page`` view will have the values we need -to construct URLs and find model objects. +The ``add_page`` function will be invoked when a user clicks on a *WikiWord* +which isn't yet represented as a page in the system. The ``check`` function +within the ``view_page`` view generates URLs to this view. It also acts as a +handler for the form that is generated when we want to add a page object. +The ``matchdict`` attribute of the request passed to the ``add_page`` view +will have the values we need to construct URLs and find model objects. + +.. literalinclude:: src/views/tutorial/views.py + :pyobject: add_page + :linenos: + :language: python -The matchdict will have a ``pagename`` key that matches the name of -the page we'd like to add. If our add view is invoked via, -e.g. ``http://localhost:6543/add_page/SomeName``, the ``pagename`` -value in the matchdict will be ``SomeName``. +The matchdict will have a ``pagename`` key that matches the name of the page +we'd like to add. If our add view is invoked via, +e.g. ``http://localhost:6543/add_page/SomeName``, the ``pagename`` value in +the matchdict will be ``SomeName``. If the view execution is *not* a result of a form submission (if the -expression ``'form.submitted' in request.params`` is ``False``), the -view callable renders a template. To do so, it generates a "save url" -which the template use as the form post URL during rendering. We're -lazy here, so we're trying to use the same template -(``templates/edit.pt``) for the add view as well as the page edit -view, so we create a dummy Page object in order to satisfy the edit -form's desire to have *some* page object exposed as ``page``, and -:app:`Pyramid` will render the template associated with this view -to a response. - -If the view execution *is* a result of a form submission (if the -expression ``'form.submitted' in request.params`` is ``True``), we -scrape the page body from the form data, create a Page object using -the name in the matchdict ``pagename``, and obtain the page body from -the request, and save it into the database using ``session.add``. We -then redirect back to the ``view_page`` view (the :term:`default view` -for a Page) for the newly created page. +expression ``'form.submitted' in request.params`` is ``False``), the view +callable renders a template. To do so, it generates a "save url" which the +template use as the form post URL during rendering. We're lazy here, so +we're trying to use the same template (``templates/edit.pt``) for the add +view as well as the page edit view, so we create a dummy Page object in order +to satisfy the edit form's desire to have *some* page object exposed as +``page``, and :app:`Pyramid` will render the template associated with this +view to a response. + +If the view execution *is* a result of a form submission (if the expression +``'form.submitted' in request.params`` is ``True``), we scrape the page body +from the form data, create a Page object using the name in the matchdict +``pagename``, and obtain the page body from the request, and save it into the +database using ``session.add``. We then redirect back to the ``view_page`` +view (the :term:`default view` for a Page) for the newly created page. The ``edit_page`` view function ------------------------------- -The ``edit_page`` function will be invoked when a user clicks the -"Edit this Page" button on the view form. It renders an edit form but -it also acts as the handler for the form it renders. The -``matchdict`` attribute of the request passed to the ``add_page`` view -will have a ``pagename`` key matching the name of the page the user -wants to edit. +The ``edit_page`` function will be invoked when a user clicks the "Edit this +Page" button on the view form. It renders an edit form but it also acts as +the handler for the form it renders. The ``matchdict`` attribute of the +request passed to the ``edit_page`` view will have a ``pagename`` key +matching the name of the page the user wants to edit. + +.. literalinclude:: src/views/tutorial/views.py + :pyobject: edit_page + :linenos: + :language: python If the view execution is *not* a result of a form submission (if the -expression ``'form.submitted' in request.params`` is ``False``), the -view simply renders the edit form, passing the request, the page -object, and a save_url which will be used as the action of the -generated form. - -If the view execution *is* a result of a form submission (if the -expression ``'form.submitted' in request.params`` is ``True``), the -view grabs the ``body`` element of the request parameter and sets it -as the ``data`` key in the matchdict. It then redirects to the -default view of the wiki page, which will always be the ``view_page`` -view. - -Viewing the Result of Our Edits to ``views.py`` -=============================================== +expression ``'form.submitted' in request.params`` is ``False``), the view +simply renders the edit form, passing the request, the page object, and a +save_url which will be used as the action of the generated form. + +If the view execution *is* a result of a form submission (if the expression +``'form.submitted' in request.params`` is ``True``), the view grabs the +``body`` element of the request parameter and sets it as the ``data`` +attribute of the page object. It then redirects to the default view of the +wiki page, which will always be the ``view_page`` view. + +Viewing the Result of all Our Edits to ``views.py`` +=================================================== The result of all of our edits to ``views.py`` will leave it looking like this: @@ -201,18 +213,16 @@ The views we've added all reference a :term:`template`. Each template is a The ``view.pt`` Template ------------------------ -The ``view.pt`` template is used for viewing a single wiki page. It -is used by the ``view_page`` view function. It should have a div that -is "structure replaced" with the ``content`` value provided by the -view. It should also have a link on the rendered page that points at -the "edit" URL (the URL which invokes the ``edit_page`` view for the -page being viewed). +The ``view.pt`` template is used for viewing a single wiki page. It is used +by the ``view_page`` view function. It should have a div that is "structure +replaced" with the ``content`` value provided by the view. It should also +have a link on the rendered page that points at the "edit" URL (the URL which +invokes the ``edit_page`` view for the page being viewed). -Once we're done with the ``view.pt`` template, it will look a lot like -the below: +Once we're done with the ``view.pt`` template, it will look a lot like the +below: .. literalinclude:: src/views/tutorial/templates/view.pt - :linenos: :language: xml .. note:: The names available for our use in a template are always @@ -228,37 +238,35 @@ the below: The ``edit.pt`` Template ------------------------ -The ``edit.pt`` template is used for adding and editing a wiki page. -It is used by the ``add_page`` and ``edit_page`` view functions. It -should display a page containing a form that POSTs back to the -"save_url" argument supplied by the view. The form should have a -"body" textarea field (the page data), and a submit button that has -the name "form.submitted". The textarea in the form should be filled -with any existing page data when it is rendered. +The ``edit.pt`` template is used for adding and editing a wiki page. It is +used by the ``add_page`` and ``edit_page`` view functions. It should display +a page containing a form that POSTs back to the "save_url" argument supplied +by the view. The form should have a "body" textarea field (the page data), +and a submit button that has the name "form.submitted". The textarea in the +form should be filled with any existing page data when it is rendered. Once we're done with the ``edit.pt`` template, it will look a lot like the below: .. literalinclude:: src/views/tutorial/templates/edit.pt - :linenos: :language: xml -Static Resources ----------------- - -Our templates name a single static resource named ``style.css``. We need to -create this and place it in a file named ``style.css`` within our package's -``static`` directory. This file is a little too long to replicate within the -body of this guide, however it is available `online -<http://github.com/Pylons/pyramid/blob/master/docs/tutorials/wiki2/src/views/tutorial/static/style.css>`_. +Static Assets +------------- +Our templates name a single static asset named ``pylons.css``. We don't need +to create this file within our package's ``static`` directory because it was +provided at the time we created the project. This file is a little too long +to replicate within the body of this guide, however it is available `online +<http://github.com/Pylons/pyramid/blob/master/docs/tutorials/wiki2/src/views/tutorial/static/pylons.css>`_. This CSS file will be accessed via -e.g. ``http://localhost:6543/static/style.css`` by virtue of the call we've -made to :meth:`pyramid.config.Configurator.add_static_view` within our -``__init__.py`` file. Any number and type of static resources can be placed -in this directory (or subdirectories) and are just referred to by URL within -templates. +e.g. ``http://localhost:6543/static/pylons.css`` by virtue of the call to +``add_static_view`` directive we've made in the ``__init__`` file. Any +number and type of static assets can be placed in this directory (or +subdirectories) and are just referred to by URL or by using the convenience +method ``static_url`` +e.g. ``request.static_url('{{package}}:static/foo.css')`` within templates. Mapping Views to URLs in ``__init__.py`` ======================================== diff --git a/docs/tutorials/wiki2/distributing.rst b/docs/tutorials/wiki2/distributing.rst index f4421e145..c80b43337 100644 --- a/docs/tutorials/wiki2/distributing.rst +++ b/docs/tutorials/wiki2/distributing.rst @@ -18,14 +18,7 @@ On Windows: .. code-block:: text - c:\bigfntut> ..\Scripts\python setup.py sdist - -.. warning:: If your project files are not checked in to a version - control repository (such as Subversion), the dist tarball will - *not* contain all the files it needs to. In particular, it will - not contain non-Python-source files (such as templates and static - files). To ensure that these are included, check your files into a - version control repository before running ``setup.py sdist``. + c:\pyramidtut> ..\Scripts\python setup.py sdist The output of such a command will be something like: diff --git a/docs/tutorials/wiki2/index.rst b/docs/tutorials/wiki2/index.rst index 03b405048..1aff949b9 100644 --- a/docs/tutorials/wiki2/index.rst +++ b/docs/tutorials/wiki2/index.rst @@ -1,7 +1,7 @@ .. _bfg_sql_wiki_tutorial: -SQLAlchemy + URL Dispatch Wiki Tutorial (For Developers Familiar with Pylons 1) -=============================================================================== +SQLAlchemy + URL Dispatch Wiki Tutorial +======================================= This tutorial introduces a :term:`SQLAlchemy` and :term:`url dispatch` -based :app:`Pyramid` application to a developer familiar with Python, and will be diff --git a/docs/tutorials/wiki2/installation.rst b/docs/tutorials/wiki2/installation.rst index e6fd5e6b9..ed81e3774 100644 --- a/docs/tutorials/wiki2/installation.rst +++ b/docs/tutorials/wiki2/installation.rst @@ -2,10 +2,9 @@ Installation ============ -For the most part, the installation process for this tutorial -duplicates the steps described in :ref:`installing_chapter` and -:ref:`project_narr`, however it also explains how to install -additional libraries for tutorial purposes. +This tutorial assumes that Python and virtualenv are already installed +and working in your system. If you need help setting this up, you should +refer to the chapters on :ref:`installing_chapter`. Preparation =========== @@ -22,39 +21,17 @@ Preparation, UNIX manager. For example, on a Debian Linux system, do ``sudo apt-get install libsqlite3-dev``. -#. If you don't already have a Python 2.6 interpreter installed on - your system, obtain, install, or find `Python 2.6 - <http://www.python.org/download/releases/2.6.6/>`_ for your system. - -#. Install the latest `setuptools` into the Python you - obtained/installed/found in the step above: download `ez_setup.py - <http://peak.telecommunity.com/dist/ez_setup.py>`_ and run it using - the ``python`` interpreter of your Python 2.6 installation: - - .. code-block:: text - - $ /path/to/my/Python-2.6/bin/python ez_setup.py - -#. Use that Python's `bin/easy_install` to install `virtualenv`: +#. Use your Python's virtualenv to make a workspace: .. code-block:: text - $ /path/to/my/Python-2.6/bin/easy_install virtualenv + $ path/to/my/Python-2.6/bin/virtualenv --no-site-packages pyramidtut -#. Use that Python's virtualenv to make a workspace: +#. Switch to the ``pyramidtut`` directory: .. code-block:: text - $ path/to/my/Python-2.6/bin/virtualenv --no-site-packages bigfntut - -#. Switch to the ``bigfntut`` directory: - - .. code-block:: text - - $ cd bigfntut - -#. (Optional) Consider using ``source bin/activate`` to make your - shell environment wired to use the virtualenv. + $ cd pyramidtut #. Use ``easy_install`` to get :app:`Pyramid` and its direct dependencies installed: @@ -73,52 +50,30 @@ Preparation, UNIX Preparation, Windows -------------------- -#. Install, or find `Python 2.6.6 - <http://python.org/download/releases/2.6.6/>`_ for your system. - -#. Install the latest `setuptools` into the Python you - obtained/installed/found in the step above: download `ez_setup.py - <http://peak.telecommunity.com/dist/ez_setup.py>`_ and run it using - the ``python`` interpreter of your Python 2.6 installation using a - command prompt: - - .. code-block:: text - - c:\> c:\Python26\python ez_setup.py - -#. Use that Python's `bin/easy_install` to install `virtualenv`: +#. Use your Python's virtualenv to make a workspace: .. code-block:: text - c:\> c:\Python26\Scripts\easy_install virtualenv + c:\> c:\Python26\Scripts\virtualenv --no-site-packages pyramidtut -#. Use that Python's virtualenv to make a workspace: +#. Switch to the ``pyramidtut`` directory: .. code-block:: text - c:\> c:\Python26\Scripts\virtualenv --no-site-packages bigfntut - -#. Switch to the ``bigfntut`` directory: - - .. code-block:: text - - c:\> cd bigfntut - -#. (Optional) Consider using ``bin\activate.bat`` to make your shell - environment wired to use the virtualenv. + c:\> cd pyramidtut #. Use ``easy_install`` to get :app:`Pyramid` and its direct dependencies installed: .. code-block:: text - c:\bigfntut> Scripts\easy_install pyramid + c:\pyramidtut> Scripts\easy_install pyramid #. Use ``easy_install`` to install various packages from PyPI. .. code-block:: text - c:\bigfntut> Scripts\easy_install -i docutils \ + c:\pyramidtut> Scripts\easy_install -i docutils \ nose coverage zope.sqlalchemy SQLAlchemy repoze.tm2 @@ -133,7 +88,7 @@ variety of templates to generate sample projects. We will use the that uses :term:`SQLAlchemy` and :term:`URL dispatch`. The below instructions assume your current working directory is the -"virtualenv" named "bigfntut". +"virtualenv" named "pyramidtut". On UNIX: @@ -145,7 +100,7 @@ On Windows: .. code-block:: text - c:\bigfntut> Scripts\paster create -t pyramid_routesalchemy tutorial + c:\pyramidtut> Scripts\paster create -t pyramid_routesalchemy tutorial .. note:: If you are using Windows, the ``pyramid_routesalchemy`` Paster template may not deal gracefully with installation into a @@ -173,8 +128,8 @@ On Windows: .. code-block:: text - c:\bigfntut> cd tutorial - c:\bigfntut\tutorial> ..\Scripts\python setup.py develop + c:\pyramidtut> cd tutorial + c:\pyramidtut\tutorial> ..\Scripts\python setup.py develop .. _sql_running_tests: @@ -194,7 +149,7 @@ On Windows: .. code-block:: text - c:\bigfntut\tutorial> ..\Scripts\python setup.py test -q + c:\pyramidtut\tutorial> ..\Scripts\python setup.py test -q Starting the Application ======================== @@ -211,7 +166,7 @@ On Windows: .. code-block:: text - c:\bifgfntut\tutorial> ..\Scripts\paster serve development.ini --reload + c:\pyramidtut\tutorial> ..\Scripts\paster serve development.ini --reload Exposing Test Coverage Information ================================== @@ -235,7 +190,7 @@ On Windows: .. code-block:: text - c:\bigfntut\tutorial> ..\Scripts\easy_install nose coverage + c:\pyramidtut\tutorial> ..\Scripts\easy_install nose coverage Once ``nose`` and ``coverage`` are installed, we can actually run the coverage tests. @@ -250,7 +205,7 @@ On Windows: .. code-block:: text - c:\bigfntut\tutorial> ..\Scripts\nosetests --cover-package=tutorial \ + c:\pyramidtut\tutorial> ..\Scripts\nosetests --cover-package=tutorial \ --cover-erase --with-coverage Looks like our package's ``models`` module doesn't quite have 100% diff --git a/docs/tutorials/wiki2/src/authorization/MANIFEST.in b/docs/tutorials/wiki2/src/authorization/MANIFEST.in new file mode 100644 index 000000000..81beba1b1 --- /dev/null +++ b/docs/tutorials/wiki2/src/authorization/MANIFEST.in @@ -0,0 +1,2 @@ +include *.txt *.ini *.cfg *.rst +recursive-include tutorial *.ico *.png *.css *.gif *.jpg *.pt *.txt *.mak *.mako *.js *.html *.xml diff --git a/docs/tutorials/wiki2/src/authorization/development.ini b/docs/tutorials/wiki2/src/authorization/development.ini index b0cfd12a7..3b615f635 100644 --- a/docs/tutorials/wiki2/src/authorization/development.ini +++ b/docs/tutorials/wiki2/src/authorization/development.ini @@ -11,9 +11,13 @@ sqlalchemy.url = sqlite:///%(here)s/tutorial.db [pipeline:main] pipeline = egg:WebError#evalerror - egg:repoze.tm2#tm + tm tutorial +[filter:tm] +use = egg:repoze.tm2#tm +commit_veto = repoze.tm:default_commit_veto + [server:main] use = egg:Paste#http host = 0.0.0.0 diff --git a/docs/tutorials/wiki2/src/authorization/production.ini b/docs/tutorials/wiki2/src/authorization/production.ini new file mode 100644 index 000000000..0fdc38811 --- /dev/null +++ b/docs/tutorials/wiki2/src/authorization/production.ini @@ -0,0 +1,77 @@ +[app:tutorial] +use = egg:tutorial +reload_templates = false +debug_authorization = false +debug_notfound = false +debug_routematch = false +debug_templates = false +default_locale_name = en +sqlalchemy.url = sqlite:///%(here)s/tutorial.db + +[filter:weberror] +use = egg:WebError#error_catcher +debug = false +;error_log = +;show_exceptions_in_wsgi_errors = true +;smtp_server = localhost +;error_email = janitor@example.com +;smtp_username = janitor +;smtp_password = "janitor's password" +;from_address = paste@localhost +;error_subject_prefix = "Pyramid Error" +;smtp_use_tls = +;error_message = + +[filter:tm] +use = egg:repoze.tm2#tm +commit_veto = repoze.tm:default_commit_veto + +[pipeline:main] +pipeline = + weberror + tm + tutorial + +[server:main] +use = egg:Paste#http +host = 0.0.0.0 +port = 6543 + +# Begin logging configuration + +[loggers] +keys = root, tutorial, sqlalchemy + +[handlers] +keys = console + +[formatters] +keys = generic + +[logger_root] +level = WARN +handlers = console + +[logger_tutorial] +level = WARN +handlers = +qualname = tutorial + +[logger_sqlalchemy] +level = WARN +handlers = +qualname = sqlalchemy.engine +# "level = INFO" logs SQL queries. +# "level = DEBUG" logs SQL queries and results. +# "level = WARN" logs neither. (Recommended for production systems.) + +[handler_console] +class = StreamHandler +args = (sys.stderr,) +level = NOTSET +formatter = generic + +[formatter_generic] +format = %(asctime)s %(levelname)-5.5s [%(name)s][%(threadName)s] %(message)s + +# End logging configuration diff --git a/docs/tutorials/wiki2/src/authorization/setup.py b/docs/tutorials/wiki2/src/authorization/setup.py index 3be3146b7..ae9869d50 100644 --- a/docs/tutorials/wiki2/src/authorization/setup.py +++ b/docs/tutorials/wiki2/src/authorization/setup.py @@ -11,10 +11,10 @@ requires = [ 'pyramid', 'SQLAlchemy', 'transaction', - 'repoze.tm2', + 'repoze.tm2>=1.0b1', # default_commit_veto 'zope.sqlalchemy', 'WebError', - 'docutils' + 'docutils', ] if sys.version_info[:3] < (2,5,0): diff --git a/docs/tutorials/wiki2/src/authorization/tutorial/static/footerbg.png b/docs/tutorials/wiki2/src/authorization/tutorial/static/footerbg.png Binary files differnew file mode 100644 index 000000000..1fbc873da --- /dev/null +++ b/docs/tutorials/wiki2/src/authorization/tutorial/static/footerbg.png diff --git a/docs/tutorials/wiki2/src/authorization/tutorial/static/headerbg.png b/docs/tutorials/wiki2/src/authorization/tutorial/static/headerbg.png Binary files differnew file mode 100644 index 000000000..0596f2020 --- /dev/null +++ b/docs/tutorials/wiki2/src/authorization/tutorial/static/headerbg.png diff --git a/docs/tutorials/wiki2/src/authorization/tutorial/static/ie6.css b/docs/tutorials/wiki2/src/authorization/tutorial/static/ie6.css new file mode 100644 index 000000000..b7c8493d8 --- /dev/null +++ b/docs/tutorials/wiki2/src/authorization/tutorial/static/ie6.css @@ -0,0 +1,8 @@ +* html img, +* html .png{position:relative;behavior:expression((this.runtimeStyle.behavior="none")&&(this.pngSet?this.pngSet=true:(this.nodeName == "IMG" && this.src.toLowerCase().indexOf('.png')>-1?(this.runtimeStyle.backgroundImage = "none", +this.runtimeStyle.filter = "progid:DXImageTransform.Microsoft.AlphaImageLoader(src='" + this.src + "',sizingMethod='image')", +this.src = "static/transparent.gif"):(this.origBg = this.origBg? this.origBg :this.currentStyle.backgroundImage.toString().replace('url("','').replace('")',''), +this.runtimeStyle.filter = "progid:DXImageTransform.Microsoft.AlphaImageLoader(src='" + this.origBg + "',sizingMethod='crop')", +this.runtimeStyle.backgroundImage = "none")),this.pngSet=true) +);} +#wrap{display:table;height:100%} diff --git a/docs/tutorials/wiki2/src/authorization/tutorial/static/logo.png b/docs/tutorials/wiki2/src/authorization/tutorial/static/logo.png Binary files differdeleted file mode 100644 index 88f5d9865..000000000 --- a/docs/tutorials/wiki2/src/authorization/tutorial/static/logo.png +++ /dev/null diff --git a/docs/tutorials/wiki2/src/authorization/tutorial/static/middlebg.png b/docs/tutorials/wiki2/src/authorization/tutorial/static/middlebg.png Binary files differnew file mode 100644 index 000000000..2369cfb7d --- /dev/null +++ b/docs/tutorials/wiki2/src/authorization/tutorial/static/middlebg.png diff --git a/docs/tutorials/wiki2/src/authorization/tutorial/static/pylons.css b/docs/tutorials/wiki2/src/authorization/tutorial/static/pylons.css index c153be07f..fd1914d8d 100644 --- a/docs/tutorials/wiki2/src/authorization/tutorial/static/pylons.css +++ b/docs/tutorials/wiki2/src/authorization/tutorial/static/pylons.css @@ -4,34 +4,23 @@ body{line-height:1;} ol,ul{list-style:none;} blockquote,q{quotes:none;} blockquote:before,blockquote:after,q:before,q:after{content:'';content:none;} -/* remember to define focus styles! */ :focus{outline:0;} -/* remember to highlight inserts somehow! */ ins{text-decoration:none;} del{text-decoration:line-through;} -/* tables still need 'cellspacing="0"' in the markup */ table{border-collapse:collapse;border-spacing:0;} -/* restyling */ sub{vertical-align:sub;font-size:smaller;line-height:normal;} sup{vertical-align:super;font-size:smaller;line-height:normal;} -/* lists */ ul,menu,dir{display:block;list-style-type:disc;margin:1em 0;padding-left:40px;} ol{display:block;list-style-type:decimal-leading-zero;margin:1em 0;padding-left:40px;} li{display:list-item;} -/* nested lists have no top/bottom margins */ ul ul,ul ol,ul dir,ul menu,ul dl,ol ul,ol ol,ol dir,ol menu,ol dl,dir ul,dir ol,dir dir,dir menu,dir dl,menu ul,menu ol,menu dir,menu menu,menu dl,dl ul,dl ol,dl dir,dl menu,dl dl{margin-top:0;margin-bottom:0;} -/* 2 deep unordered lists use a circle */ ol ul,ul ul,menu ul,dir ul,ol menu,ul menu,menu menu,dir menu,ol dir,ul dir,menu dir,dir dir{list-style-type:circle;} -/* 3 deep (or more) unordered lists use a square */ ol ol ul,ol ul ul,ol menu ul,ol dir ul,ol ol menu,ol ul menu,ol menu menu,ol dir menu,ol ol dir,ol ul dir,ol menu dir,ol dir dir,ul ol ul,ul ul ul,ul menu ul,ul dir ul,ul ol menu,ul ul menu,ul menu menu,ul dir menu,ul ol dir,ul ul dir,ul menu dir,ul dir dir,menu ol ul,menu ul ul,menu menu ul,menu dir ul,menu ol menu,menu ul menu,menu menu menu,menu dir menu,menu ol dir,menu ul dir,menu menu dir,menu dir dir,dir ol ul,dir ul ul,dir menu ul,dir dir ul,dir ol menu,dir ul menu,dir menu menu,dir dir menu,dir ol dir,dir ul dir,dir menu dir,dir dir dir{list-style-type:square;} .hidden{display:none;} p{line-height:1.5em;} -h1{font-size:1.75em;/* 28px */ -line-height:1.7em;font-family:helvetica,verdana;} -h2{font-size:1.5em;/* 24px */ -line-height:1.7em;font-family:helvetica,verdana;} -h3{font-size:1.25em;/* 20px */ -line-height:1.7em;font-family:helvetica,verdana;} +h1{font-size:1.75em;line-height:1.7em;font-family:helvetica,verdana;} +h2{font-size:1.5em;line-height:1.7em;font-family:helvetica,verdana;} +h3{font-size:1.25em;line-height:1.7em;font-family:helvetica,verdana;} h4{font-size:1em;line-height:1.7em;font-family:helvetica,verdana;} html,body{width:100%;height:100%;} body{margin:0;padding:0;background-color:#ffffff;position:relative;font:16px/24px "Nobile","Lucida Grande",Lucida,Verdana,sans-serif;} @@ -42,23 +31,26 @@ body h2, body h3, body h4, body h5, -body h6{font-family:"Nobile","Lucida Grande",Lucida,Verdana,sans-serif;font-weight:normal;color:#144fb2;font-style:normal;} -#wrap {min-height: 100%;} -#header,#footer{width:100%;color:#ffffff;height:40px;position:absolute;text-align:center;line-height:40px;overflow:hidden;font-size:12px;} -#header{background-color:#e88f00;top:0;font-size:14px;} -#footer{background-color:#000000;bottom:0;position: relative;margin-top:-40px;clear:both;} -.header,.footer{width:700px;margin-right:auto;margin-left:auto;} +body h6{font-family:"Neuton","Lucida Grande",Lucida,Verdana,sans-serif;font-weight:normal;color:#373839;font-style:normal;} +#wrap{min-height:100%;} +#header,#footer{width:100%;color:#ffffff;height:40px;position:absolute;text-align:center;line-height:40px;overflow:hidden;font-size:12px;vertical-align:middle;} +#header{background:#000000;top:0;font-size:14px;} +#footer{bottom:0;background:#000000 url(footerbg.png) repeat-x 0 top;position:relative;margin-top:-40px;clear:both;} +.header,.footer{width:750px;margin-right:auto;margin-left:auto;} .wrapper{width:100%} -#top,#bottom{width:100%;} -#top{color:#888;background-color:#eee;height:300px;border-bottom:2px solid #ddd;} -#bottom{color:#222;background-color:#ffffff;overflow:hidden;padding-bottom:80px;} -.top,.bottom{width:700px;margin-right:auto;margin-left:auto;} -.top{padding-top:100px;} +#top,#top-small,#bottom{width:100%;} +#top{color:#000000;height:230px;background:#ffffff url(headerbg.png) repeat-x 0 top;position:relative;} +#top-small{color:#000000;height:60px;background:#ffffff url(headerbg.png) repeat-x 0 top;position:relative;} +#bottom{color:#222;background-color:#ffffff;} +.top,.top-small,.middle,.bottom{width:750px;margin-right:auto;margin-left:auto;} +.top{padding-top:40px;} +.top-small{padding-top:10px;} +#middle{width:100%;height:100px;background:url(middlebg.png) repeat-x;border-top:2px solid #ffffff;border-bottom:2px solid #b2b2b2;} .app-welcome{margin-top:25px;} .app-name{color:#000000;font-weight:bold;} .bottom{padding-top:50px;} -#left{width:325px;float:left;padding-right:25px;} -#right{width:325px;float:right;padding-left:25px;} +#left{width:350px;float:left;padding-right:25px;} +#right{width:350px;float:right;padding-left:25px;} .align-left{text-align:left;} .align-right{text-align:right;} .align-center{text-align:center;} @@ -67,7 +59,7 @@ ul.links li{list-style-type:none;font-size:14px;} form{border-style:none;} fieldset{border-style:none;} input{color:#222;border:1px solid #ccc;font-family:sans-serif;font-size:12px;line-height:16px;} -input[type=text]{} +input[type=text],input[type=password]{width:205px;} input[type=submit]{background-color:#ddd;font-weight:bold;} /*Opera Fix*/ -body:before {content:"";height:100%;float:left;width:0;margin-top:-32767px;} +body:before{content:"";height:100%;float:left;width:0;margin-top:-32767px;} diff --git a/docs/tutorials/wiki2/src/authorization/tutorial/static/pyramid-small.png b/docs/tutorials/wiki2/src/authorization/tutorial/static/pyramid-small.png Binary files differnew file mode 100644 index 000000000..a5bc0ade7 --- /dev/null +++ b/docs/tutorials/wiki2/src/authorization/tutorial/static/pyramid-small.png diff --git a/docs/tutorials/wiki2/src/authorization/tutorial/static/pyramid.png b/docs/tutorials/wiki2/src/authorization/tutorial/static/pyramid.png Binary files differnew file mode 100644 index 000000000..347e05549 --- /dev/null +++ b/docs/tutorials/wiki2/src/authorization/tutorial/static/pyramid.png diff --git a/docs/tutorials/wiki2/src/authorization/tutorial/static/style.css b/docs/tutorials/wiki2/src/authorization/tutorial/static/style.css deleted file mode 100644 index cad87e0d4..000000000 --- a/docs/tutorials/wiki2/src/authorization/tutorial/static/style.css +++ /dev/null @@ -1,109 +0,0 @@ -html, body { - color: black; - background-color: #ddd; - font: x-small "Lucida Grande", "Lucida Sans Unicode", geneva, sans-serif; - margin: 0; - padding: 0; -} - -td, th {padding:3px;border:none;} -tr th {text-align:left;background-color:#f0f0f0;color:#333;} -tr.odd td {background-color:#edf3fe;} -tr.even td {background-color:#fff;} - -#header { - height: 80px; - width: 777px; - background: blue URL('../images/header_inner.png') no-repeat; - border-left: 1px solid #aaa; - border-right: 1px solid #aaa; - margin: 0 auto 0 auto; -} - -a.link, a, a.active { - color: #369; -} - - -#main_content { - color: black; - font-size: 127%; - background-color: white; - width: 757px; - margin: 0 auto 0 auto; - border-left: 1px solid #aaa; - border-right: 1px solid #aaa; - padding: 10px; -} - -#sidebar { - border: 1px solid #aaa; - background-color: #eee; - margin: 0.5em; - padding: 1em; - float: right; - width: 200px; - font-size: 88%; -} - -#sidebar h2 { - margin-top: 0; -} - -#sidebar ul { - margin-left: 1.5em; - padding-left: 0; -} - -h1,h2,h3,h4,h5,h6,#getting_started_steps { - font-family: "Century Schoolbook L", Georgia, serif; - font-weight: bold; -} - -h2 { - font-size: 150%; -} - -#footer { - border: 1px solid #aaa; - border-top: 0px none; - color: #999; - background-color: white; - padding: 10px; - font-size: 80%; - text-align: center; - width: 757px; - margin: 0 auto 1em auto; -} - -.code { - font-family: monospace; -} - -span.code { - font-weight: bold; - background: #eee; -} - -#status_block { - margin: 0 auto 0.5em auto; - padding: 15px 10px 15px 55px; - background: #cec URL('../images/ok.png') left center no-repeat; - border: 1px solid #9c9; - width: 450px; - font-size: 120%; - font-weight: bolder; -} - -.notice { - margin: 0.5em auto 0.5em auto; - padding: 15px 10px 15px 55px; - width: 450px; - background: #eef URL('../images/info.png') left center no-repeat; - border: 1px solid #cce; -} - -.fielderror { - color: red; - font-weight: bold; -} diff --git a/docs/tutorials/wiki2/src/authorization/tutorial/static/transparent.gif b/docs/tutorials/wiki2/src/authorization/tutorial/static/transparent.gif Binary files differnew file mode 100644 index 000000000..0341802e5 --- /dev/null +++ b/docs/tutorials/wiki2/src/authorization/tutorial/static/transparent.gif diff --git a/docs/tutorials/wiki2/src/authorization/tutorial/templates/edit.pt b/docs/tutorials/wiki2/src/authorization/tutorial/templates/edit.pt index 05e2ecd76..ca28b9fa5 100644 --- a/docs/tutorials/wiki2/src/authorization/tutorial/templates/edit.pt +++ b/docs/tutorials/wiki2/src/authorization/tutorial/templates/edit.pt @@ -1,35 +1,62 @@ -<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" - "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"> -<html - xmlns="http://www.w3.org/1999/xhtml" +<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" + "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd"> +<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en" xmlns:tal="http://xml.zope.org/namespaces/tal"> - <head> - <meta content="text/html; charset=utf-8" http-equiv="Content-Type"/> - <title>Pyramid tutorial wiki (based on TurboGears 20-Minute Wiki) - Editing: ${page.name}</title> - <link rel="stylesheet" type="text/css" - href="${request.application_url}/static/style.css" /> + <title>${page.name} - Pyramid tutorial wiki (based on + TurboGears 20-Minute Wiki)</title> + <meta http-equiv="Content-Type" content="text/html;charset=UTF-8"/> + <meta name="keywords" content="python web application" /> + <meta name="description" content="pyramid web application" /> + <link rel="shortcut icon" + href="${request.static_url('tutorial:static/favicon.ico')}" /> + <link rel="stylesheet" + href="${request.static_url('tutorial:static/pylons.css')}" + type="text/css" media="screen" charset="utf-8" /> + <!--[if lte IE 6]> + <link rel="stylesheet" + href="${request.static_url('tutorial:static/ie6.css')}" + type="text/css" media="screen" charset="utf-8" /> + <![endif]--> </head> - <body> - -<div class="main_content"> - <div style="float:right; width: 10em;"> Viewing - <span tal:replace="page.name">Page Name Goes Here</span> <br/> - You can return to the <a href="${request.application_url}" - >FrontPage</a>. - <span tal:condition="logged_in"> - <a href="${request.application_url}/logout">Logout</a> - </span> - </div> - - <div> - <form action="${save_url}" method="post"> - <textarea name="body" tal:content="page.data" rows="10" cols="60"/> - <input type="submit" name="form.submitted" value="Save"/> - </form> + <div id="wrap"> + <div id="top-small"> + <div class="top-small align-center"> + <div> + <img width="220" height="50" alt="pyramid" + src="${request.static_url('tutorial:static/pyramid-small.png')}" /> + </div> + </div> + </div> + <div id="middle"> + <div class="middle align-right"> + <div id="left" class="app-welcome align-left"> + Editing <b><span tal:replace="page.name">Page Name + Goes Here</span></b><br/> + You can return to the + <a href="${request.application_url}">FrontPage</a>.<br/> + </div> + <div id="right" class="app-welcome align-right"> + <span tal:condition="logged_in"> + <a href="${request.application_url}/logout">Logout</a> + </span> + </div> + </div> + </div> + <div id="bottom"> + <div class="bottom"> + <form action="${save_url}" method="post"> + <textarea name="body" tal:content="page.data" rows="10" + cols="60"/><br/> + <input type="submit" name="form.submitted" value="Save"/> + </form> + </div> + </div> + </div> + <div id="footer"> + <div class="footer" + >© Copyright 2008-2011, Agendaless Consulting.</div> </div> -</div> </body> </html> diff --git a/docs/tutorials/wiki2/src/authorization/tutorial/templates/login.pt b/docs/tutorials/wiki2/src/authorization/tutorial/templates/login.pt index c56983d64..64e592ea9 100644 --- a/docs/tutorials/wiki2/src/authorization/tutorial/templates/login.pt +++ b/docs/tutorials/wiki2/src/authorization/tutorial/templates/login.pt @@ -1,32 +1,58 @@ -<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" - "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"> -<html - xmlns="http://www.w3.org/1999/xhtml" - xmlns:tal="http://xml.zope.org/namespaces/tal"> - +<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" + "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd"> +<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en" + xmlns:tal="http://xml.zope.org/namespaces/tal"> <head> - <meta content="text/html; charset=utf-8" http-equiv="Content-Type"/> - <title>Pyramid tutorial wiki (based on TurboGears 20-Minute Wiki)</title> - <link rel="stylesheet" type="text/css" - href="${request.application_url}/static/style.css" /> + <title>Login - Pyramid tutorial wiki (based on TurboGears + 20-Minute Wiki)</title> + <meta http-equiv="Content-Type" content="text/html;charset=UTF-8"/> + <meta name="keywords" content="python web application" /> + <meta name="description" content="pyramid web application" /> + <link rel="shortcut icon" + href="${request.static_url('tutorial:static/favicon.ico')}" /> + <link rel="stylesheet" + href="${request.static_url('tutorial:static/pylons.css')}" + type="text/css" media="screen" charset="utf-8" /> + <!--[if lte IE 6]> + <link rel="stylesheet" + href="${request.static_url('tutorial:static/ie6.css')}" + type="text/css" media="screen" charset="utf-8" /> + <![endif]--> </head> - <body> - -<h1>Log In</h1> - -<div tal:replace="message"/> - -<div class="main_content"> - <form action="${url}" method="post"> - <input type="hidden" name="came_from" value="${came_from}"/> - <input type="text" name="login" value="${login}"/> - <br/> - <input type="password" name="password" value="${password}"/> - <br/> - <input type="submit" name="form.submitted" value="Log In"/> - </form> -</div> - + <div id="wrap"> + <div id="top-small"> + <div class="top-small align-center"> + <div> + <img width="220" height="50" alt="pyramid" + src="${request.static_url('tutorial:static/pyramid-small.png')}" /> + </div> + </div> + </div> + <div id="middle"> + <div class="middle align-right"> + <div id="left" class="app-welcome align-left"> + <b>Login</b><br/> + <span tal:replace="message"/> + </div> + <div id="right" class="app-welcome align-right"></div> + </div> + </div> + <div id="bottom"> + <div class="bottom"> + <form action="${url}" method="post"> + <input type="hidden" name="came_from" value="${came_from}"/> + <input type="text" name="login" value="${login}"/><br/> + <input type="password" name="password" + value="${password}"/><br/> + <input type="submit" name="form.submitted" value="Log In"/> + </form> + </div> + </div> + </div> + <div id="footer"> + <div class="footer" + >© Copyright 2008-2011, Agendaless Consulting.</div> + </div> </body> </html> diff --git a/docs/tutorials/wiki2/src/authorization/tutorial/templates/mytemplate.pt b/docs/tutorials/wiki2/src/authorization/tutorial/templates/mytemplate.pt index 6ad23d44f..d98420680 100644 --- a/docs/tutorials/wiki2/src/authorization/tutorial/templates/mytemplate.pt +++ b/docs/tutorials/wiki2/src/authorization/tutorial/templates/mytemplate.pt @@ -1,79 +1,75 @@ <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd"> <html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en" xmlns:tal="http://xml.zope.org/namespaces/tal"> <head> - <title>The Pyramid Web Application Development Framework</title> - <meta http-equiv="Content-Type" content="text/html;charset=UTF-8"/> - <meta name="keywords" content="python web application" /> - <meta name="description" content="pyramid web application" /> - <link rel="shortcut icon" href="${request.application_url}/static/favicon.ico" /> - <link rel="stylesheet" href="${request.application_url}/static/pylons.css" type="text/css" media="screen" charset="utf-8" /> - <link rel="stylesheet" href="http://fonts.googleapis.com/css?family=Nobile:regular,italic,bold,bolditalic&subset=latin" type="text/css" media="screen" charset="utf-8" /> - <!--[if !IE 7]> - <style type="text/css"> - #wrap {display:table;height:100%} - </style> - <![endif]--> + <title>The Pyramid Web Application Development Framework</title> + <meta http-equiv="Content-Type" content="text/html;charset=UTF-8"/> + <meta name="keywords" content="python web application" /> + <meta name="description" content="pyramid web application" /> + <link rel="shortcut icon" href="${request.static_url('tutorial:static/favicon.ico')}" /> + <link rel="stylesheet" href="${request.static_url('tutorial:static/pylons.css')}" type="text/css" media="screen" charset="utf-8" /> + <link rel="stylesheet" href="http://fonts.googleapis.com/css?family=Neuton|Nobile:regular,i,b,bi&subset=latin" type="text/css" media="screen" charset="utf-8" /> + <!--[if lte IE 6]> + <link rel="stylesheet" href="${request.static_url('tutorial:static/ie6.css')}" type="text/css" media="screen" charset="utf-8" /> + <![endif]--> </head> <body> - <div id="wrap"> - <div id="header"> - <div class="header">The Pyramid Web Application Development Framework</div> - </div> - <div id="top"> - <div class="top align-center"> - <img src="${request.application_url}/static/logo.png" width="300" height="80"/> - <p class="app-welcome"> - Welcome to <span class="app-name">${project}</span>, an application generated by<br/> - the Pyramid web application development framework. - </p> - </div> - </div> - <div id="bottom"> - <div class="bottom"> - <div id="left" class="align-right"> - <h3>Search Pyramid documentation</h3> - <form method="get" action="http://docs.pylonshq.com/pyramid/dev/search.html"> - <input type="text" id="q" name="q" value="" /> - <input type="submit" id="x" value="Search" /> - </form> - </div> - <div id="right" class="align-left"> - <h3>Pyramid links</h3> - <ul class="links"> - <li> - <a href="http://pylonshq.com">Pylons Website</a> - </li> - <li> - <a href="http://docs.pylonshq.com/">The Pylons Project Documentation</a> - </li> - <li> - <a href="http://docs.pylonshq.com/pyramid/dev/#narrative-documentation">Narrative Documentation</a> - </li> - <li> - <a href="http://docs.pylonshq.com/pyramid/dev/#api-documentation">API Documentation</a> - </li> - <li> - <a href="http://docs.pylonshq.com/pyramid/dev/#tutorials">Tutorials</a> - </li> - <li> - <a href="http://docs.pylonshq.com/pyramid/dev/#change-history">Change History</a> - </li> - <li> - <a href="http://docs.pylonshq.com/pyramid/dev/#sample-applications">Sample Applications</a> - </li> - <li> - <a href="http://docs.pylonshq.com/pyramid/dev/#support-and-development">Support and Development</a> - </li> - <li> - <a href="irc://irc.freenode.net#pyramid">IRC Channel</a> - </li> - </ul> - </div> - </div> - </div> - </div> - <div id="footer"> - <div class="footer">© Copyright 2008-2010, Agendaless Consulting.</div> - </div> + <div id="wrap"> + <div id="top"> + <div class="top align-center"> + <div><img src="${request.static_url('tutorial:static/pyramid.png')}" width="750" height="169" alt="pyramid"/></div> + </div> + </div> + <div id="middle"> + <div class="middle align-center"> + <p class="app-welcome"> + Welcome to <span class="app-name">${project}</span>, an application generated by<br/> + the Pyramid web application development framework. + </p> + </div> + </div> + <div id="bottom"> + <div class="bottom"> + <div id="left" class="align-right"> + <h2>Search documentation</h2> + <form method="get" action="http://docs.pylonsproject.org/projects/pyramid/dev/search.html"> + <input type="text" id="q" name="q" value="" /> + <input type="submit" id="x" value="Go" /> + </form> + </div> + <div id="right" class="align-left"> + <h2>Pyramid links</h2> + <ul class="links"> + <li> + <a href="http://pylonsproject.org">Pylons Website</a> + </li> + <li> + <a href="http://docs.pylonsproject.org/projects/pyramid/dev/#narrative-documentation">Narrative Documentation</a> + </li> + <li> + <a href="http://docs.pylonsproject.org/projects/pyramid/dev/#api-documentation">API Documentation</a> + </li> + <li> + <a href="http://docs.pylonsproject.org/projects/pyramid/dev/#tutorials">Tutorials</a> + </li> + <li> + <a href="http://docs.pylonsproject.org/projects/pyramid/dev/#change-history">Change History</a> + </li> + <li> + <a href="http://docs.pylonsproject.org/projects/pyramid/dev/#sample-applications">Sample Applications</a> + </li> + <li> + <a href="http://docs.pylonsproject.org/projects/pyramid/dev/#support-and-development">Support and Development</a> + </li> + <li> + <a href="irc://irc.freenode.net#pyramid">IRC Channel</a> + </li> + </ul> + </div> + </div> + </div> + </div> + <div id="footer"> + <div class="footer">© Copyright 2008-2011, Agendaless Consulting.</div> + </div> </body> -</html>
\ No newline at end of file +</html> diff --git a/docs/tutorials/wiki2/src/authorization/tutorial/templates/view.pt b/docs/tutorials/wiki2/src/authorization/tutorial/templates/view.pt index 0c654250a..5a69818c1 100644 --- a/docs/tutorials/wiki2/src/authorization/tutorial/templates/view.pt +++ b/docs/tutorials/wiki2/src/authorization/tutorial/templates/view.pt @@ -1,31 +1,65 @@ -<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" - "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"> -<html - xmlns="http://www.w3.org/1999/xhtml" +<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" + "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd"> +<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en" xmlns:tal="http://xml.zope.org/namespaces/tal"> - <head> - <meta content="text/html; charset=utf-8" http-equiv="Content-Type"/> - <title>${page.name} - Pyramid tutorial wiki - (based on TurboGears 20-Minute Wiki)</title> - <link rel="stylesheet" type="text/css" - href="${request.application_url}/static/style.css" /> + <title>${page.name} - Pyramid tutorial wiki (based on + TurboGears 20-Minute Wiki)</title> + <meta http-equiv="Content-Type" content="text/html;charset=UTF-8"/> + <meta name="keywords" content="python web application" /> + <meta name="description" content="pyramid web application" /> + <link rel="shortcut icon" + href="${request.static_url('tutorial:static/favicon.ico')}" /> + <link rel="stylesheet" + href="${request.static_url('tutorial:static/pylons.css')}" + type="text/css" media="screen" charset="utf-8" /> + <!--[if lte IE 6]> + <link rel="stylesheet" + href="${request.static_url('tutorial:static/ie6.css')}" + type="text/css" media="screen" charset="utf-8" /> + <![endif]--> </head> - <body> - -<div class="main_content"> -<div style="float:right; width: 10em;"> Viewing -<span tal:replace="page.name">Page Name Goes Here</span> <br/> -You can return to the <a href="${request.application_url}">FrontPage</a>. -<span tal:condition="logged_in"> - <a href="${request.application_url}/logout">Logout</a> -</span> -</div> - -<div tal:replace="structure content">Page text goes here.</div> -<p><a tal:attributes="href edit_url" href="">Edit this page</a></p> -</div> - + <div id="wrap"> + <div id="top-small"> + <div class="top-small align-center"> + <div> + <img width="220" height="50" alt="pyramid" + src="${request.static_url('tutorial:static/pyramid-small.png')}" /> + </div> + </div> + </div> + <div id="middle"> + <div class="middle align-right"> + <div id="left" class="app-welcome align-left"> + Viewing <b><span tal:replace="page.name">Page Name + Goes Here</span></b><br/> + You can return to the + <a href="${request.application_url}">FrontPage</a>.<br/> + </div> + <div id="right" class="app-welcome align-right"> + <span tal:condition="logged_in"> + <a href="${request.application_url}/logout">Logout</a> + </span> + </div> + </div> + </div> + <div id="bottom"> + <div class="bottom"> + <div tal:replace="structure content"> + Page text goes here. + </div> + <p> + <a tal:attributes="href edit_url" href=""> + Edit this page + </a> + </p> + </div> + </div> + </div> + <div id="footer"> + <div class="footer" + >© Copyright 2008-2011, Agendaless Consulting.</div> + </div> </body> </html> diff --git a/docs/tutorials/wiki2/src/authorization/tutorial/tests.py b/docs/tutorials/wiki2/src/authorization/tutorial/tests.py index 1020a8b99..332031ba4 100644 --- a/docs/tutorials/wiki2/src/authorization/tutorial/tests.py +++ b/docs/tutorials/wiki2/src/authorization/tutorial/tests.py @@ -1,6 +1,5 @@ import unittest -from pyramid.config import Configurator from pyramid import testing def _initTestingDB(): @@ -20,28 +19,28 @@ def _registerRoutes(config): class ViewWikiTests(unittest.TestCase): def setUp(self): - self.config = Configurator(autocommit=True) - self.config.begin() + self.config = testing.setUp() def tearDown(self): - self.config.end() + testing.tearDown() + + def _callFUT(self, request): + from tutorial.views import view_wiki + return view_wiki(request) def test_it(self): - from tutorial.views import view_wiki - self.config.add_route('view_page', '{pagename}') + _registerRoutes(self.config) request = testing.DummyRequest() - response = view_wiki(request) + response = self._callFUT(request) self.assertEqual(response.location, 'http://example.com/FrontPage') class ViewPageTests(unittest.TestCase): def setUp(self): self.session = _initTestingDB() - self.config = Configurator(autocommit=True) - self.config.begin() + self.config = testing.setUp() def tearDown(self): - self.session.remove() - self.config.end() + testing.tearDown() def _callFUT(self, request): from tutorial.views import view_page @@ -71,12 +70,11 @@ class ViewPageTests(unittest.TestCase): class AddPageTests(unittest.TestCase): def setUp(self): self.session = _initTestingDB() - self.config = Configurator(autocommit=True) - self.config.begin() + self.config = testing.setUp() def tearDown(self): self.session.remove() - self.config.end() + testing.tearDown() def _callFUT(self, request): from tutorial.views import add_page @@ -104,12 +102,11 @@ class AddPageTests(unittest.TestCase): class EditPageTests(unittest.TestCase): def setUp(self): self.session = _initTestingDB() - self.config = Configurator(autocommit=True) - self.config.begin() + self.config = testing.setUp() def tearDown(self): self.session.remove() - self.config.end() + testing.tearDown() def _callFUT(self, request): from tutorial.views import edit_page diff --git a/docs/tutorials/wiki2/src/basiclayout/MANIFEST.in b/docs/tutorials/wiki2/src/basiclayout/MANIFEST.in new file mode 100644 index 000000000..81beba1b1 --- /dev/null +++ b/docs/tutorials/wiki2/src/basiclayout/MANIFEST.in @@ -0,0 +1,2 @@ +include *.txt *.ini *.cfg *.rst +recursive-include tutorial *.ico *.png *.css *.gif *.jpg *.pt *.txt *.mak *.mako *.js *.html *.xml diff --git a/docs/tutorials/wiki2/src/basiclayout/development.ini b/docs/tutorials/wiki2/src/basiclayout/development.ini index b0cfd12a7..3b615f635 100644 --- a/docs/tutorials/wiki2/src/basiclayout/development.ini +++ b/docs/tutorials/wiki2/src/basiclayout/development.ini @@ -11,9 +11,13 @@ sqlalchemy.url = sqlite:///%(here)s/tutorial.db [pipeline:main] pipeline = egg:WebError#evalerror - egg:repoze.tm2#tm + tm tutorial +[filter:tm] +use = egg:repoze.tm2#tm +commit_veto = repoze.tm:default_commit_veto + [server:main] use = egg:Paste#http host = 0.0.0.0 diff --git a/docs/tutorials/wiki2/src/basiclayout/production.ini b/docs/tutorials/wiki2/src/basiclayout/production.ini new file mode 100644 index 000000000..0fdc38811 --- /dev/null +++ b/docs/tutorials/wiki2/src/basiclayout/production.ini @@ -0,0 +1,77 @@ +[app:tutorial] +use = egg:tutorial +reload_templates = false +debug_authorization = false +debug_notfound = false +debug_routematch = false +debug_templates = false +default_locale_name = en +sqlalchemy.url = sqlite:///%(here)s/tutorial.db + +[filter:weberror] +use = egg:WebError#error_catcher +debug = false +;error_log = +;show_exceptions_in_wsgi_errors = true +;smtp_server = localhost +;error_email = janitor@example.com +;smtp_username = janitor +;smtp_password = "janitor's password" +;from_address = paste@localhost +;error_subject_prefix = "Pyramid Error" +;smtp_use_tls = +;error_message = + +[filter:tm] +use = egg:repoze.tm2#tm +commit_veto = repoze.tm:default_commit_veto + +[pipeline:main] +pipeline = + weberror + tm + tutorial + +[server:main] +use = egg:Paste#http +host = 0.0.0.0 +port = 6543 + +# Begin logging configuration + +[loggers] +keys = root, tutorial, sqlalchemy + +[handlers] +keys = console + +[formatters] +keys = generic + +[logger_root] +level = WARN +handlers = console + +[logger_tutorial] +level = WARN +handlers = +qualname = tutorial + +[logger_sqlalchemy] +level = WARN +handlers = +qualname = sqlalchemy.engine +# "level = INFO" logs SQL queries. +# "level = DEBUG" logs SQL queries and results. +# "level = WARN" logs neither. (Recommended for production systems.) + +[handler_console] +class = StreamHandler +args = (sys.stderr,) +level = NOTSET +formatter = generic + +[formatter_generic] +format = %(asctime)s %(levelname)-5.5s [%(name)s][%(threadName)s] %(message)s + +# End logging configuration diff --git a/docs/tutorials/wiki2/src/basiclayout/setup.py b/docs/tutorials/wiki2/src/basiclayout/setup.py index 09764f40f..eaf1ddcfe 100644 --- a/docs/tutorials/wiki2/src/basiclayout/setup.py +++ b/docs/tutorials/wiki2/src/basiclayout/setup.py @@ -11,7 +11,7 @@ requires = [ 'pyramid', 'SQLAlchemy', 'transaction', - 'repoze.tm2', + 'repoze.tm2>=1.0b1', # default_commit_veto 'zope.sqlalchemy', 'WebError', ] diff --git a/docs/tutorials/wiki2/src/basiclayout/tutorial/models.py b/docs/tutorials/wiki2/src/basiclayout/tutorial/models.py index 9da906752..4fd010c5c 100644 --- a/docs/tutorials/wiki2/src/basiclayout/tutorial/models.py +++ b/docs/tutorials/wiki2/src/basiclayout/tutorial/models.py @@ -12,7 +12,8 @@ from sqlalchemy.orm import sessionmaker from zope.sqlalchemy import ZopeTransactionExtension -DBSession = scoped_session(sessionmaker(extension=ZopeTransactionExtension())) +DBSession = scoped_session(sessionmaker( + extension=ZopeTransactionExtension())) Base = declarative_base() class MyModel(Base): diff --git a/docs/tutorials/wiki2/src/basiclayout/tutorial/static/footerbg.png b/docs/tutorials/wiki2/src/basiclayout/tutorial/static/footerbg.png Binary files differnew file mode 100644 index 000000000..1fbc873da --- /dev/null +++ b/docs/tutorials/wiki2/src/basiclayout/tutorial/static/footerbg.png diff --git a/docs/tutorials/wiki2/src/basiclayout/tutorial/static/headerbg.png b/docs/tutorials/wiki2/src/basiclayout/tutorial/static/headerbg.png Binary files differnew file mode 100644 index 000000000..0596f2020 --- /dev/null +++ b/docs/tutorials/wiki2/src/basiclayout/tutorial/static/headerbg.png diff --git a/docs/tutorials/wiki2/src/basiclayout/tutorial/static/ie6.css b/docs/tutorials/wiki2/src/basiclayout/tutorial/static/ie6.css new file mode 100644 index 000000000..b7c8493d8 --- /dev/null +++ b/docs/tutorials/wiki2/src/basiclayout/tutorial/static/ie6.css @@ -0,0 +1,8 @@ +* html img, +* html .png{position:relative;behavior:expression((this.runtimeStyle.behavior="none")&&(this.pngSet?this.pngSet=true:(this.nodeName == "IMG" && this.src.toLowerCase().indexOf('.png')>-1?(this.runtimeStyle.backgroundImage = "none", +this.runtimeStyle.filter = "progid:DXImageTransform.Microsoft.AlphaImageLoader(src='" + this.src + "',sizingMethod='image')", +this.src = "static/transparent.gif"):(this.origBg = this.origBg? this.origBg :this.currentStyle.backgroundImage.toString().replace('url("','').replace('")',''), +this.runtimeStyle.filter = "progid:DXImageTransform.Microsoft.AlphaImageLoader(src='" + this.origBg + "',sizingMethod='crop')", +this.runtimeStyle.backgroundImage = "none")),this.pngSet=true) +);} +#wrap{display:table;height:100%} diff --git a/docs/tutorials/wiki2/src/basiclayout/tutorial/static/logo.png b/docs/tutorials/wiki2/src/basiclayout/tutorial/static/logo.png Binary files differdeleted file mode 100644 index 88f5d9865..000000000 --- a/docs/tutorials/wiki2/src/basiclayout/tutorial/static/logo.png +++ /dev/null diff --git a/docs/tutorials/wiki2/src/basiclayout/tutorial/static/middlebg.png b/docs/tutorials/wiki2/src/basiclayout/tutorial/static/middlebg.png Binary files differnew file mode 100644 index 000000000..2369cfb7d --- /dev/null +++ b/docs/tutorials/wiki2/src/basiclayout/tutorial/static/middlebg.png diff --git a/docs/tutorials/wiki2/src/basiclayout/tutorial/static/pylons.css b/docs/tutorials/wiki2/src/basiclayout/tutorial/static/pylons.css index c153be07f..fd1914d8d 100644 --- a/docs/tutorials/wiki2/src/basiclayout/tutorial/static/pylons.css +++ b/docs/tutorials/wiki2/src/basiclayout/tutorial/static/pylons.css @@ -4,34 +4,23 @@ body{line-height:1;} ol,ul{list-style:none;} blockquote,q{quotes:none;} blockquote:before,blockquote:after,q:before,q:after{content:'';content:none;} -/* remember to define focus styles! */ :focus{outline:0;} -/* remember to highlight inserts somehow! */ ins{text-decoration:none;} del{text-decoration:line-through;} -/* tables still need 'cellspacing="0"' in the markup */ table{border-collapse:collapse;border-spacing:0;} -/* restyling */ sub{vertical-align:sub;font-size:smaller;line-height:normal;} sup{vertical-align:super;font-size:smaller;line-height:normal;} -/* lists */ ul,menu,dir{display:block;list-style-type:disc;margin:1em 0;padding-left:40px;} ol{display:block;list-style-type:decimal-leading-zero;margin:1em 0;padding-left:40px;} li{display:list-item;} -/* nested lists have no top/bottom margins */ ul ul,ul ol,ul dir,ul menu,ul dl,ol ul,ol ol,ol dir,ol menu,ol dl,dir ul,dir ol,dir dir,dir menu,dir dl,menu ul,menu ol,menu dir,menu menu,menu dl,dl ul,dl ol,dl dir,dl menu,dl dl{margin-top:0;margin-bottom:0;} -/* 2 deep unordered lists use a circle */ ol ul,ul ul,menu ul,dir ul,ol menu,ul menu,menu menu,dir menu,ol dir,ul dir,menu dir,dir dir{list-style-type:circle;} -/* 3 deep (or more) unordered lists use a square */ ol ol ul,ol ul ul,ol menu ul,ol dir ul,ol ol menu,ol ul menu,ol menu menu,ol dir menu,ol ol dir,ol ul dir,ol menu dir,ol dir dir,ul ol ul,ul ul ul,ul menu ul,ul dir ul,ul ol menu,ul ul menu,ul menu menu,ul dir menu,ul ol dir,ul ul dir,ul menu dir,ul dir dir,menu ol ul,menu ul ul,menu menu ul,menu dir ul,menu ol menu,menu ul menu,menu menu menu,menu dir menu,menu ol dir,menu ul dir,menu menu dir,menu dir dir,dir ol ul,dir ul ul,dir menu ul,dir dir ul,dir ol menu,dir ul menu,dir menu menu,dir dir menu,dir ol dir,dir ul dir,dir menu dir,dir dir dir{list-style-type:square;} .hidden{display:none;} p{line-height:1.5em;} -h1{font-size:1.75em;/* 28px */ -line-height:1.7em;font-family:helvetica,verdana;} -h2{font-size:1.5em;/* 24px */ -line-height:1.7em;font-family:helvetica,verdana;} -h3{font-size:1.25em;/* 20px */ -line-height:1.7em;font-family:helvetica,verdana;} +h1{font-size:1.75em;line-height:1.7em;font-family:helvetica,verdana;} +h2{font-size:1.5em;line-height:1.7em;font-family:helvetica,verdana;} +h3{font-size:1.25em;line-height:1.7em;font-family:helvetica,verdana;} h4{font-size:1em;line-height:1.7em;font-family:helvetica,verdana;} html,body{width:100%;height:100%;} body{margin:0;padding:0;background-color:#ffffff;position:relative;font:16px/24px "Nobile","Lucida Grande",Lucida,Verdana,sans-serif;} @@ -42,23 +31,26 @@ body h2, body h3, body h4, body h5, -body h6{font-family:"Nobile","Lucida Grande",Lucida,Verdana,sans-serif;font-weight:normal;color:#144fb2;font-style:normal;} -#wrap {min-height: 100%;} -#header,#footer{width:100%;color:#ffffff;height:40px;position:absolute;text-align:center;line-height:40px;overflow:hidden;font-size:12px;} -#header{background-color:#e88f00;top:0;font-size:14px;} -#footer{background-color:#000000;bottom:0;position: relative;margin-top:-40px;clear:both;} -.header,.footer{width:700px;margin-right:auto;margin-left:auto;} +body h6{font-family:"Neuton","Lucida Grande",Lucida,Verdana,sans-serif;font-weight:normal;color:#373839;font-style:normal;} +#wrap{min-height:100%;} +#header,#footer{width:100%;color:#ffffff;height:40px;position:absolute;text-align:center;line-height:40px;overflow:hidden;font-size:12px;vertical-align:middle;} +#header{background:#000000;top:0;font-size:14px;} +#footer{bottom:0;background:#000000 url(footerbg.png) repeat-x 0 top;position:relative;margin-top:-40px;clear:both;} +.header,.footer{width:750px;margin-right:auto;margin-left:auto;} .wrapper{width:100%} -#top,#bottom{width:100%;} -#top{color:#888;background-color:#eee;height:300px;border-bottom:2px solid #ddd;} -#bottom{color:#222;background-color:#ffffff;overflow:hidden;padding-bottom:80px;} -.top,.bottom{width:700px;margin-right:auto;margin-left:auto;} -.top{padding-top:100px;} +#top,#top-small,#bottom{width:100%;} +#top{color:#000000;height:230px;background:#ffffff url(headerbg.png) repeat-x 0 top;position:relative;} +#top-small{color:#000000;height:60px;background:#ffffff url(headerbg.png) repeat-x 0 top;position:relative;} +#bottom{color:#222;background-color:#ffffff;} +.top,.top-small,.middle,.bottom{width:750px;margin-right:auto;margin-left:auto;} +.top{padding-top:40px;} +.top-small{padding-top:10px;} +#middle{width:100%;height:100px;background:url(middlebg.png) repeat-x;border-top:2px solid #ffffff;border-bottom:2px solid #b2b2b2;} .app-welcome{margin-top:25px;} .app-name{color:#000000;font-weight:bold;} .bottom{padding-top:50px;} -#left{width:325px;float:left;padding-right:25px;} -#right{width:325px;float:right;padding-left:25px;} +#left{width:350px;float:left;padding-right:25px;} +#right{width:350px;float:right;padding-left:25px;} .align-left{text-align:left;} .align-right{text-align:right;} .align-center{text-align:center;} @@ -67,7 +59,7 @@ ul.links li{list-style-type:none;font-size:14px;} form{border-style:none;} fieldset{border-style:none;} input{color:#222;border:1px solid #ccc;font-family:sans-serif;font-size:12px;line-height:16px;} -input[type=text]{} +input[type=text],input[type=password]{width:205px;} input[type=submit]{background-color:#ddd;font-weight:bold;} /*Opera Fix*/ -body:before {content:"";height:100%;float:left;width:0;margin-top:-32767px;} +body:before{content:"";height:100%;float:left;width:0;margin-top:-32767px;} diff --git a/docs/tutorials/wiki2/src/basiclayout/tutorial/static/pyramid-small.png b/docs/tutorials/wiki2/src/basiclayout/tutorial/static/pyramid-small.png Binary files differnew file mode 100644 index 000000000..a5bc0ade7 --- /dev/null +++ b/docs/tutorials/wiki2/src/basiclayout/tutorial/static/pyramid-small.png diff --git a/docs/tutorials/wiki2/src/basiclayout/tutorial/static/pyramid.png b/docs/tutorials/wiki2/src/basiclayout/tutorial/static/pyramid.png Binary files differnew file mode 100644 index 000000000..347e05549 --- /dev/null +++ b/docs/tutorials/wiki2/src/basiclayout/tutorial/static/pyramid.png diff --git a/docs/tutorials/wiki2/src/basiclayout/tutorial/static/transparent.gif b/docs/tutorials/wiki2/src/basiclayout/tutorial/static/transparent.gif Binary files differnew file mode 100644 index 000000000..0341802e5 --- /dev/null +++ b/docs/tutorials/wiki2/src/basiclayout/tutorial/static/transparent.gif diff --git a/docs/tutorials/wiki2/src/basiclayout/tutorial/templates/mytemplate.pt b/docs/tutorials/wiki2/src/basiclayout/tutorial/templates/mytemplate.pt index 6ad23d44f..d98420680 100644 --- a/docs/tutorials/wiki2/src/basiclayout/tutorial/templates/mytemplate.pt +++ b/docs/tutorials/wiki2/src/basiclayout/tutorial/templates/mytemplate.pt @@ -1,79 +1,75 @@ <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd"> <html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en" xmlns:tal="http://xml.zope.org/namespaces/tal"> <head> - <title>The Pyramid Web Application Development Framework</title> - <meta http-equiv="Content-Type" content="text/html;charset=UTF-8"/> - <meta name="keywords" content="python web application" /> - <meta name="description" content="pyramid web application" /> - <link rel="shortcut icon" href="${request.application_url}/static/favicon.ico" /> - <link rel="stylesheet" href="${request.application_url}/static/pylons.css" type="text/css" media="screen" charset="utf-8" /> - <link rel="stylesheet" href="http://fonts.googleapis.com/css?family=Nobile:regular,italic,bold,bolditalic&subset=latin" type="text/css" media="screen" charset="utf-8" /> - <!--[if !IE 7]> - <style type="text/css"> - #wrap {display:table;height:100%} - </style> - <![endif]--> + <title>The Pyramid Web Application Development Framework</title> + <meta http-equiv="Content-Type" content="text/html;charset=UTF-8"/> + <meta name="keywords" content="python web application" /> + <meta name="description" content="pyramid web application" /> + <link rel="shortcut icon" href="${request.static_url('tutorial:static/favicon.ico')}" /> + <link rel="stylesheet" href="${request.static_url('tutorial:static/pylons.css')}" type="text/css" media="screen" charset="utf-8" /> + <link rel="stylesheet" href="http://fonts.googleapis.com/css?family=Neuton|Nobile:regular,i,b,bi&subset=latin" type="text/css" media="screen" charset="utf-8" /> + <!--[if lte IE 6]> + <link rel="stylesheet" href="${request.static_url('tutorial:static/ie6.css')}" type="text/css" media="screen" charset="utf-8" /> + <![endif]--> </head> <body> - <div id="wrap"> - <div id="header"> - <div class="header">The Pyramid Web Application Development Framework</div> - </div> - <div id="top"> - <div class="top align-center"> - <img src="${request.application_url}/static/logo.png" width="300" height="80"/> - <p class="app-welcome"> - Welcome to <span class="app-name">${project}</span>, an application generated by<br/> - the Pyramid web application development framework. - </p> - </div> - </div> - <div id="bottom"> - <div class="bottom"> - <div id="left" class="align-right"> - <h3>Search Pyramid documentation</h3> - <form method="get" action="http://docs.pylonshq.com/pyramid/dev/search.html"> - <input type="text" id="q" name="q" value="" /> - <input type="submit" id="x" value="Search" /> - </form> - </div> - <div id="right" class="align-left"> - <h3>Pyramid links</h3> - <ul class="links"> - <li> - <a href="http://pylonshq.com">Pylons Website</a> - </li> - <li> - <a href="http://docs.pylonshq.com/">The Pylons Project Documentation</a> - </li> - <li> - <a href="http://docs.pylonshq.com/pyramid/dev/#narrative-documentation">Narrative Documentation</a> - </li> - <li> - <a href="http://docs.pylonshq.com/pyramid/dev/#api-documentation">API Documentation</a> - </li> - <li> - <a href="http://docs.pylonshq.com/pyramid/dev/#tutorials">Tutorials</a> - </li> - <li> - <a href="http://docs.pylonshq.com/pyramid/dev/#change-history">Change History</a> - </li> - <li> - <a href="http://docs.pylonshq.com/pyramid/dev/#sample-applications">Sample Applications</a> - </li> - <li> - <a href="http://docs.pylonshq.com/pyramid/dev/#support-and-development">Support and Development</a> - </li> - <li> - <a href="irc://irc.freenode.net#pyramid">IRC Channel</a> - </li> - </ul> - </div> - </div> - </div> - </div> - <div id="footer"> - <div class="footer">© Copyright 2008-2010, Agendaless Consulting.</div> - </div> + <div id="wrap"> + <div id="top"> + <div class="top align-center"> + <div><img src="${request.static_url('tutorial:static/pyramid.png')}" width="750" height="169" alt="pyramid"/></div> + </div> + </div> + <div id="middle"> + <div class="middle align-center"> + <p class="app-welcome"> + Welcome to <span class="app-name">${project}</span>, an application generated by<br/> + the Pyramid web application development framework. + </p> + </div> + </div> + <div id="bottom"> + <div class="bottom"> + <div id="left" class="align-right"> + <h2>Search documentation</h2> + <form method="get" action="http://docs.pylonsproject.org/projects/pyramid/dev/search.html"> + <input type="text" id="q" name="q" value="" /> + <input type="submit" id="x" value="Go" /> + </form> + </div> + <div id="right" class="align-left"> + <h2>Pyramid links</h2> + <ul class="links"> + <li> + <a href="http://pylonsproject.org">Pylons Website</a> + </li> + <li> + <a href="http://docs.pylonsproject.org/projects/pyramid/dev/#narrative-documentation">Narrative Documentation</a> + </li> + <li> + <a href="http://docs.pylonsproject.org/projects/pyramid/dev/#api-documentation">API Documentation</a> + </li> + <li> + <a href="http://docs.pylonsproject.org/projects/pyramid/dev/#tutorials">Tutorials</a> + </li> + <li> + <a href="http://docs.pylonsproject.org/projects/pyramid/dev/#change-history">Change History</a> + </li> + <li> + <a href="http://docs.pylonsproject.org/projects/pyramid/dev/#sample-applications">Sample Applications</a> + </li> + <li> + <a href="http://docs.pylonsproject.org/projects/pyramid/dev/#support-and-development">Support and Development</a> + </li> + <li> + <a href="irc://irc.freenode.net#pyramid">IRC Channel</a> + </li> + </ul> + </div> + </div> + </div> + </div> + <div id="footer"> + <div class="footer">© Copyright 2008-2011, Agendaless Consulting.</div> + </div> </body> -</html>
\ No newline at end of file +</html> diff --git a/docs/tutorials/wiki2/src/basiclayout/tutorial/tests.py b/docs/tutorials/wiki2/src/basiclayout/tutorial/tests.py index fa3788340..5efa6affa 100644 --- a/docs/tutorials/wiki2/src/basiclayout/tutorial/tests.py +++ b/docs/tutorials/wiki2/src/basiclayout/tutorial/tests.py @@ -1,5 +1,4 @@ import unittest -from pyramid.config import Configurator from pyramid import testing def _initTestingDB(): @@ -10,12 +9,11 @@ def _initTestingDB(): class TestMyView(unittest.TestCase): def setUp(self): - self.config = Configurator(autocommit=True) - self.config.begin() + self.config = testing.setUp() _initTestingDB() def tearDown(self): - self.config.end() + testing.tearDown() def test_it(self): from tutorial.views import my_view diff --git a/docs/tutorials/wiki2/src/models/MANIFEST.in b/docs/tutorials/wiki2/src/models/MANIFEST.in new file mode 100644 index 000000000..81beba1b1 --- /dev/null +++ b/docs/tutorials/wiki2/src/models/MANIFEST.in @@ -0,0 +1,2 @@ +include *.txt *.ini *.cfg *.rst +recursive-include tutorial *.ico *.png *.css *.gif *.jpg *.pt *.txt *.mak *.mako *.js *.html *.xml diff --git a/docs/tutorials/wiki2/src/models/development.ini b/docs/tutorials/wiki2/src/models/development.ini index b0cfd12a7..3b615f635 100644 --- a/docs/tutorials/wiki2/src/models/development.ini +++ b/docs/tutorials/wiki2/src/models/development.ini @@ -11,9 +11,13 @@ sqlalchemy.url = sqlite:///%(here)s/tutorial.db [pipeline:main] pipeline = egg:WebError#evalerror - egg:repoze.tm2#tm + tm tutorial +[filter:tm] +use = egg:repoze.tm2#tm +commit_veto = repoze.tm:default_commit_veto + [server:main] use = egg:Paste#http host = 0.0.0.0 diff --git a/docs/tutorials/wiki2/src/models/production.ini b/docs/tutorials/wiki2/src/models/production.ini new file mode 100644 index 000000000..0fdc38811 --- /dev/null +++ b/docs/tutorials/wiki2/src/models/production.ini @@ -0,0 +1,77 @@ +[app:tutorial] +use = egg:tutorial +reload_templates = false +debug_authorization = false +debug_notfound = false +debug_routematch = false +debug_templates = false +default_locale_name = en +sqlalchemy.url = sqlite:///%(here)s/tutorial.db + +[filter:weberror] +use = egg:WebError#error_catcher +debug = false +;error_log = +;show_exceptions_in_wsgi_errors = true +;smtp_server = localhost +;error_email = janitor@example.com +;smtp_username = janitor +;smtp_password = "janitor's password" +;from_address = paste@localhost +;error_subject_prefix = "Pyramid Error" +;smtp_use_tls = +;error_message = + +[filter:tm] +use = egg:repoze.tm2#tm +commit_veto = repoze.tm:default_commit_veto + +[pipeline:main] +pipeline = + weberror + tm + tutorial + +[server:main] +use = egg:Paste#http +host = 0.0.0.0 +port = 6543 + +# Begin logging configuration + +[loggers] +keys = root, tutorial, sqlalchemy + +[handlers] +keys = console + +[formatters] +keys = generic + +[logger_root] +level = WARN +handlers = console + +[logger_tutorial] +level = WARN +handlers = +qualname = tutorial + +[logger_sqlalchemy] +level = WARN +handlers = +qualname = sqlalchemy.engine +# "level = INFO" logs SQL queries. +# "level = DEBUG" logs SQL queries and results. +# "level = WARN" logs neither. (Recommended for production systems.) + +[handler_console] +class = StreamHandler +args = (sys.stderr,) +level = NOTSET +formatter = generic + +[formatter_generic] +format = %(asctime)s %(levelname)-5.5s [%(name)s][%(threadName)s] %(message)s + +# End logging configuration diff --git a/docs/tutorials/wiki2/src/models/setup.py b/docs/tutorials/wiki2/src/models/setup.py index 09764f40f..eaf1ddcfe 100644 --- a/docs/tutorials/wiki2/src/models/setup.py +++ b/docs/tutorials/wiki2/src/models/setup.py @@ -11,7 +11,7 @@ requires = [ 'pyramid', 'SQLAlchemy', 'transaction', - 'repoze.tm2', + 'repoze.tm2>=1.0b1', # default_commit_veto 'zope.sqlalchemy', 'WebError', ] diff --git a/docs/tutorials/wiki2/src/models/tutorial/models.py b/docs/tutorials/wiki2/src/models/tutorial/models.py index 23b8afab8..797fff929 100644 --- a/docs/tutorials/wiki2/src/models/tutorial/models.py +++ b/docs/tutorials/wiki2/src/models/tutorial/models.py @@ -12,7 +12,8 @@ from sqlalchemy.orm import sessionmaker from zope.sqlalchemy import ZopeTransactionExtension -DBSession = scoped_session(sessionmaker(extension=ZopeTransactionExtension())) +DBSession = scoped_session(sessionmaker( + extension=ZopeTransactionExtension())) Base = declarative_base() class Page(Base): diff --git a/docs/tutorials/wiki2/src/models/tutorial/static/footerbg.png b/docs/tutorials/wiki2/src/models/tutorial/static/footerbg.png Binary files differnew file mode 100644 index 000000000..1fbc873da --- /dev/null +++ b/docs/tutorials/wiki2/src/models/tutorial/static/footerbg.png diff --git a/docs/tutorials/wiki2/src/models/tutorial/static/headerbg.png b/docs/tutorials/wiki2/src/models/tutorial/static/headerbg.png Binary files differnew file mode 100644 index 000000000..0596f2020 --- /dev/null +++ b/docs/tutorials/wiki2/src/models/tutorial/static/headerbg.png diff --git a/docs/tutorials/wiki2/src/models/tutorial/static/ie6.css b/docs/tutorials/wiki2/src/models/tutorial/static/ie6.css new file mode 100644 index 000000000..b7c8493d8 --- /dev/null +++ b/docs/tutorials/wiki2/src/models/tutorial/static/ie6.css @@ -0,0 +1,8 @@ +* html img, +* html .png{position:relative;behavior:expression((this.runtimeStyle.behavior="none")&&(this.pngSet?this.pngSet=true:(this.nodeName == "IMG" && this.src.toLowerCase().indexOf('.png')>-1?(this.runtimeStyle.backgroundImage = "none", +this.runtimeStyle.filter = "progid:DXImageTransform.Microsoft.AlphaImageLoader(src='" + this.src + "',sizingMethod='image')", +this.src = "static/transparent.gif"):(this.origBg = this.origBg? this.origBg :this.currentStyle.backgroundImage.toString().replace('url("','').replace('")',''), +this.runtimeStyle.filter = "progid:DXImageTransform.Microsoft.AlphaImageLoader(src='" + this.origBg + "',sizingMethod='crop')", +this.runtimeStyle.backgroundImage = "none")),this.pngSet=true) +);} +#wrap{display:table;height:100%} diff --git a/docs/tutorials/wiki2/src/models/tutorial/static/logo.png b/docs/tutorials/wiki2/src/models/tutorial/static/logo.png Binary files differdeleted file mode 100644 index 88f5d9865..000000000 --- a/docs/tutorials/wiki2/src/models/tutorial/static/logo.png +++ /dev/null diff --git a/docs/tutorials/wiki2/src/models/tutorial/static/middlebg.png b/docs/tutorials/wiki2/src/models/tutorial/static/middlebg.png Binary files differnew file mode 100644 index 000000000..2369cfb7d --- /dev/null +++ b/docs/tutorials/wiki2/src/models/tutorial/static/middlebg.png diff --git a/docs/tutorials/wiki2/src/models/tutorial/static/pylons.css b/docs/tutorials/wiki2/src/models/tutorial/static/pylons.css index c153be07f..fd1914d8d 100644 --- a/docs/tutorials/wiki2/src/models/tutorial/static/pylons.css +++ b/docs/tutorials/wiki2/src/models/tutorial/static/pylons.css @@ -4,34 +4,23 @@ body{line-height:1;} ol,ul{list-style:none;} blockquote,q{quotes:none;} blockquote:before,blockquote:after,q:before,q:after{content:'';content:none;} -/* remember to define focus styles! */ :focus{outline:0;} -/* remember to highlight inserts somehow! */ ins{text-decoration:none;} del{text-decoration:line-through;} -/* tables still need 'cellspacing="0"' in the markup */ table{border-collapse:collapse;border-spacing:0;} -/* restyling */ sub{vertical-align:sub;font-size:smaller;line-height:normal;} sup{vertical-align:super;font-size:smaller;line-height:normal;} -/* lists */ ul,menu,dir{display:block;list-style-type:disc;margin:1em 0;padding-left:40px;} ol{display:block;list-style-type:decimal-leading-zero;margin:1em 0;padding-left:40px;} li{display:list-item;} -/* nested lists have no top/bottom margins */ ul ul,ul ol,ul dir,ul menu,ul dl,ol ul,ol ol,ol dir,ol menu,ol dl,dir ul,dir ol,dir dir,dir menu,dir dl,menu ul,menu ol,menu dir,menu menu,menu dl,dl ul,dl ol,dl dir,dl menu,dl dl{margin-top:0;margin-bottom:0;} -/* 2 deep unordered lists use a circle */ ol ul,ul ul,menu ul,dir ul,ol menu,ul menu,menu menu,dir menu,ol dir,ul dir,menu dir,dir dir{list-style-type:circle;} -/* 3 deep (or more) unordered lists use a square */ ol ol ul,ol ul ul,ol menu ul,ol dir ul,ol ol menu,ol ul menu,ol menu menu,ol dir menu,ol ol dir,ol ul dir,ol menu dir,ol dir dir,ul ol ul,ul ul ul,ul menu ul,ul dir ul,ul ol menu,ul ul menu,ul menu menu,ul dir menu,ul ol dir,ul ul dir,ul menu dir,ul dir dir,menu ol ul,menu ul ul,menu menu ul,menu dir ul,menu ol menu,menu ul menu,menu menu menu,menu dir menu,menu ol dir,menu ul dir,menu menu dir,menu dir dir,dir ol ul,dir ul ul,dir menu ul,dir dir ul,dir ol menu,dir ul menu,dir menu menu,dir dir menu,dir ol dir,dir ul dir,dir menu dir,dir dir dir{list-style-type:square;} .hidden{display:none;} p{line-height:1.5em;} -h1{font-size:1.75em;/* 28px */ -line-height:1.7em;font-family:helvetica,verdana;} -h2{font-size:1.5em;/* 24px */ -line-height:1.7em;font-family:helvetica,verdana;} -h3{font-size:1.25em;/* 20px */ -line-height:1.7em;font-family:helvetica,verdana;} +h1{font-size:1.75em;line-height:1.7em;font-family:helvetica,verdana;} +h2{font-size:1.5em;line-height:1.7em;font-family:helvetica,verdana;} +h3{font-size:1.25em;line-height:1.7em;font-family:helvetica,verdana;} h4{font-size:1em;line-height:1.7em;font-family:helvetica,verdana;} html,body{width:100%;height:100%;} body{margin:0;padding:0;background-color:#ffffff;position:relative;font:16px/24px "Nobile","Lucida Grande",Lucida,Verdana,sans-serif;} @@ -42,23 +31,26 @@ body h2, body h3, body h4, body h5, -body h6{font-family:"Nobile","Lucida Grande",Lucida,Verdana,sans-serif;font-weight:normal;color:#144fb2;font-style:normal;} -#wrap {min-height: 100%;} -#header,#footer{width:100%;color:#ffffff;height:40px;position:absolute;text-align:center;line-height:40px;overflow:hidden;font-size:12px;} -#header{background-color:#e88f00;top:0;font-size:14px;} -#footer{background-color:#000000;bottom:0;position: relative;margin-top:-40px;clear:both;} -.header,.footer{width:700px;margin-right:auto;margin-left:auto;} +body h6{font-family:"Neuton","Lucida Grande",Lucida,Verdana,sans-serif;font-weight:normal;color:#373839;font-style:normal;} +#wrap{min-height:100%;} +#header,#footer{width:100%;color:#ffffff;height:40px;position:absolute;text-align:center;line-height:40px;overflow:hidden;font-size:12px;vertical-align:middle;} +#header{background:#000000;top:0;font-size:14px;} +#footer{bottom:0;background:#000000 url(footerbg.png) repeat-x 0 top;position:relative;margin-top:-40px;clear:both;} +.header,.footer{width:750px;margin-right:auto;margin-left:auto;} .wrapper{width:100%} -#top,#bottom{width:100%;} -#top{color:#888;background-color:#eee;height:300px;border-bottom:2px solid #ddd;} -#bottom{color:#222;background-color:#ffffff;overflow:hidden;padding-bottom:80px;} -.top,.bottom{width:700px;margin-right:auto;margin-left:auto;} -.top{padding-top:100px;} +#top,#top-small,#bottom{width:100%;} +#top{color:#000000;height:230px;background:#ffffff url(headerbg.png) repeat-x 0 top;position:relative;} +#top-small{color:#000000;height:60px;background:#ffffff url(headerbg.png) repeat-x 0 top;position:relative;} +#bottom{color:#222;background-color:#ffffff;} +.top,.top-small,.middle,.bottom{width:750px;margin-right:auto;margin-left:auto;} +.top{padding-top:40px;} +.top-small{padding-top:10px;} +#middle{width:100%;height:100px;background:url(middlebg.png) repeat-x;border-top:2px solid #ffffff;border-bottom:2px solid #b2b2b2;} .app-welcome{margin-top:25px;} .app-name{color:#000000;font-weight:bold;} .bottom{padding-top:50px;} -#left{width:325px;float:left;padding-right:25px;} -#right{width:325px;float:right;padding-left:25px;} +#left{width:350px;float:left;padding-right:25px;} +#right{width:350px;float:right;padding-left:25px;} .align-left{text-align:left;} .align-right{text-align:right;} .align-center{text-align:center;} @@ -67,7 +59,7 @@ ul.links li{list-style-type:none;font-size:14px;} form{border-style:none;} fieldset{border-style:none;} input{color:#222;border:1px solid #ccc;font-family:sans-serif;font-size:12px;line-height:16px;} -input[type=text]{} +input[type=text],input[type=password]{width:205px;} input[type=submit]{background-color:#ddd;font-weight:bold;} /*Opera Fix*/ -body:before {content:"";height:100%;float:left;width:0;margin-top:-32767px;} +body:before{content:"";height:100%;float:left;width:0;margin-top:-32767px;} diff --git a/docs/tutorials/wiki2/src/models/tutorial/static/pyramid-small.png b/docs/tutorials/wiki2/src/models/tutorial/static/pyramid-small.png Binary files differnew file mode 100644 index 000000000..a5bc0ade7 --- /dev/null +++ b/docs/tutorials/wiki2/src/models/tutorial/static/pyramid-small.png diff --git a/docs/tutorials/wiki2/src/models/tutorial/static/pyramid.png b/docs/tutorials/wiki2/src/models/tutorial/static/pyramid.png Binary files differnew file mode 100644 index 000000000..347e05549 --- /dev/null +++ b/docs/tutorials/wiki2/src/models/tutorial/static/pyramid.png diff --git a/docs/tutorials/wiki2/src/models/tutorial/static/transparent.gif b/docs/tutorials/wiki2/src/models/tutorial/static/transparent.gif Binary files differnew file mode 100644 index 000000000..0341802e5 --- /dev/null +++ b/docs/tutorials/wiki2/src/models/tutorial/static/transparent.gif diff --git a/docs/tutorials/wiki2/src/models/tutorial/templates/mytemplate.pt b/docs/tutorials/wiki2/src/models/tutorial/templates/mytemplate.pt index 6ad23d44f..d98420680 100644 --- a/docs/tutorials/wiki2/src/models/tutorial/templates/mytemplate.pt +++ b/docs/tutorials/wiki2/src/models/tutorial/templates/mytemplate.pt @@ -1,79 +1,75 @@ <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd"> <html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en" xmlns:tal="http://xml.zope.org/namespaces/tal"> <head> - <title>The Pyramid Web Application Development Framework</title> - <meta http-equiv="Content-Type" content="text/html;charset=UTF-8"/> - <meta name="keywords" content="python web application" /> - <meta name="description" content="pyramid web application" /> - <link rel="shortcut icon" href="${request.application_url}/static/favicon.ico" /> - <link rel="stylesheet" href="${request.application_url}/static/pylons.css" type="text/css" media="screen" charset="utf-8" /> - <link rel="stylesheet" href="http://fonts.googleapis.com/css?family=Nobile:regular,italic,bold,bolditalic&subset=latin" type="text/css" media="screen" charset="utf-8" /> - <!--[if !IE 7]> - <style type="text/css"> - #wrap {display:table;height:100%} - </style> - <![endif]--> + <title>The Pyramid Web Application Development Framework</title> + <meta http-equiv="Content-Type" content="text/html;charset=UTF-8"/> + <meta name="keywords" content="python web application" /> + <meta name="description" content="pyramid web application" /> + <link rel="shortcut icon" href="${request.static_url('tutorial:static/favicon.ico')}" /> + <link rel="stylesheet" href="${request.static_url('tutorial:static/pylons.css')}" type="text/css" media="screen" charset="utf-8" /> + <link rel="stylesheet" href="http://fonts.googleapis.com/css?family=Neuton|Nobile:regular,i,b,bi&subset=latin" type="text/css" media="screen" charset="utf-8" /> + <!--[if lte IE 6]> + <link rel="stylesheet" href="${request.static_url('tutorial:static/ie6.css')}" type="text/css" media="screen" charset="utf-8" /> + <![endif]--> </head> <body> - <div id="wrap"> - <div id="header"> - <div class="header">The Pyramid Web Application Development Framework</div> - </div> - <div id="top"> - <div class="top align-center"> - <img src="${request.application_url}/static/logo.png" width="300" height="80"/> - <p class="app-welcome"> - Welcome to <span class="app-name">${project}</span>, an application generated by<br/> - the Pyramid web application development framework. - </p> - </div> - </div> - <div id="bottom"> - <div class="bottom"> - <div id="left" class="align-right"> - <h3>Search Pyramid documentation</h3> - <form method="get" action="http://docs.pylonshq.com/pyramid/dev/search.html"> - <input type="text" id="q" name="q" value="" /> - <input type="submit" id="x" value="Search" /> - </form> - </div> - <div id="right" class="align-left"> - <h3>Pyramid links</h3> - <ul class="links"> - <li> - <a href="http://pylonshq.com">Pylons Website</a> - </li> - <li> - <a href="http://docs.pylonshq.com/">The Pylons Project Documentation</a> - </li> - <li> - <a href="http://docs.pylonshq.com/pyramid/dev/#narrative-documentation">Narrative Documentation</a> - </li> - <li> - <a href="http://docs.pylonshq.com/pyramid/dev/#api-documentation">API Documentation</a> - </li> - <li> - <a href="http://docs.pylonshq.com/pyramid/dev/#tutorials">Tutorials</a> - </li> - <li> - <a href="http://docs.pylonshq.com/pyramid/dev/#change-history">Change History</a> - </li> - <li> - <a href="http://docs.pylonshq.com/pyramid/dev/#sample-applications">Sample Applications</a> - </li> - <li> - <a href="http://docs.pylonshq.com/pyramid/dev/#support-and-development">Support and Development</a> - </li> - <li> - <a href="irc://irc.freenode.net#pyramid">IRC Channel</a> - </li> - </ul> - </div> - </div> - </div> - </div> - <div id="footer"> - <div class="footer">© Copyright 2008-2010, Agendaless Consulting.</div> - </div> + <div id="wrap"> + <div id="top"> + <div class="top align-center"> + <div><img src="${request.static_url('tutorial:static/pyramid.png')}" width="750" height="169" alt="pyramid"/></div> + </div> + </div> + <div id="middle"> + <div class="middle align-center"> + <p class="app-welcome"> + Welcome to <span class="app-name">${project}</span>, an application generated by<br/> + the Pyramid web application development framework. + </p> + </div> + </div> + <div id="bottom"> + <div class="bottom"> + <div id="left" class="align-right"> + <h2>Search documentation</h2> + <form method="get" action="http://docs.pylonsproject.org/projects/pyramid/dev/search.html"> + <input type="text" id="q" name="q" value="" /> + <input type="submit" id="x" value="Go" /> + </form> + </div> + <div id="right" class="align-left"> + <h2>Pyramid links</h2> + <ul class="links"> + <li> + <a href="http://pylonsproject.org">Pylons Website</a> + </li> + <li> + <a href="http://docs.pylonsproject.org/projects/pyramid/dev/#narrative-documentation">Narrative Documentation</a> + </li> + <li> + <a href="http://docs.pylonsproject.org/projects/pyramid/dev/#api-documentation">API Documentation</a> + </li> + <li> + <a href="http://docs.pylonsproject.org/projects/pyramid/dev/#tutorials">Tutorials</a> + </li> + <li> + <a href="http://docs.pylonsproject.org/projects/pyramid/dev/#change-history">Change History</a> + </li> + <li> + <a href="http://docs.pylonsproject.org/projects/pyramid/dev/#sample-applications">Sample Applications</a> + </li> + <li> + <a href="http://docs.pylonsproject.org/projects/pyramid/dev/#support-and-development">Support and Development</a> + </li> + <li> + <a href="irc://irc.freenode.net#pyramid">IRC Channel</a> + </li> + </ul> + </div> + </div> + </div> + </div> + <div id="footer"> + <div class="footer">© Copyright 2008-2011, Agendaless Consulting.</div> + </div> </body> -</html>
\ No newline at end of file +</html> diff --git a/docs/tutorials/wiki2/src/models/tutorial/tests.py b/docs/tutorials/wiki2/src/models/tutorial/tests.py index 42b0aaada..71f5e21e3 100644 --- a/docs/tutorials/wiki2/src/models/tutorial/tests.py +++ b/docs/tutorials/wiki2/src/models/tutorial/tests.py @@ -1,5 +1,4 @@ import unittest -from pyramid.config import Configurator from pyramid import testing def _initTestingDB(): @@ -9,12 +8,11 @@ def _initTestingDB(): class TestMyView(unittest.TestCase): def setUp(self): - self.config = Configurator(autocommit=True) - self.config.begin() + self.config = testing.setUp() _initTestingDB() def tearDown(self): - self.config.end() + testing.tearDown() def test_it(self): from tutorial.views import my_view diff --git a/docs/tutorials/wiki2/src/views/MANIFEST.in b/docs/tutorials/wiki2/src/views/MANIFEST.in new file mode 100644 index 000000000..81beba1b1 --- /dev/null +++ b/docs/tutorials/wiki2/src/views/MANIFEST.in @@ -0,0 +1,2 @@ +include *.txt *.ini *.cfg *.rst +recursive-include tutorial *.ico *.png *.css *.gif *.jpg *.pt *.txt *.mak *.mako *.js *.html *.xml diff --git a/docs/tutorials/wiki2/src/views/development.ini b/docs/tutorials/wiki2/src/views/development.ini index b0cfd12a7..3b615f635 100644 --- a/docs/tutorials/wiki2/src/views/development.ini +++ b/docs/tutorials/wiki2/src/views/development.ini @@ -11,9 +11,13 @@ sqlalchemy.url = sqlite:///%(here)s/tutorial.db [pipeline:main] pipeline = egg:WebError#evalerror - egg:repoze.tm2#tm + tm tutorial +[filter:tm] +use = egg:repoze.tm2#tm +commit_veto = repoze.tm:default_commit_veto + [server:main] use = egg:Paste#http host = 0.0.0.0 diff --git a/docs/tutorials/wiki2/src/views/production.ini b/docs/tutorials/wiki2/src/views/production.ini new file mode 100644 index 000000000..0fdc38811 --- /dev/null +++ b/docs/tutorials/wiki2/src/views/production.ini @@ -0,0 +1,77 @@ +[app:tutorial] +use = egg:tutorial +reload_templates = false +debug_authorization = false +debug_notfound = false +debug_routematch = false +debug_templates = false +default_locale_name = en +sqlalchemy.url = sqlite:///%(here)s/tutorial.db + +[filter:weberror] +use = egg:WebError#error_catcher +debug = false +;error_log = +;show_exceptions_in_wsgi_errors = true +;smtp_server = localhost +;error_email = janitor@example.com +;smtp_username = janitor +;smtp_password = "janitor's password" +;from_address = paste@localhost +;error_subject_prefix = "Pyramid Error" +;smtp_use_tls = +;error_message = + +[filter:tm] +use = egg:repoze.tm2#tm +commit_veto = repoze.tm:default_commit_veto + +[pipeline:main] +pipeline = + weberror + tm + tutorial + +[server:main] +use = egg:Paste#http +host = 0.0.0.0 +port = 6543 + +# Begin logging configuration + +[loggers] +keys = root, tutorial, sqlalchemy + +[handlers] +keys = console + +[formatters] +keys = generic + +[logger_root] +level = WARN +handlers = console + +[logger_tutorial] +level = WARN +handlers = +qualname = tutorial + +[logger_sqlalchemy] +level = WARN +handlers = +qualname = sqlalchemy.engine +# "level = INFO" logs SQL queries. +# "level = DEBUG" logs SQL queries and results. +# "level = WARN" logs neither. (Recommended for production systems.) + +[handler_console] +class = StreamHandler +args = (sys.stderr,) +level = NOTSET +formatter = generic + +[formatter_generic] +format = %(asctime)s %(levelname)-5.5s [%(name)s][%(threadName)s] %(message)s + +# End logging configuration diff --git a/docs/tutorials/wiki2/src/views/setup.py b/docs/tutorials/wiki2/src/views/setup.py index 58f464f8c..ae9869d50 100644 --- a/docs/tutorials/wiki2/src/views/setup.py +++ b/docs/tutorials/wiki2/src/views/setup.py @@ -11,7 +11,7 @@ requires = [ 'pyramid', 'SQLAlchemy', 'transaction', - 'repoze.tm2', + 'repoze.tm2>=1.0b1', # default_commit_veto 'zope.sqlalchemy', 'WebError', 'docutils', diff --git a/docs/tutorials/wiki2/src/views/tutorial/__init__.py b/docs/tutorials/wiki2/src/views/tutorial/__init__.py index 334fde814..1a8d24499 100644 --- a/docs/tutorials/wiki2/src/views/tutorial/__init__.py +++ b/docs/tutorials/wiki2/src/views/tutorial/__init__.py @@ -10,7 +10,7 @@ def main(global_config, **settings): initialize_sql(engine) config = Configurator(settings=settings) config.add_static_view('static', 'tutorial:static') - config.add_route('home', '/', view='tutorial.views.view_wiki') + config.add_route('view_wiki', '/', view='tutorial.views.view_wiki') config.add_route('view_page', '/{pagename}', view='tutorial.views.view_page', view_renderer='tutorial:templates/view.pt') diff --git a/docs/tutorials/wiki2/src/views/tutorial/static/footerbg.png b/docs/tutorials/wiki2/src/views/tutorial/static/footerbg.png Binary files differnew file mode 100644 index 000000000..1fbc873da --- /dev/null +++ b/docs/tutorials/wiki2/src/views/tutorial/static/footerbg.png diff --git a/docs/tutorials/wiki2/src/views/tutorial/static/headerbg.png b/docs/tutorials/wiki2/src/views/tutorial/static/headerbg.png Binary files differnew file mode 100644 index 000000000..0596f2020 --- /dev/null +++ b/docs/tutorials/wiki2/src/views/tutorial/static/headerbg.png diff --git a/docs/tutorials/wiki2/src/views/tutorial/static/ie6.css b/docs/tutorials/wiki2/src/views/tutorial/static/ie6.css new file mode 100644 index 000000000..b7c8493d8 --- /dev/null +++ b/docs/tutorials/wiki2/src/views/tutorial/static/ie6.css @@ -0,0 +1,8 @@ +* html img, +* html .png{position:relative;behavior:expression((this.runtimeStyle.behavior="none")&&(this.pngSet?this.pngSet=true:(this.nodeName == "IMG" && this.src.toLowerCase().indexOf('.png')>-1?(this.runtimeStyle.backgroundImage = "none", +this.runtimeStyle.filter = "progid:DXImageTransform.Microsoft.AlphaImageLoader(src='" + this.src + "',sizingMethod='image')", +this.src = "static/transparent.gif"):(this.origBg = this.origBg? this.origBg :this.currentStyle.backgroundImage.toString().replace('url("','').replace('")',''), +this.runtimeStyle.filter = "progid:DXImageTransform.Microsoft.AlphaImageLoader(src='" + this.origBg + "',sizingMethod='crop')", +this.runtimeStyle.backgroundImage = "none")),this.pngSet=true) +);} +#wrap{display:table;height:100%} diff --git a/docs/tutorials/wiki2/src/views/tutorial/static/logo.png b/docs/tutorials/wiki2/src/views/tutorial/static/logo.png Binary files differdeleted file mode 100644 index 88f5d9865..000000000 --- a/docs/tutorials/wiki2/src/views/tutorial/static/logo.png +++ /dev/null diff --git a/docs/tutorials/wiki2/src/views/tutorial/static/middlebg.png b/docs/tutorials/wiki2/src/views/tutorial/static/middlebg.png Binary files differnew file mode 100644 index 000000000..2369cfb7d --- /dev/null +++ b/docs/tutorials/wiki2/src/views/tutorial/static/middlebg.png diff --git a/docs/tutorials/wiki2/src/views/tutorial/static/pylons.css b/docs/tutorials/wiki2/src/views/tutorial/static/pylons.css index c153be07f..fd1914d8d 100644 --- a/docs/tutorials/wiki2/src/views/tutorial/static/pylons.css +++ b/docs/tutorials/wiki2/src/views/tutorial/static/pylons.css @@ -4,34 +4,23 @@ body{line-height:1;} ol,ul{list-style:none;} blockquote,q{quotes:none;} blockquote:before,blockquote:after,q:before,q:after{content:'';content:none;} -/* remember to define focus styles! */ :focus{outline:0;} -/* remember to highlight inserts somehow! */ ins{text-decoration:none;} del{text-decoration:line-through;} -/* tables still need 'cellspacing="0"' in the markup */ table{border-collapse:collapse;border-spacing:0;} -/* restyling */ sub{vertical-align:sub;font-size:smaller;line-height:normal;} sup{vertical-align:super;font-size:smaller;line-height:normal;} -/* lists */ ul,menu,dir{display:block;list-style-type:disc;margin:1em 0;padding-left:40px;} ol{display:block;list-style-type:decimal-leading-zero;margin:1em 0;padding-left:40px;} li{display:list-item;} -/* nested lists have no top/bottom margins */ ul ul,ul ol,ul dir,ul menu,ul dl,ol ul,ol ol,ol dir,ol menu,ol dl,dir ul,dir ol,dir dir,dir menu,dir dl,menu ul,menu ol,menu dir,menu menu,menu dl,dl ul,dl ol,dl dir,dl menu,dl dl{margin-top:0;margin-bottom:0;} -/* 2 deep unordered lists use a circle */ ol ul,ul ul,menu ul,dir ul,ol menu,ul menu,menu menu,dir menu,ol dir,ul dir,menu dir,dir dir{list-style-type:circle;} -/* 3 deep (or more) unordered lists use a square */ ol ol ul,ol ul ul,ol menu ul,ol dir ul,ol ol menu,ol ul menu,ol menu menu,ol dir menu,ol ol dir,ol ul dir,ol menu dir,ol dir dir,ul ol ul,ul ul ul,ul menu ul,ul dir ul,ul ol menu,ul ul menu,ul menu menu,ul dir menu,ul ol dir,ul ul dir,ul menu dir,ul dir dir,menu ol ul,menu ul ul,menu menu ul,menu dir ul,menu ol menu,menu ul menu,menu menu menu,menu dir menu,menu ol dir,menu ul dir,menu menu dir,menu dir dir,dir ol ul,dir ul ul,dir menu ul,dir dir ul,dir ol menu,dir ul menu,dir menu menu,dir dir menu,dir ol dir,dir ul dir,dir menu dir,dir dir dir{list-style-type:square;} .hidden{display:none;} p{line-height:1.5em;} -h1{font-size:1.75em;/* 28px */ -line-height:1.7em;font-family:helvetica,verdana;} -h2{font-size:1.5em;/* 24px */ -line-height:1.7em;font-family:helvetica,verdana;} -h3{font-size:1.25em;/* 20px */ -line-height:1.7em;font-family:helvetica,verdana;} +h1{font-size:1.75em;line-height:1.7em;font-family:helvetica,verdana;} +h2{font-size:1.5em;line-height:1.7em;font-family:helvetica,verdana;} +h3{font-size:1.25em;line-height:1.7em;font-family:helvetica,verdana;} h4{font-size:1em;line-height:1.7em;font-family:helvetica,verdana;} html,body{width:100%;height:100%;} body{margin:0;padding:0;background-color:#ffffff;position:relative;font:16px/24px "Nobile","Lucida Grande",Lucida,Verdana,sans-serif;} @@ -42,23 +31,26 @@ body h2, body h3, body h4, body h5, -body h6{font-family:"Nobile","Lucida Grande",Lucida,Verdana,sans-serif;font-weight:normal;color:#144fb2;font-style:normal;} -#wrap {min-height: 100%;} -#header,#footer{width:100%;color:#ffffff;height:40px;position:absolute;text-align:center;line-height:40px;overflow:hidden;font-size:12px;} -#header{background-color:#e88f00;top:0;font-size:14px;} -#footer{background-color:#000000;bottom:0;position: relative;margin-top:-40px;clear:both;} -.header,.footer{width:700px;margin-right:auto;margin-left:auto;} +body h6{font-family:"Neuton","Lucida Grande",Lucida,Verdana,sans-serif;font-weight:normal;color:#373839;font-style:normal;} +#wrap{min-height:100%;} +#header,#footer{width:100%;color:#ffffff;height:40px;position:absolute;text-align:center;line-height:40px;overflow:hidden;font-size:12px;vertical-align:middle;} +#header{background:#000000;top:0;font-size:14px;} +#footer{bottom:0;background:#000000 url(footerbg.png) repeat-x 0 top;position:relative;margin-top:-40px;clear:both;} +.header,.footer{width:750px;margin-right:auto;margin-left:auto;} .wrapper{width:100%} -#top,#bottom{width:100%;} -#top{color:#888;background-color:#eee;height:300px;border-bottom:2px solid #ddd;} -#bottom{color:#222;background-color:#ffffff;overflow:hidden;padding-bottom:80px;} -.top,.bottom{width:700px;margin-right:auto;margin-left:auto;} -.top{padding-top:100px;} +#top,#top-small,#bottom{width:100%;} +#top{color:#000000;height:230px;background:#ffffff url(headerbg.png) repeat-x 0 top;position:relative;} +#top-small{color:#000000;height:60px;background:#ffffff url(headerbg.png) repeat-x 0 top;position:relative;} +#bottom{color:#222;background-color:#ffffff;} +.top,.top-small,.middle,.bottom{width:750px;margin-right:auto;margin-left:auto;} +.top{padding-top:40px;} +.top-small{padding-top:10px;} +#middle{width:100%;height:100px;background:url(middlebg.png) repeat-x;border-top:2px solid #ffffff;border-bottom:2px solid #b2b2b2;} .app-welcome{margin-top:25px;} .app-name{color:#000000;font-weight:bold;} .bottom{padding-top:50px;} -#left{width:325px;float:left;padding-right:25px;} -#right{width:325px;float:right;padding-left:25px;} +#left{width:350px;float:left;padding-right:25px;} +#right{width:350px;float:right;padding-left:25px;} .align-left{text-align:left;} .align-right{text-align:right;} .align-center{text-align:center;} @@ -67,7 +59,7 @@ ul.links li{list-style-type:none;font-size:14px;} form{border-style:none;} fieldset{border-style:none;} input{color:#222;border:1px solid #ccc;font-family:sans-serif;font-size:12px;line-height:16px;} -input[type=text]{} +input[type=text],input[type=password]{width:205px;} input[type=submit]{background-color:#ddd;font-weight:bold;} /*Opera Fix*/ -body:before {content:"";height:100%;float:left;width:0;margin-top:-32767px;} +body:before{content:"";height:100%;float:left;width:0;margin-top:-32767px;} diff --git a/docs/tutorials/wiki2/src/views/tutorial/static/pyramid-small.png b/docs/tutorials/wiki2/src/views/tutorial/static/pyramid-small.png Binary files differnew file mode 100644 index 000000000..a5bc0ade7 --- /dev/null +++ b/docs/tutorials/wiki2/src/views/tutorial/static/pyramid-small.png diff --git a/docs/tutorials/wiki2/src/views/tutorial/static/pyramid.png b/docs/tutorials/wiki2/src/views/tutorial/static/pyramid.png Binary files differnew file mode 100644 index 000000000..347e05549 --- /dev/null +++ b/docs/tutorials/wiki2/src/views/tutorial/static/pyramid.png diff --git a/docs/tutorials/wiki2/src/views/tutorial/static/style.css b/docs/tutorials/wiki2/src/views/tutorial/static/style.css deleted file mode 100644 index cad87e0d4..000000000 --- a/docs/tutorials/wiki2/src/views/tutorial/static/style.css +++ /dev/null @@ -1,109 +0,0 @@ -html, body { - color: black; - background-color: #ddd; - font: x-small "Lucida Grande", "Lucida Sans Unicode", geneva, sans-serif; - margin: 0; - padding: 0; -} - -td, th {padding:3px;border:none;} -tr th {text-align:left;background-color:#f0f0f0;color:#333;} -tr.odd td {background-color:#edf3fe;} -tr.even td {background-color:#fff;} - -#header { - height: 80px; - width: 777px; - background: blue URL('../images/header_inner.png') no-repeat; - border-left: 1px solid #aaa; - border-right: 1px solid #aaa; - margin: 0 auto 0 auto; -} - -a.link, a, a.active { - color: #369; -} - - -#main_content { - color: black; - font-size: 127%; - background-color: white; - width: 757px; - margin: 0 auto 0 auto; - border-left: 1px solid #aaa; - border-right: 1px solid #aaa; - padding: 10px; -} - -#sidebar { - border: 1px solid #aaa; - background-color: #eee; - margin: 0.5em; - padding: 1em; - float: right; - width: 200px; - font-size: 88%; -} - -#sidebar h2 { - margin-top: 0; -} - -#sidebar ul { - margin-left: 1.5em; - padding-left: 0; -} - -h1,h2,h3,h4,h5,h6,#getting_started_steps { - font-family: "Century Schoolbook L", Georgia, serif; - font-weight: bold; -} - -h2 { - font-size: 150%; -} - -#footer { - border: 1px solid #aaa; - border-top: 0px none; - color: #999; - background-color: white; - padding: 10px; - font-size: 80%; - text-align: center; - width: 757px; - margin: 0 auto 1em auto; -} - -.code { - font-family: monospace; -} - -span.code { - font-weight: bold; - background: #eee; -} - -#status_block { - margin: 0 auto 0.5em auto; - padding: 15px 10px 15px 55px; - background: #cec URL('../images/ok.png') left center no-repeat; - border: 1px solid #9c9; - width: 450px; - font-size: 120%; - font-weight: bolder; -} - -.notice { - margin: 0.5em auto 0.5em auto; - padding: 15px 10px 15px 55px; - width: 450px; - background: #eef URL('../images/info.png') left center no-repeat; - border: 1px solid #cce; -} - -.fielderror { - color: red; - font-weight: bold; -} diff --git a/docs/tutorials/wiki2/src/views/tutorial/static/transparent.gif b/docs/tutorials/wiki2/src/views/tutorial/static/transparent.gif Binary files differnew file mode 100644 index 000000000..0341802e5 --- /dev/null +++ b/docs/tutorials/wiki2/src/views/tutorial/static/transparent.gif diff --git a/docs/tutorials/wiki2/src/views/tutorial/templates/edit.pt b/docs/tutorials/wiki2/src/views/tutorial/templates/edit.pt index 047a64eb3..3f2039cb6 100644 --- a/docs/tutorials/wiki2/src/views/tutorial/templates/edit.pt +++ b/docs/tutorials/wiki2/src/views/tutorial/templates/edit.pt @@ -1,32 +1,58 @@ -<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" - "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"> -<html - xmlns="http://www.w3.org/1999/xhtml" +<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" + "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd"> +<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en" xmlns:tal="http://xml.zope.org/namespaces/tal"> - <head> - <meta content="text/html; charset=utf-8" http-equiv="Content-Type"/> - <title>Pyramid tutorial wiki (based on TurboGears 20-Minute Wiki) - Editing: ${page.name}</title> - <link rel="stylesheet" type="text/css" - href="${request.application_url}/static/style.css" /> + <title>${page.name} - Pyramid tutorial wiki (based on + TurboGears 20-Minute Wiki)</title> + <meta http-equiv="Content-Type" content="text/html;charset=UTF-8"/> + <meta name="keywords" content="python web application" /> + <meta name="description" content="pyramid web application" /> + <link rel="shortcut icon" + href="${request.static_url('tutorial:static/favicon.ico')}" /> + <link rel="stylesheet" + href="${request.static_url('tutorial:static/pylons.css')}" + type="text/css" media="screen" charset="utf-8" /> + <!--[if lte IE 6]> + <link rel="stylesheet" + href="${request.static_url('tutorial:static/ie6.css')}" + type="text/css" media="screen" charset="utf-8" /> + <![endif]--> </head> - <body> - -<div class="main_content"> - <div style="float:right; width: 10em;"> Viewing - <span tal:replace="page.name">Page Name Goes Here</span> <br/> - You can return to the <a href="${request.application_url}" - >FrontPage</a>. - </div> - - <div> - <form action="${save_url}" method="post"> - <textarea name="body" tal:content="page.data" rows="10" cols="60"/> - <input type="submit" name="form.submitted" value="Save"/> - </form> + <div id="wrap"> + <div id="top-small"> + <div class="top-small align-center"> + <div> + <img width="220" height="50" alt="pyramid" + src="${request.static_url('tutorial:static/pyramid-small.png')}" /> + </div> + </div> + </div> + <div id="middle"> + <div class="middle align-right"> + <div id="left" class="app-welcome align-left"> + Editing <b><span tal:replace="page.name">Page Name Goes + Here</span></b><br/> + You can return to the + <a href="${request.application_url}">FrontPage</a>.<br/> + </div> + <div id="right" class="app-welcome align-right"></div> + </div> + </div> + <div id="bottom"> + <div class="bottom"> + <form action="${save_url}" method="post"> + <textarea name="body" tal:content="page.data" rows="10" + cols="60"/><br/> + <input type="submit" name="form.submitted" value="Save"/> + </form> + </div> + </div> + </div> + <div id="footer"> + <div class="footer" + >© Copyright 2008-2011, Agendaless Consulting.</div> </div> -</div> </body> </html> diff --git a/docs/tutorials/wiki2/src/views/tutorial/templates/mytemplate.pt b/docs/tutorials/wiki2/src/views/tutorial/templates/mytemplate.pt index 6ad23d44f..d98420680 100644 --- a/docs/tutorials/wiki2/src/views/tutorial/templates/mytemplate.pt +++ b/docs/tutorials/wiki2/src/views/tutorial/templates/mytemplate.pt @@ -1,79 +1,75 @@ <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd"> <html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en" xmlns:tal="http://xml.zope.org/namespaces/tal"> <head> - <title>The Pyramid Web Application Development Framework</title> - <meta http-equiv="Content-Type" content="text/html;charset=UTF-8"/> - <meta name="keywords" content="python web application" /> - <meta name="description" content="pyramid web application" /> - <link rel="shortcut icon" href="${request.application_url}/static/favicon.ico" /> - <link rel="stylesheet" href="${request.application_url}/static/pylons.css" type="text/css" media="screen" charset="utf-8" /> - <link rel="stylesheet" href="http://fonts.googleapis.com/css?family=Nobile:regular,italic,bold,bolditalic&subset=latin" type="text/css" media="screen" charset="utf-8" /> - <!--[if !IE 7]> - <style type="text/css"> - #wrap {display:table;height:100%} - </style> - <![endif]--> + <title>The Pyramid Web Application Development Framework</title> + <meta http-equiv="Content-Type" content="text/html;charset=UTF-8"/> + <meta name="keywords" content="python web application" /> + <meta name="description" content="pyramid web application" /> + <link rel="shortcut icon" href="${request.static_url('tutorial:static/favicon.ico')}" /> + <link rel="stylesheet" href="${request.static_url('tutorial:static/pylons.css')}" type="text/css" media="screen" charset="utf-8" /> + <link rel="stylesheet" href="http://fonts.googleapis.com/css?family=Neuton|Nobile:regular,i,b,bi&subset=latin" type="text/css" media="screen" charset="utf-8" /> + <!--[if lte IE 6]> + <link rel="stylesheet" href="${request.static_url('tutorial:static/ie6.css')}" type="text/css" media="screen" charset="utf-8" /> + <![endif]--> </head> <body> - <div id="wrap"> - <div id="header"> - <div class="header">The Pyramid Web Application Development Framework</div> - </div> - <div id="top"> - <div class="top align-center"> - <img src="${request.application_url}/static/logo.png" width="300" height="80"/> - <p class="app-welcome"> - Welcome to <span class="app-name">${project}</span>, an application generated by<br/> - the Pyramid web application development framework. - </p> - </div> - </div> - <div id="bottom"> - <div class="bottom"> - <div id="left" class="align-right"> - <h3>Search Pyramid documentation</h3> - <form method="get" action="http://docs.pylonshq.com/pyramid/dev/search.html"> - <input type="text" id="q" name="q" value="" /> - <input type="submit" id="x" value="Search" /> - </form> - </div> - <div id="right" class="align-left"> - <h3>Pyramid links</h3> - <ul class="links"> - <li> - <a href="http://pylonshq.com">Pylons Website</a> - </li> - <li> - <a href="http://docs.pylonshq.com/">The Pylons Project Documentation</a> - </li> - <li> - <a href="http://docs.pylonshq.com/pyramid/dev/#narrative-documentation">Narrative Documentation</a> - </li> - <li> - <a href="http://docs.pylonshq.com/pyramid/dev/#api-documentation">API Documentation</a> - </li> - <li> - <a href="http://docs.pylonshq.com/pyramid/dev/#tutorials">Tutorials</a> - </li> - <li> - <a href="http://docs.pylonshq.com/pyramid/dev/#change-history">Change History</a> - </li> - <li> - <a href="http://docs.pylonshq.com/pyramid/dev/#sample-applications">Sample Applications</a> - </li> - <li> - <a href="http://docs.pylonshq.com/pyramid/dev/#support-and-development">Support and Development</a> - </li> - <li> - <a href="irc://irc.freenode.net#pyramid">IRC Channel</a> - </li> - </ul> - </div> - </div> - </div> - </div> - <div id="footer"> - <div class="footer">© Copyright 2008-2010, Agendaless Consulting.</div> - </div> + <div id="wrap"> + <div id="top"> + <div class="top align-center"> + <div><img src="${request.static_url('tutorial:static/pyramid.png')}" width="750" height="169" alt="pyramid"/></div> + </div> + </div> + <div id="middle"> + <div class="middle align-center"> + <p class="app-welcome"> + Welcome to <span class="app-name">${project}</span>, an application generated by<br/> + the Pyramid web application development framework. + </p> + </div> + </div> + <div id="bottom"> + <div class="bottom"> + <div id="left" class="align-right"> + <h2>Search documentation</h2> + <form method="get" action="http://docs.pylonsproject.org/projects/pyramid/dev/search.html"> + <input type="text" id="q" name="q" value="" /> + <input type="submit" id="x" value="Go" /> + </form> + </div> + <div id="right" class="align-left"> + <h2>Pyramid links</h2> + <ul class="links"> + <li> + <a href="http://pylonsproject.org">Pylons Website</a> + </li> + <li> + <a href="http://docs.pylonsproject.org/projects/pyramid/dev/#narrative-documentation">Narrative Documentation</a> + </li> + <li> + <a href="http://docs.pylonsproject.org/projects/pyramid/dev/#api-documentation">API Documentation</a> + </li> + <li> + <a href="http://docs.pylonsproject.org/projects/pyramid/dev/#tutorials">Tutorials</a> + </li> + <li> + <a href="http://docs.pylonsproject.org/projects/pyramid/dev/#change-history">Change History</a> + </li> + <li> + <a href="http://docs.pylonsproject.org/projects/pyramid/dev/#sample-applications">Sample Applications</a> + </li> + <li> + <a href="http://docs.pylonsproject.org/projects/pyramid/dev/#support-and-development">Support and Development</a> + </li> + <li> + <a href="irc://irc.freenode.net#pyramid">IRC Channel</a> + </li> + </ul> + </div> + </div> + </div> + </div> + <div id="footer"> + <div class="footer">© Copyright 2008-2011, Agendaless Consulting.</div> + </div> </body> -</html>
\ No newline at end of file +</html> diff --git a/docs/tutorials/wiki2/src/views/tutorial/templates/view.pt b/docs/tutorials/wiki2/src/views/tutorial/templates/view.pt index 86fcc914e..423c1d5a1 100644 --- a/docs/tutorials/wiki2/src/views/tutorial/templates/view.pt +++ b/docs/tutorials/wiki2/src/views/tutorial/templates/view.pt @@ -1,28 +1,61 @@ -<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" - "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"> -<html - xmlns="http://www.w3.org/1999/xhtml" +<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" + "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd"> +<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en" xmlns:tal="http://xml.zope.org/namespaces/tal"> - <head> - <meta content="text/html; charset=utf-8" http-equiv="Content-Type"/> - <title>${page.name} - Pyramid tutorial wiki - (based on TurboGears 20-Minute Wiki)</title> - <link rel="stylesheet" type="text/css" - href="${request.application_url}/static/style.css" /> + <title>${page.name} - Pyramid tutorial wiki (based on + TurboGears 20-Minute Wiki)</title> + <meta http-equiv="Content-Type" content="text/html;charset=UTF-8"/> + <meta name="keywords" content="python web application" /> + <meta name="description" content="pyramid web application" /> + <link rel="shortcut icon" + href="${request.static_url('tutorial:static/favicon.ico')}" /> + <link rel="stylesheet" + href="${request.static_url('tutorial:static/pylons.css')}" + type="text/css" media="screen" charset="utf-8" /> + <!--[if lte IE 6]> + <link rel="stylesheet" + href="${request.static_url('tutorial:static/ie6.css')}" + type="text/css" media="screen" charset="utf-8" /> + <![endif]--> </head> - <body> - -<div class="main_content"> -<div style="float:right; width: 10em;"> Viewing -<span tal:replace="page.name">Page Name Goes Here</span> <br/> -You can return to the <a href="${request.application_url}">FrontPage</a>. -</div> - -<div tal:replace="structure content">Page text goes here.</div> -<p><a tal:attributes="href edit_url" href="">Edit this page</a></p> -</div> - + <div id="wrap"> + <div id="top-small"> + <div class="top-small align-center"> + <div> + <img width="220" height="50" alt="pyramid" + src="${request.static_url('tutorial:static/pyramid-small.png')}" /> + </div> + </div> + </div> + <div id="middle"> + <div class="middle align-right"> + <div id="left" class="app-welcome align-left"> + Viewing <b><span tal:replace="page.name">Page Name + Goes Here</span></b><br/> + You can return to the + <a href="${request.application_url}">FrontPage</a>.<br/> + </div> + <div id="right" class="app-welcome align-right"></div> + </div> + </div> + <div id="bottom"> + <div class="bottom"> + <div tal:replace="structure content"> + Page text goes here. + </div> + <p> + <a tal:attributes="href edit_url" href=""> + Edit this page + </a> + </p> + </div> + </div> + </div> + <div id="footer"> + <div class="footer" + >© Copyright 2008-2011, Agendaless Consulting.</div> + </div> </body> </html> diff --git a/docs/tutorials/wiki2/src/views/tutorial/tests.py b/docs/tutorials/wiki2/src/views/tutorial/tests.py index 7b770f927..0bc343833 100644 --- a/docs/tutorials/wiki2/src/views/tutorial/tests.py +++ b/docs/tutorials/wiki2/src/views/tutorial/tests.py @@ -1,6 +1,5 @@ import unittest -from pyramid.config import Configurator from pyramid import testing def _initTestingDB(): @@ -20,28 +19,29 @@ def _registerRoutes(config): class ViewWikiTests(unittest.TestCase): def setUp(self): - self.config = Configurator(autocommit=True) - self.config.begin() + self.config = testing.setUp() def tearDown(self): - self.config.end() - - def test_it(self): + testing.tearDown() + + def _callFUT(self, request): from tutorial.views import view_wiki - self.config.add_route('view_page', '{pagename}') + return view_wiki(request) + + def test_it(self): + _registerRoutes(self.config) request = testing.DummyRequest() - response = view_wiki(request) + response = self._callFUT(request) self.assertEqual(response.location, 'http://example.com/FrontPage') class ViewPageTests(unittest.TestCase): def setUp(self): self.session = _initTestingDB() - self.config = Configurator(autocommit=True) - self.config.begin() + self.config = testing.setUp() def tearDown(self): self.session.remove() - self.config.end() + testing.tearDown() def _callFUT(self, request): from tutorial.views import view_page @@ -71,12 +71,12 @@ class ViewPageTests(unittest.TestCase): class AddPageTests(unittest.TestCase): def setUp(self): self.session = _initTestingDB() - self.config = Configurator(autocommit=True) + self.config = testing.setUp() self.config.begin() def tearDown(self): self.session.remove() - self.config.end() + testing.tearDown() def _callFUT(self, request): from tutorial.views import add_page @@ -104,12 +104,11 @@ class AddPageTests(unittest.TestCase): class EditPageTests(unittest.TestCase): def setUp(self): self.session = _initTestingDB() - self.config = Configurator(autocommit=True) - self.config.begin() + self.config = testing.setUp() def tearDown(self): self.session.remove() - self.config.end() + testing.tearDown() def _callFUT(self, request): from tutorial.views import edit_page |
