Multiple Menus

The integration of menus has already been briefly mentioned in the chapter Convert HTML Templates . This chapter summarizes the necessary steps and explains the optional menu parameters of the show_menu2() function.

Difference of multiple menus and multiple menu calls

The term multiple menus is used for menus which acts independent of each other. This term should not be mixed up with multiple menu calls, which can be used to display different variants of one single menu. The application of both variants is highlighted below.

Multiple menus (independent of each other)

One application of two different menus is shown in the example template introduced in the previous sections. The template uses two independent menus. The top menu covers the pages "Disclaimer" and "Contact" another menu is used for the main navigation shown in the left column. Multiple menus allow to assign pages to different menu groups. This way one do not take care about menu levels, PAGE_ID and so on.

Multiple menus require additional entries in the file info.php of your template. Apart from that the usage of multiple menus must be enabled in the WB Settings.

Multiple menu calls

It is possible to invoke the menu functions (show_menu, show_menu2) several times for one and the same menu. Multiple menu calls can be used to display all parent pages (root level) of one menu at one location, all pages from the second menu level onwards (root level +1 ) at another location. This method is e.g. used for the set-up of multilingual pages. Another examplte is to output a "You are here link trail" (breadcrumbs) by the use of the external code snippet show_menu2 beside the main navigation menu.

You can use multiple menu calls for one menu (first parameter of the menu function $menu_number is identical) by adding several menu calls to the index.php file of your template. This method does not required to add additional entries to the info.php or to change any WB settings.

Using multiple menus

Multiple menus can be used to group pages to a certain menu (e.g. "Disclaimer" and "Contact"). To use more than one independent menu (don´t mix up with multiple menu calls) requires the steps shown below.

Step 1: Modifying the template files

File: info.php
WebsiteBaker requires a unique name in the info.php file for each additional menu. This information is provided via the array variable $menu2[x]. The main menu should be labeled as number 1, followed by the additional menus you want to add. An example with two independent menus is provided below. 

// definitions for multiple menues (required if more than one menu is used)
$menu[1]    = 'Main-Navigation';
$menu[2]    = 'Foot-Navigation';

The menu names are shown in the WB backend to assign pages to a certain menu. Therefore one should use speaking names for the different menus.

File: index.php
Each individual menu requires a template function call in the index.php file of your template. The parameter passed over to the function show_menu2(x) corresponds to the menu number assigned in the info.php file. Place the template function calls at the location in your template where the menu should be displayed.

<?php show_menu2(1); ?>
<?php show_menu2(2); ?>   

Step 2: Adapt the WB setting

Multiple menus are disabled per default in the WebsiteBaker default settings. The usage of multiple menus can be enabled via the WB backend: Settings -> Show Advanced Options -> Multiple Menus -> Enabled

Step 3: Assign pages to different menus

If you add a new page via the WB backend, it will be assigned by default to the first menu $menu[1].
You can assign a page to another menu via the the WB backend: Pages -> Settings Page Settings

The following dialogue appears.

Assign a page to a menu

Figure 1: Assign a page to a menu

Via the dropdown menu "Menu:" shown in the figure above, one can assign a page to any menu defined in the info.php file of your template.

Variables of show_menu2

show_menu2, version 4.9x

Show_Menu2 is a code snippet for the CMS WebsiteBaker. Since WebsiteBaker 2.7 it is included with the CMS.
The former show_menu function is completely replaced and extended with show_menu2. All data required to create the menu is generated by a single database query. By extensive adjustment possibilities of the generated HTML code all possible menu types (lists, breadcrumbs, sitemaps, etc.) can be generated.

INSTALLATION up

Since show_menu2 is usually present in WebsiteBaker, no installation is required. If, contrary to expectations, it does not exist, you can download it here .

Using SHOW_MENU2 up

To use show_menu2 you have to modify the template where you want the menu to appear. Please note: If old menu calls are replaced, the corresponding new parameters that show_menu2 needs must also be used.

In most cases the standard call with at least 4 parameters of show_menu2 is sufficient. In this case the default values are used, this creates a menu that displays the current page and the subpages of the current page:

show_menu2(0, SM2_ROOT, SM2_START, SM2_TRIM);

Please note: the call to show_menu2 is PHP and must normally be enclosed in PHP code characters (unless the call is already inside PHP code):

 <?php show_menu2(0, SM2_ROOT, SM2_START, SM2_TRIM); ?>

This default menu already creates a complete menu on a list basis with several classes that allow easy formatting using CSS. For example, the class "menu-current" is added to the <li> tag of the current menu item. Additionally each menu item of the subitems contains the class "menu-expand". This allows to create very differentiated CSS rules for each menu item.
For example:

li.menu-expand { font-weight: bold; }
li.menu-current { background: red; }

The section "HTML Output" contains a detailed description of which classes are assigned to which element. By using different parameters in the show_menu2 function call, it is also possible to create quite extensive and different menu structures. For example, to display only menu items from the top level of the menu structure, you could use the following call:

show_menu2(0, SM2_ROOT, SM2_START, SM2_TRIM);

Or, for example, to display up to two sublevels of the current page:

show_menu2(0, SM2_CURR+1, SM2_CURR+2, SM2_TRIM);

There are a lot of possibilities to create different menu structures. Numerous examples can be found on the demo website: KLICK

FAQ up

Q: I'm not a programmer. Is there no simpler documentation?
A: No, because this is already the simple documentation.

Q: How can I create a drop-down menu?
A: This has nothing to do with show_menu2. To create a drop-down menu you only have to adjust the CSS code of the respective template. The necessary adjustments can be found e.g. in the "allcss2" template from the WebsiteBaker Addon Repository -> https://addon.websitebaker.org/

Q: Why does the menu disappear after I have used the search function in a multilingual WebsiteBaker page?
A: The necessary lines are missing in the template used:

1. In the WB Admin Backend: Options -> Show advanced options -> Search options -> Header - insert the following line directly after the opening <form> tag:
<input type="hidden" name="referrer" value="[REFERRER_ID]" />
2. insert the following line in the index.php of the used template immediately after the opening <form> tag of the search:
<input type="hidden" name="referrer" value="<?php echo defined('REFERRER_ID')?REFERRER_ID:PAGE_ID;?>" />

Q: Multilingual? That sounds great. How do you do it?
A: https://help.websitebaker.org/en/designerguide/multilingual-websites.php

Q: Each time a page is called, SM2 generates the following warning message:
"show_menu2 error: $aOptions is invalid. No flags from group 1 supplied!"
A: The wrong values or a wrong number of values were passed to the function.
See the PARAMETERS section for the correct flag values to pass to the $aOptions parameter.

Q: How do I use a different class/picture/color/widget for each entry in a menu?
A: Use the [page_id] format string in the $aItemOpen string. Create a unique class or id for each menu item, then reference that item in your CSS or Javascript to do whatever you want.
To add a unique class for each menu item (or similar):

"<li><a href="[url]" target="[target]" class="[class] p[page_id]">[menu_title]</a>"

... creating menu items like ...

<li><a href="/pages/foo/bar.php" target="_top" class="menu-top p45">Top Menu</a>

Reference this in your CSS like:

a.p45 { color: red; }

To add a unique ID for each menu item (or similar):

"<li><a id="p[page_id]" href="[url]" target="[target]" class="[class]">[menu_title]</a>"

... creating menu items like ...

<li><a id="p45" href="/pages/foo/bar.php" target="_top" class="menu-top">Top Menu</a>

Reference this in your CSS like:

a#p45 { color: red; }

