1:模板布局准备

准备一套Twitter引导主题的jinja2模板。

背景

在这个遍历教程中,我们将有许多视图和模板,每个视图和模板都有一些样式和布局。让我们高效地工作,并通过我们的基本布局获得一些视图和jinja2模板,从而产生良好的视觉吸引力。

目标

  • 使用视图和模板基于 pyramid_jinja2 .

  • 有一个“布局”主模板和一些包含的子模板。

步骤

  1. Let's start with an empty hierarchy of directories. Starting in a tutorial workspace (e.g., quick_traversal ):

    $ mkdir -p layout/tutorial/templates
    $ cd layout
    
  2. 做一个 layout/setup.py

     1from setuptools import setup
     2
     3requires = [
     4    'pyramid',
     5    'pyramid_jinja2',
     6    'pyramid_debugtoolbar'
     7]
     8
     9setup(name='tutorial',
    10      install_requires=requires,
    11      entry_points="""\
    12      [paste.app_factory]
    13      main = tutorial:main
    14      """,
    15)
    
  3. 现在可以在开发模式下安装项目:

    $ $VENV/bin/python setup.py develop
    
  4. We need a configuration file at layout/development.ini

     1[app:main]
     2use = egg:tutorial
     3pyramid.reload_templates = true
     4pyramid.includes =
     5    pyramid_debugtoolbar
     6
     7[server:main]
     8use = egg:pyramid#wsgiref
     9host = 0.0.0.0
    10port = 6543
    11
    12# Begin logging configuration
    13
    14[loggers]
    15keys = root, tutorial
    16
    17[logger_tutorial]
    18level = DEBUG
    19handlers =
    20qualname = tutorial
    21
    22[handlers]
    23keys = console
    24
    25[formatters]
    26keys = generic
    27
    28[logger_root]
    29level = INFO
    30handlers = console
    31
    32[handler_console]
    33class = StreamHandler
    34args = (sys.stderr,)
    35level = NOTSET
    36formatter = generic
    37
    38[formatter_generic]
    39format = %(asctime)s %(levelname)-5.5s [%(name)s][%(threadName)s] %(message)s
    40
    41# End logging configuration
    
  5. layout/tutorial/__init__.py 上电 pyramid_jinja2

    1from pyramid.config import Configurator
    2
    3
    4def main(global_config, **settings):
    5    config = Configurator(settings=settings)
    6    config.include('pyramid_jinja2')
    7    config.scan('.views')
    8    return config.make_wsgi_app()
    
  6. 我们的观点 layout/tutorial/views.py just has a single view that will answer an incoming request for /hello

     1from pyramid.view import view_config
     2
     3
     4class TutorialViews(object):
     5    def __init__(self, request):
     6        self.request = request
     7
     8    @view_config(name='hello', renderer='templates/site.jinja2')
     9    def site(self):
    10        page_title = 'Quick Tutorial: Site View'
    11        return dict(page_title=page_title)
    
  7. layout/tutorial/templates/site.jinja2

    1{% extends "templates/layout.jinja2" %}
    2{% block content %}
    3
    4<p>Welcome to the site.</p>
    5
    6{% endblock content %}
    
  8. That template asks to use a master "layout" template at layout/tutorial/templates/layout.jinja2

     1<!DOCTYPE html>
     2<html lang="en">
     3<head>
     4    <title>{{ page_title }}</title>
     5    <link rel="stylesheet"
     6          href="http://netdna.bootstrapcdn.com/bootstrap/3.0.0/css/bootstrap.min.css">
     7</head>
     8<body>
     9
    10<div class="navbar navbar-inverse">
    11    <div class="container">
    12        {% include "templates/header.jinja2" %}
    13    </div>
    14</div>
    15
    16<div class="container">
    17
    18    <div>
    19        {% include "templates/breadcrumbs.jinja2" %}
    20    </div>
    21
    22    <h1>{{ page_title }}</h1>
    23    {% block content %}
    24    {% endblock content %}
    25
    26</div>
    27
    28</body>
    29</html>
    
  9. layout/tutorial/templates/header.jinja2

    1<a class="navbar-brand" 
    2   href="{{ request.resource_url(request.root) }}">Tutorial</a>
    
  10. layout/tutorial/templates/breadcrumbs.jinja2

    1<span>
    2  <a href="#">Home</a> >> 
    3</span>
    
  11. layout/tutorial/tests.py

     1import unittest
     2
     3from pyramid.testing import DummyRequest
     4
     5
     6class TutorialViewsUnitTests(unittest.TestCase):
     7    def _makeOne(self, request):
     8        from .views import TutorialViews
     9        inst = TutorialViews(request)
    10        return inst
    11
    12    def test_site_view(self):
    13        request = DummyRequest()
    14        inst = self._makeOne(request)
    15        result = inst.site()
    16        self.assertIn('Site View', result['page_title'])
    17
    18
    19class TutorialFunctionalTests(unittest.TestCase):
    20    def setUp(self):
    21        from tutorial import main
    22        app = main({})
    23        from webtest import TestApp
    24        self.testapp = TestApp(app)
    25
    26    def test_it(self):
    27        result = self.testapp.get('/hello', status=200)
    28        self.assertIn(b'Site View', result.body)
    
  12. 现在运行测试:

    1$ $VENV/bin/nosetests tutorial
    2.
    3----------------------------------------------------------------------
    4Ran 2 tests in 0.141s
    5
    6OK
    
  13. 运行 Pyramid 应用程序时使用:

    $ $VENV/bin/pserve development.ini --reload
    
  14. 正常开放 http://localhost:6543/hello in your browser.

分析

这个 @view_config uses a new attribute: name='hello' hello

视图的渲染器使用jinja2的机制指向主布局并从视图模板填充某些区域。布局提供了一个基本的HTML布局,并指向内容交付网络上的Twitter引导CSS进行样式设置。