"in menu" flags for pages - refactor

227 views
Skip to first unread message

Stephen McDonald

unread,
Jun 23, 2012, 2:59:22 AM6/23/12
to mezzani...@googlegroups.com
Just wanted to bring the conversation for this issue onto the mailing list:


Currently pages have two flags for appearing in menus, "in navigation" and "in footer". This doesn't really make sense, as there maybe more than two types of menus on a site, and not necessarily a "footer" menu. The above issue talks about adding a new flag for the left-hand menu, but again the menus in use are going to be different for each site, and the flags should reflect this.

I think the ideal setup would be one where we replaced the "in nav/footer" flags with a multi-select field, that allowed users to choose multiple selections from a list of menus, that the page is to appear in. The choices in that field would map directly to each menu implemented on the site, and then the checks could occur inside the actual page_menu template tag as to whether the pages being passed to the menu template should be available.

The only thing I'm unsure about is how to populate the field with each type of menu available for selection. I'd love for it to not require any configuration or data. The menu templates are already conveniently bound to a single template directory (pages/menus) so we could simply provide a list of all the templates found in there for selection. The only problem with this is that there'd be more templates in the selection field than those that are actually in use. You might only implement a primary and a footer menu, but there'd be at least half a dozen to choose from.

So I guess there could be a new setting that contained the names of the menu templates actually in use. Then the new field would be populated by it.

Any thoughts on this change? Any gotchas? Any idea how to make it not require configuration?


--
Stephen McDonald
http://jupo.org

POKOLI I PUNTO

unread,
Jun 23, 2012, 3:32:01 PM6/23/12
to mezzani...@googlegroups.com
We can add a table called menu to hold all the menu types (left, right, footer,whatever you want) and the template to render it. With this aproach two menus can use the the same template, and you can create all the templates you want.

this table would be popullated by default with the main menu an the footer menu.

What do you think?

Stephen McDonald <st...@jupo.org> escribió:

Brian Schott

unread,
Jun 23, 2012, 10:04:27 PM6/23/12
to mezzani...@googlegroups.com
So, if we convert the current menu flags to be a many-to-many foreign key multi-select to a menu model, the menu model would have:

- name
- template
- many-to-many list of pages so you can edit the page membership from the menu side rather than editing every single page.
- menu options:
-- drop down level?
-- group/roles required for menu to appear?
-- what to do if the user doesn't have privilege to see the page?  for example, do you show a login_required page to an anonymous user?  This behavior might have a default for that menu, but be overridden in the page-menu relation table (django calls them intermediary models).

Instead of an include, the menu would be a template tag?  Filter tag so we can add options?  This does open up some architectural choices in mezzanine.  It would be great if there were a standard mezzanine way to deal with content plugins inside a page and one of the plugin types could be menus.  Django-cms has the concept of placeholders in a page and everything else is a plugin (text fields, forms, menus, etc.).  It seems that others are building this sub-page block functionality. 


Brian

-------------------------------------------------
Brian Schott, CTO
Nimbis Services, Inc.


Stephen McDonald

unread,
Jun 28, 2012, 5:17:04 PM6/28/12
to mezzani...@googlegroups.com
Sorry about the delay in replying on this - I was hoping to answer it with code but I just haven't found the time. 

Firstly to answer the larger question of Mezzanine's architecture, as I think that will add some perspective to the smaller question of menus. 

So there's definitely two clear classes of design here. There's Mezzanine's content types, which are Page model subclasses, with template types mapping directly to each content type. Then there's the larger class if design - one where pages are all of the same type, and built up by blocks fo content individually represented by different records in databases, and selectable templates per page. The corporate CMS project I work on during my day job is of this latter type, and as I vaguely understand, is how Django CMS works as well.

I don't think there's any question that the latter type is more advanced and powerful. However I think the former design that Mezzanine implements has a definite attractive simplicity to it. The relationships between Page subclasses and templates are very easy to understand and think about, easy to implement, and easy to extend. I think this design appeals to a particular class of developers, and has worked well for Mezzanine for the last couple of years.