Note that the ID can only be used if that menu is generated and displayed one time only on the page (because HTML ID's must be unique within a page).

FUNCTION up

The complete call and the default parameter values for show_menu2 are as follows:

show_menu2(
  $aMenu = 0,
  $aStart = SM2_ROOT,
  $aMaxLevel = SM2_CURR+1,
  $aOptions = SM2_TRIM,
  $aItemOpen = '[li][a][menu_title]</a>',
  $aItemClose = '</li>',
  $aMenuOpen = '[ul]',
  $aMenuClose = '</ul>',
  $aTopItemOpen = false,
  $aTopMenuOpen = false
);

The "Parameters" section contains a detailed description of each individual parameter.
Each parameter must be used absolutely correctly. The following rules can help:

$aMenu = 0 is the best value in most cases.
$aStart must be either a page ID or a value starting with "SM2_".
$aMaxLevel can only get values starting with "SM2_".
$aOptions except for a few special cases only values beginning with "SM2_" are allowed.
All other parameters contain the (HTML)tags that control the output of the menu.
Starting from $aItemOpen each parameter can be passed the value false to get the respective default value.

This can be used, for example, to create a numbered list, while the default values are still used for the individual menu items:

show_menu2(0, SM2_ROOT, SM2_ALL, SM2_ALL, false, false, '<ol>', '</ol>');

Please note: up to and including $aOptions all parameters must be passed explicitly!

HTML Output up

The HTML output depends largely on which parameters are passed to the function. Irrespective of this, subsequent classes are always used for each menu, whereby individual menu items can also have several classes if necessary.

CLASS ASSIGNMENT
menu-top Only the first menu item.
menu-parent Any main menu item.
menu-current Only the menu item of the current page.
menu-sibling All "siblings" of the current page.
menu-child Any submenu of the current page.
menu-expand Any menu that has submenus.
menu-first The first item of any menu or submenu.
menu-last The last item of any menu or submenu.
The following classes are only added if the SM2_NUMCLASS flag is set:
menu-N Each menu item, where the N stands for the ABSOLUTE menu depth, starting with 0, of the respective menu item.
So the top level is always menu-0, the next level is menu-1, and so on.
menu-child-N Each submenu of the current pages, where the N stands for the RELATIVE depth of the submenu, starting with 0.

Example of HTML output:

<ul class="menu-top menu-0">
  <li class="menu-0 menu-first"> ... </li>
  <li class="menu-0 menu-expand menu-parent"> ...
  <ul class="menu-1">
    <li class="menu-1 menu-expand menu-first"> ...
    <ul class="menu-2">
        <li class="menu-2 menu-first"> ...
        <li class="menu-2 menu-last"> ...
    </ul>
    </li>
    <li class="menu-1 menu-expand menu-parent"> ...
    <ul class="menu-2">
        <li class="menu-2 menu-expand menu-current menu-first"> ... ** CURRENT PAGE **
        <ul class="menu-3">
            <li class="menu-3 menu-child menu-child-0 menu-first"> ...
            <ul class="menu-4">
                <li class="menu-4 menu-child menu-child-1 menu-first"> ... </li>
                <li class="menu-4 menu-child menu-child-1 menu-last"> ... </li>
            </ul>
            </li>
            <li class="menu-3 menu-child menu-child-0 menu-last"> ... </li>
        </ul>
        </li>
        <li class="menu-2 menu-sibling menu-last"> ... </li>
    </ul>
    </li>
    <li class="menu-1"> ... </li>
    <li class="menu-1 menu-expand menu-last"> ...
    <ul class="menu-2">
        <li class="menu-2 menu-first menu-last"> ... </li>
    </ul>
    </li>
  </ul>
  </li>
  <li class="menu-0 menu-last"> ... </li>
 </ul>
 

PARAMETER up

$aMenu

Menu number. This is useful to use multiple menus on one page. Menu number 0 is the default menu of the current page, SM2_ALLMENU returns all menus used in the system.

$aStart

Specifies the level from which the creation of the menu is to begin. In most cases, this will be the top level of the menu to be displayed. One of the following values can be used:

SM2_ROOT+N

Starts N levels below the top level, e.g.:
SM2_ROOT Starts at the top level
SM2_ROOT+1 Starts a layer below the topmost layer
SM2_ROOT+2 Starts two levels below the top level
SM2_CURR+N
Starts N levels below the current level, e.g.:
SM2_CURR Starts at the current layer. All siblings of the current level
SM2_CURR+1 Starts a layer below the current layer with all sublevels.
page_id
Uses the page with the specified page id as the parent element.
All submenus of this page are displayed. (The page id can be determined by editing the page in the admin backend, it will be displayed in the address bar of the browser: http://SITE/admin/pages/modify.php?page_id=35

 

$aMaxLevel

The maximum number of levels that can be displayed. The display
starts from the level specified in $aStart, up to the level specified here.
SM2_ALL
No restriction, all levels are displayed.
SM2_CURR+N
Always shows the current page + N levels.
SM2_CURR Current layer (no sublayer)
SM2_CURR+3 All parent + current + 3 sublevels
SM2_START+N
Always starts at the start level + N levels.
The levels are displayed regardless of which level the current page is on.
SM2_START A single level from the start level.
SM2_START+1 Start level + one level below.
SM2_MAX+N
Displays a maximum of N levels from the start level.
Layers below the current level are not displayed.
SM2_MAX Only the start plane (same effect as SM2_START)
SM2_MAX+1 The start level and one level below it.

$aOptions

Special flags for different menu generation options. They can be combined with each other using an OR link (|).
For example, to define both TRIM and PRETTY, use : (SM2_TRIM | SM2_PRETTY).
 

GROUP 1
-------
One flag must always be specified from this group. These flags determine how the sibling elements in the menu tree are suppressed in the output.

SM2_ALL
Shows all branches of the menu tree
 A-1 -> B-1
     -> B-2  -> C-1
             -> C-2 (CURRENT)
                       -> D-1
                       -> D-2
             -> C-3
 A-2 -> B-3
     -> B-4
SM2_TRIM
Shows all sibling menus of the page in the current path.
All submenus of items that are not in the path.
are removed.
 A-1 -> B-1
     -> B-2  -> C-1
             -> C-2 (CURRENT)
                       -> D-1
                       -> D-2
             -> C-3
 A-2 
SM2_CRUMB
Displays the breadcrumb path of the menu, i.e. the current
Menu item and all menu items leading to it.
A-1 -> B-2 -> C-2 (CURRENT)
SM2_SIBLING
Like SM2_TRIM, but only sibling menus of the current page are displayed. All other items are suppressed.
 A-1 -> B-2 -> C-1
            -> C-2 (CURRENT)
                     -> D-1
                     -> D-2
            -> C-3
            
 

GROUP 2
-------
These flags are optional, they can be combined in any number.

SM2_NUMCLASS
Adds the numbered menu classes "menu-N" and "menu-child-N".
SM2_ALLINFO
Loads all fields from the page table of the database.
This causes a fairly high memory consumption and should be
should therefore be used with caution.
This means, for example, that the keywords, page description and
all the other information available that is normally not
can be loaded.
Please note: this flag must be set at FIRST call of schow_menu2
can be used for the respective menu ID, or in conjunction with the
with SM2_NOCACHE, otherwise it has no effect.
SM2_NOCACHE
The data read from the database is not reused when show_menu2 is called again, but is read again from the database.
SM2_PRETTY
Brings the HTML output of the menu with blanks and
Line breaks into a legible form. This is especially useful when debugging the menu output.
SM2_BUFFER
Does not output the HTML code directly, but saves it internally and outputs it as a complete string.
SM2_CURRTREE
Excludes all other top level menus from viewing.
Only menu items of the current menu branch are displayed.
If required, this flag can be combined with any flag from group 1.
SM2_ESCAPE
Applies htmlspecialchars to the menu string.
This may be required for older WebsiteBaker installations.
to generate a valid HTML output.
SM2_SHOWHIDDEN
Hidden pages are usually hidden all of the time, including when they are active (i.e. current page or a parent page).
Use private pages for time when you want pages to be hidden except when active. However for compatibility with release 4.8, supply this flag to enable hidden pages to become visible when they are active.
SM2_XHTML_STRICT
Ensures the XHTML compatibility of the links by removing the target specification in links formatted with [a] or [ac] and inserting the argument title="[page_titel]". For manually compiled links, the designer is responsible for the XHTML conformity.
SM2_NO_TITLE
Suppresses the output of the content of the Title attribute for [a] or [ac] formatted links.
For this parameter there is also an extended mode where the options are passed as an associative array. See the ADVANCED OPTIONS section for details. For most applications, however, this is NOT required.

$aItemOpen

This defines the format string with which each individual menu item is started. A different format string can be defined for the very first menu item using $aTopItemOpen.
If this parameter is set to false, the default format string
'[li][a][menu_title]</a>' to ensure compatibility with the WebsiteBaker standard function show_menu().
Since formatting using CSS classes is often easier when applied to the <a> tag, it is recommended to use the following format string: '<li>[ac][menu_title]</a>'.
This parameter can also be used as an instance of a formatting class for the menu. A more detailed description can be found in the FORMATTER section. If a formatter is specified here, all arguments after $aItemOpen are ignored.

$aItemClose

This string completes each menu item. Please note: this is not a format string and no keywords will be replaced!
If this parameter is set to false, the default '</li>' is used.

$aMenuOpen

This format string opens a list of menu items. A different format string can be defined for the first menu using $aTopMenuOpen.
If this parameter is set to false, the default value '[ul]' is used.

$aMenuClose

This string completes each menu. Please note: this is not a format string and no keywords will be replaced!
If this parameter is set to false, the default '</ul>' is used.

$aTopItemOpen

The format string for the very first menu item. If this parameter is set to false, the same format string is used as for $aItemOpen.

$aTopMenuOpen

The format string for the first menu. If this parameter is set to false, the same format string as $aMenuOpen is used.

ADVANCED OPTIONS up

Der Parameter $aOptions kann auf zweierlei Arten verwendet werden. Zum einen, wie oben im Abschnitt PARAMETER beschrieben, diese Art sollte für die allermeisten Anwendungsfälle ausreichen. Um allerdings in speziellen Fällen die Sonderoptionen ansprechen zu können, müssen die erforderlichen Werte als assoziatives Array bereitgestellt werden.
Bitte beachten: Die SM2_* Flags sind auch hierbei erforderlich und müßen als 'flags' übergeben werden.

'flags'
**CONCELARY REQUIRED** These are the flags described above in the PARAMETERS section under $aOptions.
'notrim'

This defines a number of levels that are always displayed relative to the menu level defined in $aStart. This causes the SM2_TRIM flag to be ignored for these levels.

To use this array it is recommended to first create it and then supply the $aOptions parameter with the created array:

$options = array('flags' => (SM2_TRIM|...), 'notrim' => 1);
 show_menu2(0, SM2_ROOT, SM2_CURR+1, $options);

FORMAT STRINGS up

The following tags can be used in the format strings for $aItemOpen and $aMenuOpen and should be replaced by the corresponding text.

[a] <a> tag without class:
'<a href="[url]" target="[target]">'
[ac] <a> tag with class:
'<a href="[url]" target="[target]" class="[class]">'
[li] <li> tag with class:
'<li class="[class]">'
[ul] <ul> tag with class:
'<ul class="[class]">'
[class] List of classes for this page
[menu_title] Text of the menu title
(HTML entity escaped unless the SM2_NOESCAPE flag is set)
[menu_icon_0] The URL to an image file with normal - representation
[menu_icon_1] The URL to an image file with active/hover display
[page_title] Page title text
(HTML entity escaped unless the SM2_NOESCAPE flag is set)
[page_icon] The URL to a page-related image file
[url] The URL of the pages for the <a> tag
[target] The page target for the <a> tag
[page_id] The Page ID of the current menu item.
[parent] The Page ID of the parent menu item.
[level] You page level, this is the same number used in the "menu-N" CSS tag.
[sib] Number of siblings of the current menu item.
[sibCount] Number of all siblings in this menu.
[if] Condition (see section "Conditional Formatting" for details)

The following tags are ONLY available if the SM2_ALLINFO flag is set.

[description] page description
[keywords] Keywords of the page

Conditional Formatting up

The conditional formatting statement can take one of the following forms:

[if(A){B}]
[if(A){B}else{C}]
A
The condition. See below for details.
B
The expression used when the condition is met.
This can be any string that does not contain the character '}'.
may contain. It can contain any format string from the section
Format Strings', but no further condition test (because the character '}' is not allowed).
C
The expression used when the condition is not met.
This can be any string that does not contain the character '}'.
may contain. It can contain any format string from the section
Format Strings', but no further condition test (because the character '}' is not allowed).

