Stone
Stone

Reputation: 749

Extending the page With menus

I create a new field for page extending the page, I follow the documentation for that.

So now each page have a image. In my case I show the submenu in my template using this

{% show_menu 2 100 100 100 "partials/menu_image.html" %}

so in my menu_image.html I show my menu like this

<ul>
  {% for child in children %}
    <li>
      <div class="project_item">
        <a href="{{ child.get_absolute_url }}">
        {% if request.current_page %}
          <img src="{% static request.current_page.iconextension.image.url %}">
        {% endif %}
        <div class="title_project">{{ child.get_menu_title }}</div>
        <div class="description_project"> 
          {{ request.current_page.PageDescriptionExtension.description_page }}
        </div>
        </a>
      </div>

    </li>
  {% endfor %}
</ul>

My problem here is that I want to show the image of each page here in the menu, for that I have to create a cms_menus.py so I have this

from menus.base import Modifier
from menus.menu_pool import menu_pool
from cms.models import Page

class MyMode(Modifier):
    """
    """
    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
        # otherwise loop over the nodes
        for node in nodes:
            # does this node represent a Page?
            if node.attr["is_page"]:
                # if so, put its changed_by attribute on the node

                node.attr["changed_by"] = Page.objects.get(id=node.id).changed_by
        return nodes

menu_pool.register_modifier(MyMode)

in this point I have a little confused, because I don't know how communicate this with my menu to show the image here and the documentation in this point is no clear

where I have to use extension = page.iconextension and child.extension.icon any idea or example to see

Thanks in advance!

Upvotes: 0

Views: 435

Answers (1)

petr
petr

Reputation: 2586

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.

Upvotes: 1

Related Questions