Skip to main content

This site requires you to update your browser. Your browsing experience maybe affected by not having the most up to date version.

We're retiring the forums!

The SilverStripe forums have passed their heyday. They'll stick around, but will be read only. We'd encourage you to get involved in the community via the following channels instead:

Template Questions /

Moderators: martimiz, Sean, Ed, biapar, Willr, Ingo, swaiba

Multiple menus. How best?

Go to End

7 Posts   3991 Views


Community Member, 102 Posts

29 May 2010 at 5:15am

It's common to have more than one menu in a website. e.g. main menu and footer menu. What's the best way to achieve this?

The most elegant solution would be for the CMS have 2 'Site Content' icons for the 2 menus. But I can't see how to do that.

There could be two top-level virtual pages called Main and Footer with the respective menus underneath. In the template, the main menu fetches the children of Main and the Footer fetches the children of Footer. This has the disadvantage that in the CMS I have to click the + next to Main every time I edit the site (Footer contains Ts & Cs etc and is rarely edited)

Alternatively, the main menu could be done as normal, but have a virtual page called Footer which has 'Show in menus' unchecked. In the template, the main menu is done as usual and the footer fetches the children of Footer. This is less 'pure' because the footer is NOT actually a child of the main menu. But it has the advantage that the main menu (which is most frequently edited) is shown opened up when you log into the CMS.

Am I missing something? How do people normally solve this?



Community Member, 57 Posts

29 May 2010 at 12:01pm


We solve this by adding a checkbox in the Behaviour tab next to 'Show in menus' which is 'Show in footer menu'. For the footer we then loop through the results of a query which matched ShowInFooter = 1.

Does this help? And seem elegant? Always looking for improvements!


Community Member, 102 Posts

29 May 2010 at 7:58pm

Edited: 29/05/2010 7:59pm

Thanks Joshy, that does help because it's another nice, simple solution.

The only problem is, when looking at the site tree in the CMS, you can't tell which pages are on which menu, because they are mixed together. Of course, you could put main menu items first, followed by footer menu items. But the person manging the site needs to know something about the implementation that should be hidden from them.

I don't think it's 100% 'pure' because the purpose of the tree is to represent site structure, and this method subverts that, and uses a property of the page. You've put the 'Footer menu' checkbox next to 'Show in menus' which makes perfect sense on the face of it because they are both about menus. But 'Show in menus' controls the behaviour of that page only, while 'Footer Menu' controls the structure of the site, which should be the responsibility of the Tree in the CMS and the Parent property in the database.

Having said that, the guy I'm working with prefers your method :)


Community Member, 81 Posts

9 June 2010 at 9:47pm

You can create hidden page with name "Footer Menu" and display subpages on other pages by using <% control ChildrenOf(page-url) %>


Community Member, 102 Posts

10 June 2010 at 4:11am

Thanks Tonyair - that's beautifully simple - no extra functions or code in the php class, no bending the rules, 100% pure :)

The only problem I've had with hard-coding URLs in templates is when my client brought in an SEO guy who renamed all the pages to include keywords, so breaking the hard-coded links, and they couldn't work out why parts of the site 'just stopped working'. Guess it's hard to make a CMS completely foolproof.


Community Member, 81 Posts

10 June 2010 at 9:09am

PageByLang is function for multilingual pages I just fixed error here if there're no such page.

This is function to display changed url by translation, but I think it will be easy to remake it to get page url by another field in table and u can add this is field to ur pages by adding getCMSFields function to ur Page_Controller:
function getCMSFields() {
$fields = parent::getCMSFields();
$fields->addFieldToTab('Root.Content.Main', new TextField('Page_ID'), 'Content');

public function PageByLang($url, $lang) {
$SQL_url = Convert::raw2sql($url);
$SQL_lang = Convert::raw2sql($lang);

$page = Translatable::get_one_by_lang('SiteTree', $SQL_lang, "URLSegment = '$SQL_url'");
// Fallback to Russian
if(is_object($page)) { //FIX
if ($page->Locale != Translatable::get_current_locale()) {
$page = $page->getTranslation(Translatable::get_current_locale());
$page = $page->getTranslation('ru_RU');
return $page;


Community Member, 102 Posts

17 June 2010 at 6:16am

Thanks for your code Tonyair.

Yes, it's a more robust solution to attach to something more permanent that the URL - such as the page id.

It would be nice to be able to set permissions to 'lock' a URL (e.g. if it's hard-coded or linked from another site) so it can only be changed by an administrator.