Simple Menu for Django Flatpages

Generate a menu dynamically from your Django flatpages using templatetags. Using Django as a simple CMS.

Create a folder called 'templatetags' in your app folder (I use an app called utils) and inside it create a file called flatpage_menu.py, put the follwing code inside:

from django.template import Library, Node
from django.contrib.flatpages.models import FlatPage
register = Library()

def flatpage_menu():
    # Create an unordered list of all flatpages
    pages = FlatPage.objects.all()
    menu = '<ul>'
    for i in range(len(pages)):
        menu += '<li>'+'<a href="'+pages[i].url+'" title="'+pages[i].title+'">'+pages[i].title+'</a></li>'
    menu += '</ul>'
    return menu 

register.simple_tag(flatpage_menu)

now add this to the top of your template to register the template tag:

{% load flatpage_menu %}

and finally where you want the menu to appear in your template place this:

{% flatpage_menu %}

You should now have a nice menu of all your flatpages.

Files

Simple Menu for Django Flatpages

Posted on July 29, 2007
Tags: Django, Python

Comments

1

giorgi commented, on August 21, 2007 at 7:24 p.m.:

nice hint - thanks ;)

2

areczek commented, on January 22, 2008 at 5:36 p.m.:

for page in pages:
menu += ...
would be simpler ;)

3

Oliver Leitner commented, on October 1, 2008 at 7:34 p.m.:

'flatpage_menu' is not a valid tag library: Could not load template library from django.templatetags.flatpage_menu, No module named flatpage_menu

even with an __init__.py in the dir

4

Muslu commented, on January 5, 2009 at 2:07 p.m.:

@Oliver

hi;
i am new programmer for django and i am preparing to CMS.
i found this site but i understand now and its works now
i think you didnt create application.
first of all:
create one app
python manage.py startapp flat
cd flat
mkdir templatetags
create flatpage_menu.py and save
later go to templates dir.
and edit default.html
add this codes
{% load flatpage_menu %}
{% flatpage_menu %}

its ok
(;

5

dfolland commented, on September 24, 2009 at 11:10 p.m.:

It might be better to create the templatetag that returns a dictionary. This would be rendered in an html page. You could also add a sort flag to it as well.

@register.inclusion_tag('_flatpage_menu.html')
def flatpage_menu(sorted=False):
"""
Create a dictionary that can be sorted, and the html page determines the layout.
"""
if sorted:
fp_menu = FlatPage.objects.all().order_by('title')
else:
fp_menu = FlatPage.objects.all()
return {'fp_menu': fp_menu,}

Here is an example of the html page:

{# File: _flatpage_menu.html #}
<ul>
{% for fp in fp_menu %}
<li><a href="{{fp.url}}" title="{{fp.title}}">{{fp.title}}</a></li>
{% endfor %}
</ul>

6

Adam commented, on September 25, 2009 at 10:36 a.m.:

That's a great idea.

7

Andrey Shipilov commented, on May 12, 2010 at 10:06 p.m.:

It might be better to mark selected menu items as not links but just text. It is. Common way of rendering them all as a list of links on every page is rediculously stupid.

8

issy commented, on October 19, 2010 at 9:03 p.m.:

Thanks for the tip, though to any new programmers in django... you dont want to follow the tip in this post. Rather use the inclusion tag, generating HTML code from python is NEVER what you want to do. The template system exists for a reason, use it. Use an inclusion tag as above or a normal template tag and return the list of pages as a context variable.

9

manarius commented, on January 14, 2012 at 8:31 p.m.:

@dfolland: thanks a lot, works like a charm :)
actually you provided exactly the solution i was looking for but didnt know how to :)

have fun, thanks again
manarius

Post a comment

Your name:

Comment: