Files
canonical-canonical.com/templates/maas/docs/base_docs.html
Peter French 33810b3cd7 feat: Migrate maas.io to /maas (#1772)
* feat: Migrate maas.io to /maas

* Fix linters

* Address review comments

* fix: Don't perge venbox styles

* fix: Address review comments

* fix: Remove brokenn link from /resources
2025-07-11 10:32:13 +02:00

327 lines
12 KiB
HTML

{% extends "base_index.html" %}
{% block page_class %}docs{% endblock page_class %}
{% set is_docs = True %}
{% block body %}
{% macro create_navigation(nav_items, expandable=False, expanded=False) %}
{% if request.path == '/docs/api' %}
{% set expanded = False %}
{% endif %}
<ul class="p-side-navigation__list">
{% for element in nav_items %}
<li class="p-side-navigation__item">
{% if element.navlink_href %}
<a
class="p-side-navigation__link {% if expandable and element.children %}is-expandable{% endif %}"
href="{{ element.navlink_href }}"
{% if expandable and element.children %}aria-expanded={% if expanded or element.is_active %}"true"{% else %}"false"{% endif %}{% endif %}
{% if element.is_active and not element.navlink_fragment %}aria-current="page"{% endif %}
>{{ element.navlink_text }}</a>
{% else %}
<strong
class="p-side-navigation__text {% if expandable and element.children %}is-expandable{% endif %}"
{% if expandable and element.children %}aria-expanded={% if expanded %}"true"{% else %}"false"{% endif %}{% endif %}
{% if element.is_active %}aria-current="page"{% endif %}
>{{ element.navlink_text }}</strong>
{% endif %}
{% if expandable %}
{% if element.children %}
<button class="p-side-navigation__expand" aria-expanded={% if element.is_active or element.has_active_child %}"true"{% else %}"false"{% endif %} aria-label="show submenu for {{ element.navlink_text }}"></button>
{% endif %}
{{ create_navigation(element.children, expandable, element.is_active or element.has_active_child) }}
{% else %}
{% if element.children %}
{{ create_navigation(element.children, expandable) }}
{% endif %}
{% endif %}
</li>
{% endfor %}
</ul>
{% endmacro %}
<div class="l-docs">
<div class="l-docs__header">
{% include "includes/header.html" %}
<section id="search-docs" class="p-strip--light is-shallow is-bordered l-docs__subgrid">
<div class="l-docs__main">
<div class="row">
<form class="p-search-box u-no-margin--bottom" action="/docs/search">
<input type="search" class="p-search-box__input" name="q" {% if query %}value="{{ query }}"{% endif %} placeholder="Search documentation" required/>
<button type="reset" class="p-search-box__reset" alt="reset"><i class="p-icon--close">Close</i></button>
<button type="submit" class="p-search-box__button" alt="search"><i class="p-icon--search">Search</i></button>
</form>
</div>
</div>
</section>
</div>
<div class="l-docs__sidebar">
<div class="l-docs__sticky-container">
{% if versions | length > 1 %}
<label for="version-select" class="u-hide">Version</label>
<select name="version-select" id="version-select" onChange="window.location.href=this.value">
{% for version in versions %}
{% set active = docs_version == version['path'] %}
<option value="{{ version_paths[version['path']] }}"{% if active %} selected{% endif %}>{{ version['version'] }}</option>
{% endfor %}
</select>
{% endif %}
<nav data-js="navigation" class="p-side-navigation" id="{{ navigation['path'] or 'default' }}" style="margin-top: 0.5rem">
<div class="u-fixed-width">
<a href="#{{ navigation['path'] or 'default' }}" class="p-side-navigation__toggle js-drawer-toggle" aria-controls="{{ navigation['path'] or 'default' }}">
Toggle side navigation
</a>
</div>
<div class="p-side-navigation__overlay js-drawer-toggle" aria-controls="{{ navigation['path'] or 'default' }}"></div>
<div class="p-side-navigation__drawer">
<div class="p-side-navigation__drawer-header">
<a href="#" class="p-side-navigation__toggle--in-drawer js-drawer-toggle" aria-controls="{{ navigation['path'] or 'default' }}">
Toggle side navigation
</a>
</div>
{% for nav_group in navigation.nav_items %}
{% if not nav_group.hidden %}
{% if nav_group.navlink_text %}
{% if nav_group.navlink_href %}
<h3 class="p-side-navigation__heading--linked">
<a class="p-side-navigation__link" href="{{ nav_group.navlink_href }}" {% if nav_group.is_active %}aria-current="page"{% endif %}>
{{ nav_group.navlink_text }}
</a>
</h3>
{% else %}
<h3 class="p-side-navigation__heading">{{ nav_group.navlink_text }}</h3>
{% endif %}
{% endif %}
{#
Use `create_navigation(nav_group.children)` for a default, fully expanded navigation.
Use `create_navigation(nav_group.children, expandable=True)` for the nested nav levels to expand only when parent page is active.
#}
{{ create_navigation(nav_group.children, expandable=True) }}
{% endif %}
{% endfor %}
</div>
</nav>
</div>
</div>
<div class="l-docs__title">
<div class="p-section--shallow">
<div class="u-fixed-width">
{% block title %}{% endblock %}
</div>
</div>
</div>
{% if document is defined and document.headings_map is defined and document.headings_map|length > 0 %}
<div class="l-docs__meta">
<div class="l-docs__sticky-container">
<aside class="p-table-of-contents">
<div class="p-table-of-contents__section">
<h4 class="p-table-of-contents__header">On this page</h4>
<nav class="p-table-of-contents__nav" aria-label="Table of contents">
<ul class="p-table-of-contents__list">
{% for heading in document.headings_map %}
<li class="p-table-of-contents__item"><a class="p-table-of-contents__link" href="#{{ heading.heading_slug }}">{{ heading.heading_text }}</a></li>
{% if heading.children %}
<ul class="p-table-of-contents__list">
{% for child in heading.children %}
<li class="p-table-of-contents__item"><a href="#{{ child.heading_slug }}" class="p-table-of-contents__link">{{ child.heading_text }}</a></li>
{% endfor %}
</ul>
{% endif %}
{% endfor %}
</ul>
</nav>
</div>
</aside>
</div>
</div>
{% endif %}
{% block content %}{% endblock content %}
<div class="l-docs__footer">
{% include "includes/footer.html" %}
</div>
</div>
{% block js_extra %}
<script src="/static/js/highlight.pack.js"></script>
<script>
hljs.initHighlightingOnLoad();
window.addEventListener("DOMContentLoaded", function() {
// Based on Vanilla side navigation example
// Should be moved out from the template as part of a given project JS
/**
Toggles the expanded/collapsed classed on side navigation element.
@param {HTMLElement} sideNavigation The side navigation element.
@param {Boolean} show Whether to show or hide the drawer.
*/
function toggleDrawer(sideNavigation, show) {
const toggleButtonOutsideDrawer = sideNavigation.querySelector(
".p-side-navigation__toggle"
);
const toggleButtonInsideDrawer = sideNavigation.querySelector(
".p-side-navigation__toggle--in-drawer"
);
if (sideNavigation) {
if (show) {
sideNavigation.classList.remove("is-drawer-collapsed");
sideNavigation.classList.add("is-drawer-expanded");
toggleButtonInsideDrawer.focus();
toggleButtonOutsideDrawer.setAttribute("aria-expanded", true);
toggleButtonInsideDrawer.setAttribute("aria-expanded", true);
} else {
sideNavigation.classList.remove("is-drawer-expanded");
sideNavigation.classList.add("is-drawer-collapsed");
toggleButtonOutsideDrawer.focus();
toggleButtonOutsideDrawer.setAttribute("aria-expanded", false);
toggleButtonInsideDrawer.setAttribute("aria-expanded", false);
}
}
}
// throttle util (for window resize event)
var throttle = function (fn, delay) {
var timer = null;
return function () {
var context = this,
args = arguments;
clearTimeout(timer);
timer = setTimeout(function () {
fn.apply(context, args);
}, delay);
};
};
/**
Attaches event listeners for the side navigation toggles
@param {HTMLElement} sideNavigation The side navigation element.
*/
function setupSideNavigation(sideNavigation) {
var toggles = [].slice.call(
sideNavigation.querySelectorAll(".js-drawer-toggle")
);
var drawerEl = sideNavigation.querySelector(".p-side-navigation__drawer");
// hide navigation drawer on small screens
sideNavigation.classList.add("is-drawer-hidden");
// setup drawer element
drawerEl.addEventListener("animationend", () => {
if (!sideNavigation.classList.contains("is-drawer-expanded")) {
sideNavigation.classList.add("is-drawer-hidden");
}
});
window.addEventListener("keydown", (e) => {
if (e.key === "Escape") {
toggleDrawer(sideNavigation, false);
}
});
// setup toggle buttons
toggles.forEach(function (toggle) {
toggle.addEventListener("click", function (event) {
event.preventDefault();
if (sideNavigation) {
sideNavigation.classList.remove("is-drawer-hidden");
toggleDrawer(
sideNavigation,
!sideNavigation.classList.contains("is-drawer-expanded")
);
}
});
});
// hide side navigation drawer when screen is resized
window.addEventListener(
"resize",
throttle(function () {
toggles.forEach((toggle) => {
return toggle.setAttribute("aria-expanded", false);
});
// remove expanded/collapsed class names to avoid unexpected animations
sideNavigation.classList.remove("is-drawer-expanded");
sideNavigation.classList.remove("is-drawer-collapsed");
sideNavigation.classList.add("is-drawer-hidden");
}, 10)
);
}
/**
Attaches event listeners for all the side navigations in the document.
@param {String} sideNavigationSelector The CSS selector matching side navigation elements.
*/
function setupSideNavigations(sideNavigationSelector) {
// Setup all side navigations on the page.
var sideNavigations = [].slice.call(
document.querySelectorAll(sideNavigationSelector)
);
sideNavigations.forEach(setupSideNavigation);
}
setupSideNavigations('.p-side-navigation, [class*="p-side-navigation--"]');
// Setup expandable side navigation
var expandToggles = document.querySelectorAll(".p-side-navigation__expand");
var navigationLinks = document.querySelectorAll(".p-side-navigation__link");
// setup default values of aria-expanded for the toggle button, list title and list itself
const setup = (toggle) => {
const isExpanded = toggle.getAttribute("aria-expanded") === "true";
if (!isExpanded) {
toggle.setAttribute("aria-expanded", isExpanded);
}
const item = toggle.closest(".p-side-navigation__item");
const link = item.querySelector(".p-side-navigation__link");
const nestedList = item.querySelector(".p-side-navigation__list");
if (!link?.hasAttribute("aria-expanded")) {
link.setAttribute("aria-expanded", isExpanded);
}
if (!nestedList?.hasAttribute("aria-expanded")) {
nestedList.setAttribute("aria-expanded", isExpanded);
}
};
const handleToggle = (e) => {
const item = e.currentTarget.closest(".p-side-navigation__item");
const button = item.querySelector(".p-side-navigation__expand");
const link = item.querySelector(".p-side-navigation__link");
const nestedList = item.querySelector(".p-side-navigation__list");
[button, link, nestedList].forEach((el) =>
el.setAttribute(
"aria-expanded",
el.getAttribute("aria-expanded") === "true" ? "false" : "true"
)
);
};
expandToggles.forEach((toggle) => {
setup(toggle);
toggle.addEventListener("click", (e) => {
handleToggle(e);
});
});
});
</script>
<script src="/static/js/modules/discourse-rad-parser/discourse-rad-parser.js"></script>
<script>
drpNs.DiscourseRADParser();
</script>
{% endblock js_extra %}
{% endblock body %}