[Fixed]-Extending the page With menus

1👍

I’ve faced the same problem – you want to fetch the page’s extension object in the menu modifier, see my example below:

from menus.base import Modifier
from menus.menu_pool import menu_pool
from raven.contrib.django.raven_compat.models import client

from cms.models import Page

class MenuModifier(Modifier):
    """
    Injects page object into menus to be able to access page icons
    """
    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

        for node in nodes:

            try: 
                if "is_page" in node.attr and node.attr["is_page"]:

                    class LazyPage(object):
                        id = node.id
                        page = None
                        def pagemenuiconextension(self):
                            try:
                                if not self.page:
                                    self.page = Page.objects.get(id=self.id)
                                return self.page.pagemenuiconextension
                            except AttributeError, ae:
                                # print ae
                                return False
                            except Exception, e:
                                print e
                                client.captureException()

                    node.pageobj = LazyPage()

                else:
                    pass
            except Exception, e:
                client.captureException()

        return nodes

menu_pool.register_modifier(MenuModifier)

I am using lazy loading to ensure I do not load the page (and potentially hit DB) unless the template requests it.

In the menu template html, I then have the following:

<div class="{{ child.pageobj.pagemenuiconextension.menu_navicon }}" style="height: 16px;">{{ child.get_menu_title }}</div>

You can see I am using a simple string representing class of the menu item but you can use any field.

👤petr

Leave a comment