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've moved the forum!

Please use forum.silverstripe.org for any new questions (announcement).
The forum archive will stick around, but will be read only.

You can also use our Slack channel or StackOverflow to ask for help.
Check out our community overview for more options to contribute.

General Questions /

General questions about getting started with SilverStripe that don't fit in any of the categories above.

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

Fun with menus


Go to End


14 Posts   2525 Views

Avatar
Junglefish

Community Member, 109 Posts

10 September 2009 at 2:17am

Okay, imagine a basic SS site layout, two-level menu down the left, some content in the middle, and a side bar on the right.

What I'd like to do for one of the first-level menu items is prevent it appearing in the menu structure on the left, and instead build it into the side bar on the right.

My first thought was a simple hack inside <% control Menu(1) %>, something like:

<% if $MenuTitle.XML != 'My Headline' %>
show the item
<% end_if %>

and then in the side bar on the right doing the exact opposite, so that ONLY the node I want, plus its children appear.

But this causes a parsing error - I'm probably breaking a whole load of SS syntax rules that I know nothing of.

So, can anybody suggest the *correct* way of doing this? Either doing it the *proper* SS way, or by cleaning up my hack?

jf\

Avatar
dhensby

Community Member, 253 Posts

10 September 2009 at 1:33pm

The 'SS' way of doing it would be to add a field to Page.php that was 'ShowOnlyInSideMenu' (or whatever) that could then be a check box in the cms. if it is checked then you can do a simple if statment in the template!

If you don't want it showing in the CMS, just dont add the checkbox to it!

Avatar
Bruce B

Community Member, 164 Posts

10 September 2009 at 2:10pm

I generally don't want my home page included on the side menu because I handle it differently to other pages. I just uncheck 'show in menu' in the CMS. The right menu would then call a specific page control. You could have extra checkboxes in the CMS but if the intention is to hand the site over to a client, that sounds too much like a problem waiting to happen - better to hard code it.

Avatar
Junglefish

Community Member, 109 Posts

10 September 2009 at 9:06pm

@Pigeon Thanks for the suggestion. Can I get a bit more detail?

I set up a new field in Page.php, let's call it "MoveItemFromLeftMenuToRightMenu". It might be a checkbox exposed in the CMS or I might keep it hidden away from the client.

Once that's done, how do I test for it inside the <% control Menu(1) %> loop?

I imagine it's something like <% if MoveItemFromLeftMenuToRightMenu = 1 %>don't show the item<% end_if %>, but what is the correct syntax? Or is there a more elegant way of testing for its presence?

jf\

Avatar
Junglefish

Community Member, 109 Posts

10 September 2009 at 9:10pm

@ bruceb, Thanks also for your suggestion.

So, I uncheck 'show in menu', no problem.

However, I'm not sure about how I could then set up a 'specific page control' to grab that specific node and its child nodes. Could you explain a little further please?

Thanks,

jf\

Avatar
dhensby

Community Member, 253 Posts

11 September 2009 at 4:01am

Edited: 11/09/2009 4:03am

Junglefish,

This is how i would do it:

class Page extends SiteTree {
...
public static $db = array(
"MoveItemFromLeftMenuToRightMenu" => "Boolean"
);

...
function getCMSFields() {
$fields = parent::getCMSFields();
...
$fields->addFieldToTab('Root.Behaviour', new CheckboxField('MoveItemFromLeftMenuToRightMenu', 'Show in right menu?'),'ShowInSearch');
...
return $fields;
}
...
}

class Page_Controller extends ContentController {
...
function RightMenu() {
return DataObject::get('Page','`MoveItemFromLeftMenuToRightMenu` = 1');
}
...
}

Then, in the template:

...
<% control RightMenu %>
<li><a href="$Link" title="Go to the $Title.XML page" class="$LinkingMode">$MenuTitle.XML</a></li>
<% end_control %>
...

This means, if a user checks the 'show in right menu' or whatever, then it shows in that menu. To stop it appearing in both the user would have to uncheck the 'show in menus'. If you only wanted it to show in one or the other, then you can modify the Menu() function so it excludes items with MoveItemFromLeftMenuToRightMenu and then use this:

function RightMenu() {
return DataObject::get('Page','`MoveItemFromLeftMenuToRightMenu` = 1 AND `ShowInMenus` = 1');
}

:)

PS: You don't have to give the user a check-box of course, you could code in the value, BUT then what about when they make new pages?

Avatar
Bruce B

Community Member, 164 Posts

11 September 2009 at 12:25pm

Pigeon's reply is much more elegant than what I was suggesting but you will definitely need to document it clearly for the client.

General info on using controls is here:
http://doc.silverstripe.org/doku.php?id=built-in-page-controls

Avatar
martimiz

Forum Moderator, 1391 Posts

11 September 2009 at 10:39pm

There's lots of good solutions suggested here :-) but I'd like to add that you could still do something like your first try. Only: the <% if %> structure doesn't (yet?) seem to support the != operator. A workaround could be:

<% if MenuTitle = 'My Headline' %><% else %> [your code goes here] <% end_if %>  

I think this might also be a 'Silverstripe way' as the template gets to decide what goes where in the display...

Go to Top