DjangoCMS NavigationNode - 自定义节点

时间:2016-08-04 09:06:03

标签: python django django-cms

DjangoCMS中的默认NavigationNode节点为:

  • 儿童
  • 标题
  • get_menu_title
  • get_attribute

在相同的上下文中,我想添加我的自定义节点,名为:类别 _ 名称,它会返回一个字符串'某些内容' (仅用于测试目的)。

official documentation之后,找不到任何可以帮助我解决问题的内容。在查找默认NavigationNode的声明时,将显示以下代码:

  

from menus.base import NavigationNode

base.py 档案:

class NavigationNode(object):

    def __init__(self, title, url, id, parent_id=None, parent_namespace=None,
                 attr=None, visible=True):
        self.children = []  # do not touch
        self.parent = None  # do not touch, code depends on this
        self.namespace = None  # TODO: Assert why we need this and above
        self.title = title
        self.url = url
        self.id = id
        self.parent_id = parent_id
        self.parent_namespace = parent_namespace
        self.visible = visible
        self.attr = attr or {} # To avoid declaring a dict in defaults...

    def __repr__(self):
        return "<Navigation Node: %s>" % smart_str(self.title)

    def get_menu_title(self):
        return self.title

    def get_absolute_url(self):
        return self.url

    def get_attribute(self, name):
        return self.attr.get(name, None)

    def get_descendants(self):
        return sum(([node] + node.get_descendants() for node in self.children), [])

    def get_ancestors(self):
        if getattr(self, 'parent', None):
            return [self.parent] + self.parent.get_ancestors()
        else:
            return []

如果我在这里添加名为category_name的自定义节点,它将起作用。但它不是修改基本文件的智能解决方案。

所以我的问题是:

  

如何在base.py之外添加我的自定义节点?即如果我想补充一下   它在我的应用程序models.py文件中。这甚至可能吗?

1 个答案:

答案 0 :(得分:0)

我终于找到了解决方案。答案是:是的!有可能的。

正如文档中所述,您可以使用 modify()方法。

但它对我不起作用,因为我对node.attr["changed_by"]感到困惑。在模板中,我想使用这样的东西:{{ child.category_name }},但很明显,我修改错了。

正确的方法是:

from menus.base import Modifier
from menus.menu_pool import menu_pool

from cms.models import Page

class MyMode(Modifier):
    """

    """
    def modify(self, request, nodes, namespace, root_id, post_cut, breadcrumb):
        # if the menu is not yet cut, don't do anything
        if post_cut:
            return nodes
        # otherwise loop over the nodes
        for node in nodes:
            # does this node represent a Page?
            if node.attr["is_page"]:
                # if so, put its changed_by attribute on the node
                node.category_name = "Some category name here"
        return nodes

menu_pool.register_modifier(MyMode)

现在,在menu.html中,您可以使用child.category_name,它将输出字符串&#34;此处的某些类别名称&#34;

{% load i18n menu_tags cache %}

{% for child in children %}
<li>
    {% if child.children %}
    <a href="{{ child.get_absolute_url }}">
        {{ child.get_menu_title }} <span class="caret"></span>
    </a>
    <ul class="menu-vertical">
        {% show_menu from_level to_level extra_inactive extra_active template "" "" child %}
    </ul>
    {% else %}
        <a class1="{{ child.get_absolute_url }}" href="{{ child.get_absolute_url }}">
            {% if child.category_name %}
                <b>{{ child.category }}</b>
            {% endif %}
            {{ child.get_menu_title }}
        </a>
    {% endif %}
</li>
{% if class and forloop.last and not forloop.parentloop %}{% endif %}
{% endfor %}

最后,经过几个小时的尝试,我解决了这个问题。