webapp2, Jinja2: how to cut large html file into multiple html files

若如初见. 提交于 2019-12-21 22:00:52

问题


When I blog, I like to separate each blog-post into its own .html file (is that ok?)

This prevents the file getting too big, and makes it easy to go back and edit a previously written blog post if need be.

Occasionally the blog post will contain css/js/ajax/template variables.

But on my website, I like all the blog posts on one page (so I can scroll through them all, instead of going to a separate page for each post)

Here is an html file that contains two blog posts:

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

and in base.html I have something like:

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

What is the best way for me to split these blog posts out into separate files using webapp2 and jinja2?

e.g. blog1.html might look like:

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

(And I would want the links and the blogposts to be displayed in the right order on the website)

I could think of a way of doing it where post2 extends post1.html, post3 extends post2.html etc, but I would prefer to fan out more

"Henry and Kafura introduced Software Structure Metrics Based on Information Flow in 1981[2] which measures complexity as a function of fan in and fan out."

Thanks


回答1:


@robert king, your design has data embedded directly in the template. Templates should only contain the blueprint to a view, and they should be rendered with new data generated from your main code every time. I simulate this process here (Edited to illustrate the use of a loop to extract post titles, and the display of a single post.):

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])

Hope this helps.

EDIT See also my answer to a question on "Site fragments - composite views"




回答2:


When I read the raw html file (file.read()) and passed the data to my template, it escaped all the html.

instead of {{data}} i had to use {{data|safe}} which allowed raw html.

something like:

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

(make sure the directory isn't a static directory)




回答3:


I just found another option in the jinja2 tutorial. I think it makes more sense for my handler to pass my template a list of filenames of blog posts, and then to include the blog posts.

include - returns the rendered contents of that file into the current namespace:

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

Included templates have access to the variables of the active context by default. For more details about context behavior of imports and includes see Import Context Behavior.

From Jinja 2.2 onwards you can mark an include with ignore missing in which case Jinja will ignore the statement if the template to be ignored does not exist. When combined with with or without context it has to be placed before the context visibility statement. Here some valid examples:

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

New in version 2.2.

You can also provide a list of templates that are checked for existence before inclusion. The first template that exists will be included. If ignore missing is given, it will fall back to rendering nothing if none of the templates exist, otherwise it will raise an exception. Example:

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


来源:https://stackoverflow.com/questions/10369486/webapp2-jinja2-how-to-cut-large-html-file-into-multiple-html-files

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!