The condition is a combination of one or more boolean comparisons.
If more than one comparison is required, it must be combined with the other comparisons
can be linked using || (boolean or - OR) or && (boolean and - AND).

A single comparison consists of the left operand, the operator and the right operand.
e.g. X == Y - where X is the left operand, == the operator and Y the right operand.

Left operand. Must be one of the following keywords:
class Check whether this class exists. Only the "==" and "!=" operators are allowed. In this case the operators have the meaning "contains" or "does not contain" instead of "is equal" or "is not equal".
level Checking the page level.
sib Check the number of siblings on the current page.
sibCount Check the total number of siblings in the current menu.
id Check the page id.
target Verification of the target specification.
Operator. Must be one of the following:
< Less than
<= Less than or equal to
== Equal
!= Not equal
>= Greater than or equal to
> Greater than
Right operand. The type of this operand depends on the keyword used for the left operand.
class One of the "menu-*" Class names as specified in the "Output" section.
level Check the page level against the following values:
  • <number> the absolute page level
  • root is the top level of the page
  • granny a page level Above the parent page level
  • parent the parent page level
  • current the current page level
  • child the subordinate page level
id Check the page id against the following values:
  • <number> the absolute page id
  • parent the parent page id
  • current the current page id
sib A positive integer, or "sibCount" to check the number of siblings in this menu.
sibCount A positive integer number
target A string that represents a possible target specification.
The following examples result in "true" and the expression {exp} is executed if true:
[if(class==menu-expand){exp}] Has a submenu
[if(class==menu-first){exp}] If the first entry in a menu is
[if(class!=menu-first){exp}] Is NOT the first item in a menu
[if(class==menu-last){exp}] If the last entry in a menu is
[if(level==0){exp}] Located at the topmost level
[if(level>0){exp}] Is NOT on the top level
[if(sib==2){exp}] If the second entry in a menu is
[if(sibCount>1){exp}] If in a menu with more than one entry
[if(sibCount!=2){exp}] Is in a menu that does not have exactly 2 items
[if(level>parent){exp}] Is in a sibling menu or in the submenu of a sibling menu
[if(id==parent){exp}] Is the parent point of the current id
[if(target==_self){exp}] The string '_self' is contained in the target attribute.

