跳转到主要内容

Django的树形菜单应用。

项目描述

https://travis-ci.org/jphalip/django-treemenus.png

这是一个简单通用的Django树形菜单系统,具有易于使用的管理界面。它涵盖了构建树形菜单的所有基本要素,应该足够用于许多项目。如果您需要为菜单项添加一些特殊行为,它也易于扩展。

django-treemenus与Django 1.0及以上版本以及Python 2.5及以上版本兼容。

安装

安装官方版本

django-treemenus可在PyPI上找到,并可以使用Pip安装

pip install django-treemenus

或者,官方源代码发布可以在https://pypi.python.org/pypi/django-treemenus找到

下载.zip发行文件,解压它。其中包含一个名为setup.py的脚本。运行以下命令

python setup.py install

…然后软件包将自动安装。

安装开发版本

如果您希望定期更新Django Tree Menus以获取最新的错误修复和改进,在官方版本中包含之前,请使用git clone

git clone https://github.com/jphalip/django-treemenus

然后将treemenus文件夹添加到您的PYTHONPATH或符号链接(如果是Windows系统,则是junction),例如在Python的site-packages目录下。

将树形菜单链接到您的项目

  1. treemenus添加到Django项目的INSTALLED_APPS设置中。

  2. 通过在项目根目录运行以下命令创建django-treemenus表

    python manage.py syncdb
  3. 在项目模板文件夹中创建并添加您自定义的模板。这些模板是必要的,用于指定您希望在网站上显示菜单的方式(以下将提供更多有关模板使用的详细信息)。包中也提供了一些示例模板,以帮助您开始。

基本使用

要构建一个菜单,登录到管理界面,然后在Treemenus应用程序部分下点击“菜单”,然后点击“添加菜单”。为新菜单命名并保存。

然后,要创建菜单项,点击菜单列表中的菜单。您将在页面底部看到一张表格,其中只有一个条目:菜单的根。点击“添加条目”,选择其父级(显然,因为这是您创建的第一个条目,您只能选择根)。填写条目的详细信息并点击“保存”。新的条目现在显示在表格中。现在继续创建尽可能多的分支,以构建整个树形菜单的结构。

当您从管理界面完成菜单的构建后,您必须编写适当的模板来在您的网站上显示菜单(以下将说明)。

django-treemenus使用的模板

django-treemenus中包含的视图使用两个模板。您需要在自己的模板文件夹中创建自己的模板或任何在项目的TEMPLATE_DIRS设置中引用的文件夹。

treemenus/menu.html

指定如何显示菜单的模板。

上下文

  • menu

    要显示的菜单的指针。您可以使用menu.root_item访问其根项。

  • menu_type(可选)

    如果在使用模板标签调用时指定了此变量,则此变量将存在。(有关更多详细信息,请参阅“模板标签”部分)。

此模板的示例:

{% load tree_menu_tags %}

{% ifequal menu_type "unordered-list" %}
    <ul>
        {% for menu_item in menu.root_item.children %}
            {% show_menu_item menu_item %}
        {% endfor %}
    </ul>
{% endifequal %}
{% ifequal menu_type "ordered-list" %}
    <ol>
        {% for menu_item in menu.root_item.children %}
            {% show_menu_item menu_item %}
        {% endfor %}
    </ol>
{% endifequal %}

treemenus/menu_item.html

指定如何显示菜单项的模板。

上下文

  • menu_item

    要显示的菜单项的指针。您可以直接访问其所有方法和变量。

  • menu_type(可选)

    如果在使用模板标签调用时指定了此变量,则此变量将可访问。(有关更多详细信息,请参阅“模板标签”部分)。

此模板的示例:

{% load tree_menu_tags %}
<li><a href="{{ menu_item.url }}">{{ menu_item.caption }}</a>
    {% if menu_item.children %}
    <ul>
        {% for child_item in menu_item.children %}
        {% show_menu_item child_item %}
        {% endfor %}
    </ul>
    {% endif %}
</li>

模板标签

有三个模板标签可让您显示菜单。要使用它们,您必须首先使用以下代码加载包含它们的库:

{% load tree_menu_tags %}

show_menu

这是起点。您可以在任何需要显示菜单的地方调用它(通常是在网站的基模板中)。

有两个属性

  • menu_name

    要显示的菜单的名称,就像通过管理界面保存的那样。

  • menu_type

    此属性是可选的。如果提供了它,它将简单地传递给treemenus/menu.html模板。它没有特定的预定义功能,但可以通过(% ifequal menu_type “sometype” %}来测试以确定如何显示菜单(有关模板treemenus/menu.html的示例,请参阅上方)。

