用于有条件渲染的模板标记,如果存在一个或多个路径,则包含另一个模板

时间:2015-08-12 15:10:42

标签: python django templates django-templates

我正在Django应用程序中实现通用下拉菜单。在大多数情况下,这些页面都是通用的,并且它们具有简单的通用“儿童”字样。菜单。但是在某些情况下,我希望能够根据页面slug(page.slug)在一个完全不同的模板中包含或呈现一组特殊的子项或自定义内容。

我考虑过实现一个包含标记,但我不确定如何在模板标记中执行此操作。我知道你可以在视图中实现它:

blog_post = get_object_or_404(blog_posts, slug=slug)
...
templates = [u"blog/blog_post_detail_%s.html" % str(slug), template]
return render(request, templates, context)

我对标签的设计模式很简单:

  1. 查看页面/ SLUG / dropdown.html
  2. 尝试使用pages / dropdown_SLUG.html
  3. 如果这些文件都不存在,则不显示任何内容。
  4. 如何从模板标签中执行此操作?包含标记是正确的方式,还是render_tag?

1 个答案:

答案 0 :(得分:0)

这是我提出的解决方案:

@register.render_tag
def page_menu_special(context, token):
    page = None
    template_name = None
    menu_templates = []

    parts = token.split_contents()[1:]
    for part in parts:
        part = Variable(part).resolve(context)
        if isinstance(part, str):
            template_name = part
        elif isinstance(part, Page) or isinstance(part, CustomPage):
            page = part

    if page and page.slug:
        page_template = str(page.slug) if page.slug != home_slug() else "index"
        method_template = page.get_content_model().get_template_name()

        menu_templates.extend([
            u'pages/menus/dropdown_%s.html' % (page_template),
            u'pages/menus/dropdown/%s.html' % (page_template),
        ])

        if method_template:
            menu_templates.append(method_template)

    if template_name:
        menu_templates.insert(0, template_name)

    try:
        t = select_template(menu_templates)
        return t.render(Context(context))
    except TemplateDoesNotExist:
        return u''

这是Mezzanine特有的,但逻辑可以重复使用:

  1. 构建潜在模板的路径。
  2. 将列表传递给select_template
  3. 如果不存在则捕获异常,并返回空的或合适的呈现内容。
  4. 我仍然试图弄清楚如何默认另一个模板标记,来自 这个定义。所以我可以调用page_menu_special,如果这个失败,它会恢复为使用相同参数调用page_menu,并为我们节省if/else块。