views:

50

answers:

2

Hi. Can someone please help me figure out a way to achieve the following (see snippets below) in Django templates? I know that you cannot use more than one extends, but I am new to django and I do not know the proper syntax for something like this. I want to be able to do this so that I can use my nested div layout for css reasons without having to type it like that each time and risking a typo. In words, I want to be able to have a page template extend my base.html file and then use html snippets of dynamic template content (i.e. template for loops or other template logic devices, not just a context variable I set from my view controller).


edit: I want to be able to display arbitrary content in an arbitrary fashion in each column. For example I would like to be able to display a ul of images in one column and then on the same page show another set of columns displaying a table of data. Here is an example that I typed out: example of alot of random columns


I realize that the example picture has all text generated from the django web tester output but each coulmn should be able to have random content. And they should be nestable. Is this possible with the default django template language?

------------------------------------------------------------
base.html
------------------------------------------------------------
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd"&gt;
<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en" lang="en">
    <head>
        <meta http-equiv="Content-Type" content="text/html;charset=utf-8" />
        <title>{% block title %}Title{% endblock %}</title>
    </head>
    <body>
        <div class="wrapper">
            <div class="header">
                This is the common header
            </div>
            <div class="nav">
                This is the common nav              
            </div>
            {% if messages %}
                <div class="messages">
                    <ul>
                        {% for message in messages %}
                        <li{% if message.tags %} class="{{ message.tags }}"{% endif %}>{{ message }}</li>
                        {% endfor %}
                    </ul>
                </div>
            {% endif %}
            <div class="content">
                {% block content %}Page Content{% endblock %}
            </div>
            <div class="footer">
                This is the common footer
            </div>
        </div>
    </body>
</html>
------------------------------------------------------------
columnlayout2.html
------------------------------------------------------------
<div class="twocol container2">
    <div class="container1">
        <div class="col1">
            {% block twocol_col1 %}{% endblock %}
        </div>
        <div class="col2">
            {% block twocol_col2 %}{% endblock %}
        </div>
    </div>
</div>

------------------------------------------------------------
columnlayout3.html
------------------------------------------------------------
<div class="threecol container3">
    <div class="container2">
        <div class="container1">
            <div class="col1">
                {% block threecol_col1 %}{% endblock %}
            </div>
            <div class="col2">
                {% block threecol_col2 %}{% endblock %}
            </div>
            <div class="col3">
                {% block threecol_col3 %}{% endblock %}
            </div>
        </div>
    </div>
</div>

------------------------------------------------------------
page.html
------------------------------------------------------------
{% extends "base.html" %}

{% block content %}

    {% extends "columnlayout2.html" %}
        {% block twocol_col1 %}twocolumn column 1{% endblock %}
        {% block twocol_col2 %}twocolumn column 2{% endblock %}

    {% extends "columnlayout3.html" %}
        {% block threecol_col1 %}threecol column 1{% endblock %}
        {% block threecol_col2 %}threecol column 2{% endblock %}
        {% block threecol_col3 %}threecol column 3{% endblock %}

{% endblock %}

------------------------------------------------------------
page.html output
------------------------------------------------------------
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd"&gt;
<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en" lang="en">
    <head>
        <meta http-equiv="Content-Type" content="text/html;charset=utf-8" />
        <title>Title</title>
    </head>
    <body>
        <div class="wrapper">
            <div class="header">
                This is the common header
            </div>
            <div class="nav">
                This is the common nav              
            </div>
            <div class="content">
                <div class="twocol container2">
                    <div class="container1">
                        <div class="col1">
                            twocolumn column 1
                        </div>
                        <div class="col2">
                            twocolumn column 2
                        </div>
                    </div>
                </div>
                <div class="threecol container3">
                    <div class="container2">
                        <div class="container1">
                            <div class="col1">
                                threecol column 1
                            </div>
                            <div class="col2">
                                threecol column 2
                            </div>
                            <div class="col3">
                                threecol column 3
                            </div>
                        </div>
                    </div>
                </div>
            </div>
            <div class="footer">
                This is the common footer
            </div>
        </div>
    </body>
</html>
+1  A: 

Sounds like inclusion tags are what you're after.

Daniel Roseman
I think inclusion tags are too specific for what I am hoping to accomplish. I want the content of each column to be arbitrary. The inclusion tags seem to be used to display content that is always similar like navigation buttons.
A: 

I agree with Daniel, inclusion tags are probably what you're after and I think you are misunderstanding them and {% extends %}.

If your content is static or in the context, you can use {% include %} blocks like

{% block content %}
    {% include "columnlayout2.html" %}
    {% include "columnlayout3.html" %}
{% endblock %}

so you could store the content you want in something like {{ two_columns }} and {{ three_columns }} and render

------------------------------------------------------------
columnlayout2.html
------------------------------------------------------------
<div class="twocol container2">
    <div class="container1">
        <div class="col1">
            {{ two_columns[0] }}
        </div>
        <div class="col2">
            {{ two_columns[1] }}
        </div>
    </div>
</div>

Or you can use inclusion tags inside page.html

EDIT

Moderator needs to render HTML with a different structure (not just content) on different pages, so you can do something like "nesting" inclusion tag calls.

{% block content %}
    {% show_two_columns two_columns %}
    {% show_three_columns three_columns %}
{% endblock %}

templatetag

@register.inclusion_tag("columns/two_columns.html")
def show_two_columns(columns):
    return {'columns': columns}

two_columns.html

<div class="twocol container2">
    <div class="container1">
        <div class="col1">
            {% render_column columns[0] %}
        </div>
        <div class="col2">
            {% render_column columns[1] %}
        </div>
    </div>
</div>

and then you can do whatever logic you need to change what you want to show in the render_column inclusion tag and the template it uses. I wish I could say more but it's pretty specific to what the column content depends on and how different it is in each case.

Casey Stark
Okay. I marked this as the answer. How do you manipulate the list/queryset/data you pass through the include filter in the page.html? I want to be able to use the column snippets in several different page templates, so the data passed through the include filter would already need to be formatted into html.
Ah I see. It's true that you don't want to construct any HTML in your views. Is the HTML completely different every time?
Casey Stark
Yea it is... =/ that's what is giving me headaches.