django之block extend标签
class ExtendsNode(Node):
must_be_first = True
context_key = 'extends_context' def __init__(self, nodelist, parent_name, template_dirs=None):
self.nodelist = nodelist
self.parent_name = parent_name
self.template_dirs = template_dirs
self.blocks = {n.name: n for n in nodelist.get_nodes_by_type(BlockNode)} def __repr__(self):
return '<ExtendsNode: extends %s>' % self.parent_name.token def find_template(self, template_name, context):
"""
This is a wrapper around engine.find_template(). A history is kept in
the render_context attribute between successive extends calls and
passed as the skip argument. This enables extends to work recursively
without extending the same template twice.
"""
# RemovedInDjango20Warning: If any non-recursive loaders are installed
# do a direct template lookup. If the same template name appears twice,
# raise an exception to avoid system recursion.
for loader in context.template.engine.template_loaders:
if not loader.supports_recursion:
history = context.render_context.setdefault(
self.context_key, [context.template.origin.template_name],
)
if template_name in history:
raise ExtendsError(
"Cannot extend templates recursively when using "
"non-recursive template loaders",
)
template = context.template.engine.get_template(template_name)
history.append(template_name)
return template history = context.render_context.setdefault(
self.context_key, [context.template.origin],
)
template, origin = context.template.engine.find_template(
template_name, skip=history,
)
history.append(origin)
return template def get_parent(self, context):
parent = self.parent_name.resolve(context)
if not parent:
error_msg = "Invalid template name in 'extends' tag: %r." % parent
if self.parent_name.filters or\
isinstance(self.parent_name.var, Variable):
error_msg += " Got this from the '%s' variable." %\
self.parent_name.token
raise TemplateSyntaxError(error_msg)
if isinstance(parent, Template):
# parent is a django.template.Template
return parent
if isinstance(getattr(parent, 'template', None), Template):
# parent is a django.template.backends.django.Template
return parent.template
return self.find_template(parent, context) def render(self, context):
compiled_parent = self.get_parent(context)#获取父模板对象 if BLOCK_CONTEXT_KEY not in context.render_context:
context.render_context[BLOCK_CONTEXT_KEY] = BlockContext()#在context中块上下文,默认词典
block_context = context.render_context[BLOCK_CONTEXT_KEY] # Add the block nodes from this node to the block context
block_context.add_blocks(self.blocks)#为块上下文添加当前页的块。 # If this block's parent doesn't have an extends node it is the root,
# and its block nodes also need to be added to the block context.
for node in compiled_parent.nodelist:
# The ExtendsNode has to be the first non-text node.
if not isinstance(node, TextNode):
if not isinstance(node, ExtendsNode):
blocks = {n.name: n for n in#取得父类中的块节点
compiled_parent.nodelist.get_nodes_by_type(BlockNode)}
block_context.add_blocks(blocks)#使得块节点插到最前面
break # Call Template._render explicitly so the parser context stays
# the same.
return compiled_parent._render(context)#看块节点怎么样render??? @register.tag('extends')
def do_extends(parser, token):#从html文件中生成extend node
"""
Signal that this template extends a parent template. This tag may be used in two ways: ``{% extends "base" %}`` (with quotes)
uses the literal value "base" as the name of the parent template to extend,
or ``{% extends variable %}`` uses the value of ``variable`` as either the
name of the parent template to extend (if it evaluates to a string) or as
the parent template itself (if it evaluates to a Template object).
"""
bits = token.split_contents()
if len(bits) != 2:
raise TemplateSyntaxError("'%s' takes one argument" % bits[0])
parent_name = parser.compile_filter(bits[1])#父模板名字
nodelist = parser.parse()#当前html的所有node列表。
if nodelist.get_nodes_by_type(ExtendsNode):
raise TemplateSyntaxError("'%s' cannot appear more than once in the same template" % bits[0])
return ExtendsNode(nodelist, parent_name)
class BlockNode(Node):
def __init__(self, name, nodelist, parent=None):
self.name, self.nodelist, self.parent = name, nodelist, parent def __repr__(self):
return "<Block Node: %s. Contents: %r>" % (self.name, self.nodelist) def render(self, context):
block_context = context.render_context.get(BLOCK_CONTEXT_KEY)#从上下文取得块node的信息
with context.push():
if block_context is None:
context['block'] = self
result = self.nodelist.render(context)
else:
push = block = block_context.pop(self.name)#弹出块node,排在后面的先出
if block is None:
block = self
# Create new block so we can store context without thread-safety issues.
block = type(self)(block.name, block.nodelist)
block.context = context
context['block'] = block
result = block.nodelist.render(context)
if push is not None:
block_context.push(self.name, push)
return result
django之block extend标签的更多相关文章
- Django 模板继承extend 标签include block
# block 站网页位置# includ 导入网页标签# extends 导入网页模板 # common_js.html <script src="/static/plugins/j ...
- Django内置模板标签
Django内置标签总览 可以查询下表来总览Django的内置标签: 标签 说明 autoescape 自动转义开关 block 块引用 comment 注释 csrf_token CSRF令牌 cy ...
- 第三章:模版层 - 2:Django内置模板标签
Django内置标签总览 可以查询下表来总览Django的内置标签: 标签 说明 autoescape 自动转义开关 block 块引用 comment 注释 csrf_token CSRF令牌 cy ...
- Django项目中模板标签及模板的继承与引用【网站中快速布置广告】
Django项目中模板标签及模板的继承与引用 常见模板标签 {% static %} {% for x in range(x) %}{% endfor %} 循环的序号{% forloop %} 循环 ...
- Django模板语言,标签整理
Django模板语言 标签 内置标签引用 1. autoescape 控制自动转义是否可用. 这种标签带有任何 on 或 off 作为参数的话,他将决定转义块内效果. 该标签会以一个endautoes ...
- Django模板结构优化{% include %}和{% extend %}标签
https://blog.csdn.net/xujin0/article/details/83420633
- django模板 内建标签
autoescape 控制当前自动转义的行为,有on和off两个选项 {% autoescape on %} {{ body }} {% endautoescape %} block 定义一个子模板可 ...
- 测试开发之Django——No6.Django模板中的标签语言
模板中的标签语言 1.if/else {% if %} 标签检查(evaluate)一个变量,如果这个变量为真(即:变量存在,非空,不是布尔值假),系统会显示在{% if %} 和 {% endi ...
- 11:django 模板 内建标签
django 内建标签 autoescape 控制当前自动转义的行为,有on和off两个选项 {% autoescape on %} {{ body }} {% endautoescape %} bl ...
随机推荐
- IntelliJ IDEA Configuring projects
https://www.jetbrains.com/help/idea/configuring-projects.html Configuring projects A project in Inte ...
- iis重新注册.netframework4.0
开始-运行-CMD (管理员权限运行) %windir%\Microsoft.NET\Framework\v4.0.30319\aspnet_regiis.exe -i 废话不多说直接上图:
- 【AMQ】之概述
消息中间件的主要作用: 基本功能,将信息以消息的形式在多个应用之间传递 特点: 消息异步接受,发送者不需要等待接收者的响应,减少系统之间的耦合性. 消息可靠性接收,确保消息在中间件可靠保存,只有接收方 ...
- 1123.(重、错)Is It a Complete AVL Tree
题意:给定结点个数n和插入序列,判断构造的AVL树是否是完全二叉树? 思路:AVL树的建立很简单.而如何判断是不是完全二叉树呢?通过层序遍历进行判断:当一个结点的孩子结点为空时,则此后就不能有新的结点 ...
- TCP:WireShark分析,序列号Seq和确认号Ack
转载自 http://blog.csdn.net/a19881029/article/details/38091243 序列号为当前端成功发送的数据位数,确认号为当前端成功接收的数据位数,SYN标志位 ...
- Python 里面什么时候用一个=,什么时候用两个=
赋值用= i != j != k >>>> ...
- tomcat中class和jar的加载顺序(转)
https://blog.csdn.net/lipei1220/article/details/53924799 加载顺序: 1. $java_home/lib 目录下的java核心api 2. $j ...
- word&excel&ppt文档加密方式
ppt excel word
- C语言怎么简单测试为大小端模式
作者:Slience_J 原文地址:https://blog.csdn.net/slience_j/article/details/52048267 1.什么是大小端模式? 大端模式,是指数据的高字节 ...
- 字符编码-ASCII,GB2312,GBK,GB18030
ASCII ASCII,GB2312,GBK,GB18030依次增加,向下兼容. 手机只需要支持GB2312 电脑中文windows只支持GBK 发展历程 如果你使用编译器是python2.0版本,默 ...