Programatically hide a page from the menu

Silverstripe Version: 4

Question:

How do I hide a page from menus programatically? For example, I want my registration page to only show to people who aren’t logged in (it doesn’t make much sense for someone who already has a login to register).

I had this code in the past, but it doesn’t seem to work any more.

/**
     * Hide from menus if logged in
     *
     * @return boolean
     */
    public function ShowInMenus()
    {
        $member = Security::getCurrentUser();
        return !$member;
    }

ShowInMenus is handled via DB Attriute, so creating this method on the registration page class doesn’t do anything. You could try to rename it to getShowInMenus(), which would take precedence over the value in the DB when calling $page->ShowInMenus.

Personally, I think that this is not really the “best” solution, as you are basically making it impossible to access the DB value directly (at least via common notation) and this could break if the way the __get method works is changed in the future. Additionally, you would disable the functionality of the “Show in Menus?” options in the page settings (think: what if a client wants to completely hide the page but not unpublish it?). If you have access to the template, I would recommend to handle this case using an

<% if ... %>
  Link
<% end_if %>

I got around it by changing the function to canView

That’s an alternative solution, but make sure to correctly check for permissions. Otherwise a CMS editor may not be able to edit / create the page.