{ "info": { "author": "Julien Phalip", "author_email": "jphalip@gmail.com", "bugtrack_url": null, "classifiers": [ "Development Status :: 5 - Production/Stable", "Environment :: Web Environment", "Framework :: Django", "Intended Audience :: Developers", "License :: OSI Approved :: BSD License", "Operating System :: OS Independent", "Programming Language :: Python", "Programming Language :: Python :: 2", "Programming Language :: Python :: 2.5", "Programming Language :: Python :: 2.6", "Programming Language :: Python :: 2.7", "Programming Language :: Python :: 3", "Programming Language :: Python :: 3.2", "Programming Language :: Python :: 3.3", "Topic :: Internet :: WWW/HTTP", "Topic :: Internet :: WWW/HTTP :: Dynamic Content", "Topic :: Software Development :: Libraries :: Python Modules" ], "description": "=================\r\nDjango Tree Menus\r\n=================\r\n\r\n.. image:: https://travis-ci.org/jphalip/django-treemenus.png\r\n\r\nThis is a simple and generic tree-like menuing system for Django_ with an\r\neasy-to-use admin interface. It covers all the essentials for building\r\ntree-structured menus and should be enough for a lot of projects.\r\nIt is also easily extendable if you need to add some special behaviour to\r\nyour menu items.\r\n\r\ndjango-treemenus works with Django 1.0 and above and with python 2.5 and above.\r\n\r\n.. _Django: http://www.djangoproject.com/\r\n\r\nInstallation\r\n============\r\n\r\nInstalling an official release\r\n------------------------------\r\n\r\ndjango-treemenus is available on PyPI, and can be installed using Pip::\r\n\r\n pip install django-treemenus\r\n\r\nAlternatively, official source releases are made available at https://pypi.python.org/pypi/django-treemenus\r\n\r\nDownload the .zip distribution file and unpack it. Inside is a script\r\nnamed ``setup.py``. Run this command::\r\n\r\n python setup.py install\r\n\r\n...and the package will install automatically.\r\n\r\nInstalling the development version\r\n----------------------------------\r\n\r\nIf you prefer to update Django Tree Menus occasionally to get the latest bug\r\nfixes and improvements before they are included in an official release, do a\r\ngit clone instead::\r\n\r\n git clone https://github.com/jphalip/django-treemenus\r\n\r\nThen add the ``treemenus`` folder to your PYTHONPATH or symlink (junction, if\r\nyou're on Windows), such as in your Python's ``site-packages`` directory.\r\n\r\nHooking Tree Menus to your project\r\n----------------------------------\r\n\r\n1. Add ``treemenus`` to the ``INSTALLED_APPS`` setting of your\r\n Django project.\r\n\r\n2. Create django-treemenus tables by running the following command from the\r\n root of your project::\r\n\r\n python manage.py syncdb\r\n\r\n3. Create and add your custom templates to your project template folder. These\r\n templates are necessary to specify how you want your menus to be displayed\r\n on your site (See further below for more details on the use of templates).\r\n Some sample templates are also provided in the package to get you started.\r\n\r\nBasic use\r\n=========\r\n\r\nTo build a menu, log into the admin interface, and click \"Menus\" under\r\nthe Treemenus application section, then click \"Add menu\". Give your new\r\nmenu a name and then save.\r\n\r\nThen, to create menu items, click on your menu in the menu list. You will\r\nthen see a table in the bottom part of the page with only one item: the\r\nmenu's root. Click \"Add an item\", select its parent (obviously, since this\r\nis the first item you're creating you can only select the root). Fill out\r\nthe item's details and click \"Save\". The new item now shows up in the table.\r\nNow keep going to build the whole structure of your tree menu by creating as\r\nmany branches as you like.\r\n\r\nWhen you've finished building your menu from the admin interface, you will\r\nhave to write the appropriate templates to display the menu on your site\r\n(see below).\r\n\r\nTemplates used by django-treemenus\r\n==================================\r\n\r\nThe views included in django-treemenus use two templates. You need to create\r\nyour own templates into your template folder or any folder referenced in the\r\n``TEMPLATE_DIRS`` setting of your project.\r\n\r\n``treemenus/menu.html``\r\n-----------------------\r\n\r\nTemplate to specify how to display a menu.\r\n\r\n**Context:**\r\n\r\n* ``menu``\r\n Pointer to the menu to display. You can access its root item with\r\n ``menu.root_item``.\r\n\r\n* ``menu_type`` (optional)\r\n This variable will only be present if it has been specified when\r\n calling the ``show_menu`` template tag. (See the \"Template tags\"\r\n section for more details).\r\n\r\n**Example for this template**::\r\n\r\n {% load tree_menu_tags %}\r\n\r\n {% ifequal menu_type \"unordered-list\" %}\r\n \r\n {% endifequal %}\r\n {% ifequal menu_type \"ordered-list\" %}\r\n
    \r\n {% for menu_item in menu.root_item.children %}\r\n {% show_menu_item menu_item %}\r\n {% endfor %}\r\n
\r\n {% endifequal %}\r\n\r\n\r\n``treemenus/menu_item.html``\r\n----------------------------\r\n\r\nTemplate to specify how to display a menu item.\r\n\r\n**Context:**\r\n\r\n* ``menu_item``\r\n Pointer to the menu_item to display. You can directly access all\r\n its methods and variables.\r\n\r\n* ``menu_type`` (optional)\r\n This variable will only be accessible if it has been specified when\r\n calling the ``show_menu`` template tag (See the \"Template tags\"\r\n section for more details).\r\n\r\n**Example for this template**::\r\n\r\n {% load tree_menu_tags %}\r\n
  • {{ menu_item.caption }}\r\n {% if menu_item.children %}\r\n \r\n {% endif %}\r\n
  • \r\n\r\n\r\nTemplate tags\r\n=============\r\n\r\nThere a 3 template tags to let you display your menus. To be able to use them\r\nyou will first have to load the library they are contained in, with::\r\n\r\n {% load tree_menu_tags %}\r\n\r\n``show_menu``\r\n-------------\r\n\r\nThis is the starting point. Call it wherever you want to display your menu\r\n(most of the time it will be in your site's base template).\r\n\r\nThere are two attributes:\r\n\r\n* ``menu_name``\r\n Name of the menu to display, as it has been saved via the admin interface.\r\n* ``menu_type``\r\n This attribute is optional. If it is given it is simply\r\n passed to the ``treemenus/menu.html`` template. It does\r\n not have any particular pre-defined function but can be\r\n tested with (% ifequal menu_type \"sometype\" %} to\r\n determine how to display the menu (See above example for\r\n the template ``treemenus/menu.html``).\r\n\r\n**Example of use**::\r\n\r\n {% show_menu \"TopMenu\" %}\r\n ...\r\n {% show_menu \"LeftMenu\" \"vertical\" %}\r\n ...\r\n {% show_menu \"RightMenu\" \"horizontal\" %}\r\n\r\n``show_menu_item``\r\n------------------\r\n\r\nThis tag allows you to display a menu item, which is the only attribute.\r\n\r\n**Example of use**::\r\n\r\n {% show_menu_item menu_item %}\r\n\r\n``reverse_named_url``\r\n---------------------\r\n\r\nThis tag allows you to reverse the named URL of a menu item, which is passed as a\r\nsingle string. To know more about named URLs, refer to `the Django template documentation`_.\r\nFor example, the passed value could be 'latest_news' or 'show_profile user.id', and that\r\nwould be reversed to the corresponding URL (as defined in your URLConf).\r\n\r\n.. _the Django template documentation: https://docs.djangoproject.com/en/dev/ref/templates/builtins/#url\r\n\r\n**Example of use**::\r\n\r\n
  • {{ menu_item.caption }}
  • \r\n\r\nAttributes and methods\r\n======================\r\n\r\nAs you've guessed it, you can manipulate two types of objects: menus and menu\r\nitems. In this section I present their attributes and methods, which you can use\r\nin your templates.\r\n\r\nMenu\r\n----\r\n\r\nThere is only one attribute that is available: ``root_item``, which points to...\r\nyou got it, the menu's root item.\r\n\r\nMenu item\r\n---------\r\n\r\n* ``menu``\r\n Returns the menu to which it belongs.\r\n\r\n* ``url``\r\n Returns the item's url.\r\n\r\n **Example of use**::\r\n\r\n
  • {{ menu_item.caption }}
  • \r\n\r\n* ``parent``\r\n Returns the menu item's parent (that is, another menu item).\r\n\r\n* ``rank``\r\n Returns the item's rank amongst its siblings. The first item of a branch has\r\n a rank of 0, the second one has a rank of 1, etc. To change an item's ranking\r\n you can move it up or down through the admin interface.\r\n\r\n **Example of use**::\r\n\r\n
  • {{ menu_item.caption }}
  • \r\n\r\n* ``level``\r\n Returns the item's level in the hierarchy. This is automatically calculated by\r\n the system. For example, the root item has a level 0, and its children have a\r\n level 1.\r\n\r\n **Example of use**::\r\n\r\n {% ifequal menu_item.level 1 %}\r\n
  • {{ menu_item.caption }}
  • \r\n {% else %}\r\n
  • {{ menu_item.caption }}
  • \r\n {% endifequal %}\r\n\r\n* ``caption``\r\n Returns the item's caption.\r\n\r\n* ``named_url``\r\n Use this attribute if you want to use named URLs instead of raw URLs.\r\n\r\n **Example of use**::\r\n\r\n
  • {{ menu_item.caption }}
  • \r\n\r\n* ``has_children``\r\n Returns True if the item has some children, False otherwise.\r\n\r\n* ``children``\r\n Returns a list with the menu item's children, ordered by rank.\r\n\r\n **Example of use**::\r\n\r\n {% if menu_item.has_children %}\r\n
  • {{ menu_item.caption }}\r\n \r\n
  • \r\n {% else %}\r\n
  • {{ menu_item.caption }}
  • \r\n {% endif %}\r\n\r\n* ``siblings``\r\n Returns a list with the menu item's siblings (i.e all other items that have the\r\n same parent), ordered by rank.\r\n\r\nCustomizing/Extending\r\n=====================\r\n\r\nThe attributes and methods enumerated above provide the essential behaviour for a\r\ntree-structured menu. If that is not enough for you, it is also possible to add\r\ncustomized behaviour by extending the menu item definition. To do so, you need to\r\ncreate a model class that will contain all the extra attributes for your menu items.\r\n\r\nTo illustrate this, let's say that you'd like to add a ``published`` attribute to your\r\nmenu items so that they only show up on your site if ``published`` is turned to ``True``.\r\n\r\nTo do so, create a new application (let's call it ``menu_extension``), with the following\r\nstructure::\r\n\r\n menu_extension\r\n __init__.py\r\n models.py\r\n forms.py\r\n\r\nThen, in ``menu_extension.models.py`` add the following::\r\n\r\n from django.db import models\r\n from treemenus.models import MenuItem\r\n\r\n class MenuItemExtension(models.Model):\r\n menu_item = models.OneToOneField (MenuItem, related_name=\"extension\")\r\n published = models.BooleanField(default=False)\r\n\r\nIt is required that your extension object has the attribute ``menu_item`` that is a **unique** link\r\nto a menu item object. This is what makes the extension possible.\r\nThen you can notice our attribute ``published``, feel free to add any other attribute there to\r\ncustomize your menu items.\r\n\r\nYou then need to create the database table that will store your extension data by adding\r\n``menu_extension`` to the ``INSTALLED_APPS`` setting of your Django project, and then running\r\nthe following command from the root of your project::\r\n\r\n python manage.py syncdb\r\n\r\nNow, you need to specify a form to let you edit those extra attributes from the admin interface.\r\nIn your project's ``admin.py`` or your extension menu app's ``admin.py``, add the following::\r\n\r\n from django.contrib import admin\r\n from treemenus.admin import MenuAdmin, MenuItemAdmin\r\n from treemenus.models import Menu\r\n from menu_extension.models import MenuItemExtension\r\n\r\n class MenuItemExtensionInline(admin.StackedInline):\r\n model = MenuItemExtension\r\n max_num = 1\r\n\r\n class CustomMenuItemAdmin(MenuItemAdmin):\r\n inlines = [MenuItemExtensionInline,]\r\n\r\n class CustomMenuAdmin(MenuAdmin):\r\n menu_item_admin_class = CustomMenuItemAdmin\r\n\r\n admin.site.unregister(Menu) # Unregister the standard admin options\r\n admin.site.register(Menu, CustomMenuAdmin) # Register the new, customized, admin options\r\n\r\nAnd that's it! Now, when creating or editing a menu item, you'll see an inline form with\r\nall the extension attributes (in this example, the ``published`` check box).\r\n\r\nNow, if you want to use ``published`` attribute in your template, you need to use the\r\nmenu item's ``extension`` method, as follows::\r\n\r\n {% if menu_item.extension.published %}\r\n
  • {{ menu_item.caption }}
  • \r\n {% endif %}\r\n\r\nYour menu items will now only appear if their ``published`` check box has been ticked.\r\n\r\nUsing this technique, you can obviously extend your menu items with whatever attribute\r\nyou'd like. Other examples might be that you want to add special CSS styles to certain\r\nmenu items, or to make some of them show up only if the user is logged in, etc. Simply\r\nadd attributes in you extension model and make use of them in your templates to create\r\nspecial behaviour. See the 'Tips and Tricks' section for more ideas.\r\n\r\nTips and tricks\r\n===============\r\n\r\nIn this section I give some examples on using or extending menus.\r\nThese may just cover some of your own specific needs or at least inspire you and get\r\nyou started to make the most out of your menus.\r\n\r\nInternationalization\r\n--------------------\r\n\r\nMaking your menus multi-lingual is very easy if you use the `Django internationalization`_\r\nmodule. What you can do is apply the translation to the ``caption`` attribute\r\nof a menu_item. For example::\r\n\r\n {% load i18n %}\r\n ...\r\n
  • {% trans menu_item.caption %}
  • \r\n\r\nThen, add manually the translation entries in your ``*.po`` file.\r\n\r\n.. _Django internationalization: https://docs.djangoproject.com/en/dev/topics/i18n/\r\n\r\nIf you use more complex or custom translation systems, you may simply define your\r\nextension class (or create it if you don't already have one) with a method to manage\r\nthe translation, for example::\r\n\r\n class MenuItemExtension(models.Model):\r\n menu_item = models.OneToOneField (MenuItem, related_name=\"extension\")\r\n ...\r\n\r\n def translation():\r\n translation = do_something_with(self.menu_item.caption)\r\n return translation\r\n\r\nAnd then in your template::\r\n\r\n
  • {% trans menu_item.extension.translation %}
  • \r\n\r\nLogin restriction\r\n-----------------\r\n\r\nIf you want to make some of your menus items private and only available to logged in\r\nusers, that's simple! Simply define your extension class (or create it if you don't\r\nalready have one) like the following::\r\n\r\n class MenuItemExtension(models.Model):\r\n menu_item = models.OneToOneField (MenuItem, related_name=\"extension\")\r\n protected = models.BooleanField(default=False)\r\n ...\r\n\r\nAnd then in your template::\r\n\r\n {% if menu_item.extension.protected %}\r\n {% if user.is_authenticated %}\r\n
  • {{ menu_item.caption }}
  • \r\n {% endif %}\r\n {% else %}\r\n
  • {{ menu_item.caption }}
  • \r\n {% endif %}\r\n\r\n(assuming that the context variable 'user' represents the currently logged-in user)\r\n\r\nAutomatically select menu items\r\n-------------------------------\r\n\r\nHere I'm going to explain how to automatically select a menu item when visiting\r\na given page of your site. This is a good example to illustrate the power of\r\nextensions for customizing your menu's behaviour.\r\nFor this example, let's say that you'd like to visually select the menu item\r\n'Contact' when visiting the url 'http://www.example.com/contact/'\r\n\r\nFirst, define your extension class (or create it if you don't already have one)\r\nlike the following::\r\n\r\n class MenuItemExtension(models.Model):\r\n menu_item = models.OneToOneField (MenuItem, related_name=\"extension\")\r\n selected_patterns = models.TextField(blank=True)\r\n\r\n``selected_patterns`` is the attribute which will specify for what urls the menu\r\nitem should have the 'selected' status.\r\nRefer to the section on extensions above to see how to hook your extension class\r\nto your menus.\r\n\r\nNow, in the admin section, edit the 'Contact' menu item and type the following\r\nline in its ``selected_patterns`` textfield::\r\n\r\n ^/contact/$\r\n\r\nHere we're using regular expressions so that gives us some flexibility to specify\r\nour 'selected' url patterns. Refer to the official python documentation on\r\n`regular expressions syntax`_ for more detailed information. In this example we're\r\nonly using one regular expression pattern (^/contact/$) but you could add as many\r\nas you'd like by typing a different pattern on each line of the textfield.\r\n\r\n.. _regular expressions syntax: http://docs.python.org/lib/re-syntax.html\r\n\r\nThen, in your ``menu_item.html`` template, use the following 'if' statement::\r\n\r\n {% load menu_extension_filters %}\r\n ...\r\n
  • {{ menu_item.caption }}
  • \r\n\r\nWith this code, every menu item whose attribute ``selected_patterns`` matches the\r\ncurrent url will be given the 'selected' CSS class (it's up to you to define in\r\nyour style sheet what that 'selected' class actually does - maybe change the colour\r\nor the font?). In this example we're allocating a special style to visually\r\ndistinguish the selected menu items, but you're obviously free to use the 'if'\r\nstatement above to do any form of disctinction you like (for example displaying\r\nall children of a selected menu, etc.)\r\nDon't forget to load the ``menu_extension_filters`` module, which we're going to\r\ncreate in a moment.\r\n\r\nWe now need to create the 'match_path' filter. In your ``menu_extension``\r\napplication (or whatever name you've given to your menu extension application)\r\ncreate a directory ``templatetags`` containing two files: ``__init__.py`` (leave it\r\nempty) and ``menu_extension_filters.py`` containing the following code::\r\n\r\n import re\r\n from django import template\r\n\r\n register = template.Library()\r\n\r\n def match_path(patterns, path):\r\n if patterns:\r\n for pattern in patterns.splitlines():\r\n if re.compile(pattern).match(path):\r\n return True\r\n return False\r\n register.filter('match_path', match_path)\r\n\r\nWhat it does is test each pattern on each line of our patterns (remember, you can\r\nadd one pattern on each line of the ``selected_patterns`` textfield) and returns\r\ntrue if any of those matches the given path.\r\n\r\nFinally, to be able to access the current url through ``request.path`` in your\r\ntemplate, you need to do 2 things:\r\n\r\n1) Add ``django.core.context_processors.request`` to your\r\n``TEMPLATE_CONTEXT_PROCESSORS`` setting (see the Django documentation on `context\r\nprocessors`_ for more details).\r\n\r\n.. _context processors: https://docs.djangoproject.com/en/dev/ref/templates/api/#django-core-context-processors-request\r\n\r\n2) Use a RequestContext object in your views to pass to your templates. (see Django\r\ndocumentation on RequestContext_).\r\n\r\n.. _RequestContext: https://docs.djangoproject.com/en/dev/ref/templates/api/#subclassing-context-requestcontext\r\n\r\nThat's it!!\r\n===========\r\n\r\nPlease log any issue or bug report at https://github.com/jphalip/django-treemenus/issues\r\n\r\nEnjoy!\r\n\r\n`Julien Phalip`_ (project developer)\r\n\r\n.. _Julien Phalip: https://twitter.com/julienphalip\r\n", "description_content_type": null, "docs_url": null, "download_url": "UNKNOWN", "downloads": { "last_day": -1, "last_month": -1, "last_week": -1 }, "home_page": "http://github.com/jphalip/django-treemenus/", "keywords": null, "license": "BSD", "maintainer": null, "maintainer_email": null, "name": "django-treemenus2", "package_url": "https://pypi.org/project/django-treemenus2/", "platform": "UNKNOWN", "project_url": "https://pypi.org/project/django-treemenus2/", "project_urls": { "Download": "UNKNOWN", "Homepage": "http://github.com/jphalip/django-treemenus/" }, "release_url": "https://pypi.org/project/django-treemenus2/0.9.3/", "requires_dist": null, "requires_python": null, "summary": "Tree-structured menuing application for Django.", "version": "0.9.3" }, "last_serial": 1856106, "releases": { "0.9.2a0": [ { "comment_text": "", "digests": { "md5": "b5f75832adb62a40d9bd98cd7a414eca", "sha256": "0b7e59fd7e1f8db8b200a24ab96b355c85ee33e640ebc4920eba0607a99e44f2" }, "downloads": -1, "filename": "django-treemenus2-0.9.2a0.tar.gz", "has_sig": false, "md5_digest": "b5f75832adb62a40d9bd98cd7a414eca", "packagetype": "sdist", "python_version": "source", "requires_python": null, "size": 18412, "upload_time": "2015-12-10T18:23:20", "url": "https://files.pythonhosted.org/packages/b1/5c/010f8c658412b439400b6e8b8f1eec422f54020b0ddd3874f0119eae22a4/django-treemenus2-0.9.2a0.tar.gz" } ], "0.9.3": [ { "comment_text": "", "digests": { "md5": "006c55cee72ee7af80d1e3d621c6eda8", "sha256": "618e73cf85ae6dfb7222ab879681f01325ce3248c897c36950c512b15d4a801d" }, "downloads": -1, "filename": "django-treemenus2-0.9.3.tar.gz", "has_sig": false, "md5_digest": "006c55cee72ee7af80d1e3d621c6eda8", "packagetype": "sdist", "python_version": "source", "requires_python": null, "size": 18401, "upload_time": "2015-12-10T18:25:42", "url": "https://files.pythonhosted.org/packages/8d/fb/663b02fc9bc4d238cd5563efb9c857bb3a8fc484852af79d8e1b5979070e/django-treemenus2-0.9.3.tar.gz" } ] }, "urls": [ { "comment_text": "", "digests": { "md5": "006c55cee72ee7af80d1e3d621c6eda8", "sha256": "618e73cf85ae6dfb7222ab879681f01325ce3248c897c36950c512b15d4a801d" }, "downloads": -1, "filename": "django-treemenus2-0.9.3.tar.gz", "has_sig": false, "md5_digest": "006c55cee72ee7af80d1e3d621c6eda8", "packagetype": "sdist", "python_version": "source", "requires_python": null, "size": 18401, "upload_time": "2015-12-10T18:25:42", "url": "https://files.pythonhosted.org/packages/8d/fb/663b02fc9bc4d238cd5563efb9c857bb3a8fc484852af79d8e1b5979070e/django-treemenus2-0.9.3.tar.gz" } ] }