If an else clause is added, it will be executed in all other cases.

For example, "foo" is always executed when the if check is wrong, so:

[if(sib==2){exp}else{foo}] Is NOT the second item in the menu
[if(sibCount>2){exp}else{foo}] is NOT in a menu with more than two entries
In multiple comparisons, the expression "exp" is only executed if:
[if(sib == 1 || sib > 3){exp}] is the first entry OR is the fourth or higher entry in the menu
[if(id == current && class == menu-expand){exp}] If the current entry is AND has submenus

Please note:
All checks will be performed in the order in which they are noted, because:

  • There is no check for possible loops (all checks are always executed).
  • Checks are not grouped (parentheses of checks are not supported)
  • Both these things have the same value.

FORMATTER up

Attention: This is an advanced and rarely used feature!

With extensive knowledge in PHP programming it is possible to use the predefined
Formatting of show_menu2 with your own.
In the include.php of show_menu2 you can see how to write the formatter.
The API that must be used looks like this:

class SM2_Formatter
{
 // called once before any menu is processed to allow object initialization
 function initialize() { }
 // called to open the menu list
 function startList($aPage, $aUrl) { }
 // called to open the menu item
 function startItem($aPage, $aUrl, $aCurrSib, $aSibCount) { }
 // called to close the menu item
 function finishItem() { }
 // called to close the menu list
 function finishList() { }
 // called once after all menu has been processed to allow object finalization
 function finalize() { }
 // called once after finalize() if the SM2_NOOUTPUT flag is used
 function getOutput() { }
};

WebsiteBaker is released under the GNU General Public License

Examples

Forum: Show_Menu2 - README + Solutions for different navigations