TSRef - TypoScript Reference

1.7.10. HMENU

Generates hierarchical menus.

Property:

Data type:

Description:

Default:

(1 / 2 / 3 /...)

menuObj

Required!

Defines which menuObj that should render the menu items on the various levels.

1 is the first level, 2 is the second level, 3 is the third level, 4 is ....

 

Example:

temp.sidemenu = HMENU

temp.sidemenu.1 = GMENU  

 (no menu)

cache_period

int

The number of seconds a menu may remain in cache. If this value is not set, the first available value of the following will be used:

    1) cache_timeout of the current page

    2) config.cache_period defined globally

    3) 86400 (= 1 day)

 

entryLevel

int /stdWrap

Defines at which level in the rootLine, the menu should start.

Default is "0" which gives us a menu of the very first pages on the site.

If the value is < 0, entryLevel is chosen from "behind" in the rootLine. Thus "-1" is a menu with items from the outermost level, "-2" is the level before the outermost...

0

special

"directory" / "list" / "updated" / "browse" / "rootline" / "keywords" / "language"

(See separate table below)

 

special.value

list of page-uid's /stdWrap

See above

 

minItems

int

The minimum items in the menu. If the number of pages does not reach this level, a dummy-page with the title "..." and uid=[currentpage_id] is inserted.

 

Notice: Affects all sub menus as well. To set the value for each menu level individually, set the properties in the menu objects (see "Common properties" table).

 

maxItems

int

The maximum items in the menu. More items will be ignored.

 

Notice: Affects all sub menus as well. (See "minItems" for notice)

 

begin

int +calc

The first item in the menu.

 

Example:

This results in a menu, where the first two items are skipped starting with item number 3:

  begin = 3  

 

Notice: Affects all sub menus as well. (See "minItems" for notice)

 

excludeUidList

list of int

This is a list of page uid's to exclude when the select statement is done. Comma-separated. You may add "current" to the list to exclude the current page.

 

Example:

The pages with these uid-number will NOT be within the menu!! Additionally the current page is always excluded too.

  excludeUidList = 34,2,current

 

excludeDoktypes

list of integers

Enter the list of page document types (doktype) to exclude from menus. By default pages that are "not in menu" (5) are excluded and those marked for backend user access only (6).

5,6

includeNotInMenu

boolean

If set, pages with the checkbox "Not in menu" checked will be included in menus.

 

alwaysActivePIDlist

list of integers /stdWrap

This is a list of page UID numbers that will always be regarded as active menu items and thereby automatically opened regardless of the rootline.

 

protectLvar

boolean / keyword

If set, then for each page in the menu it will be checked if an Alternative Page Language record for the language defined in "config.sys_language_uid" (typically defined via &L) exists for the page. If that is not the case and the pages "Localization settings" have the "Hide page if no translation for current language exists" flag set, then the menu item will link to a non accessible page that will yield an error page to the user. Setting this option will prevent that situation by simply adding "&L=0" for such pages, meaning that they will switch to the default language rather than keeping the current language.

The check is only carried out if a translation is requested ("config.sys_language_uid" is not zero).

 

Keyword: "all"

When set to "all" the same check is carried out but it will not look if "Hide page if no translation for current language exists" is set - it always reverts to default language if no translation is found.

 

For these options to make sense, they should only be used when "config.sys_language_mode" is not set to "content_fallback".

 

addQueryString

string

see typolink.addQueryString

 

Notice: This works only for special=language.

 

if

->if

If "if" returns false, the menu is not generated

 

wrap

wrap

 

 

stdWrap

->stdWrap

 

 

[tsref:(cObject).HMENU]

Example:
  temp.sidemenu = HMENU 
  temp.sidemenu.entryLevel = 1 
  temp.sidemenu.1 = TMENU 
  temp.sidemenu.1 { 
    target = page 
    NO.afterImg = media/bullets/dots2.gif |*||*| _ 
    NO.afterImgTagParams = hspace="4" 
    NO.linkWrap = {$fontTag} 
    NO.ATagBeforeWrap = 1 
    
    ACT < .NO 
    ACT = 1 
    ACT.linkWrap = <b>{$fontTag}</b> 
  } 

