Search code examples
pythondjango-templatesjinja2webapp2

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


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


Solution

  • @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"