如何重复“a”;块;在django模板中
我想在同一django模板中使用相同的{%block%}两次。我希望此块在我的基本模板中出现多次:如何重复“a”;块;在django模板中,django,django-templates,dry,Django,Django Templates,Dry,我想在同一django模板中使用相同的{%block%}两次。我希望此块在我的基本模板中出现多次: # base.html <html> <head> <title>{% block title %}My Cool Website{% endblock %}</title> </head> <body> <h1>{% block title %}My Coo
# base.html
<html>
<head>
<title>{% block title %}My Cool Website{% endblock %}</title>
</head>
<body>
<h1>{% block title %}My Cool Website{% endblock %}</h1>
</body>
</html>
{% extends 'base.html' %}
...
{% block meta_image %}
{% block meta_image_secure %}
{% if object.cover_pic %}
{{ object.cover_pic.url }}
{% else %}
https://live-static.welovemicro.com/static/img/device-dark.png
{% endif %}
{% endblock %}
{% endblock %}
...
我将得到一个异常,因为Django希望块只出现一次:
模板语法错误位于/
出现名为“title”的“block”标记
不止一次
一个快速而肮脏的解决方案是将区块标题复制为标题1和标题2:
但这违反了原则。这将是非常困难的,因为我有很多继承模板,也因为我不想下地狱;-)
这个问题有什么解决办法吗?如何在不复制所有代码的情况下在模板中重复相同的块?您可能实际上不想使用块,而只是使用变量:
# base.html
<html>
<head>
<title>{{ title|default:"My Cool Website" }}</title>
</head>
<body>
<h1>{{ title|default:"My Cool Website" }}</h1>
</body>
</html>
#base.html
{{title}默认值:“我的酷网站”}
{{title}默认值:“我的酷网站”}
然后通过上下文设置标题。有两种简单的解决方案 最简单的方法是将标题放入上下文变量中。您可以在视图中设置上下文变量 如果您使用的是通用视图之类的东西,并且没有用于图片、猫等的views.py,那么您可以使用一个 走这条路线将使您能够执行以下操作:
{% extends "base.html" %}
{% load set_page_title %}
{% page_title "My Pictures" %}
...
然后在base.html中:
...
{% block title %}{{ page_title }}{% endblock %}
...
<h1>{{ page_title }}</h1>
<!DOCTYPE html>
<html lang="en">
<head>
{% block head %}
<title>{{ title }}</title>
{% endblock %}
</head>
<body>
<h1>{{ title }}</h1>
</body>
</html>
。。。
{%block title%}{{page_title}{%endblock%}
...
{{page_title}}
您可以多次使用{%include subtemplate.html%}
。它与块不一样,但确实起到了作用。我认为在这种情况下使用上下文处理器是一种过度使用。您可以轻松做到这一点:
#base.html
<html>
<head>
<title>{% block title %}My Cool Website{% endblock %}</title>
</head>
<body>
{% block content %}{% endblock %}
</body>
</html>
#base.html
{%block title%}我的酷网站{%endblock%}
{%block content%}{%endblock%}
然后:
# blog.html
{% extends 'base.html' %}
{% block content %}
<h1>{% block title %}My Blog{% endblock %}</h1>
Lorem ipsum here...
{% endblock %}
#blog.html
{%extends'base.html%}
{%block content%}
{%block title%}我的博客{%endblock%}
我是Lorem ipsum。。。
{%endblock%}
等等。。。看起来是干兼容的。使用Django模板宏插件: (django>=1.4) 或 (django<1.4) django>=1.4 django<1.4
当我自己尝试做同样的事情时,我发现了一个方法:
# base_helper.html
<html>
<head>
<title>{% block _title1 %}{% endblock %}</title>
</head>
<body>
<h1>{% block _title2 %}{% endblock %}</h1>
</body>
</html>
# base.html
{% extends "base_helper.html" %}
# Copy title into _title1 & _title2, using "My Cool Website" as a default.
{% block _title1 %}{% block _title2 %}{% block title %}My Cool Website{% endblock %}{% endblock %}{% endblock %}
#base_helper.html
{%block{u title1%}{%endblock%}
{%block{u title2%}{%endblock%}
#base.html
{%extensed“base_helper.html”%}
#使用“我的酷网站”作为默认设置,将标题复制到_title1和_title2中。
{%block_title1%}{%block_title2%}{%block title%}我的酷网站{%endblock%}{%endblock%}{%endblock%}{%endblock%}
不幸的是,需要一个额外的文件,但不需要您从视图中传递标题。根据Van Gale的建议,您可以通过将以下内容添加到templatetags.py文件中来创建get和set标记:
register = template.Library()
Stateful = {}
def do_set(parser, token):
_, key = token.split_contents()
nodelist = parser.parse(('endset',))
parser.delete_first_token() # from the example -- why?
return SetStatefulNode(key,nodelist)
class SetStatefulNode(template.Node):
def __init__(self, key, nodes):
Stateful[key] = nodes
def render(self, context):
return ''
register.tag('set', do_set)
def do_get(parser, token):
tag_name, key = token.split_contents()
return GetStatefulNode(key)
class GetStatefulNode(template.Node):
def __init__(self, key):
self.key = key
def render(self, context):
return ''.join( [x.render(context) for x in Stateful[self.key]] )
register.tag('get', do_get)
然后通过
{%set foo%}在一个模板中设置值将数据放在这里{%endset%}
并通过{%get foo%}
在另一个模板中获取值。这里有一些讨论:
显然,django核心团队拒绝了这张罚单,因为他们认为这不是一个常用的场景,但我不同意
重复块是实现此功能的简单而干净的方法:
模板宏是另一个,但作者提到它没有经过仔细测试:
我使用了repeatblock。我也遇到了在模板文件中重复使用{%block%}的同样需要。问题是,我希望在Django条件的任何一种情况下都使用Django{%block%},并且我希望{%block%}可以被可能扩展当前文件的后续文件过度写入。(在这种情况下,我想要的肯定是一个块而不是一个变量,因为从技术上讲,我没有重复使用它,它只是出现在条件的两端 问题: 下面的Django模板代码将导致模板语法错误,但我认为在条件中使用定义的{%block%}是一个有效的“希望”(即,为什么Django解析器要验证条件两端的语法,它不应该只验证TRUTHY条件吗?)
#此示例显示加载的{{DEBUG}}条件
#未压缩的JavaScript文件(如果为TRUE)
#如果为FALSE,则加载异步缩小的JavaScript文件。
#BASE.html
{%if DEBUG%}
{%block page_js%}
var page=new$site.page();
{%endblock页面_js%}
{%else%}
//加载站点的生产版本
//缩小并异步加载
耶普诺普([
{
加载:“{MEDIA_URL}}js/flatfiles.min.js”,
等等:是的,
完成:函数(){
{%block page_js%}//请注意page_js块
var page=new$site.page();
{%endblock页面_js%}
}
}
)];
{%endif%}
#关于.html
{%extends'页/base.html%}
{%block page_js%}
var page=new$site.page.About();
{%endblock页面_js%}
解决方案:
您可以使用{%include%}多次有条件地插入{%block%}。这对我来说很有效,因为Django语法检查器只包括TRUTHY{%include%}。请参见下面的结果:
# partials/page.js
{% block page_js %}
var page = new $site.Page();
{% endblock %}
# base.html
{% if DEBUG %}
<script src="{{MEDIA_URL}}js/flatfile.1.js"></script>
<script src="{{MEDIA_URL}}js/flatfile.2.js"></script>
<script src="{{MEDIA_URL}}js/flatfile.3.js"></script>
<script type="text/javascript">
{% include 'partials/page_js.html' %}
</script>
{% else %}
<script type="text/javascript">
yepnope([
{
load : '{MEDIA_URL}}js/flatfiles.min.js',
wait : true,
complete : function() {
{% include 'partials/page_js.html' %}
}
}
)];
</script>
{% endif %}
#partials/page.js
{%block page_js%}
var page=new$site.page();
{%endblock%}
#base.html
{%if DEBUG%}
{%include'partials/page_js.html%}
{%else%}
耶普诺普([
{
加载:“{MEDIA_URL}}js/flatfiles.min.js”,
等等:是的,
完成:函数(){
{%include'partials/page_js.html%}
}
}
)];
{%endif%}
在中,您可以这样做:
# base.html
<html>
<head>
<title>{{ block('title') }}</title>
</head>
<body>
<h1>{{ block('title') }}</h1>
</body>
</html>
# blog.html
{% extends 'base.html' %}
{% block title %}My Blog{% endblock %}
# pictures.html
{% extends 'base.html' %}
{% block title %}My Pictures{% endblock %}
# cats.html
{% extends 'base.html' %}
{% block title %}My Cats{% endblock %}
# base_helper.html
<html>
<head>
<title>{% block _title1 %}{% endblock %}</title>
</head>
<body>
<h1>{% block _title2 %}{% endblock %}</h1>
</body>
</html>
# base.html
{% extends "base_helper.html" %}
# Copy title into _title1 & _title2, using "My Cool Website" as a default.
{% block _title1 %}{% block _title2 %}{% block title %}My Cool Website{% endblock %}{% endblock %}{% endblock %}
register = template.Library()
Stateful = {}
def do_set(parser, token):
_, key = token.split_contents()
nodelist = parser.parse(('endset',))
parser.delete_first_token() # from the example -- why?
return SetStatefulNode(key,nodelist)
class SetStatefulNode(template.Node):
def __init__(self, key, nodes):
Stateful[key] = nodes
def render(self, context):
return ''
register.tag('set', do_set)
def do_get(parser, token):
tag_name, key = token.split_contents()
return GetStatefulNode(key)
class GetStatefulNode(template.Node):
def __init__(self, key):
self.key = key
def render(self, context):
return ''.join( [x.render(context) for x in Stateful[self.key]] )
register.tag('get', do_get)
# This example shows a {{ DEBUG }} conditional that loads
# Uncompressed JavaScript files if TRUE
# and loads Asynchronous minified JavaScript files if FALSE.
# BASE.html
{% if DEBUG %}
<script src="{{MEDIA_URL}}js/flatfile.1.js"></script>
<script src="{{MEDIA_URL}}js/flatfile.2.js"></script>
<script src="{{MEDIA_URL}}js/flatfile.3.js"></script>
<script type="text/javascript">
{% block page_js %}
var page = new $site.Page();
{% endblock page_js %}
</script>
{% else %}
<script type="text/javascript">
// load in the PRODUCTION VERSION of the site
// minified and asynchronosly loaded
yepnope([
{
load : '{MEDIA_URL}}js/flatfiles.min.js',
wait : true,
complete : function() {
{% block page_js %} // NOTE THE PAGE_JS BLOCK
var page = new $site.Page();
{% endblock page_js %}
}
}
)];
</script>
{% endif %}
# ABOUT.html
{% extends 'pages/base.html' %}
{% block page_js %}
var page = new $site.Page.About();
{% endblock page_js %}
# partials/page.js
{% block page_js %}
var page = new $site.Page();
{% endblock %}
# base.html
{% if DEBUG %}
<script src="{{MEDIA_URL}}js/flatfile.1.js"></script>
<script src="{{MEDIA_URL}}js/flatfile.2.js"></script>
<script src="{{MEDIA_URL}}js/flatfile.3.js"></script>
<script type="text/javascript">
{% include 'partials/page_js.html' %}
</script>
{% else %}
<script type="text/javascript">
yepnope([
{
load : '{MEDIA_URL}}js/flatfiles.min.js',
wait : true,
complete : function() {
{% include 'partials/page_js.html' %}
}
}
)];
</script>
{% endif %}
# base.html
<html>
<head>
<title>{{ block('title') }}</title>
</head>
<body>
<h1>{{ block('title') }}</h1>
</body>
</html>
# blog.html
{% extends 'base.html' %}
{% block title %}My Blog{% endblock %}
# pictures.html
{% extends 'base.html' %}
{% block title %}My Pictures{% endblock %}
# cats.html
{% extends 'base.html' %}
{% block title %}My Cats{% endblock %}
<!DOCTYPE html>
<html lang="en">
<head>
{% block head %}
<title>{{ title }}</title>
{% endblock %}
</head>
<body>
<h1>{{ title }}</h1>
</body>
</html>
{% extends "base.html" %}
{% block head %}
{% define 'title' 'Homepage | title' %}
{{ block.super }}
{% endblock %}
@register.simple_tag(takes_context=True)
def define(context, key, value):
context.dicts[0][key] = value
return ''
{% extends "base.html" %}
{% with "Entry Title" as title %}
{% block title %}{{ title }}{% endblock %}
{% block h1 %}{{ title }}{% endblock %}
{% endwith %}
{% extends 'base.html' %}
...
{% block meta_image %}
{% block meta_image_secure %}
{% if object.cover_pic %}
{{ object.cover_pic.url }}
{% else %}
https://live-static.welovemicro.com/static/img/device-dark.png
{% endif %}
{% endblock %}
{% endblock %}
...
...
<meta property="og:image" itemprop="image" content="{% block meta_image %}https://live-static.welovemicro.com/static/img/device-dark.png{% endblock %}">
<meta property="og:image:secure_url" itemprop="image" content="{% block meta_image_secure %}https://live-static.welovemicro.com/static/img/device-dark.png{% endblock %}">
...