The .special property

This property makes it possible to create menus that are not strictly reflecting the current page-structure, but rather creating menus with links to pages like "next/previous", "last modified", "pages in a certain page" and so on.

NOTE: Don't set .entryLevel for a HMENU when using this option! Also be aware that this selects pages for the first level in the menu. Submenus by menuPbjects 2+ will be created as usual.

special.directory

A HMENU of type special = directory lets you create a menu listing the subpages of one or more parent pages. The parent pages are defined in the property ".value". It is usually used for sitemaps.

Mount pages are supported.

Property:

Data type:

Description:

Default:

value

list of page ids /stdWrap

This will generate a menu of all pages with pid = 35 and pid = 56.

  20 = HMENU

  20.special = directory

  20.special.value = 35, 56

current page id

[tsref:(cObject).HMENU.special.directory]

special.list

A HMENU of type special = list lets you create a menu that lists the pages you define in the property ".value".

Mount pages are supported.

Property:

Data type:

Description:

Default:

value

list of page ids /stdWrap

This will generate a menu with the two pages (uid=35 and uid=36) listed:

 

  20 = HMENU

  20.special = list

  20.special.value = 35, 56

 

If .value is not set, the default uid is the .entryLevel uid.

.entryLevel uid

[tsref:(cObject).HMENU.special.list]

special.updated

A HMENU with the property special = updated will create a menu of the most recently updated pages.

A note on ordering: The sorting menu is by default done in reverse order (desc) with the field specified by "mode", but setting "alternativeSortingField" for the menu object (eg TMENU or GMENU, see later) will override that.

Mount pages are supported.

Property:

Data type:

Description:

Default:

value

list of page ids /stdWrap

This will generate a menu of the most recently updated pages from the branches in the tree starting with the uid's (uid=35 and uid=36) listed.

  20 = HMENU

  20.special = updated

  20.special.value = 35, 56

 

mode

string

The field in the database that contains the information about the last update. The following values are possible:

- SYS_LASTCHANGED (default)

- crdate

- tstamp  (is set automatically when the record is changed)

- lastUpdated  (set manually in the page-record)

- manual  (an alias for lastUpdated)

- starttime

 

Fields with empty values are generally not selected.

SYS_LASTCHANGED

depth

int

Defines the treedepth.

The allowed range is 1-20.

A depth of 1 means only the start id, depth of 2 means start-id + first level.

Notice: "depth" is relative to "beginAtLevel".

20

beginAtLevel

int

Determines starting level for the pagetrees generated based on .value and .depth.

 

0 is default and includes the start id.

1 starts with the first row of subpages,

2 starts with the second row of subpages.

 

Notice: "depth" is relative to this property.

0

maxAge

int (seconds) +calc

Pages with update-dates older than the current time minus this number of seconds will not be shown in the menu no matter what. Default is "not used". You may use +-*/ for calculations.

 

limit

int

Maximal number of items in the menu. Default is 10, max is 100.

10

excludeNoSearchPages

boolean

If set, pages marked "No search" are not included into special-menus.

 

[tsref:(cObject).HMENU.special.updated]

Example for special = updated:

The following example will generate a menu of the most recently updated pages from the branches in the tree starting with the uid's (uid=35 and uid=36) listed. Furthermore the field "tstamp" is used (default is SYS_LASTCHANGED) and the treedepth is 2 levels. Also there will be shown a maximum of 8 pages and they must have been updated within the last three days (3600*24*3):

 

    20 = HMENU 
    20.special = updated 
    20.special.value = 35, 56 
    20.special { 
      mode = tstamp 
      depth = 2 
      maxAge = 3600*24*3 
      limit = 8 
    } 
special.rootline

A HMENU with the property special = rootline creates a rootline menu (also known as "breadcrumb trail") that could look like this:

Page level 1 > Page level 2 > Page level 3 > Current page

