【问题标题】:webapp2, Jinja2: how to cut large html file into multiple html fileswebapp2,Jinja2:如何将大 html 文件切割成多个 html 文件
【发布时间】:2012-05-09 07:33:06
【问题描述】:

当我写博客时,我喜欢将每篇博文分成自己的 .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 将这些博客文章分成单独的文件的最佳方法是什么?

例如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] 引入了基于信息流的软件结构度量,它根据扇入和扇出测量复杂性。”

谢谢

【问题讨论】:

    标签: python django-templates jinja2 webapp2


    【解决方案1】:

    @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"的问题的回答

    【讨论】:

    • 谢谢,这很有意义。而不是“内容”:“我的第二篇文章是探索 Foo Bar。”我可以去'内容': html_file.read() 吗?我认为我的问题是我试图读取静态文件,这是我的坏事。
    • 另外,如果我最终在博客文章中使用 javascript 或 css,我会尝试在文章范围内对其进行沙箱处理。
    • 抱歉,我没有在您的第一条评论中看到问题。是的,当然,您可以动态加载内容并将其提供给您的模板。是的,您可以从静态文件中加载此类内容。但是将内容存储在数据库中并从那里加载它会更常见。此外,根据您的应用程序的复杂程度,您可能需要研究像 Django 这样的框架,它可以为您完成大部分繁重的工作。
    • 啊,感谢您提供其他答案的链接。我刚刚找到了 jinja2 选项“包含”。这让我也可以在我的博客文章中使用模板代码。
    【解决方案2】:

    我刚刚在 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 %}
    

    【讨论】:

      【解决方案3】:

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

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

      类似:

      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 %}
      

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

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多