webapp2,Jinja2:如何将大型html文件剪切成多个html文件

时间:2012-04-29 03:34:28

标签: python django-templates jinja2 webapp2

当我在博客时,我喜欢将每个博客文章分成自己的.html文件(可以吗?)

这可以防止文件变得太大,并且如果需要,可以轻松返回并编辑以前编写的博客文章。

博客文章有时会包含css / js / ajax / template变量。

但是在我的网站上,我喜欢一个页面上的所有博客帖子(所以我可以滚动浏览所有帖子,而不是每个帖子单独的页面)

这是一个包含两篇博文的html文件:

{% extends "base.html" %}
{% block blog_posts %}
    <!-- links/targest for the side menu to jump to a post -->
    <li><a href="#post2">Post2 - April 2012</a></li>
    <li><a href="#post1">Post1 - Feb 2012</a></li>
{% endblock %}

{% block content %}

<div id="post1">
spam1 blah blah
</div>

<div id="post2">
spam2
</div>
{% endblock %}

在base.html我有类似的东西:

<div id="content-container">
        <div id="section-navigation">
            <ul>
                {% block blog_posts %}
                {% endblock %}
            </ul>
        </div>
        <div id="content">
            {% block content %}{% endblock %}
        </div>
</div>

使用webapp2和jinja2将这些博客文章拆分为单独文件的最佳方法是什么?

e.g。 blog1.html可能看起来像:

{% block blog_posts %}
        <!-- links/targest for the side menu to jump to a post -->
        <li><a href="#post1">Post1 - Feb 2012</a></li>
    {% endblock %}

{% block content %}

    <div id="post1">
    spam1 blah blah
    </div>
{% endblock %}

(我希望链接和博客帖子能够在网站上以正确的顺序显示)

我可以想到这样做的方法,post2扩展post1.html,post3扩展post2.html等,但我更喜欢扇出更多

“Henry和Kafura在1981年引入了基于信息流的软件结构指标[2],它根据粉丝和扇出来衡量复杂性。”

由于

3 个答案:

答案 0 :(得分:3)

@robert king,您的设计将数据直接嵌入模板中。模板应该只包含视图的蓝图,并且应该使用每次从主代码生成的新数据来呈现它们。我在这里模拟了这个过程(编辑说明使用循环来提取帖子标题,以及显示单个帖子。):

import jinja2

# NOTE: in this template there is no data relating to specific posts.
# There are only references to data structures passed in from your main code
page_template = jinja2.Template('''
    <!-- this is a navigation block that should probably be in base.html -->
    {% block blog_posts %}
        <!-- links/targets for the side menu to jump to a post -->
        {% for post in posts %}
          <li><a href="{{ post.url }}">{{ post.title }} 
                                       - {{ post.date }}</a></li>
        {% endfor %}
    {% endblock %}

    <!-- this is a content block that should probably be in page.html -->
    {% block content %}
        <div id="post">
            <h1>{{ current.title }}</h1>
            <h2>{{ current.date }}</h2>
            <p>{{ current.content }}</p>
        </div>
    {% endblock %}
''')

# NOTE your main code would create a data structure such as this 
# list of dictionaries ready to pass in to your template
list_of_posts = [
         { 'url' : '#post1',
          'title' : 'My first post',
          'date' : 'Feb 2012',
          'content' : 'My first post is about Hello World.'},

         { 'url' : '#post2',
          'title' : 'My second post',
          'date' : 'Apr 2012',
          'content' : 'My second post is about Foo Bar.'}
         ]

# Pass in a full list of posts and a variable containing the last
# post in the list, assumed to be the most recent. 
print page_template.render(posts = list_of_posts,
                           current = list_of_posts[-1])

希望这有帮助。

编辑另请参阅我对"Site fragments - composite views"

上的问题的回答

答案 1 :(得分:1)

当我读取原始html文件(file.read())并将数据传递给我的模板时,它会转义所有的html。

而不是{{data}}我必须使用允许原始html的{{data | safe}}。

类似的东西:

class HomeHandler(BaseHandler):
    def get(self):
        file_names = sorted(os.listdir('blog_posts'))
        html = [open('blog_posts/%s' % fn).read() for fn in file_names]
        templates = {'html': enumerate(html)}
        self.render_template('home.html', **templates)

{% block content %}

    {% for num,data in html %}
        <div id="post{{num}}">
            {{data|safe}}
        </div>
        <br />
        <img src="http://www.sadmuffin.net/screamcute/graphics/graphics-page-divider/page-divider-007.gif" border=0>
        <br />
    {% endfor %}

{% endblock %}

(确保该目录不是静态目录)

答案 2 :(得分:1)

我刚刚在jinja2教程中找到了另一个选项。我认为我的处理程序更有意义的是将我的模板传递给博客文章的文件名列表,然后包含博客文章。

include - 将该文件的渲染内容返回到当前名称空间:

{% include 'header.html' %}
    <div ...
{% include 'footer.html' %}

默认情况下,包含的模板可以访问活动上下文的变量。有关导入的上下文行为的更多详细信息,请参阅Import Context Behavior

从Jinja 2.2开始,您可以标记包含忽略忽略的包含,在这种情况下,如果要忽略的模板不存在,Jinja将忽略该语句。当与有或没有上下文结合时,它必须放在上下文可见性语句之前。这里有一些有效的例子:

{% include "sidebar.html" ignore missing %}
{% include "sidebar.html" ignore missing with context %}
{% include "sidebar.html" ignore missing without context %}

2.2版中的新功能。

您还可以提供在包含之前检查存在的模板列表。将包含存在的第一个模板。如果给出了ignore missing,那么如果没有模板存在,它将回退为什么,否则它将引发异常。例如:

{% include ['page_detailed.html', 'page.html'] %}
{% include ['special_sidebar.html', 'sidebar.html'] ignore missing %}