(For a description of "rootline" see further up in this document.)

Mount pages are supported.

Property:

Data type:

Description:

Default:

range

string /stdWrap

[begin-level] | [end-level] (same way as you reference the .entryLevel for HMENU). The following example will start at level 1 and not show the page the user is currently on:

temp.breadcrumbs = HMENU

temp.breadcrumbs.special = rootline
temp.breadcrumbs.special.range = 1|-2

 

reverseOrder

boolean

If set to true, the order of the rootline menu elements will be reversed.

false

targets.[level number]

string

For framesets. You can set a default target and a target for each level by using the level number as subproperty. In the following example the links to pages on level 3 will have target="page", while all other levels will have target="_top" through the TMENU property .target.

 

page.2 = HMENU

page.2.special = rootline

page.2.special.range = 1|-2

page.2.special.targets.3 = page

page.2.1 = TMENU

page.2.1.target = _top

page.2.1.wrap = <HR> | <HR>

page.2.1.NO {

  linkWrap = | >

}

 

[tsref:(cObject).HMENU.special.rootline]

special.browse

Warning: Mount pages are not supported!

This kind of menu is built of items given by a list from the property ".item".

 

Ordering is by default done in reverse order (desc) with the field specified by "mode" , but setting "alternativeSortingField" for the menu object (eg GMENU, see later) will override that.

 

Property:

Data type:

Description:

Default:

value

int
/stdWrap

Default is current page id. Seldomly you might want to override this value with another page-uid which will then act as the basepoint for the menu and the predefined items.

current page id

items

list of itemnames seperated by "|"

Each element in the list (separated by "|") is either a reserved item name (see list) with a predefined function, or a userdefined name which you can assign a link to any page. Note that the current page cannot be the root-page of a site.

 

Reserved itemnames:

next / prev : links to next page / previous page. Next and previous pages are from the same "pid" as the current page id (or "value") - that is the next item in a menu with the current page. Also referred to as current level.

If ".prevnextToSection" is set then next/prev will link to the first page of next section / last page of previous section.

nextsection / prevsection : links to next section / previous section. A section is defined as the subpages of a page on the same level as the parent (pid) page of the current page. Will not work if parent page of current page is the root page of the site.

nextsection_last | prevsection_last: Where nextsection/prevsection links to the first page in a section, these links to the last pages. If there is only one page in the section that will be both first and last. Will not work if parent page of current page is the root page of the site.

first / last : First / Last page on current level. If there is only one page on the current level that page will be both first and last.

up : Links to the parent (pid) page of the current page. (up 1 level) Will always be available

index : Links to the parent of the parent page of the current page (up 2 levels). May not be available if that page is out of the rootline.

 


Examples:

 

If id=20 is current page then:

21= prev and first, 19 = next, 18 = last, 17 = up, 1=index, 10 = nextsection, 11 = nextsection_last

 

prevsection and prevsection_last is not present because id=3 has no subpages!

 

TypoScript (only "browse"-part, needs also TMENU/GMENU):

xxx = HMENU

xxx.special = browse

xxx.special {

  items = index|up|next|prev

  items.prevnextToSection = 1

  index.target = _blank

  index.fields.title = INDEX

  index.uid = 8

}

 

items.prevnextToSection

boolean

If set, the "prev" and "next" navigation will jump to the next section when it reaches the end of pages in the current section

 

[itemnames].target

string

Optional/alternative target of the item

 

[itemnames].uid

int

(uid of page) - optional/alternative page-uid to link to

 

[itemnames].fields.[fieldname]

string

Override field "fieldname" in pagerecord

 

[tsref:(cObject).HMENU.special.browse]

special.keywords

Makes a menu of pages with one or more keywords also found on the current page.

Mount pages are supported.

Property:

Data type:

Description:

Default:

value

int
/stdWrap

Page for which keywords to find similar pages

 

mode

string

Which field in the pages-table to use for sorting. Possible values are:

 

SYS_LASTCHANGED (which is updated when a page is generated to the youngest tstamp of the records on the page).

