djangodjango-cmsdjangocms-text-ckeditor

Django CMS icon in menu


I am trying to show my uploaded icon on navigation but i guess, i am going through a wrong way.

this is my model that extended

class IconExtension(PageExtension):
    image = models.ImageField(upload_to='icons')


extension_pool.register(IconExtension)

and this is my cms_toolbars.py file

@toolbar_pool.register
class IconExtensionToolbar(ExtensionToolbar):
    # defines the model for the current toolbar
    model = IconExtension

    def populate(self):
        # setup the extension toolbar with permissions and sanity checks
        current_page_menu = self._setup_extension_toolbar()

        # if it's all ok
        if current_page_menu:
            # retrieves the instance of the current extension (if any) and the toolbar item URL
            page_extension, url = self.get_page_extension_admin()
            if url:
                # adds a toolbar item in position 0 (at the top of the menu)
                current_page_menu.add_modal_item(_('Page Icon'), url=url,
                    disabled=not self.toolbar.edit_mode_active, position=0)

and this is my menu.html file

{% load menu_tags %}

{% for child in children %}
<li class="child{% if child.selected %} selected{% endif %}{% if child.ancestor %} ancestor{% endif %}{% if child.sibling %} sibling{% endif %}{% if child.descendant %} descendant{% endif %}">
    <a href="{{ child.attr.redirect_url|default:child.get_absolute_url }}">{{ child.get_menu_title }}
    <img src="{{ child.image.url }}">
  </a>
    {% if child.children %}
    <ul>
        {% show_menu from_level to_level extra_inactive extra_active template "" "" child %}
    </ul>
    {% endif %}
</li>
{% endfor %}

I am not getting why it is not working, I don't see any error even I don't see any image url here, my everything is working fine, only going through problem showing menu icon, can anyone help me in this case?


Solution

  • It looks like you're just missing the reference to the object from the page, you're going straight to it's attribute.

    I've got a very similar setup with images associated with pages;

    class PageImage(PageExtension):
        """ Add images to pages """
        image = models.FileField(
            verbose_name=_("Image"),
            upload_to=upload_to('page_images')
        )
    

    Which in my templates becomes;

    {% if request.current_page.pageimage.image %}
        {{ request.current_page.pageimage.image.url }}
    {% endif %}
    

    So in your example, if you did this in a template you'd do;

    {% if request.current_page.iconextension %}
        <img src="{{ request.current_page.iconextension.image.url }}">
    {% endif %}
    

    Checking if the extension exists is important to avoid attribute errors etc.

    In a menu, the child isn't a Page object though, it's a NavigationNode from the menu system. So it doesn't have your extension.

    I think the proper solution to this is to setup a navigation Modifier. The docs for this are here; http://docs.django-cms.org/en/latest/how_to/menus.html#navigation-modifiers

    Alternatively you could setup a template tag which you pass your child which could then use the reverse_id attribute to query the database for the Page that corresponds to, and return the iconextension of that page. I've used this method before.