diff options
| author | Chris McDonough <chrism@plope.com> | 2015-06-05 14:06:02 -0400 |
|---|---|---|
| committer | Chris McDonough <chrism@plope.com> | 2015-06-05 14:06:02 -0400 |
| commit | f3c67a4217504bc7f2862ec1616342240738efae (patch) | |
| tree | 9e7452b3ffdc8d4f30739cfc9d898169d6719206 /docs | |
| parent | 7b4ed3088af03de473ad164c314062c283afce39 (diff) | |
| parent | c1dbb5092d486df5d7fbad8e52cd1dbcc2c834d9 (diff) | |
| download | pyramid-f3c67a4217504bc7f2862ec1616342240738efae.tar.gz pyramid-f3c67a4217504bc7f2862ec1616342240738efae.tar.bz2 pyramid-f3c67a4217504bc7f2862ec1616342240738efae.zip | |
Merge branch 'master' of github.com:Pylons/pyramid
Diffstat (limited to 'docs')
210 files changed, 4649 insertions, 6520 deletions
diff --git a/docs/api/request.rst b/docs/api/request.rst index b325ad076..105ffb5a7 100644 --- a/docs/api/request.rst +++ b/docs/api/request.rst @@ -11,7 +11,7 @@ :exclude-members: add_response_callback, add_finished_callback, route_url, route_path, current_route_url, current_route_path, static_url, static_path, - model_url, resource_url, set_property, + model_url, resource_url, resource_path, set_property, effective_principals, authenticated_userid, unauthenticated_userid, has_permission diff --git a/docs/conventions.rst b/docs/conventions.rst index 21b506623..0492ab4fd 100644 --- a/docs/conventions.rst +++ b/docs/conventions.rst @@ -1,19 +1,19 @@ Typographical Conventions ========================= -Literals, filenames and function arguments are presented using the +Literals, filenames, and function arguments are presented using the following style: ``argument1`` -Warnings, which represent limitations and need-to-know information +Warnings which represent limitations and need-to-know information related to a topic or concept are presented in the following style: .. warning:: This is a warning. -Notes, which represent additional information related to a topic or +Notes which represent additional information related to a topic or concept are presented in the following style: .. note:: @@ -105,7 +105,7 @@ It may look unusual, but it has advantages: * It allows one to swap out the higher-level package ``foo`` for something else that provides the similar API. An example would be swapping out - one Database for another (e.g. graduating from SQLite to PostgreSQL). + one Database for another (e.g., graduating from SQLite to PostgreSQL). * Looks more neat in cases where a large number of objects get imported from that package. diff --git a/docs/copyright.rst b/docs/copyright.rst index 980335827..3beaee7f7 100644 --- a/docs/copyright.rst +++ b/docs/copyright.rst @@ -39,7 +39,7 @@ any trademark or service mark. Every effort has been made to make this book as complete and as accurate as possible, but no warranty or fitness is implied. The -information provided is on as "as-is" basis. The author and the +information provided is on an "as-is" basis. The author and the publisher shall have neither liability nor responsibility to any person or entity with respect to any loss or damages arising from the information contained in this book. No patent liability is assumed @@ -89,14 +89,14 @@ Contacting The Publisher Please send documentation licensing inquiries, translation inquiries, and other business communications to `Agendaless Consulting <mailto:webmaster@agendaless.com>`_. Please send software and other -technical queries to the `Pylons-devel maillist +technical queries to the `Pylons-devel mailing list <http://groups.google.com/group/pylons-devel>`_. HTML Version and Source Code ---------------------------- An HTML version of this book is freely available via -http://docs.pylonsproject.org +http://docs.pylonsproject.org/projects/pyramid/en/latest/ The source code for the examples used in this book are available within the :app:`Pyramid` software distribution, always available diff --git a/docs/narr/introduction.rst b/docs/narr/introduction.rst index a37d74c9b..2d3cd23e9 100644 --- a/docs/narr/introduction.rst +++ b/docs/narr/introduction.rst @@ -65,11 +65,11 @@ Openness .. _what_makes_pyramid_unique: -What Makes Pyramid Unique +What makes Pyramid unique ------------------------- Understandably, people don't usually want to hear about squishy engineering -principles, they want to hear about concrete stuff that solves their +principles; they want to hear about concrete stuff that solves their problems. With that in mind, what would make someone want to use Pyramid instead of one of the many other web frameworks available today? What makes Pyramid unique? @@ -78,13 +78,13 @@ This is a hard question to answer, because there are lots of excellent choices, and it's actually quite hard to make a wrong choice, particularly in the Python web framework market. But one reasonable answer is this: you can write very small applications in Pyramid without needing to know a lot. -"What?", you say, "that can't possibly be a unique feature, lots of other web +"What?", you say. "That can't possibly be a unique feature. Lots of other web frameworks let you do that!" Well, you're right. But unlike many other systems, you can also write very large applications in Pyramid if you learn a little more about it. Pyramid will allow you to become productive quickly, -and will grow with you; it won't hold you back when your application is small +and will grow with you. It won't hold you back when your application is small, and it won't get in your way when your application becomes large. "Well -that's fine," you say, "lots of other frameworks let me write large apps +that's fine," you say. "Lots of other frameworks let me write large apps, too." Absolutely. But other Python web frameworks don't seamlessly let you do both. They seem to fall into two non-overlapping categories: frameworks for "small apps" and frameworks for "big apps". The "small app" frameworks @@ -95,15 +95,15 @@ in a "small framework" and "big apps" in a "big framework". You can't really know to what size every application will eventually grow. We don't really want to have to rewrite a previously small application in another framework when it gets "too big". We believe the current binary distinction between -frameworks for small and large applications is just false; a well-designed +frameworks for small and large applications is just false. A well-designed framework should be able to be good at both. Pyramid strives to be that kind of framework. To this end, Pyramid provides a set of features that, combined, are unique amongst Python web frameworks. Lots of other frameworks contain some -combination of these features; Pyramid of course actually stole many of them +combination of these features. Pyramid of course actually stole many of them from those other frameworks. But Pyramid is the only one that has all of -them in one place, documented appropriately, and useful a la carte without +them in one place, documented appropriately, and useful *Ã la carte* without necessarily paying for the entire banquet. These are detailed below. Single-file applications @@ -143,14 +143,14 @@ decorators to localize the configuration. For example: return Response('fred') However, unlike some other systems, using decorators for Pyramid -configuration does not make your application difficult to extend, test or +configuration does not make your application difficult to extend, test, or reuse. The :class:`~pyramid.view.view_config` decorator, for example, does not actually *change* the input or output of the function it decorates, so -testing it is a "WYSIWYG" operation; you don't need to understand the -framework to test your own code, you just behave as if the decorator is not +testing it is a "WYSIWYG" operation. You don't need to understand the +framework to test your own code. You just behave as if the decorator is not there. You can also instruct Pyramid to ignore some decorators, or use completely imperative configuration instead of decorators to add views. -Pyramid decorators are inert instead of eager: you detect and activate them +Pyramid decorators are inert instead of eager. You detect and activate them with a :term:`scan`. Example: :ref:`mapping_views_using_a_decorator_section`. @@ -171,24 +171,24 @@ Static file serving Pyramid is perfectly willing to serve static files itself. It won't make you use some external web server to do that. You can even serve more than one set of static files in a single Pyramid web application (e.g. ``/static`` and -``/static2``). You can also, optionally, place your files on an external web -server and ask Pyramid to help you generate URLs to those files, so you can -use Pyramid's internal fileserving while doing development, and a faster -static file server in production without changing any code. +``/static2``). You can optionally place your files on an external web +server and ask Pyramid to help you generate URLs to those files. This let's +you use Pyramid's internal file serving while doing development, and a faster +static file server in production, without changing any code. Example: :ref:`static_assets_section`. -Fully Interactive Development +Fully interactive development ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ When developing a Pyramid application, several interactive features are available. Pyramid can automatically utilize changed templates when rendering -pages and automatically restart the application to incorporate changed python +pages and automatically restart the application to incorporate changed Python code. Plain old ``print()`` calls used for debugging can display to a console. Pyramid's debug toolbar comes activated when you use a Pyramid scaffold to render a project. This toolbar overlays your application in the browser, and -allows you access to framework data such as the routes configured, the last +allows you access to framework data, such as the routes configured, the last renderings performed, the current set of packages installed, SQLAlchemy queries run, logging data, and various other facts. When an exception occurs, you can use its interactive debugger to poke around right in your @@ -201,16 +201,16 @@ Debugging settings Pyramid has debugging settings that allow you to print Pyramid runtime information to the console when things aren't behaving as you're expecting. -For example, you can turn on "debug_notfound", which prints an informative +For example, you can turn on ``debug_notfound``, which prints an informative message to the console every time a URL does not match any view. You can -turn on "debug_authorization", which lets you know why a view execution was +turn on ``debug_authorization``, which lets you know why a view execution was allowed or denied by printing a message to the console. These features are useful for those WTF moments. There are also a number of commands that you can invoke within a Pyramid -environment that allow you to introspect the configuration of your system: +environment that allow you to introspect the configuration of your system. ``proutes`` shows all configured routes for an application in the order -they'll be evaluated for matching; ``pviews`` shows all configured views for +they'll be evaluated for matching. ``pviews`` shows all configured views for any given URL. These are also WTF-crushers in some circumstances. Examples: :ref:`debug_authorization_section` and :ref:`command_line_chapter`. @@ -224,8 +224,8 @@ that the Pyramid core doesn't. Add-on packages already exist which let you easily send email, let you use the Jinja2 templating system, let you use XML-RPC or JSON-RPC, let you integrate with jQuery Mobile, etc. -Examples: http://docs.pylonsproject.org/en/latest/docs/pyramid.html#pyramid-add-on-documentation - +Examples: +http://docs.pylonsproject.org/en/latest/docs/pyramid.html#pyramid-add-on-documentation Class-based and function-based views ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ @@ -233,13 +233,13 @@ Class-based and function-based views Pyramid has a structured, unified concept of a :term:`view callable`. View callables can be functions, methods of classes, or even instances. When you add a new view callable, you can choose to make it a function or a method -of a class; in either case, Pyramid treats it largely the same way. You can -change your mind later, and move code between methods of classes and +of a class. In either case Pyramid treats it largely the same way. You can +change your mind later and move code between methods of classes and functions. A collection of similar view callables can be attached to a single class as methods, if that floats your boat, and they can share initialization code as necessary. All kinds of views are easy to understand -and use and operate similarly. There is no phony distinction between them; -they can be used for the same purposes. +and use, and operate similarly. There is no phony distinction between them. +They can be used for the same purposes. Here's a view callable defined as a function: @@ -283,10 +283,10 @@ Asset specifications ~~~~~~~~~~~~~~~~~~~~ Asset specifications are strings that contain both a Python package name and -a file or directory name, e.g. ``MyPackage:static/index.html``. Use of these +a file or directory name, e.g., ``MyPackage:static/index.html``. Use of these specifications is omnipresent in Pyramid. An asset specification can refer to a template, a translation directory, or any other package-bound static -resource. This makes a system built on Pyramid extensible, because you don't +resource. This makes a system built on Pyramid extensible because you don't have to rely on globals ("*the* static directory") or lookup schemes ("*the* ordered set of template directories") to address your files. You can move files around as necessary, and include other packages that may not share your @@ -325,10 +325,9 @@ If you use a :term:`renderer`, you don't have to return a special kind of "webby" ``Response`` object from a view. Instead, you can return a dictionary, and Pyramid will take care of converting that dictionary to a Response using a template on your behalf. This makes the view easier to -test, because you don't have to parse HTML in your tests; just make an -assertion instead that the view returns "the right stuff" in the dictionary -it returns. You can write "real" unit tests instead of functionally testing -all of your views. +test, because you don't have to parse HTML in your tests; instead just make an +assertion that the view returns "the right stuff" in the dictionary. You can +write "real" unit tests instead of functionally testing all of your views. .. index:: pair: renderer; explicitly calling @@ -394,7 +393,7 @@ Built-in internationalization Pyramid ships with internationalization-related features in its core: localization, pluralization, and creating message catalogs from source files -and templates. Pyramid allows for a plurality of message catalog via the use +and templates. Pyramid allows for a plurality of message catalogs via the use of translation domains: you can create a system that has its own translations without conflict with other translations in other domains. @@ -445,7 +444,7 @@ useless without requirements and goals, but if you need speed, Pyramid will almost certainly never be your application's bottleneck; at least no more than Python will be a bottleneck. -Example: http://blog.curiasolutions.com/the-great-web-framework-shootout/ +Example: http://blog.curiasolutions.com/pages/the-great-web-framework-shootout.html Exception views ~~~~~~~~~~~~~~~ @@ -469,11 +468,11 @@ No singletons ~~~~~~~~~~~~~ Pyramid is written in such a way that it requires your application to have -exactly zero "singleton" data structures. Or, put another way, Pyramid +exactly zero "singleton" data structures. Or put another way, Pyramid doesn't require you to construct any "mutable globals". Or put even a different way, an import of a Pyramid application needn't have any "import-time side effects". This is esoteric-sounding, but if you've ever -tried to cope with parameterizing a Django "settings.py" file for multiple +tried to cope with parameterizing a Django ``settings.py`` file for multiple installations of the same application, or if you've ever needed to monkey-patch some framework fixture so that it behaves properly for your use case, or if you've ever wanted to deploy your system using an asynchronous @@ -494,7 +493,7 @@ is the most basic thing you can do with a view predicate. You can also associate views with other request parameters such as the elements in the query string, the Accept header, whether the request is an XHR request or not, and lots of other things. This feature allows you to keep your -individual views "clean"; they won't need much conditional logic, so they'll +individual views clean. They won't need much conditional logic, so they'll be easier to test. Example: :ref:`view_configuration_parameters`. @@ -505,10 +504,10 @@ Transaction management Pyramid's :term:`scaffold` system renders projects that include a *transaction management* system, stolen from Zope. When you use this transaction management system, you cease being responsible for committing -your data anymore. Instead, Pyramid takes care of committing: it commits at +your data anymore. Instead Pyramid takes care of committing: it commits at the end of a request or aborts if there's an exception. Why is that a good thing? Having a centralized place for transaction management is a great -thing. If, instead of managing your transactions in a centralized place, you +thing. If instead of managing your transactions in a centralized place you sprinkle ``session.commit`` calls in your application logic itself, you can wind up in a bad place. Wherever you manually commit data to your database, it's likely that some of your other code is going to run *after* your commit. @@ -521,8 +520,8 @@ who also care about data integrity. Either the request completes successfully, and all changes are committed, or it does not, and all changes are aborted. -Also, Pyramid's transaction management system allows you to synchronize -commits between multiple databases, and allows you to do things like +Pyramid's transaction management system allows you to synchronize +commits between multiple databases. It also allows you to do things like conditionally send email if a transaction commits, but otherwise keep quiet. Example: :ref:`bfg_sql_wiki_tutorial` (note the lack of commit statements @@ -534,13 +533,14 @@ Configuration conflict detection When a system is small, it's reasonably easy to keep it all in your head. But when systems grow large, you may have hundreds or thousands of configuration statements which add a view, add a route, and so forth. -Pyramid's configuration system keeps track of your configuration statements, -and if you accidentally add two that are identical, or Pyramid can't make + +Pyramid's configuration system keeps track of your configuration statements. +If you accidentally add two that are identical, or Pyramid can't make sense out of what it would mean to have both statements active at the same -time, it will complain loudly at startup time. It's not dumb though: it will +time, it will complain loudly at startup time. It's not dumb though. It will automatically resolve conflicting configuration statements on its own if you -use the configuration :meth:`~pyramid.config.Configurator.include` system: -"more local" statements are preferred over "less local" ones. This allows +use the configuration :meth:`~pyramid.config.Configurator.include` system. +"More local" statements are preferred over "less local" ones. This allows you to intelligently factor large systems into smaller ones. Example: :ref:`conflict_detection`. @@ -552,15 +552,15 @@ Unlike other systems, Pyramid provides a structured "include" mechanism (see :meth:`~pyramid.config.Configurator.include`) that allows you to combine applications from multiple Python packages. All the configuration statements that can be performed in your "main" Pyramid application can also be -performed by included packages including the addition of views, routes, +performed by included packages, including the addition of views, routes, subscribers, and even authentication and authorization policies. You can even extend or override an existing application by including another application's configuration in your own, overriding or adding new views and routes to it. This has the potential to allow you to create a big application out of many other smaller ones. For example, if you want to reuse an existing application that already has a bunch of routes, you can just use the -``include`` statement with a ``route_prefix``; the new application will live -within your application at a URL prefix. It's not a big deal, and requires +``include`` statement with a ``route_prefix``. The new application will live +within your application at an URL prefix. It's not a big deal, and requires little up-front engineering effort. For example: @@ -603,8 +603,8 @@ Traversal :term:`Traversal` is a concept stolen from :term:`Zope`. It allows you to create a tree of resources, each of which can be addressed by one or more URLs. Each of those resources can have one or more *views* associated with -it. If your data isn't naturally treelike (or you're unwilling to create a -treelike representation of your data), you aren't going to find traversal +it. If your data isn't naturally treelike, or you're unwilling to create a +treelike representation of your data, you aren't going to find traversal very useful. However, traversal is absolutely fantastic for sites that need to be arbitrarily extensible: it's a lot easier to add a node to a tree than it is to shoehorn a route into an ordered list of other routes, or to create @@ -635,7 +635,7 @@ View response adapters A lot is made of the aesthetics of what *kinds* of objects you're allowed to return from view callables in various frameworks. In a previous section in -this document we showed you that, if you use a :term:`renderer`, you can +this document, we showed you that, if you use a :term:`renderer`, you can usually return a dictionary from a view callable instead of a full-on :term:`Response` object. But some frameworks allow you to return strings or tuples from view callables. When frameworks allow for this, code looks @@ -826,7 +826,7 @@ within a function called when another user uses the See also :ref:`add_directive`. -Programmatic Introspection +Programmatic introspection ~~~~~~~~~~~~~~~~~~~~~~~~~~ If you're building a large system that other users may plug code into, it's @@ -856,7 +856,7 @@ callable: See also :ref:`using_introspection`. -Python 3 Compatibility +Python 3 compatibility ~~~~~~~~~~~~~~~~~~~~~~ Pyramid and most of its add-ons are Python 3 compatible. If you develop a @@ -871,11 +871,11 @@ Every release of Pyramid has 100% statement coverage via unit and integration tests, as measured by the ``coverage`` tool available on PyPI. It also has greater than 95% decision/condition coverage as measured by the ``instrumental`` tool available on PyPI. It is automatically tested by the -Jenkins tool on Python 2.6, Python 2.7, Python 3.2 and PyPy after each commit -to its GitHub repository. Official Pyramid add-ons are held to a similar -testing standard. We still find bugs in Pyramid and its official add-ons, -but we've noticed we find a lot more of them while working on other projects -that don't have a good testing regime. +Jenkins tool on Python 2.6, Python 2.7, Python 3.2, Python 3.3, Python 3.4, +PyPy, and PyPy3 after each commit to its GitHub repository. Official Pyramid +add-ons are held to a similar testing standard. We still find bugs in Pyramid +and its official add-ons, but we've noticed we find a lot more of them while +working on other projects that don't have a good testing regime. Example: http://jenkins.pylonsproject.org/ @@ -883,15 +883,15 @@ Support ~~~~~~~ It's our goal that no Pyramid question go unanswered. Whether you ask a -question on IRC, on the Pylons-discuss maillist, or on StackOverflow, you're -likely to get a reasonably prompt response. We don't tolerate "support +question on IRC, on the Pylons-discuss mailing list, or on StackOverflow, +you're likely to get a reasonably prompt response. We don't tolerate "support trolls" or other people who seem to get their rocks off by berating fellow users in our various official support channels. We try to keep it well-lit and new-user-friendly. Example: Visit irc\://freenode.net#pyramid (the ``#pyramid`` channel on irc.freenode.net in an IRC client) or the pylons-discuss maillist at -http://groups.google.com/group/pylons-discuss/ . +http://groups.google.com/group/pylons-discuss/. Documentation ~~~~~~~~~~~~~ @@ -900,12 +900,12 @@ It's a constant struggle, but we try to maintain a balance between completeness and new-user-friendliness in the official narrative Pyramid documentation (concrete suggestions for improvement are always appreciated, by the way). We also maintain a "cookbook" of recipes, which are usually -demonstrations of common integration scenarios, too specific to add to the +demonstrations of common integration scenarios too specific to add to the official narrative docs. In any case, the Pyramid documentation is comprehensive. -Example: The rest of this documentation and the cookbook at -http://docs.pylonsproject.org/projects/pyramid_cookbook/dev/ . +Example: The Pyramid Cookbook at +http://docs.pylonsproject.org/projects/pyramid-cookbook/en/latest/. .. index:: single: Pylons Project @@ -934,25 +934,26 @@ in July of 2008. At the end of 2010, we changed the name of as :app:`Pyramid` in November of that year. :app:`Pyramid` was inspired by :term:`Zope`, :term:`Pylons` (version -1.0) and :term:`Django`. As a result, :app:`Pyramid` borrows several +1.0), and :term:`Django`. As a result, :app:`Pyramid` borrows several concepts and features from each, combining them into a unique web framework. Many features of :app:`Pyramid` trace their origins back to :term:`Zope`. -Like Zope applications, :app:`Pyramid` applications can be easily extended: -if you obey certain constraints, the application you produce can be reused, +Like Zope applications, :app:`Pyramid` applications can be easily extended. +If you obey certain constraints, the application you produce can be reused, modified, re-integrated, or extended by third-party developers without forking the original application. The concepts of :term:`traversal` and declarative security in :app:`Pyramid` were pioneered first in Zope. The :app:`Pyramid` concept of :term:`URL dispatch` is inspired by the -:term:`Routes` system used by :term:`Pylons` version 1.0. Like Pylons -version 1.0, :app:`Pyramid` is mostly policy-free. It makes no -assertions about which database you should use, and its built-in -templating facilities are included only for convenience. In essence, -it only supplies a mechanism to map URLs to :term:`view` code, along -with a set of conventions for calling those views. You are free to -use third-party components that fit your needs in your applications. +:term:`Routes` system used by :term:`Pylons` version 1.0. Like Pylons version +1.0, :app:`Pyramid` is mostly policy-free. It makes no assertions about which +database you should use. Pyramid no longer has built-in templating facilities +as of version 1.5a2, but instead officially supports bindings for templating +languages, including Chameleon, Jinja2, and Mako. In essence, it only +supplies a mechanism to map URLs to :term:`view` code, along with a set of +conventions for calling those views. You are free to use third-party +components that fit your needs in your applications. The concept of :term:`view` is used by :app:`Pyramid` mostly as it would be by Django. :app:`Pyramid` has a documentation culture more like Django's @@ -967,15 +968,15 @@ declarations are used for this purpose. Out of the box, Pyramid supports imperative and decorator-based configuration; :term:`ZCML` may be used via an add-on package named ``pyramid_zcml``. -Also unlike :term:`Zope` and unlike other "full-stack" frameworks such +Also unlike :term:`Zope` and other "full-stack" frameworks such as :term:`Django`, :app:`Pyramid` makes no assumptions about which persistence mechanisms you should use to build an application. Zope applications are typically reliant on :term:`ZODB`; :app:`Pyramid` allows you to build :term:`ZODB` applications, but it has no reliance on the ZODB software. Likewise, :term:`Django` tends to assume that you want to store your application's data in a relational database. -:app:`Pyramid` makes no such assumption; it allows you to use a -relational database but doesn't encourage or discourage the decision. +:app:`Pyramid` makes no such assumption, allowing you to use a +relational database, and neither encouraging nor discouraging the decision. Other Python web frameworks advertise themselves as members of a class of web frameworks named `model-view-controller @@ -987,7 +988,7 @@ frameworks, :app:`Pyramid` also generally fits into this class. The :app:`Pyramid` authors believe that the MVC pattern just doesn't really fit the web very well. In a :app:`Pyramid` application, there is a - resource tree, which represents the site structure, and views, which tend + resource tree which represents the site structure, and views which tend to present the data stored in the resource tree and a user-defined "domain model". However, no facility provided *by the framework* actually necessarily maps to the concept of a "controller" or "model". So if you diff --git a/docs/narr/sessions.rst b/docs/narr/sessions.rst index 5c103405a..916c6c1f6 100644 --- a/docs/narr/sessions.rst +++ b/docs/narr/sessions.rst @@ -56,7 +56,7 @@ by using the :meth:`pyramid.config.Configurator.set_session_factory` method. config = Configurator() config.set_session_factory(my_session_factory) -.. warning:: +.. warning:: By default the :func:`~pyramid.session.SignedCookieSessionFactory` implementation is *unencrypted*. You should not use it @@ -112,7 +112,7 @@ Extra attributes: An integer timestamp indicating the time that this session was created. ``new`` - A boolean. If ``new`` is True, this session is new. Otherwise, it has + A boolean. If ``new`` is True, this session is new. Otherwise, it has been constituted from data that was already serialized. Extra methods: @@ -225,7 +225,7 @@ method: request.session.flash('mymessage') The ``flash()`` method appends a message to a flash queue, creating the queue -if necessary. +if necessary. ``flash()`` accepts three arguments: @@ -406,7 +406,7 @@ Checking CSRF Tokens With A View Predicate A convenient way to require a valid CSRF Token for a particular view is to include ``check_csrf=True`` as a view predicate. -See :meth:`pyramid.config.Configurator.add_route`. +See :meth:`pyramid.config.Configurator.add_view`. .. code-block:: python @@ -414,6 +414,12 @@ See :meth:`pyramid.config.Configurator.add_route`. def myview(request): ... +.. note:: + A mismatch of CSRF token is treated like any other predicate miss, and the + predicate system, when it doesn't find a view, raises ``HTTPNotFound`` + instead of ``HTTPBadRequest``, so ``check_csrf=True`` behavior is different + from calling :func:`pyramid.session.check_csrf_token`. + Using the ``session.new_csrf_token`` Method ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ diff --git a/docs/narr/viewconfig.rst b/docs/narr/viewconfig.rst index d5203c6ba..fc5ae6dc6 100644 --- a/docs/narr/viewconfig.rst +++ b/docs/narr/viewconfig.rst @@ -234,6 +234,21 @@ Non-Predicate Arguments def myview(request): ... + All view callables in the decorator chain must return a response object + implementing :class:`pyramid.interfaces.IResponse` or raise an exception: + + .. code-block:: python + + def log_timer(wrapped): + def wrapper(context, request): + start = time.time() + response = wrapped(context, request) + duration = time.time() - start + response.headers['X-View-Time'] = '%.3f' % (duration,) + log.info('view took %.3f seconds', duration) + return response + return wrapper + ``mapper`` A Python object or :term:`dotted Python name` which refers to a :term:`view mapper`, or ``None``. By default it is ``None``, which indicates that the diff --git a/docs/quick_tour.rst b/docs/quick_tour.rst index 1b8c82b0a..0fc3a7ab8 100644 --- a/docs/quick_tour.rst +++ b/docs/quick_tour.rst @@ -39,12 +39,12 @@ For Windows: Of course Pyramid runs fine on Python 2.6+, as do the examples in this *Quick Tour*. We're just showing Python 3 a little love (Pyramid had -production support in October 2011.) +production support for Python 3 in October 2011). .. note:: Why ``easy_install`` and not ``pip``? Pyramid encourages use of namespace - packages which, until recently, ``pip`` didn't permit. Also, Pyramid has + packages which, until recently, ``pip`` didn't permit. Also Pyramid has some optional C extensions for performance. With ``easy_install``, Windows users can get these extensions without needing a C compiler. @@ -69,8 +69,8 @@ This simple example is easy to run. Save this as ``app.py`` and run it: $ python ./app.py -Next, open `http://localhost:6543/ <http://localhost:6543/>`_ in a -browser and you will see the ``Hello World!`` message. +Next open http://localhost:6543/ in a browser, and you will see the ``Hello +World!`` message. New to Python web programming? If so, some lines in the module merit explanation: @@ -96,7 +96,7 @@ one that we will revisit regurlarly in this *Quick Tour*. :ref:`firstapp_chapter`, and :ref:`Single File Tasks tutorial <tutorials:single-file-tutorial>` -Handling Web Requests and Responses +Handling web requests and responses =================================== Developing for the web means processing web requests. As this is a @@ -104,21 +104,20 @@ critical part of a web application, web developers need a robust, mature set of software for web requests. Pyramid has always fit nicely into the existing world of Python web -development (virtual environments, packaging, scaffolding, -first to embrace Python 3, etc.) For request handling, Pyramid turned -to the well-regarded :term:`WebOb` Python library for request and -response handling. In our example -above, Pyramid hands ``hello_world`` a ``request`` that is -:ref:`based on WebOb <webob_chapter>`. +development (virtual environments, packaging, scaffolding, one of the first to +embrace Python 3, etc.). Pyramid turned to the well-regarded :term:`WebOb` +Python library for request and response handling. In our example above, +Pyramid hands ``hello_world`` a ``request`` that is :ref:`based on WebOb +<webob_chapter>`. Let's see some features of requests and responses in action: .. literalinclude:: quick_tour/requests/app.py :pyobject: hello_world -In this Pyramid view, we get the URL being visited from ``request.url``. -Also, if you visited ``http://localhost:6543/?name=alice``, -the name is included in the body of the response:: +In this Pyramid view, we get the URL being visited from ``request.url``. Also, +if you visited http://localhost:6543/?name=alice in a browser, the name is +included in the body of the response:: URL http://localhost:6543/?name=alice with name: alice @@ -142,13 +141,15 @@ So far our examples place everything in one file: - its registration with the configurator -- the route to map it to a URL +- the route to map it to an URL - the WSGI application launcher Let's move the views out to their own ``views.py`` module and change the ``app.py`` to scan that module, looking for decorators that set up -the views. First, our revised ``app.py``: +the views. + +First, our revised ``app.py``: .. literalinclude:: quick_tour/views/app.py :linenos: @@ -163,8 +164,8 @@ and responses: .. literalinclude:: quick_tour/views/views.py :linenos: -We have 4 views, each leading to the other. If you start at -``http://localhost:6543/``, you get a response with a link to the next +We have four views, each leading to the other. If you start at +http://localhost:6543/, you get a response with a link to the next view. The ``hello_view`` (available at the URL ``/howdy``) has a link to the ``redirect_view``, which issues a redirect to the final view. @@ -175,7 +176,7 @@ section introduces ``@view_config``. Pyramid's configuration supports the previous example. You can also use :term:`declarative configuration`, in which a Python :term:`decorator` is placed on the line above the view. Both approaches result in the same final -configuration, thus usually, it is simply a matter of taste. +configuration, thus usually it is simply a matter of taste. .. seealso:: See also: :ref:`Quick Tutorial Views <qtut_views>`, @@ -195,7 +196,7 @@ Above we saw the basics of routing URLs to views in Pyramid: - Your project's "setup" code registers a route name to be used when matching part of the URL -- Elsewhere, a view is configured to be called for that route name +- Elsewhere a view is configured to be called for that route name .. note:: @@ -282,12 +283,12 @@ we can use ``name`` as a variable in our template via :ref:`debugging_templates`, and :ref:`available_template_system_bindings` -Templating With ``jinja2`` +Templating with ``jinja2`` ========================== We just said Pyramid doesn't prefer one templating language over another. Time to prove it. Jinja2 is a popular templating system, -modelled after Django's templates. Let's add ``pyramid_jinja2``, +modeled after Django's templates. Let's add ``pyramid_jinja2``, a Pyramid :term:`add-on` which enables Jinja2 as a :term:`renderer` in our Pyramid applications: @@ -324,12 +325,12 @@ renderer. `Jinja2 homepage <http://jinja.pocoo.org/>`_, and :ref:`pyramid_jinja2 Overview <jinja2:overview>` -Static Assets +Static assets ============= Of course the Web is more than just markup. You need static assets: CSS, JS, and images. Let's point our web app at a directory where -Pyramid will serve some static assets. First, another call to the +Pyramid will serve some static assets. First another call to the :term:`configurator`: .. literalinclude:: quick_tour/static_assets/app.py @@ -337,10 +338,10 @@ Pyramid will serve some static assets. First, another call to the :end-before: End Static 1 This tells our WSGI application to map requests under -``http://localhost:6543/static/`` to files and directories inside a +http://localhost:6543/static/ to files and directories inside a ``static`` directory alongside our Python module. -Next, make a directory ``static`` and place ``app.css`` inside: +Next make a directory named ``static``, and place ``app.css`` inside: .. literalinclude:: quick_tour/static_assets/static/app.css :language: css @@ -394,14 +395,13 @@ into JSON and set the appropriate HTTP headers. :ref:`json_renderer`, and :ref:`adding_and_overriding_renderers` -View Classes +View classes ============ So far our views have been simple, free-standing functions. Many times your views are related: different ways to look at or work on the same -data or a REST API that handles multiple operations. Grouping these -together as a -:ref:`view class <class_as_view>` makes sense: +data, or a REST API that handles multiple operations. Grouping these +together as a :ref:`view class <class_as_view>` makes sense. - Group views @@ -425,14 +425,14 @@ Specifically: - The second view is returned when the form data contains a field with ``form.edit``, such as clicking on - ``<input type="submit" name="form.edit" value="Save"/>``. This rule + ``<input type="submit" name="form.edit" value="Save">``. This rule is specified in the ``@view_config`` for that view. - The third view is returned when clicking on a button such - as ``<input type="submit" name="form.delete" value="Delete"/>``. + as ``<input type="submit" name="form.delete" value="Delete">``. -Only one route needed, stated in one place atop the view class. Also, -the assignment of the ``name`` is done in the ``__init__``. Our +Only one route is needed, stated in one place atop the view class. Also, +the assignment of ``name`` is done in the ``__init__`` function. Our templates can then use ``{{ view.name }}``. Pyramid view classes, combined with built-in and custom predicates, @@ -450,7 +450,7 @@ have much more to offer: :ref:`Quick Tutorial More View Classes <qtut_more_view_classes>`, and :ref:`class_as_view` -Quick Project Startup with Scaffolds +Quick project startup with scaffolds ==================================== So far we have done all of our *Quick Tour* as a single Python file. @@ -501,7 +501,7 @@ Let's look at ``pserve`` and configuration in more depth. :ref:`project_narr`, and :doc:`../narr/scaffolding` -Application Running with ``pserve`` +Application running with ``pserve`` =================================== Prior to scaffolds, our project mixed a number of operational details @@ -530,19 +530,19 @@ take a look at this configuration file. .. seealso:: See also: :ref:`what_is_this_pserve_thing` -Configuration with ``.ini`` Files +Configuration with ``.ini`` files ================================= Earlier in *Quick Tour* we first met Pyramid's configuration system. At that point we did all configuration in Python code. For example, the port number chosen for our HTTP server was right there in Python -code. Our scaffold has moved this decision, and more, into the +code. Our scaffold has moved this decision and more into the ``development.ini`` file: .. literalinclude:: quick_tour/package/development.ini :language: ini -Let's take a quick high-level look. First, the ``.ini`` file is divided +Let's take a quick high-level look. First the ``.ini`` file is divided into sections: - ``[app:hello_world]`` configures our WSGI app @@ -555,23 +555,21 @@ into sections: We have a few decisions made for us in this configuration: -#. *Choice of web server*. The ``use = egg:pyramid#wsgiref`` tells - ``pserve`` to use the ``wsgiref`` server that is wrapped in the Pyramid - package. +#. *Choice of web server:* ``use = egg:pyramid#wsgiref`` tells ``pserve`` to + use the ``wsgiref`` server that is wrapped in the Pyramid package. -#. *Port number*. ``port = 6543`` tells ``wsgiref`` to listen on port - 6543. +#. *Port number:* ``port = 6543`` tells ``wsgiref`` to listen on port 6543. -#. *WSGI app*. What package has our WSGI application in it? +#. *WSGI app:* What package has our WSGI application in it? ``use = egg:hello_world`` in the app section tells the configuration what application to load. -#. *Easier development by automatic template reloading*. In development - mode, you shouldn't have to restart the server when editing a Jinja2 - template. ``reload_templates = true`` sets this policy, - which might be different in production. +#. *Easier development by automatic template reloading:* In development mode, + you shouldn't have to restart the server when editing a Jinja2 template. + ``reload_templates = true`` sets this policy, which might be different in + production. -Additionally, the ``development.ini`` generated by this scaffold wired +Additionally the ``development.ini`` generated by this scaffold wired up Python's standard logging. We'll now see in the console, for example, a log on every request that comes in, as well as traceback information. @@ -581,7 +579,7 @@ a log on every request that comes in, as well as traceback information. :doc:`../narr/paste` -Easier Development with ``debugtoolbar`` +Easier development with ``debugtoolbar`` ======================================== As we introduce the basics, we also want to show how to be productive in @@ -592,21 +590,21 @@ reloading and earlier we showed ``--reload`` for application reloading. several tools available in your browser. Adding it to your project illustrates several points about configuration. -First, change your ``setup.py`` to say: +First change your ``setup.py`` to say: .. literalinclude:: quick_tour/package/setup.py :start-after: Start Requires :end-before: End Requires -...and re-run your setup: +...and rerun your setup: .. code-block:: bash $ python ./setup.py develop -The Python package was now installed into our environment. The package -is a Pyramid add-on, which means we need to include its configuration -into our web application. We could do this with imperative +The Python package ``pyramid_debugtoolbar`` is now installed into our +environment. The package is a Pyramid add-on, which means we need to include +its configuration into our web application. We could do this with imperative configuration, as we did above for the ``pyramid_jinja2`` add-on: .. literalinclude:: quick_tour/package/hello_world/__init__.py @@ -635,12 +633,12 @@ configuration file. pyramid_debugtoolbar <qtut_debugtoolbar>` and :ref:`pyramid_debugtoolbar <toolbar:overview>` -Unit Tests and ``nose`` +Unit tests and ``nose`` ======================= -Yikes! We got this far and we haven't yet discussed tests. Particularly -egregious, as Pyramid has had a deep commitment to full test coverage -since before it was released. +Yikes! We got this far and we haven't yet discussed tests. This is +particularly egregious, as Pyramid has had a deep commitment to full test +coverage since before its release. Our ``pyramid_jinja2_starter`` scaffold generated a ``tests.py`` module with one unit test in it. To run it, let's install the handy ``nose`` @@ -656,7 +654,7 @@ the ``coverage`` tool which yells at us for code that isn't tested: } ) -We changed ``setup.py`` which means we need to re-run +We changed ``setup.py`` which means we need to rerun ``python ./setup.py develop``. We can now run all our tests: .. code-block:: bash @@ -694,7 +692,7 @@ Logging ======= It's important to know what is going on inside our web application. -In development we might need to collect some output. In production, +In development we might need to collect some output. In production we might need to detect situations when other people use the site. We need *logging*. @@ -716,7 +714,7 @@ You can now, in your code, log messages: :start-after: Start Logging 2 :end-before: End Logging 2 -This will log ``Some Message`` at a ``debug`` log level, +This will log ``Some Message`` at a ``debug`` log level to the application-configured logger in your ``development.ini``. What controls that? These sections in the configuration file: @@ -727,7 +725,7 @@ controls that? These sections in the configuration file: Our application, a package named ``hello_world``, is set up as a logger and configured to log messages at a ``DEBUG`` or higher level. When you -visit ``http://localhost:6543`` your console will now show:: +visit http://localhost:6543, your console will now show:: 2013-08-09 10:42:42,968 DEBUG [hello_world.views][MainThread] Some Message @@ -886,8 +884,8 @@ widgets, schemas, and validation. Recent versions of Deform also include a :ref:`retail mode <deform:retail>` for gaining Deform features on custom forms. -Also, the ``deform_bootstrap`` Pyramid add-on restyles the stock Deform -widgets using attractive CSS from Bootstrap and more powerful widgets +Also the ``deform_bootstrap`` Pyramid add-on restyles the stock Deform +widgets using attractive CSS from Twitter Bootstrap and more powerful widgets from Chosen. .. seealso:: See also: diff --git a/docs/quick_tutorial/authentication.rst b/docs/quick_tutorial/authentication.rst index 4b4eb1ba3..a4ab83c45 100644 --- a/docs/quick_tutorial/authentication.rst +++ b/docs/quick_tutorial/authentication.rst @@ -93,7 +93,7 @@ Steps Analysis ======== -Unlike many web frameworks, Pyramid includes a built-in (but optional) +Unlike many web frameworks, Pyramid includes a built-in but optional security model for authentication and authorization. This security system is intended to be flexible and support many needs. In this security model, authentication (who are you) and authorization (what diff --git a/docs/quick_tutorial/authentication/tutorial/home.pt b/docs/quick_tutorial/authentication/tutorial/home.pt index 6ecd0081b..ed911b673 100644 --- a/docs/quick_tutorial/authentication/tutorial/home.pt +++ b/docs/quick_tutorial/authentication/tutorial/home.pt @@ -1,7 +1,7 @@ <!DOCTYPE html> <html lang="en"> <head> - <title>Quick Tour: ${name}</title> + <title>Quick Tutorial: ${name}</title> </head> <body> @@ -15,4 +15,4 @@ <h1>Hi ${name}</h1> <p>Visit <a href="${request.route_url('hello')}">hello</a></p> </body> -</html>
\ No newline at end of file +</html> diff --git a/docs/quick_tutorial/authentication/tutorial/login.pt b/docs/quick_tutorial/authentication/tutorial/login.pt index 4451fc4f8..9e5bfe2ad 100644 --- a/docs/quick_tutorial/authentication/tutorial/login.pt +++ b/docs/quick_tutorial/authentication/tutorial/login.pt @@ -1,7 +1,7 @@ <!DOCTYPE html> <html lang="en"> <head> - <title>Quick Tour: ${name}</title> + <title>Quick Tutorial: ${name}</title> </head> <body> <h1>Login</h1> @@ -22,4 +22,4 @@ value="Log In"/> </form> </body> -</html>
\ No newline at end of file +</html> diff --git a/docs/quick_tutorial/authorization.rst b/docs/quick_tutorial/authorization.rst index dc159234c..08df15a28 100644 --- a/docs/quick_tutorial/authorization.rst +++ b/docs/quick_tutorial/authorization.rst @@ -11,7 +11,7 @@ Background Our application has URLs that allow people to add/edit/delete content via a web browser. Time to add security to the application. Let's protect our add/edit views to require a login (username of -``editor`` and password of ``editor``.) We will allow the other views +``editor`` and password of ``editor``). We will allow the other views to continue working without a password. Objectives @@ -101,7 +101,7 @@ by decorating the view with ``@forbidden_view_config``. Extra Credit ============ -#. Perhaps you would like experience of not having enough permissions +#. Perhaps you would like the experience of not having enough permissions (forbidden) to be richer. How could you change this? #. Perhaps we want to store security statements in a database and diff --git a/docs/quick_tutorial/authorization/tutorial/home.pt b/docs/quick_tutorial/authorization/tutorial/home.pt index 6ecd0081b..ed911b673 100644 --- a/docs/quick_tutorial/authorization/tutorial/home.pt +++ b/docs/quick_tutorial/authorization/tutorial/home.pt @@ -1,7 +1,7 @@ <!DOCTYPE html> <html lang="en"> <head> - <title>Quick Tour: ${name}</title> + <title>Quick Tutorial: ${name}</title> </head> <body> @@ -15,4 +15,4 @@ <h1>Hi ${name}</h1> <p>Visit <a href="${request.route_url('hello')}">hello</a></p> </body> -</html>
\ No newline at end of file +</html> diff --git a/docs/quick_tutorial/authorization/tutorial/login.pt b/docs/quick_tutorial/authorization/tutorial/login.pt index 4451fc4f8..9e5bfe2ad 100644 --- a/docs/quick_tutorial/authorization/tutorial/login.pt +++ b/docs/quick_tutorial/authorization/tutorial/login.pt @@ -1,7 +1,7 @@ <!DOCTYPE html> <html lang="en"> <head> - <title>Quick Tour: ${name}</title> + <title>Quick Tutorial: ${name}</title> </head> <body> <h1>Login</h1> @@ -22,4 +22,4 @@ value="Log In"/> </form> </body> -</html>
\ No newline at end of file +</html> diff --git a/docs/quick_tutorial/databases.rst b/docs/quick_tutorial/databases.rst index 7c019dbfc..19dfd066d 100644 --- a/docs/quick_tutorial/databases.rst +++ b/docs/quick_tutorial/databases.rst @@ -53,8 +53,8 @@ Steps .. note:: - We aren't yet doing ``python3.3 setup.py develop`` as we - are changing it later. + We aren't yet doing ``$VENV/bin/python setup.py develop`` as we + will change it later. #. Our configuration file at ``databases/development.ini`` wires together some new pieces: @@ -72,6 +72,7 @@ Steps to initialize the database: .. literalinclude:: databases/tutorial/initialize_db.py + :linenos: #. Since ``setup.py`` changed, we now run it: @@ -89,21 +90,34 @@ Steps .. code-block:: bash $ $VENV/bin/initialize_tutorial_db development.ini - 2013-09-06 15:54:08,050 INFO [sqlalchemy.engine.base.Engine][MainThread] PRAGMA table_info("wikipages") - 2013-09-06 15:54:08,050 INFO [sqlalchemy.engine.base.Engine][MainThread] () - 2013-09-06 15:54:08,051 INFO [sqlalchemy.engine.base.Engine][MainThread] + 2015-06-01 11:22:52,650 INFO [sqlalchemy.engine.base.Engine][MainThread] SELECT CAST('test plain returns' AS VARCHAR(60)) AS anon_1 + 2015-06-01 11:22:52,650 INFO [sqlalchemy.engine.base.Engine][MainThread] () + 2015-06-01 11:22:52,651 INFO [sqlalchemy.engine.base.Engine][MainThread] SELECT CAST('test unicode returns' AS VARCHAR(60)) AS anon_1 + 2015-06-01 11:22:52,651 INFO [sqlalchemy.engine.base.Engine][MainThread] () + 2015-06-01 11:22:52,652 INFO [sqlalchemy.engine.base.Engine][MainThread] PRAGMA table_info("wikipages") + 2015-06-01 11:22:52,652 INFO [sqlalchemy.engine.base.Engine][MainThread] () + 2015-06-01 11:22:52,653 INFO [sqlalchemy.engine.base.Engine][MainThread] CREATE TABLE wikipages ( - uid INTEGER NOT NULL, - title TEXT, - body TEXT, - PRIMARY KEY (uid), - UNIQUE (title) + uid INTEGER NOT NULL, + title TEXT, + body TEXT, + PRIMARY KEY (uid), + UNIQUE (title) ) + + 2015-06-01 11:22:52,653 INFO [sqlalchemy.engine.base.Engine][MainThread] () + 2015-06-01 11:22:52,655 INFO [sqlalchemy.engine.base.Engine][MainThread] COMMIT + 2015-06-01 11:22:52,658 INFO [sqlalchemy.engine.base.Engine][MainThread] BEGIN (implicit) + 2015-06-01 11:22:52,659 INFO [sqlalchemy.engine.base.Engine][MainThread] INSERT INTO wikipages (title, body) VALUES (?, ?) + 2015-06-01 11:22:52,659 INFO [sqlalchemy.engine.base.Engine][MainThread] ('Root', '<p>Root</p>') + 2015-06-01 11:22:52,659 INFO [sqlalchemy.engine.base.Engine][MainThread] COMMIT + #. With our data now driven by SQLAlchemy queries, we need to update our ``databases/tutorial/views.py``: .. literalinclude:: databases/tutorial/views.py + :linenos: #. Our tests in ``databases/tutorial/tests.py`` changed to include SQLAlchemy bootstrapping: @@ -138,8 +152,8 @@ Let's start with the dependencies. We made the decision to use ``pyramid_tm`` and ``zope.sqlalchemy``. Why? Pyramid has a strong orientation towards support for ``transactions``. -Specifically, you can install a transaction manager into your app -application, either as middleware or a Pyramid "tween". Then, +Specifically, you can install a transaction manager into your +application either as middleware or a Pyramid "tween". Then, just before you return the response, all transaction-aware parts of your application are executed. @@ -149,7 +163,7 @@ aborts the transaction. This is a very liberating way to write code. The ``pyramid_tm`` package provides a "tween" that is configured in the ``development.ini`` configuration file. That installs it. We then need -a package that makes SQLAlchemy and thus the RDBMS transaction manager +a package that makes SQLAlchemy, and thus the RDBMS transaction manager, integrate with the Pyramid transaction manager. That's what ``zope.sqlalchemy`` does. @@ -167,8 +181,8 @@ console script follows the pattern of being fed a configuration file with all the bootstrapping. It then opens SQLAlchemy and creates the root of the wiki, which also makes the SQLite file. Note the ``with transaction.manager`` part that puts the work in the scope of a -transaction (as we aren't inside a web request where this is done -automatically.) +transaction, as we aren't inside a web request where this is done +automatically. The ``models.py`` does a little bit extra work to hook up SQLAlchemy into the Pyramid transaction manager. It then declares the model for a diff --git a/docs/quick_tutorial/databases/development.ini b/docs/quick_tutorial/databases/development.ini index 04c249a62..5da87d602 100644 --- a/docs/quick_tutorial/databases/development.ini +++ b/docs/quick_tutorial/databases/development.ini @@ -11,3 +11,39 @@ sqlalchemy.url = sqlite:///%(here)s/sqltutorial.sqlite use = egg:pyramid#wsgiref host = 0.0.0.0 port = 6543 + +# Begin logging configuration + +[loggers] +keys = root, tutorial, sqlalchemy.engine.base.Engine + +[logger_tutorial] +level = DEBUG +handlers = +qualname = tutorial + +[handlers] +keys = console + +[formatters] +keys = generic + +[logger_root] +level = INFO +handlers = console + +[logger_sqlalchemy.engine.base.Engine] +level = INFO +handlers = +qualname = sqlalchemy.engine.base.Engine + +[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/quick_tutorial/databases/tutorial/tests.py b/docs/quick_tutorial/databases/tutorial/tests.py index e18e70c8c..11e747d15 100644 --- a/docs/quick_tutorial/databases/tutorial/tests.py +++ b/docs/quick_tutorial/databases/tutorial/tests.py @@ -40,16 +40,14 @@ class WikiViewTests(unittest.TestCase): class WikiFunctionalTests(unittest.TestCase): def setUp(self): - self.session = _initTestingDB() - self.config = testing.setUp() from pyramid.paster import get_app app = get_app('development.ini') from webtest import TestApp self.testapp = TestApp(app) def tearDown(self): - self.session.remove() - testing.tearDown() + from .models import DBSession + DBSession.remove() def test_it(self): res = self.testapp.get('/', status=200) diff --git a/docs/quick_tutorial/databases/tutorial/wikipage_addedit.pt b/docs/quick_tutorial/databases/tutorial/wikipage_addedit.pt index d1fea0d7f..01955ef72 100644 --- a/docs/quick_tutorial/databases/tutorial/wikipage_addedit.pt +++ b/docs/quick_tutorial/databases/tutorial/wikipage_addedit.pt @@ -4,10 +4,12 @@ <title>WikiPage: Add/Edit</title> <tal:block tal:repeat="reqt view.reqts['css']"> <link rel="stylesheet" type="text/css" - href="${request.static_url('deform:static/' + reqt)}"/> + href="${request.static_url(reqt)}"> </tal:block> + <script type="text/javascript" + src="${request.static_url('deform:static/scripts/jquery-2.0.3.min.js')}"></script> <tal:block tal:repeat="reqt view.reqts['js']"> - <script src="${request.static_url('deform:static/' + reqt)}" + <script src="${request.static_url(reqt)}" type="text/javascript"></script> </tal:block> </head> diff --git a/docs/quick_tutorial/forms.rst b/docs/quick_tutorial/forms.rst index b08167edc..f81b88fc2 100644 --- a/docs/quick_tutorial/forms.rst +++ b/docs/quick_tutorial/forms.rst @@ -12,13 +12,13 @@ Background Modern web applications deal extensively with forms. Developers, though, have a wide range of philosophies about how frameworks should help them with their forms. As such, Pyramid doesn't directly bundle -one particular form library. Instead, there are a variety of form +one particular form library. Instead there are a variety of form libraries that are easy to use in Pyramid. :ref:`Deform <deform:overview>` is one such library. In this step, we introduce Deform for our -forms and validation. This also gives us the -:ref:`Colander <colander:overview>` for schemas and validation. +forms and validation. This also gives us :ref:`Colander <colander:overview>` +for schemas and validation. Deform is getting a facelift, with styling from Twitter Bootstrap and advanced widgets from popular JavaScript projects. The work began in diff --git a/docs/quick_tutorial/forms/tutorial/wikipage_addedit.pt b/docs/quick_tutorial/forms/tutorial/wikipage_addedit.pt index 3292dfd90..547465018 100644 --- a/docs/quick_tutorial/forms/tutorial/wikipage_addedit.pt +++ b/docs/quick_tutorial/forms/tutorial/wikipage_addedit.pt @@ -6,6 +6,8 @@ <link rel="stylesheet" type="text/css" href="${request.static_url(reqt)}"/> </tal:block> + <script src="${request.static_url('deform:static/scripts/jquery-2.0.3.min.js')}" + type="text/javascript"></script> <tal:block tal:repeat="reqt view.reqts['js']"> <script src="${request.static_url(reqt)}" type="text/javascript"></script> diff --git a/docs/quick_tutorial/functional_testing.rst b/docs/quick_tutorial/functional_testing.rst index 09b05b0bc..6f1544e79 100644 --- a/docs/quick_tutorial/functional_testing.rst +++ b/docs/quick_tutorial/functional_testing.rst @@ -10,7 +10,7 @@ Background ========== Unit tests are a common and popular approach to test-driven development -(TDD.) In web applications, though, the templating and entire apparatus +(TDD). In web applications, though, the templating and entire apparatus of a web site are important parts of the delivered quality. We'd like a way to test these. diff --git a/docs/quick_tutorial/jinja2.rst b/docs/quick_tutorial/jinja2.rst index 613542349..2121803f9 100644 --- a/docs/quick_tutorial/jinja2.rst +++ b/docs/quick_tutorial/jinja2.rst @@ -6,7 +6,7 @@ We just said Pyramid doesn't prefer one templating language over another. Time to prove it. Jinja2 is a popular templating system, -used in Flask and modelled after Django's templates. Let's add +used in Flask and modeled after Django's templates. Let's add ``pyramid_jinja2``, a Pyramid :term:`add-on` which enables Jinja2 as a :term:`renderer` in our Pyramid applications. diff --git a/docs/quick_tutorial/jinja2/tutorial/home.jinja2 b/docs/quick_tutorial/jinja2/tutorial/home.jinja2 index 975323169..20d33b733 100644 --- a/docs/quick_tutorial/jinja2/tutorial/home.jinja2 +++ b/docs/quick_tutorial/jinja2/tutorial/home.jinja2 @@ -1,9 +1,9 @@ <!DOCTYPE html> <html lang="en"> <head> - <title>Quick Tour: {{ name }}</title> + <title>Quick Tutorial: {{ name }}</title> </head> <body> <h1>Hi {{ name }}</h1> </body> -</html>
\ No newline at end of file +</html> diff --git a/docs/quick_tutorial/json/tutorial/home.pt b/docs/quick_tutorial/json/tutorial/home.pt index a0cc08e7a..fd4ef8764 100644 --- a/docs/quick_tutorial/json/tutorial/home.pt +++ b/docs/quick_tutorial/json/tutorial/home.pt @@ -1,9 +1,9 @@ <!DOCTYPE html> <html lang="en"> <head> - <title>Quick Tour: ${name}</title> + <title>Quick Tutorial: ${name}</title> </head> <body> <h1>Hi ${name}</h1> </body> -</html>
\ No newline at end of file +</html> diff --git a/docs/quick_tutorial/logging.rst b/docs/quick_tutorial/logging.rst index 82cfbe3c3..5d29cd196 100644 --- a/docs/quick_tutorial/logging.rst +++ b/docs/quick_tutorial/logging.rst @@ -16,9 +16,9 @@ we might need to detect problems when other people use the site. We need *logging*. Fortunately Pyramid uses the normal Python approach to logging. The -scaffold generated, in your ``development.ini``, has a number of lines that +scaffold generated in your ``development.ini`` has a number of lines that configure the logging for you to some reasonable defaults. You then see -messages sent by Pyramid (for example, when a new request comes in.) +messages sent by Pyramid, for example, when a new request comes in. Objectives ========== diff --git a/docs/quick_tutorial/logging/tutorial/home.pt b/docs/quick_tutorial/logging/tutorial/home.pt index a0cc08e7a..fd4ef8764 100644 --- a/docs/quick_tutorial/logging/tutorial/home.pt +++ b/docs/quick_tutorial/logging/tutorial/home.pt @@ -1,9 +1,9 @@ <!DOCTYPE html> <html lang="en"> <head> - <title>Quick Tour: ${name}</title> + <title>Quick Tutorial: ${name}</title> </head> <body> <h1>Hi ${name}</h1> </body> -</html>
\ No newline at end of file +</html> diff --git a/docs/quick_tutorial/more_view_classes.rst b/docs/quick_tutorial/more_view_classes.rst index 9cc4cc520..c06fb0f15 100644 --- a/docs/quick_tutorial/more_view_classes.rst +++ b/docs/quick_tutorial/more_view_classes.rst @@ -95,6 +95,23 @@ Steps .. literalinclude:: more_view_classes/tutorial/delete.pt :language: html +#. Our tests in ``more_view_classes/tutorial/tests.py`` fail, so let's modify + them: + + .. literalinclude:: more_view_classes/tutorial/tests.py + :linenos: + +#. Now run the tests: + + .. code-block:: bash + + $ $VENV/bin/nosetests tutorial + . + ---------------------------------------------------------------------- + Ran 2 tests in 0.248s + + OK + #. Run your Pyramid application with: .. code-block:: bash @@ -125,7 +142,7 @@ Specifically: - The fourth view is returned when clicking on a button such as ``<input type="submit" name="form.delete" value="Delete"/>``. -In this step we show using the following information as criteria to +In this step we show, using the following information as criteria, how to decide which view to use: - Method of the HTTP request (``GET``, ``POST``, etc.) diff --git a/docs/quick_tutorial/more_view_classes/tutorial/delete.pt b/docs/quick_tutorial/more_view_classes/tutorial/delete.pt index 67cc8bf09..7bd4d3b0d 100644 --- a/docs/quick_tutorial/more_view_classes/tutorial/delete.pt +++ b/docs/quick_tutorial/more_view_classes/tutorial/delete.pt @@ -1,9 +1,9 @@ <!DOCTYPE html> <html lang="en"> <head> - <title>Quick Tour: ${page_title}</title> + <title>Quick Tutorial: ${page_title}</title> </head> <body> <h1>${view.view_name} - ${page_title}</h1> </body> -</html>
\ No newline at end of file +</html> diff --git a/docs/quick_tutorial/more_view_classes/tutorial/edit.pt b/docs/quick_tutorial/more_view_classes/tutorial/edit.pt index 1bd204065..523a4ce5d 100644 --- a/docs/quick_tutorial/more_view_classes/tutorial/edit.pt +++ b/docs/quick_tutorial/more_view_classes/tutorial/edit.pt @@ -1,10 +1,10 @@ <!DOCTYPE html> <html lang="en"> <head> - <title>Quick Tour: ${view.view_name} - ${page_title}</title> + <title>Quick Tutorial: ${view.view_name} - ${page_title}</title> </head> <body> <h1>${view.view_name} - ${page_title}</h1> <p>You submitted <code>${new_name}</code></p> </body> -</html>
\ No newline at end of file +</html> diff --git a/docs/quick_tutorial/more_view_classes/tutorial/hello.pt b/docs/quick_tutorial/more_view_classes/tutorial/hello.pt index 8a39aed09..40b00bfe4 100644 --- a/docs/quick_tutorial/more_view_classes/tutorial/hello.pt +++ b/docs/quick_tutorial/more_view_classes/tutorial/hello.pt @@ -1,7 +1,7 @@ <!DOCTYPE html> <html lang="en"> <head> - <title>Quick Tour: ${view.view_name} - ${page_title}</title> + <title>Quick Tutorial: ${view.view_name} - ${page_title}</title> </head> <body> <h1>${view.view_name} - ${page_title}</h1> @@ -13,4 +13,4 @@ <input type="submit" name="form.delete" value="Delete"/> </form> </body> -</html>
\ No newline at end of file +</html> diff --git a/docs/quick_tutorial/more_view_classes/tutorial/home.pt b/docs/quick_tutorial/more_view_classes/tutorial/home.pt index fa9016705..fa0436f7e 100644 --- a/docs/quick_tutorial/more_view_classes/tutorial/home.pt +++ b/docs/quick_tutorial/more_view_classes/tutorial/home.pt @@ -1,7 +1,7 @@ <!DOCTYPE html> <html lang="en"> <head> - <title>Quick Tour: ${view.view_name} - ${page_title}</title> + <title>Quick Tutorial: ${view.view_name} - ${page_title}</title> </head> <body> <h1>${view.view_name} - ${page_title}</h1> @@ -9,4 +9,4 @@ <p>Go to the <a href="${request.route_url('hello', first='jane', last='doe')}">form</a>.</p> </body> -</html>
\ No newline at end of file +</html> diff --git a/docs/quick_tutorial/request_response.rst b/docs/quick_tutorial/request_response.rst index 504803804..4f8de0221 100644 --- a/docs/quick_tutorial/request_response.rst +++ b/docs/quick_tutorial/request_response.rst @@ -46,14 +46,17 @@ Steps #. Simplify the routes in ``request_response/tutorial/__init__.py``: .. literalinclude:: request_response/tutorial/__init__.py + :linenos: #. We only need one view in ``request_response/tutorial/views.py``: .. literalinclude:: request_response/tutorial/views.py + :linenos: #. Update the tests in ``request_response/tutorial/tests.py``: .. literalinclude:: request_response/tutorial/tests.py + :linenos: #. Now run the tests: diff --git a/docs/quick_tutorial/routing.rst b/docs/quick_tutorial/routing.rst index 54dff5c39..1b79a5889 100644 --- a/docs/quick_tutorial/routing.rst +++ b/docs/quick_tutorial/routing.rst @@ -14,7 +14,7 @@ Writing web applications usually means sophisticated URL design. We just saw some Pyramid machinery for requests and views. Let's look at features that help in routing. -Previously we saw the basics of routing URLs to views in +Previously we saw the basics of routing URLs to views in Pyramid. - Your project's "setup" code registers a route name to be used when matching part of the URL diff --git a/docs/quick_tutorial/routing/tutorial/home.pt b/docs/quick_tutorial/routing/tutorial/home.pt index f2b991059..b68e96338 100644 --- a/docs/quick_tutorial/routing/tutorial/home.pt +++ b/docs/quick_tutorial/routing/tutorial/home.pt @@ -1,10 +1,10 @@ <!DOCTYPE html> <html lang="en"> <head> - <title>Quick Tour: ${name}</title> + <title>Quick Tutorial: ${name}</title> </head> <body> <h1>${name}</h1> <p>First: ${first}, Last: ${last}</p> </body> -</html>
\ No newline at end of file +</html> diff --git a/docs/quick_tutorial/sessions.rst b/docs/quick_tutorial/sessions.rst index b4887beb8..f97405500 100644 --- a/docs/quick_tutorial/sessions.rst +++ b/docs/quick_tutorial/sessions.rst @@ -89,7 +89,7 @@ when you add an item using a form ``POST``, the site usually issues a second HTTP Redirect web request to view the new item. You might want a message to appear after that second web request saying "Your item was added." You can't just return it in the web response for the POST, -as it will be tossed out during the second web requests. +as it will be tossed out during the second web request. Flash messages are a technique where messages can be stored between requests, using sessions, then removed when they finally get displayed. diff --git a/docs/quick_tutorial/sessions/tutorial/home.pt b/docs/quick_tutorial/sessions/tutorial/home.pt index 0b27ba1d8..50342e52f 100644 --- a/docs/quick_tutorial/sessions/tutorial/home.pt +++ b/docs/quick_tutorial/sessions/tutorial/home.pt @@ -1,10 +1,10 @@ <!DOCTYPE html> <html lang="en"> <head> - <title>Quick Tour: ${name}</title> + <title>Quick Tutorial: ${name}</title> </head> <body> <h1>Hi ${name}</h1> <p>Count: ${view.counter}</p> </body> -</html>
\ No newline at end of file +</html> diff --git a/docs/quick_tutorial/static_assets/tutorial/home.pt b/docs/quick_tutorial/static_assets/tutorial/home.pt index 5d347f057..57867a1ff 100644 --- a/docs/quick_tutorial/static_assets/tutorial/home.pt +++ b/docs/quick_tutorial/static_assets/tutorial/home.pt @@ -1,11 +1,11 @@ <!DOCTYPE html> <html lang="en"> <head> - <title>Quick Tour: ${name}</title> + <title>Quick Tutorial: ${name}</title> <link rel="stylesheet" href="${request.static_url('tutorial:static/app.css') }"/> </head> <body> <h1>Hi ${name}</h1> </body> -</html>
\ No newline at end of file +</html> diff --git a/docs/quick_tutorial/templating.rst b/docs/quick_tutorial/templating.rst index d73067f48..cf56d2a96 100644 --- a/docs/quick_tutorial/templating.rst +++ b/docs/quick_tutorial/templating.rst @@ -112,7 +112,7 @@ Analysis Ahh, that looks better. We have a view that is focused on Python code. Our ``@view_config`` decorator specifies a :term:`renderer` that points -our template file. Our view then simply returns data which is then +to our template file. Our view then simply returns data which is then supplied to our template. Note that we used the same template for both views. diff --git a/docs/quick_tutorial/templating/tutorial/home.pt b/docs/quick_tutorial/templating/tutorial/home.pt index a0cc08e7a..fd4ef8764 100644 --- a/docs/quick_tutorial/templating/tutorial/home.pt +++ b/docs/quick_tutorial/templating/tutorial/home.pt @@ -1,9 +1,9 @@ <!DOCTYPE html> <html lang="en"> <head> - <title>Quick Tour: ${name}</title> + <title>Quick Tutorial: ${name}</title> </head> <body> <h1>Hi ${name}</h1> </body> -</html>
\ No newline at end of file +</html> diff --git a/docs/quick_tutorial/unit_testing.rst b/docs/quick_tutorial/unit_testing.rst index f8a33b39d..4cb7ef714 100644 --- a/docs/quick_tutorial/unit_testing.rst +++ b/docs/quick_tutorial/unit_testing.rst @@ -24,7 +24,7 @@ and functionality. The Pyramid developers use ``nose``, which we'll thus use in this tutorial. Don't worry, this tutorial won't be pedantic about "test-driven -development" (TDD.) We'll do just enough to ensure that, in each step, +development" (TDD). We'll do just enough to ensure that, in each step, we haven't majorly broken the code. As you're writing your code you might find this more convenient than changing to your browser constantly and clicking reload. diff --git a/docs/quick_tutorial/view_classes.rst b/docs/quick_tutorial/view_classes.rst index 58ab43e40..50a7ee0af 100644 --- a/docs/quick_tutorial/view_classes.rst +++ b/docs/quick_tutorial/view_classes.rst @@ -51,7 +51,7 @@ Steps :linenos: #. Our unit tests in ``view_classes/tutorial/tests.py`` don't run, - so let's modify the to import the view class and make an instance + so let's modify them to import the view class and make an instance before getting a response: .. literalinclude:: view_classes/tutorial/tests.py @@ -88,7 +88,7 @@ view class, then updated the tests. In our ``TutorialViews`` view class you can see that our two view classes are logically grouped together as methods on a common class. Since the two views shared the same template, we could move that to a -``@view_defaults`` decorator on at the class level. +``@view_defaults`` decorator at the class level. The tests needed to change. Obviously we needed to import the view class. But you can also see the pattern in the tests of instantiating diff --git a/docs/tutorials/wiki/authorization.rst b/docs/tutorials/wiki/authorization.rst index 6c98b6f3a..b0a8c155d 100644 --- a/docs/tutorials/wiki/authorization.rst +++ b/docs/tutorials/wiki/authorization.rst @@ -1,19 +1,20 @@ +.. _wiki_adding_authorization: + ==================== -Adding Authorization +Adding authorization ==================== :app:`Pyramid` provides facilities for :term:`authentication` and -:term:`authorization`. We'll make use of both features to provide security -to our application. Our application currently allows anyone with access to -the server to view, edit, and add pages to our wiki. We'll change that -to allow only people who are members of a *group* named ``group:editors`` -to add and edit wiki pages but we'll continue allowing -anyone with access to the server to view pages. - -We will also add a login page and a logout link on all the -pages. The login page will be shown when a user is denied -access to any of the views that require a permission, instead of -a default "403 Forbidden" page. +::term:`authorization`. We'll make use of both features to provide security +:to our application. Our application currently allows anyone with access to +:the server to view, edit, and add pages to our wiki. We'll change that to +:allow only people who are members of a *group* named ``group:editors`` to add +:and edit wiki pages but we'll continue allowing anyone with access to the +:server to view pages. + +We will also add a login page and a logout link on all the pages. The login +page will be shown when a user is denied access to any of the views that +require permission, instead of a default "403 Forbidden" page. We will implement the access control with the following steps: @@ -28,12 +29,13 @@ Then we will add the login and logout feature: * Add ``login`` and ``logout`` views (``views.py``). * Add a login template (``login.pt``). -* Make the existing views return a ``logged_in`` flag to the renderer (``views.py``). +* Make the existing views return a ``logged_in`` flag to the renderer + (``views.py``). * Add a "Logout" link to be shown when logged in and viewing or editing a page (``view.pt``, ``edit.pt``). -Access Control +Access control -------------- Add users and groups @@ -49,11 +51,9 @@ following content: The ``groupfinder`` function accepts a userid and a request and returns one of these values: -- If the userid exists in the system, it will return a - sequence of group identifiers (or an empty sequence if the user - isn't a member of any groups). -- If the userid *does not* exist in the system, it will - return ``None``. +- If the userid exists in the system, it will return a sequence of group + identifiers (or an empty sequence if the user isn't a member of any groups). +- If the userid *does not* exist in the system, it will return ``None``. For example, ``groupfinder('editor', request )`` returns ``['group:editor']``, ``groupfinder('viewer', request)`` returns ``[]``, and ``groupfinder('admin', @@ -61,9 +61,8 @@ request)`` returns ``None``. We will use ``groupfinder()`` as an :term:`authentication policy` "callback" that will provide the :term:`principal` or principals for a user. -In a production system, user and group -data will most often come from a database, but here we use "dummy" -data to represent user and groups sources. +In a production system, user and group data will most often come from a +database, but here we use "dummy" data to represent user and groups sources. Add an ACL ~~~~~~~~~~ @@ -81,44 +80,42 @@ Add the following lines to the ``Wiki`` class: .. literalinclude:: src/authorization/tutorial/models.py :lines: 9-13 :linenos: + :lineno-start: 9 :emphasize-lines: 4-5 :language: python -We import :data:`~pyramid.security.Allow`, an action that -means that permission is allowed, and -:data:`~pyramid.security.Everyone`, a special :term:`principal` -that is associated to all requests. Both are used in the +We import :data:`~pyramid.security.Allow`, an action that means that +permission is allowed, and :data:`~pyramid.security.Everyone`, a special +:term:`principal` that is associated to all requests. Both are used in the :term:`ACE` entries that make up the ACL. -The ACL is a list that needs to be named `__acl__` and be an -attribute of a class. We define an :term:`ACL` with two -:term:`ACE` entries: the first entry allows any user the `view` -permission, and the second entry allows the ``group:editors`` -principal the `edit` permission. +The ACL is a list that needs to be named `__acl__` and be an attribute of a +class. We define an :term:`ACL` with two :term:`ACE` entries: the first entry +allows any user the `view` permission. The second entry allows the +``group:editors`` principal the `edit` permission. -The ``Wiki`` class that contains the ACL is the :term:`resource` -constructor for the :term:`root` resource, which is -a ``Wiki`` instance. The ACL is -provided to each view in the :term:`context` of the request, as -the ``context`` attribute. +The ``Wiki`` class that contains the ACL is the :term:`resource` constructor +for the :term:`root` resource, which is a ``Wiki`` instance. The ACL is +provided to each view in the :term:`context` of the request as the ``context`` +attribute. It's only happenstance that we're assigning this ACL at class scope. An ACL can be attached to an object *instance* too; this is how "row level security" can be achieved in :app:`Pyramid` applications. We actually need only *one* ACL for the entire system, however, because our security requirements are -simple, so this feature is not demonstrated. See -:ref:`assigning_acls` for more information about what an -:term:`ACL` represents. +simple, so this feature is not demonstrated. See :ref:`assigning_acls` for +more information about what an :term:`ACL` represents. -Add Authentication and Authorization Policies +Add authentication and authorization policies ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ -Open ``tutorial/__init__.py`` and -add these import statements: +Open ``tutorial/tutorial/__init__.py`` and add the highlighted import +statements: .. literalinclude:: src/authorization/tutorial/__init__.py - :lines: 4-5,8 + :lines: 1-8 :linenos: + :emphasize-lines: 4-5,8 :language: python Now add those policies to the configuration: @@ -126,15 +123,16 @@ Now add those policies to the configuration: .. literalinclude:: src/authorization/tutorial/__init__.py :lines: 18-23 :linenos: + :lineno-start: 18 :emphasize-lines: 1-3,5-6 :language: python -(Only the highlighted lines need to be added.) +Only the highlighted lines need to be added. -We are enabling an ``AuthTktAuthenticationPolicy``, it is based in an -auth ticket that may be included in the request, and an -``ACLAuthorizationPolicy`` that uses an ACL to determine the allow or deny -outcome for a view. +We are enabling an ``AuthTktAuthenticationPolicy``, which is based in an auth +ticket that may be included in the request. We are also enabling an +``ACLAuthorizationPolicy``, which uses an ACL to determine the *allow* or +*deny* outcome for a view. Note that the :class:`pyramid.authentication.AuthTktAuthenticationPolicy` constructor accepts two arguments: ``secret`` and ``callback``. ``secret`` is @@ -144,235 +142,231 @@ machinery represented by this policy: it is required. The ``callback`` is the Add permission declarations ~~~~~~~~~~~~~~~~~~~~~~~~~~~ -Open ``tutorial/tutorial/views.py``. Add a ``permission='edit'`` parameter -to the ``@view_config`` decorator for ``add_page()`` and -``edit_page()``, for example: +Open ``tutorial/tutorial/views.py`` and add a ``permission='edit'`` parameter +to the ``@view_config`` decorators for ``add_page()`` and ``edit_page()``: -.. code-block:: python - :linenos: - :emphasize-lines: 3 +.. literalinclude:: src/authorization/tutorial/views.py + :lines: 50-52 + :emphasize-lines: 2-3 + :language: python - @view_config(name='add_page', context='.models.Wiki', - renderer='templates/edit.pt', - permission='edit') +.. literalinclude:: src/authorization/tutorial/views.py + :lines: 70-72 + :emphasize-lines: 2-3 + :language: python -(Only the highlighted line, along with its preceding comma, -needs to be added.) +Only the highlighted lines, along with their preceding commas, need to be +edited and added. -The result is that only users who possess the ``edit`` -permission at the time of the request may invoke those two views. +The result is that only users who possess the ``edit`` permission at the time +of the request may invoke those two views. -Add a ``permission='view'`` parameter to the ``@view_config`` -decorator for ``view_wiki()`` and ``view_page()``, like this: +Add a ``permission='view'`` parameter to the ``@view_config`` decorator for +``view_wiki()`` and ``view_page()`` as follows: -.. code-block:: python - :linenos: - :emphasize-lines: 2 +.. literalinclude:: src/authorization/tutorial/views.py + :lines: 23-24 + :emphasize-lines: 1-2 + :language: python - @view_config(context='.models.Page', renderer='templates/view.pt', - permission='view') +.. literalinclude:: src/authorization/tutorial/views.py + :lines: 28-29 + :emphasize-lines: 1-2 + :language: python -(Only the highlighted line, along with its preceding comma, -needs to be added.) +Only the highlighted lines, along with their preceding commas, need to be +edited and added. This allows anyone to invoke these two views. -We are done with the changes needed to control access. The -changes that follow will add the login and logout feature. +We are done with the changes needed to control access. The changes that +follow will add the login and logout feature. -Login, Logout +Login, logout ------------- -Add Login and Logout Views +Add login and logout views ~~~~~~~~~~~~~~~~~~~~~~~~~~ -We'll add a ``login`` view which renders a login form and processes -the post from the login form, checking credentials. +We'll add a ``login`` view which renders a login form and processes the post +from the login form, checking credentials. -We'll also add a ``logout`` view callable to our application and -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 also add a ``logout`` view callable to our application and provide a +link to it. This view will clear the credentials of the logged in user and +redirect back to the front page. -Add the following import statements to the -head of ``tutorial/tutorial/views.py``: +Add the following import statements to the head of +``tutorial/tutorial/views.py``: .. literalinclude:: src/authorization/tutorial/views.py :lines: 6-17 - :linenos: - :emphasize-lines: 3,6-11 + :emphasize-lines: 1-12 :language: python -(Only the highlighted lines, with other necessary modifications, -need to be added.) +All the highlighted lines need to be added or edited. -:meth:`~pyramid.view.forbidden_view_config` will be used -to customize the default 403 Forbidden page. -:meth:`~pyramid.security.remember` and -:meth:`~pyramid.security.forget` help to create and -expire an auth ticket cookie. +:meth:`~pyramid.view.forbidden_view_config` will be used to customize the +default 403 Forbidden page. :meth:`~pyramid.security.remember` and +:meth:`~pyramid.security.forget` help to create and expire an auth ticket +cookie. -Now add the ``login`` and ``logout`` views: +Now add the ``login`` and ``logout`` views at the end of the file: .. literalinclude:: src/authorization/tutorial/views.py - :lines: 82-120 + :lines: 82-116 :linenos: + :lineno-start: 82 :language: python ``login()`` has two decorators: -- a ``@view_config`` decorator which associates it with the - ``login`` route and makes it visible when we visit ``/login``, -- a ``@forbidden_view_config`` decorator which turns it into - a :term:`forbidden view`. ``login()`` will be invoked - when a user tries to execute a view callable for which they lack - authorization. For example, if a user has not logged in - and tries to add or edit a Wiki page, they will be shown the - login form before being allowed to continue. +- a ``@view_config`` decorator which associates it with the ``login`` route + and makes it visible when we visit ``/login``, +- a ``@forbidden_view_config`` decorator which turns it into a + :term:`forbidden view`. ``login()`` will be invoked when a user tries to + execute a view callable for which they lack authorization. For example, if + a user has not logged in and tries to add or edit a Wiki page, they will be + shown the login form before being allowed to continue. -The order of these two :term:`view configuration` decorators -is unimportant. +The order of these two :term:`view configuration` decorators is unimportant. -``logout()`` is decorated with a ``@view_config`` decorator -which associates it with the ``logout`` route. It will be -invoked when we visit ``/logout``. +``logout()`` is decorated with a ``@view_config`` decorator which associates +it with the ``logout`` route. It will be invoked when we visit ``/logout``. Add the ``login.pt`` Template ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ -Create ``tutorial/tutorial/templates/login.pt`` with the following -content: +Create ``tutorial/tutorial/templates/login.pt`` with the following content: .. literalinclude:: src/authorization/tutorial/templates/login.pt - :language: xml + :language: html -The above template is referred in the login view that we just added -in ``views.py``. +The above template is referenced in the login view that we just added in +``views.py``. -Return a logged_in flag to the renderer -~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +Return a ``logged_in`` flag to the renderer +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ -Add a ``logged_in`` parameter to the return value of -``view_page()``, ``edit_page()`` and ``add_page()``, -like this: +Open ``tutorial/tutorial/views.py`` again. Add a ``logged_in`` parameter to +the return value of ``view_page()``, ``edit_page()``, and ``add_page()`` as +follows: -.. code-block:: python - :linenos: - :emphasize-lines: 4 +.. literalinclude:: src/authorization/tutorial/views.py + :lines: 47-48 + :emphasize-lines: 1-2 + :language: python - return dict(page = page, - content = content, - edit_url = edit_url, - logged_in = request.authenticated_userid) +.. literalinclude:: src/authorization/tutorial/views.py + :lines: 67-68 + :emphasize-lines: 1-2 + :language: python -(Only the highlighted line and a trailing comma on the preceding -line need to be added.) +.. literalinclude:: src/authorization/tutorial/views.py + :lines: 75-77 + :emphasize-lines: 2-3 + :language: python + +Only the highlighted lines need to be added or edited. The :meth:`pyramid.request.Request.authenticated_userid` will be ``None`` if -the user is not authenticated, or a user id if the user is authenticated. +the user is not authenticated, or a userid if the user is authenticated. Add a "Logout" link when logged in ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ Open ``tutorial/tutorial/templates/edit.pt`` and -``tutorial/tutorial/templates/view.pt`` and add this within the -``<div id="right" class="app-welcome align-right">`` div: +``tutorial/tutorial/templates/view.pt`` and add the following code as +indicated by the highlighted lines. -.. code-block:: xml - - <span tal:condition="logged_in"> - <a href="${request.application_url}/logout">Logout</a> - </span> +.. literalinclude:: src/authorization/tutorial/templates/edit.pt + :lines: 34-38 + :emphasize-lines: 3-5 + :language: html -The attribute ``tal:condition="logged_in"`` will make the element be -included when ``logged_in`` is any user id. The link will invoke -the logout view. The above element will not be included if ``logged_in`` -is ``None``, such as when a user is not authenticated. +The attribute ``tal:condition="logged_in"`` will make the element be included +when ``logged_in`` is any user id. The link will invoke the logout view. The +above element will not be included if ``logged_in`` is ``None``, such as when +a user is not authenticated. -Seeing Our Changes ------------------- +Reviewing our changes +--------------------- -Our ``tutorial/tutorial/__init__.py`` will look something like this -when we're done: +Our ``tutorial/tutorial/__init__.py`` will look like this when we're done: .. literalinclude:: src/authorization/tutorial/__init__.py :linenos: :emphasize-lines: 4-5,8,18-20,22-23 :language: python -(Only the highlighted lines need to be added.) +Only the highlighted lines need to be added or edited. -Our ``tutorial/tutorial/models.py`` will look something like this -when we're done: +Our ``tutorial/tutorial/models.py`` will look like this when we're done: .. literalinclude:: src/authorization/tutorial/models.py :linenos: :emphasize-lines: 4-7,12-13 :language: python -(Only the highlighted lines need to be added.) +Only the highlighted lines need to be added or edited. -Our ``tutorial/tutorial/views.py`` will look something like this -when we're done: +Our ``tutorial/tutorial/views.py`` will look like this when we're done: .. literalinclude:: src/authorization/tutorial/views.py :linenos: :emphasize-lines: 8,11-15,17,24,29,48,52,68,72,80,82-120 :language: python -(Only the highlighted lines need to be added.) +Only the highlighted lines need to be added or edited. -Our ``tutorial/tutorial/templates/edit.pt`` template will look -something like this when we're done: +Our ``tutorial/tutorial/templates/edit.pt`` template will look like this when +we're done: .. literalinclude:: src/authorization/tutorial/templates/edit.pt :linenos: - :emphasize-lines: 41-43 - :language: xml + :emphasize-lines: 36-38 + :language: html -(Only the highlighted lines need to be added.) +Only the highlighted lines need to be added or edited. -Our ``tutorial/tutorial/templates/view.pt`` template will look -something like this when we're done: +Our ``tutorial/tutorial/templates/view.pt`` template will look like this when +we're done: .. literalinclude:: src/authorization/tutorial/templates/view.pt :linenos: - :emphasize-lines: 41-43 - :language: xml + :emphasize-lines: 36-38 + :language: html -(Only the highlighted lines need to be added.) +Only the highlighted lines need to be added or edited. -Viewing the Application in a Browser +Viewing the application in a browser ------------------------------------ We can finally examine our application in a browser (See -:ref:`wiki-start-the-application`). Launch a browser and visit -each of the following URLs, check that the result is as expected: - -- ``http://localhost:6543/`` invokes the - ``view_wiki`` view. This always redirects to the ``view_page`` view - of the ``FrontPage`` Page resource. It is executable by any user. - -- ``http://localhost:6543/FrontPage`` invokes - the ``view_page`` view of the ``FrontPage`` Page resource. This is because - it's the :term:`default view` (a view without a ``name``) for ``Page`` - resources. It is executable by any user. - -- ``http://localhost:6543/FrontPage/edit_page`` - invokes the edit view for the FrontPage object. It is executable by - only the ``editor`` user. If a different user (or the anonymous - user) invokes it, a login form will be displayed. Supplying the - credentials with the username ``editor``, password ``editor`` will - display the edit page form. - -- ``http://localhost:6543/add_page/SomePageName`` - invokes the add view for a page. It is executable by only - the ``editor`` user. If a different user (or the anonymous user) - invokes it, a login form will be displayed. Supplying the - credentials with the username ``editor``, password ``editor`` will - display the edit page form. - -- After logging in (as a result of hitting an edit or add page - and submitting the login form with the ``editor`` - credentials), we'll see a Logout link in the upper right hand - corner. When we click it, we're logged out, and redirected - back to the front page. +:ref:`wiki-start-the-application`). Launch a browser and visit each of the +following URLs, checking that the result is as expected: + +- http://localhost:6543/ invokes the ``view_wiki`` view. This always + redirects to the ``view_page`` view of the ``FrontPage`` Page resource. It + is executable by any user. + +- http://localhost:6543/FrontPage invokes the ``view_page`` view of the + ``FrontPage`` Page resource. This is because it's the :term:`default view` + (a view without a ``name``) for ``Page`` resources. It is executable by any + user. + +- http://localhost:6543/FrontPage/edit_page invokes the edit view for the + FrontPage object. It is executable by only the ``editor`` user. If a + different user (or the anonymous user) invokes it, a login form will be + displayed. Supplying the credentials with the username ``editor``, password + ``editor`` will display the edit page form. + +- http://localhost:6543/add_page/SomePageName invokes the add view for a page. + It is executable by only the ``editor`` user. If a different user (or the + anonymous user) invokes it, a login form will be displayed. Supplying the + credentials with the username ``editor``, password ``editor`` will display + the edit page form. + +- After logging in (as a result of hitting an edit or add page and submitting + the login form with the ``editor`` credentials), we'll see a Logout link in + the upper right hand corner. When we click it, we're logged out, and + redirected back to the front page. diff --git a/docs/tutorials/wiki/basiclayout.rst b/docs/tutorials/wiki/basiclayout.rst index cdf52b73e..0484ebf17 100644 --- a/docs/tutorials/wiki/basiclayout.rst +++ b/docs/tutorials/wiki/basiclayout.rst @@ -2,25 +2,27 @@ Basic Layout ============ -The starter files generated by the ``zodb`` scaffold are basic, but +The starter files generated by the ``zodb`` scaffold are very basic, but they provide a good orientation for the high-level patterns common to most -:term:`traversal` -based :app:`Pyramid` (and :term:`ZODB` -based) projects. +:term:`traversal`-based (and :term:`ZODB`-based) :app:`Pyramid` projects. -Application Configuration with ``__init__.py`` ------------------------------------------------- +Application configuration with ``__init__.py`` +---------------------------------------------- A directory on disk can be turned into a Python :term:`package` by containing an ``__init__.py`` file. Even if empty, this marks a directory as a Python -package. Our application uses ``__init__.py`` both as a package marker and -to contain application configuration code. +package. We use ``__init__.py`` both as a marker, indicating the directory +in which it's contained is a package, and to contain application configuration +code. When you run the application using the ``pserve`` command using the -``development.ini`` generated config file, the application configuration -points at a Setuptools *entry point* described as ``egg:tutorial``. In our -application, because the application's ``setup.py`` file says so, this entry -point happens to be the ``main`` function within the file named -``__init__.py``: +``development.ini`` generated configuration file, the application +configuration points at a Setuptools *entry point* described as +``egg:tutorial``. In our application, because the application's ``setup.py`` +file says so, this entry point happens to be the ``main`` function within the +file named ``__init__.py``. Let's take a look at the code and describe what +it does: .. literalinclude:: src/basiclayout/tutorial/__init__.py :linenos: @@ -28,17 +30,19 @@ point happens to be the ``main`` function within the file named #. *Lines 1-3*. Perform some dependency imports. -#. *Lines 6-8*. Define a root factory for our Pyramid application. +#. *Lines 6-8*. Define a :term:`root factory` for our Pyramid application. -#. *Line 14*. We construct a :term:`Configurator` with a :term:`root - factory` and the settings keywords parsed by :term:`PasteDeploy`. The root +#. *Line 11*. ``__init__.py`` defines a function named ``main``. + +#. *Line 14*. We construct a :term:`Configurator` with a root + factory and the settings keywords parsed by :term:`PasteDeploy`. The root factory is named ``root_factory``. #. *Line 15*. Include support for the :term:`Chameleon` template rendering bindings, allowing us to use the ``.pt`` templates. -#. *Line 16*. Register a "static view" which answers requests whose URL path - start with ``/static`` using the +#. *Line 16*. Register a "static view", which answers requests whose URL + paths start with ``/static``, using the :meth:`pyramid.config.Configurator.add_static_view` method. This statement registers a view that will serve up static assets, such as CSS and image files, for us, in this case, at @@ -63,7 +67,7 @@ point happens to be the ``main`` function within the file named :meth:`pyramid.config.Configurator.make_wsgi_app` method to return a :term:`WSGI` application. -Resources and Models with ``models.py`` +Resources and models with ``models.py`` --------------------------------------- :app:`Pyramid` uses the word :term:`resource` to describe objects arranged @@ -93,13 +97,12 @@ Here is the source for ``models.py``: root* object. It is called on *every request* to the :app:`Pyramid` application. It also performs bootstrapping by *creating* an application root (inside the ZODB root object) if one - does not already exist. It is used by the "root_factory" we've defined + does not already exist. It is used by the ``root_factory`` we've defined in our ``__init__.py``. - We do so by first seeing if the database has the persistent - application root. If not, we make an instance, store it, and - commit the transaction. We then return the application root - object. + Bootstrapping is done by first seeing if the database has the persistent + application root. If not, we make an instance, store it, and commit the + transaction. We then return the application root object. Views With ``views.py`` ----------------------- @@ -171,6 +174,6 @@ opposed to the tutorial :term:`package` directory) looks like this: Note the existence of a ``[app:main]`` section which specifies our WSGI application. Our ZODB database settings are specified as the ``zodbconn.uri`` setting within this section. This value, and the other -values within this section are passed as ``**settings`` to the ``main`` +values within this section, are passed as ``**settings`` to the ``main`` function we defined in ``__init__.py`` when the server is started via ``pserve``. diff --git a/docs/tutorials/wiki/definingmodels.rst b/docs/tutorials/wiki/definingmodels.rst index 49372179f..859e902ab 100644 --- a/docs/tutorials/wiki/definingmodels.rst +++ b/docs/tutorials/wiki/definingmodels.rst @@ -15,7 +15,7 @@ single instance of the "Wiki" class will serve as a container for "Page" objects, which will be instances of the "Page" class. -Delete the Database +Delete the database ------------------- In the next step, we're going to remove the ``MyModel`` Python model @@ -32,12 +32,19 @@ Edit ``models.py`` .. note:: - There is nothing automagically special about the filename ``models.py``. A + There is nothing special about the filename ``models.py``. A project may have many models throughout its codebase in arbitrarily named - files. Files implementing models often have ``model`` in their filenames, + files. Files implementing models often have ``model`` in their filenames or they may live in a Python subpackage of your application package named ``models``, but this is only by convention. +Open ``tutorial/tutorial/models.py`` file and edit it to look like the +following: + +.. literalinclude:: src/models/tutorial/models.py + :linenos: + :language: python + The first thing we want to do is remove the ``MyModel`` class from the generated ``models.py`` file. The ``MyModel`` class is only a sample and we're not going to use it. @@ -70,17 +77,7 @@ front page) into the Wiki within the ``appmaker``. This will provide :term:`traversal` a :term:`resource tree` to work against when it attempts to resolve URLs to resources. -Look at the Result of Our Edits to ``models.py`` ------------------------------------------------- - -The result of all of our edits to ``models.py`` will end up looking -something like this: - -.. literalinclude:: src/models/tutorial/models.py - :linenos: - :language: python - -View the Application in a Browser +View the application in a browser --------------------------------- We can't. At this point, our system is in a "non-runnable" state; we'll need diff --git a/docs/tutorials/wiki/definingviews.rst b/docs/tutorials/wiki/definingviews.rst index e06468267..ed173a706 100644 --- a/docs/tutorials/wiki/definingviews.rst +++ b/docs/tutorials/wiki/definingviews.rst @@ -17,7 +17,7 @@ assumed to return a :term:`response` object. interchangeably as necessary. In :term:`traversal` based applications, URLs are mapped to a context :term:`resource`, and since our :term:`resource tree` also represents our application's - "domain model", we're often interested in the context, because + "domain model", we're often interested in the context because it represents the persistent storage of our application. For this reason, in this tutorial we define views as callables that accept ``context`` in the callable argument list. If you do @@ -35,35 +35,80 @@ 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 ``pcreate`` 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. +about our custom application requirements. -Our resulting ``setup.py`` should look like so: +We need to add a dependency on the ``docutils`` package to our ``tutorial`` +package's ``setup.py`` file by assigning this dependency to the ``requires`` +parameter in the ``setup()`` function. + +Open ``tutorial/setup.py`` and edit it to look like the following: .. literalinclude:: src/views/setup.py :linenos: + :emphasize-lines: 20 + :language: python + +Only the highlighted line needs to be added. + +Running ``setup.py develop`` +============================ + +Since a new software dependency was added, you will need to run ``python +setup.py develop`` again inside the root of the ``tutorial`` package to obtain +and register the newly added dependency distribution. + +Make sure your current working directory is the root of the project (the +directory in which ``setup.py`` lives) and execute the following command. + +On UNIX: + +.. code-block:: text + + $ cd tutorial + $ $VENV/bin/python setup.py develop + +On Windows: + +.. code-block:: text + + c:\pyramidtut> cd tutorial + c:\pyramidtut\tutorial> %VENV%\Scripts\python setup.py develop + +Success executing this command will end with a line to the console something +like:: + + Finished processing dependencies for tutorial==0.0 + +Adding view functions in ``views.py`` +===================================== + +It's time for a major change. Open ``tutorial/tutorial/views.py`` and edit it +to look like the following: + +.. literalinclude:: src/views/tutorial/views.py + :linenos: :language: python -.. note:: After these new dependencies are added, you will need to - rerun ``python setup.py develop`` inside the root of the - ``tutorial`` package to obtain and register the newly added - dependency package. +We added some imports and created a regular expression to find "WikiWords". + +We got rid of the ``my_view`` view function and its decorator that was added +when we originally rendered the ``zodb`` scaffold. It was only an example and +isn't relevant to our application. + +Then we added four :term:`view callable` functions to our ``views.py`` +module: -Adding View Functions -===================== +* ``view_wiki()`` - Displays the wiki itself. It will answer on the root URL. +* ``view_page()`` - Displays an individual page. +* ``add_page()`` - Allows the user to add a page. +* ``edit_page()`` - Allows the user to edit a page. -We're going to add four :term:`view callable` functions to our ``views.py`` -module. One view 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 named ``edit_page`` will allow a page to be edited. +We'll describe each one briefly in the following sections. .. note:: There is nothing special about the filename ``views.py``. A project may - have many view callables throughout its codebase in arbitrarily-named + 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. @@ -71,44 +116,55 @@ and a final view named ``edit_page`` will allow a page to be edited. The ``view_wiki`` view function ------------------------------- -Here is the code for the ``view_wiki`` view function and its decorator, which -will be added to ``views.py``: +Following is the code for the ``view_wiki`` view function and its decorator: .. literalinclude:: src/views/tutorial/views.py :lines: 12-14 + :lineno-start: 12 + :linenos: :language: python -The ``view_wiki`` function will be configured to respond as the default view -callable for a Wiki resource. We'll provide it with a ``@view_config`` -decorator which names the class ``tutorial.models.Wiki`` as its context. -This means that when a Wiki resource is the context, and no :term:`view name` -exists in the request, this view will be used. The view configuration -associated with ``view_wiki`` does not use a ``renderer`` because the view -callable always returns a :term:`response` object rather than a dictionary. -No renderer is necessary when a view returns a response object. - -The ``view_wiki`` view callable always redirects to the URL of a Page -resource named "FrontPage". To do so, it returns an instance of the +.. note:: In our code, we use an *import* that is *relative* to our package + named ``tutorial``, meaning we can omit the name of the package in the + ``import`` and ``context`` statements. In our narrative, however, we refer + to a *class* and thus we use the *absolute* form, meaning that the name of + the package is included. + +``view_wiki()`` is the :term:`default view` that gets called when a request is +made to the root URL of our wiki. It always redirects to an URL which +represents the path to our "FrontPage". + +We provide it with a ``@view_config`` decorator which names the class +``tutorial.models.Wiki`` as its context. This means that when a Wiki resource +is the context and no :term:`view name` exists in the request, then this view +will be used. The view configuration associated with ``view_wiki`` does not +use a ``renderer`` because the view callable always returns a :term:`response` +object rather than a dictionary. No renderer is necessary when a view returns +a response object. + +The ``view_wiki`` view callable always redirects to the URL of a Page resource +named "FrontPage". To do so, it returns an instance of the :class:`pyramid.httpexceptions.HTTPFound` class (instances of which implement -the :class:`pyramid.interfaces.IResponse` interface like -:class:`pyramid.response.Response` does). -:meth:`pyramid.request.Request.resource_url` constructs a URL to the +the :class:`pyramid.interfaces.IResponse` interface, like +:class:`pyramid.response.Response` does). It uses the +:meth:`pyramid.request.Request.route_url` API to construct an URL to the ``FrontPage`` page resource (i.e., ``http://localhost:6543/FrontPage``), and -uses it as the "location" of the HTTPFound response, forming an HTTP +uses it as the "location" of the ``HTTPFound`` response, forming an HTTP redirect. The ``view_page`` view function ------------------------------- -Here is the code for the ``view_page`` view function and its decorator, which -will be added to ``views.py``: +Here is the code for the ``view_page`` view function and its decorator: .. literalinclude:: src/views/tutorial/views.py :lines: 16-33 + :lineno-start: 16 + :linenos: :language: python -The ``view_page`` function will be configured to respond as the default view -of a Page resource. We'll provide it with a ``@view_config`` decorator which +The ``view_page`` function is configured to respond as the default view +of a Page resource. We provide it with a ``@view_config`` decorator which names the class ``tutorial.models.Page`` as its context. This means that when a Page resource is the context, and no :term:`view name` exists in the request, this view will be used. We inform :app:`Pyramid` this view will use @@ -116,9 +172,9 @@ the ``templates/view.pt`` template file as a ``renderer``. The ``view_page`` function generates the :term:`reStructuredText` body of a page (stored as the ``data`` attribute of the context passed to the view; the -context will be a Page resource) as HTML. Then it substitutes an HTML anchor -for each *WikiWord* reference in the rendered HTML using a compiled regular -expression. +context will be a ``Page`` resource) as HTML. Then it substitutes an HTML +anchor for each *WikiWord* reference in the rendered HTML using a compiled +regular expression. 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 @@ -133,8 +189,8 @@ 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 resource. -We then generate an edit URL (because it's easier to do here than in the -template), and we wrap up a number of arguments in a dictionary and return +We then generate an edit URL because it's easier to do here than in the +template, and we wrap up a number of arguments in a dictionary and return it. The arguments we wrap into a dictionary include ``page``, ``content``, and @@ -153,22 +209,23 @@ callable. In the ``view_wiki`` view callable, we unconditionally return a The ``add_page`` view function ------------------------------ -Here is the code for the ``add_page`` view function and its decorator, which -will be added to ``views.py``: +Here is the code for the ``add_page`` view function and its decorator: .. literalinclude:: src/views/tutorial/views.py :lines: 35-50 + :lineno-start: 35 + :linenos: :language: python -The ``add_page`` function will be configured to respond when the context -resource is a Wiki and the :term:`view name` is ``add_page``. We'll provide -it with a ``@view_config`` decorator which names the string ``add_page`` as -its :term:`view name` (via name=), the class ``tutorial.models.Wiki`` as its -context, and the renderer named ``templates/edit.pt``. This means that when -a Wiki resource is the context, and a :term:`view name` named ``add_page`` +The ``add_page`` function is configured to respond when the context resource +is a Wiki and the :term:`view name` is ``add_page``. We provide it with a +``@view_config`` decorator which names the string ``add_page`` as its +:term:`view name` (via ``name=``), the class ``tutorial.models.Wiki`` as its +context, and the renderer named ``templates/edit.pt``. This means that when a +Wiki resource is the context, and a :term:`view name` named ``add_page`` exists as the result of traversal, this view will be used. We inform -:app:`Pyramid` this view will use the ``templates/edit.pt`` template file as -a ``renderer``. We share the same template between add and edit views, thus +:app:`Pyramid` this view will use the ``templates/edit.pt`` template file as a +``renderer``. We share the same template between add and edit views, thus ``edit.pt`` instead of ``add.pt``. The ``add_page`` function will be invoked when a user clicks on a WikiWord @@ -181,7 +238,7 @@ Page resource). The request :term:`subpath` in :app:`Pyramid` is the sequence of names that are found *after* the :term:`view name` in the URL segments given in the ``PATH_INFO`` of the WSGI request as the result of :term:`traversal`. If our -add view is invoked via, e.g. ``http://localhost:6543/add_page/SomeName``, +add view is invoked via, e.g., ``http://localhost:6543/add_page/SomeName``, the :term:`subpath` will be a tuple: ``('SomeName',)``. The add view takes the zeroth element of the subpath (the wiki page name), @@ -198,7 +255,7 @@ order to satisfy the edit form's desire to have *some* page object exposed as ``page``, and we'll render the template to a response. If the view rendering *is* a result of a form submission (if the expression -``'form.submitted' in request.params`` is ``True``), we scrape the page body +``'form.submitted' in request.params`` is ``True``), we grab the page body from the form data, create a Page object using the name in the subpath and the page body, and save it into "our context" (the Wiki) using the ``__setitem__`` method of the context. We then redirect back to the @@ -207,15 +264,16 @@ the page body, and save it into "our context" (the Wiki) using the The ``edit_page`` view function ------------------------------- -Here is the code for the ``edit_page`` view function and its decorator, which -will be added to ``views.py``: +Here is the code for the ``edit_page`` view function and its decorator: .. literalinclude:: src/views/tutorial/views.py :lines: 52-60 + :lineno-start: 52 + :linenos: :language: python -The ``edit_page`` function will be configured to respond when the context is -a Page resource and the :term:`view name` is ``edit_page``. We'll provide it +The ``edit_page`` function is configured to respond when the context is +a Page resource and the :term:`view name` is ``edit_page``. We provide it with a ``@view_config`` decorator which names the string ``edit_page`` as its :term:`view name` (via ``name=``), the class ``tutorial.models.Page`` as its context, and the renderer named ``templates/edit.pt``. This means that when @@ -240,26 +298,16 @@ If the view execution *is* a result of a form submission (if the expression attribute of the page context. It then redirects to the default view of the context (the 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: - -.. literalinclude:: src/views/tutorial/views.py - :linenos: - :language: python - -Adding Templates +Adding templates ================ The ``view_page``, ``add_page`` and ``edit_page`` views that we've added -reference a :term:`template`. Each template is a :term:`Chameleon` :term:`ZPT` -template. These templates will live in the ``templates`` directory of our -tutorial package. Chameleon templates must have a ``.pt`` extension to be -recognized as such. +reference a :term:`template`. Each template is a :term:`Chameleon` +:term:`ZPT` template. These templates will live in the ``templates`` +directory of our tutorial package. Chameleon templates must have a ``.pt`` +extension to be recognized as such. -The ``view.pt`` Template +The ``view.pt`` template ------------------------ Create ``tutorial/tutorial/templates/view.pt`` and add the following @@ -267,20 +315,18 @@ content: .. literalinclude:: src/views/tutorial/templates/view.pt :linenos: - :language: xml + :language: html This template is used by ``view_page()`` for displaying a single wiki page. It includes: -- A ``div`` element that is replaced with the ``content`` - value provided by the view (rows 45-47). ``content`` - contains HTML, so the ``structure`` keyword is used - to prevent escaping it (i.e. changing ">" to ">", etc.) -- A link that points - at the "edit" URL which invokes the ``edit_page`` view for - the page being viewed (rows 49-51). +- A ``div`` element that is replaced with the ``content`` value provided by + the view (lines 36-38). ``content`` contains HTML, so the ``structure`` + keyword is used to prevent escaping it (i.e., changing ">" to ">", etc.) +- A link that points at the "edit" URL which invokes the ``edit_page`` view + for the page being viewed (lines 40-42). -The ``edit.pt`` Template +The ``edit.pt`` template ------------------------ Create ``tutorial/tutorial/templates/edit.pt`` and add the following @@ -288,66 +334,58 @@ content: .. literalinclude:: src/views/tutorial/templates/edit.pt :linenos: - :language: xml + :language: html -This template is used by ``add_page()`` and ``edit_page()`` for adding -and editing a wiki page. It displays -a page containing a form that includes: +This template is used by ``add_page()`` and ``edit_page()`` for adding and +editing a wiki page. It displays a page containing a form that includes: - A 10 row by 60 column ``textarea`` field named ``body`` that is filled - with any existing page data when it is rendered (rows 46-47). -- A submit button that has the name ``form.submitted`` (row 48). - -The form POSTs back to the "save_url" argument supplied -by the view (row 45). The view will use the ``body`` and -``form.submitted`` values. - -.. note:: Our templates use a ``request`` object that - none of our tutorial views return in their dictionary. - ``request`` is one of several - names that are available "by default" in a template when a template - renderer is used. See :ref:`renderer_system_values` for - information about other names that are available by default - when a template is used as a renderer. - -Static Assets + with any existing page data when it is rendered (line 45). +- A submit button that has the name ``form.submitted`` (line 48). + +The form POSTs back to the ``save_url`` argument supplied by the view (line +43). The view will use the ``body`` and ``form.submitted`` values. + +.. note:: Our templates use a ``request`` object that none of our tutorial + views return in their dictionary. ``request`` is one of several names that + are available "by default" in a template when a template renderer is used. + See :ref:`renderer_system_values` for information about other names that + are available by default when a template is used as a renderer. + +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 -<https://github.com/Pylons/pyramid/blob/master/docs/tutorials/wiki/src/views/tutorial/static/pylons.css>`_. +Our templates name static assets, including CSS and images. We don't need +to create these files within our package's ``static`` directory because they +were provided at the time we created the project. -This CSS file will be accessed via -e.g. ``/static/pylons.css`` by virtue of the call to +As an example, the CSS file will be accessed via +``http://localhost:6543/static/theme.css`` by virtue of the call to the ``add_static_view`` directive we've made in the ``__init__.py`` file. Any number and type of static assets can be placed in this directory (or -subdirectories) and are just referred to by URL. +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. -Viewing the Application in a Browser +Viewing the application in a browser ==================================== We can finally examine our application in a browser (See :ref:`wiki-start-the-application`). Launch a browser and visit -each of the following URLs, check that the result is as expected: +each of the following URLs, checking that the result is as expected: -- ``http://localhost:6543/`` invokes the ``view_wiki`` - view. This always redirects to the ``view_page`` view of the ``FrontPage`` - Page resource. +- http://localhost:6543/ invokes the ``view_wiki`` view. This always + redirects to the ``view_page`` view of the ``FrontPage`` Page resource. -- ``http://localhost:6543/FrontPage/`` invokes - the ``view_page`` view of the front page resource. This is - because it's the :term:`default view` (a view without a ``name``) for Page - resources. +- http://localhost:6543/FrontPage/ invokes the ``view_page`` view of the front + page resource. This is because it's the :term:`default view` (a view + without a ``name``) for Page resources. -- ``http://localhost:6543/FrontPage/edit_page`` - invokes the edit view for the ``FrontPage`` Page resource. +- http://localhost:6543/FrontPage/edit_page invokes the edit view for the + ``FrontPage`` Page resource. -- ``http://localhost:6543/add_page/SomePageName`` - invokes the add view for a Page. +- http://localhost:6543/add_page/SomePageName invokes the add view for a Page. -- To generate an error, visit ``http://localhost:6543/add_page`` which - will generate an ``IndexErrorr: tuple index out of range`` error. - You'll see an interactive traceback - facility provided by :term:`pyramid_debugtoolbar`. +- To generate an error, visit http://localhost:6543/add_page which will + generate an ``IndexErrorr: tuple index out of range`` error. You'll see an + interactive traceback facility provided by :term:`pyramid_debugtoolbar`. diff --git a/docs/tutorials/wiki/design.rst b/docs/tutorials/wiki/design.rst index 28380bd66..49c30d29a 100644 --- a/docs/tutorials/wiki/design.rst +++ b/docs/tutorials/wiki/design.rst @@ -2,22 +2,22 @@ Design ========== -Following is a quick overview of our wiki application, to help -us understand the changes that we will be doing next in our -default files generated by the ``zodb`` scaffold. +Following is a quick overview of the design of our wiki application, to help +us understand the changes that we will be making as we work through the +tutorial. Overall ------- -We choose to use ``reStructuredText`` markup in the wiki text. -Translation from reStructuredText to HTML is provided by the -widely used ``docutils`` Python module. We will add this module -in the dependency list on the project ``setup.py`` file. +We choose to use :term:`reStructuredText` markup in the wiki text. Translation +from reStructuredText to HTML is provided by the widely used ``docutils`` +Python module. We will add this module in the dependency list on the project +``setup.py`` file. Models ------ -The root resource, named *Wiki*, will be a mapping of wiki page +The root resource named ``Wiki`` will be a mapping of wiki page names to page resources. The page resources will be instances of a *Page* class and they store the text content. @@ -29,9 +29,9 @@ To add a page to the wiki, a new instance of the page resource is created and its name and reference are added to the Wiki mapping. -A page named *FrontPage* containing the text *This is the front -page*, will be created when the storage is initialized, and will -be used as the wiki home page. +A page named ``FrontPage`` containing the text *This is the front page*, will +be created when the storage is initialized, and will be used as the wiki home +page. Views ----- @@ -57,14 +57,13 @@ use to do this are below. corresponding passwords. - GROUPS, a dictionary mapping :term:`userids <userid>` to a - list of groups to which they belong to. + list of groups to which they belong. -- ``groupfinder``, an *authorization callback* that looks up - USERS and GROUPS. It will be provided in a new - *security.py* file. +- ``groupfinder``, an *authorization callback* that looks up USERS and + GROUPS. It will be provided in a new ``security.py`` file. -- An :term:`ACL` is attached to the root :term:`resource`. Each - row below details an :term:`ACE`: +- An :term:`ACL` is attached to the root :term:`resource`. Each row below + details an :term:`ACE`: +----------+----------------+----------------+ | Action | Principal | Permission | @@ -125,7 +124,7 @@ listed in the following table: | | | | authenticate. | | | | | | | | | | | | | | - If authentication | | | -| | | | successful, | | | +| | | | succeeds, | | | | | | | redirect to the | | | | | | | page that we | | | | | | | came from. | | | @@ -145,6 +144,6 @@ listed in the following table: when there is no view name. .. [2] Pyramid will return a default 404 Not Found page if the page *PageName* does not exist yet. -.. [3] pyramid.exceptions.Forbidden is reached when a +.. [3] ``pyramid.exceptions.Forbidden`` is reached when a user tries to invoke a view that is not authorized by the authorization policy. diff --git a/docs/tutorials/wiki/distributing.rst b/docs/tutorials/wiki/distributing.rst index 9c63cf0bd..fee50a1cf 100644 --- a/docs/tutorials/wiki/distributing.rst +++ b/docs/tutorials/wiki/distributing.rst @@ -2,11 +2,11 @@ Distributing Your Application ============================= -Once your application works properly, you can create a "tarball" from -it by using the ``setup.py sdist`` command. The following commands -assume your current working directory is the ``tutorial`` package -we've created and that the parent directory of the ``tutorial`` -package is a virtualenv representing a :app:`Pyramid` environment. +Once your application works properly, you can create a "tarball" from it by +using the ``setup.py sdist`` command. The following commands assume your +current working directory is the ``tutorial`` package we've created and that +the parent directory of the ``tutorial`` package is a virtualenv representing +a :app:`Pyramid` environment. On UNIX: @@ -27,16 +27,14 @@ The output of such a command will be something like: running sdist # .. more output .. creating dist - tar -cf dist/tutorial-0.1.tar tutorial-0.1 - gzip -f9 dist/tutorial-0.1.tar - removing 'tutorial-0.1' (and everything under it) - -Note that this command creates a tarball in the "dist" subdirectory -named ``tutorial-0.1.tar.gz``. You can send this file to your friends -to show them your cool new application. They should be able to -install it by pointing the ``easy_install`` command directly at it. -Or you can upload it to `PyPI <http://pypi.python.org>`_ and share it -with the rest of the world, where it can be downloaded via -``easy_install`` remotely like any other package people download from -PyPI. - + tar -cf dist/tutorial-0.0.tar tutorial-0.0 + gzip -f9 dist/tutorial-0.0.tar + removing 'tutorial-0.0' (and everything under it) + +Note that this command creates a tarball in the "dist" subdirectory named +``tutorial-0.0.tar.gz``. You can send this file to your friends to show them +your cool new application. They should be able to install it by pointing the +``easy_install`` command directly at it. Or you can upload it to `PyPI +<http://pypi.python.org>`_ and share it with the rest of the world, where it +can be downloaded via ``easy_install`` remotely like any other package people +download from PyPI. diff --git a/docs/tutorials/wiki/index.rst b/docs/tutorials/wiki/index.rst index 981d135c7..89c026dac 100644 --- a/docs/tutorials/wiki/index.rst +++ b/docs/tutorials/wiki/index.rst @@ -3,10 +3,10 @@ ZODB + Traversal Wiki Tutorial ============================== -This tutorial introduces a :term:`traversal` -based :app:`Pyramid` -application to a developer familiar with Python. It will be most familiar to -developers with previous :term:`Zope` experience. When we're done with the -tutorial, the developer will have created a basic Wiki application with +This tutorial introduces a :term:`ZODB` and :term:`traversal`-based +:app:`Pyramid` application to a developer familiar with Python. It will be +most familiar to developers with previous :term:`Zope` experience. When the +is finished, the developer will have created a basic Wiki application with authentication. For cut and paste purposes, the source code for all stages of this diff --git a/docs/tutorials/wiki/installation.rst b/docs/tutorials/wiki/installation.rst index b51254b92..20df389c6 100644 --- a/docs/tutorials/wiki/installation.rst +++ b/docs/tutorials/wiki/installation.rst @@ -2,125 +2,218 @@ Installation ============ -Preparation -=========== +Before you begin +================ -Follow the steps in :ref:`installing_chapter`, but name the virtualenv -directory ``pyramidtut``. +This tutorial assumes that you have already followed the steps in +:ref:`installing_chapter`, except **do not create a virtualenv or install +Pyramid**. Thereby you will satisfy the following requirements. -Preparation, UNIX ------------------ +* Python interpreter is installed on your operating system +* :term:`setuptools` or :term:`distribute` is installed +* :term:`virtualenv` is installed +Create directory to contain the project +--------------------------------------- -#. Switch to the ``pyramidtut`` directory: +We need a workspace for our project files. - .. code-block:: text +On UNIX +^^^^^^^ - $ cd pyramidtut +.. code-block:: text + + $ mkdir ~/pyramidtut + +On Windows +^^^^^^^^^^ + +.. code-block:: text + + c:\> mkdir pyramidtut -#. Install tutorial dependencies: +Create and use a virtual Python environment +------------------------------------------- - .. code-block:: text +Next let's create a `virtualenv` workspace for our project. We will +use the `VENV` environment variable instead of the absolute path of the +virtual environment. - $ $VENV/bin/easy_install docutils pyramid_tm pyramid_zodbconn \ - pyramid_debugtoolbar nose coverage +On UNIX +^^^^^^^ -Preparation, Windows --------------------- +.. code-block:: text + + $ export VENV=~/pyramidtut + $ virtualenv $VENV + New python executable in /home/foo/env/bin/python + Installing setuptools.............done. + +On Windows +^^^^^^^^^^ +.. code-block:: text + + c:\> set VENV=c:\pyramidtut -#. Switch to the ``pyramidtut`` directory: +Versions of Python use different paths, so you will need to adjust the +path to the command for your Python version. - .. code-block:: text +Python 2.7: - c:\> cd pyramidtut +.. code-block:: text -#. Install tutorial dependencies: + c:\> c:\Python27\Scripts\virtualenv %VENV% - .. code-block:: text +Python 3.2: + +.. code-block:: text + + c:\> c:\Python32\Scripts\virtualenv %VENV% + +Install Pyramid and tutorial dependencies into the virtual Python environment +----------------------------------------------------------------------------- + +On UNIX +^^^^^^^ + +.. code-block:: text + + $ $VENV/bin/easy_install docutils pyramid_tm pyramid_zodbconn \ + pyramid_debugtoolbar nose coverage + +On Windows +^^^^^^^^^^ + +.. code-block:: text - c:\pyramidtut> %VENV%\Scripts\easy_install docutils pyramid_tm \ - pyramid_zodbconn pyramid_debugtoolbar nose coverage + c:\> %VENV%\Scripts\easy_install docutils pyramid_tm pyramid_zodbconn \ + pyramid_debugtoolbar nose coverage + +Change Directory to Your Virtual Python Environment +--------------------------------------------------- + +Change directory to the ``pyramidtut`` directory. + +On UNIX +^^^^^^^ + +.. code-block:: text + + $ cd pyramidtut + +On Windows +^^^^^^^^^^ + +.. code-block:: text + + c:\> cd pyramidtut .. _making_a_project: -Make a Project -============== +Making a project +================ + +Your next step is to create a project. For this tutorial, we will use +the :term:`scaffold` named ``zodb``, which generates an application +that uses :term:`ZODB` and :term:`traversal`. -Your next step is to create a project. For this tutorial, we will use the -:term:`scaffold` named ``zodb``, which generates an application -that uses :term:`ZODB` and :term:`traversal`. :app:`Pyramid` -supplies a variety of scaffolds to generate sample projects. +:app:`Pyramid` supplies a variety of scaffolds to generate sample +projects. We will use `pcreate`—a script that comes with Pyramid to +quickly and easily generate scaffolds, usually with a single command—to +create the scaffold for our project. -The below instructions assume your current working directory is the -"virtualenv" named "pyramidtut". +By passing `zodb` into the `pcreate` command, the script creates +the files needed to use ZODB. By passing in our application name +`tutorial`, the script inserts that application name into all the +required files. -On UNIX: +The below instructions assume your current working directory is "pyramidtut". + +On UNIX +------- .. code-block:: text - $ $VENV/bin/pcreate -s zodb tutorial + $ $VENV/bin/pcreate -s zodb tutorial -On Windows: +On Windows +---------- .. code-block:: text c:\pyramidtut> %VENV%\Scripts\pcreate -s zodb tutorial -.. note:: You don't have to call it `tutorial` -- the code uses - relative paths for imports and finding templates and static - resources. +.. note:: If you are using Windows, the ``zodb`` + scaffold may not deal gracefully with installation into a + location that contains spaces in the path. If you experience + startup problems, try putting both the virtualenv and the project + into directories that do not contain spaces in their paths. -.. note:: If you are using Windows, the ``zodb`` scaffold - doesn't currently deal gracefully with installation into a location - that contains spaces in the path. If you experience startup - problems, try putting both the virtualenv and the project into - directories that do not contain spaces in their paths. +.. _installing_project_in_dev_mode_zodb: -Install the Project in "Development Mode" -========================================= +Installing the project in development mode +========================================== In order to do development on the project easily, you must "register" the project as a development egg in your workspace using the -``setup.py develop`` command. In order to do so, cd to the "tutorial" +``setup.py develop`` command. In order to do so, cd to the `tutorial` directory you created in :ref:`making_a_project`, and run the -"setup.py develop" command using virtualenv Python interpreter. +``setup.py develop`` command using the virtualenv Python interpreter. -On UNIX: +On UNIX +------- .. code-block:: text - $ cd tutorial - $ $VENV/bin/python setup.py develop + $ cd tutorial + $ $VENV/bin/python setup.py develop -On Windows: +On Windows +---------- .. code-block:: text - C:\pyramidtut> cd tutorial - C:\pyramidtut\tutorial> %VENV%\Scripts\python setup.py develop + c:\pyramidtut> cd tutorial + c:\pyramidtut\tutorial> %VENV%\Scripts\python setup.py develop + +The console will show `setup.py` checking for packages and installing +missing packages. Success executing this command will show a line like +the following:: + + Finished processing dependencies for tutorial==0.0 .. _running_tests: -Run the Tests +Run the tests ============= After you've installed the project in development mode, you may run the tests for the project. -On UNIX: +On UNIX +------- .. code-block:: text - $ $VENV/bin/python setup.py test -q + $ $VENV/bin/python setup.py test -q -On Windows: +On Windows +---------- .. code-block:: text - c:\pyramidtut\tutorial> %VENV%\Scripts\python setup.py test -q + c:\pyramidtut\tutorial> %VENV%\Scripts\python setup.py test -q -Expose Test Coverage Information +For a successful test run, you should see output that ends like this:: + + . + ---------------------------------------------------------------------- + Ran 1 test in 0.094s + + OK + +Expose test coverage information ================================ You can run the ``nosetests`` command to see test coverage @@ -129,48 +222,73 @@ test`` does but provides additional "coverage" information, exposing which lines of your project are "covered" (or not covered) by the tests. -On UNIX: +On UNIX +------- .. code-block:: text - $ $VENV/bin/nosetests --cover-package=tutorial --cover-erase --with-coverage + $ $VENV/bin/nosetests --cover-package=tutorial --cover-erase --with-coverage -On Windows: +On Windows +---------- .. code-block:: text - c:\pyramidtut\tutorial> %VENV%\Scripts\nosetests --cover-package=tutorial ^ - --cover-erase --with-coverage + c:\pyramidtut\tutorial> %VENV%\Scripts\nosetests --cover-package=tutorial \ + --cover-erase --with-coverage + +If successful, you will see output something like this:: -Looks like the code in the ``zodb`` scaffold for ZODB projects is -missing some test coverage, particularly in the file named -``models.py``. + . + Name Stmts Miss Cover Missing + -------------------------------------------------- + tutorial.py 12 7 42% 7-8, 14-18 + tutorial/models.py 10 6 40% 9-14 + tutorial/views.py 4 0 100% + -------------------------------------------------- + TOTAL 26 13 50% + ---------------------------------------------------------------------- + Ran 1 test in 0.392s + + OK + +Looks like our package doesn't quite have 100% test coverage. .. _wiki-start-the-application: -Start the Application +Start the application ===================== Start the application. -On UNIX: +On UNIX +------- .. code-block:: text - $ $VENV/bin/pserve development.ini --reload + $ $VENV/bin/pserve development.ini --reload -On Windows: +On Windows +---------- .. code-block:: text - c:\pyramidtut\tutorial> %VENV%\Scripts\pserve development.ini --reload + c:\pyramidtut\tutorial> %VENV%\Scripts\pserve development.ini --reload .. note:: Your OS firewall, if any, may pop up a dialog asking for authorization to allow python to accept incoming network connections. -Visit the Application in a Browser +If successful, you will see something like this on your console:: + + Starting subprocess with file monitor + Starting server in PID 95736. + serving on http://0.0.0.0:6543 + +This means the server is ready to accept requests. + +Visit the application in a browser ================================== In a browser, visit `http://localhost:6543/ <http://localhost:6543>`_. You @@ -181,7 +299,7 @@ page. You can read more about the purpose of the icon at :ref:`debug_toolbar`. It allows you to get information about your application while you develop. -Decisions the ``zodb`` Scaffold Has Made For You +Decisions the ``zodb`` scaffold has made for you ================================================ Creating a project using the ``zodb`` scaffold makes the following @@ -189,11 +307,11 @@ assumptions: - you are willing to use :term:`ZODB` as persistent storage -- you are willing to use :term:`traversal` to map URLs to code. +- you are willing to use :term:`traversal` to map URLs to code .. note:: :app:`Pyramid` supports any persistent storage mechanism (e.g., a SQL - database or filesystem files). :app:`Pyramid` also supports an additional + database or filesystem files). It also supports an additional mechanism to map URLs to code (:term:`URL dispatch`). However, for the purposes of this tutorial, we'll only be using traversal and ZODB. diff --git a/docs/tutorials/wiki/src/authorization/setup.py b/docs/tutorials/wiki/src/authorization/setup.py index 5ab4f73cd..e2e96379d 100644 --- a/docs/tutorials/wiki/src/authorization/setup.py +++ b/docs/tutorials/wiki/src/authorization/setup.py @@ -11,10 +11,10 @@ with open(os.path.join(here, 'CHANGES.txt')) as f: requires = [ 'pyramid', 'pyramid_chameleon', + 'pyramid_debugtoolbar', + 'pyramid_tm', 'pyramid_zodbconn', 'transaction', - 'pyramid_tm', - 'pyramid_debugtoolbar', 'ZODB3', 'waitress', 'docutils', diff --git a/docs/tutorials/wiki/src/authorization/tutorial/static/favicon.ico b/docs/tutorials/wiki/src/authorization/tutorial/static/favicon.ico Binary files differdeleted file mode 100644 index 71f837c9e..000000000 --- a/docs/tutorials/wiki/src/authorization/tutorial/static/favicon.ico +++ /dev/null diff --git a/docs/tutorials/wiki/src/authorization/tutorial/static/footerbg.png b/docs/tutorials/wiki/src/authorization/tutorial/static/footerbg.png Binary files differdeleted file mode 100644 index 1fbc873da..000000000 --- a/docs/tutorials/wiki/src/authorization/tutorial/static/footerbg.png +++ /dev/null diff --git a/docs/tutorials/wiki/src/authorization/tutorial/static/headerbg.png b/docs/tutorials/wiki/src/authorization/tutorial/static/headerbg.png Binary files differdeleted file mode 100644 index 0596f2020..000000000 --- a/docs/tutorials/wiki/src/authorization/tutorial/static/headerbg.png +++ /dev/null diff --git a/docs/tutorials/wiki/src/authorization/tutorial/static/ie6.css b/docs/tutorials/wiki/src/authorization/tutorial/static/ie6.css deleted file mode 100644 index b7c8493d8..000000000 --- a/docs/tutorials/wiki/src/authorization/tutorial/static/ie6.css +++ /dev/null @@ -1,8 +0,0 @@ -* 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/wiki/src/authorization/tutorial/static/middlebg.png b/docs/tutorials/wiki/src/authorization/tutorial/static/middlebg.png Binary files differdeleted file mode 100644 index 2369cfb7d..000000000 --- a/docs/tutorials/wiki/src/authorization/tutorial/static/middlebg.png +++ /dev/null diff --git a/docs/tutorials/wiki/src/authorization/tutorial/static/pylons.css b/docs/tutorials/wiki/src/authorization/tutorial/static/pylons.css deleted file mode 100644 index 4b1c017cd..000000000 --- a/docs/tutorials/wiki/src/authorization/tutorial/static/pylons.css +++ /dev/null @@ -1,372 +0,0 @@ -html, body, div, span, applet, object, iframe, h1, h2, h3, h4, h5, h6, p, blockquote, pre, a, abbr, acronym, address, big, cite, code, del, dfn, em, font, img, ins, kbd, q, s, samp, small, strike, strong, sub, sup, tt, var, b, u, i, center, dl, dt, dd, ol, ul, li, fieldset, form, label, legend, table, caption, tbody, tfoot, thead, tr, th, td -{ - margin: 0; - padding: 0; - border: 0; - outline: 0; - font-size: 100%; /* 16px */ - vertical-align: baseline; - background: transparent; -} - -body -{ - line-height: 1; -} - -ol, ul -{ - list-style: none; -} - -blockquote, q -{ - quotes: none; -} - -blockquote:before, blockquote:after, q:before, q:after -{ - content: ''; - content: none; -} - -:focus -{ - outline: 0; -} - -ins -{ - text-decoration: none; -} - -del -{ - text-decoration: line-through; -} - -table -{ - border-collapse: collapse; - border-spacing: 0; -} - -sub -{ - vertical-align: sub; - font-size: smaller; - line-height: normal; -} - -sup -{ - vertical-align: super; - font-size: smaller; - line-height: normal; -} - -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; -} - -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; -} - -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; -} - -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; - 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: #fff; - position: relative; - font: 16px/24px NobileRegular, "Lucida Grande", Lucida, Verdana, sans-serif; -} - -a -{ - color: #1b61d6; - text-decoration: none; -} - -a:hover -{ - color: #e88f00; - text-decoration: underline; -} - -body h1, body h2, body h3, body h4, body h5, body h6 -{ - font-family: NeutonRegular, "Lucida Grande", Lucida, Verdana, sans-serif; - font-weight: 400; - color: #373839; - font-style: normal; -} - -#wrap -{ - min-height: 100%; -} - -#header, #footer -{ - width: 100%; - color: #fff; - height: 40px; - position: absolute; - text-align: center; - line-height: 40px; - overflow: hidden; - font-size: 12px; - vertical-align: middle; -} - -#header -{ - background: #000; - top: 0; - font-size: 14px; -} - -#footer -{ - bottom: 0; - background: #000 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, #top-small, #bottom -{ - width: 100%; -} - -#top -{ - color: #000; - height: 230px; - background: #fff url(headerbg.png) repeat-x 0 top; - position: relative; -} - -#top-small -{ - color: #000; - height: 60px; - background: #fff url(headerbg.png) repeat-x 0 top; - position: relative; -} - -#bottom -{ - color: #222; - background-color: #fff; -} - -.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 #fff; - border-bottom: 2px solid #b2b2b2; -} - -.app-welcome -{ - margin-top: 25px; -} - -.app-name -{ - color: #000; - font-weight: 700; -} - -.bottom -{ - padding-top: 50px; -} - -#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; -} - -ul.links -{ - margin: 0; - padding: 0; -} - -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=password] -{ - width: 205px; -} - -input[type=submit] -{ - background-color: #ddd; - font-weight: 700; -} - -/*Opera Fix*/ -body:before -{ - content: ""; - height: 100%; - float: left; - width: 0; - margin-top: -32767px; -} diff --git a/docs/tutorials/wiki/src/authorization/tutorial/static/pyramid-16x16.png b/docs/tutorials/wiki/src/authorization/tutorial/static/pyramid-16x16.png Binary files differnew file mode 100644 index 000000000..979203112 --- /dev/null +++ b/docs/tutorials/wiki/src/authorization/tutorial/static/pyramid-16x16.png diff --git a/docs/tutorials/wiki/src/authorization/tutorial/static/pyramid-small.png b/docs/tutorials/wiki/src/authorization/tutorial/static/pyramid-small.png Binary files differdeleted file mode 100644 index a5bc0ade7..000000000 --- a/docs/tutorials/wiki/src/authorization/tutorial/static/pyramid-small.png +++ /dev/null diff --git a/docs/tutorials/wiki/src/authorization/tutorial/static/pyramid.png b/docs/tutorials/wiki/src/authorization/tutorial/static/pyramid.png Binary files differindex 347e05549..4ab837be9 100644 --- a/docs/tutorials/wiki/src/authorization/tutorial/static/pyramid.png +++ b/docs/tutorials/wiki/src/authorization/tutorial/static/pyramid.png diff --git a/docs/tutorials/wiki/src/authorization/tutorial/static/theme.css b/docs/tutorials/wiki/src/authorization/tutorial/static/theme.css new file mode 100644 index 000000000..0f4b1a4d4 --- /dev/null +++ b/docs/tutorials/wiki/src/authorization/tutorial/static/theme.css @@ -0,0 +1,154 @@ +@import url(//fonts.googleapis.com/css?family=Open+Sans:300,400,600,700); +body { + font-family: "Open Sans", "Helvetica Neue", Helvetica, Arial, sans-serif; + font-weight: 300; + color: #ffffff; + background: #bc2131; +} +h1, +h2, +h3, +h4, +h5, +h6 { + font-family: "Open Sans", "Helvetica Neue", Helvetica, Arial, sans-serif; + font-weight: 300; +} +p { + font-weight: 300; +} +.font-normal { + font-weight: 400; +} +.font-semi-bold { + font-weight: 600; +} +.font-bold { + font-weight: 700; +} +.starter-template { + margin-top: 250px; +} +.starter-template .content { + margin-left: 10px; +} +.starter-template .content h1 { + margin-top: 10px; + font-size: 60px; +} +.starter-template .content h1 .smaller { + font-size: 40px; + color: #f2b7bd; +} +.starter-template .content .lead { + font-size: 25px; + color: #f2b7bd; +} +.starter-template .content .lead .font-normal { + color: #ffffff; +} +.starter-template .links { + float: right; + right: 0; + margin-top: 125px; +} +.starter-template .links ul { + display: block; + padding: 0; + margin: 0; +} +.starter-template .links ul li { + list-style: none; + display: inline; + margin: 0 10px; +} +.starter-template .links ul li:first-child { + margin-left: 0; +} +.starter-template .links ul li:last-child { + margin-right: 0; +} +.starter-template .links ul li.current-version { + color: #f2b7bd; + font-weight: 400; +} +.starter-template .links ul li a, a { + color: #f2b7bd; + text-decoration: underline; +} +.starter-template .links ul li a:hover, a:hover { + color: #ffffff; + text-decoration: underline; +} +.starter-template .links ul li .icon-muted { + color: #eb8b95; + margin-right: 5px; +} +.starter-template .links ul li:hover .icon-muted { + color: #ffffff; +} +.starter-template .copyright { + margin-top: 10px; + font-size: 0.9em; + color: #f2b7bd; + text-transform: lowercase; + float: right; + right: 0; +} +@media (max-width: 1199px) { + .starter-template .content h1 { + font-size: 45px; + } + .starter-template .content h1 .smaller { + font-size: 30px; + } + .starter-template .content .lead { + font-size: 20px; + } +} +@media (max-width: 991px) { + .starter-template { + margin-top: 0; + } + .starter-template .logo { + margin: 40px auto; + } + .starter-template .content { + margin-left: 0; + text-align: center; + } + .starter-template .content h1 { + margin-bottom: 20px; + } + .starter-template .links { + float: none; + text-align: center; + margin-top: 60px; + } + .starter-template .copyright { + float: none; + text-align: center; + } +} +@media (max-width: 767px) { + .starter-template .content h1 .smaller { + font-size: 25px; + display: block; + } + .starter-template .content .lead { + font-size: 16px; + } + .starter-template .links { + margin-top: 40px; + } + .starter-template .links ul li { + display: block; + margin: 0; + } + .starter-template .links ul li .icon-muted { + display: none; + } + .starter-template .copyright { + margin-top: 20px; + } +} diff --git a/docs/tutorials/wiki/src/authorization/tutorial/static/theme.min.css b/docs/tutorials/wiki/src/authorization/tutorial/static/theme.min.css new file mode 100644 index 000000000..2f924bcc5 --- /dev/null +++ b/docs/tutorials/wiki/src/authorization/tutorial/static/theme.min.css @@ -0,0 +1 @@ +@import url(//fonts.googleapis.com/css?family=Open+Sans:300,400,600,700);body{font-family:"Open Sans","Helvetica Neue",Helvetica,Arial,sans-serif;font-weight:300;color:#fff;background:#bc2131}h1,h2,h3,h4,h5,h6{font-family:"Open Sans","Helvetica Neue",Helvetica,Arial,sans-serif;font-weight:300}p{font-weight:300}.font-normal{font-weight:400}.font-semi-bold{font-weight:600}.font-bold{font-weight:700}.starter-template{margin-top:250px}.starter-template .content{margin-left:10px}.starter-template .content h1{margin-top:10px;font-size:60px}.starter-template .content h1 .smaller{font-size:40px;color:#f2b7bd}.starter-template .content .lead{font-size:25px;color:#f2b7bd}.starter-template .content .lead .font-normal{color:#fff}.starter-template .links{float:right;right:0;margin-top:125px}.starter-template .links ul{display:block;padding:0;margin:0}.starter-template .links ul li{list-style:none;display:inline;margin:0 10px}.starter-template .links ul li:first-child{margin-left:0}.starter-template .links ul li:last-child{margin-right:0}.starter-template .links ul li.current-version{color:#f2b7bd;font-weight:400}.starter-template .links ul li a{color:#fff}.starter-template .links ul li a:hover{text-decoration:underline}.starter-template .links ul li .icon-muted{color:#eb8b95;margin-right:5px}.starter-template .links ul li:hover .icon-muted{color:#fff}.starter-template .copyright{margin-top:10px;font-size:.9em;color:#f2b7bd;text-transform:lowercase;float:right;right:0}@media (max-width:1199px){.starter-template .content h1{font-size:45px}.starter-template .content h1 .smaller{font-size:30px}.starter-template .content .lead{font-size:20px}}@media (max-width:991px){.starter-template{margin-top:0}.starter-template .logo{margin:40px auto}.starter-template .content{margin-left:0;text-align:center}.starter-template .content h1{margin-bottom:20px}.starter-template .links{float:none;text-align:center;margin-top:60px}.starter-template .copyright{float:none;text-align:center}}@media (max-width:767px){.starter-template .content h1 .smaller{font-size:25px;display:block}.starter-template .content .lead{font-size:16px}.starter-template .links{margin-top:40px}.starter-template .links ul li{display:block;margin:0}.starter-template .links ul li .icon-muted{display:none}.starter-template .copyright{margin-top:20px}}
\ No newline at end of file diff --git a/docs/tutorials/wiki/src/authorization/tutorial/static/transparent.gif b/docs/tutorials/wiki/src/authorization/tutorial/static/transparent.gif Binary files differdeleted file mode 100644 index 0341802e5..000000000 --- a/docs/tutorials/wiki/src/authorization/tutorial/static/transparent.gif +++ /dev/null diff --git a/docs/tutorials/wiki/src/authorization/tutorial/templates/edit.pt b/docs/tutorials/wiki/src/authorization/tutorial/templates/edit.pt index c3a0acf6b..823fa8972 100644 --- a/docs/tutorials/wiki/src/authorization/tutorial/templates/edit.pt +++ b/docs/tutorials/wiki/src/authorization/tutorial/templates/edit.pt @@ -1,58 +1,72 @@ -<!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>${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="/static/favicon.ico" /> - <link rel="stylesheet" - href="/static/pylons.css" - type="text/css" media="screen" charset="utf-8" /> - <!--[if lte IE 6]> - <link rel="stylesheet" - href="/static/ie6.css" - type="text/css" media="screen" charset="utf-8" /> - <![endif]--> -</head> -<body> - <div id="wrap"> - <div id="top-small"> - <div class="top-small align-center"> - <div> - <img width="220" height="50" alt="pyramid" - src="/static/pyramid-small.png" /> +<!DOCTYPE html> +<html lang="${request.locale_name}"> + <head> + <meta charset="utf-8"> + <meta http-equiv="X-UA-Compatible" content="IE=edge"> + <meta name="viewport" content="width=device-width, initial-scale=1.0"> + <meta name="description" content="pyramid web application"> + <meta name="author" content="Pylons Project"> + <link rel="shortcut icon" href="${request.static_url('tutorial:static/pyramid-16x16.png')}"> + + <title>${page.__name__} - Pyramid tutorial wiki (based on + TurboGears 20-Minute Wiki)</title> + + <!-- Bootstrap core CSS --> + <link href="//oss.maxcdn.com/libs/twitter-bootstrap/3.0.3/css/bootstrap.min.css" rel="stylesheet"> + + <!-- Custom styles for this scaffold --> + <link href="${request.static_url('tutorial:static/theme.css')}" rel="stylesheet"> + + <!-- HTML5 shim and Respond.js IE8 support of HTML5 elements and media queries --> + <!--[if lt IE 9]> + <script src="//oss.maxcdn.com/libs/html5shiv/3.7.0/html5shiv.js"></script> + <script src="//oss.maxcdn.com/libs/respond.js/1.3.0/respond.min.js"></script> + <![endif]--> + </head> + <body> + + <div class="starter-template"> + <div class="container"> + <div class="row"> + <div class="col-md-2"> + <img class="logo img-responsive" src="${request.static_url('tutorial:static/pyramid.png')}" alt="pyramid web framework"> + </div> + <div class="col-md-10"> + <div class="content"> + <p tal:condition="logged_in" class="pull-right"> + <a href="${request.application_url}/logout">Logout</a> + </p> + <p> + Editing <strong><span tal:replace="page.__name__"> + Page Name Goes Here</span></strong> + </p> + <p>You can return to the + <a href="${request.application_url}">FrontPage</a>. + </p> + <form action="${save_url}" method="post"> + <div class="form-group"> + <textarea class="form-control" name="body" tal:content="page.data" rows="10" cols="60"></textarea> + </div> + <div class="form-group"> + <button type="submit" name="form.submitted" value="Save" class="btn btn-default">Save</button> + </div> + </form> + </div> + </div> </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 class="row"> + <div class="copyright"> + Copyright © Pylons Project + </div> </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> -</body> + + + <!-- Bootstrap core JavaScript + ================================================== --> + <!-- Placed at the end of the document so the pages load faster --> + <script src="//oss.maxcdn.com/libs/jquery/1.10.2/jquery.min.js"></script> + <script src="//oss.maxcdn.com/libs/twitter-bootstrap/3.0.3/js/bootstrap.min.js"></script> + </body> </html> diff --git a/docs/tutorials/wiki/src/authorization/tutorial/templates/login.pt b/docs/tutorials/wiki/src/authorization/tutorial/templates/login.pt index 3612dccde..4a938e9bb 100644 --- a/docs/tutorials/wiki/src/authorization/tutorial/templates/login.pt +++ b/docs/tutorials/wiki/src/authorization/tutorial/templates/login.pt @@ -1,54 +1,74 @@ -<!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>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="/static/favicon.ico" /> - <link rel="stylesheet" - href="/static/pylons.css" - type="text/css" media="screen" charset="utf-8" /> - <!--[if lte IE 6]> - <link rel="stylesheet" - href="/static/ie6.css" - type="text/css" media="screen" charset="utf-8" /> - <![endif]--> -</head> -<body> - <div id="wrap"> - <div id="top-small"> - <div class="top-small align-center"> - <div> - <img width="220" height="50" alt="pyramid" - src="/static/pyramid-small.png" /> +<!DOCTYPE html> +<html lang="${request.locale_name}"> + <head> + <meta charset="utf-8"> + <meta http-equiv="X-UA-Compatible" content="IE=edge"> + <meta name="viewport" content="width=device-width, initial-scale=1.0"> + <meta name="description" content="pyramid web application"> + <meta name="author" content="Pylons Project"> + <link rel="shortcut icon" href="${request.static_url('tutorial:static/pyramid-16x16.png')}"> + + <title>Login - Pyramid tutorial wiki (based on + TurboGears 20-Minute Wiki)</title> + + <!-- Bootstrap core CSS --> + <link href="//oss.maxcdn.com/libs/twitter-bootstrap/3.0.3/css/bootstrap.min.css" rel="stylesheet"> + + <!-- Custom styles for this scaffold --> + <link href="${request.static_url('tutorial:static/theme.css')}" rel="stylesheet"> + + <!-- HTML5 shim and Respond.js IE8 support of HTML5 elements and media queries --> + <!--[if lt IE 9]> + <script src="//oss.maxcdn.com/libs/html5shiv/3.7.0/html5shiv.js"></script> + <script src="//oss.maxcdn.com/libs/respond.js/1.3.0/respond.min.js"></script> + <![endif]--> + </head> + <body> + + <div class="starter-template"> + <div class="container"> + <div class="row"> + <div class="col-md-2"> + <img class="logo img-responsive" src="${request.static_url('tutorial:static/pyramid.png')}" alt="pyramid web framework"> + </div> + <div class="col-md-10"> + <div class="content"> + <p> + <strong> + Login + </strong><br> + <span tal:replace="message"></span> + </p> + <form action="${url}" method="post"> + <input type="hidden" name="came_from" value="${came_from}"> + <div class="form-group"> + <label for="login">Username</label> + <input type="text" name="login" value="${login}"> + </div> + <div class="form-group"> + <label for="password">Password</label> + <input type="password" name="password" value="${password}"> + </div> + <div class="form-group"> + <button type="submit" name="form.submitted" value="Log In" class="btn btn-default">Log In</button> + </div> + </form> + </div> + </div> </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 class="row"> + <div class="copyright"> + Copyright © Pylons Project + </div> </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> -</body> + + + <!-- Bootstrap core JavaScript + ================================================== --> + <!-- Placed at the end of the document so the pages load faster --> + <script src="//oss.maxcdn.com/libs/jquery/1.10.2/jquery.min.js"></script> + <script src="//oss.maxcdn.com/libs/twitter-bootstrap/3.0.3/js/bootstrap.min.js"></script> + </body> </html> diff --git a/docs/tutorials/wiki/src/authorization/tutorial/templates/mytemplate.pt b/docs/tutorials/wiki/src/authorization/tutorial/templates/mytemplate.pt index 13b41f823..1b30f42b6 100644 --- a/docs/tutorials/wiki/src/authorization/tutorial/templates/mytemplate.pt +++ b/docs/tutorials/wiki/src/authorization/tutorial/templates/mytemplate.pt @@ -1,73 +1,66 @@ -<!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 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="/static/favicon.ico" /> - <link rel="stylesheet" href="/static/pylons.css" type="text/css" media="screen" charset="utf-8" /> - <link rel="stylesheet" href="http://static.pylonsproject.org/fonts/nobile/stylesheet.css" media="screen" /> - <link rel="stylesheet" href="http://static.pylonsproject.org/fonts/neuton/stylesheet.css" media="screen" /> - <!--[if lte IE 6]> - <link rel="stylesheet" href="/static/ie6.css" type="text/css" media="screen" charset="utf-8" /> - <![endif]--> -</head> -<body> - <div id="wrap"> - <div id="top"> - <div class="top align-center"> - <div><img src="/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 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/current/search.html"> - <input type="text" id="q" name="q" value="" /> - <input type="submit" id="x" value="Go" /> - </form> +<!DOCTYPE html> +<html lang="${request.locale_name}"> + <head> + <meta charset="utf-8"> + <meta http-equiv="X-UA-Compatible" content="IE=edge"> + <meta name="viewport" content="width=device-width, initial-scale=1.0"> + <meta name="description" content="pyramid web application"> + <meta name="author" content="Pylons Project"> + <link rel="shortcut icon" href="${request.static_url('tutorial:static/pyramid-16x16.png')}"> + + <title>ZODB Scaffold for The Pyramid Web Framework</title> + + <!-- Bootstrap core CSS --> + <link href="//oss.maxcdn.com/libs/twitter-bootstrap/3.0.3/css/bootstrap.min.css" rel="stylesheet"> + + <!-- Custom styles for this scaffold --> + <link href="${request.static_url('tutorial:static/theme.css')}" rel="stylesheet"> + + <!-- HTML5 shim and Respond.js IE8 support of HTML5 elements and media queries --> + <!--[if lt IE 9]> + <script src="//oss.maxcdn.com/libs/html5shiv/3.7.0/html5shiv.js"></script> + <script src="//oss.maxcdn.com/libs/respond.js/1.3.0/respond.min.js"></script> + <![endif]--> + </head> + + <body> + + <div class="starter-template"> + <div class="container"> + <div class="row"> + <div class="col-md-2"> + <img class="logo img-responsive" src="${request.static_url('tutorial:static/pyramid.png')}" alt="pyramid web framework"> + </div> + <div class="col-md-10"> + <div class="content"> + <h1><span class="font-semi-bold">Pyramid</span> <span class="smaller">ZODB scaffold</span></h1> + <p class="lead">Welcome to <span class="font-normal">${project}</span>, an application generated by<br>the <span class="font-normal">Pyramid Web Framework</span>.</p> + </div> + </div> </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/current/#narrative-documentation">Narrative Documentation</a> - </li> - <li> - <a href="http://docs.pylonsproject.org/projects/pyramid/current/#api-documentation">API Documentation</a> - </li> - <li> - <a href="http://docs.pylonsproject.org/projects/pyramid/current/#tutorials">Tutorials</a> - </li> - <li> - <a href="http://docs.pylonsproject.org/projects/pyramid/current/#change-history">Change History</a> - </li> - <li> - <a href="http://docs.pylonsproject.org/projects/pyramid/current/#sample-applications">Sample Applications</a> - </li> - <li> - <a href="http://docs.pylonsproject.org/projects/pyramid/current/#support-and-development">Support and Development</a> - </li> - <li> - <a href="irc://irc.freenode.net#pyramid">IRC Channel</a> - </li> + <div class="row"> + <div class="links"> + <ul> + <li><i class="glyphicon glyphicon-bookmark icon-muted"></i><a href="http://docs.pylonsproject.org/projects/pyramid/en/latest/">Docs</a></li> + <li><i class="glyphicon glyphicon-cog icon-muted"></i><a href="https://github.com/Pylons/pyramid">Github Project</a></li> + <li><i class="glyphicon glyphicon-globe icon-muted"></i><a href="irc://irc.freenode.net#pyramid">IRC Channel</a></li> + <li><i class="glyphicon glyphicon-home icon-muted"></i><a href="http://pylonsproject.org">Pylons Project</a></li> </ul> + </div> + </div> + <div class="row"> + <div class="copyright"> + Copyright © Pylons Project + </div> </div> </div> </div> - </div> -</body> + + + <!-- Bootstrap core JavaScript + ================================================== --> + <!-- Placed at the end of the document so the pages load faster --> + <script src="//oss.maxcdn.com/libs/jquery/1.10.2/jquery.min.js"></script> + <script src="//oss.maxcdn.com/libs/twitter-bootstrap/3.0.3/js/bootstrap.min.js"></script> + </body> </html> diff --git a/docs/tutorials/wiki/src/authorization/tutorial/templates/view.pt b/docs/tutorials/wiki/src/authorization/tutorial/templates/view.pt index 90e20764d..fa35d758d 100644 --- a/docs/tutorials/wiki/src/authorization/tutorial/templates/view.pt +++ b/docs/tutorials/wiki/src/authorization/tutorial/templates/view.pt @@ -1,61 +1,72 @@ -<!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>${page.__name__} - Pyramid tutorial wiki (based on +<!DOCTYPE html> +<html lang="${request.locale_name}"> + <head> + <meta charset="utf-8"> + <meta http-equiv="X-UA-Compatible" content="IE=edge"> + <meta name="viewport" content="width=device-width, initial-scale=1.0"> + <meta name="description" content="pyramid web application"> + <meta name="author" content="Pylons Project"> + <link rel="shortcut icon" href="${request.static_url('tutorial:static/pyramid-16x16.png')}"> + + <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="/static/favicon.ico" /> - <link rel="stylesheet" - href="/static/pylons.css" - type="text/css" media="screen" charset="utf-8" /> - <!--[if lte IE 6]> - <link rel="stylesheet" - href="/static/ie6.css" - type="text/css" media="screen" charset="utf-8" /> - <![endif]--> -</head> -<body> - <div id="wrap"> - <div id="top-small"> - <div class="top-small align-center"> - <div> - <img width="220" height="50" alt="pyramid" - src="/static/pyramid-small.png" /> + + <!-- Bootstrap core CSS --> + <link href="//oss.maxcdn.com/libs/twitter-bootstrap/3.0.3/css/bootstrap.min.css" rel="stylesheet"> + + <!-- Custom styles for this scaffold --> + <link href="${request.static_url('tutorial:static/theme.css')}" rel="stylesheet"> + + <!-- HTML5 shim and Respond.js IE8 support of HTML5 elements and media queries --> + <!--[if lt IE 9]> + <script src="//oss.maxcdn.com/libs/html5shiv/3.7.0/html5shiv.js"></script> + <script src="//oss.maxcdn.com/libs/respond.js/1.3.0/respond.min.js"></script> + <![endif]--> + </head> + <body> + + <div class="starter-template"> + <div class="container"> + <div class="row"> + <div class="col-md-2"> + <img class="logo img-responsive" src="${request.static_url('tutorial:static/pyramid.png')}" alt="pyramid web framework"> + </div> + <div class="col-md-10"> + <div class="content"> + <p tal:condition="logged_in" class="pull-right"> + <a href="${request.application_url}/logout">Logout</a> + </p> + <div tal:replace="structure content"> + Page text goes here. + </div> + <p> + <a tal:attributes="href edit_url" href=""> + Edit this page + </a> + </p> + <p> + Viewing <strong><span tal:replace="page.__name__"> + Page Name Goes Here</span></strong> + </p> + <p>You can return to the + <a href="${request.application_url}">FrontPage</a>. + </p> + </div> + </div> </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 class="row"> + <div class="copyright"> + Copyright © Pylons Project + </div> </div> - <p> - <a tal:attributes="href edit_url" href=""> - Edit this page - </a> - </p> </div> </div> - </div> -</body> + + + <!-- Bootstrap core JavaScript + ================================================== --> + <!-- Placed at the end of the document so the pages load faster --> + <script src="//oss.maxcdn.com/libs/jquery/1.10.2/jquery.min.js"></script> + <script src="//oss.maxcdn.com/libs/twitter-bootstrap/3.0.3/js/bootstrap.min.js"></script> + </body> </html> diff --git a/docs/tutorials/wiki/src/basiclayout/setup.py b/docs/tutorials/wiki/src/basiclayout/setup.py index da79881ab..58a454f80 100644 --- a/docs/tutorials/wiki/src/basiclayout/setup.py +++ b/docs/tutorials/wiki/src/basiclayout/setup.py @@ -11,10 +11,10 @@ with open(os.path.join(here, 'CHANGES.txt')) as f: requires = [ 'pyramid', 'pyramid_chameleon', + 'pyramid_debugtoolbar', + 'pyramid_tm', 'pyramid_zodbconn', 'transaction', - 'pyramid_tm', - 'pyramid_debugtoolbar', 'ZODB3', 'waitress', ] diff --git a/docs/tutorials/wiki/src/basiclayout/tutorial/static/favicon.ico b/docs/tutorials/wiki/src/basiclayout/tutorial/static/favicon.ico Binary files differdeleted file mode 100644 index 71f837c9e..000000000 --- a/docs/tutorials/wiki/src/basiclayout/tutorial/static/favicon.ico +++ /dev/null diff --git a/docs/tutorials/wiki/src/basiclayout/tutorial/static/footerbg.png b/docs/tutorials/wiki/src/basiclayout/tutorial/static/footerbg.png Binary files differdeleted file mode 100644 index 1fbc873da..000000000 --- a/docs/tutorials/wiki/src/basiclayout/tutorial/static/footerbg.png +++ /dev/null diff --git a/docs/tutorials/wiki/src/basiclayout/tutorial/static/headerbg.png b/docs/tutorials/wiki/src/basiclayout/tutorial/static/headerbg.png Binary files differdeleted file mode 100644 index 0596f2020..000000000 --- a/docs/tutorials/wiki/src/basiclayout/tutorial/static/headerbg.png +++ /dev/null diff --git a/docs/tutorials/wiki/src/basiclayout/tutorial/static/ie6.css b/docs/tutorials/wiki/src/basiclayout/tutorial/static/ie6.css deleted file mode 100644 index b7c8493d8..000000000 --- a/docs/tutorials/wiki/src/basiclayout/tutorial/static/ie6.css +++ /dev/null @@ -1,8 +0,0 @@ -* 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/wiki/src/basiclayout/tutorial/static/middlebg.png b/docs/tutorials/wiki/src/basiclayout/tutorial/static/middlebg.png Binary files differdeleted file mode 100644 index 2369cfb7d..000000000 --- a/docs/tutorials/wiki/src/basiclayout/tutorial/static/middlebg.png +++ /dev/null diff --git a/docs/tutorials/wiki/src/basiclayout/tutorial/static/pylons.css b/docs/tutorials/wiki/src/basiclayout/tutorial/static/pylons.css deleted file mode 100644 index 4b1c017cd..000000000 --- a/docs/tutorials/wiki/src/basiclayout/tutorial/static/pylons.css +++ /dev/null @@ -1,372 +0,0 @@ -html, body, div, span, applet, object, iframe, h1, h2, h3, h4, h5, h6, p, blockquote, pre, a, abbr, acronym, address, big, cite, code, del, dfn, em, font, img, ins, kbd, q, s, samp, small, strike, strong, sub, sup, tt, var, b, u, i, center, dl, dt, dd, ol, ul, li, fieldset, form, label, legend, table, caption, tbody, tfoot, thead, tr, th, td -{ - margin: 0; - padding: 0; - border: 0; - outline: 0; - font-size: 100%; /* 16px */ - vertical-align: baseline; - background: transparent; -} - -body -{ - line-height: 1; -} - -ol, ul -{ - list-style: none; -} - -blockquote, q -{ - quotes: none; -} - -blockquote:before, blockquote:after, q:before, q:after -{ - content: ''; - content: none; -} - -:focus -{ - outline: 0; -} - -ins -{ - text-decoration: none; -} - -del -{ - text-decoration: line-through; -} - -table -{ - border-collapse: collapse; - border-spacing: 0; -} - -sub -{ - vertical-align: sub; - font-size: smaller; - line-height: normal; -} - -sup -{ - vertical-align: super; - font-size: smaller; - line-height: normal; -} - -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; -} - -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; -} - -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; -} - -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; - 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: #fff; - position: relative; - font: 16px/24px NobileRegular, "Lucida Grande", Lucida, Verdana, sans-serif; -} - -a -{ - color: #1b61d6; - text-decoration: none; -} - -a:hover -{ - color: #e88f00; - text-decoration: underline; -} - -body h1, body h2, body h3, body h4, body h5, body h6 -{ - font-family: NeutonRegular, "Lucida Grande", Lucida, Verdana, sans-serif; - font-weight: 400; - color: #373839; - font-style: normal; -} - -#wrap -{ - min-height: 100%; -} - -#header, #footer -{ - width: 100%; - color: #fff; - height: 40px; - position: absolute; - text-align: center; - line-height: 40px; - overflow: hidden; - font-size: 12px; - vertical-align: middle; -} - -#header -{ - background: #000; - top: 0; - font-size: 14px; -} - -#footer -{ - bottom: 0; - background: #000 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, #top-small, #bottom -{ - width: 100%; -} - -#top -{ - color: #000; - height: 230px; - background: #fff url(headerbg.png) repeat-x 0 top; - position: relative; -} - -#top-small -{ - color: #000; - height: 60px; - background: #fff url(headerbg.png) repeat-x 0 top; - position: relative; -} - -#bottom -{ - color: #222; - background-color: #fff; -} - -.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 #fff; - border-bottom: 2px solid #b2b2b2; -} - -.app-welcome -{ - margin-top: 25px; -} - -.app-name -{ - color: #000; - font-weight: 700; -} - -.bottom -{ - padding-top: 50px; -} - -#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; -} - -ul.links -{ - margin: 0; - padding: 0; -} - -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=password] -{ - width: 205px; -} - -input[type=submit] -{ - background-color: #ddd; - font-weight: 700; -} - -/*Opera Fix*/ -body:before -{ - content: ""; - height: 100%; - float: left; - width: 0; - margin-top: -32767px; -} diff --git a/docs/tutorials/wiki/src/basiclayout/tutorial/static/pyramid-16x16.png b/docs/tutorials/wiki/src/basiclayout/tutorial/static/pyramid-16x16.png Binary files differnew file mode 100644 index 000000000..979203112 --- /dev/null +++ b/docs/tutorials/wiki/src/basiclayout/tutorial/static/pyramid-16x16.png diff --git a/docs/tutorials/wiki/src/basiclayout/tutorial/static/pyramid-small.png b/docs/tutorials/wiki/src/basiclayout/tutorial/static/pyramid-small.png Binary files differdeleted file mode 100644 index a5bc0ade7..000000000 --- a/docs/tutorials/wiki/src/basiclayout/tutorial/static/pyramid-small.png +++ /dev/null diff --git a/docs/tutorials/wiki/src/basiclayout/tutorial/static/pyramid.png b/docs/tutorials/wiki/src/basiclayout/tutorial/static/pyramid.png Binary files differindex 347e05549..4ab837be9 100644 --- a/docs/tutorials/wiki/src/basiclayout/tutorial/static/pyramid.png +++ b/docs/tutorials/wiki/src/basiclayout/tutorial/static/pyramid.png diff --git a/docs/tutorials/wiki/src/basiclayout/tutorial/static/theme.css b/docs/tutorials/wiki/src/basiclayout/tutorial/static/theme.css new file mode 100644 index 000000000..0f4b1a4d4 --- /dev/null +++ b/docs/tutorials/wiki/src/basiclayout/tutorial/static/theme.css @@ -0,0 +1,154 @@ +@import url(//fonts.googleapis.com/css?family=Open+Sans:300,400,600,700); +body { + font-family: "Open Sans", "Helvetica Neue", Helvetica, Arial, sans-serif; + font-weight: 300; + color: #ffffff; + background: #bc2131; +} +h1, +h2, +h3, +h4, +h5, +h6 { + font-family: "Open Sans", "Helvetica Neue", Helvetica, Arial, sans-serif; + font-weight: 300; +} +p { + font-weight: 300; +} +.font-normal { + font-weight: 400; +} +.font-semi-bold { + font-weight: 600; +} +.font-bold { + font-weight: 700; +} +.starter-template { + margin-top: 250px; +} +.starter-template .content { + margin-left: 10px; +} +.starter-template .content h1 { + margin-top: 10px; + font-size: 60px; +} +.starter-template .content h1 .smaller { + font-size: 40px; + color: #f2b7bd; +} +.starter-template .content .lead { + font-size: 25px; + color: #f2b7bd; +} +.starter-template .content .lead .font-normal { + color: #ffffff; +} +.starter-template .links { + float: right; + right: 0; + margin-top: 125px; +} +.starter-template .links ul { + display: block; + padding: 0; + margin: 0; +} +.starter-template .links ul li { + list-style: none; + display: inline; + margin: 0 10px; +} +.starter-template .links ul li:first-child { + margin-left: 0; +} +.starter-template .links ul li:last-child { + margin-right: 0; +} +.starter-template .links ul li.current-version { + color: #f2b7bd; + font-weight: 400; +} +.starter-template .links ul li a, a { + color: #f2b7bd; + text-decoration: underline; +} +.starter-template .links ul li a:hover, a:hover { + color: #ffffff; + text-decoration: underline; +} +.starter-template .links ul li .icon-muted { + color: #eb8b95; + margin-right: 5px; +} +.starter-template .links ul li:hover .icon-muted { + color: #ffffff; +} +.starter-template .copyright { + margin-top: 10px; + font-size: 0.9em; + color: #f2b7bd; + text-transform: lowercase; + float: right; + right: 0; +} +@media (max-width: 1199px) { + .starter-template .content h1 { + font-size: 45px; + } + .starter-template .content h1 .smaller { + font-size: 30px; + } + .starter-template .content .lead { + font-size: 20px; + } +} +@media (max-width: 991px) { + .starter-template { + margin-top: 0; + } + .starter-template .logo { + margin: 40px auto; + } + .starter-template .content { + margin-left: 0; + text-align: center; + } + .starter-template .content h1 { + margin-bottom: 20px; + } + .starter-template .links { + float: none; + text-align: center; + margin-top: 60px; + } + .starter-template .copyright { + float: none; + text-align: center; + } +} +@media (max-width: 767px) { + .starter-template .content h1 .smaller { + font-size: 25px; + display: block; + } + .starter-template .content .lead { + font-size: 16px; + } + .starter-template .links { + margin-top: 40px; + } + .starter-template .links ul li { + display: block; + margin: 0; + } + .starter-template .links ul li .icon-muted { + display: none; + } + .starter-template .copyright { + margin-top: 20px; + } +} diff --git a/docs/tutorials/wiki/src/basiclayout/tutorial/static/theme.min.css b/docs/tutorials/wiki/src/basiclayout/tutorial/static/theme.min.css new file mode 100644 index 000000000..2f924bcc5 --- /dev/null +++ b/docs/tutorials/wiki/src/basiclayout/tutorial/static/theme.min.css @@ -0,0 +1 @@ +@import url(//fonts.googleapis.com/css?family=Open+Sans:300,400,600,700);body{font-family:"Open Sans","Helvetica Neue",Helvetica,Arial,sans-serif;font-weight:300;color:#fff;background:#bc2131}h1,h2,h3,h4,h5,h6{font-family:"Open Sans","Helvetica Neue",Helvetica,Arial,sans-serif;font-weight:300}p{font-weight:300}.font-normal{font-weight:400}.font-semi-bold{font-weight:600}.font-bold{font-weight:700}.starter-template{margin-top:250px}.starter-template .content{margin-left:10px}.starter-template .content h1{margin-top:10px;font-size:60px}.starter-template .content h1 .smaller{font-size:40px;color:#f2b7bd}.starter-template .content .lead{font-size:25px;color:#f2b7bd}.starter-template .content .lead .font-normal{color:#fff}.starter-template .links{float:right;right:0;margin-top:125px}.starter-template .links ul{display:block;padding:0;margin:0}.starter-template .links ul li{list-style:none;display:inline;margin:0 10px}.starter-template .links ul li:first-child{margin-left:0}.starter-template .links ul li:last-child{margin-right:0}.starter-template .links ul li.current-version{color:#f2b7bd;font-weight:400}.starter-template .links ul li a{color:#fff}.starter-template .links ul li a:hover{text-decoration:underline}.starter-template .links ul li .icon-muted{color:#eb8b95;margin-right:5px}.starter-template .links ul li:hover .icon-muted{color:#fff}.starter-template .copyright{margin-top:10px;font-size:.9em;color:#f2b7bd;text-transform:lowercase;float:right;right:0}@media (max-width:1199px){.starter-template .content h1{font-size:45px}.starter-template .content h1 .smaller{font-size:30px}.starter-template .content .lead{font-size:20px}}@media (max-width:991px){.starter-template{margin-top:0}.starter-template .logo{margin:40px auto}.starter-template .content{margin-left:0;text-align:center}.starter-template .content h1{margin-bottom:20px}.starter-template .links{float:none;text-align:center;margin-top:60px}.starter-template .copyright{float:none;text-align:center}}@media (max-width:767px){.starter-template .content h1 .smaller{font-size:25px;display:block}.starter-template .content .lead{font-size:16px}.starter-template .links{margin-top:40px}.starter-template .links ul li{display:block;margin:0}.starter-template .links ul li .icon-muted{display:none}.starter-template .copyright{margin-top:20px}}
\ No newline at end of file diff --git a/docs/tutorials/wiki/src/basiclayout/tutorial/static/transparent.gif b/docs/tutorials/wiki/src/basiclayout/tutorial/static/transparent.gif Binary files differdeleted file mode 100644 index 0341802e5..000000000 --- a/docs/tutorials/wiki/src/basiclayout/tutorial/static/transparent.gif +++ /dev/null diff --git a/docs/tutorials/wiki/src/basiclayout/tutorial/templates/mytemplate.pt b/docs/tutorials/wiki/src/basiclayout/tutorial/templates/mytemplate.pt index 13b41f823..1b30f42b6 100644 --- a/docs/tutorials/wiki/src/basiclayout/tutorial/templates/mytemplate.pt +++ b/docs/tutorials/wiki/src/basiclayout/tutorial/templates/mytemplate.pt @@ -1,73 +1,66 @@ -<!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 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="/static/favicon.ico" /> - <link rel="stylesheet" href="/static/pylons.css" type="text/css" media="screen" charset="utf-8" /> - <link rel="stylesheet" href="http://static.pylonsproject.org/fonts/nobile/stylesheet.css" media="screen" /> - <link rel="stylesheet" href="http://static.pylonsproject.org/fonts/neuton/stylesheet.css" media="screen" /> - <!--[if lte IE 6]> - <link rel="stylesheet" href="/static/ie6.css" type="text/css" media="screen" charset="utf-8" /> - <![endif]--> -</head> -<body> - <div id="wrap"> - <div id="top"> - <div class="top align-center"> - <div><img src="/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 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/current/search.html"> - <input type="text" id="q" name="q" value="" /> - <input type="submit" id="x" value="Go" /> - </form> +<!DOCTYPE html> +<html lang="${request.locale_name}"> + <head> + <meta charset="utf-8"> + <meta http-equiv="X-UA-Compatible" content="IE=edge"> + <meta name="viewport" content="width=device-width, initial-scale=1.0"> + <meta name="description" content="pyramid web application"> + <meta name="author" content="Pylons Project"> + <link rel="shortcut icon" href="${request.static_url('tutorial:static/pyramid-16x16.png')}"> + + <title>ZODB Scaffold for The Pyramid Web Framework</title> + + <!-- Bootstrap core CSS --> + <link href="//oss.maxcdn.com/libs/twitter-bootstrap/3.0.3/css/bootstrap.min.css" rel="stylesheet"> + + <!-- Custom styles for this scaffold --> + <link href="${request.static_url('tutorial:static/theme.css')}" rel="stylesheet"> + + <!-- HTML5 shim and Respond.js IE8 support of HTML5 elements and media queries --> + <!--[if lt IE 9]> + <script src="//oss.maxcdn.com/libs/html5shiv/3.7.0/html5shiv.js"></script> + <script src="//oss.maxcdn.com/libs/respond.js/1.3.0/respond.min.js"></script> + <![endif]--> + </head> + + <body> + + <div class="starter-template"> + <div class="container"> + <div class="row"> + <div class="col-md-2"> + <img class="logo img-responsive" src="${request.static_url('tutorial:static/pyramid.png')}" alt="pyramid web framework"> + </div> + <div class="col-md-10"> + <div class="content"> + <h1><span class="font-semi-bold">Pyramid</span> <span class="smaller">ZODB scaffold</span></h1> + <p class="lead">Welcome to <span class="font-normal">${project}</span>, an application generated by<br>the <span class="font-normal">Pyramid Web Framework</span>.</p> + </div> + </div> </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/current/#narrative-documentation">Narrative Documentation</a> - </li> - <li> - <a href="http://docs.pylonsproject.org/projects/pyramid/current/#api-documentation">API Documentation</a> - </li> - <li> - <a href="http://docs.pylonsproject.org/projects/pyramid/current/#tutorials">Tutorials</a> - </li> - <li> - <a href="http://docs.pylonsproject.org/projects/pyramid/current/#change-history">Change History</a> - </li> - <li> - <a href="http://docs.pylonsproject.org/projects/pyramid/current/#sample-applications">Sample Applications</a> - </li> - <li> - <a href="http://docs.pylonsproject.org/projects/pyramid/current/#support-and-development">Support and Development</a> - </li> - <li> - <a href="irc://irc.freenode.net#pyramid">IRC Channel</a> - </li> + <div class="row"> + <div class="links"> + <ul> + <li><i class="glyphicon glyphicon-bookmark icon-muted"></i><a href="http://docs.pylonsproject.org/projects/pyramid/en/latest/">Docs</a></li> + <li><i class="glyphicon glyphicon-cog icon-muted"></i><a href="https://github.com/Pylons/pyramid">Github Project</a></li> + <li><i class="glyphicon glyphicon-globe icon-muted"></i><a href="irc://irc.freenode.net#pyramid">IRC Channel</a></li> + <li><i class="glyphicon glyphicon-home icon-muted"></i><a href="http://pylonsproject.org">Pylons Project</a></li> </ul> + </div> + </div> + <div class="row"> + <div class="copyright"> + Copyright © Pylons Project + </div> </div> </div> </div> - </div> -</body> + + + <!-- Bootstrap core JavaScript + ================================================== --> + <!-- Placed at the end of the document so the pages load faster --> + <script src="//oss.maxcdn.com/libs/jquery/1.10.2/jquery.min.js"></script> + <script src="//oss.maxcdn.com/libs/twitter-bootstrap/3.0.3/js/bootstrap.min.js"></script> + </body> </html> diff --git a/docs/tutorials/wiki/src/models/setup.py b/docs/tutorials/wiki/src/models/setup.py index da79881ab..58a454f80 100644 --- a/docs/tutorials/wiki/src/models/setup.py +++ b/docs/tutorials/wiki/src/models/setup.py @@ -11,10 +11,10 @@ with open(os.path.join(here, 'CHANGES.txt')) as f: requires = [ 'pyramid', 'pyramid_chameleon', + 'pyramid_debugtoolbar', + 'pyramid_tm', 'pyramid_zodbconn', 'transaction', - 'pyramid_tm', - 'pyramid_debugtoolbar', 'ZODB3', 'waitress', ] diff --git a/docs/tutorials/wiki/src/models/tutorial/static/favicon.ico b/docs/tutorials/wiki/src/models/tutorial/static/favicon.ico Binary files differdeleted file mode 100644 index 71f837c9e..000000000 --- a/docs/tutorials/wiki/src/models/tutorial/static/favicon.ico +++ /dev/null diff --git a/docs/tutorials/wiki/src/models/tutorial/static/footerbg.png b/docs/tutorials/wiki/src/models/tutorial/static/footerbg.png Binary files differdeleted file mode 100644 index 1fbc873da..000000000 --- a/docs/tutorials/wiki/src/models/tutorial/static/footerbg.png +++ /dev/null diff --git a/docs/tutorials/wiki/src/models/tutorial/static/headerbg.png b/docs/tutorials/wiki/src/models/tutorial/static/headerbg.png Binary files differdeleted file mode 100644 index 0596f2020..000000000 --- a/docs/tutorials/wiki/src/models/tutorial/static/headerbg.png +++ /dev/null diff --git a/docs/tutorials/wiki/src/models/tutorial/static/ie6.css b/docs/tutorials/wiki/src/models/tutorial/static/ie6.css deleted file mode 100644 index b7c8493d8..000000000 --- a/docs/tutorials/wiki/src/models/tutorial/static/ie6.css +++ /dev/null @@ -1,8 +0,0 @@ -* 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/wiki/src/models/tutorial/static/middlebg.png b/docs/tutorials/wiki/src/models/tutorial/static/middlebg.png Binary files differdeleted file mode 100644 index 2369cfb7d..000000000 --- a/docs/tutorials/wiki/src/models/tutorial/static/middlebg.png +++ /dev/null diff --git a/docs/tutorials/wiki/src/models/tutorial/static/pylons.css b/docs/tutorials/wiki/src/models/tutorial/static/pylons.css deleted file mode 100644 index 4b1c017cd..000000000 --- a/docs/tutorials/wiki/src/models/tutorial/static/pylons.css +++ /dev/null @@ -1,372 +0,0 @@ -html, body, div, span, applet, object, iframe, h1, h2, h3, h4, h5, h6, p, blockquote, pre, a, abbr, acronym, address, big, cite, code, del, dfn, em, font, img, ins, kbd, q, s, samp, small, strike, strong, sub, sup, tt, var, b, u, i, center, dl, dt, dd, ol, ul, li, fieldset, form, label, legend, table, caption, tbody, tfoot, thead, tr, th, td -{ - margin: 0; - padding: 0; - border: 0; - outline: 0; - font-size: 100%; /* 16px */ - vertical-align: baseline; - background: transparent; -} - -body -{ - line-height: 1; -} - -ol, ul -{ - list-style: none; -} - -blockquote, q -{ - quotes: none; -} - -blockquote:before, blockquote:after, q:before, q:after -{ - content: ''; - content: none; -} - -:focus -{ - outline: 0; -} - -ins -{ - text-decoration: none; -} - -del -{ - text-decoration: line-through; -} - -table -{ - border-collapse: collapse; - border-spacing: 0; -} - -sub -{ - vertical-align: sub; - font-size: smaller; - line-height: normal; -} - -sup -{ - vertical-align: super; - font-size: smaller; - line-height: normal; -} - -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; -} - -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; -} - -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; -} - -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; - 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: #fff; - position: relative; - font: 16px/24px NobileRegular, "Lucida Grande", Lucida, Verdana, sans-serif; -} - -a -{ - color: #1b61d6; - text-decoration: none; -} - -a:hover -{ - color: #e88f00; - text-decoration: underline; -} - -body h1, body h2, body h3, body h4, body h5, body h6 -{ - font-family: NeutonRegular, "Lucida Grande", Lucida, Verdana, sans-serif; - font-weight: 400; - color: #373839; - font-style: normal; -} - -#wrap -{ - min-height: 100%; -} - -#header, #footer -{ - width: 100%; - color: #fff; - height: 40px; - position: absolute; - text-align: center; - line-height: 40px; - overflow: hidden; - font-size: 12px; - vertical-align: middle; -} - -#header -{ - background: #000; - top: 0; - font-size: 14px; -} - -#footer -{ - bottom: 0; - background: #000 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, #top-small, #bottom -{ - width: 100%; -} - -#top -{ - color: #000; - height: 230px; - background: #fff url(headerbg.png) repeat-x 0 top; - position: relative; -} - -#top-small -{ - color: #000; - height: 60px; - background: #fff url(headerbg.png) repeat-x 0 top; - position: relative; -} - -#bottom -{ - color: #222; - background-color: #fff; -} - -.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 #fff; - border-bottom: 2px solid #b2b2b2; -} - -.app-welcome -{ - margin-top: 25px; -} - -.app-name -{ - color: #000; - font-weight: 700; -} - -.bottom -{ - padding-top: 50px; -} - -#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; -} - -ul.links -{ - margin: 0; - padding: 0; -} - -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=password] -{ - width: 205px; -} - -input[type=submit] -{ - background-color: #ddd; - font-weight: 700; -} - -/*Opera Fix*/ -body:before -{ - content: ""; - height: 100%; - float: left; - width: 0; - margin-top: -32767px; -} diff --git a/docs/tutorials/wiki/src/models/tutorial/static/pyramid-16x16.png b/docs/tutorials/wiki/src/models/tutorial/static/pyramid-16x16.png Binary files differnew file mode 100644 index 000000000..979203112 --- /dev/null +++ b/docs/tutorials/wiki/src/models/tutorial/static/pyramid-16x16.png diff --git a/docs/tutorials/wiki/src/models/tutorial/static/pyramid-small.png b/docs/tutorials/wiki/src/models/tutorial/static/pyramid-small.png Binary files differdeleted file mode 100644 index a5bc0ade7..000000000 --- a/docs/tutorials/wiki/src/models/tutorial/static/pyramid-small.png +++ /dev/null diff --git a/docs/tutorials/wiki/src/models/tutorial/static/pyramid.png b/docs/tutorials/wiki/src/models/tutorial/static/pyramid.png Binary files differindex 347e05549..4ab837be9 100644 --- a/docs/tutorials/wiki/src/models/tutorial/static/pyramid.png +++ b/docs/tutorials/wiki/src/models/tutorial/static/pyramid.png diff --git a/docs/tutorials/wiki/src/models/tutorial/static/theme.css b/docs/tutorials/wiki/src/models/tutorial/static/theme.css new file mode 100644 index 000000000..0f4b1a4d4 --- /dev/null +++ b/docs/tutorials/wiki/src/models/tutorial/static/theme.css @@ -0,0 +1,154 @@ +@import url(//fonts.googleapis.com/css?family=Open+Sans:300,400,600,700); +body { + font-family: "Open Sans", "Helvetica Neue", Helvetica, Arial, sans-serif; + font-weight: 300; + color: #ffffff; + background: #bc2131; +} +h1, +h2, +h3, +h4, +h5, +h6 { + font-family: "Open Sans", "Helvetica Neue", Helvetica, Arial, sans-serif; + font-weight: 300; +} +p { + font-weight: 300; +} +.font-normal { + font-weight: 400; +} +.font-semi-bold { + font-weight: 600; +} +.font-bold { + font-weight: 700; +} +.starter-template { + margin-top: 250px; +} +.starter-template .content { + margin-left: 10px; +} +.starter-template .content h1 { + margin-top: 10px; + font-size: 60px; +} +.starter-template .content h1 .smaller { + font-size: 40px; + color: #f2b7bd; +} +.starter-template .content .lead { + font-size: 25px; + color: #f2b7bd; +} +.starter-template .content .lead .font-normal { + color: #ffffff; +} +.starter-template .links { + float: right; + right: 0; + margin-top: 125px; +} +.starter-template .links ul { + display: block; + padding: 0; + margin: 0; +} +.starter-template .links ul li { + list-style: none; + display: inline; + margin: 0 10px; +} +.starter-template .links ul li:first-child { + margin-left: 0; +} +.starter-template .links ul li:last-child { + margin-right: 0; +} +.starter-template .links ul li.current-version { + color: #f2b7bd; + font-weight: 400; +} +.starter-template .links ul li a, a { + color: #f2b7bd; + text-decoration: underline; +} +.starter-template .links ul li a:hover, a:hover { + color: #ffffff; + text-decoration: underline; +} +.starter-template .links ul li .icon-muted { + color: #eb8b95; + margin-right: 5px; +} +.starter-template .links ul li:hover .icon-muted { + color: #ffffff; +} +.starter-template .copyright { + margin-top: 10px; + font-size: 0.9em; + color: #f2b7bd; + text-transform: lowercase; + float: right; + right: 0; +} +@media (max-width: 1199px) { + .starter-template .content h1 { + font-size: 45px; + } + .starter-template .content h1 .smaller { + font-size: 30px; + } + .starter-template .content .lead { + font-size: 20px; + } +} +@media (max-width: 991px) { + .starter-template { + margin-top: 0; + } + .starter-template .logo { + margin: 40px auto; + } + .starter-template .content { + margin-left: 0; + text-align: center; + } + .starter-template .content h1 { + margin-bottom: 20px; + } + .starter-template .links { + float: none; + text-align: center; + margin-top: 60px; + } + .starter-template .copyright { + float: none; + text-align: center; + } +} +@media (max-width: 767px) { + .starter-template .content h1 .smaller { + font-size: 25px; + display: block; + } + .starter-template .content .lead { + font-size: 16px; + } + .starter-template .links { + margin-top: 40px; + } + .starter-template .links ul li { + display: block; + margin: 0; + } + .starter-template .links ul li .icon-muted { + display: none; + } + .starter-template .copyright { + margin-top: 20px; + } +} diff --git a/docs/tutorials/wiki/src/models/tutorial/static/theme.min.css b/docs/tutorials/wiki/src/models/tutorial/static/theme.min.css new file mode 100644 index 000000000..2f924bcc5 --- /dev/null +++ b/docs/tutorials/wiki/src/models/tutorial/static/theme.min.css @@ -0,0 +1 @@ +@import url(//fonts.googleapis.com/css?family=Open+Sans:300,400,600,700);body{font-family:"Open Sans","Helvetica Neue",Helvetica,Arial,sans-serif;font-weight:300;color:#fff;background:#bc2131}h1,h2,h3,h4,h5,h6{font-family:"Open Sans","Helvetica Neue",Helvetica,Arial,sans-serif;font-weight:300}p{font-weight:300}.font-normal{font-weight:400}.font-semi-bold{font-weight:600}.font-bold{font-weight:700}.starter-template{margin-top:250px}.starter-template .content{margin-left:10px}.starter-template .content h1{margin-top:10px;font-size:60px}.starter-template .content h1 .smaller{font-size:40px;color:#f2b7bd}.starter-template .content .lead{font-size:25px;color:#f2b7bd}.starter-template .content .lead .font-normal{color:#fff}.starter-template .links{float:right;right:0;margin-top:125px}.starter-template .links ul{display:block;padding:0;margin:0}.starter-template .links ul li{list-style:none;display:inline;margin:0 10px}.starter-template .links ul li:first-child{margin-left:0}.starter-template .links ul li:last-child{margin-right:0}.starter-template .links ul li.current-version{color:#f2b7bd;font-weight:400}.starter-template .links ul li a{color:#fff}.starter-template .links ul li a:hover{text-decoration:underline}.starter-template .links ul li .icon-muted{color:#eb8b95;margin-right:5px}.starter-template .links ul li:hover .icon-muted{color:#fff}.starter-template .copyright{margin-top:10px;font-size:.9em;color:#f2b7bd;text-transform:lowercase;float:right;right:0}@media (max-width:1199px){.starter-template .content h1{font-size:45px}.starter-template .content h1 .smaller{font-size:30px}.starter-template .content .lead{font-size:20px}}@media (max-width:991px){.starter-template{margin-top:0}.starter-template .logo{margin:40px auto}.starter-template .content{margin-left:0;text-align:center}.starter-template .content h1{margin-bottom:20px}.starter-template .links{float:none;text-align:center;margin-top:60px}.starter-template .copyright{float:none;text-align:center}}@media (max-width:767px){.starter-template .content h1 .smaller{font-size:25px;display:block}.starter-template .content .lead{font-size:16px}.starter-template .links{margin-top:40px}.starter-template .links ul li{display:block;margin:0}.starter-template .links ul li .icon-muted{display:none}.starter-template .copyright{margin-top:20px}}
\ No newline at end of file diff --git a/docs/tutorials/wiki/src/models/tutorial/static/transparent.gif b/docs/tutorials/wiki/src/models/tutorial/static/transparent.gif Binary files differdeleted file mode 100644 index 0341802e5..000000000 --- a/docs/tutorials/wiki/src/models/tutorial/static/transparent.gif +++ /dev/null diff --git a/docs/tutorials/wiki/src/models/tutorial/templates/mytemplate.pt b/docs/tutorials/wiki/src/models/tutorial/templates/mytemplate.pt index 13b41f823..1b30f42b6 100644 --- a/docs/tutorials/wiki/src/models/tutorial/templates/mytemplate.pt +++ b/docs/tutorials/wiki/src/models/tutorial/templates/mytemplate.pt @@ -1,73 +1,66 @@ -<!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 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="/static/favicon.ico" /> - <link rel="stylesheet" href="/static/pylons.css" type="text/css" media="screen" charset="utf-8" /> - <link rel="stylesheet" href="http://static.pylonsproject.org/fonts/nobile/stylesheet.css" media="screen" /> - <link rel="stylesheet" href="http://static.pylonsproject.org/fonts/neuton/stylesheet.css" media="screen" /> - <!--[if lte IE 6]> - <link rel="stylesheet" href="/static/ie6.css" type="text/css" media="screen" charset="utf-8" /> - <![endif]--> -</head> -<body> - <div id="wrap"> - <div id="top"> - <div class="top align-center"> - <div><img src="/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 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/current/search.html"> - <input type="text" id="q" name="q" value="" /> - <input type="submit" id="x" value="Go" /> - </form> +<!DOCTYPE html> +<html lang="${request.locale_name}"> + <head> + <meta charset="utf-8"> + <meta http-equiv="X-UA-Compatible" content="IE=edge"> + <meta name="viewport" content="width=device-width, initial-scale=1.0"> + <meta name="description" content="pyramid web application"> + <meta name="author" content="Pylons Project"> + <link rel="shortcut icon" href="${request.static_url('tutorial:static/pyramid-16x16.png')}"> + + <title>ZODB Scaffold for The Pyramid Web Framework</title> + + <!-- Bootstrap core CSS --> + <link href="//oss.maxcdn.com/libs/twitter-bootstrap/3.0.3/css/bootstrap.min.css" rel="stylesheet"> + + <!-- Custom styles for this scaffold --> + <link href="${request.static_url('tutorial:static/theme.css')}" rel="stylesheet"> + + <!-- HTML5 shim and Respond.js IE8 support of HTML5 elements and media queries --> + <!--[if lt IE 9]> + <script src="//oss.maxcdn.com/libs/html5shiv/3.7.0/html5shiv.js"></script> + <script src="//oss.maxcdn.com/libs/respond.js/1.3.0/respond.min.js"></script> + <![endif]--> + </head> + + <body> + + <div class="starter-template"> + <div class="container"> + <div class="row"> + <div class="col-md-2"> + <img class="logo img-responsive" src="${request.static_url('tutorial:static/pyramid.png')}" alt="pyramid web framework"> + </div> + <div class="col-md-10"> + <div class="content"> + <h1><span class="font-semi-bold">Pyramid</span> <span class="smaller">ZODB scaffold</span></h1> + <p class="lead">Welcome to <span class="font-normal">${project}</span>, an application generated by<br>the <span class="font-normal">Pyramid Web Framework</span>.</p> + </div> + </div> </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/current/#narrative-documentation">Narrative Documentation</a> - </li> - <li> - <a href="http://docs.pylonsproject.org/projects/pyramid/current/#api-documentation">API Documentation</a> - </li> - <li> - <a href="http://docs.pylonsproject.org/projects/pyramid/current/#tutorials">Tutorials</a> - </li> - <li> - <a href="http://docs.pylonsproject.org/projects/pyramid/current/#change-history">Change History</a> - </li> - <li> - <a href="http://docs.pylonsproject.org/projects/pyramid/current/#sample-applications">Sample Applications</a> - </li> - <li> - <a href="http://docs.pylonsproject.org/projects/pyramid/current/#support-and-development">Support and Development</a> - </li> - <li> - <a href="irc://irc.freenode.net#pyramid">IRC Channel</a> - </li> + <div class="row"> + <div class="links"> + <ul> + <li><i class="glyphicon glyphicon-bookmark icon-muted"></i><a href="http://docs.pylonsproject.org/projects/pyramid/en/latest/">Docs</a></li> + <li><i class="glyphicon glyphicon-cog icon-muted"></i><a href="https://github.com/Pylons/pyramid">Github Project</a></li> + <li><i class="glyphicon glyphicon-globe icon-muted"></i><a href="irc://irc.freenode.net#pyramid">IRC Channel</a></li> + <li><i class="glyphicon glyphicon-home icon-muted"></i><a href="http://pylonsproject.org">Pylons Project</a></li> </ul> + </div> + </div> + <div class="row"> + <div class="copyright"> + Copyright © Pylons Project + </div> </div> </div> </div> - </div> -</body> + + + <!-- Bootstrap core JavaScript + ================================================== --> + <!-- Placed at the end of the document so the pages load faster --> + <script src="//oss.maxcdn.com/libs/jquery/1.10.2/jquery.min.js"></script> + <script src="//oss.maxcdn.com/libs/twitter-bootstrap/3.0.3/js/bootstrap.min.js"></script> + </body> </html> diff --git a/docs/tutorials/wiki/src/tests/setup.py b/docs/tutorials/wiki/src/tests/setup.py index 2e7ed2398..b67b702cf 100644 --- a/docs/tutorials/wiki/src/tests/setup.py +++ b/docs/tutorials/wiki/src/tests/setup.py @@ -11,10 +11,10 @@ with open(os.path.join(here, 'CHANGES.txt')) as f: requires = [ 'pyramid', 'pyramid_chameleon', + 'pyramid_debugtoolbar', + 'pyramid_tm', 'pyramid_zodbconn', 'transaction', - 'pyramid_tm', - 'pyramid_debugtoolbar', 'ZODB3', 'waitress', 'docutils', diff --git a/docs/tutorials/wiki/src/tests/tutorial/static/favicon.ico b/docs/tutorials/wiki/src/tests/tutorial/static/favicon.ico Binary files differdeleted file mode 100644 index 71f837c9e..000000000 --- a/docs/tutorials/wiki/src/tests/tutorial/static/favicon.ico +++ /dev/null diff --git a/docs/tutorials/wiki/src/tests/tutorial/static/footerbg.png b/docs/tutorials/wiki/src/tests/tutorial/static/footerbg.png Binary files differdeleted file mode 100644 index 1fbc873da..000000000 --- a/docs/tutorials/wiki/src/tests/tutorial/static/footerbg.png +++ /dev/null diff --git a/docs/tutorials/wiki/src/tests/tutorial/static/headerbg.png b/docs/tutorials/wiki/src/tests/tutorial/static/headerbg.png Binary files differdeleted file mode 100644 index 0596f2020..000000000 --- a/docs/tutorials/wiki/src/tests/tutorial/static/headerbg.png +++ /dev/null diff --git a/docs/tutorials/wiki/src/tests/tutorial/static/ie6.css b/docs/tutorials/wiki/src/tests/tutorial/static/ie6.css deleted file mode 100644 index b7c8493d8..000000000 --- a/docs/tutorials/wiki/src/tests/tutorial/static/ie6.css +++ /dev/null @@ -1,8 +0,0 @@ -* 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/wiki/src/tests/tutorial/static/middlebg.png b/docs/tutorials/wiki/src/tests/tutorial/static/middlebg.png Binary files differdeleted file mode 100644 index 2369cfb7d..000000000 --- a/docs/tutorials/wiki/src/tests/tutorial/static/middlebg.png +++ /dev/null diff --git a/docs/tutorials/wiki/src/tests/tutorial/static/pylons.css b/docs/tutorials/wiki/src/tests/tutorial/static/pylons.css deleted file mode 100644 index 4b1c017cd..000000000 --- a/docs/tutorials/wiki/src/tests/tutorial/static/pylons.css +++ /dev/null @@ -1,372 +0,0 @@ -html, body, div, span, applet, object, iframe, h1, h2, h3, h4, h5, h6, p, blockquote, pre, a, abbr, acronym, address, big, cite, code, del, dfn, em, font, img, ins, kbd, q, s, samp, small, strike, strong, sub, sup, tt, var, b, u, i, center, dl, dt, dd, ol, ul, li, fieldset, form, label, legend, table, caption, tbody, tfoot, thead, tr, th, td -{ - margin: 0; - padding: 0; - border: 0; - outline: 0; - font-size: 100%; /* 16px */ - vertical-align: baseline; - background: transparent; -} - -body -{ - line-height: 1; -} - -ol, ul -{ - list-style: none; -} - -blockquote, q -{ - quotes: none; -} - -blockquote:before, blockquote:after, q:before, q:after -{ - content: ''; - content: none; -} - -:focus -{ - outline: 0; -} - -ins -{ - text-decoration: none; -} - -del -{ - text-decoration: line-through; -} - -table -{ - border-collapse: collapse; - border-spacing: 0; -} - -sub -{ - vertical-align: sub; - font-size: smaller; - line-height: normal; -} - -sup -{ - vertical-align: super; - font-size: smaller; - line-height: normal; -} - -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; -} - -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; -} - -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; -} - -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; - 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: #fff; - position: relative; - font: 16px/24px NobileRegular, "Lucida Grande", Lucida, Verdana, sans-serif; -} - -a -{ - color: #1b61d6; - text-decoration: none; -} - -a:hover -{ - color: #e88f00; - text-decoration: underline; -} - -body h1, body h2, body h3, body h4, body h5, body h6 -{ - font-family: NeutonRegular, "Lucida Grande", Lucida, Verdana, sans-serif; - font-weight: 400; - color: #373839; - font-style: normal; -} - -#wrap -{ - min-height: 100%; -} - -#header, #footer -{ - width: 100%; - color: #fff; - height: 40px; - position: absolute; - text-align: center; - line-height: 40px; - overflow: hidden; - font-size: 12px; - vertical-align: middle; -} - -#header -{ - background: #000; - top: 0; - font-size: 14px; -} - -#footer -{ - bottom: 0; - background: #000 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, #top-small, #bottom -{ - width: 100%; -} - -#top -{ - color: #000; - height: 230px; - background: #fff url(headerbg.png) repeat-x 0 top; - position: relative; -} - -#top-small -{ - color: #000; - height: 60px; - background: #fff url(headerbg.png) repeat-x 0 top; - position: relative; -} - -#bottom -{ - color: #222; - background-color: #fff; -} - -.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 #fff; - border-bottom: 2px solid #b2b2b2; -} - -.app-welcome -{ - margin-top: 25px; -} - -.app-name -{ - color: #000; - font-weight: 700; -} - -.bottom -{ - padding-top: 50px; -} - -#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; -} - -ul.links -{ - margin: 0; - padding: 0; -} - -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=password] -{ - width: 205px; -} - -input[type=submit] -{ - background-color: #ddd; - font-weight: 700; -} - -/*Opera Fix*/ -body:before -{ - content: ""; - height: 100%; - float: left; - width: 0; - margin-top: -32767px; -} diff --git a/docs/tutorials/wiki/src/tests/tutorial/static/pyramid-16x16.png b/docs/tutorials/wiki/src/tests/tutorial/static/pyramid-16x16.png Binary files differnew file mode 100644 index 000000000..979203112 --- /dev/null +++ b/docs/tutorials/wiki/src/tests/tutorial/static/pyramid-16x16.png diff --git a/docs/tutorials/wiki/src/tests/tutorial/static/pyramid-small.png b/docs/tutorials/wiki/src/tests/tutorial/static/pyramid-small.png Binary files differdeleted file mode 100644 index a5bc0ade7..000000000 --- a/docs/tutorials/wiki/src/tests/tutorial/static/pyramid-small.png +++ /dev/null diff --git a/docs/tutorials/wiki/src/tests/tutorial/static/pyramid.png b/docs/tutorials/wiki/src/tests/tutorial/static/pyramid.png Binary files differindex 347e05549..4ab837be9 100644 --- a/docs/tutorials/wiki/src/tests/tutorial/static/pyramid.png +++ b/docs/tutorials/wiki/src/tests/tutorial/static/pyramid.png diff --git a/docs/tutorials/wiki/src/tests/tutorial/static/theme.css b/docs/tutorials/wiki/src/tests/tutorial/static/theme.css new file mode 100644 index 000000000..0f4b1a4d4 --- /dev/null +++ b/docs/tutorials/wiki/src/tests/tutorial/static/theme.css @@ -0,0 +1,154 @@ +@import url(//fonts.googleapis.com/css?family=Open+Sans:300,400,600,700); +body { + font-family: "Open Sans", "Helvetica Neue", Helvetica, Arial, sans-serif; + font-weight: 300; + color: #ffffff; + background: #bc2131; +} +h1, +h2, +h3, +h4, +h5, +h6 { + font-family: "Open Sans", "Helvetica Neue", Helvetica, Arial, sans-serif; + font-weight: 300; +} +p { + font-weight: 300; +} +.font-normal { + font-weight: 400; +} +.font-semi-bold { + font-weight: 600; +} +.font-bold { + font-weight: 700; +} +.starter-template { + margin-top: 250px; +} +.starter-template .content { + margin-left: 10px; +} +.starter-template .content h1 { + margin-top: 10px; + font-size: 60px; +} +.starter-template .content h1 .smaller { + font-size: 40px; + color: #f2b7bd; +} +.starter-template .content .lead { + font-size: 25px; + color: #f2b7bd; +} +.starter-template .content .lead .font-normal { + color: #ffffff; +} +.starter-template .links { + float: right; + right: 0; + margin-top: 125px; +} +.starter-template .links ul { + display: block; + padding: 0; + margin: 0; +} +.starter-template .links ul li { + list-style: none; + display: inline; + margin: 0 10px; +} +.starter-template .links ul li:first-child { + margin-left: 0; +} +.starter-template .links ul li:last-child { + margin-right: 0; +} +.starter-template .links ul li.current-version { + color: #f2b7bd; + font-weight: 400; +} +.starter-template .links ul li a, a { + color: #f2b7bd; + text-decoration: underline; +} +.starter-template .links ul li a:hover, a:hover { + color: #ffffff; + text-decoration: underline; +} +.starter-template .links ul li .icon-muted { + color: #eb8b95; + margin-right: 5px; +} +.starter-template .links ul li:hover .icon-muted { + color: #ffffff; +} +.starter-template .copyright { + margin-top: 10px; + font-size: 0.9em; + color: #f2b7bd; + text-transform: lowercase; + float: right; + right: 0; +} +@media (max-width: 1199px) { + .starter-template .content h1 { + font-size: 45px; + } + .starter-template .content h1 .smaller { + font-size: 30px; + } + .starter-template .content .lead { + font-size: 20px; + } +} +@media (max-width: 991px) { + .starter-template { + margin-top: 0; + } + .starter-template .logo { + margin: 40px auto; + } + .starter-template .content { + margin-left: 0; + text-align: center; + } + .starter-template .content h1 { + margin-bottom: 20px; + } + .starter-template .links { + float: none; + text-align: center; + margin-top: 60px; + } + .starter-template .copyright { + float: none; + text-align: center; + } +} +@media (max-width: 767px) { + .starter-template .content h1 .smaller { + font-size: 25px; + display: block; + } + .starter-template .content .lead { + font-size: 16px; + } + .starter-template .links { + margin-top: 40px; + } + .starter-template .links ul li { + display: block; + margin: 0; + } + .starter-template .links ul li .icon-muted { + display: none; + } + .starter-template .copyright { + margin-top: 20px; + } +} diff --git a/docs/tutorials/wiki/src/tests/tutorial/static/theme.min.css b/docs/tutorials/wiki/src/tests/tutorial/static/theme.min.css new file mode 100644 index 000000000..2f924bcc5 --- /dev/null +++ b/docs/tutorials/wiki/src/tests/tutorial/static/theme.min.css @@ -0,0 +1 @@ +@import url(//fonts.googleapis.com/css?family=Open+Sans:300,400,600,700);body{font-family:"Open Sans","Helvetica Neue",Helvetica,Arial,sans-serif;font-weight:300;color:#fff;background:#bc2131}h1,h2,h3,h4,h5,h6{font-family:"Open Sans","Helvetica Neue",Helvetica,Arial,sans-serif;font-weight:300}p{font-weight:300}.font-normal{font-weight:400}.font-semi-bold{font-weight:600}.font-bold{font-weight:700}.starter-template{margin-top:250px}.starter-template .content{margin-left:10px}.starter-template .content h1{margin-top:10px;font-size:60px}.starter-template .content h1 .smaller{font-size:40px;color:#f2b7bd}.starter-template .content .lead{font-size:25px;color:#f2b7bd}.starter-template .content .lead .font-normal{color:#fff}.starter-template .links{float:right;right:0;margin-top:125px}.starter-template .links ul{display:block;padding:0;margin:0}.starter-template .links ul li{list-style:none;display:inline;margin:0 10px}.starter-template .links ul li:first-child{margin-left:0}.starter-template .links ul li:last-child{margin-right:0}.starter-template .links ul li.current-version{color:#f2b7bd;font-weight:400}.starter-template .links ul li a{color:#fff}.starter-template .links ul li a:hover{text-decoration:underline}.starter-template .links ul li .icon-muted{color:#eb8b95;margin-right:5px}.starter-template .links ul li:hover .icon-muted{color:#fff}.starter-template .copyright{margin-top:10px;font-size:.9em;color:#f2b7bd;text-transform:lowercase;float:right;right:0}@media (max-width:1199px){.starter-template .content h1{font-size:45px}.starter-template .content h1 .smaller{font-size:30px}.starter-template .content .lead{font-size:20px}}@media (max-width:991px){.starter-template{margin-top:0}.starter-template .logo{margin:40px auto}.starter-template .content{margin-left:0;text-align:center}.starter-template .content h1{margin-bottom:20px}.starter-template .links{float:none;text-align:center;margin-top:60px}.starter-template .copyright{float:none;text-align:center}}@media (max-width:767px){.starter-template .content h1 .smaller{font-size:25px;display:block}.starter-template .content .lead{font-size:16px}.starter-template .links{margin-top:40px}.starter-template .links ul li{display:block;margin:0}.starter-template .links ul li .icon-muted{display:none}.starter-template .copyright{margin-top:20px}}
\ No newline at end of file diff --git a/docs/tutorials/wiki/src/tests/tutorial/static/transparent.gif b/docs/tutorials/wiki/src/tests/tutorial/static/transparent.gif Binary files differdeleted file mode 100644 index 0341802e5..000000000 --- a/docs/tutorials/wiki/src/tests/tutorial/static/transparent.gif +++ /dev/null diff --git a/docs/tutorials/wiki/src/tests/tutorial/templates/edit.pt b/docs/tutorials/wiki/src/tests/tutorial/templates/edit.pt index c3a0acf6b..823fa8972 100644 --- a/docs/tutorials/wiki/src/tests/tutorial/templates/edit.pt +++ b/docs/tutorials/wiki/src/tests/tutorial/templates/edit.pt @@ -1,58 +1,72 @@ -<!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>${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="/static/favicon.ico" /> - <link rel="stylesheet" - href="/static/pylons.css" - type="text/css" media="screen" charset="utf-8" /> - <!--[if lte IE 6]> - <link rel="stylesheet" - href="/static/ie6.css" - type="text/css" media="screen" charset="utf-8" /> - <![endif]--> -</head> -<body> - <div id="wrap"> - <div id="top-small"> - <div class="top-small align-center"> - <div> - <img width="220" height="50" alt="pyramid" - src="/static/pyramid-small.png" /> +<!DOCTYPE html> +<html lang="${request.locale_name}"> + <head> + <meta charset="utf-8"> + <meta http-equiv="X-UA-Compatible" content="IE=edge"> + <meta name="viewport" content="width=device-width, initial-scale=1.0"> + <meta name="description" content="pyramid web application"> + <meta name="author" content="Pylons Project"> + <link rel="shortcut icon" href="${request.static_url('tutorial:static/pyramid-16x16.png')}"> + + <title>${page.__name__} - Pyramid tutorial wiki (based on + TurboGears 20-Minute Wiki)</title> + + <!-- Bootstrap core CSS --> + <link href="//oss.maxcdn.com/libs/twitter-bootstrap/3.0.3/css/bootstrap.min.css" rel="stylesheet"> + + <!-- Custom styles for this scaffold --> + <link href="${request.static_url('tutorial:static/theme.css')}" rel="stylesheet"> + + <!-- HTML5 shim and Respond.js IE8 support of HTML5 elements and media queries --> + <!--[if lt IE 9]> + <script src="//oss.maxcdn.com/libs/html5shiv/3.7.0/html5shiv.js"></script> + <script src="//oss.maxcdn.com/libs/respond.js/1.3.0/respond.min.js"></script> + <![endif]--> + </head> + <body> + + <div class="starter-template"> + <div class="container"> + <div class="row"> + <div class="col-md-2"> + <img class="logo img-responsive" src="${request.static_url('tutorial:static/pyramid.png')}" alt="pyramid web framework"> + </div> + <div class="col-md-10"> + <div class="content"> + <p tal:condition="logged_in" class="pull-right"> + <a href="${request.application_url}/logout">Logout</a> + </p> + <p> + Editing <strong><span tal:replace="page.__name__"> + Page Name Goes Here</span></strong> + </p> + <p>You can return to the + <a href="${request.application_url}">FrontPage</a>. + </p> + <form action="${save_url}" method="post"> + <div class="form-group"> + <textarea class="form-control" name="body" tal:content="page.data" rows="10" cols="60"></textarea> + </div> + <div class="form-group"> + <button type="submit" name="form.submitted" value="Save" class="btn btn-default">Save</button> + </div> + </form> + </div> + </div> </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 class="row"> + <div class="copyright"> + Copyright © Pylons Project + </div> </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> -</body> + + + <!-- Bootstrap core JavaScript + ================================================== --> + <!-- Placed at the end of the document so the pages load faster --> + <script src="//oss.maxcdn.com/libs/jquery/1.10.2/jquery.min.js"></script> + <script src="//oss.maxcdn.com/libs/twitter-bootstrap/3.0.3/js/bootstrap.min.js"></script> + </body> </html> diff --git a/docs/tutorials/wiki/src/tests/tutorial/templates/login.pt b/docs/tutorials/wiki/src/tests/tutorial/templates/login.pt index 3612dccde..4a938e9bb 100644 --- a/docs/tutorials/wiki/src/tests/tutorial/templates/login.pt +++ b/docs/tutorials/wiki/src/tests/tutorial/templates/login.pt @@ -1,54 +1,74 @@ -<!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>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="/static/favicon.ico" /> - <link rel="stylesheet" - href="/static/pylons.css" - type="text/css" media="screen" charset="utf-8" /> - <!--[if lte IE 6]> - <link rel="stylesheet" - href="/static/ie6.css" - type="text/css" media="screen" charset="utf-8" /> - <![endif]--> -</head> -<body> - <div id="wrap"> - <div id="top-small"> - <div class="top-small align-center"> - <div> - <img width="220" height="50" alt="pyramid" - src="/static/pyramid-small.png" /> +<!DOCTYPE html> +<html lang="${request.locale_name}"> + <head> + <meta charset="utf-8"> + <meta http-equiv="X-UA-Compatible" content="IE=edge"> + <meta name="viewport" content="width=device-width, initial-scale=1.0"> + <meta name="description" content="pyramid web application"> + <meta name="author" content="Pylons Project"> + <link rel="shortcut icon" href="${request.static_url('tutorial:static/pyramid-16x16.png')}"> + + <title>Login - Pyramid tutorial wiki (based on + TurboGears 20-Minute Wiki)</title> + + <!-- Bootstrap core CSS --> + <link href="//oss.maxcdn.com/libs/twitter-bootstrap/3.0.3/css/bootstrap.min.css" rel="stylesheet"> + + <!-- Custom styles for this scaffold --> + <link href="${request.static_url('tutorial:static/theme.css')}" rel="stylesheet"> + + <!-- HTML5 shim and Respond.js IE8 support of HTML5 elements and media queries --> + <!--[if lt IE 9]> + <script src="//oss.maxcdn.com/libs/html5shiv/3.7.0/html5shiv.js"></script> + <script src="//oss.maxcdn.com/libs/respond.js/1.3.0/respond.min.js"></script> + <![endif]--> + </head> + <body> + + <div class="starter-template"> + <div class="container"> + <div class="row"> + <div class="col-md-2"> + <img class="logo img-responsive" src="${request.static_url('tutorial:static/pyramid.png')}" alt="pyramid web framework"> + </div> + <div class="col-md-10"> + <div class="content"> + <p> + <strong> + Login + </strong><br> + <span tal:replace="message"></span> + </p> + <form action="${url}" method="post"> + <input type="hidden" name="came_from" value="${came_from}"> + <div class="form-group"> + <label for="login">Username</label> + <input type="text" name="login" value="${login}"> + </div> + <div class="form-group"> + <label for="password">Password</label> + <input type="password" name="password" value="${password}"> + </div> + <div class="form-group"> + <button type="submit" name="form.submitted" value="Log In" class="btn btn-default">Log In</button> + </div> + </form> + </div> + </div> </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 class="row"> + <div class="copyright"> + Copyright © Pylons Project + </div> </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> -</body> + + + <!-- Bootstrap core JavaScript + ================================================== --> + <!-- Placed at the end of the document so the pages load faster --> + <script src="//oss.maxcdn.com/libs/jquery/1.10.2/jquery.min.js"></script> + <script src="//oss.maxcdn.com/libs/twitter-bootstrap/3.0.3/js/bootstrap.min.js"></script> + </body> </html> diff --git a/docs/tutorials/wiki/src/tests/tutorial/templates/mytemplate.pt b/docs/tutorials/wiki/src/tests/tutorial/templates/mytemplate.pt index 13b41f823..1b30f42b6 100644 --- a/docs/tutorials/wiki/src/tests/tutorial/templates/mytemplate.pt +++ b/docs/tutorials/wiki/src/tests/tutorial/templates/mytemplate.pt @@ -1,73 +1,66 @@ -<!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 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="/static/favicon.ico" /> - <link rel="stylesheet" href="/static/pylons.css" type="text/css" media="screen" charset="utf-8" /> - <link rel="stylesheet" href="http://static.pylonsproject.org/fonts/nobile/stylesheet.css" media="screen" /> - <link rel="stylesheet" href="http://static.pylonsproject.org/fonts/neuton/stylesheet.css" media="screen" /> - <!--[if lte IE 6]> - <link rel="stylesheet" href="/static/ie6.css" type="text/css" media="screen" charset="utf-8" /> - <![endif]--> -</head> -<body> - <div id="wrap"> - <div id="top"> - <div class="top align-center"> - <div><img src="/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 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/current/search.html"> - <input type="text" id="q" name="q" value="" /> - <input type="submit" id="x" value="Go" /> - </form> +<!DOCTYPE html> +<html lang="${request.locale_name}"> + <head> + <meta charset="utf-8"> + <meta http-equiv="X-UA-Compatible" content="IE=edge"> + <meta name="viewport" content="width=device-width, initial-scale=1.0"> + <meta name="description" content="pyramid web application"> + <meta name="author" content="Pylons Project"> + <link rel="shortcut icon" href="${request.static_url('tutorial:static/pyramid-16x16.png')}"> + + <title>ZODB Scaffold for The Pyramid Web Framework</title> + + <!-- Bootstrap core CSS --> + <link href="//oss.maxcdn.com/libs/twitter-bootstrap/3.0.3/css/bootstrap.min.css" rel="stylesheet"> + + <!-- Custom styles for this scaffold --> + <link href="${request.static_url('tutorial:static/theme.css')}" rel="stylesheet"> + + <!-- HTML5 shim and Respond.js IE8 support of HTML5 elements and media queries --> + <!--[if lt IE 9]> + <script src="//oss.maxcdn.com/libs/html5shiv/3.7.0/html5shiv.js"></script> + <script src="//oss.maxcdn.com/libs/respond.js/1.3.0/respond.min.js"></script> + <![endif]--> + </head> + + <body> + + <div class="starter-template"> + <div class="container"> + <div class="row"> + <div class="col-md-2"> + <img class="logo img-responsive" src="${request.static_url('tutorial:static/pyramid.png')}" alt="pyramid web framework"> + </div> + <div class="col-md-10"> + <div class="content"> + <h1><span class="font-semi-bold">Pyramid</span> <span class="smaller">ZODB scaffold</span></h1> + <p class="lead">Welcome to <span class="font-normal">${project}</span>, an application generated by<br>the <span class="font-normal">Pyramid Web Framework</span>.</p> + </div> + </div> </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/current/#narrative-documentation">Narrative Documentation</a> - </li> - <li> - <a href="http://docs.pylonsproject.org/projects/pyramid/current/#api-documentation">API Documentation</a> - </li> - <li> - <a href="http://docs.pylonsproject.org/projects/pyramid/current/#tutorials">Tutorials</a> - </li> - <li> - <a href="http://docs.pylonsproject.org/projects/pyramid/current/#change-history">Change History</a> - </li> - <li> - <a href="http://docs.pylonsproject.org/projects/pyramid/current/#sample-applications">Sample Applications</a> - </li> - <li> - <a href="http://docs.pylonsproject.org/projects/pyramid/current/#support-and-development">Support and Development</a> - </li> - <li> - <a href="irc://irc.freenode.net#pyramid">IRC Channel</a> - </li> + <div class="row"> + <div class="links"> + <ul> + <li><i class="glyphicon glyphicon-bookmark icon-muted"></i><a href="http://docs.pylonsproject.org/projects/pyramid/en/latest/">Docs</a></li> + <li><i class="glyphicon glyphicon-cog icon-muted"></i><a href="https://github.com/Pylons/pyramid">Github Project</a></li> + <li><i class="glyphicon glyphicon-globe icon-muted"></i><a href="irc://irc.freenode.net#pyramid">IRC Channel</a></li> + <li><i class="glyphicon glyphicon-home icon-muted"></i><a href="http://pylonsproject.org">Pylons Project</a></li> </ul> + </div> + </div> + <div class="row"> + <div class="copyright"> + Copyright © Pylons Project + </div> </div> </div> </div> - </div> -</body> + + + <!-- Bootstrap core JavaScript + ================================================== --> + <!-- Placed at the end of the document so the pages load faster --> + <script src="//oss.maxcdn.com/libs/jquery/1.10.2/jquery.min.js"></script> + <script src="//oss.maxcdn.com/libs/twitter-bootstrap/3.0.3/js/bootstrap.min.js"></script> + </body> </html> diff --git a/docs/tutorials/wiki/src/tests/tutorial/templates/view.pt b/docs/tutorials/wiki/src/tests/tutorial/templates/view.pt index 90e20764d..fa35d758d 100644 --- a/docs/tutorials/wiki/src/tests/tutorial/templates/view.pt +++ b/docs/tutorials/wiki/src/tests/tutorial/templates/view.pt @@ -1,61 +1,72 @@ -<!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>${page.__name__} - Pyramid tutorial wiki (based on +<!DOCTYPE html> +<html lang="${request.locale_name}"> + <head> + <meta charset="utf-8"> + <meta http-equiv="X-UA-Compatible" content="IE=edge"> + <meta name="viewport" content="width=device-width, initial-scale=1.0"> + <meta name="description" content="pyramid web application"> + <meta name="author" content="Pylons Project"> + <link rel="shortcut icon" href="${request.static_url('tutorial:static/pyramid-16x16.png')}"> + + <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="/static/favicon.ico" /> - <link rel="stylesheet" - href="/static/pylons.css" - type="text/css" media="screen" charset="utf-8" /> - <!--[if lte IE 6]> - <link rel="stylesheet" - href="/static/ie6.css" - type="text/css" media="screen" charset="utf-8" /> - <![endif]--> -</head> -<body> - <div id="wrap"> - <div id="top-small"> - <div class="top-small align-center"> - <div> - <img width="220" height="50" alt="pyramid" - src="/static/pyramid-small.png" /> + + <!-- Bootstrap core CSS --> + <link href="//oss.maxcdn.com/libs/twitter-bootstrap/3.0.3/css/bootstrap.min.css" rel="stylesheet"> + + <!-- Custom styles for this scaffold --> + <link href="${request.static_url('tutorial:static/theme.css')}" rel="stylesheet"> + + <!-- HTML5 shim and Respond.js IE8 support of HTML5 elements and media queries --> + <!--[if lt IE 9]> + <script src="//oss.maxcdn.com/libs/html5shiv/3.7.0/html5shiv.js"></script> + <script src="//oss.maxcdn.com/libs/respond.js/1.3.0/respond.min.js"></script> + <![endif]--> + </head> + <body> + + <div class="starter-template"> + <div class="container"> + <div class="row"> + <div class="col-md-2"> + <img class="logo img-responsive" src="${request.static_url('tutorial:static/pyramid.png')}" alt="pyramid web framework"> + </div> + <div class="col-md-10"> + <div class="content"> + <p tal:condition="logged_in" class="pull-right"> + <a href="${request.application_url}/logout">Logout</a> + </p> + <div tal:replace="structure content"> + Page text goes here. + </div> + <p> + <a tal:attributes="href edit_url" href=""> + Edit this page + </a> + </p> + <p> + Viewing <strong><span tal:replace="page.__name__"> + Page Name Goes Here</span></strong> + </p> + <p>You can return to the + <a href="${request.application_url}">FrontPage</a>. + </p> + </div> + </div> </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 class="row"> + <div class="copyright"> + Copyright © Pylons Project + </div> </div> - <p> - <a tal:attributes="href edit_url" href=""> - Edit this page - </a> - </p> </div> </div> - </div> -</body> + + + <!-- Bootstrap core JavaScript + ================================================== --> + <!-- Placed at the end of the document so the pages load faster --> + <script src="//oss.maxcdn.com/libs/jquery/1.10.2/jquery.min.js"></script> + <script src="//oss.maxcdn.com/libs/twitter-bootstrap/3.0.3/js/bootstrap.min.js"></script> + </body> </html> diff --git a/docs/tutorials/wiki/src/views/setup.py b/docs/tutorials/wiki/src/views/setup.py index 5ab4f73cd..e2e96379d 100644 --- a/docs/tutorials/wiki/src/views/setup.py +++ b/docs/tutorials/wiki/src/views/setup.py @@ -11,10 +11,10 @@ with open(os.path.join(here, 'CHANGES.txt')) as f: requires = [ 'pyramid', 'pyramid_chameleon', + 'pyramid_debugtoolbar', + 'pyramid_tm', 'pyramid_zodbconn', 'transaction', - 'pyramid_tm', - 'pyramid_debugtoolbar', 'ZODB3', 'waitress', 'docutils', diff --git a/docs/tutorials/wiki/src/views/tutorial/static/favicon.ico b/docs/tutorials/wiki/src/views/tutorial/static/favicon.ico Binary files differdeleted file mode 100644 index 71f837c9e..000000000 --- a/docs/tutorials/wiki/src/views/tutorial/static/favicon.ico +++ /dev/null diff --git a/docs/tutorials/wiki/src/views/tutorial/static/footerbg.png b/docs/tutorials/wiki/src/views/tutorial/static/footerbg.png Binary files differdeleted file mode 100644 index 1fbc873da..000000000 --- a/docs/tutorials/wiki/src/views/tutorial/static/footerbg.png +++ /dev/null diff --git a/docs/tutorials/wiki/src/views/tutorial/static/headerbg.png b/docs/tutorials/wiki/src/views/tutorial/static/headerbg.png Binary files differdeleted file mode 100644 index 0596f2020..000000000 --- a/docs/tutorials/wiki/src/views/tutorial/static/headerbg.png +++ /dev/null diff --git a/docs/tutorials/wiki/src/views/tutorial/static/ie6.css b/docs/tutorials/wiki/src/views/tutorial/static/ie6.css deleted file mode 100644 index b7c8493d8..000000000 --- a/docs/tutorials/wiki/src/views/tutorial/static/ie6.css +++ /dev/null @@ -1,8 +0,0 @@ -* 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/wiki/src/views/tutorial/static/middlebg.png b/docs/tutorials/wiki/src/views/tutorial/static/middlebg.png Binary files differdeleted file mode 100644 index 2369cfb7d..000000000 --- a/docs/tutorials/wiki/src/views/tutorial/static/middlebg.png +++ /dev/null diff --git a/docs/tutorials/wiki/src/views/tutorial/static/pylons.css b/docs/tutorials/wiki/src/views/tutorial/static/pylons.css deleted file mode 100644 index 4b1c017cd..000000000 --- a/docs/tutorials/wiki/src/views/tutorial/static/pylons.css +++ /dev/null @@ -1,372 +0,0 @@ -html, body, div, span, applet, object, iframe, h1, h2, h3, h4, h5, h6, p, blockquote, pre, a, abbr, acronym, address, big, cite, code, del, dfn, em, font, img, ins, kbd, q, s, samp, small, strike, strong, sub, sup, tt, var, b, u, i, center, dl, dt, dd, ol, ul, li, fieldset, form, label, legend, table, caption, tbody, tfoot, thead, tr, th, td -{ - margin: 0; - padding: 0; - border: 0; - outline: 0; - font-size: 100%; /* 16px */ - vertical-align: baseline; - background: transparent; -} - -body -{ - line-height: 1; -} - -ol, ul -{ - list-style: none; -} - -blockquote, q -{ - quotes: none; -} - -blockquote:before, blockquote:after, q:before, q:after -{ - content: ''; - content: none; -} - -:focus -{ - outline: 0; -} - -ins -{ - text-decoration: none; -} - -del -{ - text-decoration: line-through; -} - -table -{ - border-collapse: collapse; - border-spacing: 0; -} - -sub -{ - vertical-align: sub; - font-size: smaller; - line-height: normal; -} - -sup -{ - vertical-align: super; - font-size: smaller; - line-height: normal; -} - -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; -} - -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; -} - -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; -} - -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; - 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: #fff; - position: relative; - font: 16px/24px NobileRegular, "Lucida Grande", Lucida, Verdana, sans-serif; -} - -a -{ - color: #1b61d6; - text-decoration: none; -} - -a:hover -{ - color: #e88f00; - text-decoration: underline; -} - -body h1, body h2, body h3, body h4, body h5, body h6 -{ - font-family: NeutonRegular, "Lucida Grande", Lucida, Verdana, sans-serif; - font-weight: 400; - color: #373839; - font-style: normal; -} - -#wrap -{ - min-height: 100%; -} - -#header, #footer -{ - width: 100%; - color: #fff; - height: 40px; - position: absolute; - text-align: center; - line-height: 40px; - overflow: hidden; - font-size: 12px; - vertical-align: middle; -} - -#header -{ - background: #000; - top: 0; - font-size: 14px; -} - -#footer -{ - bottom: 0; - background: #000 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, #top-small, #bottom -{ - width: 100%; -} - -#top -{ - color: #000; - height: 230px; - background: #fff url(headerbg.png) repeat-x 0 top; - position: relative; -} - -#top-small -{ - color: #000; - height: 60px; - background: #fff url(headerbg.png) repeat-x 0 top; - position: relative; -} - -#bottom -{ - color: #222; - background-color: #fff; -} - -.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 #fff; - border-bottom: 2px solid #b2b2b2; -} - -.app-welcome -{ - margin-top: 25px; -} - -.app-name -{ - color: #000; - font-weight: 700; -} - -.bottom -{ - padding-top: 50px; -} - -#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; -} - -ul.links -{ - margin: 0; - padding: 0; -} - -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=password] -{ - width: 205px; -} - -input[type=submit] -{ - background-color: #ddd; - font-weight: 700; -} - -/*Opera Fix*/ -body:before -{ - content: ""; - height: 100%; - float: left; - width: 0; - margin-top: -32767px; -} diff --git a/docs/tutorials/wiki/src/views/tutorial/static/pyramid-16x16.png b/docs/tutorials/wiki/src/views/tutorial/static/pyramid-16x16.png Binary files differnew file mode 100644 index 000000000..979203112 --- /dev/null +++ b/docs/tutorials/wiki/src/views/tutorial/static/pyramid-16x16.png diff --git a/docs/tutorials/wiki/src/views/tutorial/static/pyramid-small.png b/docs/tutorials/wiki/src/views/tutorial/static/pyramid-small.png Binary files differdeleted file mode 100644 index a5bc0ade7..000000000 --- a/docs/tutorials/wiki/src/views/tutorial/static/pyramid-small.png +++ /dev/null diff --git a/docs/tutorials/wiki/src/views/tutorial/static/pyramid.png b/docs/tutorials/wiki/src/views/tutorial/static/pyramid.png Binary files differindex 347e05549..4ab837be9 100644 --- a/docs/tutorials/wiki/src/views/tutorial/static/pyramid.png +++ b/docs/tutorials/wiki/src/views/tutorial/static/pyramid.png diff --git a/docs/tutorials/wiki/src/views/tutorial/static/theme.css b/docs/tutorials/wiki/src/views/tutorial/static/theme.css new file mode 100644 index 000000000..0f4b1a4d4 --- /dev/null +++ b/docs/tutorials/wiki/src/views/tutorial/static/theme.css @@ -0,0 +1,154 @@ +@import url(//fonts.googleapis.com/css?family=Open+Sans:300,400,600,700); +body { + font-family: "Open Sans", "Helvetica Neue", Helvetica, Arial, sans-serif; + font-weight: 300; + color: #ffffff; + background: #bc2131; +} +h1, +h2, +h3, +h4, +h5, +h6 { + font-family: "Open Sans", "Helvetica Neue", Helvetica, Arial, sans-serif; + font-weight: 300; +} +p { + font-weight: 300; +} +.font-normal { + font-weight: 400; +} +.font-semi-bold { + font-weight: 600; +} +.font-bold { + font-weight: 700; +} +.starter-template { + margin-top: 250px; +} +.starter-template .content { + margin-left: 10px; +} +.starter-template .content h1 { + margin-top: 10px; + font-size: 60px; +} +.starter-template .content h1 .smaller { + font-size: 40px; + color: #f2b7bd; +} +.starter-template .content .lead { + font-size: 25px; + color: #f2b7bd; +} +.starter-template .content .lead .font-normal { + color: #ffffff; +} +.starter-template .links { + float: right; + right: 0; + margin-top: 125px; +} +.starter-template .links ul { + display: block; + padding: 0; + margin: 0; +} +.starter-template .links ul li { + list-style: none; + display: inline; + margin: 0 10px; +} +.starter-template .links ul li:first-child { + margin-left: 0; +} +.starter-template .links ul li:last-child { + margin-right: 0; +} +.starter-template .links ul li.current-version { + color: #f2b7bd; + font-weight: 400; +} +.starter-template .links ul li a, a { + color: #f2b7bd; + text-decoration: underline; +} +.starter-template .links ul li a:hover, a:hover { + color: #ffffff; + text-decoration: underline; +} +.starter-template .links ul li .icon-muted { + color: #eb8b95; + margin-right: 5px; +} +.starter-template .links ul li:hover .icon-muted { + color: #ffffff; +} +.starter-template .copyright { + margin-top: 10px; + font-size: 0.9em; + color: #f2b7bd; + text-transform: lowercase; + float: right; + right: 0; +} +@media (max-width: 1199px) { + .starter-template .content h1 { + font-size: 45px; + } + .starter-template .content h1 .smaller { + font-size: 30px; + } + .starter-template .content .lead { + font-size: 20px; + } +} +@media (max-width: 991px) { + .starter-template { + margin-top: 0; + } + .starter-template .logo { + margin: 40px auto; + } + .starter-template .content { + margin-left: 0; + text-align: center; + } + .starter-template .content h1 { + margin-bottom: 20px; + } + .starter-template .links { + float: none; + text-align: center; + margin-top: 60px; + } + .starter-template .copyright { + float: none; + text-align: center; + } +} +@media (max-width: 767px) { + .starter-template .content h1 .smaller { + font-size: 25px; + display: block; + } + .starter-template .content .lead { + font-size: 16px; + } + .starter-template .links { + margin-top: 40px; + } + .starter-template .links ul li { + display: block; + margin: 0; + } + .starter-template .links ul li .icon-muted { + display: none; + } + .starter-template .copyright { + margin-top: 20px; + } +} diff --git a/docs/tutorials/wiki/src/views/tutorial/static/theme.min.css b/docs/tutorials/wiki/src/views/tutorial/static/theme.min.css new file mode 100644 index 000000000..2f924bcc5 --- /dev/null +++ b/docs/tutorials/wiki/src/views/tutorial/static/theme.min.css @@ -0,0 +1 @@ +@import url(//fonts.googleapis.com/css?family=Open+Sans:300,400,600,700);body{font-family:"Open Sans","Helvetica Neue",Helvetica,Arial,sans-serif;font-weight:300;color:#fff;background:#bc2131}h1,h2,h3,h4,h5,h6{font-family:"Open Sans","Helvetica Neue",Helvetica,Arial,sans-serif;font-weight:300}p{font-weight:300}.font-normal{font-weight:400}.font-semi-bold{font-weight:600}.font-bold{font-weight:700}.starter-template{margin-top:250px}.starter-template .content{margin-left:10px}.starter-template .content h1{margin-top:10px;font-size:60px}.starter-template .content h1 .smaller{font-size:40px;color:#f2b7bd}.starter-template .content .lead{font-size:25px;color:#f2b7bd}.starter-template .content .lead .font-normal{color:#fff}.starter-template .links{float:right;right:0;margin-top:125px}.starter-template .links ul{display:block;padding:0;margin:0}.starter-template .links ul li{list-style:none;display:inline;margin:0 10px}.starter-template .links ul li:first-child{margin-left:0}.starter-template .links ul li:last-child{margin-right:0}.starter-template .links ul li.current-version{color:#f2b7bd;font-weight:400}.starter-template .links ul li a{color:#fff}.starter-template .links ul li a:hover{text-decoration:underline}.starter-template .links ul li .icon-muted{color:#eb8b95;margin-right:5px}.starter-template .links ul li:hover .icon-muted{color:#fff}.starter-template .copyright{margin-top:10px;font-size:.9em;color:#f2b7bd;text-transform:lowercase;float:right;right:0}@media (max-width:1199px){.starter-template .content h1{font-size:45px}.starter-template .content h1 .smaller{font-size:30px}.starter-template .content .lead{font-size:20px}}@media (max-width:991px){.starter-template{margin-top:0}.starter-template .logo{margin:40px auto}.starter-template .content{margin-left:0;text-align:center}.starter-template .content h1{margin-bottom:20px}.starter-template .links{float:none;text-align:center;margin-top:60px}.starter-template .copyright{float:none;text-align:center}}@media (max-width:767px){.starter-template .content h1 .smaller{font-size:25px;display:block}.starter-template .content .lead{font-size:16px}.starter-template .links{margin-top:40px}.starter-template .links ul li{display:block;margin:0}.starter-template .links ul li .icon-muted{display:none}.starter-template .copyright{margin-top:20px}}
\ No newline at end of file diff --git a/docs/tutorials/wiki/src/views/tutorial/static/transparent.gif b/docs/tutorials/wiki/src/views/tutorial/static/transparent.gif Binary files differdeleted file mode 100644 index 0341802e5..000000000 --- a/docs/tutorials/wiki/src/views/tutorial/static/transparent.gif +++ /dev/null diff --git a/docs/tutorials/wiki/src/views/tutorial/templates/edit.pt b/docs/tutorials/wiki/src/views/tutorial/templates/edit.pt index 24ed2e592..b23f45d56 100644 --- a/docs/tutorials/wiki/src/views/tutorial/templates/edit.pt +++ b/docs/tutorials/wiki/src/views/tutorial/templates/edit.pt @@ -1,58 +1,69 @@ -<!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>${page.__name__} - Pyramid tutorial wiki (based on +<!DOCTYPE html> +<html lang="${request.locale_name}"> + <head> + <meta charset="utf-8"> + <meta http-equiv="X-UA-Compatible" content="IE=edge"> + <meta name="viewport" content="width=device-width, initial-scale=1.0"> + <meta name="description" content="pyramid web application"> + <meta name="author" content="Pylons Project"> + <link rel="shortcut icon" href="${request.static_url('tutorial:static/pyramid-16x16.png')}"> + + <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="/static/favicon.ico" /> - <link rel="stylesheet" - href="/static/pylons.css" - type="text/css" media="screen" charset="utf-8" /> - <!--[if lte IE 6]> - <link rel="stylesheet" - href="/static/ie6.css" - type="text/css" media="screen" charset="utf-8" /> - <![endif]--> -</head> -<body> - <div id="wrap"> - <div id="top-small"> - <div class="top-small align-center"> - <div> - <img width="220" height="50" alt="pyramid" - src="/static/pyramid-small.png" /> + + <!-- Bootstrap core CSS --> + <link href="//oss.maxcdn.com/libs/twitter-bootstrap/3.0.3/css/bootstrap.min.css" rel="stylesheet"> + + <!-- Custom styles for this scaffold --> + <link href="${request.static_url('tutorial:static/theme.css')}" rel="stylesheet"> + + <!-- HTML5 shim and Respond.js IE8 support of HTML5 elements and media queries --> + <!--[if lt IE 9]> + <script src="//oss.maxcdn.com/libs/html5shiv/3.7.0/html5shiv.js"></script> + <script src="//oss.maxcdn.com/libs/respond.js/1.3.0/respond.min.js"></script> + <![endif]--> + </head> + <body> + + <div class="starter-template"> + <div class="container"> + <div class="row"> + <div class="col-md-2"> + <img class="logo img-responsive" src="${request.static_url('tutorial:static/pyramid.png')}" alt="pyramid web framework"> + </div> + <div class="col-md-10"> + <div class="content"> + <p> + Editing <strong><span tal:replace="page.__name__"> + Page Name Goes Here</span></strong> + </p> + <p>You can return to the + <a href="${request.application_url}">FrontPage</a>. + </p> + <form action="${save_url}" method="post"> + <div class="form-group"> + <textarea class="form-control" name="body" tal:content="page.data" rows="10" cols="60"></textarea> + </div> + <div class="form-group"> + <button type="submit" name="form.submitted" value="Save" class="btn btn-default">Save</button> + </div> + </form> + </div> + </div> </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 class="row"> + <div class="copyright"> + Copyright © Pylons Project + </div> </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> -</body> + + + <!-- Bootstrap core JavaScript + ================================================== --> + <!-- Placed at the end of the document so the pages load faster --> + <script src="//oss.maxcdn.com/libs/jquery/1.10.2/jquery.min.js"></script> + <script src="//oss.maxcdn.com/libs/twitter-bootstrap/3.0.3/js/bootstrap.min.js"></script> + </body> </html> diff --git a/docs/tutorials/wiki/src/views/tutorial/templates/mytemplate.pt b/docs/tutorials/wiki/src/views/tutorial/templates/mytemplate.pt index 50102aa20..1b30f42b6 100644 --- a/docs/tutorials/wiki/src/views/tutorial/templates/mytemplate.pt +++ b/docs/tutorials/wiki/src/views/tutorial/templates/mytemplate.pt @@ -1,76 +1,66 @@ -<!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 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="/static/favicon.ico" /> - <link rel="stylesheet" href="/static/pylons.css" type="text/css" media="screen" charset="utf-8" /> - <link rel="stylesheet" href="http://static.pylonsproject.org/fonts/nobile/stylesheet.css" media="screen" /> - <link rel="stylesheet" href="http://static.pylonsproject.org/fonts/neuton/stylesheet.css" media="screen" /> - <!--[if lte IE 6]> - <link rel="stylesheet" href="/static/ie6.css" type="text/css" media="screen" charset="utf-8" /> - <![endif]--> -</head> -<body> - <div id="wrap"> - <div id="top"> - <div class="top align-center"> - <div><img src="/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 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/current/search.html"> - <input type="text" id="q" name="q" value="" /> - <input type="submit" id="x" value="Go" /> - </form> +<!DOCTYPE html> +<html lang="${request.locale_name}"> + <head> + <meta charset="utf-8"> + <meta http-equiv="X-UA-Compatible" content="IE=edge"> + <meta name="viewport" content="width=device-width, initial-scale=1.0"> + <meta name="description" content="pyramid web application"> + <meta name="author" content="Pylons Project"> + <link rel="shortcut icon" href="${request.static_url('tutorial:static/pyramid-16x16.png')}"> + + <title>ZODB Scaffold for The Pyramid Web Framework</title> + + <!-- Bootstrap core CSS --> + <link href="//oss.maxcdn.com/libs/twitter-bootstrap/3.0.3/css/bootstrap.min.css" rel="stylesheet"> + + <!-- Custom styles for this scaffold --> + <link href="${request.static_url('tutorial:static/theme.css')}" rel="stylesheet"> + + <!-- HTML5 shim and Respond.js IE8 support of HTML5 elements and media queries --> + <!--[if lt IE 9]> + <script src="//oss.maxcdn.com/libs/html5shiv/3.7.0/html5shiv.js"></script> + <script src="//oss.maxcdn.com/libs/respond.js/1.3.0/respond.min.js"></script> + <![endif]--> + </head> + + <body> + + <div class="starter-template"> + <div class="container"> + <div class="row"> + <div class="col-md-2"> + <img class="logo img-responsive" src="${request.static_url('tutorial:static/pyramid.png')}" alt="pyramid web framework"> + </div> + <div class="col-md-10"> + <div class="content"> + <h1><span class="font-semi-bold">Pyramid</span> <span class="smaller">ZODB scaffold</span></h1> + <p class="lead">Welcome to <span class="font-normal">${project}</span>, an application generated by<br>the <span class="font-normal">Pyramid Web Framework</span>.</p> + </div> + </div> </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/current/#narrative-documentation">Narrative Documentation</a> - </li> - <li> - <a href="http://docs.pylonsproject.org/projects/pyramid/current/#api-documentation">API Documentation</a> - </li> - <li> - <a href="http://docs.pylonsproject.org/projects/pyramid/current/#tutorials">Tutorials</a> - </li> - <li> - <a href="http://docs.pylonsproject.org/projects/pyramid/current/#change-history">Change History</a> - </li> - <li> - <a href="http://docs.pylonsproject.org/projects/pyramid/current/#sample-applications">Sample Applications</a> - </li> - <li> - <a href="http://docs.pylonsproject.org/projects/pyramid/current/#support-and-development">Support and Development</a> - </li> - <li> - <a href="irc://irc.freenode.net#pyramid">IRC Channel</a> - </li> + <div class="row"> + <div class="links"> + <ul> + <li><i class="glyphicon glyphicon-bookmark icon-muted"></i><a href="http://docs.pylonsproject.org/projects/pyramid/en/latest/">Docs</a></li> + <li><i class="glyphicon glyphicon-cog icon-muted"></i><a href="https://github.com/Pylons/pyramid">Github Project</a></li> + <li><i class="glyphicon glyphicon-globe icon-muted"></i><a href="irc://irc.freenode.net#pyramid">IRC Channel</a></li> + <li><i class="glyphicon glyphicon-home icon-muted"></i><a href="http://pylonsproject.org">Pylons Project</a></li> </ul> + </div> + </div> + <div class="row"> + <div class="copyright"> + Copyright © Pylons Project + </div> </div> </div> </div> - </div> - <div id="footer"> - <div class="footer">© Copyright 2008-2012, Agendaless Consulting.</div> - </div> -</body> + + + <!-- Bootstrap core JavaScript + ================================================== --> + <!-- Placed at the end of the document so the pages load faster --> + <script src="//oss.maxcdn.com/libs/jquery/1.10.2/jquery.min.js"></script> + <script src="//oss.maxcdn.com/libs/twitter-bootstrap/3.0.3/js/bootstrap.min.js"></script> + </body> </html> diff --git a/docs/tutorials/wiki/src/views/tutorial/templates/view.pt b/docs/tutorials/wiki/src/views/tutorial/templates/view.pt index 424c4302a..e7b0dc23e 100644 --- a/docs/tutorials/wiki/src/views/tutorial/templates/view.pt +++ b/docs/tutorials/wiki/src/views/tutorial/templates/view.pt @@ -1,61 +1,69 @@ -<!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>${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="/static/favicon.ico" /> - <link rel="stylesheet" - href="/static/pylons.css" - type="text/css" media="screen" charset="utf-8" /> - <!--[if lte IE 6]> - <link rel="stylesheet" - href="/static/ie6.css" - type="text/css" media="screen" charset="utf-8" /> - <![endif]--> -</head> -<body> - <div id="wrap"> - <div id="top-small"> - <div class="top-small align-center"> - <div> - <img width="220" height="50" alt="pyramid" - src="/static/pyramid-small.png" /> +<!DOCTYPE html> +<html lang="${request.locale_name}"> + <head> + <meta charset="utf-8"> + <meta http-equiv="X-UA-Compatible" content="IE=edge"> + <meta name="viewport" content="width=device-width, initial-scale=1.0"> + <meta name="description" content="pyramid web application"> + <meta name="author" content="Pylons Project"> + <link rel="shortcut icon" href="${request.static_url('tutorial:static/pyramid-16x16.png')}"> + + <title>${page.name} - Pyramid tutorial wiki (based on + TurboGears 20-Minute Wiki)</title> + + <!-- Bootstrap core CSS --> + <link href="//oss.maxcdn.com/libs/twitter-bootstrap/3.0.3/css/bootstrap.min.css" rel="stylesheet"> + + <!-- Custom styles for this scaffold --> + <link href="${request.static_url('tutorial:static/theme.css')}" rel="stylesheet"> + + <!-- HTML5 shim and Respond.js IE8 support of HTML5 elements and media queries --> + <!--[if lt IE 9]> + <script src="//oss.maxcdn.com/libs/html5shiv/3.7.0/html5shiv.js"></script> + <script src="//oss.maxcdn.com/libs/respond.js/1.3.0/respond.min.js"></script> + <![endif]--> + </head> + <body> + + <div class="starter-template"> + <div class="container"> + <div class="row"> + <div class="col-md-2"> + <img class="logo img-responsive" src="${request.static_url('tutorial:static/pyramid.png')}" alt="pyramid web framework"> + </div> + <div class="col-md-10"> + <div class="content"> + <div tal:replace="structure content"> + Page text goes here. + </div> + <p> + <a tal:attributes="href edit_url" href=""> + Edit this page + </a> + </p> + <p> + Viewing <strong><span tal:replace="page.__name__"> + Page Name Goes Here</span></strong> + </p> + <p>You can return to the + <a href="${request.application_url}">FrontPage</a>. + </p> + </div> + </div> </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 class="row"> + <div class="copyright"> + Copyright © Pylons Project + </div> </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> + + + <!-- Bootstrap core JavaScript + ================================================== --> + <!-- Placed at the end of the document so the pages load faster --> + <script src="//oss.maxcdn.com/libs/jquery/1.10.2/jquery.min.js"></script> + <script src="//oss.maxcdn.com/libs/twitter-bootstrap/3.0.3/js/bootstrap.min.js"></script> + </body> </html> diff --git a/docs/tutorials/wiki/tests.rst b/docs/tutorials/wiki/tests.rst index e724f3e18..e255812fc 100644 --- a/docs/tutorials/wiki/tests.rst +++ b/docs/tutorials/wiki/tests.rst @@ -2,38 +2,36 @@ Adding Tests ============ -We will now add tests for the models and the views and a few functional -tests in the ``tests.py``. Tests ensure that an application works, and -that it continues to work after some changes are made in the future. +We will now add tests for the models and the views and a few functional tests +in ``tests.py``. Tests ensure that an application works, and that it +continues to work when changes are made in the future. - -Test the Models +Test the models =============== -We write tests for the model classes and the appmaker. Changing -``tests.py``, we'll write a separate test class for each model class, and +We write tests for the ``model`` classes and the ``appmaker``. Changing +``tests.py``, we'll write a separate test class for each ``model`` class, and we'll write a test class for the ``appmaker``. To do so, we'll retain the ``tutorial.tests.ViewTests`` class that was -generated as part of the ``zodb`` scaffold. We'll add three test -classes: one for the ``Page`` model named ``PageModelTests``, one for the -``Wiki`` model named ``WikiModelTests``, and one for the appmaker named -``AppmakerTests``. +generated as part of the ``zodb`` scaffold. We'll add three test classes: one +for the ``Page`` model named ``PageModelTests``, one for the ``Wiki`` model +named ``WikiModelTests``, and one for the appmaker named ``AppmakerTests``. -Test the Views +Test the views ============== We'll modify our ``tests.py`` file, adding tests for each view function we -added above. As a result, we'll *delete* the ``ViewTests`` test in the file, -and add four other test classes: ``ViewWikiTests``, ``ViewPageTests``, -``AddPageTests``, and ``EditPageTests``. These test the ``view_wiki``, -``view_page``, ``add_page``, and ``edit_page`` views respectively. - +added previously. As a result, we'll *delete* the ``ViewTests`` class that +the ``zodb`` scaffold provided, and add four other test classes: +``ViewWikiTests``, ``ViewPageTests``, ``AddPageTests``, and ``EditPageTests``. +These test the ``view_wiki``, ``view_page``, ``add_page``, and ``edit_page`` +views. Functional tests ================ -We test the whole application, covering security aspects that are not +We'll test the whole application, covering security aspects that are not tested in the unit tests, like logging in, logging out, checking that the ``viewer`` user cannot add or edit pages, but the ``editor`` user can, and so on. @@ -41,14 +39,14 @@ can, and so on. View the results of all our edits to ``tests.py`` ================================================= -Once we're done with the ``tests.py`` module, it will look a lot like the -below: +Open the ``tutorial/tests.py`` module, and edit it such that it appears as +follows: .. literalinclude:: src/tests/tutorial/tests.py :linenos: :language: python -Running the Tests +Running the tests ================= We can run these tests by using ``setup.py test`` in the same way we did in @@ -62,7 +60,7 @@ Change the ``requires`` list in ``setup.py`` to include ``WebTest``. :lines: 11-22 :emphasize-lines: 11 -After we've added a dependency on WebTest in ``setup.py``, we need to rerun +After we've added a dependency on WebTest in ``setup.py``, we need to run ``setup.py develop`` to get WebTest installed into our virtualenv. Assuming our shell's current working directory is the "tutorial" distribution directory: @@ -94,7 +92,7 @@ On Windows: c:\pyramidtut\tutorial> %VENV%\Scripts\python setup.py test -q -The expected result looks something like: +The expected result should look like the following: .. code-block:: text diff --git a/docs/tutorials/wiki2/authorization.rst b/docs/tutorials/wiki2/authorization.rst index 90a89d63e..d2ad7a9ca 100644 --- a/docs/tutorials/wiki2/authorization.rst +++ b/docs/tutorials/wiki2/authorization.rst @@ -1,27 +1,25 @@ .. _wiki2_adding_authorization: ==================== -Adding Authorization +Adding authorization ==================== :app:`Pyramid` provides facilities for :term:`authentication` and -:term:`authorization`. We'll make use of both features to provide security -to our application. Our application currently allows anyone with access to -the server to view, edit, and add pages to our wiki. We'll change that -to allow only people who are members of a *group* named ``group:editors`` -to add and edit wiki pages but we'll continue allowing -anyone with access to the server to view pages. - -We will also add a login page and a logout link on all the -pages. The login page will be shown when a user is denied -access to any of the views that require permission, instead of -a default "403 Forbidden" page. +::term:`authorization`. We'll make use of both features to provide security +:to our application. Our application currently allows anyone with access to +:the server to view, edit, and add pages to our wiki. We'll change that to +:allow only people who are members of a *group* named ``group:editors`` to add +:and edit wiki pages but we'll continue allowing anyone with access to the +:server to view pages. + +We will also add a login page and a logout link on all the pages. The login +page will be shown when a user is denied access to any of the views that +require permission, instead of a default "403 Forbidden" page. We will implement the access control with the following steps: * Add users and groups (``security.py``, a new module). -* Add an :term:`ACL` (``models.py`` and - ``__init__.py``). +* Add an :term:`ACL` (``models.py`` and ``__init__.py``). * Add an :term:`authentication policy` and an :term:`authorization policy` (``__init__.py``). * Add :term:`permission` declarations to the ``edit_page`` and ``add_page`` @@ -32,12 +30,13 @@ Then we will add the login and logout feature: * Add routes for /login and /logout (``__init__.py``). * Add ``login`` and ``logout`` views (``views.py``). * Add a login template (``login.pt``). -* Make the existing views return a ``logged_in`` flag to the renderer (``views.py``). +* Make the existing views return a ``logged_in`` flag to the renderer + (``views.py``). * Add a "Logout" link to be shown when logged in and viewing or editing a page (``view.pt``, ``edit.pt``). -Access Control +Access control -------------- Add users and groups @@ -53,21 +52,18 @@ following content: The ``groupfinder`` function accepts a userid and a request and returns one of these values: -- If the userid exists in the system, it will return a - sequence of group identifiers (or an empty sequence if the user - isn't a member of any groups). -- If the userid *does not* exist in the system, it will - return ``None``. +- If the userid exists in the system, it will return a sequence of group + identifiers (or an empty sequence if the user isn't a member of any groups). +- If the userid *does not* exist in the system, it will return ``None``. For example, ``groupfinder('editor', request )`` returns ``['group:editor']``, -``groupfinder('viewer', request)`` returns [], and ``groupfinder('admin', request)`` -returns ``None``. We will use ``groupfinder()`` as an :term:`authentication policy` -"callback" that will provide the :term:`principal` or principals -for a user. +``groupfinder('viewer', request)`` returns ``[]``, and ``groupfinder('admin', +request)`` returns ``None``. We will use ``groupfinder()`` as an +:term:`authentication policy` "callback" that will provide the +:term:`principal` or principals for a user. -In a production system, user and group -data will most often come from a database, but here we use "dummy" -data to represent user and groups sources. +In a production system, user and group data will most often come from a +database, but here we use "dummy" data to represent user and groups sources. Add an ACL ~~~~~~~~~~ @@ -80,62 +76,60 @@ statement at the head: :linenos: :language: python -Add the following class definition: +Add the following class definition at the end: .. literalinclude:: src/authorization/tutorial/models.py :lines: 33-37 :linenos: + :lineno-start: 33 :language: python -We import :data:`~pyramid.security.Allow`, an action that -means that permission is allowed:, and -:data:`~pyramid.security.Everyone`, a special :term:`principal` -that is associated to all requests. Both are used in the +We import :data:`~pyramid.security.Allow`, an action that means that +permission is allowed, and :data:`~pyramid.security.Everyone`, a special +:term:`principal` that is associated to all requests. Both are used in the :term:`ACE` entries that make up the ACL. -The ACL is a list that needs to be named `__acl__` and be an -attribute of a class. We define an :term:`ACL` with two -:term:`ACE` entries: the first entry allows any user the `view` -permission. The second entry allows the ``group:editors`` -principal the `edit` permission. +The ACL is a list that needs to be named `__acl__` and be an attribute of a +class. We define an :term:`ACL` with two :term:`ACE` entries: the first entry +allows any user the `view` permission. The second entry allows the +``group:editors`` principal the `edit` permission. -The ``RootFactory`` class that contains the ACL is a :term:`root factory`. -We need to associate it to our :app:`Pyramid` application, so the ACL is -provided to each view in the :term:`context` of the request, as -the ``context`` attribute. +The ``RootFactory`` class that contains the ACL is a :term:`root factory`. We +need to associate it to our :app:`Pyramid` application, so the ACL is provided +to each view in the :term:`context` of the request as the ``context`` +attribute. -Open ``tutorial/tutorial/__init__.py`` and add a ``root_factory`` -parameter to our :term:`Configurator` constructor, that points to -the class we created above: +Open ``tutorial/tutorial/__init__.py`` and add a ``root_factory`` parameter to +our :term:`Configurator` constructor, that points to the class we created +above: .. literalinclude:: src/authorization/tutorial/__init__.py :lines: 24-25 :linenos: :emphasize-lines: 2 + :lineno-start: 16 :language: python -(Only the highlighted line needs to be added.) - -We are now providing the ACL to the application. See -:ref:`assigning_acls` for more information about what an -:term:`ACL` represents. +Only the highlighted line needs to be added. -.. note:: +We are now providing the ACL to the application. See :ref:`assigning_acls` +for more information about what an :term:`ACL` represents. - Although we don't use the functionality here, the ``factory`` used - to create route contexts may differ per-route as opposed to globally. See - the ``factory`` argument to - :meth:`pyramid.config.Configurator.add_route` for more info. +.. 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 + the ``factory`` argument to :meth:`pyramid.config.Configurator.add_route` + for more info. -Add Authentication and Authorization Policies +Add authentication and authorization policies ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ -Open ``tutorial/__init__.py`` and -add these import statements: +Open ``tutorial/tutorial/__init__.py`` and add the highlighted import +statements: .. literalinclude:: src/authorization/tutorial/__init__.py - :lines: 2-3,7 + :lines: 1-7 :linenos: + :emphasize-lines: 2-3,7 :language: python Now add those policies to the configuration: @@ -143,17 +137,18 @@ Now add those policies to the configuration: .. literalinclude:: src/authorization/tutorial/__init__.py :lines: 21-27 :linenos: + :lineno-start: 21 :emphasize-lines: 1-3,6-7 :language: python -(Only the highlighted lines need to be added.) +Only the highlighted lines need to be added. -We are enabling an ``AuthTktAuthenticationPolicy``, which is based in an -auth ticket that may be included in the request. -We are also enabling an ``ACLAuthorizationPolicy``, which uses an ACL to -determine the *allow* or *deny* outcome for a view. +We are enabling an ``AuthTktAuthenticationPolicy``, which is based in an auth +ticket that may be included in the request. We are also enabling an +``ACLAuthorizationPolicy``, which uses an ACL to determine the *allow* or +*deny* outcome for a view. -Note that the :class:`~pyramid.authentication.AuthTktAuthenticationPolicy` +Note that the :class:`pyramid.authentication.AuthTktAuthenticationPolicy` constructor accepts two arguments: ``secret`` and ``callback``. ``secret`` is a string representing an encryption key used by the "authentication ticket" machinery represented by this policy: it is required. The ``callback`` is the @@ -161,50 +156,57 @@ machinery represented by this policy: it is required. The ``callback`` is the Add permission declarations ~~~~~~~~~~~~~~~~~~~~~~~~~~~ +Open ``tutorial/tutorial/views.py`` and add a ``permission='edit'`` parameter +to the ``@view_config`` decorators for ``add_page()`` and ``edit_page()``: -Add a ``permission='edit'`` parameter to the ``@view_config`` -decorator for ``add_page()`` and ``edit_page()``, for example: - -.. code-block:: python - :linenos: - :emphasize-lines: 2 +.. literalinclude:: src/authorization/tutorial/views.py + :lines: 60-61 + :emphasize-lines: 1-2 + :language: python - @view_config(route_name='add_page', renderer='templates/edit.pt', - permission='edit') +.. literalinclude:: src/authorization/tutorial/views.py + :lines: 75-76 + :emphasize-lines: 1-2 + :language: python -(Only the highlighted line needs to be added.) +Only the highlighted lines, along with their preceding commas, need to be +edited and added. -The result is that only users who possess the ``edit`` -permission at the time of the request may invoke those two views. +The result is that only users who possess the ``edit`` permission at the time +of the request may invoke those two views. -Add a ``permission='view'`` parameter to the ``@view_config`` -decorator for ``view_wiki()`` and ``view_page()``, like this: +Add a ``permission='view'`` parameter to the ``@view_config`` decorator for +``view_wiki()`` and ``view_page()`` as follows: -.. code-block:: python - :linenos: - :emphasize-lines: 2 +.. literalinclude:: src/authorization/tutorial/views.py + :lines: 30-31 + :emphasize-lines: 1-2 + :language: python - @view_config(route_name='view_page', renderer='templates/view.pt', - permission='view') +.. literalinclude:: src/authorization/tutorial/views.py + :lines: 36-37 + :emphasize-lines: 1-2 + :language: python -(Only the highlighted line needs to be added.) +Only the highlighted lines, along with their preceding commas, need to be +edited and added. This allows anyone to invoke these two views. -We are done with the changes needed to control access. The -changes that follow will add the login and logout feature. +We are done with the changes needed to control access. The changes that +follow will add the login and logout feature. -Login, Logout +Login, logout ------------- Add routes for /login and /logout ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ -Go back to ``tutorial/tutorial/__init__.py`` and add these two -routes: +Go back to ``tutorial/tutorial/__init__.py`` and add these two routes as +highlighted: .. literalinclude:: src/authorization/tutorial/__init__.py - :lines: 31-32 - :linenos: + :lines: 30-33 + :emphasize-lines: 2-3 :language: python .. note:: The preceding lines must be added *before* the following @@ -212,202 +214,193 @@ routes: .. literalinclude:: src/authorization/tutorial/__init__.py :lines: 33 - :linenos: :language: python This is because ``view_page``'s route definition uses a catch-all "replacement marker" ``/{pagename}`` (see :ref:`route_pattern_syntax`) - which will catch any route that was not already caught by any - route listed above it in ``__init__.py``. Hence, for ``login`` and - ``logout`` views to have the opportunity of being matched - (or "caught"), they must be above ``/{pagename}``. + which will catch any route that was not already caught by any route listed + above it in ``__init__.py``. Hence, for ``login`` and ``logout`` views to + have the opportunity of being matched (or "caught"), they must be above + ``/{pagename}``. -Add Login and Logout Views +Add login and logout views ~~~~~~~~~~~~~~~~~~~~~~~~~~ -We'll add a ``login`` view which renders a login form and processes -the post from the login form, checking credentials. +We'll add a ``login`` view which renders a login form and processes the post +from the login form, checking credentials. -We'll also add a ``logout`` view callable to our application and -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 also add a ``logout`` view callable to our application and provide a +link to it. This view will clear the credentials of the logged in user and +redirect back to the front page. -Add the following import statements to the -head of ``tutorial/tutorial/views.py``: +Add the following import statements to the head of +``tutorial/tutorial/views.py``: .. literalinclude:: src/authorization/tutorial/views.py :lines: 9-19 - :linenos: - :emphasize-lines: 3,6-9,11 + :emphasize-lines: 1-11 :language: python -(Only the highlighted lines need to be added.) +All the highlighted lines need to be added or edited. -:meth:`~pyramid.view.forbidden_view_config` will be used -to customize the default 403 Forbidden page. -:meth:`~pyramid.security.remember` and -:meth:`~pyramid.security.forget` help to create and -expire an auth ticket cookie. +:meth:`~pyramid.view.forbidden_view_config` will be used to customize the +default 403 Forbidden page. :meth:`~pyramid.security.remember` and +:meth:`~pyramid.security.forget` help to create and expire an auth ticket +cookie. -Now add the ``login`` and ``logout`` views: +Now add the ``login`` and ``logout`` views at the end of the file: .. literalinclude:: src/authorization/tutorial/views.py :lines: 91-123 - :linenos: :language: python -``login()`` is decorated with two decorators: +``login()`` has two decorators: -- a ``@view_config`` decorator which associates it with the - ``login`` route and makes it visible when we visit ``/login``, -- a ``@forbidden_view_config`` decorator which turns it into - an :term:`forbidden view`. ``login()`` will be invoked - when a users tries to execute a view callable that - they are not allowed to. For example, if a user has not logged in - and tries to add or edit a Wiki page, he will be shown the - login form before being allowed to continue on. +- a ``@view_config`` decorator which associates it with the ``login`` route + and makes it visible when we visit ``/login``, +- a ``@forbidden_view_config`` decorator which turns it into a + :term:`forbidden view`. ``login()`` will be invoked when a user tries to + execute a view callable for which they lack authorization. For example, if + a user has not logged in and tries to add or edit a Wiki page, they will be + shown the login form before being allowed to continue. -The order of these two :term:`view configuration` decorators -is unimportant. +The order of these two :term:`view configuration` decorators is unimportant. -``logout()`` is decorated with a ``@view_config`` decorator -which associates it with the ``logout`` route. It will be -invoked when we visit ``/logout``. +``logout()`` is decorated with a ``@view_config`` decorator which associates +it with the ``logout`` route. It will be invoked when we visit ``/logout``. Add the ``login.pt`` Template ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ -Create ``tutorial/tutorial/templates/login.pt`` with the following -content: +Create ``tutorial/tutorial/templates/login.pt`` with the following content: .. literalinclude:: src/authorization/tutorial/templates/login.pt - :language: xml + :language: html -The above template is referred to within the login view we just -added to ``views.py``. +The above template is referenced in the login view that we just added in +``views.py``. -Return a logged_in flag to the renderer -~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +Return a ``logged_in`` flag to the renderer +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ -Add a ``logged_in`` parameter to the return value of -``view_page()``, ``edit_page()`` and ``add_page()``, -like this: +Open ``tutorial/tutorial/views.py`` again. Add a ``logged_in`` parameter to +the return value of ``view_page()``, ``edit_page()``, and ``add_page()`` as +follows: -.. code-block:: python - :linenos: - :emphasize-lines: 4 +.. literalinclude:: src/authorization/tutorial/views.py + :lines: 57-58 + :emphasize-lines: 1-2 + :language: python - return dict(page = page, - content = content, - edit_url = edit_url, - logged_in = request.authenticated_userid) +.. literalinclude:: src/authorization/tutorial/views.py + :lines: 72-73 + :emphasize-lines: 1-2 + :language: python -(Only the highlighted line needs to be added.) +.. literalinclude:: src/authorization/tutorial/views.py + :lines: 85-89 + :emphasize-lines: 3-4 + :language: python -The :meth:`~pyramid.request.Request.authenticated_userid` property will be -``None`` if the user is not authenticated. +Only the highlighted lines need to be added or edited. + +The :meth:`pyramid.request.Request.authenticated_userid` will be ``None`` if +the user is not authenticated, or a userid if the user is authenticated. Add a "Logout" link when logged in ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ Open ``tutorial/tutorial/templates/edit.pt`` and -``tutorial/tutorial/templates/view.pt`` and add this within the -``<div id="right" class="app-welcome align-right">`` div: - -.. code-block:: xml +``tutorial/tutorial/templates/view.pt`` and add the following code as +indicated by the highlighted lines. - <span tal:condition="logged_in"> - <a href="${request.application_url}/logout">Logout</a> - </span> +.. literalinclude:: src/authorization/tutorial/templates/edit.pt + :lines: 34-38 + :emphasize-lines: 3-5 + :language: html -The attribute ``tal:condition="logged_in"`` will make the element be -included when ``logged_in`` is any user id. The link will invoke -the logout view. The above element will not be included if ``logged_in`` -is ``None``, such as when a user is not authenticated. +The attribute ``tal:condition="logged_in"`` will make the element be included +when ``logged_in`` is any user id. The link will invoke the logout view. The +above element will not be included if ``logged_in`` is ``None``, such as when +a user is not authenticated. -Seeing Our Changes ------------------- +Reviewing our changes +--------------------- -Our ``tutorial/tutorial/__init__.py`` will look something like this -when we're done: +Our ``tutorial/tutorial/__init__.py`` will look like this when we're done: .. literalinclude:: src/authorization/tutorial/__init__.py :linenos: :emphasize-lines: 2-3,7,21-23,25-27,31-32 :language: python -(Only the highlighted lines need to be added.) +Only the highlighted lines need to be added or edited. -Our ``tutorial/tutorial/models.py`` will look something like this -when we're done: +Our ``tutorial/tutorial/models.py`` will look like this when we're done: .. literalinclude:: src/authorization/tutorial/models.py :linenos: :emphasize-lines: 1-4,33-37 :language: python -(Only the highlighted lines need to be added.) +Only the highlighted lines need to be added or edited. -Our ``tutorial/tutorial/views.py`` will look something like this -when we're done: +Our ``tutorial/tutorial/views.py`` will look like this when we're done: .. literalinclude:: src/authorization/tutorial/views.py :linenos: - :emphasize-lines: 11,14-19,25,31,37,58,61,73,76,88,91-117,119-123 + :emphasize-lines: 9-11,14-19,25,31,37,58,61,73,76,88,91-117,119-123 :language: python -(Only the highlighted lines need to be added.) +Only the highlighted lines need to be added or edited. -Our ``tutorial/tutorial/templates/edit.pt`` template will look -something like this when we're done: +Our ``tutorial/tutorial/templates/edit.pt`` template will look like this when +we're done: .. literalinclude:: src/authorization/tutorial/templates/edit.pt :linenos: - :emphasize-lines: 41-43 - :language: xml + :emphasize-lines: 36-38 + :language: html -(Only the highlighted lines need to be added.) +Only the highlighted lines need to be added or edited. -Our ``tutorial/tutorial/templates/view.pt`` template will look -something like this when we're done: +Our ``tutorial/tutorial/templates/view.pt`` template will look like this when +we're done: .. literalinclude:: src/authorization/tutorial/templates/view.pt :linenos: - :emphasize-lines: 41-43 - :language: xml + :emphasize-lines: 36-38 + :language: html -(Only the highlighted lines need to be added.) +Only the highlighted lines need to be added or edited. -Viewing the Application in a Browser +Viewing the application in a browser ------------------------------------ We can finally examine our application in a browser (See -:ref:`wiki2-start-the-application`). Launch a browser and visit -each of the following URLs, check that the result is as expected: - -- http://localhost:6543/ invokes the - ``view_wiki`` view. This always redirects to the ``view_page`` view - of the FrontPage page object. It is executable by any user. - -- http://localhost:6543/FrontPage invokes - the ``view_page`` view of the FrontPage page object. - -- http://localhost:6543/FrontPage/edit_page - invokes the edit view for the FrontPage object. It is executable by - only the ``editor`` user. If a different user (or the anonymous - user) invokes it, a login form will be displayed. Supplying the - credentials with the username ``editor``, password ``editor`` will - display the edit page form. - -- http://localhost:6543/add_page/SomePageName - invokes the add view for a page. It is executable by only - the ``editor`` user. If a different user (or the anonymous user) - invokes it, a login form will be displayed. Supplying the - credentials with the username ``editor``, password ``editor`` will - display the edit page form. - -- After logging in (as a result of hitting an edit or add page - and submitting the login form with the ``editor`` - credentials), we'll see a Logout link in the upper right hand - corner. When we click it, we're logged out, and redirected - back to the front page. +:ref:`wiki2-start-the-application`). Launch a browser and visit each of the +following URLs, checking that the result is as expected: + +- http://localhost:6543/ invokes the ``view_wiki`` view. This always + redirects to the ``view_page`` view of the ``FrontPage`` page object. It + is executable by any user. + +- http://localhost:6543/FrontPage invokes the ``view_page`` view of the + ``FrontPage`` page object. + +- http://localhost:6543/FrontPage/edit_page invokes the edit view for the + FrontPage object. It is executable by only the ``editor`` user. If a + different user (or the anonymous user) invokes it, a login form will be + displayed. Supplying the credentials with the username ``editor``, password + ``editor`` will display the edit page form. + +- http://localhost:6543/add_page/SomePageName invokes the add view for a page. + It is executable by only the ``editor`` user. If a different user (or the + anonymous user) invokes it, a login form will be displayed. Supplying the + credentials with the username ``editor``, password ``editor`` will display + the edit page form. + +- After logging in (as a result of hitting an edit or add page and submitting + the login form with the ``editor`` credentials), we'll see a Logout link in + the upper right hand corner. When we click it, we're logged out, and + redirected back to the front page. diff --git a/docs/tutorials/wiki2/background.rst b/docs/tutorials/wiki2/background.rst index 1f9582903..b8afb8305 100644 --- a/docs/tutorials/wiki2/background.rst +++ b/docs/tutorials/wiki2/background.rst @@ -2,10 +2,12 @@ Background ========== -This tutorial presents a :app:`Pyramid` application that uses technologies -which will be familiar to someone with SQL database experience. It uses +This version of the :app:`Pyramid` wiki tutorial presents a +:app:`Pyramid` application that uses technologies which will be +familiar to someone with SQL database experience. It uses :term:`SQLAlchemy` as a persistence mechanism and :term:`url dispatch` to map -URLs to code. +URLs to code. It can also be followed by people without any prior +Python web framework experience. To code along with this tutorial, the developer will need a UNIX machine with development tools (Mac OS X with XCode, any Linux or BSD diff --git a/docs/tutorials/wiki2/basiclayout.rst b/docs/tutorials/wiki2/basiclayout.rst index 05781c044..623882516 100644 --- a/docs/tutorials/wiki2/basiclayout.rst +++ b/docs/tutorials/wiki2/basiclayout.rst @@ -4,16 +4,17 @@ Basic Layout The starter files generated by the ``alchemy`` scaffold are very basic, but they provide a good orientation for the high-level patterns common to most -:term:`url dispatch` -based :app:`Pyramid` projects. +:term:`URL dispatch`-based :app:`Pyramid` projects. -Application Configuration with ``__init__.py`` +Application configuration with ``__init__.py`` ---------------------------------------------- A directory on disk can be turned into a Python :term:`package` by containing an ``__init__.py`` file. Even if empty, this marks a directory as a Python -package. We use ``__init__.py`` both as a marker indicating the directory -it's contained within is a package, and to contain configuration code. +package. We use ``__init__.py`` both as a marker, indicating the directory +in which it's contained is a package, and to contain application configuration +code. Open ``tutorial/tutorial/__init__.py``. It should already contain the following: @@ -114,7 +115,7 @@ used when the URL is ``/``: :lines: 19 :language: py -Since this route has a ``pattern`` equalling ``/`` it is the route that will +Since this route has a ``pattern`` equaling ``/`` it is the route that will be matched when the URL ``/`` is visited, e.g. ``http://localhost:6543/``. ``main`` next calls the ``scan`` method of the configurator @@ -136,7 +137,7 @@ Finally, ``main`` is finished configuring things, so it uses the :lines: 21 :language: py -View Declarations via ``views.py`` +View declarations via ``views.py`` ---------------------------------- The main function of a web framework is mapping each URL pattern to code (a @@ -167,7 +168,7 @@ Note that ``my_view()`` accepts a single argument named ``request``. This is the standard call signature for a Pyramid :term:`view callable`. Remember in our ``__init__.py`` when we executed the -:meth:`pyramid.config.Configurator.scan` method, i.e. ``config.scan()``? The +:meth:`pyramid.config.Configurator.scan` method ``config.scan()``? The purpose of calling the scan method was to find and process this ``@view_config`` decorator in order to create a view configuration within our application. Without being processed by ``scan``, the decorator effectively @@ -175,7 +176,7 @@ does nothing. ``@view_config`` is inert without being detected via a :term:`scan`. The sample ``my_view()`` created by the scaffold uses a ``try:`` and ``except:`` -clause, to detect if there is a problem accessing the project database and +clause to detect if there is a problem accessing the project database and provide an alternate error response. That response will include the text shown at the end of the file, which will be displayed in the browser to inform the user about possible actions to take to solve the problem. diff --git a/docs/tutorials/wiki2/definingmodels.rst b/docs/tutorials/wiki2/definingmodels.rst index e30af12b2..b2d9bf83a 100644 --- a/docs/tutorials/wiki2/definingmodels.rst +++ b/docs/tutorials/wiki2/definingmodels.rst @@ -7,26 +7,27 @@ be to define a :term:`domain model` constructor representing a wiki page. We'll do this inside our ``models.py`` file. -Making Edits to ``models.py`` ------------------------------ +Edit ``models.py`` +------------------ .. note:: There is nothing special about the filename ``models.py``. A - project may have many models throughout its codebase in arbitrarily-named + project may have many models throughout its codebase in arbitrarily named files. Files implementing models often have ``model`` in their filenames - (or they may live in a Python subpackage of your application package named - ``models``) , but this is only by convention. + or they may live in a Python subpackage of your application package named + ``models``, but this is only by convention. -Open ``tutorial/tutorial/models.py`` file and edit it to look like the +Open ``tutorial/tutorial/models.py`` file and edit it to look like the following: .. literalinclude:: src/models/tutorial/models.py :linenos: :language: py - :emphasize-lines: 20-22,25 + :emphasize-lines: 20-22,24,25 -(The highlighted lines are the ones that need to be changed.) +The highlighted lines are the ones that need to be changed, as well as +removing lines that reference ``Index``. The first thing we've done is remove the stock ``MyModel`` class from the generated ``models.py`` file. The ``MyModel`` class is only a @@ -44,74 +45,74 @@ this class inherits from an instance of 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``, ``name`` and -``data`` (all instances of :class:`sqlalchemy.schema.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. +``Page`` class will also have class-level attributes named ``id``, ``name`` +and ``data`` (all instances of :class:`sqlalchemy.schema.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. Changing ``scripts/initializedb.py`` ------------------------------------ We haven't looked at the details of this file yet, but within the ``scripts`` -directory of your ``tutorial`` package is a file named ``initializedb.py``. Code -in this file is executed whenever we run the ``initialize_tutorial_db`` command -(as we did in the installation step of this tutorial). +directory of your ``tutorial`` package is a file named ``initializedb.py``. +Code in this file is executed whenever we run the ``initialize_tutorial_db`` +command, as we did in the installation step of this tutorial. -Since we've changed our model, we need to make changes to our ``initializedb.py`` -script. In particular, we'll replace our import of ``MyModel`` with one of -``Page`` and we'll change the very end of the script to create a ``Page`` -rather than a ``MyModel`` and add it to our ``DBSession``. +Since we've changed our model, we need to make changes to our +``initializedb.py`` script. In particular, we'll replace our import of +``MyModel`` with one of ``Page`` and we'll change the very end of the script +to create a ``Page`` rather than a ``MyModel`` and add it to our +``DBSession``. -Open ``tutorial/tutorial/scripts/initializedb.py`` and edit it to look like the -following: +Open ``tutorial/tutorial/scripts/initializedb.py`` and edit it to look like +the following: .. literalinclude:: src/models/tutorial/scripts/initializedb.py :linenos: :language: python - :emphasize-lines: 14,36 + :emphasize-lines: 14,31,36 -(Only the highlighted lines need to be changed.) +Only the highlighted lines need to be changed, as well as removing the lines +referencing ``pyramid.scripts.common`` and ``options`` under the ``main`` +function. -Installing the Project and re-initializing the Database +Installing the project and re-initializing the database ------------------------------------------------------- Because our model has changed, in order to reinitialize the database, we need -to rerun the ``initialize_tutorial_db`` command to pick up the changes you've made -to both the models.py file and to the initializedb.py file. -See :ref:`initialize_db_wiki2` for instructions. +to rerun the ``initialize_tutorial_db`` command to pick up the changes you've +made to both the models.py file and to the initializedb.py file. See +:ref:`initialize_db_wiki2` for instructions. Success will look something like this:: - 2011-11-27 01:22:45,277 INFO [sqlalchemy.engine.base.Engine][MainThread] - PRAGMA table_info("pages") - 2011-11-27 01:22:45,277 INFO [sqlalchemy.engine.base.Engine][MainThread] () - 2011-11-27 01:22:45,277 INFO [sqlalchemy.engine.base.Engine][MainThread] - CREATE TABLE pages ( - id INTEGER NOT NULL, - name TEXT, - data TEXT, - PRIMARY KEY (id), - UNIQUE (name) - ) - - - 2011-11-27 01:22:45,278 INFO [sqlalchemy.engine.base.Engine][MainThread] () - 2011-11-27 01:22:45,397 INFO [sqlalchemy.engine.base.Engine][MainThread] - COMMIT - 2011-11-27 01:22:45,400 INFO [sqlalchemy.engine.base.Engine][MainThread] - BEGIN (implicit) - 2011-11-27 01:22:45,401 INFO [sqlalchemy.engine.base.Engine][MainThread] - INSERT INTO pages (name, data) VALUES (?, ?) - 2011-11-27 01:22:45,401 INFO [sqlalchemy.engine.base.Engine][MainThread] - ('FrontPage', 'This is the front page') - 2011-11-27 01:22:45,402 INFO [sqlalchemy.engine.base.Engine][MainThread] - COMMIT - -Viewing the Application in a Browser ------------------------------------- + 2015-05-24 15:34:14,542 INFO [sqlalchemy.engine.base.Engine:1192][MainThread] SELECT CAST('test plain returns' AS VARCHAR(60)) AS anon_1 + 2015-05-24 15:34:14,542 INFO [sqlalchemy.engine.base.Engine:1193][MainThread] () + 2015-05-24 15:34:14,543 INFO [sqlalchemy.engine.base.Engine:1192][MainThread] SELECT CAST('test unicode returns' AS VARCHAR(60)) AS anon_1 + 2015-05-24 15:34:14,543 INFO [sqlalchemy.engine.base.Engine:1193][MainThread] () + 2015-05-24 15:34:14,543 INFO [sqlalchemy.engine.base.Engine:1097][MainThread] PRAGMA table_info("pages") + 2015-05-24 15:34:14,544 INFO [sqlalchemy.engine.base.Engine:1100][MainThread] () + 2015-05-24 15:34:14,544 INFO [sqlalchemy.engine.base.Engine:1097][MainThread] + CREATE TABLE pages ( + id INTEGER NOT NULL, + name TEXT, + data TEXT, + PRIMARY KEY (id), + UNIQUE (name) + ) + + + 2015-05-24 15:34:14,545 INFO [sqlalchemy.engine.base.Engine:1100][MainThread] () + 2015-05-24 15:34:14,546 INFO [sqlalchemy.engine.base.Engine:686][MainThread] COMMIT + 2015-05-24 15:34:14,548 INFO [sqlalchemy.engine.base.Engine:646][MainThread] BEGIN (implicit) + 2015-05-24 15:34:14,549 INFO [sqlalchemy.engine.base.Engine:1097][MainThread] INSERT INTO pages (name, data) VALUES (?, ?) + 2015-05-24 15:34:14,549 INFO [sqlalchemy.engine.base.Engine:1100][MainThread] ('FrontPage', 'This is the front page') + 2015-05-24 15:34:14,550 INFO [sqlalchemy.engine.base.Engine:686][MainThread] COMMIT + +View 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 diff --git a/docs/tutorials/wiki2/definingviews.rst b/docs/tutorials/wiki2/definingviews.rst index 49dbed50f..0b495445a 100644 --- a/docs/tutorials/wiki2/definingviews.rst +++ b/docs/tutorials/wiki2/definingviews.rst @@ -11,8 +11,8 @@ The request object has a dictionary as an attribute named ``matchdict``. A substrings of the path in the :term:`request` URL. For instance, if a call to :meth:`pyramid.config.Configurator.add_route` has the pattern ``/{one}/{two}``, and a user visits ``http://example.com/foo/bar``, our pattern would be matched -against ``/foo/bar`` and the ``matchdict`` would look like: ``{'one':'foo', -'two':'bar'}`` +against ``/foo/bar`` and the ``matchdict`` would look like ``{'one':'foo', +'two':'bar'}``. Declaring Dependencies in Our ``setup.py`` File =============================================== @@ -23,26 +23,27 @@ application was generated by the ``pcreate`` 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 ``requires`` parameter in ``setup()``. +package's ``setup.py`` file by assigning this dependency to the ``requires`` +parameter in the ``setup()`` function. Open ``tutorial/setup.py`` and edit it to look like the following: .. literalinclude:: src/views/setup.py :linenos: - :language: python :emphasize-lines: 20 + :language: python -(Only the highlighted line needs to be added.) +Only the highlighted line needs to be added. Running ``setup.py develop`` ============================ -Since a new software dependency was added, you will need to rerun ``python -setup.py develop`` inside the root of the ``tutorial`` package to obtain and -register the newly added dependency distribution. +Since a new software dependency was added, you will need to run ``python +setup.py develop`` again inside the root of the ``tutorial`` package to obtain +and register the newly added dependency distribution. Make sure your current working directory is the root of the project (the -directory in which setup.py lives) and execute the following command. +directory in which ``setup.py`` lives) and execute the following command. On UNIX: @@ -63,21 +64,24 @@ like:: Finished processing dependencies for tutorial==0.0 -Changing the ``views.py`` File -============================== +Adding view functions in ``views.py`` +===================================== -It's time for a major change. Open ``tutorial/tutorial/views.py`` and edit it to look like the following: +It's time for a major change. Open ``tutorial/tutorial/views.py`` and edit it +to look like the following: .. literalinclude:: src/views/tutorial/views.py :linenos: :language: python - :emphasize-lines: 1-7,12,15-70 + :emphasize-lines: 1-7,14,16-72 -(The highlighted lines are the ones that need to be added or edited.) +The highlighted lines need to be added or edited. -We got rid of the ``my_view`` view function and its decorator that was -added when we originally rendered the ``alchemy`` scaffold. It was only an -example and isn't relevant to our application. +We added some imports and created a regular expression to find "WikiWords". + +We got rid of the ``my_view`` view function and its decorator that was added +when we originally rendered the ``alchemy`` scaffold. It was only an example +and isn't relevant to our application. Then we added four :term:`view callable` functions to our ``views.py`` module: @@ -87,13 +91,12 @@ module: * ``add_page()`` - Allows the user to add a page. * ``edit_page()`` - Allows the user to edit a page. -We'll describe each one briefly and show the resulting ``views.py`` file -afterward. +We'll describe each one briefly in the following sections. .. note:: There is nothing special about the filename ``views.py``. A project may - have many view callables throughout its codebase in arbitrarily-named + 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. @@ -101,39 +104,44 @@ afterward. The ``view_wiki`` view function ------------------------------- -``view_wiki()`` is the :term:`default view` that gets called when a request -is made to the root URL of our wiki. It always redirects to -a URL which represents the path to our "FrontPage". +Following is the code for the ``view_wiki`` view function and its decorator: .. literalinclude:: src/views/tutorial/views.py - :lines: 18-21 + :lines: 20-24 + :lineno-start: 20 :linenos: :language: python -``view_wiki()`` returns an instance of the -:class:`pyramid.httpexceptions.HTTPFound` class (instances of which implement -the :class:`pyramid.interfaces.IResponse` interface like -:class:`pyramid.response.Response` does). +``view_wiki()`` is the :term:`default view` that gets called when a request is +made to the root URL of our wiki. It always redirects to an URL which +represents the path to our "FrontPage". -It uses the :meth:`pyramid.request.Request.route_url` API to construct a -URL to the ``FrontPage`` page (e.g. ``http://localhost:6543/FrontPage``), which -is used as the "location" of the ``HTTPFound`` response, forming an HTTP redirect. +The ``view_wiki`` view callable always redirects to the URL of a Page resource +named "FrontPage". To do so, it returns an instance of the +:class:`pyramid.httpexceptions.HTTPFound` class (instances of which implement +the :class:`pyramid.interfaces.IResponse` interface, like +:class:`pyramid.response.Response` does). It uses the +:meth:`pyramid.request.Request.route_url` API to construct an URL to the +``FrontPage`` page (i.e., ``http://localhost:6543/FrontPage``), and uses it as +the "location" of the ``HTTPFound`` response, forming an HTTP redirect. The ``view_page`` view function ------------------------------- -``view_page()`` is used to display a single page of our -wiki. It renders the :term:`reStructuredText` body of a page (stored as -the ``data`` attribute of a ``Page`` model object) as HTML. Then it substitutes an -HTML anchor for each *WikiWord* reference in the rendered HTML using a -compiled regular expression. +Here is the code for the ``view_page`` view function and its decorator: .. literalinclude:: src/views/tutorial/views.py - :lines: 23-43 + :lines: 25-45 + :lineno-start: 25 :linenos: :language: python -The ``check()`` function is used as the first argument to +``view_page()`` is used to display a single page of our wiki. It renders the +:term:`reStructuredText` body of a page (stored as the ``data`` attribute of a +``Page`` model object) as HTML. Then it substitutes an HTML anchor for each +*WikiWord* reference in the rendered HTML using a compiled regular expression. + +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, ``check()`` generates a view @@ -156,6 +164,14 @@ renderer used will be the ``templates/view.pt`` template, as indicated in the The ``add_page`` view function ------------------------------ +Here is the code for the ``add_page`` view function and its decorator: + +.. literalinclude:: src/views/tutorial/views.py + :lines: 47-58 + :lineno-start: 47 + :linenos: + :language: python + ``add_page()`` is 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. @@ -164,26 +180,21 @@ 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 - :lines: 45-56 - :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 value for +e.g., ``http://localhost:6543/add_page/SomeName``, the value for ``'pagename'`` in the ``matchdict`` will be ``'SomeName'``. -If the view execution *is* a result of a form submission (i.e. the expression -``'form.submitted' in request.params`` is ``True``), we scrape the page body +If the view execution *is* a result of a form submission (i.e., the expression +``'form.submitted' in request.params`` is ``True``), we grab the page body from the form data, create a Page object with this page body and the name taken from ``matchdict['pagename']``, and save it into the database using ``DBSession.add``. We then redirect back to the ``view_page`` view for the newly created page. -If the view execution is *not* a result of a form submission (i.e. the +If the view execution is *not* a result of a form submission (i.e., 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 +callable renders a template. To do so, it generates a ``save_url`` which the template uses as the form post URL during rendering. We're lazy here, so we're going to use the same template (``templates/edit.pt``) for the add view as well as the page edit view. To do so we create a dummy Page object @@ -194,38 +205,41 @@ with this view to a response. The ``edit_page`` view function ------------------------------- +Here is the code for the ``edit_page`` view function and its decorator: + +.. literalinclude:: src/views/tutorial/views.py + :lines: 60-72 + :lineno-start: 60 + :linenos: + :language: python + ``edit_page()`` is 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 - :lines: 58-70 - :linenos: - :language: python - -If the view execution *is* a result of a form submission (i.e. the expression +If the view execution *is* a result of a form submission (i.e., the expression ``'form.submitted' in request.params`` is ``True``), the view grabs the ``body`` element of the request parameters and sets it as the ``data`` attribute of the page object. It then redirects to the ``view_page`` view of the wiki page. -If the view execution is *not* a result of a form submission (i.e. the +If the view execution is *not* a result of a form submission (i.e., the expression ``'form.submitted' in request.params`` is ``False``), the view simply renders the edit form, passing the page object and a ``save_url`` which will be used as the action of the generated form. -Adding Templates +Adding templates ================ The ``view_page``, ``add_page`` and ``edit_page`` views that we've added -reference a :term:`template`. Each template is a :term:`Chameleon` :term:`ZPT` -template. These templates will live in the ``templates`` directory of our -tutorial package. Chameleon templates must have a ``.pt`` extension to be -recognized as such. +reference a :term:`template`. Each template is a :term:`Chameleon` +:term:`ZPT` template. These templates will live in the ``templates`` +directory of our tutorial package. Chameleon templates must have a ``.pt`` +extension to be recognized as such. -The ``view.pt`` Template +The ``view.pt`` template ------------------------ Create ``tutorial/tutorial/templates/view.pt`` and add the following @@ -233,20 +247,18 @@ content: .. literalinclude:: src/views/tutorial/templates/view.pt :linenos: - :language: xml + :language: html This template is used by ``view_page()`` for displaying a single wiki page. It includes: -- A ``div`` element that is replaced with the ``content`` - value provided by the view (rows 45-47). ``content`` - contains HTML, so the ``structure`` keyword is used - to prevent escaping it (i.e. changing ">" to ">", etc.) -- A link that points - at the "edit" URL which invokes the ``edit_page`` view for - the page being viewed (rows 49-51). +- A ``div`` element that is replaced with the ``content`` value provided by + the view (lines 36-38). ``content`` contains HTML, so the ``structure`` + keyword is used to prevent escaping it (i.e., changing ">" to ">", etc.) +- A link that points at the "edit" URL which invokes the ``edit_page`` view + for the page being viewed (lines 40-42). -The ``edit.pt`` Template +The ``edit.pt`` template ------------------------ Create ``tutorial/tutorial/templates/edit.pt`` and add the following @@ -254,44 +266,38 @@ content: .. literalinclude:: src/views/tutorial/templates/edit.pt :linenos: - :language: xml + :language: html -This template is used by ``add_page()`` and ``edit_page()`` for adding -and editing a wiki page. It displays -a page containing a form that includes: +This template is used by ``add_page()`` and ``edit_page()`` for adding and +editing a wiki page. It displays a page containing a form that includes: - A 10 row by 60 column ``textarea`` field named ``body`` that is filled - with any existing page data when it is rendered (rows 46-47). -- A submit button that has the name ``form.submitted`` (row 48). + with any existing page data when it is rendered (line 45). +- A submit button that has the name ``form.submitted`` (line 48). -The form POSTs back to the "save_url" argument supplied -by the view (row 45). The view will use the ``body`` and -``form.submitted`` values. +The form POSTs back to the ``save_url`` argument supplied by the view (line +43). The view will use the ``body`` and ``form.submitted`` values. -.. note:: Our templates use a ``request`` object that - none of our tutorial views return in their dictionary. - ``request`` is one of several - names that are available "by default" in a template when a template - renderer is used. See :ref:`renderer_system_values` for - information about other names that are available by default - when a template is used as a renderer. +.. note:: Our templates use a ``request`` object that none of our tutorial + views return in their dictionary. ``request`` is one of several names that + are available "by default" in a template when a template renderer is used. + See :ref:`renderer_system_values` for information about other names that + are available by default when a template is used as a renderer. 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 -<https://github.com/Pylons/pyramid/blob/master/docs/tutorials/wiki2/src/views/tutorial/static/pylons.css>`_. +Our templates name static assets, including CSS and images. We don't need +to create these files within our package's ``static`` directory because they +were provided at the time we created the project. -This CSS file will be accessed via -e.g. ``http://localhost:6543/static/pylons.css`` by virtue of the call to +As an example, the CSS file will be accessed via +``http://localhost:6543/static/theme.css`` by virtue of the call to the ``add_static_view`` directive we've made in the ``__init__.py`` 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. +method ``static_url``, e.g., +``request.static_url('<package>:static/foo.css')`` within templates. Adding Routes to ``__init__.py`` ================================ @@ -334,33 +340,30 @@ something like: .. literalinclude:: src/views/tutorial/__init__.py :linenos: - :language: python :emphasize-lines: 19-22 + :language: python -(The highlighted lines are the ones that need to be added or edited.) +The highlighted lines are the ones that need to be added or edited. -Viewing the Application in a Browser +Viewing the application in a browser ==================================== We can finally examine our application in a browser (See :ref:`wiki2-start-the-application`). Launch a browser and visit -each of the following URLs, check that the result is as expected: +each of the following URLs, checking that the result is as expected: -- http://localhost:6543 in a browser invokes the - ``view_wiki`` view. This always redirects to the ``view_page`` view - of the FrontPage page object. +- http://localhost:6543/ invokes the ``view_wiki`` view. This always + redirects to the ``view_page`` view of the ``FrontPage`` page object. -- http://localhost:6543/FrontPage in a browser invokes - the ``view_page`` view of the front page object. +- http://localhost:6543/FrontPage invokes the ``view_page`` view of the front + page object. -- http://localhost:6543/FrontPage/edit_page in a browser - invokes the edit view for the front page object. +- http://localhost:6543/FrontPage/edit_page invokes the edit view for the + front page object. -- http://localhost:6543/add_page/SomePageName in a - browser invokes the add view for a page. +- http://localhost:6543/add_page/SomePageName invokes the add view for a page. - To generate an error, visit http://localhost:6543/foobars/edit_page which - will generate a ``NoResultFound: No row was found for one()`` error. - You'll see an interactive traceback facility provided - by :term:`pyramid_debugtoolbar`. - + will generate a ``NoResultFound: No row was found for one()`` error. You'll + see an interactive traceback facility provided by + :term:`pyramid_debugtoolbar`. diff --git a/docs/tutorials/wiki2/design.rst b/docs/tutorials/wiki2/design.rst index ff7413668..e9f361e7d 100644 --- a/docs/tutorials/wiki2/design.rst +++ b/docs/tutorials/wiki2/design.rst @@ -9,7 +9,7 @@ tutorial. Overall ------- -We choose to use :term:`reStructuredText` markup in the wiki text. Translation +We choose to use :term:`reStructuredText` markup in the wiki text. Translation from reStructuredText to HTML is provided by the widely used ``docutils`` Python module. We will add this module in the dependency list on the project ``setup.py`` file. @@ -37,8 +37,8 @@ Views ----- There will be three views to handle the normal operations of adding, -editing and viewing wiki pages, plus one view for the wiki front page. -Two templates will be used, one for viewing, and one for both for adding +editing, and viewing wiki pages, plus one view for the wiki front page. +Two templates will be used, one for viewing, and one for both adding and editing wiki pages. The default templating systems in :app:`Pyramid` are @@ -53,13 +53,14 @@ Security We'll eventually be adding security to our application. The components we'll use to do this are below. -- USERS, a dictionary mapping users names (the user's :term:`userids - <userid>`) to their corresponding passwords. +- USERS, a dictionary mapping :term:`userids <userid>` to their + corresponding passwords. -- GROUPS, a dictionary mapping user names to a list of groups they belong to. +- GROUPS, a dictionary mapping :term:`userids <userid>` to a + list of groups to which they belong. - ``groupfinder``, an *authorization callback* that looks up USERS and - GROUPS. It will be provided in a new *security.py* file. + GROUPS. It will be provided in a new ``security.py`` file. - An :term:`ACL` is attached to the root :term:`resource`. Each row below details an :term:`ACE`: @@ -101,7 +102,7 @@ listed in the following table: | | with existing | | | | | | content. | | | | | | | | | | -| | If the form is | | | | +| | If the form was | | | | | | submitted, redirect | | | | | | to /PageName | | | | +----------------------+-----------------------+-------------+------------+------------+ @@ -111,7 +112,7 @@ listed in the following table: | | the edit form | | | | | | without content. | | | | | | | | | | -| | If the form is | | | | +| | If the form was | | | | | | submitted, | | | | | | redirect to | | | | | | /PageName | | | | @@ -119,12 +120,12 @@ listed in the following table: | /login | Display login form, | login | login.pt | | | | Forbidden [3]_ | | | | | | | | | | -| | If the form is | | | | +| | If the form was | | | | | | submitted, | | | | | | authenticate. | | | | | | | | | | | | - If authentication | | | | -| | successful, | | | | +| | succeeds, | | | | | | redirect to the | | | | | | page that we | | | | | | came from. | | | | @@ -144,6 +145,6 @@ listed in the following table: when there is no view name. .. [2] Pyramid will return a default 404 Not Found page if the page *PageName* does not exist yet. -.. [3] pyramid.exceptions.Forbidden is reached when a +.. [3] ``pyramid.exceptions.Forbidden`` is reached when a user tries to invoke a view that is not authorized by the authorization policy. diff --git a/docs/tutorials/wiki2/distributing.rst b/docs/tutorials/wiki2/distributing.rst index 3b048a141..fee50a1cf 100644 --- a/docs/tutorials/wiki2/distributing.rst +++ b/docs/tutorials/wiki2/distributing.rst @@ -2,11 +2,11 @@ Distributing Your Application ============================= -Once your application works properly, you can create a "tarball" from -it by using the ``setup.py sdist`` command. The following commands -assume your current working directory is the ``tutorial`` package -we've created and that the parent directory of the ``tutorial`` -package is a virtualenv representing a :app:`Pyramid` environment. +Once your application works properly, you can create a "tarball" from it by +using the ``setup.py sdist`` command. The following commands assume your +current working directory is the ``tutorial`` package we've created and that +the parent directory of the ``tutorial`` package is a virtualenv representing +a :app:`Pyramid` environment. On UNIX: @@ -25,18 +25,16 @@ The output of such a command will be something like: .. code-block:: text running sdist - # ... more output ... + # .. more output .. creating dist tar -cf dist/tutorial-0.0.tar tutorial-0.0 gzip -f9 dist/tutorial-0.0.tar removing 'tutorial-0.0' (and everything under it) -Note that this command creates a tarball in the "dist" subdirectory -named ``tutorial-0.0.tar.gz``. You can send this file to your friends -to show them your cool new application. They should be able to -install it by pointing the ``easy_install`` command directly at it. -Or you can upload it to `PyPI <http://pypi.python.org>`_ and share it -with the rest of the world, where it can be downloaded via -``easy_install`` remotely like any other package people download from -PyPI. - +Note that this command creates a tarball in the "dist" subdirectory named +``tutorial-0.0.tar.gz``. You can send this file to your friends to show them +your cool new application. They should be able to install it by pointing the +``easy_install`` command directly at it. Or you can upload it to `PyPI +<http://pypi.python.org>`_ and share it with the rest of the world, where it +can be downloaded via ``easy_install`` remotely like any other package people +download from PyPI. diff --git a/docs/tutorials/wiki2/index.rst b/docs/tutorials/wiki2/index.rst index 0a614cb23..0a3873dcd 100644 --- a/docs/tutorials/wiki2/index.rst +++ b/docs/tutorials/wiki2/index.rst @@ -3,7 +3,7 @@ SQLAlchemy + URL Dispatch Wiki Tutorial ======================================= -This tutorial introduces a :term:`SQLAlchemy` and :term:`url dispatch` -based +This tutorial introduces a :term:`SQLAlchemy` and :term:`url dispatch`-based :app:`Pyramid` application to a developer familiar with Python. When the tutorial is finished, the developer will have created a basic Wiki application with authentication. @@ -26,4 +26,3 @@ which corresponds to the same location if you have Pyramid sources. tests distributing - diff --git a/docs/tutorials/wiki2/installation.rst b/docs/tutorials/wiki2/installation.rst index e21bf7108..1385ab8c7 100644 --- a/docs/tutorials/wiki2/installation.rst +++ b/docs/tutorials/wiki2/installation.rst @@ -2,22 +2,41 @@ Installation ============ -Before You Begin +Before you begin ================ This tutorial assumes that you have already followed the steps in -:ref:`installing_chapter`, thereby satisfying the following -requirements. +:ref:`installing_chapter`, except **do not create a virtualenv or install +Pyramid**. Thereby you will satisfy the following requirements. * Python interpreter is installed on your operating system * :term:`setuptools` or :term:`distribute` is installed * :term:`virtualenv` is installed -Create and Use a Virtual Python Environment +Create directory to contain the project +--------------------------------------- + +We need a workspace for our project files. + +On UNIX +^^^^^^^ + +.. code-block:: text + + $ mkdir ~/pyramidtut + +On Windows +^^^^^^^^^^ + +.. code-block:: text + + c:\> mkdir pyramidtut + +Create and use a virtual Python environment ------------------------------------------- Next let's create a `virtualenv` workspace for our project. We will -use the `VENV` environment variable instead of absolute path of the +use the `VENV` environment variable instead of the absolute path of the virtual environment. On UNIX @@ -33,8 +52,6 @@ On UNIX On Windows ^^^^^^^^^^ -Set the `VENV` environment variable. - .. code-block:: text c:\> set VENV=c:\pyramidtut @@ -54,7 +71,7 @@ Python 3.2: c:\> c:\Python32\Scripts\virtualenv %VENV% -Install Pyramid Into the Virtual Python Environment +Install Pyramid into the virtual Python environment --------------------------------------------------- On UNIX @@ -69,9 +86,9 @@ On Windows .. code-block:: text - c:\env> %VENV%\Scripts\easy_install pyramid + c:\> %VENV%\Scripts\easy_install pyramid -Install SQLite3 and Its Development Packages +Install SQLite3 and its development packages -------------------------------------------- If you used a package manager to install your Python or if you compiled @@ -87,7 +104,7 @@ the Debian system and apt-get, the command would be the following: $ sudo apt-get install libsqlite3-dev -Change Directory to Your Virtual Python Environment +Change directory to your virtual Python environment --------------------------------------------------- Change directory to the ``pyramidtut`` directory. @@ -108,7 +125,7 @@ On Windows .. _sql_making_a_project: -Making a Project +Making a project ================ Your next step is to create a project. For this tutorial we will use @@ -117,17 +134,16 @@ that uses :term:`SQLAlchemy` and :term:`URL dispatch`. :app:`Pyramid` supplies a variety of scaffolds to generate sample projects. We will use `pcreate`—a script that comes with Pyramid to -quickly and easily generate scaffolds usually with a single command—to +quickly and easily generate scaffolds, usually with a single command—to create the scaffold for our project. -By passing in `alchemy` into the `pcreate` command, the script creates +By passing `alchemy` into the `pcreate` command, the script creates the files needed to use SQLAlchemy. By passing in our application name `tutorial`, the script inserts that application name into all the required files. For example, `pcreate` creates the ``initialize_tutorial_db`` in the ``pyramidtut/bin`` directory. -The below instructions assume your current working directory is the -"virtualenv" named "pyramidtut". +The below instructions assume your current working directory is "pyramidtut". On UNIX ------- @@ -141,7 +157,7 @@ On Windows .. code-block:: text - c:\pyramidtut> %VENV%\pcreate -s alchemy tutorial + c:\pyramidtut> %VENV%\Scripts\pcreate -s alchemy tutorial .. note:: If you are using Windows, the ``alchemy`` scaffold may not deal gracefully with installation into a @@ -151,7 +167,7 @@ On Windows .. _installing_project_in_dev_mode: -Installing the Project in Development Mode +Installing the project in development mode ========================================== In order to do development on the project easily, you must "register" @@ -184,8 +200,8 @@ the following:: .. _sql_running_tests: -Running the Tests -================= +Run the tests +============= After you've installed the project in development mode, you may run the tests for the project. @@ -212,8 +228,8 @@ For a successful test run, you should see output that ends like this:: OK -Exposing Test Coverage Information -================================== +Expose test coverage information +================================ You can run the ``nosetests`` command to see test coverage information. This runs the tests in the same way that ``setup.py @@ -258,33 +274,31 @@ On Windows If successful, you will see output something like this:: - . - Name Stmts Miss Cover Missing - ------------------------------------------------ - tutorial 11 7 36% 9-15 - tutorial.models 17 0 100% - tutorial.scripts 0 0 100% - tutorial.tests 24 0 100% - tutorial.views 6 0 100% - ------------------------------------------------ - TOTAL 58 7 88% - ---------------------------------------------------------------------- - Ran 1 test in 0.459s + . + Name Stmts Miss Cover Missing + --------------------------------------------------- + tutorial.py 13 9 31% 13-21 + tutorial/models.py 12 0 100% + tutorial/scripts.py 0 0 100% + tutorial/views.py 11 0 100% + --------------------------------------------------- + TOTAL 36 9 75% + ---------------------------------------------------------------------- + Ran 2 tests in 0.643s - OK + OK Looks like our package doesn't quite have 100% test coverage. - .. _initialize_db_wiki2: -Initializing the Database +Initializing the database ========================= We need to use the ``initialize_tutorial_db`` :term:`console script` to initialize our database. -Type the following command, make sure you are still in the ``tutorial`` +Type the following command, making sure you are still in the ``tutorial`` directory (the directory with a ``development.ini`` in it): On UNIX @@ -303,28 +317,30 @@ On Windows The output to your console should be something like this:: - 2011-11-26 14:42:25,012 INFO [sqlalchemy.engine.base.Engine][MainThread] - PRAGMA table_info("models") - 2011-11-26 14:42:25,013 INFO [sqlalchemy.engine.base.Engine][MainThread] () - 2011-11-26 14:42:25,013 INFO [sqlalchemy.engine.base.Engine][MainThread] - CREATE TABLE models ( - id INTEGER NOT NULL, - name VARCHAR(255), - value INTEGER, - PRIMARY KEY (id), - UNIQUE (name) - ) - 2011-11-26 14:42:25,013 INFO [sqlalchemy.engine.base.Engine][MainThread] () - 2011-11-26 14:42:25,135 INFO [sqlalchemy.engine.base.Engine][MainThread] - COMMIT - 2011-11-26 14:42:25,137 INFO [sqlalchemy.engine.base.Engine][MainThread] - BEGIN (implicit) - 2011-11-26 14:42:25,138 INFO [sqlalchemy.engine.base.Engine][MainThread] - INSERT INTO models (name, value) VALUES (?, ?) - 2011-11-26 14:42:25,139 INFO [sqlalchemy.engine.base.Engine][MainThread] - (u'one', 1) - 2011-11-26 14:42:25,140 INFO [sqlalchemy.engine.base.Engine][MainThread] - COMMIT + 2015-05-23 16:49:49,609 INFO [sqlalchemy.engine.base.Engine:1192][MainThread] SELECT CAST('test plain returns' AS VARCHAR(60)) AS anon_1 + 2015-05-23 16:49:49,609 INFO [sqlalchemy.engine.base.Engine:1193][MainThread] () + 2015-05-23 16:49:49,610 INFO [sqlalchemy.engine.base.Engine:1192][MainThread] SELECT CAST('test unicode returns' AS VARCHAR(60)) AS anon_1 + 2015-05-23 16:49:49,610 INFO [sqlalchemy.engine.base.Engine:1193][MainThread] () + 2015-05-23 16:49:49,610 INFO [sqlalchemy.engine.base.Engine:1097][MainThread] PRAGMA table_info("models") + 2015-05-23 16:49:49,610 INFO [sqlalchemy.engine.base.Engine:1100][MainThread] () + 2015-05-23 16:49:49,612 INFO [sqlalchemy.engine.base.Engine:1097][MainThread] + CREATE TABLE models ( + id INTEGER NOT NULL, + name TEXT, + value INTEGER, + PRIMARY KEY (id) + ) + + + 2015-05-23 16:49:49,612 INFO [sqlalchemy.engine.base.Engine:1100][MainThread] () + 2015-05-23 16:49:49,613 INFO [sqlalchemy.engine.base.Engine:686][MainThread] COMMIT + 2015-05-23 16:49:49,613 INFO [sqlalchemy.engine.base.Engine:1097][MainThread] CREATE UNIQUE INDEX my_index ON models (name) + 2015-05-23 16:49:49,613 INFO [sqlalchemy.engine.base.Engine:1100][MainThread] () + 2015-05-23 16:49:49,614 INFO [sqlalchemy.engine.base.Engine:686][MainThread] COMMIT + 2015-05-23 16:49:49,616 INFO [sqlalchemy.engine.base.Engine:646][MainThread] BEGIN (implicit) + 2015-05-23 16:49:49,617 INFO [sqlalchemy.engine.base.Engine:1097][MainThread] INSERT INTO models (name, value) VALUES (?, ?) + 2015-05-23 16:49:49,617 INFO [sqlalchemy.engine.base.Engine:1100][MainThread] ('one', 1) + 2015-05-23 16:49:49,618 INFO [sqlalchemy.engine.base.Engine:686][MainThread] COMMIT Success! You should now have a ``tutorial.sqlite`` file in your current working directory. This will be a SQLite database with a single table defined in it @@ -332,8 +348,8 @@ directory. This will be a SQLite database with a single table defined in it .. _wiki2-start-the-application: -Starting the Application -======================== +Start the application +===================== Start the application. @@ -351,6 +367,11 @@ On Windows c:\pyramidtut\tutorial> %VENV%\Scripts\pserve development.ini --reload +.. note:: + + Your OS firewall, if any, may pop up a dialog asking for authorization + to allow python to accept incoming network connections. + If successful, you will see something like this on your console:: Starting subprocess with file monitor @@ -359,31 +380,34 @@ If successful, you will see something like this on your console:: This means the server is ready to accept requests. -At this point, when you visit ``http://localhost:6543/`` in your web browser, -you will see the generated application's default page. +Visit the application in a browser +================================== + +In a browser, visit `http://localhost:6543/ <http://localhost:6543>`_. You +will see the generated application's default page. One thing you'll notice is the "debug toolbar" icon on right hand side of the page. You can read more about the purpose of the icon at :ref:`debug_toolbar`. It allows you to get information about your application while you develop. -Decisions the ``alchemy`` Scaffold Has Made For You +Decisions the ``alchemy`` scaffold has made for you ================================================================= -Creating a project using the ``alchemy`` scaffold makes -the following assumptions: +Creating a project using the ``alchemy`` scaffold makes the following +assumptions: - you are willing to use :term:`SQLAlchemy` as a database access tool -- you are willing to use :term:`url dispatch` to map URLs to code. +- you are willing to use :term:`URL dispatch` to map URLs to code - you want to use ``ZopeTransactionExtension`` and ``pyramid_tm`` to scope sessions to requests .. note:: - :app:`Pyramid` supports any persistent storage mechanism (e.g. object - database or filesystem files, etc). It also supports an additional + :app:`Pyramid` supports any persistent storage mechanism (e.g., object + database or filesystem files). It also supports an additional mechanism to map URLs to code (:term:`traversal`). However, for the - purposes of this tutorial, we'll only be using url dispatch and + purposes of this tutorial, we'll only be using URL dispatch and SQLAlchemy. diff --git a/docs/tutorials/wiki2/src/authorization/tutorial/static/favicon.ico b/docs/tutorials/wiki2/src/authorization/tutorial/static/favicon.ico Binary files differdeleted file mode 100644 index 71f837c9e..000000000 --- a/docs/tutorials/wiki2/src/authorization/tutorial/static/favicon.ico +++ /dev/null diff --git a/docs/tutorials/wiki2/src/authorization/tutorial/static/footerbg.png b/docs/tutorials/wiki2/src/authorization/tutorial/static/footerbg.png Binary files differdeleted file mode 100644 index 1fbc873da..000000000 --- a/docs/tutorials/wiki2/src/authorization/tutorial/static/footerbg.png +++ /dev/null diff --git a/docs/tutorials/wiki2/src/authorization/tutorial/static/headerbg.png b/docs/tutorials/wiki2/src/authorization/tutorial/static/headerbg.png Binary files differdeleted file mode 100644 index 0596f2020..000000000 --- a/docs/tutorials/wiki2/src/authorization/tutorial/static/headerbg.png +++ /dev/null diff --git a/docs/tutorials/wiki2/src/authorization/tutorial/static/ie6.css b/docs/tutorials/wiki2/src/authorization/tutorial/static/ie6.css deleted file mode 100644 index b7c8493d8..000000000 --- a/docs/tutorials/wiki2/src/authorization/tutorial/static/ie6.css +++ /dev/null @@ -1,8 +0,0 @@ -* 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/middlebg.png b/docs/tutorials/wiki2/src/authorization/tutorial/static/middlebg.png Binary files differdeleted file mode 100644 index 2369cfb7d..000000000 --- a/docs/tutorials/wiki2/src/authorization/tutorial/static/middlebg.png +++ /dev/null diff --git a/docs/tutorials/wiki2/src/authorization/tutorial/static/pylons.css b/docs/tutorials/wiki2/src/authorization/tutorial/static/pylons.css deleted file mode 100644 index 4b1c017cd..000000000 --- a/docs/tutorials/wiki2/src/authorization/tutorial/static/pylons.css +++ /dev/null @@ -1,372 +0,0 @@ -html, body, div, span, applet, object, iframe, h1, h2, h3, h4, h5, h6, p, blockquote, pre, a, abbr, acronym, address, big, cite, code, del, dfn, em, font, img, ins, kbd, q, s, samp, small, strike, strong, sub, sup, tt, var, b, u, i, center, dl, dt, dd, ol, ul, li, fieldset, form, label, legend, table, caption, tbody, tfoot, thead, tr, th, td -{ - margin: 0; - padding: 0; - border: 0; - outline: 0; - font-size: 100%; /* 16px */ - vertical-align: baseline; - background: transparent; -} - -body -{ - line-height: 1; -} - -ol, ul -{ - list-style: none; -} - -blockquote, q -{ - quotes: none; -} - -blockquote:before, blockquote:after, q:before, q:after -{ - content: ''; - content: none; -} - -:focus -{ - outline: 0; -} - -ins -{ - text-decoration: none; -} - -del -{ - text-decoration: line-through; -} - -table -{ - border-collapse: collapse; - border-spacing: 0; -} - -sub -{ - vertical-align: sub; - font-size: smaller; - line-height: normal; -} - -sup -{ - vertical-align: super; - font-size: smaller; - line-height: normal; -} - -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; -} - -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; -} - -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; -} - -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; - 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: #fff; - position: relative; - font: 16px/24px NobileRegular, "Lucida Grande", Lucida, Verdana, sans-serif; -} - -a -{ - color: #1b61d6; - text-decoration: none; -} - -a:hover -{ - color: #e88f00; - text-decoration: underline; -} - -body h1, body h2, body h3, body h4, body h5, body h6 -{ - font-family: NeutonRegular, "Lucida Grande", Lucida, Verdana, sans-serif; - font-weight: 400; - color: #373839; - font-style: normal; -} - -#wrap -{ - min-height: 100%; -} - -#header, #footer -{ - width: 100%; - color: #fff; - height: 40px; - position: absolute; - text-align: center; - line-height: 40px; - overflow: hidden; - font-size: 12px; - vertical-align: middle; -} - -#header -{ - background: #000; - top: 0; - font-size: 14px; -} - -#footer -{ - bottom: 0; - background: #000 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, #top-small, #bottom -{ - width: 100%; -} - -#top -{ - color: #000; - height: 230px; - background: #fff url(headerbg.png) repeat-x 0 top; - position: relative; -} - -#top-small -{ - color: #000; - height: 60px; - background: #fff url(headerbg.png) repeat-x 0 top; - position: relative; -} - -#bottom -{ - color: #222; - background-color: #fff; -} - -.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 #fff; - border-bottom: 2px solid #b2b2b2; -} - -.app-welcome -{ - margin-top: 25px; -} - -.app-name -{ - color: #000; - font-weight: 700; -} - -.bottom -{ - padding-top: 50px; -} - -#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; -} - -ul.links -{ - margin: 0; - padding: 0; -} - -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=password] -{ - width: 205px; -} - -input[type=submit] -{ - background-color: #ddd; - font-weight: 700; -} - -/*Opera Fix*/ -body:before -{ - content: ""; - height: 100%; - float: left; - width: 0; - margin-top: -32767px; -} diff --git a/docs/tutorials/wiki2/src/authorization/tutorial/static/pyramid-16x16.png b/docs/tutorials/wiki2/src/authorization/tutorial/static/pyramid-16x16.png Binary files differnew file mode 100644 index 000000000..979203112 --- /dev/null +++ b/docs/tutorials/wiki2/src/authorization/tutorial/static/pyramid-16x16.png 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 differdeleted file mode 100644 index a5bc0ade7..000000000 --- a/docs/tutorials/wiki2/src/authorization/tutorial/static/pyramid-small.png +++ /dev/null diff --git a/docs/tutorials/wiki2/src/authorization/tutorial/static/pyramid.png b/docs/tutorials/wiki2/src/authorization/tutorial/static/pyramid.png Binary files differindex 347e05549..4ab837be9 100644 --- a/docs/tutorials/wiki2/src/authorization/tutorial/static/pyramid.png +++ b/docs/tutorials/wiki2/src/authorization/tutorial/static/pyramid.png diff --git a/docs/tutorials/wiki2/src/authorization/tutorial/static/theme.css b/docs/tutorials/wiki2/src/authorization/tutorial/static/theme.css new file mode 100644 index 000000000..0f4b1a4d4 --- /dev/null +++ b/docs/tutorials/wiki2/src/authorization/tutorial/static/theme.css @@ -0,0 +1,154 @@ +@import url(//fonts.googleapis.com/css?family=Open+Sans:300,400,600,700); +body { + font-family: "Open Sans", "Helvetica Neue", Helvetica, Arial, sans-serif; + font-weight: 300; + color: #ffffff; + background: #bc2131; +} +h1, +h2, +h3, +h4, +h5, +h6 { + font-family: "Open Sans", "Helvetica Neue", Helvetica, Arial, sans-serif; + font-weight: 300; +} +p { + font-weight: 300; +} +.font-normal { + font-weight: 400; +} +.font-semi-bold { + font-weight: 600; +} +.font-bold { + font-weight: 700; +} +.starter-template { + margin-top: 250px; +} +.starter-template .content { + margin-left: 10px; +} +.starter-template .content h1 { + margin-top: 10px; + font-size: 60px; +} +.starter-template .content h1 .smaller { + font-size: 40px; + color: #f2b7bd; +} +.starter-template .content .lead { + font-size: 25px; + color: #f2b7bd; +} +.starter-template .content .lead .font-normal { + color: #ffffff; +} +.starter-template .links { + float: right; + right: 0; + margin-top: 125px; +} +.starter-template .links ul { + display: block; + padding: 0; + margin: 0; +} +.starter-template .links ul li { + list-style: none; + display: inline; + margin: 0 10px; +} +.starter-template .links ul li:first-child { + margin-left: 0; +} +.starter-template .links ul li:last-child { + margin-right: 0; +} +.starter-template .links ul li.current-version { + color: #f2b7bd; + font-weight: 400; +} +.starter-template .links ul li a, a { + color: #f2b7bd; + text-decoration: underline; +} +.starter-template .links ul li a:hover, a:hover { + color: #ffffff; + text-decoration: underline; +} +.starter-template .links ul li .icon-muted { + color: #eb8b95; + margin-right: 5px; +} +.starter-template .links ul li:hover .icon-muted { + color: #ffffff; +} +.starter-template .copyright { + margin-top: 10px; + font-size: 0.9em; + color: #f2b7bd; + text-transform: lowercase; + float: right; + right: 0; +} +@media (max-width: 1199px) { + .starter-template .content h1 { + font-size: 45px; + } + .starter-template .content h1 .smaller { + font-size: 30px; + } + .starter-template .content .lead { + font-size: 20px; + } +} +@media (max-width: 991px) { + .starter-template { + margin-top: 0; + } + .starter-template .logo { + margin: 40px auto; + } + .starter-template .content { + margin-left: 0; + text-align: center; + } + .starter-template .content h1 { + margin-bottom: 20px; + } + .starter-template .links { + float: none; + text-align: center; + margin-top: 60px; + } + .starter-template .copyright { + float: none; + text-align: center; + } +} +@media (max-width: 767px) { + .starter-template .content h1 .smaller { + font-size: 25px; + display: block; + } + .starter-template .content .lead { + font-size: 16px; + } + .starter-template .links { + margin-top: 40px; + } + .starter-template .links ul li { + display: block; + margin: 0; + } + .starter-template .links ul li .icon-muted { + display: none; + } + .starter-template .copyright { + margin-top: 20px; + } +} diff --git a/docs/tutorials/wiki2/src/authorization/tutorial/static/theme.min.css b/docs/tutorials/wiki2/src/authorization/tutorial/static/theme.min.css new file mode 100644 index 000000000..2f924bcc5 --- /dev/null +++ b/docs/tutorials/wiki2/src/authorization/tutorial/static/theme.min.css @@ -0,0 +1 @@ +@import url(//fonts.googleapis.com/css?family=Open+Sans:300,400,600,700);body{font-family:"Open Sans","Helvetica Neue",Helvetica,Arial,sans-serif;font-weight:300;color:#fff;background:#bc2131}h1,h2,h3,h4,h5,h6{font-family:"Open Sans","Helvetica Neue",Helvetica,Arial,sans-serif;font-weight:300}p{font-weight:300}.font-normal{font-weight:400}.font-semi-bold{font-weight:600}.font-bold{font-weight:700}.starter-template{margin-top:250px}.starter-template .content{margin-left:10px}.starter-template .content h1{margin-top:10px;font-size:60px}.starter-template .content h1 .smaller{font-size:40px;color:#f2b7bd}.starter-template .content .lead{font-size:25px;color:#f2b7bd}.starter-template .content .lead .font-normal{color:#fff}.starter-template .links{float:right;right:0;margin-top:125px}.starter-template .links ul{display:block;padding:0;margin:0}.starter-template .links ul li{list-style:none;display:inline;margin:0 10px}.starter-template .links ul li:first-child{margin-left:0}.starter-template .links ul li:last-child{margin-right:0}.starter-template .links ul li.current-version{color:#f2b7bd;font-weight:400}.starter-template .links ul li a{color:#fff}.starter-template .links ul li a:hover{text-decoration:underline}.starter-template .links ul li .icon-muted{color:#eb8b95;margin-right:5px}.starter-template .links ul li:hover .icon-muted{color:#fff}.starter-template .copyright{margin-top:10px;font-size:.9em;color:#f2b7bd;text-transform:lowercase;float:right;right:0}@media (max-width:1199px){.starter-template .content h1{font-size:45px}.starter-template .content h1 .smaller{font-size:30px}.starter-template .content .lead{font-size:20px}}@media (max-width:991px){.starter-template{margin-top:0}.starter-template .logo{margin:40px auto}.starter-template .content{margin-left:0;text-align:center}.starter-template .content h1{margin-bottom:20px}.starter-template .links{float:none;text-align:center;margin-top:60px}.starter-template .copyright{float:none;text-align:center}}@media (max-width:767px){.starter-template .content h1 .smaller{font-size:25px;display:block}.starter-template .content .lead{font-size:16px}.starter-template .links{margin-top:40px}.starter-template .links ul li{display:block;margin:0}.starter-template .links ul li .icon-muted{display:none}.starter-template .copyright{margin-top:20px}}
\ No newline at end of file diff --git a/docs/tutorials/wiki2/src/authorization/tutorial/static/transparent.gif b/docs/tutorials/wiki2/src/authorization/tutorial/static/transparent.gif Binary files differdeleted file mode 100644 index 0341802e5..000000000 --- a/docs/tutorials/wiki2/src/authorization/tutorial/static/transparent.gif +++ /dev/null diff --git a/docs/tutorials/wiki2/src/authorization/tutorial/templates/edit.pt b/docs/tutorials/wiki2/src/authorization/tutorial/templates/edit.pt index ca28b9fa5..ed355434d 100644 --- a/docs/tutorials/wiki2/src/authorization/tutorial/templates/edit.pt +++ b/docs/tutorials/wiki2/src/authorization/tutorial/templates/edit.pt @@ -1,62 +1,72 @@ -<!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>${page.name} - Pyramid tutorial wiki (based on +<!DOCTYPE html> +<html lang="${request.locale_name}"> + <head> + <meta charset="utf-8"> + <meta http-equiv="X-UA-Compatible" content="IE=edge"> + <meta name="viewport" content="width=device-width, initial-scale=1.0"> + <meta name="description" content="pyramid web application"> + <meta name="author" content="Pylons Project"> + <link rel="shortcut icon" href="${request.static_url('tutorial:static/pyramid-16x16.png')}"> + + <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 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')}" /> + + <!-- Bootstrap core CSS --> + <link href="//oss.maxcdn.com/libs/twitter-bootstrap/3.0.3/css/bootstrap.min.css" rel="stylesheet"> + + <!-- Custom styles for this scaffold --> + <link href="${request.static_url('tutorial:static/theme.css')}" rel="stylesheet"> + + <!-- HTML5 shim and Respond.js IE8 support of HTML5 elements and media queries --> + <!--[if lt IE 9]> + <script src="//oss.maxcdn.com/libs/html5shiv/3.7.0/html5shiv.js"></script> + <script src="//oss.maxcdn.com/libs/respond.js/1.3.0/respond.min.js"></script> + <![endif]--> + </head> + <body> + + <div class="starter-template"> + <div class="container"> + <div class="row"> + <div class="col-md-2"> + <img class="logo img-responsive" src="${request.static_url('tutorial:static/pyramid.png')}" alt="pyramid web framework"> + </div> + <div class="col-md-10"> + <div class="content"> + <p tal:condition="logged_in" class="pull-right"> + <a href="${request.application_url}/logout">Logout</a> + </p> + <p> + Editing <strong><span tal:replace="page.name">Page Name Goes + Here</span></strong> + </p> + <p>You can return to the + <a href="${request.application_url}">FrontPage</a>. + </p> + <form action="${save_url}" method="post"> + <div class="form-group"> + <textarea class="form-control" name="body" tal:content="page.data" rows="10" cols="60"></textarea> + </div> + <div class="form-group"> + <button type="submit" name="form.submitted" value="Save" class="btn btn-default">Save</button> + </div> + </form> + </div> + </div> </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 class="row"> + <div class="copyright"> + Copyright © Pylons Project + </div> </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> -</body> + + + <!-- Bootstrap core JavaScript + ================================================== --> + <!-- Placed at the end of the document so the pages load faster --> + <script src="//oss.maxcdn.com/libs/jquery/1.10.2/jquery.min.js"></script> + <script src="//oss.maxcdn.com/libs/twitter-bootstrap/3.0.3/js/bootstrap.min.js"></script> + </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 64e592ea9..4a938e9bb 100644 --- a/docs/tutorials/wiki2/src/authorization/tutorial/templates/login.pt +++ b/docs/tutorials/wiki2/src/authorization/tutorial/templates/login.pt @@ -1,58 +1,74 @@ -<!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>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> - <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')}" /> +<!DOCTYPE html> +<html lang="${request.locale_name}"> + <head> + <meta charset="utf-8"> + <meta http-equiv="X-UA-Compatible" content="IE=edge"> + <meta name="viewport" content="width=device-width, initial-scale=1.0"> + <meta name="description" content="pyramid web application"> + <meta name="author" content="Pylons Project"> + <link rel="shortcut icon" href="${request.static_url('tutorial:static/pyramid-16x16.png')}"> + + <title>Login - Pyramid tutorial wiki (based on + TurboGears 20-Minute Wiki)</title> + + <!-- Bootstrap core CSS --> + <link href="//oss.maxcdn.com/libs/twitter-bootstrap/3.0.3/css/bootstrap.min.css" rel="stylesheet"> + + <!-- Custom styles for this scaffold --> + <link href="${request.static_url('tutorial:static/theme.css')}" rel="stylesheet"> + + <!-- HTML5 shim and Respond.js IE8 support of HTML5 elements and media queries --> + <!--[if lt IE 9]> + <script src="//oss.maxcdn.com/libs/html5shiv/3.7.0/html5shiv.js"></script> + <script src="//oss.maxcdn.com/libs/respond.js/1.3.0/respond.min.js"></script> + <![endif]--> + </head> + <body> + + <div class="starter-template"> + <div class="container"> + <div class="row"> + <div class="col-md-2"> + <img class="logo img-responsive" src="${request.static_url('tutorial:static/pyramid.png')}" alt="pyramid web framework"> + </div> + <div class="col-md-10"> + <div class="content"> + <p> + <strong> + Login + </strong><br> + <span tal:replace="message"></span> + </p> + <form action="${url}" method="post"> + <input type="hidden" name="came_from" value="${came_from}"> + <div class="form-group"> + <label for="login">Username</label> + <input type="text" name="login" value="${login}"> + </div> + <div class="form-group"> + <label for="password">Password</label> + <input type="password" name="password" value="${password}"> + </div> + <div class="form-group"> + <button type="submit" name="form.submitted" value="Log In" class="btn btn-default">Log In</button> + </div> + </form> + </div> + </div> </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 class="row"> + <div class="copyright"> + Copyright © Pylons Project + </div> </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> + + + <!-- Bootstrap core JavaScript + ================================================== --> + <!-- Placed at the end of the document so the pages load faster --> + <script src="//oss.maxcdn.com/libs/jquery/1.10.2/jquery.min.js"></script> + <script src="//oss.maxcdn.com/libs/twitter-bootstrap/3.0.3/js/bootstrap.min.js"></script> + </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 cf3da2073..c9b0cec21 100644 --- a/docs/tutorials/wiki2/src/authorization/tutorial/templates/mytemplate.pt +++ b/docs/tutorials/wiki2/src/authorization/tutorial/templates/mytemplate.pt @@ -1,76 +1,66 @@ -<!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 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="http://static.pylonsproject.org/fonts/nobile/stylesheet.css" media="screen" /> - <link rel="stylesheet" href="http://static.pylonsproject.org/fonts/neuton/stylesheet.css" media="screen" /> - <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 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 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/current/search.html"> - <input type="text" id="q" name="q" value="" /> - <input type="submit" id="x" value="Go" /> - </form> +<!DOCTYPE html> +<html lang="${request.locale_name}"> + <head> + <meta charset="utf-8"> + <meta http-equiv="X-UA-Compatible" content="IE=edge"> + <meta name="viewport" content="width=device-width, initial-scale=1.0"> + <meta name="description" content="pyramid web application"> + <meta name="author" content="Pylons Project"> + <link rel="shortcut icon" href="${request.static_url('tutorial:static/pyramid-16x16.png')}"> + + <title>Alchemy Scaffold for The Pyramid Web Framework</title> + + <!-- Bootstrap core CSS --> + <link href="//oss.maxcdn.com/libs/twitter-bootstrap/3.0.3/css/bootstrap.min.css" rel="stylesheet"> + + <!-- Custom styles for this scaffold --> + <link href="${request.static_url('tutorial:static/theme.css')}" rel="stylesheet"> + + <!-- HTML5 shim and Respond.js IE8 support of HTML5 elements and media queries --> + <!--[if lt IE 9]> + <script src="//oss.maxcdn.com/libs/html5shiv/3.7.0/html5shiv.js"></script> + <script src="//oss.maxcdn.com/libs/respond.js/1.3.0/respond.min.js"></script> + <![endif]--> + </head> + + <body> + + <div class="starter-template"> + <div class="container"> + <div class="row"> + <div class="col-md-2"> + <img class="logo img-responsive" src="${request.static_url('tutorial:static/pyramid.png')}" alt="pyramid web framework"> + </div> + <div class="col-md-10"> + <div class="content"> + <h1><span class="font-semi-bold">Pyramid</span> <span class="smaller">Alchemy scaffold</span></h1> + <p class="lead">Welcome to <span class="font-normal">${project}</span>, an application generated by<br>the <span class="font-normal">Pyramid Web Framework</span>.</p> + </div> + </div> </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/current/#narrative-documentation">Narrative Documentation</a> - </li> - <li> - <a href="http://docs.pylonsproject.org/projects/pyramid/current/#api-documentation">API Documentation</a> - </li> - <li> - <a href="http://docs.pylonsproject.org/projects/pyramid/current/#tutorials">Tutorials</a> - </li> - <li> - <a href="http://docs.pylonsproject.org/projects/pyramid/current/#change-history">Change History</a> - </li> - <li> - <a href="http://docs.pylonsproject.org/projects/pyramid/current/#sample-applications">Sample Applications</a> - </li> - <li> - <a href="http://docs.pylonsproject.org/projects/pyramid/current/#support-and-development">Support and Development</a> - </li> - <li> - <a href="irc://irc.freenode.net#pyramid">IRC Channel</a> - </li> + <div class="row"> + <div class="links"> + <ul> + <li><i class="glyphicon glyphicon-bookmark icon-muted"></i><a href="http://docs.pylonsproject.org/projects/pyramid/en/latest/">Docs</a></li> + <li><i class="glyphicon glyphicon-cog icon-muted"></i><a href="https://github.com/Pylons/pyramid">Github Project</a></li> + <li><i class="glyphicon glyphicon-globe icon-muted"></i><a href="irc://irc.freenode.net#pyramid">IRC Channel</a></li> + <li><i class="glyphicon glyphicon-home icon-muted"></i><a href="http://pylonsproject.org">Pylons Project</a></li> </ul> + </div> + </div> + <div class="row"> + <div class="copyright"> + Copyright © Pylons Project + </div> </div> </div> </div> - </div> - <div id="footer"> - <div class="footer">© Copyright 2008-2011, Agendaless Consulting.</div> - </div> -</body> + + + <!-- Bootstrap core JavaScript + ================================================== --> + <!-- Placed at the end of the document so the pages load faster --> + <script src="//oss.maxcdn.com/libs/jquery/1.10.2/jquery.min.js"></script> + <script src="//oss.maxcdn.com/libs/twitter-bootstrap/3.0.3/js/bootstrap.min.js"></script> + </body> </html> diff --git a/docs/tutorials/wiki2/src/authorization/tutorial/templates/view.pt b/docs/tutorials/wiki2/src/authorization/tutorial/templates/view.pt index 5a69818c1..02cb8e73b 100644 --- a/docs/tutorials/wiki2/src/authorization/tutorial/templates/view.pt +++ b/docs/tutorials/wiki2/src/authorization/tutorial/templates/view.pt @@ -1,65 +1,72 @@ -<!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>${page.name} - Pyramid tutorial wiki (based on +<!DOCTYPE html> +<html lang="${request.locale_name}"> + <head> + <meta charset="utf-8"> + <meta http-equiv="X-UA-Compatible" content="IE=edge"> + <meta name="viewport" content="width=device-width, initial-scale=1.0"> + <meta name="description" content="pyramid web application"> + <meta name="author" content="Pylons Project"> + <link rel="shortcut icon" href="${request.static_url('tutorial:static/pyramid-16x16.png')}"> + + <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 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')}" /> + + <!-- Bootstrap core CSS --> + <link href="//oss.maxcdn.com/libs/twitter-bootstrap/3.0.3/css/bootstrap.min.css" rel="stylesheet"> + + <!-- Custom styles for this scaffold --> + <link href="${request.static_url('tutorial:static/theme.css')}" rel="stylesheet"> + + <!-- HTML5 shim and Respond.js IE8 support of HTML5 elements and media queries --> + <!--[if lt IE 9]> + <script src="//oss.maxcdn.com/libs/html5shiv/3.7.0/html5shiv.js"></script> + <script src="//oss.maxcdn.com/libs/respond.js/1.3.0/respond.min.js"></script> + <![endif]--> + </head> + <body> + + <div class="starter-template"> + <div class="container"> + <div class="row"> + <div class="col-md-2"> + <img class="logo img-responsive" src="${request.static_url('tutorial:static/pyramid.png')}" alt="pyramid web framework"> + </div> + <div class="col-md-10"> + <div class="content"> + <p tal:condition="logged_in" class="pull-right"> + <a href="${request.application_url}/logout">Logout</a> + </p> + <div tal:replace="structure content"> + Page text goes here. + </div> + <p> + <a tal:attributes="href edit_url" href=""> + Edit this page + </a> + </p> + <p> + Viewing <strong><span tal:replace="page.name"> + Page Name Goes Here</span></strong> + </p> + <p>You can return to the + <a href="${request.application_url}">FrontPage</a>. + </p> + </div> + </div> </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 class="row"> + <div class="copyright"> + Copyright © Pylons Project + </div> </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> + + + <!-- Bootstrap core JavaScript + ================================================== --> + <!-- Placed at the end of the document so the pages load faster --> + <script src="//oss.maxcdn.com/libs/jquery/1.10.2/jquery.min.js"></script> + <script src="//oss.maxcdn.com/libs/twitter-bootstrap/3.0.3/js/bootstrap.min.js"></script> + </body> </html> diff --git a/docs/tutorials/wiki2/src/basiclayout/tutorial/static/favicon.ico b/docs/tutorials/wiki2/src/basiclayout/tutorial/static/favicon.ico Binary files differdeleted file mode 100644 index 71f837c9e..000000000 --- a/docs/tutorials/wiki2/src/basiclayout/tutorial/static/favicon.ico +++ /dev/null diff --git a/docs/tutorials/wiki2/src/basiclayout/tutorial/static/footerbg.png b/docs/tutorials/wiki2/src/basiclayout/tutorial/static/footerbg.png Binary files differdeleted file mode 100644 index 1fbc873da..000000000 --- a/docs/tutorials/wiki2/src/basiclayout/tutorial/static/footerbg.png +++ /dev/null diff --git a/docs/tutorials/wiki2/src/basiclayout/tutorial/static/headerbg.png b/docs/tutorials/wiki2/src/basiclayout/tutorial/static/headerbg.png Binary files differdeleted file mode 100644 index 0596f2020..000000000 --- a/docs/tutorials/wiki2/src/basiclayout/tutorial/static/headerbg.png +++ /dev/null diff --git a/docs/tutorials/wiki2/src/basiclayout/tutorial/static/ie6.css b/docs/tutorials/wiki2/src/basiclayout/tutorial/static/ie6.css deleted file mode 100644 index b7c8493d8..000000000 --- a/docs/tutorials/wiki2/src/basiclayout/tutorial/static/ie6.css +++ /dev/null @@ -1,8 +0,0 @@ -* 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/middlebg.png b/docs/tutorials/wiki2/src/basiclayout/tutorial/static/middlebg.png Binary files differdeleted file mode 100644 index 2369cfb7d..000000000 --- a/docs/tutorials/wiki2/src/basiclayout/tutorial/static/middlebg.png +++ /dev/null diff --git a/docs/tutorials/wiki2/src/basiclayout/tutorial/static/pylons.css b/docs/tutorials/wiki2/src/basiclayout/tutorial/static/pylons.css deleted file mode 100644 index 4b1c017cd..000000000 --- a/docs/tutorials/wiki2/src/basiclayout/tutorial/static/pylons.css +++ /dev/null @@ -1,372 +0,0 @@ -html, body, div, span, applet, object, iframe, h1, h2, h3, h4, h5, h6, p, blockquote, pre, a, abbr, acronym, address, big, cite, code, del, dfn, em, font, img, ins, kbd, q, s, samp, small, strike, strong, sub, sup, tt, var, b, u, i, center, dl, dt, dd, ol, ul, li, fieldset, form, label, legend, table, caption, tbody, tfoot, thead, tr, th, td -{ - margin: 0; - padding: 0; - border: 0; - outline: 0; - font-size: 100%; /* 16px */ - vertical-align: baseline; - background: transparent; -} - -body -{ - line-height: 1; -} - -ol, ul -{ - list-style: none; -} - -blockquote, q -{ - quotes: none; -} - -blockquote:before, blockquote:after, q:before, q:after -{ - content: ''; - content: none; -} - -:focus -{ - outline: 0; -} - -ins -{ - text-decoration: none; -} - -del -{ - text-decoration: line-through; -} - -table -{ - border-collapse: collapse; - border-spacing: 0; -} - -sub -{ - vertical-align: sub; - font-size: smaller; - line-height: normal; -} - -sup -{ - vertical-align: super; - font-size: smaller; - line-height: normal; -} - -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; -} - -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; -} - -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; -} - -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; - 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: #fff; - position: relative; - font: 16px/24px NobileRegular, "Lucida Grande", Lucida, Verdana, sans-serif; -} - -a -{ - color: #1b61d6; - text-decoration: none; -} - -a:hover -{ - color: #e88f00; - text-decoration: underline; -} - -body h1, body h2, body h3, body h4, body h5, body h6 -{ - font-family: NeutonRegular, "Lucida Grande", Lucida, Verdana, sans-serif; - font-weight: 400; - color: #373839; - font-style: normal; -} - -#wrap -{ - min-height: 100%; -} - -#header, #footer -{ - width: 100%; - color: #fff; - height: 40px; - position: absolute; - text-align: center; - line-height: 40px; - overflow: hidden; - font-size: 12px; - vertical-align: middle; -} - -#header -{ - background: #000; - top: 0; - font-size: 14px; -} - -#footer -{ - bottom: 0; - background: #000 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, #top-small, #bottom -{ - width: 100%; -} - -#top -{ - color: #000; - height: 230px; - background: #fff url(headerbg.png) repeat-x 0 top; - position: relative; -} - -#top-small -{ - color: #000; - height: 60px; - background: #fff url(headerbg.png) repeat-x 0 top; - position: relative; -} - -#bottom -{ - color: #222; - background-color: #fff; -} - -.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 #fff; - border-bottom: 2px solid #b2b2b2; -} - -.app-welcome -{ - margin-top: 25px; -} - -.app-name -{ - color: #000; - font-weight: 700; -} - -.bottom -{ - padding-top: 50px; -} - -#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; -} - -ul.links -{ - margin: 0; - padding: 0; -} - -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=password] -{ - width: 205px; -} - -input[type=submit] -{ - background-color: #ddd; - font-weight: 700; -} - -/*Opera Fix*/ -body:before -{ - content: ""; - height: 100%; - float: left; - width: 0; - margin-top: -32767px; -} diff --git a/docs/tutorials/wiki2/src/basiclayout/tutorial/static/pyramid-16x16.png b/docs/tutorials/wiki2/src/basiclayout/tutorial/static/pyramid-16x16.png Binary files differnew file mode 100644 index 000000000..979203112 --- /dev/null +++ b/docs/tutorials/wiki2/src/basiclayout/tutorial/static/pyramid-16x16.png 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 differdeleted file mode 100644 index a5bc0ade7..000000000 --- a/docs/tutorials/wiki2/src/basiclayout/tutorial/static/pyramid-small.png +++ /dev/null diff --git a/docs/tutorials/wiki2/src/basiclayout/tutorial/static/pyramid.png b/docs/tutorials/wiki2/src/basiclayout/tutorial/static/pyramid.png Binary files differindex 347e05549..4ab837be9 100644 --- a/docs/tutorials/wiki2/src/basiclayout/tutorial/static/pyramid.png +++ b/docs/tutorials/wiki2/src/basiclayout/tutorial/static/pyramid.png diff --git a/docs/tutorials/wiki2/src/basiclayout/tutorial/static/theme.css b/docs/tutorials/wiki2/src/basiclayout/tutorial/static/theme.css new file mode 100644 index 000000000..0f4b1a4d4 --- /dev/null +++ b/docs/tutorials/wiki2/src/basiclayout/tutorial/static/theme.css @@ -0,0 +1,154 @@ +@import url(//fonts.googleapis.com/css?family=Open+Sans:300,400,600,700); +body { + font-family: "Open Sans", "Helvetica Neue", Helvetica, Arial, sans-serif; + font-weight: 300; + color: #ffffff; + background: #bc2131; +} +h1, +h2, +h3, +h4, +h5, +h6 { + font-family: "Open Sans", "Helvetica Neue", Helvetica, Arial, sans-serif; + font-weight: 300; +} +p { + font-weight: 300; +} +.font-normal { + font-weight: 400; +} +.font-semi-bold { + font-weight: 600; +} +.font-bold { + font-weight: 700; +} +.starter-template { + margin-top: 250px; +} +.starter-template .content { + margin-left: 10px; +} +.starter-template .content h1 { + margin-top: 10px; + font-size: 60px; +} +.starter-template .content h1 .smaller { + font-size: 40px; + color: #f2b7bd; +} +.starter-template .content .lead { + font-size: 25px; + color: #f2b7bd; +} +.starter-template .content .lead .font-normal { + color: #ffffff; +} +.starter-template .links { + float: right; + right: 0; + margin-top: 125px; +} +.starter-template .links ul { + display: block; + padding: 0; + margin: 0; +} +.starter-template .links ul li { + list-style: none; + display: inline; + margin: 0 10px; +} +.starter-template .links ul li:first-child { + margin-left: 0; +} +.starter-template .links ul li:last-child { + margin-right: 0; +} +.starter-template .links ul li.current-version { + color: #f2b7bd; + font-weight: 400; +} +.starter-template .links ul li a, a { + color: #f2b7bd; + text-decoration: underline; +} +.starter-template .links ul li a:hover, a:hover { + color: #ffffff; + text-decoration: underline; +} +.starter-template .links ul li .icon-muted { + color: #eb8b95; + margin-right: 5px; +} +.starter-template .links ul li:hover .icon-muted { + color: #ffffff; +} +.starter-template .copyright { + margin-top: 10px; + font-size: 0.9em; + color: #f2b7bd; + text-transform: lowercase; + float: right; + right: 0; +} +@media (max-width: 1199px) { + .starter-template .content h1 { + font-size: 45px; + } + .starter-template .content h1 .smaller { + font-size: 30px; + } + .starter-template .content .lead { + font-size: 20px; + } +} +@media (max-width: 991px) { + .starter-template { + margin-top: 0; + } + .starter-template .logo { + margin: 40px auto; + } + .starter-template .content { + margin-left: 0; + text-align: center; + } + .starter-template .content h1 { + margin-bottom: 20px; + } + .starter-template .links { + float: none; + text-align: center; + margin-top: 60px; + } + .starter-template .copyright { + float: none; + text-align: center; + } +} +@media (max-width: 767px) { + .starter-template .content h1 .smaller { + font-size: 25px; + display: block; + } + .starter-template .content .lead { + font-size: 16px; + } + .starter-template .links { + margin-top: 40px; + } + .starter-template .links ul li { + display: block; + margin: 0; + } + .starter-template .links ul li .icon-muted { + display: none; + } + .starter-template .copyright { + margin-top: 20px; + } +} diff --git a/docs/tutorials/wiki2/src/basiclayout/tutorial/static/theme.min.css b/docs/tutorials/wiki2/src/basiclayout/tutorial/static/theme.min.css new file mode 100644 index 000000000..2f924bcc5 --- /dev/null +++ b/docs/tutorials/wiki2/src/basiclayout/tutorial/static/theme.min.css @@ -0,0 +1 @@ +@import url(//fonts.googleapis.com/css?family=Open+Sans:300,400,600,700);body{font-family:"Open Sans","Helvetica Neue",Helvetica,Arial,sans-serif;font-weight:300;color:#fff;background:#bc2131}h1,h2,h3,h4,h5,h6{font-family:"Open Sans","Helvetica Neue",Helvetica,Arial,sans-serif;font-weight:300}p{font-weight:300}.font-normal{font-weight:400}.font-semi-bold{font-weight:600}.font-bold{font-weight:700}.starter-template{margin-top:250px}.starter-template .content{margin-left:10px}.starter-template .content h1{margin-top:10px;font-size:60px}.starter-template .content h1 .smaller{font-size:40px;color:#f2b7bd}.starter-template .content .lead{font-size:25px;color:#f2b7bd}.starter-template .content .lead .font-normal{color:#fff}.starter-template .links{float:right;right:0;margin-top:125px}.starter-template .links ul{display:block;padding:0;margin:0}.starter-template .links ul li{list-style:none;display:inline;margin:0 10px}.starter-template .links ul li:first-child{margin-left:0}.starter-template .links ul li:last-child{margin-right:0}.starter-template .links ul li.current-version{color:#f2b7bd;font-weight:400}.starter-template .links ul li a{color:#fff}.starter-template .links ul li a:hover{text-decoration:underline}.starter-template .links ul li .icon-muted{color:#eb8b95;margin-right:5px}.starter-template .links ul li:hover .icon-muted{color:#fff}.starter-template .copyright{margin-top:10px;font-size:.9em;color:#f2b7bd;text-transform:lowercase;float:right;right:0}@media (max-width:1199px){.starter-template .content h1{font-size:45px}.starter-template .content h1 .smaller{font-size:30px}.starter-template .content .lead{font-size:20px}}@media (max-width:991px){.starter-template{margin-top:0}.starter-template .logo{margin:40px auto}.starter-template .content{margin-left:0;text-align:center}.starter-template .content h1{margin-bottom:20px}.starter-template .links{float:none;text-align:center;margin-top:60px}.starter-template .copyright{float:none;text-align:center}}@media (max-width:767px){.starter-template .content h1 .smaller{font-size:25px;display:block}.starter-template .content .lead{font-size:16px}.starter-template .links{margin-top:40px}.starter-template .links ul li{display:block;margin:0}.starter-template .links ul li .icon-muted{display:none}.starter-template .copyright{margin-top:20px}}
\ No newline at end of file diff --git a/docs/tutorials/wiki2/src/basiclayout/tutorial/static/transparent.gif b/docs/tutorials/wiki2/src/basiclayout/tutorial/static/transparent.gif Binary files differdeleted file mode 100644 index 0341802e5..000000000 --- a/docs/tutorials/wiki2/src/basiclayout/tutorial/static/transparent.gif +++ /dev/null diff --git a/docs/tutorials/wiki2/src/basiclayout/tutorial/templates/mytemplate.pt b/docs/tutorials/wiki2/src/basiclayout/tutorial/templates/mytemplate.pt index ca4e0af26..c9b0cec21 100644 --- a/docs/tutorials/wiki2/src/basiclayout/tutorial/templates/mytemplate.pt +++ b/docs/tutorials/wiki2/src/basiclayout/tutorial/templates/mytemplate.pt @@ -1,73 +1,66 @@ -<!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 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://static.pylonsproject.org/fonts/nobile/stylesheet.css" media="screen" /> - <link rel="stylesheet" href="http://static.pylonsproject.org/fonts/neuton/stylesheet.css" media="screen" /> - <!--[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="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 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/current/search.html"> - <input type="text" id="q" name="q" value="" /> - <input type="submit" id="x" value="Go" /> - </form> +<!DOCTYPE html> +<html lang="${request.locale_name}"> + <head> + <meta charset="utf-8"> + <meta http-equiv="X-UA-Compatible" content="IE=edge"> + <meta name="viewport" content="width=device-width, initial-scale=1.0"> + <meta name="description" content="pyramid web application"> + <meta name="author" content="Pylons Project"> + <link rel="shortcut icon" href="${request.static_url('tutorial:static/pyramid-16x16.png')}"> + + <title>Alchemy Scaffold for The Pyramid Web Framework</title> + + <!-- Bootstrap core CSS --> + <link href="//oss.maxcdn.com/libs/twitter-bootstrap/3.0.3/css/bootstrap.min.css" rel="stylesheet"> + + <!-- Custom styles for this scaffold --> + <link href="${request.static_url('tutorial:static/theme.css')}" rel="stylesheet"> + + <!-- HTML5 shim and Respond.js IE8 support of HTML5 elements and media queries --> + <!--[if lt IE 9]> + <script src="//oss.maxcdn.com/libs/html5shiv/3.7.0/html5shiv.js"></script> + <script src="//oss.maxcdn.com/libs/respond.js/1.3.0/respond.min.js"></script> + <![endif]--> + </head> + + <body> + + <div class="starter-template"> + <div class="container"> + <div class="row"> + <div class="col-md-2"> + <img class="logo img-responsive" src="${request.static_url('tutorial:static/pyramid.png')}" alt="pyramid web framework"> + </div> + <div class="col-md-10"> + <div class="content"> + <h1><span class="font-semi-bold">Pyramid</span> <span class="smaller">Alchemy scaffold</span></h1> + <p class="lead">Welcome to <span class="font-normal">${project}</span>, an application generated by<br>the <span class="font-normal">Pyramid Web Framework</span>.</p> + </div> + </div> </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/current/#narrative-documentation">Narrative Documentation</a> - </li> - <li> - <a href="http://docs.pylonsproject.org/projects/pyramid/current/#api-documentation">API Documentation</a> - </li> - <li> - <a href="http://docs.pylonsproject.org/projects/pyramid/current/#tutorials">Tutorials</a> - </li> - <li> - <a href="http://docs.pylonsproject.org/projects/pyramid/current/#change-history">Change History</a> - </li> - <li> - <a href="http://docs.pylonsproject.org/projects/pyramid/current/#sample-applications">Sample Applications</a> - </li> - <li> - <a href="http://docs.pylonsproject.org/projects/pyramid/current/#support-and-development">Support and Development</a> - </li> - <li> - <a href="irc://irc.freenode.net#pyramid">IRC Channel</a> - </li> + <div class="row"> + <div class="links"> + <ul> + <li><i class="glyphicon glyphicon-bookmark icon-muted"></i><a href="http://docs.pylonsproject.org/projects/pyramid/en/latest/">Docs</a></li> + <li><i class="glyphicon glyphicon-cog icon-muted"></i><a href="https://github.com/Pylons/pyramid">Github Project</a></li> + <li><i class="glyphicon glyphicon-globe icon-muted"></i><a href="irc://irc.freenode.net#pyramid">IRC Channel</a></li> + <li><i class="glyphicon glyphicon-home icon-muted"></i><a href="http://pylonsproject.org">Pylons Project</a></li> </ul> + </div> + </div> + <div class="row"> + <div class="copyright"> + Copyright © Pylons Project + </div> </div> </div> </div> - </div> -</body> + + + <!-- Bootstrap core JavaScript + ================================================== --> + <!-- Placed at the end of the document so the pages load faster --> + <script src="//oss.maxcdn.com/libs/jquery/1.10.2/jquery.min.js"></script> + <script src="//oss.maxcdn.com/libs/twitter-bootstrap/3.0.3/js/bootstrap.min.js"></script> + </body> </html> diff --git a/docs/tutorials/wiki2/src/models/tutorial/static/favicon.ico b/docs/tutorials/wiki2/src/models/tutorial/static/favicon.ico Binary files differdeleted file mode 100644 index 71f837c9e..000000000 --- a/docs/tutorials/wiki2/src/models/tutorial/static/favicon.ico +++ /dev/null diff --git a/docs/tutorials/wiki2/src/models/tutorial/static/footerbg.png b/docs/tutorials/wiki2/src/models/tutorial/static/footerbg.png Binary files differdeleted file mode 100644 index 1fbc873da..000000000 --- a/docs/tutorials/wiki2/src/models/tutorial/static/footerbg.png +++ /dev/null diff --git a/docs/tutorials/wiki2/src/models/tutorial/static/headerbg.png b/docs/tutorials/wiki2/src/models/tutorial/static/headerbg.png Binary files differdeleted file mode 100644 index 0596f2020..000000000 --- a/docs/tutorials/wiki2/src/models/tutorial/static/headerbg.png +++ /dev/null diff --git a/docs/tutorials/wiki2/src/models/tutorial/static/ie6.css b/docs/tutorials/wiki2/src/models/tutorial/static/ie6.css deleted file mode 100644 index b7c8493d8..000000000 --- a/docs/tutorials/wiki2/src/models/tutorial/static/ie6.css +++ /dev/null @@ -1,8 +0,0 @@ -* 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/middlebg.png b/docs/tutorials/wiki2/src/models/tutorial/static/middlebg.png Binary files differdeleted file mode 100644 index 2369cfb7d..000000000 --- a/docs/tutorials/wiki2/src/models/tutorial/static/middlebg.png +++ /dev/null diff --git a/docs/tutorials/wiki2/src/models/tutorial/static/pylons.css b/docs/tutorials/wiki2/src/models/tutorial/static/pylons.css deleted file mode 100644 index 4b1c017cd..000000000 --- a/docs/tutorials/wiki2/src/models/tutorial/static/pylons.css +++ /dev/null @@ -1,372 +0,0 @@ -html, body, div, span, applet, object, iframe, h1, h2, h3, h4, h5, h6, p, blockquote, pre, a, abbr, acronym, address, big, cite, code, del, dfn, em, font, img, ins, kbd, q, s, samp, small, strike, strong, sub, sup, tt, var, b, u, i, center, dl, dt, dd, ol, ul, li, fieldset, form, label, legend, table, caption, tbody, tfoot, thead, tr, th, td -{ - margin: 0; - padding: 0; - border: 0; - outline: 0; - font-size: 100%; /* 16px */ - vertical-align: baseline; - background: transparent; -} - -body -{ - line-height: 1; -} - -ol, ul -{ - list-style: none; -} - -blockquote, q -{ - quotes: none; -} - -blockquote:before, blockquote:after, q:before, q:after -{ - content: ''; - content: none; -} - -:focus -{ - outline: 0; -} - -ins -{ - text-decoration: none; -} - -del -{ - text-decoration: line-through; -} - -table -{ - border-collapse: collapse; - border-spacing: 0; -} - -sub -{ - vertical-align: sub; - font-size: smaller; - line-height: normal; -} - -sup -{ - vertical-align: super; - font-size: smaller; - line-height: normal; -} - -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; -} - -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; -} - -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; -} - -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; - 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: #fff; - position: relative; - font: 16px/24px NobileRegular, "Lucida Grande", Lucida, Verdana, sans-serif; -} - -a -{ - color: #1b61d6; - text-decoration: none; -} - -a:hover -{ - color: #e88f00; - text-decoration: underline; -} - -body h1, body h2, body h3, body h4, body h5, body h6 -{ - font-family: NeutonRegular, "Lucida Grande", Lucida, Verdana, sans-serif; - font-weight: 400; - color: #373839; - font-style: normal; -} - -#wrap -{ - min-height: 100%; -} - -#header, #footer -{ - width: 100%; - color: #fff; - height: 40px; - position: absolute; - text-align: center; - line-height: 40px; - overflow: hidden; - font-size: 12px; - vertical-align: middle; -} - -#header -{ - background: #000; - top: 0; - font-size: 14px; -} - -#footer -{ - bottom: 0; - background: #000 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, #top-small, #bottom -{ - width: 100%; -} - -#top -{ - color: #000; - height: 230px; - background: #fff url(headerbg.png) repeat-x 0 top; - position: relative; -} - -#top-small -{ - color: #000; - height: 60px; - background: #fff url(headerbg.png) repeat-x 0 top; - position: relative; -} - -#bottom -{ - color: #222; - background-color: #fff; -} - -.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 #fff; - border-bottom: 2px solid #b2b2b2; -} - -.app-welcome -{ - margin-top: 25px; -} - -.app-name -{ - color: #000; - font-weight: 700; -} - -.bottom -{ - padding-top: 50px; -} - -#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; -} - -ul.links -{ - margin: 0; - padding: 0; -} - -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=password] -{ - width: 205px; -} - -input[type=submit] -{ - background-color: #ddd; - font-weight: 700; -} - -/*Opera Fix*/ -body:before -{ - content: ""; - height: 100%; - float: left; - width: 0; - margin-top: -32767px; -} diff --git a/docs/tutorials/wiki2/src/models/tutorial/static/pyramid-16x16.png b/docs/tutorials/wiki2/src/models/tutorial/static/pyramid-16x16.png Binary files differnew file mode 100644 index 000000000..979203112 --- /dev/null +++ b/docs/tutorials/wiki2/src/models/tutorial/static/pyramid-16x16.png 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 differdeleted file mode 100644 index a5bc0ade7..000000000 --- a/docs/tutorials/wiki2/src/models/tutorial/static/pyramid-small.png +++ /dev/null diff --git a/docs/tutorials/wiki2/src/models/tutorial/static/pyramid.png b/docs/tutorials/wiki2/src/models/tutorial/static/pyramid.png Binary files differindex 347e05549..4ab837be9 100644 --- a/docs/tutorials/wiki2/src/models/tutorial/static/pyramid.png +++ b/docs/tutorials/wiki2/src/models/tutorial/static/pyramid.png diff --git a/docs/tutorials/wiki2/src/models/tutorial/static/theme.css b/docs/tutorials/wiki2/src/models/tutorial/static/theme.css new file mode 100644 index 000000000..0f4b1a4d4 --- /dev/null +++ b/docs/tutorials/wiki2/src/models/tutorial/static/theme.css @@ -0,0 +1,154 @@ +@import url(//fonts.googleapis.com/css?family=Open+Sans:300,400,600,700); +body { + font-family: "Open Sans", "Helvetica Neue", Helvetica, Arial, sans-serif; + font-weight: 300; + color: #ffffff; + background: #bc2131; +} +h1, +h2, +h3, +h4, +h5, +h6 { + font-family: "Open Sans", "Helvetica Neue", Helvetica, Arial, sans-serif; + font-weight: 300; +} +p { + font-weight: 300; +} +.font-normal { + font-weight: 400; +} +.font-semi-bold { + font-weight: 600; +} +.font-bold { + font-weight: 700; +} +.starter-template { + margin-top: 250px; +} +.starter-template .content { + margin-left: 10px; +} +.starter-template .content h1 { + margin-top: 10px; + font-size: 60px; +} +.starter-template .content h1 .smaller { + font-size: 40px; + color: #f2b7bd; +} +.starter-template .content .lead { + font-size: 25px; + color: #f2b7bd; +} +.starter-template .content .lead .font-normal { + color: #ffffff; +} +.starter-template .links { + float: right; + right: 0; + margin-top: 125px; +} +.starter-template .links ul { + display: block; + padding: 0; + margin: 0; +} +.starter-template .links ul li { + list-style: none; + display: inline; + margin: 0 10px; +} +.starter-template .links ul li:first-child { + margin-left: 0; +} +.starter-template .links ul li:last-child { + margin-right: 0; +} +.starter-template .links ul li.current-version { + color: #f2b7bd; + font-weight: 400; +} +.starter-template .links ul li a, a { + color: #f2b7bd; + text-decoration: underline; +} +.starter-template .links ul li a:hover, a:hover { + color: #ffffff; + text-decoration: underline; +} +.starter-template .links ul li .icon-muted { + color: #eb8b95; + margin-right: 5px; +} +.starter-template .links ul li:hover .icon-muted { + color: #ffffff; +} +.starter-template .copyright { + margin-top: 10px; + font-size: 0.9em; + color: #f2b7bd; + text-transform: lowercase; + float: right; + right: 0; +} +@media (max-width: 1199px) { + .starter-template .content h1 { + font-size: 45px; + } + .starter-template .content h1 .smaller { + font-size: 30px; + } + .starter-template .content .lead { + font-size: 20px; + } +} +@media (max-width: 991px) { + .starter-template { + margin-top: 0; + } + .starter-template .logo { + margin: 40px auto; + } + .starter-template .content { + margin-left: 0; + text-align: center; + } + .starter-template .content h1 { + margin-bottom: 20px; + } + .starter-template .links { + float: none; + text-align: center; + margin-top: 60px; + } + .starter-template .copyright { + float: none; + text-align: center; + } +} +@media (max-width: 767px) { + .starter-template .content h1 .smaller { + font-size: 25px; + display: block; + } + .starter-template .content .lead { + font-size: 16px; + } + .starter-template .links { + margin-top: 40px; + } + .starter-template .links ul li { + display: block; + margin: 0; + } + .starter-template .links ul li .icon-muted { + display: none; + } + .starter-template .copyright { + margin-top: 20px; + } +} diff --git a/docs/tutorials/wiki2/src/models/tutorial/static/theme.min.css b/docs/tutorials/wiki2/src/models/tutorial/static/theme.min.css new file mode 100644 index 000000000..2f924bcc5 --- /dev/null +++ b/docs/tutorials/wiki2/src/models/tutorial/static/theme.min.css @@ -0,0 +1 @@ +@import url(//fonts.googleapis.com/css?family=Open+Sans:300,400,600,700);body{font-family:"Open Sans","Helvetica Neue",Helvetica,Arial,sans-serif;font-weight:300;color:#fff;background:#bc2131}h1,h2,h3,h4,h5,h6{font-family:"Open Sans","Helvetica Neue",Helvetica,Arial,sans-serif;font-weight:300}p{font-weight:300}.font-normal{font-weight:400}.font-semi-bold{font-weight:600}.font-bold{font-weight:700}.starter-template{margin-top:250px}.starter-template .content{margin-left:10px}.starter-template .content h1{margin-top:10px;font-size:60px}.starter-template .content h1 .smaller{font-size:40px;color:#f2b7bd}.starter-template .content .lead{font-size:25px;color:#f2b7bd}.starter-template .content .lead .font-normal{color:#fff}.starter-template .links{float:right;right:0;margin-top:125px}.starter-template .links ul{display:block;padding:0;margin:0}.starter-template .links ul li{list-style:none;display:inline;margin:0 10px}.starter-template .links ul li:first-child{margin-left:0}.starter-template .links ul li:last-child{margin-right:0}.starter-template .links ul li.current-version{color:#f2b7bd;font-weight:400}.starter-template .links ul li a{color:#fff}.starter-template .links ul li a:hover{text-decoration:underline}.starter-template .links ul li .icon-muted{color:#eb8b95;margin-right:5px}.starter-template .links ul li:hover .icon-muted{color:#fff}.starter-template .copyright{margin-top:10px;font-size:.9em;color:#f2b7bd;text-transform:lowercase;float:right;right:0}@media (max-width:1199px){.starter-template .content h1{font-size:45px}.starter-template .content h1 .smaller{font-size:30px}.starter-template .content .lead{font-size:20px}}@media (max-width:991px){.starter-template{margin-top:0}.starter-template .logo{margin:40px auto}.starter-template .content{margin-left:0;text-align:center}.starter-template .content h1{margin-bottom:20px}.starter-template .links{float:none;text-align:center;margin-top:60px}.starter-template .copyright{float:none;text-align:center}}@media (max-width:767px){.starter-template .content h1 .smaller{font-size:25px;display:block}.starter-template .content .lead{font-size:16px}.starter-template .links{margin-top:40px}.starter-template .links ul li{display:block;margin:0}.starter-template .links ul li .icon-muted{display:none}.starter-template .copyright{margin-top:20px}}
\ No newline at end of file diff --git a/docs/tutorials/wiki2/src/models/tutorial/static/transparent.gif b/docs/tutorials/wiki2/src/models/tutorial/static/transparent.gif Binary files differdeleted file mode 100644 index 0341802e5..000000000 --- a/docs/tutorials/wiki2/src/models/tutorial/static/transparent.gif +++ /dev/null diff --git a/docs/tutorials/wiki2/src/models/tutorial/templates/mytemplate.pt b/docs/tutorials/wiki2/src/models/tutorial/templates/mytemplate.pt index ca4e0af26..c9b0cec21 100644 --- a/docs/tutorials/wiki2/src/models/tutorial/templates/mytemplate.pt +++ b/docs/tutorials/wiki2/src/models/tutorial/templates/mytemplate.pt @@ -1,73 +1,66 @@ -<!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 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://static.pylonsproject.org/fonts/nobile/stylesheet.css" media="screen" /> - <link rel="stylesheet" href="http://static.pylonsproject.org/fonts/neuton/stylesheet.css" media="screen" /> - <!--[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="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 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/current/search.html"> - <input type="text" id="q" name="q" value="" /> - <input type="submit" id="x" value="Go" /> - </form> +<!DOCTYPE html> +<html lang="${request.locale_name}"> + <head> + <meta charset="utf-8"> + <meta http-equiv="X-UA-Compatible" content="IE=edge"> + <meta name="viewport" content="width=device-width, initial-scale=1.0"> + <meta name="description" content="pyramid web application"> + <meta name="author" content="Pylons Project"> + <link rel="shortcut icon" href="${request.static_url('tutorial:static/pyramid-16x16.png')}"> + + <title>Alchemy Scaffold for The Pyramid Web Framework</title> + + <!-- Bootstrap core CSS --> + <link href="//oss.maxcdn.com/libs/twitter-bootstrap/3.0.3/css/bootstrap.min.css" rel="stylesheet"> + + <!-- Custom styles for this scaffold --> + <link href="${request.static_url('tutorial:static/theme.css')}" rel="stylesheet"> + + <!-- HTML5 shim and Respond.js IE8 support of HTML5 elements and media queries --> + <!--[if lt IE 9]> + <script src="//oss.maxcdn.com/libs/html5shiv/3.7.0/html5shiv.js"></script> + <script src="//oss.maxcdn.com/libs/respond.js/1.3.0/respond.min.js"></script> + <![endif]--> + </head> + + <body> + + <div class="starter-template"> + <div class="container"> + <div class="row"> + <div class="col-md-2"> + <img class="logo img-responsive" src="${request.static_url('tutorial:static/pyramid.png')}" alt="pyramid web framework"> + </div> + <div class="col-md-10"> + <div class="content"> + <h1><span class="font-semi-bold">Pyramid</span> <span class="smaller">Alchemy scaffold</span></h1> + <p class="lead">Welcome to <span class="font-normal">${project}</span>, an application generated by<br>the <span class="font-normal">Pyramid Web Framework</span>.</p> + </div> + </div> </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/current/#narrative-documentation">Narrative Documentation</a> - </li> - <li> - <a href="http://docs.pylonsproject.org/projects/pyramid/current/#api-documentation">API Documentation</a> - </li> - <li> - <a href="http://docs.pylonsproject.org/projects/pyramid/current/#tutorials">Tutorials</a> - </li> - <li> - <a href="http://docs.pylonsproject.org/projects/pyramid/current/#change-history">Change History</a> - </li> - <li> - <a href="http://docs.pylonsproject.org/projects/pyramid/current/#sample-applications">Sample Applications</a> - </li> - <li> - <a href="http://docs.pylonsproject.org/projects/pyramid/current/#support-and-development">Support and Development</a> - </li> - <li> - <a href="irc://irc.freenode.net#pyramid">IRC Channel</a> - </li> + <div class="row"> + <div class="links"> + <ul> + <li><i class="glyphicon glyphicon-bookmark icon-muted"></i><a href="http://docs.pylonsproject.org/projects/pyramid/en/latest/">Docs</a></li> + <li><i class="glyphicon glyphicon-cog icon-muted"></i><a href="https://github.com/Pylons/pyramid">Github Project</a></li> + <li><i class="glyphicon glyphicon-globe icon-muted"></i><a href="irc://irc.freenode.net#pyramid">IRC Channel</a></li> + <li><i class="glyphicon glyphicon-home icon-muted"></i><a href="http://pylonsproject.org">Pylons Project</a></li> </ul> + </div> + </div> + <div class="row"> + <div class="copyright"> + Copyright © Pylons Project + </div> </div> </div> </div> - </div> -</body> + + + <!-- Bootstrap core JavaScript + ================================================== --> + <!-- Placed at the end of the document so the pages load faster --> + <script src="//oss.maxcdn.com/libs/jquery/1.10.2/jquery.min.js"></script> + <script src="//oss.maxcdn.com/libs/twitter-bootstrap/3.0.3/js/bootstrap.min.js"></script> + </body> </html> diff --git a/docs/tutorials/wiki2/src/tests/tutorial/static/favicon.ico b/docs/tutorials/wiki2/src/tests/tutorial/static/favicon.ico Binary files differdeleted file mode 100644 index 71f837c9e..000000000 --- a/docs/tutorials/wiki2/src/tests/tutorial/static/favicon.ico +++ /dev/null diff --git a/docs/tutorials/wiki2/src/tests/tutorial/static/footerbg.png b/docs/tutorials/wiki2/src/tests/tutorial/static/footerbg.png Binary files differdeleted file mode 100644 index 1fbc873da..000000000 --- a/docs/tutorials/wiki2/src/tests/tutorial/static/footerbg.png +++ /dev/null diff --git a/docs/tutorials/wiki2/src/tests/tutorial/static/headerbg.png b/docs/tutorials/wiki2/src/tests/tutorial/static/headerbg.png Binary files differdeleted file mode 100644 index 0596f2020..000000000 --- a/docs/tutorials/wiki2/src/tests/tutorial/static/headerbg.png +++ /dev/null diff --git a/docs/tutorials/wiki2/src/tests/tutorial/static/ie6.css b/docs/tutorials/wiki2/src/tests/tutorial/static/ie6.css deleted file mode 100644 index b7c8493d8..000000000 --- a/docs/tutorials/wiki2/src/tests/tutorial/static/ie6.css +++ /dev/null @@ -1,8 +0,0 @@ -* 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/tests/tutorial/static/middlebg.png b/docs/tutorials/wiki2/src/tests/tutorial/static/middlebg.png Binary files differdeleted file mode 100644 index 2369cfb7d..000000000 --- a/docs/tutorials/wiki2/src/tests/tutorial/static/middlebg.png +++ /dev/null diff --git a/docs/tutorials/wiki2/src/tests/tutorial/static/pylons.css b/docs/tutorials/wiki2/src/tests/tutorial/static/pylons.css deleted file mode 100644 index 4b1c017cd..000000000 --- a/docs/tutorials/wiki2/src/tests/tutorial/static/pylons.css +++ /dev/null @@ -1,372 +0,0 @@ -html, body, div, span, applet, object, iframe, h1, h2, h3, h4, h5, h6, p, blockquote, pre, a, abbr, acronym, address, big, cite, code, del, dfn, em, font, img, ins, kbd, q, s, samp, small, strike, strong, sub, sup, tt, var, b, u, i, center, dl, dt, dd, ol, ul, li, fieldset, form, label, legend, table, caption, tbody, tfoot, thead, tr, th, td -{ - margin: 0; - padding: 0; - border: 0; - outline: 0; - font-size: 100%; /* 16px */ - vertical-align: baseline; - background: transparent; -} - -body -{ - line-height: 1; -} - -ol, ul -{ - list-style: none; -} - -blockquote, q -{ - quotes: none; -} - -blockquote:before, blockquote:after, q:before, q:after -{ - content: ''; - content: none; -} - -:focus -{ - outline: 0; -} - -ins -{ - text-decoration: none; -} - -del -{ - text-decoration: line-through; -} - -table -{ - border-collapse: collapse; - border-spacing: 0; -} - -sub -{ - vertical-align: sub; - font-size: smaller; - line-height: normal; -} - -sup -{ - vertical-align: super; - font-size: smaller; - line-height: normal; -} - -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; -} - -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; -} - -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; -} - -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; - 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: #fff; - position: relative; - font: 16px/24px NobileRegular, "Lucida Grande", Lucida, Verdana, sans-serif; -} - -a -{ - color: #1b61d6; - text-decoration: none; -} - -a:hover -{ - color: #e88f00; - text-decoration: underline; -} - -body h1, body h2, body h3, body h4, body h5, body h6 -{ - font-family: NeutonRegular, "Lucida Grande", Lucida, Verdana, sans-serif; - font-weight: 400; - color: #373839; - font-style: normal; -} - -#wrap -{ - min-height: 100%; -} - -#header, #footer -{ - width: 100%; - color: #fff; - height: 40px; - position: absolute; - text-align: center; - line-height: 40px; - overflow: hidden; - font-size: 12px; - vertical-align: middle; -} - -#header -{ - background: #000; - top: 0; - font-size: 14px; -} - -#footer -{ - bottom: 0; - background: #000 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, #top-small, #bottom -{ - width: 100%; -} - -#top -{ - color: #000; - height: 230px; - background: #fff url(headerbg.png) repeat-x 0 top; - position: relative; -} - -#top-small -{ - color: #000; - height: 60px; - background: #fff url(headerbg.png) repeat-x 0 top; - position: relative; -} - -#bottom -{ - color: #222; - background-color: #fff; -} - -.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 #fff; - border-bottom: 2px solid #b2b2b2; -} - -.app-welcome -{ - margin-top: 25px; -} - -.app-name -{ - color: #000; - font-weight: 700; -} - -.bottom -{ - padding-top: 50px; -} - -#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; -} - -ul.links -{ - margin: 0; - padding: 0; -} - -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=password] -{ - width: 205px; -} - -input[type=submit] -{ - background-color: #ddd; - font-weight: 700; -} - -/*Opera Fix*/ -body:before -{ - content: ""; - height: 100%; - float: left; - width: 0; - margin-top: -32767px; -} diff --git a/docs/tutorials/wiki2/src/tests/tutorial/static/pyramid-16x16.png b/docs/tutorials/wiki2/src/tests/tutorial/static/pyramid-16x16.png Binary files differnew file mode 100644 index 000000000..979203112 --- /dev/null +++ b/docs/tutorials/wiki2/src/tests/tutorial/static/pyramid-16x16.png diff --git a/docs/tutorials/wiki2/src/tests/tutorial/static/pyramid-small.png b/docs/tutorials/wiki2/src/tests/tutorial/static/pyramid-small.png Binary files differdeleted file mode 100644 index a5bc0ade7..000000000 --- a/docs/tutorials/wiki2/src/tests/tutorial/static/pyramid-small.png +++ /dev/null diff --git a/docs/tutorials/wiki2/src/tests/tutorial/static/pyramid.png b/docs/tutorials/wiki2/src/tests/tutorial/static/pyramid.png Binary files differindex 347e05549..4ab837be9 100644 --- a/docs/tutorials/wiki2/src/tests/tutorial/static/pyramid.png +++ b/docs/tutorials/wiki2/src/tests/tutorial/static/pyramid.png diff --git a/docs/tutorials/wiki2/src/tests/tutorial/static/theme.css b/docs/tutorials/wiki2/src/tests/tutorial/static/theme.css new file mode 100644 index 000000000..0f4b1a4d4 --- /dev/null +++ b/docs/tutorials/wiki2/src/tests/tutorial/static/theme.css @@ -0,0 +1,154 @@ +@import url(//fonts.googleapis.com/css?family=Open+Sans:300,400,600,700); +body { + font-family: "Open Sans", "Helvetica Neue", Helvetica, Arial, sans-serif; + font-weight: 300; + color: #ffffff; + background: #bc2131; +} +h1, +h2, +h3, +h4, +h5, +h6 { + font-family: "Open Sans", "Helvetica Neue", Helvetica, Arial, sans-serif; + font-weight: 300; +} +p { + font-weight: 300; +} +.font-normal { + font-weight: 400; +} +.font-semi-bold { + font-weight: 600; +} +.font-bold { + font-weight: 700; +} +.starter-template { + margin-top: 250px; +} +.starter-template .content { + margin-left: 10px; +} +.starter-template .content h1 { + margin-top: 10px; + font-size: 60px; +} +.starter-template .content h1 .smaller { + font-size: 40px; + color: #f2b7bd; +} +.starter-template .content .lead { + font-size: 25px; + color: #f2b7bd; +} +.starter-template .content .lead .font-normal { + color: #ffffff; +} +.starter-template .links { + float: right; + right: 0; + margin-top: 125px; +} +.starter-template .links ul { + display: block; + padding: 0; + margin: 0; +} +.starter-template .links ul li { + list-style: none; + display: inline; + margin: 0 10px; +} +.starter-template .links ul li:first-child { + margin-left: 0; +} +.starter-template .links ul li:last-child { + margin-right: 0; +} +.starter-template .links ul li.current-version { + color: #f2b7bd; + font-weight: 400; +} +.starter-template .links ul li a, a { + color: #f2b7bd; + text-decoration: underline; +} +.starter-template .links ul li a:hover, a:hover { + color: #ffffff; + text-decoration: underline; +} +.starter-template .links ul li .icon-muted { + color: #eb8b95; + margin-right: 5px; +} +.starter-template .links ul li:hover .icon-muted { + color: #ffffff; +} +.starter-template .copyright { + margin-top: 10px; + font-size: 0.9em; + color: #f2b7bd; + text-transform: lowercase; + float: right; + right: 0; +} +@media (max-width: 1199px) { + .starter-template .content h1 { + font-size: 45px; + } + .starter-template .content h1 .smaller { + font-size: 30px; + } + .starter-template .content .lead { + font-size: 20px; + } +} +@media (max-width: 991px) { + .starter-template { + margin-top: 0; + } + .starter-template .logo { + margin: 40px auto; + } + .starter-template .content { + margin-left: 0; + text-align: center; + } + .starter-template .content h1 { + margin-bottom: 20px; + } + .starter-template .links { + float: none; + text-align: center; + margin-top: 60px; + } + .starter-template .copyright { + float: none; + text-align: center; + } +} +@media (max-width: 767px) { + .starter-template .content h1 .smaller { + font-size: 25px; + display: block; + } + .starter-template .content .lead { + font-size: 16px; + } + .starter-template .links { + margin-top: 40px; + } + .starter-template .links ul li { + display: block; + margin: 0; + } + .starter-template .links ul li .icon-muted { + display: none; + } + .starter-template .copyright { + margin-top: 20px; + } +} diff --git a/docs/tutorials/wiki2/src/tests/tutorial/static/theme.min.css b/docs/tutorials/wiki2/src/tests/tutorial/static/theme.min.css new file mode 100644 index 000000000..2f924bcc5 --- /dev/null +++ b/docs/tutorials/wiki2/src/tests/tutorial/static/theme.min.css @@ -0,0 +1 @@ +@import url(//fonts.googleapis.com/css?family=Open+Sans:300,400,600,700);body{font-family:"Open Sans","Helvetica Neue",Helvetica,Arial,sans-serif;font-weight:300;color:#fff;background:#bc2131}h1,h2,h3,h4,h5,h6{font-family:"Open Sans","Helvetica Neue",Helvetica,Arial,sans-serif;font-weight:300}p{font-weight:300}.font-normal{font-weight:400}.font-semi-bold{font-weight:600}.font-bold{font-weight:700}.starter-template{margin-top:250px}.starter-template .content{margin-left:10px}.starter-template .content h1{margin-top:10px;font-size:60px}.starter-template .content h1 .smaller{font-size:40px;color:#f2b7bd}.starter-template .content .lead{font-size:25px;color:#f2b7bd}.starter-template .content .lead .font-normal{color:#fff}.starter-template .links{float:right;right:0;margin-top:125px}.starter-template .links ul{display:block;padding:0;margin:0}.starter-template .links ul li{list-style:none;display:inline;margin:0 10px}.starter-template .links ul li:first-child{margin-left:0}.starter-template .links ul li:last-child{margin-right:0}.starter-template .links ul li.current-version{color:#f2b7bd;font-weight:400}.starter-template .links ul li a{color:#fff}.starter-template .links ul li a:hover{text-decoration:underline}.starter-template .links ul li .icon-muted{color:#eb8b95;margin-right:5px}.starter-template .links ul li:hover .icon-muted{color:#fff}.starter-template .copyright{margin-top:10px;font-size:.9em;color:#f2b7bd;text-transform:lowercase;float:right;right:0}@media (max-width:1199px){.starter-template .content h1{font-size:45px}.starter-template .content h1 .smaller{font-size:30px}.starter-template .content .lead{font-size:20px}}@media (max-width:991px){.starter-template{margin-top:0}.starter-template .logo{margin:40px auto}.starter-template .content{margin-left:0;text-align:center}.starter-template .content h1{margin-bottom:20px}.starter-template .links{float:none;text-align:center;margin-top:60px}.starter-template .copyright{float:none;text-align:center}}@media (max-width:767px){.starter-template .content h1 .smaller{font-size:25px;display:block}.starter-template .content .lead{font-size:16px}.starter-template .links{margin-top:40px}.starter-template .links ul li{display:block;margin:0}.starter-template .links ul li .icon-muted{display:none}.starter-template .copyright{margin-top:20px}}
\ No newline at end of file diff --git a/docs/tutorials/wiki2/src/tests/tutorial/static/transparent.gif b/docs/tutorials/wiki2/src/tests/tutorial/static/transparent.gif Binary files differdeleted file mode 100644 index 0341802e5..000000000 --- a/docs/tutorials/wiki2/src/tests/tutorial/static/transparent.gif +++ /dev/null diff --git a/docs/tutorials/wiki2/src/tests/tutorial/templates/edit.pt b/docs/tutorials/wiki2/src/tests/tutorial/templates/edit.pt index 2004273fe..50e55c850 100644 --- a/docs/tutorials/wiki2/src/tests/tutorial/templates/edit.pt +++ b/docs/tutorials/wiki2/src/tests/tutorial/templates/edit.pt @@ -1,58 +1,74 @@ -<!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>${page.name} - Pyramid tutorial wiki (based on +<!DOCTYPE html> +<html lang="${request.locale_name}"> + <head> + <meta charset="utf-8"> + <meta http-equiv="X-UA-Compatible" content="IE=edge"> + <meta name="viewport" content="width=device-width, initial-scale=1.0"> + <meta name="description" content="pyramid web application"> + <meta name="author" content="Pylons Project"> + <link rel="shortcut icon" href="${request.static_url('tutorial:static/pyramid-16x16.png')}"> + + <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 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')}" /> + + <!-- Bootstrap core CSS --> + <link href="//oss.maxcdn.com/libs/twitter-bootstrap/3.0.3/css/bootstrap.min.css" rel="stylesheet"> + + <!-- Custom styles for this scaffold --> + <link href="${request.static_url('tutorial:static/theme.css')}" rel="stylesheet"> + + <!-- HTML5 shim and Respond.js IE8 support of HTML5 elements and media queries --> + <!--[if lt IE 9]> + <script src="//oss.maxcdn.com/libs/html5shiv/3.7.0/html5shiv.js"></script> + <script src="//oss.maxcdn.com/libs/respond.js/1.3.0/respond.min.js"></script> + <![endif]--> + </head> + <body> + + <div class="starter-template"> + <div class="container"> + <div class="row"> + <div class="col-md-2"> + <img class="logo img-responsive" src="${request.static_url('tutorial:static/pyramid.png')}" alt="pyramid web framework"> + </div> + <div class="col-md-10"> + <div class="content"> + <p> + Editing <strong><span tal:replace="page.name">Page Name Goes + Here</span></strong> + </p> + <p>You can return to the + <a href="${request.application_url}">FrontPage</a>. + </p> + <p class="pull-right"> + <span tal:condition="logged_in"> + <a href="${request.application_url}/logout">Logout</a> + </span> + </p> + <form action="${save_url}" method="post"> + <div class="form-group"> + <textarea class="form-control" name="body" tal:content="page.data" rows="10" cols="60"></textarea> + </div> + <div class="form-group"> + <button type="submit" name="form.submitted" value="Save" class="btn btn-default">Save</button> + </div> + </form> + </div> + </div> </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 class="row"> + <div class="copyright"> + Copyright © Pylons Project + </div> </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> -</body> + + + <!-- Bootstrap core JavaScript + ================================================== --> + <!-- Placed at the end of the document so the pages load faster --> + <script src="//oss.maxcdn.com/libs/jquery/1.10.2/jquery.min.js"></script> + <script src="//oss.maxcdn.com/libs/twitter-bootstrap/3.0.3/js/bootstrap.min.js"></script> + </body> </html> diff --git a/docs/tutorials/wiki2/src/tests/tutorial/templates/mytemplate.pt b/docs/tutorials/wiki2/src/tests/tutorial/templates/mytemplate.pt index 6c1ca924a..c9b0cec21 100644 --- a/docs/tutorials/wiki2/src/tests/tutorial/templates/mytemplate.pt +++ b/docs/tutorials/wiki2/src/tests/tutorial/templates/mytemplate.pt @@ -1,73 +1,66 @@ -<!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 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="http://static.pylonsproject.org/fonts/nobile/stylesheet.css" media="screen" /> - <link rel="stylesheet" href="http://static.pylonsproject.org/fonts/neuton/stylesheet.css" media="screen" /> - <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 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 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/current/search.html"> - <input type="text" id="q" name="q" value="" /> - <input type="submit" id="x" value="Go" /> - </form> +<!DOCTYPE html> +<html lang="${request.locale_name}"> + <head> + <meta charset="utf-8"> + <meta http-equiv="X-UA-Compatible" content="IE=edge"> + <meta name="viewport" content="width=device-width, initial-scale=1.0"> + <meta name="description" content="pyramid web application"> + <meta name="author" content="Pylons Project"> + <link rel="shortcut icon" href="${request.static_url('tutorial:static/pyramid-16x16.png')}"> + + <title>Alchemy Scaffold for The Pyramid Web Framework</title> + + <!-- Bootstrap core CSS --> + <link href="//oss.maxcdn.com/libs/twitter-bootstrap/3.0.3/css/bootstrap.min.css" rel="stylesheet"> + + <!-- Custom styles for this scaffold --> + <link href="${request.static_url('tutorial:static/theme.css')}" rel="stylesheet"> + + <!-- HTML5 shim and Respond.js IE8 support of HTML5 elements and media queries --> + <!--[if lt IE 9]> + <script src="//oss.maxcdn.com/libs/html5shiv/3.7.0/html5shiv.js"></script> + <script src="//oss.maxcdn.com/libs/respond.js/1.3.0/respond.min.js"></script> + <![endif]--> + </head> + + <body> + + <div class="starter-template"> + <div class="container"> + <div class="row"> + <div class="col-md-2"> + <img class="logo img-responsive" src="${request.static_url('tutorial:static/pyramid.png')}" alt="pyramid web framework"> + </div> + <div class="col-md-10"> + <div class="content"> + <h1><span class="font-semi-bold">Pyramid</span> <span class="smaller">Alchemy scaffold</span></h1> + <p class="lead">Welcome to <span class="font-normal">${project}</span>, an application generated by<br>the <span class="font-normal">Pyramid Web Framework</span>.</p> + </div> + </div> </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/current/#narrative-documentation">Narrative Documentation</a> - </li> - <li> - <a href="http://docs.pylonsproject.org/projects/pyramid/current/#api-documentation">API Documentation</a> - </li> - <li> - <a href="http://docs.pylonsproject.org/projects/pyramid/current/#tutorials">Tutorials</a> - </li> - <li> - <a href="http://docs.pylonsproject.org/projects/pyramid/current/#change-history">Change History</a> - </li> - <li> - <a href="http://docs.pylonsproject.org/projects/pyramid/current/#sample-applications">Sample Applications</a> - </li> - <li> - <a href="http://docs.pylonsproject.org/projects/pyramid/current/#support-and-development">Support and Development</a> - </li> - <li> - <a href="irc://irc.freenode.net#pyramid">IRC Channel</a> - </li> + <div class="row"> + <div class="links"> + <ul> + <li><i class="glyphicon glyphicon-bookmark icon-muted"></i><a href="http://docs.pylonsproject.org/projects/pyramid/en/latest/">Docs</a></li> + <li><i class="glyphicon glyphicon-cog icon-muted"></i><a href="https://github.com/Pylons/pyramid">Github Project</a></li> + <li><i class="glyphicon glyphicon-globe icon-muted"></i><a href="irc://irc.freenode.net#pyramid">IRC Channel</a></li> + <li><i class="glyphicon glyphicon-home icon-muted"></i><a href="http://pylonsproject.org">Pylons Project</a></li> </ul> + </div> + </div> + <div class="row"> + <div class="copyright"> + Copyright © Pylons Project + </div> </div> </div> </div> - </div> -</body> + + + <!-- Bootstrap core JavaScript + ================================================== --> + <!-- Placed at the end of the document so the pages load faster --> + <script src="//oss.maxcdn.com/libs/jquery/1.10.2/jquery.min.js"></script> + <script src="//oss.maxcdn.com/libs/twitter-bootstrap/3.0.3/js/bootstrap.min.js"></script> + </body> </html> diff --git a/docs/tutorials/wiki2/src/tests/tutorial/templates/view.pt b/docs/tutorials/wiki2/src/tests/tutorial/templates/view.pt index 19c50fb36..4e5772de0 100644 --- a/docs/tutorials/wiki2/src/tests/tutorial/templates/view.pt +++ b/docs/tutorials/wiki2/src/tests/tutorial/templates/view.pt @@ -1,61 +1,74 @@ -<!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>${page.name} - Pyramid tutorial wiki (based on +<!DOCTYPE html> +<html lang="${request.locale_name}"> + <head> + <meta charset="utf-8"> + <meta http-equiv="X-UA-Compatible" content="IE=edge"> + <meta name="viewport" content="width=device-width, initial-scale=1.0"> + <meta name="description" content="pyramid web application"> + <meta name="author" content="Pylons Project"> + <link rel="shortcut icon" href="${request.static_url('tutorial:static/pyramid-16x16.png')}"> + + <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 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')}" /> + + <!-- Bootstrap core CSS --> + <link href="//oss.maxcdn.com/libs/twitter-bootstrap/3.0.3/css/bootstrap.min.css" rel="stylesheet"> + + <!-- Custom styles for this scaffold --> + <link href="${request.static_url('tutorial:static/theme.css')}" rel="stylesheet"> + + <!-- HTML5 shim and Respond.js IE8 support of HTML5 elements and media queries --> + <!--[if lt IE 9]> + <script src="//oss.maxcdn.com/libs/html5shiv/3.7.0/html5shiv.js"></script> + <script src="//oss.maxcdn.com/libs/respond.js/1.3.0/respond.min.js"></script> + <![endif]--> + </head> + <body> + + <div class="starter-template"> + <div class="container"> + <div class="row"> + <div class="col-md-2"> + <img class="logo img-responsive" src="${request.static_url('tutorial:static/pyramid.png')}" alt="pyramid web framework"> + </div> + <div class="col-md-10"> + <div class="content"> + <div tal:replace="structure content"> + Page text goes here. + </div> + <p> + <a tal:attributes="href edit_url" href=""> + Edit this page + </a> + </p> + <p> + Viewing <strong><span tal:replace="page.name"> + Page Name Goes Here</span></strong> + </p> + <p>You can return to the + <a href="${request.application_url}">FrontPage</a>. + </p> + <p class="pull-right"> + <span tal:condition="logged_in"> + <a href="${request.application_url}/logout">Logout</a> + </span> + </p> + </div> + </div> </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 class="row"> + <div class="copyright"> + Copyright © Pylons Project + </div> </div> - <p> - <a tal:attributes="href edit_url" href=""> - Edit this page - </a> - </p> </div> </div> - </div> -</body> + + + <!-- Bootstrap core JavaScript + ================================================== --> + <!-- Placed at the end of the document so the pages load faster --> + <script src="//oss.maxcdn.com/libs/jquery/1.10.2/jquery.min.js"></script> + <script src="//oss.maxcdn.com/libs/twitter-bootstrap/3.0.3/js/bootstrap.min.js"></script> + </body> </html> diff --git a/docs/tutorials/wiki2/src/views/tutorial/static/favicon.ico b/docs/tutorials/wiki2/src/views/tutorial/static/favicon.ico Binary files differdeleted file mode 100644 index 71f837c9e..000000000 --- a/docs/tutorials/wiki2/src/views/tutorial/static/favicon.ico +++ /dev/null diff --git a/docs/tutorials/wiki2/src/views/tutorial/static/footerbg.png b/docs/tutorials/wiki2/src/views/tutorial/static/footerbg.png Binary files differdeleted file mode 100644 index 1fbc873da..000000000 --- a/docs/tutorials/wiki2/src/views/tutorial/static/footerbg.png +++ /dev/null diff --git a/docs/tutorials/wiki2/src/views/tutorial/static/headerbg.png b/docs/tutorials/wiki2/src/views/tutorial/static/headerbg.png Binary files differdeleted file mode 100644 index 0596f2020..000000000 --- a/docs/tutorials/wiki2/src/views/tutorial/static/headerbg.png +++ /dev/null diff --git a/docs/tutorials/wiki2/src/views/tutorial/static/ie6.css b/docs/tutorials/wiki2/src/views/tutorial/static/ie6.css deleted file mode 100644 index b7c8493d8..000000000 --- a/docs/tutorials/wiki2/src/views/tutorial/static/ie6.css +++ /dev/null @@ -1,8 +0,0 @@ -* 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/middlebg.png b/docs/tutorials/wiki2/src/views/tutorial/static/middlebg.png Binary files differdeleted file mode 100644 index 2369cfb7d..000000000 --- a/docs/tutorials/wiki2/src/views/tutorial/static/middlebg.png +++ /dev/null diff --git a/docs/tutorials/wiki2/src/views/tutorial/static/pylons.css b/docs/tutorials/wiki2/src/views/tutorial/static/pylons.css deleted file mode 100644 index 4b1c017cd..000000000 --- a/docs/tutorials/wiki2/src/views/tutorial/static/pylons.css +++ /dev/null @@ -1,372 +0,0 @@ -html, body, div, span, applet, object, iframe, h1, h2, h3, h4, h5, h6, p, blockquote, pre, a, abbr, acronym, address, big, cite, code, del, dfn, em, font, img, ins, kbd, q, s, samp, small, strike, strong, sub, sup, tt, var, b, u, i, center, dl, dt, dd, ol, ul, li, fieldset, form, label, legend, table, caption, tbody, tfoot, thead, tr, th, td -{ - margin: 0; - padding: 0; - border: 0; - outline: 0; - font-size: 100%; /* 16px */ - vertical-align: baseline; - background: transparent; -} - -body -{ - line-height: 1; -} - -ol, ul -{ - list-style: none; -} - -blockquote, q -{ - quotes: none; -} - -blockquote:before, blockquote:after, q:before, q:after -{ - content: ''; - content: none; -} - -:focus -{ - outline: 0; -} - -ins -{ - text-decoration: none; -} - -del -{ - text-decoration: line-through; -} - -table -{ - border-collapse: collapse; - border-spacing: 0; -} - -sub -{ - vertical-align: sub; - font-size: smaller; - line-height: normal; -} - -sup -{ - vertical-align: super; - font-size: smaller; - line-height: normal; -} - -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; -} - -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; -} - -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; -} - -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; - 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: #fff; - position: relative; - font: 16px/24px NobileRegular, "Lucida Grande", Lucida, Verdana, sans-serif; -} - -a -{ - color: #1b61d6; - text-decoration: none; -} - -a:hover -{ - color: #e88f00; - text-decoration: underline; -} - -body h1, body h2, body h3, body h4, body h5, body h6 -{ - font-family: NeutonRegular, "Lucida Grande", Lucida, Verdana, sans-serif; - font-weight: 400; - color: #373839; - font-style: normal; -} - -#wrap -{ - min-height: 100%; -} - -#header, #footer -{ - width: 100%; - color: #fff; - height: 40px; - position: absolute; - text-align: center; - line-height: 40px; - overflow: hidden; - font-size: 12px; - vertical-align: middle; -} - -#header -{ - background: #000; - top: 0; - font-size: 14px; -} - -#footer -{ - bottom: 0; - background: #000 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, #top-small, #bottom -{ - width: 100%; -} - -#top -{ - color: #000; - height: 230px; - background: #fff url(headerbg.png) repeat-x 0 top; - position: relative; -} - -#top-small -{ - color: #000; - height: 60px; - background: #fff url(headerbg.png) repeat-x 0 top; - position: relative; -} - -#bottom -{ - color: #222; - background-color: #fff; -} - -.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 #fff; - border-bottom: 2px solid #b2b2b2; -} - -.app-welcome -{ - margin-top: 25px; -} - -.app-name -{ - color: #000; - font-weight: 700; -} - -.bottom -{ - padding-top: 50px; -} - -#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; -} - -ul.links -{ - margin: 0; - padding: 0; -} - -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=password] -{ - width: 205px; -} - -input[type=submit] -{ - background-color: #ddd; - font-weight: 700; -} - -/*Opera Fix*/ -body:before -{ - content: ""; - height: 100%; - float: left; - width: 0; - margin-top: -32767px; -} diff --git a/docs/tutorials/wiki2/src/views/tutorial/static/pyramid-16x16.png b/docs/tutorials/wiki2/src/views/tutorial/static/pyramid-16x16.png Binary files differnew file mode 100644 index 000000000..979203112 --- /dev/null +++ b/docs/tutorials/wiki2/src/views/tutorial/static/pyramid-16x16.png 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 differdeleted file mode 100644 index a5bc0ade7..000000000 --- a/docs/tutorials/wiki2/src/views/tutorial/static/pyramid-small.png +++ /dev/null diff --git a/docs/tutorials/wiki2/src/views/tutorial/static/pyramid.png b/docs/tutorials/wiki2/src/views/tutorial/static/pyramid.png Binary files differindex 347e05549..4ab837be9 100644 --- a/docs/tutorials/wiki2/src/views/tutorial/static/pyramid.png +++ b/docs/tutorials/wiki2/src/views/tutorial/static/pyramid.png diff --git a/docs/tutorials/wiki2/src/views/tutorial/static/theme.css b/docs/tutorials/wiki2/src/views/tutorial/static/theme.css new file mode 100644 index 000000000..0f4b1a4d4 --- /dev/null +++ b/docs/tutorials/wiki2/src/views/tutorial/static/theme.css @@ -0,0 +1,154 @@ +@import url(//fonts.googleapis.com/css?family=Open+Sans:300,400,600,700); +body { + font-family: "Open Sans", "Helvetica Neue", Helvetica, Arial, sans-serif; + font-weight: 300; + color: #ffffff; + background: #bc2131; +} +h1, +h2, +h3, +h4, +h5, +h6 { + font-family: "Open Sans", "Helvetica Neue", Helvetica, Arial, sans-serif; + font-weight: 300; +} +p { + font-weight: 300; +} +.font-normal { + font-weight: 400; +} +.font-semi-bold { + font-weight: 600; +} +.font-bold { + font-weight: 700; +} +.starter-template { + margin-top: 250px; +} +.starter-template .content { + margin-left: 10px; +} +.starter-template .content h1 { + margin-top: 10px; + font-size: 60px; +} +.starter-template .content h1 .smaller { + font-size: 40px; + color: #f2b7bd; +} +.starter-template .content .lead { + font-size: 25px; + color: #f2b7bd; +} +.starter-template .content .lead .font-normal { + color: #ffffff; +} +.starter-template .links { + float: right; + right: 0; + margin-top: 125px; +} +.starter-template .links ul { + display: block; + padding: 0; + margin: 0; +} +.starter-template .links ul li { + list-style: none; + display: inline; + margin: 0 10px; +} +.starter-template .links ul li:first-child { + margin-left: 0; +} +.starter-template .links ul li:last-child { + margin-right: 0; +} +.starter-template .links ul li.current-version { + color: #f2b7bd; + font-weight: 400; +} +.starter-template .links ul li a, a { + color: #f2b7bd; + text-decoration: underline; +} +.starter-template .links ul li a:hover, a:hover { + color: #ffffff; + text-decoration: underline; +} +.starter-template .links ul li .icon-muted { + color: #eb8b95; + margin-right: 5px; +} +.starter-template .links ul li:hover .icon-muted { + color: #ffffff; +} +.starter-template .copyright { + margin-top: 10px; + font-size: 0.9em; + color: #f2b7bd; + text-transform: lowercase; + float: right; + right: 0; +} +@media (max-width: 1199px) { + .starter-template .content h1 { + font-size: 45px; + } + .starter-template .content h1 .smaller { + font-size: 30px; + } + .starter-template .content .lead { + font-size: 20px; + } +} +@media (max-width: 991px) { + .starter-template { + margin-top: 0; + } + .starter-template .logo { + margin: 40px auto; + } + .starter-template .content { + margin-left: 0; + text-align: center; + } + .starter-template .content h1 { + margin-bottom: 20px; + } + .starter-template .links { + float: none; + text-align: center; + margin-top: 60px; + } + .starter-template .copyright { + float: none; + text-align: center; + } +} +@media (max-width: 767px) { + .starter-template .content h1 .smaller { + font-size: 25px; + display: block; + } + .starter-template .content .lead { + font-size: 16px; + } + .starter-template .links { + margin-top: 40px; + } + .starter-template .links ul li { + display: block; + margin: 0; + } + .starter-template .links ul li .icon-muted { + display: none; + } + .starter-template .copyright { + margin-top: 20px; + } +} diff --git a/docs/tutorials/wiki2/src/views/tutorial/static/theme.min.css b/docs/tutorials/wiki2/src/views/tutorial/static/theme.min.css new file mode 100644 index 000000000..0d25de5b6 --- /dev/null +++ b/docs/tutorials/wiki2/src/views/tutorial/static/theme.min.css @@ -0,0 +1 @@ +@import url(//fonts.googleapis.com/css?family=Open+Sans:300,400,600,700);body{font-family:"Open Sans","Helvetica Neue",Helvetica,Arial,sans-serif;font-weight:300;color:#fff;background:#bc2131}h1,h2,h3,h4,h5,h6{font-family:"Open Sans","Helvetica Neue",Helvetica,Arial,sans-serif;font-weight:300}p{font-weight:300}.font-normal{font-weight:400}.font-semi-bold{font-weight:600}.font-bold{font-weight:700}.starter-template{margin-top:250px}.starter-template .content{margin-left:10px}.starter-template .content h1{margin-top:10px;font-size:60px}.starter-template .content h1 .smaller{font-size:40px;color:#f2b7bd}.starter-template .content .lead{font-size:25px;color:#f2b7bd}.starter-template .content .lead .font-normal{color:#fff}.starter-template .links{float:right;right:0;margin-top:125px}.starter-template .links ul{display:block;padding:0;margin:0}.starter-template .links ul li{list-style:none;display:inline;margin:0 10px}.starter-template .links ul li:first-child{margin-left:0}.starter-template .links ul li:last-child{margin-right:0}.starter-template .links ul li.current-version{color:#f2b7bd;font-weight:400}.starter-template .links ul li a,a{color:#f2b7bd;text-decoration:underline}.starter-template .links ul li a:hover,a:hover{color:#fff;text-decoration:underline}.starter-template .links ul li .icon-muted{color:#eb8b95;margin-right:5px}.starter-template .links ul li:hover .icon-muted{color:#fff}.starter-template .copyright{margin-top:10px;font-size:.9em;color:#f2b7bd;text-transform:lowercase;float:right;right:0}@media (max-width:1199px){.starter-template .content h1{font-size:45px}.starter-template .content h1 .smaller{font-size:30px}.starter-template .content .lead{font-size:20px}}@media (max-width:991px){.starter-template{margin-top:0}.starter-template .logo{margin:40px auto}.starter-template .content{margin-left:0;text-align:center}.starter-template .content h1{margin-bottom:20px}.starter-template .links{float:none;text-align:center;margin-top:60px}.starter-template .copyright{float:none;text-align:center}}@media (max-width:767px){.starter-template .content h1 .smaller{font-size:25px;display:block}.starter-template .content .lead{font-size:16px}.starter-template .links{margin-top:40px}.starter-template .links ul li{display:block;margin:0}.starter-template .links ul li .icon-muted{display:none}.starter-template .copyright{margin-top:20px}} diff --git a/docs/tutorials/wiki2/src/views/tutorial/static/transparent.gif b/docs/tutorials/wiki2/src/views/tutorial/static/transparent.gif Binary files differdeleted file mode 100644 index 0341802e5..000000000 --- a/docs/tutorials/wiki2/src/views/tutorial/static/transparent.gif +++ /dev/null diff --git a/docs/tutorials/wiki2/src/views/tutorial/templates/edit.pt b/docs/tutorials/wiki2/src/views/tutorial/templates/edit.pt index 5f962bbf5..c0c1b6c20 100644 --- a/docs/tutorials/wiki2/src/views/tutorial/templates/edit.pt +++ b/docs/tutorials/wiki2/src/views/tutorial/templates/edit.pt @@ -1,54 +1,69 @@ -<!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>${page.name} - Pyramid tutorial wiki (based on +<!DOCTYPE html> +<html lang="${request.locale_name}"> + <head> + <meta charset="utf-8"> + <meta http-equiv="X-UA-Compatible" content="IE=edge"> + <meta name="viewport" content="width=device-width, initial-scale=1.0"> + <meta name="description" content="pyramid web application"> + <meta name="author" content="Pylons Project"> + <link rel="shortcut icon" href="${request.static_url('tutorial:static/pyramid-16x16.png')}"> + + <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 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')}" /> + + <!-- Bootstrap core CSS --> + <link href="//oss.maxcdn.com/libs/twitter-bootstrap/3.0.3/css/bootstrap.min.css" rel="stylesheet"> + + <!-- Custom styles for this scaffold --> + <link href="${request.static_url('tutorial:static/theme.css')}" rel="stylesheet"> + + <!-- HTML5 shim and Respond.js IE8 support of HTML5 elements and media queries --> + <!--[if lt IE 9]> + <script src="//oss.maxcdn.com/libs/html5shiv/3.7.0/html5shiv.js"></script> + <script src="//oss.maxcdn.com/libs/respond.js/1.3.0/respond.min.js"></script> + <![endif]--> + </head> + <body> + + <div class="starter-template"> + <div class="container"> + <div class="row"> + <div class="col-md-2"> + <img class="logo img-responsive" src="${request.static_url('tutorial:static/pyramid.png')}" alt="pyramid web framework"> + </div> + <div class="col-md-10"> + <div class="content"> + <p> + Editing <strong><span tal:replace="page.name">Page Name Goes + Here</span></strong> + </p> + <p>You can return to the + <a href="${request.application_url}">FrontPage</a>. + </p> + <form action="${save_url}" method="post"> + <div class="form-group"> + <textarea class="form-control" name="body" tal:content="page.data" rows="10" cols="60"></textarea> + </div> + <div class="form-group"> + <button type="submit" name="form.submitted" value="Save" class="btn btn-default">Save</button> + </div> + </form> + </div> + </div> </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 class="row"> + <div class="copyright"> + Copyright © Pylons Project + </div> </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> -</body> + + + <!-- Bootstrap core JavaScript + ================================================== --> + <!-- Placed at the end of the document so the pages load faster --> + <script src="//oss.maxcdn.com/libs/jquery/1.10.2/jquery.min.js"></script> + <script src="//oss.maxcdn.com/libs/twitter-bootstrap/3.0.3/js/bootstrap.min.js"></script> + </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 ca4e0af26..c9b0cec21 100644 --- a/docs/tutorials/wiki2/src/views/tutorial/templates/mytemplate.pt +++ b/docs/tutorials/wiki2/src/views/tutorial/templates/mytemplate.pt @@ -1,73 +1,66 @@ -<!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 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://static.pylonsproject.org/fonts/nobile/stylesheet.css" media="screen" /> - <link rel="stylesheet" href="http://static.pylonsproject.org/fonts/neuton/stylesheet.css" media="screen" /> - <!--[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="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 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/current/search.html"> - <input type="text" id="q" name="q" value="" /> - <input type="submit" id="x" value="Go" /> - </form> +<!DOCTYPE html> +<html lang="${request.locale_name}"> + <head> + <meta charset="utf-8"> + <meta http-equiv="X-UA-Compatible" content="IE=edge"> + <meta name="viewport" content="width=device-width, initial-scale=1.0"> + <meta name="description" content="pyramid web application"> + <meta name="author" content="Pylons Project"> + <link rel="shortcut icon" href="${request.static_url('tutorial:static/pyramid-16x16.png')}"> + + <title>Alchemy Scaffold for The Pyramid Web Framework</title> + + <!-- Bootstrap core CSS --> + <link href="//oss.maxcdn.com/libs/twitter-bootstrap/3.0.3/css/bootstrap.min.css" rel="stylesheet"> + + <!-- Custom styles for this scaffold --> + <link href="${request.static_url('tutorial:static/theme.css')}" rel="stylesheet"> + + <!-- HTML5 shim and Respond.js IE8 support of HTML5 elements and media queries --> + <!--[if lt IE 9]> + <script src="//oss.maxcdn.com/libs/html5shiv/3.7.0/html5shiv.js"></script> + <script src="//oss.maxcdn.com/libs/respond.js/1.3.0/respond.min.js"></script> + <![endif]--> + </head> + + <body> + + <div class="starter-template"> + <div class="container"> + <div class="row"> + <div class="col-md-2"> + <img class="logo img-responsive" src="${request.static_url('tutorial:static/pyramid.png')}" alt="pyramid web framework"> + </div> + <div class="col-md-10"> + <div class="content"> + <h1><span class="font-semi-bold">Pyramid</span> <span class="smaller">Alchemy scaffold</span></h1> + <p class="lead">Welcome to <span class="font-normal">${project}</span>, an application generated by<br>the <span class="font-normal">Pyramid Web Framework</span>.</p> + </div> + </div> </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/current/#narrative-documentation">Narrative Documentation</a> - </li> - <li> - <a href="http://docs.pylonsproject.org/projects/pyramid/current/#api-documentation">API Documentation</a> - </li> - <li> - <a href="http://docs.pylonsproject.org/projects/pyramid/current/#tutorials">Tutorials</a> - </li> - <li> - <a href="http://docs.pylonsproject.org/projects/pyramid/current/#change-history">Change History</a> - </li> - <li> - <a href="http://docs.pylonsproject.org/projects/pyramid/current/#sample-applications">Sample Applications</a> - </li> - <li> - <a href="http://docs.pylonsproject.org/projects/pyramid/current/#support-and-development">Support and Development</a> - </li> - <li> - <a href="irc://irc.freenode.net#pyramid">IRC Channel</a> - </li> + <div class="row"> + <div class="links"> + <ul> + <li><i class="glyphicon glyphicon-bookmark icon-muted"></i><a href="http://docs.pylonsproject.org/projects/pyramid/en/latest/">Docs</a></li> + <li><i class="glyphicon glyphicon-cog icon-muted"></i><a href="https://github.com/Pylons/pyramid">Github Project</a></li> + <li><i class="glyphicon glyphicon-globe icon-muted"></i><a href="irc://irc.freenode.net#pyramid">IRC Channel</a></li> + <li><i class="glyphicon glyphicon-home icon-muted"></i><a href="http://pylonsproject.org">Pylons Project</a></li> </ul> + </div> + </div> + <div class="row"> + <div class="copyright"> + Copyright © Pylons Project + </div> </div> </div> </div> - </div> -</body> + + + <!-- Bootstrap core JavaScript + ================================================== --> + <!-- Placed at the end of the document so the pages load faster --> + <script src="//oss.maxcdn.com/libs/jquery/1.10.2/jquery.min.js"></script> + <script src="//oss.maxcdn.com/libs/twitter-bootstrap/3.0.3/js/bootstrap.min.js"></script> + </body> </html> diff --git a/docs/tutorials/wiki2/src/views/tutorial/templates/view.pt b/docs/tutorials/wiki2/src/views/tutorial/templates/view.pt index 78c0d2d4c..0f564b16c 100644 --- a/docs/tutorials/wiki2/src/views/tutorial/templates/view.pt +++ b/docs/tutorials/wiki2/src/views/tutorial/templates/view.pt @@ -1,57 +1,69 @@ -<!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>${page.name} - Pyramid tutorial wiki (based on +<!DOCTYPE html> +<html lang="${request.locale_name}"> + <head> + <meta charset="utf-8"> + <meta http-equiv="X-UA-Compatible" content="IE=edge"> + <meta name="viewport" content="width=device-width, initial-scale=1.0"> + <meta name="description" content="pyramid web application"> + <meta name="author" content="Pylons Project"> + <link rel="shortcut icon" href="${request.static_url('tutorial:static/pyramid-16x16.png')}"> + + <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 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')}" /> + + <!-- Bootstrap core CSS --> + <link href="//oss.maxcdn.com/libs/twitter-bootstrap/3.0.3/css/bootstrap.min.css" rel="stylesheet"> + + <!-- Custom styles for this scaffold --> + <link href="${request.static_url('tutorial:static/theme.css')}" rel="stylesheet"> + + <!-- HTML5 shim and Respond.js IE8 support of HTML5 elements and media queries --> + <!--[if lt IE 9]> + <script src="//oss.maxcdn.com/libs/html5shiv/3.7.0/html5shiv.js"></script> + <script src="//oss.maxcdn.com/libs/respond.js/1.3.0/respond.min.js"></script> + <![endif]--> + </head> + <body> + + <div class="starter-template"> + <div class="container"> + <div class="row"> + <div class="col-md-2"> + <img class="logo img-responsive" src="${request.static_url('tutorial:static/pyramid.png')}" alt="pyramid web framework"> + </div> + <div class="col-md-10"> + <div class="content"> + <div tal:replace="structure content"> + Page text goes here. + </div> + <p> + <a tal:attributes="href edit_url" href=""> + Edit this page + </a> + </p> + <p> + Viewing <strong><span tal:replace="page.name"> + Page Name Goes Here</span></strong> + </p> + <p>You can return to the + <a href="${request.application_url}">FrontPage</a>. + </p> + </div> + </div> </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 class="row"> + <div class="copyright"> + Copyright © Pylons Project + </div> </div> - <p> - <a tal:attributes="href edit_url" href=""> - Edit this page - </a> - </p> </div> </div> - </div> -</body> + + + <!-- Bootstrap core JavaScript + ================================================== --> + <!-- Placed at the end of the document so the pages load faster --> + <script src="//oss.maxcdn.com/libs/jquery/1.10.2/jquery.min.js"></script> + <script src="//oss.maxcdn.com/libs/twitter-bootstrap/3.0.3/js/bootstrap.min.js"></script> + </body> </html> diff --git a/docs/tutorials/wiki2/src/views/tutorial/views.py b/docs/tutorials/wiki2/src/views/tutorial/views.py index b41d4ab40..a3707dab5 100644 --- a/docs/tutorials/wiki2/src/views/tutorial/views.py +++ b/docs/tutorials/wiki2/src/views/tutorial/views.py @@ -6,6 +6,7 @@ from pyramid.httpexceptions import ( HTTPFound, HTTPNotFound, ) + from pyramid.view import view_config from .models import ( diff --git a/docs/tutorials/wiki2/tests.rst b/docs/tutorials/wiki2/tests.rst index 9aca0c5b7..9db95334a 100644 --- a/docs/tutorials/wiki2/tests.rst +++ b/docs/tutorials/wiki2/tests.rst @@ -2,29 +2,25 @@ Adding Tests ============ -We will now add tests for the models and the views and a few functional -tests in the ``tests.py``. Tests ensure that an application works, and -that it continues to work after changes are made in the future. +We will now add tests for the models and the views and a few functional tests +in ``tests.py``. Tests ensure that an application works, and that it +continues to work when changes are made in the future. +Test the models +=============== +To test the model class ``Page`` we'll add a new ``PageModelTests`` class to +our ``tests.py`` file that was generated as part of the ``alchemy`` scaffold. -Testing the Models -================== +Test the views +============== -To test the model class ``Page`` we'll add a new ``PageModelTests`` -class to our ``tests.py`` file that was generated as part of the -``alchemy`` scaffold. - -Testing the Views -================= - -We'll modify our ``tests.py`` file, adding tests for each view -function we added above. As a result, we'll *delete* the -``ViewTests`` class that the ``alchemy`` scaffold provided, and add -four other test classes: ``ViewWikiTests``, ``ViewPageTests``, -``AddPageTests``, and ``EditPageTests``. These test the -``view_wiki``, ``view_page``, ``add_page``, and ``edit_page`` views -respectively. +We'll modify our ``tests.py`` file, adding tests for each view function we +added previously. As a result, we'll *delete* the ``ViewTests`` class that +the ``alchemy`` scaffold provided, and add four other test classes: +``ViewWikiTests``, ``ViewPageTests``, ``AddPageTests``, and ``EditPageTests``. +These test the ``view_wiki``, ``view_page``, ``add_page``, and ``edit_page`` +views. Functional tests ================ @@ -34,16 +30,17 @@ tested in the unit tests, like logging in, logging out, checking that the ``viewer`` user cannot add or edit pages, but the ``editor`` user can, and so on. -Viewing the results of all our edits to ``tests.py`` -==================================================== +View the results of all our edits to ``tests.py`` +================================================= -Once we're done with the ``tests.py`` module, it will look a lot like: +Open the ``tutorial/tests.py`` module, and edit it such that it appears as +follows: .. literalinclude:: src/tests/tutorial/tests.py :linenos: :language: python -Running the Tests +Running the tests ================= We can run these tests by using ``setup.py test`` in the same way we did in @@ -57,7 +54,7 @@ Change the ``requires`` list in ``setup.py`` to include ``WebTest``. :lines: 11-22 :emphasize-lines: 11 -After we've added a dependency on WebTest in ``setup.py``, we need to rerun +After we've added a dependency on WebTest in ``setup.py``, we need to run ``setup.py develop`` to get WebTest installed into our virtualenv. Assuming our shell's current working directory is the "tutorial" distribution directory: @@ -89,7 +86,7 @@ On Windows: c:\pyramidtut\tutorial> %VENV%\Scripts\python setup.py test -q -The expected result ends something like: +The expected result should look like the following: .. code-block:: text |