manual or lastUpdated will use the field "lastUpdated" (set manually in the page-record).

tstamp will use the "tstamp"-field of the pagerecord, which is set automatically when the record is changed.

crdate will use "crdate"-field of the pagerecord.

starttime will use the starttime field.

SYS_LAST_CHANGED

entryLevel

int

Where in the rootline the search begins.

Standard rootline syntax (-x to x)

 

depth

int

(same as in section "special.updated")

20

limit

int

(same as in section "special.updated")

10

excludeNoSearchPages

boolean

(same as in section "special.updated")

 

begin

boolean

(same as in section "special.updated")

 

setKeywords

string
/stdWrap

lets you define the keywords manually by defining them as a commaseparated list. If this property is defined, it overrides the default, which is the keywords of the current page.

 

keywordsField

string

defines the field in the pages-table in which to search for the keywords. Default is the fieldname "keyword". No check is done to see if the field you enter here exists, so enter an existing field, OK?!

keywords

keywordsField.sourceField

string

defines the field from the current page from which to take the keywords being matched. The default is "keyword". (Notice that ".keywordsField" is only setting the page-record field to search in !)

keywords

[tsref:(cObject).HMENU.special.keywords]

special.language

Creates a language selector menu. Typically this is made as a menu with flags for each language a page is translated to and when the user clicks any element the same page id is hit but with a change to the "&L" parameter in the URL.

The "language" type will create menu items based on the current page record but with the language record for each language overlaid if available. The items all link to the current page id and only "&L" is changed.

Note on item states:

When "TSFE->sys_language_uid" matches the sys_language uid for an element the state is set to "ACT", otherwise "NO". However, if a page is not available due to the pages "Localization settings" (which can disable translations) or if no Alternative Page Language record was found (can be disabled with ".normalWhenNoLanguage", see below)  the state is set to "USERDEF1" for non-active items and "USERDEF2" for active items. So in total there are four states to create designs for. It is recommended to disable the link on menu items rendered with "USERDEF1" and "USERDEF2" in this case since they are disabled exactly because a page in that language does not exist and might even issue an error if tried accessed (depending on site configuration).

Property:

Data type:

Description:

Default:

value

comma list of sys_language uids
/stdWrap

The number of elements in this list determines the number of menu items.

 

normalWhenNoLanguage

boolean

If set to 1 the button for a language will ve rendered as a non-disabled button even if no translation is found for the language.

 

[tsref:(cObject).HMENU.special.language]

Example

Creates a language menu with flags (notice that some lines break):

  
lib.langMenu = HMENU
  lib.langMenu.special = language 
  lib.langMenu.special.value = 0,1,2 
  lib.langMenu.1 = GMENU 
  lib.langMenu.1.NO { 
    XY = [5.w]+4, [5.h]+4 
    backColor = white 
    5 = IMAGE 
    5.file = media/flags/flag_uk.gif  || media/flags/flag_fr.gif  || media/flags/flag_es.gif  
    5.offset = 2,2 
  } 
    
  lib.langMenu.1.ACT < lib.langMenu.1.NO 
  lib.langMenu.1.ACT=1 
  lib.langMenu.1.ACT.backColor = black 
    
  lib.langMenu.1.USERDEF1 < lib.langMenu.1.NO 
  lib.langMenu.1.USERDEF1=1 
  lib.langMenu.1.USERDEF1.5.file = media/flags/flag_uk_d.gif  || media/flags/flag_fr_d.gif  || media/flags/flag_es_d.gif  
  lib.langMenu.1.USERDEF1.noLink = 1 
special.userdefined

Lets you write your own little PHP-script that generates the array of menuitems.

Property:

Data type:

Description:

Default:

file

resource

Filename of the php-file to include. (Just like cObject PHP_SCRIPT)

 

[any other key]

 

Your own variables to your script. They are all accessible in the array $conf in your script.

 

[tsref:(cObject).HMENU.special.userdefined]

Howto:

