mezzanine的page_menu tag
mezzanine的head 导航条、左侧tree、footer是由page_menu产生的。page_menu的算法,先计算出每一页的孩子,然后再逐页去page_menu。
@register.render_tag
def page_menu(context, token):
"""
Return a list of child pages for the given parent, storing all
pages in a dict in the context when first called using parents as keys
for retrieval on subsequent recursive calls from the menu template.
"""
# First arg could be the menu template file name, or the parent page.
# Also allow for both to be used.
template_name = None
parent_page = None
parts = token.split_contents()[1:]#对page_menu菜单分离,取得参数
for part in parts:
part = Variable(part).resolve(context)
if isinstance(part, str):
template_name = part#文本为模板名
elif isinstance(part, Page):
parent_page = part#父页
if template_name is None:#没有提供模板的话,从上下文中获取
try:
template_name = context["menu_template_name"]
except KeyError:
error = "No template found for page_menu in: %s" % parts
raise TemplateSyntaxError(error)
context["menu_template_name"] = template_name#设置模板
if "menu_pages" not in context:#没有菜单页,取得当前用户有权访问的页
try:
user = context["request"].user
slug = context["request"].path
except KeyError:
user = None
slug = ""
num_children = lambda id: lambda: len(context["menu_pages"][id])#匿名函数,函数中包含函数
has_children = lambda id: lambda: num_children(id)() > 0
rel = [m.__name__.lower()#取得Page的子类,但不包括Page自身
for m in Page.get_content_models()
if not m._meta.proxy]
published = Page.objects.published(for_user=user).select_related(*rel)#把相关联的model也进行查询
# Store the current page being viewed in the context. Used
# for comparisons in page.set_menu_helpers.
if "page" not in context:
try:
context.dicts[0]["_current_page"] = published.exclude(
content_model="link").get(slug=slug)
except Page.DoesNotExist:
context.dicts[0]["_current_page"] = None
elif slug:
context.dicts[0]["_current_page"] = context["page"]#记录当前页
# Some homepage related context flags. on_home is just a helper
# indicated we're on the homepage. has_home indicates an actual
# page object exists for the homepage, which can be used to
# determine whether or not to show a hard-coded homepage link
# in the page menu.
home = home_slug()
context.dicts[0]["on_home"] = slug == home
context.dicts[0]["has_home"] = False
# Maintain a dict of page IDs -> parent IDs for fast
# lookup in setting page.is_current_or_ascendant in
# page.set_menu_helpers.
context.dicts[0]["_parent_page_ids"] = {}#保存父页id的词典
pages = defaultdict(list)#pages[]不存在时,不会出错,返回[]
for page in published.order_by("_order"):
page.set_helpers(context)#判断是否是当前页,有无孩子
context["_parent_page_ids"][page.id] = page.parent_id#各页的父
setattr(page, "num_children", num_children(page.id))
setattr(page, "has_children", has_children(page.id))
pages[page.parent_id].append(page)#取得各页的子页list
if page.slug == home:
context.dicts[0]["has_home"] = True
# Include menu_pages in all contexts, not only in the
# block being rendered.
context.dicts[0]["menu_pages"] = pages
# ``branch_level`` must be stored against each page so that the
# calculation of it is correctly applied. This looks weird but if we do
# the ``branch_level`` as a separate arg to the template tag with the
# addition performed on it, the addition occurs each time the template
# tag is called rather than once per level.
context["branch_level"] = 0#默认层次为0
parent_page_id = None
if parent_page is not None:
context["branch_level"] = getattr(parent_page, "branch_level", 0) + 1
parent_page_id = parent_page.id # Build the ``page_branch`` template variable, which is the list of
# pages for the current parent. Here we also assign the attributes
# to the page object that determines whether it belongs in the
# current menu template being rendered.
context["page_branch"] = context["menu_pages"].get(parent_page_id, [])#取得该页的子页
context["page_branch_in_menu"] = False
for page in context["page_branch"]:#处理该分支
page.in_menu = page.in_menu_template(template_name)#判断是否在该菜单
page.num_children_in_menu = 0
if page.in_menu:
context["page_branch_in_menu"] = True
for child in context["menu_pages"].get(page.id, []):
if child.in_menu_template(template_name):
page.num_children_in_menu += 1
page.has_children_in_menu = page.num_children_in_menu > 0
page.branch_level = context["branch_level"]
page.parent = parent_page
context["parent_page"] = page.parent # Prior to pages having the ``in_menus`` field, pages had two
# boolean fields ``in_navigation`` and ``in_footer`` for
# controlling menu inclusion. Attributes and variables
# simulating these are maintained here for backwards
# compatibility in templates, but will be removed eventually.
page.in_navigation = page.in_menu
page.in_footer = not (not page.in_menu and "footer" in template_name)
if page.in_navigation:
context["page_branch_in_navigation"] = True
if page.in_footer:
context["page_branch_in_footer"] = True t = get_template(template_name)
return t.render(Context(context))
mezzanine的page_menu tag的更多相关文章
- mezzanine的page_menu tag(二)
dict的特性,key可以是None >>> def f(): a=[2,3] return a #函数返回local变量 >>> a=f() >>&g ...
- mezzanine的breadcrumb
page_menu tag为什么能渲染出当前页的面包屑路径??靠的是request的page对象,要是page的自己或是它的的祖先才渲染,是根据page的属性page.is_current_or_as ...
- mezzanine的page表
class Orderable(with_metaclass(OrderableBase, models.Model)): """ Abstract model that ...
- Git 进阶指南(git ssh keys / reset / rebase / alias / tag / submodule )
在掌握了基础的 Git 使用 之后,可能会遇到一些常见的问题.以下是猫哥筛选总结的部分常见问题,分享给各位朋友,掌握了这些问题的中的要点之后,git 进阶也就完成了,它包含以下部分: 如何修改 ori ...
- 05.GitHub实战系列~5.发布版本之分支操作+Tag讲解 2015-12-14
GitHub实战系列汇总:http://www.cnblogs.com/dunitian/p/5038719.html ———————————————————————————————————————— ...
- Encountered an unexpected error when attempting to resolve tag helper directive '@addTagHelper' with value '"*, Microsoft.AspNet.Mvc.TagHelpers"'
project.json 配置: { "version": "1.0.0-*", "compilationOptions": { " ...
- ASP.NET Core 中文文档 第四章 MVC(3.6.1 )Tag Helpers 介绍
原文:Introduction to Tag Helpers 作者:Rick Anderson 翻译:刘浩杨 校对:高嵩(Jack) 什么是 Tag Helpers? Tag Helpers 提供了什 ...
- ASP.NET Core 中文文档 第四章 MVC(3.6.2 )自定义标签辅助类(Tag Helpers)
原文:Authoring Tag Helpers 作者:Rick Anderson 翻译:张海龙(jiechen) 校对:许登洋(Seay) 示例代码查看与下载 从 Tag Helper 讲起 本篇教 ...
- VS2015突然报错————Encountered an unexpected error when attempting to resolve tag helper directive '@addTagHelper' with value 'Microsoft.AspNet.Mvc.Razor.TagHelpers.UrlResolutionTagHelper
Encountered an unexpected error when attempting to resolve tag helper directive '@addTagHelper' with ...
随机推荐
- 解决nginx转发websocket报400错误
解决nginx转发websocket报400错误 说明 由于个人服务器上面有多个项目,配置了二级域名,需要对二级域名进行转发,在转发工作这快采取了大名鼎鼎的nginx.在这之前所有的项目运行转发都没问 ...
- Java第08次实验提纲(多线程)
PTA与参考资料 题集:多线程 多线程实验参考文件 ThreadReading 实验-基础部分 基础题目MyThread类.PrintTask(讲解线程Thread与任务Runnable相分离的概念) ...
- 运行startup.bat的启动过程
一.前言 一般启动tomcat都是找到bin目录下的startup.bat(windows)下或者startup.sh(linux下),所以要研究tomcat的启动,startup脚本是避不开的.那么 ...
- C/C++基础--模板与泛型编程
模板参数 函数模板,编译器根据实参来为我们推断模板实参. 模板中可以定义非类型参数,表示一个值而非一个类型,这些值必须是常量表达式,从而允许编译器在编译时实例化模板. 非类型参数可以是整型,或者一个指 ...
- 自定义鼠标右键(层叠式菜单:cascading menu)
Author:KillerLegend From:http://www.cnblogs.com/killerlegend/p/3575391.html Date:Tuesday, February 1 ...
- HTML-CSS font-family:中文字体的英文名称
本文转自网络,找不到原地址了,在这里保留了作者名. font-family:中文字体的英文名称 ellisontang 发表于2011-07-15 16:33 宋体* SimSun 黑体* SimHe ...
- fiddler 手机 https 抓包 以及一些fiddler无法解决的https问题http2、tcp、udp、websocket证书写死在app中无法抓包
原文: https://blog.csdn.net/wangjun5159/article/details/52202059 fiddler手机抓包原理 fiddler手机抓包的原理与抓pc上的web ...
- [UE4]需要保存的数据
数据存储原则是“相关的放在一起,不相关的分开”. 如果存档有几十上百兆,如果放在一起存储容易出现问题(特别是网络游戏):断线.电脑死机.游戏出错等等,存档就会损坏,所以一定要分割存储.
- Mysql 之分库分表方案
Mysql分库分表方案 为什么要分表 当一张表的数据达到几千万时,你查询一次所花的时间会变多,如果有联合查询的话,我想有可能会死在那儿了.分表的目的就在于此,减小数据库的负担,缩短查询时间. mysq ...
- C#存储过程 传入参数 传出参数 结果集
作者:卞功鑫 转载请保留:http://www.cnblogs.com/BinBinGo/p/6400928.html //1 连接字符串 string connectionString = &quo ...