Building sites

Menus

A menu is a list of links editors arrange under Menus, with submenus. The theme declares the areas menus go in (a main menu and a footer menu to start with), and a header, footer or page shows an area, never a menu: choosing which menu fills an area changes every page that shows it, and nobody edits the part.

Areas

The areas are part of the theme's tokens (menu_areas: each area's id and name), so they publish with the theme and sync with its file. Add, rename or remove one under Theme → Colours & type → Header & footer; an area's id is how parts and code name it, so renaming keeps it. Kits keep the site's areas.

The Areas card at the top of the Menus screen says which menu fills each one and changes it. An area is filled by one menu: giving a menu an area takes it from the menu that had it (each change a revision of both).

Items

Each item has a label and links to one of:

  • a page of the site, kept by its id, so moving or renaming the page keeps the link right;
  • an entry of a content type, also by id;
  • an address: a path, a web address, mailto:, tel: or #section;
  • nothing: the item heads the items under it (its label opens them when submenus are buttons).

An item linking to a page or entry may leave its label empty to show the page's or entry's title. Items nest four levels deep: the arrows move an item (with what is under it) up and down, into the submenu of the item above, or out of its submenu; the plus adds an item under it. The gear shows two more settings: a class for the item's list element, for a site's own CSS, and open in a new tab.

Menus are drawn into pages every visitor is served from the cache, so a link to a page or entry that is a draft, or not for everyone, is left out until it is published for everyone; an item that loses its link but has items under it still heads them. Saving a menu puts it live at once and keeps a revision; History brings an earlier one back, and Compare shows the items added, removed and changed since. Changing menus needs the theme permissions (edit and publish), which editors have; the screen is open to the rest of the staff to look at.

Showing a menu

  • The Navigation widget (nav) with its Menu setting (menu, an area's id) shows that area. Without one it shows the page navigation.
  • The built-in header, used until a header part is published, shows the main area once a menu fills it.
  • Custom code places an area with <gansey-menu area="main"></gansey-menu> (see Menus in code under The page builder).

The widget writes a <nav> holding the menu's list:

<nav class="gsy-nav gsy-nav-horizontal gsy-nav-toggles" aria-label="Main" data-gsy-menu="main" data-gsy-dismiss>
  <ul class="gsy-nav-list" data-gsy-open="gsy-open">
    <li><a href="/" aria-current="page" class="gsy-current">Home</a></li>
    <li class="gsy-nav-parent">
      <button type="button" class="gsy-nav-toggle gsy-nav-label" aria-expanded="false" aria-controls="gsy-menu-w1-1" data-gsy-toggle>Courses</button>
      <ul class="gsy-nav-sub" id="gsy-menu-w1-1">
        <li><a href="/courses">About courses</a></li>
        …
      </ul>
    </li>
    <li class="gsy-nav-parent">
      <a href="/venison">Venison</a>
      <button type="button" class="gsy-nav-toggle" aria-expanded="false" aria-controls="gsy-menu-w1-2" aria-label="Venison submenu" data-gsy-toggle></button>
      <ul class="gsy-nav-sub" id="gsy-menu-w1-2">…</ul>
    </li>
  </ul>
</nav>

Submenus (submenus) open on hover and keyboard focus (dropdown, CSS alone), with a button (toggle), or are always shown nested (open, for footers and slide-out panels styled by the site). A button sits beside an item that links somewhere; an item that links nowhere is the button itself. The bundled gansey-menu.js runs the buttons, and pages load it only when they have one: a click sets aria-expanded and gives the item the classes the list names in data-gsy-open, opening one closes the others open beside it, Escape closes the submenu the focus is in, and in a row of dropdowns (data-gsy-dismiss) a click elsewhere closes it. Markup of your own works with it too: any [data-gsy-toggle] button with aria-controls, inside an li.

Folding behind a menu button (collapse): on tablets and phones (tablet, below 1024px) or phones only (mobile, below 768px) the links fold away behind a button with three bars, which opens them below it (collapse_style: dropdown) or in a panel down the right-hand side of the screen with a shade over the page (drawer). The button's name (burger_label, default "Menu") is read out, and shown beside the bars with burger_show_label. Opening moves the focus to the first link; Escape, a click outside, the drawer's close button or following a link closes it. Folded menus show their submenus nested under each item, unless submenus are buttons. The built-in header folds its links like this on phones. The menu is drawn as

<nav class="gsy-nav gsy-nav-horizontal gsy-nav-collapse gsy-collapse-mobile gsy-collapse-dropdown" aria-label="Main">
  <button type="button" class="gsy-nav-burger" aria-expanded="false" aria-controls="gsy-menu-w1-panel" data-gsy-burger>…</button>
  <div class="gsy-nav-panel" id="gsy-menu-w1-panel"><ul class="gsy-nav-list">…</ul></div>
</nav>

and gansey-menu.js runs the button (any [data-gsy-burger] button with aria-controls naming the panel, in your own markup too), marking the nav gsy-nav-open. A page read without scripts shows the links instead of the button. A plain menu keeps the folding classes, which say when the button shows.

Look (look): gansey styles the menu with the theme's tokens (gsy-nav-* classes). plain writes none of core's classes, only those you give, for a site's own CSS or an old design's stylesheet.

Classes (classes) go on the menu's elements, each a space-separated list: nav (the nav element), list (the top list), item (every item), link (every link), parent (items with a submenu), sub (every submenu), current (the link to the page being shown), current_parent (the items above it), open (an item a button opened), toggle (the buttons), and for a folding menu burger (its menu button) and panel (the panel its links sit in). With these and each item's own class, a plain menu can carry an old design's markup: classes: { "list": "nav_main", "sub": "hide", "open": "show", "current": "active" } and an item class courses-overview give the classes its CSS expects.

On a site deployed from git, each menu is a definition file, menus/<slug>.menu.json (see The files), merged at every deploy like a part: an item changed on one side and another changed on the other both stay. Assistants change menus with the save_menu tool (Design area).