You must populate an array called $menuItemsArray with page-records of the menuitems you want to be in the menu.

It goes like this:

$menuItemsArray[] = pageRow1;

$menuItemsArray[] = pageRow2;

$menuItemsArray[] = pageRow3;

...

 

A "pageRow" is a record from the table "pages" with all fields selected (SELECT * FROM...)

If you create fake page rows, make sure to add at least "title" and "uid" field values.

Notice:

If you work with mount-points you can set the MP param which should be set for the page by setting the internal field "_MP_PARAM" in the page-record (xxx-xxx).

Overriding URLs:

You can also use the internal field "_OVERRIDE_HREF" to set a custom href-value (eg. "http://www.typo3.org") which will in any case be used rather than a link to the page that the page otherwise might represent. If you use "_OVERRIDE_HREF" then "_OVERRIDE_TARGET" can be used to override the target value as well (See example below).

Other reserved keys:

"_ADD_GETVARS" can be used to add get parameters to the URL, eg. "&L=xxx".

"_SAFE" can be used to protect the element to make sure it is not filtered out for any reason.

Creating submenus:

You can create submenus for the next level easily by just adding an array of menu items in the internal field "_SUB_MENU" (See example below).

Presetting element state

If you would like to preset an element to be recognized as a SPC, IFSUB, ACT, CUR or USR mode item, you can do so by specifying one of these values in the key "ITEM_STATE" of the page record. This setting will override the natural state-evaluation.

special.userfunction

Calls a user function/method in class which should (as with "userdefined" above) return an array with page records for the menu.

Property:

Data type:

Description:

Default:

userFunc

string

Name of the function

 

[tsref:(cObject).HMENU.special.userfunction]

Example: Creating hierarchical menus of custom links

By default the HMENU object is designed to create menus from pages in TYPO3. Such pages are represented by their page-record contents. Usually the "title" field is used for the title and the "uid" field is used to create a link to that page in the menu.

However the HMENU and sub-menu objects are so powerful that it would be very useful to use these objects for creating menus of links which does not relate to pages in TYPO3 by their ids. This could be a menu reflecting a menu structure of a plugin where each link might link to the same page id in TYPO3 but where the difference would be in some parameter value.

This can be easily done with the special-type "userdefined" (see table above) where you can return an array of menu items customly build in a PHP-script you write.

 

First, this listing creates a menu in three levels where the first two are graphical items:

     0: # ************************ 
     1: # MENU LEFT 
     2: # ************************ 
     3: lib.leftmenu.20 = HMENU 
     4: lib.leftmenu.20.special = userfunction 
     5: lib.leftmenu.20.special.userFunc = user_3dsplm_pi2->makeMenuArray 
     6: lib.leftmenu.20.1 = GMENU 
     7: lib.leftmenu.20.1.NO { 
     8:   wrap = <tr><td>|</td></tr><tr><td class="bckgdgrey1" height="1"></td></tr> 
     9:   XY = 163,19 
    10:   backColor = white 
    11:   10 = TEXT 
    12:   10.text.field = title 
    13:   10.text.case = upper 
    14:   10.fontColor = red 
    15:   10.fontFile = fileadmin/fonts/ARIALNB.TTF 
    16:   10.niceText = 1 
    17:   10.offset = 14,12 
    18:   10.fontSize = 10 
    19: } 
    20: lib.leftmenu.20.2 = GMENU 
    21: lib.leftmenu.20.2.wrap = | <tr><td class="bckgdwhite" height="4"></td></tr><tr><td class="bckgdgrey1" height="1"></td></tr> 
    22: lib.leftmenu.20.2.NO { 
    23:   wrap = <tr><td class="bckgdwhite" height="4"></td></tr><tr><td>|</td></tr> 
    24:   XY = 163,16 
    25:   backColor = white 
    26:   10 = TEXT 
    27:   10.text.field = title 
    28:   10.text.case = upper 
    29:   10.fontColor = #666666 
    30:   10.fontFile = fileadmin/fonts/ARIALNB.TTF 
    31:   10.niceText = 1 
    32:   10.offset = 14,12 
    33:   10.fontSize = 11 
    34: } 
    35: lib.leftmenu.20.2.RO < lib.leftmenu.20.2.NO 
    36: lib.leftmenu.20.2.RO = 1 
    37: lib.leftmenu.20.2.RO.backColor = #eeeeee 
    38: lib.leftmenu.20.2.ACT < lib.leftmenu.20.2.NO 
    39: lib.leftmenu.20.2.ACT = 1 
    40: lib.leftmenu.20.2.ACT.10.fontColor = red 
    41: lib.leftmenu.20.3 = TMENU 
    42: lib.leftmenu.20.3.NO { 
    43:   allWrap = <tr><td>|</td></tr> 
    44:   linkWrap ( 
    45:    <table border="0" cellpadding="0" cellspacing="0" style="margin: 2px; 0px; 2px; 0px;"> 
    46:       <tr> 
    47:         <td><img src="clear.gif" width="15" height="1" /></td> 
    48:         <td><img src="fileadmin/arrow_gray.gif" height="9" width="9" hspace="3" /></td> 
    49:         <td>|</td> 
    50:       </tr> 
    51:    </table> 
    52:   ) 
    53: } 
    