I'm not arguing one class of design is better than the other. Both have their pros and cons. I guess the point I'm trying to make is that Mezzanine's elaning towards one end of this scale is a defining characteristic of it, and that changing it would change a key aspect of it that I think appeals to the developers that have adopted it.

The great thing is that for those wishing to create a more dynamic architecture such as the latter of the two, separate tools like those you listed have sprung up around Mezzanine, so the option is there. This is a really good thing and I hope those projects developer further - but ultimately I think Mezzanine's current architecture is a defining quality of it, and for that reason will probably stay for the future.

So with all that in mind, as for the menus I think it would be best kept simple to start with - a setting that defines the menu templates available, and then each page can select from one or more of these as to whether it should be included in that menu. The page_menu template tag can then compare itself to this and choose whether the page should be included in the menu, with this replacing the in_nav/in_fotter flags we currently have.

That's my take on the whole subject.

Brian Schott

unread,
Jun 28, 2012, 10:12:03 PM6/28/12
to mezzani...@googlegroups.com
It's good to understand the high-level design paradigm and I appreciate the thought that has gone into it.  It makes sense.  So, the menu membership would be a MultipleChoiceField configured through a setting?  No need then, for a many-to-many relationship to another table.  The menu templates would define any special behavior like drop-down level or group-based visibility and users could build their own.  Would it be possible to have an admin view that is menu-centric, meaning not having to go edit every page to assign them to a new menu.  Could be an action on pages view.

-------------------------------------------------
Brian Schott, CTO
Nimbis Services, Inc.



Stephen McDonald

unread,
Jun 28, 2012, 10:13:39 PM6/28/12
to mezzani...@googlegroups.com
On Fri, Jun 29, 2012 at 12:12 PM, Brian Schott <brian....@nimbisservices.com> wrote:
It's good to understand the high-level design paradigm and I appreciate the thought that has gone into it.  It makes sense.  So, the menu membership would be a MultipleChoiceField configured through a setting?  No need then, for a many-to-many relationship to another table.  The menu templates would define any special behavior like drop-down level or group-based visibility and users could build their own.  

That's the plan - I started working on it this morning, might have something to show tomorrow.
 
Would it be possible to have an admin view that is menu-centric, meaning not having to go edit every page to assign them to a new menu.  Could be an action on pages view.

Hadn't thought of that but I think it's a great idea.

Stephen McDonald

unread,
Jul 1, 2012, 4:45:12 PM7/1/12
to mezzani...@googlegroups.com
I've pushed up a first version of the new "in_menus" field for pages:


Here's the gist of it:

The "in_navigation" and "in_footer" fields are gone and replace with a new field "in_menus", which contains a comma-separated list of menu IDs that the page belongs to. The menu IDs are defined in the setting PAGE_MENU_TEMPLATES which looks like this:

    PAGE_MENU_TEMPLATES = (
        (1, "Top nav", "pages/menus/dropdown.html"),
        (2, "Left tree nav", "pages/menus/tree.html"),
        (3, "Footer", "pages/menus/footer.html"),
    )

So you can define the exact menu templates available in your project.

In the menu templates, page objects now have an attribute "in_menu", to use in place of the removed fields, and the variables "page_branch_in_footer" and "page_branch_in_navigation" are replaced with "page_branch_in_menu" (the old attributes and variables remain for now as best as possible, for backward compatibility with templates, take a look at the above commit to see their behaviour).

A couple of notes around the behaviour of this inside the "page_menu" template tag, which I'm going to add with some new docs for the way menus work:

- Just as the old flags behaved, the new "in_menus" field doesn't actually filter pages from a menu - it's up to the menu template to check "page.in_menu" itself.
- If a menu template isn't defined in PAGE_MENU_TEMPLATES, "page.in_menu" will always be True. Think of the "in_menus" field as controlling what menus the  page *won't* be in, by unchecking them.
- The default selection for the "in_menus" field with a new page is all menu templates, you can change the default selection by setting a sequence of menu IDs in the new PAGE_MENU_TEMPLATES_DEFAULT setting.

Stephen McDonald

