content_for等效于Django模板

时间:2011-03-14 17:38:33

标签: python django django-templates

有没有办法在Django中复制Rails的content_for?

用例如下:

# base.html
<html>
  <head>
    <script type='text/javascript' src='jquery.js'></script>
    {% yield 'head' %}
  </head>
  <body>
    {% block content %}{% endblock %}
  </body>
</html>

# page.html
{% extends 'base.html' %}
{% contentfor 'head' %}
<script type='text/javascript' src='some_library_only_for_this_page.js'></script>
{% endcontentfor %}

{% block content %}
This is the content for the page.
{% include 'widget.html' %}
{% endblock %}

# widget.html
{% contentfor 'head' %}
<script type='text/javascript' src='some_library_only_for_this_widget.js'></scirpt>
{% endcontentfor %}

<div id='the_html_for_the_widget'>
  ...
</div>

contentfor的行为大致

相同
{% block %}{{block.super}}new content{% endblock %}

但请注意,block.super方法不适用于widget.html内部。

在Django中执行此操作的标准方法是什么?

编辑:此处包含小部件而不是小部件扩展页面,因为我可能在一个页面中包含许多小部件

2 个答案:

答案 0 :(得分:1)

尝试从page.html模板扩展widget.html。

另请查看Admin app @ / site-packages / django / contrib / admin / templates中的模板(例如base_site.html,change_form.html)

# base.html
<html>
  <head>
    <script type='text/javascript' src='jquery.js'></script>
    {% block extrahead %}{% endblock %}
  </head>
  <body>
    {% block content %}{% endblock %}
  </body>
</html>


# page.html
{% extends "base.html" %}
{% block extrahead %}
    {{ block.super }}
    <script type='text/javascript' src='some_library_only_for_this_page.js'></script>
{% endblock %}

{% block content %}
    This is the content for the page.
{% endblock %}


# widget.html
{% extends "page.html" %}

{% block extrahead %}
    {{ block.super }}
    <script type='text/javascript' src='some_library_only_for_this_widget.js'></script>
{% endblock %}

{% block content %}
    {{ block.super }}   
    <div id='the_html_for_the_widget'>
    </div>
{% endblock %}

<强>更新 关于更新的问题。

创建基本窗口小部件类并将其重用于其他小部件,这些小部件将存储在单独的模块中,例如widgets.py。

这些小部件应通过例如请求处理例程传递给page.html模板。 views.py。

# widgets.py
from django.utils.safestring import mark_safe
from django.template import Template, Context

class BaseWidget(object):  
    def content(self, content=''):
        template = '''
        <div class="w_content">
                {{content}}
        </div>
        '''
        context = {'content': content}          
        html = Template(template).render(Context(context))            
        return mark_safe(html)


class HelloWorldWidget(BaseWidget)
    def header(self):
        return '<script type='text/javascript' src='some_library_only_for_this_widget.js'></script>'

    def content(self):
        html = '<a>Hello World</a>'
        return super(HelloWorldWidget, self).content(html)


# views.py
from django.shortcuts render_to_response
from django.http import HttpResponse
from django.template import RequestContext
from widgets import *

def page(request):
    w_headers = []
    w_contents = []
    w = HelloWorldWidget() # here you could loop through all widgets.py widgets
    w_headers.append(w.header())
    w_contents.append(w.content())
    return render_to_response('templates/page.html', {'widget_headers': w_headers, 'widget_contents': w_contents}, context_instance=RequestContext(request))


# page.html
{% extends "base.html" %}
{% block extrahead %}
    {{ block.super }}
    <script type='text/javascript' src='some_library_only_for_this_page.js'></script>
    {% for header in widget_headers %}{{header}}{% endfor %}
{% endblock %}

{% block content %}
    This is the content for the page.
    {% for content in widget_contents %}{{content}}{% endfor %}
{% endblock %}

答案 1 :(得分:0)

我使用Django {%block%}模板标签以完全相同的方式构建内容......

{#page.html#} {%extends'base.html'%}

{%block head%}     {{block.super}}     {%include'shared / my_widget.html'%} {%endblock%}

块可以出现在任何地方,几乎可以填充任何内容。您在块中包含的任何内容都将了解请求上下文中的对象和属性。如果您需要将变量传递给随后呈现某些内容的函数,例如Rails中的render_partial,则需要查看模板标记。

亲切的问候, 布兰登