navbar.html| Commit | Message |
|---|---|
ac75fabf3 | 2021-08-10 Jekyll site migration |
site.data.navigation_header — a YAML file (_data/navigation_header.yml). The template iterates over .left and .right arrays, rendering links, dropdowns, and buttons dynamically. Changing the nav is a YAML edit, not an HTML edit.<div data-uk-navbar> <!-- UIkit flex container -->
<div class="uk-navbar-left"> <!-- ZONE 1: Logo + desktop nav links -->
<a class="uk-logo uk-visible@m"> <!-- Logo (desktop only) -->
<a class="uk-navbar-toggle uk-hidden@m"> <!-- Hamburger (mobile only) -->
<ul class="uk-navbar-nav uk-visible@m"> <!-- LEFT nav items from YAML -->
</div>
<div class="uk-navbar-center uk-hidden@m"> <!-- ZONE 2: Logo (mobile center) -->
</div>
<div class="uk-navbar-right"> <!-- ZONE 3: Search + RIGHT nav items -->
<!-- SimpleJekyllSearch toggle -->
<ul class="uk-navbar-nav uk-visible@m"> <!-- RIGHT nav items from YAML -->
<a class="uk-navbar-toggle uk-hidden@m"> <!-- Mobile site nav toggle -->
</div>
</div>{% for link in site.data.navigation_header.left %} <!-- Iterate YAML data -->
{% if link.url contains 'http' %} <!-- External link detection -->
{% assign domain = '' %} <!-- No relative_url for http links -->
{% else %}
{% assign domain = '' | relative_url %} <!-- Prepend base URL for internal -->
{% endif %}
{% if link.url == page.url %} <!-- Active page detection -->
{% assign current = ' class="uk-active"' %} <!-- Highlight current page -->
{% endif %}
{% if link.button %} <!-- Button-styled nav item -->
<li><a class="uk-button uk-button-{{ link.button }}"> <!-- Dynamic button style -->
{% elsif link.url %}
<li{{ current }}><a href="{{ domain }}{{ link.url }}"> <!-- Standard nav link -->
{% else %}
<!-- Dropdown: link without URL → section header -->
<div class="uk-navbar-dropdown">
{% for child in link.dropdown %} <!-- Nested loop for children -->
{% if child.url %}
<li><a href="...">{{ child.title }}</a></li>
{% else %}
<li class="uk-nav-header">{{ child.title }}</li> <!-- Section header -->
{% endif %}
{% endfor %}
</div>
{% endif %}
{% endfor %}The nav rendering logic has three branches per link item:
| Branch | Condition | Renders |
|---|---|---|
| Button | link.button is set | A button-styled nav item (.uk-button-{{ link.button }}). Button style (primary/secondary/danger) comes from YAML. |
| Standard link | link.url exists, no button | A regular <a> link. Gets .uk-active class if link.url == page.url. |
| Dropdown | Neither url nor button | A dropdown menu with nested {% for %} loop. Children with URLs become links; children without become .uk-nav-header section headers. |
External link detection: {% if link.url contains 'http' %} — if the URL contains http, domain is set to empty string (the URL is absolute). Otherwise, relative_url filter prepends the site's base URL. This gracefully handles both internal doc links and external links (GitHub, SourceForge).
Active page detection: {% if link.url == page.url %} — exact string comparison between the link's URL and the current page's URL. If they match, the .uk-active class is added, which UIkit styles with the active nav item appearance. This is simple but fragile — it won't match if one URL has a trailing slash and the other doesn't.
<script>
SimpleJekyllSearch({
searchInput: document.getElementById('search-navbar'),
resultsContainer: document.getElementById('search-navbar-results'),
noResultsText: '...',
searchResultTemplate: '<li><a href="{url}">{title}</a></li>',
json: "{{ '/search.json' | relative_url }}"
});
searchResults("search-navbar");
</script>Two different search implementations coexist on the site:
| Search | Library | Where | Data source |
|---|---|---|---|
| Navbar search | SimpleJekyllSearch | Navbar toggle (desktop) | search.json (#4094) |
| Page search | Tipue Search | /search/ (#4093) | search.json (#4094) |
Both use the SAME data source (search.json) but different JavaScript libraries. SimpleJekyllSearch is simpler — it takes a JSON file, an input element, and a results container, and does client-side filtering. It's used in the navbar because it's lighter than Tipue and works well for a compact dropdown results list.
The searchResults("search-navbar") call on line 86 is a custom function (not from SimpleJekyllSearch) — likely defined elsewhere to handle the toggle behavior (show/hide results on input focus).
The navbar has TWO separate mobile menus:
| Toggle | Target | Visible text |
|---|---|---|
| Left hamburger | #offcanvas-docs | "Documentation" (from site.data.translation[site.lang].mobile_nav_docs) |
| Right hamburger | #offcanvas | "Site" (from site.data.translation[site.lang].mobile_nav_site) |
This dual-menu pattern separates documentation navigation from site navigation on mobile — a thoughtful UX decision. The translation keys (mobile_nav_docs, mobile_nav_site) enable multi-language support. If translations are absent (lines 9-10, 143-144), the hamburger appears without text — just the icon.
The offcanvas panels themselves are defined in separate include files (offcanvas.html, offcanvas-docs.html), not in this template.
data-uk-sticky="animation: uk-animation-slide-top; sel-target: .uk-navbar-container; cls-active: uk-navbar-sticky; cls-inactive: uk-navbar-transparent; top: 200"
UIkit's Sticky component is configured via a data attribute string with semicolon-separated parameters:
animation: uk-animation-slide-top — when the navbar becomes sticky (user scrolls past 200px), it slides down from the top with a smooth animation.sel-target: .uk-navbar-container — the sticky behavior applies to the inner .uk-navbar-container, not the outer wrapper <div>. This keeps the wrapper in flow while the container becomes fixed.cls-active: uk-navbar-sticky — when stuck, this class is added (themed by sticky.scss #4076 to add a shadow).cls-inactive: uk-navbar-transparent — when not stuck (at the top), the navbar is transparent. This creates a "reveal on scroll" effect.top: 200 — the navbar becomes sticky after the user scrolls 200px. This delay prevents the sticky transition from being too aggressive on short pages.
The navbar has 5 logical zones arranged via UIkit's flex navbar component. Zones 1 and 3 are the main content areas (desktop), zone 2 is a mobile-only centered logo, and zones 4-5 are implicit (the search dropdown and mobile offcanvas toggle).
The
uk-visible@m/uk-hidden@mpattern appears throughout — desktop elements are hidden on mobile, mobile elements are hidden on desktop. The breakpoint@mis 960px (from$breakpoint-mediumin variables.scss #4091).