unread,
Jul 1, 2012, 4:50:14 PM7/1/12
to mezzani...@googlegroups.com
On Mon, Jul 2, 2012 at 6:45 AM, Stephen McDonald <st...@jupo.org> wrote:
I've pushed up a first version of the new "in_menus" field for pages:


Here's the gist of it:

The "in_navigation" and "in_footer" fields are gone and replace with a new field "in_menus", which contains a comma-separated list of menu IDs that the page belongs to. The menu IDs are defined in the setting PAGE_MENU_TEMPLATES which looks like this:

    PAGE_MENU_TEMPLATES = (
        (1, "Top nav", "pages/menus/dropdown.html"),
        (2, "Left tree nav", "pages/menus/tree.html"),
        (3, "Footer", "pages/menus/footer.html"),
    )

So you can define the exact menu templates available in your project.

In the menu templates, page objects now have an attribute "in_menu", to use in place of the removed fields, and the variables "page_branch_in_footer" and "page_branch_in_navigation" are replaced with "page_branch_in_menu" (the old attributes and variables remain for now as best as possible, for backward compatibility with templates, take a look at the above commit to see their behaviour).

Linked commit in last email was missing a file, namely the changes to the page_menu template tag, which contains the backward compatibility I mentioned. Here it is:

 

A couple of notes around the behaviour of this inside the "page_menu" template tag, which I'm going to add with some new docs for the way menus work:

- Just as the old flags behaved, the new "in_menus" field doesn't actually filter pages from a menu - it's up to the menu template to check "page.in_menu" itself.
- If a menu template isn't defined in PAGE_MENU_TEMPLATES, "page.in_menu" will always be True. Think of the "in_menus" field as controlling what menus the  page *won't* be in, by unchecking them.
- The default selection for the "in_menus" field with a new page is all menu templates, you can change the default selection by setting a sequence of menu IDs in the new PAGE_MENU_TEMPLATES_DEFAULT setting.




On Sat, Jun 23, 2012 at 4:59 PM, Stephen McDonald <st...@jupo.org> wrote:
Just wanted to bring the conversation for this issue onto the mailing list:


Currently pages have two flags for appearing in menus, "in navigation" and "in footer". This doesn't really make sense, as there maybe more than two types of menus on a site, and not necessarily a "footer" menu. The above issue talks about adding a new flag for the left-hand menu, but again the menus in use are going to be different for each site, and the flags should reflect this.

I think the ideal setup would be one where we replaced the "in nav/footer" flags with a multi-select field, that allowed users to choose multiple selections from a list of menus, that the page is to appear in. The choices in that field would map directly to each menu implemented on the site, and then the checks could occur inside the actual page_menu template tag as to whether the pages being passed to the menu template should be available.

The only thing I'm unsure about is how to populate the field with each type of menu available for selection. I'd love for it to not require any configuration or data. The menu templates are already conveniently bound to a single template directory (pages/menus) so we could simply provide a list of all the templates found in there for selection. The only problem with this is that there'd be more templates in the selection field than those that are actually in use. You might only implement a primary and a footer menu, but there'd be at least half a dozen to choose from.

So I guess there could be a new setting that contained the names of the menu templates actually in use. Then the new field would be populated by it.

Any thoughts on this change? Any gotchas? Any idea how to make it not require configuration?


--
Stephen McDonald
http://jupo.org



--
Stephen McDonald
http://jupo.org

Brian Schott

unread,
Jul 1, 2012, 10:42:18 PM7/1/12
to mezzani...@googlegroups.com
Great!  I'll take this for a spin early this week.

Brian

-------------------------------------------------
Brian Schott, CTO
Nimbis Services, Inc.



Stephen McDonald

unread,
Jul 2, 2012, 5:04:45 AM7/2/12
to mezzani...@googlegroups.com
On Mon, Jul 2, 2012 at 6:45 AM, Stephen McDonald <st...@jupo.org> wrote:
I've pushed up a first version of the new "in_menus" field for pages:


Here's the gist of it:

