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 ...
随机推荐
- ALGO-18_蓝桥杯_算法训练_单词接龙(搜索)
问题描述 单词接龙是一个与我们经常玩的成语接龙相类似的游戏,现在我们已知一组单词,且给定一个开头的字母,要求出以这个字母开头的最长的“龙”(每个单词都最多在“龙”中出现两次),在两个单词相连时,其重合 ...
- Tablacus Explorer双心封装版
Tablacus Explorer双心封装版 http://cloud.189.cn/t/mYj67j7r2Afq (TablacusExplorer17.3.27双心封装版.exe) http:// ...
- ghost之后仍然中病毒----与病毒的斗争
ghost之后仍然中病毒----与病毒的斗争我的电脑系统是XP,从来都没有安装任何杀毒软件,所有的软件都是安装在C盘的,感觉系统卡顿就用Windows一键还原(基于DOS下的ghost)还原一下,一直 ...
- 【springBoot】之starter pom
SpringBoot针对不同业务提供了不同的starter pom,根据springboot版本不同可能有差异. spring-boot-starter springboot核心starter ,包括 ...
- KeyBoardEvent
顺便提一句 在纯Flash CS环境下初始要这样写stage?init(null):addEventListener (Event.ADDED_TO_STAGE, init);即 if(stage ! ...
- java浅析final关键字
谈到final关键字,想必很多人都不陌生,在使用匿名内部类的时候可能会经常用到final关键字.另外,Java中的String类就是一个final类,那么今天我们就来了解final这个关键字的用法. ...
- appium 点击物理按键
有时候我们遇到一些需要点击手机物理返回按键,或者home键等操作,总结如下: adb shell input keyevent 点击home键: adb shell input keyevent 3 ...
- Spring @Async使用方法总结
引言: 在Java应用中,绝大多数情况下都是通过同步的方式来实现交互处理的:但是在处理与第三方系统交互的时候,容易造成响应迟缓的情况,之前大部分都是使用多线程来完成此类任务,其实,在spring 3. ...
- Java-Runoob-高级教程-实例-数组:14. Java 实例 – 在数组中查找指定元素
ylbtech-Java-Runoob-高级教程-实例-数组:14. Java 实例 – 在数组中查找指定元素 1.返回顶部 1. Java 实例 - 在数组中查找指定元素 Java 实例 以下实例 ...
- 廖雪峰Java2面向对象编程-6Java核心类-5枚举类
直接定义常量 public class Weekday { //定义int常量 public static final int SUN = 0; public static final int MON ...