GithubHelp home page GithubHelp logo

jphalip / django-treemenus Goto Github PK

View Code? Open in Web Editor NEW
127.0 6.0 61.0 537 KB

A simple django app to manage navigation menus via the django admin

License: BSD 3-Clause "New" or "Revised" License

Python 100.00%

django-treemenus's Introduction

Django Tree Menus

image

This is a simple and generic tree-like menuing system for Django with an easy-to-use admin interface. It covers all the essentials for building tree-structured menus and should be enough for a lot of projects. It is also easily extendable if you need to add some special behaviour to your menu items.

django-treemenus works with Django 1.0 and above and with python 2.5 and above.

Installation

Installing an official release

django-treemenus is available on PyPI, and can be installed using Pip:

pip install django-treemenus

Alternatively, official source releases are made available at https://pypi.python.org/pypi/django-treemenus

Download the .zip distribution file and unpack it. Inside is a script named setup.py. Run this command:

python setup.py install

...and the package will install automatically.

Installing the development version

If you prefer to update Django Tree Menus occasionally to get the latest bug fixes and improvements before they are included in an official release, do a git clone instead:

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

Then add the treemenus folder to your PYTHONPATH or symlink (junction, if you're on Windows), such as in your Python's site-packages directory.

Hooking Tree Menus to your project

  1. Add treemenus to the INSTALLED_APPS setting of your Django project.
  2. Create django-treemenus tables by running the following command from the root of your project:

    python manage.py syncdb
  3. Create and add your custom templates to your project template folder. These templates are necessary to specify how you want your menus to be displayed on your site (See further below for more details on the use of templates). Some sample templates are also provided in the package to get you started.

Basic use

To build a menu, log into the admin interface, and click "Menus" under the Treemenus application section, then click "Add menu". Give your new menu a name and then save.

Then, to create menu items, click on your menu in the menu list. You will then see a table in the bottom part of the page with only one item: the menu's root. Click "Add an item", select its parent (obviously, since this is the first item you're creating you can only select the root). Fill out the item's details and click "Save". The new item now shows up in the table. Now keep going to build the whole structure of your tree menu by creating as many branches as you like.

When you've finished building your menu from the admin interface, you will have to write the appropriate templates to display the menu on your site (see below).

Templates used by django-treemenus

The views included in django-treemenus use two templates. You need to create your own templates into your template folder or any folder referenced in the TEMPLATE_DIRS setting of your project.

treemenus/menu.html

Template to specify how to display a menu.

Context:

  • menu

    Pointer to the menu to display. You can access its root item with menu.root_item.

  • menu_type (optional)

    This variable will only be present if it has been specified when calling the show_menu template tag. (See the "Template tags" section for more details).

Example for this template:

{% 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

Template to specify how to display a menu item.

Context:

  • menu_item

    Pointer to the menu_item to display. You can directly access all its methods and variables.

  • menu_type (optional)

    This variable will only be accessible if it has been specified when calling the show_menu template tag (See the "Template tags" section for more details).

Example for this template:

{% 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>

Template tags

There a 3 template tags to let you display your menus. To be able to use them you will first have to load the library they are contained in, with:

{% load tree_menu_tags %}

show_menu

This is the starting point. Call it wherever you want to display your menu (most of the time it will be in your site's base template).

There are two attributes:

  • menu_name

    Name of the menu to display, as it has been saved via the admin interface.

  • menu_type

    This attribute is optional. If it is given it is simply passed to the treemenus/menu.html template. It does not have any particular pre-defined function but can be tested with (% ifequal menu_type "sometype" %} to determine how to display the menu (See above example for the template treemenus/menu.html).

Example of use:

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

show_menu_item

This tag allows you to display a menu item, which is the only attribute.

Example of use:

{% show_menu_item menu_item %}

reverse_named_url

This tag allows you to reverse the named URL of a menu item, which is passed as a single string. To know more about named URLs, refer to the Django template documentation. For example, the passed value could be 'latest_news' or 'show_profile user.id', and that would be reversed to the corresponding URL (as defined in your URLConf).

Example of use:

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

Attributes and methods

As you've guessed it, you can manipulate two types of objects: menus and menu items. In this section I present their attributes and methods, which you can use in your templates.

Menu

There is only one attribute that is available: root_item, which points to... you got it, the menu's root item.

Menu item

  • menu

    Returns the menu to which it belongs.

  • url

    Returns the item's url.

    Example of use:

    <li><a href="{{ menu_item.url }}">{{ menu_item.caption }}</a></li>
  • parent

    Returns the menu item's parent (that is, another menu item).

  • rank

    Returns the item's rank amongst its siblings. The first item of a branch has a rank of 0, the second one has a rank of 1, etc. To change an item's ranking you can move it up or down through the admin interface.

    Example of use:

    <li><a class="menuitem-{{ menu_item.rank }}" href="{{ menu_item.url }}">{{ menu_item.caption }}</a></li>
  • level

    Returns the item's level in the hierarchy. This is automatically calculated by the system. For example, the root item has a level 0, and its children have a level 1.

    Example of use:

    {% ifequal menu_item.level 1 %}
        <li><a class="top-item" href="{{ menu_item.url }}">{{ menu_item.caption }}</a></li>
    {% else %}
        <li><a href="{{ menu_item.url }}">{{ menu_item.caption }}</a></li>
    {% endifequal %}
  • caption

    Returns the item's caption.

  • named_url

    Use this attribute if you want to use named URLs instead of raw URLs.

    Example of use:

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

    Returns True if the item has some children, False otherwise.

  • children

    Returns a list with the menu item's children, ordered by rank.

    Example of use:

    {% if menu_item.has_children %}
        <li><a class="daddy" href="{{ menu_item.url }}">{{ menu_item.caption }}</a>
            <ul>
                {% for child in menu_item.children %}
                    {% show_menu_item child %}
                {% endfor %}
            </ul>
        </li>
    {% else %}
        <li><a href="{{ menu_item.url }}">{{ menu_item.caption }}</a></li>
    {% endif %}
  • siblings

    Returns a list with the menu item's siblings (i.e all other items that have the same parent), ordered by rank.

Customizing/Extending

The attributes and methods enumerated above provide the essential behaviour for a tree-structured menu. If that is not enough for you, it is also possible to add customized behaviour by extending the menu item definition. To do so, you need to create a model class that will contain all the extra attributes for your menu items.

To illustrate this, let's say that you'd like to add a published attribute to your menu items so that they only show up on your site if published is turned to True.

To do so, create a new application (let's call it menu_extension), with the following structure:

menu_extension
    __init__.py
    models.py
    forms.py

Then, in menu_extension.models.py add the following:

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)

It is required that your extension object has the attribute menu_item that is a unique link to a menu item object. This is what makes the extension possible. Then you can notice our attribute published, feel free to add any other attribute there to customize your menu items.

You then need to create the database table that will store your extension data by adding menu_extension to the INSTALLED_APPS setting of your Django project, and then running the following command from the root of your project:

python manage.py syncdb

Now, you need to specify a form to let you edit those extra attributes from the admin interface. In your project's admin.py or your extension menu app's admin.py, add the following:

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

And that's it! Now, when creating or editing a menu item, you'll see an inline form with all the extension attributes (in this example, the published check box).

Now, if you want to use published attribute in your template, you need to use the menu item's extension method, as follows:

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

Your menu items will now only appear if their published check box has been ticked.

Using this technique, you can obviously extend your menu items with whatever attribute you'd like. Other examples might be that you want to add special CSS styles to certain menu items, or to make some of them show up only if the user is logged in, etc. Simply add attributes in you extension model and make use of them in your templates to create special behaviour. See the 'Tips and Tricks' section for more ideas.

Tips and tricks

In this section I give some examples on using or extending menus. These may just cover some of your own specific needs or at least inspire you and get you started to make the most out of your menus.

Internationalization

Making your menus multi-lingual is very easy if you use the Django internationalization module. What you can do is apply the translation to the caption attribute of a menu_item. For example:

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

Then, add manually the translation entries in your *.po file.

If you use more complex or custom translation systems, you may simply define your extension class (or create it if you don't already have one) with a method to manage the translation, for example:

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

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

And then in your template:

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

Login restriction

If you want to make some of your menus items private and only available to logged in users, that's simple! Simply define your extension class (or create it if you don't already have one) like the following:

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

And then in your template:

{% 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 %}

(assuming that the context variable 'user' represents the currently logged-in user)

Automatically select menu items

Here I'm going to explain how to automatically select a menu item when visiting a given page of your site. This is a good example to illustrate the power of extensions for customizing your menu's behaviour. For this example, let's say that you'd like to visually select the menu item 'Contact' when visiting the url 'http://www.example.com/contact/'

First, define your extension class (or create it if you don't already have one) like the following:

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

selected_patterns is the attribute which will specify for what urls the menu item should have the 'selected' status. Refer to the section on extensions above to see how to hook your extension class to your menus.

Now, in the admin section, edit the 'Contact' menu item and type the following line in its selected_patterns textfield:

^/contact/$

Here we're using regular expressions so that gives us some flexibility to specify our 'selected' url patterns. Refer to the official python documentation on regular expressions syntax for more detailed information. In this example we're only using one regular expression pattern (^/contact/$) but you could add as many as you'd like by typing a different pattern on each line of the textfield.

Then, in your menu_item.html template, use the following 'if' statement:

{% 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>

With this code, every menu item whose attribute selected_patterns matches the current url will be given the 'selected' CSS class (it's up to you to define in your style sheet what that 'selected' class actually does - maybe change the colour or the font?). In this example we're allocating a special style to visually distinguish the selected menu items, but you're obviously free to use the 'if' statement above to do any form of disctinction you like (for example displaying all children of a selected menu, etc.) Don't forget to load the menu_extension_filters module, which we're going to create in a moment.

We now need to create the 'match_path' filter. In your menu_extension application (or whatever name you've given to your menu extension application) create a directory templatetags containing two files: __init__.py (leave it empty) and menu_extension_filters.py containing the following code:

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)

What it does is test each pattern on each line of our patterns (remember, you can add one pattern on each line of the selected_patterns textfield) and returns true if any of those matches the given path.

Finally, to be able to access the current url through request.path in your template, you need to do 2 things:

1) Add django.core.context_processors.request to your TEMPLATE_CONTEXT_PROCESSORS setting (see the Django documentation on context processors for more details).

2) Use a RequestContext object in your views to pass to your templates. (see Django documentation on RequestContext).

That's it!!

Please log any issue or bug report at https://github.com/jphalip/django-treemenus/issues

Enjoy!

Julien Phalip (project developer)

django-treemenus's People

Contributors

artscoop avatar aweakley avatar beyang avatar dhiana avatar domenkozar avatar eos87 avatar fallenflint avatar freakboy3742 avatar jphalip avatar lorddaedra avatar reavis avatar sdfsdhgjkbmnmxc avatar tcsorrel avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar

django-treemenus's Issues

cannot import name TOKEN_BLOCK

Hi,
Thank you for your work. I tried to use it with django 1.8 and there is a small compatibility problem.
In treemenus/templatetags/tree_menu_tags at line 63 you wrote from django.template import TOKEN_BLOCK, Token while in django 1.8 you need to import from django.template.base.
I think you may consider to update the code.

Again, thank you very much

Best regards,
Luca

Strong DB dependency

The show_menu template tag performs Menu.objects.get(...). If the database is not populated (for example, when running tests), any view referencing a template with this templatetag (which is usually at base template, affecting all pages!) will raise DoesNotExist.

Shouldn't the menu fail gracefully by not showing anything (just like django's own templatetags) instead of allowing this exception?

Please review MANUAL

Please review the MANUAL.txt.

Outdated content:

  • current django needs Python 2.5 (2.3 not supported)
  • Code is at github, not google.
    ....

Treemenus disappearing under Nginx

I've had a very strange issue with using treemenus in production. It was all going swimmingly well, working great on my local setup with the django-server, but when I moved to the live site it basically disappeared.

On the front-end the templates cause no error, but the output simply does not appear. (I had done a dump-data import-data to get the local menus onto the live site, there should have been something there.)

In the admin section, the menu page would appear fine, but in the change-menu page is blank after the name. The rest of the admin template loads ok, but it's just blank in the middle.

Is treemenu doing anything that Nginx might not like? It is the usual mod_wsgi setup, I haven't had any similar issues with other apps, and I'm a bit stumped as to how to de-bug it.

version numbers in setup.py confuse pip

i'm using pip to manage dependencies for my project.

it seems like setup.py for django-treemenus 0.8.6 reports its version as 0.8.5, and that setup.py for version 0.8.7 reports its version as 0.8.7-pre.

if i list "django-treemenus==0.8.7" in a requirements file and do "pip install -r requirements.txt". i get the error "Source in [...]/build/django-treemenus has version 0.8.7-pre that conflicts with django-treemenus==0.8.7 (from -r requirements.txt (line 1))"

if i change the requirement to "django-treemenus==0.8.7-pre", i get "No distributions matching the version for django-treemenus==0.8.7-pre (from -r requirements.txt (line 1))"

any chance you could change your version numbers or PyPi index so that they correspond to each other?

Item deletion in django 1.5

Hi,
Trying to delete an item makes it redirect to homepage, as it says in admin.py.
Running off "commit 4c136a4"
Changed:

--- a/treemenus/admin.py
+++ b/treemenus/admin.py
@@ -115,7 +115,7 @@ class MenuAdmin(admin.ModelAdmin):
                 url(r'^item_changelist/$', RedirectView.as_view(url='/'), name='treemenus_menuitem_changelist'),
                 url(r'^item_add/$', RedirectView.as_view(url='/'), name='treemenus_menuitem_add'),
                 url(r'^item_history/(?P<pk>[-\w]+)/$', RedirectView.as_view(url='/'), name='treemenus_menuitem_history'),
-                url(r'^item_delete/(?P<pk>[-\w]+)/$', RedirectView.as_view(url='/'), name='treemenus_menuitem_delete'),
+                url(r'^item_delete/(?P<menu_item_pk>[-\w]+)/$', self.admin_site.admin_view(self.delete_menu_item), name='treemenus_m
             )
         return my_urls + urls

@@ -146,8 +146,10 @@ class MenuAdmin(admin.ModelAdmin):
         menu_item_admin = self.menu_item_admin_class(MenuItem, self.admin_site, menu)
         return menu_item_admin.change_view(request, menu_item_pk, extra_context={'menu': menu})

-    def delete_menu_item(self, request, menu_pk, menu_item_pk):
+    def delete_menu_item(self, request, menu_pk=None, menu_item_pk=None):
         ''' Custom view '''
+        if not menu_pk:
+            menu_pk = MenuItem.objects.select_related('menu').get(id=menu_item_pk).menu.id
         menu = self.get_object_with_change_permissions(request, Menu, menu_pk)
         menu_item_admin = self.menu_item_admin_class(MenuItem, self.admin_site, menu)

This project is dead?

Hi, if yes please put in the description is deprecated please!
So many people would not bother to try it

Thank

Caught AttributeError while rendering: 'NoneType' object has no attribute 'objects'

When i run my django app using the development server everything is working just fine.
On my production server i ran the app under apache mod_wsgi and i get the following error randomly ( not every time ).

Django Version: 1.3
Exception Type: TemplateSyntaxError
Exception Value:

Caught AttributeError while rendering: 'NoneType' object has no attribute 'objects'

Exception Location: /home/django/ysma.grve/lib/python2.5/site-packages/django_treemenus-0.8.7_pre-py2.5.egg/treemenus/models.py in children, line 99
Python Executable: /usr/bin/python
Python Version: 2.5.2
Python Path:

['/var/www/vhosts/orbitlab.gr/subdomains/ysma/httpdocs/',
'/home/django/ysma.grve/lib/python2.5/site-packages/setuptools-0.6c8-py2.5.egg',
'/home/django/ysma.grve/lib/python2.5/site-packages/Django-1.3-py2.5.egg',
'/home/django/ysma.grve/lib/python2.5/site-packages/django_localeurl-1.4-py2.5.egg',
'/home/django/ysma.grve/lib/python2.5/site-packages/django_reversetag-0.3.2-py2.5.egg',
'/home/django/ysma.grve/lib/python2.5/site-packages/South-0.7.3-py2.5.egg',
'/home/django/ysma.grve/lib/python2.5/site-packages/MySQL_python-1.2.3-py2.5-linux-x86_64.egg',
'/home/django/ysma.grve/lib/python2.5/site-packages/django_tinymce-1.5.1a2-py2.5.egg',
'/home/django/ysma.grve/lib/python2.5/site-packages/django_treemenus-0.8.7_pre-py2.5.egg',
'/home/django/ysma.grve/lib/python2.5/site-packages/PIL-1.1.7-py2.5-linux-x86_64.egg',
'/home/django/ysma.grve/lib/python2.5/site-packages/sorl_thumbnail-11.05.2-py2.5.egg',
'/home/django/ysma.grve/lib/python2.5/site-packages/python_memcached-1.47-py2.5.egg',
'/home/django/ysma.grve/lib/python2.5/site-packages/django_haystack-1.2.4-py2.5.egg',
'/home/django/ysma.grve/lib/python2.5/site-packages/django_modeltranslation-0.3.2-py2.5.egg',
'/home/django/ysma.grve/lib/python2.5/site-packages',
'/usr/lib/python2.5',
'/usr/lib/python2.5/plat-linux2',
'/usr/lib/python2.5/lib-tk',
'/usr/lib/python2.5/lib-dynload',
'/usr/local/lib/python2.5/site-packages',
'/usr/lib/python2.5/site-packages',
'/var/lib/python-support/python2.5',
'/home/django/ysma.grve/bin']

Server time: Tue, 9 Aug 2011 13:12:42 +0300
Template error

In template /var/www/vhosts/orbitlab.gr/subdomains/ysma/httpdocs/ysmaWebsite/templates/treemenus/menu.html, error at line 2
Caught AttributeError while rendering: 'NoneType' object has no attribute 'objects'
1 {% load tree_menu_tags %}
2 {% for menu_item in menu.root_item.children %}
3 {% show_menu_item menu_item %}
4 {% endfor %}
5

'MenuAdmin' object has no attribute '__name__'

I get the following error on Django 1.7.6 (python 3) after installing with pip.

Environment:


Request Method: GET
Request URL: http://localhost:8000/admin/treemenus/menu/add/

Django Version: 1.7.6
Python Version: 3.4.1
Installed Applications:
('suit',
 'adminsortable',
 'modeltranslation',
 'django.contrib.admin',
 'django.contrib.auth',
 'django.contrib.contenttypes',
 'django.contrib.sessions',
 'django.contrib.messages',
 'django.contrib.staticfiles',
 'django.contrib.sitemaps',
 'promo',
 'taggit',
 'rosetta',
 'embed_video',
 'treemenus',
 'relatedwidget',
 'inplaceeditform')
Installed Middleware:
('django.contrib.sessions.middleware.SessionMiddleware',
 'django.middleware.locale.LocaleMiddleware',
 'django.middleware.common.CommonMiddleware',
 'django.middleware.csrf.CsrfViewMiddleware',
 'django.contrib.auth.middleware.AuthenticationMiddleware',
 'django.contrib.auth.middleware.SessionAuthenticationMiddleware',
 'django.contrib.messages.middleware.MessageMiddleware',
 'django.middleware.clickjacking.XFrameOptionsMiddleware')


Template error:
In template /Users/nonni/Code/beta-test/venv/lib/python3.4/site-packages/suit/templates/admin/change_form.html, error at line 128
   'MenuAdmin' object has no attribute '__name__'
   118 :             </ul>


   119 :           {% endif %}{% endif %}


   120 :         {% endblock %}


   121 : 


   122 :       {% block sidebar %}{% endblock %}


   123 : 


   124 :       </div>


   125 :       <div class="inner-center-column">


   126 :         {% csrf_token %}{% block form_top %}{% endblock %}


   127 :         {% block suit_form_tabs %}


   128 :            {% if adminform.model_admin.suit_form_tabs %} 


   129 :             <ul id="suit_form_tabs" class="nav nav-tabs nav-tabs-suit" data-tab-prefix="suit-tab">


   130 :               {% for tab in adminform.model_admin.suit_form_tabs %}


   131 :                 <li><a href="#{{ tab.0 }}">{{ tab.1 }}</a></li>{% endfor %}


   132 :             </ul>


   133 :           {% endif %}


   134 :         {% endblock %}


   135 :         <div class="tab-content tab-content-main">


   136 :           {% if is_popup %}


   137 :             <input type="hidden" name="_popup" value="1"/>{% endif %}


   138 :           {% if errors %}


Traceback:
File "/Users/nonni/Code/beta-test/venv/lib/python3.4/site-packages/django/core/handlers/base.py" in get_response
  137.                 response = response.render()
File "/Users/nonni/Code/beta-test/venv/lib/python3.4/site-packages/django/template/response.py" in render
  103.             self.content = self.rendered_content
File "/Users/nonni/Code/beta-test/venv/lib/python3.4/site-packages/django/template/response.py" in rendered_content
  80.         content = template.render(context)
File "/Users/nonni/Code/beta-test/venv/lib/python3.4/site-packages/django/template/base.py" in render
  148.             return self._render(context)
File "/Users/nonni/Code/beta-test/venv/lib/python3.4/site-packages/django/template/base.py" in _render
  142.         return self.nodelist.render(context)
File "/Users/nonni/Code/beta-test/venv/lib/python3.4/site-packages/django/template/base.py" in render
  844.                 bit = self.render_node(node, context)
File "/Users/nonni/Code/beta-test/venv/lib/python3.4/site-packages/django/template/debug.py" in render_node
  80.             return node.render(context)
File "/Users/nonni/Code/beta-test/venv/lib/python3.4/site-packages/django/template/loader_tags.py" in render
  126.         return compiled_parent._render(context)
File "/Users/nonni/Code/beta-test/venv/lib/python3.4/site-packages/django/template/base.py" in _render
  142.         return self.nodelist.render(context)
File "/Users/nonni/Code/beta-test/venv/lib/python3.4/site-packages/django/template/base.py" in render
  844.                 bit = self.render_node(node, context)
File "/Users/nonni/Code/beta-test/venv/lib/python3.4/site-packages/django/template/debug.py" in render_node
  80.             return node.render(context)
File "/Users/nonni/Code/beta-test/venv/lib/python3.4/site-packages/django/template/loader_tags.py" in render
  126.         return compiled_parent._render(context)
File "/Users/nonni/Code/beta-test/venv/lib/python3.4/site-packages/django/template/base.py" in _render
  142.         return self.nodelist.render(context)
File "/Users/nonni/Code/beta-test/venv/lib/python3.4/site-packages/django/template/base.py" in render
  844.                 bit = self.render_node(node, context)
File "/Users/nonni/Code/beta-test/venv/lib/python3.4/site-packages/django/template/debug.py" in render_node
  80.             return node.render(context)
File "/Users/nonni/Code/beta-test/venv/lib/python3.4/site-packages/django/template/loader_tags.py" in render
  126.         return compiled_parent._render(context)
File "/Users/nonni/Code/beta-test/venv/lib/python3.4/site-packages/django/template/base.py" in _render
  142.         return self.nodelist.render(context)
File "/Users/nonni/Code/beta-test/venv/lib/python3.4/site-packages/django/template/base.py" in render
  844.                 bit = self.render_node(node, context)
File "/Users/nonni/Code/beta-test/venv/lib/python3.4/site-packages/django/template/debug.py" in render_node
  80.             return node.render(context)
File "/Users/nonni/Code/beta-test/venv/lib/python3.4/site-packages/django/template/loader_tags.py" in render
  65.                 result = block.nodelist.render(context)
File "/Users/nonni/Code/beta-test/venv/lib/python3.4/site-packages/django/template/base.py" in render
  844.                 bit = self.render_node(node, context)
File "/Users/nonni/Code/beta-test/venv/lib/python3.4/site-packages/django/template/debug.py" in render_node
  80.             return node.render(context)
File "/Users/nonni/Code/beta-test/venv/lib/python3.4/site-packages/django/template/loader_tags.py" in render
  65.                 result = block.nodelist.render(context)
File "/Users/nonni/Code/beta-test/venv/lib/python3.4/site-packages/django/template/base.py" in render
  844.                 bit = self.render_node(node, context)
File "/Users/nonni/Code/beta-test/venv/lib/python3.4/site-packages/django/template/debug.py" in render_node
  80.             return node.render(context)
File "/Users/nonni/Code/beta-test/venv/lib/python3.4/site-packages/django/template/loader_tags.py" in render
  65.                 result = block.nodelist.render(context)
File "/Users/nonni/Code/beta-test/venv/lib/python3.4/site-packages/django/template/base.py" in render
  844.                 bit = self.render_node(node, context)
File "/Users/nonni/Code/beta-test/venv/lib/python3.4/site-packages/django/template/debug.py" in render_node
  80.             return node.render(context)
File "/Users/nonni/Code/beta-test/venv/lib/python3.4/site-packages/django/template/loader_tags.py" in render
  65.                 result = block.nodelist.render(context)
File "/Users/nonni/Code/beta-test/venv/lib/python3.4/site-packages/django/template/base.py" in render
  844.                 bit = self.render_node(node, context)
File "/Users/nonni/Code/beta-test/venv/lib/python3.4/site-packages/django/template/debug.py" in render_node
  80.             return node.render(context)
File "/Users/nonni/Code/beta-test/venv/lib/python3.4/site-packages/django/template/defaulttags.py" in render
  305.                     match = condition.eval(context)
File "/Users/nonni/Code/beta-test/venv/lib/python3.4/site-packages/django/template/defaulttags.py" in eval
  898.         return self.value.resolve(context, ignore_failures=True)
File "/Users/nonni/Code/beta-test/venv/lib/python3.4/site-packages/django/template/base.py" in resolve
  596.                 obj = self.var.resolve(context)
File "/Users/nonni/Code/beta-test/venv/lib/python3.4/site-packages/django/template/base.py" in resolve
  734.             value = self._resolve_lookup(context)
File "/Users/nonni/Code/beta-test/venv/lib/python3.4/site-packages/django/template/base.py" in _resolve_lookup
  791.                                 getcallargs(current)
File "/Library/Frameworks/Python.framework/Versions/3.4/lib/python3.4/inspect.py" in getcallargs
  1167.     f_name = func.__name__

Exception Type: AttributeError at /admin/treemenus/menu/add/
Exception Value: 'MenuAdmin' object has no attribute '__name__'

Django 1.4 Admin URL Change

It looks like Changeset 16857 has broken the app. I get a "Reverse for 'treemenus_menuitem_changelist' with arguments '()' and keyword arguments '{}' not found." when adding a menu item.

how to test django-treemenus?

hi,

I'm using django-treemenus in a project. I've got 'treemenus', 'treemenus.tests' and 'tremenus.tests.fake_menu_extension' in my INSTALLED_APPS. when running the tests, I receive 11 errors for 11 tests, mostly because

ImportError: No module named fake_menu_extension

how do I have to configure my project to test your app correctly?

testing treemenus in a project

hi,

I'm using the github-version of treemenus in my django project and want to run the tests in context of the project. to make it short: it doesn't work. long story:

1st. not having added "treemenus.tests.fake_menu_extension", to the installed_apps I get:

Error: Database test_bb couldn't be flushed. Possible reasons:

  • The database isn't running or isn't configured correctly.
    • At least one of the expected database tables doesn't exist.
    • The SQL was invalid.
      Hint: Look at the output of 'django-admin.py sqlflush'. That's the SQL this command
      wasn't able to run.
      The full error: (1146, "Table 'test_bb.fake_menu_extension_fakemenuitemextension'
      doesn't exist")

twice. so I actually add "treemenus.tests.fake_menu_extension", to my installed apps, which leads to the 2nd situation:

2nd. I'm using custom templates using the url-tag referring to some urls of my project. the problem is, obviously you are using your own testing-urls and you are modifying the settings at runtime. so my tests don't pass but give me errors like:

TemplateSyntaxError: Caught NoReverseMatch while rendering:
Reverse for 'home' with arguments '()' and keyword arguments '{}' not found.

solution: please use the setup's test_suite option, as seen in http://github.com/alex/django-taggit/blob/master/setup.py for example.

Screenshot in manual

Hi! It would nice to see its look and feel of this tree representation. Thank you!

imports fail on django 1.9.4

Encountered following issues when installing tremens in a 1.9.4 site:
in admin.py, importing from django.contrib.admin.util fails. In 1.9.4. this package is django.contrib.admin.utils.

In addition, added AppConfig to apps.py and to init to be compliant with latests changes.

See below GIT file for suggested changes, works for me on 1.9.4. Not tested against older versions.
Cheers
Ernst

Suggested_corrections.txt

django-treemenus by request

Hi,
i'm trying to setup django-treemenus with multiple databases. Users choose database to connect when they log in. I modified tree_menu_tags.py and put using('db') in show_menu
menu = Menu.objects.using('db').get(name=menu_name) but it doesn't return menu_item

named urls doesnt work

Hello,
named urls does not seem to work.

when pointing to via 'kunden_detail', the generated href is empty...
url(r'^kunden/detail/$', 'abc.views.kunden_detail', name='kunden_detail'),

Thx

can't compare offset-naive and offset-aware datetimes

On Django 1.4 I've seen this problem. Could you give me some help?
Thanks,
Jan

Environment:

Request Method: GET
Request URL: http://localhost:8000/

Django Version: 1.4
Python Version: 2.7.3
Installed Applications:
('django.contrib.auth',
'django.contrib.contenttypes',
'django.contrib.sessions',
'django.contrib.admin',
'django.contrib.admindocs',
'django.contrib.markup',
'elevenbits.blog',
'elevenbits.static',
'elevenbits',
'treemenus',
'tracking')
Installed Middleware:
('tracking.middleware.BannedIPMiddleware',
'django.middleware.gzip.GZipMiddleware',
'django.middleware.common.CommonMiddleware',
'django.contrib.sessions.middleware.SessionMiddleware',
'django.contrib.auth.middleware.AuthenticationMiddleware',
'tracking.middleware.VisitorTrackingMiddleware')

Traceback:
File "/usr/local/lib/python2.7/dist-packages/django/core/handlers/base.py" in get_response

  1.                 response = middleware_method(request)
    
    File "/usr/local/lib/python2.7/dist-packages/tracking/middleware.py" in process_request
  2.     if not visitor.last_update or visitor.last_update <= one_hour_ago:
    

Exception Type: TypeError at /
Exception Value: can't compare offset-naive and offset-aware datetimes

Compatibility with django-grappelli

In admin, arrow-down and arrow-up images do not appear.

$ grep -R "arrow-down" eggs/django_grappelli-2.3.3-py2.7.egg/
eggs/django_grappelli-2.3.3-py2.7.egg/EGG-INFO/SOURCES.txt:grappelli/static/grappelli/img/icons/icon-tools-arrow-down-handler-hover.png
eggs/django_grappelli-2.3.3-py2.7.egg/EGG-INFO/SOURCES.txt:grappelli/static/grappelli/img/icons/icon-tools-arrow-down-handler.png
eggs/django_grappelli-2.3.3-py2.7.egg/grappelli/static/grappelli/css/tools.css:.tools a.arrow-down-handler:link, .tools a.arrow-down-handler:visited {
eggs/django_grappelli-2.3.3-py2.7.egg/grappelli/static/grappelli/css/tools.css: background-image: url('../img/icons/icon-tools-arrow-down-handler.png');
eggs/django_grappelli-2.3.3-py2.7.egg/grappelli/static/grappelli/css/tools.css:.tools a.arrow-down-handler:hover, .tools a.arrow-down-handler:active {
eggs/django_grappelli-2.3.3-py2.7.egg/grappelli/static/grappelli/css/tools.css: background-image: url('../img/icons/icon-tools-arrow-down-handler-hover.png');

$ grep -R "arrow-down" eggs/django_treemenus-0.8.7_pre-py2.7.egg/
eggs/django_treemenus-0.8.7_pre-py2.7.egg/treemenus/templates/admin/treemenus/menu/change_form.html: {% trans 'Down' %}

Default model additions for expanding menus

Hi,

I was trying to get treemenus to create an expanding menu effect, where the children of the current page get expanded, but not other sections. (e.g. http://ukwindsurfing.com/information/regions/). NB: I'm not a programmer as such, so I may have missed a point or two.

I've got it working, as it's a similar problem to highlighting the current page. However, it's much easier with a couple of additions to the menu item model:

def this_section(self):
    url_part = self.url
    list_of_sections = url_part.split("/")
    section = list_of_sections[-2]
    return section

def matching_url(self):
    return "^" + self.url + "$"

Combined with the code from 'Automatically select menu items' section you can use this in the templates:

{% load tree_menu_tags %}
{% if menu_item.has_children %}
<li>{% if menu_item.matching_url|match_path:request.path %}<strong class="nolink">{{ menu_item.caption }}</strong>{% else %}
    <a href="{{ menu_item.url }}">{{ menu_item.caption }}</a>{% endif %}
    {% if menu_item.this_section in request.path %}
    <ul>
        {% for child in menu_item.children %}
            {% show_menu_item child %}
        {% endfor %}
    </ul>{% endif %}
</li>{% else %}
<li>{% if menu_item.matching_url|match_path:request.path %}<strong class="nolink">{{ menu_item.caption }}</strong>{% else %}
<a href="{{ menu_item.url }}">{{ menu_item.caption }} </a>{% endif %}</li>{% endif %}

I know you've outlined extension methods, but as someone with limited programming experience,
it seems a lot simpler to make a couple of additions to the model (and the match_path addition to the template tags).

Could those be included by default?

I've created a patch if that helps, which is my first foray into Git.

Treemenus are not appearing

I had the same issue in #13

I downloaded the latest update today with the fixes (jphalip-django-treemenus-4ed8ad9)

I added the template files as per the packaged documentation (I had some errors due to the online documentation's inaccurate/out of date instructions for coding of the menu template files.)

The site displays without errors (its on a development local machine) but I don't see the tree menus.

If I change the menu name in my template file, I get an error (error: Menu matching query does not exist) and when I enter the correct menu name, the site displays without errors but there is no menu displayed and there is no html mark up for the menus (when the page is viewed through firebug.)

(I only started using Django a couple of days back so I'm afraid I can't look deeper/diagnose the issue deeper.)

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    ๐Ÿ–– Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. ๐Ÿ“Š๐Ÿ“ˆ๐ŸŽ‰

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google โค๏ธ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.