The menu looks like this on a webpage:


The TypoScript code above generates this menu, but the items does not link straight to pages as usual. This is because the whole menu is generated from this array, which was returned from the function "menuMenuArray" called in TypoScript line 4+5

 

     1:     function makeMenuArray($content,$conf)    { 
     2:         return array( 
     3:             array( 
     4:                 'title' => 'Contact', 
     5:                 '_OVERRIDE_HREF' => 'index.php?id=10', 
     6:                 '_SUB_MENU' => array( 
     7:                     array( 
     8:                         'title' => 'Offices', 
     9:                         '_OVERRIDE_HREF' => 'index.php?id=11', 
    10:                         '_OVERRIDE_TARGET' => '_top', 
    11:                         'ITEM_STATE' => 'ACT', 
    12:                         '_SUB_MENU' => array( 
    13:                             array( 
    14:                                 'title' => 'Copenhagen Office', 
    15:                                 '_OVERRIDE_HREF' => 'index.php?id=11&officeId=cph', 
    16:                             ), 
    17:                             array( 
    18:                                 'title' => 'Paris Office', 
    19:                                 '_OVERRIDE_HREF' => 'index.php?id=11&officeId=paris', 
    20:                             ), 
    21:                             array( 
    22:                                 'title' => 'New York Office', 
    23:                                 '_OVERRIDE_HREF' => 'http://www.newyork-office.com', 
    24:                                 '_OVERRIDE_TARGET' => '_blank', 
    25:                             ) 
    26:                         ) 
    27:                     ), 
    28:                     array( 
    29:                         'title' => 'Form', 
    30:                         '_OVERRIDE_HREF' => 'index.php?id=10&cmd=showform', 
    31:                     ), 
    32:                     array( 
    33:                         'title' => 'Thank you', 
    34:                         '_OVERRIDE_HREF' => 'index.php?id=10&cmd=thankyou', 
    35:                     ), 
    36:                 ), 
    37:             ), 
    38:             array( 
    39:                 'title' => 'Products', 
    40:                 '_OVERRIDE_HREF' => 'index.php?id=14', 
    41:             ) 
    42:         ); 
    43:     } 
    

Notice how the array contains "fake" page-records which has no uid field, only a "title" and "_OVERRIDE_HREF" as required and some other fields as it fits.

  1. The first level with items "Contact" and "Products" contains "title" and "_OVERRIDE_HREF" fields, but "Contact" extends this by a "_SUB_MENU" array which contains a similar array of items.

  2. The first item on the second level, "Offices", contains a field called "_OVERRIDE_TARGET". Further the item has its state set to "ACT" which means it will render as an "active" item (you will have to calculate such stuff manually when you are not rendering a menu of real pages!). Finally there is even another sub-level of menu items.


Valid XHTML 1.0!