The "in_navigation" and "in_footer" fields are gone and replace with a new field "in_menus", which contains a comma-separated list of menu IDs that the page belongs to. The menu IDs are defined in the setting PAGE_MENU_TEMPLATES which looks like this:

    PAGE_MENU_TEMPLATES = (
        (1, "Top nav", "pages/menus/dropdown.html"),
        (2, "Left tree nav", "pages/menus/tree.html"),
        (3, "Footer", "pages/menus/footer.html"),
    )

So you can define the exact menu templates available in your project.

In the menu templates, page objects now have an attribute "in_menu", to use in place of the removed fields, and the variables "page_branch_in_footer" and "page_branch_in_navigation" are replaced with "page_branch_in_menu" (the old attributes and variables remain for now as best as possible, for backward compatibility with templates, take a look at the above commit to see their behaviour).

A couple of notes around the behaviour of this inside the "page_menu" template tag, which I'm going to add with some new docs for the way menus work:

 

- Just as the old flags behaved, the new "in_menus" field doesn't actually filter pages from a menu - it's up to the menu template to check "page.in_menu" itself.
- If a menu template isn't defined in PAGE_MENU_TEMPLATES, "page.in_menu" will always be True. Think of the "in_menus" field as controlling what menus the  page *won't* be in, by unchecking them.
- The default selection for the "in_menus" field with a new page is all menu templates, you can change the default selection by setting a sequence of menu IDs in the new PAGE_MENU_TEMPLATES_DEFAULT setting.




On Sat, Jun 23, 2012 at 4:59 PM, Stephen McDonald <st...@jupo.org> wrote:
Just wanted to bring the conversation for this issue onto the mailing list:


Currently pages have two flags for appearing in menus, "in navigation" and "in footer". This doesn't really make sense, as there maybe more than two types of menus on a site, and not necessarily a "footer" menu. The above issue talks about adding a new flag for the left-hand menu, but again the menus in use are going to be different for each site, and the flags should reflect this.

I think the ideal setup would be one where we replaced the "in nav/footer" flags with a multi-select field, that allowed users to choose multiple selections from a list of menus, that the page is to appear in. The choices in that field would map directly to each menu implemented on the site, and then the checks could occur inside the actual page_menu template tag as to whether the pages being passed to the menu template should be available.

The only thing I'm unsure about is how to populate the field with each type of menu available for selection. I'd love for it to not require any configuration or data. The menu templates are already conveniently bound to a single template directory (pages/menus) so we could simply provide a list of all the templates found in there for selection. The only problem with this is that there'd be more templates in the selection field than those that are actually in use. You might only implement a primary and a footer menu, but there'd be at least half a dozen to choose from.

So I guess there could be a new setting that contained the names of the menu templates actually in use. Then the new field would be populated by it.

Any thoughts on this change? Any gotchas? Any idea how to make it not require configuration?


--
Stephen McDonald
http://jupo.org



--
Stephen McDonald
http://jupo.org

michela

unread,
Jul 10, 2012, 9:48:29 AM7/10/12
to mezzani...@googlegroups.com

Just checking the refactoring out. What should your homepage page slug be recorded as?

I've got URL as "/" but if I include this page in a menu the generated url is "///"

Any thoughts? Not sure this is a new issue but that's the only issue I've hitting on my test site.

Michela

Brian Schott

unread,
Jul 10, 2012, 9:59:52 AM7/10/12
to mezzani...@googlegroups.com
The default pages/menus/ templates add home as a static page, are you seeing two copies of "Home"?

    {% if page.is_primary and forloop.first %}
    <li class="{% if on_home %} active{% endif %}" id="dropdown-menu-{{ page.html_id }}">
        <a href="{% url home %}">{% trans "Home" %}</a>
    </li>
    <li class="divider-vertical"></li>
    {% endif %}

Stephen McDonald

unread,
Jul 14, 2012, 1:16:27 AM7/14/12
to mezzani...@googlegroups.com
Hey Michela,

Just traced this down to a recent change where a new "Link" page type was added. What it meant is that we needed to change the way urls for page objects were used in templates. Here's the whole commit, including the changes to the menu templates that need to happen:


Short story: page URLs in menu templates need to change from using:

{% url page page.slug %}

to using:

{{ page.get_absolute_url }}
Reply all
Reply to author
Forward
0 new messages