使用示例:

{% show_menu "TopMenu" %}
...
{% show_menu "LeftMenu" "vertical" %}
...
{% show_menu "RightMenu" "horizontal" %}

show_menu_item

此标签允许您显示一个菜单项,它只有一个属性。

使用示例:

{% show_menu_item menu_item %}

reverse_named_url

此标签允许您反转菜单项的命名URL,该URL作为单个字符串传递。要了解更多关于命名URL的信息,请参阅Django模板文档。例如,传递的值可以是“latest_news”或“show_profile user.id”,这将反转到相应的URL(在您的URLConf中定义)。

使用示例:

<li><a href="{% reverse_named_url menu_item.named_url %}">{{ menu_item.caption }}</a></li>

属性和方法

正如您所猜想的,您可以操作两种类型的对象:菜单和菜单项。在本节中,我介绍了它们的属性和方法,您可以在模板中使用它们。

自定义/扩展

上面列出的属性和方法为树状菜单提供了基本的行为。如果您觉得不够,还可以通过扩展菜单项定义来添加自定义行为。为此,您需要创建一个模型类,该类将包含您菜单项的所有额外属性。

为了说明这一点,假设您想向您的菜单项添加一个published属性,这样只有当published设置为True时,它们才会显示在您的网站上。

为此,创建一个新的应用(让我们称其为menu_extension),具有以下结构

menu_extension
    __init__.py
    models.py
    forms.py

然后,在menu_extension.models.py中添加以下内容

from django.db import models
from treemenus.models import MenuItem

class MenuItemExtension(models.Model):
    menu_item = models.OneToOneField (MenuItem, related_name="extension")
    published = models.BooleanField(default=False)

您的扩展对象需要有一个属性menu_item,它是一个指向菜单项对象的唯一链接。这就是扩展成为可能的原因。然后您会注意到我们的属性published,您可以在那里自由添加任何其他属性来自定义您的菜单项。

然后您需要创建数据库表来存储您的扩展数据,通过将menu_extension添加到Django项目的INSTALLED_APPS设置,然后从项目的根目录运行以下命令

python manage.py syncdb

现在,您需要指定一个表单,让您可以从管理界面编辑这些额外属性。在您的项目的admin.py或您的扩展菜单应用中的admin.py中,添加以下内容

from django.contrib import admin
from treemenus.admin import MenuAdmin, MenuItemAdmin
from treemenus.models import Menu
from menu_extension.models import MenuItemExtension

class MenuItemExtensionInline(admin.StackedInline):
    model = MenuItemExtension
    max_num = 1

class CustomMenuItemAdmin(MenuItemAdmin):
    inlines = [MenuItemExtensionInline,]

class CustomMenuAdmin(MenuAdmin):
    menu_item_admin_class = CustomMenuItemAdmin

admin.site.unregister(Menu) # Unregister the standard admin options
admin.site.register(Menu, CustomMenuAdmin) # Register the new, customized, admin options

就这样!现在,当创建或编辑菜单项时,您将看到一个包含所有扩展属性的内联表单(在这个例子中,是published复选框)。

现在,如果您想在模板中使用 published 属性,您需要使用菜单项的 extension 方法,如下所示

{% if menu_item.extension.published %}
    <li><a href="{{ menu_item.url }}">{{ menu_item.caption }}</a></li>
{% endif %}

现在,只有当菜单项的 published 复选框被勾选时,您的菜单项才会显示。

使用这种技术,您显然可以扩展菜单项以包含您想要的任何属性。其他示例可能包括您想要为某些菜单项添加特殊的CSS样式,或者使它们仅在用户登录时显示等。只需在扩展模型中添加属性,并在模板中使用它们来创建特殊的行为。请参阅“技巧和技巧”部分以获取更多想法。

技巧和技巧

在本节中,我将提供一些关于使用或扩展菜单的示例。这些示例可能仅涵盖您自己的某些特定需求,或者至少可以激发您并帮助您充分利用菜单。

国际化

如果您使用 Django 国际化 模块,使您的菜单多语言化非常简单。您可以做的就是在菜单项的 caption 属性上应用翻译。例如

{% load i18n %}
...
<li><a href="{{ menu_item.url }}">{% trans menu_item.caption %}</a></li>

然后,手动在您的 *.po 文件中添加翻译条目。

如果您使用更复杂或定制的翻译系统,您可以简单地定义您的扩展类(或者如果您还没有创建,则创建它)并使用一个管理翻译的方法,例如

