mirror of
https://github.com/canonical/canonical.com.git
synced 2025-08-16 16:46:05 +00:00

* 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
327 lines
12 KiB
HTML
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 %} |