class MenuItemExtension(models.Model):
    menu_item = models.OneToOneField (MenuItem, related_name="extension")
    ...

    def translation():
        translation = do_something_with(self.menu_item.caption)
        return translation

然后在您的模板中

<li><a href="{{ menu_item.url }}">{% trans menu_item.extension.translation %}</a></li>

登录限制

如果您想要使某些菜单项私有,并且仅对已登录用户可用,这是很简单的事情!只需像以下那样定义您的扩展类(或者如果您还没有创建,则创建它)

class MenuItemExtension(models.Model):
    menu_item = models.OneToOneField (MenuItem, related_name="extension")
    protected = models.BooleanField(default=False)
    ...

然后在您的模板中

{% if menu_item.extension.protected %}
    {% if user.is_authenticated %}
        <li><a href="{{ menu_item.url }}">{{ menu_item.caption }}</a></li>
    {% endif %}
{% else %}
    <li><a href="{{ menu_item.url }}">{{ menu_item.caption }}</a></li>
{% endif %}

(假设上下文变量‘user’代表当前已登录用户)

自动选择菜单项

在此,我将解释如何在访问您网站上的给定页面时自动选择菜单项。这是一个说明扩展如何自定义菜单行为的强大功能的良好示例。对于此示例,让我们假设您希望在访问网址‘http://www.example.com/contact/’时,在视觉上选择菜单项‘联系’

首先,定义您的扩展类(或者如果您还没有创建,则创建它),如下所示

class MenuItemExtension(models.Model):
    menu_item = models.OneToOneField (MenuItem, related_name="extension")
    selected_patterns = models.TextField(blank=True)

selected_patterns 是一个属性,它将指定菜单项应具有哪个 URL 的“selected”状态。有关如何将扩展类连接到菜单的说明,请参阅上面的扩展部分。

现在,在管理员部分,编辑‘联系’菜单项,并在其 selected_patterns 文本框中输入以下行

^/contact/$

我们在这里使用正则表达式,这为我们提供了指定“selected”URL模式的灵活性。有关更多信息,请参阅 正则表达式语法 的官方 Python 文档。在此示例中,我们仅使用一个正则表达式模式 (^/contact/$),但您可以通过在文本框的每一行中输入不同的模式来添加尽可能多的模式。

然后,在您的 menu_item.html 模板中,使用以下“if”语句

{% load menu_extension_filters %}
...
<li><a href="{{ menu_item.url }}" class="{% if menu_item.extension.selected_patterns|match_path:request.path %}selected{% endif %}">{{ menu_item.caption }}</a></li>

使用此代码,将匹配当前 URL 的任何菜单项的属性 selected_patterns 将被赋予“selected”CSS类(您需要根据您的样式表定义“selected”类实际执行的操作 - 例如更改颜色或字体?)。在此示例中,我们分配了特殊样式以在视觉上区分选定的菜单项,但您显然可以使用上述“if”语句执行任何形式的区分(例如显示选定菜单的所有子菜单等)。别忘了加载我们即将创建的 menu_extension_filters 模块。

现在我们需要创建一个名为‘match_path’的过滤器。在你的 menu_extension 应用程序(或者你给菜单扩展应用程序取的任何名字)中,创建一个名为 templatetags 的目录,该目录包含两个文件: __init__.py(保持为空)和包含以下代码的 menu_extension_filters.py 文件。

import re
from django import template

register = template.Library()

def match_path(patterns, path):
    if patterns:
        for pattern in patterns.splitlines():
            if re.compile(pattern).match(path):
                return True
    return False
register.filter('match_path', match_path)

它的作用是测试每行中的每个模式(记住,你可以在 selected_patterns 文本字段的每行添加一个模式)并返回 true,如果这些模式中的任何一个与给定的路径匹配。

最后,为了能够在模板中通过 request.path 访问当前 URL,你需要做两件事

1) 将 django.core.context_processors.request 添加到你的 TEMPLATE_CONTEXT_PROCESSORS 设置中(有关详细信息,请参阅 Django 文档中的 上下文处理器)。

2) 在你的视图中使用 RequestContext 对象并将其传递到你的模板中。(请参阅 Django 文档中的 RequestContext)。

这就完成了!

请在 https://github.com/jphalip/django-treemenus/issues 上记录任何问题或错误报告。

享受吧!

Julien Phalip(项目开发者)

项目详情


下载文件

下载适合您平台的应用程序文件。如果您不确定选择哪个,请了解有关 安装包 的更多信息。

源分布

django-treemenus-0.9.2.tar.gz (18.0 kB 查看哈希

上传时间

由以下机构支持