fix queries
This commit is contained in:
1 parent
2f473f7c97
commit
037a248ad9
294 files changed
+60706
-263
No files matched your search
@@ -0,0 +1 @@
|
||||
This file makes sure that Github Pages doesn't process mdBook's output.
|
||||
@@ -0,0 +1,186 @@
|
||||
<!DOCTYPE HTML>
|
||||
<html lang="en" class="sidebar-visible no-js light">
|
||||
<head>
|
||||
<!-- Book generated using mdBook -->
|
||||
<meta charset="UTF-8">
|
||||
<title></title>
|
||||
<base href="/">
|
||||
|
||||
|
||||
<!-- Custom HTML head -->
|
||||
|
||||
<meta content="text/html; charset=utf-8" http-equiv="Content-Type">
|
||||
<meta name="description" content="">
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1">
|
||||
<meta name="theme-color" content="#ffffff" />
|
||||
|
||||
<link rel="icon" href="favicon.svg">
|
||||
<link rel="shortcut icon" href="favicon.png">
|
||||
<link rel="stylesheet" href="css/variables.css">
|
||||
<link rel="stylesheet" href="css/general.css">
|
||||
<link rel="stylesheet" href="css/chrome.css">
|
||||
<link rel="stylesheet" href="css/print.css" media="print">
|
||||
|
||||
<!-- Fonts -->
|
||||
<link rel="stylesheet" href="FontAwesome/css/font-awesome.css">
|
||||
<link rel="stylesheet" href="fonts/fonts.css">
|
||||
|
||||
<!-- Highlight.js Stylesheets -->
|
||||
<link rel="stylesheet" href="highlight.css">
|
||||
<link rel="stylesheet" href="tomorrow-night.css">
|
||||
<link rel="stylesheet" href="ayu-highlight.css">
|
||||
|
||||
<!-- Custom theme stylesheets -->
|
||||
|
||||
</head>
|
||||
<body>
|
||||
<!-- Provide site root to javascript -->
|
||||
<script type="text/javascript">
|
||||
var path_to_root = "";
|
||||
var default_theme = window.matchMedia("(prefers-color-scheme: dark)").matches ? "navy" : "light";
|
||||
</script>
|
||||
|
||||
<!-- Work around some values being stored in localStorage wrapped in quotes -->
|
||||
<script type="text/javascript">
|
||||
try {
|
||||
var theme = localStorage.getItem('mdbook-theme');
|
||||
var sidebar = localStorage.getItem('mdbook-sidebar');
|
||||
|
||||
if (theme.startsWith('"') && theme.endsWith('"')) {
|
||||
localStorage.setItem('mdbook-theme', theme.slice(1, theme.length - 1));
|
||||
}
|
||||
|
||||
if (sidebar.startsWith('"') && sidebar.endsWith('"')) {
|
||||
localStorage.setItem('mdbook-sidebar', sidebar.slice(1, sidebar.length - 1));
|
||||
}
|
||||
} catch (e) { }
|
||||
</script>
|
||||
|
||||
<!-- Set the theme before any content is loaded, prevents flash -->
|
||||
<script type="text/javascript">
|
||||
var theme;
|
||||
try { theme = localStorage.getItem('mdbook-theme'); } catch(e) { }
|
||||
if (theme === null || theme === undefined) { theme = default_theme; }
|
||||
var html = document.querySelector('html');
|
||||
html.classList.remove('no-js')
|
||||
html.classList.remove('light')
|
||||
html.classList.add(theme);
|
||||
html.classList.add('js');
|
||||
</script>
|
||||
|
||||
<!-- Hide / unhide sidebar before it is displayed -->
|
||||
<script type="text/javascript">
|
||||
var html = document.querySelector('html');
|
||||
var sidebar = 'hidden';
|
||||
if (document.body.clientWidth >= 1080) {
|
||||
try { sidebar = localStorage.getItem('mdbook-sidebar'); } catch(e) { }
|
||||
sidebar = sidebar || 'visible';
|
||||
}
|
||||
html.classList.remove('sidebar-visible');
|
||||
html.classList.add("sidebar-" + sidebar);
|
||||
</script>
|
||||
|
||||
<nav id="sidebar" class="sidebar" aria-label="Table of contents">
|
||||
<div class="sidebar-scrollbox">
|
||||
<ol class="chapter"><li class="chapter-item expanded affix "><a href="index.html">Introduction</a></li><li class="chapter-item expanded affix "><li class="part-title">Features</li><li class="chapter-item expanded "><a href="features/index.html"><strong aria-hidden="true">1.</strong> Adding the Router to Your Application</a></li><li class="chapter-item expanded "><a href="features/routes/index.html"><strong aria-hidden="true">2.</strong> Defining Routes</a></li><li><ol class="section"><li class="chapter-item expanded "><a href="features/routes/nested.html"><strong aria-hidden="true">2.1.</strong> Nested Routes</a></li><li class="chapter-item expanded "><a href="features/routes/catch_all.html"><strong aria-hidden="true">2.2.</strong> Catch All Routes</a></li><li class="chapter-item expanded "><a href="features/routes/matching.html"><strong aria-hidden="true">2.3.</strong> Matching Routes</a></li><li class="chapter-item expanded "><a href="features/routes/fallback.html"><strong aria-hidden="true">2.4.</strong> Fallback Routes (404 page)</a></li><li class="chapter-item expanded "><a href="features/routes/multiple-and-redirect.html"><strong aria-hidden="true">2.5.</strong> Multiple Components & Redirects</a></li></ol></li><li class="chapter-item expanded "><a href="features/outlets.html"><strong aria-hidden="true">3.</strong> Outlets</a></li><li class="chapter-item expanded "><a href="features/navigation/index.html"><strong aria-hidden="true">4.</strong> Links & Navigation</a></li><li><ol class="section"><li class="chapter-item expanded "><a href="features/navigation/name.html"><strong aria-hidden="true">4.1.</strong> Named Navigation</a></li><li class="chapter-item expanded "><a href="features/navigation/external.html"><strong aria-hidden="true">4.2.</strong> External Navigation</a></li><li class="chapter-item expanded "><a href="features/navigation/programmatic.html"><strong aria-hidden="true">4.3.</strong> Programmatic Navigation</a></li></ol></li><li class="chapter-item expanded "><a href="features/query.html"><strong aria-hidden="true">5.</strong> Query</a></li><li class="chapter-item expanded "><a href="features/failures/index.html"><strong aria-hidden="true">6.</strong> Navigation Failures</a></li><li><ol class="section"><li class="chapter-item expanded "><a href="features/failures/named.html"><strong aria-hidden="true">6.1.</strong> Named Navigation Failure</a></li><li class="chapter-item expanded "><a href="features/failures/external.html"><strong aria-hidden="true">6.2.</strong> External Navigation Failure</a></li><li class="chapter-item expanded "><a href="features/failures/redirection-limit.html"><strong aria-hidden="true">6.3.</strong> Redirection Limit Failure</a></li></ol></li><li class="chapter-item expanded "><a href="features/history-providers.html"><strong aria-hidden="true">7.</strong> History Providers</a></li><li class="chapter-item expanded "><a href="features/history-buttons.html"><strong aria-hidden="true">8.</strong> History Buttons</a></li><li class="chapter-item expanded "><a href="features/sitemap-generation.html"><strong aria-hidden="true">9.</strong> Sitemap Generation</a></li><li class="chapter-item expanded "><a href="features/routing-update-callback.html"><strong aria-hidden="true">10.</strong> Routing Update Callback</a></li><li class="chapter-item expanded affix "><li class="part-title">Example Project</li><li class="chapter-item expanded "><a href="example/index.html"><strong aria-hidden="true">11.</strong> Overview</a></li><li class="chapter-item expanded "><a href="example/first-route.html"><strong aria-hidden="true">12.</strong> Creating Our First Route</a></li><li class="chapter-item expanded "><a href="example/building-a-nest.html"><strong aria-hidden="true">13.</strong> Building a Nest</a></li><li class="chapter-item expanded "><a href="example/navigation-targets.html"><strong aria-hidden="true">14.</strong> Navigation Targets</a></li><li class="chapter-item expanded "><a href="example/redirection-perfection.html"><strong aria-hidden="true">15.</strong> Redirection Perfection</a></li><li class="chapter-item expanded "><a href="example/full-code.html"><strong aria-hidden="true">16.</strong> Full Code</a></li></ol>
|
||||
</div>
|
||||
<div id="sidebar-resize-handle" class="sidebar-resize-handle"></div>
|
||||
</nav>
|
||||
|
||||
<div id="page-wrapper" class="page-wrapper">
|
||||
|
||||
<div class="page">
|
||||
<div id="menu-bar-hover-placeholder"></div>
|
||||
<div id="menu-bar" class="menu-bar sticky bordered">
|
||||
<div class="left-buttons">
|
||||
<button id="sidebar-toggle" class="icon-button" type="button" title="Toggle Table of Contents" aria-label="Toggle Table of Contents" aria-controls="sidebar">
|
||||
<i class="fa fa-bars"></i>
|
||||
</button>
|
||||
<button id="theme-toggle" class="icon-button" type="button" title="Change theme" aria-label="Change theme" aria-haspopup="true" aria-expanded="false" aria-controls="theme-list">
|
||||
<i class="fa fa-paint-brush"></i>
|
||||
</button>
|
||||
<ul id="theme-list" class="theme-popup" aria-label="Themes" role="menu">
|
||||
<li role="none"><button role="menuitem" class="theme" id="light">Light (default)</button></li>
|
||||
<li role="none"><button role="menuitem" class="theme" id="rust">Rust</button></li>
|
||||
<li role="none"><button role="menuitem" class="theme" id="coal">Coal</button></li>
|
||||
<li role="none"><button role="menuitem" class="theme" id="navy">Navy</button></li>
|
||||
<li role="none"><button role="menuitem" class="theme" id="ayu">Ayu</button></li>
|
||||
</ul>
|
||||
<button id="search-toggle" class="icon-button" type="button" title="Search. (Shortkey: s)" aria-label="Toggle Searchbar" aria-expanded="false" aria-keyshortcuts="S" aria-controls="searchbar">
|
||||
<i class="fa fa-search"></i>
|
||||
</button>
|
||||
</div>
|
||||
|
||||
<h1 class="menu-title">Dioxus Router</h1>
|
||||
|
||||
<div class="right-buttons">
|
||||
<a href="print.html" title="Print this book" aria-label="Print this book">
|
||||
<i id="print-button" class="fa fa-print"></i>
|
||||
</a>
|
||||
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div id="search-wrapper" class="hidden">
|
||||
<form id="searchbar-outer" class="searchbar-outer">
|
||||
<input type="search" id="searchbar" name="searchbar" placeholder="Search this book ..." aria-controls="searchresults-outer" aria-describedby="searchresults-header">
|
||||
</form>
|
||||
<div id="searchresults-outer" class="searchresults-outer hidden">
|
||||
<div id="searchresults-header" class="searchresults-header"></div>
|
||||
<ul id="searchresults">
|
||||
</ul>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- Apply ARIA attributes after the sidebar and the sidebar toggle button are added to the DOM -->
|
||||
<script type="text/javascript">
|
||||
document.getElementById('sidebar-toggle').setAttribute('aria-expanded', sidebar === 'visible');
|
||||
document.getElementById('sidebar').setAttribute('aria-hidden', sidebar !== 'visible');
|
||||
Array.from(document.querySelectorAll('#sidebar a')).forEach(function(link) {
|
||||
link.setAttribute('tabIndex', sidebar === 'visible' ? 0 : -1);
|
||||
});
|
||||
</script>
|
||||
|
||||
<div id="content" class="content">
|
||||
<main>
|
||||
<h1 id="document-not-found-404"><a class="header" href="#document-not-found-404">Document not found (404)</a></h1>
|
||||
<p>This URL is invalid, sorry. Please use the navigation bar or search to continue.</p>
|
||||
|
||||
</main>
|
||||
|
||||
<nav class="nav-wrapper" aria-label="Page navigation">
|
||||
<!-- Mobile navigation buttons -->
|
||||
|
||||
|
||||
<div style="clear: both"></div>
|
||||
</nav>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<nav class="nav-wide-wrapper" aria-label="Page navigation">
|
||||
|
||||
</nav>
|
||||
|
||||
</div>
|
||||
|
||||
|
||||
|
||||
|
||||
<script type="text/javascript">
|
||||
window.playground_copyable = true;
|
||||
</script>
|
||||
|
||||
|
||||
<script src="elasticlunr.min.js" type="text/javascript" charset="utf-8"></script>
|
||||
<script src="mark.min.js" type="text/javascript" charset="utf-8"></script>
|
||||
<script src="searcher.js" type="text/javascript" charset="utf-8"></script>
|
||||
|
||||
<script src="clipboard.min.js" type="text/javascript" charset="utf-8"></script>
|
||||
<script src="highlight.js" type="text/javascript" charset="utf-8"></script>
|
||||
<script src="book.js" type="text/javascript" charset="utf-8"></script>
|
||||
|
||||
<!-- Custom JS scripts -->
|
||||
|
||||
|
||||
</body>
|
||||
</html>
|
||||
@@ -0,0 +1,4 @@
|
||||
/*!
|
||||
* Font Awesome 4.7.0 by @davegandy - http://fontawesome.io - @fontawesome
|
||||
* License - http://fontawesome.io/license (Font: SIL OFL 1.1, CSS: MIT License)
|
||||
*/@font-face{font-family:'FontAwesome';src:url('../fonts/fontawesome-webfont.eot?v=4.7.0');src:url('../fonts/fontawesome-webfont.eot?#iefix&v=4.7.0') format('embedded-opentype'),url('../fonts/fontawesome-webfont.woff2?v=4.7.0') format('woff2'),url('../fonts/fontawesome-webfont.woff?v=4.7.0') format('woff'),url('../fonts/fontawesome-webfont.ttf?v=4.7.0') format('truetype'),url('../fonts/fontawesome-webfont.svg?v=4.7.0#fontawesomeregular') format('svg');font-weight:normal;font-style:normal}.fa{display:inline-block;font:normal normal normal 14px/1 FontAwesome;font-size:inherit;text-rendering:auto;-webkit-font-smoothing:antialiased;-moz-osx-font-smoothing:grayscale}.fa-lg{font-size:1.33333333em;line-height:.75em;vertical-align:-15%}.fa-2x{font-size:2em}.fa-3x{font-size:3em}.fa-4x{font-size:4em}.fa-5x{font-size:5em}.fa-fw{width:1.28571429em;text-align:center}.fa-ul{padding-left:0;margin-left:2.14285714em;list-style-type:none}.fa-ul>li{position:relative}.fa-li{position:absolute;left:-2.14285714em;width:2.14285714em;top:.14285714em;text-align:center}.fa-li.fa-lg{left:-1.85714286em}.fa-border{padding:.2em .25em .15em;border:solid .08em #eee;border-radius:.1em}.fa-pull-left{float:left}.fa-pull-right{float:right}.fa.fa-pull-left{margin-right:.3em}.fa.fa-pull-right{margin-left:.3em}.pull-right{float:right}.pull-left{float:left}.fa.pull-left{margin-right:.3em}.fa.pull-right{margin-left:.3em}.fa-spin{-webkit-animation:fa-spin 2s infinite linear;animation:fa-spin 2s infinite linear}.fa-pulse{-webkit-animation:fa-spin 1s infinite steps(8);animation:fa-spin 1s infinite steps(8)}@-webkit-keyframes fa-spin{0%{-webkit-transform:rotate(0deg);transform:rotate(0deg)}100%{-webkit-transform:rotate(359deg);transform:rotate(359deg)}}@keyframes fa-spin{0%{-webkit-transform:rotate(0deg);transform:rotate(0deg)}100%{-webkit-transform:rotate(359deg);transform:rotate(359deg)}}.fa-rotate-90{-ms-filter:"progid:DXImageTransform.Microsoft.BasicImage(rotation=1)";-webkit-transform:rotate(90deg);-ms-transform:rotate(90deg);transform:rotate(90deg)}.fa-rotate-180{-ms-filter:"progid:DXImageTransform.Microsoft.BasicImage(rotation=2)";-webkit-transform:rotate(180deg);-ms-transform:rotate(180deg);transform:rotate(180deg)}.fa-rotate-270{-ms-filter:"progid:DXImageTransform.Microsoft.BasicImage(rotation=3)";-webkit-transform:rotate(270deg);-ms-transform:rotate(270deg);transform:rotate(270deg)}.fa-flip-horizontal{-ms-filter:"progid:DXImageTransform.Microsoft.BasicImage(rotation=0, mirror=1)";-webkit-transform:scale(-1, 1);-ms-transform:scale(-1, 1);transform:scale(-1, 1)}.fa-flip-vertical{-ms-filter:"progid:DXImageTransform.Microsoft.BasicImage(rotation=2, mirror=1)";-webkit-transform:scale(1, -1);-ms-transform:scale(1, -1);transform:scale(1, -1)}:root .fa-rotate-90,:root .fa-rotate-180,:root .fa-rotate-270,:root .fa-flip-horizontal,:root .fa-flip-vertical{filter:none}.fa-stack{position:relative;display:inline-block;width:2em;height:2em;line-height:2em;vertical-align:middle}.fa-stack-1x,.fa-stack-2x{position:absolute;left:0;width:100%;text-align:center}.fa-stack-1x{line-height:inherit}.fa-stack-2x{font-size:2em}.fa-inverse{color:#fff}.fa-glass:before{content:"\f000"}.fa-music:before{content:"\f001"}.fa-search:before{content:"\f002"}.fa-envelope-o:before{content:"\f003"}.fa-heart:before{content:"\f004"}.fa-star:before{content:"\f005"}.fa-star-o:before{content:"\f006"}.fa-user:before{content:"\f007"}.fa-film:before{content:"\f008"}.fa-th-large:before{content:"\f009"}.fa-th:before{content:"\f00a"}.fa-th-list:before{content:"\f00b"}.fa-check:before{content:"\f00c"}.fa-remove:before,.fa-close:before,.fa-times:before{content:"\f00d"}.fa-search-plus:before{content:"\f00e"}.fa-search-minus:before{content:"\f010"}.fa-power-off:before{content:"\f011"}.fa-signal:before{content:"\f012"}.fa-gear:before,.fa-cog:before{content:"\f013"}.fa-trash-o:before{content:"\f014"}.fa-home:before{content:"\f015"}.fa-file-o:before{content:"\f016"}.fa-clock-o:before{content:"\f017"}.fa-road:before{content:"\f018"}.fa-download:before{content:"\f019"}.fa-arrow-circle-o-down:before{content:"\f01a"}.fa-arrow-circle-o-up:before{content:"\f01b"}.fa-inbox:before{content:"\f01c"}.fa-play-circle-o:before{content:"\f01d"}.fa-rotate-right:before,.fa-repeat:before{content:"\f01e"}.fa-refresh:before{content:"\f021"}.fa-list-alt:before{content:"\f022"}.fa-lock:before{content:"\f023"}.fa-flag:before{content:"\f024"}.fa-headphones:before{content:"\f025"}.fa-volume-off:before{content:"\f026"}.fa-volume-down:before{content:"\f027"}.fa-volume-up:before{content:"\f028"}.fa-qrcode:before{content:"\f029"}.fa-barcode:before{content:"\f02a"}.fa-tag:before{content:"\f02b"}.fa-tags:before{content:"\f02c"}.fa-book:before{content:"\f02d"}.fa-bookmark:before{content:"\f02e"}.fa-print:before{content:"\f02f"}.fa-camera:before{content:"\f030"}.fa-font:before{content:"\f031"}.fa-bold:before{content:"\f032"}.fa-italic:before{content:"\f033"}.fa-text-height:before{content:"\f034"}.fa-text-width:before{content:"\f03Line truncated
|
||||
Binary file not shown.
Binary file not shown.
File diff suppressed because it is too large.
Load diff
|
After Width: | Height: | Size: 434 KiB |
Binary file not shown.
Binary file not shown.
Binary file not shown.
@@ -0,0 +1,79 @@
|
||||
/*
|
||||
Based off of the Ayu theme
|
||||
Original by Dempfi (https://github.com/dempfi/ayu)
|
||||
*/
|
||||
|
||||
.hljs {
|
||||
display: block;
|
||||
overflow-x: auto;
|
||||
background: #191f26;
|
||||
color: #e6e1cf;
|
||||
padding: 0.5em;
|
||||
}
|
||||
|
||||
.hljs-comment,
|
||||
.hljs-quote {
|
||||
color: #5c6773;
|
||||
font-style: italic;
|
||||
}
|
||||
|
||||
.hljs-variable,
|
||||
.hljs-template-variable,
|
||||
.hljs-attribute,
|
||||
.hljs-attr,
|
||||
.hljs-regexp,
|
||||
.hljs-link,
|
||||
.hljs-selector-id,
|
||||
.hljs-selector-class {
|
||||
color: #ff7733;
|
||||
}
|
||||
|
||||
.hljs-number,
|
||||
.hljs-meta,
|
||||
.hljs-builtin-name,
|
||||
.hljs-literal,
|
||||
.hljs-type,
|
||||
.hljs-params {
|
||||
color: #ffee99;
|
||||
}
|
||||
|
||||
.hljs-string,
|
||||
.hljs-bullet {
|
||||
color: #b8cc52;
|
||||
}
|
||||
|
||||
.hljs-title,
|
||||
.hljs-built_in,
|
||||
.hljs-section {
|
||||
color: #ffb454;
|
||||
}
|
||||
|
||||
.hljs-keyword,
|
||||
.hljs-selector-tag,
|
||||
.hljs-symbol {
|
||||
color: #ff7733;
|
||||
}
|
||||
|
||||
.hljs-name {
|
||||
color: #36a3d9;
|
||||
}
|
||||
|
||||
.hljs-tag {
|
||||
color: #00568d;
|
||||
}
|
||||
|
||||
.hljs-emphasis {
|
||||
font-style: italic;
|
||||
}
|
||||
|
||||
.hljs-strong {
|
||||
font-weight: bold;
|
||||
}
|
||||
|
||||
.hljs-addition {
|
||||
color: #91b362;
|
||||
}
|
||||
|
||||
.hljs-deletion {
|
||||
color: #d96c75;
|
||||
}
|
||||
@@ -0,0 +1,762 @@
|
||||
"use strict";
|
||||
|
||||
// Fix back button cache problem
|
||||
window.onunload = function () { };
|
||||
|
||||
// Global variable, shared between modules
|
||||
function playground_text(playground) {
|
||||
let code_block = playground.querySelector("code");
|
||||
|
||||
if (window.ace && code_block.classList.contains("editable")) {
|
||||
let editor = window.ace.edit(code_block);
|
||||
return editor.getValue();
|
||||
} else {
|
||||
return code_block.textContent;
|
||||
}
|
||||
}
|
||||
|
||||
(function codeSnippets() {
|
||||
function fetch_with_timeout(url, options, timeout = 6000) {
|
||||
return Promise.race([
|
||||
fetch(url, options),
|
||||
new Promise((_, reject) => setTimeout(() => reject(new Error('timeout')), timeout))
|
||||
]);
|
||||
}
|
||||
|
||||
var playgrounds = Array.from(document.querySelectorAll(".playground"));
|
||||
if (playgrounds.length > 0) {
|
||||
fetch_with_timeout("https://play.rust-lang.org/meta/crates", {
|
||||
headers: {
|
||||
'Content-Type': "application/json",
|
||||
},
|
||||
method: 'POST',
|
||||
mode: 'cors',
|
||||
})
|
||||
.then(response => response.json())
|
||||
.then(response => {
|
||||
// get list of crates available in the rust playground
|
||||
let playground_crates = response.crates.map(item => item["id"]);
|
||||
playgrounds.forEach(block => handle_crate_list_update(block, playground_crates));
|
||||
});
|
||||
}
|
||||
|
||||
function handle_crate_list_update(playground_block, playground_crates) {
|
||||
// update the play buttons after receiving the response
|
||||
update_play_button(playground_block, playground_crates);
|
||||
|
||||
// and install on change listener to dynamically update ACE editors
|
||||
if (window.ace) {
|
||||
let code_block = playground_block.querySelector("code");
|
||||
if (code_block.classList.contains("editable")) {
|
||||
let editor = window.ace.edit(code_block);
|
||||
editor.addEventListener("change", function (e) {
|
||||
update_play_button(playground_block, playground_crates);
|
||||
});
|
||||
// add Ctrl-Enter command to execute rust code
|
||||
editor.commands.addCommand({
|
||||
name: "run",
|
||||
bindKey: {
|
||||
win: "Ctrl-Enter",
|
||||
mac: "Ctrl-Enter"
|
||||
},
|
||||
exec: _editor => run_rust_code(playground_block)
|
||||
});
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// updates the visibility of play button based on `no_run` class and
|
||||
// used crates vs ones available on http://play.rust-lang.org
|
||||
function update_play_button(pre_block, playground_crates) {
|
||||
var play_button = pre_block.querySelector(".play-button");
|
||||
|
||||
// skip if code is `no_run`
|
||||
if (pre_block.querySelector('code').classList.contains("no_run")) {
|
||||
play_button.classList.add("hidden");
|
||||
return;
|
||||
}
|
||||
|
||||
// get list of `extern crate`'s from snippet
|
||||
var txt = playground_text(pre_block);
|
||||
var re = /extern\s+crate\s+([a-zA-Z_0-9]+)\s*;/g;
|
||||
var snippet_crates = [];
|
||||
var item;
|
||||
while (item = re.exec(txt)) {
|
||||
snippet_crates.push(item[1]);
|
||||
}
|
||||
|
||||
// check if all used crates are available on play.rust-lang.org
|
||||
var all_available = snippet_crates.every(function (elem) {
|
||||
return playground_crates.indexOf(elem) > -1;
|
||||
});
|
||||
|
||||
if (all_available) {
|
||||
play_button.classList.remove("hidden");
|
||||
} else {
|
||||
play_button.classList.add("hidden");
|
||||
}
|
||||
}
|
||||
|
||||
function run_rust_code(code_block) {
|
||||
var result_block = code_block.querySelector(".result");
|
||||
if (!result_block) {
|
||||
result_block = document.createElement('code');
|
||||
result_block.className = 'result hljs language-bash';
|
||||
|
||||
code_block.append(result_block);
|
||||
}
|
||||
|
||||
let text = playground_text(code_block);
|
||||
let classes = code_block.querySelector('code').classList;
|
||||
let edition = "2015";
|
||||
if(classes.contains("edition2018")) {
|
||||
edition = "2018";
|
||||
} else if(classes.contains("edition2021")) {
|
||||
edition = "2021";
|
||||
}
|
||||
var params = {
|
||||
version: "stable",
|
||||
optimize: "0",
|
||||
code: text,
|
||||
edition: edition
|
||||
};
|
||||
|
||||
if (text.indexOf("#![feature") !== -1) {
|
||||
params.version = "nightly";
|
||||
}
|
||||
|
||||
result_block.innerText = "Running...";
|
||||
|
||||
fetch_with_timeout("https://play.rust-lang.org/evaluate.json", {
|
||||
headers: {
|
||||
'Content-Type': "application/json",
|
||||
},
|
||||
method: 'POST',
|
||||
mode: 'cors',
|
||||
body: JSON.stringify(params)
|
||||
})
|
||||
.then(response => response.json())
|
||||
.then(response => {
|
||||
if (response.result.trim() === '') {
|
||||
result_block.innerText = "No output";
|
||||
result_block.classList.add("result-no-output");
|
||||
} else {
|
||||
result_block.innerText = response.result;
|
||||
result_block.classList.remove("result-no-output");
|
||||
}
|
||||
})
|
||||
.catch(error => result_block.innerText = "Playground Communication: " + error.message);
|
||||
}
|
||||
|
||||
// Syntax highlighting Configuration
|
||||
hljs.configure({
|
||||
tabReplace: ' ', // 4 spaces
|
||||
languages: [], // Languages used for auto-detection
|
||||
});
|
||||
|
||||
let code_nodes = Array
|
||||
.from(document.querySelectorAll('code'))
|
||||
// Don't highlight `inline code` blocks in headers.
|
||||
.filter(function (node) {return !node.parentElement.classList.contains("header"); });
|
||||
|
||||
if (window.ace) {
|
||||
// language-rust class needs to be removed for editable
|
||||
// blocks or highlightjs will capture events
|
||||
code_nodes
|
||||
.filter(function (node) {return node.classList.contains("editable"); })
|
||||
.forEach(function (block) { block.classList.remove('language-rust'); });
|
||||
|
||||
Array
|
||||
code_nodes
|
||||
.filter(function (node) {return !node.classList.contains("editable"); })
|
||||
.forEach(function (block) { hljs.highlightBlock(block); });
|
||||
} else {
|
||||
code_nodes.forEach(function (block) { hljs.highlightBlock(block); });
|
||||
}
|
||||
|
||||
// Adding the hljs class gives code blocks the color css
|
||||
// even if highlighting doesn't apply
|
||||
code_nodes.forEach(function (block) { block.classList.add('hljs'); });
|
||||
|
||||
Array.from(document.querySelectorAll("code.language-rust")).forEach(function (block) {
|
||||
|
||||
var lines = Array.from(block.querySelectorAll('.boring'));
|
||||
// If no lines were hidden, return
|
||||
if (!lines.length) { return; }
|
||||
block.classList.add("hide-boring");
|
||||
|
||||
var buttons = document.createElement('div');
|
||||
buttons.className = 'buttons';
|
||||
buttons.innerHTML = "<button class=\"fa fa-eye\" title=\"Show hidden lines\" aria-label=\"Show hidden lines\"></button>";
|
||||
|
||||
// add expand button
|
||||
var pre_block = block.parentNode;
|
||||
pre_block.insertBefore(buttons, pre_block.firstChild);
|
||||
|
||||
pre_block.querySelector('.buttons').addEventListener('click', function (e) {
|
||||
if (e.target.classList.contains('fa-eye')) {
|
||||
e.target.classList.remove('fa-eye');
|
||||
e.target.classList.add('fa-eye-slash');
|
||||
e.target.title = 'Hide lines';
|
||||
e.target.setAttribute('aria-label', e.target.title);
|
||||
|
||||
block.classList.remove('hide-boring');
|
||||
} else if (e.target.classList.contains('fa-eye-slash')) {
|
||||
e.target.classList.remove('fa-eye-slash');
|
||||
e.target.classList.add('fa-eye');
|
||||
e.target.title = 'Show hidden lines';
|
||||
e.target.setAttribute('aria-label', e.target.title);
|
||||
|
||||
block.classList.add('hide-boring');
|
||||
}
|
||||
});
|
||||
});
|
||||
|
||||
if (window.playground_copyable) {
|
||||
Array.from(document.querySelectorAll('pre code')).forEach(function (block) {
|
||||
var pre_block = block.parentNode;
|
||||
if (!pre_block.classList.contains('playground')) {
|
||||
var buttons = pre_block.querySelector(".buttons");
|
||||
if (!buttons) {
|
||||
buttons = document.createElement('div');
|
||||
buttons.className = 'buttons';
|
||||
pre_block.insertBefore(buttons, pre_block.firstChild);
|
||||
}
|
||||
|
||||
var clipButton = document.createElement('button');
|
||||
clipButton.className = 'fa fa-copy clip-button';
|
||||
clipButton.title = 'Copy to clipboard';
|
||||
clipButton.setAttribute('aria-label', clipButton.title);
|
||||
clipButton.innerHTML = '<i class=\"tooltiptext\"></i>';
|
||||
|
||||
buttons.insertBefore(clipButton, buttons.firstChild);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
// Process playground code blocks
|
||||
Array.from(document.querySelectorAll(".playground")).forEach(function (pre_block) {
|
||||
// Add play button
|
||||
var buttons = pre_block.querySelector(".buttons");
|
||||
if (!buttons) {
|
||||
buttons = document.createElement('div');
|
||||
buttons.className = 'buttons';
|
||||
pre_block.insertBefore(buttons, pre_block.firstChild);
|
||||
}
|
||||
|
||||
var runCodeButton = document.createElement('button');
|
||||
runCodeButton.className = 'fa fa-play play-button';
|
||||
runCodeButton.hidden = true;
|
||||
runCodeButton.title = 'Run this code';
|
||||
runCodeButton.setAttribute('aria-label', runCodeButton.title);
|
||||
|
||||
buttons.insertBefore(runCodeButton, buttons.firstChild);
|
||||
runCodeButton.addEventListener('click', function (e) {
|
||||
run_rust_code(pre_block);
|
||||
});
|
||||
|
||||
if (window.playground_copyable) {
|
||||
var copyCodeClipboardButton = document.createElement('button');
|
||||
copyCodeClipboardButton.className = 'fa fa-copy clip-button';
|
||||
copyCodeClipboardButton.innerHTML = '<i class="tooltiptext"></i>';
|
||||
copyCodeClipboardButton.title = 'Copy to clipboard';
|
||||
copyCodeClipboardButton.setAttribute('aria-label', copyCodeClipboardButton.title);
|
||||
|
||||
buttons.insertBefore(copyCodeClipboardButton, buttons.firstChild);
|
||||
}
|
||||
|
||||
let code_block = pre_block.querySelector("code");
|
||||
if (window.ace && code_block.classList.contains("editable")) {
|
||||
var undoChangesButton = document.createElement('button');
|
||||
undoChangesButton.className = 'fa fa-history reset-button';
|
||||
undoChangesButton.title = 'Undo changes';
|
||||
undoChangesButton.setAttribute('aria-label', undoChangesButton.title);
|
||||
|
||||
buttons.insertBefore(undoChangesButton, buttons.firstChild);
|
||||
|
||||
undoChangesButton.addEventListener('click', function () {
|
||||
let editor = window.ace.edit(code_block);
|
||||
editor.setValue(editor.originalCode);
|
||||
editor.clearSelection();
|
||||
});
|
||||
}
|
||||
});
|
||||
})();
|
||||
|
||||
(function themes() {
|
||||
var html = document.querySelector('html');
|
||||
var themeToggleButton = document.getElementById('theme-toggle');
|
||||
var themePopup = document.getElementById('theme-list');
|
||||
var themeColorMetaTag = document.querySelector('meta[name="theme-color"]');
|
||||
var stylesheets = {
|
||||
ayuHighlight: document.querySelector("[href$='ayu-highlight.css']"),
|
||||
tomorrowNight: document.querySelector("[href$='tomorrow-night.css']"),
|
||||
highlight: document.querySelector("[href$='highlight.css']"),
|
||||
};
|
||||
|
||||
function showThemes() {
|
||||
themePopup.style.display = 'block';
|
||||
themeToggleButton.setAttribute('aria-expanded', true);
|
||||
themePopup.querySelector("button#" + get_theme()).focus();
|
||||
}
|
||||
|
||||
function hideThemes() {
|
||||
themePopup.style.display = 'none';
|
||||
themeToggleButton.setAttribute('aria-expanded', false);
|
||||
themeToggleButton.focus();
|
||||
}
|
||||
|
||||
function get_theme() {
|
||||
var theme;
|
||||
try { theme = localStorage.getItem('mdbook-theme'); } catch (e) { }
|
||||
if (theme === null || theme === undefined) {
|
||||
return default_theme;
|
||||
} else {
|
||||
return theme;
|
||||
}
|
||||
}
|
||||
|
||||
function set_theme(theme, store = true) {
|
||||
let ace_theme;
|
||||
|
||||
if (theme == 'coal' || theme == 'navy') {
|
||||
stylesheets.ayuHighlight.disabled = true;
|
||||
stylesheets.tomorrowNight.disabled = false;
|
||||
stylesheets.highlight.disabled = true;
|
||||
|
||||
ace_theme = "ace/theme/tomorrow_night";
|
||||
} else if (theme == 'ayu') {
|
||||
stylesheets.ayuHighlight.disabled = false;
|
||||
stylesheets.tomorrowNight.disabled = true;
|
||||
stylesheets.highlight.disabled = true;
|
||||
ace_theme = "ace/theme/tomorrow_night";
|
||||
} else {
|
||||
stylesheets.ayuHighlight.disabled = true;
|
||||
stylesheets.tomorrowNight.disabled = true;
|
||||
stylesheets.highlight.disabled = false;
|
||||
ace_theme = "ace/theme/dawn";
|
||||
}
|
||||
|
||||
setTimeout(function () {
|
||||
themeColorMetaTag.content = getComputedStyle(document.body).backgroundColor;
|
||||
}, 1);
|
||||
|
||||
if (window.ace && window.editors) {
|
||||
window.editors.forEach(function (editor) {
|
||||
editor.setTheme(ace_theme);
|
||||
});
|
||||
}
|
||||
|
||||
var previousTheme = get_theme();
|
||||
|
||||
if (store) {
|
||||
try { localStorage.setItem('mdbook-theme', theme); } catch (e) { }
|
||||
}
|
||||
|
||||
html.classList.remove(previousTheme);
|
||||
html.classList.add(theme);
|
||||
}
|
||||
|
||||
// Set theme
|
||||
var theme = get_theme();
|
||||
|
||||
set_theme(theme, false);
|
||||
|
||||
themeToggleButton.addEventListener('click', function () {
|
||||
if (themePopup.style.display === 'block') {
|
||||
hideThemes();
|
||||
} else {
|
||||
showThemes();
|
||||
}
|
||||
});
|
||||
|
||||
themePopup.addEventListener('click', function (e) {
|
||||
var theme;
|
||||
if (e.target.className === "theme") {
|
||||
theme = e.target.id;
|
||||
} else if (e.target.parentElement.className === "theme") {
|
||||
theme = e.target.parentElement.id;
|
||||
} else {
|
||||
return;
|
||||
}
|
||||
set_theme(theme);
|
||||
});
|
||||
|
||||
themePopup.addEventListener('focusout', function(e) {
|
||||
// e.relatedTarget is null in Safari and Firefox on macOS (see workaround below)
|
||||
if (!!e.relatedTarget && !themeToggleButton.contains(e.relatedTarget) && !themePopup.contains(e.relatedTarget)) {
|
||||
hideThemes();
|
||||
}
|
||||
});
|
||||
|
||||
// Should not be needed, but it works around an issue on macOS & iOS: https://github.com/rust-lang/mdBook/issues/628
|
||||
document.addEventListener('click', function(e) {
|
||||
if (themePopup.style.display === 'block' && !themeToggleButton.contains(e.target) && !themePopup.contains(e.target)) {
|
||||
hideThemes();
|
||||
}
|
||||
});
|
||||
|
||||
document.addEventListener('keydown', function (e) {
|
||||
if (e.altKey || e.ctrlKey || e.metaKey || e.shiftKey) { return; }
|
||||
if (!themePopup.contains(e.target)) { return; }
|
||||
|
||||
switch (e.key) {
|
||||
case 'Escape':
|
||||
e.preventDefault();
|
||||
hideThemes();
|
||||
break;
|
||||
case 'ArrowUp':
|
||||
e.preventDefault();
|
||||
var li = document.activeElement.parentElement;
|
||||
if (li && li.previousElementSibling) {
|
||||
li.previousElementSibling.querySelector('button').focus();
|
||||
}
|
||||
break;
|
||||
case 'ArrowDown':
|
||||
e.preventDefault();
|
||||
var li = document.activeElement.parentElement;
|
||||
if (li && li.nextElementSibling) {
|
||||
li.nextElementSibling.querySelector('button').focus();
|
||||
}
|
||||
break;
|
||||
case 'Home':
|
||||
e.preventDefault();
|
||||
themePopup.querySelector('li:first-child button').focus();
|
||||
break;
|
||||
case 'End':
|
||||
e.preventDefault();
|
||||
themePopup.querySelector('li:last-child button').focus();
|
||||
break;
|
||||
}
|
||||
});
|
||||
})();
|
||||
|
||||
(function languages() {
|
||||
var languageToggleButton = document.getElementById('language-toggle');
|
||||
var languagePopup = document.getElementById('language-list');
|
||||
|
||||
if (languageToggleButton !== null) {
|
||||
function showLanguages() {
|
||||
languagePopup.style.display = 'block';
|
||||
languageToggleButton.setAttribute('aria-expanded', true);
|
||||
}
|
||||
|
||||
function hideLanguages() {
|
||||
languagePopup.style.display = 'none';
|
||||
languageToggleButton.setAttribute('aria-expanded', false);
|
||||
languageToggleButton.focus();
|
||||
}
|
||||
|
||||
function set_language(language) {
|
||||
console.log("Set language " + language)
|
||||
}
|
||||
|
||||
languageToggleButton.addEventListener('click', function () {
|
||||
if (languagePopup.style.display === 'block') {
|
||||
hideLanguages();
|
||||
} else {
|
||||
showLanguages();
|
||||
}
|
||||
});
|
||||
|
||||
languagePopup.addEventListener('click', function (e) {
|
||||
var language = e.target.id || e.target.parentElement.id;
|
||||
set_language(language);
|
||||
});
|
||||
|
||||
languagePopup.addEventListener('focusout', function(e) {
|
||||
// e.relatedTarget is null in Safari and Firefox on macOS (see workaround below)
|
||||
if (!!e.relatedTarget && !languageToggleButton.contains(e.relatedTarget) && !languagePopup.contains(e.relatedTarget)) {
|
||||
hideLanguages();
|
||||
}
|
||||
});
|
||||
|
||||
// Should not be needed, but it works around an issue on macOS & iOS: https://github.com/rust-lang/mdBook/issues/628
|
||||
document.addEventListener('click', function(e) {
|
||||
if (languagePopup.style.display === 'block' && !languageToggleButton.contains(e.target) && !languagePopup.contains(e.target)) {
|
||||
hideLanguages();
|
||||
}
|
||||
});
|
||||
|
||||
document.addEventListener('keydown', function (e) {
|
||||
if (e.altKey || e.ctrlKey || e.metaKey || e.shiftKey) { return; }
|
||||
if (!languagePopup.contains(e.target)) { return; }
|
||||
|
||||
switch (e.key) {
|
||||
case 'Escape':
|
||||
e.preventDefault();
|
||||
hideLanguages();
|
||||
break;
|
||||
case 'ArrowUp':
|
||||
e.preventDefault();
|
||||
var li = document.activeElement.parentElement;
|
||||
if (li && li.previousElementSibling) {
|
||||
li.previousElementSibling.querySelector('button').focus();
|
||||
}
|
||||
break;
|
||||
case 'ArrowDown':
|
||||
e.preventDefault();
|
||||
var li = document.activeElement.parentElement;
|
||||
if (li && li.nextElementSibling) {
|
||||
li.nextElementSibling.querySelector('button').focus();
|
||||
}
|
||||
break;
|
||||
case 'Home':
|
||||
e.preventDefault();
|
||||
languagePopup.querySelector('li:first-child button').focus();
|
||||
break;
|
||||
case 'End':
|
||||
e.preventDefault();
|
||||
languagePopup.querySelector('li:last-child button').focus();
|
||||
break;
|
||||
}
|
||||
});
|
||||
}
|
||||
})();
|
||||
|
||||
(function sidebar() {
|
||||
var html = document.querySelector("html");
|
||||
var sidebar = document.getElementById("sidebar");
|
||||
var sidebarLinks = document.querySelectorAll('#sidebar a');
|
||||
var sidebarToggleButton = document.getElementById("sidebar-toggle");
|
||||
var sidebarResizeHandle = document.getElementById("sidebar-resize-handle");
|
||||
var firstContact = null;
|
||||
|
||||
function showSidebar() {
|
||||
html.classList.remove('sidebar-hidden')
|
||||
html.classList.add('sidebar-visible');
|
||||
Array.from(sidebarLinks).forEach(function (link) {
|
||||
link.setAttribute('tabIndex', 0);
|
||||
});
|
||||
sidebarToggleButton.setAttribute('aria-expanded', true);
|
||||
sidebar.setAttribute('aria-hidden', false);
|
||||
try { localStorage.setItem('mdbook-sidebar', 'visible'); } catch (e) { }
|
||||
}
|
||||
|
||||
|
||||
var sidebarAnchorToggles = document.querySelectorAll('#sidebar a.toggle');
|
||||
|
||||
function toggleSection(ev) {
|
||||
ev.currentTarget.parentElement.classList.toggle('expanded');
|
||||
}
|
||||
|
||||
Array.from(sidebarAnchorToggles).forEach(function (el) {
|
||||
el.addEventListener('click', toggleSection);
|
||||
});
|
||||
|
||||
function hideSidebar() {
|
||||
html.classList.remove('sidebar-visible')
|
||||
html.classList.add('sidebar-hidden');
|
||||
Array.from(sidebarLinks).forEach(function (link) {
|
||||
link.setAttribute('tabIndex', -1);
|
||||
});
|
||||
sidebarToggleButton.setAttribute('aria-expanded', false);
|
||||
sidebar.setAttribute('aria-hidden', true);
|
||||
try { localStorage.setItem('mdbook-sidebar', 'hidden'); } catch (e) { }
|
||||
}
|
||||
|
||||
// Toggle sidebar
|
||||
sidebarToggleButton.addEventListener('click', function sidebarToggle() {
|
||||
if (html.classList.contains("sidebar-hidden")) {
|
||||
var current_width = parseInt(
|
||||
document.documentElement.style.getPropertyValue('--sidebar-width'), 10);
|
||||
if (current_width < 150) {
|
||||
document.documentElement.style.setProperty('--sidebar-width', '150px');
|
||||
}
|
||||
showSidebar();
|
||||
} else if (html.classList.contains("sidebar-visible")) {
|
||||
hideSidebar();
|
||||
} else {
|
||||
if (getComputedStyle(sidebar)['transform'] === 'none') {
|
||||
hideSidebar();
|
||||
} else {
|
||||
showSidebar();
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
sidebarResizeHandle.addEventListener('mousedown', initResize, false);
|
||||
|
||||
function initResize(e) {
|
||||
window.addEventListener('mousemove', resize, false);
|
||||
window.addEventListener('mouseup', stopResize, false);
|
||||
html.classList.add('sidebar-resizing');
|
||||
}
|
||||
function resize(e) {
|
||||
var pos = (e.clientX - sidebar.offsetLeft);
|
||||
if (pos < 20) {
|
||||
hideSidebar();
|
||||
} else {
|
||||
if (html.classList.contains("sidebar-hidden")) {
|
||||
showSidebar();
|
||||
}
|
||||
pos = Math.min(pos, window.innerWidth - 100);
|
||||
document.documentElement.style.setProperty('--sidebar-width', pos + 'px');
|
||||
}
|
||||
}
|
||||
//on mouseup remove windows functions mousemove & mouseup
|
||||
function stopResize(e) {
|
||||
html.classList.remove('sidebar-resizing');
|
||||
window.removeEventListener('mousemove', resize, false);
|
||||
window.removeEventListener('mouseup', stopResize, false);
|
||||
}
|
||||
|
||||
document.addEventListener('touchstart', function (e) {
|
||||
firstContact = {
|
||||
x: e.touches[0].clientX,
|
||||
time: Date.now()
|
||||
};
|
||||
}, { passive: true });
|
||||
|
||||
document.addEventListener('touchmove', function (e) {
|
||||
if (!firstContact)
|
||||
return;
|
||||
|
||||
var curX = e.touches[0].clientX;
|
||||
var xDiff = curX - firstContact.x,
|
||||
tDiff = Date.now() - firstContact.time;
|
||||
|
||||
if (tDiff < 250 && Math.abs(xDiff) >= 150) {
|
||||
if (xDiff >= 0 && firstContact.x < Math.min(document.body.clientWidth * 0.25, 300))
|
||||
showSidebar();
|
||||
else if (xDiff < 0 && curX < 300)
|
||||
hideSidebar();
|
||||
|
||||
firstContact = null;
|
||||
}
|
||||
}, { passive: true });
|
||||
|
||||
// Scroll sidebar to current active section
|
||||
var activeSection = document.getElementById("sidebar").querySelector(".active");
|
||||
if (activeSection) {
|
||||
// https://developer.mozilla.org/en-US/docs/Web/API/Element/scrollIntoView
|
||||
activeSection.scrollIntoView({ block: 'center' });
|
||||
}
|
||||
})();
|
||||
|
||||
(function chapterNavigation() {
|
||||
document.addEventListener('keydown', function (e) {
|
||||
if (e.altKey || e.ctrlKey || e.metaKey || e.shiftKey) { return; }
|
||||
if (window.search && window.search.hasFocus()) { return; }
|
||||
|
||||
switch (e.key) {
|
||||
case 'ArrowRight':
|
||||
e.preventDefault();
|
||||
var nextButton = document.querySelector('.nav-chapters.next');
|
||||
if (nextButton) {
|
||||
window.location.href = nextButton.href;
|
||||
}
|
||||
break;
|
||||
case 'ArrowLeft':
|
||||
e.preventDefault();
|
||||
var previousButton = document.querySelector('.nav-chapters.previous');
|
||||
if (previousButton) {
|
||||
window.location.href = previousButton.href;
|
||||
}
|
||||
break;
|
||||
}
|
||||
});
|
||||
})();
|
||||
|
||||
(function clipboard() {
|
||||
var clipButtons = document.querySelectorAll('.clip-button');
|
||||
|
||||
function hideTooltip(elem) {
|
||||
elem.firstChild.innerText = "";
|
||||
elem.className = 'fa fa-copy clip-button';
|
||||
}
|
||||
|
||||
function showTooltip(elem, msg) {
|
||||
elem.firstChild.innerText = msg;
|
||||
elem.className = 'fa fa-copy tooltipped';
|
||||
}
|
||||
|
||||
var clipboardSnippets = new ClipboardJS('.clip-button', {
|
||||
text: function (trigger) {
|
||||
hideTooltip(trigger);
|
||||
let playground = trigger.closest("pre");
|
||||
return playground_text(playground);
|
||||
}
|
||||
});
|
||||
|
||||
Array.from(clipButtons).forEach(function (clipButton) {
|
||||
clipButton.addEventListener('mouseout', function (e) {
|
||||
hideTooltip(e.currentTarget);
|
||||
});
|
||||
});
|
||||
|
||||
clipboardSnippets.on('success', function (e) {
|
||||
e.clearSelection();
|
||||
showTooltip(e.trigger, "Copied!");
|
||||
});
|
||||
|
||||
clipboardSnippets.on('error', function (e) {
|
||||
showTooltip(e.trigger, "Clipboard error!");
|
||||
});
|
||||
})();
|
||||
|
||||
(function scrollToTop () {
|
||||
var menuTitle = document.querySelector('.menu-title');
|
||||
|
||||
menuTitle.addEventListener('click', function () {
|
||||
document.scrollingElement.scrollTo({ top: 0, behavior: 'smooth' });
|
||||
});
|
||||
})();
|
||||
|
||||
(function controllMenu() {
|
||||
var menu = document.getElementById('menu-bar');
|
||||
|
||||
(function controllPosition() {
|
||||
var scrollTop = document.scrollingElement.scrollTop;
|
||||
var prevScrollTop = scrollTop;
|
||||
var minMenuY = -menu.clientHeight - 50;
|
||||
// When the script loads, the page can be at any scroll (e.g. if you reforesh it).
|
||||
menu.style.top = scrollTop + 'px';
|
||||
// Same as parseInt(menu.style.top.slice(0, -2), but faster
|
||||
var topCache = menu.style.top.slice(0, -2);
|
||||
menu.classList.remove('sticky');
|
||||
var stickyCache = false; // Same as menu.classList.contains('sticky'), but faster
|
||||
document.addEventListener('scroll', function () {
|
||||
scrollTop = Math.max(document.scrollingElement.scrollTop, 0);
|
||||
// `null` means that it doesn't need to be updated
|
||||
var nextSticky = null;
|
||||
var nextTop = null;
|
||||
var scrollDown = scrollTop > prevScrollTop;
|
||||
var menuPosAbsoluteY = topCache - scrollTop;
|
||||
if (scrollDown) {
|
||||
nextSticky = false;
|
||||
if (menuPosAbsoluteY > 0) {
|
||||
nextTop = prevScrollTop;
|
||||
}
|
||||
} else {
|
||||
if (menuPosAbsoluteY > 0) {
|
||||
nextSticky = true;
|
||||
} else if (menuPosAbsoluteY < minMenuY) {
|
||||
nextTop = prevScrollTop + minMenuY;
|
||||
}
|
||||
}
|
||||
if (nextSticky === true && stickyCache === false) {
|
||||
menu.classList.add('sticky');
|
||||
stickyCache = true;
|
||||
} else if (nextSticky === false && stickyCache === true) {
|
||||
menu.classList.remove('sticky');
|
||||
stickyCache = false;
|
||||
}
|
||||
if (nextTop !== null) {
|
||||
menu.style.top = nextTop + 'px';
|
||||
topCache = nextTop;
|
||||
}
|
||||
prevScrollTop = scrollTop;
|
||||
}, { passive: true });
|
||||
})();
|
||||
(function controllBorder() {
|
||||
menu.classList.remove('bordered');
|
||||
document.addEventListener('scroll', function () {
|
||||
if (menu.offsetTop === 0) {
|
||||
menu.classList.remove('bordered');
|
||||
} else {
|
||||
menu.classList.add('bordered');
|
||||
}
|
||||
}, { passive: true });
|
||||
})();
|
||||
})();
|
||||
Vendored
+7
@@ -0,0 +1,7 @@
|
||||
/*!
|
||||
* clipboard.js v2.0.4
|
||||
* https://zenorocha.github.io/clipboard.js
|
||||
*
|
||||
* Licensed MIT © Zeno Rocha
|
||||
*/
|
||||
!function(t,e){"object"==typeof exports&&"object"==typeof module?module.exports=e():"function"==typeof define&&define.amd?define([],e):"object"==typeof exports?exports.ClipboardJS=e():t.ClipboardJS=e()}(this,function(){return function(n){var o={};function r(t){if(o[t])return o[t].exports;var e=o[t]={i:t,l:!1,exports:{}};return n[t].call(e.exports,e,e.exports,r),e.l=!0,e.exports}return r.m=n,r.c=o,r.d=function(t,e,n){r.o(t,e)||Object.defineProperty(t,e,{enumerable:!0,get:n})},r.r=function(t){"undefined"!=typeof Symbol&&Symbol.toStringTag&&Object.defineProperty(t,Symbol.toStringTag,{value:"Module"}),Object.defineProperty(t,"__esModule",{value:!0})},r.t=function(e,t){if(1&t&&(e=r(e)),8&t)return e;if(4&t&&"object"==typeof e&&e&&e.__esModule)return e;var n=Object.create(null);if(r.r(n),Object.defineProperty(n,"default",{enumerable:!0,value:e}),2&t&&"string"!=typeof e)for(var o in e)r.d(n,o,function(t){return e[t]}.bind(null,o));return n},r.n=function(t){var e=t&&t.__esModule?function(){return t.default}:function(){return t};return r.d(e,"a",e),e},r.o=function(t,e){return Object.prototype.hasOwnProperty.call(t,e)},r.p="",r(r.s=0)}([function(t,e,n){"use strict";var r="function"==typeof Symbol&&"symbol"==typeof Symbol.iterator?function(t){return typeof t}:function(t){return t&&"function"==typeof Symbol&&t.constructor===Symbol&&t!==Symbol.prototype?"symbol":typeof t},i=function(){function o(t,e){for(var n=0;n<e.length;n++){var o=e[n];o.enumerable=o.enumerable||!1,o.configurable=!0,"value"in o&&(o.writable=!0),Object.defineProperty(t,o.key,o)}}return function(t,e,n){return e&&o(t.prototype,e),n&&o(t,n),t}}(),a=o(n(1)),c=o(n(3)),u=o(n(4));function o(t){return t&&t.__esModule?t:{default:t}}var l=function(t){function o(t,e){!function(t,e){if(!(t instanceof e))throw new TypeError("Cannot call a class as a function")}(this,o);var n=function(t,e){if(!t)throw new ReferenceError("this hasn't been initialised - super() hasn't been called");return!e||"object"!=typeof e&&"function"!=typeof e?t:e}(this,(o.__proto__||Object.getPrototypeOf(o)).call(this));return n.resolveOptions(e),n.listenClick(t),n}return function(t,e){if("function"!=typeof e&&null!==e)throw new TypeError("Super expression must either be null or a function, not "+typeof e);t.prototype=Object.create(e&&e.prototype,{constructor:{value:t,enumerable:!1,writable:!0,configurable:!0}}),e&&(Object.setPrototypeOf?Object.setPrototypeOf(t,e):t.__proto__=e)}(o,c.default),i(o,[{key:"resolveOptions",value:function(){var t=0<arguments.length&&void 0!==arguments[0]?arguments[0]:{};this.action="function"==typeof t.action?t.action:this.defaultAction,this.target="function"==typeof t.target?t.target:this.defaultTarget,this.text="function"==typeof t.text?t.text:this.defaultText,this.container="object"===r(t.container)?t.container:document.body}},{key:"listenClick",value:function(t){var e=this;this.listener=(0,u.default)(t,"click",function(t){return e.onClick(t)})}},{key:"onClick",value:function(t){var e=t.delegateTarget||t.currentTarget;this.clipboardAction&&(this.clipboardAction=null),this.clipboardAction=new a.default({action:this.action(e),target:this.target(e),text:this.text(e),container:this.container,trigger:e,emitter:this})}},{key:"defaultAction",value:function(t){return s("action",t)}},{key:"defaultTarget",value:function(t){var e=s("target",t);if(e)return document.querySelector(e)}},{key:"defaultText",value:function(t){return s("text",t)}},{key:"destroy",value:function(){this.listener.destroy(),this.clipboardAction&&(this.clipboardAction.destroy(),this.clipboardAction=null)}}],[{key:"isSupported",value:function(){var t=0<arguments.length&&void 0!==arguments[0]?arguments[0]:["copy","cut"],e="string"==typeof t?[t]:t,n=!!document.queryCommandSupported;return e.forEach(function(t){n=n&&!!document.queryCommandSupported(t)}),n}}]),o}();function s(t,e){var n="data-clipboard-"+t;if(e.hasAttribute(n))return e.getAttribute(n)}t.exports=l},function(t,e,n){"use strict";var o,r="function"==typeof Symbol&&"symbol"==typeof Symbol.iterator?function(t){return typeof t}:function(t){return t&&"function"==typeof Symbol&&t.constructor===Symbol&&t!==Symbol.prototype?"symbol":typeof t},i=function(){function o(t,e){for(var n=0;n<e.length;n++){var o=e[n];o.enumerable=o.enumerable||!1,o.configurable=!0,"value"in o&&(o.writable=!0),Object.defineProperty(t,o.key,o)}}return function(t,e,n){return e&&o(t.prototype,e),n&&o(t,n),t}}(),a=n(2),c=(o=a)&&o.__esModule?o:{default:o};var u=function(){function e(t){!function(t,e){if(!(t instanceof e))throw new TypeError("Cannot call a class as a function")}(this,e),this.resolveOptions(t),this.initSelection()}return i(e,[{key:"resolveOptions",value:function(){var t=0<arguments.length&&void 0!==arguments[0]?arguments[0]:{};this.action=t.action,this.container=t.container,this.emitter=t.emitter,this.target=t.target,this.text=t.text,this.trigger=t.trigger,this.selectedText=""}},{key:"initSelection",value:function(){this.text?this.selectFake():this.target&&this.selectTLine truncated
|
||||
@@ -0,0 +1,542 @@
|
||||
/* CSS for UI elements (a.k.a. chrome) */
|
||||
|
||||
@import 'variables.css';
|
||||
|
||||
::-webkit-scrollbar {
|
||||
background: var(--bg);
|
||||
}
|
||||
::-webkit-scrollbar-thumb {
|
||||
background: var(--scrollbar);
|
||||
}
|
||||
html {
|
||||
scrollbar-color: var(--scrollbar) var(--bg);
|
||||
}
|
||||
#searchresults a,
|
||||
.content a:link,
|
||||
a:visited,
|
||||
a > .hljs {
|
||||
color: var(--links);
|
||||
}
|
||||
|
||||
/* Menu Bar */
|
||||
|
||||
#menu-bar,
|
||||
#menu-bar-hover-placeholder {
|
||||
z-index: 101;
|
||||
margin: auto calc(0px - var(--page-padding));
|
||||
}
|
||||
#menu-bar {
|
||||
position: relative;
|
||||
display: flex;
|
||||
flex-wrap: wrap;
|
||||
background-color: var(--bg);
|
||||
border-bottom-color: var(--bg);
|
||||
border-bottom-width: 1px;
|
||||
border-bottom-style: solid;
|
||||
}
|
||||
#menu-bar.sticky,
|
||||
.js #menu-bar-hover-placeholder:hover + #menu-bar,
|
||||
.js #menu-bar:hover,
|
||||
.js.sidebar-visible #menu-bar {
|
||||
position: -webkit-sticky;
|
||||
position: sticky;
|
||||
top: 0 !important;
|
||||
}
|
||||
#menu-bar-hover-placeholder {
|
||||
position: sticky;
|
||||
position: -webkit-sticky;
|
||||
top: 0;
|
||||
height: var(--menu-bar-height);
|
||||
}
|
||||
#menu-bar.bordered {
|
||||
border-bottom-color: var(--table-border-color);
|
||||
}
|
||||
#menu-bar i, #menu-bar .icon-button {
|
||||
position: relative;
|
||||
padding: 0 8px;
|
||||
z-index: 10;
|
||||
line-height: var(--menu-bar-height);
|
||||
cursor: pointer;
|
||||
transition: color 0.5s;
|
||||
}
|
||||
@media only screen and (max-width: 420px) {
|
||||
#menu-bar i, #menu-bar .icon-button {
|
||||
padding: 0 5px;
|
||||
}
|
||||
}
|
||||
|
||||
.icon-button {
|
||||
border: none;
|
||||
background: none;
|
||||
padding: 0;
|
||||
color: inherit;
|
||||
}
|
||||
.icon-button i {
|
||||
margin: 0;
|
||||
}
|
||||
|
||||
.right-buttons {
|
||||
margin: 0 15px;
|
||||
}
|
||||
.right-buttons a {
|
||||
text-decoration: none;
|
||||
}
|
||||
|
||||
.left-buttons {
|
||||
display: flex;
|
||||
margin: 0 5px;
|
||||
}
|
||||
.no-js .left-buttons {
|
||||
display: none;
|
||||
}
|
||||
|
||||
.menu-title {
|
||||
display: inline-block;
|
||||
font-weight: 200;
|
||||
font-size: 2.4rem;
|
||||
line-height: var(--menu-bar-height);
|
||||
text-align: center;
|
||||
margin: 0;
|
||||
flex: 1;
|
||||
white-space: nowrap;
|
||||
overflow: hidden;
|
||||
text-overflow: ellipsis;
|
||||
}
|
||||
.js .menu-title {
|
||||
cursor: pointer;
|
||||
}
|
||||
|
||||
.menu-bar,
|
||||
.menu-bar:visited,
|
||||
.nav-chapters,
|
||||
.nav-chapters:visited,
|
||||
.mobile-nav-chapters,
|
||||
.mobile-nav-chapters:visited,
|
||||
.menu-bar .icon-button,
|
||||
.menu-bar a i {
|
||||
color: var(--icons);
|
||||
}
|
||||
|
||||
.menu-bar i:hover,
|
||||
.menu-bar .icon-button:hover,
|
||||
.nav-chapters:hover,
|
||||
.mobile-nav-chapters i:hover {
|
||||
color: var(--icons-hover);
|
||||
}
|
||||
|
||||
/* Nav Icons */
|
||||
|
||||
.nav-chapters {
|
||||
font-size: 2.5em;
|
||||
text-align: center;
|
||||
text-decoration: none;
|
||||
|
||||
position: fixed;
|
||||
top: 0;
|
||||
bottom: 0;
|
||||
margin: 0;
|
||||
max-width: 150px;
|
||||
min-width: 90px;
|
||||
|
||||
display: flex;
|
||||
justify-content: center;
|
||||
align-content: center;
|
||||
flex-direction: column;
|
||||
|
||||
transition: color 0.5s, background-color 0.5s;
|
||||
}
|
||||
|
||||
.nav-chapters:hover {
|
||||
text-decoration: none;
|
||||
background-color: var(--theme-hover);
|
||||
transition: background-color 0.15s, color 0.15s;
|
||||
}
|
||||
|
||||
.nav-wrapper {
|
||||
margin-top: 50px;
|
||||
display: none;
|
||||
}
|
||||
|
||||
.mobile-nav-chapters {
|
||||
font-size: 2.5em;
|
||||
text-align: center;
|
||||
text-decoration: none;
|
||||
width: 90px;
|
||||
border-radius: 5px;
|
||||
background-color: var(--sidebar-bg);
|
||||
}
|
||||
|
||||
.previous {
|
||||
float: left;
|
||||
}
|
||||
|
||||
.next {
|
||||
float: right;
|
||||
right: var(--page-padding);
|
||||
}
|
||||
|
||||
@media only screen and (max-width: 1080px) {
|
||||
.nav-wide-wrapper { display: none; }
|
||||
.nav-wrapper { display: block; }
|
||||
}
|
||||
|
||||
@media only screen and (max-width: 1380px) {
|
||||
.sidebar-visible .nav-wide-wrapper { display: none; }
|
||||
.sidebar-visible .nav-wrapper { display: block; }
|
||||
}
|
||||
|
||||
/* Inline code */
|
||||
|
||||
:not(pre) > .hljs {
|
||||
display: inline;
|
||||
padding: 0.1em 0.3em;
|
||||
border-radius: 3px;
|
||||
}
|
||||
|
||||
:not(pre):not(a) > .hljs {
|
||||
color: var(--inline-code-color);
|
||||
overflow-x: initial;
|
||||
}
|
||||
|
||||
a:hover > .hljs {
|
||||
text-decoration: underline;
|
||||
}
|
||||
|
||||
pre {
|
||||
position: relative;
|
||||
}
|
||||
pre > .buttons {
|
||||
position: absolute;
|
||||
z-index: 100;
|
||||
right: 5px;
|
||||
top: 5px;
|
||||
|
||||
color: var(--sidebar-fg);
|
||||
cursor: pointer;
|
||||
}
|
||||
pre > .buttons :hover {
|
||||
color: var(--sidebar-active);
|
||||
}
|
||||
pre > .buttons i {
|
||||
margin-left: 8px;
|
||||
}
|
||||
pre > .buttons button {
|
||||
color: inherit;
|
||||
background: transparent;
|
||||
border: none;
|
||||
cursor: inherit;
|
||||
}
|
||||
pre > .result {
|
||||
margin-top: 10px;
|
||||
}
|
||||
|
||||
/* Search */
|
||||
|
||||
#searchresults a {
|
||||
text-decoration: none;
|
||||
}
|
||||
|
||||
mark {
|
||||
border-radius: 2px;
|
||||
padding: 0 3px 1px 3px;
|
||||
margin: 0 -3px -1px -3px;
|
||||
background-color: var(--search-mark-bg);
|
||||
transition: background-color 300ms linear;
|
||||
cursor: pointer;
|
||||
}
|
||||
|
||||
mark.fade-out {
|
||||
background-color: rgba(0,0,0,0) !important;
|
||||
cursor: auto;
|
||||
}
|
||||
|
||||
.searchbar-outer {
|
||||
margin-left: auto;
|
||||
margin-right: auto;
|
||||
max-width: var(--content-max-width);
|
||||
}
|
||||
|
||||
#searchbar {
|
||||
width: 100%;
|
||||
margin: 5px auto 0px auto;
|
||||
padding: 10px 16px;
|
||||
transition: box-shadow 300ms ease-in-out;
|
||||
border: 1px solid var(--searchbar-border-color);
|
||||
border-radius: 3px;
|
||||
background-color: var(--searchbar-bg);
|
||||
color: var(--searchbar-fg);
|
||||
}
|
||||
#searchbar:focus,
|
||||
#searchbar.active {
|
||||
box-shadow: 0 0 3px var(--searchbar-shadow-color);
|
||||
}
|
||||
|
||||
.searchresults-header {
|
||||
font-weight: bold;
|
||||
font-size: 1em;
|
||||
padding: 18px 0 0 5px;
|
||||
color: var(--searchresults-header-fg);
|
||||
}
|
||||
|
||||
.searchresults-outer {
|
||||
margin-left: auto;
|
||||
margin-right: auto;
|
||||
max-width: var(--content-max-width);
|
||||
border-bottom: 1px dashed var(--searchresults-border-color);
|
||||
}
|
||||
|
||||
ul#searchresults {
|
||||
list-style: none;
|
||||
padding-left: 20px;
|
||||
}
|
||||
ul#searchresults li {
|
||||
margin: 10px 0px;
|
||||
padding: 2px;
|
||||
border-radius: 2px;
|
||||
}
|
||||
ul#searchresults li.focus {
|
||||
background-color: var(--searchresults-li-bg);
|
||||
}
|
||||
ul#searchresults span.teaser {
|
||||
display: block;
|
||||
clear: both;
|
||||
margin: 5px 0 0 20px;
|
||||
font-size: 0.8em;
|
||||
}
|
||||
ul#searchresults span.teaser em {
|
||||
font-weight: bold;
|
||||
font-style: normal;
|
||||
}
|
||||
|
||||
/* Sidebar */
|
||||
|
||||
.sidebar {
|
||||
position: fixed;
|
||||
left: 0;
|
||||
top: 0;
|
||||
bottom: 0;
|
||||
width: var(--sidebar-width);
|
||||
font-size: 0.875em;
|
||||
box-sizing: border-box;
|
||||
-webkit-overflow-scrolling: touch;
|
||||
overscroll-behavior-y: contain;
|
||||
background-color: var(--sidebar-bg);
|
||||
color: var(--sidebar-fg);
|
||||
}
|
||||
.sidebar-resizing {
|
||||
-moz-user-select: none;
|
||||
-webkit-user-select: none;
|
||||
-ms-user-select: none;
|
||||
user-select: none;
|
||||
}
|
||||
.js:not(.sidebar-resizing) .sidebar {
|
||||
transition: transform 0.3s; /* Animation: slide away */
|
||||
}
|
||||
.sidebar code {
|
||||
line-height: 2em;
|
||||
}
|
||||
.sidebar .sidebar-scrollbox {
|
||||
overflow-y: auto;
|
||||
position: absolute;
|
||||
top: 0;
|
||||
bottom: 0;
|
||||
left: 0;
|
||||
right: 0;
|
||||
padding: 10px 10px;
|
||||
}
|
||||
.sidebar .sidebar-resize-handle {
|
||||
position: absolute;
|
||||
cursor: col-resize;
|
||||
width: 0;
|
||||
right: 0;
|
||||
top: 0;
|
||||
bottom: 0;
|
||||
}
|
||||
.js .sidebar .sidebar-resize-handle {
|
||||
cursor: col-resize;
|
||||
width: 5px;
|
||||
}
|
||||
.sidebar-hidden .sidebar {
|
||||
transform: translateX(calc(0px - var(--sidebar-width)));
|
||||
}
|
||||
.sidebar::-webkit-scrollbar {
|
||||
background: var(--sidebar-bg);
|
||||
}
|
||||
.sidebar::-webkit-scrollbar-thumb {
|
||||
background: var(--scrollbar);
|
||||
}
|
||||
|
||||
.sidebar-visible .page-wrapper {
|
||||
transform: translateX(var(--sidebar-width));
|
||||
}
|
||||
@media only screen and (min-width: 620px) {
|
||||
.sidebar-visible .page-wrapper {
|
||||
transform: none;
|
||||
margin-left: var(--sidebar-width);
|
||||
}
|
||||
}
|
||||
|
||||
.chapter {
|
||||
list-style: none outside none;
|
||||
padding-left: 0;
|
||||
line-height: 2.2em;
|
||||
}
|
||||
|
||||
.chapter ol {
|
||||
width: 100%;
|
||||
}
|
||||
|
||||
.chapter li {
|
||||
display: flex;
|
||||
color: var(--sidebar-non-existant);
|
||||
}
|
||||
.chapter li a {
|
||||
display: block;
|
||||
padding: 0;
|
||||
text-decoration: none;
|
||||
color: var(--sidebar-fg);
|
||||
}
|
||||
|
||||
.chapter li a:hover {
|
||||
color: var(--sidebar-active);
|
||||
}
|
||||
|
||||
.chapter li a.active {
|
||||
color: var(--sidebar-active);
|
||||
}
|
||||
|
||||
.chapter li > a.toggle {
|
||||
cursor: pointer;
|
||||
display: block;
|
||||
margin-left: auto;
|
||||
padding: 0 10px;
|
||||
user-select: none;
|
||||
opacity: 0.68;
|
||||
}
|
||||
|
||||
.chapter li > a.toggle div {
|
||||
transition: transform 0.5s;
|
||||
}
|
||||
|
||||
/* collapse the section */
|
||||
.chapter li:not(.expanded) + li > ol {
|
||||
display: none;
|
||||
}
|
||||
|
||||
.chapter li.chapter-item {
|
||||
line-height: 1.5em;
|
||||
margin-top: 0.6em;
|
||||
}
|
||||
|
||||
.chapter li.expanded > a.toggle div {
|
||||
transform: rotate(90deg);
|
||||
}
|
||||
|
||||
.spacer {
|
||||
width: 100%;
|
||||
height: 3px;
|
||||
margin: 5px 0px;
|
||||
}
|
||||
.chapter .spacer {
|
||||
background-color: var(--sidebar-spacer);
|
||||
}
|
||||
|
||||
@media (-moz-touch-enabled: 1), (pointer: coarse) {
|
||||
.chapter li a { padding: 5px 0; }
|
||||
.spacer { margin: 10px 0; }
|
||||
}
|
||||
|
||||
.section {
|
||||
list-style: none outside none;
|
||||
padding-left: 20px;
|
||||
line-height: 1.9em;
|
||||
}
|
||||
|
||||
/* Theme Menu Popup */
|
||||
|
||||
.theme-popup {
|
||||
position: absolute;
|
||||
left: 10px;
|
||||
top: var(--menu-bar-height);
|
||||
z-index: 1000;
|
||||
border-radius: 4px;
|
||||
font-size: 0.7em;
|
||||
color: var(--fg);
|
||||
background: var(--theme-popup-bg);
|
||||
border: 1px solid var(--theme-popup-border);
|
||||
margin: 0;
|
||||
padding: 0;
|
||||
list-style: none;
|
||||
display: none;
|
||||
}
|
||||
.theme-popup .default {
|
||||
color: var(--icons);
|
||||
}
|
||||
.theme-popup .theme {
|
||||
width: 100%;
|
||||
border: 0;
|
||||
margin: 0;
|
||||
padding: 2px 10px;
|
||||
line-height: 25px;
|
||||
white-space: nowrap;
|
||||
text-align: left;
|
||||
cursor: pointer;
|
||||
color: inherit;
|
||||
background: inherit;
|
||||
font-size: inherit;
|
||||
}
|
||||
.theme-popup .theme:hover {
|
||||
background-color: var(--theme-hover);
|
||||
}
|
||||
.theme-popup .theme:hover:first-child,
|
||||
.theme-popup .theme:hover:last-child {
|
||||
border-top-left-radius: inherit;
|
||||
border-top-right-radius: inherit;
|
||||
}
|
||||
|
||||
/* Language Menu Popup */
|
||||
|
||||
.language-popup {
|
||||
position: absolute;
|
||||
left: 150px;
|
||||
top: var(--menu-bar-height);
|
||||
z-index: 1000;
|
||||
border-radius: 4px;
|
||||
font-size: 0.7em;
|
||||
color: var(--fg);
|
||||
background: var(--theme-popup-bg);
|
||||
border: 1px solid var(--theme-popup-border);
|
||||
margin: 0;
|
||||
padding: 0;
|
||||
list-style: none;
|
||||
display: none;
|
||||
}
|
||||
.language-popup .default {
|
||||
color: var(--icons);
|
||||
}
|
||||
.language-popup .language {
|
||||
width: 100%;
|
||||
border: 0;
|
||||
margin: 0;
|
||||
padding: 2px 10px;
|
||||
line-height: 25px;
|
||||
white-space: nowrap;
|
||||
text-align: left;
|
||||
cursor: pointer;
|
||||
color: inherit;
|
||||
background: inherit;
|
||||
font-size: inherit;
|
||||
}
|
||||
.language-popup .language:hover {
|
||||
background-color: var(--theme-hover);
|
||||
}
|
||||
.language-popup .language:hover:first-child,
|
||||
.language-popup .language:hover:last-child {
|
||||
border-top-left-radius: inherit;
|
||||
border-top-right-radius: inherit;
|
||||
}
|
||||
|
||||
.language-popup a {
|
||||
color: var(--fg);
|
||||
text-decoration: none;
|
||||
}
|
||||
@@ -0,0 +1,182 @@
|
||||
/* Base styles and content styles */
|
||||
|
||||
@import 'variables.css';
|
||||
|
||||
:root {
|
||||
/* Browser default font-size is 16px, this way 1 rem = 10px */
|
||||
font-size: 62.5%;
|
||||
}
|
||||
|
||||
html {
|
||||
font-family: "Open Sans", sans-serif;
|
||||
color: var(--fg);
|
||||
background-color: var(--bg);
|
||||
text-size-adjust: none;
|
||||
-webkit-text-size-adjust: none;
|
||||
}
|
||||
|
||||
body {
|
||||
margin: 0;
|
||||
font-size: 1.6rem;
|
||||
overflow-x: hidden;
|
||||
}
|
||||
|
||||
code {
|
||||
font-family: "Source Code Pro", Consolas, "Ubuntu Mono", Menlo, "DejaVu Sans Mono", monospace, monospace !important;
|
||||
font-size: 0.875em; /* please adjust the ace font size accordingly in editor.js */
|
||||
}
|
||||
|
||||
/* Don't change font size in headers. */
|
||||
h1 code, h2 code, h3 code, h4 code, h5 code, h6 code {
|
||||
font-size: unset;
|
||||
}
|
||||
|
||||
.left { float: left; }
|
||||
.right { float: right; }
|
||||
.boring { opacity: 0.6; }
|
||||
.hide-boring .boring { display: none; }
|
||||
.hidden { display: none !important; }
|
||||
|
||||
h2, h3 { margin-top: 2.5em; }
|
||||
h4, h5 { margin-top: 2em; }
|
||||
|
||||
.header + .header h3,
|
||||
.header + .header h4,
|
||||
.header + .header h5 {
|
||||
margin-top: 1em;
|
||||
}
|
||||
|
||||
h1:target::before,
|
||||
h2:target::before,
|
||||
h3:target::before,
|
||||
h4:target::before,
|
||||
h5:target::before,
|
||||
h6:target::before {
|
||||
display: inline-block;
|
||||
content: "»";
|
||||
margin-left: -30px;
|
||||
width: 30px;
|
||||
}
|
||||
|
||||
/* This is broken on Safari as of version 14, but is fixed
|
||||
in Safari Technology Preview 117 which I think will be Safari 14.2.
|
||||
https://bugs.webkit.org/show_bug.cgi?id=218076
|
||||
*/
|
||||
:target {
|
||||
scroll-margin-top: calc(var(--menu-bar-height) + 0.5em);
|
||||
}
|
||||
|
||||
.page {
|
||||
outline: 0;
|
||||
padding: 0 var(--page-padding);
|
||||
margin-top: calc(0px - var(--menu-bar-height)); /* Compensate for the #menu-bar-hover-placeholder */
|
||||
}
|
||||
.page-wrapper {
|
||||
box-sizing: border-box;
|
||||
}
|
||||
.js:not(.sidebar-resizing) .page-wrapper {
|
||||
transition: margin-left 0.3s ease, transform 0.3s ease; /* Animation: slide away */
|
||||
}
|
||||
|
||||
.content {
|
||||
overflow-y: auto;
|
||||
padding: 0 15px;
|
||||
padding-bottom: 50px;
|
||||
}
|
||||
.content main {
|
||||
margin-left: auto;
|
||||
margin-right: auto;
|
||||
max-width: var(--content-max-width);
|
||||
}
|
||||
.content p { line-height: 1.45em; }
|
||||
.content ol { line-height: 1.45em; }
|
||||
.content ul { line-height: 1.45em; }
|
||||
.content a { text-decoration: none; }
|
||||
.content a:hover { text-decoration: underline; }
|
||||
.content img, .content video { max-width: 100%; }
|
||||
.content .header:link,
|
||||
.content .header:visited {
|
||||
color: var(--fg);
|
||||
}
|
||||
.content .header:link,
|
||||
.content .header:visited:hover {
|
||||
text-decoration: none;
|
||||
}
|
||||
|
||||
table {
|
||||
margin: 0 auto;
|
||||
border-collapse: collapse;
|
||||
}
|
||||
table td {
|
||||
padding: 3px 20px;
|
||||
border: 1px var(--table-border-color) solid;
|
||||
}
|
||||
table thead {
|
||||
background: var(--table-header-bg);
|
||||
}
|
||||
table thead td {
|
||||
font-weight: 700;
|
||||
border: none;
|
||||
}
|
||||
table thead th {
|
||||
padding: 3px 20px;
|
||||
}
|
||||
table thead tr {
|
||||
border: 1px var(--table-header-bg) solid;
|
||||
}
|
||||
/* Alternate background colors for rows */
|
||||
table tbody tr:nth-child(2n) {
|
||||
background: var(--table-alternate-bg);
|
||||
}
|
||||
|
||||
|
||||
blockquote {
|
||||
margin: 20px 0;
|
||||
padding: 0 20px;
|
||||
color: var(--fg);
|
||||
background-color: var(--quote-bg);
|
||||
border-top: .1em solid var(--quote-border);
|
||||
border-bottom: .1em solid var(--quote-border);
|
||||
}
|
||||
|
||||
|
||||
:not(.footnote-definition) + .footnote-definition,
|
||||
.footnote-definition + :not(.footnote-definition) {
|
||||
margin-top: 2em;
|
||||
}
|
||||
.footnote-definition {
|
||||
font-size: 0.9em;
|
||||
margin: 0.5em 0;
|
||||
}
|
||||
.footnote-definition p {
|
||||
display: inline;
|
||||
}
|
||||
|
||||
.tooltiptext {
|
||||
position: absolute;
|
||||
visibility: hidden;
|
||||
color: #fff;
|
||||
background-color: #333;
|
||||
transform: translateX(-50%); /* Center by moving tooltip 50% of its width left */
|
||||
left: -8px; /* Half of the width of the icon */
|
||||
top: -35px;
|
||||
font-size: 0.8em;
|
||||
text-align: center;
|
||||
border-radius: 6px;
|
||||
padding: 5px 8px;
|
||||
margin: 5px;
|
||||
z-index: 1000;
|
||||
}
|
||||
.tooltipped .tooltiptext {
|
||||
visibility: visible;
|
||||
}
|
||||
|
||||
.chapter li.part-title {
|
||||
color: var(--sidebar-fg);
|
||||
margin: 5px 0px;
|
||||
font-weight: bold;
|
||||
}
|
||||
|
||||
.result-no-output {
|
||||
font-style: italic;
|
||||
}
|
||||
@@ -0,0 +1,54 @@
|
||||
|
||||
#sidebar,
|
||||
#menu-bar,
|
||||
.nav-chapters,
|
||||
.mobile-nav-chapters {
|
||||
display: none;
|
||||
}
|
||||
|
||||
#page-wrapper.page-wrapper {
|
||||
transform: none;
|
||||
margin-left: 0px;
|
||||
overflow-y: initial;
|
||||
}
|
||||
|
||||
#content {
|
||||
max-width: none;
|
||||
margin: 0;
|
||||
padding: 0;
|
||||
}
|
||||
|
||||
.page {
|
||||
overflow-y: initial;
|
||||
}
|
||||
|
||||
code {
|
||||
background-color: #666666;
|
||||
border-radius: 5px;
|
||||
|
||||
/* Force background to be printed in Chrome */
|
||||
-webkit-print-color-adjust: exact;
|
||||
}
|
||||
|
||||
pre > .buttons {
|
||||
z-index: 2;
|
||||
}
|
||||
|
||||
a, a:visited, a:active, a:hover {
|
||||
color: #4183c4;
|
||||
text-decoration: none;
|
||||
}
|
||||
|
||||
h1, h2, h3, h4, h5, h6 {
|
||||
page-break-inside: avoid;
|
||||
page-break-after: avoid;
|
||||
}
|
||||
|
||||
pre, code {
|
||||
page-break-inside: avoid;
|
||||
white-space: pre-wrap;
|
||||
}
|
||||
|
||||
.fa {
|
||||
display: none !important;
|
||||
}
|
||||
@@ -0,0 +1,253 @@
|
||||
|
||||
/* Globals */
|
||||
|
||||
:root {
|
||||
--sidebar-width: 300px;
|
||||
--page-padding: 15px;
|
||||
--content-max-width: 750px;
|
||||
--menu-bar-height: 50px;
|
||||
}
|
||||
|
||||
/* Themes */
|
||||
|
||||
.ayu {
|
||||
--bg: hsl(210, 25%, 8%);
|
||||
--fg: #c5c5c5;
|
||||
|
||||
--sidebar-bg: #14191f;
|
||||
--sidebar-fg: #c8c9db;
|
||||
--sidebar-non-existant: #5c6773;
|
||||
--sidebar-active: #ffb454;
|
||||
--sidebar-spacer: #2d334f;
|
||||
|
||||
--scrollbar: var(--sidebar-fg);
|
||||
|
||||
--icons: #737480;
|
||||
--icons-hover: #b7b9cc;
|
||||
|
||||
--links: #0096cf;
|
||||
|
||||
--inline-code-color: #ffb454;
|
||||
|
||||
--theme-popup-bg: #14191f;
|
||||
--theme-popup-border: #5c6773;
|
||||
--theme-hover: #191f26;
|
||||
|
||||
--quote-bg: hsl(226, 15%, 17%);
|
||||
--quote-border: hsl(226, 15%, 22%);
|
||||
|
||||
--table-border-color: hsl(210, 25%, 13%);
|
||||
--table-header-bg: hsl(210, 25%, 28%);
|
||||
--table-alternate-bg: hsl(210, 25%, 11%);
|
||||
|
||||
--searchbar-border-color: #848484;
|
||||
--searchbar-bg: #424242;
|
||||
--searchbar-fg: #fff;
|
||||
--searchbar-shadow-color: #d4c89f;
|
||||
--searchresults-header-fg: #666;
|
||||
--searchresults-border-color: #888;
|
||||
--searchresults-li-bg: #252932;
|
||||
--search-mark-bg: #e3b171;
|
||||
}
|
||||
|
||||
.coal {
|
||||
--bg: hsl(200, 7%, 8%);
|
||||
--fg: #98a3ad;
|
||||
|
||||
--sidebar-bg: #292c2f;
|
||||
--sidebar-fg: #a1adb8;
|
||||
--sidebar-non-existant: #505254;
|
||||
--sidebar-active: #3473ad;
|
||||
--sidebar-spacer: #393939;
|
||||
|
||||
--scrollbar: var(--sidebar-fg);
|
||||
|
||||
--icons: #43484d;
|
||||
--icons-hover: #b3c0cc;
|
||||
|
||||
--links: #2b79a2;
|
||||
|
||||
--inline-code-color: #c5c8c6;
|
||||
|
||||
--theme-popup-bg: #141617;
|
||||
--theme-popup-border: #43484d;
|
||||
--theme-hover: #1f2124;
|
||||
|
||||
--quote-bg: hsl(234, 21%, 18%);
|
||||
--quote-border: hsl(234, 21%, 23%);
|
||||
|
||||
--table-border-color: hsl(200, 7%, 13%);
|
||||
--table-header-bg: hsl(200, 7%, 28%);
|
||||
--table-alternate-bg: hsl(200, 7%, 11%);
|
||||
|
||||
--searchbar-border-color: #aaa;
|
||||
--searchbar-bg: #b7b7b7;
|
||||
--searchbar-fg: #000;
|
||||
--searchbar-shadow-color: #aaa;
|
||||
--searchresults-header-fg: #666;
|
||||
--searchresults-border-color: #98a3ad;
|
||||
--searchresults-li-bg: #2b2b2f;
|
||||
--search-mark-bg: #355c7d;
|
||||
}
|
||||
|
||||
.light {
|
||||
--bg: hsl(0, 0%, 100%);
|
||||
--fg: hsl(0, 0%, 0%);
|
||||
|
||||
--sidebar-bg: #fafafa;
|
||||
--sidebar-fg: hsl(0, 0%, 0%);
|
||||
--sidebar-non-existant: #aaaaaa;
|
||||
--sidebar-active: #1f1fff;
|
||||
--sidebar-spacer: #f4f4f4;
|
||||
|
||||
--scrollbar: #8F8F8F;
|
||||
|
||||
--icons: #747474;
|
||||
--icons-hover: #000000;
|
||||
|
||||
--links: #20609f;
|
||||
|
||||
--inline-code-color: #301900;
|
||||
|
||||
--theme-popup-bg: #fafafa;
|
||||
--theme-popup-border: #cccccc;
|
||||
--theme-hover: #e6e6e6;
|
||||
|
||||
--quote-bg: hsl(197, 37%, 96%);
|
||||
--quote-border: hsl(197, 37%, 91%);
|
||||
|
||||
--table-border-color: hsl(0, 0%, 95%);
|
||||
--table-header-bg: hsl(0, 0%, 80%);
|
||||
--table-alternate-bg: hsl(0, 0%, 97%);
|
||||
|
||||
--searchbar-border-color: #aaa;
|
||||
--searchbar-bg: #fafafa;
|
||||
--searchbar-fg: #000;
|
||||
--searchbar-shadow-color: #aaa;
|
||||
--searchresults-header-fg: #666;
|
||||
--searchresults-border-color: #888;
|
||||
--searchresults-li-bg: #e4f2fe;
|
||||
--search-mark-bg: #a2cff5;
|
||||
}
|
||||
|
||||
.navy {
|
||||
--bg: hsl(226, 23%, 11%);
|
||||
--fg: #bcbdd0;
|
||||
|
||||
--sidebar-bg: #282d3f;
|
||||
--sidebar-fg: #c8c9db;
|
||||
--sidebar-non-existant: #505274;
|
||||
--sidebar-active: #2b79a2;
|
||||
--sidebar-spacer: #2d334f;
|
||||
|
||||
--scrollbar: var(--sidebar-fg);
|
||||
|
||||
--icons: #737480;
|
||||
--icons-hover: #b7b9cc;
|
||||
|
||||
--links: #2b79a2;
|
||||
|
||||
--inline-code-color: #c5c8c6;
|
||||
|
||||
--theme-popup-bg: #161923;
|
||||
--theme-popup-border: #737480;
|
||||
--theme-hover: #282e40;
|
||||
|
||||
--quote-bg: hsl(226, 15%, 17%);
|
||||
--quote-border: hsl(226, 15%, 22%);
|
||||
|
||||
--table-border-color: hsl(226, 23%, 16%);
|
||||
--table-header-bg: hsl(226, 23%, 31%);
|
||||
--table-alternate-bg: hsl(226, 23%, 14%);
|
||||
|
||||
--searchbar-border-color: #aaa;
|
||||
--searchbar-bg: #aeaec6;
|
||||
--searchbar-fg: #000;
|
||||
--searchbar-shadow-color: #aaa;
|
||||
--searchresults-header-fg: #5f5f71;
|
||||
--searchresults-border-color: #5c5c68;
|
||||
--searchresults-li-bg: #242430;
|
||||
--search-mark-bg: #a2cff5;
|
||||
}
|
||||
|
||||
.rust {
|
||||
--bg: hsl(60, 9%, 87%);
|
||||
--fg: #262625;
|
||||
|
||||
--sidebar-bg: #3b2e2a;
|
||||
--sidebar-fg: #c8c9db;
|
||||
--sidebar-non-existant: #505254;
|
||||
--sidebar-active: #e69f67;
|
||||
--sidebar-spacer: #45373a;
|
||||
|
||||
--scrollbar: var(--sidebar-fg);
|
||||
|
||||
--icons: #737480;
|
||||
--icons-hover: #262625;
|
||||
|
||||
--links: #2b79a2;
|
||||
|
||||
--inline-code-color: #6e6b5e;
|
||||
|
||||
--theme-popup-bg: #e1e1db;
|
||||
--theme-popup-border: #b38f6b;
|
||||
--theme-hover: #99908a;
|
||||
|
||||
--quote-bg: hsl(60, 5%, 75%);
|
||||
--quote-border: hsl(60, 5%, 70%);
|
||||
|
||||
--table-border-color: hsl(60, 9%, 82%);
|
||||
--table-header-bg: #b3a497;
|
||||
--table-alternate-bg: hsl(60, 9%, 84%);
|
||||
|
||||
--searchbar-border-color: #aaa;
|
||||
--searchbar-bg: #fafafa;
|
||||
--searchbar-fg: #000;
|
||||
--searchbar-shadow-color: #aaa;
|
||||
--searchresults-header-fg: #666;
|
||||
--searchresults-border-color: #888;
|
||||
--searchresults-li-bg: #dec2a2;
|
||||
--search-mark-bg: #e69f67;
|
||||
}
|
||||
|
||||
@media (prefers-color-scheme: dark) {
|
||||
.light.no-js {
|
||||
--bg: hsl(200, 7%, 8%);
|
||||
--fg: #98a3ad;
|
||||
|
||||
--sidebar-bg: #292c2f;
|
||||
--sidebar-fg: #a1adb8;
|
||||
--sidebar-non-existant: #505254;
|
||||
--sidebar-active: #3473ad;
|
||||
--sidebar-spacer: #393939;
|
||||
|
||||
--scrollbar: var(--sidebar-fg);
|
||||
|
||||
--icons: #43484d;
|
||||
--icons-hover: #b3c0cc;
|
||||
|
||||
--links: #2b79a2;
|
||||
|
||||
--inline-code-color: #c5c8c6;
|
||||
|
||||
--theme-popup-bg: #141617;
|
||||
--theme-popup-border: #43484d;
|
||||
--theme-hover: #1f2124;
|
||||
|
||||
--quote-bg: hsl(234, 21%, 18%);
|
||||
--quote-border: hsl(234, 21%, 23%);
|
||||
|
||||
--table-border-color: hsl(200, 7%, 13%);
|
||||
--table-header-bg: hsl(200, 7%, 28%);
|
||||
--table-alternate-bg: hsl(200, 7%, 11%);
|
||||
|
||||
--searchbar-border-color: #aaa;
|
||||
--searchbar-bg: #b7b7b7;
|
||||
--searchbar-fg: #000;
|
||||
--searchbar-shadow-color: #aaa;
|
||||
--searchresults-header-fg: #666;
|
||||
--searchresults-border-color: #98a3ad;
|
||||
--searchresults-li-bg: #2b2b2f;
|
||||
--search-mark-bg: #355c7d;
|
||||
}
|
||||
}
|
||||
+10
@@ -0,0 +1,10 @@
|
||||
/**
|
||||
* elasticlunr - http://weixsong.github.io
|
||||
* Lightweight full-text search engine in Javascript for browser search and offline search. - 0.9.5
|
||||
*
|
||||
* Copyright (C) 2017 Oliver Nightingale
|
||||
* Copyright (C) 2017 Wei Song
|
||||
* MIT Licensed
|
||||
* @license
|
||||
*/
|
||||
!function(){function e(e){if(null===e||"object"!=typeof e)return e;var t=e.constructor();for(var n in e)e.hasOwnProperty(n)&&(t[n]=e[n]);return t}var t=function(e){var n=new t.Index;return n.pipeline.add(t.trimmer,t.stopWordFilter,t.stemmer),e&&e.call(n,n),n};t.version="0.9.5",lunr=t,t.utils={},t.utils.warn=function(e){return function(t){e.console&&console.warn&&console.warn(t)}}(this),t.utils.toString=function(e){return void 0===e||null===e?"":e.toString()},t.EventEmitter=function(){this.events={}},t.EventEmitter.prototype.addListener=function(){var e=Array.prototype.slice.call(arguments),t=e.pop(),n=e;if("function"!=typeof t)throw new TypeError("last argument must be a function");n.forEach(function(e){this.hasHandler(e)||(this.events[e]=[]),this.events[e].push(t)},this)},t.EventEmitter.prototype.removeListener=function(e,t){if(this.hasHandler(e)){var n=this.events[e].indexOf(t);-1!==n&&(this.events[e].splice(n,1),0==this.events[e].length&&delete this.events[e])}},t.EventEmitter.prototype.emit=function(e){if(this.hasHandler(e)){var t=Array.prototype.slice.call(arguments,1);this.events[e].forEach(function(e){e.apply(void 0,t)},this)}},t.EventEmitter.prototype.hasHandler=function(e){return e in this.events},t.tokenizer=function(e){if(!arguments.length||null===e||void 0===e)return[];if(Array.isArray(e)){var n=e.filter(function(e){return null===e||void 0===e?!1:!0});n=n.map(function(e){return t.utils.toString(e).toLowerCase()});var i=[];return n.forEach(function(e){var n=e.split(t.tokenizer.seperator);i=i.concat(n)},this),i}return e.toString().trim().toLowerCase().split(t.tokenizer.seperator)},t.tokenizer.defaultSeperator=/[\s\-]+/,t.tokenizer.seperator=t.tokenizer.defaultSeperator,t.tokenizer.setSeperator=function(e){null!==e&&void 0!==e&&"object"==typeof e&&(t.tokenizer.seperator=e)},t.tokenizer.resetSeperator=function(){t.tokenizer.seperator=t.tokenizer.defaultSeperator},t.tokenizer.getSeperator=function(){return t.tokenizer.seperator},t.Pipeline=function(){this._queue=[]},t.Pipeline.registeredFunctions={},t.Pipeline.registerFunction=function(e,n){n in t.Pipeline.registeredFunctions&&t.utils.warn("Overwriting existing registered function: "+n),e.label=n,t.Pipeline.registeredFunctions[n]=e},t.Pipeline.getRegisteredFunction=function(e){return e in t.Pipeline.registeredFunctions!=!0?null:t.Pipeline.registeredFunctions[e]},t.Pipeline.warnIfFunctionNotRegistered=function(e){var n=e.label&&e.label in this.registeredFunctions;n||t.utils.warn("Function is not registered with pipeline. This may cause problems when serialising the index.\n",e)},t.Pipeline.load=function(e){var n=new t.Pipeline;return e.forEach(function(e){var i=t.Pipeline.getRegisteredFunction(e);if(!i)throw new Error("Cannot load un-registered function: "+e);n.add(i)}),n},t.Pipeline.prototype.add=function(){var e=Array.prototype.slice.call(arguments);e.forEach(function(e){t.Pipeline.warnIfFunctionNotRegistered(e),this._queue.push(e)},this)},t.Pipeline.prototype.after=function(e,n){t.Pipeline.warnIfFunctionNotRegistered(n);var i=this._queue.indexOf(e);if(-1===i)throw new Error("Cannot find existingFn");this._queue.splice(i+1,0,n)},t.Pipeline.prototype.before=function(e,n){t.Pipeline.warnIfFunctionNotRegistered(n);var i=this._queue.indexOf(e);if(-1===i)throw new Error("Cannot find existingFn");this._queue.splice(i,0,n)},t.Pipeline.prototype.remove=function(e){var t=this._queue.indexOf(e);-1!==t&&this._queue.splice(t,1)},t.Pipeline.prototype.run=function(e){for(var t=[],n=e.length,i=this._queue.length,o=0;n>o;o++){for(var r=e[o],s=0;i>s&&(r=this._queue[s](r,o,e),void 0!==r&&null!==r);s++);void 0!==r&&null!==r&&t.push(r)}return t},t.Pipeline.prototype.reset=function(){this._queue=[]},t.Pipeline.prototype.get=function(){return this._queue},t.Pipeline.prototype.toJSON=function(){return this._queue.map(function(e){return t.Pipeline.warnIfFunctionNotRegistered(e),e.label})},t.Index=function(){this._fields=[],this._ref="id",this.pipeline=new t.Pipeline,this.documentStore=new t.DocumentStore,this.index={},this.eventEmitter=new t.EventEmitter,this._idfCache={},this.on("add","remove","update",function(){this._idfCache={}}.bind(this))},t.Index.prototype.on=function(){var e=Array.prototype.slice.call(arguments);return this.eventEmitter.addListener.apply(this.eventEmitter,e)},t.Index.prototype.off=function(e,t){return this.eventEmitter.removeListener(e,t)},t.Index.load=function(e){e.version!==t.version&&t.utils.warn("version mismatch: current "+t.version+" importing "+e.version);var n=new this;n._fields=e.fields,n._ref=e.ref,n.documentStore=t.DocumentStore.load(e.documentStore),n.pipeline=t.Pipeline.load(e.pipeline),n.index={};for(var i in e.index)n.index[i]=t.InvertedIndex.load(e.index[i]);return n},t.Index.prototype.addField=function(e){return this._fields.push(e),this.index[e]=new t.InvertedIndex,this},t.Index.prototype.setRef=function(e){return this._ref=e,this},t.Index.prototype.saveDocument=function(e){return this.documentStore=new t.DocumentStore(e),this},tLine truncated
|
||||
@@ -0,0 +1,463 @@
|
||||
<!DOCTYPE HTML>
|
||||
<html lang="en" class="sidebar-visible no-js light">
|
||||
<head>
|
||||
<!-- Book generated using mdBook -->
|
||||
<meta charset="UTF-8">
|
||||
<title>Building a Nest - Dioxus Router</title>
|
||||
|
||||
|
||||
<!-- Custom HTML head -->
|
||||
|
||||
<meta content="text/html; charset=utf-8" http-equiv="Content-Type">
|
||||
<meta name="description" content="">
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1">
|
||||
<meta name="theme-color" content="#ffffff" />
|
||||
|
||||
<link rel="icon" href="../favicon.svg">
|
||||
<link rel="shortcut icon" href="../favicon.png">
|
||||
<link rel="stylesheet" href="../css/variables.css">
|
||||
<link rel="stylesheet" href="../css/general.css">
|
||||
<link rel="stylesheet" href="../css/chrome.css">
|
||||
<link rel="stylesheet" href="../css/print.css" media="print">
|
||||
|
||||
<!-- Fonts -->
|
||||
<link rel="stylesheet" href="../FontAwesome/css/font-awesome.css">
|
||||
<link rel="stylesheet" href="../fonts/fonts.css">
|
||||
|
||||
<!-- Highlight.js Stylesheets -->
|
||||
<link rel="stylesheet" href="../highlight.css">
|
||||
<link rel="stylesheet" href="../tomorrow-night.css">
|
||||
<link rel="stylesheet" href="../ayu-highlight.css">
|
||||
|
||||
<!-- Custom theme stylesheets -->
|
||||
|
||||
</head>
|
||||
<body>
|
||||
<!-- Provide site root to javascript -->
|
||||
<script type="text/javascript">
|
||||
var path_to_root = "../";
|
||||
var default_theme = window.matchMedia("(prefers-color-scheme: dark)").matches ? "navy" : "light";
|
||||
</script>
|
||||
|
||||
<!-- Work around some values being stored in localStorage wrapped in quotes -->
|
||||
<script type="text/javascript">
|
||||
try {
|
||||
var theme = localStorage.getItem('mdbook-theme');
|
||||
var sidebar = localStorage.getItem('mdbook-sidebar');
|
||||
|
||||
if (theme.startsWith('"') && theme.endsWith('"')) {
|
||||
localStorage.setItem('mdbook-theme', theme.slice(1, theme.length - 1));
|
||||
}
|
||||
|
||||
if (sidebar.startsWith('"') && sidebar.endsWith('"')) {
|
||||
localStorage.setItem('mdbook-sidebar', sidebar.slice(1, sidebar.length - 1));
|
||||
}
|
||||
} catch (e) { }
|
||||
</script>
|
||||
|
||||
<!-- Set the theme before any content is loaded, prevents flash -->
|
||||
<script type="text/javascript">
|
||||
var theme;
|
||||
try { theme = localStorage.getItem('mdbook-theme'); } catch(e) { }
|
||||
if (theme === null || theme === undefined) { theme = default_theme; }
|
||||
var html = document.querySelector('html');
|
||||
html.classList.remove('no-js')
|
||||
html.classList.remove('light')
|
||||
html.classList.add(theme);
|
||||
html.classList.add('js');
|
||||
</script>
|
||||
|
||||
<!-- Hide / unhide sidebar before it is displayed -->
|
||||
<script type="text/javascript">
|
||||
var html = document.querySelector('html');
|
||||
var sidebar = 'hidden';
|
||||
if (document.body.clientWidth >= 1080) {
|
||||
try { sidebar = localStorage.getItem('mdbook-sidebar'); } catch(e) { }
|
||||
sidebar = sidebar || 'visible';
|
||||
}
|
||||
html.classList.remove('sidebar-visible');
|
||||
html.classList.add("sidebar-" + sidebar);
|
||||
</script>
|
||||
|
||||
<nav id="sidebar" class="sidebar" aria-label="Table of contents">
|
||||
<div class="sidebar-scrollbox">
|
||||
<ol class="chapter"><li class="chapter-item expanded affix "><a href="../index.html">Introduction</a></li><li class="chapter-item expanded affix "><li class="part-title">Features</li><li class="chapter-item expanded "><a href="../features/index.html"><strong aria-hidden="true">1.</strong> Adding the Router to Your Application</a></li><li class="chapter-item expanded "><a href="../features/routes/index.html"><strong aria-hidden="true">2.</strong> Defining Routes</a></li><li><ol class="section"><li class="chapter-item expanded "><a href="../features/routes/nested.html"><strong aria-hidden="true">2.1.</strong> Nested Routes</a></li><li class="chapter-item expanded "><a href="../features/routes/catch_all.html"><strong aria-hidden="true">2.2.</strong> Catch All Routes</a></li><li class="chapter-item expanded "><a href="../features/routes/matching.html"><strong aria-hidden="true">2.3.</strong> Matching Routes</a></li><li class="chapter-item expanded "><a href="../features/routes/fallback.html"><strong aria-hidden="true">2.4.</strong> Fallback Routes (404 page)</a></li><li class="chapter-item expanded "><a href="../features/routes/multiple-and-redirect.html"><strong aria-hidden="true">2.5.</strong> Multiple Components & Redirects</a></li></ol></li><li class="chapter-item expanded "><a href="../features/outlets.html"><strong aria-hidden="true">3.</strong> Outlets</a></li><li class="chapter-item expanded "><a href="../features/navigation/index.html"><strong aria-hidden="true">4.</strong> Links & Navigation</a></li><li><ol class="section"><li class="chapter-item expanded "><a href="../features/navigation/name.html"><strong aria-hidden="true">4.1.</strong> Named Navigation</a></li><li class="chapter-item expanded "><a href="../features/navigation/external.html"><strong aria-hidden="true">4.2.</strong> External Navigation</a></li><li class="chapter-item expanded "><a href="../features/navigation/programmatic.html"><strong aria-hidden="true">4.3.</strong> Programmatic Navigation</a></li></ol></li><li class="chapter-item expanded "><a href="../features/query.html"><strong aria-hidden="true">5.</strong> Query</a></li><li class="chapter-item expanded "><a href="../features/failures/index.html"><strong aria-hidden="true">6.</strong> Navigation Failures</a></li><li><ol class="section"><li class="chapter-item expanded "><a href="../features/failures/named.html"><strong aria-hidden="true">6.1.</strong> Named Navigation Failure</a></li><li class="chapter-item expanded "><a href="../features/failures/external.html"><strong aria-hidden="true">6.2.</strong> External Navigation Failure</a></li><li class="chapter-item expanded "><a href="../features/failures/redirection-limit.html"><strong aria-hidden="true">6.3.</strong> Redirection Limit Failure</a></li></ol></li><li class="chapter-item expanded "><a href="../features/history-providers.html"><strong aria-hidden="true">7.</strong> History Providers</a></li><li class="chapter-item expanded "><a href="../features/history-buttons.html"><strong aria-hidden="true">8.</strong> History Buttons</a></li><li class="chapter-item expanded "><a href="../features/sitemap-generation.html"><strong aria-hidden="true">9.</strong> Sitemap Generation</a></li><li class="chapter-item expanded "><a href="../features/routing-update-callback.html"><strong aria-hidden="true">10.</strong> Routing Update Callback</a></li><li class="chapter-item expanded affix "><li class="part-title">Example Project</li><li class="chapter-item expanded "><a href="../example/index.html"><strong aria-hidden="true">11.</strong> Overview</a></li><li class="chapter-item expanded "><a href="../example/first-route.html"><strong aria-hidden="true">12.</strong> Creating Our First Route</a></li><li class="chapter-item expanded "><a href="../example/building-a-nest.html" class="active"><strong aria-hidden="true">13.</strong> Building a Nest</a></li><li class="chapter-item expanded "><a href="../example/navigation-targets.html"><strong aria-hidden="true">14.</strong> Navigation Targets</a></li><li class="chapter-item expanded "><a href="../example/redirection-perfection.html"><strong aria-hidden="true">15.</strong> Redirection Perfection</a></li><li class="chapter-item expanded "><a href="../example/full-code.html"><strong aria-hidden="true">16.</strong> Full Code</a></li></ol>
|
||||
</div>
|
||||
<div id="sidebar-resize-handle" class="sidebar-resize-handle"></div>
|
||||
</nav>
|
||||
|
||||
<div id="page-wrapper" class="page-wrapper">
|
||||
|
||||
<div class="page">
|
||||
<div id="menu-bar-hover-placeholder"></div>
|
||||
<div id="menu-bar" class="menu-bar sticky bordered">
|
||||
<div class="left-buttons">
|
||||
<button id="sidebar-toggle" class="icon-button" type="button" title="Toggle Table of Contents" aria-label="Toggle Table of Contents" aria-controls="sidebar">
|
||||
<i class="fa fa-bars"></i>
|
||||
</button>
|
||||
<button id="theme-toggle" class="icon-button" type="button" title="Change theme" aria-label="Change theme" aria-haspopup="true" aria-expanded="false" aria-controls="theme-list">
|
||||
<i class="fa fa-paint-brush"></i>
|
||||
</button>
|
||||
<ul id="theme-list" class="theme-popup" aria-label="Themes" role="menu">
|
||||
<li role="none"><button role="menuitem" class="theme" id="light">Light (default)</button></li>
|
||||
<li role="none"><button role="menuitem" class="theme" id="rust">Rust</button></li>
|
||||
<li role="none"><button role="menuitem" class="theme" id="coal">Coal</button></li>
|
||||
<li role="none"><button role="menuitem" class="theme" id="navy">Navy</button></li>
|
||||
<li role="none"><button role="menuitem" class="theme" id="ayu">Ayu</button></li>
|
||||
</ul>
|
||||
<button id="search-toggle" class="icon-button" type="button" title="Search. (Shortkey: s)" aria-label="Toggle Searchbar" aria-expanded="false" aria-keyshortcuts="S" aria-controls="searchbar">
|
||||
<i class="fa fa-search"></i>
|
||||
</button>
|
||||
</div>
|
||||
|
||||
<h1 class="menu-title">Dioxus Router</h1>
|
||||
|
||||
<div class="right-buttons">
|
||||
<a href="../print.html" title="Print this book" aria-label="Print this book">
|
||||
<i id="print-button" class="fa fa-print"></i>
|
||||
</a>
|
||||
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div id="search-wrapper" class="hidden">
|
||||
<form id="searchbar-outer" class="searchbar-outer">
|
||||
<input type="search" id="searchbar" name="searchbar" placeholder="Search this book ..." aria-controls="searchresults-outer" aria-describedby="searchresults-header">
|
||||
</form>
|
||||
<div id="searchresults-outer" class="searchresults-outer hidden">
|
||||
<div id="searchresults-header" class="searchresults-header"></div>
|
||||
<ul id="searchresults">
|
||||
</ul>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- Apply ARIA attributes after the sidebar and the sidebar toggle button are added to the DOM -->
|
||||
<script type="text/javascript">
|
||||
document.getElementById('sidebar-toggle').setAttribute('aria-expanded', sidebar === 'visible');
|
||||
document.getElementById('sidebar').setAttribute('aria-hidden', sidebar !== 'visible');
|
||||
Array.from(document.querySelectorAll('#sidebar a')).forEach(function(link) {
|
||||
link.setAttribute('tabIndex', sidebar === 'visible' ? 0 : -1);
|
||||
});
|
||||
</script>
|
||||
|
||||
<div id="content" class="content">
|
||||
<main>
|
||||
<h1 id="building-a-nest"><a class="header" href="#building-a-nest">Building a Nest</a></h1>
|
||||
<p>Not a bird's nest! A nest of routes!</p>
|
||||
<p>In this chapter we will begin to build the blog portion of our site which will
|
||||
include links, nested URLs, and URL parameters. We will also explore the use
|
||||
case of rendering components directly in the component calling <a href="https://docs.rs/dioxus-router/latest/dioxus_router/hooks/fn.use_router.html"><code>use_router</code></a>.</p>
|
||||
<h2 id="site-navigation"><a class="header" href="#site-navigation">Site Navigation</a></h2>
|
||||
<p>Our site visitors won't know all the available pages and blogs on our site so we
|
||||
should provide a navigation bar for them.
|
||||
Let's create a new <code>NavBar</code> component:</p>
|
||||
<pre><pre class="playground"><code class="language-rust no_run edition2021">
|
||||
<span class="boring">#![allow(unused)]
|
||||
</span><span class="boring">fn main() {
|
||||
</span><span class="boring">// Hidden lines (like this one) make the documentation tests work.
|
||||
</span><span class="boring">extern crate dioxus;
|
||||
</span><span class="boring">use dioxus::prelude::*;
|
||||
</span><span class="boring">extern crate dioxus_router;
|
||||
</span><span class="boring">use dioxus_router::prelude::*;
|
||||
</span><span class="boring">
|
||||
</span>fn NavBar(cx: Scope) -> Element {
|
||||
render! {
|
||||
nav {
|
||||
ul { }
|
||||
}
|
||||
}
|
||||
}
|
||||
<span class="boring">}
|
||||
</span></code></pre></pre>
|
||||
<p>Our navbar will be a list of links going between our pages. We could always use
|
||||
an HTML anchor element but that would cause our page to reload unnecessarily.
|
||||
Instead we want to use the <a href="https://docs.rs/dioxus-router/latest/dioxus_router/components/fn.Link.html"><code>Link</code></a> component provided by Dioxus Router.</p>
|
||||
<p>The <a href="https://docs.rs/dioxus-router/latest/dioxus_router/components/fn.Link.html"><code>Link</code></a> is similar to a regular <code>a</code> tag. It takes a target (for now a path,
|
||||
more on other targets later) and an element. Let's add our links</p>
|
||||
<pre><pre class="playground"><code class="language-rust no_run edition2021">
|
||||
<span class="boring">#![allow(unused)]
|
||||
</span><span class="boring">fn main() {
|
||||
</span><span class="boring">// Hidden lines (like this one) make the documentation tests work.
|
||||
</span><span class="boring">extern crate dioxus;
|
||||
</span><span class="boring">use dioxus::prelude::*;
|
||||
</span><span class="boring">extern crate dioxus_router;
|
||||
</span><span class="boring">use dioxus_router::prelude::*;
|
||||
</span><span class="boring">
|
||||
</span>fn NavBar(cx: Scope) -> Element {
|
||||
render! {
|
||||
nav {
|
||||
ul {
|
||||
// new stuff starts here
|
||||
li { Link {
|
||||
target: NavigationTarget::Internal(String::from("/")),
|
||||
"Home"
|
||||
} }
|
||||
li { Link {
|
||||
target: "/blog", // short form
|
||||
"Blog"
|
||||
} }
|
||||
// new stuff ends here
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
<span class="boring">}
|
||||
</span></code></pre></pre>
|
||||
<blockquote>
|
||||
<p>Using this method, the <a href="https://docs.rs/dioxus-router/latest/dioxus_router/components/fn.Link.html"><code>Link</code></a> component only works for links within our
|
||||
application. To learn more about navigation targets see
|
||||
<a href="./navigation-targets.html">here</a>.</p>
|
||||
</blockquote>
|
||||
<p>And finally, we add the navbar component in our app component:</p>
|
||||
<pre><pre class="playground"><code class="language-rust no_run edition2021">
|
||||
<span class="boring">#![allow(unused)]
|
||||
</span><span class="boring">fn main() {
|
||||
</span><span class="boring">// Hidden lines (like this one) make the documentation tests work.
|
||||
</span><span class="boring">extern crate dioxus;
|
||||
</span><span class="boring">use dioxus::prelude::*;
|
||||
</span><span class="boring">extern crate dioxus_router;
|
||||
</span><span class="boring">use dioxus_router::prelude::*;
|
||||
</span><span class="boring">fn Home(cx: Scope) -> Element { unimplemented!() }
|
||||
</span><span class="boring">fn NavBar(cx: Scope) -> Element { unimplemented!() }
|
||||
</span><span class="boring">fn PageNotFound(cx: Scope) -> Element { unimplemented!() }
|
||||
</span><span class="boring">
|
||||
</span>fn App(cx: Scope) -> Element {
|
||||
use_router(
|
||||
cx,
|
||||
&|| RouterConfiguration::default(),
|
||||
&|| Segment::content(comp(Home)).fallback(comp(PageNotFound))
|
||||
);
|
||||
|
||||
render! {
|
||||
NavBar { } // this is new
|
||||
Outlet { }
|
||||
}
|
||||
}
|
||||
<span class="boring">}
|
||||
</span></code></pre></pre>
|
||||
<p>Now you should see a list of links near the top of your page. Click on one and
|
||||
you should seamlessly travel between pages.</p>
|
||||
<h3 id="active-link-styling"><a class="header" href="#active-link-styling">Active Link Styling</a></h3>
|
||||
<p>You might want to style links differently, when their page is currently open.
|
||||
To achieve this, we can tell the <a href="https://docs.rs/dioxus-router/latest/dioxus_router/components/fn.Link.html"><code>Link</code></a> to give its internal <code>a</code> tag a class
|
||||
in that case.</p>
|
||||
<pre><pre class="playground"><code class="language-rust no_run edition2021">
|
||||
<span class="boring">#![allow(unused)]
|
||||
</span><span class="boring">fn main() {
|
||||
</span><span class="boring">// Hidden lines (like this one) make the documentation tests work.
|
||||
</span><span class="boring">extern crate dioxus;
|
||||
</span><span class="boring">use dioxus::prelude::*;
|
||||
</span><span class="boring">extern crate dioxus_router;
|
||||
</span><span class="boring">use dioxus_router::prelude::*;
|
||||
</span><span class="boring">
|
||||
</span>fn NavBar(cx: Scope) -> Element {
|
||||
render! {
|
||||
nav {
|
||||
ul {
|
||||
li { Link {
|
||||
target: NavigationTarget::Internal(String::from("/")),
|
||||
active_class: "active", // this is new
|
||||
"Home"
|
||||
} }
|
||||
li { Link {
|
||||
target: "/blog",
|
||||
active_class: "active", // this is new
|
||||
"Blog"
|
||||
} }
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
<span class="boring">}
|
||||
</span></code></pre></pre>
|
||||
<blockquote>
|
||||
<p>This will not be reflected in the <a href="./full-code.html">full example code</a>.</p>
|
||||
</blockquote>
|
||||
<h2 id="url-parameters-and-nested-routes"><a class="header" href="#url-parameters-and-nested-routes">URL Parameters and Nested Routes</a></h2>
|
||||
<p>Many websites such as GitHub put parameters in their URL. For example,
|
||||
<code>https://github.com/DioxusLabs</code> utilizes the text after the domain to
|
||||
dynamically search and display content about an organization.</p>
|
||||
<p>We want to store our blogs in a database and load them as needed. This'll help
|
||||
prevent our app from being bloated therefor providing faster load times. We also
|
||||
want our users to be able to send people a link to a specific blog post.</p>
|
||||
<p>We could utilize a search page that loads a blog when clicked but then our users
|
||||
won't be able to share our blogs easily. This is where URL parameters come in.</p>
|
||||
<p>The path to our blog will look like <code>/blog/myBlogPage</code>, <code>myBlogPage</code> being the
|
||||
URL parameter.</p>
|
||||
<p>First, lets create a component that wraps around all blog content. This allows
|
||||
us to add a heading that tells the user they are on the blog.</p>
|
||||
<pre><pre class="playground"><code class="language-rust no_run edition2021">
|
||||
<span class="boring">#![allow(unused)]
|
||||
</span><span class="boring">fn main() {
|
||||
</span><span class="boring">// Hidden lines (like this one) make the documentation tests work.
|
||||
</span><span class="boring">extern crate dioxus;
|
||||
</span><span class="boring">use dioxus::prelude::*;
|
||||
</span><span class="boring">extern crate dioxus_router;
|
||||
</span><span class="boring">use dioxus_router::prelude::*;
|
||||
</span><span class="boring">
|
||||
</span>fn Blog(cx: Scope) -> Element {
|
||||
render! {
|
||||
h1 { "Blog" }
|
||||
Outlet {}
|
||||
}
|
||||
}
|
||||
<span class="boring">}
|
||||
</span></code></pre></pre>
|
||||
<blockquote>
|
||||
<p>Note the <code>Outlet { }</code> component. For the components of a nested route to be
|
||||
rendered, we need an equally nested outlet. For more details, see the
|
||||
<a href="../features/routes/nested.html">nested routes</a> chapter of the features section.</p>
|
||||
</blockquote>
|
||||
<p>Now we'll create another index component, that'll be displayed when no blog post
|
||||
is selected:</p>
|
||||
<pre><pre class="playground"><code class="language-rust no_run edition2021">
|
||||
<span class="boring">#![allow(unused)]
|
||||
</span><span class="boring">fn main() {
|
||||
</span><span class="boring">// Hidden lines (like this one) make the documentation tests work.
|
||||
</span><span class="boring">extern crate dioxus;
|
||||
</span><span class="boring">use dioxus::prelude::*;
|
||||
</span><span class="boring">extern crate dioxus_router;
|
||||
</span><span class="boring">use dioxus_router::prelude::*;
|
||||
</span><span class="boring">
|
||||
</span>fn BlogList(cx: Scope) -> Element {
|
||||
render! {
|
||||
h2 { "Choose a post" }
|
||||
ul {
|
||||
li { Link {
|
||||
target: "/blog/1",
|
||||
"Read the first blog post"
|
||||
} }
|
||||
li { Link {
|
||||
target: "/blog/2",
|
||||
"Read the second blog post"
|
||||
} }
|
||||
}
|
||||
}
|
||||
}
|
||||
<span class="boring">}
|
||||
</span></code></pre></pre>
|
||||
<p>We also need to create a component that displays an actual blog post. Within
|
||||
this component we can use the <code>use_route</code> hook to gain access to our URL
|
||||
parameters:</p>
|
||||
<pre><pre class="playground"><code class="language-rust no_run edition2021">
|
||||
<span class="boring">#![allow(unused)]
|
||||
</span><span class="boring">fn main() {
|
||||
</span><span class="boring">// Hidden lines (like this one) make the documentation tests work.
|
||||
</span><span class="boring">extern crate dioxus;
|
||||
</span><span class="boring">use dioxus::prelude::*;
|
||||
</span><span class="boring">extern crate dioxus_router;
|
||||
</span><span class="boring">use dioxus_router::prelude::*;
|
||||
</span><span class="boring">
|
||||
</span>struct PostId;
|
||||
|
||||
fn BlogPost(cx: Scope) -> Element {
|
||||
let route = use_route(cx).unwrap();
|
||||
|
||||
let post_id = route.parameter::<PostId>();
|
||||
let post = post_id
|
||||
.map(|id| id.to_string())
|
||||
.unwrap_or(String::from("unknown"));
|
||||
|
||||
render! {
|
||||
h2 { "Blog Post: {post}"}
|
||||
}
|
||||
}
|
||||
<span class="boring">}
|
||||
</span></code></pre></pre>
|
||||
<p>Finally, let's tell our router about those components.</p>
|
||||
<pre><pre class="playground"><code class="language-rust no_run edition2021">
|
||||
<span class="boring">#![allow(unused)]
|
||||
</span><span class="boring">fn main() {
|
||||
</span><span class="boring">// Hidden lines (like this one) make the documentation tests work.
|
||||
</span><span class="boring">extern crate dioxus;
|
||||
</span><span class="boring">use dioxus::prelude::*;
|
||||
</span><span class="boring">extern crate dioxus_router;
|
||||
</span><span class="boring">use dioxus_router::prelude::*;
|
||||
</span><span class="boring">fn Blog(cx: Scope) -> Element { unimplemented!() }
|
||||
</span><span class="boring">fn BlogList(cx: Scope) -> Element { unimplemented!() }
|
||||
</span><span class="boring">struct PostId;
|
||||
</span><span class="boring">fn BlogPost(cx: Scope) -> Element { unimplemented!() }
|
||||
</span><span class="boring">fn Home(cx: Scope) -> Element { unimplemented!() }
|
||||
</span><span class="boring">fn NavBar(cx: Scope) -> Element { unimplemented!() }
|
||||
</span><span class="boring">fn PageNotFound(cx: Scope) -> Element { unimplemented!() }
|
||||
</span><span class="boring">
|
||||
</span>fn App(cx: Scope) -> Element {
|
||||
use_router(
|
||||
cx,
|
||||
&|| RouterConfiguration::default(),
|
||||
&|| {
|
||||
Segment::content(comp(Home))
|
||||
// new stuff starts here
|
||||
.fixed("blog", Route::content(comp(Blog)).nested(
|
||||
Segment::content(comp(BlogList))
|
||||
.catch_all((comp(BlogPost), PostId { }))
|
||||
))
|
||||
// new stuff ends here
|
||||
.fallback(comp(PageNotFound))
|
||||
}
|
||||
);
|
||||
|
||||
render! {
|
||||
NavBar { }
|
||||
Outlet { }
|
||||
}
|
||||
}
|
||||
<span class="boring">}
|
||||
</span></code></pre></pre>
|
||||
<p>That's it! If you head to <code>/blog/1</code> you should see our sample post.</p>
|
||||
<h2 id="conclusion"><a class="header" href="#conclusion">Conclusion</a></h2>
|
||||
<p>In this chapter we utilized Dioxus Router's Link, URL Parameter, and <code>use_route</code>
|
||||
functionality to build the blog portion of our application. In the next chapter,
|
||||
we will go over how navigation targets (like the one we passed to our links)
|
||||
work.</p>
|
||||
|
||||
</main>
|
||||
|
||||
<nav class="nav-wrapper" aria-label="Page navigation">
|
||||
<!-- Mobile navigation buttons -->
|
||||
<a rel="prev" href="../example/first-route.html" class="mobile-nav-chapters previous" title="Previous chapter" aria-label="Previous chapter" aria-keyshortcuts="Left">
|
||||
<i class="fa fa-angle-left"></i>
|
||||
</a>
|
||||
|
||||
<a rel="next" href="../example/navigation-targets.html" class="mobile-nav-chapters next" title="Next chapter" aria-label="Next chapter" aria-keyshortcuts="Right">
|
||||
<i class="fa fa-angle-right"></i>
|
||||
</a>
|
||||
|
||||
<div style="clear: both"></div>
|
||||
</nav>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<nav class="nav-wide-wrapper" aria-label="Page navigation">
|
||||
<a rel="prev" href="../example/first-route.html" class="nav-chapters previous" title="Previous chapter" aria-label="Previous chapter" aria-keyshortcuts="Left">
|
||||
<i class="fa fa-angle-left"></i>
|
||||
</a>
|
||||
|
||||
<a rel="next" href="../example/navigation-targets.html" class="nav-chapters next" title="Next chapter" aria-label="Next chapter" aria-keyshortcuts="Right">
|
||||
<i class="fa fa-angle-right"></i>
|
||||
</a>
|
||||
</nav>
|
||||
|
||||
</div>
|
||||
|
||||
|
||||
|
||||
|
||||
<script type="text/javascript">
|
||||
window.playground_copyable = true;
|
||||
</script>
|
||||
|
||||
|
||||
<script src="../elasticlunr.min.js" type="text/javascript" charset="utf-8"></script>
|
||||
<script src="../mark.min.js" type="text/javascript" charset="utf-8"></script>
|
||||
<script src="../searcher.js" type="text/javascript" charset="utf-8"></script>
|
||||
|
||||
<script src="../clipboard.min.js" type="text/javascript" charset="utf-8"></script>
|
||||
<script src="../highlight.js" type="text/javascript" charset="utf-8"></script>
|
||||
<script src="../book.js" type="text/javascript" charset="utf-8"></script>
|
||||
|
||||
<!-- Custom JS scripts -->
|
||||
|
||||
|
||||
</body>
|
||||
</html>
|
||||
@@ -0,0 +1,91 @@
|
||||
use dioxus::prelude::*;
|
||||
use dioxus_router::prelude::*;
|
||||
|
||||
fn main() {
|
||||
dioxus_web::launch(App);
|
||||
}
|
||||
|
||||
fn App(cx: Scope) -> Element {
|
||||
use_router(
|
||||
cx,
|
||||
&|| RouterConfiguration::default(),
|
||||
&|| {
|
||||
Segment::content(comp(Home))
|
||||
.fixed("blog", Route::content(comp(Blog)).nested(
|
||||
Segment::content(comp(BlogList)).catch_all(
|
||||
ParameterRoute::content::<PostId>(comp(BlogPost))
|
||||
.name::<BlogPostName>()
|
||||
)
|
||||
))
|
||||
.fixed("myblog", "/blog") // this is new
|
||||
.fallback(comp(PageNotFound))
|
||||
}
|
||||
);
|
||||
|
||||
render! {
|
||||
NavBar {}
|
||||
Outlet {}
|
||||
}
|
||||
}
|
||||
|
||||
fn NavBar(cx: Scope) -> Element {
|
||||
render! {
|
||||
nav {
|
||||
ul {
|
||||
li { Link { target: named::<RootIndex>(), "Home" } }
|
||||
li { Link { target: "/blog", "Blog" } }
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
fn Home(cx: Scope) -> Element {
|
||||
render! {
|
||||
h1 { "Welcome to the Dioxus Blog!" }
|
||||
}
|
||||
}
|
||||
|
||||
fn Blog(cx: Scope) -> Element {
|
||||
render! {
|
||||
h1 { "Blog" }
|
||||
Outlet {}
|
||||
}
|
||||
}
|
||||
|
||||
fn BlogList(cx: Scope) -> Element {
|
||||
render! {
|
||||
h2 { "Choose a post" }
|
||||
ul {
|
||||
li { Link {
|
||||
target: named::<BlogPostName>().parameter::<PostId>("1"),
|
||||
"Read the first blog post"
|
||||
} }
|
||||
li { Link {
|
||||
target: named::<BlogPostName>().parameter::<PostId>("2"),
|
||||
"Read the second blog post"
|
||||
} }
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
struct PostId;
|
||||
struct BlogPostName;
|
||||
fn BlogPost(cx: Scope) -> Element {
|
||||
let route = use_route(cx).unwrap();
|
||||
|
||||
let post_id = route.parameter::<PostId>();
|
||||
let post = post_id
|
||||
.map(|id| id.to_string())
|
||||
.unwrap_or(String::from("unknown"));
|
||||
|
||||
render! {
|
||||
h2 { "Blog Post: {post}"}
|
||||
}
|
||||
}
|
||||
|
||||
fn PageNotFound(cx: Scope) -> Element {
|
||||
render! {
|
||||
h1 { "Page not found" }
|
||||
p { "We are terribly sorry, but the page you requested doesn't exist." }
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,313 @@
|
||||
<!DOCTYPE HTML>
|
||||
<html lang="en" class="sidebar-visible no-js light">
|
||||
<head>
|
||||
<!-- Book generated using mdBook -->
|
||||
<meta charset="UTF-8">
|
||||
<title>Creating Our First Route - Dioxus Router</title>
|
||||
|
||||
|
||||
<!-- Custom HTML head -->
|
||||
|
||||
<meta content="text/html; charset=utf-8" http-equiv="Content-Type">
|
||||
<meta name="description" content="">
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1">
|
||||
<meta name="theme-color" content="#ffffff" />
|
||||
|
||||
<link rel="icon" href="../favicon.svg">
|
||||
<link rel="shortcut icon" href="../favicon.png">
|
||||
<link rel="stylesheet" href="../css/variables.css">
|
||||
<link rel="stylesheet" href="../css/general.css">
|
||||
<link rel="stylesheet" href="../css/chrome.css">
|
||||
<link rel="stylesheet" href="../css/print.css" media="print">
|
||||
|
||||
<!-- Fonts -->
|
||||
<link rel="stylesheet" href="../FontAwesome/css/font-awesome.css">
|
||||
<link rel="stylesheet" href="../fonts/fonts.css">
|
||||
|
||||
<!-- Highlight.js Stylesheets -->
|
||||
<link rel="stylesheet" href="../highlight.css">
|
||||
<link rel="stylesheet" href="../tomorrow-night.css">
|
||||
<link rel="stylesheet" href="../ayu-highlight.css">
|
||||
|
||||
<!-- Custom theme stylesheets -->
|
||||
|
||||
</head>
|
||||
<body>
|
||||
<!-- Provide site root to javascript -->
|
||||
<script type="text/javascript">
|
||||
var path_to_root = "../";
|
||||
var default_theme = window.matchMedia("(prefers-color-scheme: dark)").matches ? "navy" : "light";
|
||||
</script>
|
||||
|
||||
<!-- Work around some values being stored in localStorage wrapped in quotes -->
|
||||
<script type="text/javascript">
|
||||
try {
|
||||
var theme = localStorage.getItem('mdbook-theme');
|
||||
var sidebar = localStorage.getItem('mdbook-sidebar');
|
||||
|
||||
if (theme.startsWith('"') && theme.endsWith('"')) {
|
||||
localStorage.setItem('mdbook-theme', theme.slice(1, theme.length - 1));
|
||||
}
|
||||
|
||||
if (sidebar.startsWith('"') && sidebar.endsWith('"')) {
|
||||
localStorage.setItem('mdbook-sidebar', sidebar.slice(1, sidebar.length - 1));
|
||||
}
|
||||
} catch (e) { }
|
||||
</script>
|
||||
|
||||
<!-- Set the theme before any content is loaded, prevents flash -->
|
||||
<script type="text/javascript">
|
||||
var theme;
|
||||
try { theme = localStorage.getItem('mdbook-theme'); } catch(e) { }
|
||||
if (theme === null || theme === undefined) { theme = default_theme; }
|
||||
var html = document.querySelector('html');
|
||||
html.classList.remove('no-js')
|
||||
html.classList.remove('light')
|
||||
html.classList.add(theme);
|
||||
html.classList.add('js');
|
||||
</script>
|
||||
|
||||
<!-- Hide / unhide sidebar before it is displayed -->
|
||||
<script type="text/javascript">
|
||||
var html = document.querySelector('html');
|
||||
var sidebar = 'hidden';
|
||||
if (document.body.clientWidth >= 1080) {
|
||||
try { sidebar = localStorage.getItem('mdbook-sidebar'); } catch(e) { }
|
||||
sidebar = sidebar || 'visible';
|
||||
}
|
||||
html.classList.remove('sidebar-visible');
|
||||
html.classList.add("sidebar-" + sidebar);
|
||||
</script>
|
||||
|
||||
<nav id="sidebar" class="sidebar" aria-label="Table of contents">
|
||||
<div class="sidebar-scrollbox">
|
||||
<ol class="chapter"><li class="chapter-item expanded affix "><a href="../index.html">Introduction</a></li><li class="chapter-item expanded affix "><li class="part-title">Features</li><li class="chapter-item expanded "><a href="../features/index.html"><strong aria-hidden="true">1.</strong> Adding the Router to Your Application</a></li><li class="chapter-item expanded "><a href="../features/routes/index.html"><strong aria-hidden="true">2.</strong> Defining Routes</a></li><li><ol class="section"><li class="chapter-item expanded "><a href="../features/routes/nested.html"><strong aria-hidden="true">2.1.</strong> Nested Routes</a></li><li class="chapter-item expanded "><a href="../features/routes/catch_all.html"><strong aria-hidden="true">2.2.</strong> Catch All Routes</a></li><li class="chapter-item expanded "><a href="../features/routes/matching.html"><strong aria-hidden="true">2.3.</strong> Matching Routes</a></li><li class="chapter-item expanded "><a href="../features/routes/fallback.html"><strong aria-hidden="true">2.4.</strong> Fallback Routes (404 page)</a></li><li class="chapter-item expanded "><a href="../features/routes/multiple-and-redirect.html"><strong aria-hidden="true">2.5.</strong> Multiple Components & Redirects</a></li></ol></li><li class="chapter-item expanded "><a href="../features/outlets.html"><strong aria-hidden="true">3.</strong> Outlets</a></li><li class="chapter-item expanded "><a href="../features/navigation/index.html"><strong aria-hidden="true">4.</strong> Links & Navigation</a></li><li><ol class="section"><li class="chapter-item expanded "><a href="../features/navigation/name.html"><strong aria-hidden="true">4.1.</strong> Named Navigation</a></li><li class="chapter-item expanded "><a href="../features/navigation/external.html"><strong aria-hidden="true">4.2.</strong> External Navigation</a></li><li class="chapter-item expanded "><a href="../features/navigation/programmatic.html"><strong aria-hidden="true">4.3.</strong> Programmatic Navigation</a></li></ol></li><li class="chapter-item expanded "><a href="../features/query.html"><strong aria-hidden="true">5.</strong> Query</a></li><li class="chapter-item expanded "><a href="../features/failures/index.html"><strong aria-hidden="true">6.</strong> Navigation Failures</a></li><li><ol class="section"><li class="chapter-item expanded "><a href="../features/failures/named.html"><strong aria-hidden="true">6.1.</strong> Named Navigation Failure</a></li><li class="chapter-item expanded "><a href="../features/failures/external.html"><strong aria-hidden="true">6.2.</strong> External Navigation Failure</a></li><li class="chapter-item expanded "><a href="../features/failures/redirection-limit.html"><strong aria-hidden="true">6.3.</strong> Redirection Limit Failure</a></li></ol></li><li class="chapter-item expanded "><a href="../features/history-providers.html"><strong aria-hidden="true">7.</strong> History Providers</a></li><li class="chapter-item expanded "><a href="../features/history-buttons.html"><strong aria-hidden="true">8.</strong> History Buttons</a></li><li class="chapter-item expanded "><a href="../features/sitemap-generation.html"><strong aria-hidden="true">9.</strong> Sitemap Generation</a></li><li class="chapter-item expanded "><a href="../features/routing-update-callback.html"><strong aria-hidden="true">10.</strong> Routing Update Callback</a></li><li class="chapter-item expanded affix "><li class="part-title">Example Project</li><li class="chapter-item expanded "><a href="../example/index.html"><strong aria-hidden="true">11.</strong> Overview</a></li><li class="chapter-item expanded "><a href="../example/first-route.html" class="active"><strong aria-hidden="true">12.</strong> Creating Our First Route</a></li><li class="chapter-item expanded "><a href="../example/building-a-nest.html"><strong aria-hidden="true">13.</strong> Building a Nest</a></li><li class="chapter-item expanded "><a href="../example/navigation-targets.html"><strong aria-hidden="true">14.</strong> Navigation Targets</a></li><li class="chapter-item expanded "><a href="../example/redirection-perfection.html"><strong aria-hidden="true">15.</strong> Redirection Perfection</a></li><li class="chapter-item expanded "><a href="../example/full-code.html"><strong aria-hidden="true">16.</strong> Full Code</a></li></ol>
|
||||
</div>
|
||||
<div id="sidebar-resize-handle" class="sidebar-resize-handle"></div>
|
||||
</nav>
|
||||
|
||||
<div id="page-wrapper" class="page-wrapper">
|
||||
|
||||
<div class="page">
|
||||
<div id="menu-bar-hover-placeholder"></div>
|
||||
<div id="menu-bar" class="menu-bar sticky bordered">
|
||||
<div class="left-buttons">
|
||||
<button id="sidebar-toggle" class="icon-button" type="button" title="Toggle Table of Contents" aria-label="Toggle Table of Contents" aria-controls="sidebar">
|
||||
<i class="fa fa-bars"></i>
|
||||
</button>
|
||||
<button id="theme-toggle" class="icon-button" type="button" title="Change theme" aria-label="Change theme" aria-haspopup="true" aria-expanded="false" aria-controls="theme-list">
|
||||
<i class="fa fa-paint-brush"></i>
|
||||
</button>
|
||||
<ul id="theme-list" class="theme-popup" aria-label="Themes" role="menu">
|
||||
<li role="none"><button role="menuitem" class="theme" id="light">Light (default)</button></li>
|
||||
<li role="none"><button role="menuitem" class="theme" id="rust">Rust</button></li>
|
||||
<li role="none"><button role="menuitem" class="theme" id="coal">Coal</button></li>
|
||||
<li role="none"><button role="menuitem" class="theme" id="navy">Navy</button></li>
|
||||
<li role="none"><button role="menuitem" class="theme" id="ayu">Ayu</button></li>
|
||||
</ul>
|
||||
<button id="search-toggle" class="icon-button" type="button" title="Search. (Shortkey: s)" aria-label="Toggle Searchbar" aria-expanded="false" aria-keyshortcuts="S" aria-controls="searchbar">
|
||||
<i class="fa fa-search"></i>
|
||||
</button>
|
||||
</div>
|
||||
|
||||
<h1 class="menu-title">Dioxus Router</h1>
|
||||
|
||||
<div class="right-buttons">
|
||||
<a href="../print.html" title="Print this book" aria-label="Print this book">
|
||||
<i id="print-button" class="fa fa-print"></i>
|
||||
</a>
|
||||
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div id="search-wrapper" class="hidden">
|
||||
<form id="searchbar-outer" class="searchbar-outer">
|
||||
<input type="search" id="searchbar" name="searchbar" placeholder="Search this book ..." aria-controls="searchresults-outer" aria-describedby="searchresults-header">
|
||||
</form>
|
||||
<div id="searchresults-outer" class="searchresults-outer hidden">
|
||||
<div id="searchresults-header" class="searchresults-header"></div>
|
||||
<ul id="searchresults">
|
||||
</ul>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- Apply ARIA attributes after the sidebar and the sidebar toggle button are added to the DOM -->
|
||||
<script type="text/javascript">
|
||||
document.getElementById('sidebar-toggle').setAttribute('aria-expanded', sidebar === 'visible');
|
||||
document.getElementById('sidebar').setAttribute('aria-hidden', sidebar !== 'visible');
|
||||
Array.from(document.querySelectorAll('#sidebar a')).forEach(function(link) {
|
||||
link.setAttribute('tabIndex', sidebar === 'visible' ? 0 : -1);
|
||||
});
|
||||
</script>
|
||||
|
||||
<div id="content" class="content">
|
||||
<main>
|
||||
<h1 id="creating-our-first-route"><a class="header" href="#creating-our-first-route">Creating Our First Route</a></h1>
|
||||
<p>In this chapter, we will start utilizing Dioxus Router and add a homepage and a
|
||||
404 page to our project.</p>
|
||||
<h2 id="fundamentals"><a class="header" href="#fundamentals">Fundamentals</a></h2>
|
||||
<p>Dioxus Router works based on a <a href="https://docs.rs/dioxus-router/latest/dioxus_router/hooks/fn.use_router.html"><code>use_router</code></a> hook, a route definition in pure
|
||||
rust and <a href="https://docs.rs/dioxus-router/latest/dioxus_router/components/fn.Outlet.html"><code>Outlet</code></a> components. If you've ever used <a href="https://router.vuejs.org/">Vue Router</a>, you should
|
||||
feel right at home with Dioxus Router.</p>
|
||||
<p>First we need an actual page to route to! Let's add a homepage component:</p>
|
||||
<pre><pre class="playground"><code class="language-rust no_run edition2021">
|
||||
<span class="boring">#![allow(unused)]
|
||||
</span><span class="boring">fn main() {
|
||||
</span><span class="boring">// Hidden lines (like this one) make the documentation tests work.
|
||||
</span><span class="boring">extern crate dioxus;
|
||||
</span><span class="boring">use dioxus::prelude::*;
|
||||
</span><span class="boring">
|
||||
</span>fn Home(cx: Scope) -> Element {
|
||||
render! {
|
||||
h1 { "Welcome to the Dioxus Blog!" }
|
||||
}
|
||||
}
|
||||
<span class="boring">}
|
||||
</span></code></pre></pre>
|
||||
<h2 id="to-route-or-not-to-route"><a class="header" href="#to-route-or-not-to-route">To Route or Not to Route</a></h2>
|
||||
<p>We want to use Dioxus Router to separate our application into different "pages".
|
||||
Dioxus Router will then determine which page to render based on the URL path.</p>
|
||||
<p>To start using Dioxus Router, we need to use the <a href="https://docs.rs/dioxus-router/latest/dioxus_router/hooks/fn.use_router.html"><code>use_router</code></a> hook. All other
|
||||
hooks and components the router provides can only be used as a descendant of a
|
||||
component calling <a href="https://docs.rs/dioxus-router/latest/dioxus_router/hooks/fn.use_router.html"><code>use_router</code></a>.</p>
|
||||
<p>The <a href="https://docs.rs/dioxus-router/latest/dioxus_router/hooks/fn.use_router.html"><code>use_router</code></a> hook takes three arguments:</p>
|
||||
<ol>
|
||||
<li><code>cx</code>, which is a common argument for all hooks.</li>
|
||||
<li>A <a href="https://docs.rs/dioxus-router/latest/dioxus_router/hooks/struct.RouterConfiguration.html"><code>RouterConfiguration</code></a>, which allows us to modify its behavior.</li>
|
||||
<li>A definition of all routes the application contains, in the form of its root
|
||||
<a href="https://docs.rs/dioxus-router-core/latest/dioxus_router_core/routes/struct.Segment.html"><code>Segment</code></a>.</li>
|
||||
</ol>
|
||||
<pre><pre class="playground"><code class="language-rust no_run edition2021">
|
||||
<span class="boring">#![allow(unused)]
|
||||
</span><span class="boring">fn main() {
|
||||
</span><span class="boring">// Hidden lines (like this one) make the documentation tests work.
|
||||
</span><span class="boring">extern crate dioxus;
|
||||
</span>use dioxus::prelude::*;
|
||||
<span class="boring">extern crate dioxus_router;
|
||||
</span>use dioxus_router::prelude::*;
|
||||
<span class="boring">fn Home(cx: Scope) -> Element { unimplemented!() }
|
||||
</span>
|
||||
fn App(cx: Scope) -> Element {
|
||||
use_router(
|
||||
cx,
|
||||
&|| RouterConfiguration::default(),
|
||||
&|| Segment::content(comp(Home))
|
||||
);
|
||||
|
||||
render! {
|
||||
Outlet { }
|
||||
}
|
||||
}
|
||||
<span class="boring">}
|
||||
</span></code></pre></pre>
|
||||
<p>If you head to your application's browser tab, you should now see the text
|
||||
<code>Welcome to Dioxus Blog!</code> when on the root URL (<code>http://localhost:8080/</code>). If
|
||||
you enter a different path for the URL, nothing should be displayed.</p>
|
||||
<p>This is because we told Dioxus Router to render the <code>Home</code> component only when
|
||||
the URL path is <code>/</code>. The <em>index</em> (<code>Segment::content()</code>) functionality we used
|
||||
basically emulates how web servers treat <code>index.html</code> files.</p>
|
||||
<h2 id="what-if-a-route-doesnt-exist"><a class="header" href="#what-if-a-route-doesnt-exist">What if a Route Doesn't Exist?</a></h2>
|
||||
<p>In our example Dioxus Router doesn't render anything. Many sites also have a
|
||||
"404" page for when a URL path leads to nowhere. Dioxus Router can do this too!</p>
|
||||
<p>First, we create a new <code>PageNotFound</code> component.</p>
|
||||
<pre><pre class="playground"><code class="language-rust no_run edition2021">
|
||||
<span class="boring">#![allow(unused)]
|
||||
</span><span class="boring">fn main() {
|
||||
</span><span class="boring">// Hidden lines (like this one) make the documentation tests work.
|
||||
</span><span class="boring">extern crate dioxus;
|
||||
</span><span class="boring">use dioxus::prelude::*;
|
||||
</span><span class="boring">
|
||||
</span>fn PageNotFound(cx: Scope) -> Element {
|
||||
render! {
|
||||
h1 { "Page not found" }
|
||||
p { "We are terribly sorry, but the page you requested doesn't exist." }
|
||||
}
|
||||
}
|
||||
<span class="boring">}
|
||||
</span></code></pre></pre>
|
||||
<p>Now to tell Dioxus Router to render our new component when no route exists.</p>
|
||||
<pre><pre class="playground"><code class="language-rust no_run edition2021">
|
||||
<span class="boring">#![allow(unused)]
|
||||
</span><span class="boring">fn main() {
|
||||
</span><span class="boring">// Hidden lines (like this one) make the documentation tests work.
|
||||
</span><span class="boring">extern crate dioxus;
|
||||
</span><span class="boring">use dioxus::prelude::*;
|
||||
</span><span class="boring">extern crate dioxus_router;
|
||||
</span><span class="boring">use dioxus_router::prelude::*;
|
||||
</span><span class="boring">fn Home(cx: Scope) -> Element { unimplemented!() }
|
||||
</span><span class="boring">fn PageNotFound(cx: Scope) -> Element { unimplemented!() }
|
||||
</span><span class="boring">
|
||||
</span>fn App(cx: Scope) -> Element {
|
||||
use_router(
|
||||
cx,
|
||||
&|| RouterConfiguration::default(),
|
||||
&|| {
|
||||
Segment::content(comp(Home))
|
||||
.fallback(comp(PageNotFound)) // this is new
|
||||
}
|
||||
);
|
||||
|
||||
render! {
|
||||
Outlet { }
|
||||
}
|
||||
}
|
||||
<span class="boring">}
|
||||
</span></code></pre></pre>
|
||||
<p>Now when you go to a route that doesn't exist, you should see the page not found
|
||||
text.</p>
|
||||
<h2 id="conclusion"><a class="header" href="#conclusion">Conclusion</a></h2>
|
||||
<p>In this chapter we learned how to create a route and tell Dioxus Router what
|
||||
component to render when the URL path is <code>/</code>. We also created a 404 page to
|
||||
handle when a route doesn't exist. Next, we'll create the blog portion of our
|
||||
site. We will utilize nested routes and URL parameters.</p>
|
||||
|
||||
</main>
|
||||
|
||||
<nav class="nav-wrapper" aria-label="Page navigation">
|
||||
<!-- Mobile navigation buttons -->
|
||||
<a rel="prev" href="../example/index.html" class="mobile-nav-chapters previous" title="Previous chapter" aria-label="Previous chapter" aria-keyshortcuts="Left">
|
||||
<i class="fa fa-angle-left"></i>
|
||||
</a>
|
||||
|
||||
<a rel="next" href="../example/building-a-nest.html" class="mobile-nav-chapters next" title="Next chapter" aria-label="Next chapter" aria-keyshortcuts="Right">
|
||||
<i class="fa fa-angle-right"></i>
|
||||
</a>
|
||||
|
||||
<div style="clear: both"></div>
|
||||
</nav>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<nav class="nav-wide-wrapper" aria-label="Page navigation">
|
||||
<a rel="prev" href="../example/index.html" class="nav-chapters previous" title="Previous chapter" aria-label="Previous chapter" aria-keyshortcuts="Left">
|
||||
<i class="fa fa-angle-left"></i>
|
||||
</a>
|
||||
|
||||
<a rel="next" href="../example/building-a-nest.html" class="nav-chapters next" title="Next chapter" aria-label="Next chapter" aria-keyshortcuts="Right">
|
||||
<i class="fa fa-angle-right"></i>
|
||||
</a>
|
||||
</nav>
|
||||
|
||||
</div>
|
||||
|
||||
|
||||
|
||||
|
||||
<script type="text/javascript">
|
||||
window.playground_copyable = true;
|
||||
</script>
|
||||
|
||||
|
||||
<script src="../elasticlunr.min.js" type="text/javascript" charset="utf-8"></script>
|
||||
<script src="../mark.min.js" type="text/javascript" charset="utf-8"></script>
|
||||
<script src="../searcher.js" type="text/javascript" charset="utf-8"></script>
|
||||
|
||||
<script src="../clipboard.min.js" type="text/javascript" charset="utf-8"></script>
|
||||
<script src="../highlight.js" type="text/javascript" charset="utf-8"></script>
|
||||
<script src="../book.js" type="text/javascript" charset="utf-8"></script>
|
||||
|
||||
<!-- Custom JS scripts -->
|
||||
|
||||
|
||||
</body>
|
||||
</html>
|
||||
@@ -0,0 +1,286 @@
|
||||
<!DOCTYPE HTML>
|
||||
<html lang="en" class="sidebar-visible no-js light">
|
||||
<head>
|
||||
<!-- Book generated using mdBook -->
|
||||
<meta charset="UTF-8">
|
||||
<title>Full Code - Dioxus Router</title>
|
||||
|
||||
|
||||
<!-- Custom HTML head -->
|
||||
|
||||
<meta content="text/html; charset=utf-8" http-equiv="Content-Type">
|
||||
<meta name="description" content="">
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1">
|
||||
<meta name="theme-color" content="#ffffff" />
|
||||
|
||||
<link rel="icon" href="../favicon.svg">
|
||||
<link rel="shortcut icon" href="../favicon.png">
|
||||
<link rel="stylesheet" href="../css/variables.css">
|
||||
<link rel="stylesheet" href="../css/general.css">
|
||||
<link rel="stylesheet" href="../css/chrome.css">
|
||||
<link rel="stylesheet" href="../css/print.css" media="print">
|
||||
|
||||
<!-- Fonts -->
|
||||
<link rel="stylesheet" href="../FontAwesome/css/font-awesome.css">
|
||||
<link rel="stylesheet" href="../fonts/fonts.css">
|
||||
|
||||
<!-- Highlight.js Stylesheets -->
|
||||
<link rel="stylesheet" href="../highlight.css">
|
||||
<link rel="stylesheet" href="../tomorrow-night.css">
|
||||
<link rel="stylesheet" href="../ayu-highlight.css">
|
||||
|
||||
<!-- Custom theme stylesheets -->
|
||||
|
||||
</head>
|
||||
<body>
|
||||
<!-- Provide site root to javascript -->
|
||||
<script type="text/javascript">
|
||||
var path_to_root = "../";
|
||||
var default_theme = window.matchMedia("(prefers-color-scheme: dark)").matches ? "navy" : "light";
|
||||
</script>
|
||||
|
||||
<!-- Work around some values being stored in localStorage wrapped in quotes -->
|
||||
<script type="text/javascript">
|
||||
try {
|
||||
var theme = localStorage.getItem('mdbook-theme');
|
||||
var sidebar = localStorage.getItem('mdbook-sidebar');
|
||||
|
||||
if (theme.startsWith('"') && theme.endsWith('"')) {
|
||||
localStorage.setItem('mdbook-theme', theme.slice(1, theme.length - 1));
|
||||
}
|
||||
|
||||
if (sidebar.startsWith('"') && sidebar.endsWith('"')) {
|
||||
localStorage.setItem('mdbook-sidebar', sidebar.slice(1, sidebar.length - 1));
|
||||
}
|
||||
} catch (e) { }
|
||||
</script>
|
||||
|
||||
<!-- Set the theme before any content is loaded, prevents flash -->
|
||||
<script type="text/javascript">
|
||||
var theme;
|
||||
try { theme = localStorage.getItem('mdbook-theme'); } catch(e) { }
|
||||
if (theme === null || theme === undefined) { theme = default_theme; }
|
||||
var html = document.querySelector('html');
|
||||
html.classList.remove('no-js')
|
||||
html.classList.remove('light')
|
||||
html.classList.add(theme);
|
||||
html.classList.add('js');
|
||||
</script>
|
||||
|
||||
<!-- Hide / unhide sidebar before it is displayed -->
|
||||
<script type="text/javascript">
|
||||
var html = document.querySelector('html');
|
||||
var sidebar = 'hidden';
|
||||
if (document.body.clientWidth >= 1080) {
|
||||
try { sidebar = localStorage.getItem('mdbook-sidebar'); } catch(e) { }
|
||||
sidebar = sidebar || 'visible';
|
||||
}
|
||||
html.classList.remove('sidebar-visible');
|
||||
html.classList.add("sidebar-" + sidebar);
|
||||
</script>
|
||||
|
||||
<nav id="sidebar" class="sidebar" aria-label="Table of contents">
|
||||
<div class="sidebar-scrollbox">
|
||||
<ol class="chapter"><li class="chapter-item expanded affix "><a href="../index.html">Introduction</a></li><li class="chapter-item expanded affix "><li class="part-title">Features</li><li class="chapter-item expanded "><a href="../features/index.html"><strong aria-hidden="true">1.</strong> Adding the Router to Your Application</a></li><li class="chapter-item expanded "><a href="../features/routes/index.html"><strong aria-hidden="true">2.</strong> Defining Routes</a></li><li><ol class="section"><li class="chapter-item expanded "><a href="../features/routes/nested.html"><strong aria-hidden="true">2.1.</strong> Nested Routes</a></li><li class="chapter-item expanded "><a href="../features/routes/catch_all.html"><strong aria-hidden="true">2.2.</strong> Catch All Routes</a></li><li class="chapter-item expanded "><a href="../features/routes/matching.html"><strong aria-hidden="true">2.3.</strong> Matching Routes</a></li><li class="chapter-item expanded "><a href="../features/routes/fallback.html"><strong aria-hidden="true">2.4.</strong> Fallback Routes (404 page)</a></li><li class="chapter-item expanded "><a href="../features/routes/multiple-and-redirect.html"><strong aria-hidden="true">2.5.</strong> Multiple Components & Redirects</a></li></ol></li><li class="chapter-item expanded "><a href="../features/outlets.html"><strong aria-hidden="true">3.</strong> Outlets</a></li><li class="chapter-item expanded "><a href="../features/navigation/index.html"><strong aria-hidden="true">4.</strong> Links & Navigation</a></li><li><ol class="section"><li class="chapter-item expanded "><a href="../features/navigation/name.html"><strong aria-hidden="true">4.1.</strong> Named Navigation</a></li><li class="chapter-item expanded "><a href="../features/navigation/external.html"><strong aria-hidden="true">4.2.</strong> External Navigation</a></li><li class="chapter-item expanded "><a href="../features/navigation/programmatic.html"><strong aria-hidden="true">4.3.</strong> Programmatic Navigation</a></li></ol></li><li class="chapter-item expanded "><a href="../features/query.html"><strong aria-hidden="true">5.</strong> Query</a></li><li class="chapter-item expanded "><a href="../features/failures/index.html"><strong aria-hidden="true">6.</strong> Navigation Failures</a></li><li><ol class="section"><li class="chapter-item expanded "><a href="../features/failures/named.html"><strong aria-hidden="true">6.1.</strong> Named Navigation Failure</a></li><li class="chapter-item expanded "><a href="../features/failures/external.html"><strong aria-hidden="true">6.2.</strong> External Navigation Failure</a></li><li class="chapter-item expanded "><a href="../features/failures/redirection-limit.html"><strong aria-hidden="true">6.3.</strong> Redirection Limit Failure</a></li></ol></li><li class="chapter-item expanded "><a href="../features/history-providers.html"><strong aria-hidden="true">7.</strong> History Providers</a></li><li class="chapter-item expanded "><a href="../features/history-buttons.html"><strong aria-hidden="true">8.</strong> History Buttons</a></li><li class="chapter-item expanded "><a href="../features/sitemap-generation.html"><strong aria-hidden="true">9.</strong> Sitemap Generation</a></li><li class="chapter-item expanded "><a href="../features/routing-update-callback.html"><strong aria-hidden="true">10.</strong> Routing Update Callback</a></li><li class="chapter-item expanded affix "><li class="part-title">Example Project</li><li class="chapter-item expanded "><a href="../example/index.html"><strong aria-hidden="true">11.</strong> Overview</a></li><li class="chapter-item expanded "><a href="../example/first-route.html"><strong aria-hidden="true">12.</strong> Creating Our First Route</a></li><li class="chapter-item expanded "><a href="../example/building-a-nest.html"><strong aria-hidden="true">13.</strong> Building a Nest</a></li><li class="chapter-item expanded "><a href="../example/navigation-targets.html"><strong aria-hidden="true">14.</strong> Navigation Targets</a></li><li class="chapter-item expanded "><a href="../example/redirection-perfection.html"><strong aria-hidden="true">15.</strong> Redirection Perfection</a></li><li class="chapter-item expanded "><a href="../example/full-code.html" class="active"><strong aria-hidden="true">16.</strong> Full Code</a></li></ol>
|
||||
</div>
|
||||
<div id="sidebar-resize-handle" class="sidebar-resize-handle"></div>
|
||||
</nav>
|
||||
|
||||
<div id="page-wrapper" class="page-wrapper">
|
||||
|
||||
<div class="page">
|
||||
<div id="menu-bar-hover-placeholder"></div>
|
||||
<div id="menu-bar" class="menu-bar sticky bordered">
|
||||
<div class="left-buttons">
|
||||
<button id="sidebar-toggle" class="icon-button" type="button" title="Toggle Table of Contents" aria-label="Toggle Table of Contents" aria-controls="sidebar">
|
||||
<i class="fa fa-bars"></i>
|
||||
</button>
|
||||
<button id="theme-toggle" class="icon-button" type="button" title="Change theme" aria-label="Change theme" aria-haspopup="true" aria-expanded="false" aria-controls="theme-list">
|
||||
<i class="fa fa-paint-brush"></i>
|
||||
</button>
|
||||
<ul id="theme-list" class="theme-popup" aria-label="Themes" role="menu">
|
||||
<li role="none"><button role="menuitem" class="theme" id="light">Light (default)</button></li>
|
||||
<li role="none"><button role="menuitem" class="theme" id="rust">Rust</button></li>
|
||||
<li role="none"><button role="menuitem" class="theme" id="coal">Coal</button></li>
|
||||
<li role="none"><button role="menuitem" class="theme" id="navy">Navy</button></li>
|
||||
<li role="none"><button role="menuitem" class="theme" id="ayu">Ayu</button></li>
|
||||
</ul>
|
||||
<button id="search-toggle" class="icon-button" type="button" title="Search. (Shortkey: s)" aria-label="Toggle Searchbar" aria-expanded="false" aria-keyshortcuts="S" aria-controls="searchbar">
|
||||
<i class="fa fa-search"></i>
|
||||
</button>
|
||||
</div>
|
||||
|
||||
<h1 class="menu-title">Dioxus Router</h1>
|
||||
|
||||
<div class="right-buttons">
|
||||
<a href="../print.html" title="Print this book" aria-label="Print this book">
|
||||
<i id="print-button" class="fa fa-print"></i>
|
||||
</a>
|
||||
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div id="search-wrapper" class="hidden">
|
||||
<form id="searchbar-outer" class="searchbar-outer">
|
||||
<input type="search" id="searchbar" name="searchbar" placeholder="Search this book ..." aria-controls="searchresults-outer" aria-describedby="searchresults-header">
|
||||
</form>
|
||||
<div id="searchresults-outer" class="searchresults-outer hidden">
|
||||
<div id="searchresults-header" class="searchresults-header"></div>
|
||||
<ul id="searchresults">
|
||||
</ul>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- Apply ARIA attributes after the sidebar and the sidebar toggle button are added to the DOM -->
|
||||
<script type="text/javascript">
|
||||
document.getElementById('sidebar-toggle').setAttribute('aria-expanded', sidebar === 'visible');
|
||||
document.getElementById('sidebar').setAttribute('aria-hidden', sidebar !== 'visible');
|
||||
Array.from(document.querySelectorAll('#sidebar a')).forEach(function(link) {
|
||||
link.setAttribute('tabIndex', sidebar === 'visible' ? 0 : -1);
|
||||
});
|
||||
</script>
|
||||
|
||||
<div id="content" class="content">
|
||||
<main>
|
||||
<h1 id="full-code"><a class="header" href="#full-code">Full Code</a></h1>
|
||||
<pre><pre class="playground"><code class="language-rust no_run edition2021"><span class="boring">// Hidden lines (like this one) make the documentation tests work.
|
||||
</span><span class="boring">extern crate dioxus;
|
||||
</span><span class="boring">extern crate dioxus_router;
|
||||
</span><span class="boring">extern crate dioxus_web;
|
||||
</span>use dioxus::prelude::*;
|
||||
use dioxus_router::prelude::*;
|
||||
|
||||
fn main() {
|
||||
dioxus_web::launch(App);
|
||||
}
|
||||
|
||||
fn App(cx: Scope) -> Element {
|
||||
use_router(
|
||||
cx,
|
||||
&|| RouterConfiguration::default(),
|
||||
&|| {
|
||||
Segment::content(comp(Home))
|
||||
.fixed("blog", Route::content(comp(Blog)).nested(
|
||||
Segment::content(comp(BlogList)).catch_all(
|
||||
ParameterRoute::content::<PostId>(comp(BlogPost))
|
||||
.name::<BlogPostName>()
|
||||
)
|
||||
))
|
||||
.fixed("myblog", "/blog") // this is new
|
||||
.fallback(comp(PageNotFound))
|
||||
}
|
||||
);
|
||||
|
||||
render! {
|
||||
NavBar {}
|
||||
Outlet {}
|
||||
}
|
||||
}
|
||||
|
||||
fn NavBar(cx: Scope) -> Element {
|
||||
render! {
|
||||
nav {
|
||||
ul {
|
||||
li { Link { target: named::<RootIndex>(), "Home" } }
|
||||
li { Link { target: "/blog", "Blog" } }
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
fn Home(cx: Scope) -> Element {
|
||||
render! {
|
||||
h1 { "Welcome to the Dioxus Blog!" }
|
||||
}
|
||||
}
|
||||
|
||||
fn Blog(cx: Scope) -> Element {
|
||||
render! {
|
||||
h1 { "Blog" }
|
||||
Outlet {}
|
||||
}
|
||||
}
|
||||
|
||||
fn BlogList(cx: Scope) -> Element {
|
||||
render! {
|
||||
h2 { "Choose a post" }
|
||||
ul {
|
||||
li { Link {
|
||||
target: named::<BlogPostName>().parameter::<PostId>("1"),
|
||||
"Read the first blog post"
|
||||
} }
|
||||
li { Link {
|
||||
target: named::<BlogPostName>().parameter::<PostId>("2"),
|
||||
"Read the second blog post"
|
||||
} }
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
struct PostId;
|
||||
struct BlogPostName;
|
||||
fn BlogPost(cx: Scope) -> Element {
|
||||
let route = use_route(cx).unwrap();
|
||||
|
||||
let post_id = route.parameter::<PostId>();
|
||||
let post = post_id
|
||||
.map(|id| id.to_string())
|
||||
.unwrap_or(String::from("unknown"));
|
||||
|
||||
render! {
|
||||
h2 { "Blog Post: {post}"}
|
||||
}
|
||||
}
|
||||
|
||||
fn PageNotFound(cx: Scope) -> Element {
|
||||
render! {
|
||||
h1 { "Page not found" }
|
||||
p { "We are terribly sorry, but the page you requested doesn't exist." }
|
||||
}
|
||||
}
|
||||
</code></pre></pre>
|
||||
|
||||
</main>
|
||||
|
||||
<nav class="nav-wrapper" aria-label="Page navigation">
|
||||
<!-- Mobile navigation buttons -->
|
||||
<a rel="prev" href="../example/redirection-perfection.html" class="mobile-nav-chapters previous" title="Previous chapter" aria-label="Previous chapter" aria-keyshortcuts="Left">
|
||||
<i class="fa fa-angle-left"></i>
|
||||
</a>
|
||||
|
||||
|
||||
<div style="clear: both"></div>
|
||||
</nav>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<nav class="nav-wide-wrapper" aria-label="Page navigation">
|
||||
<a rel="prev" href="../example/redirection-perfection.html" class="nav-chapters previous" title="Previous chapter" aria-label="Previous chapter" aria-keyshortcuts="Left">
|
||||
<i class="fa fa-angle-left"></i>
|
||||
</a>
|
||||
|
||||
</nav>
|
||||
|
||||
</div>
|
||||
|
||||
|
||||
|
||||
|
||||
<script type="text/javascript">
|
||||
window.playground_copyable = true;
|
||||
</script>
|
||||
|
||||
|
||||
<script src="../elasticlunr.min.js" type="text/javascript" charset="utf-8"></script>
|
||||
<script src="../mark.min.js" type="text/javascript" charset="utf-8"></script>
|
||||
<script src="../searcher.js" type="text/javascript" charset="utf-8"></script>
|
||||
|
||||
<script src="../clipboard.min.js" type="text/javascript" charset="utf-8"></script>
|
||||
<script src="../highlight.js" type="text/javascript" charset="utf-8"></script>
|
||||
<script src="../book.js" type="text/javascript" charset="utf-8"></script>
|
||||
|
||||
<!-- Custom JS scripts -->
|
||||
|
||||
|
||||
</body>
|
||||
</html>
|
||||
@@ -0,0 +1,224 @@
|
||||
<!DOCTYPE HTML>
|
||||
<html lang="en" class="sidebar-visible no-js light">
|
||||
<head>
|
||||
<!-- Book generated using mdBook -->
|
||||
<meta charset="UTF-8">
|
||||
<title>Overview - Dioxus Router</title>
|
||||
|
||||
|
||||
<!-- Custom HTML head -->
|
||||
|
||||
<meta content="text/html; charset=utf-8" http-equiv="Content-Type">
|
||||
<meta name="description" content="">
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1">
|
||||
<meta name="theme-color" content="#ffffff" />
|
||||
|
||||
<link rel="icon" href="../favicon.svg">
|
||||
<link rel="shortcut icon" href="../favicon.png">
|
||||
<link rel="stylesheet" href="../css/variables.css">
|
||||
<link rel="stylesheet" href="../css/general.css">
|
||||
<link rel="stylesheet" href="../css/chrome.css">
|
||||
<link rel="stylesheet" href="../css/print.css" media="print">
|
||||
|
||||
<!-- Fonts -->
|
||||
<link rel="stylesheet" href="../FontAwesome/css/font-awesome.css">
|
||||
<link rel="stylesheet" href="../fonts/fonts.css">
|
||||
|
||||
<!-- Highlight.js Stylesheets -->
|
||||
<link rel="stylesheet" href="../highlight.css">
|
||||
<link rel="stylesheet" href="../tomorrow-night.css">
|
||||
<link rel="stylesheet" href="../ayu-highlight.css">
|
||||
|
||||
<!-- Custom theme stylesheets -->
|
||||
|
||||
</head>
|
||||
<body>
|
||||
<!-- Provide site root to javascript -->
|
||||
<script type="text/javascript">
|
||||
var path_to_root = "../";
|
||||
var default_theme = window.matchMedia("(prefers-color-scheme: dark)").matches ? "navy" : "light";
|
||||
</script>
|
||||
|
||||
<!-- Work around some values being stored in localStorage wrapped in quotes -->
|
||||
<script type="text/javascript">
|
||||
try {
|
||||
var theme = localStorage.getItem('mdbook-theme');
|
||||
var sidebar = localStorage.getItem('mdbook-sidebar');
|
||||
|
||||
if (theme.startsWith('"') && theme.endsWith('"')) {
|
||||
localStorage.setItem('mdbook-theme', theme.slice(1, theme.length - 1));
|
||||
}
|
||||
|
||||
if (sidebar.startsWith('"') && sidebar.endsWith('"')) {
|
||||
localStorage.setItem('mdbook-sidebar', sidebar.slice(1, sidebar.length - 1));
|
||||
}
|
||||
} catch (e) { }
|
||||
</script>
|
||||
|
||||
<!-- Set the theme before any content is loaded, prevents flash -->
|
||||
<script type="text/javascript">
|
||||
var theme;
|
||||
try { theme = localStorage.getItem('mdbook-theme'); } catch(e) { }
|
||||
if (theme === null || theme === undefined) { theme = default_theme; }
|
||||
var html = document.querySelector('html');
|
||||
html.classList.remove('no-js')
|
||||
html.classList.remove('light')
|
||||
html.classList.add(theme);
|
||||
html.classList.add('js');
|
||||
</script>
|
||||
|
||||
<!-- Hide / unhide sidebar before it is displayed -->
|
||||
<script type="text/javascript">
|
||||
var html = document.querySelector('html');
|
||||
var sidebar = 'hidden';
|
||||
if (document.body.clientWidth >= 1080) {
|
||||
try { sidebar = localStorage.getItem('mdbook-sidebar'); } catch(e) { }
|
||||
sidebar = sidebar || 'visible';
|
||||
}
|
||||
html.classList.remove('sidebar-visible');
|
||||
html.classList.add("sidebar-" + sidebar);
|
||||
</script>
|
||||
|
||||
<nav id="sidebar" class="sidebar" aria-label="Table of contents">
|
||||
<div class="sidebar-scrollbox">
|
||||
<ol class="chapter"><li class="chapter-item expanded affix "><a href="../index.html">Introduction</a></li><li class="chapter-item expanded affix "><li class="part-title">Features</li><li class="chapter-item expanded "><a href="../features/index.html"><strong aria-hidden="true">1.</strong> Adding the Router to Your Application</a></li><li class="chapter-item expanded "><a href="../features/routes/index.html"><strong aria-hidden="true">2.</strong> Defining Routes</a></li><li><ol class="section"><li class="chapter-item expanded "><a href="../features/routes/nested.html"><strong aria-hidden="true">2.1.</strong> Nested Routes</a></li><li class="chapter-item expanded "><a href="../features/routes/catch_all.html"><strong aria-hidden="true">2.2.</strong> Catch All Routes</a></li><li class="chapter-item expanded "><a href="../features/routes/matching.html"><strong aria-hidden="true">2.3.</strong> Matching Routes</a></li><li class="chapter-item expanded "><a href="../features/routes/fallback.html"><strong aria-hidden="true">2.4.</strong> Fallback Routes (404 page)</a></li><li class="chapter-item expanded "><a href="../features/routes/multiple-and-redirect.html"><strong aria-hidden="true">2.5.</strong> Multiple Components & Redirects</a></li></ol></li><li class="chapter-item expanded "><a href="../features/outlets.html"><strong aria-hidden="true">3.</strong> Outlets</a></li><li class="chapter-item expanded "><a href="../features/navigation/index.html"><strong aria-hidden="true">4.</strong> Links & Navigation</a></li><li><ol class="section"><li class="chapter-item expanded "><a href="../features/navigation/name.html"><strong aria-hidden="true">4.1.</strong> Named Navigation</a></li><li class="chapter-item expanded "><a href="../features/navigation/external.html"><strong aria-hidden="true">4.2.</strong> External Navigation</a></li><li class="chapter-item expanded "><a href="../features/navigation/programmatic.html"><strong aria-hidden="true">4.3.</strong> Programmatic Navigation</a></li></ol></li><li class="chapter-item expanded "><a href="../features/query.html"><strong aria-hidden="true">5.</strong> Query</a></li><li class="chapter-item expanded "><a href="../features/failures/index.html"><strong aria-hidden="true">6.</strong> Navigation Failures</a></li><li><ol class="section"><li class="chapter-item expanded "><a href="../features/failures/named.html"><strong aria-hidden="true">6.1.</strong> Named Navigation Failure</a></li><li class="chapter-item expanded "><a href="../features/failures/external.html"><strong aria-hidden="true">6.2.</strong> External Navigation Failure</a></li><li class="chapter-item expanded "><a href="../features/failures/redirection-limit.html"><strong aria-hidden="true">6.3.</strong> Redirection Limit Failure</a></li></ol></li><li class="chapter-item expanded "><a href="../features/history-providers.html"><strong aria-hidden="true">7.</strong> History Providers</a></li><li class="chapter-item expanded "><a href="../features/history-buttons.html"><strong aria-hidden="true">8.</strong> History Buttons</a></li><li class="chapter-item expanded "><a href="../features/sitemap-generation.html"><strong aria-hidden="true">9.</strong> Sitemap Generation</a></li><li class="chapter-item expanded "><a href="../features/routing-update-callback.html"><strong aria-hidden="true">10.</strong> Routing Update Callback</a></li><li class="chapter-item expanded affix "><li class="part-title">Example Project</li><li class="chapter-item expanded "><a href="../example/index.html" class="active"><strong aria-hidden="true">11.</strong> Overview</a></li><li class="chapter-item expanded "><a href="../example/first-route.html"><strong aria-hidden="true">12.</strong> Creating Our First Route</a></li><li class="chapter-item expanded "><a href="../example/building-a-nest.html"><strong aria-hidden="true">13.</strong> Building a Nest</a></li><li class="chapter-item expanded "><a href="../example/navigation-targets.html"><strong aria-hidden="true">14.</strong> Navigation Targets</a></li><li class="chapter-item expanded "><a href="../example/redirection-perfection.html"><strong aria-hidden="true">15.</strong> Redirection Perfection</a></li><li class="chapter-item expanded "><a href="../example/full-code.html"><strong aria-hidden="true">16.</strong> Full Code</a></li></ol>
|
||||
</div>
|
||||
<div id="sidebar-resize-handle" class="sidebar-resize-handle"></div>
|
||||
</nav>
|
||||
|
||||
<div id="page-wrapper" class="page-wrapper">
|
||||
|
||||
<div class="page">
|
||||
<div id="menu-bar-hover-placeholder"></div>
|
||||
<div id="menu-bar" class="menu-bar sticky bordered">
|
||||
<div class="left-buttons">
|
||||
<button id="sidebar-toggle" class="icon-button" type="button" title="Toggle Table of Contents" aria-label="Toggle Table of Contents" aria-controls="sidebar">
|
||||
<i class="fa fa-bars"></i>
|
||||
</button>
|
||||
<button id="theme-toggle" class="icon-button" type="button" title="Change theme" aria-label="Change theme" aria-haspopup="true" aria-expanded="false" aria-controls="theme-list">
|
||||
<i class="fa fa-paint-brush"></i>
|
||||
</button>
|
||||
<ul id="theme-list" class="theme-popup" aria-label="Themes" role="menu">
|
||||
<li role="none"><button role="menuitem" class="theme" id="light">Light (default)</button></li>
|
||||
<li role="none"><button role="menuitem" class="theme" id="rust">Rust</button></li>
|
||||
<li role="none"><button role="menuitem" class="theme" id="coal">Coal</button></li>
|
||||
<li role="none"><button role="menuitem" class="theme" id="navy">Navy</button></li>
|
||||
<li role="none"><button role="menuitem" class="theme" id="ayu">Ayu</button></li>
|
||||
</ul>
|
||||
<button id="search-toggle" class="icon-button" type="button" title="Search. (Shortkey: s)" aria-label="Toggle Searchbar" aria-expanded="false" aria-keyshortcuts="S" aria-controls="searchbar">
|
||||
<i class="fa fa-search"></i>
|
||||
</button>
|
||||
</div>
|
||||
|
||||
<h1 class="menu-title">Dioxus Router</h1>
|
||||
|
||||
<div class="right-buttons">
|
||||
<a href="../print.html" title="Print this book" aria-label="Print this book">
|
||||
<i id="print-button" class="fa fa-print"></i>
|
||||
</a>
|
||||
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div id="search-wrapper" class="hidden">
|
||||
<form id="searchbar-outer" class="searchbar-outer">
|
||||
<input type="search" id="searchbar" name="searchbar" placeholder="Search this book ..." aria-controls="searchresults-outer" aria-describedby="searchresults-header">
|
||||
</form>
|
||||
<div id="searchresults-outer" class="searchresults-outer hidden">
|
||||
<div id="searchresults-header" class="searchresults-header"></div>
|
||||
<ul id="searchresults">
|
||||
</ul>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- Apply ARIA attributes after the sidebar and the sidebar toggle button are added to the DOM -->
|
||||
<script type="text/javascript">
|
||||
document.getElementById('sidebar-toggle').setAttribute('aria-expanded', sidebar === 'visible');
|
||||
document.getElementById('sidebar').setAttribute('aria-hidden', sidebar !== 'visible');
|
||||
Array.from(document.querySelectorAll('#sidebar a')).forEach(function(link) {
|
||||
link.setAttribute('tabIndex', sidebar === 'visible' ? 0 : -1);
|
||||
});
|
||||
</script>
|
||||
|
||||
<div id="content" class="content">
|
||||
<main>
|
||||
<h1 id="overview"><a class="header" href="#overview">Overview</a></h1>
|
||||
<p>In this guide you'll learn to effectively use Dioxus Router whether you're
|
||||
building a small todo app or the next FAANG company. We will create a small
|
||||
website with a blog, homepage, and more!</p>
|
||||
<blockquote>
|
||||
<p>To follow along with the router example, you'll need a working Dioxus app.
|
||||
Check out the <a href="https://dioxuslabs.com/guide/">Dioxus book</a> to get started.</p>
|
||||
</blockquote>
|
||||
<blockquote>
|
||||
<p>Make sure to add Dioxus Router as a dependency, as explained in the
|
||||
<a href="../index.html">introduction</a>.</p>
|
||||
</blockquote>
|
||||
<h2 id="youll-learn-how-to"><a class="header" href="#youll-learn-how-to">You'll learn how to</a></h2>
|
||||
<ul>
|
||||
<li>Create routes and render "pages".</li>
|
||||
<li>Utilize nested routes, create a navigation bar, and render content for a
|
||||
set of routes.</li>
|
||||
<li>Gather URL parameters to dynamically display content.</li>
|
||||
<li>Redirect your visitors wherever you want.</li>
|
||||
</ul>
|
||||
<blockquote>
|
||||
<p><strong>Disclaimer</strong></p>
|
||||
<p>The example will only display the features of Dioxus Router. It will not
|
||||
include any actual functionality. To keep things simple we will only be using
|
||||
a single file, this is not the recommended way of doing things with a real
|
||||
application.</p>
|
||||
</blockquote>
|
||||
<p>You can find the complete application in the <a href="./full-code.html">full code</a>
|
||||
chapter.</p>
|
||||
|
||||
</main>
|
||||
|
||||
<nav class="nav-wrapper" aria-label="Page navigation">
|
||||
<!-- Mobile navigation buttons -->
|
||||
<a rel="prev" href="../features/routing-update-callback.html" class="mobile-nav-chapters previous" title="Previous chapter" aria-label="Previous chapter" aria-keyshortcuts="Left">
|
||||
<i class="fa fa-angle-left"></i>
|
||||
</a>
|
||||
|
||||
<a rel="next" href="../example/first-route.html" class="mobile-nav-chapters next" title="Next chapter" aria-label="Next chapter" aria-keyshortcuts="Right">
|
||||
<i class="fa fa-angle-right"></i>
|
||||
</a>
|
||||
|
||||
<div style="clear: both"></div>
|
||||
</nav>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<nav class="nav-wide-wrapper" aria-label="Page navigation">
|
||||
<a rel="prev" href="../features/routing-update-callback.html" class="nav-chapters previous" title="Previous chapter" aria-label="Previous chapter" aria-keyshortcuts="Left">
|
||||
<i class="fa fa-angle-left"></i>
|
||||
</a>
|
||||
|
||||
<a rel="next" href="../example/first-route.html" class="nav-chapters next" title="Next chapter" aria-label="Next chapter" aria-keyshortcuts="Right">
|
||||
<i class="fa fa-angle-right"></i>
|
||||
</a>
|
||||
</nav>
|
||||
|
||||
</div>
|
||||
|
||||
|
||||
|
||||
|
||||
<script type="text/javascript">
|
||||
window.playground_copyable = true;
|
||||
</script>
|
||||
|
||||
|
||||
<script src="../elasticlunr.min.js" type="text/javascript" charset="utf-8"></script>
|
||||
<script src="../mark.min.js" type="text/javascript" charset="utf-8"></script>
|
||||
<script src="../searcher.js" type="text/javascript" charset="utf-8"></script>
|
||||
|
||||
<script src="../clipboard.min.js" type="text/javascript" charset="utf-8"></script>
|
||||
<script src="../highlight.js" type="text/javascript" charset="utf-8"></script>
|
||||
<script src="../book.js" type="text/javascript" charset="utf-8"></script>
|
||||
|
||||
<!-- Custom JS scripts -->
|
||||
|
||||
|
||||
</body>
|
||||
</html>
|
||||
@@ -0,0 +1,357 @@
|
||||
<!DOCTYPE HTML>
|
||||
<html lang="en" class="sidebar-visible no-js light">
|
||||
<head>
|
||||
<!-- Book generated using mdBook -->
|
||||
<meta charset="UTF-8">
|
||||
<title>Navigation Targets - Dioxus Router</title>
|
||||
|
||||
|
||||
<!-- Custom HTML head -->
|
||||
|
||||
<meta content="text/html; charset=utf-8" http-equiv="Content-Type">
|
||||
<meta name="description" content="">
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1">
|
||||
<meta name="theme-color" content="#ffffff" />
|
||||
|
||||
<link rel="icon" href="../favicon.svg">
|
||||
<link rel="shortcut icon" href="../favicon.png">
|
||||
<link rel="stylesheet" href="../css/variables.css">
|
||||
<link rel="stylesheet" href="../css/general.css">
|
||||
<link rel="stylesheet" href="../css/chrome.css">
|
||||
<link rel="stylesheet" href="../css/print.css" media="print">
|
||||
|
||||
<!-- Fonts -->
|
||||
<link rel="stylesheet" href="../FontAwesome/css/font-awesome.css">
|
||||
<link rel="stylesheet" href="../fonts/fonts.css">
|
||||
|
||||
<!-- Highlight.js Stylesheets -->
|
||||
<link rel="stylesheet" href="../highlight.css">
|
||||
<link rel="stylesheet" href="../tomorrow-night.css">
|
||||
<link rel="stylesheet" href="../ayu-highlight.css">
|
||||
|
||||
<!-- Custom theme stylesheets -->
|
||||
|
||||
</head>
|
||||
<body>
|
||||
<!-- Provide site root to javascript -->
|
||||
<script type="text/javascript">
|
||||
var path_to_root = "../";
|
||||
var default_theme = window.matchMedia("(prefers-color-scheme: dark)").matches ? "navy" : "light";
|
||||
</script>
|
||||
|
||||
<!-- Work around some values being stored in localStorage wrapped in quotes -->
|
||||
<script type="text/javascript">
|
||||
try {
|
||||
var theme = localStorage.getItem('mdbook-theme');
|
||||
var sidebar = localStorage.getItem('mdbook-sidebar');
|
||||
|
||||
if (theme.startsWith('"') && theme.endsWith('"')) {
|
||||
localStorage.setItem('mdbook-theme', theme.slice(1, theme.length - 1));
|
||||
}
|
||||
|
||||
if (sidebar.startsWith('"') && sidebar.endsWith('"')) {
|
||||
localStorage.setItem('mdbook-sidebar', sidebar.slice(1, sidebar.length - 1));
|
||||
}
|
||||
} catch (e) { }
|
||||
</script>
|
||||
|
||||
<!-- Set the theme before any content is loaded, prevents flash -->
|
||||
<script type="text/javascript">
|
||||
var theme;
|
||||
try { theme = localStorage.getItem('mdbook-theme'); } catch(e) { }
|
||||
if (theme === null || theme === undefined) { theme = default_theme; }
|
||||
var html = document.querySelector('html');
|
||||
html.classList.remove('no-js')
|
||||
html.classList.remove('light')
|
||||
html.classList.add(theme);
|
||||
html.classList.add('js');
|
||||
</script>
|
||||
|
||||
<!-- Hide / unhide sidebar before it is displayed -->
|
||||
<script type="text/javascript">
|
||||
var html = document.querySelector('html');
|
||||
var sidebar = 'hidden';
|
||||
if (document.body.clientWidth >= 1080) {
|
||||
try { sidebar = localStorage.getItem('mdbook-sidebar'); } catch(e) { }
|
||||
sidebar = sidebar || 'visible';
|
||||
}
|
||||
html.classList.remove('sidebar-visible');
|
||||
html.classList.add("sidebar-" + sidebar);
|
||||
</script>
|
||||
|
||||
<nav id="sidebar" class="sidebar" aria-label="Table of contents">
|
||||
<div class="sidebar-scrollbox">
|
||||
<ol class="chapter"><li class="chapter-item expanded affix "><a href="../index.html">Introduction</a></li><li class="chapter-item expanded affix "><li class="part-title">Features</li><li class="chapter-item expanded "><a href="../features/index.html"><strong aria-hidden="true">1.</strong> Adding the Router to Your Application</a></li><li class="chapter-item expanded "><a href="../features/routes/index.html"><strong aria-hidden="true">2.</strong> Defining Routes</a></li><li><ol class="section"><li class="chapter-item expanded "><a href="../features/routes/nested.html"><strong aria-hidden="true">2.1.</strong> Nested Routes</a></li><li class="chapter-item expanded "><a href="../features/routes/catch_all.html"><strong aria-hidden="true">2.2.</strong> Catch All Routes</a></li><li class="chapter-item expanded "><a href="../features/routes/matching.html"><strong aria-hidden="true">2.3.</strong> Matching Routes</a></li><li class="chapter-item expanded "><a href="../features/routes/fallback.html"><strong aria-hidden="true">2.4.</strong> Fallback Routes (404 page)</a></li><li class="chapter-item expanded "><a href="../features/routes/multiple-and-redirect.html"><strong aria-hidden="true">2.5.</strong> Multiple Components & Redirects</a></li></ol></li><li class="chapter-item expanded "><a href="../features/outlets.html"><strong aria-hidden="true">3.</strong> Outlets</a></li><li class="chapter-item expanded "><a href="../features/navigation/index.html"><strong aria-hidden="true">4.</strong> Links & Navigation</a></li><li><ol class="section"><li class="chapter-item expanded "><a href="../features/navigation/name.html"><strong aria-hidden="true">4.1.</strong> Named Navigation</a></li><li class="chapter-item expanded "><a href="../features/navigation/external.html"><strong aria-hidden="true">4.2.</strong> External Navigation</a></li><li class="chapter-item expanded "><a href="../features/navigation/programmatic.html"><strong aria-hidden="true">4.3.</strong> Programmatic Navigation</a></li></ol></li><li class="chapter-item expanded "><a href="../features/query.html"><strong aria-hidden="true">5.</strong> Query</a></li><li class="chapter-item expanded "><a href="../features/failures/index.html"><strong aria-hidden="true">6.</strong> Navigation Failures</a></li><li><ol class="section"><li class="chapter-item expanded "><a href="../features/failures/named.html"><strong aria-hidden="true">6.1.</strong> Named Navigation Failure</a></li><li class="chapter-item expanded "><a href="../features/failures/external.html"><strong aria-hidden="true">6.2.</strong> External Navigation Failure</a></li><li class="chapter-item expanded "><a href="../features/failures/redirection-limit.html"><strong aria-hidden="true">6.3.</strong> Redirection Limit Failure</a></li></ol></li><li class="chapter-item expanded "><a href="../features/history-providers.html"><strong aria-hidden="true">7.</strong> History Providers</a></li><li class="chapter-item expanded "><a href="../features/history-buttons.html"><strong aria-hidden="true">8.</strong> History Buttons</a></li><li class="chapter-item expanded "><a href="../features/sitemap-generation.html"><strong aria-hidden="true">9.</strong> Sitemap Generation</a></li><li class="chapter-item expanded "><a href="../features/routing-update-callback.html"><strong aria-hidden="true">10.</strong> Routing Update Callback</a></li><li class="chapter-item expanded affix "><li class="part-title">Example Project</li><li class="chapter-item expanded "><a href="../example/index.html"><strong aria-hidden="true">11.</strong> Overview</a></li><li class="chapter-item expanded "><a href="../example/first-route.html"><strong aria-hidden="true">12.</strong> Creating Our First Route</a></li><li class="chapter-item expanded "><a href="../example/building-a-nest.html"><strong aria-hidden="true">13.</strong> Building a Nest</a></li><li class="chapter-item expanded "><a href="../example/navigation-targets.html" class="active"><strong aria-hidden="true">14.</strong> Navigation Targets</a></li><li class="chapter-item expanded "><a href="../example/redirection-perfection.html"><strong aria-hidden="true">15.</strong> Redirection Perfection</a></li><li class="chapter-item expanded "><a href="../example/full-code.html"><strong aria-hidden="true">16.</strong> Full Code</a></li></ol>
|
||||
</div>
|
||||
<div id="sidebar-resize-handle" class="sidebar-resize-handle"></div>
|
||||
</nav>
|
||||
|
||||
<div id="page-wrapper" class="page-wrapper">
|
||||
|
||||
<div class="page">
|
||||
<div id="menu-bar-hover-placeholder"></div>
|
||||
<div id="menu-bar" class="menu-bar sticky bordered">
|
||||
<div class="left-buttons">
|
||||
<button id="sidebar-toggle" class="icon-button" type="button" title="Toggle Table of Contents" aria-label="Toggle Table of Contents" aria-controls="sidebar">
|
||||
<i class="fa fa-bars"></i>
|
||||
</button>
|
||||
<button id="theme-toggle" class="icon-button" type="button" title="Change theme" aria-label="Change theme" aria-haspopup="true" aria-expanded="false" aria-controls="theme-list">
|
||||
<i class="fa fa-paint-brush"></i>
|
||||
</button>
|
||||
<ul id="theme-list" class="theme-popup" aria-label="Themes" role="menu">
|
||||
<li role="none"><button role="menuitem" class="theme" id="light">Light (default)</button></li>
|
||||
<li role="none"><button role="menuitem" class="theme" id="rust">Rust</button></li>
|
||||
<li role="none"><button role="menuitem" class="theme" id="coal">Coal</button></li>
|
||||
<li role="none"><button role="menuitem" class="theme" id="navy">Navy</button></li>
|
||||
<li role="none"><button role="menuitem" class="theme" id="ayu">Ayu</button></li>
|
||||
</ul>
|
||||
<button id="search-toggle" class="icon-button" type="button" title="Search. (Shortkey: s)" aria-label="Toggle Searchbar" aria-expanded="false" aria-keyshortcuts="S" aria-controls="searchbar">
|
||||
<i class="fa fa-search"></i>
|
||||
</button>
|
||||
</div>
|
||||
|
||||
<h1 class="menu-title">Dioxus Router</h1>
|
||||
|
||||
<div class="right-buttons">
|
||||
<a href="../print.html" title="Print this book" aria-label="Print this book">
|
||||
<i id="print-button" class="fa fa-print"></i>
|
||||
</a>
|
||||
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div id="search-wrapper" class="hidden">
|
||||
<form id="searchbar-outer" class="searchbar-outer">
|
||||
<input type="search" id="searchbar" name="searchbar" placeholder="Search this book ..." aria-controls="searchresults-outer" aria-describedby="searchresults-header">
|
||||
</form>
|
||||
<div id="searchresults-outer" class="searchresults-outer hidden">
|
||||
<div id="searchresults-header" class="searchresults-header"></div>
|
||||
<ul id="searchresults">
|
||||
</ul>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- Apply ARIA attributes after the sidebar and the sidebar toggle button are added to the DOM -->
|
||||
<script type="text/javascript">
|
||||
document.getElementById('sidebar-toggle').setAttribute('aria-expanded', sidebar === 'visible');
|
||||
document.getElementById('sidebar').setAttribute('aria-hidden', sidebar !== 'visible');
|
||||
Array.from(document.querySelectorAll('#sidebar a')).forEach(function(link) {
|
||||
link.setAttribute('tabIndex', sidebar === 'visible' ? 0 : -1);
|
||||
});
|
||||
</script>
|
||||
|
||||
<div id="content" class="content">
|
||||
<main>
|
||||
<h1 id="navigation-targets"><a class="header" href="#navigation-targets">Navigation Targets</a></h1>
|
||||
<p>In the previous chapter we learned how to create links to pages within our app.
|
||||
We told them where to go using the <code>target</code> property. This property takes a
|
||||
<a href="https://docs.rs/dioxus-router-core/latest/dioxus_router_core/navigation/enum.NavigationTarget.html"><code>NavigationTarget</code></a>.</p>
|
||||
<h2 id="what-is-a-navigation-target"><a class="header" href="#what-is-a-navigation-target">What is a navigation target?</a></h2>
|
||||
<p>A <a href="https://docs.rs/dioxus-router-core/latest/dioxus_router_core/navigation/enum.NavigationTarget.html"><code>NavigationTarget</code></a> is similar to the <code>href</code> of an HTML anchor element.It
|
||||
tells the router where to navigate to. The Dioxus Router knows three kinds of
|
||||
navigation targets:</p>
|
||||
<ul>
|
||||
<li><a href="https://docs.rs/dioxus-router-core/latest/dioxus_router_core/navigation/enum.NavigationTarget.html#variant.Internal"><code>Internal</code></a>: we already saw that. It's basically an <code>href</code>, but cannot
|
||||
link to content outside our app.</li>
|
||||
<li><a href="https://docs.rs/dioxus-router-core/latest/dioxus_router_core/navigation/enum.NavigationTarget.html#variant.External"><code>External</code></a>: This works exactly like an HTML anchors <code>href</code>. In fact,
|
||||
it is just passed through. Don't use this for in-app navigation as it'll
|
||||
trigger a page reload by the browser.</li>
|
||||
<li><a href="https://docs.rs/dioxus-router-core/latest/dioxus_router_core/navigation/enum.NavigationTarget.html#variant.Named"><code>Named</code></a>: this is the most interesting form of navigation target. We'll look
|
||||
at it in detail in this chapter.</li>
|
||||
</ul>
|
||||
<h2 id="external-navigation"><a class="header" href="#external-navigation">External navigation</a></h2>
|
||||
<p>If we need a link to an external page we can do it like this:</p>
|
||||
<pre><pre class="playground"><code class="language-rust no_run edition2021">
|
||||
<span class="boring">#![allow(unused)]
|
||||
</span><span class="boring">fn main() {
|
||||
</span><span class="boring">// Hidden lines (like this one) make the documentation tests work.
|
||||
</span><span class="boring">extern crate dioxus;
|
||||
</span><span class="boring">use dioxus::prelude::*;
|
||||
</span><span class="boring">extern crate dioxus_router;
|
||||
</span><span class="boring">use dioxus_router::prelude::*;
|
||||
</span><span class="boring">
|
||||
</span>fn GoToDioxus(cx: Scope) -> Element {
|
||||
render! {
|
||||
Link {
|
||||
target: NavigationTarget::External("https://dioxuslabs.com".into()),
|
||||
"Explicit ExternalTarget target"
|
||||
}
|
||||
Link {
|
||||
target: "https://dioxuslabs.com", // short form
|
||||
"Implicit ExternalTarget target"
|
||||
}
|
||||
}
|
||||
}
|
||||
<span class="boring">}
|
||||
</span></code></pre></pre>
|
||||
<blockquote>
|
||||
<p>Note that we can use a <code>str</code>, just like with <a href="https://docs.rs/dioxus-router-core/latest/dioxus_router_core/navigation/enum.NavigationTarget.html#variant.Internal"><code>Internal</code></a>s. The router will
|
||||
convert a <code>str</code> to an <a href="https://docs.rs/dioxus-router-core/latest/dioxus_router_core/navigation/enum.NavigationTarget.html#variant.External"><code>External</code></a> if the URL is absolute.</p>
|
||||
</blockquote>
|
||||
<h2 id="named-navigation"><a class="header" href="#named-navigation">Named navigation</a></h2>
|
||||
<p>When defining our routes, we can optionally give them unique static names. This
|
||||
is required for a feature we call named navigation.</p>
|
||||
<p>Up to now, when creating links we told the router the exact path to go to. With
|
||||
named navigation we instead give it a name, and let it figure out the path.</p>
|
||||
<p>This has several advantages:</p>
|
||||
<ul>
|
||||
<li>We don't have to remember absolute paths or care about what the current path
|
||||
is.</li>
|
||||
<li>Changing paths later on won't break internal links.</li>
|
||||
<li>Paths can easily be localized without affecting app logic.</li>
|
||||
<li>The compiler makes sure we don't have typos.</li>
|
||||
</ul>
|
||||
<p>Let's try that now! First, we give our blog post route a name. We can reuse our
|
||||
<code>BlogPost</code> component as a name.</p>
|
||||
<pre><pre class="playground"><code class="language-rust no_run edition2021">
|
||||
<span class="boring">#![allow(unused)]
|
||||
</span><span class="boring">fn main() {
|
||||
</span><span class="boring">// Hidden lines (like this one) make the documentation tests work.
|
||||
</span><span class="boring">extern crate dioxus;
|
||||
</span><span class="boring">use dioxus::prelude::*;
|
||||
</span><span class="boring">extern crate dioxus_router;
|
||||
</span><span class="boring">use dioxus_router::prelude::*;
|
||||
</span><span class="boring">fn Blog(cx: Scope) -> Element { unimplemented!() }
|
||||
</span><span class="boring">fn BlogList(cx: Scope) -> Element { unimplemented!() }
|
||||
</span><span class="boring">struct PostId;
|
||||
</span><span class="boring">fn BlogPost(cx: Scope) -> Element { unimplemented!() }
|
||||
</span><span class="boring">fn Home(cx: Scope) -> Element { unimplemented!() }
|
||||
</span><span class="boring">fn PageNotFound(cx: Scope) -> Element { unimplemented!() }
|
||||
</span><span class="boring">
|
||||
</span>struct BlogPostName;
|
||||
|
||||
fn App(cx: Scope) -> Element {
|
||||
use_router(
|
||||
cx,
|
||||
&|| RouterConfiguration::default(),
|
||||
&|| {
|
||||
Segment::content(comp(Home))
|
||||
.fixed("blog", Route::content(comp(Blog)).nested(
|
||||
Segment::content(comp(BlogList)).catch_all(
|
||||
ParameterRoute::content::<PostId>(comp(BlogPost))
|
||||
.name::<BlogPostName>() // this is new
|
||||
)
|
||||
))
|
||||
.fallback(comp(PageNotFound))
|
||||
}
|
||||
);
|
||||
|
||||
// ...
|
||||
<span class="boring"> unimplemented!()
|
||||
</span>}
|
||||
<span class="boring">}
|
||||
</span></code></pre></pre>
|
||||
<p>Now we can change the targets of the links in our <code>BlogList</code> component.</p>
|
||||
<pre><pre class="playground"><code class="language-rust no_run edition2021">
|
||||
<span class="boring">#![allow(unused)]
|
||||
</span><span class="boring">fn main() {
|
||||
</span><span class="boring">// Hidden lines (like this one) make the documentation tests work.
|
||||
</span><span class="boring">extern crate dioxus;
|
||||
</span><span class="boring">use dioxus::prelude::*;
|
||||
</span><span class="boring">extern crate dioxus_router;
|
||||
</span><span class="boring">use dioxus_router::prelude::*;
|
||||
</span><span class="boring">struct PostId;
|
||||
</span><span class="boring">struct BlogPostName;
|
||||
</span><span class="boring">fn BlogPost(cx: Scope) -> Element { unimplemented!() }
|
||||
</span><span class="boring">
|
||||
</span>fn BlogList(cx: Scope) -> Element {
|
||||
render! {
|
||||
h2 { "Choose a post" }
|
||||
ul {
|
||||
li { Link {
|
||||
target: named::<BlogPostName>().parameter::<PostId>("1"),
|
||||
"Read the first blog post"
|
||||
} }
|
||||
li { Link {
|
||||
target: named::<BlogPostName>()
|
||||
.parameter::<PostId>("1")
|
||||
.query("query"),
|
||||
"Read the second blog post"
|
||||
} }
|
||||
}
|
||||
}
|
||||
}
|
||||
<span class="boring">}
|
||||
</span></code></pre></pre>
|
||||
<p>As you can see, a <a href="https://docs.rs/dioxus-router-core/latest/dioxus_router_core/navigation/enum.NavigationTarget.html#variant.Named"><code>Named</code></a> requires three fields:</p>
|
||||
<ol>
|
||||
<li>the name to navigate to</li>
|
||||
<li>a <code>Vec</code> containing all parameters that need to be inserted into the path</li>
|
||||
<li>optionally a query string to use.</li>
|
||||
</ol>
|
||||
<h3 id="the-special-root-index-name"><a class="header" href="#the-special-root-index-name">The special root index name</a></h3>
|
||||
<p>Whether we define any names or not, the router always knows about the
|
||||
<a href="https://docs.rs/dioxus-router-core/latest/dioxus_router_core/prelude/struct.RootIndex.html"><code>RootIndex</code></a> name. Navigating to it tells the router to go to <code>/</code>.</p>
|
||||
<p>We can change the link in our <code>NavBar</code> component to take advantage of that.</p>
|
||||
<pre><pre class="playground"><code class="language-rust no_run edition2021">
|
||||
<span class="boring">#![allow(unused)]
|
||||
</span><span class="boring">fn main() {
|
||||
</span><span class="boring">// Hidden lines (like this one) make the documentation tests work.
|
||||
</span><span class="boring">extern crate dioxus;
|
||||
</span><span class="boring">use dioxus::prelude::*;
|
||||
</span><span class="boring">extern crate dioxus_router;
|
||||
</span><span class="boring">use dioxus_router::prelude::*;
|
||||
</span><span class="boring">
|
||||
</span>fn NavBar(cx: Scope) -> Element {
|
||||
render! {
|
||||
nav {
|
||||
ul {
|
||||
li { Link { target: named::<RootIndex>(), "Home" } }
|
||||
li { Link { target: "/blog", "Blog" } }
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
<span class="boring">}
|
||||
</span></code></pre></pre>
|
||||
|
||||
</main>
|
||||
|
||||
<nav class="nav-wrapper" aria-label="Page navigation">
|
||||
<!-- Mobile navigation buttons -->
|
||||
<a rel="prev" href="../example/building-a-nest.html" class="mobile-nav-chapters previous" title="Previous chapter" aria-label="Previous chapter" aria-keyshortcuts="Left">
|
||||
<i class="fa fa-angle-left"></i>
|
||||
</a>
|
||||
|
||||
<a rel="next" href="../example/redirection-perfection.html" class="mobile-nav-chapters next" title="Next chapter" aria-label="Next chapter" aria-keyshortcuts="Right">
|
||||
<i class="fa fa-angle-right"></i>
|
||||
</a>
|
||||
|
||||
<div style="clear: both"></div>
|
||||
</nav>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<nav class="nav-wide-wrapper" aria-label="Page navigation">
|
||||
<a rel="prev" href="../example/building-a-nest.html" class="nav-chapters previous" title="Previous chapter" aria-label="Previous chapter" aria-keyshortcuts="Left">
|
||||
<i class="fa fa-angle-left"></i>
|
||||
</a>
|
||||
|
||||
<a rel="next" href="../example/redirection-perfection.html" class="nav-chapters next" title="Next chapter" aria-label="Next chapter" aria-keyshortcuts="Right">
|
||||
<i class="fa fa-angle-right"></i>
|
||||
</a>
|
||||
</nav>
|
||||
|
||||
</div>
|
||||
|
||||
|
||||
|
||||
|
||||
<script type="text/javascript">
|
||||
window.playground_copyable = true;
|
||||
</script>
|
||||
|
||||
|
||||
<script src="../elasticlunr.min.js" type="text/javascript" charset="utf-8"></script>
|
||||
<script src="../mark.min.js" type="text/javascript" charset="utf-8"></script>
|
||||
<script src="../searcher.js" type="text/javascript" charset="utf-8"></script>
|
||||
|
||||
<script src="../clipboard.min.js" type="text/javascript" charset="utf-8"></script>
|
||||
<script src="../highlight.js" type="text/javascript" charset="utf-8"></script>
|
||||
<script src="../book.js" type="text/javascript" charset="utf-8"></script>
|
||||
|
||||
<!-- Custom JS scripts -->
|
||||
|
||||
|
||||
</body>
|
||||
</html>
|
||||
@@ -0,0 +1,259 @@
|
||||
<!DOCTYPE HTML>
|
||||
<html lang="en" class="sidebar-visible no-js light">
|
||||
<head>
|
||||
<!-- Book generated using mdBook -->
|
||||
<meta charset="UTF-8">
|
||||
<title>Redirection Perfection - Dioxus Router</title>
|
||||
|
||||
|
||||
<!-- Custom HTML head -->
|
||||
|
||||
<meta content="text/html; charset=utf-8" http-equiv="Content-Type">
|
||||
<meta name="description" content="">
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1">
|
||||
<meta name="theme-color" content="#ffffff" />
|
||||
|
||||
<link rel="icon" href="../favicon.svg">
|
||||
<link rel="shortcut icon" href="../favicon.png">
|
||||
<link rel="stylesheet" href="../css/variables.css">
|
||||
<link rel="stylesheet" href="../css/general.css">
|
||||
<link rel="stylesheet" href="../css/chrome.css">
|
||||
<link rel="stylesheet" href="../css/print.css" media="print">
|
||||
|
||||
<!-- Fonts -->
|
||||
<link rel="stylesheet" href="../FontAwesome/css/font-awesome.css">
|
||||
<link rel="stylesheet" href="../fonts/fonts.css">
|
||||
|
||||
<!-- Highlight.js Stylesheets -->
|
||||
<link rel="stylesheet" href="../highlight.css">
|
||||
<link rel="stylesheet" href="../tomorrow-night.css">
|
||||
<link rel="stylesheet" href="../ayu-highlight.css">
|
||||
|
||||
<!-- Custom theme stylesheets -->
|
||||
|
||||
</head>
|
||||
<body>
|
||||
<!-- Provide site root to javascript -->
|
||||
<script type="text/javascript">
|
||||
var path_to_root = "../";
|
||||
var default_theme = window.matchMedia("(prefers-color-scheme: dark)").matches ? "navy" : "light";
|
||||
</script>
|
||||
|
||||
<!-- Work around some values being stored in localStorage wrapped in quotes -->
|
||||
<script type="text/javascript">
|
||||
try {
|
||||
var theme = localStorage.getItem('mdbook-theme');
|
||||
var sidebar = localStorage.getItem('mdbook-sidebar');
|
||||
|
||||
if (theme.startsWith('"') && theme.endsWith('"')) {
|
||||
localStorage.setItem('mdbook-theme', theme.slice(1, theme.length - 1));
|
||||
}
|
||||
|
||||
if (sidebar.startsWith('"') && sidebar.endsWith('"')) {
|
||||
localStorage.setItem('mdbook-sidebar', sidebar.slice(1, sidebar.length - 1));
|
||||
}
|
||||
} catch (e) { }
|
||||
</script>
|
||||
|
||||
<!-- Set the theme before any content is loaded, prevents flash -->
|
||||
<script type="text/javascript">
|
||||
var theme;
|
||||
try { theme = localStorage.getItem('mdbook-theme'); } catch(e) { }
|
||||
if (theme === null || theme === undefined) { theme = default_theme; }
|
||||
var html = document.querySelector('html');
|
||||
html.classList.remove('no-js')
|
||||
html.classList.remove('light')
|
||||
html.classList.add(theme);
|
||||
html.classList.add('js');
|
||||
</script>
|
||||
|
||||
<!-- Hide / unhide sidebar before it is displayed -->
|
||||
<script type="text/javascript">
|
||||
var html = document.querySelector('html');
|
||||
var sidebar = 'hidden';
|
||||
if (document.body.clientWidth >= 1080) {
|
||||
try { sidebar = localStorage.getItem('mdbook-sidebar'); } catch(e) { }
|
||||
sidebar = sidebar || 'visible';
|
||||
}
|
||||
html.classList.remove('sidebar-visible');
|
||||
html.classList.add("sidebar-" + sidebar);
|
||||
</script>
|
||||
|
||||
<nav id="sidebar" class="sidebar" aria-label="Table of contents">
|
||||
<div class="sidebar-scrollbox">
|
||||
<ol class="chapter"><li class="chapter-item expanded affix "><a href="../index.html">Introduction</a></li><li class="chapter-item expanded affix "><li class="part-title">Features</li><li class="chapter-item expanded "><a href="../features/index.html"><strong aria-hidden="true">1.</strong> Adding the Router to Your Application</a></li><li class="chapter-item expanded "><a href="../features/routes/index.html"><strong aria-hidden="true">2.</strong> Defining Routes</a></li><li><ol class="section"><li class="chapter-item expanded "><a href="../features/routes/nested.html"><strong aria-hidden="true">2.1.</strong> Nested Routes</a></li><li class="chapter-item expanded "><a href="../features/routes/catch_all.html"><strong aria-hidden="true">2.2.</strong> Catch All Routes</a></li><li class="chapter-item expanded "><a href="../features/routes/matching.html"><strong aria-hidden="true">2.3.</strong> Matching Routes</a></li><li class="chapter-item expanded "><a href="../features/routes/fallback.html"><strong aria-hidden="true">2.4.</strong> Fallback Routes (404 page)</a></li><li class="chapter-item expanded "><a href="../features/routes/multiple-and-redirect.html"><strong aria-hidden="true">2.5.</strong> Multiple Components & Redirects</a></li></ol></li><li class="chapter-item expanded "><a href="../features/outlets.html"><strong aria-hidden="true">3.</strong> Outlets</a></li><li class="chapter-item expanded "><a href="../features/navigation/index.html"><strong aria-hidden="true">4.</strong> Links & Navigation</a></li><li><ol class="section"><li class="chapter-item expanded "><a href="../features/navigation/name.html"><strong aria-hidden="true">4.1.</strong> Named Navigation</a></li><li class="chapter-item expanded "><a href="../features/navigation/external.html"><strong aria-hidden="true">4.2.</strong> External Navigation</a></li><li class="chapter-item expanded "><a href="../features/navigation/programmatic.html"><strong aria-hidden="true">4.3.</strong> Programmatic Navigation</a></li></ol></li><li class="chapter-item expanded "><a href="../features/query.html"><strong aria-hidden="true">5.</strong> Query</a></li><li class="chapter-item expanded "><a href="../features/failures/index.html"><strong aria-hidden="true">6.</strong> Navigation Failures</a></li><li><ol class="section"><li class="chapter-item expanded "><a href="../features/failures/named.html"><strong aria-hidden="true">6.1.</strong> Named Navigation Failure</a></li><li class="chapter-item expanded "><a href="../features/failures/external.html"><strong aria-hidden="true">6.2.</strong> External Navigation Failure</a></li><li class="chapter-item expanded "><a href="../features/failures/redirection-limit.html"><strong aria-hidden="true">6.3.</strong> Redirection Limit Failure</a></li></ol></li><li class="chapter-item expanded "><a href="../features/history-providers.html"><strong aria-hidden="true">7.</strong> History Providers</a></li><li class="chapter-item expanded "><a href="../features/history-buttons.html"><strong aria-hidden="true">8.</strong> History Buttons</a></li><li class="chapter-item expanded "><a href="../features/sitemap-generation.html"><strong aria-hidden="true">9.</strong> Sitemap Generation</a></li><li class="chapter-item expanded "><a href="../features/routing-update-callback.html"><strong aria-hidden="true">10.</strong> Routing Update Callback</a></li><li class="chapter-item expanded affix "><li class="part-title">Example Project</li><li class="chapter-item expanded "><a href="../example/index.html"><strong aria-hidden="true">11.</strong> Overview</a></li><li class="chapter-item expanded "><a href="../example/first-route.html"><strong aria-hidden="true">12.</strong> Creating Our First Route</a></li><li class="chapter-item expanded "><a href="../example/building-a-nest.html"><strong aria-hidden="true">13.</strong> Building a Nest</a></li><li class="chapter-item expanded "><a href="../example/navigation-targets.html"><strong aria-hidden="true">14.</strong> Navigation Targets</a></li><li class="chapter-item expanded "><a href="../example/redirection-perfection.html" class="active"><strong aria-hidden="true">15.</strong> Redirection Perfection</a></li><li class="chapter-item expanded "><a href="../example/full-code.html"><strong aria-hidden="true">16.</strong> Full Code</a></li></ol>
|
||||
</div>
|
||||
<div id="sidebar-resize-handle" class="sidebar-resize-handle"></div>
|
||||
</nav>
|
||||
|
||||
<div id="page-wrapper" class="page-wrapper">
|
||||
|
||||
<div class="page">
|
||||
<div id="menu-bar-hover-placeholder"></div>
|
||||
<div id="menu-bar" class="menu-bar sticky bordered">
|
||||
<div class="left-buttons">
|
||||
<button id="sidebar-toggle" class="icon-button" type="button" title="Toggle Table of Contents" aria-label="Toggle Table of Contents" aria-controls="sidebar">
|
||||
<i class="fa fa-bars"></i>
|
||||
</button>
|
||||
<button id="theme-toggle" class="icon-button" type="button" title="Change theme" aria-label="Change theme" aria-haspopup="true" aria-expanded="false" aria-controls="theme-list">
|
||||
<i class="fa fa-paint-brush"></i>
|
||||
</button>
|
||||
<ul id="theme-list" class="theme-popup" aria-label="Themes" role="menu">
|
||||
<li role="none"><button role="menuitem" class="theme" id="light">Light (default)</button></li>
|
||||
<li role="none"><button role="menuitem" class="theme" id="rust">Rust</button></li>
|
||||
<li role="none"><button role="menuitem" class="theme" id="coal">Coal</button></li>
|
||||
<li role="none"><button role="menuitem" class="theme" id="navy">Navy</button></li>
|
||||
<li role="none"><button role="menuitem" class="theme" id="ayu">Ayu</button></li>
|
||||
</ul>
|
||||
<button id="search-toggle" class="icon-button" type="button" title="Search. (Shortkey: s)" aria-label="Toggle Searchbar" aria-expanded="false" aria-keyshortcuts="S" aria-controls="searchbar">
|
||||
<i class="fa fa-search"></i>
|
||||
</button>
|
||||
</div>
|
||||
|
||||
<h1 class="menu-title">Dioxus Router</h1>
|
||||
|
||||
<div class="right-buttons">
|
||||
<a href="../print.html" title="Print this book" aria-label="Print this book">
|
||||
<i id="print-button" class="fa fa-print"></i>
|
||||
</a>
|
||||
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div id="search-wrapper" class="hidden">
|
||||
<form id="searchbar-outer" class="searchbar-outer">
|
||||
<input type="search" id="searchbar" name="searchbar" placeholder="Search this book ..." aria-controls="searchresults-outer" aria-describedby="searchresults-header">
|
||||
</form>
|
||||
<div id="searchresults-outer" class="searchresults-outer hidden">
|
||||
<div id="searchresults-header" class="searchresults-header"></div>
|
||||
<ul id="searchresults">
|
||||
</ul>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- Apply ARIA attributes after the sidebar and the sidebar toggle button are added to the DOM -->
|
||||
<script type="text/javascript">
|
||||
document.getElementById('sidebar-toggle').setAttribute('aria-expanded', sidebar === 'visible');
|
||||
document.getElementById('sidebar').setAttribute('aria-hidden', sidebar !== 'visible');
|
||||
Array.from(document.querySelectorAll('#sidebar a')).forEach(function(link) {
|
||||
link.setAttribute('tabIndex', sidebar === 'visible' ? 0 : -1);
|
||||
});
|
||||
</script>
|
||||
|
||||
<div id="content" class="content">
|
||||
<main>
|
||||
<h1 id="redirection-perfection"><a class="header" href="#redirection-perfection">Redirection Perfection</a></h1>
|
||||
<p>You're well on your way to becoming a routing master!</p>
|
||||
<p>In this chapter we will cover utilizing redirects so you can take Rickrolling to
|
||||
the next level.</p>
|
||||
<h2 id="what-is-this-redirect-thing"><a class="header" href="#what-is-this-redirect-thing">What Is This Redirect Thing?</a></h2>
|
||||
<p>A redirect is very simple. When dioxus encounters a redirect while finding out
|
||||
what components to render, it will redirect the user to the target of the
|
||||
redirect.</p>
|
||||
<p>As a simple example, let's say you want user to still land on your blog, even
|
||||
if they used the path <code>/myblog</code>.</p>
|
||||
<p>All we need to do is update our route definition in our app component:</p>
|
||||
<pre><pre class="playground"><code class="language-rust no_run edition2021">
|
||||
<span class="boring">#![allow(unused)]
|
||||
</span><span class="boring">fn main() {
|
||||
</span><span class="boring">// Hidden lines (like this one) make the documentation tests work.
|
||||
</span><span class="boring">extern crate dioxus;
|
||||
</span><span class="boring">use dioxus::prelude::*;
|
||||
</span><span class="boring">extern crate dioxus_router;
|
||||
</span><span class="boring">use dioxus_router::prelude::*;
|
||||
</span><span class="boring">fn Blog(cx: Scope) -> Element { unimplemented!() }
|
||||
</span><span class="boring">fn BlogList(cx: Scope) -> Element { unimplemented!() }
|
||||
</span><span class="boring">struct PostId;
|
||||
</span><span class="boring">struct BlogPostName;
|
||||
</span><span class="boring">fn BlogPost(cx: Scope) -> Element { unimplemented!() }
|
||||
</span><span class="boring">fn Home(cx: Scope) -> Element { unimplemented!() }
|
||||
</span><span class="boring">fn NavBar(cx: Scope) -> Element { unimplemented!() }
|
||||
</span><span class="boring">fn PageNotFound(cx: Scope) -> Element { unimplemented!() }
|
||||
</span><span class="boring">fn App(cx: Scope) -> Element {
|
||||
</span>use_router(
|
||||
cx,
|
||||
&|| RouterConfiguration::default(),
|
||||
&|| {
|
||||
Segment::content(comp(Home))
|
||||
.fixed("blog", Route::content(comp(Blog)).nested(
|
||||
Segment::content(comp(BlogList)).catch_all(
|
||||
ParameterRoute::content::<PostId>(comp(BlogPost))
|
||||
.name::<BlogPostName>()
|
||||
)
|
||||
))
|
||||
.fixed("myblog", "/blog") // this is new
|
||||
.fallback(comp(PageNotFound))
|
||||
}
|
||||
);
|
||||
<span class="boring">unimplemented!()
|
||||
</span><span class="boring">}
|
||||
</span><span class="boring">}
|
||||
</span></code></pre></pre>
|
||||
<p>That's it! Now your users will be redirected to the blog.</p>
|
||||
<p>Notice that the <code>"/blog"</code> <code>str</code> is a <a href="./navigation-targets.html">navigation target</a>.
|
||||
We could also use external or named targets.</p>
|
||||
<h3 id="conclusion"><a class="header" href="#conclusion">Conclusion</a></h3>
|
||||
<p>Well done! You've completed the Dioxus Router guide book. You've built a small
|
||||
application and learned about the many things you can do with Dioxus Router.
|
||||
To continue your journey, you can find a list of challenges down below, or you
|
||||
can check out the <a href="https://docs.rs/dioxus-router/">API reference</a>.</p>
|
||||
<h3 id="challenges"><a class="header" href="#challenges">Challenges</a></h3>
|
||||
<ul>
|
||||
<li>Organize your components into seperate files for better maintainability.</li>
|
||||
<li>Give your app some style if you haven't already.</li>
|
||||
<li>Build an about page so your visitors know who you are.</li>
|
||||
<li>Add a user system that uses URL parameters.</li>
|
||||
<li>Create a simple admin system to create, delete, and edit blogs.</li>
|
||||
<li>If you want to go to the max, hook up your application to a rest API and database.</li>
|
||||
</ul>
|
||||
|
||||
</main>
|
||||
|
||||
<nav class="nav-wrapper" aria-label="Page navigation">
|
||||
<!-- Mobile navigation buttons -->
|
||||
<a rel="prev" href="../example/navigation-targets.html" class="mobile-nav-chapters previous" title="Previous chapter" aria-label="Previous chapter" aria-keyshortcuts="Left">
|
||||
<i class="fa fa-angle-left"></i>
|
||||
</a>
|
||||
|
||||
<a rel="next" href="../example/full-code.html" class="mobile-nav-chapters next" title="Next chapter" aria-label="Next chapter" aria-keyshortcuts="Right">
|
||||
<i class="fa fa-angle-right"></i>
|
||||
</a>
|
||||
|
||||
<div style="clear: both"></div>
|
||||
</nav>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<nav class="nav-wide-wrapper" aria-label="Page navigation">
|
||||
<a rel="prev" href="../example/navigation-targets.html" class="nav-chapters previous" title="Previous chapter" aria-label="Previous chapter" aria-keyshortcuts="Left">
|
||||
<i class="fa fa-angle-left"></i>
|
||||
</a>
|
||||
|
||||
<a rel="next" href="../example/full-code.html" class="nav-chapters next" title="Next chapter" aria-label="Next chapter" aria-keyshortcuts="Right">
|
||||
<i class="fa fa-angle-right"></i>
|
||||
</a>
|
||||
</nav>
|
||||
|
||||
</div>
|
||||
|
||||
|
||||
|
||||
|
||||
<script type="text/javascript">
|
||||
window.playground_copyable = true;
|
||||
</script>
|
||||
|
||||
|
||||
<script src="../elasticlunr.min.js" type="text/javascript" charset="utf-8"></script>
|
||||
<script src="../mark.min.js" type="text/javascript" charset="utf-8"></script>
|
||||
<script src="../searcher.js" type="text/javascript" charset="utf-8"></script>
|
||||
|
||||
<script src="../clipboard.min.js" type="text/javascript" charset="utf-8"></script>
|
||||
<script src="../highlight.js" type="text/javascript" charset="utf-8"></script>
|
||||
<script src="../book.js" type="text/javascript" charset="utf-8"></script>
|
||||
|
||||
<!-- Custom JS scripts -->
|
||||
|
||||
|
||||
</body>
|
||||
</html>
|
||||
Binary file not shown.
|
After Width: | Height: | Size: 5.5 KiB |
@@ -0,0 +1,22 @@
|
||||
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 199.7 184.2">
|
||||
<style>
|
||||
@media (prefers-color-scheme: dark) {
|
||||
svg { fill: white; }
|
||||
}
|
||||
</style>
|
||||
<path d="M189.5,36.8c0.2,2.8,0,5.1-0.6,6.8L153,162c-0.6,2.1-2,3.7-4.2,5c-2.2,1.2-4.4,1.9-6.7,1.9H31.4c-9.6,0-15.3-2.8-17.3-8.4
|
||||
c-0.8-2.2-0.8-3.9,0.1-5.2c0.9-1.2,2.4-1.8,4.6-1.8H123c7.4,0,12.6-1.4,15.4-4.1s5.7-8.9,8.6-18.4l32.9-108.6
|
||||
c1.8-5.9,1-11.1-2.2-15.6S169.9,0,164,0H72.7c-1,0-3.1,0.4-6.1,1.1l0.1-0.4C64.5,0.2,62.6,0,61,0.1s-3,0.5-4.3,1.4
|
||||
c-1.3,0.9-2.4,1.8-3.2,2.8S52,6.5,51.2,8.1c-0.8,1.6-1.4,3-1.9,4.3s-1.1,2.7-1.8,4.2c-0.7,1.5-1.3,2.7-2,3.7c-0.5,0.6-1.2,1.5-2,2.5
|
||||
s-1.6,2-2.2,2.8s-0.9,1.5-1.1,2.2c-0.2,0.7-0.1,1.8,0.2,3.2c0.3,1.4,0.4,2.4,0.4,3.1c-0.3,3-1.4,6.9-3.3,11.6
|
||||
c-1.9,4.7-3.6,8.1-5.1,10.1c-0.3,0.4-1.2,1.3-2.6,2.7c-1.4,1.4-2.3,2.6-2.6,3.7c-0.3,0.4-0.3,1.5-0.1,3.4c0.3,1.8,0.4,3.1,0.3,3.8
|
||||
c-0.3,2.7-1.3,6.3-3,10.8c-1.7,4.5-3.4,8.2-5,11c-0.2,0.5-0.9,1.4-2,2.8c-1.1,1.4-1.8,2.5-2,3.4c-0.2,0.6-0.1,1.8,0.1,3.4
|
||||
c0.2,1.6,0.2,2.8-0.1,3.6c-0.6,3-1.8,6.7-3.6,11c-1.8,4.3-3.6,7.9-5.4,11c-0.5,0.8-1.1,1.7-2,2.8c-0.8,1.1-1.5,2-2,2.8
|
||||
s-0.8,1.6-1,2.5c-0.1,0.5,0,1.3,0.4,2.3c0.3,1.1,0.4,1.9,0.4,2.6c-0.1,1.1-0.2,2.6-0.5,4.4c-0.2,1.8-0.4,2.9-0.4,3.2
|
||||
c-1.8,4.8-1.7,9.9,0.2,15.2c2.2,6.2,6.2,11.5,11.9,15.8c5.7,4.3,11.7,6.4,17.8,6.4h110.7c5.2,0,10.1-1.7,14.7-5.2s7.7-7.8,9.2-12.9
|
||||
l33-108.6c1.8-5.8,1-10.9-2.2-15.5C194.9,39.7,192.6,38,189.5,36.8z M59.6,122.8L73.8,80c0,0,7,0,10.8,0s28.8-1.7,25.4,17.5
|
||||
c-3.4,19.2-18.8,25.2-36.8,25.4S59.6,122.8,59.6,122.8z M78.6,116.8c4.7-0.1,18.9-2.9,22.1-17.1S89.2,86.3,89.2,86.3l-8.9,0
|
||||
l-10.2,30.5C70.2,116.9,74,116.9,78.6,116.8z M75.3,68.7L89,26.2h9.8l0.8,34l23.6-34h9.9l-13.6,42.5h-7.1l12.5-35.4l-24.5,35.4h-6.8
|
||||
l-0.8-35L82,68.7H75.3z"/>
|
||||
</svg>
|
||||
<!-- Original image Copyright Dave Gandy — CC BY 4.0 License -->
|
||||
|
After Width: | Height: | Size: 1.8 KiB |
@@ -0,0 +1,260 @@
|
||||
<!DOCTYPE HTML>
|
||||
<html lang="en" class="sidebar-visible no-js light">
|
||||
<head>
|
||||
<!-- Book generated using mdBook -->
|
||||
<meta charset="UTF-8">
|
||||
<title>External Navigation Failure - Dioxus Router</title>
|
||||
|
||||
|
||||
<!-- Custom HTML head -->
|
||||
|
||||
<meta content="text/html; charset=utf-8" http-equiv="Content-Type">
|
||||
<meta name="description" content="">
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1">
|
||||
<meta name="theme-color" content="#ffffff" />
|
||||
|
||||
<link rel="icon" href="../../favicon.svg">
|
||||
<link rel="shortcut icon" href="../../favicon.png">
|
||||
<link rel="stylesheet" href="../../css/variables.css">
|
||||
<link rel="stylesheet" href="../../css/general.css">
|
||||
<link rel="stylesheet" href="../../css/chrome.css">
|
||||
<link rel="stylesheet" href="../../css/print.css" media="print">
|
||||
|
||||
<!-- Fonts -->
|
||||
<link rel="stylesheet" href="../../FontAwesome/css/font-awesome.css">
|
||||
<link rel="stylesheet" href="../../fonts/fonts.css">
|
||||
|
||||
<!-- Highlight.js Stylesheets -->
|
||||
<link rel="stylesheet" href="../../highlight.css">
|
||||
<link rel="stylesheet" href="../../tomorrow-night.css">
|
||||
<link rel="stylesheet" href="../../ayu-highlight.css">
|
||||
|
||||
<!-- Custom theme stylesheets -->
|
||||
|
||||
</head>
|
||||
<body>
|
||||
<!-- Provide site root to javascript -->
|
||||
<script type="text/javascript">
|
||||
var path_to_root = "../../";
|
||||
var default_theme = window.matchMedia("(prefers-color-scheme: dark)").matches ? "navy" : "light";
|
||||
</script>
|
||||
|
||||
<!-- Work around some values being stored in localStorage wrapped in quotes -->
|
||||
<script type="text/javascript">
|
||||
try {
|
||||
var theme = localStorage.getItem('mdbook-theme');
|
||||
var sidebar = localStorage.getItem('mdbook-sidebar');
|
||||
|
||||
if (theme.startsWith('"') && theme.endsWith('"')) {
|
||||
localStorage.setItem('mdbook-theme', theme.slice(1, theme.length - 1));
|
||||
}
|
||||
|
||||
if (sidebar.startsWith('"') && sidebar.endsWith('"')) {
|
||||
localStorage.setItem('mdbook-sidebar', sidebar.slice(1, sidebar.length - 1));
|
||||
}
|
||||
} catch (e) { }
|
||||
</script>
|
||||
|
||||
<!-- Set the theme before any content is loaded, prevents flash -->
|
||||
<script type="text/javascript">
|
||||
var theme;
|
||||
try { theme = localStorage.getItem('mdbook-theme'); } catch(e) { }
|
||||
if (theme === null || theme === undefined) { theme = default_theme; }
|
||||
var html = document.querySelector('html');
|
||||
html.classList.remove('no-js')
|
||||
html.classList.remove('light')
|
||||
html.classList.add(theme);
|
||||
html.classList.add('js');
|
||||
</script>
|
||||
|
||||
<!-- Hide / unhide sidebar before it is displayed -->
|
||||
<script type="text/javascript">
|
||||
var html = document.querySelector('html');
|
||||
var sidebar = 'hidden';
|
||||
if (document.body.clientWidth >= 1080) {
|
||||
try { sidebar = localStorage.getItem('mdbook-sidebar'); } catch(e) { }
|
||||
sidebar = sidebar || 'visible';
|
||||
}
|
||||
html.classList.remove('sidebar-visible');
|
||||
html.classList.add("sidebar-" + sidebar);
|
||||
</script>
|
||||
|
||||
<nav id="sidebar" class="sidebar" aria-label="Table of contents">
|
||||
<div class="sidebar-scrollbox">
|
||||
<ol class="chapter"><li class="chapter-item expanded affix "><a href="../../index.html">Introduction</a></li><li class="chapter-item expanded affix "><li class="part-title">Features</li><li class="chapter-item expanded "><a href="../../features/index.html"><strong aria-hidden="true">1.</strong> Adding the Router to Your Application</a></li><li class="chapter-item expanded "><a href="../../features/routes/index.html"><strong aria-hidden="true">2.</strong> Defining Routes</a></li><li><ol class="section"><li class="chapter-item expanded "><a href="../../features/routes/nested.html"><strong aria-hidden="true">2.1.</strong> Nested Routes</a></li><li class="chapter-item expanded "><a href="../../features/routes/catch_all.html"><strong aria-hidden="true">2.2.</strong> Catch All Routes</a></li><li class="chapter-item expanded "><a href="../../features/routes/matching.html"><strong aria-hidden="true">2.3.</strong> Matching Routes</a></li><li class="chapter-item expanded "><a href="../../features/routes/fallback.html"><strong aria-hidden="true">2.4.</strong> Fallback Routes (404 page)</a></li><li class="chapter-item expanded "><a href="../../features/routes/multiple-and-redirect.html"><strong aria-hidden="true">2.5.</strong> Multiple Components & Redirects</a></li></ol></li><li class="chapter-item expanded "><a href="../../features/outlets.html"><strong aria-hidden="true">3.</strong> Outlets</a></li><li class="chapter-item expanded "><a href="../../features/navigation/index.html"><strong aria-hidden="true">4.</strong> Links & Navigation</a></li><li><ol class="section"><li class="chapter-item expanded "><a href="../../features/navigation/name.html"><strong aria-hidden="true">4.1.</strong> Named Navigation</a></li><li class="chapter-item expanded "><a href="../../features/navigation/external.html"><strong aria-hidden="true">4.2.</strong> External Navigation</a></li><li class="chapter-item expanded "><a href="../../features/navigation/programmatic.html"><strong aria-hidden="true">4.3.</strong> Programmatic Navigation</a></li></ol></li><li class="chapter-item expanded "><a href="../../features/query.html"><strong aria-hidden="true">5.</strong> Query</a></li><li class="chapter-item expanded "><a href="../../features/failures/index.html"><strong aria-hidden="true">6.</strong> Navigation Failures</a></li><li><ol class="section"><li class="chapter-item expanded "><a href="../../features/failures/named.html"><strong aria-hidden="true">6.1.</strong> Named Navigation Failure</a></li><li class="chapter-item expanded "><a href="../../features/failures/external.html" class="active"><strong aria-hidden="true">6.2.</strong> External Navigation Failure</a></li><li class="chapter-item expanded "><a href="../../features/failures/redirection-limit.html"><strong aria-hidden="true">6.3.</strong> Redirection Limit Failure</a></li></ol></li><li class="chapter-item expanded "><a href="../../features/history-providers.html"><strong aria-hidden="true">7.</strong> History Providers</a></li><li class="chapter-item expanded "><a href="../../features/history-buttons.html"><strong aria-hidden="true">8.</strong> History Buttons</a></li><li class="chapter-item expanded "><a href="../../features/sitemap-generation.html"><strong aria-hidden="true">9.</strong> Sitemap Generation</a></li><li class="chapter-item expanded "><a href="../../features/routing-update-callback.html"><strong aria-hidden="true">10.</strong> Routing Update Callback</a></li><li class="chapter-item expanded affix "><li class="part-title">Example Project</li><li class="chapter-item expanded "><a href="../../example/index.html"><strong aria-hidden="true">11.</strong> Overview</a></li><li class="chapter-item expanded "><a href="../../example/first-route.html"><strong aria-hidden="true">12.</strong> Creating Our First Route</a></li><li class="chapter-item expanded "><a href="../../example/building-a-nest.html"><strong aria-hidden="true">13.</strong> Building a Nest</a></li><li class="chapter-item expanded "><a href="../../example/navigation-targets.html"><strong aria-hidden="true">14.</strong> Navigation Targets</a></li><li class="chapter-item expanded "><a href="../../example/redirection-perfection.html"><strong aria-hidden="true">15.</strong> Redirection Perfection</a></li><li class="chapter-item expanded "><a href="../../example/full-code.html"><strong aria-hidden="true">16.</strong> Full Code</a></li></ol>
|
||||
</div>
|
||||
<div id="sidebar-resize-handle" class="sidebar-resize-handle"></div>
|
||||
</nav>
|
||||
|
||||
<div id="page-wrapper" class="page-wrapper">
|
||||
|
||||
<div class="page">
|
||||
<div id="menu-bar-hover-placeholder"></div>
|
||||
<div id="menu-bar" class="menu-bar sticky bordered">
|
||||
<div class="left-buttons">
|
||||
<button id="sidebar-toggle" class="icon-button" type="button" title="Toggle Table of Contents" aria-label="Toggle Table of Contents" aria-controls="sidebar">
|
||||
<i class="fa fa-bars"></i>
|
||||
</button>
|
||||
<button id="theme-toggle" class="icon-button" type="button" title="Change theme" aria-label="Change theme" aria-haspopup="true" aria-expanded="false" aria-controls="theme-list">
|
||||
<i class="fa fa-paint-brush"></i>
|
||||
</button>
|
||||
<ul id="theme-list" class="theme-popup" aria-label="Themes" role="menu">
|
||||
<li role="none"><button role="menuitem" class="theme" id="light">Light (default)</button></li>
|
||||
<li role="none"><button role="menuitem" class="theme" id="rust">Rust</button></li>
|
||||
<li role="none"><button role="menuitem" class="theme" id="coal">Coal</button></li>
|
||||
<li role="none"><button role="menuitem" class="theme" id="navy">Navy</button></li>
|
||||
<li role="none"><button role="menuitem" class="theme" id="ayu">Ayu</button></li>
|
||||
</ul>
|
||||
<button id="search-toggle" class="icon-button" type="button" title="Search. (Shortkey: s)" aria-label="Toggle Searchbar" aria-expanded="false" aria-keyshortcuts="S" aria-controls="searchbar">
|
||||
<i class="fa fa-search"></i>
|
||||
</button>
|
||||
</div>
|
||||
|
||||
<h1 class="menu-title">Dioxus Router</h1>
|
||||
|
||||
<div class="right-buttons">
|
||||
<a href="../../print.html" title="Print this book" aria-label="Print this book">
|
||||
<i id="print-button" class="fa fa-print"></i>
|
||||
</a>
|
||||
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div id="search-wrapper" class="hidden">
|
||||
<form id="searchbar-outer" class="searchbar-outer">
|
||||
<input type="search" id="searchbar" name="searchbar" placeholder="Search this book ..." aria-controls="searchresults-outer" aria-describedby="searchresults-header">
|
||||
</form>
|
||||
<div id="searchresults-outer" class="searchresults-outer hidden">
|
||||
<div id="searchresults-header" class="searchresults-header"></div>
|
||||
<ul id="searchresults">
|
||||
</ul>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- Apply ARIA attributes after the sidebar and the sidebar toggle button are added to the DOM -->
|
||||
<script type="text/javascript">
|
||||
document.getElementById('sidebar-toggle').setAttribute('aria-expanded', sidebar === 'visible');
|
||||
document.getElementById('sidebar').setAttribute('aria-hidden', sidebar !== 'visible');
|
||||
Array.from(document.querySelectorAll('#sidebar a')).forEach(function(link) {
|
||||
link.setAttribute('tabIndex', sidebar === 'visible' ? 0 : -1);
|
||||
});
|
||||
</script>
|
||||
|
||||
<div id="content" class="content">
|
||||
<main>
|
||||
<h1 id="external-navigation-failure"><a class="header" href="#external-navigation-failure">External Navigation Failure</a></h1>
|
||||
<blockquote>
|
||||
<p>This section doesn't apply when specifying a <code>target</code> on a <a href="https://docs.rs/dioxus-router/latest/dioxus_router/components/fn.Link.html"><code>Link</code></a>. See the
|
||||
chapter about <a href="../navigation/external.html">external navigation</a> for more
|
||||
details.</p>
|
||||
</blockquote>
|
||||
<p>When we ask the router to navigate to an external target, either through
|
||||
<a href="../navigation/programmatic.html">programmatic navigation</a> or a
|
||||
<a href="../routes/multiple-and-redirect.html#redirects">redirect</a> the router needs to
|
||||
navigate to an external target without being able to rely on an anchor element.</p>
|
||||
<p>This will only work in the browser, when using either <a href="https://docs.rs/dioxus-router-core/latest/dioxus_router_core/history/struct.WebHistory.html"><code>WebHistory</code></a> or
|
||||
<a href="https://docs.rs/dioxus-router-core/latest/dioxus_router_core/history/struct.WebHashHistory.html"><code>WebHashHistory</code></a>.</p>
|
||||
<h2 id="failure-handling"><a class="header" href="#failure-handling">Failure handling</a></h2>
|
||||
<p>When the router encounters an external navigation it cannot fulfill, it changes
|
||||
the path to <code>/</code> and shows some fallback content.</p>
|
||||
<blockquote>
|
||||
<p>You can detect if the router is in the external navigation failure handling
|
||||
state by <a href="../navigation/name.html#check-if-a-name-is-present">checking</a> if the
|
||||
<a href="https://docs.rs/dioxus-router-core/latest/dioxus_router_core/prelude/struct.FailureExternalNavigation.html"><code>FailureExternalNavigation</code></a> name is present.</p>
|
||||
</blockquote>
|
||||
<p>The default fallback explains to the user that the navigation was unsuccessful
|
||||
and provides them with a <a href="https://docs.rs/dioxus-router/latest/dioxus_router/components/fn.Link.html"><code>Link</code></a> to fulfill it manually. It also allows them to
|
||||
go back to the previous page.</p>
|
||||
<p>You can override it by setting the <code>failure_external_navigation</code> value of the
|
||||
<a href="https://docs.rs/dioxus-router/latest/dioxus_router/hooks/struct.RouterConfiguration.html"><code>RouterConfiguration</code></a>. The external URL will be provided via the
|
||||
<a href="https://docs.rs/dioxus-router-core/latest/dioxus_router_core/prelude/struct.FailureExternalNavigation.html"><code>FailureExternalNavigation</code></a> parameter.</p>
|
||||
<pre><pre class="playground"><code class="language-rust no_run edition2021">
|
||||
<span class="boring">#![allow(unused)]
|
||||
</span><span class="boring">fn main() {
|
||||
</span><span class="boring">// Hidden lines (like this one) make the documentation tests work.
|
||||
</span><span class="boring">extern crate dioxus;
|
||||
</span><span class="boring">use dioxus::prelude::*;
|
||||
</span><span class="boring">extern crate dioxus_router;
|
||||
</span><span class="boring">use dioxus_router::prelude::*;
|
||||
</span>fn ExternalNavigationFallback(cx: Scope) -> Element {
|
||||
let route = use_route(cx).expect("is nested within a Router component");
|
||||
let url = route
|
||||
.parameter::<FailureExternalNavigation>()
|
||||
.unwrap_or_default();
|
||||
|
||||
render! {
|
||||
h1 { "External navigation failure!" }
|
||||
Link {
|
||||
target: url,
|
||||
"Go to external site"
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
fn App(cx: Scope) -> Element {
|
||||
use_router(
|
||||
cx,
|
||||
&|| RouterConfiguration {
|
||||
failure_external_navigation: comp(ExternalNavigationFallback),
|
||||
..Default::default()
|
||||
},
|
||||
&|| Segment::empty()
|
||||
);
|
||||
|
||||
render! {
|
||||
Outlet { }
|
||||
}
|
||||
}
|
||||
<span class="boring">}
|
||||
</span></code></pre></pre>
|
||||
|
||||
</main>
|
||||
|
||||
<nav class="nav-wrapper" aria-label="Page navigation">
|
||||
<!-- Mobile navigation buttons -->
|
||||
<a rel="prev" href="../../features/failures/named.html" class="mobile-nav-chapters previous" title="Previous chapter" aria-label="Previous chapter" aria-keyshortcuts="Left">
|
||||
<i class="fa fa-angle-left"></i>
|
||||
</a>
|
||||
|
||||
<a rel="next" href="../../features/failures/redirection-limit.html" class="mobile-nav-chapters next" title="Next chapter" aria-label="Next chapter" aria-keyshortcuts="Right">
|
||||
<i class="fa fa-angle-right"></i>
|
||||
</a>
|
||||
|
||||
<div style="clear: both"></div>
|
||||
</nav>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<nav class="nav-wide-wrapper" aria-label="Page navigation">
|
||||
<a rel="prev" href="../../features/failures/named.html" class="nav-chapters previous" title="Previous chapter" aria-label="Previous chapter" aria-keyshortcuts="Left">
|
||||
<i class="fa fa-angle-left"></i>
|
||||
</a>
|
||||
|
||||
<a rel="next" href="../../features/failures/redirection-limit.html" class="nav-chapters next" title="Next chapter" aria-label="Next chapter" aria-keyshortcuts="Right">
|
||||
<i class="fa fa-angle-right"></i>
|
||||
</a>
|
||||
</nav>
|
||||
|
||||
</div>
|
||||
|
||||
|
||||
|
||||
|
||||
<script type="text/javascript">
|
||||
window.playground_copyable = true;
|
||||
</script>
|
||||
|
||||
|
||||
<script src="../../elasticlunr.min.js" type="text/javascript" charset="utf-8"></script>
|
||||
<script src="../../mark.min.js" type="text/javascript" charset="utf-8"></script>
|
||||
<script src="../../searcher.js" type="text/javascript" charset="utf-8"></script>
|
||||
|
||||
<script src="../../clipboard.min.js" type="text/javascript" charset="utf-8"></script>
|
||||
<script src="../../highlight.js" type="text/javascript" charset="utf-8"></script>
|
||||
<script src="../../book.js" type="text/javascript" charset="utf-8"></script>
|
||||
|
||||
<!-- Custom JS scripts -->
|
||||
|
||||
|
||||
</body>
|
||||
</html>
|
||||
@@ -0,0 +1,198 @@
|
||||
<!DOCTYPE HTML>
|
||||
<html lang="en" class="sidebar-visible no-js light">
|
||||
<head>
|
||||
<!-- Book generated using mdBook -->
|
||||
<meta charset="UTF-8">
|
||||
<title>Navigation Failures - Dioxus Router</title>
|
||||
|
||||
|
||||
<!-- Custom HTML head -->
|
||||
|
||||
<meta content="text/html; charset=utf-8" http-equiv="Content-Type">
|
||||
<meta name="description" content="">
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1">
|
||||
<meta name="theme-color" content="#ffffff" />
|
||||
|
||||
<link rel="icon" href="../../favicon.svg">
|
||||
<link rel="shortcut icon" href="../../favicon.png">
|
||||
<link rel="stylesheet" href="../../css/variables.css">
|
||||
<link rel="stylesheet" href="../../css/general.css">
|
||||
<link rel="stylesheet" href="../../css/chrome.css">
|
||||
<link rel="stylesheet" href="../../css/print.css" media="print">
|
||||
|
||||
<!-- Fonts -->
|
||||
<link rel="stylesheet" href="../../FontAwesome/css/font-awesome.css">
|
||||
<link rel="stylesheet" href="../../fonts/fonts.css">
|
||||
|
||||
<!-- Highlight.js Stylesheets -->
|
||||
<link rel="stylesheet" href="../../highlight.css">
|
||||
<link rel="stylesheet" href="../../tomorrow-night.css">
|
||||
<link rel="stylesheet" href="../../ayu-highlight.css">
|
||||
|
||||
<!-- Custom theme stylesheets -->
|
||||
|
||||
</head>
|
||||
<body>
|
||||
<!-- Provide site root to javascript -->
|
||||
<script type="text/javascript">
|
||||
var path_to_root = "../../";
|
||||
var default_theme = window.matchMedia("(prefers-color-scheme: dark)").matches ? "navy" : "light";
|
||||
</script>
|
||||
|
||||
<!-- Work around some values being stored in localStorage wrapped in quotes -->
|
||||
<script type="text/javascript">
|
||||
try {
|
||||
var theme = localStorage.getItem('mdbook-theme');
|
||||
var sidebar = localStorage.getItem('mdbook-sidebar');
|
||||
|
||||
if (theme.startsWith('"') && theme.endsWith('"')) {
|
||||
localStorage.setItem('mdbook-theme', theme.slice(1, theme.length - 1));
|
||||
}
|
||||
|
||||
if (sidebar.startsWith('"') && sidebar.endsWith('"')) {
|
||||
localStorage.setItem('mdbook-sidebar', sidebar.slice(1, sidebar.length - 1));
|
||||
}
|
||||
} catch (e) { }
|
||||
</script>
|
||||
|
||||
<!-- Set the theme before any content is loaded, prevents flash -->
|
||||
<script type="text/javascript">
|
||||
var theme;
|
||||
try { theme = localStorage.getItem('mdbook-theme'); } catch(e) { }
|
||||
if (theme === null || theme === undefined) { theme = default_theme; }
|
||||
var html = document.querySelector('html');
|
||||
html.classList.remove('no-js')
|
||||
html.classList.remove('light')
|
||||
html.classList.add(theme);
|
||||
html.classList.add('js');
|
||||
</script>
|
||||
|
||||
<!-- Hide / unhide sidebar before it is displayed -->
|
||||
<script type="text/javascript">
|
||||
var html = document.querySelector('html');
|
||||
var sidebar = 'hidden';
|
||||
if (document.body.clientWidth >= 1080) {
|
||||
try { sidebar = localStorage.getItem('mdbook-sidebar'); } catch(e) { }
|
||||
sidebar = sidebar || 'visible';
|
||||
}
|
||||
html.classList.remove('sidebar-visible');
|
||||
html.classList.add("sidebar-" + sidebar);
|
||||
</script>
|
||||
|
||||
<nav id="sidebar" class="sidebar" aria-label="Table of contents">
|
||||
<div class="sidebar-scrollbox">
|
||||
<ol class="chapter"><li class="chapter-item expanded affix "><a href="../../index.html">Introduction</a></li><li class="chapter-item expanded affix "><li class="part-title">Features</li><li class="chapter-item expanded "><a href="../../features/index.html"><strong aria-hidden="true">1.</strong> Adding the Router to Your Application</a></li><li class="chapter-item expanded "><a href="../../features/routes/index.html"><strong aria-hidden="true">2.</strong> Defining Routes</a></li><li><ol class="section"><li class="chapter-item expanded "><a href="../../features/routes/nested.html"><strong aria-hidden="true">2.1.</strong> Nested Routes</a></li><li class="chapter-item expanded "><a href="../../features/routes/catch_all.html"><strong aria-hidden="true">2.2.</strong> Catch All Routes</a></li><li class="chapter-item expanded "><a href="../../features/routes/matching.html"><strong aria-hidden="true">2.3.</strong> Matching Routes</a></li><li class="chapter-item expanded "><a href="../../features/routes/fallback.html"><strong aria-hidden="true">2.4.</strong> Fallback Routes (404 page)</a></li><li class="chapter-item expanded "><a href="../../features/routes/multiple-and-redirect.html"><strong aria-hidden="true">2.5.</strong> Multiple Components & Redirects</a></li></ol></li><li class="chapter-item expanded "><a href="../../features/outlets.html"><strong aria-hidden="true">3.</strong> Outlets</a></li><li class="chapter-item expanded "><a href="../../features/navigation/index.html"><strong aria-hidden="true">4.</strong> Links & Navigation</a></li><li><ol class="section"><li class="chapter-item expanded "><a href="../../features/navigation/name.html"><strong aria-hidden="true">4.1.</strong> Named Navigation</a></li><li class="chapter-item expanded "><a href="../../features/navigation/external.html"><strong aria-hidden="true">4.2.</strong> External Navigation</a></li><li class="chapter-item expanded "><a href="../../features/navigation/programmatic.html"><strong aria-hidden="true">4.3.</strong> Programmatic Navigation</a></li></ol></li><li class="chapter-item expanded "><a href="../../features/query.html"><strong aria-hidden="true">5.</strong> Query</a></li><li class="chapter-item expanded "><a href="../../features/failures/index.html" class="active"><strong aria-hidden="true">6.</strong> Navigation Failures</a></li><li><ol class="section"><li class="chapter-item expanded "><a href="../../features/failures/named.html"><strong aria-hidden="true">6.1.</strong> Named Navigation Failure</a></li><li class="chapter-item expanded "><a href="../../features/failures/external.html"><strong aria-hidden="true">6.2.</strong> External Navigation Failure</a></li><li class="chapter-item expanded "><a href="../../features/failures/redirection-limit.html"><strong aria-hidden="true">6.3.</strong> Redirection Limit Failure</a></li></ol></li><li class="chapter-item expanded "><a href="../../features/history-providers.html"><strong aria-hidden="true">7.</strong> History Providers</a></li><li class="chapter-item expanded "><a href="../../features/history-buttons.html"><strong aria-hidden="true">8.</strong> History Buttons</a></li><li class="chapter-item expanded "><a href="../../features/sitemap-generation.html"><strong aria-hidden="true">9.</strong> Sitemap Generation</a></li><li class="chapter-item expanded "><a href="../../features/routing-update-callback.html"><strong aria-hidden="true">10.</strong> Routing Update Callback</a></li><li class="chapter-item expanded affix "><li class="part-title">Example Project</li><li class="chapter-item expanded "><a href="../../example/index.html"><strong aria-hidden="true">11.</strong> Overview</a></li><li class="chapter-item expanded "><a href="../../example/first-route.html"><strong aria-hidden="true">12.</strong> Creating Our First Route</a></li><li class="chapter-item expanded "><a href="../../example/building-a-nest.html"><strong aria-hidden="true">13.</strong> Building a Nest</a></li><li class="chapter-item expanded "><a href="../../example/navigation-targets.html"><strong aria-hidden="true">14.</strong> Navigation Targets</a></li><li class="chapter-item expanded "><a href="../../example/redirection-perfection.html"><strong aria-hidden="true">15.</strong> Redirection Perfection</a></li><li class="chapter-item expanded "><a href="../../example/full-code.html"><strong aria-hidden="true">16.</strong> Full Code</a></li></ol>
|
||||
</div>
|
||||
<div id="sidebar-resize-handle" class="sidebar-resize-handle"></div>
|
||||
</nav>
|
||||
|
||||
<div id="page-wrapper" class="page-wrapper">
|
||||
|
||||
<div class="page">
|
||||
<div id="menu-bar-hover-placeholder"></div>
|
||||
<div id="menu-bar" class="menu-bar sticky bordered">
|
||||
<div class="left-buttons">
|
||||
<button id="sidebar-toggle" class="icon-button" type="button" title="Toggle Table of Contents" aria-label="Toggle Table of Contents" aria-controls="sidebar">
|
||||
<i class="fa fa-bars"></i>
|
||||
</button>
|
||||
<button id="theme-toggle" class="icon-button" type="button" title="Change theme" aria-label="Change theme" aria-haspopup="true" aria-expanded="false" aria-controls="theme-list">
|
||||
<i class="fa fa-paint-brush"></i>
|
||||
</button>
|
||||
<ul id="theme-list" class="theme-popup" aria-label="Themes" role="menu">
|
||||
<li role="none"><button role="menuitem" class="theme" id="light">Light (default)</button></li>
|
||||
<li role="none"><button role="menuitem" class="theme" id="rust">Rust</button></li>
|
||||
<li role="none"><button role="menuitem" class="theme" id="coal">Coal</button></li>
|
||||
<li role="none"><button role="menuitem" class="theme" id="navy">Navy</button></li>
|
||||
<li role="none"><button role="menuitem" class="theme" id="ayu">Ayu</button></li>
|
||||
</ul>
|
||||
<button id="search-toggle" class="icon-button" type="button" title="Search. (Shortkey: s)" aria-label="Toggle Searchbar" aria-expanded="false" aria-keyshortcuts="S" aria-controls="searchbar">
|
||||
<i class="fa fa-search"></i>
|
||||
</button>
|
||||
</div>
|
||||
|
||||
<h1 class="menu-title">Dioxus Router</h1>
|
||||
|
||||
<div class="right-buttons">
|
||||
<a href="../../print.html" title="Print this book" aria-label="Print this book">
|
||||
<i id="print-button" class="fa fa-print"></i>
|
||||
</a>
|
||||
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div id="search-wrapper" class="hidden">
|
||||
<form id="searchbar-outer" class="searchbar-outer">
|
||||
<input type="search" id="searchbar" name="searchbar" placeholder="Search this book ..." aria-controls="searchresults-outer" aria-describedby="searchresults-header">
|
||||
</form>
|
||||
<div id="searchresults-outer" class="searchresults-outer hidden">
|
||||
<div id="searchresults-header" class="searchresults-header"></div>
|
||||
<ul id="searchresults">
|
||||
</ul>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- Apply ARIA attributes after the sidebar and the sidebar toggle button are added to the DOM -->
|
||||
<script type="text/javascript">
|
||||
document.getElementById('sidebar-toggle').setAttribute('aria-expanded', sidebar === 'visible');
|
||||
document.getElementById('sidebar').setAttribute('aria-hidden', sidebar !== 'visible');
|
||||
Array.from(document.querySelectorAll('#sidebar a')).forEach(function(link) {
|
||||
link.setAttribute('tabIndex', sidebar === 'visible' ? 0 : -1);
|
||||
});
|
||||
</script>
|
||||
|
||||
<div id="content" class="content">
|
||||
<main>
|
||||
<h1 id="navigation-failures"><a class="header" href="#navigation-failures">Navigation Failures</a></h1>
|
||||
<p>Some specific operations can cause a failure within router operations. The
|
||||
subchapters contain information on how the router lets us handle such failures.</p>
|
||||
|
||||
</main>
|
||||
|
||||
<nav class="nav-wrapper" aria-label="Page navigation">
|
||||
<!-- Mobile navigation buttons -->
|
||||
<a rel="prev" href="../../features/query.html" class="mobile-nav-chapters previous" title="Previous chapter" aria-label="Previous chapter" aria-keyshortcuts="Left">
|
||||
<i class="fa fa-angle-left"></i>
|
||||
</a>
|
||||
|
||||
<a rel="next" href="../../features/failures/named.html" class="mobile-nav-chapters next" title="Next chapter" aria-label="Next chapter" aria-keyshortcuts="Right">
|
||||
<i class="fa fa-angle-right"></i>
|
||||
</a>
|
||||
|
||||
<div style="clear: both"></div>
|
||||
</nav>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<nav class="nav-wide-wrapper" aria-label="Page navigation">
|
||||
<a rel="prev" href="../../features/query.html" class="nav-chapters previous" title="Previous chapter" aria-label="Previous chapter" aria-keyshortcuts="Left">
|
||||
<i class="fa fa-angle-left"></i>
|
||||
</a>
|
||||
|
||||
<a rel="next" href="../../features/failures/named.html" class="nav-chapters next" title="Next chapter" aria-label="Next chapter" aria-keyshortcuts="Right">
|
||||
<i class="fa fa-angle-right"></i>
|
||||
</a>
|
||||
</nav>
|
||||
|
||||
</div>
|
||||
|
||||
|
||||
|
||||
|
||||
<script type="text/javascript">
|
||||
window.playground_copyable = true;
|
||||
</script>
|
||||
|
||||
|
||||
<script src="../../elasticlunr.min.js" type="text/javascript" charset="utf-8"></script>
|
||||
<script src="../../mark.min.js" type="text/javascript" charset="utf-8"></script>
|
||||
<script src="../../searcher.js" type="text/javascript" charset="utf-8"></script>
|
||||
|
||||
<script src="../../clipboard.min.js" type="text/javascript" charset="utf-8"></script>
|
||||
<script src="../../highlight.js" type="text/javascript" charset="utf-8"></script>
|
||||
<script src="../../book.js" type="text/javascript" charset="utf-8"></script>
|
||||
|
||||
<!-- Custom JS scripts -->
|
||||
|
||||
|
||||
</body>
|
||||
</html>
|
||||
@@ -0,0 +1,254 @@
|
||||
<!DOCTYPE HTML>
|
||||
<html lang="en" class="sidebar-visible no-js light">
|
||||
<head>
|
||||
<!-- Book generated using mdBook -->
|
||||
<meta charset="UTF-8">
|
||||
<title>Named Navigation Failure - Dioxus Router</title>
|
||||
|
||||
|
||||
<!-- Custom HTML head -->
|
||||
|
||||
<meta content="text/html; charset=utf-8" http-equiv="Content-Type">
|
||||
<meta name="description" content="">
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1">
|
||||
<meta name="theme-color" content="#ffffff" />
|
||||
|
||||
<link rel="icon" href="../../favicon.svg">
|
||||
<link rel="shortcut icon" href="../../favicon.png">
|
||||
<link rel="stylesheet" href="../../css/variables.css">
|
||||
<link rel="stylesheet" href="../../css/general.css">
|
||||
<link rel="stylesheet" href="../../css/chrome.css">
|
||||
<link rel="stylesheet" href="../../css/print.css" media="print">
|
||||
|
||||
<!-- Fonts -->
|
||||
<link rel="stylesheet" href="../../FontAwesome/css/font-awesome.css">
|
||||
<link rel="stylesheet" href="../../fonts/fonts.css">
|
||||
|
||||
<!-- Highlight.js Stylesheets -->
|
||||
<link rel="stylesheet" href="../../highlight.css">
|
||||
<link rel="stylesheet" href="../../tomorrow-night.css">
|
||||
<link rel="stylesheet" href="../../ayu-highlight.css">
|
||||
|
||||
<!-- Custom theme stylesheets -->
|
||||
|
||||
</head>
|
||||
<body>
|
||||
<!-- Provide site root to javascript -->
|
||||
<script type="text/javascript">
|
||||
var path_to_root = "../../";
|
||||
var default_theme = window.matchMedia("(prefers-color-scheme: dark)").matches ? "navy" : "light";
|
||||
</script>
|
||||
|
||||
<!-- Work around some values being stored in localStorage wrapped in quotes -->
|
||||
<script type="text/javascript">
|
||||
try {
|
||||
var theme = localStorage.getItem('mdbook-theme');
|
||||
var sidebar = localStorage.getItem('mdbook-sidebar');
|
||||
|
||||
if (theme.startsWith('"') && theme.endsWith('"')) {
|
||||
localStorage.setItem('mdbook-theme', theme.slice(1, theme.length - 1));
|
||||
}
|
||||
|
||||
if (sidebar.startsWith('"') && sidebar.endsWith('"')) {
|
||||
localStorage.setItem('mdbook-sidebar', sidebar.slice(1, sidebar.length - 1));
|
||||
}
|
||||
} catch (e) { }
|
||||
</script>
|
||||
|
||||
<!-- Set the theme before any content is loaded, prevents flash -->
|
||||
<script type="text/javascript">
|
||||
var theme;
|
||||
try { theme = localStorage.getItem('mdbook-theme'); } catch(e) { }
|
||||
if (theme === null || theme === undefined) { theme = default_theme; }
|
||||
var html = document.querySelector('html');
|
||||
html.classList.remove('no-js')
|
||||
html.classList.remove('light')
|
||||
html.classList.add(theme);
|
||||
html.classList.add('js');
|
||||
</script>
|
||||
|
||||
<!-- Hide / unhide sidebar before it is displayed -->
|
||||
<script type="text/javascript">
|
||||
var html = document.querySelector('html');
|
||||
var sidebar = 'hidden';
|
||||
if (document.body.clientWidth >= 1080) {
|
||||
try { sidebar = localStorage.getItem('mdbook-sidebar'); } catch(e) { }
|
||||
sidebar = sidebar || 'visible';
|
||||
}
|
||||
html.classList.remove('sidebar-visible');
|
||||
html.classList.add("sidebar-" + sidebar);
|
||||
</script>
|
||||
|
||||
<nav id="sidebar" class="sidebar" aria-label="Table of contents">
|
||||
<div class="sidebar-scrollbox">
|
||||
<ol class="chapter"><li class="chapter-item expanded affix "><a href="../../index.html">Introduction</a></li><li class="chapter-item expanded affix "><li class="part-title">Features</li><li class="chapter-item expanded "><a href="../../features/index.html"><strong aria-hidden="true">1.</strong> Adding the Router to Your Application</a></li><li class="chapter-item expanded "><a href="../../features/routes/index.html"><strong aria-hidden="true">2.</strong> Defining Routes</a></li><li><ol class="section"><li class="chapter-item expanded "><a href="../../features/routes/nested.html"><strong aria-hidden="true">2.1.</strong> Nested Routes</a></li><li class="chapter-item expanded "><a href="../../features/routes/catch_all.html"><strong aria-hidden="true">2.2.</strong> Catch All Routes</a></li><li class="chapter-item expanded "><a href="../../features/routes/matching.html"><strong aria-hidden="true">2.3.</strong> Matching Routes</a></li><li class="chapter-item expanded "><a href="../../features/routes/fallback.html"><strong aria-hidden="true">2.4.</strong> Fallback Routes (404 page)</a></li><li class="chapter-item expanded "><a href="../../features/routes/multiple-and-redirect.html"><strong aria-hidden="true">2.5.</strong> Multiple Components & Redirects</a></li></ol></li><li class="chapter-item expanded "><a href="../../features/outlets.html"><strong aria-hidden="true">3.</strong> Outlets</a></li><li class="chapter-item expanded "><a href="../../features/navigation/index.html"><strong aria-hidden="true">4.</strong> Links & Navigation</a></li><li><ol class="section"><li class="chapter-item expanded "><a href="../../features/navigation/name.html"><strong aria-hidden="true">4.1.</strong> Named Navigation</a></li><li class="chapter-item expanded "><a href="../../features/navigation/external.html"><strong aria-hidden="true">4.2.</strong> External Navigation</a></li><li class="chapter-item expanded "><a href="../../features/navigation/programmatic.html"><strong aria-hidden="true">4.3.</strong> Programmatic Navigation</a></li></ol></li><li class="chapter-item expanded "><a href="../../features/query.html"><strong aria-hidden="true">5.</strong> Query</a></li><li class="chapter-item expanded "><a href="../../features/failures/index.html"><strong aria-hidden="true">6.</strong> Navigation Failures</a></li><li><ol class="section"><li class="chapter-item expanded "><a href="../../features/failures/named.html" class="active"><strong aria-hidden="true">6.1.</strong> Named Navigation Failure</a></li><li class="chapter-item expanded "><a href="../../features/failures/external.html"><strong aria-hidden="true">6.2.</strong> External Navigation Failure</a></li><li class="chapter-item expanded "><a href="../../features/failures/redirection-limit.html"><strong aria-hidden="true">6.3.</strong> Redirection Limit Failure</a></li></ol></li><li class="chapter-item expanded "><a href="../../features/history-providers.html"><strong aria-hidden="true">7.</strong> History Providers</a></li><li class="chapter-item expanded "><a href="../../features/history-buttons.html"><strong aria-hidden="true">8.</strong> History Buttons</a></li><li class="chapter-item expanded "><a href="../../features/sitemap-generation.html"><strong aria-hidden="true">9.</strong> Sitemap Generation</a></li><li class="chapter-item expanded "><a href="../../features/routing-update-callback.html"><strong aria-hidden="true">10.</strong> Routing Update Callback</a></li><li class="chapter-item expanded affix "><li class="part-title">Example Project</li><li class="chapter-item expanded "><a href="../../example/index.html"><strong aria-hidden="true">11.</strong> Overview</a></li><li class="chapter-item expanded "><a href="../../example/first-route.html"><strong aria-hidden="true">12.</strong> Creating Our First Route</a></li><li class="chapter-item expanded "><a href="../../example/building-a-nest.html"><strong aria-hidden="true">13.</strong> Building a Nest</a></li><li class="chapter-item expanded "><a href="../../example/navigation-targets.html"><strong aria-hidden="true">14.</strong> Navigation Targets</a></li><li class="chapter-item expanded "><a href="../../example/redirection-perfection.html"><strong aria-hidden="true">15.</strong> Redirection Perfection</a></li><li class="chapter-item expanded "><a href="../../example/full-code.html"><strong aria-hidden="true">16.</strong> Full Code</a></li></ol>
|
||||
</div>
|
||||
<div id="sidebar-resize-handle" class="sidebar-resize-handle"></div>
|
||||
</nav>
|
||||
|
||||
<div id="page-wrapper" class="page-wrapper">
|
||||
|
||||
<div class="page">
|
||||
<div id="menu-bar-hover-placeholder"></div>
|
||||
<div id="menu-bar" class="menu-bar sticky bordered">
|
||||
<div class="left-buttons">
|
||||
<button id="sidebar-toggle" class="icon-button" type="button" title="Toggle Table of Contents" aria-label="Toggle Table of Contents" aria-controls="sidebar">
|
||||
<i class="fa fa-bars"></i>
|
||||
</button>
|
||||
<button id="theme-toggle" class="icon-button" type="button" title="Change theme" aria-label="Change theme" aria-haspopup="true" aria-expanded="false" aria-controls="theme-list">
|
||||
<i class="fa fa-paint-brush"></i>
|
||||
</button>
|
||||
<ul id="theme-list" class="theme-popup" aria-label="Themes" role="menu">
|
||||
<li role="none"><button role="menuitem" class="theme" id="light">Light (default)</button></li>
|
||||
<li role="none"><button role="menuitem" class="theme" id="rust">Rust</button></li>
|
||||
<li role="none"><button role="menuitem" class="theme" id="coal">Coal</button></li>
|
||||
<li role="none"><button role="menuitem" class="theme" id="navy">Navy</button></li>
|
||||
<li role="none"><button role="menuitem" class="theme" id="ayu">Ayu</button></li>
|
||||
</ul>
|
||||
<button id="search-toggle" class="icon-button" type="button" title="Search. (Shortkey: s)" aria-label="Toggle Searchbar" aria-expanded="false" aria-keyshortcuts="S" aria-controls="searchbar">
|
||||
<i class="fa fa-search"></i>
|
||||
</button>
|
||||
</div>
|
||||
|
||||
<h1 class="menu-title">Dioxus Router</h1>
|
||||
|
||||
<div class="right-buttons">
|
||||
<a href="../../print.html" title="Print this book" aria-label="Print this book">
|
||||
<i id="print-button" class="fa fa-print"></i>
|
||||
</a>
|
||||
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div id="search-wrapper" class="hidden">
|
||||
<form id="searchbar-outer" class="searchbar-outer">
|
||||
<input type="search" id="searchbar" name="searchbar" placeholder="Search this book ..." aria-controls="searchresults-outer" aria-describedby="searchresults-header">
|
||||
</form>
|
||||
<div id="searchresults-outer" class="searchresults-outer hidden">
|
||||
<div id="searchresults-header" class="searchresults-header"></div>
|
||||
<ul id="searchresults">
|
||||
</ul>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- Apply ARIA attributes after the sidebar and the sidebar toggle button are added to the DOM -->
|
||||
<script type="text/javascript">
|
||||
document.getElementById('sidebar-toggle').setAttribute('aria-expanded', sidebar === 'visible');
|
||||
document.getElementById('sidebar').setAttribute('aria-hidden', sidebar !== 'visible');
|
||||
Array.from(document.querySelectorAll('#sidebar a')).forEach(function(link) {
|
||||
link.setAttribute('tabIndex', sidebar === 'visible' ? 0 : -1);
|
||||
});
|
||||
</script>
|
||||
|
||||
<div id="content" class="content">
|
||||
<main>
|
||||
<h1 id="named-navigation-failure"><a class="header" href="#named-navigation-failure">Named Navigation Failure</a></h1>
|
||||
<p>When using <a href="../navigation/name.html">named navigation</a>, the router runs into a
|
||||
problem under these circumstances:</p>
|
||||
<ol>
|
||||
<li>The name we try to navigate to is not contained within our routes.</li>
|
||||
<li>The route we navigate to requires a parameter that we don't provide when
|
||||
triggering the navigation.</li>
|
||||
</ol>
|
||||
<blockquote>
|
||||
<p>Users cannot directly interact with named navigation. If a named navigation
|
||||
failure occurs, your app (or the router) has a bug.</p>
|
||||
</blockquote>
|
||||
<p>The router reacts to this problem differently, depending on our apps build kind.</p>
|
||||
<h2 id="debug"><a class="header" href="#debug">Debug</a></h2>
|
||||
<p>When running a debug build, the router will <code>panic</code> whenever it encounters an
|
||||
invalid navigation. This ensures that we notice these problems when we are
|
||||
testing our application.</p>
|
||||
<h2 id="release"><a class="header" href="#release">Release</a></h2>
|
||||
<p>When running a release build, the router can't just <code>panic</code>, as that would be a
|
||||
horrible user experience. Instead, it changes to show some fallback content.</p>
|
||||
<blockquote>
|
||||
<p>You can detect if the router is in the named navigation failure handling state
|
||||
by <a href="../navigation/name.html#check-if-a-name-is-present">checking</a> if the
|
||||
<a href="https://docs.rs/dioxus-router-core/latest/dioxus_router_core/prelude/struct.FailureNamedNavigation.html"><code>FailureNamedNavigation</code></a> name is present.</p>
|
||||
</blockquote>
|
||||
<p>The default fallback explains to the user that an error occurred and asks them
|
||||
to report the bug to the app developer.</p>
|
||||
<p>You can override it by setting the <code>failure_named_navigation</code> value of the
|
||||
<a href="https://docs.rs/dioxus-router/latest/dioxus_router/hooks/struct.RouterConfiguration.html"><code>RouterConfiguration</code></a>.</p>
|
||||
<pre><pre class="playground"><code class="language-rust no_run edition2021">
|
||||
<span class="boring">#![allow(unused)]
|
||||
</span><span class="boring">fn main() {
|
||||
</span><span class="boring">// Hidden lines (like this one) make the documentation tests work.
|
||||
</span><span class="boring">extern crate dioxus;
|
||||
</span><span class="boring">use dioxus::prelude::*;
|
||||
</span><span class="boring">extern crate dioxus_router;
|
||||
</span><span class="boring">use dioxus_router::prelude::*;
|
||||
</span>fn NamedNavigationFallback(cx: Scope) -> Element {
|
||||
render! {
|
||||
h1 { "Named navigation failure!" }
|
||||
}
|
||||
}
|
||||
|
||||
fn App(cx: Scope) -> Element {
|
||||
use_router(
|
||||
cx,
|
||||
&|| RouterConfiguration {
|
||||
failure_named_navigation: comp(NamedNavigationFallback),
|
||||
..Default::default()
|
||||
},
|
||||
&|| Segment::empty()
|
||||
);
|
||||
|
||||
render! {
|
||||
Outlet { }
|
||||
}
|
||||
}
|
||||
<span class="boring">}
|
||||
</span></code></pre></pre>
|
||||
|
||||
</main>
|
||||
|
||||
<nav class="nav-wrapper" aria-label="Page navigation">
|
||||
<!-- Mobile navigation buttons -->
|
||||
<a rel="prev" href="../../features/failures/index.html" class="mobile-nav-chapters previous" title="Previous chapter" aria-label="Previous chapter" aria-keyshortcuts="Left">
|
||||
<i class="fa fa-angle-left"></i>
|
||||
</a>
|
||||
|
||||
<a rel="next" href="../../features/failures/external.html" class="mobile-nav-chapters next" title="Next chapter" aria-label="Next chapter" aria-keyshortcuts="Right">
|
||||
<i class="fa fa-angle-right"></i>
|
||||
</a>
|
||||
|
||||
<div style="clear: both"></div>
|
||||
</nav>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<nav class="nav-wide-wrapper" aria-label="Page navigation">
|
||||
<a rel="prev" href="../../features/failures/index.html" class="nav-chapters previous" title="Previous chapter" aria-label="Previous chapter" aria-keyshortcuts="Left">
|
||||
<i class="fa fa-angle-left"></i>
|
||||
</a>
|
||||
|
||||
<a rel="next" href="../../features/failures/external.html" class="nav-chapters next" title="Next chapter" aria-label="Next chapter" aria-keyshortcuts="Right">
|
||||
<i class="fa fa-angle-right"></i>
|
||||
</a>
|
||||
</nav>
|
||||
|
||||
</div>
|
||||
|
||||
|
||||
|
||||
|
||||
<script type="text/javascript">
|
||||
window.playground_copyable = true;
|
||||
</script>
|
||||
|
||||
|
||||
<script src="../../elasticlunr.min.js" type="text/javascript" charset="utf-8"></script>
|
||||
<script src="../../mark.min.js" type="text/javascript" charset="utf-8"></script>
|
||||
<script src="../../searcher.js" type="text/javascript" charset="utf-8"></script>
|
||||
|
||||
<script src="../../clipboard.min.js" type="text/javascript" charset="utf-8"></script>
|
||||
<script src="../../highlight.js" type="text/javascript" charset="utf-8"></script>
|
||||
<script src="../../book.js" type="text/javascript" charset="utf-8"></script>
|
||||
|
||||
<!-- Custom JS scripts -->
|
||||
|
||||
|
||||
</body>
|
||||
</html>
|
||||
@@ -0,0 +1,255 @@
|
||||
<!DOCTYPE HTML>
|
||||
<html lang="en" class="sidebar-visible no-js light">
|
||||
<head>
|
||||
<!-- Book generated using mdBook -->
|
||||
<meta charset="UTF-8">
|
||||
<title>Redirection Limit Failure - Dioxus Router</title>
|
||||
|
||||
|
||||
<!-- Custom HTML head -->
|
||||
|
||||
<meta content="text/html; charset=utf-8" http-equiv="Content-Type">
|
||||
<meta name="description" content="">
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1">
|
||||
<meta name="theme-color" content="#ffffff" />
|
||||
|
||||
<link rel="icon" href="../../favicon.svg">
|
||||
<link rel="shortcut icon" href="../../favicon.png">
|
||||
<link rel="stylesheet" href="../../css/variables.css">
|
||||
<link rel="stylesheet" href="../../css/general.css">
|
||||
<link rel="stylesheet" href="../../css/chrome.css">
|
||||
<link rel="stylesheet" href="../../css/print.css" media="print">
|
||||
|
||||
<!-- Fonts -->
|
||||
<link rel="stylesheet" href="../../FontAwesome/css/font-awesome.css">
|
||||
<link rel="stylesheet" href="../../fonts/fonts.css">
|
||||
|
||||
<!-- Highlight.js Stylesheets -->
|
||||
<link rel="stylesheet" href="../../highlight.css">
|
||||
<link rel="stylesheet" href="../../tomorrow-night.css">
|
||||
<link rel="stylesheet" href="../../ayu-highlight.css">
|
||||
|
||||
<!-- Custom theme stylesheets -->
|
||||
|
||||
</head>
|
||||
<body>
|
||||
<!-- Provide site root to javascript -->
|
||||
<script type="text/javascript">
|
||||
var path_to_root = "../../";
|
||||
var default_theme = window.matchMedia("(prefers-color-scheme: dark)").matches ? "navy" : "light";
|
||||
</script>
|
||||
|
||||
<!-- Work around some values being stored in localStorage wrapped in quotes -->
|
||||
<script type="text/javascript">
|
||||
try {
|
||||
var theme = localStorage.getItem('mdbook-theme');
|
||||
var sidebar = localStorage.getItem('mdbook-sidebar');
|
||||
|
||||
if (theme.startsWith('"') && theme.endsWith('"')) {
|
||||
localStorage.setItem('mdbook-theme', theme.slice(1, theme.length - 1));
|
||||
}
|
||||
|
||||
if (sidebar.startsWith('"') && sidebar.endsWith('"')) {
|
||||
localStorage.setItem('mdbook-sidebar', sidebar.slice(1, sidebar.length - 1));
|
||||
}
|
||||
} catch (e) { }
|
||||
</script>
|
||||
|
||||
<!-- Set the theme before any content is loaded, prevents flash -->
|
||||
<script type="text/javascript">
|
||||
var theme;
|
||||
try { theme = localStorage.getItem('mdbook-theme'); } catch(e) { }
|
||||
if (theme === null || theme === undefined) { theme = default_theme; }
|
||||
var html = document.querySelector('html');
|
||||
html.classList.remove('no-js')
|
||||
html.classList.remove('light')
|
||||
html.classList.add(theme);
|
||||
html.classList.add('js');
|
||||
</script>
|
||||
|
||||
<!-- Hide / unhide sidebar before it is displayed -->
|
||||
<script type="text/javascript">
|
||||
var html = document.querySelector('html');
|
||||
var sidebar = 'hidden';
|
||||
if (document.body.clientWidth >= 1080) {
|
||||
try { sidebar = localStorage.getItem('mdbook-sidebar'); } catch(e) { }
|
||||
sidebar = sidebar || 'visible';
|
||||
}
|
||||
html.classList.remove('sidebar-visible');
|
||||
html.classList.add("sidebar-" + sidebar);
|
||||
</script>
|
||||
|
||||
<nav id="sidebar" class="sidebar" aria-label="Table of contents">
|
||||
<div class="sidebar-scrollbox">
|
||||
<ol class="chapter"><li class="chapter-item expanded affix "><a href="../../index.html">Introduction</a></li><li class="chapter-item expanded affix "><li class="part-title">Features</li><li class="chapter-item expanded "><a href="../../features/index.html"><strong aria-hidden="true">1.</strong> Adding the Router to Your Application</a></li><li class="chapter-item expanded "><a href="../../features/routes/index.html"><strong aria-hidden="true">2.</strong> Defining Routes</a></li><li><ol class="section"><li class="chapter-item expanded "><a href="../../features/routes/nested.html"><strong aria-hidden="true">2.1.</strong> Nested Routes</a></li><li class="chapter-item expanded "><a href="../../features/routes/catch_all.html"><strong aria-hidden="true">2.2.</strong> Catch All Routes</a></li><li class="chapter-item expanded "><a href="../../features/routes/matching.html"><strong aria-hidden="true">2.3.</strong> Matching Routes</a></li><li class="chapter-item expanded "><a href="../../features/routes/fallback.html"><strong aria-hidden="true">2.4.</strong> Fallback Routes (404 page)</a></li><li class="chapter-item expanded "><a href="../../features/routes/multiple-and-redirect.html"><strong aria-hidden="true">2.5.</strong> Multiple Components & Redirects</a></li></ol></li><li class="chapter-item expanded "><a href="../../features/outlets.html"><strong aria-hidden="true">3.</strong> Outlets</a></li><li class="chapter-item expanded "><a href="../../features/navigation/index.html"><strong aria-hidden="true">4.</strong> Links & Navigation</a></li><li><ol class="section"><li class="chapter-item expanded "><a href="../../features/navigation/name.html"><strong aria-hidden="true">4.1.</strong> Named Navigation</a></li><li class="chapter-item expanded "><a href="../../features/navigation/external.html"><strong aria-hidden="true">4.2.</strong> External Navigation</a></li><li class="chapter-item expanded "><a href="../../features/navigation/programmatic.html"><strong aria-hidden="true">4.3.</strong> Programmatic Navigation</a></li></ol></li><li class="chapter-item expanded "><a href="../../features/query.html"><strong aria-hidden="true">5.</strong> Query</a></li><li class="chapter-item expanded "><a href="../../features/failures/index.html"><strong aria-hidden="true">6.</strong> Navigation Failures</a></li><li><ol class="section"><li class="chapter-item expanded "><a href="../../features/failures/named.html"><strong aria-hidden="true">6.1.</strong> Named Navigation Failure</a></li><li class="chapter-item expanded "><a href="../../features/failures/external.html"><strong aria-hidden="true">6.2.</strong> External Navigation Failure</a></li><li class="chapter-item expanded "><a href="../../features/failures/redirection-limit.html" class="active"><strong aria-hidden="true">6.3.</strong> Redirection Limit Failure</a></li></ol></li><li class="chapter-item expanded "><a href="../../features/history-providers.html"><strong aria-hidden="true">7.</strong> History Providers</a></li><li class="chapter-item expanded "><a href="../../features/history-buttons.html"><strong aria-hidden="true">8.</strong> History Buttons</a></li><li class="chapter-item expanded "><a href="../../features/sitemap-generation.html"><strong aria-hidden="true">9.</strong> Sitemap Generation</a></li><li class="chapter-item expanded "><a href="../../features/routing-update-callback.html"><strong aria-hidden="true">10.</strong> Routing Update Callback</a></li><li class="chapter-item expanded affix "><li class="part-title">Example Project</li><li class="chapter-item expanded "><a href="../../example/index.html"><strong aria-hidden="true">11.</strong> Overview</a></li><li class="chapter-item expanded "><a href="../../example/first-route.html"><strong aria-hidden="true">12.</strong> Creating Our First Route</a></li><li class="chapter-item expanded "><a href="../../example/building-a-nest.html"><strong aria-hidden="true">13.</strong> Building a Nest</a></li><li class="chapter-item expanded "><a href="../../example/navigation-targets.html"><strong aria-hidden="true">14.</strong> Navigation Targets</a></li><li class="chapter-item expanded "><a href="../../example/redirection-perfection.html"><strong aria-hidden="true">15.</strong> Redirection Perfection</a></li><li class="chapter-item expanded "><a href="../../example/full-code.html"><strong aria-hidden="true">16.</strong> Full Code</a></li></ol>
|
||||
</div>
|
||||
<div id="sidebar-resize-handle" class="sidebar-resize-handle"></div>
|
||||
</nav>
|
||||
|
||||
<div id="page-wrapper" class="page-wrapper">
|
||||
|
||||
<div class="page">
|
||||
<div id="menu-bar-hover-placeholder"></div>
|
||||
<div id="menu-bar" class="menu-bar sticky bordered">
|
||||
<div class="left-buttons">
|
||||
<button id="sidebar-toggle" class="icon-button" type="button" title="Toggle Table of Contents" aria-label="Toggle Table of Contents" aria-controls="sidebar">
|
||||
<i class="fa fa-bars"></i>
|
||||
</button>
|
||||
<button id="theme-toggle" class="icon-button" type="button" title="Change theme" aria-label="Change theme" aria-haspopup="true" aria-expanded="false" aria-controls="theme-list">
|
||||
<i class="fa fa-paint-brush"></i>
|
||||
</button>
|
||||
<ul id="theme-list" class="theme-popup" aria-label="Themes" role="menu">
|
||||
<li role="none"><button role="menuitem" class="theme" id="light">Light (default)</button></li>
|
||||
<li role="none"><button role="menuitem" class="theme" id="rust">Rust</button></li>
|
||||
<li role="none"><button role="menuitem" class="theme" id="coal">Coal</button></li>
|
||||
<li role="none"><button role="menuitem" class="theme" id="navy">Navy</button></li>
|
||||
<li role="none"><button role="menuitem" class="theme" id="ayu">Ayu</button></li>
|
||||
</ul>
|
||||
<button id="search-toggle" class="icon-button" type="button" title="Search. (Shortkey: s)" aria-label="Toggle Searchbar" aria-expanded="false" aria-keyshortcuts="S" aria-controls="searchbar">
|
||||
<i class="fa fa-search"></i>
|
||||
</button>
|
||||
</div>
|
||||
|
||||
<h1 class="menu-title">Dioxus Router</h1>
|
||||
|
||||
<div class="right-buttons">
|
||||
<a href="../../print.html" title="Print this book" aria-label="Print this book">
|
||||
<i id="print-button" class="fa fa-print"></i>
|
||||
</a>
|
||||
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div id="search-wrapper" class="hidden">
|
||||
<form id="searchbar-outer" class="searchbar-outer">
|
||||
<input type="search" id="searchbar" name="searchbar" placeholder="Search this book ..." aria-controls="searchresults-outer" aria-describedby="searchresults-header">
|
||||
</form>
|
||||
<div id="searchresults-outer" class="searchresults-outer hidden">
|
||||
<div id="searchresults-header" class="searchresults-header"></div>
|
||||
<ul id="searchresults">
|
||||
</ul>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- Apply ARIA attributes after the sidebar and the sidebar toggle button are added to the DOM -->
|
||||
<script type="text/javascript">
|
||||
document.getElementById('sidebar-toggle').setAttribute('aria-expanded', sidebar === 'visible');
|
||||
document.getElementById('sidebar').setAttribute('aria-hidden', sidebar !== 'visible');
|
||||
Array.from(document.querySelectorAll('#sidebar a')).forEach(function(link) {
|
||||
link.setAttribute('tabIndex', sidebar === 'visible' ? 0 : -1);
|
||||
});
|
||||
</script>
|
||||
|
||||
<div id="content" class="content">
|
||||
<main>
|
||||
<h1 id="redirection-limit-failure"><a class="header" href="#redirection-limit-failure">Redirection Limit Failure</a></h1>
|
||||
<p>The router enforces a limit of 25 redirects during a single routing navigation.
|
||||
This is done to prevent infinite loops. If your app breaches that limit, you
|
||||
should reorganize its routes to reduce the number of redirects.</p>
|
||||
<blockquote>
|
||||
<p>Users cannot trigger a redirection. If the redirection limit is breached, your
|
||||
app (or the router) has a bug.</p>
|
||||
</blockquote>
|
||||
<blockquote>
|
||||
<p>The <a href="../routing-update-callback.html"><code>on_update</code></a> callback doesn't count
|
||||
towards the limit, and resets it. You may have 25 redirects, then add an other
|
||||
one via the callback, and then have another 25.</p>
|
||||
</blockquote>
|
||||
<p>The router reacts to a breach differently, depending on our apps build kind.</p>
|
||||
<h2 id="debug"><a class="header" href="#debug">Debug</a></h2>
|
||||
<p>When running a debug build, the router will <code>panic</code> whenever the redirecion
|
||||
limit is breached. This ensures that we notice these problems when we are
|
||||
testing our application.</p>
|
||||
<h2 id="release"><a class="header" href="#release">Release</a></h2>
|
||||
<p>When running a release build, the router can't just <code>panic</code>, as that would be a
|
||||
horrible user experience. Instead, it changes to show some fallback content.</p>
|
||||
<blockquote>
|
||||
<p>You can detect if the router is in the redirection limit failure handling
|
||||
state by <a href="../navigation/name.html#check-if-a-name-is-present">checking</a> if the
|
||||
<a href="https://docs.rs/dioxus-router-core/latest/dioxus_router_core/prelude/struct.FailureRedirectionLimit.html"><code>FailureRedirectionLimit</code></a> name is present.</p>
|
||||
</blockquote>
|
||||
<p>The default fallback explains to the user that an error occurred and asks them
|
||||
to report the bug to the app developer.</p>
|
||||
<p>You can override it by setting the <code>failure_redirection_limit</code> value of the
|
||||
<a href="https://docs.rs/dioxus-router/latest/dioxus_router/hooks/struct.RouterConfiguration.html"><code>RouterConfiguration</code></a>.</p>
|
||||
<pre><pre class="playground"><code class="language-rust no_run edition2021">
|
||||
<span class="boring">#![allow(unused)]
|
||||
</span><span class="boring">fn main() {
|
||||
</span><span class="boring">// Hidden lines (like this one) make the documentation tests work.
|
||||
</span><span class="boring">extern crate dioxus;
|
||||
</span><span class="boring">use dioxus::prelude::*;
|
||||
</span><span class="boring">extern crate dioxus_router;
|
||||
</span><span class="boring">use dioxus_router::prelude::*;
|
||||
</span>fn RedirectionLimitFallback(cx: Scope) -> Element {
|
||||
render! {
|
||||
h1 { "Redirection limit breached!" }
|
||||
}
|
||||
}
|
||||
|
||||
fn App(cx: Scope) -> Element {
|
||||
use_router(
|
||||
cx,
|
||||
&|| RouterConfiguration {
|
||||
failure_redirection_limit: comp(RedirectionLimitFallback),
|
||||
..Default::default()
|
||||
},
|
||||
&|| Segment::empty()
|
||||
);
|
||||
|
||||
render! {
|
||||
Outlet { }
|
||||
}
|
||||
}
|
||||
<span class="boring">}
|
||||
</span></code></pre></pre>
|
||||
|
||||
</main>
|
||||
|
||||
<nav class="nav-wrapper" aria-label="Page navigation">
|
||||
<!-- Mobile navigation buttons -->
|
||||
<a rel="prev" href="../../features/failures/external.html" class="mobile-nav-chapters previous" title="Previous chapter" aria-label="Previous chapter" aria-keyshortcuts="Left">
|
||||
<i class="fa fa-angle-left"></i>
|
||||
</a>
|
||||
|
||||
<a rel="next" href="../../features/history-providers.html" class="mobile-nav-chapters next" title="Next chapter" aria-label="Next chapter" aria-keyshortcuts="Right">
|
||||
<i class="fa fa-angle-right"></i>
|
||||
</a>
|
||||
|
||||
<div style="clear: both"></div>
|
||||
</nav>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<nav class="nav-wide-wrapper" aria-label="Page navigation">
|
||||
<a rel="prev" href="../../features/failures/external.html" class="nav-chapters previous" title="Previous chapter" aria-label="Previous chapter" aria-keyshortcuts="Left">
|
||||
<i class="fa fa-angle-left"></i>
|
||||
</a>
|
||||
|
||||
<a rel="next" href="../../features/history-providers.html" class="nav-chapters next" title="Next chapter" aria-label="Next chapter" aria-keyshortcuts="Right">
|
||||
<i class="fa fa-angle-right"></i>
|
||||
</a>
|
||||
</nav>
|
||||
|
||||
</div>
|
||||
|
||||
|
||||
|
||||
|
||||
<script type="text/javascript">
|
||||
window.playground_copyable = true;
|
||||
</script>
|
||||
|
||||
|
||||
<script src="../../elasticlunr.min.js" type="text/javascript" charset="utf-8"></script>
|
||||
<script src="../../mark.min.js" type="text/javascript" charset="utf-8"></script>
|
||||
<script src="../../searcher.js" type="text/javascript" charset="utf-8"></script>
|
||||
|
||||
<script src="../../clipboard.min.js" type="text/javascript" charset="utf-8"></script>
|
||||
<script src="../../highlight.js" type="text/javascript" charset="utf-8"></script>
|
||||
<script src="../../book.js" type="text/javascript" charset="utf-8"></script>
|
||||
|
||||
<!-- Custom JS scripts -->
|
||||
|
||||
|
||||
</body>
|
||||
</html>
|
||||
@@ -0,0 +1,240 @@
|
||||
<!DOCTYPE HTML>
|
||||
<html lang="en" class="sidebar-visible no-js light">
|
||||
<head>
|
||||
<!-- Book generated using mdBook -->
|
||||
<meta charset="UTF-8">
|
||||
<title>History Buttons - Dioxus Router</title>
|
||||
|
||||
|
||||
<!-- Custom HTML head -->
|
||||
|
||||
<meta content="text/html; charset=utf-8" http-equiv="Content-Type">
|
||||
<meta name="description" content="">
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1">
|
||||
<meta name="theme-color" content="#ffffff" />
|
||||
|
||||
<link rel="icon" href="../favicon.svg">
|
||||
<link rel="shortcut icon" href="../favicon.png">
|
||||
<link rel="stylesheet" href="../css/variables.css">
|
||||
<link rel="stylesheet" href="../css/general.css">
|
||||
<link rel="stylesheet" href="../css/chrome.css">
|
||||
<link rel="stylesheet" href="../css/print.css" media="print">
|
||||
|
||||
<!-- Fonts -->
|
||||
<link rel="stylesheet" href="../FontAwesome/css/font-awesome.css">
|
||||
<link rel="stylesheet" href="../fonts/fonts.css">
|
||||
|
||||
<!-- Highlight.js Stylesheets -->
|
||||
<link rel="stylesheet" href="../highlight.css">
|
||||
<link rel="stylesheet" href="../tomorrow-night.css">
|
||||
<link rel="stylesheet" href="../ayu-highlight.css">
|
||||
|
||||
<!-- Custom theme stylesheets -->
|
||||
|
||||
</head>
|
||||
<body>
|
||||
<!-- Provide site root to javascript -->
|
||||
<script type="text/javascript">
|
||||
var path_to_root = "../";
|
||||
var default_theme = window.matchMedia("(prefers-color-scheme: dark)").matches ? "navy" : "light";
|
||||
</script>
|
||||
|
||||
<!-- Work around some values being stored in localStorage wrapped in quotes -->
|
||||
<script type="text/javascript">
|
||||
try {
|
||||
var theme = localStorage.getItem('mdbook-theme');
|
||||
var sidebar = localStorage.getItem('mdbook-sidebar');
|
||||
|
||||
if (theme.startsWith('"') && theme.endsWith('"')) {
|
||||
localStorage.setItem('mdbook-theme', theme.slice(1, theme.length - 1));
|
||||
}
|
||||
|
||||
if (sidebar.startsWith('"') && sidebar.endsWith('"')) {
|
||||
localStorage.setItem('mdbook-sidebar', sidebar.slice(1, sidebar.length - 1));
|
||||
}
|
||||
} catch (e) { }
|
||||
</script>
|
||||
|
||||
<!-- Set the theme before any content is loaded, prevents flash -->
|
||||
<script type="text/javascript">
|
||||
var theme;
|
||||
try { theme = localStorage.getItem('mdbook-theme'); } catch(e) { }
|
||||
if (theme === null || theme === undefined) { theme = default_theme; }
|
||||
var html = document.querySelector('html');
|
||||
html.classList.remove('no-js')
|
||||
html.classList.remove('light')
|
||||
html.classList.add(theme);
|
||||
html.classList.add('js');
|
||||
</script>
|
||||
|
||||
<!-- Hide / unhide sidebar before it is displayed -->
|
||||
<script type="text/javascript">
|
||||
var html = document.querySelector('html');
|
||||
var sidebar = 'hidden';
|
||||
if (document.body.clientWidth >= 1080) {
|
||||
try { sidebar = localStorage.getItem('mdbook-sidebar'); } catch(e) { }
|
||||
sidebar = sidebar || 'visible';
|
||||
}
|
||||
html.classList.remove('sidebar-visible');
|
||||
html.classList.add("sidebar-" + sidebar);
|
||||
</script>
|
||||
|
||||
<nav id="sidebar" class="sidebar" aria-label="Table of contents">
|
||||
<div class="sidebar-scrollbox">
|
||||
<ol class="chapter"><li class="chapter-item expanded affix "><a href="../index.html">Introduction</a></li><li class="chapter-item expanded affix "><li class="part-title">Features</li><li class="chapter-item expanded "><a href="../features/index.html"><strong aria-hidden="true">1.</strong> Adding the Router to Your Application</a></li><li class="chapter-item expanded "><a href="../features/routes/index.html"><strong aria-hidden="true">2.</strong> Defining Routes</a></li><li><ol class="section"><li class="chapter-item expanded "><a href="../features/routes/nested.html"><strong aria-hidden="true">2.1.</strong> Nested Routes</a></li><li class="chapter-item expanded "><a href="../features/routes/catch_all.html"><strong aria-hidden="true">2.2.</strong> Catch All Routes</a></li><li class="chapter-item expanded "><a href="../features/routes/matching.html"><strong aria-hidden="true">2.3.</strong> Matching Routes</a></li><li class="chapter-item expanded "><a href="../features/routes/fallback.html"><strong aria-hidden="true">2.4.</strong> Fallback Routes (404 page)</a></li><li class="chapter-item expanded "><a href="../features/routes/multiple-and-redirect.html"><strong aria-hidden="true">2.5.</strong> Multiple Components & Redirects</a></li></ol></li><li class="chapter-item expanded "><a href="../features/outlets.html"><strong aria-hidden="true">3.</strong> Outlets</a></li><li class="chapter-item expanded "><a href="../features/navigation/index.html"><strong aria-hidden="true">4.</strong> Links & Navigation</a></li><li><ol class="section"><li class="chapter-item expanded "><a href="../features/navigation/name.html"><strong aria-hidden="true">4.1.</strong> Named Navigation</a></li><li class="chapter-item expanded "><a href="../features/navigation/external.html"><strong aria-hidden="true">4.2.</strong> External Navigation</a></li><li class="chapter-item expanded "><a href="../features/navigation/programmatic.html"><strong aria-hidden="true">4.3.</strong> Programmatic Navigation</a></li></ol></li><li class="chapter-item expanded "><a href="../features/query.html"><strong aria-hidden="true">5.</strong> Query</a></li><li class="chapter-item expanded "><a href="../features/failures/index.html"><strong aria-hidden="true">6.</strong> Navigation Failures</a></li><li><ol class="section"><li class="chapter-item expanded "><a href="../features/failures/named.html"><strong aria-hidden="true">6.1.</strong> Named Navigation Failure</a></li><li class="chapter-item expanded "><a href="../features/failures/external.html"><strong aria-hidden="true">6.2.</strong> External Navigation Failure</a></li><li class="chapter-item expanded "><a href="../features/failures/redirection-limit.html"><strong aria-hidden="true">6.3.</strong> Redirection Limit Failure</a></li></ol></li><li class="chapter-item expanded "><a href="../features/history-providers.html"><strong aria-hidden="true">7.</strong> History Providers</a></li><li class="chapter-item expanded "><a href="../features/history-buttons.html" class="active"><strong aria-hidden="true">8.</strong> History Buttons</a></li><li class="chapter-item expanded "><a href="../features/sitemap-generation.html"><strong aria-hidden="true">9.</strong> Sitemap Generation</a></li><li class="chapter-item expanded "><a href="../features/routing-update-callback.html"><strong aria-hidden="true">10.</strong> Routing Update Callback</a></li><li class="chapter-item expanded affix "><li class="part-title">Example Project</li><li class="chapter-item expanded "><a href="../example/index.html"><strong aria-hidden="true">11.</strong> Overview</a></li><li class="chapter-item expanded "><a href="../example/first-route.html"><strong aria-hidden="true">12.</strong> Creating Our First Route</a></li><li class="chapter-item expanded "><a href="../example/building-a-nest.html"><strong aria-hidden="true">13.</strong> Building a Nest</a></li><li class="chapter-item expanded "><a href="../example/navigation-targets.html"><strong aria-hidden="true">14.</strong> Navigation Targets</a></li><li class="chapter-item expanded "><a href="../example/redirection-perfection.html"><strong aria-hidden="true">15.</strong> Redirection Perfection</a></li><li class="chapter-item expanded "><a href="../example/full-code.html"><strong aria-hidden="true">16.</strong> Full Code</a></li></ol>
|
||||
</div>
|
||||
<div id="sidebar-resize-handle" class="sidebar-resize-handle"></div>
|
||||
</nav>
|
||||
|
||||
<div id="page-wrapper" class="page-wrapper">
|
||||
|
||||
<div class="page">
|
||||
<div id="menu-bar-hover-placeholder"></div>
|
||||
<div id="menu-bar" class="menu-bar sticky bordered">
|
||||
<div class="left-buttons">
|
||||
<button id="sidebar-toggle" class="icon-button" type="button" title="Toggle Table of Contents" aria-label="Toggle Table of Contents" aria-controls="sidebar">
|
||||
<i class="fa fa-bars"></i>
|
||||
</button>
|
||||
<button id="theme-toggle" class="icon-button" type="button" title="Change theme" aria-label="Change theme" aria-haspopup="true" aria-expanded="false" aria-controls="theme-list">
|
||||
<i class="fa fa-paint-brush"></i>
|
||||
</button>
|
||||
<ul id="theme-list" class="theme-popup" aria-label="Themes" role="menu">
|
||||
<li role="none"><button role="menuitem" class="theme" id="light">Light (default)</button></li>
|
||||
<li role="none"><button role="menuitem" class="theme" id="rust">Rust</button></li>
|
||||
<li role="none"><button role="menuitem" class="theme" id="coal">Coal</button></li>
|
||||
<li role="none"><button role="menuitem" class="theme" id="navy">Navy</button></li>
|
||||
<li role="none"><button role="menuitem" class="theme" id="ayu">Ayu</button></li>
|
||||
</ul>
|
||||
<button id="search-toggle" class="icon-button" type="button" title="Search. (Shortkey: s)" aria-label="Toggle Searchbar" aria-expanded="false" aria-keyshortcuts="S" aria-controls="searchbar">
|
||||
<i class="fa fa-search"></i>
|
||||
</button>
|
||||
</div>
|
||||
|
||||
<h1 class="menu-title">Dioxus Router</h1>
|
||||
|
||||
<div class="right-buttons">
|
||||
<a href="../print.html" title="Print this book" aria-label="Print this book">
|
||||
<i id="print-button" class="fa fa-print"></i>
|
||||
</a>
|
||||
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div id="search-wrapper" class="hidden">
|
||||
<form id="searchbar-outer" class="searchbar-outer">
|
||||
<input type="search" id="searchbar" name="searchbar" placeholder="Search this book ..." aria-controls="searchresults-outer" aria-describedby="searchresults-header">
|
||||
</form>
|
||||
<div id="searchresults-outer" class="searchresults-outer hidden">
|
||||
<div id="searchresults-header" class="searchresults-header"></div>
|
||||
<ul id="searchresults">
|
||||
</ul>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- Apply ARIA attributes after the sidebar and the sidebar toggle button are added to the DOM -->
|
||||
<script type="text/javascript">
|
||||
document.getElementById('sidebar-toggle').setAttribute('aria-expanded', sidebar === 'visible');
|
||||
document.getElementById('sidebar').setAttribute('aria-hidden', sidebar !== 'visible');
|
||||
Array.from(document.querySelectorAll('#sidebar a')).forEach(function(link) {
|
||||
link.setAttribute('tabIndex', sidebar === 'visible' ? 0 : -1);
|
||||
});
|
||||
</script>
|
||||
|
||||
<div id="content" class="content">
|
||||
<main>
|
||||
<h1 id="history-buttons"><a class="header" href="#history-buttons">History Buttons</a></h1>
|
||||
<p>Some platforms, like web browsers, provide users with an easy way to navigate
|
||||
through an apps history. They have UI elements or integrate with the OS.</p>
|
||||
<p>However, native platforms usually don't provide such amenities, which means that
|
||||
apps wanting users to have access to them, need to implement them. For this
|
||||
reason the router comes with two components, which emulate a browsers back and
|
||||
forward buttons:</p>
|
||||
<ul>
|
||||
<li><a href="https://docs.rs/dioxus-router/latest/dioxus_router/components/fn.GoBackButton.html"><code>GoBackButton</code></a></li>
|
||||
<li><a href="https://docs.rs/dioxus-router/latest/dioxus_router/components/fn.GoForwardButton.html"><code>GoForwardButton</code></a></li>
|
||||
</ul>
|
||||
<blockquote>
|
||||
<p>If you want to navigate through the history programmatically, take a look at
|
||||
<a href="./navigation/programmatic.html"><code>programmatic navigation</code></a>.</p>
|
||||
</blockquote>
|
||||
<pre><pre class="playground"><code class="language-rust no_run edition2021">
|
||||
<span class="boring">#![allow(unused)]
|
||||
</span><span class="boring">fn main() {
|
||||
</span><span class="boring">// Hidden lines (like this one) make the documentation tests work.
|
||||
</span><span class="boring">extern crate dioxus;
|
||||
</span>use dioxus::prelude::*;
|
||||
<span class="boring">extern crate dioxus_router;
|
||||
</span>use dioxus_router::prelude::*;
|
||||
|
||||
fn HistoryNavigation(cx: Scope) -> Element {
|
||||
render! {
|
||||
GoBackButton {
|
||||
"Back to the Past"
|
||||
}
|
||||
GoForwardButton {
|
||||
"Back to the Future" /* You see what I did there? 😉 */
|
||||
}
|
||||
}
|
||||
}
|
||||
<span class="boring">}
|
||||
</span></code></pre></pre>
|
||||
<p>As you might know, browsers usually disable the back and forward buttons if
|
||||
there is no history to navigate to. The routers history buttons try to do that
|
||||
too, but depending on the <a href="./history-providers.html">history provider</a> that might not be possible.</p>
|
||||
<p>Importantly, neither <a href="https://docs.rs/dioxus-router-core/latest/dioxus_router_core/history/struct.WebHistory.html"><code>WebHistory</code></a> nor <a href="https://docs.rs/dioxus-router-core/latest/dioxus_router_core/history/struct.WebHashHistory.html"><code>WebHashHistory</code></a> support that feature.
|
||||
This is due to limitations of the browser History API.</p>
|
||||
<p>However, in both cases the router will just ignore button presses, if there is
|
||||
no history to navigate to.</p>
|
||||
<p>Also, when using <a href="https://docs.rs/dioxus-router-core/latest/dioxus_router_core/history/struct.WebHistory.html"><code>WebHistory</code></a> or <a href="https://docs.rs/dioxus-router-core/latest/dioxus_router_core/history/struct.WebHashHistory.html"><code>WebHashHistory</code></a>, the history buttons might
|
||||
navigate a user to a history entry outside your app.</p>
|
||||
|
||||
</main>
|
||||
|
||||
<nav class="nav-wrapper" aria-label="Page navigation">
|
||||
<!-- Mobile navigation buttons -->
|
||||
<a rel="prev" href="../features/history-providers.html" class="mobile-nav-chapters previous" title="Previous chapter" aria-label="Previous chapter" aria-keyshortcuts="Left">
|
||||
<i class="fa fa-angle-left"></i>
|
||||
</a>
|
||||
|
||||
<a rel="next" href="../features/sitemap-generation.html" class="mobile-nav-chapters next" title="Next chapter" aria-label="Next chapter" aria-keyshortcuts="Right">
|
||||
<i class="fa fa-angle-right"></i>
|
||||
</a>
|
||||
|
||||
<div style="clear: both"></div>
|
||||
</nav>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<nav class="nav-wide-wrapper" aria-label="Page navigation">
|
||||
<a rel="prev" href="../features/history-providers.html" class="nav-chapters previous" title="Previous chapter" aria-label="Previous chapter" aria-keyshortcuts="Left">
|
||||
<i class="fa fa-angle-left"></i>
|
||||
</a>
|
||||
|
||||
<a rel="next" href="../features/sitemap-generation.html" class="nav-chapters next" title="Next chapter" aria-label="Next chapter" aria-keyshortcuts="Right">
|
||||
<i class="fa fa-angle-right"></i>
|
||||
</a>
|
||||
</nav>
|
||||
|
||||
</div>
|
||||
|
||||
|
||||
|
||||
|
||||
<script type="text/javascript">
|
||||
window.playground_copyable = true;
|
||||
</script>
|
||||
|
||||
|
||||
<script src="../elasticlunr.min.js" type="text/javascript" charset="utf-8"></script>
|
||||
<script src="../mark.min.js" type="text/javascript" charset="utf-8"></script>
|
||||
<script src="../searcher.js" type="text/javascript" charset="utf-8"></script>
|
||||
|
||||
<script src="../clipboard.min.js" type="text/javascript" charset="utf-8"></script>
|
||||
<script src="../highlight.js" type="text/javascript" charset="utf-8"></script>
|
||||
<script src="../book.js" type="text/javascript" charset="utf-8"></script>
|
||||
|
||||
<!-- Custom JS scripts -->
|
||||
|
||||
|
||||
</body>
|
||||
</html>
|
||||
@@ -0,0 +1,235 @@
|
||||
<!DOCTYPE HTML>
|
||||
<html lang="en" class="sidebar-visible no-js light">
|
||||
<head>
|
||||
<!-- Book generated using mdBook -->
|
||||
<meta charset="UTF-8">
|
||||
<title>History Providers - Dioxus Router</title>
|
||||
|
||||
|
||||
<!-- Custom HTML head -->
|
||||
|
||||
<meta content="text/html; charset=utf-8" http-equiv="Content-Type">
|
||||
<meta name="description" content="">
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1">
|
||||
<meta name="theme-color" content="#ffffff" />
|
||||
|
||||
<link rel="icon" href="../favicon.svg">
|
||||
<link rel="shortcut icon" href="../favicon.png">
|
||||
<link rel="stylesheet" href="../css/variables.css">
|
||||
<link rel="stylesheet" href="../css/general.css">
|
||||
<link rel="stylesheet" href="../css/chrome.css">
|
||||
<link rel="stylesheet" href="../css/print.css" media="print">
|
||||
|
||||
<!-- Fonts -->
|
||||
<link rel="stylesheet" href="../FontAwesome/css/font-awesome.css">
|
||||
<link rel="stylesheet" href="../fonts/fonts.css">
|
||||
|
||||
<!-- Highlight.js Stylesheets -->
|
||||
<link rel="stylesheet" href="../highlight.css">
|
||||
<link rel="stylesheet" href="../tomorrow-night.css">
|
||||
<link rel="stylesheet" href="../ayu-highlight.css">
|
||||
|
||||
<!-- Custom theme stylesheets -->
|
||||
|
||||
</head>
|
||||
<body>
|
||||
<!-- Provide site root to javascript -->
|
||||
<script type="text/javascript">
|
||||
var path_to_root = "../";
|
||||
var default_theme = window.matchMedia("(prefers-color-scheme: dark)").matches ? "navy" : "light";
|
||||
</script>
|
||||
|
||||
<!-- Work around some values being stored in localStorage wrapped in quotes -->
|
||||
<script type="text/javascript">
|
||||
try {
|
||||
var theme = localStorage.getItem('mdbook-theme');
|
||||
var sidebar = localStorage.getItem('mdbook-sidebar');
|
||||
|
||||
if (theme.startsWith('"') && theme.endsWith('"')) {
|
||||
localStorage.setItem('mdbook-theme', theme.slice(1, theme.length - 1));
|
||||
}
|
||||
|
||||
if (sidebar.startsWith('"') && sidebar.endsWith('"')) {
|
||||
localStorage.setItem('mdbook-sidebar', sidebar.slice(1, sidebar.length - 1));
|
||||
}
|
||||
} catch (e) { }
|
||||
</script>
|
||||
|
||||
<!-- Set the theme before any content is loaded, prevents flash -->
|
||||
<script type="text/javascript">
|
||||
var theme;
|
||||
try { theme = localStorage.getItem('mdbook-theme'); } catch(e) { }
|
||||
if (theme === null || theme === undefined) { theme = default_theme; }
|
||||
var html = document.querySelector('html');
|
||||
html.classList.remove('no-js')
|
||||
html.classList.remove('light')
|
||||
html.classList.add(theme);
|
||||
html.classList.add('js');
|
||||
</script>
|
||||
|
||||
<!-- Hide / unhide sidebar before it is displayed -->
|
||||
<script type="text/javascript">
|
||||
var html = document.querySelector('html');
|
||||
var sidebar = 'hidden';
|
||||
if (document.body.clientWidth >= 1080) {
|
||||
try { sidebar = localStorage.getItem('mdbook-sidebar'); } catch(e) { }
|
||||
sidebar = sidebar || 'visible';
|
||||
}
|
||||
html.classList.remove('sidebar-visible');
|
||||
html.classList.add("sidebar-" + sidebar);
|
||||
</script>
|
||||
|
||||
<nav id="sidebar" class="sidebar" aria-label="Table of contents">
|
||||
<div class="sidebar-scrollbox">
|
||||
<ol class="chapter"><li class="chapter-item expanded affix "><a href="../index.html">Introduction</a></li><li class="chapter-item expanded affix "><li class="part-title">Features</li><li class="chapter-item expanded "><a href="../features/index.html"><strong aria-hidden="true">1.</strong> Adding the Router to Your Application</a></li><li class="chapter-item expanded "><a href="../features/routes/index.html"><strong aria-hidden="true">2.</strong> Defining Routes</a></li><li><ol class="section"><li class="chapter-item expanded "><a href="../features/routes/nested.html"><strong aria-hidden="true">2.1.</strong> Nested Routes</a></li><li class="chapter-item expanded "><a href="../features/routes/catch_all.html"><strong aria-hidden="true">2.2.</strong> Catch All Routes</a></li><li class="chapter-item expanded "><a href="../features/routes/matching.html"><strong aria-hidden="true">2.3.</strong> Matching Routes</a></li><li class="chapter-item expanded "><a href="../features/routes/fallback.html"><strong aria-hidden="true">2.4.</strong> Fallback Routes (404 page)</a></li><li class="chapter-item expanded "><a href="../features/routes/multiple-and-redirect.html"><strong aria-hidden="true">2.5.</strong> Multiple Components & Redirects</a></li></ol></li><li class="chapter-item expanded "><a href="../features/outlets.html"><strong aria-hidden="true">3.</strong> Outlets</a></li><li class="chapter-item expanded "><a href="../features/navigation/index.html"><strong aria-hidden="true">4.</strong> Links & Navigation</a></li><li><ol class="section"><li class="chapter-item expanded "><a href="../features/navigation/name.html"><strong aria-hidden="true">4.1.</strong> Named Navigation</a></li><li class="chapter-item expanded "><a href="../features/navigation/external.html"><strong aria-hidden="true">4.2.</strong> External Navigation</a></li><li class="chapter-item expanded "><a href="../features/navigation/programmatic.html"><strong aria-hidden="true">4.3.</strong> Programmatic Navigation</a></li></ol></li><li class="chapter-item expanded "><a href="../features/query.html"><strong aria-hidden="true">5.</strong> Query</a></li><li class="chapter-item expanded "><a href="../features/failures/index.html"><strong aria-hidden="true">6.</strong> Navigation Failures</a></li><li><ol class="section"><li class="chapter-item expanded "><a href="../features/failures/named.html"><strong aria-hidden="true">6.1.</strong> Named Navigation Failure</a></li><li class="chapter-item expanded "><a href="../features/failures/external.html"><strong aria-hidden="true">6.2.</strong> External Navigation Failure</a></li><li class="chapter-item expanded "><a href="../features/failures/redirection-limit.html"><strong aria-hidden="true">6.3.</strong> Redirection Limit Failure</a></li></ol></li><li class="chapter-item expanded "><a href="../features/history-providers.html" class="active"><strong aria-hidden="true">7.</strong> History Providers</a></li><li class="chapter-item expanded "><a href="../features/history-buttons.html"><strong aria-hidden="true">8.</strong> History Buttons</a></li><li class="chapter-item expanded "><a href="../features/sitemap-generation.html"><strong aria-hidden="true">9.</strong> Sitemap Generation</a></li><li class="chapter-item expanded "><a href="../features/routing-update-callback.html"><strong aria-hidden="true">10.</strong> Routing Update Callback</a></li><li class="chapter-item expanded affix "><li class="part-title">Example Project</li><li class="chapter-item expanded "><a href="../example/index.html"><strong aria-hidden="true">11.</strong> Overview</a></li><li class="chapter-item expanded "><a href="../example/first-route.html"><strong aria-hidden="true">12.</strong> Creating Our First Route</a></li><li class="chapter-item expanded "><a href="../example/building-a-nest.html"><strong aria-hidden="true">13.</strong> Building a Nest</a></li><li class="chapter-item expanded "><a href="../example/navigation-targets.html"><strong aria-hidden="true">14.</strong> Navigation Targets</a></li><li class="chapter-item expanded "><a href="../example/redirection-perfection.html"><strong aria-hidden="true">15.</strong> Redirection Perfection</a></li><li class="chapter-item expanded "><a href="../example/full-code.html"><strong aria-hidden="true">16.</strong> Full Code</a></li></ol>
|
||||
</div>
|
||||
<div id="sidebar-resize-handle" class="sidebar-resize-handle"></div>
|
||||
</nav>
|
||||
|
||||
<div id="page-wrapper" class="page-wrapper">
|
||||
|
||||
<div class="page">
|
||||
<div id="menu-bar-hover-placeholder"></div>
|
||||
<div id="menu-bar" class="menu-bar sticky bordered">
|
||||
<div class="left-buttons">
|
||||
<button id="sidebar-toggle" class="icon-button" type="button" title="Toggle Table of Contents" aria-label="Toggle Table of Contents" aria-controls="sidebar">
|
||||
<i class="fa fa-bars"></i>
|
||||
</button>
|
||||
<button id="theme-toggle" class="icon-button" type="button" title="Change theme" aria-label="Change theme" aria-haspopup="true" aria-expanded="false" aria-controls="theme-list">
|
||||
<i class="fa fa-paint-brush"></i>
|
||||
</button>
|
||||
<ul id="theme-list" class="theme-popup" aria-label="Themes" role="menu">
|
||||
<li role="none"><button role="menuitem" class="theme" id="light">Light (default)</button></li>
|
||||
<li role="none"><button role="menuitem" class="theme" id="rust">Rust</button></li>
|
||||
<li role="none"><button role="menuitem" class="theme" id="coal">Coal</button></li>
|
||||
<li role="none"><button role="menuitem" class="theme" id="navy">Navy</button></li>
|
||||
<li role="none"><button role="menuitem" class="theme" id="ayu">Ayu</button></li>
|
||||
</ul>
|
||||
<button id="search-toggle" class="icon-button" type="button" title="Search. (Shortkey: s)" aria-label="Toggle Searchbar" aria-expanded="false" aria-keyshortcuts="S" aria-controls="searchbar">
|
||||
<i class="fa fa-search"></i>
|
||||
</button>
|
||||
</div>
|
||||
|
||||
<h1 class="menu-title">Dioxus Router</h1>
|
||||
|
||||
<div class="right-buttons">
|
||||
<a href="../print.html" title="Print this book" aria-label="Print this book">
|
||||
<i id="print-button" class="fa fa-print"></i>
|
||||
</a>
|
||||
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div id="search-wrapper" class="hidden">
|
||||
<form id="searchbar-outer" class="searchbar-outer">
|
||||
<input type="search" id="searchbar" name="searchbar" placeholder="Search this book ..." aria-controls="searchresults-outer" aria-describedby="searchresults-header">
|
||||
</form>
|
||||
<div id="searchresults-outer" class="searchresults-outer hidden">
|
||||
<div id="searchresults-header" class="searchresults-header"></div>
|
||||
<ul id="searchresults">
|
||||
</ul>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- Apply ARIA attributes after the sidebar and the sidebar toggle button are added to the DOM -->
|
||||
<script type="text/javascript">
|
||||
document.getElementById('sidebar-toggle').setAttribute('aria-expanded', sidebar === 'visible');
|
||||
document.getElementById('sidebar').setAttribute('aria-hidden', sidebar !== 'visible');
|
||||
Array.from(document.querySelectorAll('#sidebar a')).forEach(function(link) {
|
||||
link.setAttribute('tabIndex', sidebar === 'visible' ? 0 : -1);
|
||||
});
|
||||
</script>
|
||||
|
||||
<div id="content" class="content">
|
||||
<main>
|
||||
<h1 id="history-providers"><a class="header" href="#history-providers">History Providers</a></h1>
|
||||
<p>In order to provide the ability to traverse the navigation history, the router
|
||||
uses <a href="https://docs.rs/dioxus-router-core/latest/dioxus_router_core/history/trait.HistoryProvider.html"><code>HistoryProvider</code></a>s. Those implement the actual back-and-forth
|
||||
functionality.</p>
|
||||
<p>The router provides five <a href="https://docs.rs/dioxus-router-core/latest/dioxus_router_core/history/trait.HistoryProvider.html"><code>HistoryProvider</code></a>s, but you can also create your own.
|
||||
The five default implementations are:</p>
|
||||
<ul>
|
||||
<li>The <a href="https://docs.rs/dioxus-router-core/latest/dioxus_router_core/history/struct.MemoryHistory.html"><code>MemoryHistory</code></a> is a custom implementation that works in memory.</li>
|
||||
<li>The <a href="https://docs.rs/dioxus-router-core/latest/dioxus_router_core/history/struct.WebHistory.html"><code>WebHistory</code></a> integrates with the browsers URL.</li>
|
||||
<li>The <a href="https://docs.rs/dioxus-router-core/latest/dioxus_router_core/history/struct.WebHashHistory.html"><code>WebHashHistory</code></a> also integrates with the browser, but uses the fragment
|
||||
part of the URL.</li>
|
||||
</ul>
|
||||
<p>By default the router uses the <a href="https://docs.rs/dioxus-router-core/latest/dioxus_router_core/history/struct.MemoryHistory.html"><code>MemoryHistory</code></a>. It might be changed to use
|
||||
<a href="https://docs.rs/dioxus-router-core/latest/dioxus_router_core/history/struct.WebHistory.html"><code>WebHistory</code></a> when the <code>web</code> feature is active, but that is not guaranteed.</p>
|
||||
<p>You can override the default history:</p>
|
||||
<pre><pre class="playground"><code class="language-rust no_run edition2021">
|
||||
<span class="boring">#![allow(unused)]
|
||||
</span><span class="boring">fn main() {
|
||||
</span><span class="boring">// Hidden lines (like this one) make the documentation tests work.
|
||||
</span><span class="boring">extern crate dioxus;
|
||||
</span>use dioxus::prelude::*;
|
||||
<span class="boring">extern crate dioxus_router;
|
||||
</span>use dioxus_router::{prelude::*, history::WebHashHistory};
|
||||
|
||||
fn App(cx: Scope) -> Element {
|
||||
use_router(
|
||||
cx,
|
||||
&|| RouterConfiguration {
|
||||
history: Box::new(WebHashHistory::new(true)),
|
||||
..Default::default()
|
||||
},
|
||||
&|| Segment::empty()
|
||||
);
|
||||
|
||||
render! {
|
||||
Outlet { }
|
||||
}
|
||||
}
|
||||
<span class="boring">}
|
||||
</span></code></pre></pre>
|
||||
|
||||
</main>
|
||||
|
||||
<nav class="nav-wrapper" aria-label="Page navigation">
|
||||
<!-- Mobile navigation buttons -->
|
||||
<a rel="prev" href="../features/failures/redirection-limit.html" class="mobile-nav-chapters previous" title="Previous chapter" aria-label="Previous chapter" aria-keyshortcuts="Left">
|
||||
<i class="fa fa-angle-left"></i>
|
||||
</a>
|
||||
|
||||
<a rel="next" href="../features/history-buttons.html" class="mobile-nav-chapters next" title="Next chapter" aria-label="Next chapter" aria-keyshortcuts="Right">
|
||||
<i class="fa fa-angle-right"></i>
|
||||
</a>
|
||||
|
||||
<div style="clear: both"></div>
|
||||
</nav>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<nav class="nav-wide-wrapper" aria-label="Page navigation">
|
||||
<a rel="prev" href="../features/failures/redirection-limit.html" class="nav-chapters previous" title="Previous chapter" aria-label="Previous chapter" aria-keyshortcuts="Left">
|
||||
<i class="fa fa-angle-left"></i>
|
||||
</a>
|
||||
|
||||
<a rel="next" href="../features/history-buttons.html" class="nav-chapters next" title="Next chapter" aria-label="Next chapter" aria-keyshortcuts="Right">
|
||||
<i class="fa fa-angle-right"></i>
|
||||
</a>
|
||||
</nav>
|
||||
|
||||
</div>
|
||||
|
||||
|
||||
|
||||
|
||||
<script type="text/javascript">
|
||||
window.playground_copyable = true;
|
||||
</script>
|
||||
|
||||
|
||||
<script src="../elasticlunr.min.js" type="text/javascript" charset="utf-8"></script>
|
||||
<script src="../mark.min.js" type="text/javascript" charset="utf-8"></script>
|
||||
<script src="../searcher.js" type="text/javascript" charset="utf-8"></script>
|
||||
|
||||
<script src="../clipboard.min.js" type="text/javascript" charset="utf-8"></script>
|
||||
<script src="../highlight.js" type="text/javascript" charset="utf-8"></script>
|
||||
<script src="../book.js" type="text/javascript" charset="utf-8"></script>
|
||||
|
||||
<!-- Custom JS scripts -->
|
||||
|
||||
|
||||
</body>
|
||||
</html>
|
||||
@@ -0,0 +1,248 @@
|
||||
<!DOCTYPE HTML>
|
||||
<html lang="en" class="sidebar-visible no-js light">
|
||||
<head>
|
||||
<!-- Book generated using mdBook -->
|
||||
<meta charset="UTF-8">
|
||||
<title>Adding the Router to Your Application - Dioxus Router</title>
|
||||
|
||||
|
||||
<!-- Custom HTML head -->
|
||||
|
||||
<meta content="text/html; charset=utf-8" http-equiv="Content-Type">
|
||||
<meta name="description" content="">
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1">
|
||||
<meta name="theme-color" content="#ffffff" />
|
||||
|
||||
<link rel="icon" href="../favicon.svg">
|
||||
<link rel="shortcut icon" href="../favicon.png">
|
||||
<link rel="stylesheet" href="../css/variables.css">
|
||||
<link rel="stylesheet" href="../css/general.css">
|
||||
<link rel="stylesheet" href="../css/chrome.css">
|
||||
<link rel="stylesheet" href="../css/print.css" media="print">
|
||||
|
||||
<!-- Fonts -->
|
||||
<link rel="stylesheet" href="../FontAwesome/css/font-awesome.css">
|
||||
<link rel="stylesheet" href="../fonts/fonts.css">
|
||||
|
||||
<!-- Highlight.js Stylesheets -->
|
||||
<link rel="stylesheet" href="../highlight.css">
|
||||
<link rel="stylesheet" href="../tomorrow-night.css">
|
||||
<link rel="stylesheet" href="../ayu-highlight.css">
|
||||
|
||||
<!-- Custom theme stylesheets -->
|
||||
|
||||
</head>
|
||||
<body>
|
||||
<!-- Provide site root to javascript -->
|
||||
<script type="text/javascript">
|
||||
var path_to_root = "../";
|
||||
var default_theme = window.matchMedia("(prefers-color-scheme: dark)").matches ? "navy" : "light";
|
||||
</script>
|
||||
|
||||
<!-- Work around some values being stored in localStorage wrapped in quotes -->
|
||||
<script type="text/javascript">
|
||||
try {
|
||||
var theme = localStorage.getItem('mdbook-theme');
|
||||
var sidebar = localStorage.getItem('mdbook-sidebar');
|
||||
|
||||
if (theme.startsWith('"') && theme.endsWith('"')) {
|
||||
localStorage.setItem('mdbook-theme', theme.slice(1, theme.length - 1));
|
||||
}
|
||||
|
||||
if (sidebar.startsWith('"') && sidebar.endsWith('"')) {
|
||||
localStorage.setItem('mdbook-sidebar', sidebar.slice(1, sidebar.length - 1));
|
||||
}
|
||||
} catch (e) { }
|
||||
</script>
|
||||
|
||||
<!-- Set the theme before any content is loaded, prevents flash -->
|
||||
<script type="text/javascript">
|
||||
var theme;
|
||||
try { theme = localStorage.getItem('mdbook-theme'); } catch(e) { }
|
||||
if (theme === null || theme === undefined) { theme = default_theme; }
|
||||
var html = document.querySelector('html');
|
||||
html.classList.remove('no-js')
|
||||
html.classList.remove('light')
|
||||
html.classList.add(theme);
|
||||
html.classList.add('js');
|
||||
</script>
|
||||
|
||||
<!-- Hide / unhide sidebar before it is displayed -->
|
||||
<script type="text/javascript">
|
||||
var html = document.querySelector('html');
|
||||
var sidebar = 'hidden';
|
||||
if (document.body.clientWidth >= 1080) {
|
||||
try { sidebar = localStorage.getItem('mdbook-sidebar'); } catch(e) { }
|
||||
sidebar = sidebar || 'visible';
|
||||
}
|
||||
html.classList.remove('sidebar-visible');
|
||||
html.classList.add("sidebar-" + sidebar);
|
||||
</script>
|
||||
|
||||
<nav id="sidebar" class="sidebar" aria-label="Table of contents">
|
||||
<div class="sidebar-scrollbox">
|
||||
<ol class="chapter"><li class="chapter-item expanded affix "><a href="../index.html">Introduction</a></li><li class="chapter-item expanded affix "><li class="part-title">Features</li><li class="chapter-item expanded "><a href="../features/index.html" class="active"><strong aria-hidden="true">1.</strong> Adding the Router to Your Application</a></li><li class="chapter-item expanded "><a href="../features/routes/index.html"><strong aria-hidden="true">2.</strong> Defining Routes</a></li><li><ol class="section"><li class="chapter-item expanded "><a href="../features/routes/nested.html"><strong aria-hidden="true">2.1.</strong> Nested Routes</a></li><li class="chapter-item expanded "><a href="../features/routes/catch_all.html"><strong aria-hidden="true">2.2.</strong> Catch All Routes</a></li><li class="chapter-item expanded "><a href="../features/routes/matching.html"><strong aria-hidden="true">2.3.</strong> Matching Routes</a></li><li class="chapter-item expanded "><a href="../features/routes/fallback.html"><strong aria-hidden="true">2.4.</strong> Fallback Routes (404 page)</a></li><li class="chapter-item expanded "><a href="../features/routes/multiple-and-redirect.html"><strong aria-hidden="true">2.5.</strong> Multiple Components & Redirects</a></li></ol></li><li class="chapter-item expanded "><a href="../features/outlets.html"><strong aria-hidden="true">3.</strong> Outlets</a></li><li class="chapter-item expanded "><a href="../features/navigation/index.html"><strong aria-hidden="true">4.</strong> Links & Navigation</a></li><li><ol class="section"><li class="chapter-item expanded "><a href="../features/navigation/name.html"><strong aria-hidden="true">4.1.</strong> Named Navigation</a></li><li class="chapter-item expanded "><a href="../features/navigation/external.html"><strong aria-hidden="true">4.2.</strong> External Navigation</a></li><li class="chapter-item expanded "><a href="../features/navigation/programmatic.html"><strong aria-hidden="true">4.3.</strong> Programmatic Navigation</a></li></ol></li><li class="chapter-item expanded "><a href="../features/query.html"><strong aria-hidden="true">5.</strong> Query</a></li><li class="chapter-item expanded "><a href="../features/failures/index.html"><strong aria-hidden="true">6.</strong> Navigation Failures</a></li><li><ol class="section"><li class="chapter-item expanded "><a href="../features/failures/named.html"><strong aria-hidden="true">6.1.</strong> Named Navigation Failure</a></li><li class="chapter-item expanded "><a href="../features/failures/external.html"><strong aria-hidden="true">6.2.</strong> External Navigation Failure</a></li><li class="chapter-item expanded "><a href="../features/failures/redirection-limit.html"><strong aria-hidden="true">6.3.</strong> Redirection Limit Failure</a></li></ol></li><li class="chapter-item expanded "><a href="../features/history-providers.html"><strong aria-hidden="true">7.</strong> History Providers</a></li><li class="chapter-item expanded "><a href="../features/history-buttons.html"><strong aria-hidden="true">8.</strong> History Buttons</a></li><li class="chapter-item expanded "><a href="../features/sitemap-generation.html"><strong aria-hidden="true">9.</strong> Sitemap Generation</a></li><li class="chapter-item expanded "><a href="../features/routing-update-callback.html"><strong aria-hidden="true">10.</strong> Routing Update Callback</a></li><li class="chapter-item expanded affix "><li class="part-title">Example Project</li><li class="chapter-item expanded "><a href="../example/index.html"><strong aria-hidden="true">11.</strong> Overview</a></li><li class="chapter-item expanded "><a href="../example/first-route.html"><strong aria-hidden="true">12.</strong> Creating Our First Route</a></li><li class="chapter-item expanded "><a href="../example/building-a-nest.html"><strong aria-hidden="true">13.</strong> Building a Nest</a></li><li class="chapter-item expanded "><a href="../example/navigation-targets.html"><strong aria-hidden="true">14.</strong> Navigation Targets</a></li><li class="chapter-item expanded "><a href="../example/redirection-perfection.html"><strong aria-hidden="true">15.</strong> Redirection Perfection</a></li><li class="chapter-item expanded "><a href="../example/full-code.html"><strong aria-hidden="true">16.</strong> Full Code</a></li></ol>
|
||||
</div>
|
||||
<div id="sidebar-resize-handle" class="sidebar-resize-handle"></div>
|
||||
</nav>
|
||||
|
||||
<div id="page-wrapper" class="page-wrapper">
|
||||
|
||||
<div class="page">
|
||||
<div id="menu-bar-hover-placeholder"></div>
|
||||
<div id="menu-bar" class="menu-bar sticky bordered">
|
||||
<div class="left-buttons">
|
||||
<button id="sidebar-toggle" class="icon-button" type="button" title="Toggle Table of Contents" aria-label="Toggle Table of Contents" aria-controls="sidebar">
|
||||
<i class="fa fa-bars"></i>
|
||||
</button>
|
||||
<button id="theme-toggle" class="icon-button" type="button" title="Change theme" aria-label="Change theme" aria-haspopup="true" aria-expanded="false" aria-controls="theme-list">
|
||||
<i class="fa fa-paint-brush"></i>
|
||||
</button>
|
||||
<ul id="theme-list" class="theme-popup" aria-label="Themes" role="menu">
|
||||
<li role="none"><button role="menuitem" class="theme" id="light">Light (default)</button></li>
|
||||
<li role="none"><button role="menuitem" class="theme" id="rust">Rust</button></li>
|
||||
<li role="none"><button role="menuitem" class="theme" id="coal">Coal</button></li>
|
||||
<li role="none"><button role="menuitem" class="theme" id="navy">Navy</button></li>
|
||||
<li role="none"><button role="menuitem" class="theme" id="ayu">Ayu</button></li>
|
||||
</ul>
|
||||
<button id="search-toggle" class="icon-button" type="button" title="Search. (Shortkey: s)" aria-label="Toggle Searchbar" aria-expanded="false" aria-keyshortcuts="S" aria-controls="searchbar">
|
||||
<i class="fa fa-search"></i>
|
||||
</button>
|
||||
</div>
|
||||
|
||||
<h1 class="menu-title">Dioxus Router</h1>
|
||||
|
||||
<div class="right-buttons">
|
||||
<a href="../print.html" title="Print this book" aria-label="Print this book">
|
||||
<i id="print-button" class="fa fa-print"></i>
|
||||
</a>
|
||||
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div id="search-wrapper" class="hidden">
|
||||
<form id="searchbar-outer" class="searchbar-outer">
|
||||
<input type="search" id="searchbar" name="searchbar" placeholder="Search this book ..." aria-controls="searchresults-outer" aria-describedby="searchresults-header">
|
||||
</form>
|
||||
<div id="searchresults-outer" class="searchresults-outer hidden">
|
||||
<div id="searchresults-header" class="searchresults-header"></div>
|
||||
<ul id="searchresults">
|
||||
</ul>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- Apply ARIA attributes after the sidebar and the sidebar toggle button are added to the DOM -->
|
||||
<script type="text/javascript">
|
||||
document.getElementById('sidebar-toggle').setAttribute('aria-expanded', sidebar === 'visible');
|
||||
document.getElementById('sidebar').setAttribute('aria-hidden', sidebar !== 'visible');
|
||||
Array.from(document.querySelectorAll('#sidebar a')).forEach(function(link) {
|
||||
link.setAttribute('tabIndex', sidebar === 'visible' ? 0 : -1);
|
||||
});
|
||||
</script>
|
||||
|
||||
<div id="content" class="content">
|
||||
<main>
|
||||
<h1 id="adding-the-router-to-your-application"><a class="header" href="#adding-the-router-to-your-application">Adding the Router to Your Application</a></h1>
|
||||
<p>In this chapter we will learn how to add the router to our app. By it self, this
|
||||
is not very useful. However, it is a prerequisite for all the functionality
|
||||
described in the other chapters.</p>
|
||||
<blockquote>
|
||||
<p>Make sure you added the <code>dioxus-router</code> dependency as explained in the
|
||||
<a href="../index.html">introduction</a>.</p>
|
||||
</blockquote>
|
||||
<p>In most cases we want to add the router to the root component of our app. This
|
||||
way, we can ensure that we have access to all its functionality everywhere. We
|
||||
add it by using the <a href="https://docs.rs/dioxus-router/latest/dioxus_router/hooks/fn.use_router.html"><code>use_router</code></a> hook</p>
|
||||
<pre><pre class="playground"><code class="language-rust edition2021">
|
||||
<span class="boring">#![allow(unused)]
|
||||
</span><span class="boring">fn main() {
|
||||
</span><span class="boring">// Hidden lines (like this one) make the documentation tests work.
|
||||
</span><span class="boring">extern crate dioxus;
|
||||
</span>use dioxus::prelude::*;
|
||||
<span class="boring">extern crate dioxus_router;
|
||||
</span>use dioxus_router::prelude::*;
|
||||
<span class="boring">extern crate dioxus_ssr;
|
||||
</span>
|
||||
// This is the component we pass to dioxus when launching our app.
|
||||
fn App(cx: Scope) -> Element {
|
||||
// Here we add the router. All components inside `App` have access to its
|
||||
// functionality.
|
||||
let routes = use_router(
|
||||
cx,
|
||||
// The router can be configured with this parameter.
|
||||
&|| RouterConfiguration {
|
||||
<span class="boring"> synchronous: true,
|
||||
</span> ..Default::default()
|
||||
},
|
||||
// This tells the router about all the routes in our application. As we
|
||||
// don't have any, we pass an empty segment
|
||||
&|| Segment::empty()
|
||||
);
|
||||
|
||||
render! {
|
||||
h1 { "Our sites title" }
|
||||
|
||||
// The Outlet tells the Router where to render active content.
|
||||
Outlet { }
|
||||
}
|
||||
}
|
||||
<span class="boring">
|
||||
</span><span class="boring">let mut vdom = VirtualDom::new(App);
|
||||
</span><span class="boring">let _ = vdom.rebuild();
|
||||
</span><span class="boring">assert_eq!(
|
||||
</span><span class="boring"> dioxus_ssr::render(&vdom),
|
||||
</span><span class="boring"> "<h1>Our sites title</h1>"
|
||||
</span><span class="boring">);
|
||||
</span><span class="boring">}
|
||||
</span></code></pre></pre>
|
||||
|
||||
</main>
|
||||
|
||||
<nav class="nav-wrapper" aria-label="Page navigation">
|
||||
<!-- Mobile navigation buttons -->
|
||||
<a rel="prev" href="../index.html" class="mobile-nav-chapters previous" title="Previous chapter" aria-label="Previous chapter" aria-keyshortcuts="Left">
|
||||
<i class="fa fa-angle-left"></i>
|
||||
</a>
|
||||
|
||||
<a rel="next" href="../features/routes/index.html" class="mobile-nav-chapters next" title="Next chapter" aria-label="Next chapter" aria-keyshortcuts="Right">
|
||||
<i class="fa fa-angle-right"></i>
|
||||
</a>
|
||||
|
||||
<div style="clear: both"></div>
|
||||
</nav>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<nav class="nav-wide-wrapper" aria-label="Page navigation">
|
||||
<a rel="prev" href="../index.html" class="nav-chapters previous" title="Previous chapter" aria-label="Previous chapter" aria-keyshortcuts="Left">
|
||||
<i class="fa fa-angle-left"></i>
|
||||
</a>
|
||||
|
||||
<a rel="next" href="../features/routes/index.html" class="nav-chapters next" title="Next chapter" aria-label="Next chapter" aria-keyshortcuts="Right">
|
||||
<i class="fa fa-angle-right"></i>
|
||||
</a>
|
||||
</nav>
|
||||
|
||||
</div>
|
||||
|
||||
|
||||
|
||||
|
||||
<script type="text/javascript">
|
||||
window.playground_copyable = true;
|
||||
</script>
|
||||
|
||||
|
||||
<script src="../elasticlunr.min.js" type="text/javascript" charset="utf-8"></script>
|
||||
<script src="../mark.min.js" type="text/javascript" charset="utf-8"></script>
|
||||
<script src="../searcher.js" type="text/javascript" charset="utf-8"></script>
|
||||
|
||||
<script src="../clipboard.min.js" type="text/javascript" charset="utf-8"></script>
|
||||
<script src="../highlight.js" type="text/javascript" charset="utf-8"></script>
|
||||
<script src="../book.js" type="text/javascript" charset="utf-8"></script>
|
||||
|
||||
<!-- Custom JS scripts -->
|
||||
|
||||
|
||||
</body>
|
||||
</html>
|
||||
@@ -0,0 +1,263 @@
|
||||
<!DOCTYPE HTML>
|
||||
<html lang="en" class="sidebar-visible no-js light">
|
||||
<head>
|
||||
<!-- Book generated using mdBook -->
|
||||
<meta charset="UTF-8">
|
||||
<title>External Navigation - Dioxus Router</title>
|
||||
|
||||
|
||||
<!-- Custom HTML head -->
|
||||
|
||||
<meta content="text/html; charset=utf-8" http-equiv="Content-Type">
|
||||
<meta name="description" content="">
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1">
|
||||
<meta name="theme-color" content="#ffffff" />
|
||||
|
||||
<link rel="icon" href="../../favicon.svg">
|
||||
<link rel="shortcut icon" href="../../favicon.png">
|
||||
<link rel="stylesheet" href="../../css/variables.css">
|
||||
<link rel="stylesheet" href="../../css/general.css">
|
||||
<link rel="stylesheet" href="../../css/chrome.css">
|
||||
<link rel="stylesheet" href="../../css/print.css" media="print">
|
||||
|
||||
<!-- Fonts -->
|
||||
<link rel="stylesheet" href="../../FontAwesome/css/font-awesome.css">
|
||||
<link rel="stylesheet" href="../../fonts/fonts.css">
|
||||
|
||||
<!-- Highlight.js Stylesheets -->
|
||||
<link rel="stylesheet" href="../../highlight.css">
|
||||
<link rel="stylesheet" href="../../tomorrow-night.css">
|
||||
<link rel="stylesheet" href="../../ayu-highlight.css">
|
||||
|
||||
<!-- Custom theme stylesheets -->
|
||||
|
||||
</head>
|
||||
<body>
|
||||
<!-- Provide site root to javascript -->
|
||||
<script type="text/javascript">
|
||||
var path_to_root = "../../";
|
||||
var default_theme = window.matchMedia("(prefers-color-scheme: dark)").matches ? "navy" : "light";
|
||||
</script>
|
||||
|
||||
<!-- Work around some values being stored in localStorage wrapped in quotes -->
|
||||
<script type="text/javascript">
|
||||
try {
|
||||
var theme = localStorage.getItem('mdbook-theme');
|
||||
var sidebar = localStorage.getItem('mdbook-sidebar');
|
||||
|
||||
if (theme.startsWith('"') && theme.endsWith('"')) {
|
||||
localStorage.setItem('mdbook-theme', theme.slice(1, theme.length - 1));
|
||||
}
|
||||
|
||||
if (sidebar.startsWith('"') && sidebar.endsWith('"')) {
|
||||
localStorage.setItem('mdbook-sidebar', sidebar.slice(1, sidebar.length - 1));
|
||||
}
|
||||
} catch (e) { }
|
||||
</script>
|
||||
|
||||
<!-- Set the theme before any content is loaded, prevents flash -->
|
||||
<script type="text/javascript">
|
||||
var theme;
|
||||
try { theme = localStorage.getItem('mdbook-theme'); } catch(e) { }
|
||||
if (theme === null || theme === undefined) { theme = default_theme; }
|
||||
var html = document.querySelector('html');
|
||||
html.classList.remove('no-js')
|
||||
html.classList.remove('light')
|
||||
html.classList.add(theme);
|
||||
html.classList.add('js');
|
||||
</script>
|
||||
|
||||
<!-- Hide / unhide sidebar before it is displayed -->
|
||||
<script type="text/javascript">
|
||||
var html = document.querySelector('html');
|
||||
var sidebar = 'hidden';
|
||||
if (document.body.clientWidth >= 1080) {
|
||||
try { sidebar = localStorage.getItem('mdbook-sidebar'); } catch(e) { }
|
||||
sidebar = sidebar || 'visible';
|
||||
}
|
||||
html.classList.remove('sidebar-visible');
|
||||
html.classList.add("sidebar-" + sidebar);
|
||||
</script>
|
||||
|
||||
<nav id="sidebar" class="sidebar" aria-label="Table of contents">
|
||||
<div class="sidebar-scrollbox">
|
||||
<ol class="chapter"><li class="chapter-item expanded affix "><a href="../../index.html">Introduction</a></li><li class="chapter-item expanded affix "><li class="part-title">Features</li><li class="chapter-item expanded "><a href="../../features/index.html"><strong aria-hidden="true">1.</strong> Adding the Router to Your Application</a></li><li class="chapter-item expanded "><a href="../../features/routes/index.html"><strong aria-hidden="true">2.</strong> Defining Routes</a></li><li><ol class="section"><li class="chapter-item expanded "><a href="../../features/routes/nested.html"><strong aria-hidden="true">2.1.</strong> Nested Routes</a></li><li class="chapter-item expanded "><a href="../../features/routes/catch_all.html"><strong aria-hidden="true">2.2.</strong> Catch All Routes</a></li><li class="chapter-item expanded "><a href="../../features/routes/matching.html"><strong aria-hidden="true">2.3.</strong> Matching Routes</a></li><li class="chapter-item expanded "><a href="../../features/routes/fallback.html"><strong aria-hidden="true">2.4.</strong> Fallback Routes (404 page)</a></li><li class="chapter-item expanded "><a href="../../features/routes/multiple-and-redirect.html"><strong aria-hidden="true">2.5.</strong> Multiple Components & Redirects</a></li></ol></li><li class="chapter-item expanded "><a href="../../features/outlets.html"><strong aria-hidden="true">3.</strong> Outlets</a></li><li class="chapter-item expanded "><a href="../../features/navigation/index.html"><strong aria-hidden="true">4.</strong> Links & Navigation</a></li><li><ol class="section"><li class="chapter-item expanded "><a href="../../features/navigation/name.html"><strong aria-hidden="true">4.1.</strong> Named Navigation</a></li><li class="chapter-item expanded "><a href="../../features/navigation/external.html" class="active"><strong aria-hidden="true">4.2.</strong> External Navigation</a></li><li class="chapter-item expanded "><a href="../../features/navigation/programmatic.html"><strong aria-hidden="true">4.3.</strong> Programmatic Navigation</a></li></ol></li><li class="chapter-item expanded "><a href="../../features/query.html"><strong aria-hidden="true">5.</strong> Query</a></li><li class="chapter-item expanded "><a href="../../features/failures/index.html"><strong aria-hidden="true">6.</strong> Navigation Failures</a></li><li><ol class="section"><li class="chapter-item expanded "><a href="../../features/failures/named.html"><strong aria-hidden="true">6.1.</strong> Named Navigation Failure</a></li><li class="chapter-item expanded "><a href="../../features/failures/external.html"><strong aria-hidden="true">6.2.</strong> External Navigation Failure</a></li><li class="chapter-item expanded "><a href="../../features/failures/redirection-limit.html"><strong aria-hidden="true">6.3.</strong> Redirection Limit Failure</a></li></ol></li><li class="chapter-item expanded "><a href="../../features/history-providers.html"><strong aria-hidden="true">7.</strong> History Providers</a></li><li class="chapter-item expanded "><a href="../../features/history-buttons.html"><strong aria-hidden="true">8.</strong> History Buttons</a></li><li class="chapter-item expanded "><a href="../../features/sitemap-generation.html"><strong aria-hidden="true">9.</strong> Sitemap Generation</a></li><li class="chapter-item expanded "><a href="../../features/routing-update-callback.html"><strong aria-hidden="true">10.</strong> Routing Update Callback</a></li><li class="chapter-item expanded affix "><li class="part-title">Example Project</li><li class="chapter-item expanded "><a href="../../example/index.html"><strong aria-hidden="true">11.</strong> Overview</a></li><li class="chapter-item expanded "><a href="../../example/first-route.html"><strong aria-hidden="true">12.</strong> Creating Our First Route</a></li><li class="chapter-item expanded "><a href="../../example/building-a-nest.html"><strong aria-hidden="true">13.</strong> Building a Nest</a></li><li class="chapter-item expanded "><a href="../../example/navigation-targets.html"><strong aria-hidden="true">14.</strong> Navigation Targets</a></li><li class="chapter-item expanded "><a href="../../example/redirection-perfection.html"><strong aria-hidden="true">15.</strong> Redirection Perfection</a></li><li class="chapter-item expanded "><a href="../../example/full-code.html"><strong aria-hidden="true">16.</strong> Full Code</a></li></ol>
|
||||
</div>
|
||||
<div id="sidebar-resize-handle" class="sidebar-resize-handle"></div>
|
||||
</nav>
|
||||
|
||||
<div id="page-wrapper" class="page-wrapper">
|
||||
|
||||
<div class="page">
|
||||
<div id="menu-bar-hover-placeholder"></div>
|
||||
<div id="menu-bar" class="menu-bar sticky bordered">
|
||||
<div class="left-buttons">
|
||||
<button id="sidebar-toggle" class="icon-button" type="button" title="Toggle Table of Contents" aria-label="Toggle Table of Contents" aria-controls="sidebar">
|
||||
<i class="fa fa-bars"></i>
|
||||
</button>
|
||||
<button id="theme-toggle" class="icon-button" type="button" title="Change theme" aria-label="Change theme" aria-haspopup="true" aria-expanded="false" aria-controls="theme-list">
|
||||
<i class="fa fa-paint-brush"></i>
|
||||
</button>
|
||||
<ul id="theme-list" class="theme-popup" aria-label="Themes" role="menu">
|
||||
<li role="none"><button role="menuitem" class="theme" id="light">Light (default)</button></li>
|
||||
<li role="none"><button role="menuitem" class="theme" id="rust">Rust</button></li>
|
||||
<li role="none"><button role="menuitem" class="theme" id="coal">Coal</button></li>
|
||||
<li role="none"><button role="menuitem" class="theme" id="navy">Navy</button></li>
|
||||
<li role="none"><button role="menuitem" class="theme" id="ayu">Ayu</button></li>
|
||||
</ul>
|
||||
<button id="search-toggle" class="icon-button" type="button" title="Search. (Shortkey: s)" aria-label="Toggle Searchbar" aria-expanded="false" aria-keyshortcuts="S" aria-controls="searchbar">
|
||||
<i class="fa fa-search"></i>
|
||||
</button>
|
||||
</div>
|
||||
|
||||
<h1 class="menu-title">Dioxus Router</h1>
|
||||
|
||||
<div class="right-buttons">
|
||||
<a href="../../print.html" title="Print this book" aria-label="Print this book">
|
||||
<i id="print-button" class="fa fa-print"></i>
|
||||
</a>
|
||||
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div id="search-wrapper" class="hidden">
|
||||
<form id="searchbar-outer" class="searchbar-outer">
|
||||
<input type="search" id="searchbar" name="searchbar" placeholder="Search this book ..." aria-controls="searchresults-outer" aria-describedby="searchresults-header">
|
||||
</form>
|
||||
<div id="searchresults-outer" class="searchresults-outer hidden">
|
||||
<div id="searchresults-header" class="searchresults-header"></div>
|
||||
<ul id="searchresults">
|
||||
</ul>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- Apply ARIA attributes after the sidebar and the sidebar toggle button are added to the DOM -->
|
||||
<script type="text/javascript">
|
||||
document.getElementById('sidebar-toggle').setAttribute('aria-expanded', sidebar === 'visible');
|
||||
document.getElementById('sidebar').setAttribute('aria-hidden', sidebar !== 'visible');
|
||||
Array.from(document.querySelectorAll('#sidebar a')).forEach(function(link) {
|
||||
link.setAttribute('tabIndex', sidebar === 'visible' ? 0 : -1);
|
||||
});
|
||||
</script>
|
||||
|
||||
<div id="content" class="content">
|
||||
<main>
|
||||
<h1 id="external-navigation"><a class="header" href="#external-navigation">External Navigation</a></h1>
|
||||
<p>In modern apps, and especially on the web, we often want to send our users to an
|
||||
other website. <a href="https://docs.rs/dioxus-router-core/latest/dioxus_router_core/navigation/enum.NavigationTarget.html#variant.External"><code>External</code></a> allows us to make a <a href="https://docs.rs/dioxus-router/latest/dioxus_router/components/fn.Link.html"><code>Link</code></a> navigate to an
|
||||
external page.</p>
|
||||
<blockquote>
|
||||
<p>You might already now about
|
||||
<a href="../failures/external.html">external navigation failures</a>. The <a href="https://docs.rs/dioxus-router/latest/dioxus_router/components/fn.Link.html"><code>Link</code></a>
|
||||
component doesn't rely on the code path where those originate. Therefore a
|
||||
<a href="https://docs.rs/dioxus-router/latest/dioxus_router/components/fn.Link.html"><code>Link</code></a> will never trigger an external navigation failure.</p>
|
||||
</blockquote>
|
||||
<p>Strictly speaking, a <a href="https://docs.rs/dioxus-router/latest/dioxus_router/components/fn.Link.html"><code>Link</code></a> is not necessary for navigating to external
|
||||
targets, since by definition the router cannot handle them internally. However,
|
||||
the <a href="https://docs.rs/dioxus-router/latest/dioxus_router/components/fn.Link.html"><code>Link</code></a> component is more convenient to use, as it automatically sets the
|
||||
<code>rel</code> attribute for the link, when the target is external.</p>
|
||||
<h2 id="code-example"><a class="header" href="#code-example">Code Example</a></h2>
|
||||
<pre><pre class="playground"><code class="language-rust edition2021">
|
||||
<span class="boring">#![allow(unused)]
|
||||
</span><span class="boring">fn main() {
|
||||
</span><span class="boring">// Hidden lines (like this one) make the documentation tests work.
|
||||
</span><span class="boring">extern crate dioxus;
|
||||
</span>use dioxus::prelude::*;
|
||||
<span class="boring">extern crate dioxus_router;
|
||||
</span>use dioxus_router::prelude::*;
|
||||
<span class="boring">extern crate dioxus_ssr;
|
||||
</span>
|
||||
fn App(cx: Scope) -> Element {
|
||||
use_router(
|
||||
cx,
|
||||
&|| RouterConfiguration {
|
||||
<span class="boring"> synchronous: true,
|
||||
</span> ..Default::default()
|
||||
},
|
||||
&|| Segment::empty()
|
||||
);
|
||||
|
||||
render! {
|
||||
// links need to be inside a router, even if they navigate to an
|
||||
// external page
|
||||
Link {
|
||||
target: NavigationTarget::External("https://dioxuslabs.com/".into()),
|
||||
"Go to the dioxus home page"
|
||||
}
|
||||
Link {
|
||||
target: "https://dioxuslabs.com/", // short form
|
||||
"Go to the dioxus home page 2"
|
||||
}
|
||||
}
|
||||
}
|
||||
<span class="boring">
|
||||
</span><span class="boring">let mut vdom = VirtualDom::new(App);
|
||||
</span><span class="boring">vdom.rebuild();
|
||||
</span><span class="boring">let html = dioxus_ssr::render(&vdom);
|
||||
</span><span class="boring">assert_eq!(
|
||||
</span><span class="boring"> html,
|
||||
</span><span class="boring"> format!(
|
||||
</span><span class="boring"> "<a {attr1} {attr2}>{text}</a><a {attr1} {attr2}>{text} 2</a>",
|
||||
</span><span class="boring"> attr1 = r#"href="https://dioxuslabs.com/" dioxus-prevent-default="""#,
|
||||
</span><span class="boring"> attr2 = r#"class="" id="" rel="noopener noreferrer" target="""#,
|
||||
</span><span class="boring"> text = "Go to the dioxus home page"
|
||||
</span><span class="boring"> )
|
||||
</span><span class="boring">)
|
||||
</span><span class="boring">}
|
||||
</span></code></pre></pre>
|
||||
<blockquote>
|
||||
<p>Note that the short form for an [<code>ExternalTarget</code>] looks like the short form
|
||||
for an [<code>InternalTarget</code>]. The router will create an [<code>ExternalTarget</code>] only
|
||||
if the URL is absolute.</p>
|
||||
</blockquote>
|
||||
|
||||
</main>
|
||||
|
||||
<nav class="nav-wrapper" aria-label="Page navigation">
|
||||
<!-- Mobile navigation buttons -->
|
||||
<a rel="prev" href="../../features/navigation/name.html" class="mobile-nav-chapters previous" title="Previous chapter" aria-label="Previous chapter" aria-keyshortcuts="Left">
|
||||
<i class="fa fa-angle-left"></i>
|
||||
</a>
|
||||
|
||||
<a rel="next" href="../../features/navigation/programmatic.html" class="mobile-nav-chapters next" title="Next chapter" aria-label="Next chapter" aria-keyshortcuts="Right">
|
||||
<i class="fa fa-angle-right"></i>
|
||||
</a>
|
||||
|
||||
<div style="clear: both"></div>
|
||||
</nav>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<nav class="nav-wide-wrapper" aria-label="Page navigation">
|
||||
<a rel="prev" href="../../features/navigation/name.html" class="nav-chapters previous" title="Previous chapter" aria-label="Previous chapter" aria-keyshortcuts="Left">
|
||||
<i class="fa fa-angle-left"></i>
|
||||
</a>
|
||||
|
||||
<a rel="next" href="../../features/navigation/programmatic.html" class="nav-chapters next" title="Next chapter" aria-label="Next chapter" aria-keyshortcuts="Right">
|
||||
<i class="fa fa-angle-right"></i>
|
||||
</a>
|
||||
</nav>
|
||||
|
||||
</div>
|
||||
|
||||
|
||||
|
||||
|
||||
<script type="text/javascript">
|
||||
window.playground_copyable = true;
|
||||
</script>
|
||||
|
||||
|
||||
<script src="../../elasticlunr.min.js" type="text/javascript" charset="utf-8"></script>
|
||||
<script src="../../mark.min.js" type="text/javascript" charset="utf-8"></script>
|
||||
<script src="../../searcher.js" type="text/javascript" charset="utf-8"></script>
|
||||
|
||||
<script src="../../clipboard.min.js" type="text/javascript" charset="utf-8"></script>
|
||||
<script src="../../highlight.js" type="text/javascript" charset="utf-8"></script>
|
||||
<script src="../../book.js" type="text/javascript" charset="utf-8"></script>
|
||||
|
||||
<!-- Custom JS scripts -->
|
||||
|
||||
|
||||
</body>
|
||||
</html>
|
||||
@@ -0,0 +1,248 @@
|
||||
<!DOCTYPE HTML>
|
||||
<html lang="en" class="sidebar-visible no-js light">
|
||||
<head>
|
||||
<!-- Book generated using mdBook -->
|
||||
<meta charset="UTF-8">
|
||||
<title>Links & Navigation - Dioxus Router</title>
|
||||
|
||||
|
||||
<!-- Custom HTML head -->
|
||||
|
||||
<meta content="text/html; charset=utf-8" http-equiv="Content-Type">
|
||||
<meta name="description" content="">
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1">
|
||||
<meta name="theme-color" content="#ffffff" />
|
||||
|
||||
<link rel="icon" href="../../favicon.svg">
|
||||
<link rel="shortcut icon" href="../../favicon.png">
|
||||
<link rel="stylesheet" href="../../css/variables.css">
|
||||
<link rel="stylesheet" href="../../css/general.css">
|
||||
<link rel="stylesheet" href="../../css/chrome.css">
|
||||
<link rel="stylesheet" href="../../css/print.css" media="print">
|
||||
|
||||
<!-- Fonts -->
|
||||
<link rel="stylesheet" href="../../FontAwesome/css/font-awesome.css">
|
||||
<link rel="stylesheet" href="../../fonts/fonts.css">
|
||||
|
||||
<!-- Highlight.js Stylesheets -->
|
||||
<link rel="stylesheet" href="../../highlight.css">
|
||||
<link rel="stylesheet" href="../../tomorrow-night.css">
|
||||
<link rel="stylesheet" href="../../ayu-highlight.css">
|
||||
|
||||
<!-- Custom theme stylesheets -->
|
||||
|
||||
</head>
|
||||
<body>
|
||||
<!-- Provide site root to javascript -->
|
||||
<script type="text/javascript">
|
||||
var path_to_root = "../../";
|
||||
var default_theme = window.matchMedia("(prefers-color-scheme: dark)").matches ? "navy" : "light";
|
||||
</script>
|
||||
|
||||
<!-- Work around some values being stored in localStorage wrapped in quotes -->
|
||||
<script type="text/javascript">
|
||||
try {
|
||||
var theme = localStorage.getItem('mdbook-theme');
|
||||
var sidebar = localStorage.getItem('mdbook-sidebar');
|
||||
|
||||
if (theme.startsWith('"') && theme.endsWith('"')) {
|
||||
localStorage.setItem('mdbook-theme', theme.slice(1, theme.length - 1));
|
||||
}
|
||||
|
||||
if (sidebar.startsWith('"') && sidebar.endsWith('"')) {
|
||||
localStorage.setItem('mdbook-sidebar', sidebar.slice(1, sidebar.length - 1));
|
||||
}
|
||||
} catch (e) { }
|
||||
</script>
|
||||
|
||||
<!-- Set the theme before any content is loaded, prevents flash -->
|
||||
<script type="text/javascript">
|
||||
var theme;
|
||||
try { theme = localStorage.getItem('mdbook-theme'); } catch(e) { }
|
||||
if (theme === null || theme === undefined) { theme = default_theme; }
|
||||
var html = document.querySelector('html');
|
||||
html.classList.remove('no-js')
|
||||
html.classList.remove('light')
|
||||
html.classList.add(theme);
|
||||
html.classList.add('js');
|
||||
</script>
|
||||
|
||||
<!-- Hide / unhide sidebar before it is displayed -->
|
||||
<script type="text/javascript">
|
||||
var html = document.querySelector('html');
|
||||
var sidebar = 'hidden';
|
||||
if (document.body.clientWidth >= 1080) {
|
||||
try { sidebar = localStorage.getItem('mdbook-sidebar'); } catch(e) { }
|
||||
sidebar = sidebar || 'visible';
|
||||
}
|
||||
html.classList.remove('sidebar-visible');
|
||||
html.classList.add("sidebar-" + sidebar);
|
||||
</script>
|
||||
|
||||
<nav id="sidebar" class="sidebar" aria-label="Table of contents">
|
||||
<div class="sidebar-scrollbox">
|
||||
<ol class="chapter"><li class="chapter-item expanded affix "><a href="../../index.html">Introduction</a></li><li class="chapter-item expanded affix "><li class="part-title">Features</li><li class="chapter-item expanded "><a href="../../features/index.html"><strong aria-hidden="true">1.</strong> Adding the Router to Your Application</a></li><li class="chapter-item expanded "><a href="../../features/routes/index.html"><strong aria-hidden="true">2.</strong> Defining Routes</a></li><li><ol class="section"><li class="chapter-item expanded "><a href="../../features/routes/nested.html"><strong aria-hidden="true">2.1.</strong> Nested Routes</a></li><li class="chapter-item expanded "><a href="../../features/routes/catch_all.html"><strong aria-hidden="true">2.2.</strong> Catch All Routes</a></li><li class="chapter-item expanded "><a href="../../features/routes/matching.html"><strong aria-hidden="true">2.3.</strong> Matching Routes</a></li><li class="chapter-item expanded "><a href="../../features/routes/fallback.html"><strong aria-hidden="true">2.4.</strong> Fallback Routes (404 page)</a></li><li class="chapter-item expanded "><a href="../../features/routes/multiple-and-redirect.html"><strong aria-hidden="true">2.5.</strong> Multiple Components & Redirects</a></li></ol></li><li class="chapter-item expanded "><a href="../../features/outlets.html"><strong aria-hidden="true">3.</strong> Outlets</a></li><li class="chapter-item expanded "><a href="../../features/navigation/index.html" class="active"><strong aria-hidden="true">4.</strong> Links & Navigation</a></li><li><ol class="section"><li class="chapter-item expanded "><a href="../../features/navigation/name.html"><strong aria-hidden="true">4.1.</strong> Named Navigation</a></li><li class="chapter-item expanded "><a href="../../features/navigation/external.html"><strong aria-hidden="true">4.2.</strong> External Navigation</a></li><li class="chapter-item expanded "><a href="../../features/navigation/programmatic.html"><strong aria-hidden="true">4.3.</strong> Programmatic Navigation</a></li></ol></li><li class="chapter-item expanded "><a href="../../features/query.html"><strong aria-hidden="true">5.</strong> Query</a></li><li class="chapter-item expanded "><a href="../../features/failures/index.html"><strong aria-hidden="true">6.</strong> Navigation Failures</a></li><li><ol class="section"><li class="chapter-item expanded "><a href="../../features/failures/named.html"><strong aria-hidden="true">6.1.</strong> Named Navigation Failure</a></li><li class="chapter-item expanded "><a href="../../features/failures/external.html"><strong aria-hidden="true">6.2.</strong> External Navigation Failure</a></li><li class="chapter-item expanded "><a href="../../features/failures/redirection-limit.html"><strong aria-hidden="true">6.3.</strong> Redirection Limit Failure</a></li></ol></li><li class="chapter-item expanded "><a href="../../features/history-providers.html"><strong aria-hidden="true">7.</strong> History Providers</a></li><li class="chapter-item expanded "><a href="../../features/history-buttons.html"><strong aria-hidden="true">8.</strong> History Buttons</a></li><li class="chapter-item expanded "><a href="../../features/sitemap-generation.html"><strong aria-hidden="true">9.</strong> Sitemap Generation</a></li><li class="chapter-item expanded "><a href="../../features/routing-update-callback.html"><strong aria-hidden="true">10.</strong> Routing Update Callback</a></li><li class="chapter-item expanded affix "><li class="part-title">Example Project</li><li class="chapter-item expanded "><a href="../../example/index.html"><strong aria-hidden="true">11.</strong> Overview</a></li><li class="chapter-item expanded "><a href="../../example/first-route.html"><strong aria-hidden="true">12.</strong> Creating Our First Route</a></li><li class="chapter-item expanded "><a href="../../example/building-a-nest.html"><strong aria-hidden="true">13.</strong> Building a Nest</a></li><li class="chapter-item expanded "><a href="../../example/navigation-targets.html"><strong aria-hidden="true">14.</strong> Navigation Targets</a></li><li class="chapter-item expanded "><a href="../../example/redirection-perfection.html"><strong aria-hidden="true">15.</strong> Redirection Perfection</a></li><li class="chapter-item expanded "><a href="../../example/full-code.html"><strong aria-hidden="true">16.</strong> Full Code</a></li></ol>
|
||||
</div>
|
||||
<div id="sidebar-resize-handle" class="sidebar-resize-handle"></div>
|
||||
</nav>
|
||||
|
||||
<div id="page-wrapper" class="page-wrapper">
|
||||
|
||||
<div class="page">
|
||||
<div id="menu-bar-hover-placeholder"></div>
|
||||
<div id="menu-bar" class="menu-bar sticky bordered">
|
||||
<div class="left-buttons">
|
||||
<button id="sidebar-toggle" class="icon-button" type="button" title="Toggle Table of Contents" aria-label="Toggle Table of Contents" aria-controls="sidebar">
|
||||
<i class="fa fa-bars"></i>
|
||||
</button>
|
||||
<button id="theme-toggle" class="icon-button" type="button" title="Change theme" aria-label="Change theme" aria-haspopup="true" aria-expanded="false" aria-controls="theme-list">
|
||||
<i class="fa fa-paint-brush"></i>
|
||||
</button>
|
||||
<ul id="theme-list" class="theme-popup" aria-label="Themes" role="menu">
|
||||
<li role="none"><button role="menuitem" class="theme" id="light">Light (default)</button></li>
|
||||
<li role="none"><button role="menuitem" class="theme" id="rust">Rust</button></li>
|
||||
<li role="none"><button role="menuitem" class="theme" id="coal">Coal</button></li>
|
||||
<li role="none"><button role="menuitem" class="theme" id="navy">Navy</button></li>
|
||||
<li role="none"><button role="menuitem" class="theme" id="ayu">Ayu</button></li>
|
||||
</ul>
|
||||
<button id="search-toggle" class="icon-button" type="button" title="Search. (Shortkey: s)" aria-label="Toggle Searchbar" aria-expanded="false" aria-keyshortcuts="S" aria-controls="searchbar">
|
||||
<i class="fa fa-search"></i>
|
||||
</button>
|
||||
</div>
|
||||
|
||||
<h1 class="menu-title">Dioxus Router</h1>
|
||||
|
||||
<div class="right-buttons">
|
||||
<a href="../../print.html" title="Print this book" aria-label="Print this book">
|
||||
<i id="print-button" class="fa fa-print"></i>
|
||||
</a>
|
||||
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div id="search-wrapper" class="hidden">
|
||||
<form id="searchbar-outer" class="searchbar-outer">
|
||||
<input type="search" id="searchbar" name="searchbar" placeholder="Search this book ..." aria-controls="searchresults-outer" aria-describedby="searchresults-header">
|
||||
</form>
|
||||
<div id="searchresults-outer" class="searchresults-outer hidden">
|
||||
<div id="searchresults-header" class="searchresults-header"></div>
|
||||
<ul id="searchresults">
|
||||
</ul>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- Apply ARIA attributes after the sidebar and the sidebar toggle button are added to the DOM -->
|
||||
<script type="text/javascript">
|
||||
document.getElementById('sidebar-toggle').setAttribute('aria-expanded', sidebar === 'visible');
|
||||
document.getElementById('sidebar').setAttribute('aria-hidden', sidebar !== 'visible');
|
||||
Array.from(document.querySelectorAll('#sidebar a')).forEach(function(link) {
|
||||
link.setAttribute('tabIndex', sidebar === 'visible' ? 0 : -1);
|
||||
});
|
||||
</script>
|
||||
|
||||
<div id="content" class="content">
|
||||
<main>
|
||||
<h1 id="links--navigation"><a class="header" href="#links--navigation">Links & Navigation</a></h1>
|
||||
<p>When we split our app into pages, we need to provide our users with a way to
|
||||
navigate between them. On regular web pages we'd use an anchor element for that,
|
||||
like this:</p>
|
||||
<pre><code class="language-html"><a href="/other">Link to an other page</a>
|
||||
</code></pre>
|
||||
<p>However, we cannot do that when using the router for two reasons:</p>
|
||||
<ol>
|
||||
<li>Anchor tags make the browser load a new page from the server. This takes a
|
||||
lot of time, and it is much faster to let the router handle the navigation
|
||||
client-side.</li>
|
||||
<li>Navigation using anchor tags only works when the app is running inside a
|
||||
browser. This means we cannot use them inside apps using Dioxus Desktop.</li>
|
||||
</ol>
|
||||
<p>To solve these problems, the router provides us with a <a href="https://docs.rs/dioxus-router/latest/dioxus_router/components/fn.Link.html"><code>Link</code></a> component we can
|
||||
use like this:</p>
|
||||
<pre><pre class="playground"><code class="language-rust no_run edition2021">
|
||||
<span class="boring">#![allow(unused)]
|
||||
</span><span class="boring">fn main() {
|
||||
</span><span class="boring">// Hidden lines (like this one) make the documentation tests work.
|
||||
</span><span class="boring">extern crate dioxus;
|
||||
</span><span class="boring">use dioxus::prelude::*;
|
||||
</span><span class="boring">extern crate dioxus_router;
|
||||
</span><span class="boring">use dioxus_router::prelude::*;
|
||||
</span>fn SomeComponent(cx: Scope) -> Element {
|
||||
render! {
|
||||
Link {
|
||||
target: NavigationTarget::Internal(String::from("/some/path")),
|
||||
"Link text"
|
||||
}
|
||||
Link {
|
||||
target: "/some/path", // short form
|
||||
"Other link text"
|
||||
}
|
||||
}
|
||||
}
|
||||
<span class="boring">}
|
||||
</span></code></pre></pre>
|
||||
<p>The <code>target</code> in the example above is similar to the <code>href</code> of a regular anchor
|
||||
element. However, it tells the router more about what kind of navigation it
|
||||
should perform:</p>
|
||||
<ul>
|
||||
<li>The example uses <a href="https://docs.rs/dioxus-router-core/latest/dioxus_router_core/navigation/enum.NavigationTarget.html#variant.Internal"><code>Internal</code></a>. We give it an arbitrary path that will be
|
||||
merged with the current URL.</li>
|
||||
<li><a href="https://docs.rs/dioxus-router-core/latest/dioxus_router_core/navigation/enum.NavigationTarget.html#variant.Named"><code>Named</code></a> allows us to navigate within our app using predefined names.
|
||||
See the chapter about <a href="./name.html">named navigation</a> for more details.</li>
|
||||
<li><a href="https://docs.rs/dioxus-router-core/latest/dioxus_router_core/navigation/enum.NavigationTarget.html#variant.External"><code>External</code></a> allows us to navigate to URLs outside of our app. See the
|
||||
chapter about <a href="./external.html">external navigation</a> for more details.</li>
|
||||
</ul>
|
||||
<blockquote>
|
||||
<p>The <a href="https://docs.rs/dioxus-router/latest/dioxus_router/components/fn.Link.html"><code>Link</code></a> accepts several props that modify its behavior. See the API docs
|
||||
for more details.</p>
|
||||
</blockquote>
|
||||
|
||||
</main>
|
||||
|
||||
<nav class="nav-wrapper" aria-label="Page navigation">
|
||||
<!-- Mobile navigation buttons -->
|
||||
<a rel="prev" href="../../features/outlets.html" class="mobile-nav-chapters previous" title="Previous chapter" aria-label="Previous chapter" aria-keyshortcuts="Left">
|
||||
<i class="fa fa-angle-left"></i>
|
||||
</a>
|
||||
|
||||
<a rel="next" href="../../features/navigation/name.html" class="mobile-nav-chapters next" title="Next chapter" aria-label="Next chapter" aria-keyshortcuts="Right">
|
||||
<i class="fa fa-angle-right"></i>
|
||||
</a>
|
||||
|
||||
<div style="clear: both"></div>
|
||||
</nav>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<nav class="nav-wide-wrapper" aria-label="Page navigation">
|
||||
<a rel="prev" href="../../features/outlets.html" class="nav-chapters previous" title="Previous chapter" aria-label="Previous chapter" aria-keyshortcuts="Left">
|
||||
<i class="fa fa-angle-left"></i>
|
||||
</a>
|
||||
|
||||
<a rel="next" href="../../features/navigation/name.html" class="nav-chapters next" title="Next chapter" aria-label="Next chapter" aria-keyshortcuts="Right">
|
||||
<i class="fa fa-angle-right"></i>
|
||||
</a>
|
||||
</nav>
|
||||
|
||||
</div>
|
||||
|
||||
|
||||
|
||||
|
||||
<script type="text/javascript">
|
||||
window.playground_copyable = true;
|
||||
</script>
|
||||
|
||||
|
||||
<script src="../../elasticlunr.min.js" type="text/javascript" charset="utf-8"></script>
|
||||
<script src="../../mark.min.js" type="text/javascript" charset="utf-8"></script>
|
||||
<script src="../../searcher.js" type="text/javascript" charset="utf-8"></script>
|
||||
|
||||
<script src="../../clipboard.min.js" type="text/javascript" charset="utf-8"></script>
|
||||
<script src="../../highlight.js" type="text/javascript" charset="utf-8"></script>
|
||||
<script src="../../book.js" type="text/javascript" charset="utf-8"></script>
|
||||
|
||||
<!-- Custom JS scripts -->
|
||||
|
||||
|
||||
</body>
|
||||
</html>
|
||||
@@ -0,0 +1,313 @@
|
||||
<!DOCTYPE HTML>
|
||||
<html lang="en" class="sidebar-visible no-js light">
|
||||
<head>
|
||||
<!-- Book generated using mdBook -->
|
||||
<meta charset="UTF-8">
|
||||
<title>Named Navigation - Dioxus Router</title>
|
||||
|
||||
|
||||
<!-- Custom HTML head -->
|
||||
|
||||
<meta content="text/html; charset=utf-8" http-equiv="Content-Type">
|
||||
<meta name="description" content="">
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1">
|
||||
<meta name="theme-color" content="#ffffff" />
|
||||
|
||||
<link rel="icon" href="../../favicon.svg">
|
||||
<link rel="shortcut icon" href="../../favicon.png">
|
||||
<link rel="stylesheet" href="../../css/variables.css">
|
||||
<link rel="stylesheet" href="../../css/general.css">
|
||||
<link rel="stylesheet" href="../../css/chrome.css">
|
||||
<link rel="stylesheet" href="../../css/print.css" media="print">
|
||||
|
||||
<!-- Fonts -->
|
||||
<link rel="stylesheet" href="../../FontAwesome/css/font-awesome.css">
|
||||
<link rel="stylesheet" href="../../fonts/fonts.css">
|
||||
|
||||
<!-- Highlight.js Stylesheets -->
|
||||
<link rel="stylesheet" href="../../highlight.css">
|
||||
<link rel="stylesheet" href="../../tomorrow-night.css">
|
||||
<link rel="stylesheet" href="../../ayu-highlight.css">
|
||||
|
||||
<!-- Custom theme stylesheets -->
|
||||
|
||||
</head>
|
||||
<body>
|
||||
<!-- Provide site root to javascript -->
|
||||
<script type="text/javascript">
|
||||
var path_to_root = "../../";
|
||||
var default_theme = window.matchMedia("(prefers-color-scheme: dark)").matches ? "navy" : "light";
|
||||
</script>
|
||||
|
||||
<!-- Work around some values being stored in localStorage wrapped in quotes -->
|
||||
<script type="text/javascript">
|
||||
try {
|
||||
var theme = localStorage.getItem('mdbook-theme');
|
||||
var sidebar = localStorage.getItem('mdbook-sidebar');
|
||||
|
||||
if (theme.startsWith('"') && theme.endsWith('"')) {
|
||||
localStorage.setItem('mdbook-theme', theme.slice(1, theme.length - 1));
|
||||
}
|
||||
|
||||
if (sidebar.startsWith('"') && sidebar.endsWith('"')) {
|
||||
localStorage.setItem('mdbook-sidebar', sidebar.slice(1, sidebar.length - 1));
|
||||
}
|
||||
} catch (e) { }
|
||||
</script>
|
||||
|
||||
<!-- Set the theme before any content is loaded, prevents flash -->
|
||||
<script type="text/javascript">
|
||||
var theme;
|
||||
try { theme = localStorage.getItem('mdbook-theme'); } catch(e) { }
|
||||
if (theme === null || theme === undefined) { theme = default_theme; }
|
||||
var html = document.querySelector('html');
|
||||
html.classList.remove('no-js')
|
||||
html.classList.remove('light')
|
||||
html.classList.add(theme);
|
||||
html.classList.add('js');
|
||||
</script>
|
||||
|
||||
<!-- Hide / unhide sidebar before it is displayed -->
|
||||
<script type="text/javascript">
|
||||
var html = document.querySelector('html');
|
||||
var sidebar = 'hidden';
|
||||
if (document.body.clientWidth >= 1080) {
|
||||
try { sidebar = localStorage.getItem('mdbook-sidebar'); } catch(e) { }
|
||||
sidebar = sidebar || 'visible';
|
||||
}
|
||||
html.classList.remove('sidebar-visible');
|
||||
html.classList.add("sidebar-" + sidebar);
|
||||
</script>
|
||||
|
||||
<nav id="sidebar" class="sidebar" aria-label="Table of contents">
|
||||
<div class="sidebar-scrollbox">
|
||||
<ol class="chapter"><li class="chapter-item expanded affix "><a href="../../index.html">Introduction</a></li><li class="chapter-item expanded affix "><li class="part-title">Features</li><li class="chapter-item expanded "><a href="../../features/index.html"><strong aria-hidden="true">1.</strong> Adding the Router to Your Application</a></li><li class="chapter-item expanded "><a href="../../features/routes/index.html"><strong aria-hidden="true">2.</strong> Defining Routes</a></li><li><ol class="section"><li class="chapter-item expanded "><a href="../../features/routes/nested.html"><strong aria-hidden="true">2.1.</strong> Nested Routes</a></li><li class="chapter-item expanded "><a href="../../features/routes/catch_all.html"><strong aria-hidden="true">2.2.</strong> Catch All Routes</a></li><li class="chapter-item expanded "><a href="../../features/routes/matching.html"><strong aria-hidden="true">2.3.</strong> Matching Routes</a></li><li class="chapter-item expanded "><a href="../../features/routes/fallback.html"><strong aria-hidden="true">2.4.</strong> Fallback Routes (404 page)</a></li><li class="chapter-item expanded "><a href="../../features/routes/multiple-and-redirect.html"><strong aria-hidden="true">2.5.</strong> Multiple Components & Redirects</a></li></ol></li><li class="chapter-item expanded "><a href="../../features/outlets.html"><strong aria-hidden="true">3.</strong> Outlets</a></li><li class="chapter-item expanded "><a href="../../features/navigation/index.html"><strong aria-hidden="true">4.</strong> Links & Navigation</a></li><li><ol class="section"><li class="chapter-item expanded "><a href="../../features/navigation/name.html" class="active"><strong aria-hidden="true">4.1.</strong> Named Navigation</a></li><li class="chapter-item expanded "><a href="../../features/navigation/external.html"><strong aria-hidden="true">4.2.</strong> External Navigation</a></li><li class="chapter-item expanded "><a href="../../features/navigation/programmatic.html"><strong aria-hidden="true">4.3.</strong> Programmatic Navigation</a></li></ol></li><li class="chapter-item expanded "><a href="../../features/query.html"><strong aria-hidden="true">5.</strong> Query</a></li><li class="chapter-item expanded "><a href="../../features/failures/index.html"><strong aria-hidden="true">6.</strong> Navigation Failures</a></li><li><ol class="section"><li class="chapter-item expanded "><a href="../../features/failures/named.html"><strong aria-hidden="true">6.1.</strong> Named Navigation Failure</a></li><li class="chapter-item expanded "><a href="../../features/failures/external.html"><strong aria-hidden="true">6.2.</strong> External Navigation Failure</a></li><li class="chapter-item expanded "><a href="../../features/failures/redirection-limit.html"><strong aria-hidden="true">6.3.</strong> Redirection Limit Failure</a></li></ol></li><li class="chapter-item expanded "><a href="../../features/history-providers.html"><strong aria-hidden="true">7.</strong> History Providers</a></li><li class="chapter-item expanded "><a href="../../features/history-buttons.html"><strong aria-hidden="true">8.</strong> History Buttons</a></li><li class="chapter-item expanded "><a href="../../features/sitemap-generation.html"><strong aria-hidden="true">9.</strong> Sitemap Generation</a></li><li class="chapter-item expanded "><a href="../../features/routing-update-callback.html"><strong aria-hidden="true">10.</strong> Routing Update Callback</a></li><li class="chapter-item expanded affix "><li class="part-title">Example Project</li><li class="chapter-item expanded "><a href="../../example/index.html"><strong aria-hidden="true">11.</strong> Overview</a></li><li class="chapter-item expanded "><a href="../../example/first-route.html"><strong aria-hidden="true">12.</strong> Creating Our First Route</a></li><li class="chapter-item expanded "><a href="../../example/building-a-nest.html"><strong aria-hidden="true">13.</strong> Building a Nest</a></li><li class="chapter-item expanded "><a href="../../example/navigation-targets.html"><strong aria-hidden="true">14.</strong> Navigation Targets</a></li><li class="chapter-item expanded "><a href="../../example/redirection-perfection.html"><strong aria-hidden="true">15.</strong> Redirection Perfection</a></li><li class="chapter-item expanded "><a href="../../example/full-code.html"><strong aria-hidden="true">16.</strong> Full Code</a></li></ol>
|
||||
</div>
|
||||
<div id="sidebar-resize-handle" class="sidebar-resize-handle"></div>
|
||||
</nav>
|
||||
|
||||
<div id="page-wrapper" class="page-wrapper">
|
||||
|
||||
<div class="page">
|
||||
<div id="menu-bar-hover-placeholder"></div>
|
||||
<div id="menu-bar" class="menu-bar sticky bordered">
|
||||
<div class="left-buttons">
|
||||
<button id="sidebar-toggle" class="icon-button" type="button" title="Toggle Table of Contents" aria-label="Toggle Table of Contents" aria-controls="sidebar">
|
||||
<i class="fa fa-bars"></i>
|
||||
</button>
|
||||
<button id="theme-toggle" class="icon-button" type="button" title="Change theme" aria-label="Change theme" aria-haspopup="true" aria-expanded="false" aria-controls="theme-list">
|
||||
<i class="fa fa-paint-brush"></i>
|
||||
</button>
|
||||
<ul id="theme-list" class="theme-popup" aria-label="Themes" role="menu">
|
||||
<li role="none"><button role="menuitem" class="theme" id="light">Light (default)</button></li>
|
||||
<li role="none"><button role="menuitem" class="theme" id="rust">Rust</button></li>
|
||||
<li role="none"><button role="menuitem" class="theme" id="coal">Coal</button></li>
|
||||
<li role="none"><button role="menuitem" class="theme" id="navy">Navy</button></li>
|
||||
<li role="none"><button role="menuitem" class="theme" id="ayu">Ayu</button></li>
|
||||
</ul>
|
||||
<button id="search-toggle" class="icon-button" type="button" title="Search. (Shortkey: s)" aria-label="Toggle Searchbar" aria-expanded="false" aria-keyshortcuts="S" aria-controls="searchbar">
|
||||
<i class="fa fa-search"></i>
|
||||
</button>
|
||||
</div>
|
||||
|
||||
<h1 class="menu-title">Dioxus Router</h1>
|
||||
|
||||
<div class="right-buttons">
|
||||
<a href="../../print.html" title="Print this book" aria-label="Print this book">
|
||||
<i id="print-button" class="fa fa-print"></i>
|
||||
</a>
|
||||
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div id="search-wrapper" class="hidden">
|
||||
<form id="searchbar-outer" class="searchbar-outer">
|
||||
<input type="search" id="searchbar" name="searchbar" placeholder="Search this book ..." aria-controls="searchresults-outer" aria-describedby="searchresults-header">
|
||||
</form>
|
||||
<div id="searchresults-outer" class="searchresults-outer hidden">
|
||||
<div id="searchresults-header" class="searchresults-header"></div>
|
||||
<ul id="searchresults">
|
||||
</ul>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- Apply ARIA attributes after the sidebar and the sidebar toggle button are added to the DOM -->
|
||||
<script type="text/javascript">
|
||||
document.getElementById('sidebar-toggle').setAttribute('aria-expanded', sidebar === 'visible');
|
||||
document.getElementById('sidebar').setAttribute('aria-hidden', sidebar !== 'visible');
|
||||
Array.from(document.querySelectorAll('#sidebar a')).forEach(function(link) {
|
||||
link.setAttribute('tabIndex', sidebar === 'visible' ? 0 : -1);
|
||||
});
|
||||
</script>
|
||||
|
||||
<div id="content" class="content">
|
||||
<main>
|
||||
<h1 id="named-navigation"><a class="header" href="#named-navigation">Named Navigation</a></h1>
|
||||
<p>When creating large applications, it can become difficult to keep track of all
|
||||
routes and how to navigate to them. It also can be hard to find all links to
|
||||
them, which makes it difficult to change paths.</p>
|
||||
<p>To solve these problems, the router implements named navigation. When we define
|
||||
our routes we can give them arbitrary, unique names (completely independent from
|
||||
the path) and later ask the router to navigate to those names. The router will
|
||||
automatically create the actual path to navigate to, even inserting required
|
||||
parameters.</p>
|
||||
<p><em>Named</em> navigation has a few advantages over <em>path-based</em> navigation:</p>
|
||||
<ul>
|
||||
<li>Links can be created without knowing the actual path.</li>
|
||||
<li>It is much easier to find all links to a specific route.</li>
|
||||
<li>The router knows what links are invalid (and will panic in debug builds).</li>
|
||||
</ul>
|
||||
<blockquote>
|
||||
<p>When the router encounters an invalid link in a release build, it has to
|
||||
handle that problem. You can hook into that process, to display a custom error
|
||||
message. See the chapter about
|
||||
<a href="../failures/named.html">named navigation failures</a>.</p>
|
||||
</blockquote>
|
||||
<blockquote>
|
||||
<p>The router will automatically define the name <a href="https://docs.rs/dioxus-router-core/latest/dioxus_router_core/prelude/struct.RootIndex.html"><code>RootIndex</code></a> to refer to the
|
||||
root index route (<code>/</code>).</p>
|
||||
<p>It will also add other names (all of them are in the prelude module) in
|
||||
certain conditions. None of these names can be used for app defined routes.</p>
|
||||
</blockquote>
|
||||
<h2 id="code-example"><a class="header" href="#code-example">Code Example</a></h2>
|
||||
<pre><pre class="playground"><code class="language-rust edition2021">
|
||||
<span class="boring">#![allow(unused)]
|
||||
</span><span class="boring">fn main() {
|
||||
</span><span class="boring">// Hidden lines (like this one) make the documentation tests work.
|
||||
</span><span class="boring">extern crate dioxus;
|
||||
</span>use dioxus::prelude::*;
|
||||
<span class="boring">extern crate dioxus_router;
|
||||
</span>use dioxus_router::prelude::*;
|
||||
<span class="boring">extern crate dioxus_ssr;
|
||||
</span>
|
||||
// we define a unit struct which will serve as our name
|
||||
struct TargetName;
|
||||
|
||||
fn Source(cx: Scope) -> Element {
|
||||
render! {
|
||||
Link {
|
||||
// instead of InternalTarget we use NamedTarget (via the `named` fn)
|
||||
// we can use the returned value to add parameters or a query
|
||||
target: named::<TargetName>().query("query"),
|
||||
"Go to target"
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
fn Target(cx: Scope) -> Element {
|
||||
render! {
|
||||
h1 { "Target" }
|
||||
}
|
||||
}
|
||||
|
||||
fn App(cx: Scope) -> Element {
|
||||
use_router(
|
||||
cx,
|
||||
&|| RouterConfiguration {
|
||||
<span class="boring"> synchronous: true,
|
||||
</span> ..Default::default()
|
||||
},
|
||||
&|| {
|
||||
Segment::content(comp(Source))
|
||||
.fixed(
|
||||
"target_path",
|
||||
Route::content(comp(Target)).name::<TargetName>()
|
||||
)
|
||||
}
|
||||
);
|
||||
|
||||
render! {
|
||||
Outlet { }
|
||||
}
|
||||
}
|
||||
<span class="boring">
|
||||
</span><span class="boring">let mut vdom = VirtualDom::new(App);
|
||||
</span><span class="boring">vdom.rebuild();
|
||||
</span><span class="boring">let html = dioxus_ssr::render(&vdom);
|
||||
</span><span class="boring">assert_eq!(
|
||||
</span><span class="boring"> html,
|
||||
</span><span class="boring"> format!(
|
||||
</span><span class="boring"> "<a {attr1} {attr2}>Go to target</a>",
|
||||
</span><span class="boring"> attr1 = r#"href="/target_path?query" dioxus-prevent-default="onclick""#,
|
||||
</span><span class="boring"> attr2 = r#"class="" id="" rel="" target="""#
|
||||
</span><span class="boring"> )
|
||||
</span><span class="boring">)
|
||||
</span><span class="boring">}
|
||||
</span></code></pre></pre>
|
||||
<h2 id="check-if-a-name-is-present"><a class="header" href="#check-if-a-name-is-present">Check if a name is present</a></h2>
|
||||
<p>You can check if a specific name is present for the current route. This works
|
||||
similar to getting the value of a <a href="../routes/parameter.html">parameter route</a> and
|
||||
the same restrictions apply.</p>
|
||||
<pre><pre class="playground"><code class="language-rust no_run edition2021">
|
||||
<span class="boring">#![allow(unused)]
|
||||
</span><span class="boring">fn main() {
|
||||
</span><span class="boring">// Hidden lines (like this one) make the documentation tests work.
|
||||
</span><span class="boring">extern crate dioxus;
|
||||
</span>use dioxus::prelude::*;
|
||||
<span class="boring">extern crate dioxus_router;
|
||||
</span>use dioxus_router::prelude::*;
|
||||
struct SomeName;
|
||||
|
||||
fn Content(cx: Scope) -> Element {
|
||||
let route = use_route(cx).expect("needs to be in router");
|
||||
|
||||
if route.is_at(&named::<SomeName>(), false) {
|
||||
// do something
|
||||
}
|
||||
|
||||
// ...
|
||||
<span class="boring"> todo!()
|
||||
</span>}
|
||||
<span class="boring">}
|
||||
</span></code></pre></pre>
|
||||
|
||||
</main>
|
||||
|
||||
<nav class="nav-wrapper" aria-label="Page navigation">
|
||||
<!-- Mobile navigation buttons -->
|
||||
<a rel="prev" href="../../features/navigation/index.html" class="mobile-nav-chapters previous" title="Previous chapter" aria-label="Previous chapter" aria-keyshortcuts="Left">
|
||||
<i class="fa fa-angle-left"></i>
|
||||
</a>
|
||||
|
||||
<a rel="next" href="../../features/navigation/external.html" class="mobile-nav-chapters next" title="Next chapter" aria-label="Next chapter" aria-keyshortcuts="Right">
|
||||
<i class="fa fa-angle-right"></i>
|
||||
</a>
|
||||
|
||||
<div style="clear: both"></div>
|
||||
</nav>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<nav class="nav-wide-wrapper" aria-label="Page navigation">
|
||||
<a rel="prev" href="../../features/navigation/index.html" class="nav-chapters previous" title="Previous chapter" aria-label="Previous chapter" aria-keyshortcuts="Left">
|
||||
<i class="fa fa-angle-left"></i>
|
||||
</a>
|
||||
|
||||
<a rel="next" href="../../features/navigation/external.html" class="nav-chapters next" title="Next chapter" aria-label="Next chapter" aria-keyshortcuts="Right">
|
||||
<i class="fa fa-angle-right"></i>
|
||||
</a>
|
||||
</nav>
|
||||
|
||||
</div>
|
||||
|
||||
|
||||
|
||||
|
||||
<script type="text/javascript">
|
||||
window.playground_copyable = true;
|
||||
</script>
|
||||
|
||||
|
||||
<script src="../../elasticlunr.min.js" type="text/javascript" charset="utf-8"></script>
|
||||
<script src="../../mark.min.js" type="text/javascript" charset="utf-8"></script>
|
||||
<script src="../../searcher.js" type="text/javascript" charset="utf-8"></script>
|
||||
|
||||
<script src="../../clipboard.min.js" type="text/javascript" charset="utf-8"></script>
|
||||
<script src="../../highlight.js" type="text/javascript" charset="utf-8"></script>
|
||||
<script src="../../book.js" type="text/javascript" charset="utf-8"></script>
|
||||
|
||||
<!-- Custom JS scripts -->
|
||||
|
||||
|
||||
</body>
|
||||
</html>
|
||||
@@ -0,0 +1,267 @@
|
||||
<!DOCTYPE HTML>
|
||||
<html lang="en" class="sidebar-visible no-js light">
|
||||
<head>
|
||||
<!-- Book generated using mdBook -->
|
||||
<meta charset="UTF-8">
|
||||
<title>Programmatic Navigation - Dioxus Router</title>
|
||||
|
||||
|
||||
<!-- Custom HTML head -->
|
||||
|
||||
<meta content="text/html; charset=utf-8" http-equiv="Content-Type">
|
||||
<meta name="description" content="">
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1">
|
||||
<meta name="theme-color" content="#ffffff" />
|
||||
|
||||
<link rel="icon" href="../../favicon.svg">
|
||||
<link rel="shortcut icon" href="../../favicon.png">
|
||||
<link rel="stylesheet" href="../../css/variables.css">
|
||||
<link rel="stylesheet" href="../../css/general.css">
|
||||
<link rel="stylesheet" href="../../css/chrome.css">
|
||||
<link rel="stylesheet" href="../../css/print.css" media="print">
|
||||
|
||||
<!-- Fonts -->
|
||||
<link rel="stylesheet" href="../../FontAwesome/css/font-awesome.css">
|
||||
<link rel="stylesheet" href="../../fonts/fonts.css">
|
||||
|
||||
<!-- Highlight.js Stylesheets -->
|
||||
<link rel="stylesheet" href="../../highlight.css">
|
||||
<link rel="stylesheet" href="../../tomorrow-night.css">
|
||||
<link rel="stylesheet" href="../../ayu-highlight.css">
|
||||
|
||||
<!-- Custom theme stylesheets -->
|
||||
|
||||
</head>
|
||||
<body>
|
||||
<!-- Provide site root to javascript -->
|
||||
<script type="text/javascript">
|
||||
var path_to_root = "../../";
|
||||
var default_theme = window.matchMedia("(prefers-color-scheme: dark)").matches ? "navy" : "light";
|
||||
</script>
|
||||
|
||||
<!-- Work around some values being stored in localStorage wrapped in quotes -->
|
||||
<script type="text/javascript">
|
||||
try {
|
||||
var theme = localStorage.getItem('mdbook-theme');
|
||||
var sidebar = localStorage.getItem('mdbook-sidebar');
|
||||
|
||||
if (theme.startsWith('"') && theme.endsWith('"')) {
|
||||
localStorage.setItem('mdbook-theme', theme.slice(1, theme.length - 1));
|
||||
}
|
||||
|
||||
if (sidebar.startsWith('"') && sidebar.endsWith('"')) {
|
||||
localStorage.setItem('mdbook-sidebar', sidebar.slice(1, sidebar.length - 1));
|
||||
}
|
||||
} catch (e) { }
|
||||
</script>
|
||||
|
||||
<!-- Set the theme before any content is loaded, prevents flash -->
|
||||
<script type="text/javascript">
|
||||
var theme;
|
||||
try { theme = localStorage.getItem('mdbook-theme'); } catch(e) { }
|
||||
if (theme === null || theme === undefined) { theme = default_theme; }
|
||||
var html = document.querySelector('html');
|
||||
html.classList.remove('no-js')
|
||||
html.classList.remove('light')
|
||||
html.classList.add(theme);
|
||||
html.classList.add('js');
|
||||
</script>
|
||||
|
||||
<!-- Hide / unhide sidebar before it is displayed -->
|
||||
<script type="text/javascript">
|
||||
var html = document.querySelector('html');
|
||||
var sidebar = 'hidden';
|
||||
if (document.body.clientWidth >= 1080) {
|
||||
try { sidebar = localStorage.getItem('mdbook-sidebar'); } catch(e) { }
|
||||
sidebar = sidebar || 'visible';
|
||||
}
|
||||
html.classList.remove('sidebar-visible');
|
||||
html.classList.add("sidebar-" + sidebar);
|
||||
</script>
|
||||
|
||||
<nav id="sidebar" class="sidebar" aria-label="Table of contents">
|
||||
<div class="sidebar-scrollbox">
|
||||
<ol class="chapter"><li class="chapter-item expanded affix "><a href="../../index.html">Introduction</a></li><li class="chapter-item expanded affix "><li class="part-title">Features</li><li class="chapter-item expanded "><a href="../../features/index.html"><strong aria-hidden="true">1.</strong> Adding the Router to Your Application</a></li><li class="chapter-item expanded "><a href="../../features/routes/index.html"><strong aria-hidden="true">2.</strong> Defining Routes</a></li><li><ol class="section"><li class="chapter-item expanded "><a href="../../features/routes/nested.html"><strong aria-hidden="true">2.1.</strong> Nested Routes</a></li><li class="chapter-item expanded "><a href="../../features/routes/catch_all.html"><strong aria-hidden="true">2.2.</strong> Catch All Routes</a></li><li class="chapter-item expanded "><a href="../../features/routes/matching.html"><strong aria-hidden="true">2.3.</strong> Matching Routes</a></li><li class="chapter-item expanded "><a href="../../features/routes/fallback.html"><strong aria-hidden="true">2.4.</strong> Fallback Routes (404 page)</a></li><li class="chapter-item expanded "><a href="../../features/routes/multiple-and-redirect.html"><strong aria-hidden="true">2.5.</strong> Multiple Components & Redirects</a></li></ol></li><li class="chapter-item expanded "><a href="../../features/outlets.html"><strong aria-hidden="true">3.</strong> Outlets</a></li><li class="chapter-item expanded "><a href="../../features/navigation/index.html"><strong aria-hidden="true">4.</strong> Links & Navigation</a></li><li><ol class="section"><li class="chapter-item expanded "><a href="../../features/navigation/name.html"><strong aria-hidden="true">4.1.</strong> Named Navigation</a></li><li class="chapter-item expanded "><a href="../../features/navigation/external.html"><strong aria-hidden="true">4.2.</strong> External Navigation</a></li><li class="chapter-item expanded "><a href="../../features/navigation/programmatic.html" class="active"><strong aria-hidden="true">4.3.</strong> Programmatic Navigation</a></li></ol></li><li class="chapter-item expanded "><a href="../../features/query.html"><strong aria-hidden="true">5.</strong> Query</a></li><li class="chapter-item expanded "><a href="../../features/failures/index.html"><strong aria-hidden="true">6.</strong> Navigation Failures</a></li><li><ol class="section"><li class="chapter-item expanded "><a href="../../features/failures/named.html"><strong aria-hidden="true">6.1.</strong> Named Navigation Failure</a></li><li class="chapter-item expanded "><a href="../../features/failures/external.html"><strong aria-hidden="true">6.2.</strong> External Navigation Failure</a></li><li class="chapter-item expanded "><a href="../../features/failures/redirection-limit.html"><strong aria-hidden="true">6.3.</strong> Redirection Limit Failure</a></li></ol></li><li class="chapter-item expanded "><a href="../../features/history-providers.html"><strong aria-hidden="true">7.</strong> History Providers</a></li><li class="chapter-item expanded "><a href="../../features/history-buttons.html"><strong aria-hidden="true">8.</strong> History Buttons</a></li><li class="chapter-item expanded "><a href="../../features/sitemap-generation.html"><strong aria-hidden="true">9.</strong> Sitemap Generation</a></li><li class="chapter-item expanded "><a href="../../features/routing-update-callback.html"><strong aria-hidden="true">10.</strong> Routing Update Callback</a></li><li class="chapter-item expanded affix "><li class="part-title">Example Project</li><li class="chapter-item expanded "><a href="../../example/index.html"><strong aria-hidden="true">11.</strong> Overview</a></li><li class="chapter-item expanded "><a href="../../example/first-route.html"><strong aria-hidden="true">12.</strong> Creating Our First Route</a></li><li class="chapter-item expanded "><a href="../../example/building-a-nest.html"><strong aria-hidden="true">13.</strong> Building a Nest</a></li><li class="chapter-item expanded "><a href="../../example/navigation-targets.html"><strong aria-hidden="true">14.</strong> Navigation Targets</a></li><li class="chapter-item expanded "><a href="../../example/redirection-perfection.html"><strong aria-hidden="true">15.</strong> Redirection Perfection</a></li><li class="chapter-item expanded "><a href="../../example/full-code.html"><strong aria-hidden="true">16.</strong> Full Code</a></li></ol>
|
||||
</div>
|
||||
<div id="sidebar-resize-handle" class="sidebar-resize-handle"></div>
|
||||
</nav>
|
||||
|
||||
<div id="page-wrapper" class="page-wrapper">
|
||||
|
||||
<div class="page">
|
||||
<div id="menu-bar-hover-placeholder"></div>
|
||||
<div id="menu-bar" class="menu-bar sticky bordered">
|
||||
<div class="left-buttons">
|
||||
<button id="sidebar-toggle" class="icon-button" type="button" title="Toggle Table of Contents" aria-label="Toggle Table of Contents" aria-controls="sidebar">
|
||||
<i class="fa fa-bars"></i>
|
||||
</button>
|
||||
<button id="theme-toggle" class="icon-button" type="button" title="Change theme" aria-label="Change theme" aria-haspopup="true" aria-expanded="false" aria-controls="theme-list">
|
||||
<i class="fa fa-paint-brush"></i>
|
||||
</button>
|
||||
<ul id="theme-list" class="theme-popup" aria-label="Themes" role="menu">
|
||||
<li role="none"><button role="menuitem" class="theme" id="light">Light (default)</button></li>
|
||||
<li role="none"><button role="menuitem" class="theme" id="rust">Rust</button></li>
|
||||
<li role="none"><button role="menuitem" class="theme" id="coal">Coal</button></li>
|
||||
<li role="none"><button role="menuitem" class="theme" id="navy">Navy</button></li>
|
||||
<li role="none"><button role="menuitem" class="theme" id="ayu">Ayu</button></li>
|
||||
</ul>
|
||||
<button id="search-toggle" class="icon-button" type="button" title="Search. (Shortkey: s)" aria-label="Toggle Searchbar" aria-expanded="false" aria-keyshortcuts="S" aria-controls="searchbar">
|
||||
<i class="fa fa-search"></i>
|
||||
</button>
|
||||
</div>
|
||||
|
||||
<h1 class="menu-title">Dioxus Router</h1>
|
||||
|
||||
<div class="right-buttons">
|
||||
<a href="../../print.html" title="Print this book" aria-label="Print this book">
|
||||
<i id="print-button" class="fa fa-print"></i>
|
||||
</a>
|
||||
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div id="search-wrapper" class="hidden">
|
||||
<form id="searchbar-outer" class="searchbar-outer">
|
||||
<input type="search" id="searchbar" name="searchbar" placeholder="Search this book ..." aria-controls="searchresults-outer" aria-describedby="searchresults-header">
|
||||
</form>
|
||||
<div id="searchresults-outer" class="searchresults-outer hidden">
|
||||
<div id="searchresults-header" class="searchresults-header"></div>
|
||||
<ul id="searchresults">
|
||||
</ul>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- Apply ARIA attributes after the sidebar and the sidebar toggle button are added to the DOM -->
|
||||
<script type="text/javascript">
|
||||
document.getElementById('sidebar-toggle').setAttribute('aria-expanded', sidebar === 'visible');
|
||||
document.getElementById('sidebar').setAttribute('aria-hidden', sidebar !== 'visible');
|
||||
Array.from(document.querySelectorAll('#sidebar a')).forEach(function(link) {
|
||||
link.setAttribute('tabIndex', sidebar === 'visible' ? 0 : -1);
|
||||
});
|
||||
</script>
|
||||
|
||||
<div id="content" class="content">
|
||||
<main>
|
||||
<h1 id="programmatic-navigation"><a class="header" href="#programmatic-navigation">Programmatic Navigation</a></h1>
|
||||
<p>Sometimes we want our application to navigate to another page without having the
|
||||
user click on a link. This is called programmatic navigation.</p>
|
||||
<h2 id="acquiring-a-navigator"><a class="header" href="#acquiring-a-navigator">Acquiring a <a href="https://docs.rs/dioxus-router-core/latest/dioxus_router_core/hooks/struct.Navigator.html"><code>Navigator</code></a></a></h2>
|
||||
<p>To use programmatic navigation, we first have to acquire a <a href="https://docs.rs/dioxus-router-core/latest/dioxus_router_core/hooks/struct.Navigator.html"><code>Navigator</code></a>. For
|
||||
that purpose we can use the <a href="https://docs.rs/dioxus-router/latest/dioxus_router/hooks/fn.use_navigate.html"><code>use_navigate</code></a> hook.</p>
|
||||
<pre><pre class="playground"><code class="language-rust no_run edition2021">
|
||||
<span class="boring">#![allow(unused)]
|
||||
</span><span class="boring">fn main() {
|
||||
</span><span class="boring">// Hidden lines (like this one) make the documentation tests work.
|
||||
</span><span class="boring">extern crate dioxus;
|
||||
</span>use dioxus::prelude::*;
|
||||
<span class="boring">extern crate dioxus_router;
|
||||
</span>use dioxus_router::prelude::*;
|
||||
|
||||
fn Content(cx: Scope) -> Element {
|
||||
let nav = use_navigate(cx).expect("called inside a router");
|
||||
|
||||
// ...
|
||||
<span class="boring"> unimplemented!()
|
||||
</span>}
|
||||
<span class="boring">}
|
||||
</span></code></pre></pre>
|
||||
<h2 id="triggering-a-navigation"><a class="header" href="#triggering-a-navigation">Triggering a Navigation</a></h2>
|
||||
<p>We can use the <a href="https://docs.rs/dioxus-router-core/latest/dioxus_router_core/hooks/struct.Navigator.html"><code>Navigator</code></a> to trigger four different kinds of navigation:</p>
|
||||
<ul>
|
||||
<li><code>push</code> will navigate to the target. It works like a regular anchor tag.</li>
|
||||
<li><code>replace</code> works like <code>push</code>, except that it replaces the current history entry
|
||||
instead of adding a new one. This means the prior page cannot be restored with
|
||||
the browsers back button.</li>
|
||||
<li><code>Go back</code> works like the browsers back button.</li>
|
||||
<li><code>Go forward</code> works like the browsers forward button (the opposite of the back
|
||||
button).</li>
|
||||
</ul>
|
||||
<pre><pre class="playground"><code class="language-rust no_run edition2021">
|
||||
<span class="boring">#![allow(unused)]
|
||||
</span><span class="boring">fn main() {
|
||||
</span><span class="boring">// Hidden lines (like this one) make the documentation tests work.
|
||||
</span><span class="boring">extern crate dioxus;
|
||||
</span><span class="boring">use dioxus::prelude::*;
|
||||
</span><span class="boring">extern crate dioxus_router;
|
||||
</span><span class="boring">use dioxus_router::prelude::*;
|
||||
</span><span class="boring">
|
||||
</span>fn Content(cx: Scope) -> Element {
|
||||
let nav = use_navigate(cx).expect("called inside a router");
|
||||
|
||||
// push
|
||||
nav.push("/target");
|
||||
|
||||
// replace
|
||||
nav.replace("/target");
|
||||
|
||||
// go back
|
||||
nav.go_back();
|
||||
|
||||
// go forward
|
||||
nav.go_forward();
|
||||
|
||||
// ...
|
||||
<span class="boring"> unimplemented!()
|
||||
</span>}
|
||||
<span class="boring">}
|
||||
</span></code></pre></pre>
|
||||
<p>You might have noticed that, like <a href="https://docs.rs/dioxus-router/latest/dioxus_router/components/fn.Link.html"><code>Link</code></a>, the <a href="https://docs.rs/dioxus-router-core/latest/dioxus_router_core/hooks/struct.Navigator.html"><code>Navigator</code></a>s <code>push</code> and
|
||||
<code>replace</code> functions take a <a href="https://docs.rs/dioxus-router-core/latest/dioxus_router_core/navigation/enum.NavigationTarget.html"><code>NavigationTarget</code></a>. This means we can use
|
||||
<a href="https://docs.rs/dioxus-router-core/latest/dioxus_router_core/navigation/enum.NavigationTarget.html#variant.Internal"><code>Internal</code></a>, <a href="https://docs.rs/dioxus-router-core/latest/dioxus_router_core/navigation/enum.NavigationTarget.html#variant.Named"><code>Named</code></a> and <a href="https://docs.rs/dioxus-router-core/latest/dioxus_router_core/navigation/enum.NavigationTarget.html#variant.External"><code>External</code></a>.</p>
|
||||
<h2 id="external-navigation-targets"><a class="header" href="#external-navigation-targets">External Navigation Targets</a></h2>
|
||||
<p>Unlike a <a href="https://docs.rs/dioxus-router/latest/dioxus_router/components/fn.Link.html"><code>Link</code></a>, the <a href="https://docs.rs/dioxus-router-core/latest/dioxus_router_core/hooks/struct.Navigator.html"><code>Navigator</code></a> cannot rely on the browser (or webview) to
|
||||
handle navigation to external targets via a generated anchor element.</p>
|
||||
<p>This means, that under certain conditions, navigation to external targets can
|
||||
fail. See the chapter about
|
||||
<a href="../failures/external.html">external navigation failures</a> for more details.</p>
|
||||
|
||||
</main>
|
||||
|
||||
<nav class="nav-wrapper" aria-label="Page navigation">
|
||||
<!-- Mobile navigation buttons -->
|
||||
<a rel="prev" href="../../features/navigation/external.html" class="mobile-nav-chapters previous" title="Previous chapter" aria-label="Previous chapter" aria-keyshortcuts="Left">
|
||||
<i class="fa fa-angle-left"></i>
|
||||
</a>
|
||||
|
||||
<a rel="next" href="../../features/query.html" class="mobile-nav-chapters next" title="Next chapter" aria-label="Next chapter" aria-keyshortcuts="Right">
|
||||
<i class="fa fa-angle-right"></i>
|
||||
</a>
|
||||
|
||||
<div style="clear: both"></div>
|
||||
</nav>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<nav class="nav-wide-wrapper" aria-label="Page navigation">
|
||||
<a rel="prev" href="../../features/navigation/external.html" class="nav-chapters previous" title="Previous chapter" aria-label="Previous chapter" aria-keyshortcuts="Left">
|
||||
<i class="fa fa-angle-left"></i>
|
||||
</a>
|
||||
|
||||
<a rel="next" href="../../features/query.html" class="nav-chapters next" title="Next chapter" aria-label="Next chapter" aria-keyshortcuts="Right">
|
||||
<i class="fa fa-angle-right"></i>
|
||||
</a>
|
||||
</nav>
|
||||
|
||||
</div>
|
||||
|
||||
|
||||
|
||||
|
||||
<script type="text/javascript">
|
||||
window.playground_copyable = true;
|
||||
</script>
|
||||
|
||||
|
||||
<script src="../../elasticlunr.min.js" type="text/javascript" charset="utf-8"></script>
|
||||
<script src="../../mark.min.js" type="text/javascript" charset="utf-8"></script>
|
||||
<script src="../../searcher.js" type="text/javascript" charset="utf-8"></script>
|
||||
|
||||
<script src="../../clipboard.min.js" type="text/javascript" charset="utf-8"></script>
|
||||
<script src="../../highlight.js" type="text/javascript" charset="utf-8"></script>
|
||||
<script src="../../book.js" type="text/javascript" charset="utf-8"></script>
|
||||
|
||||
<!-- Custom JS scripts -->
|
||||
|
||||
|
||||
</body>
|
||||
</html>
|
||||
@@ -0,0 +1,432 @@
|
||||
<!DOCTYPE HTML>
|
||||
<html lang="en" class="sidebar-visible no-js light">
|
||||
<head>
|
||||
<!-- Book generated using mdBook -->
|
||||
<meta charset="UTF-8">
|
||||
<title>Outlets - Dioxus Router</title>
|
||||
|
||||
|
||||
<!-- Custom HTML head -->
|
||||
|
||||
<meta content="text/html; charset=utf-8" http-equiv="Content-Type">
|
||||
<meta name="description" content="">
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1">
|
||||
<meta name="theme-color" content="#ffffff" />
|
||||
|
||||
<link rel="icon" href="../favicon.svg">
|
||||
<link rel="shortcut icon" href="../favicon.png">
|
||||
<link rel="stylesheet" href="../css/variables.css">
|
||||
<link rel="stylesheet" href="../css/general.css">
|
||||
<link rel="stylesheet" href="../css/chrome.css">
|
||||
<link rel="stylesheet" href="../css/print.css" media="print">
|
||||
|
||||
<!-- Fonts -->
|
||||
<link rel="stylesheet" href="../FontAwesome/css/font-awesome.css">
|
||||
<link rel="stylesheet" href="../fonts/fonts.css">
|
||||
|
||||
<!-- Highlight.js Stylesheets -->
|
||||
<link rel="stylesheet" href="../highlight.css">
|
||||
<link rel="stylesheet" href="../tomorrow-night.css">
|
||||
<link rel="stylesheet" href="../ayu-highlight.css">
|
||||
|
||||
<!-- Custom theme stylesheets -->
|
||||
|
||||
</head>
|
||||
<body>
|
||||
<!-- Provide site root to javascript -->
|
||||
<script type="text/javascript">
|
||||
var path_to_root = "../";
|
||||
var default_theme = window.matchMedia("(prefers-color-scheme: dark)").matches ? "navy" : "light";
|
||||
</script>
|
||||
|
||||
<!-- Work around some values being stored in localStorage wrapped in quotes -->
|
||||
<script type="text/javascript">
|
||||
try {
|
||||
var theme = localStorage.getItem('mdbook-theme');
|
||||
var sidebar = localStorage.getItem('mdbook-sidebar');
|
||||
|
||||
if (theme.startsWith('"') && theme.endsWith('"')) {
|
||||
localStorage.setItem('mdbook-theme', theme.slice(1, theme.length - 1));
|
||||
}
|
||||
|
||||
if (sidebar.startsWith('"') && sidebar.endsWith('"')) {
|
||||
localStorage.setItem('mdbook-sidebar', sidebar.slice(1, sidebar.length - 1));
|
||||
}
|
||||
} catch (e) { }
|
||||
</script>
|
||||
|
||||
<!-- Set the theme before any content is loaded, prevents flash -->
|
||||
<script type="text/javascript">
|
||||
var theme;
|
||||
try { theme = localStorage.getItem('mdbook-theme'); } catch(e) { }
|
||||
if (theme === null || theme === undefined) { theme = default_theme; }
|
||||
var html = document.querySelector('html');
|
||||
html.classList.remove('no-js')
|
||||
html.classList.remove('light')
|
||||
html.classList.add(theme);
|
||||
html.classList.add('js');
|
||||
</script>
|
||||
|
||||
<!-- Hide / unhide sidebar before it is displayed -->
|
||||
<script type="text/javascript">
|
||||
var html = document.querySelector('html');
|
||||
var sidebar = 'hidden';
|
||||
if (document.body.clientWidth >= 1080) {
|
||||
try { sidebar = localStorage.getItem('mdbook-sidebar'); } catch(e) { }
|
||||
sidebar = sidebar || 'visible';
|
||||
}
|
||||
html.classList.remove('sidebar-visible');
|
||||
html.classList.add("sidebar-" + sidebar);
|
||||
</script>
|
||||
|
||||
<nav id="sidebar" class="sidebar" aria-label="Table of contents">
|
||||
<div class="sidebar-scrollbox">
|
||||
<ol class="chapter"><li class="chapter-item expanded affix "><a href="../index.html">Introduction</a></li><li class="chapter-item expanded affix "><li class="part-title">Features</li><li class="chapter-item expanded "><a href="../features/index.html"><strong aria-hidden="true">1.</strong> Adding the Router to Your Application</a></li><li class="chapter-item expanded "><a href="../features/routes/index.html"><strong aria-hidden="true">2.</strong> Defining Routes</a></li><li><ol class="section"><li class="chapter-item expanded "><a href="../features/routes/nested.html"><strong aria-hidden="true">2.1.</strong> Nested Routes</a></li><li class="chapter-item expanded "><a href="../features/routes/catch_all.html"><strong aria-hidden="true">2.2.</strong> Catch All Routes</a></li><li class="chapter-item expanded "><a href="../features/routes/matching.html"><strong aria-hidden="true">2.3.</strong> Matching Routes</a></li><li class="chapter-item expanded "><a href="../features/routes/fallback.html"><strong aria-hidden="true">2.4.</strong> Fallback Routes (404 page)</a></li><li class="chapter-item expanded "><a href="../features/routes/multiple-and-redirect.html"><strong aria-hidden="true">2.5.</strong> Multiple Components & Redirects</a></li></ol></li><li class="chapter-item expanded "><a href="../features/outlets.html" class="active"><strong aria-hidden="true">3.</strong> Outlets</a></li><li class="chapter-item expanded "><a href="../features/navigation/index.html"><strong aria-hidden="true">4.</strong> Links & Navigation</a></li><li><ol class="section"><li class="chapter-item expanded "><a href="../features/navigation/name.html"><strong aria-hidden="true">4.1.</strong> Named Navigation</a></li><li class="chapter-item expanded "><a href="../features/navigation/external.html"><strong aria-hidden="true">4.2.</strong> External Navigation</a></li><li class="chapter-item expanded "><a href="../features/navigation/programmatic.html"><strong aria-hidden="true">4.3.</strong> Programmatic Navigation</a></li></ol></li><li class="chapter-item expanded "><a href="../features/query.html"><strong aria-hidden="true">5.</strong> Query</a></li><li class="chapter-item expanded "><a href="../features/failures/index.html"><strong aria-hidden="true">6.</strong> Navigation Failures</a></li><li><ol class="section"><li class="chapter-item expanded "><a href="../features/failures/named.html"><strong aria-hidden="true">6.1.</strong> Named Navigation Failure</a></li><li class="chapter-item expanded "><a href="../features/failures/external.html"><strong aria-hidden="true">6.2.</strong> External Navigation Failure</a></li><li class="chapter-item expanded "><a href="../features/failures/redirection-limit.html"><strong aria-hidden="true">6.3.</strong> Redirection Limit Failure</a></li></ol></li><li class="chapter-item expanded "><a href="../features/history-providers.html"><strong aria-hidden="true">7.</strong> History Providers</a></li><li class="chapter-item expanded "><a href="../features/history-buttons.html"><strong aria-hidden="true">8.</strong> History Buttons</a></li><li class="chapter-item expanded "><a href="../features/sitemap-generation.html"><strong aria-hidden="true">9.</strong> Sitemap Generation</a></li><li class="chapter-item expanded "><a href="../features/routing-update-callback.html"><strong aria-hidden="true">10.</strong> Routing Update Callback</a></li><li class="chapter-item expanded affix "><li class="part-title">Example Project</li><li class="chapter-item expanded "><a href="../example/index.html"><strong aria-hidden="true">11.</strong> Overview</a></li><li class="chapter-item expanded "><a href="../example/first-route.html"><strong aria-hidden="true">12.</strong> Creating Our First Route</a></li><li class="chapter-item expanded "><a href="../example/building-a-nest.html"><strong aria-hidden="true">13.</strong> Building a Nest</a></li><li class="chapter-item expanded "><a href="../example/navigation-targets.html"><strong aria-hidden="true">14.</strong> Navigation Targets</a></li><li class="chapter-item expanded "><a href="../example/redirection-perfection.html"><strong aria-hidden="true">15.</strong> Redirection Perfection</a></li><li class="chapter-item expanded "><a href="../example/full-code.html"><strong aria-hidden="true">16.</strong> Full Code</a></li></ol>
|
||||
</div>
|
||||
<div id="sidebar-resize-handle" class="sidebar-resize-handle"></div>
|
||||
</nav>
|
||||
|
||||
<div id="page-wrapper" class="page-wrapper">
|
||||
|
||||
<div class="page">
|
||||
<div id="menu-bar-hover-placeholder"></div>
|
||||
<div id="menu-bar" class="menu-bar sticky bordered">
|
||||
<div class="left-buttons">
|
||||
<button id="sidebar-toggle" class="icon-button" type="button" title="Toggle Table of Contents" aria-label="Toggle Table of Contents" aria-controls="sidebar">
|
||||
<i class="fa fa-bars"></i>
|
||||
</button>
|
||||
<button id="theme-toggle" class="icon-button" type="button" title="Change theme" aria-label="Change theme" aria-haspopup="true" aria-expanded="false" aria-controls="theme-list">
|
||||
<i class="fa fa-paint-brush"></i>
|
||||
</button>
|
||||
<ul id="theme-list" class="theme-popup" aria-label="Themes" role="menu">
|
||||
<li role="none"><button role="menuitem" class="theme" id="light">Light (default)</button></li>
|
||||
<li role="none"><button role="menuitem" class="theme" id="rust">Rust</button></li>
|
||||
<li role="none"><button role="menuitem" class="theme" id="coal">Coal</button></li>
|
||||
<li role="none"><button role="menuitem" class="theme" id="navy">Navy</button></li>
|
||||
<li role="none"><button role="menuitem" class="theme" id="ayu">Ayu</button></li>
|
||||
</ul>
|
||||
<button id="search-toggle" class="icon-button" type="button" title="Search. (Shortkey: s)" aria-label="Toggle Searchbar" aria-expanded="false" aria-keyshortcuts="S" aria-controls="searchbar">
|
||||
<i class="fa fa-search"></i>
|
||||
</button>
|
||||
</div>
|
||||
|
||||
<h1 class="menu-title">Dioxus Router</h1>
|
||||
|
||||
<div class="right-buttons">
|
||||
<a href="../print.html" title="Print this book" aria-label="Print this book">
|
||||
<i id="print-button" class="fa fa-print"></i>
|
||||
</a>
|
||||
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div id="search-wrapper" class="hidden">
|
||||
<form id="searchbar-outer" class="searchbar-outer">
|
||||
<input type="search" id="searchbar" name="searchbar" placeholder="Search this book ..." aria-controls="searchresults-outer" aria-describedby="searchresults-header">
|
||||
</form>
|
||||
<div id="searchresults-outer" class="searchresults-outer hidden">
|
||||
<div id="searchresults-header" class="searchresults-header"></div>
|
||||
<ul id="searchresults">
|
||||
</ul>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- Apply ARIA attributes after the sidebar and the sidebar toggle button are added to the DOM -->
|
||||
<script type="text/javascript">
|
||||
document.getElementById('sidebar-toggle').setAttribute('aria-expanded', sidebar === 'visible');
|
||||
document.getElementById('sidebar').setAttribute('aria-hidden', sidebar !== 'visible');
|
||||
Array.from(document.querySelectorAll('#sidebar a')).forEach(function(link) {
|
||||
link.setAttribute('tabIndex', sidebar === 'visible' ? 0 : -1);
|
||||
});
|
||||
</script>
|
||||
|
||||
<div id="content" class="content">
|
||||
<main>
|
||||
<h1 id="outlets"><a class="header" href="#outlets">Outlets</a></h1>
|
||||
<p><a href="https://docs.rs/dioxus-router/latest/dioxus_router/components/fn.Outlet.html"><code>Outlet</code></a>s tell the router where to render content. In the following example
|
||||
the active routes content will be rendered within the <a href="https://docs.rs/dioxus-router/latest/dioxus_router/components/fn.Outlet.html"><code>Outlet</code></a>.</p>
|
||||
<pre><pre class="playground"><code class="language-rust edition2021">
|
||||
<span class="boring">#![allow(unused)]
|
||||
</span><span class="boring">fn main() {
|
||||
</span><span class="boring">// Hidden lines (like this one) make the documentation tests work.
|
||||
</span><span class="boring">extern crate dioxus;
|
||||
</span><span class="boring">use dioxus::prelude::*;
|
||||
</span><span class="boring">extern crate dioxus_router;
|
||||
</span><span class="boring">use dioxus_router::prelude::*;
|
||||
</span><span class="boring">extern crate dioxus_ssr;
|
||||
</span>
|
||||
fn Index(cx: Scope) -> Element {
|
||||
render! {
|
||||
h1 { "Index" }
|
||||
}
|
||||
}
|
||||
|
||||
fn App(cx: Scope) -> Element {
|
||||
use_router(
|
||||
cx,
|
||||
&|| RouterConfiguration {
|
||||
<span class="boring"> synchronous: true,
|
||||
</span> ..Default::default()
|
||||
},
|
||||
&|| Segment::content(comp(Index))
|
||||
);
|
||||
|
||||
render! {
|
||||
header { "header" }
|
||||
Outlet { }
|
||||
footer { "footer" }
|
||||
}
|
||||
}
|
||||
<span class="boring">
|
||||
</span><span class="boring">let mut vdom = VirtualDom::new(App);
|
||||
</span><span class="boring">vdom.rebuild();
|
||||
</span><span class="boring">let html = dioxus_ssr::render(&vdom);
|
||||
</span><span class="boring">assert_eq!(
|
||||
</span><span class="boring"> html,
|
||||
</span><span class="boring"> "<header>header</header><h1>Index</h1><footer>footer</footer>"
|
||||
</span><span class="boring">);
|
||||
</span><span class="boring">}
|
||||
</span></code></pre></pre>
|
||||
<p>The example above will output the following HTML (line breaks added for
|
||||
readability):</p>
|
||||
<pre><code class="language-html"><header>
|
||||
header
|
||||
</header>
|
||||
<h1>
|
||||
Index
|
||||
</h1>
|
||||
<footer>
|
||||
footer
|
||||
</footer>
|
||||
</code></pre>
|
||||
<h2 id="nested-outlets"><a class="header" href="#nested-outlets">Nested Outlets</a></h2>
|
||||
<p>When using nested routes, we need to provide equally nested <a href="https://docs.rs/dioxus-router/latest/dioxus_router/components/fn.Outlet.html"><code>Outlet</code></a>s.</p>
|
||||
<blockquote>
|
||||
<p>Learn more about <a href="./routes/nested.html">nested routes</a> in their own chapter.</p>
|
||||
</blockquote>
|
||||
<h2 id="named-outlets"><a class="header" href="#named-outlets">Named Outlets</a></h2>
|
||||
<p>When building complex apps, we often need to display multiple pieces of content
|
||||
simultaneously. For example, we might have a sidebar that changes its content in
|
||||
sync with the main part of the page.</p>
|
||||
<p>When defining our routes, we can use <code>RouteContentMulti</code> instead of
|
||||
<code>RouteContent::Component</code> (we've been using this through the <code>Into</code> trait) to
|
||||
tell the router about our content.</p>
|
||||
<p>We then can use a named <a href="https://docs.rs/dioxus-router/latest/dioxus_router/components/fn.Outlet.html"><code>Outlet</code></a> in our output, to tell the router where to
|
||||
put the side content.</p>
|
||||
<pre><pre class="playground"><code class="language-rust edition2021">
|
||||
<span class="boring">#![allow(unused)]
|
||||
</span><span class="boring">fn main() {
|
||||
</span><span class="boring">// Hidden lines (like this one) make the documentation tests work.
|
||||
</span><span class="boring">extern crate dioxus;
|
||||
</span><span class="boring">use dioxus::prelude::*;
|
||||
</span><span class="boring">extern crate dioxus_router;
|
||||
</span><span class="boring">use dioxus_router::prelude::*;
|
||||
</span><span class="boring">extern crate dioxus_ssr;
|
||||
</span><span class="boring">
|
||||
</span>
|
||||
fn Main(cx: Scope) -> Element {
|
||||
render! {
|
||||
main { "Main Content" }
|
||||
}
|
||||
}
|
||||
|
||||
struct AsideName;
|
||||
fn Aside(cx: Scope) -> Element {
|
||||
render! {
|
||||
aside { "Side Content" }
|
||||
}
|
||||
}
|
||||
|
||||
fn App(cx: Scope) -> Element {
|
||||
use_router(
|
||||
cx,
|
||||
&|| RouterConfiguration {
|
||||
<span class="boring"> synchronous: true,
|
||||
</span> ..Default::default()
|
||||
},
|
||||
&|| {
|
||||
Segment::content(
|
||||
multi(Some(comp(Main)))
|
||||
.add_named::<AsideName>(comp(Aside))
|
||||
)
|
||||
}
|
||||
);
|
||||
|
||||
render! {
|
||||
Outlet { }
|
||||
Outlet {
|
||||
name: Name::of::<AsideName>()
|
||||
}
|
||||
}
|
||||
}
|
||||
<span class="boring">
|
||||
</span><span class="boring">let mut vdom = VirtualDom::new(App);
|
||||
</span><span class="boring">vdom.rebuild();
|
||||
</span><span class="boring">let html = dioxus_ssr::render(&vdom);
|
||||
</span><span class="boring">assert_eq!(html, "<main>Main Content</main><aside>Side Content</aside>");
|
||||
</span><span class="boring">}
|
||||
</span></code></pre></pre>
|
||||
<p>The example above will output the following HTML (line breaks added for
|
||||
readability):</p>
|
||||
<pre><code class="language-html"><main>
|
||||
Main Content
|
||||
</main>
|
||||
<aside>
|
||||
Side Content
|
||||
</aside>
|
||||
</code></pre>
|
||||
<h2 id="outlet-depth-override"><a class="header" href="#outlet-depth-override">Outlet depth override</a></h2>
|
||||
<p>When nesting <a href="https://docs.rs/dioxus-router/latest/dioxus_router/components/fn.Outlet.html"><code>Outlet</code></a>s, they communicate with each other. This allows the
|
||||
nested <a href="https://docs.rs/dioxus-router/latest/dioxus_router/components/fn.Outlet.html"><code>Outlet</code></a> to render the content of the nested route.</p>
|
||||
<p>We can override the detected value. Be careful when doing so, it is incredibly
|
||||
easy to create an unterminated recursion. See below for an example of that.</p>
|
||||
<pre><pre class="playground"><code class="language-rust edition2021">
|
||||
<span class="boring">#![allow(unused)]
|
||||
</span><span class="boring">fn main() {
|
||||
</span><span class="boring">// Hidden lines (like this one) make the documentation tests work.
|
||||
</span><span class="boring">extern crate dioxus;
|
||||
</span><span class="boring">use dioxus::prelude::*;
|
||||
</span><span class="boring">extern crate dioxus_router;
|
||||
</span><span class="boring">use dioxus_router::{history::MemoryHistory, prelude::*};
|
||||
</span><span class="boring">extern crate dioxus_ssr;
|
||||
</span><span class="boring">
|
||||
</span>fn RootContent(cx: Scope) -> Element {
|
||||
render! {
|
||||
h1 { "Root" }
|
||||
Outlet { }
|
||||
}
|
||||
}
|
||||
|
||||
fn NestedContent(cx: Scope) -> Element {
|
||||
render! {
|
||||
h2 { "Nested" }
|
||||
}
|
||||
}
|
||||
|
||||
fn App(cx: Scope) -> Element {
|
||||
use_router(
|
||||
cx,
|
||||
&|| RouterConfiguration {
|
||||
<span class="boring"> synchronous: true,
|
||||
</span><span class="boring"> history: Box::new(MemoryHistory::with_initial_path("/root").unwrap()),
|
||||
</span> ..Default::default()
|
||||
},
|
||||
&|| {
|
||||
Segment::empty().fixed(
|
||||
"root",
|
||||
Route::content(comp(RootContent)).nested(
|
||||
Segment::content(comp(NestedContent))
|
||||
)
|
||||
)
|
||||
}
|
||||
);
|
||||
|
||||
render! {
|
||||
Outlet {
|
||||
depth: 1
|
||||
}
|
||||
}
|
||||
}
|
||||
<span class="boring">
|
||||
</span><span class="boring">let mut vdom = VirtualDom::new(App);
|
||||
</span><span class="boring">vdom.rebuild();
|
||||
</span><span class="boring">let html = dioxus_ssr::render(&vdom);
|
||||
</span><span class="boring">assert_eq!(html, "<h2>Nested</h2>");
|
||||
</span><span class="boring">}
|
||||
</span></code></pre></pre>
|
||||
<p>The example above will output the following HTML (line breaks added for
|
||||
readability):</p>
|
||||
<pre><code class="language-html"><h2>
|
||||
Nested
|
||||
</h2>
|
||||
</code></pre>
|
||||
<h3 id="outlet-recursion"><a class="header" href="#outlet-recursion">Outlet recursion</a></h3>
|
||||
<p>This code will create a crash due to an unterminated recursion using
|
||||
<a href="https://docs.rs/dioxus-router/latest/dioxus_router/components/fn.Outlet.html"><code>Outlet</code></a>s.</p>
|
||||
<pre><pre class="playground"><code class="language-rust no_run edition2021">
|
||||
<span class="boring">#![allow(unused)]
|
||||
</span><span class="boring">fn main() {
|
||||
</span><span class="boring">// Hidden lines (like this one) make the documentation tests work.
|
||||
</span><span class="boring">extern crate dioxus;
|
||||
</span><span class="boring">use dioxus::prelude::*;
|
||||
</span><span class="boring">extern crate dioxus_router;
|
||||
</span><span class="boring">use dioxus_router::prelude::*;
|
||||
</span><span class="boring">
|
||||
</span>fn Content(cx: Scope) -> Element {
|
||||
render! {
|
||||
h1 { "Heyho!" }
|
||||
Outlet {
|
||||
depth: 0,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
fn App(cx: Scope) -> Element {
|
||||
use_router(cx, &Default::default, &|| Segment::content(comp(Content)));
|
||||
|
||||
render! {
|
||||
Outlet { }
|
||||
}
|
||||
}
|
||||
<span class="boring">}
|
||||
</span></code></pre></pre>
|
||||
<p>The <a href="https://docs.rs/dioxus-router/latest/dioxus_router/components/fn.Outlet.html"><code>Outlet</code></a> in the <code>App</code> component has no parent <a href="https://docs.rs/dioxus-router/latest/dioxus_router/components/fn.Outlet.html"><code>Outlet</code></a>, so its depth
|
||||
will be <code>0</code>. When rendering for the path <code>/</code>, it therefore will render the
|
||||
<code>Content</code> component.</p>
|
||||
<p>The <code>Content</code> component will render an <code>h1</code> and an <a href="https://docs.rs/dioxus-router/latest/dioxus_router/components/fn.Outlet.html"><code>Outlet</code></a>. That <a href="https://docs.rs/dioxus-router/latest/dioxus_router/components/fn.Outlet.html"><code>OUtlet</code></a>
|
||||
would usually have a depth of <code>1</code>, since it is a descendant of the <a href="https://docs.rs/dioxus-router/latest/dioxus_router/components/fn.Outlet.html"><code>Outlet</code></a> in
|
||||
the <code>App</code> component. However, we override its depth to <code>0</code>, so it will render
|
||||
the <code>Content</code> component.</p>
|
||||
<p>That means the <code>Content</code> component will recurse until someone (e.g. the OS) puts
|
||||
a stop to it.</p>
|
||||
|
||||
</main>
|
||||
|
||||
<nav class="nav-wrapper" aria-label="Page navigation">
|
||||
<!-- Mobile navigation buttons -->
|
||||
<a rel="prev" href="../features/routes/multiple-and-redirect.html" class="mobile-nav-chapters previous" title="Previous chapter" aria-label="Previous chapter" aria-keyshortcuts="Left">
|
||||
<i class="fa fa-angle-left"></i>
|
||||
</a>
|
||||
|
||||
<a rel="next" href="../features/navigation/index.html" class="mobile-nav-chapters next" title="Next chapter" aria-label="Next chapter" aria-keyshortcuts="Right">
|
||||
<i class="fa fa-angle-right"></i>
|
||||
</a>
|
||||
|
||||
<div style="clear: both"></div>
|
||||
</nav>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<nav class="nav-wide-wrapper" aria-label="Page navigation">
|
||||
<a rel="prev" href="../features/routes/multiple-and-redirect.html" class="nav-chapters previous" title="Previous chapter" aria-label="Previous chapter" aria-keyshortcuts="Left">
|
||||
<i class="fa fa-angle-left"></i>
|
||||
</a>
|
||||
|
||||
<a rel="next" href="../features/navigation/index.html" class="nav-chapters next" title="Next chapter" aria-label="Next chapter" aria-keyshortcuts="Right">
|
||||
<i class="fa fa-angle-right"></i>
|
||||
</a>
|
||||
</nav>
|
||||
|
||||
</div>
|
||||
|
||||
|
||||
|
||||
|
||||
<script type="text/javascript">
|
||||
window.playground_copyable = true;
|
||||
</script>
|
||||
|
||||
|
||||
<script src="../elasticlunr.min.js" type="text/javascript" charset="utf-8"></script>
|
||||
<script src="../mark.min.js" type="text/javascript" charset="utf-8"></script>
|
||||
<script src="../searcher.js" type="text/javascript" charset="utf-8"></script>
|
||||
|
||||
<script src="../clipboard.min.js" type="text/javascript" charset="utf-8"></script>
|
||||
<script src="../highlight.js" type="text/javascript" charset="utf-8"></script>
|
||||
<script src="../book.js" type="text/javascript" charset="utf-8"></script>
|
||||
|
||||
<!-- Custom JS scripts -->
|
||||
|
||||
|
||||
</body>
|
||||
</html>
|
||||
@@ -0,0 +1,276 @@
|
||||
<!DOCTYPE HTML>
|
||||
<html lang="en" class="sidebar-visible no-js light">
|
||||
<head>
|
||||
<!-- Book generated using mdBook -->
|
||||
<meta charset="UTF-8">
|
||||
<title>Query - Dioxus Router</title>
|
||||
|
||||
|
||||
<!-- Custom HTML head -->
|
||||
|
||||
<meta content="text/html; charset=utf-8" http-equiv="Content-Type">
|
||||
<meta name="description" content="">
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1">
|
||||
<meta name="theme-color" content="#ffffff" />
|
||||
|
||||
<link rel="icon" href="../favicon.svg">
|
||||
<link rel="shortcut icon" href="../favicon.png">
|
||||
<link rel="stylesheet" href="../css/variables.css">
|
||||
<link rel="stylesheet" href="../css/general.css">
|
||||
<link rel="stylesheet" href="../css/chrome.css">
|
||||
<link rel="stylesheet" href="../css/print.css" media="print">
|
||||
|
||||
<!-- Fonts -->
|
||||
<link rel="stylesheet" href="../FontAwesome/css/font-awesome.css">
|
||||
<link rel="stylesheet" href="../fonts/fonts.css">
|
||||
|
||||
<!-- Highlight.js Stylesheets -->
|
||||
<link rel="stylesheet" href="../highlight.css">
|
||||
<link rel="stylesheet" href="../tomorrow-night.css">
|
||||
<link rel="stylesheet" href="../ayu-highlight.css">
|
||||
|
||||
<!-- Custom theme stylesheets -->
|
||||
|
||||
</head>
|
||||
<body>
|
||||
<!-- Provide site root to javascript -->
|
||||
<script type="text/javascript">
|
||||
var path_to_root = "../";
|
||||
var default_theme = window.matchMedia("(prefers-color-scheme: dark)").matches ? "navy" : "light";
|
||||
</script>
|
||||
|
||||
<!-- Work around some values being stored in localStorage wrapped in quotes -->
|
||||
<script type="text/javascript">
|
||||
try {
|
||||
var theme = localStorage.getItem('mdbook-theme');
|
||||
var sidebar = localStorage.getItem('mdbook-sidebar');
|
||||
|
||||
if (theme.startsWith('"') && theme.endsWith('"')) {
|
||||
localStorage.setItem('mdbook-theme', theme.slice(1, theme.length - 1));
|
||||
}
|
||||
|
||||
if (sidebar.startsWith('"') && sidebar.endsWith('"')) {
|
||||
localStorage.setItem('mdbook-sidebar', sidebar.slice(1, sidebar.length - 1));
|
||||
}
|
||||
} catch (e) { }
|
||||
</script>
|
||||
|
||||
<!-- Set the theme before any content is loaded, prevents flash -->
|
||||
<script type="text/javascript">
|
||||
var theme;
|
||||
try { theme = localStorage.getItem('mdbook-theme'); } catch(e) { }
|
||||
if (theme === null || theme === undefined) { theme = default_theme; }
|
||||
var html = document.querySelector('html');
|
||||
html.classList.remove('no-js')
|
||||
html.classList.remove('light')
|
||||
html.classList.add(theme);
|
||||
html.classList.add('js');
|
||||
</script>
|
||||
|
||||
<!-- Hide / unhide sidebar before it is displayed -->
|
||||
<script type="text/javascript">
|
||||
var html = document.querySelector('html');
|
||||
var sidebar = 'hidden';
|
||||
if (document.body.clientWidth >= 1080) {
|
||||
try { sidebar = localStorage.getItem('mdbook-sidebar'); } catch(e) { }
|
||||
sidebar = sidebar || 'visible';
|
||||
}
|
||||
html.classList.remove('sidebar-visible');
|
||||
html.classList.add("sidebar-" + sidebar);
|
||||
</script>
|
||||
|
||||
<nav id="sidebar" class="sidebar" aria-label="Table of contents">
|
||||
<div class="sidebar-scrollbox">
|
||||
<ol class="chapter"><li class="chapter-item expanded affix "><a href="../index.html">Introduction</a></li><li class="chapter-item expanded affix "><li class="part-title">Features</li><li class="chapter-item expanded "><a href="../features/index.html"><strong aria-hidden="true">1.</strong> Adding the Router to Your Application</a></li><li class="chapter-item expanded "><a href="../features/routes/index.html"><strong aria-hidden="true">2.</strong> Defining Routes</a></li><li><ol class="section"><li class="chapter-item expanded "><a href="../features/routes/nested.html"><strong aria-hidden="true">2.1.</strong> Nested Routes</a></li><li class="chapter-item expanded "><a href="../features/routes/catch_all.html"><strong aria-hidden="true">2.2.</strong> Catch All Routes</a></li><li class="chapter-item expanded "><a href="../features/routes/matching.html"><strong aria-hidden="true">2.3.</strong> Matching Routes</a></li><li class="chapter-item expanded "><a href="../features/routes/fallback.html"><strong aria-hidden="true">2.4.</strong> Fallback Routes (404 page)</a></li><li class="chapter-item expanded "><a href="../features/routes/multiple-and-redirect.html"><strong aria-hidden="true">2.5.</strong> Multiple Components & Redirects</a></li></ol></li><li class="chapter-item expanded "><a href="../features/outlets.html"><strong aria-hidden="true">3.</strong> Outlets</a></li><li class="chapter-item expanded "><a href="../features/navigation/index.html"><strong aria-hidden="true">4.</strong> Links & Navigation</a></li><li><ol class="section"><li class="chapter-item expanded "><a href="../features/navigation/name.html"><strong aria-hidden="true">4.1.</strong> Named Navigation</a></li><li class="chapter-item expanded "><a href="../features/navigation/external.html"><strong aria-hidden="true">4.2.</strong> External Navigation</a></li><li class="chapter-item expanded "><a href="../features/navigation/programmatic.html"><strong aria-hidden="true">4.3.</strong> Programmatic Navigation</a></li></ol></li><li class="chapter-item expanded "><a href="../features/query.html" class="active"><strong aria-hidden="true">5.</strong> Query</a></li><li class="chapter-item expanded "><a href="../features/failures/index.html"><strong aria-hidden="true">6.</strong> Navigation Failures</a></li><li><ol class="section"><li class="chapter-item expanded "><a href="../features/failures/named.html"><strong aria-hidden="true">6.1.</strong> Named Navigation Failure</a></li><li class="chapter-item expanded "><a href="../features/failures/external.html"><strong aria-hidden="true">6.2.</strong> External Navigation Failure</a></li><li class="chapter-item expanded "><a href="../features/failures/redirection-limit.html"><strong aria-hidden="true">6.3.</strong> Redirection Limit Failure</a></li></ol></li><li class="chapter-item expanded "><a href="../features/history-providers.html"><strong aria-hidden="true">7.</strong> History Providers</a></li><li class="chapter-item expanded "><a href="../features/history-buttons.html"><strong aria-hidden="true">8.</strong> History Buttons</a></li><li class="chapter-item expanded "><a href="../features/sitemap-generation.html"><strong aria-hidden="true">9.</strong> Sitemap Generation</a></li><li class="chapter-item expanded "><a href="../features/routing-update-callback.html"><strong aria-hidden="true">10.</strong> Routing Update Callback</a></li><li class="chapter-item expanded affix "><li class="part-title">Example Project</li><li class="chapter-item expanded "><a href="../example/index.html"><strong aria-hidden="true">11.</strong> Overview</a></li><li class="chapter-item expanded "><a href="../example/first-route.html"><strong aria-hidden="true">12.</strong> Creating Our First Route</a></li><li class="chapter-item expanded "><a href="../example/building-a-nest.html"><strong aria-hidden="true">13.</strong> Building a Nest</a></li><li class="chapter-item expanded "><a href="../example/navigation-targets.html"><strong aria-hidden="true">14.</strong> Navigation Targets</a></li><li class="chapter-item expanded "><a href="../example/redirection-perfection.html"><strong aria-hidden="true">15.</strong> Redirection Perfection</a></li><li class="chapter-item expanded "><a href="../example/full-code.html"><strong aria-hidden="true">16.</strong> Full Code</a></li></ol>
|
||||
</div>
|
||||
<div id="sidebar-resize-handle" class="sidebar-resize-handle"></div>
|
||||
</nav>
|
||||
|
||||
<div id="page-wrapper" class="page-wrapper">
|
||||
|
||||
<div class="page">
|
||||
<div id="menu-bar-hover-placeholder"></div>
|
||||
<div id="menu-bar" class="menu-bar sticky bordered">
|
||||
<div class="left-buttons">
|
||||
<button id="sidebar-toggle" class="icon-button" type="button" title="Toggle Table of Contents" aria-label="Toggle Table of Contents" aria-controls="sidebar">
|
||||
<i class="fa fa-bars"></i>
|
||||
</button>
|
||||
<button id="theme-toggle" class="icon-button" type="button" title="Change theme" aria-label="Change theme" aria-haspopup="true" aria-expanded="false" aria-controls="theme-list">
|
||||
<i class="fa fa-paint-brush"></i>
|
||||
</button>
|
||||
<ul id="theme-list" class="theme-popup" aria-label="Themes" role="menu">
|
||||
<li role="none"><button role="menuitem" class="theme" id="light">Light (default)</button></li>
|
||||
<li role="none"><button role="menuitem" class="theme" id="rust">Rust</button></li>
|
||||
<li role="none"><button role="menuitem" class="theme" id="coal">Coal</button></li>
|
||||
<li role="none"><button role="menuitem" class="theme" id="navy">Navy</button></li>
|
||||
<li role="none"><button role="menuitem" class="theme" id="ayu">Ayu</button></li>
|
||||
</ul>
|
||||
<button id="search-toggle" class="icon-button" type="button" title="Search. (Shortkey: s)" aria-label="Toggle Searchbar" aria-expanded="false" aria-keyshortcuts="S" aria-controls="searchbar">
|
||||
<i class="fa fa-search"></i>
|
||||
</button>
|
||||
</div>
|
||||
|
||||
<h1 class="menu-title">Dioxus Router</h1>
|
||||
|
||||
<div class="right-buttons">
|
||||
<a href="../print.html" title="Print this book" aria-label="Print this book">
|
||||
<i id="print-button" class="fa fa-print"></i>
|
||||
</a>
|
||||
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div id="search-wrapper" class="hidden">
|
||||
<form id="searchbar-outer" class="searchbar-outer">
|
||||
<input type="search" id="searchbar" name="searchbar" placeholder="Search this book ..." aria-controls="searchresults-outer" aria-describedby="searchresults-header">
|
||||
</form>
|
||||
<div id="searchresults-outer" class="searchresults-outer hidden">
|
||||
<div id="searchresults-header" class="searchresults-header"></div>
|
||||
<ul id="searchresults">
|
||||
</ul>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- Apply ARIA attributes after the sidebar and the sidebar toggle button are added to the DOM -->
|
||||
<script type="text/javascript">
|
||||
document.getElementById('sidebar-toggle').setAttribute('aria-expanded', sidebar === 'visible');
|
||||
document.getElementById('sidebar').setAttribute('aria-hidden', sidebar !== 'visible');
|
||||
Array.from(document.querySelectorAll('#sidebar a')).forEach(function(link) {
|
||||
link.setAttribute('tabIndex', sidebar === 'visible' ? 0 : -1);
|
||||
});
|
||||
</script>
|
||||
|
||||
<div id="content" class="content">
|
||||
<main>
|
||||
<h1 id="query"><a class="header" href="#query">Query</a></h1>
|
||||
<p>Some apps use the query part of the URL to encode information. The router allows
|
||||
you to easily access the query, as well as set it when navigating.</p>
|
||||
<h2 id="accessing-the-query"><a class="header" href="#accessing-the-query">Accessing the query</a></h2>
|
||||
<p>The <a href="https://docs.rs/dioxus-router/latest/dioxus_router/hooks/fn.use_route.html"><code>use_route</code></a> hook allows us to access the current query in two ways. The
|
||||
returned <code>struct</code> contains a <code>query</code> field, that contains the query (without the
|
||||
leading <code>?</code>).</p>
|
||||
<pre><pre class="playground"><code class="language-rust no_run edition2021">
|
||||
<span class="boring">#![allow(unused)]
|
||||
</span><span class="boring">fn main() {
|
||||
</span><span class="boring">// Hidden lines (like this one) make the documentation tests work.
|
||||
</span><span class="boring">extern crate dioxus;
|
||||
</span>use dioxus::prelude::*;
|
||||
<span class="boring">extern crate dioxus_router;
|
||||
</span>use dioxus_router::prelude::*;
|
||||
|
||||
fn SomeComponent(cx: Scope) -> Element {
|
||||
let route = use_route(cx).expect("nested in Router");
|
||||
|
||||
let query = route.query.clone().unwrap();
|
||||
|
||||
// ...
|
||||
<span class="boring"> unimplemented!()
|
||||
</span>}
|
||||
<span class="boring">}
|
||||
</span></code></pre></pre>
|
||||
<h2 id="setting-the-query"><a class="header" href="#setting-the-query">Setting the query</a></h2>
|
||||
<p>When navigating we can tell the router to change the query. However, the method
|
||||
we use to do this is very different, depending on how we specify our target.</p>
|
||||
<h3 id="internal-and-external"><a class="header" href="#internal-and-external"><a href="https://docs.rs/dioxus-router-core/latest/dioxus_router_core/navigation/enum.NavigationTarget.html#variant.Internal"><code>Internal</code></a> and <a href="https://docs.rs/dioxus-router-core/latest/dioxus_router_core/navigation/enum.NavigationTarget.html#variant.External"><code>External</code></a></a></h3>
|
||||
<p>When using <a href="https://docs.rs/dioxus-router-core/latest/dioxus_router_core/navigation/enum.NavigationTarget.html#variant.Internal"><code>Internal</code></a> or <a href="https://docs.rs/dioxus-router-core/latest/dioxus_router_core/navigation/enum.NavigationTarget.html#variant.External"><code>External</code></a> we have to append our query manually.</p>
|
||||
<pre><pre class="playground"><code class="language-rust no_run edition2021">
|
||||
<span class="boring">#![allow(unused)]
|
||||
</span><span class="boring">fn main() {
|
||||
</span><span class="boring">// Hidden lines (like this one) make the documentation tests work.
|
||||
</span><span class="boring">extern crate dioxus;
|
||||
</span><span class="boring">use dioxus::prelude::*;
|
||||
</span><span class="boring">extern crate dioxus_router;
|
||||
</span><span class="boring">use dioxus_router::prelude::*;
|
||||
</span><span class="boring">
|
||||
</span>fn SomeComponent(cx: Scope) -> Element {
|
||||
render! {
|
||||
Link {
|
||||
target: NavigationTarget::Internal("/some/path?query=yes".into()),
|
||||
"Internal target"
|
||||
}
|
||||
Link {
|
||||
target: NavigationTarget::External("https://dioxuslab.com?query=yes".into()),
|
||||
"External target"
|
||||
}
|
||||
}
|
||||
}
|
||||
<span class="boring">}
|
||||
</span></code></pre></pre>
|
||||
<h3 id="named"><a class="header" href="#named"><a href="https://docs.rs/dioxus-router-core/latest/dioxus_router_core/navigation/enum.NavigationTarget.html#variant.Named"><code>Named</code></a></a></h3>
|
||||
<p>When using <a href="./navigation/name.html">named navigation</a> we can pass the query via
|
||||
a function.</p>
|
||||
<pre><pre class="playground"><code class="language-rust no_run edition2021">
|
||||
<span class="boring">#![allow(unused)]
|
||||
</span><span class="boring">fn main() {
|
||||
</span><span class="boring">// Hidden lines (like this one) make the documentation tests work.
|
||||
</span><span class="boring">extern crate dioxus;
|
||||
</span><span class="boring">use dioxus::prelude::*;
|
||||
</span><span class="boring">extern crate dioxus_router;
|
||||
</span><span class="boring">use dioxus_router::prelude::*;
|
||||
</span><span class="boring">struct Target;
|
||||
</span><span class="boring">
|
||||
</span>fn SomeComponent(cx: Scope) -> Element {
|
||||
render! {
|
||||
Link {
|
||||
target: named::<Target>().query("query=yes"),
|
||||
"Query String"
|
||||
}
|
||||
Link {
|
||||
target: named::<Target>().query(vec![("query", "yes")]),
|
||||
"Query Vec"
|
||||
}
|
||||
}
|
||||
}
|
||||
<span class="boring">}
|
||||
</span></code></pre></pre>
|
||||
|
||||
</main>
|
||||
|
||||
<nav class="nav-wrapper" aria-label="Page navigation">
|
||||
<!-- Mobile navigation buttons -->
|
||||
<a rel="prev" href="../features/navigation/programmatic.html" class="mobile-nav-chapters previous" title="Previous chapter" aria-label="Previous chapter" aria-keyshortcuts="Left">
|
||||
<i class="fa fa-angle-left"></i>
|
||||
</a>
|
||||
|
||||
<a rel="next" href="../features/failures/index.html" class="mobile-nav-chapters next" title="Next chapter" aria-label="Next chapter" aria-keyshortcuts="Right">
|
||||
<i class="fa fa-angle-right"></i>
|
||||
</a>
|
||||
|
||||
<div style="clear: both"></div>
|
||||
</nav>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<nav class="nav-wide-wrapper" aria-label="Page navigation">
|
||||
<a rel="prev" href="../features/navigation/programmatic.html" class="nav-chapters previous" title="Previous chapter" aria-label="Previous chapter" aria-keyshortcuts="Left">
|
||||
<i class="fa fa-angle-left"></i>
|
||||
</a>
|
||||
|
||||
<a rel="next" href="../features/failures/index.html" class="nav-chapters next" title="Next chapter" aria-label="Next chapter" aria-keyshortcuts="Right">
|
||||
<i class="fa fa-angle-right"></i>
|
||||
</a>
|
||||
</nav>
|
||||
|
||||
</div>
|
||||
|
||||
|
||||
|
||||
|
||||
<script type="text/javascript">
|
||||
window.playground_copyable = true;
|
||||
</script>
|
||||
|
||||
|
||||
<script src="../elasticlunr.min.js" type="text/javascript" charset="utf-8"></script>
|
||||
<script src="../mark.min.js" type="text/javascript" charset="utf-8"></script>
|
||||
<script src="../searcher.js" type="text/javascript" charset="utf-8"></script>
|
||||
|
||||
<script src="../clipboard.min.js" type="text/javascript" charset="utf-8"></script>
|
||||
<script src="../highlight.js" type="text/javascript" charset="utf-8"></script>
|
||||
<script src="../book.js" type="text/javascript" charset="utf-8"></script>
|
||||
|
||||
<!-- Custom JS scripts -->
|
||||
|
||||
|
||||
</body>
|
||||
</html>
|
||||
@@ -0,0 +1,357 @@
|
||||
<!DOCTYPE HTML>
|
||||
<html lang="en" class="sidebar-visible no-js light">
|
||||
<head>
|
||||
<!-- Book generated using mdBook -->
|
||||
<meta charset="UTF-8">
|
||||
<title>Catch All Routes - Dioxus Router</title>
|
||||
|
||||
|
||||
<!-- Custom HTML head -->
|
||||
|
||||
<meta content="text/html; charset=utf-8" http-equiv="Content-Type">
|
||||
<meta name="description" content="">
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1">
|
||||
<meta name="theme-color" content="#ffffff" />
|
||||
|
||||
<link rel="icon" href="../../favicon.svg">
|
||||
<link rel="shortcut icon" href="../../favicon.png">
|
||||
<link rel="stylesheet" href="../../css/variables.css">
|
||||
<link rel="stylesheet" href="../../css/general.css">
|
||||
<link rel="stylesheet" href="../../css/chrome.css">
|
||||
<link rel="stylesheet" href="../../css/print.css" media="print">
|
||||
|
||||
<!-- Fonts -->
|
||||
<link rel="stylesheet" href="../../FontAwesome/css/font-awesome.css">
|
||||
<link rel="stylesheet" href="../../fonts/fonts.css">
|
||||
|
||||
<!-- Highlight.js Stylesheets -->
|
||||
<link rel="stylesheet" href="../../highlight.css">
|
||||
<link rel="stylesheet" href="../../tomorrow-night.css">
|
||||
<link rel="stylesheet" href="../../ayu-highlight.css">
|
||||
|
||||
<!-- Custom theme stylesheets -->
|
||||
|
||||
</head>
|
||||
<body>
|
||||
<!-- Provide site root to javascript -->
|
||||
<script type="text/javascript">
|
||||
var path_to_root = "../../";
|
||||
var default_theme = window.matchMedia("(prefers-color-scheme: dark)").matches ? "navy" : "light";
|
||||
</script>
|
||||
|
||||
<!-- Work around some values being stored in localStorage wrapped in quotes -->
|
||||
<script type="text/javascript">
|
||||
try {
|
||||
var theme = localStorage.getItem('mdbook-theme');
|
||||
var sidebar = localStorage.getItem('mdbook-sidebar');
|
||||
|
||||
if (theme.startsWith('"') && theme.endsWith('"')) {
|
||||
localStorage.setItem('mdbook-theme', theme.slice(1, theme.length - 1));
|
||||
}
|
||||
|
||||
if (sidebar.startsWith('"') && sidebar.endsWith('"')) {
|
||||
localStorage.setItem('mdbook-sidebar', sidebar.slice(1, sidebar.length - 1));
|
||||
}
|
||||
} catch (e) { }
|
||||
</script>
|
||||
|
||||
<!-- Set the theme before any content is loaded, prevents flash -->
|
||||
<script type="text/javascript">
|
||||
var theme;
|
||||
try { theme = localStorage.getItem('mdbook-theme'); } catch(e) { }
|
||||
if (theme === null || theme === undefined) { theme = default_theme; }
|
||||
var html = document.querySelector('html');
|
||||
html.classList.remove('no-js')
|
||||
html.classList.remove('light')
|
||||
html.classList.add(theme);
|
||||
html.classList.add('js');
|
||||
</script>
|
||||
|
||||
<!-- Hide / unhide sidebar before it is displayed -->
|
||||
<script type="text/javascript">
|
||||
var html = document.querySelector('html');
|
||||
var sidebar = 'hidden';
|
||||
if (document.body.clientWidth >= 1080) {
|
||||
try { sidebar = localStorage.getItem('mdbook-sidebar'); } catch(e) { }
|
||||
sidebar = sidebar || 'visible';
|
||||
}
|
||||
html.classList.remove('sidebar-visible');
|
||||
html.classList.add("sidebar-" + sidebar);
|
||||
</script>
|
||||
|
||||
<nav id="sidebar" class="sidebar" aria-label="Table of contents">
|
||||
<div class="sidebar-scrollbox">
|
||||
<ol class="chapter"><li class="chapter-item expanded affix "><a href="../../index.html">Introduction</a></li><li class="chapter-item expanded affix "><li class="part-title">Features</li><li class="chapter-item expanded "><a href="../../features/index.html"><strong aria-hidden="true">1.</strong> Adding the Router to Your Application</a></li><li class="chapter-item expanded "><a href="../../features/routes/index.html"><strong aria-hidden="true">2.</strong> Defining Routes</a></li><li><ol class="section"><li class="chapter-item expanded "><a href="../../features/routes/nested.html"><strong aria-hidden="true">2.1.</strong> Nested Routes</a></li><li class="chapter-item expanded "><a href="../../features/routes/catch_all.html" class="active"><strong aria-hidden="true">2.2.</strong> Catch All Routes</a></li><li class="chapter-item expanded "><a href="../../features/routes/matching.html"><strong aria-hidden="true">2.3.</strong> Matching Routes</a></li><li class="chapter-item expanded "><a href="../../features/routes/fallback.html"><strong aria-hidden="true">2.4.</strong> Fallback Routes (404 page)</a></li><li class="chapter-item expanded "><a href="../../features/routes/multiple-and-redirect.html"><strong aria-hidden="true">2.5.</strong> Multiple Components & Redirects</a></li></ol></li><li class="chapter-item expanded "><a href="../../features/outlets.html"><strong aria-hidden="true">3.</strong> Outlets</a></li><li class="chapter-item expanded "><a href="../../features/navigation/index.html"><strong aria-hidden="true">4.</strong> Links & Navigation</a></li><li><ol class="section"><li class="chapter-item expanded "><a href="../../features/navigation/name.html"><strong aria-hidden="true">4.1.</strong> Named Navigation</a></li><li class="chapter-item expanded "><a href="../../features/navigation/external.html"><strong aria-hidden="true">4.2.</strong> External Navigation</a></li><li class="chapter-item expanded "><a href="../../features/navigation/programmatic.html"><strong aria-hidden="true">4.3.</strong> Programmatic Navigation</a></li></ol></li><li class="chapter-item expanded "><a href="../../features/query.html"><strong aria-hidden="true">5.</strong> Query</a></li><li class="chapter-item expanded "><a href="../../features/failures/index.html"><strong aria-hidden="true">6.</strong> Navigation Failures</a></li><li><ol class="section"><li class="chapter-item expanded "><a href="../../features/failures/named.html"><strong aria-hidden="true">6.1.</strong> Named Navigation Failure</a></li><li class="chapter-item expanded "><a href="../../features/failures/external.html"><strong aria-hidden="true">6.2.</strong> External Navigation Failure</a></li><li class="chapter-item expanded "><a href="../../features/failures/redirection-limit.html"><strong aria-hidden="true">6.3.</strong> Redirection Limit Failure</a></li></ol></li><li class="chapter-item expanded "><a href="../../features/history-providers.html"><strong aria-hidden="true">7.</strong> History Providers</a></li><li class="chapter-item expanded "><a href="../../features/history-buttons.html"><strong aria-hidden="true">8.</strong> History Buttons</a></li><li class="chapter-item expanded "><a href="../../features/sitemap-generation.html"><strong aria-hidden="true">9.</strong> Sitemap Generation</a></li><li class="chapter-item expanded "><a href="../../features/routing-update-callback.html"><strong aria-hidden="true">10.</strong> Routing Update Callback</a></li><li class="chapter-item expanded affix "><li class="part-title">Example Project</li><li class="chapter-item expanded "><a href="../../example/index.html"><strong aria-hidden="true">11.</strong> Overview</a></li><li class="chapter-item expanded "><a href="../../example/first-route.html"><strong aria-hidden="true">12.</strong> Creating Our First Route</a></li><li class="chapter-item expanded "><a href="../../example/building-a-nest.html"><strong aria-hidden="true">13.</strong> Building a Nest</a></li><li class="chapter-item expanded "><a href="../../example/navigation-targets.html"><strong aria-hidden="true">14.</strong> Navigation Targets</a></li><li class="chapter-item expanded "><a href="../../example/redirection-perfection.html"><strong aria-hidden="true">15.</strong> Redirection Perfection</a></li><li class="chapter-item expanded "><a href="../../example/full-code.html"><strong aria-hidden="true">16.</strong> Full Code</a></li></ol>
|
||||
</div>
|
||||
<div id="sidebar-resize-handle" class="sidebar-resize-handle"></div>
|
||||
</nav>
|
||||
|
||||
<div id="page-wrapper" class="page-wrapper">
|
||||
|
||||
<div class="page">
|
||||
<div id="menu-bar-hover-placeholder"></div>
|
||||
<div id="menu-bar" class="menu-bar sticky bordered">
|
||||
<div class="left-buttons">
|
||||
<button id="sidebar-toggle" class="icon-button" type="button" title="Toggle Table of Contents" aria-label="Toggle Table of Contents" aria-controls="sidebar">
|
||||
<i class="fa fa-bars"></i>
|
||||
</button>
|
||||
<button id="theme-toggle" class="icon-button" type="button" title="Change theme" aria-label="Change theme" aria-haspopup="true" aria-expanded="false" aria-controls="theme-list">
|
||||
<i class="fa fa-paint-brush"></i>
|
||||
</button>
|
||||
<ul id="theme-list" class="theme-popup" aria-label="Themes" role="menu">
|
||||
<li role="none"><button role="menuitem" class="theme" id="light">Light (default)</button></li>
|
||||
<li role="none"><button role="menuitem" class="theme" id="rust">Rust</button></li>
|
||||
<li role="none"><button role="menuitem" class="theme" id="coal">Coal</button></li>
|
||||
<li role="none"><button role="menuitem" class="theme" id="navy">Navy</button></li>
|
||||
<li role="none"><button role="menuitem" class="theme" id="ayu">Ayu</button></li>
|
||||
</ul>
|
||||
<button id="search-toggle" class="icon-button" type="button" title="Search. (Shortkey: s)" aria-label="Toggle Searchbar" aria-expanded="false" aria-keyshortcuts="S" aria-controls="searchbar">
|
||||
<i class="fa fa-search"></i>
|
||||
</button>
|
||||
</div>
|
||||
|
||||
<h1 class="menu-title">Dioxus Router</h1>
|
||||
|
||||
<div class="right-buttons">
|
||||
<a href="../../print.html" title="Print this book" aria-label="Print this book">
|
||||
<i id="print-button" class="fa fa-print"></i>
|
||||
</a>
|
||||
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div id="search-wrapper" class="hidden">
|
||||
<form id="searchbar-outer" class="searchbar-outer">
|
||||
<input type="search" id="searchbar" name="searchbar" placeholder="Search this book ..." aria-controls="searchresults-outer" aria-describedby="searchresults-header">
|
||||
</form>
|
||||
<div id="searchresults-outer" class="searchresults-outer hidden">
|
||||
<div id="searchresults-header" class="searchresults-header"></div>
|
||||
<ul id="searchresults">
|
||||
</ul>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- Apply ARIA attributes after the sidebar and the sidebar toggle button are added to the DOM -->
|
||||
<script type="text/javascript">
|
||||
document.getElementById('sidebar-toggle').setAttribute('aria-expanded', sidebar === 'visible');
|
||||
document.getElementById('sidebar').setAttribute('aria-hidden', sidebar !== 'visible');
|
||||
Array.from(document.querySelectorAll('#sidebar a')).forEach(function(link) {
|
||||
link.setAttribute('tabIndex', sidebar === 'visible' ? 0 : -1);
|
||||
});
|
||||
</script>
|
||||
|
||||
<div id="content" class="content">
|
||||
<main>
|
||||
<h1 id="catch-all-routes"><a class="header" href="#catch-all-routes">Catch All Routes</a></h1>
|
||||
<p>Many modern web apps store parameters within their current path. This allows
|
||||
users to share URLs that link to a specific bit of content. We can create this
|
||||
functionality with catch all routes.</p>
|
||||
<blockquote>
|
||||
<p>If you want to change what route is active based on the format of the
|
||||
parameter, see <a href="./matching.html">Matching Routes</a>.</p>
|
||||
</blockquote>
|
||||
<blockquote>
|
||||
<p>The parameter will be URL decoded.</p>
|
||||
</blockquote>
|
||||
<h2 id="creating-a-content-component"><a class="header" href="#creating-a-content-component">Creating a content component</a></h2>
|
||||
<p>We start by creating a component that uses the parameters value.</p>
|
||||
<p>We can get the current state of the router using the <a href="https://docs.rs/dioxus-router/latest/dioxus_router/hooks/fn.use_route.html"><code>use_route</code></a> hook. From
|
||||
that state we can extract the current value of our parameter by using a key we
|
||||
will later also define on our route.</p>
|
||||
<blockquote>
|
||||
<p>It is <strong>VERY IMPORTANT</strong> to drop the object returned by the <a href="https://docs.rs/dioxus-router/latest/dioxus_router/hooks/fn.use_route.html"><code>use_route</code></a>
|
||||
hook once our component finished rendering. Otherwise the entire router will
|
||||
be frozen.</p>
|
||||
</blockquote>
|
||||
<blockquote>
|
||||
<p>The <a href="https://docs.rs/dioxus-router/latest/dioxus_router/hooks/fn.use_route.html"><code>use_route</code></a> hook can only be used in components nested within a
|
||||
component that called <a href="https://docs.rs/dioxus-router/latest/dioxus_router/hooks/fn.use_router.html"><code>use_router</code></a>.</p>
|
||||
</blockquote>
|
||||
<pre><pre class="playground"><code class="language-rust no_run edition2021">
|
||||
<span class="boring">#![allow(unused)]
|
||||
</span><span class="boring">fn main() {
|
||||
</span><span class="boring">// Hidden lines (like this one) make the documentation tests work.
|
||||
</span><span class="boring">extern crate dioxus;
|
||||
</span>use dioxus::prelude::*;
|
||||
<span class="boring">extern crate dioxus_router;
|
||||
</span>use dioxus_router::prelude::*;
|
||||
|
||||
struct Name;
|
||||
|
||||
fn Greeting(cx: Scope) -> Element {
|
||||
let route = use_route(cx).expect("is nested within a Router component");
|
||||
let name = route.parameter::<Name>()
|
||||
.map(|name| name.clone())
|
||||
.unwrap_or(String::from("world"));
|
||||
|
||||
render! {
|
||||
p { "Hello, {name}!" }
|
||||
}
|
||||
}
|
||||
<span class="boring">}
|
||||
</span></code></pre></pre>
|
||||
<h2 id="defining-the-routes"><a class="header" href="#defining-the-routes">Defining the routes</a></h2>
|
||||
<p>Now we can define our route. Unlike a fixed <a href="https://docs.rs/dioxus-router-core/latest/dioxus_router_core/routes/struct.Route.html"><code>Route</code></a>, a <a href="https://docs.rs/dioxus-router-core/latest/dioxus_router_core/routes/struct.ParameterRoute.html"><code>ParameterRoute</code></a>
|
||||
needs two arguments to be created.</p>
|
||||
<blockquote>
|
||||
<p>Also note that each <a href="https://docs.rs/dioxus-router-core/latest/dioxus_router_core/routes/struct.Segment.html"><code>Segment</code></a> can have exactly one parameter or
|
||||
<a href="./fallback.html">fallback route</a>.</p>
|
||||
<p>For that reason, the example below would not work in practice, but showing
|
||||
both forms (explicit and short) is more important for this example.</p>
|
||||
</blockquote>
|
||||
<pre><pre class="playground"><code class="language-rust no_run edition2021">
|
||||
<span class="boring">#![allow(unused)]
|
||||
</span><span class="boring">fn main() {
|
||||
</span><span class="boring">// Hidden lines (like this one) make the documentation tests work.
|
||||
</span><span class="boring">extern crate dioxus;
|
||||
</span><span class="boring">use dioxus::prelude::*;
|
||||
</span><span class="boring">extern crate dioxus_router;
|
||||
</span><span class="boring">use dioxus_router::prelude::*;
|
||||
</span><span class="boring">fn Greeting(cx: Scope) -> Element { unimplemented!() }
|
||||
</span><span class="boring">
|
||||
</span>struct Name;
|
||||
|
||||
fn App(cx: Scope) -> Element {
|
||||
use_router(
|
||||
cx,
|
||||
&|| RouterConfiguration {
|
||||
..Default::default()
|
||||
},
|
||||
&|| {
|
||||
Segment::empty()
|
||||
.catch_all(ParameterRoute::content::<Name>(comp(Greeting)))
|
||||
.catch_all((comp(Greeting), Name { })) // same in short
|
||||
}
|
||||
);
|
||||
|
||||
// ...
|
||||
<span class="boring"> unimplemented!()
|
||||
</span>}
|
||||
<span class="boring">}
|
||||
</span></code></pre></pre>
|
||||
<h2 id="interaction-with-other-routes"><a class="header" href="#interaction-with-other-routes">Interaction with other routes</a></h2>
|
||||
<p>Each individual <a href="https://docs.rs/dioxus-router-core/latest/dioxus_router_core/routes/struct.Segment.html"><code>Segment</code></a> can only ever have one active route. This means that
|
||||
when a <a href="https://docs.rs/dioxus-router-core/latest/dioxus_router_core/routes/struct.Segment.html"><code>Segment</code></a> has more than just a catch all route, the router has to
|
||||
decide which is active. It does that this way:</p>
|
||||
<ol start="0">
|
||||
<li>If the segment is not specified (i.e. <code>/</code>), then the index route will be
|
||||
active.</li>
|
||||
<li>If a <a href="./index.html#fixed-routes"><em>fixed</em></a> route matches the current path, it
|
||||
will be active.</li>
|
||||
<li>If a <a href="./matching.html"><em>matching</em> route</a> matches the current path, it will be
|
||||
active. <em>Matching</em> routes are checked in the order they are defined.</li>
|
||||
<li>If neither a <em>fixed</em> nor a <em>matching</em> route is active, the <em>catch all</em> route
|
||||
or <a href="./fallback.html"><em>fallback</em> route</a> will be.</li>
|
||||
</ol>
|
||||
<p>Step 0 means that if we want a parameter to be empty, that needs to be specified
|
||||
by the path, i.e. <code>//</code>.</p>
|
||||
<blockquote>
|
||||
<p>Be careful with using catch all routes on the root <a href="https://docs.rs/dioxus-router-core/latest/dioxus_router_core/routes/struct.Segment.html"><code>Segment</code></a>. Navigating to
|
||||
paths starting with <code>//</code> will <strong>NOT</strong> work. This is not a limitation of the
|
||||
router, but rather of how relative URLs work.</p>
|
||||
<p>If you absolutely need an empty parameter on the root <a href="https://docs.rs/dioxus-router-core/latest/dioxus_router_core/routes/struct.Segment.html"><code>Segment</code></a>, a URL like
|
||||
this <em>could</em> work:</p>
|
||||
<ul>
|
||||
<li><code>https://your-site.example//</code> for web sites</li>
|
||||
<li><code>dioxus://index.html//</code> for desktop apps</li>
|
||||
</ul>
|
||||
</blockquote>
|
||||
<h2 id="full-code"><a class="header" href="#full-code">Full Code</a></h2>
|
||||
<pre><pre class="playground"><code class="language-rust edition2021">
|
||||
<span class="boring">#![allow(unused)]
|
||||
</span><span class="boring">fn main() {
|
||||
</span><span class="boring">// Hidden lines (like this one) make the documentation tests work.
|
||||
</span><span class="boring">extern crate dioxus;
|
||||
</span><span class="boring">use dioxus::prelude::*;
|
||||
</span><span class="boring">extern crate dioxus_router;
|
||||
</span><span class="boring">use dioxus_router::{history::MemoryHistory, prelude::*};
|
||||
</span><span class="boring">extern crate dioxus_ssr;
|
||||
</span><span class="boring">
|
||||
</span>struct Name;
|
||||
|
||||
fn Greeting(cx: Scope) -> Element {
|
||||
let route = use_route(cx).expect("is nested within a Router component");
|
||||
let name = route.parameter::<Name>()
|
||||
.map(|name| name.clone())
|
||||
.unwrap_or(String::from("world"));
|
||||
|
||||
render! {
|
||||
p { "Hello, {name}!" }
|
||||
}
|
||||
}
|
||||
|
||||
fn App(cx: Scope) -> Element {
|
||||
let routes = use_router(
|
||||
cx,
|
||||
&|| RouterConfiguration {
|
||||
<span class="boring"> synchronous: true,
|
||||
</span><span class="boring"> history: Box::new(MemoryHistory::with_initial_path("/Dioxus").unwrap()),
|
||||
</span> ..Default::default()
|
||||
},
|
||||
&|| Segment::empty().catch_all((comp(Greeting), Name { }))
|
||||
);
|
||||
// ...
|
||||
render! {
|
||||
Outlet { }
|
||||
}
|
||||
}
|
||||
<span class="boring">
|
||||
</span><span class="boring">let mut vdom = VirtualDom::new(App);
|
||||
</span><span class="boring">vdom.rebuild();
|
||||
</span><span class="boring">assert_eq!(
|
||||
</span><span class="boring"> dioxus_ssr::render(&vdom),
|
||||
</span><span class="boring"> "<p>Hello, Dioxus!</p>"
|
||||
</span><span class="boring">);
|
||||
</span><span class="boring">}
|
||||
</span></code></pre></pre>
|
||||
|
||||
</main>
|
||||
|
||||
<nav class="nav-wrapper" aria-label="Page navigation">
|
||||
<!-- Mobile navigation buttons -->
|
||||
<a rel="prev" href="../../features/routes/nested.html" class="mobile-nav-chapters previous" title="Previous chapter" aria-label="Previous chapter" aria-keyshortcuts="Left">
|
||||
<i class="fa fa-angle-left"></i>
|
||||
</a>
|
||||
|
||||
<a rel="next" href="../../features/routes/matching.html" class="mobile-nav-chapters next" title="Next chapter" aria-label="Next chapter" aria-keyshortcuts="Right">
|
||||
<i class="fa fa-angle-right"></i>
|
||||
</a>
|
||||
|
||||
<div style="clear: both"></div>
|
||||
</nav>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<nav class="nav-wide-wrapper" aria-label="Page navigation">
|
||||
<a rel="prev" href="../../features/routes/nested.html" class="nav-chapters previous" title="Previous chapter" aria-label="Previous chapter" aria-keyshortcuts="Left">
|
||||
<i class="fa fa-angle-left"></i>
|
||||
</a>
|
||||
|
||||
<a rel="next" href="../../features/routes/matching.html" class="nav-chapters next" title="Next chapter" aria-label="Next chapter" aria-keyshortcuts="Right">
|
||||
<i class="fa fa-angle-right"></i>
|
||||
</a>
|
||||
</nav>
|
||||
|
||||
</div>
|
||||
|
||||
|
||||
|
||||
|
||||
<script type="text/javascript">
|
||||
window.playground_copyable = true;
|
||||
</script>
|
||||
|
||||
|
||||
<script src="../../elasticlunr.min.js" type="text/javascript" charset="utf-8"></script>
|
||||
<script src="../../mark.min.js" type="text/javascript" charset="utf-8"></script>
|
||||
<script src="../../searcher.js" type="text/javascript" charset="utf-8"></script>
|
||||
|
||||
<script src="../../clipboard.min.js" type="text/javascript" charset="utf-8"></script>
|
||||
<script src="../../highlight.js" type="text/javascript" charset="utf-8"></script>
|
||||
<script src="../../book.js" type="text/javascript" charset="utf-8"></script>
|
||||
|
||||
<!-- Custom JS scripts -->
|
||||
|
||||
|
||||
</body>
|
||||
</html>
|
||||
@@ -0,0 +1,330 @@
|
||||
<!DOCTYPE HTML>
|
||||
<html lang="en" class="sidebar-visible no-js light">
|
||||
<head>
|
||||
<!-- Book generated using mdBook -->
|
||||
<meta charset="UTF-8">
|
||||
<title>Fallback Routes (404 page) - Dioxus Router</title>
|
||||
|
||||
|
||||
<!-- Custom HTML head -->
|
||||
|
||||
<meta content="text/html; charset=utf-8" http-equiv="Content-Type">
|
||||
<meta name="description" content="">
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1">
|
||||
<meta name="theme-color" content="#ffffff" />
|
||||
|
||||
<link rel="icon" href="../../favicon.svg">
|
||||
<link rel="shortcut icon" href="../../favicon.png">
|
||||
<link rel="stylesheet" href="../../css/variables.css">
|
||||
<link rel="stylesheet" href="../../css/general.css">
|
||||
<link rel="stylesheet" href="../../css/chrome.css">
|
||||
<link rel="stylesheet" href="../../css/print.css" media="print">
|
||||
|
||||
<!-- Fonts -->
|
||||
<link rel="stylesheet" href="../../FontAwesome/css/font-awesome.css">
|
||||
<link rel="stylesheet" href="../../fonts/fonts.css">
|
||||
|
||||
<!-- Highlight.js Stylesheets -->
|
||||
<link rel="stylesheet" href="../../highlight.css">
|
||||
<link rel="stylesheet" href="../../tomorrow-night.css">
|
||||
<link rel="stylesheet" href="../../ayu-highlight.css">
|
||||
|
||||
<!-- Custom theme stylesheets -->
|
||||
|
||||
</head>
|
||||
<body>
|
||||
<!-- Provide site root to javascript -->
|
||||
<script type="text/javascript">
|
||||
var path_to_root = "../../";
|
||||
var default_theme = window.matchMedia("(prefers-color-scheme: dark)").matches ? "navy" : "light";
|
||||
</script>
|
||||
|
||||
<!-- Work around some values being stored in localStorage wrapped in quotes -->
|
||||
<script type="text/javascript">
|
||||
try {
|
||||
var theme = localStorage.getItem('mdbook-theme');
|
||||
var sidebar = localStorage.getItem('mdbook-sidebar');
|
||||
|
||||
if (theme.startsWith('"') && theme.endsWith('"')) {
|
||||
localStorage.setItem('mdbook-theme', theme.slice(1, theme.length - 1));
|
||||
}
|
||||
|
||||
if (sidebar.startsWith('"') && sidebar.endsWith('"')) {
|
||||
localStorage.setItem('mdbook-sidebar', sidebar.slice(1, sidebar.length - 1));
|
||||
}
|
||||
} catch (e) { }
|
||||
</script>
|
||||
|
||||
<!-- Set the theme before any content is loaded, prevents flash -->
|
||||
<script type="text/javascript">
|
||||
var theme;
|
||||
try { theme = localStorage.getItem('mdbook-theme'); } catch(e) { }
|
||||
if (theme === null || theme === undefined) { theme = default_theme; }
|
||||
var html = document.querySelector('html');
|
||||
html.classList.remove('no-js')
|
||||
html.classList.remove('light')
|
||||
html.classList.add(theme);
|
||||
html.classList.add('js');
|
||||
</script>
|
||||
|
||||
<!-- Hide / unhide sidebar before it is displayed -->
|
||||
<script type="text/javascript">
|
||||
var html = document.querySelector('html');
|
||||
var sidebar = 'hidden';
|
||||
if (document.body.clientWidth >= 1080) {
|
||||
try { sidebar = localStorage.getItem('mdbook-sidebar'); } catch(e) { }
|
||||
sidebar = sidebar || 'visible';
|
||||
}
|
||||
html.classList.remove('sidebar-visible');
|
||||
html.classList.add("sidebar-" + sidebar);
|
||||
</script>
|
||||
|
||||
<nav id="sidebar" class="sidebar" aria-label="Table of contents">
|
||||
<div class="sidebar-scrollbox">
|
||||
<ol class="chapter"><li class="chapter-item expanded affix "><a href="../../index.html">Introduction</a></li><li class="chapter-item expanded affix "><li class="part-title">Features</li><li class="chapter-item expanded "><a href="../../features/index.html"><strong aria-hidden="true">1.</strong> Adding the Router to Your Application</a></li><li class="chapter-item expanded "><a href="../../features/routes/index.html"><strong aria-hidden="true">2.</strong> Defining Routes</a></li><li><ol class="section"><li class="chapter-item expanded "><a href="../../features/routes/nested.html"><strong aria-hidden="true">2.1.</strong> Nested Routes</a></li><li class="chapter-item expanded "><a href="../../features/routes/catch_all.html"><strong aria-hidden="true">2.2.</strong> Catch All Routes</a></li><li class="chapter-item expanded "><a href="../../features/routes/matching.html"><strong aria-hidden="true">2.3.</strong> Matching Routes</a></li><li class="chapter-item expanded "><a href="../../features/routes/fallback.html" class="active"><strong aria-hidden="true">2.4.</strong> Fallback Routes (404 page)</a></li><li class="chapter-item expanded "><a href="../../features/routes/multiple-and-redirect.html"><strong aria-hidden="true">2.5.</strong> Multiple Components & Redirects</a></li></ol></li><li class="chapter-item expanded "><a href="../../features/outlets.html"><strong aria-hidden="true">3.</strong> Outlets</a></li><li class="chapter-item expanded "><a href="../../features/navigation/index.html"><strong aria-hidden="true">4.</strong> Links & Navigation</a></li><li><ol class="section"><li class="chapter-item expanded "><a href="../../features/navigation/name.html"><strong aria-hidden="true">4.1.</strong> Named Navigation</a></li><li class="chapter-item expanded "><a href="../../features/navigation/external.html"><strong aria-hidden="true">4.2.</strong> External Navigation</a></li><li class="chapter-item expanded "><a href="../../features/navigation/programmatic.html"><strong aria-hidden="true">4.3.</strong> Programmatic Navigation</a></li></ol></li><li class="chapter-item expanded "><a href="../../features/query.html"><strong aria-hidden="true">5.</strong> Query</a></li><li class="chapter-item expanded "><a href="../../features/failures/index.html"><strong aria-hidden="true">6.</strong> Navigation Failures</a></li><li><ol class="section"><li class="chapter-item expanded "><a href="../../features/failures/named.html"><strong aria-hidden="true">6.1.</strong> Named Navigation Failure</a></li><li class="chapter-item expanded "><a href="../../features/failures/external.html"><strong aria-hidden="true">6.2.</strong> External Navigation Failure</a></li><li class="chapter-item expanded "><a href="../../features/failures/redirection-limit.html"><strong aria-hidden="true">6.3.</strong> Redirection Limit Failure</a></li></ol></li><li class="chapter-item expanded "><a href="../../features/history-providers.html"><strong aria-hidden="true">7.</strong> History Providers</a></li><li class="chapter-item expanded "><a href="../../features/history-buttons.html"><strong aria-hidden="true">8.</strong> History Buttons</a></li><li class="chapter-item expanded "><a href="../../features/sitemap-generation.html"><strong aria-hidden="true">9.</strong> Sitemap Generation</a></li><li class="chapter-item expanded "><a href="../../features/routing-update-callback.html"><strong aria-hidden="true">10.</strong> Routing Update Callback</a></li><li class="chapter-item expanded affix "><li class="part-title">Example Project</li><li class="chapter-item expanded "><a href="../../example/index.html"><strong aria-hidden="true">11.</strong> Overview</a></li><li class="chapter-item expanded "><a href="../../example/first-route.html"><strong aria-hidden="true">12.</strong> Creating Our First Route</a></li><li class="chapter-item expanded "><a href="../../example/building-a-nest.html"><strong aria-hidden="true">13.</strong> Building a Nest</a></li><li class="chapter-item expanded "><a href="../../example/navigation-targets.html"><strong aria-hidden="true">14.</strong> Navigation Targets</a></li><li class="chapter-item expanded "><a href="../../example/redirection-perfection.html"><strong aria-hidden="true">15.</strong> Redirection Perfection</a></li><li class="chapter-item expanded "><a href="../../example/full-code.html"><strong aria-hidden="true">16.</strong> Full Code</a></li></ol>
|
||||
</div>
|
||||
<div id="sidebar-resize-handle" class="sidebar-resize-handle"></div>
|
||||
</nav>
|
||||
|
||||
<div id="page-wrapper" class="page-wrapper">
|
||||
|
||||
<div class="page">
|
||||
<div id="menu-bar-hover-placeholder"></div>
|
||||
<div id="menu-bar" class="menu-bar sticky bordered">
|
||||
<div class="left-buttons">
|
||||
<button id="sidebar-toggle" class="icon-button" type="button" title="Toggle Table of Contents" aria-label="Toggle Table of Contents" aria-controls="sidebar">
|
||||
<i class="fa fa-bars"></i>
|
||||
</button>
|
||||
<button id="theme-toggle" class="icon-button" type="button" title="Change theme" aria-label="Change theme" aria-haspopup="true" aria-expanded="false" aria-controls="theme-list">
|
||||
<i class="fa fa-paint-brush"></i>
|
||||
</button>
|
||||
<ul id="theme-list" class="theme-popup" aria-label="Themes" role="menu">
|
||||
<li role="none"><button role="menuitem" class="theme" id="light">Light (default)</button></li>
|
||||
<li role="none"><button role="menuitem" class="theme" id="rust">Rust</button></li>
|
||||
<li role="none"><button role="menuitem" class="theme" id="coal">Coal</button></li>
|
||||
<li role="none"><button role="menuitem" class="theme" id="navy">Navy</button></li>
|
||||
<li role="none"><button role="menuitem" class="theme" id="ayu">Ayu</button></li>
|
||||
</ul>
|
||||
<button id="search-toggle" class="icon-button" type="button" title="Search. (Shortkey: s)" aria-label="Toggle Searchbar" aria-expanded="false" aria-keyshortcuts="S" aria-controls="searchbar">
|
||||
<i class="fa fa-search"></i>
|
||||
</button>
|
||||
</div>
|
||||
|
||||
<h1 class="menu-title">Dioxus Router</h1>
|
||||
|
||||
<div class="right-buttons">
|
||||
<a href="../../print.html" title="Print this book" aria-label="Print this book">
|
||||
<i id="print-button" class="fa fa-print"></i>
|
||||
</a>
|
||||
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div id="search-wrapper" class="hidden">
|
||||
<form id="searchbar-outer" class="searchbar-outer">
|
||||
<input type="search" id="searchbar" name="searchbar" placeholder="Search this book ..." aria-controls="searchresults-outer" aria-describedby="searchresults-header">
|
||||
</form>
|
||||
<div id="searchresults-outer" class="searchresults-outer hidden">
|
||||
<div id="searchresults-header" class="searchresults-header"></div>
|
||||
<ul id="searchresults">
|
||||
</ul>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- Apply ARIA attributes after the sidebar and the sidebar toggle button are added to the DOM -->
|
||||
<script type="text/javascript">
|
||||
document.getElementById('sidebar-toggle').setAttribute('aria-expanded', sidebar === 'visible');
|
||||
document.getElementById('sidebar').setAttribute('aria-hidden', sidebar !== 'visible');
|
||||
Array.from(document.querySelectorAll('#sidebar a')).forEach(function(link) {
|
||||
link.setAttribute('tabIndex', sidebar === 'visible' ? 0 : -1);
|
||||
});
|
||||
</script>
|
||||
|
||||
<div id="content" class="content">
|
||||
<main>
|
||||
<h1 id="fallback-routes"><a class="header" href="#fallback-routes">Fallback Routes</a></h1>
|
||||
<p>Sometimes the router might be unable to find a route for the provided path. We
|
||||
might want it to show a prepared error message to our users in that case.
|
||||
Fallback routes allow us to do that.</p>
|
||||
<blockquote>
|
||||
<p>This is especially important for use cases where users can manually change the
|
||||
path, like web apps running in the browser.</p>
|
||||
</blockquote>
|
||||
<h2 id="a-single-global-fallback"><a class="header" href="#a-single-global-fallback">A single global fallback</a></h2>
|
||||
<p>To catch all cases of invalid paths within our app, we can simply add a fallback
|
||||
route to our root <a href="https://docs.rs/dioxus-router-core/latest/dioxus_router_core/routes/struct.Segment.html"><code>Segment</code></a>.</p>
|
||||
<pre><pre class="playground"><code class="language-rust edition2021">
|
||||
<span class="boring">#![allow(unused)]
|
||||
</span><span class="boring">fn main() {
|
||||
</span><span class="boring">// Hidden lines (like this one) make the documentation tests work.
|
||||
</span><span class="boring">extern crate dioxus;
|
||||
</span>use dioxus::prelude::*;
|
||||
<span class="boring">extern crate dioxus_router;
|
||||
</span>use dioxus_router::{history::MemoryHistory, prelude::*};
|
||||
<span class="boring">extern crate dioxus_ssr;
|
||||
</span>
|
||||
fn Index(cx: Scope) -> Element {
|
||||
render! {
|
||||
h1 { "Index" }
|
||||
}
|
||||
}
|
||||
|
||||
fn Fallback(cx: Scope) -> Element {
|
||||
render! {
|
||||
h1 { "Error 404 - Not Found" }
|
||||
p { "The page you asked for doesn't exist." }
|
||||
}
|
||||
}
|
||||
|
||||
fn App(cx: Scope) -> Element {
|
||||
use_router(
|
||||
cx,
|
||||
&|| RouterConfiguration {
|
||||
<span class="boring"> synchronous: true,
|
||||
</span><span class="boring"> history: Box::new(MemoryHistory::with_initial_path("/invalid").unwrap()),
|
||||
</span> ..Default::default()
|
||||
},
|
||||
&|| {
|
||||
Segment::content(comp(Index)).fallback(comp(Fallback))
|
||||
}
|
||||
);
|
||||
|
||||
render! {
|
||||
Outlet { }
|
||||
}
|
||||
}
|
||||
<span class="boring">
|
||||
</span><span class="boring">let mut vdom = VirtualDom::new(App);
|
||||
</span><span class="boring">vdom.rebuild();
|
||||
</span><span class="boring">assert_eq!(
|
||||
</span><span class="boring"> dioxus_ssr::render(&vdom),
|
||||
</span><span class="boring"> "<h1>Error 404 - Not Found</h1><p>The page you asked for doesn't exist.</p>"
|
||||
</span><span class="boring">);
|
||||
</span><span class="boring">}
|
||||
</span></code></pre></pre>
|
||||
<h2 id="more-specific-fallback-routes"><a class="header" href="#more-specific-fallback-routes">More specific fallback routes</a></h2>
|
||||
<p>In some cases we might want to show different fallback content depending on what
|
||||
section of our app the user is in.</p>
|
||||
<p>For example, our app might have several settings pages under <code>/settings</code>, such
|
||||
as the password settings <code>/settings/password</code> or the privacy settings
|
||||
<code>/settings/privacy</code>. When our user is in the settings section, we want to show
|
||||
them <em>"settings not found"</em> instead of <em>"page not found"</em>.</p>
|
||||
<p>We can easily do that by setting a fallback route on our nested <a href="https://docs.rs/dioxus-router-core/latest/dioxus_router_core/routes/struct.Segment.html"><code>Segment</code></a>. It
|
||||
will then replace the global fallback whenever our <a href="https://docs.rs/dioxus-router-core/latest/dioxus_router_core/routes/struct.Segment.html"><code>Segment</code></a> was active.</p>
|
||||
<p>Note the <code>.clear_fallback(false)</code> part. If we didn't add this, the fallback
|
||||
content would be rendered inside the <code>Settings</code> component.</p>
|
||||
<pre><pre class="playground"><code class="language-rust edition2021">
|
||||
<span class="boring">#![allow(unused)]
|
||||
</span><span class="boring">fn main() {
|
||||
</span><span class="boring">// Hidden lines (like this one) make the documentation tests work.
|
||||
</span><span class="boring">extern crate dioxus;
|
||||
</span>use dioxus::prelude::*;
|
||||
<span class="boring">extern crate dioxus_router;
|
||||
</span>use dioxus_router::{history::MemoryHistory, prelude::*};
|
||||
<span class="boring">extern crate dioxus_ssr;
|
||||
</span>
|
||||
// This example doesn't show the index or settings components. It only shows how
|
||||
// to set up several fallback routes.
|
||||
<span class="boring">fn Index(cx: Scope) -> Element { unimplemented!() }
|
||||
</span><span class="boring">fn Settings(cx: Scope) -> Element { unimplemented!() }
|
||||
</span><span class="boring">fn GeneralSettings(cx: Scope) -> Element { unimplemented!() }
|
||||
</span><span class="boring">fn PasswordSettings(cx: Scope) -> Element { unimplemented!() }
|
||||
</span><span class="boring">fn PrivacySettings(cx: Scope) -> Element { unimplemented!() }
|
||||
</span>
|
||||
fn GlobalFallback(cx: Scope) -> Element {
|
||||
render! {
|
||||
h1 { "Error 404 - Page Not Found" }
|
||||
}
|
||||
}
|
||||
|
||||
fn SettingsFallback(cx: Scope) -> Element {
|
||||
render! {
|
||||
h1 { "Error 404 - Settings Not Found" }
|
||||
}
|
||||
}
|
||||
|
||||
fn App(cx: Scope) -> Element {
|
||||
use_router(
|
||||
cx,
|
||||
&|| RouterConfiguration {
|
||||
<span class="boring"> synchronous: true,
|
||||
</span><span class="boring"> history: Box::new(MemoryHistory::with_initial_path("/settings/invalid").unwrap()),
|
||||
</span> ..Default::default()
|
||||
},
|
||||
&|| {
|
||||
Segment::empty()
|
||||
.fixed("settings", Route::content(comp(Settings)).nested(
|
||||
Segment::content(comp(GeneralSettings))
|
||||
.fixed("password", comp(PasswordSettings))
|
||||
.fixed("privacy", comp(PrivacySettings))
|
||||
.fallback(comp(SettingsFallback))
|
||||
.clear_fallback(true)
|
||||
))
|
||||
.fallback(comp(GlobalFallback))
|
||||
}
|
||||
);
|
||||
|
||||
render! {
|
||||
Outlet { }
|
||||
}
|
||||
}
|
||||
<span class="boring">
|
||||
</span><span class="boring">let mut vdom = VirtualDom::new(App);
|
||||
</span><span class="boring">vdom.rebuild();
|
||||
</span><span class="boring">assert_eq!(
|
||||
</span><span class="boring"> dioxus_ssr::render(&vdom),
|
||||
</span><span class="boring"> "<h1>Error 404 - Settings Not Found</h1>"
|
||||
</span><span class="boring">);
|
||||
</span><span class="boring">}
|
||||
</span></code></pre></pre>
|
||||
|
||||
</main>
|
||||
|
||||
<nav class="nav-wrapper" aria-label="Page navigation">
|
||||
<!-- Mobile navigation buttons -->
|
||||
<a rel="prev" href="../../features/routes/matching.html" class="mobile-nav-chapters previous" title="Previous chapter" aria-label="Previous chapter" aria-keyshortcuts="Left">
|
||||
<i class="fa fa-angle-left"></i>
|
||||
</a>
|
||||
|
||||
<a rel="next" href="../../features/routes/multiple-and-redirect.html" class="mobile-nav-chapters next" title="Next chapter" aria-label="Next chapter" aria-keyshortcuts="Right">
|
||||
<i class="fa fa-angle-right"></i>
|
||||
</a>
|
||||
|
||||
<div style="clear: both"></div>
|
||||
</nav>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<nav class="nav-wide-wrapper" aria-label="Page navigation">
|
||||
<a rel="prev" href="../../features/routes/matching.html" class="nav-chapters previous" title="Previous chapter" aria-label="Previous chapter" aria-keyshortcuts="Left">
|
||||
<i class="fa fa-angle-left"></i>
|
||||
</a>
|
||||
|
||||
<a rel="next" href="../../features/routes/multiple-and-redirect.html" class="nav-chapters next" title="Next chapter" aria-label="Next chapter" aria-keyshortcuts="Right">
|
||||
<i class="fa fa-angle-right"></i>
|
||||
</a>
|
||||
</nav>
|
||||
|
||||
</div>
|
||||
|
||||
|
||||
|
||||
|
||||
<script type="text/javascript">
|
||||
window.playground_copyable = true;
|
||||
</script>
|
||||
|
||||
|
||||
<script src="../../elasticlunr.min.js" type="text/javascript" charset="utf-8"></script>
|
||||
<script src="../../mark.min.js" type="text/javascript" charset="utf-8"></script>
|
||||
<script src="../../searcher.js" type="text/javascript" charset="utf-8"></script>
|
||||
|
||||
<script src="../../clipboard.min.js" type="text/javascript" charset="utf-8"></script>
|
||||
<script src="../../highlight.js" type="text/javascript" charset="utf-8"></script>
|
||||
<script src="../../book.js" type="text/javascript" charset="utf-8"></script>
|
||||
|
||||
<!-- Custom JS scripts -->
|
||||
|
||||
|
||||
</body>
|
||||
</html>
|
||||
@@ -0,0 +1,335 @@
|
||||
<!DOCTYPE HTML>
|
||||
<html lang="en" class="sidebar-visible no-js light">
|
||||
<head>
|
||||
<!-- Book generated using mdBook -->
|
||||
<meta charset="UTF-8">
|
||||
<title>Defining Routes - Dioxus Router</title>
|
||||
|
||||
|
||||
<!-- Custom HTML head -->
|
||||
|
||||
<meta content="text/html; charset=utf-8" http-equiv="Content-Type">
|
||||
<meta name="description" content="">
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1">
|
||||
<meta name="theme-color" content="#ffffff" />
|
||||
|
||||
<link rel="icon" href="../../favicon.svg">
|
||||
<link rel="shortcut icon" href="../../favicon.png">
|
||||
<link rel="stylesheet" href="../../css/variables.css">
|
||||
<link rel="stylesheet" href="../../css/general.css">
|
||||
<link rel="stylesheet" href="../../css/chrome.css">
|
||||
<link rel="stylesheet" href="../../css/print.css" media="print">
|
||||
|
||||
<!-- Fonts -->
|
||||
<link rel="stylesheet" href="../../FontAwesome/css/font-awesome.css">
|
||||
<link rel="stylesheet" href="../../fonts/fonts.css">
|
||||
|
||||
<!-- Highlight.js Stylesheets -->
|
||||
<link rel="stylesheet" href="../../highlight.css">
|
||||
<link rel="stylesheet" href="../../tomorrow-night.css">
|
||||
<link rel="stylesheet" href="../../ayu-highlight.css">
|
||||
|
||||
<!-- Custom theme stylesheets -->
|
||||
|
||||
</head>
|
||||
<body>
|
||||
<!-- Provide site root to javascript -->
|
||||
<script type="text/javascript">
|
||||
var path_to_root = "../../";
|
||||
var default_theme = window.matchMedia("(prefers-color-scheme: dark)").matches ? "navy" : "light";
|
||||
</script>
|
||||
|
||||
<!-- Work around some values being stored in localStorage wrapped in quotes -->
|
||||
<script type="text/javascript">
|
||||
try {
|
||||
var theme = localStorage.getItem('mdbook-theme');
|
||||
var sidebar = localStorage.getItem('mdbook-sidebar');
|
||||
|
||||
if (theme.startsWith('"') && theme.endsWith('"')) {
|
||||
localStorage.setItem('mdbook-theme', theme.slice(1, theme.length - 1));
|
||||
}
|
||||
|
||||
if (sidebar.startsWith('"') && sidebar.endsWith('"')) {
|
||||
localStorage.setItem('mdbook-sidebar', sidebar.slice(1, sidebar.length - 1));
|
||||
}
|
||||
} catch (e) { }
|
||||
</script>
|
||||
|
||||
<!-- Set the theme before any content is loaded, prevents flash -->
|
||||
<script type="text/javascript">
|
||||
var theme;
|
||||
try { theme = localStorage.getItem('mdbook-theme'); } catch(e) { }
|
||||
if (theme === null || theme === undefined) { theme = default_theme; }
|
||||
var html = document.querySelector('html');
|
||||
html.classList.remove('no-js')
|
||||
html.classList.remove('light')
|
||||
html.classList.add(theme);
|
||||
html.classList.add('js');
|
||||
</script>
|
||||
|
||||
<!-- Hide / unhide sidebar before it is displayed -->
|
||||
<script type="text/javascript">
|
||||
var html = document.querySelector('html');
|
||||
var sidebar = 'hidden';
|
||||
if (document.body.clientWidth >= 1080) {
|
||||
try { sidebar = localStorage.getItem('mdbook-sidebar'); } catch(e) { }
|
||||
sidebar = sidebar || 'visible';
|
||||
}
|
||||
html.classList.remove('sidebar-visible');
|
||||
html.classList.add("sidebar-" + sidebar);
|
||||
</script>
|
||||
|
||||
<nav id="sidebar" class="sidebar" aria-label="Table of contents">
|
||||
<div class="sidebar-scrollbox">
|
||||
<ol class="chapter"><li class="chapter-item expanded affix "><a href="../../index.html">Introduction</a></li><li class="chapter-item expanded affix "><li class="part-title">Features</li><li class="chapter-item expanded "><a href="../../features/index.html"><strong aria-hidden="true">1.</strong> Adding the Router to Your Application</a></li><li class="chapter-item expanded "><a href="../../features/routes/index.html" class="active"><strong aria-hidden="true">2.</strong> Defining Routes</a></li><li><ol class="section"><li class="chapter-item expanded "><a href="../../features/routes/nested.html"><strong aria-hidden="true">2.1.</strong> Nested Routes</a></li><li class="chapter-item expanded "><a href="../../features/routes/catch_all.html"><strong aria-hidden="true">2.2.</strong> Catch All Routes</a></li><li class="chapter-item expanded "><a href="../../features/routes/matching.html"><strong aria-hidden="true">2.3.</strong> Matching Routes</a></li><li class="chapter-item expanded "><a href="../../features/routes/fallback.html"><strong aria-hidden="true">2.4.</strong> Fallback Routes (404 page)</a></li><li class="chapter-item expanded "><a href="../../features/routes/multiple-and-redirect.html"><strong aria-hidden="true">2.5.</strong> Multiple Components & Redirects</a></li></ol></li><li class="chapter-item expanded "><a href="../../features/outlets.html"><strong aria-hidden="true">3.</strong> Outlets</a></li><li class="chapter-item expanded "><a href="../../features/navigation/index.html"><strong aria-hidden="true">4.</strong> Links & Navigation</a></li><li><ol class="section"><li class="chapter-item expanded "><a href="../../features/navigation/name.html"><strong aria-hidden="true">4.1.</strong> Named Navigation</a></li><li class="chapter-item expanded "><a href="../../features/navigation/external.html"><strong aria-hidden="true">4.2.</strong> External Navigation</a></li><li class="chapter-item expanded "><a href="../../features/navigation/programmatic.html"><strong aria-hidden="true">4.3.</strong> Programmatic Navigation</a></li></ol></li><li class="chapter-item expanded "><a href="../../features/query.html"><strong aria-hidden="true">5.</strong> Query</a></li><li class="chapter-item expanded "><a href="../../features/failures/index.html"><strong aria-hidden="true">6.</strong> Navigation Failures</a></li><li><ol class="section"><li class="chapter-item expanded "><a href="../../features/failures/named.html"><strong aria-hidden="true">6.1.</strong> Named Navigation Failure</a></li><li class="chapter-item expanded "><a href="../../features/failures/external.html"><strong aria-hidden="true">6.2.</strong> External Navigation Failure</a></li><li class="chapter-item expanded "><a href="../../features/failures/redirection-limit.html"><strong aria-hidden="true">6.3.</strong> Redirection Limit Failure</a></li></ol></li><li class="chapter-item expanded "><a href="../../features/history-providers.html"><strong aria-hidden="true">7.</strong> History Providers</a></li><li class="chapter-item expanded "><a href="../../features/history-buttons.html"><strong aria-hidden="true">8.</strong> History Buttons</a></li><li class="chapter-item expanded "><a href="../../features/sitemap-generation.html"><strong aria-hidden="true">9.</strong> Sitemap Generation</a></li><li class="chapter-item expanded "><a href="../../features/routing-update-callback.html"><strong aria-hidden="true">10.</strong> Routing Update Callback</a></li><li class="chapter-item expanded affix "><li class="part-title">Example Project</li><li class="chapter-item expanded "><a href="../../example/index.html"><strong aria-hidden="true">11.</strong> Overview</a></li><li class="chapter-item expanded "><a href="../../example/first-route.html"><strong aria-hidden="true">12.</strong> Creating Our First Route</a></li><li class="chapter-item expanded "><a href="../../example/building-a-nest.html"><strong aria-hidden="true">13.</strong> Building a Nest</a></li><li class="chapter-item expanded "><a href="../../example/navigation-targets.html"><strong aria-hidden="true">14.</strong> Navigation Targets</a></li><li class="chapter-item expanded "><a href="../../example/redirection-perfection.html"><strong aria-hidden="true">15.</strong> Redirection Perfection</a></li><li class="chapter-item expanded "><a href="../../example/full-code.html"><strong aria-hidden="true">16.</strong> Full Code</a></li></ol>
|
||||
</div>
|
||||
<div id="sidebar-resize-handle" class="sidebar-resize-handle"></div>
|
||||
</nav>
|
||||
|
||||
<div id="page-wrapper" class="page-wrapper">
|
||||
|
||||
<div class="page">
|
||||
<div id="menu-bar-hover-placeholder"></div>
|
||||
<div id="menu-bar" class="menu-bar sticky bordered">
|
||||
<div class="left-buttons">
|
||||
<button id="sidebar-toggle" class="icon-button" type="button" title="Toggle Table of Contents" aria-label="Toggle Table of Contents" aria-controls="sidebar">
|
||||
<i class="fa fa-bars"></i>
|
||||
</button>
|
||||
<button id="theme-toggle" class="icon-button" type="button" title="Change theme" aria-label="Change theme" aria-haspopup="true" aria-expanded="false" aria-controls="theme-list">
|
||||
<i class="fa fa-paint-brush"></i>
|
||||
</button>
|
||||
<ul id="theme-list" class="theme-popup" aria-label="Themes" role="menu">
|
||||
<li role="none"><button role="menuitem" class="theme" id="light">Light (default)</button></li>
|
||||
<li role="none"><button role="menuitem" class="theme" id="rust">Rust</button></li>
|
||||
<li role="none"><button role="menuitem" class="theme" id="coal">Coal</button></li>
|
||||
<li role="none"><button role="menuitem" class="theme" id="navy">Navy</button></li>
|
||||
<li role="none"><button role="menuitem" class="theme" id="ayu">Ayu</button></li>
|
||||
</ul>
|
||||
<button id="search-toggle" class="icon-button" type="button" title="Search. (Shortkey: s)" aria-label="Toggle Searchbar" aria-expanded="false" aria-keyshortcuts="S" aria-controls="searchbar">
|
||||
<i class="fa fa-search"></i>
|
||||
</button>
|
||||
</div>
|
||||
|
||||
<h1 class="menu-title">Dioxus Router</h1>
|
||||
|
||||
<div class="right-buttons">
|
||||
<a href="../../print.html" title="Print this book" aria-label="Print this book">
|
||||
<i id="print-button" class="fa fa-print"></i>
|
||||
</a>
|
||||
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div id="search-wrapper" class="hidden">
|
||||
<form id="searchbar-outer" class="searchbar-outer">
|
||||
<input type="search" id="searchbar" name="searchbar" placeholder="Search this book ..." aria-controls="searchresults-outer" aria-describedby="searchresults-header">
|
||||
</form>
|
||||
<div id="searchresults-outer" class="searchresults-outer hidden">
|
||||
<div id="searchresults-header" class="searchresults-header"></div>
|
||||
<ul id="searchresults">
|
||||
</ul>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- Apply ARIA attributes after the sidebar and the sidebar toggle button are added to the DOM -->
|
||||
<script type="text/javascript">
|
||||
document.getElementById('sidebar-toggle').setAttribute('aria-expanded', sidebar === 'visible');
|
||||
document.getElementById('sidebar').setAttribute('aria-hidden', sidebar !== 'visible');
|
||||
Array.from(document.querySelectorAll('#sidebar a')).forEach(function(link) {
|
||||
link.setAttribute('tabIndex', sidebar === 'visible' ? 0 : -1);
|
||||
});
|
||||
</script>
|
||||
|
||||
<div id="content" class="content">
|
||||
<main>
|
||||
<h1 id="defining-routes"><a class="header" href="#defining-routes">Defining Routes</a></h1>
|
||||
<p>When creating a router we need to pass it a <a href="https://docs.rs/dioxus-router-core/latest/dioxus_router_core/routes/struct.Segment.html"><code>Segment</code></a>. It tells the router
|
||||
about all the routes of our app.</p>
|
||||
<h2 id="example-content"><a class="header" href="#example-content">Example content</a></h2>
|
||||
<p>To get a good understanding of how we define routes we first need to prepare
|
||||
some example content, so we can see the routing in action.</p>
|
||||
<pre><pre class="playground"><code class="language-rust no_run edition2021">
|
||||
<span class="boring">#![allow(unused)]
|
||||
</span><span class="boring">fn main() {
|
||||
</span><span class="boring">// Hidden lines (like this one) make the documentation tests work.
|
||||
</span><span class="boring">extern crate dioxus;
|
||||
</span>use dioxus::prelude::*;
|
||||
<span class="boring">extern crate dioxus_router;
|
||||
</span>use dioxus_router::prelude::*;
|
||||
|
||||
fn Index(cx: Scope) -> Element {
|
||||
render! {
|
||||
h1 { "Welcome to our test site!" }
|
||||
}
|
||||
}
|
||||
|
||||
fn Other(cx: Scope) -> Element {
|
||||
render! {
|
||||
p { "some other content" }
|
||||
}
|
||||
}
|
||||
<span class="boring">}
|
||||
</span></code></pre></pre>
|
||||
<h2 id="index-routes"><a class="header" href="#index-routes">Index routes</a></h2>
|
||||
<p>The easiest thing to do is to define an index route.</p>
|
||||
<p>Index routes act very similar to <code>index.html</code> files in most web servers. They
|
||||
are active, when we don't specify a route.</p>
|
||||
<blockquote>
|
||||
<p>Note that we wrap our <code>Index</code> component with <a href="https://docs.rs/dioxus-router/latest/dioxus_router/prelude/fn.comp.html"><code>comp</code></a>. This is because of
|
||||
rust type system requirements.</p>
|
||||
</blockquote>
|
||||
<pre><pre class="playground"><code class="language-rust no_run edition2021">
|
||||
<span class="boring">#![allow(unused)]
|
||||
</span><span class="boring">fn main() {
|
||||
</span><span class="boring">// Hidden lines (like this one) make the documentation tests work.
|
||||
</span><span class="boring">extern crate dioxus;
|
||||
</span><span class="boring">use dioxus::prelude::*;
|
||||
</span><span class="boring">extern crate dioxus_router;
|
||||
</span><span class="boring">use dioxus_router::prelude::*;
|
||||
</span><span class="boring">fn Index(cx: Scope) -> Element { unimplemented!() }
|
||||
</span><span class="boring">
|
||||
</span>fn App(cx: Scope) -> Element {
|
||||
use_router(
|
||||
cx,
|
||||
&|| RouterConfiguration {
|
||||
..Default::default()
|
||||
},
|
||||
&|| Segment::content(comp(Index))
|
||||
);
|
||||
|
||||
// ...
|
||||
<span class="boring"> unimplemented!()
|
||||
</span>}
|
||||
<span class="boring">}
|
||||
</span></code></pre></pre>
|
||||
<h2 id="fixed-routes"><a class="header" href="#fixed-routes">Fixed routes</a></h2>
|
||||
<p>It is almost as easy to define a fixed route.</p>
|
||||
<p>Fixed routes work similar to how web servers treat files. They are active, when
|
||||
specified in the path. In the example, the path must be <code>/other</code>.</p>
|
||||
<blockquote>
|
||||
<p>The path will be URL decoded before checking if it matches our route.</p>
|
||||
</blockquote>
|
||||
<pre><pre class="playground"><code class="language-rust no_run edition2021">
|
||||
<span class="boring">#![allow(unused)]
|
||||
</span><span class="boring">fn main() {
|
||||
</span><span class="boring">// Hidden lines (like this one) make the documentation tests work.
|
||||
</span><span class="boring">extern crate dioxus;
|
||||
</span><span class="boring">use dioxus::prelude::*;
|
||||
</span><span class="boring">extern crate dioxus_router;
|
||||
</span><span class="boring">use dioxus_router::prelude::*;
|
||||
</span><span class="boring">fn Index(cx: Scope) -> Element { unimplemented!() }
|
||||
</span><span class="boring">fn Other(cx: Scope) -> Element { unimplemented!() }
|
||||
</span><span class="boring">
|
||||
</span>fn App(cx: Scope) -> Element {
|
||||
use_router(
|
||||
cx,
|
||||
&|| RouterConfiguration {
|
||||
..Default::default()
|
||||
},
|
||||
&|| Segment::content(comp(Index)).fixed("other", comp(Other))
|
||||
// ^ note the absence of a / prefix
|
||||
);
|
||||
|
||||
// ...
|
||||
<span class="boring"> unimplemented!()
|
||||
</span>}
|
||||
<span class="boring">}
|
||||
</span></code></pre></pre>
|
||||
<h2 id="full-code"><a class="header" href="#full-code">Full Code</a></h2>
|
||||
<pre><pre class="playground"><code class="language-rust edition2021">
|
||||
<span class="boring">#![allow(unused)]
|
||||
</span><span class="boring">fn main() {
|
||||
</span><span class="boring">// Hidden lines (like this one) make the documentation tests work.
|
||||
</span><span class="boring">extern crate dioxus;
|
||||
</span>use dioxus::prelude::*;
|
||||
<span class="boring">extern crate dioxus_router;
|
||||
</span>use dioxus_router::{history::MemoryHistory, prelude::*};
|
||||
<span class="boring">extern crate dioxus_ssr;
|
||||
</span>
|
||||
fn Index(cx: Scope) -> Element {
|
||||
render! {
|
||||
h1 { "Welcome to our test site!" }
|
||||
}
|
||||
}
|
||||
|
||||
fn Other(cx: Scope) -> Element {
|
||||
render! {
|
||||
p { "some other content" }
|
||||
}
|
||||
}
|
||||
|
||||
fn App(cx: Scope) -> Element {
|
||||
use_router(
|
||||
cx,
|
||||
&|| RouterConfiguration {
|
||||
<span class="boring"> synchronous: true,
|
||||
</span><span class="boring"> history: Box::new(MemoryHistory::with_initial_path("/other").unwrap()),
|
||||
</span> ..Default::default()
|
||||
},
|
||||
&|| Segment::content(comp(Index)).fixed("other", comp(Other))
|
||||
);
|
||||
|
||||
render! {
|
||||
Outlet { }
|
||||
}
|
||||
}
|
||||
<span class="boring">
|
||||
</span><span class="boring">let mut vdom = VirtualDom::new(App);
|
||||
</span><span class="boring">vdom.rebuild();
|
||||
</span><span class="boring">assert_eq!(
|
||||
</span><span class="boring"> dioxus_ssr::render(&vdom),
|
||||
</span><span class="boring"> "<p>some other content</p>"
|
||||
</span><span class="boring">);
|
||||
</span><span class="boring">}
|
||||
</span></code></pre></pre>
|
||||
|
||||
</main>
|
||||
|
||||
<nav class="nav-wrapper" aria-label="Page navigation">
|
||||
<!-- Mobile navigation buttons -->
|
||||
<a rel="prev" href="../../features/index.html" class="mobile-nav-chapters previous" title="Previous chapter" aria-label="Previous chapter" aria-keyshortcuts="Left">
|
||||
<i class="fa fa-angle-left"></i>
|
||||
</a>
|
||||
|
||||
<a rel="next" href="../../features/routes/nested.html" class="mobile-nav-chapters next" title="Next chapter" aria-label="Next chapter" aria-keyshortcuts="Right">
|
||||
<i class="fa fa-angle-right"></i>
|
||||
</a>
|
||||
|
||||
<div style="clear: both"></div>
|
||||
</nav>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<nav class="nav-wide-wrapper" aria-label="Page navigation">
|
||||
<a rel="prev" href="../../features/index.html" class="nav-chapters previous" title="Previous chapter" aria-label="Previous chapter" aria-keyshortcuts="Left">
|
||||
<i class="fa fa-angle-left"></i>
|
||||
</a>
|
||||
|
||||
<a rel="next" href="../../features/routes/nested.html" class="nav-chapters next" title="Next chapter" aria-label="Next chapter" aria-keyshortcuts="Right">
|
||||
<i class="fa fa-angle-right"></i>
|
||||
</a>
|
||||
</nav>
|
||||
|
||||
</div>
|
||||
|
||||
|
||||
|
||||
|
||||
<script type="text/javascript">
|
||||
window.playground_copyable = true;
|
||||
</script>
|
||||
|
||||
|
||||
<script src="../../elasticlunr.min.js" type="text/javascript" charset="utf-8"></script>
|
||||
<script src="../../mark.min.js" type="text/javascript" charset="utf-8"></script>
|
||||
<script src="../../searcher.js" type="text/javascript" charset="utf-8"></script>
|
||||
|
||||
<script src="../../clipboard.min.js" type="text/javascript" charset="utf-8"></script>
|
||||
<script src="../../highlight.js" type="text/javascript" charset="utf-8"></script>
|
||||
<script src="../../book.js" type="text/javascript" charset="utf-8"></script>
|
||||
|
||||
<!-- Custom JS scripts -->
|
||||
|
||||
|
||||
</body>
|
||||
</html>
|
||||
@@ -0,0 +1,335 @@
|
||||
<!DOCTYPE HTML>
|
||||
<html lang="en" class="sidebar-visible no-js light">
|
||||
<head>
|
||||
<!-- Book generated using mdBook -->
|
||||
<meta charset="UTF-8">
|
||||
<title>Matching Routes - Dioxus Router</title>
|
||||
|
||||
|
||||
<!-- Custom HTML head -->
|
||||
|
||||
<meta content="text/html; charset=utf-8" http-equiv="Content-Type">
|
||||
<meta name="description" content="">
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1">
|
||||
<meta name="theme-color" content="#ffffff" />
|
||||
|
||||
<link rel="icon" href="../../favicon.svg">
|
||||
<link rel="shortcut icon" href="../../favicon.png">
|
||||
<link rel="stylesheet" href="../../css/variables.css">
|
||||
<link rel="stylesheet" href="../../css/general.css">
|
||||
<link rel="stylesheet" href="../../css/chrome.css">
|
||||
<link rel="stylesheet" href="../../css/print.css" media="print">
|
||||
|
||||
<!-- Fonts -->
|
||||
<link rel="stylesheet" href="../../FontAwesome/css/font-awesome.css">
|
||||
<link rel="stylesheet" href="../../fonts/fonts.css">
|
||||
|
||||
<!-- Highlight.js Stylesheets -->
|
||||
<link rel="stylesheet" href="../../highlight.css">
|
||||
<link rel="stylesheet" href="../../tomorrow-night.css">
|
||||
<link rel="stylesheet" href="../../ayu-highlight.css">
|
||||
|
||||
<!-- Custom theme stylesheets -->
|
||||
|
||||
</head>
|
||||
<body>
|
||||
<!-- Provide site root to javascript -->
|
||||
<script type="text/javascript">
|
||||
var path_to_root = "../../";
|
||||
var default_theme = window.matchMedia("(prefers-color-scheme: dark)").matches ? "navy" : "light";
|
||||
</script>
|
||||
|
||||
<!-- Work around some values being stored in localStorage wrapped in quotes -->
|
||||
<script type="text/javascript">
|
||||
try {
|
||||
var theme = localStorage.getItem('mdbook-theme');
|
||||
var sidebar = localStorage.getItem('mdbook-sidebar');
|
||||
|
||||
if (theme.startsWith('"') && theme.endsWith('"')) {
|
||||
localStorage.setItem('mdbook-theme', theme.slice(1, theme.length - 1));
|
||||
}
|
||||
|
||||
if (sidebar.startsWith('"') && sidebar.endsWith('"')) {
|
||||
localStorage.setItem('mdbook-sidebar', sidebar.slice(1, sidebar.length - 1));
|
||||
}
|
||||
} catch (e) { }
|
||||
</script>
|
||||
|
||||
<!-- Set the theme before any content is loaded, prevents flash -->
|
||||
<script type="text/javascript">
|
||||
var theme;
|
||||
try { theme = localStorage.getItem('mdbook-theme'); } catch(e) { }
|
||||
if (theme === null || theme === undefined) { theme = default_theme; }
|
||||
var html = document.querySelector('html');
|
||||
html.classList.remove('no-js')
|
||||
html.classList.remove('light')
|
||||
html.classList.add(theme);
|
||||
html.classList.add('js');
|
||||
</script>
|
||||
|
||||
<!-- Hide / unhide sidebar before it is displayed -->
|
||||
<script type="text/javascript">
|
||||
var html = document.querySelector('html');
|
||||
var sidebar = 'hidden';
|
||||
if (document.body.clientWidth >= 1080) {
|
||||
try { sidebar = localStorage.getItem('mdbook-sidebar'); } catch(e) { }
|
||||
sidebar = sidebar || 'visible';
|
||||
}
|
||||
html.classList.remove('sidebar-visible');
|
||||
html.classList.add("sidebar-" + sidebar);
|
||||
</script>
|
||||
|
||||
<nav id="sidebar" class="sidebar" aria-label="Table of contents">
|
||||
<div class="sidebar-scrollbox">
|
||||
<ol class="chapter"><li class="chapter-item expanded affix "><a href="../../index.html">Introduction</a></li><li class="chapter-item expanded affix "><li class="part-title">Features</li><li class="chapter-item expanded "><a href="../../features/index.html"><strong aria-hidden="true">1.</strong> Adding the Router to Your Application</a></li><li class="chapter-item expanded "><a href="../../features/routes/index.html"><strong aria-hidden="true">2.</strong> Defining Routes</a></li><li><ol class="section"><li class="chapter-item expanded "><a href="../../features/routes/nested.html"><strong aria-hidden="true">2.1.</strong> Nested Routes</a></li><li class="chapter-item expanded "><a href="../../features/routes/catch_all.html"><strong aria-hidden="true">2.2.</strong> Catch All Routes</a></li><li class="chapter-item expanded "><a href="../../features/routes/matching.html" class="active"><strong aria-hidden="true">2.3.</strong> Matching Routes</a></li><li class="chapter-item expanded "><a href="../../features/routes/fallback.html"><strong aria-hidden="true">2.4.</strong> Fallback Routes (404 page)</a></li><li class="chapter-item expanded "><a href="../../features/routes/multiple-and-redirect.html"><strong aria-hidden="true">2.5.</strong> Multiple Components & Redirects</a></li></ol></li><li class="chapter-item expanded "><a href="../../features/outlets.html"><strong aria-hidden="true">3.</strong> Outlets</a></li><li class="chapter-item expanded "><a href="../../features/navigation/index.html"><strong aria-hidden="true">4.</strong> Links & Navigation</a></li><li><ol class="section"><li class="chapter-item expanded "><a href="../../features/navigation/name.html"><strong aria-hidden="true">4.1.</strong> Named Navigation</a></li><li class="chapter-item expanded "><a href="../../features/navigation/external.html"><strong aria-hidden="true">4.2.</strong> External Navigation</a></li><li class="chapter-item expanded "><a href="../../features/navigation/programmatic.html"><strong aria-hidden="true">4.3.</strong> Programmatic Navigation</a></li></ol></li><li class="chapter-item expanded "><a href="../../features/query.html"><strong aria-hidden="true">5.</strong> Query</a></li><li class="chapter-item expanded "><a href="../../features/failures/index.html"><strong aria-hidden="true">6.</strong> Navigation Failures</a></li><li><ol class="section"><li class="chapter-item expanded "><a href="../../features/failures/named.html"><strong aria-hidden="true">6.1.</strong> Named Navigation Failure</a></li><li class="chapter-item expanded "><a href="../../features/failures/external.html"><strong aria-hidden="true">6.2.</strong> External Navigation Failure</a></li><li class="chapter-item expanded "><a href="../../features/failures/redirection-limit.html"><strong aria-hidden="true">6.3.</strong> Redirection Limit Failure</a></li></ol></li><li class="chapter-item expanded "><a href="../../features/history-providers.html"><strong aria-hidden="true">7.</strong> History Providers</a></li><li class="chapter-item expanded "><a href="../../features/history-buttons.html"><strong aria-hidden="true">8.</strong> History Buttons</a></li><li class="chapter-item expanded "><a href="../../features/sitemap-generation.html"><strong aria-hidden="true">9.</strong> Sitemap Generation</a></li><li class="chapter-item expanded "><a href="../../features/routing-update-callback.html"><strong aria-hidden="true">10.</strong> Routing Update Callback</a></li><li class="chapter-item expanded affix "><li class="part-title">Example Project</li><li class="chapter-item expanded "><a href="../../example/index.html"><strong aria-hidden="true">11.</strong> Overview</a></li><li class="chapter-item expanded "><a href="../../example/first-route.html"><strong aria-hidden="true">12.</strong> Creating Our First Route</a></li><li class="chapter-item expanded "><a href="../../example/building-a-nest.html"><strong aria-hidden="true">13.</strong> Building a Nest</a></li><li class="chapter-item expanded "><a href="../../example/navigation-targets.html"><strong aria-hidden="true">14.</strong> Navigation Targets</a></li><li class="chapter-item expanded "><a href="../../example/redirection-perfection.html"><strong aria-hidden="true">15.</strong> Redirection Perfection</a></li><li class="chapter-item expanded "><a href="../../example/full-code.html"><strong aria-hidden="true">16.</strong> Full Code</a></li></ol>
|
||||
</div>
|
||||
<div id="sidebar-resize-handle" class="sidebar-resize-handle"></div>
|
||||
</nav>
|
||||
|
||||
<div id="page-wrapper" class="page-wrapper">
|
||||
|
||||
<div class="page">
|
||||
<div id="menu-bar-hover-placeholder"></div>
|
||||
<div id="menu-bar" class="menu-bar sticky bordered">
|
||||
<div class="left-buttons">
|
||||
<button id="sidebar-toggle" class="icon-button" type="button" title="Toggle Table of Contents" aria-label="Toggle Table of Contents" aria-controls="sidebar">
|
||||
<i class="fa fa-bars"></i>
|
||||
</button>
|
||||
<button id="theme-toggle" class="icon-button" type="button" title="Change theme" aria-label="Change theme" aria-haspopup="true" aria-expanded="false" aria-controls="theme-list">
|
||||
<i class="fa fa-paint-brush"></i>
|
||||
</button>
|
||||
<ul id="theme-list" class="theme-popup" aria-label="Themes" role="menu">
|
||||
<li role="none"><button role="menuitem" class="theme" id="light">Light (default)</button></li>
|
||||
<li role="none"><button role="menuitem" class="theme" id="rust">Rust</button></li>
|
||||
<li role="none"><button role="menuitem" class="theme" id="coal">Coal</button></li>
|
||||
<li role="none"><button role="menuitem" class="theme" id="navy">Navy</button></li>
|
||||
<li role="none"><button role="menuitem" class="theme" id="ayu">Ayu</button></li>
|
||||
</ul>
|
||||
<button id="search-toggle" class="icon-button" type="button" title="Search. (Shortkey: s)" aria-label="Toggle Searchbar" aria-expanded="false" aria-keyshortcuts="S" aria-controls="searchbar">
|
||||
<i class="fa fa-search"></i>
|
||||
</button>
|
||||
</div>
|
||||
|
||||
<h1 class="menu-title">Dioxus Router</h1>
|
||||
|
||||
<div class="right-buttons">
|
||||
<a href="../../print.html" title="Print this book" aria-label="Print this book">
|
||||
<i id="print-button" class="fa fa-print"></i>
|
||||
</a>
|
||||
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div id="search-wrapper" class="hidden">
|
||||
<form id="searchbar-outer" class="searchbar-outer">
|
||||
<input type="search" id="searchbar" name="searchbar" placeholder="Search this book ..." aria-controls="searchresults-outer" aria-describedby="searchresults-header">
|
||||
</form>
|
||||
<div id="searchresults-outer" class="searchresults-outer hidden">
|
||||
<div id="searchresults-header" class="searchresults-header"></div>
|
||||
<ul id="searchresults">
|
||||
</ul>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- Apply ARIA attributes after the sidebar and the sidebar toggle button are added to the DOM -->
|
||||
<script type="text/javascript">
|
||||
document.getElementById('sidebar-toggle').setAttribute('aria-expanded', sidebar === 'visible');
|
||||
document.getElementById('sidebar').setAttribute('aria-hidden', sidebar !== 'visible');
|
||||
Array.from(document.querySelectorAll('#sidebar a')).forEach(function(link) {
|
||||
link.setAttribute('tabIndex', sidebar === 'visible' ? 0 : -1);
|
||||
});
|
||||
</script>
|
||||
|
||||
<div id="content" class="content">
|
||||
<main>
|
||||
<h1 id="matching-routes"><a class="header" href="#matching-routes">Matching Routes</a></h1>
|
||||
<blockquote>
|
||||
<p>Make sure you understand how <a href="./catch_all.html">catch all routes</a> work before
|
||||
reading this page.</p>
|
||||
</blockquote>
|
||||
<p>When accepting parameters via the path, some complex applications might need to
|
||||
decide what route should be active based on the format of that parameter.
|
||||
<em>Matching</em> routes make it easy to implement such behavior.</p>
|
||||
<blockquote>
|
||||
<p>The parameter will be URL decoded, both for checking if the route is active
|
||||
and when it is provided to the application.</p>
|
||||
</blockquote>
|
||||
<blockquote>
|
||||
<p>The example below is only for showing <em>matching route</em> functionality. It is
|
||||
unfit for all other purposes.</p>
|
||||
</blockquote>
|
||||
<h2 id="code-example"><a class="header" href="#code-example">Code Example</a></h2>
|
||||
<blockquote>
|
||||
<p>Notice that the parameter of a <em>matching route</em> has the same type as a
|
||||
<a href="./catch_all.html"><em>catch all route</em></a>.</p>
|
||||
</blockquote>
|
||||
<pre><pre class="playground"><code class="language-rust edition2021">
|
||||
<span class="boring">#![allow(unused)]
|
||||
</span><span class="boring">fn main() {
|
||||
</span><span class="boring">// Hidden lines (like this one) make the documentation tests work.
|
||||
</span><span class="boring">extern crate dioxus;
|
||||
</span><span class="boring">use dioxus::prelude::*;
|
||||
</span><span class="boring">extern crate dioxus_router;
|
||||
</span><span class="boring">use dioxus_router::{history::MemoryHistory, prelude::*};
|
||||
</span><span class="boring">extern crate dioxus_ssr;
|
||||
</span><span class="boring">extern crate regex;
|
||||
</span>use regex::Regex;
|
||||
|
||||
struct Name;
|
||||
|
||||
fn GreetingFemale(cx: Scope) -> Element {
|
||||
let route = use_route(cx).unwrap();
|
||||
let name = route.parameter::<Name>()
|
||||
.map(|name| {
|
||||
let mut name = name.to_string();
|
||||
name.remove(0);
|
||||
name
|
||||
})
|
||||
.unwrap_or(String::from("Anonymous"));
|
||||
|
||||
render! {
|
||||
p { "Hello Mrs. {name}" }
|
||||
}
|
||||
}
|
||||
|
||||
fn GreetingMale(cx: Scope) -> Element {
|
||||
let route = use_route(cx).unwrap();
|
||||
let name = route.parameter::<Name>()
|
||||
.map(|name| {
|
||||
let mut name = name.to_string();
|
||||
name.remove(0);
|
||||
name
|
||||
})
|
||||
.unwrap_or(String::from("Anonymous"));
|
||||
|
||||
render! {
|
||||
p { "Hello Mr. {name}" }
|
||||
}
|
||||
}
|
||||
|
||||
fn GreetingWithoutGender(cx: Scope) -> Element {
|
||||
let route = use_route(cx).unwrap();
|
||||
let name = route.parameter::<Name>()
|
||||
.map(|name| name.to_string())
|
||||
.unwrap_or(String::from("Anonymous"));
|
||||
|
||||
render! {
|
||||
p { "Hello {name}" }
|
||||
}
|
||||
}
|
||||
|
||||
fn GreetingKenobi(cx: Scope) -> Element {
|
||||
render! {
|
||||
p { "Hello there." }
|
||||
p { "General Kenobi." }
|
||||
}
|
||||
}
|
||||
|
||||
fn App(cx: Scope) -> Element {
|
||||
use_router(
|
||||
cx,
|
||||
&|| RouterConfiguration {
|
||||
<span class="boring"> synchronous: true,
|
||||
</span><span class="boring"> history: Box::new(MemoryHistory::with_initial_path("/fAnna").unwrap()),
|
||||
</span> ..Default::default()
|
||||
},
|
||||
&|| {
|
||||
Segment::empty()
|
||||
.fixed("kenobi", comp(GreetingKenobi))
|
||||
.matching(
|
||||
Regex::new("^f").unwrap(),
|
||||
ParameterRoute::content::<Name>(comp(GreetingFemale))
|
||||
)
|
||||
.matching(
|
||||
Regex::new("^m").unwrap(),
|
||||
(comp(GreetingMale), Name { })
|
||||
)
|
||||
.catch_all((comp(GreetingWithoutGender), Name { }))
|
||||
}
|
||||
);
|
||||
|
||||
render! {
|
||||
Outlet { }
|
||||
}
|
||||
}
|
||||
<span class="boring">
|
||||
</span><span class="boring">let mut vdom = VirtualDom::new(App);
|
||||
</span><span class="boring">vdom.rebuild();
|
||||
</span><span class="boring">let html = dioxus_ssr::render(&vdom);
|
||||
</span><span class="boring">assert_eq!(html, "<p>Hello Mrs. Anna</p>");
|
||||
</span><span class="boring">}
|
||||
</span></code></pre></pre>
|
||||
<h2 id="matcher"><a class="header" href="#matcher">Matcher</a></h2>
|
||||
<p>In the example above, both <em>matching routes</em> use a regular expression to specify
|
||||
when they match. However, <em>matching routes</em> are not limited to those. They
|
||||
accept all types that implement the <a href="https://docs.rs/dioxus-router-core/latest/dioxus_router_core/routes/trait.Matcher.html"><code>Matcher</code></a> trait.</p>
|
||||
<p>For example, you could (but probably shouldn't) implement a matcher, that
|
||||
matches all values with an even number of characters:</p>
|
||||
<pre><pre class="playground"><code class="language-rust no_run edition2021">
|
||||
<span class="boring">#![allow(unused)]
|
||||
</span><span class="boring">fn main() {
|
||||
</span><span class="boring">// Hidden lines (like this one) make the documentation tests work.
|
||||
</span><span class="boring">extern crate dioxus_router;
|
||||
</span><span class="boring">use dioxus_router::prelude::*;
|
||||
</span><span class="boring">
|
||||
</span>#[derive(Debug)]
|
||||
struct EvenMatcher;
|
||||
|
||||
impl Matcher for EvenMatcher {
|
||||
fn matches(&self, value: &str) -> bool {
|
||||
value.len() % 2 == 0
|
||||
}
|
||||
}
|
||||
<span class="boring">}
|
||||
</span></code></pre></pre>
|
||||
|
||||
</main>
|
||||
|
||||
<nav class="nav-wrapper" aria-label="Page navigation">
|
||||
<!-- Mobile navigation buttons -->
|
||||
<a rel="prev" href="../../features/routes/catch_all.html" class="mobile-nav-chapters previous" title="Previous chapter" aria-label="Previous chapter" aria-keyshortcuts="Left">
|
||||
<i class="fa fa-angle-left"></i>
|
||||
</a>
|
||||
|
||||
<a rel="next" href="../../features/routes/fallback.html" class="mobile-nav-chapters next" title="Next chapter" aria-label="Next chapter" aria-keyshortcuts="Right">
|
||||
<i class="fa fa-angle-right"></i>
|
||||
</a>
|
||||
|
||||
<div style="clear: both"></div>
|
||||
</nav>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<nav class="nav-wide-wrapper" aria-label="Page navigation">
|
||||
<a rel="prev" href="../../features/routes/catch_all.html" class="nav-chapters previous" title="Previous chapter" aria-label="Previous chapter" aria-keyshortcuts="Left">
|
||||
<i class="fa fa-angle-left"></i>
|
||||
</a>
|
||||
|
||||
<a rel="next" href="../../features/routes/fallback.html" class="nav-chapters next" title="Next chapter" aria-label="Next chapter" aria-keyshortcuts="Right">
|
||||
<i class="fa fa-angle-right"></i>
|
||||
</a>
|
||||
</nav>
|
||||
|
||||
</div>
|
||||
|
||||
|
||||
|
||||
|
||||
<script type="text/javascript">
|
||||
window.playground_copyable = true;
|
||||
</script>
|
||||
|
||||
|
||||
<script src="../../elasticlunr.min.js" type="text/javascript" charset="utf-8"></script>
|
||||
<script src="../../mark.min.js" type="text/javascript" charset="utf-8"></script>
|
||||
<script src="../../searcher.js" type="text/javascript" charset="utf-8"></script>
|
||||
|
||||
<script src="../../clipboard.min.js" type="text/javascript" charset="utf-8"></script>
|
||||
<script src="../../highlight.js" type="text/javascript" charset="utf-8"></script>
|
||||
<script src="../../book.js" type="text/javascript" charset="utf-8"></script>
|
||||
|
||||
<!-- Custom JS scripts -->
|
||||
|
||||
|
||||
</body>
|
||||
</html>
|
||||
@@ -0,0 +1,256 @@
|
||||
<!DOCTYPE HTML>
|
||||
<html lang="en" class="sidebar-visible no-js light">
|
||||
<head>
|
||||
<!-- Book generated using mdBook -->
|
||||
<meta charset="UTF-8">
|
||||
<title>Multiple Components & Redirects - Dioxus Router</title>
|
||||
|
||||
|
||||
<!-- Custom HTML head -->
|
||||
|
||||
<meta content="text/html; charset=utf-8" http-equiv="Content-Type">
|
||||
<meta name="description" content="">
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1">
|
||||
<meta name="theme-color" content="#ffffff" />
|
||||
|
||||
<link rel="icon" href="../../favicon.svg">
|
||||
<link rel="shortcut icon" href="../../favicon.png">
|
||||
<link rel="stylesheet" href="../../css/variables.css">
|
||||
<link rel="stylesheet" href="../../css/general.css">
|
||||
<link rel="stylesheet" href="../../css/chrome.css">
|
||||
<link rel="stylesheet" href="../../css/print.css" media="print">
|
||||
|
||||
<!-- Fonts -->
|
||||
<link rel="stylesheet" href="../../FontAwesome/css/font-awesome.css">
|
||||
<link rel="stylesheet" href="../../fonts/fonts.css">
|
||||
|
||||
<!-- Highlight.js Stylesheets -->
|
||||
<link rel="stylesheet" href="../../highlight.css">
|
||||
<link rel="stylesheet" href="../../tomorrow-night.css">
|
||||
<link rel="stylesheet" href="../../ayu-highlight.css">
|
||||
|
||||
<!-- Custom theme stylesheets -->
|
||||
|
||||
</head>
|
||||
<body>
|
||||
<!-- Provide site root to javascript -->
|
||||
<script type="text/javascript">
|
||||
var path_to_root = "../../";
|
||||
var default_theme = window.matchMedia("(prefers-color-scheme: dark)").matches ? "navy" : "light";
|
||||
</script>
|
||||
|
||||
<!-- Work around some values being stored in localStorage wrapped in quotes -->
|
||||
<script type="text/javascript">
|
||||
try {
|
||||
var theme = localStorage.getItem('mdbook-theme');
|
||||
var sidebar = localStorage.getItem('mdbook-sidebar');
|
||||
|
||||
if (theme.startsWith('"') && theme.endsWith('"')) {
|
||||
localStorage.setItem('mdbook-theme', theme.slice(1, theme.length - 1));
|
||||
}
|
||||
|
||||
if (sidebar.startsWith('"') && sidebar.endsWith('"')) {
|
||||
localStorage.setItem('mdbook-sidebar', sidebar.slice(1, sidebar.length - 1));
|
||||
}
|
||||
} catch (e) { }
|
||||
</script>
|
||||
|
||||
<!-- Set the theme before any content is loaded, prevents flash -->
|
||||
<script type="text/javascript">
|
||||
var theme;
|
||||
try { theme = localStorage.getItem('mdbook-theme'); } catch(e) { }
|
||||
if (theme === null || theme === undefined) { theme = default_theme; }
|
||||
var html = document.querySelector('html');
|
||||
html.classList.remove('no-js')
|
||||
html.classList.remove('light')
|
||||
html.classList.add(theme);
|
||||
html.classList.add('js');
|
||||
</script>
|
||||
|
||||
<!-- Hide / unhide sidebar before it is displayed -->
|
||||
<script type="text/javascript">
|
||||
var html = document.querySelector('html');
|
||||
var sidebar = 'hidden';
|
||||
if (document.body.clientWidth >= 1080) {
|
||||
try { sidebar = localStorage.getItem('mdbook-sidebar'); } catch(e) { }
|
||||
sidebar = sidebar || 'visible';
|
||||
}
|
||||
html.classList.remove('sidebar-visible');
|
||||
html.classList.add("sidebar-" + sidebar);
|
||||
</script>
|
||||
|
||||
<nav id="sidebar" class="sidebar" aria-label="Table of contents">
|
||||
<div class="sidebar-scrollbox">
|
||||
<ol class="chapter"><li class="chapter-item expanded affix "><a href="../../index.html">Introduction</a></li><li class="chapter-item expanded affix "><li class="part-title">Features</li><li class="chapter-item expanded "><a href="../../features/index.html"><strong aria-hidden="true">1.</strong> Adding the Router to Your Application</a></li><li class="chapter-item expanded "><a href="../../features/routes/index.html"><strong aria-hidden="true">2.</strong> Defining Routes</a></li><li><ol class="section"><li class="chapter-item expanded "><a href="../../features/routes/nested.html"><strong aria-hidden="true">2.1.</strong> Nested Routes</a></li><li class="chapter-item expanded "><a href="../../features/routes/catch_all.html"><strong aria-hidden="true">2.2.</strong> Catch All Routes</a></li><li class="chapter-item expanded "><a href="../../features/routes/matching.html"><strong aria-hidden="true">2.3.</strong> Matching Routes</a></li><li class="chapter-item expanded "><a href="../../features/routes/fallback.html"><strong aria-hidden="true">2.4.</strong> Fallback Routes (404 page)</a></li><li class="chapter-item expanded "><a href="../../features/routes/multiple-and-redirect.html" class="active"><strong aria-hidden="true">2.5.</strong> Multiple Components & Redirects</a></li></ol></li><li class="chapter-item expanded "><a href="../../features/outlets.html"><strong aria-hidden="true">3.</strong> Outlets</a></li><li class="chapter-item expanded "><a href="../../features/navigation/index.html"><strong aria-hidden="true">4.</strong> Links & Navigation</a></li><li><ol class="section"><li class="chapter-item expanded "><a href="../../features/navigation/name.html"><strong aria-hidden="true">4.1.</strong> Named Navigation</a></li><li class="chapter-item expanded "><a href="../../features/navigation/external.html"><strong aria-hidden="true">4.2.</strong> External Navigation</a></li><li class="chapter-item expanded "><a href="../../features/navigation/programmatic.html"><strong aria-hidden="true">4.3.</strong> Programmatic Navigation</a></li></ol></li><li class="chapter-item expanded "><a href="../../features/query.html"><strong aria-hidden="true">5.</strong> Query</a></li><li class="chapter-item expanded "><a href="../../features/failures/index.html"><strong aria-hidden="true">6.</strong> Navigation Failures</a></li><li><ol class="section"><li class="chapter-item expanded "><a href="../../features/failures/named.html"><strong aria-hidden="true">6.1.</strong> Named Navigation Failure</a></li><li class="chapter-item expanded "><a href="../../features/failures/external.html"><strong aria-hidden="true">6.2.</strong> External Navigation Failure</a></li><li class="chapter-item expanded "><a href="../../features/failures/redirection-limit.html"><strong aria-hidden="true">6.3.</strong> Redirection Limit Failure</a></li></ol></li><li class="chapter-item expanded "><a href="../../features/history-providers.html"><strong aria-hidden="true">7.</strong> History Providers</a></li><li class="chapter-item expanded "><a href="../../features/history-buttons.html"><strong aria-hidden="true">8.</strong> History Buttons</a></li><li class="chapter-item expanded "><a href="../../features/sitemap-generation.html"><strong aria-hidden="true">9.</strong> Sitemap Generation</a></li><li class="chapter-item expanded "><a href="../../features/routing-update-callback.html"><strong aria-hidden="true">10.</strong> Routing Update Callback</a></li><li class="chapter-item expanded affix "><li class="part-title">Example Project</li><li class="chapter-item expanded "><a href="../../example/index.html"><strong aria-hidden="true">11.</strong> Overview</a></li><li class="chapter-item expanded "><a href="../../example/first-route.html"><strong aria-hidden="true">12.</strong> Creating Our First Route</a></li><li class="chapter-item expanded "><a href="../../example/building-a-nest.html"><strong aria-hidden="true">13.</strong> Building a Nest</a></li><li class="chapter-item expanded "><a href="../../example/navigation-targets.html"><strong aria-hidden="true">14.</strong> Navigation Targets</a></li><li class="chapter-item expanded "><a href="../../example/redirection-perfection.html"><strong aria-hidden="true">15.</strong> Redirection Perfection</a></li><li class="chapter-item expanded "><a href="../../example/full-code.html"><strong aria-hidden="true">16.</strong> Full Code</a></li></ol>
|
||||
</div>
|
||||
<div id="sidebar-resize-handle" class="sidebar-resize-handle"></div>
|
||||
</nav>
|
||||
|
||||
<div id="page-wrapper" class="page-wrapper">
|
||||
|
||||
<div class="page">
|
||||
<div id="menu-bar-hover-placeholder"></div>
|
||||
<div id="menu-bar" class="menu-bar sticky bordered">
|
||||
<div class="left-buttons">
|
||||
<button id="sidebar-toggle" class="icon-button" type="button" title="Toggle Table of Contents" aria-label="Toggle Table of Contents" aria-controls="sidebar">
|
||||
<i class="fa fa-bars"></i>
|
||||
</button>
|
||||
<button id="theme-toggle" class="icon-button" type="button" title="Change theme" aria-label="Change theme" aria-haspopup="true" aria-expanded="false" aria-controls="theme-list">
|
||||
<i class="fa fa-paint-brush"></i>
|
||||
</button>
|
||||
<ul id="theme-list" class="theme-popup" aria-label="Themes" role="menu">
|
||||
<li role="none"><button role="menuitem" class="theme" id="light">Light (default)</button></li>
|
||||
<li role="none"><button role="menuitem" class="theme" id="rust">Rust</button></li>
|
||||
<li role="none"><button role="menuitem" class="theme" id="coal">Coal</button></li>
|
||||
<li role="none"><button role="menuitem" class="theme" id="navy">Navy</button></li>
|
||||
<li role="none"><button role="menuitem" class="theme" id="ayu">Ayu</button></li>
|
||||
</ul>
|
||||
<button id="search-toggle" class="icon-button" type="button" title="Search. (Shortkey: s)" aria-label="Toggle Searchbar" aria-expanded="false" aria-keyshortcuts="S" aria-controls="searchbar">
|
||||
<i class="fa fa-search"></i>
|
||||
</button>
|
||||
</div>
|
||||
|
||||
<h1 class="menu-title">Dioxus Router</h1>
|
||||
|
||||
<div class="right-buttons">
|
||||
<a href="../../print.html" title="Print this book" aria-label="Print this book">
|
||||
<i id="print-button" class="fa fa-print"></i>
|
||||
</a>
|
||||
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div id="search-wrapper" class="hidden">
|
||||
<form id="searchbar-outer" class="searchbar-outer">
|
||||
<input type="search" id="searchbar" name="searchbar" placeholder="Search this book ..." aria-controls="searchresults-outer" aria-describedby="searchresults-header">
|
||||
</form>
|
||||
<div id="searchresults-outer" class="searchresults-outer hidden">
|
||||
<div id="searchresults-header" class="searchresults-header"></div>
|
||||
<ul id="searchresults">
|
||||
</ul>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- Apply ARIA attributes after the sidebar and the sidebar toggle button are added to the DOM -->
|
||||
<script type="text/javascript">
|
||||
document.getElementById('sidebar-toggle').setAttribute('aria-expanded', sidebar === 'visible');
|
||||
document.getElementById('sidebar').setAttribute('aria-hidden', sidebar !== 'visible');
|
||||
Array.from(document.querySelectorAll('#sidebar a')).forEach(function(link) {
|
||||
link.setAttribute('tabIndex', sidebar === 'visible' ? 0 : -1);
|
||||
});
|
||||
</script>
|
||||
|
||||
<div id="content" class="content">
|
||||
<main>
|
||||
<h1 id="multiple-components--redirects"><a class="header" href="#multiple-components--redirects">Multiple Components & Redirects</a></h1>
|
||||
<h2 id="multiple-components"><a class="header" href="#multiple-components">Multiple Components</a></h2>
|
||||
<p>When creating complex apps we sometimes want to have multiple pieces of content
|
||||
side by side. The router allows us to do this. For more details see the section
|
||||
about <a href="../outlets.html#named-outlets">named <code>Outlet</code>s</a>.</p>
|
||||
<h2 id="redirects"><a class="header" href="#redirects">Redirects</a></h2>
|
||||
<p>In some cases we may want to redirect our users to another page whenever they
|
||||
open a specific path. We can tell the router to do this when defining our
|
||||
routes.</p>
|
||||
<blockquote>
|
||||
<p>Redirects to external pages only work in certain conditions. For more details
|
||||
see the chapter about <a href="../failures/external.html">external navigation failures</a>.</p>
|
||||
</blockquote>
|
||||
<p>In the following example we will redirect everybody from <code>/</code> and <code>/start</code> to
|
||||
<code>/home</code>.</p>
|
||||
<pre><pre class="playground"><code class="language-rust edition2021">
|
||||
<span class="boring">#![allow(unused)]
|
||||
</span><span class="boring">fn main() {
|
||||
</span><span class="boring">// Hidden lines (like this one) make the documentation tests work.
|
||||
</span><span class="boring">extern crate dioxus;
|
||||
</span>use dioxus::prelude::*;
|
||||
<span class="boring">extern crate dioxus_router;
|
||||
</span>use dioxus_router::{history::MemoryHistory, prelude::*};
|
||||
<span class="boring">extern crate dioxus_ssr;
|
||||
</span>
|
||||
fn Home(cx: Scope) -> Element {
|
||||
render! {
|
||||
h1 { "Home Page" }
|
||||
}
|
||||
}
|
||||
|
||||
fn App(cx: Scope) -> Element {
|
||||
use_router(
|
||||
cx,
|
||||
&|| RouterConfiguration {
|
||||
<span class="boring"> synchronous: true,
|
||||
</span><span class="boring"> history: Box::new(MemoryHistory::with_initial_path("/home").unwrap()),
|
||||
</span> ..Default::default()
|
||||
},
|
||||
&|| {
|
||||
Segment::content(comp(Home))
|
||||
// notice that we use RouteContent::Redirect instead of
|
||||
// RouteContent::Content (which we have been using indirectly)
|
||||
.fixed(
|
||||
"home",
|
||||
RouteContent::Redirect(NavigationTarget::Internal("/".into()))
|
||||
)
|
||||
.fixed("start", "/") // short form
|
||||
});
|
||||
|
||||
render! {
|
||||
Outlet { }
|
||||
}
|
||||
}
|
||||
<span class="boring">
|
||||
</span><span class="boring">let mut vdom = VirtualDom::new(App);
|
||||
</span><span class="boring">vdom.rebuild();
|
||||
</span><span class="boring">let html = dioxus_ssr::render(&vdom);
|
||||
</span><span class="boring">assert_eq!(html, "<h1>Home Page</h1>");
|
||||
</span><span class="boring">}
|
||||
</span></code></pre></pre>
|
||||
|
||||
</main>
|
||||
|
||||
<nav class="nav-wrapper" aria-label="Page navigation">
|
||||
<!-- Mobile navigation buttons -->
|
||||
<a rel="prev" href="../../features/routes/fallback.html" class="mobile-nav-chapters previous" title="Previous chapter" aria-label="Previous chapter" aria-keyshortcuts="Left">
|
||||
<i class="fa fa-angle-left"></i>
|
||||
</a>
|
||||
|
||||
<a rel="next" href="../../features/outlets.html" class="mobile-nav-chapters next" title="Next chapter" aria-label="Next chapter" aria-keyshortcuts="Right">
|
||||
<i class="fa fa-angle-right"></i>
|
||||
</a>
|
||||
|
||||
<div style="clear: both"></div>
|
||||
</nav>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<nav class="nav-wide-wrapper" aria-label="Page navigation">
|
||||
<a rel="prev" href="../../features/routes/fallback.html" class="nav-chapters previous" title="Previous chapter" aria-label="Previous chapter" aria-keyshortcuts="Left">
|
||||
<i class="fa fa-angle-left"></i>
|
||||
</a>
|
||||
|
||||
<a rel="next" href="../../features/outlets.html" class="nav-chapters next" title="Next chapter" aria-label="Next chapter" aria-keyshortcuts="Right">
|
||||
<i class="fa fa-angle-right"></i>
|
||||
</a>
|
||||
</nav>
|
||||
|
||||
</div>
|
||||
|
||||
|
||||
|
||||
|
||||
<script type="text/javascript">
|
||||
window.playground_copyable = true;
|
||||
</script>
|
||||
|
||||
|
||||
<script src="../../elasticlunr.min.js" type="text/javascript" charset="utf-8"></script>
|
||||
<script src="../../mark.min.js" type="text/javascript" charset="utf-8"></script>
|
||||
<script src="../../searcher.js" type="text/javascript" charset="utf-8"></script>
|
||||
|
||||
<script src="../../clipboard.min.js" type="text/javascript" charset="utf-8"></script>
|
||||
<script src="../../highlight.js" type="text/javascript" charset="utf-8"></script>
|
||||
<script src="../../book.js" type="text/javascript" charset="utf-8"></script>
|
||||
|
||||
<!-- Custom JS scripts -->
|
||||
|
||||
|
||||
</body>
|
||||
</html>
|
||||
@@ -0,0 +1,398 @@
|
||||
<!DOCTYPE HTML>
|
||||
<html lang="en" class="sidebar-visible no-js light">
|
||||
<head>
|
||||
<!-- Book generated using mdBook -->
|
||||
<meta charset="UTF-8">
|
||||
<title>Nested Routes - Dioxus Router</title>
|
||||
|
||||
|
||||
<!-- Custom HTML head -->
|
||||
|
||||
<meta content="text/html; charset=utf-8" http-equiv="Content-Type">
|
||||
<meta name="description" content="">
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1">
|
||||
<meta name="theme-color" content="#ffffff" />
|
||||
|
||||
<link rel="icon" href="../../favicon.svg">
|
||||
<link rel="shortcut icon" href="../../favicon.png">
|
||||
<link rel="stylesheet" href="../../css/variables.css">
|
||||
<link rel="stylesheet" href="../../css/general.css">
|
||||
<link rel="stylesheet" href="../../css/chrome.css">
|
||||
<link rel="stylesheet" href="../../css/print.css" media="print">
|
||||
|
||||
<!-- Fonts -->
|
||||
<link rel="stylesheet" href="../../FontAwesome/css/font-awesome.css">
|
||||
<link rel="stylesheet" href="../../fonts/fonts.css">
|
||||
|
||||
<!-- Highlight.js Stylesheets -->
|
||||
<link rel="stylesheet" href="../../highlight.css">
|
||||
<link rel="stylesheet" href="../../tomorrow-night.css">
|
||||
<link rel="stylesheet" href="../../ayu-highlight.css">
|
||||
|
||||
<!-- Custom theme stylesheets -->
|
||||
|
||||
</head>
|
||||
<body>
|
||||
<!-- Provide site root to javascript -->
|
||||
<script type="text/javascript">
|
||||
var path_to_root = "../../";
|
||||
var default_theme = window.matchMedia("(prefers-color-scheme: dark)").matches ? "navy" : "light";
|
||||
</script>
|
||||
|
||||
<!-- Work around some values being stored in localStorage wrapped in quotes -->
|
||||
<script type="text/javascript">
|
||||
try {
|
||||
var theme = localStorage.getItem('mdbook-theme');
|
||||
var sidebar = localStorage.getItem('mdbook-sidebar');
|
||||
|
||||
if (theme.startsWith('"') && theme.endsWith('"')) {
|
||||
localStorage.setItem('mdbook-theme', theme.slice(1, theme.length - 1));
|
||||
}
|
||||
|
||||
if (sidebar.startsWith('"') && sidebar.endsWith('"')) {
|
||||
localStorage.setItem('mdbook-sidebar', sidebar.slice(1, sidebar.length - 1));
|
||||
}
|
||||
} catch (e) { }
|
||||
</script>
|
||||
|
||||
<!-- Set the theme before any content is loaded, prevents flash -->
|
||||
<script type="text/javascript">
|
||||
var theme;
|
||||
try { theme = localStorage.getItem('mdbook-theme'); } catch(e) { }
|
||||
if (theme === null || theme === undefined) { theme = default_theme; }
|
||||
var html = document.querySelector('html');
|
||||
html.classList.remove('no-js')
|
||||
html.classList.remove('light')
|
||||
html.classList.add(theme);
|
||||
html.classList.add('js');
|
||||
</script>
|
||||
|
||||
<!-- Hide / unhide sidebar before it is displayed -->
|
||||
<script type="text/javascript">
|
||||
var html = document.querySelector('html');
|
||||
var sidebar = 'hidden';
|
||||
if (document.body.clientWidth >= 1080) {
|
||||
try { sidebar = localStorage.getItem('mdbook-sidebar'); } catch(e) { }
|
||||
sidebar = sidebar || 'visible';
|
||||
}
|
||||
html.classList.remove('sidebar-visible');
|
||||
html.classList.add("sidebar-" + sidebar);
|
||||
</script>
|
||||
|
||||
<nav id="sidebar" class="sidebar" aria-label="Table of contents">
|
||||
<div class="sidebar-scrollbox">
|
||||
<ol class="chapter"><li class="chapter-item expanded affix "><a href="../../index.html">Introduction</a></li><li class="chapter-item expanded affix "><li class="part-title">Features</li><li class="chapter-item expanded "><a href="../../features/index.html"><strong aria-hidden="true">1.</strong> Adding the Router to Your Application</a></li><li class="chapter-item expanded "><a href="../../features/routes/index.html"><strong aria-hidden="true">2.</strong> Defining Routes</a></li><li><ol class="section"><li class="chapter-item expanded "><a href="../../features/routes/nested.html" class="active"><strong aria-hidden="true">2.1.</strong> Nested Routes</a></li><li class="chapter-item expanded "><a href="../../features/routes/catch_all.html"><strong aria-hidden="true">2.2.</strong> Catch All Routes</a></li><li class="chapter-item expanded "><a href="../../features/routes/matching.html"><strong aria-hidden="true">2.3.</strong> Matching Routes</a></li><li class="chapter-item expanded "><a href="../../features/routes/fallback.html"><strong aria-hidden="true">2.4.</strong> Fallback Routes (404 page)</a></li><li class="chapter-item expanded "><a href="../../features/routes/multiple-and-redirect.html"><strong aria-hidden="true">2.5.</strong> Multiple Components & Redirects</a></li></ol></li><li class="chapter-item expanded "><a href="../../features/outlets.html"><strong aria-hidden="true">3.</strong> Outlets</a></li><li class="chapter-item expanded "><a href="../../features/navigation/index.html"><strong aria-hidden="true">4.</strong> Links & Navigation</a></li><li><ol class="section"><li class="chapter-item expanded "><a href="../../features/navigation/name.html"><strong aria-hidden="true">4.1.</strong> Named Navigation</a></li><li class="chapter-item expanded "><a href="../../features/navigation/external.html"><strong aria-hidden="true">4.2.</strong> External Navigation</a></li><li class="chapter-item expanded "><a href="../../features/navigation/programmatic.html"><strong aria-hidden="true">4.3.</strong> Programmatic Navigation</a></li></ol></li><li class="chapter-item expanded "><a href="../../features/query.html"><strong aria-hidden="true">5.</strong> Query</a></li><li class="chapter-item expanded "><a href="../../features/failures/index.html"><strong aria-hidden="true">6.</strong> Navigation Failures</a></li><li><ol class="section"><li class="chapter-item expanded "><a href="../../features/failures/named.html"><strong aria-hidden="true">6.1.</strong> Named Navigation Failure</a></li><li class="chapter-item expanded "><a href="../../features/failures/external.html"><strong aria-hidden="true">6.2.</strong> External Navigation Failure</a></li><li class="chapter-item expanded "><a href="../../features/failures/redirection-limit.html"><strong aria-hidden="true">6.3.</strong> Redirection Limit Failure</a></li></ol></li><li class="chapter-item expanded "><a href="../../features/history-providers.html"><strong aria-hidden="true">7.</strong> History Providers</a></li><li class="chapter-item expanded "><a href="../../features/history-buttons.html"><strong aria-hidden="true">8.</strong> History Buttons</a></li><li class="chapter-item expanded "><a href="../../features/sitemap-generation.html"><strong aria-hidden="true">9.</strong> Sitemap Generation</a></li><li class="chapter-item expanded "><a href="../../features/routing-update-callback.html"><strong aria-hidden="true">10.</strong> Routing Update Callback</a></li><li class="chapter-item expanded affix "><li class="part-title">Example Project</li><li class="chapter-item expanded "><a href="../../example/index.html"><strong aria-hidden="true">11.</strong> Overview</a></li><li class="chapter-item expanded "><a href="../../example/first-route.html"><strong aria-hidden="true">12.</strong> Creating Our First Route</a></li><li class="chapter-item expanded "><a href="../../example/building-a-nest.html"><strong aria-hidden="true">13.</strong> Building a Nest</a></li><li class="chapter-item expanded "><a href="../../example/navigation-targets.html"><strong aria-hidden="true">14.</strong> Navigation Targets</a></li><li class="chapter-item expanded "><a href="../../example/redirection-perfection.html"><strong aria-hidden="true">15.</strong> Redirection Perfection</a></li><li class="chapter-item expanded "><a href="../../example/full-code.html"><strong aria-hidden="true">16.</strong> Full Code</a></li></ol>
|
||||
</div>
|
||||
<div id="sidebar-resize-handle" class="sidebar-resize-handle"></div>
|
||||
</nav>
|
||||
|
||||
<div id="page-wrapper" class="page-wrapper">
|
||||
|
||||
<div class="page">
|
||||
<div id="menu-bar-hover-placeholder"></div>
|
||||
<div id="menu-bar" class="menu-bar sticky bordered">
|
||||
<div class="left-buttons">
|
||||
<button id="sidebar-toggle" class="icon-button" type="button" title="Toggle Table of Contents" aria-label="Toggle Table of Contents" aria-controls="sidebar">
|
||||
<i class="fa fa-bars"></i>
|
||||
</button>
|
||||
<button id="theme-toggle" class="icon-button" type="button" title="Change theme" aria-label="Change theme" aria-haspopup="true" aria-expanded="false" aria-controls="theme-list">
|
||||
<i class="fa fa-paint-brush"></i>
|
||||
</button>
|
||||
<ul id="theme-list" class="theme-popup" aria-label="Themes" role="menu">
|
||||
<li role="none"><button role="menuitem" class="theme" id="light">Light (default)</button></li>
|
||||
<li role="none"><button role="menuitem" class="theme" id="rust">Rust</button></li>
|
||||
<li role="none"><button role="menuitem" class="theme" id="coal">Coal</button></li>
|
||||
<li role="none"><button role="menuitem" class="theme" id="navy">Navy</button></li>
|
||||
<li role="none"><button role="menuitem" class="theme" id="ayu">Ayu</button></li>
|
||||
</ul>
|
||||
<button id="search-toggle" class="icon-button" type="button" title="Search. (Shortkey: s)" aria-label="Toggle Searchbar" aria-expanded="false" aria-keyshortcuts="S" aria-controls="searchbar">
|
||||
<i class="fa fa-search"></i>
|
||||
</button>
|
||||
</div>
|
||||
|
||||
<h1 class="menu-title">Dioxus Router</h1>
|
||||
|
||||
<div class="right-buttons">
|
||||
<a href="../../print.html" title="Print this book" aria-label="Print this book">
|
||||
<i id="print-button" class="fa fa-print"></i>
|
||||
</a>
|
||||
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div id="search-wrapper" class="hidden">
|
||||
<form id="searchbar-outer" class="searchbar-outer">
|
||||
<input type="search" id="searchbar" name="searchbar" placeholder="Search this book ..." aria-controls="searchresults-outer" aria-describedby="searchresults-header">
|
||||
</form>
|
||||
<div id="searchresults-outer" class="searchresults-outer hidden">
|
||||
<div id="searchresults-header" class="searchresults-header"></div>
|
||||
<ul id="searchresults">
|
||||
</ul>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- Apply ARIA attributes after the sidebar and the sidebar toggle button are added to the DOM -->
|
||||
<script type="text/javascript">
|
||||
document.getElementById('sidebar-toggle').setAttribute('aria-expanded', sidebar === 'visible');
|
||||
document.getElementById('sidebar').setAttribute('aria-hidden', sidebar !== 'visible');
|
||||
Array.from(document.querySelectorAll('#sidebar a')).forEach(function(link) {
|
||||
link.setAttribute('tabIndex', sidebar === 'visible' ? 0 : -1);
|
||||
});
|
||||
</script>
|
||||
|
||||
<div id="content" class="content">
|
||||
<main>
|
||||
<h1 id="nested-routes"><a class="header" href="#nested-routes">Nested Routes</a></h1>
|
||||
<p>When developing bigger applications we often want to nest routes within each
|
||||
other. As an example, we might want to organize a settings menu using this
|
||||
pattern:</p>
|
||||
<pre><code class="language-plain">└ Settings
|
||||
├ General Settings (displayed when opening the settings)
|
||||
├ Change Password
|
||||
└ Privacy Settings
|
||||
</code></pre>
|
||||
<p>We might want to map this structure to these paths and components:</p>
|
||||
<pre><code class="language-plain">/settings -> Settings { GeneralSettings }
|
||||
/settings/password -> Settings { PWSettings }
|
||||
/settings/privacy -> Settings { PrivacySettings }
|
||||
</code></pre>
|
||||
<p>Nested routes allow us to do this.</p>
|
||||
<h2 id="route-depth"><a class="header" href="#route-depth">Route Depth</a></h2>
|
||||
<p>With nesting routes, the router manages content on multiple levels. In our
|
||||
example, when the path is <code>/settings</code>, there are two levels of content:</p>
|
||||
<ol start="0">
|
||||
<li>The <code>Settings</code> component</li>
|
||||
<li>The <code>GeneralSettings</code> component</li>
|
||||
</ol>
|
||||
<p>Dioxus Router uses the <a href="https://docs.rs/dioxus-router/latest/dioxus_router/components/fn.Outlet.html"><code>Outlet</code></a> component to actually render content, but each
|
||||
<a href="https://docs.rs/dioxus-router/latest/dioxus_router/components/fn.Outlet.html"><code>Outlet</code></a> can only render content from one level. This means that for the
|
||||
content of nested routes to actually be rendered, we also need nested
|
||||
<a href="https://docs.rs/dioxus-router/latest/dioxus_router/components/fn.Outlet.html"><code>Outlet</code></a>s.</p>
|
||||
<h2 id="defining-the-content-components"><a class="header" href="#defining-the-content-components">Defining the content components</a></h2>
|
||||
<p>We start by creating the components we want the router to render.</p>
|
||||
<p>Take a look at the <code>Settings</code> component. When it gets rendered by an <a href="https://docs.rs/dioxus-router/latest/dioxus_router/components/fn.Outlet.html"><code>Outlet</code></a>,
|
||||
it will render a second <a href="https://docs.rs/dioxus-router/latest/dioxus_router/components/fn.Outlet.html"><code>Outlet</code></a>. Thus the second <a href="https://docs.rs/dioxus-router/latest/dioxus_router/components/fn.Outlet.html"><code>Outlet</code></a> is nested within
|
||||
the first one, and will in turn render our nested content.</p>
|
||||
<pre><pre class="playground"><code class="language-rust no_run edition2021">
|
||||
<span class="boring">#![allow(unused)]
|
||||
</span><span class="boring">fn main() {
|
||||
</span><span class="boring">// Hidden lines (like this one) make the documentation tests work.
|
||||
</span><span class="boring">extern crate dioxus;
|
||||
</span><span class="boring">use dioxus::prelude::*;
|
||||
</span><span class="boring">extern crate dioxus_router;
|
||||
</span><span class="boring">use dioxus_router::prelude::*;
|
||||
</span><span class="boring">
|
||||
</span>fn Settings(cx: Scope) -> Element {
|
||||
render! {
|
||||
h1 { "Settings" }
|
||||
Outlet { }
|
||||
}
|
||||
}
|
||||
|
||||
fn GeneralSettings(cx: Scope) -> Element {
|
||||
render! {
|
||||
h2 { "General Settings" }
|
||||
}
|
||||
}
|
||||
|
||||
fn PWSettings(cx: Scope) -> Element {
|
||||
render! {
|
||||
h2 { "Password Settings" }
|
||||
}
|
||||
}
|
||||
|
||||
fn PrivacySettings(cx: Scope) -> Element {
|
||||
render! {
|
||||
h2 { "Privacy Settings" }
|
||||
}
|
||||
}
|
||||
<span class="boring">}
|
||||
</span></code></pre></pre>
|
||||
<h2 id="defining-the-root-segment"><a class="header" href="#defining-the-root-segment">Defining the root <a href="https://docs.rs/dioxus-router-core/latest/dioxus_router_core/routes/struct.Segment.html"><code>Segment</code></a></a></h2>
|
||||
<p>Now we create the <a href="https://docs.rs/dioxus-router-core/latest/dioxus_router_core/routes/struct.Segment.html"><code>Segment</code></a> that we will pass to the router.</p>
|
||||
<p>Note that we wrap <code>comp(Settings)</code> within a <a href="https://docs.rs/dioxus-router-core/latest/dioxus_router_core/routes/struct.Route.html"><code>Route</code></a>. For this exact code that
|
||||
is unnecessary, as this would be done automatically. However, in the next step
|
||||
we'll use a method of <a href="https://docs.rs/dioxus-router-core/latest/dioxus_router_core/routes/struct.Route.html"><code>Route</code></a>, so we might as well add this now.</p>
|
||||
<pre><pre class="playground"><code class="language-rust no_run edition2021">
|
||||
<span class="boring">#![allow(unused)]
|
||||
</span><span class="boring">fn main() {
|
||||
</span><span class="boring">// Hidden lines (like this one) make the documentation tests work.
|
||||
</span><span class="boring">extern crate dioxus;
|
||||
</span><span class="boring">use dioxus::prelude::*;
|
||||
</span><span class="boring">extern crate dioxus_router;
|
||||
</span><span class="boring">use dioxus_router::prelude::*;
|
||||
</span><span class="boring">fn Settings(cx: Scope) -> Element { unimplemented!() }
|
||||
</span><span class="boring">
|
||||
</span>fn App(cx: Scope) -> Element {
|
||||
use_router(
|
||||
cx,
|
||||
&|| RouterConfiguration {
|
||||
..Default::default()
|
||||
},
|
||||
&|| Segment::empty().fixed("settings", Route::content(comp(Settings)))
|
||||
);
|
||||
|
||||
// ...
|
||||
<span class="boring"> unimplemented!()
|
||||
</span>}
|
||||
<span class="boring">}
|
||||
</span></code></pre></pre>
|
||||
<h2 id="defining-the-nested-segment"><a class="header" href="#defining-the-nested-segment">Defining the nested <a href="https://docs.rs/dioxus-router-core/latest/dioxus_router_core/routes/struct.Segment.html"><code>Segment</code></a></a></h2>
|
||||
<p>In order to create nested routes we need to create a nested <a href="https://docs.rs/dioxus-router-core/latest/dioxus_router_core/routes/struct.Segment.html"><code>Segment</code></a>. We then
|
||||
pass it to the <a href="https://docs.rs/dioxus-router-core/latest/dioxus_router_core/routes/struct.Route.html"><code>Route</code></a> on the root segment.</p>
|
||||
<blockquote>
|
||||
<p>A <a href="https://docs.rs/dioxus-router-core/latest/dioxus_router_core/routes/struct.Segment.html"><code>Segment</code></a> always refers to one exact segment of the path.</p>
|
||||
<p>https://router.example/<code>root_segment</code>/<code>first_nested_segment</code>/<code>second_nested_segment</code>/...</p>
|
||||
</blockquote>
|
||||
<pre><pre class="playground"><code class="language-rust no_run edition2021">
|
||||
<span class="boring">#![allow(unused)]
|
||||
</span><span class="boring">fn main() {
|
||||
</span><span class="boring">// Hidden lines (like this one) make the documentation tests work.
|
||||
</span><span class="boring">extern crate dioxus;
|
||||
</span><span class="boring">use dioxus::prelude::*;
|
||||
</span><span class="boring">extern crate dioxus_router;
|
||||
</span><span class="boring">use dioxus_router::prelude::*;
|
||||
</span><span class="boring">fn Settings(cx: Scope) -> Element { unimplemented!() }
|
||||
</span><span class="boring">fn GeneralSettings(cx: Scope) -> Element { unimplemented!() }
|
||||
</span><span class="boring">fn PWSettings(cx: Scope) -> Element { unimplemented!() }
|
||||
</span><span class="boring">fn PrivacySettings(cx: Scope) -> Element { unimplemented!() }
|
||||
</span><span class="boring">
|
||||
</span>fn App(cx: Scope) -> Element {
|
||||
use_router(
|
||||
cx,
|
||||
&|| RouterConfiguration {
|
||||
..Default::default()
|
||||
},
|
||||
&|| Segment::empty().fixed(
|
||||
"settings",
|
||||
Route::content(comp(Settings)).nested(
|
||||
Segment::content(comp(GeneralSettings))
|
||||
.fixed("password", comp(PWSettings))
|
||||
.fixed("privacy", comp(PrivacySettings))
|
||||
)
|
||||
)
|
||||
);
|
||||
|
||||
// ...
|
||||
<span class="boring"> unimplemented!()
|
||||
</span>}
|
||||
<span class="boring">}
|
||||
</span></code></pre></pre>
|
||||
<h2 id="full-code"><a class="header" href="#full-code">Full Code</a></h2>
|
||||
<pre><pre class="playground"><code class="language-rust edition2021">
|
||||
<span class="boring">#![allow(unused)]
|
||||
</span><span class="boring">fn main() {
|
||||
</span><span class="boring">// Hidden lines (like this one) make the documentation tests work.
|
||||
</span><span class="boring">extern crate dioxus;
|
||||
</span><span class="boring">use dioxus::prelude::*;
|
||||
</span><span class="boring">extern crate dioxus_router;
|
||||
</span><span class="boring">use dioxus_router::{history::MemoryHistory, prelude::*};
|
||||
</span><span class="boring">extern crate dioxus_ssr;
|
||||
</span><span class="boring">
|
||||
</span>fn Settings(cx: Scope) -> Element {
|
||||
render! {
|
||||
h1 { "Settings" }
|
||||
Outlet { }
|
||||
}
|
||||
}
|
||||
|
||||
fn GeneralSettings(cx: Scope) -> Element {
|
||||
render! {
|
||||
h2 { "General Settings" }
|
||||
}
|
||||
}
|
||||
|
||||
fn PWSettings(cx: Scope) -> Element {
|
||||
render! {
|
||||
h2 { "Password Settings" }
|
||||
}
|
||||
}
|
||||
|
||||
fn PrivacySettings(cx: Scope) -> Element {
|
||||
render! {
|
||||
h2 { "Privacy Settings" }
|
||||
}
|
||||
}
|
||||
|
||||
fn App(cx: Scope) -> Element {
|
||||
use_router(
|
||||
cx,
|
||||
&|| RouterConfiguration {
|
||||
<span class="boring"> synchronous: true,
|
||||
</span><span class="boring"> history: Box::new(MemoryHistory::with_initial_path("/settings/privacy").unwrap()),
|
||||
</span> ..Default::default()
|
||||
},
|
||||
&|| Segment::empty().fixed(
|
||||
"settings",
|
||||
Route::content(comp(Settings)).nested(
|
||||
Segment::content(comp(GeneralSettings))
|
||||
.fixed("password", comp(PWSettings))
|
||||
.fixed("privacy", comp(PrivacySettings))
|
||||
)
|
||||
)
|
||||
);
|
||||
|
||||
render! {
|
||||
Outlet { }
|
||||
}
|
||||
}
|
||||
<span class="boring">
|
||||
</span><span class="boring">let mut vdom = VirtualDom::new(App);
|
||||
</span><span class="boring">vdom.rebuild();
|
||||
</span><span class="boring">assert_eq!(
|
||||
</span><span class="boring"> dioxus_ssr::render(&vdom),
|
||||
</span><span class="boring"> "<h1>Settings</h1><h2>Privacy Settings</h2>"
|
||||
</span><span class="boring">);
|
||||
</span><span class="boring">}
|
||||
</span></code></pre></pre>
|
||||
|
||||
</main>
|
||||
|
||||
<nav class="nav-wrapper" aria-label="Page navigation">
|
||||
<!-- Mobile navigation buttons -->
|
||||
<a rel="prev" href="../../features/routes/index.html" class="mobile-nav-chapters previous" title="Previous chapter" aria-label="Previous chapter" aria-keyshortcuts="Left">
|
||||
<i class="fa fa-angle-left"></i>
|
||||
</a>
|
||||
|
||||
<a rel="next" href="../../features/routes/catch_all.html" class="mobile-nav-chapters next" title="Next chapter" aria-label="Next chapter" aria-keyshortcuts="Right">
|
||||
<i class="fa fa-angle-right"></i>
|
||||
</a>
|
||||
|
||||
<div style="clear: both"></div>
|
||||
</nav>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<nav class="nav-wide-wrapper" aria-label="Page navigation">
|
||||
<a rel="prev" href="../../features/routes/index.html" class="nav-chapters previous" title="Previous chapter" aria-label="Previous chapter" aria-keyshortcuts="Left">
|
||||
<i class="fa fa-angle-left"></i>
|
||||
</a>
|
||||
|
||||
<a rel="next" href="../../features/routes/catch_all.html" class="nav-chapters next" title="Next chapter" aria-label="Next chapter" aria-keyshortcuts="Right">
|
||||
<i class="fa fa-angle-right"></i>
|
||||
</a>
|
||||
</nav>
|
||||
|
||||
</div>
|
||||
|
||||
|
||||
|
||||
|
||||
<script type="text/javascript">
|
||||
window.playground_copyable = true;
|
||||
</script>
|
||||
|
||||
|
||||
<script src="../../elasticlunr.min.js" type="text/javascript" charset="utf-8"></script>
|
||||
<script src="../../mark.min.js" type="text/javascript" charset="utf-8"></script>
|
||||
<script src="../../searcher.js" type="text/javascript" charset="utf-8"></script>
|
||||
|
||||
<script src="../../clipboard.min.js" type="text/javascript" charset="utf-8"></script>
|
||||
<script src="../../highlight.js" type="text/javascript" charset="utf-8"></script>
|
||||
<script src="../../book.js" type="text/javascript" charset="utf-8"></script>
|
||||
|
||||
<!-- Custom JS scripts -->
|
||||
|
||||
|
||||
</body>
|
||||
</html>
|
||||
@@ -0,0 +1,257 @@
|
||||
<!DOCTYPE HTML>
|
||||
<html lang="en" class="sidebar-visible no-js light">
|
||||
<head>
|
||||
<!-- Book generated using mdBook -->
|
||||
<meta charset="UTF-8">
|
||||
<title>Routing Update Callback - Dioxus Router</title>
|
||||
|
||||
|
||||
<!-- Custom HTML head -->
|
||||
|
||||
<meta content="text/html; charset=utf-8" http-equiv="Content-Type">
|
||||
<meta name="description" content="">
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1">
|
||||
<meta name="theme-color" content="#ffffff" />
|
||||
|
||||
<link rel="icon" href="../favicon.svg">
|
||||
<link rel="shortcut icon" href="../favicon.png">
|
||||
<link rel="stylesheet" href="../css/variables.css">
|
||||
<link rel="stylesheet" href="../css/general.css">
|
||||
<link rel="stylesheet" href="../css/chrome.css">
|
||||
<link rel="stylesheet" href="../css/print.css" media="print">
|
||||
|
||||
<!-- Fonts -->
|
||||
<link rel="stylesheet" href="../FontAwesome/css/font-awesome.css">
|
||||
<link rel="stylesheet" href="../fonts/fonts.css">
|
||||
|
||||
<!-- Highlight.js Stylesheets -->
|
||||
<link rel="stylesheet" href="../highlight.css">
|
||||
<link rel="stylesheet" href="../tomorrow-night.css">
|
||||
<link rel="stylesheet" href="../ayu-highlight.css">
|
||||
|
||||
<!-- Custom theme stylesheets -->
|
||||
|
||||
</head>
|
||||
<body>
|
||||
<!-- Provide site root to javascript -->
|
||||
<script type="text/javascript">
|
||||
var path_to_root = "../";
|
||||
var default_theme = window.matchMedia("(prefers-color-scheme: dark)").matches ? "navy" : "light";
|
||||
</script>
|
||||
|
||||
<!-- Work around some values being stored in localStorage wrapped in quotes -->
|
||||
<script type="text/javascript">
|
||||
try {
|
||||
var theme = localStorage.getItem('mdbook-theme');
|
||||
var sidebar = localStorage.getItem('mdbook-sidebar');
|
||||
|
||||
if (theme.startsWith('"') && theme.endsWith('"')) {
|
||||
localStorage.setItem('mdbook-theme', theme.slice(1, theme.length - 1));
|
||||
}
|
||||
|
||||
if (sidebar.startsWith('"') && sidebar.endsWith('"')) {
|
||||
localStorage.setItem('mdbook-sidebar', sidebar.slice(1, sidebar.length - 1));
|
||||
}
|
||||
} catch (e) { }
|
||||
</script>
|
||||
|
||||
<!-- Set the theme before any content is loaded, prevents flash -->
|
||||
<script type="text/javascript">
|
||||
var theme;
|
||||
try { theme = localStorage.getItem('mdbook-theme'); } catch(e) { }
|
||||
if (theme === null || theme === undefined) { theme = default_theme; }
|
||||
var html = document.querySelector('html');
|
||||
html.classList.remove('no-js')
|
||||
html.classList.remove('light')
|
||||
html.classList.add(theme);
|
||||
html.classList.add('js');
|
||||
</script>
|
||||
|
||||
<!-- Hide / unhide sidebar before it is displayed -->
|
||||
<script type="text/javascript">
|
||||
var html = document.querySelector('html');
|
||||
var sidebar = 'hidden';
|
||||
if (document.body.clientWidth >= 1080) {
|
||||
try { sidebar = localStorage.getItem('mdbook-sidebar'); } catch(e) { }
|
||||
sidebar = sidebar || 'visible';
|
||||
}
|
||||
html.classList.remove('sidebar-visible');
|
||||
html.classList.add("sidebar-" + sidebar);
|
||||
</script>
|
||||
|
||||
<nav id="sidebar" class="sidebar" aria-label="Table of contents">
|
||||
<div class="sidebar-scrollbox">
|
||||
<ol class="chapter"><li class="chapter-item expanded affix "><a href="../index.html">Introduction</a></li><li class="chapter-item expanded affix "><li class="part-title">Features</li><li class="chapter-item expanded "><a href="../features/index.html"><strong aria-hidden="true">1.</strong> Adding the Router to Your Application</a></li><li class="chapter-item expanded "><a href="../features/routes/index.html"><strong aria-hidden="true">2.</strong> Defining Routes</a></li><li><ol class="section"><li class="chapter-item expanded "><a href="../features/routes/nested.html"><strong aria-hidden="true">2.1.</strong> Nested Routes</a></li><li class="chapter-item expanded "><a href="../features/routes/catch_all.html"><strong aria-hidden="true">2.2.</strong> Catch All Routes</a></li><li class="chapter-item expanded "><a href="../features/routes/matching.html"><strong aria-hidden="true">2.3.</strong> Matching Routes</a></li><li class="chapter-item expanded "><a href="../features/routes/fallback.html"><strong aria-hidden="true">2.4.</strong> Fallback Routes (404 page)</a></li><li class="chapter-item expanded "><a href="../features/routes/multiple-and-redirect.html"><strong aria-hidden="true">2.5.</strong> Multiple Components & Redirects</a></li></ol></li><li class="chapter-item expanded "><a href="../features/outlets.html"><strong aria-hidden="true">3.</strong> Outlets</a></li><li class="chapter-item expanded "><a href="../features/navigation/index.html"><strong aria-hidden="true">4.</strong> Links & Navigation</a></li><li><ol class="section"><li class="chapter-item expanded "><a href="../features/navigation/name.html"><strong aria-hidden="true">4.1.</strong> Named Navigation</a></li><li class="chapter-item expanded "><a href="../features/navigation/external.html"><strong aria-hidden="true">4.2.</strong> External Navigation</a></li><li class="chapter-item expanded "><a href="../features/navigation/programmatic.html"><strong aria-hidden="true">4.3.</strong> Programmatic Navigation</a></li></ol></li><li class="chapter-item expanded "><a href="../features/query.html"><strong aria-hidden="true">5.</strong> Query</a></li><li class="chapter-item expanded "><a href="../features/failures/index.html"><strong aria-hidden="true">6.</strong> Navigation Failures</a></li><li><ol class="section"><li class="chapter-item expanded "><a href="../features/failures/named.html"><strong aria-hidden="true">6.1.</strong> Named Navigation Failure</a></li><li class="chapter-item expanded "><a href="../features/failures/external.html"><strong aria-hidden="true">6.2.</strong> External Navigation Failure</a></li><li class="chapter-item expanded "><a href="../features/failures/redirection-limit.html"><strong aria-hidden="true">6.3.</strong> Redirection Limit Failure</a></li></ol></li><li class="chapter-item expanded "><a href="../features/history-providers.html"><strong aria-hidden="true">7.</strong> History Providers</a></li><li class="chapter-item expanded "><a href="../features/history-buttons.html"><strong aria-hidden="true">8.</strong> History Buttons</a></li><li class="chapter-item expanded "><a href="../features/sitemap-generation.html"><strong aria-hidden="true">9.</strong> Sitemap Generation</a></li><li class="chapter-item expanded "><a href="../features/routing-update-callback.html" class="active"><strong aria-hidden="true">10.</strong> Routing Update Callback</a></li><li class="chapter-item expanded affix "><li class="part-title">Example Project</li><li class="chapter-item expanded "><a href="../example/index.html"><strong aria-hidden="true">11.</strong> Overview</a></li><li class="chapter-item expanded "><a href="../example/first-route.html"><strong aria-hidden="true">12.</strong> Creating Our First Route</a></li><li class="chapter-item expanded "><a href="../example/building-a-nest.html"><strong aria-hidden="true">13.</strong> Building a Nest</a></li><li class="chapter-item expanded "><a href="../example/navigation-targets.html"><strong aria-hidden="true">14.</strong> Navigation Targets</a></li><li class="chapter-item expanded "><a href="../example/redirection-perfection.html"><strong aria-hidden="true">15.</strong> Redirection Perfection</a></li><li class="chapter-item expanded "><a href="../example/full-code.html"><strong aria-hidden="true">16.</strong> Full Code</a></li></ol>
|
||||
</div>
|
||||
<div id="sidebar-resize-handle" class="sidebar-resize-handle"></div>
|
||||
</nav>
|
||||
|
||||
<div id="page-wrapper" class="page-wrapper">
|
||||
|
||||
<div class="page">
|
||||
<div id="menu-bar-hover-placeholder"></div>
|
||||
<div id="menu-bar" class="menu-bar sticky bordered">
|
||||
<div class="left-buttons">
|
||||
<button id="sidebar-toggle" class="icon-button" type="button" title="Toggle Table of Contents" aria-label="Toggle Table of Contents" aria-controls="sidebar">
|
||||
<i class="fa fa-bars"></i>
|
||||
</button>
|
||||
<button id="theme-toggle" class="icon-button" type="button" title="Change theme" aria-label="Change theme" aria-haspopup="true" aria-expanded="false" aria-controls="theme-list">
|
||||
<i class="fa fa-paint-brush"></i>
|
||||
</button>
|
||||
<ul id="theme-list" class="theme-popup" aria-label="Themes" role="menu">
|
||||
<li role="none"><button role="menuitem" class="theme" id="light">Light (default)</button></li>
|
||||
<li role="none"><button role="menuitem" class="theme" id="rust">Rust</button></li>
|
||||
<li role="none"><button role="menuitem" class="theme" id="coal">Coal</button></li>
|
||||
<li role="none"><button role="menuitem" class="theme" id="navy">Navy</button></li>
|
||||
<li role="none"><button role="menuitem" class="theme" id="ayu">Ayu</button></li>
|
||||
</ul>
|
||||
<button id="search-toggle" class="icon-button" type="button" title="Search. (Shortkey: s)" aria-label="Toggle Searchbar" aria-expanded="false" aria-keyshortcuts="S" aria-controls="searchbar">
|
||||
<i class="fa fa-search"></i>
|
||||
</button>
|
||||
</div>
|
||||
|
||||
<h1 class="menu-title">Dioxus Router</h1>
|
||||
|
||||
<div class="right-buttons">
|
||||
<a href="../print.html" title="Print this book" aria-label="Print this book">
|
||||
<i id="print-button" class="fa fa-print"></i>
|
||||
</a>
|
||||
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div id="search-wrapper" class="hidden">
|
||||
<form id="searchbar-outer" class="searchbar-outer">
|
||||
<input type="search" id="searchbar" name="searchbar" placeholder="Search this book ..." aria-controls="searchresults-outer" aria-describedby="searchresults-header">
|
||||
</form>
|
||||
<div id="searchresults-outer" class="searchresults-outer hidden">
|
||||
<div id="searchresults-header" class="searchresults-header"></div>
|
||||
<ul id="searchresults">
|
||||
</ul>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- Apply ARIA attributes after the sidebar and the sidebar toggle button are added to the DOM -->
|
||||
<script type="text/javascript">
|
||||
document.getElementById('sidebar-toggle').setAttribute('aria-expanded', sidebar === 'visible');
|
||||
document.getElementById('sidebar').setAttribute('aria-hidden', sidebar !== 'visible');
|
||||
Array.from(document.querySelectorAll('#sidebar a')).forEach(function(link) {
|
||||
link.setAttribute('tabIndex', sidebar === 'visible' ? 0 : -1);
|
||||
});
|
||||
</script>
|
||||
|
||||
<div id="content" class="content">
|
||||
<main>
|
||||
<h1 id="routing-update-callback"><a class="header" href="#routing-update-callback">Routing Update Callback</a></h1>
|
||||
<p>In some cases we might want to run custom code when the current route changes.
|
||||
For this reason, the <a href="https://docs.rs/dioxus-router/latest/dioxus_router/hooks/struct.RouterConfiguration.html"><code>RouterConfiguration</code></a> exposes an <code>on_update</code> field.</p>
|
||||
<h2 id="how-does-the-callback-behave"><a class="header" href="#how-does-the-callback-behave">How does the callback behave?</a></h2>
|
||||
<p>The <code>on_update</code> is called whenever the current routing information changes. It
|
||||
is called after the router updated its internal state, but before depended
|
||||
components and hooks are updated.</p>
|
||||
<p>If the callback returns a <a href="https://docs.rs/dioxus-router-core/latest/dioxus_router_core/navigation/enum.NavigationTarget.html"><code>NavigationTarget</code></a>, the router will replace the
|
||||
current location with the specified target. It will not call the
|
||||
<code>on_update</code> again.</p>
|
||||
<p>If at any point the router encounters a
|
||||
<a href="./failures/index.html">navigation failure</a>, it will go to the appropriate state
|
||||
without calling the <code>on_update</code>. It doesn't matter if the invalid target
|
||||
initiated the navigation, was found as a redirect target or returned by the
|
||||
<code>on_update</code> itself.</p>
|
||||
<h2 id="code-example"><a class="header" href="#code-example">Code Example</a></h2>
|
||||
<pre><pre class="playground"><code class="language-rust edition2021">
|
||||
<span class="boring">#![allow(unused)]
|
||||
</span><span class="boring">fn main() {
|
||||
</span><span class="boring">// Hidden lines (like this one) make the documentation tests work.
|
||||
</span><span class="boring">extern crate dioxus;
|
||||
</span><span class="boring">extern crate dioxus_router;
|
||||
</span><span class="boring">extern crate dioxus_ssr;
|
||||
</span><span class="boring">
|
||||
</span>use std::sync::Arc;
|
||||
|
||||
use dioxus::prelude::*;
|
||||
use dioxus_router::prelude::*;
|
||||
|
||||
fn App(cx: Scope) -> Element {
|
||||
use_router(
|
||||
cx,
|
||||
&|| RouterConfiguration {
|
||||
<span class="boring"> synchronous: true,
|
||||
</span> on_update: Some(Arc::new(|state| -> Option<NavigationTarget> {
|
||||
if state.path == "/" {
|
||||
return Some("/home".into());
|
||||
}
|
||||
|
||||
None
|
||||
})),
|
||||
..Default::default()
|
||||
},
|
||||
&|| Segment::empty().fixed("home", comp(Content))
|
||||
);
|
||||
|
||||
render! {
|
||||
Outlet { }
|
||||
}
|
||||
}
|
||||
|
||||
fn Content(cx: Scope) -> Element {
|
||||
render! {
|
||||
p { "Some content" }
|
||||
}
|
||||
}
|
||||
<span class="boring">
|
||||
</span><span class="boring">let mut vdom = VirtualDom::new(App);
|
||||
</span><span class="boring">vdom.rebuild();
|
||||
</span><span class="boring">assert_eq!(dioxus_ssr::render(&mut vdom), "<p>Some content</p>");
|
||||
</span><span class="boring">}
|
||||
</span></code></pre></pre>
|
||||
|
||||
</main>
|
||||
|
||||
<nav class="nav-wrapper" aria-label="Page navigation">
|
||||
<!-- Mobile navigation buttons -->
|
||||
<a rel="prev" href="../features/sitemap-generation.html" class="mobile-nav-chapters previous" title="Previous chapter" aria-label="Previous chapter" aria-keyshortcuts="Left">
|
||||
<i class="fa fa-angle-left"></i>
|
||||
</a>
|
||||
|
||||
<a rel="next" href="../example/index.html" class="mobile-nav-chapters next" title="Next chapter" aria-label="Next chapter" aria-keyshortcuts="Right">
|
||||
<i class="fa fa-angle-right"></i>
|
||||
</a>
|
||||
|
||||
<div style="clear: both"></div>
|
||||
</nav>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<nav class="nav-wide-wrapper" aria-label="Page navigation">
|
||||
<a rel="prev" href="../features/sitemap-generation.html" class="nav-chapters previous" title="Previous chapter" aria-label="Previous chapter" aria-keyshortcuts="Left">
|
||||
<i class="fa fa-angle-left"></i>
|
||||
</a>
|
||||
|
||||
<a rel="next" href="../example/index.html" class="nav-chapters next" title="Next chapter" aria-label="Next chapter" aria-keyshortcuts="Right">
|
||||
<i class="fa fa-angle-right"></i>
|
||||
</a>
|
||||
</nav>
|
||||
|
||||
</div>
|
||||
|
||||
|
||||
|
||||
|
||||
<script type="text/javascript">
|
||||
window.playground_copyable = true;
|
||||
</script>
|
||||
|
||||
|
||||
<script src="../elasticlunr.min.js" type="text/javascript" charset="utf-8"></script>
|
||||
<script src="../mark.min.js" type="text/javascript" charset="utf-8"></script>
|
||||
<script src="../searcher.js" type="text/javascript" charset="utf-8"></script>
|
||||
|
||||
<script src="../clipboard.min.js" type="text/javascript" charset="utf-8"></script>
|
||||
<script src="../highlight.js" type="text/javascript" charset="utf-8"></script>
|
||||
<script src="../book.js" type="text/javascript" charset="utf-8"></script>
|
||||
|
||||
<!-- Custom JS scripts -->
|
||||
|
||||
|
||||
</body>
|
||||
</html>
|
||||
@@ -0,0 +1,414 @@
|
||||
<!DOCTYPE HTML>
|
||||
<html lang="en" class="sidebar-visible no-js light">
|
||||
<head>
|
||||
<!-- Book generated using mdBook -->
|
||||
<meta charset="UTF-8">
|
||||
<title>Sitemap Generation - Dioxus Router</title>
|
||||
|
||||
|
||||
<!-- Custom HTML head -->
|
||||
|
||||
<meta content="text/html; charset=utf-8" http-equiv="Content-Type">
|
||||
<meta name="description" content="">
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1">
|
||||
<meta name="theme-color" content="#ffffff" />
|
||||
|
||||
<link rel="icon" href="../favicon.svg">
|
||||
<link rel="shortcut icon" href="../favicon.png">
|
||||
<link rel="stylesheet" href="../css/variables.css">
|
||||
<link rel="stylesheet" href="../css/general.css">
|
||||
<link rel="stylesheet" href="../css/chrome.css">
|
||||
<link rel="stylesheet" href="../css/print.css" media="print">
|
||||
|
||||
<!-- Fonts -->
|
||||
<link rel="stylesheet" href="../FontAwesome/css/font-awesome.css">
|
||||
<link rel="stylesheet" href="../fonts/fonts.css">
|
||||
|
||||
<!-- Highlight.js Stylesheets -->
|
||||
<link rel="stylesheet" href="../highlight.css">
|
||||
<link rel="stylesheet" href="../tomorrow-night.css">
|
||||
<link rel="stylesheet" href="../ayu-highlight.css">
|
||||
|
||||
<!-- Custom theme stylesheets -->
|
||||
|
||||
</head>
|
||||
<body>
|
||||
<!-- Provide site root to javascript -->
|
||||
<script type="text/javascript">
|
||||
var path_to_root = "../";
|
||||
var default_theme = window.matchMedia("(prefers-color-scheme: dark)").matches ? "navy" : "light";
|
||||
</script>
|
||||
|
||||
<!-- Work around some values being stored in localStorage wrapped in quotes -->
|
||||
<script type="text/javascript">
|
||||
try {
|
||||
var theme = localStorage.getItem('mdbook-theme');
|
||||
var sidebar = localStorage.getItem('mdbook-sidebar');
|
||||
|
||||
if (theme.startsWith('"') && theme.endsWith('"')) {
|
||||
localStorage.setItem('mdbook-theme', theme.slice(1, theme.length - 1));
|
||||
}
|
||||
|
||||
if (sidebar.startsWith('"') && sidebar.endsWith('"')) {
|
||||
localStorage.setItem('mdbook-sidebar', sidebar.slice(1, sidebar.length - 1));
|
||||
}
|
||||
} catch (e) { }
|
||||
</script>
|
||||
|
||||
<!-- Set the theme before any content is loaded, prevents flash -->
|
||||
<script type="text/javascript">
|
||||
var theme;
|
||||
try { theme = localStorage.getItem('mdbook-theme'); } catch(e) { }
|
||||
if (theme === null || theme === undefined) { theme = default_theme; }
|
||||
var html = document.querySelector('html');
|
||||
html.classList.remove('no-js')
|
||||
html.classList.remove('light')
|
||||
html.classList.add(theme);
|
||||
html.classList.add('js');
|
||||
</script>
|
||||
|
||||
<!-- Hide / unhide sidebar before it is displayed -->
|
||||
<script type="text/javascript">
|
||||
var html = document.querySelector('html');
|
||||
var sidebar = 'hidden';
|
||||
if (document.body.clientWidth >= 1080) {
|
||||
try { sidebar = localStorage.getItem('mdbook-sidebar'); } catch(e) { }
|
||||
sidebar = sidebar || 'visible';
|
||||
}
|
||||
html.classList.remove('sidebar-visible');
|
||||
html.classList.add("sidebar-" + sidebar);
|
||||
</script>
|
||||
|
||||
<nav id="sidebar" class="sidebar" aria-label="Table of contents">
|
||||
<div class="sidebar-scrollbox">
|
||||
<ol class="chapter"><li class="chapter-item expanded affix "><a href="../index.html">Introduction</a></li><li class="chapter-item expanded affix "><li class="part-title">Features</li><li class="chapter-item expanded "><a href="../features/index.html"><strong aria-hidden="true">1.</strong> Adding the Router to Your Application</a></li><li class="chapter-item expanded "><a href="../features/routes/index.html"><strong aria-hidden="true">2.</strong> Defining Routes</a></li><li><ol class="section"><li class="chapter-item expanded "><a href="../features/routes/nested.html"><strong aria-hidden="true">2.1.</strong> Nested Routes</a></li><li class="chapter-item expanded "><a href="../features/routes/catch_all.html"><strong aria-hidden="true">2.2.</strong> Catch All Routes</a></li><li class="chapter-item expanded "><a href="../features/routes/matching.html"><strong aria-hidden="true">2.3.</strong> Matching Routes</a></li><li class="chapter-item expanded "><a href="../features/routes/fallback.html"><strong aria-hidden="true">2.4.</strong> Fallback Routes (404 page)</a></li><li class="chapter-item expanded "><a href="../features/routes/multiple-and-redirect.html"><strong aria-hidden="true">2.5.</strong> Multiple Components & Redirects</a></li></ol></li><li class="chapter-item expanded "><a href="../features/outlets.html"><strong aria-hidden="true">3.</strong> Outlets</a></li><li class="chapter-item expanded "><a href="../features/navigation/index.html"><strong aria-hidden="true">4.</strong> Links & Navigation</a></li><li><ol class="section"><li class="chapter-item expanded "><a href="../features/navigation/name.html"><strong aria-hidden="true">4.1.</strong> Named Navigation</a></li><li class="chapter-item expanded "><a href="../features/navigation/external.html"><strong aria-hidden="true">4.2.</strong> External Navigation</a></li><li class="chapter-item expanded "><a href="../features/navigation/programmatic.html"><strong aria-hidden="true">4.3.</strong> Programmatic Navigation</a></li></ol></li><li class="chapter-item expanded "><a href="../features/query.html"><strong aria-hidden="true">5.</strong> Query</a></li><li class="chapter-item expanded "><a href="../features/failures/index.html"><strong aria-hidden="true">6.</strong> Navigation Failures</a></li><li><ol class="section"><li class="chapter-item expanded "><a href="../features/failures/named.html"><strong aria-hidden="true">6.1.</strong> Named Navigation Failure</a></li><li class="chapter-item expanded "><a href="../features/failures/external.html"><strong aria-hidden="true">6.2.</strong> External Navigation Failure</a></li><li class="chapter-item expanded "><a href="../features/failures/redirection-limit.html"><strong aria-hidden="true">6.3.</strong> Redirection Limit Failure</a></li></ol></li><li class="chapter-item expanded "><a href="../features/history-providers.html"><strong aria-hidden="true">7.</strong> History Providers</a></li><li class="chapter-item expanded "><a href="../features/history-buttons.html"><strong aria-hidden="true">8.</strong> History Buttons</a></li><li class="chapter-item expanded "><a href="../features/sitemap-generation.html" class="active"><strong aria-hidden="true">9.</strong> Sitemap Generation</a></li><li class="chapter-item expanded "><a href="../features/routing-update-callback.html"><strong aria-hidden="true">10.</strong> Routing Update Callback</a></li><li class="chapter-item expanded affix "><li class="part-title">Example Project</li><li class="chapter-item expanded "><a href="../example/index.html"><strong aria-hidden="true">11.</strong> Overview</a></li><li class="chapter-item expanded "><a href="../example/first-route.html"><strong aria-hidden="true">12.</strong> Creating Our First Route</a></li><li class="chapter-item expanded "><a href="../example/building-a-nest.html"><strong aria-hidden="true">13.</strong> Building a Nest</a></li><li class="chapter-item expanded "><a href="../example/navigation-targets.html"><strong aria-hidden="true">14.</strong> Navigation Targets</a></li><li class="chapter-item expanded "><a href="../example/redirection-perfection.html"><strong aria-hidden="true">15.</strong> Redirection Perfection</a></li><li class="chapter-item expanded "><a href="../example/full-code.html"><strong aria-hidden="true">16.</strong> Full Code</a></li></ol>
|
||||
</div>
|
||||
<div id="sidebar-resize-handle" class="sidebar-resize-handle"></div>
|
||||
</nav>
|
||||
|
||||
<div id="page-wrapper" class="page-wrapper">
|
||||
|
||||
<div class="page">
|
||||
<div id="menu-bar-hover-placeholder"></div>
|
||||
<div id="menu-bar" class="menu-bar sticky bordered">
|
||||
<div class="left-buttons">
|
||||
<button id="sidebar-toggle" class="icon-button" type="button" title="Toggle Table of Contents" aria-label="Toggle Table of Contents" aria-controls="sidebar">
|
||||
<i class="fa fa-bars"></i>
|
||||
</button>
|
||||
<button id="theme-toggle" class="icon-button" type="button" title="Change theme" aria-label="Change theme" aria-haspopup="true" aria-expanded="false" aria-controls="theme-list">
|
||||
<i class="fa fa-paint-brush"></i>
|
||||
</button>
|
||||
<ul id="theme-list" class="theme-popup" aria-label="Themes" role="menu">
|
||||
<li role="none"><button role="menuitem" class="theme" id="light">Light (default)</button></li>
|
||||
<li role="none"><button role="menuitem" class="theme" id="rust">Rust</button></li>
|
||||
<li role="none"><button role="menuitem" class="theme" id="coal">Coal</button></li>
|
||||
<li role="none"><button role="menuitem" class="theme" id="navy">Navy</button></li>
|
||||
<li role="none"><button role="menuitem" class="theme" id="ayu">Ayu</button></li>
|
||||
</ul>
|
||||
<button id="search-toggle" class="icon-button" type="button" title="Search. (Shortkey: s)" aria-label="Toggle Searchbar" aria-expanded="false" aria-keyshortcuts="S" aria-controls="searchbar">
|
||||
<i class="fa fa-search"></i>
|
||||
</button>
|
||||
</div>
|
||||
|
||||
<h1 class="menu-title">Dioxus Router</h1>
|
||||
|
||||
<div class="right-buttons">
|
||||
<a href="../print.html" title="Print this book" aria-label="Print this book">
|
||||
<i id="print-button" class="fa fa-print"></i>
|
||||
</a>
|
||||
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div id="search-wrapper" class="hidden">
|
||||
<form id="searchbar-outer" class="searchbar-outer">
|
||||
<input type="search" id="searchbar" name="searchbar" placeholder="Search this book ..." aria-controls="searchresults-outer" aria-describedby="searchresults-header">
|
||||
</form>
|
||||
<div id="searchresults-outer" class="searchresults-outer hidden">
|
||||
<div id="searchresults-header" class="searchresults-header"></div>
|
||||
<ul id="searchresults">
|
||||
</ul>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- Apply ARIA attributes after the sidebar and the sidebar toggle button are added to the DOM -->
|
||||
<script type="text/javascript">
|
||||
document.getElementById('sidebar-toggle').setAttribute('aria-expanded', sidebar === 'visible');
|
||||
document.getElementById('sidebar').setAttribute('aria-hidden', sidebar !== 'visible');
|
||||
Array.from(document.querySelectorAll('#sidebar a')).forEach(function(link) {
|
||||
link.setAttribute('tabIndex', sidebar === 'visible' ? 0 : -1);
|
||||
});
|
||||
</script>
|
||||
|
||||
<div id="content" class="content">
|
||||
<main>
|
||||
<h1 id="sitemap-generation"><a class="header" href="#sitemap-generation">Sitemap Generation</a></h1>
|
||||
<p>If you need a list of all routes you have defined (e.g. for statically
|
||||
generating all pages), Dioxus Router provides functions to extract that
|
||||
information from a <a href="https://docs.rs/dioxus-router-core/latest/dioxus_router_core/routes/struct.Segment.html"><code>Segment</code></a>.</p>
|
||||
<h2 id="preparing-an-app"><a class="header" href="#preparing-an-app">Preparing an app</a></h2>
|
||||
<p>We will start by preparing an app with some routes like we normally would.</p>
|
||||
<pre><pre class="playground"><code class="language-rust edition2021">
|
||||
<span class="boring">#![allow(unused)]
|
||||
</span><span class="boring">fn main() {
|
||||
</span><span class="boring">// Hidden lines (like this one) make the documentation tests work.
|
||||
</span><span class="boring">extern crate dioxus;
|
||||
</span>use dioxus::prelude::*;
|
||||
<span class="boring">extern crate dioxus_router;
|
||||
</span>use dioxus_router::{history::MemoryHistory, prelude::*};
|
||||
<span class="boring">extern crate dioxus_ssr;
|
||||
</span>
|
||||
fn Home(cx: Scope) -> Element {
|
||||
render! {
|
||||
h1 { "Home" }
|
||||
}
|
||||
}
|
||||
|
||||
fn Fixed(cx: Scope) -> Element {
|
||||
render! {
|
||||
h1 { "Fixed" }
|
||||
Outlet { }
|
||||
}
|
||||
}
|
||||
|
||||
fn Nested(cx: Scope) -> Element {
|
||||
render! {
|
||||
h2 { "Nested" }
|
||||
}
|
||||
}
|
||||
|
||||
struct ParameterName;
|
||||
fn Parameter(cx: Scope) -> Element {
|
||||
let route = use_route(cx).unwrap();
|
||||
let param = route.parameter::<ParameterName>().unwrap_or_default();
|
||||
|
||||
render! {
|
||||
h1 { "Parameter: {param}" }
|
||||
}
|
||||
}
|
||||
|
||||
fn App(cx: Scope) -> Element {
|
||||
use_router(
|
||||
cx,
|
||||
&|| RouterConfiguration {
|
||||
<span class="boring"> synchronous: true,
|
||||
</span> history: Box::new(MemoryHistory::with_initial_path("/fixed/nested").unwrap()),
|
||||
..Default::default()
|
||||
},
|
||||
&|| {
|
||||
Segment::content(comp(Home))
|
||||
.fixed(
|
||||
"fixed",
|
||||
Route::content(comp(Fixed)).nested(
|
||||
Segment::empty().fixed("nested", comp(Nested))
|
||||
)
|
||||
)
|
||||
.catch_all((comp(Parameter), ParameterName { }))
|
||||
}
|
||||
);
|
||||
|
||||
render! {
|
||||
Outlet { }
|
||||
}
|
||||
}
|
||||
<span class="boring">
|
||||
</span><span class="boring">let mut vdom = VirtualDom::new(App);
|
||||
</span><span class="boring">vdom.rebuild();
|
||||
</span><span class="boring">assert_eq!(dioxus_ssr::render(&mut vdom), "<h1>Fixed</h1><h2>Nested</h2>");
|
||||
</span><span class="boring">}
|
||||
</span></code></pre></pre>
|
||||
<h2 id="modifying-the-app-to-make-using-sitemaps-easier"><a class="header" href="#modifying-the-app-to-make-using-sitemaps-easier">Modifying the app to make using sitemaps easier</a></h2>
|
||||
<p>Preparing our app for sitemap generation is quite easy. We just need to extract
|
||||
our segment definition into its own function.</p>
|
||||
<pre><pre class="playground"><code class="language-rust no_run edition2021">
|
||||
<span class="boring">#![allow(unused)]
|
||||
</span><span class="boring">fn main() {
|
||||
</span><span class="boring">// Hidden lines (like this one) make the documentation tests work.
|
||||
</span><span class="boring">extern crate dioxus;
|
||||
</span><span class="boring">use dioxus::prelude::*;
|
||||
</span><span class="boring">extern crate dioxus_router;
|
||||
</span><span class="boring">use dioxus_router::prelude::*;
|
||||
</span><span class="boring">extern crate dioxus_ssr;
|
||||
</span><span class="boring">fn Home(cx: Scope) -> Element { unimplemented!() }
|
||||
</span><span class="boring">fn Fixed(cx: Scope) -> Element { unimplemented!() }
|
||||
</span><span class="boring">fn Nested(cx: Scope) -> Element { unimplemented!() }
|
||||
</span><span class="boring">struct ParameterName;
|
||||
</span><span class="boring">fn Parameter(cx: Scope) -> Element { unimplemented!() }
|
||||
</span><span class="boring">
|
||||
</span>fn App(cx: Scope) -> Element {
|
||||
use_router(
|
||||
cx,
|
||||
&|| RouterConfiguration {
|
||||
..Default::default()
|
||||
},
|
||||
&prepare_routes
|
||||
);
|
||||
|
||||
render! {
|
||||
Outlet { }
|
||||
}
|
||||
}
|
||||
|
||||
fn prepare_routes() -> Segment<Component> {
|
||||
Segment::content(comp(Home))
|
||||
.fixed(
|
||||
"fixed",
|
||||
Route::content(comp(Fixed)).nested(
|
||||
Segment::empty().fixed("nested", comp(Nested))
|
||||
)
|
||||
)
|
||||
.catch_all((comp(Parameter), ParameterName { }))
|
||||
}
|
||||
<span class="boring">}
|
||||
</span></code></pre></pre>
|
||||
<h2 id="sitemaps-with-parameter-names"><a class="header" href="#sitemaps-with-parameter-names">Sitemaps with parameter names</a></h2>
|
||||
<p>The first variant to generate sitemaps is very simple. It finds all routes
|
||||
within the <a href="https://docs.rs/dioxus-router-core/latest/dioxus_router_core/routes/struct.Segment.html"><code>Segment</code></a> and adds them to the returned <code>Vec</code>.</p>
|
||||
<p>Matching and parameter routes are represented by their <code>key</code>, prefixed with <code>\</code>.
|
||||
Besides that <code>\</code>, all paths are URL encoded.</p>
|
||||
<pre><pre class="playground"><code class="language-rust edition2021">
|
||||
<span class="boring">#![allow(unused)]
|
||||
</span><span class="boring">fn main() {
|
||||
</span><span class="boring">// Hidden lines (like this one) make the documentation tests work.
|
||||
</span><span class="boring">extern crate dioxus;
|
||||
</span><span class="boring">use dioxus::prelude::*;
|
||||
</span><span class="boring">extern crate dioxus_router;
|
||||
</span><span class="boring">use dioxus_router::prelude::*;
|
||||
</span><span class="boring">extern crate dioxus_ssr;
|
||||
</span><span class="boring">fn Home(cx: Scope) -> Element { unimplemented!() }
|
||||
</span><span class="boring">fn Fixed(cx: Scope) -> Element { unimplemented!() }
|
||||
</span><span class="boring">fn Nested(cx: Scope) -> Element { unimplemented!() }
|
||||
</span><span class="boring">struct ParameterName;
|
||||
</span><span class="boring">fn Parameter(cx: Scope) -> Element { unimplemented!() }
|
||||
</span><span class="boring">fn prepare_routes() -> Segment<Component> {
|
||||
</span><span class="boring"> Segment::content(comp(Home))
|
||||
</span><span class="boring"> .fixed(
|
||||
</span><span class="boring"> "fixed",
|
||||
</span><span class="boring"> Route::content(comp(Fixed)).nested(
|
||||
</span><span class="boring"> Segment::empty().fixed("nested", comp(Nested))
|
||||
</span><span class="boring"> )
|
||||
</span><span class="boring"> )
|
||||
</span><span class="boring"> .catch_all((comp(Parameter), ParameterName { }))
|
||||
</span><span class="boring">}
|
||||
</span>
|
||||
let expected = vec![
|
||||
"/",
|
||||
"/fixed",
|
||||
"/fixed/nested",
|
||||
// Usually, here would be a fourth result representing the parameter route.
|
||||
// However, due to mdbook the name for this file would constantly change,
|
||||
// which is why we cannot show it. It would look something like this:
|
||||
// "/\\your_crate::ParameterName",
|
||||
];
|
||||
let mut sitemap = prepare_routes().gen_sitemap();
|
||||
sitemap.remove(3); // see above
|
||||
assert_eq!(sitemap, expected);
|
||||
<span class="boring">}
|
||||
</span></code></pre></pre>
|
||||
<h2 id="sitemaps-with-actual-parameter-values"><a class="header" href="#sitemaps-with-actual-parameter-values">Sitemaps with actual parameter values</a></h2>
|
||||
<p>The second variant to generate sitemaps is a bit more involved. When it
|
||||
encounters a parameter route, it inserts all values with a matching <code>key</code> that
|
||||
were provided to it.</p>
|
||||
<p>Matching routes only add their path if the value matches their regex.</p>
|
||||
<p>All paths are URL encoded.</p>
|
||||
<pre><pre class="playground"><code class="language-rust edition2021">
|
||||
<span class="boring">#![allow(unused)]
|
||||
</span><span class="boring">fn main() {
|
||||
</span><span class="boring">// Hidden lines (like this one) make the documentation tests work.
|
||||
</span>use std::collections::{BTreeMap, HashSet};
|
||||
<span class="boring">extern crate dioxus;
|
||||
</span><span class="boring">use dioxus::prelude::*;
|
||||
</span><span class="boring">extern crate dioxus_router;
|
||||
</span><span class="boring">use dioxus_router::prelude::*;
|
||||
</span><span class="boring">extern crate dioxus_ssr;
|
||||
</span><span class="boring">fn Home(cx: Scope) -> Element { unimplemented!() }
|
||||
</span><span class="boring">fn Fixed(cx: Scope) -> Element { unimplemented!() }
|
||||
</span><span class="boring">fn Nested(cx: Scope) -> Element { unimplemented!() }
|
||||
</span><span class="boring">struct ParameterName;
|
||||
</span><span class="boring">fn Parameter(cx: Scope) -> Element { unimplemented!() }
|
||||
</span><span class="boring">fn prepare_routes() -> Segment<Component> {
|
||||
</span><span class="boring"> Segment::content(comp(Home))
|
||||
</span><span class="boring"> .fixed(
|
||||
</span><span class="boring"> "fixed",
|
||||
</span><span class="boring"> Route::content(comp(Fixed)).nested(
|
||||
</span><span class="boring"> Segment::empty().fixed("nested", comp(Nested))
|
||||
</span><span class="boring"> )
|
||||
</span><span class="boring"> )
|
||||
</span><span class="boring"> .catch_all((comp(Parameter), ParameterName { }))
|
||||
</span><span class="boring">}
|
||||
</span>
|
||||
let parameters = {
|
||||
let mut parameters = BTreeMap::new();
|
||||
|
||||
parameters.insert(
|
||||
Name::of::<ParameterName>(),
|
||||
vec![
|
||||
String::from("some-parameter-value"),
|
||||
String::from("other-parameter-value")
|
||||
]
|
||||
);
|
||||
|
||||
parameters
|
||||
};
|
||||
|
||||
let expected: Vec<String> = vec![
|
||||
"/",
|
||||
"/fixed",
|
||||
"/fixed/nested",
|
||||
"/some-parameter-value",
|
||||
"/other-parameter-value",
|
||||
].into_iter().map(String::from).collect();
|
||||
assert_eq!(expected, prepare_routes().gen_parameter_sitemap(&parameters));
|
||||
<span class="boring">}
|
||||
</span></code></pre></pre>
|
||||
|
||||
</main>
|
||||
|
||||
<nav class="nav-wrapper" aria-label="Page navigation">
|
||||
<!-- Mobile navigation buttons -->
|
||||
<a rel="prev" href="../features/history-buttons.html" class="mobile-nav-chapters previous" title="Previous chapter" aria-label="Previous chapter" aria-keyshortcuts="Left">
|
||||
<i class="fa fa-angle-left"></i>
|
||||
</a>
|
||||
|
||||
<a rel="next" href="../features/routing-update-callback.html" class="mobile-nav-chapters next" title="Next chapter" aria-label="Next chapter" aria-keyshortcuts="Right">
|
||||
<i class="fa fa-angle-right"></i>
|
||||
</a>
|
||||
|
||||
<div style="clear: both"></div>
|
||||
</nav>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<nav class="nav-wide-wrapper" aria-label="Page navigation">
|
||||
<a rel="prev" href="../features/history-buttons.html" class="nav-chapters previous" title="Previous chapter" aria-label="Previous chapter" aria-keyshortcuts="Left">
|
||||
<i class="fa fa-angle-left"></i>
|
||||
</a>
|
||||
|
||||
<a rel="next" href="../features/routing-update-callback.html" class="nav-chapters next" title="Next chapter" aria-label="Next chapter" aria-keyshortcuts="Right">
|
||||
<i class="fa fa-angle-right"></i>
|
||||
</a>
|
||||
</nav>
|
||||
|
||||
</div>
|
||||
|
||||
|
||||
|
||||
|
||||
<script type="text/javascript">
|
||||
window.playground_copyable = true;
|
||||
</script>
|
||||
|
||||
|
||||
<script src="../elasticlunr.min.js" type="text/javascript" charset="utf-8"></script>
|
||||
<script src="../mark.min.js" type="text/javascript" charset="utf-8"></script>
|
||||
<script src="../searcher.js" type="text/javascript" charset="utf-8"></script>
|
||||
|
||||
<script src="../clipboard.min.js" type="text/javascript" charset="utf-8"></script>
|
||||
<script src="../highlight.js" type="text/javascript" charset="utf-8"></script>
|
||||
<script src="../book.js" type="text/javascript" charset="utf-8"></script>
|
||||
|
||||
<!-- Custom JS scripts -->
|
||||
|
||||
|
||||
</body>
|
||||
</html>
|
||||
@@ -0,0 +1,202 @@
|
||||
|
||||
Apache License
|
||||
Version 2.0, January 2004
|
||||
http://www.apache.org/licenses/
|
||||
|
||||
TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION
|
||||
|
||||
1. Definitions.
|
||||
|
||||
"License" shall mean the terms and conditions for use, reproduction,
|
||||
and distribution as defined by Sections 1 through 9 of this document.
|
||||
|
||||
"Licensor" shall mean the copyright owner or entity authorized by
|
||||
the copyright owner that is granting the License.
|
||||
|
||||
"Legal Entity" shall mean the union of the acting entity and all
|
||||
other entities that control, are controlled by, or are under common
|
||||
control with that entity. For the purposes of this definition,
|
||||
"control" means (i) the power, direct or indirect, to cause the
|
||||
direction or management of such entity, whether by contract or
|
||||
otherwise, or (ii) ownership of fifty percent (50%) or more of the
|
||||
outstanding shares, or (iii) beneficial ownership of such entity.
|
||||
|
||||
"You" (or "Your") shall mean an individual or Legal Entity
|
||||
exercising permissions granted by this License.
|
||||
|
||||
"Source" form shall mean the preferred form for making modifications,
|
||||
including but not limited to software source code, documentation
|
||||
source, and configuration files.
|
||||
|
||||
"Object" form shall mean any form resulting from mechanical
|
||||
transformation or translation of a Source form, including but
|
||||
not limited to compiled object code, generated documentation,
|
||||
and conversions to other media types.
|
||||
|
||||
"Work" shall mean the work of authorship, whether in Source or
|
||||
Object form, made available under the License, as indicated by a
|
||||
copyright notice that is included in or attached to the work
|
||||
(an example is provided in the Appendix below).
|
||||
|
||||
"Derivative Works" shall mean any work, whether in Source or Object
|
||||
form, that is based on (or derived from) the Work and for which the
|
||||
editorial revisions, annotations, elaborations, or other modifications
|
||||
represent, as a whole, an original work of authorship. For the purposes
|
||||
of this License, Derivative Works shall not include works that remain
|
||||
separable from, or merely link (or bind by name) to the interfaces of,
|
||||
the Work and Derivative Works thereof.
|
||||
|
||||
"Contribution" shall mean any work of authorship, including
|
||||
the original version of the Work and any modifications or additions
|
||||
to that Work or Derivative Works thereof, that is intentionally
|
||||
submitted to Licensor for inclusion in the Work by the copyright owner
|
||||
or by an individual or Legal Entity authorized to submit on behalf of
|
||||
the copyright owner. For the purposes of this definition, "submitted"
|
||||
means any form of electronic, verbal, or written communication sent
|
||||
to the Licensor or its representatives, including but not limited to
|
||||
communication on electronic mailing lists, source code control systems,
|
||||
and issue tracking systems that are managed by, or on behalf of, the
|
||||
Licensor for the purpose of discussing and improving the Work, but
|
||||
excluding communication that is conspicuously marked or otherwise
|
||||
designated in writing by the copyright owner as "Not a Contribution."
|
||||
|
||||
"Contributor" shall mean Licensor and any individual or Legal Entity
|
||||
on behalf of whom a Contribution has been received by Licensor and
|
||||
subsequently incorporated within the Work.
|
||||
|
||||
2. Grant of Copyright License. Subject to the terms and conditions of
|
||||
this License, each Contributor hereby grants to You a perpetual,
|
||||
worldwide, non-exclusive, no-charge, royalty-free, irrevocable
|
||||
copyright license to reproduce, prepare Derivative Works of,
|
||||
publicly display, publicly perform, sublicense, and distribute the
|
||||
Work and such Derivative Works in Source or Object form.
|
||||
|
||||
3. Grant of Patent License. Subject to the terms and conditions of
|
||||
this License, each Contributor hereby grants to You a perpetual,
|
||||
worldwide, non-exclusive, no-charge, royalty-free, irrevocable
|
||||
(except as stated in this section) patent license to make, have made,
|
||||
use, offer to sell, sell, import, and otherwise transfer the Work,
|
||||
where such license applies only to those patent claims licensable
|
||||
by such Contributor that are necessarily infringed by their
|
||||
Contribution(s) alone or by combination of their Contribution(s)
|
||||
with the Work to which such Contribution(s) was submitted. If You
|
||||
institute patent litigation against any entity (including a
|
||||
cross-claim or counterclaim in a lawsuit) alleging that the Work
|
||||
or a Contribution incorporated within the Work constitutes direct
|
||||
or contributory patent infringement, then any patent licenses
|
||||
granted to You under this License for that Work shall terminate
|
||||
as of the date such litigation is filed.
|
||||
|
||||
4. Redistribution. You may reproduce and distribute copies of the
|
||||
Work or Derivative Works thereof in any medium, with or without
|
||||
modifications, and in Source or Object form, provided that You
|
||||
meet the following conditions:
|
||||
|
||||
(a) You must give any other recipients of the Work or
|
||||
Derivative Works a copy of this License; and
|
||||
|
||||
(b) You must cause any modified files to carry prominent notices
|
||||
stating that You changed the files; and
|
||||
|
||||
(c) You must retain, in the Source form of any Derivative Works
|
||||
that You distribute, all copyright, patent, trademark, and
|
||||
attribution notices from the Source form of the Work,
|
||||
excluding those notices that do not pertain to any part of
|
||||
the Derivative Works; and
|
||||
|
||||
(d) If the Work includes a "NOTICE" text file as part of its
|
||||
distribution, then any Derivative Works that You distribute must
|
||||
include a readable copy of the attribution notices contained
|
||||
within such NOTICE file, excluding those notices that do not
|
||||
pertain to any part of the Derivative Works, in at least one
|
||||
of the following places: within a NOTICE text file distributed
|
||||
as part of the Derivative Works; within the Source form or
|
||||
documentation, if provided along with the Derivative Works; or,
|
||||
within a display generated by the Derivative Works, if and
|
||||
wherever such third-party notices normally appear. The contents
|
||||
of the NOTICE file are for informational purposes only and
|
||||
do not modify the License. You may add Your own attribution
|
||||
notices within Derivative Works that You distribute, alongside
|
||||
or as an addendum to the NOTICE text from the Work, provided
|
||||
that such additional attribution notices cannot be construed
|
||||
as modifying the License.
|
||||
|
||||
You may add Your own copyright statement to Your modifications and
|
||||
may provide additional or different license terms and conditions
|
||||
for use, reproduction, or distribution of Your modifications, or
|
||||
for any such Derivative Works as a whole, provided Your use,
|
||||
reproduction, and distribution of the Work otherwise complies with
|
||||
the conditions stated in this License.
|
||||
|
||||
5. Submission of Contributions. Unless You explicitly state otherwise,
|
||||
any Contribution intentionally submitted for inclusion in the Work
|
||||
by You to the Licensor shall be under the terms and conditions of
|
||||
this License, without any additional terms or conditions.
|
||||
Notwithstanding the above, nothing herein shall supersede or modify
|
||||
the terms of any separate license agreement you may have executed
|
||||
with Licensor regarding such Contributions.
|
||||
|
||||
6. Trademarks. This License does not grant permission to use the trade
|
||||
names, trademarks, service marks, or product names of the Licensor,
|
||||
except as required for reasonable and customary use in describing the
|
||||
origin of the Work and reproducing the content of the NOTICE file.
|
||||
|
||||
7. Disclaimer of Warranty. Unless required by applicable law or
|
||||
agreed to in writing, Licensor provides the Work (and each
|
||||
Contributor provides its Contributions) on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
|
||||
implied, including, without limitation, any warranties or conditions
|
||||
of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A
|
||||
PARTICULAR PURPOSE. You are solely responsible for determining the
|
||||
appropriateness of using or redistributing the Work and assume any
|
||||
risks associated with Your exercise of permissions under this License.
|
||||
|
||||
8. Limitation of Liability. In no event and under no legal theory,
|
||||
whether in tort (including negligence), contract, or otherwise,
|
||||
unless required by applicable law (such as deliberate and grossly
|
||||
negligent acts) or agreed to in writing, shall any Contributor be
|
||||
liable to You for damages, including any direct, indirect, special,
|
||||
incidental, or consequential damages of any character arising as a
|
||||
result of this License or out of the use or inability to use the
|
||||
Work (including but not limited to damages for loss of goodwill,
|
||||
work stoppage, computer failure or malfunction, or any and all
|
||||
other commercial damages or losses), even if such Contributor
|
||||
has been advised of the possibility of such damages.
|
||||
|
||||
9. Accepting Warranty or Additional Liability. While redistributing
|
||||
the Work or Derivative Works thereof, You may choose to offer,
|
||||
and charge a fee for, acceptance of support, warranty, indemnity,
|
||||
or other liability obligations and/or rights consistent with this
|
||||
License. However, in accepting such obligations, You may act only
|
||||
on Your own behalf and on Your sole responsibility, not on behalf
|
||||
of any other Contributor, and only if You agree to indemnify,
|
||||
defend, and hold each Contributor harmless for any liability
|
||||
incurred by, or claims asserted against, such Contributor by reason
|
||||
of your accepting any such warranty or additional liability.
|
||||
|
||||
END OF TERMS AND CONDITIONS
|
||||
|
||||
APPENDIX: How to apply the Apache License to your work.
|
||||
|
||||
To apply the Apache License to your work, attach the following
|
||||
boilerplate notice, with the fields enclosed by brackets "[]"
|
||||
replaced with your own identifying information. (Don't include
|
||||
the brackets!) The text should be enclosed in the appropriate
|
||||
comment syntax for the file format. We also recommend that a
|
||||
file or class name and description of purpose be included on the
|
||||
same "printed page" as the copyright notice for easier
|
||||
identification within third-party archives.
|
||||
|
||||
Copyright [yyyy] [name of copyright owner]
|
||||
|
||||
Licensed under the Apache License, Version 2.0 (the "License");
|
||||
you may not use this file except in compliance with the License.
|
||||
You may obtain a copy of the License at
|
||||
|
||||
http://www.apache.org/licenses/LICENSE-2.0
|
||||
|
||||
Unless required by applicable law or agreed to in writing, software
|
||||
distributed under the License is distributed on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
See the License for the specific language governing permissions and
|
||||
limitations under the License.
|
||||
@@ -0,0 +1,93 @@
|
||||
Copyright 2010, 2012 Adobe Systems Incorporated (http://www.adobe.com/), with Reserved Font Name 'Source'. All Rights Reserved. Source is a trademark of Adobe Systems Incorporated in the United States and/or other countries.
|
||||
|
||||
This Font Software is licensed under the SIL Open Font License, Version 1.1.
|
||||
This license is copied below, and is also available with a FAQ at:
|
||||
http://scripts.sil.org/OFL
|
||||
|
||||
|
||||
-----------------------------------------------------------
|
||||
SIL OPEN FONT LICENSE Version 1.1 - 26 February 2007
|
||||
-----------------------------------------------------------
|
||||
|
||||
PREAMBLE
|
||||
The goals of the Open Font License (OFL) are to stimulate worldwide
|
||||
development of collaborative font projects, to support the font creation
|
||||
efforts of academic and linguistic communities, and to provide a free and
|
||||
open framework in which fonts may be shared and improved in partnership
|
||||
with others.
|
||||
|
||||
The OFL allows the licensed fonts to be used, studied, modified and
|
||||
redistributed freely as long as they are not sold by themselves. The
|
||||
fonts, including any derivative works, can be bundled, embedded,
|
||||
redistributed and/or sold with any software provided that any reserved
|
||||
names are not used by derivative works. The fonts and derivatives,
|
||||
however, cannot be released under any other type of license. The
|
||||
requirement for fonts to remain under this license does not apply
|
||||
to any document created using the fonts or their derivatives.
|
||||
|
||||
DEFINITIONS
|
||||
"Font Software" refers to the set of files released by the Copyright
|
||||
Holder(s) under this license and clearly marked as such. This may
|
||||
include source files, build scripts and documentation.
|
||||
|
||||
"Reserved Font Name" refers to any names specified as such after the
|
||||
copyright statement(s).
|
||||
|
||||
"Original Version" refers to the collection of Font Software components as
|
||||
distributed by the Copyright Holder(s).
|
||||
|
||||
"Modified Version" refers to any derivative made by adding to, deleting,
|
||||
or substituting -- in part or in whole -- any of the components of the
|
||||
Original Version, by changing formats or by porting the Font Software to a
|
||||
new environment.
|
||||
|
||||
"Author" refers to any designer, engineer, programmer, technical
|
||||
writer or other person who contributed to the Font Software.
|
||||
|
||||
PERMISSION & CONDITIONS
|
||||
Permission is hereby granted, free of charge, to any person obtaining
|
||||
a copy of the Font Software, to use, study, copy, merge, embed, modify,
|
||||
redistribute, and sell modified and unmodified copies of the Font
|
||||
Software, subject to the following conditions:
|
||||
|
||||
1) Neither the Font Software nor any of its individual components,
|
||||
in Original or Modified Versions, may be sold by itself.
|
||||
|
||||
2) Original or Modified Versions of the Font Software may be bundled,
|
||||
redistributed and/or sold with any software, provided that each copy
|
||||
contains the above copyright notice and this license. These can be
|
||||
included either as stand-alone text files, human-readable headers or
|
||||
in the appropriate machine-readable metadata fields within text or
|
||||
binary files as long as those fields can be easily viewed by the user.
|
||||
|
||||
3) No Modified Version of the Font Software may use the Reserved Font
|
||||
Name(s) unless explicit written permission is granted by the corresponding
|
||||
Copyright Holder. This restriction only applies to the primary font name as
|
||||
presented to the users.
|
||||
|
||||
4) The name(s) of the Copyright Holder(s) or the Author(s) of the Font
|
||||
Software shall not be used to promote, endorse or advertise any
|
||||
Modified Version, except to acknowledge the contribution(s) of the
|
||||
Copyright Holder(s) and the Author(s) or with their explicit written
|
||||
permission.
|
||||
|
||||
5) The Font Software, modified or unmodified, in part or in whole,
|
||||
must be distributed entirely under this license, and must not be
|
||||
distributed under any other license. The requirement for fonts to
|
||||
remain under this license does not apply to any document created
|
||||
using the Font Software.
|
||||
|
||||
TERMINATION
|
||||
This license becomes null and void if any of the above conditions are
|
||||
not met.
|
||||
|
||||
DISCLAIMER
|
||||
THE FONT SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
||||
EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO ANY WARRANTIES OF
|
||||
MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT
|
||||
OF COPYRIGHT, PATENT, TRADEMARK, OR OTHER RIGHT. IN NO EVENT SHALL THE
|
||||
COPYRIGHT HOLDER BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
|
||||
INCLUDING ANY GENERAL, SPECIAL, INDIRECT, INCIDENTAL, OR CONSEQUENTIAL
|
||||
DAMAGES, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
|
||||
FROM, OUT OF THE USE OR INABILITY TO USE THE FONT SOFTWARE OR FROM
|
||||
OTHER DEALINGS IN THE FONT SOFTWARE.
|
||||
@@ -0,0 +1,100 @@
|
||||
/* Open Sans is licensed under the Apache License, Version 2.0. See http://www.apache.org/licenses/LICENSE-2.0 */
|
||||
/* Source Code Pro is under the Open Font License. See https://scripts.sil.org/cms/scripts/page.php?site_id=nrsi&id=OFL */
|
||||
|
||||
/* open-sans-300 - latin_vietnamese_latin-ext_greek-ext_greek_cyrillic-ext_cyrillic */
|
||||
@font-face {
|
||||
font-family: 'Open Sans';
|
||||
font-style: normal;
|
||||
font-weight: 300;
|
||||
src: local('Open Sans Light'), local('OpenSans-Light'),
|
||||
url('open-sans-v17-all-charsets-300.woff2') format('woff2');
|
||||
}
|
||||
|
||||
/* open-sans-300italic - latin_vietnamese_latin-ext_greek-ext_greek_cyrillic-ext_cyrillic */
|
||||
@font-face {
|
||||
font-family: 'Open Sans';
|
||||
font-style: italic;
|
||||
font-weight: 300;
|
||||
src: local('Open Sans Light Italic'), local('OpenSans-LightItalic'),
|
||||
url('open-sans-v17-all-charsets-300italic.woff2') format('woff2');
|
||||
}
|
||||
|
||||
/* open-sans-regular - latin_vietnamese_latin-ext_greek-ext_greek_cyrillic-ext_cyrillic */
|
||||
@font-face {
|
||||
font-family: 'Open Sans';
|
||||
font-style: normal;
|
||||
font-weight: 400;
|
||||
src: local('Open Sans Regular'), local('OpenSans-Regular'),
|
||||
url('open-sans-v17-all-charsets-regular.woff2') format('woff2');
|
||||
}
|
||||
|
||||
/* open-sans-italic - latin_vietnamese_latin-ext_greek-ext_greek_cyrillic-ext_cyrillic */
|
||||
@font-face {
|
||||
font-family: 'Open Sans';
|
||||
font-style: italic;
|
||||
font-weight: 400;
|
||||
src: local('Open Sans Italic'), local('OpenSans-Italic'),
|
||||
url('open-sans-v17-all-charsets-italic.woff2') format('woff2');
|
||||
}
|
||||
|
||||
/* open-sans-600 - latin_vietnamese_latin-ext_greek-ext_greek_cyrillic-ext_cyrillic */
|
||||
@font-face {
|
||||
font-family: 'Open Sans';
|
||||
font-style: normal;
|
||||
font-weight: 600;
|
||||
src: local('Open Sans SemiBold'), local('OpenSans-SemiBold'),
|
||||
url('open-sans-v17-all-charsets-600.woff2') format('woff2');
|
||||
}
|
||||
|
||||
/* open-sans-600italic - latin_vietnamese_latin-ext_greek-ext_greek_cyrillic-ext_cyrillic */
|
||||
@font-face {
|
||||
font-family: 'Open Sans';
|
||||
font-style: italic;
|
||||
font-weight: 600;
|
||||
src: local('Open Sans SemiBold Italic'), local('OpenSans-SemiBoldItalic'),
|
||||
url('open-sans-v17-all-charsets-600italic.woff2') format('woff2');
|
||||
}
|
||||
|
||||
/* open-sans-700 - latin_vietnamese_latin-ext_greek-ext_greek_cyrillic-ext_cyrillic */
|
||||
@font-face {
|
||||
font-family: 'Open Sans';
|
||||
font-style: normal;
|
||||
font-weight: 700;
|
||||
src: local('Open Sans Bold'), local('OpenSans-Bold'),
|
||||
url('open-sans-v17-all-charsets-700.woff2') format('woff2');
|
||||
}
|
||||
|
||||
/* open-sans-700italic - latin_vietnamese_latin-ext_greek-ext_greek_cyrillic-ext_cyrillic */
|
||||
@font-face {
|
||||
font-family: 'Open Sans';
|
||||
font-style: italic;
|
||||
font-weight: 700;
|
||||
src: local('Open Sans Bold Italic'), local('OpenSans-BoldItalic'),
|
||||
url('open-sans-v17-all-charsets-700italic.woff2') format('woff2');
|
||||
}
|
||||
|
||||
/* open-sans-800 - latin_vietnamese_latin-ext_greek-ext_greek_cyrillic-ext_cyrillic */
|
||||
@font-face {
|
||||
font-family: 'Open Sans';
|
||||
font-style: normal;
|
||||
font-weight: 800;
|
||||
src: local('Open Sans ExtraBold'), local('OpenSans-ExtraBold'),
|
||||
url('open-sans-v17-all-charsets-800.woff2') format('woff2');
|
||||
}
|
||||
|
||||
/* open-sans-800italic - latin_vietnamese_latin-ext_greek-ext_greek_cyrillic-ext_cyrillic */
|
||||
@font-face {
|
||||
font-family: 'Open Sans';
|
||||
font-style: italic;
|
||||
font-weight: 800;
|
||||
src: local('Open Sans ExtraBold Italic'), local('OpenSans-ExtraBoldItalic'),
|
||||
url('open-sans-v17-all-charsets-800italic.woff2') format('woff2');
|
||||
}
|
||||
|
||||
/* source-code-pro-500 - latin_vietnamese_latin-ext_greek_cyrillic-ext_cyrillic */
|
||||
@font-face {
|
||||
font-family: 'Source Code Pro';
|
||||
font-style: normal;
|
||||
font-weight: 500;
|
||||
src: url('source-code-pro-v11-all-charsets-500.woff2') format('woff2');
|
||||
}
|
||||
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
@@ -0,0 +1,83 @@
|
||||
/*
|
||||
* An increased contrast highlighting scheme loosely based on the
|
||||
* "Base16 Atelier Dune Light" theme by Bram de Haan
|
||||
* (http://atelierbram.github.io/syntax-highlighting/atelier-schemes/dune)
|
||||
* Original Base16 color scheme by Chris Kempson
|
||||
* (https://github.com/chriskempson/base16)
|
||||
*/
|
||||
|
||||
/* Comment */
|
||||
.hljs-comment,
|
||||
.hljs-quote {
|
||||
color: #575757;
|
||||
}
|
||||
|
||||
/* Red */
|
||||
.hljs-variable,
|
||||
.hljs-template-variable,
|
||||
.hljs-attribute,
|
||||
.hljs-tag,
|
||||
.hljs-name,
|
||||
.hljs-regexp,
|
||||
.hljs-link,
|
||||
.hljs-name,
|
||||
.hljs-selector-id,
|
||||
.hljs-selector-class {
|
||||
color: #d70025;
|
||||
}
|
||||
|
||||
/* Orange */
|
||||
.hljs-number,
|
||||
.hljs-meta,
|
||||
.hljs-built_in,
|
||||
.hljs-builtin-name,
|
||||
.hljs-literal,
|
||||
.hljs-type,
|
||||
.hljs-params {
|
||||
color: #b21e00;
|
||||
}
|
||||
|
||||
/* Green */
|
||||
.hljs-string,
|
||||
.hljs-symbol,
|
||||
.hljs-bullet {
|
||||
color: #008200;
|
||||
}
|
||||
|
||||
/* Blue */
|
||||
.hljs-title,
|
||||
.hljs-section {
|
||||
color: #0030f2;
|
||||
}
|
||||
|
||||
/* Purple */
|
||||
.hljs-keyword,
|
||||
.hljs-selector-tag {
|
||||
color: #9d00ec;
|
||||
}
|
||||
|
||||
.hljs {
|
||||
display: block;
|
||||
overflow-x: auto;
|
||||
background: #f6f7f6;
|
||||
color: #000;
|
||||
padding: 0.5em;
|
||||
}
|
||||
|
||||
.hljs-emphasis {
|
||||
font-style: italic;
|
||||
}
|
||||
|
||||
.hljs-strong {
|
||||
font-weight: bold;
|
||||
}
|
||||
|
||||
.hljs-addition {
|
||||
color: #22863a;
|
||||
background-color: #f0fff4;
|
||||
}
|
||||
|
||||
.hljs-deletion {
|
||||
color: #b31d28;
|
||||
background-color: #ffeef0;
|
||||
}
|
||||
@@ -0,0 +1,6 @@
|
||||
/*
|
||||
Highlight.js 10.1.1 (93fd0d73)
|
||||
License: BSD-3-Clause
|
||||
Copyright (c) 2006-2020, Ivan Sagalaev
|
||||
*/
|
||||
var hljs=function(){"use strict";function e(n){Object.freeze(n);var t="function"==typeof n;return Object.getOwnPropertyNames(n).forEach((function(r){!Object.hasOwnProperty.call(n,r)||null===n[r]||"object"!=typeof n[r]&&"function"!=typeof n[r]||t&&("caller"===r||"callee"===r||"arguments"===r)||Object.isFrozen(n[r])||e(n[r])})),n}class n{constructor(e){void 0===e.data&&(e.data={}),this.data=e.data}ignoreMatch(){this.ignore=!0}}function t(e){return e.replace(/&/g,"&").replace(/</g,"<").replace(/>/g,">").replace(/"/g,""").replace(/'/g,"'")}function r(e,...n){var t={};for(const n in e)t[n]=e[n];return n.forEach((function(e){for(const n in e)t[n]=e[n]})),t}function a(e){return e.nodeName.toLowerCase()}var i=Object.freeze({__proto__:null,escapeHTML:t,inherit:r,nodeStream:function(e){var n=[];return function e(t,r){for(var i=t.firstChild;i;i=i.nextSibling)3===i.nodeType?r+=i.nodeValue.length:1===i.nodeType&&(n.push({event:"start",offset:r,node:i}),r=e(i,r),a(i).match(/br|hr|img|input/)||n.push({event:"stop",offset:r,node:i}));return r}(e,0),n},mergeStreams:function(e,n,r){var i=0,s="",o=[];function l(){return e.length&&n.length?e[0].offset!==n[0].offset?e[0].offset<n[0].offset?e:n:"start"===n[0].event?e:n:e.length?e:n}function c(e){s+="<"+a(e)+[].map.call(e.attributes,(function(e){return" "+e.nodeName+'="'+t(e.value)+'"'})).join("")+">"}function u(e){s+="</"+a(e)+">"}function d(e){("start"===e.event?c:u)(e.node)}for(;e.length||n.length;){var g=l();if(s+=t(r.substring(i,g[0].offset)),i=g[0].offset,g===e){o.reverse().forEach(u);do{d(g.splice(0,1)[0]),g=l()}while(g===e&&g.length&&g[0].offset===i);o.reverse().forEach(c)}else"start"===g[0].event?o.push(g[0].node):o.pop(),d(g.splice(0,1)[0])}return s+t(r.substr(i))}});const s="</span>",o=e=>!!e.kind;class l{constructor(e,n){this.buffer="",this.classPrefix=n.classPrefix,e.walk(this)}addText(e){this.buffer+=t(e)}openNode(e){if(!o(e))return;let n=e.kind;e.sublanguage||(n=`${this.classPrefix}${n}`),this.span(n)}closeNode(e){o(e)&&(this.buffer+=s)}value(){return this.buffer}span(e){this.buffer+=`<span class="${e}">`}}class c{constructor(){this.rootNode={children:[]},this.stack=[this.rootNode]}get top(){return this.stack[this.stack.length-1]}get root(){return this.rootNode}add(e){this.top.children.push(e)}openNode(e){const n={kind:e,children:[]};this.add(n),this.stack.push(n)}closeNode(){if(this.stack.length>1)return this.stack.pop()}closeAllNodes(){for(;this.closeNode(););}toJSON(){return JSON.stringify(this.rootNode,null,4)}walk(e){return this.constructor._walk(e,this.rootNode)}static _walk(e,n){return"string"==typeof n?e.addText(n):n.children&&(e.openNode(n),n.children.forEach(n=>this._walk(e,n)),e.closeNode(n)),e}static _collapse(e){"string"!=typeof e&&e.children&&(e.children.every(e=>"string"==typeof e)?e.children=[e.children.join("")]:e.children.forEach(e=>{c._collapse(e)}))}}class u extends c{constructor(e){super(),this.options=e}addKeyword(e,n){""!==e&&(this.openNode(n),this.addText(e),this.closeNode())}addText(e){""!==e&&this.add(e)}addSublanguage(e,n){const t=e.root;t.kind=n,t.sublanguage=!0,this.add(t)}toHTML(){return new l(this,this.options).value()}finalize(){return!0}}function d(e){return e?"string"==typeof e?e:e.source:null}const g="(-?)(\\b0[xX][a-fA-F0-9]+|(\\b\\d+(\\.\\d*)?|\\.\\d+)([eE][-+]?\\d+)?)",h={begin:"\\\\[\\s\\S]",relevance:0},f={className:"string",begin:"'",end:"'",illegal:"\\n",contains:[h]},p={className:"string",begin:'"',end:'"',illegal:"\\n",contains:[h]},b={begin:/\b(a|an|the|are|I'm|isn't|don't|doesn't|won't|but|just|should|pretty|simply|enough|gonna|going|wtf|so|such|will|you|your|they|like|more)\b/},m=function(e,n,t={}){var a=r({className:"comment",begin:e,end:n,contains:[]},t);return a.contains.push(b),a.contains.push({className:"doctag",begin:"(?:TODO|FIXME|NOTE|BUG|OPTIMIZE|HACK|XXX):",relevance:0}),a},v=m("//","$"),x=m("/\\*","\\*/"),E=m("#","$");var _=Object.freeze({__proto__:null,IDENT_RE:"[a-zA-Z]\\w*",UNDERSCORE_IDENT_RE:"[a-zA-Z_]\\w*",NUMBER_RE:"\\b\\d+(\\.\\d+)?",C_NUMBER_RE:g,BINARY_NUMBER_RE:"\\b(0b[01]+)",RE_STARTERS_RE:"!|!=|!==|%|%=|&|&&|&=|\\*|\\*=|\\+|\\+=|,|-|-=|/=|/|:|;|<<|<<=|<=|<|===|==|=|>>>=|>>=|>=|>>>|>>|>|\\?|\\[|\\{|\\(|\\^|\\^=|\\||\\|=|\\|\\||~",SHEBANG:(e={})=>{const n=/^#![ ]*\//;return e.binary&&(e.begin=function(...e){return e.map(e=>d(e)).join("")}(n,/.*\b/,e.binary,/\b.*/)),r({className:"meta",begin:n,end:/$/,relevance:0,"on:begin":(e,n)=>{0!==e.index&&n.ignoreMatch()}},e)},BACKSLASH_ESCAPE:h,APOS_STRING_MODE:f,QUOTE_STRING_MODE:p,PHRASAL_WORDS_MODE:b,COMMENT:m,C_LINE_COMMENT_MODE:v,C_BLOCK_COMMENT_MODE:x,HASH_COMMENT_MODE:E,NUMBER_MODE:{className:"number",begin:"\\b\\d+(\\.\\d+)?",relevance:0},C_NUMBER_MODE:{className:"number",begin:g,relevance:0},BINARY_NUMBER_MODE:{className:"number",begin:"\\b(0b[01]+)",relevance:0},CSS_NUMBER_MODE:{className:"number",begin:"\\b\\d+(\\.\\d+)?(%|em|ex|ch|rem|vw|vh|vmin|vmax|cm|mm|in|pt|pc|px|deg|grad|rad|turn|s|ms|Hz|kHz|dpi|dpcm|dppx)?",relevance:0Line truncated
|
||||
@@ -0,0 +1,226 @@
|
||||
<!DOCTYPE HTML>
|
||||
<html lang="en" class="sidebar-visible no-js light">
|
||||
<head>
|
||||
<!-- Book generated using mdBook -->
|
||||
<meta charset="UTF-8">
|
||||
<title>Introduction - Dioxus Router</title>
|
||||
|
||||
|
||||
<!-- Custom HTML head -->
|
||||
|
||||
<meta content="text/html; charset=utf-8" http-equiv="Content-Type">
|
||||
<meta name="description" content="">
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1">
|
||||
<meta name="theme-color" content="#ffffff" />
|
||||
|
||||
<link rel="icon" href="favicon.svg">
|
||||
<link rel="shortcut icon" href="favicon.png">
|
||||
<link rel="stylesheet" href="css/variables.css">
|
||||
<link rel="stylesheet" href="css/general.css">
|
||||
<link rel="stylesheet" href="css/chrome.css">
|
||||
<link rel="stylesheet" href="css/print.css" media="print">
|
||||
|
||||
<!-- Fonts -->
|
||||
<link rel="stylesheet" href="FontAwesome/css/font-awesome.css">
|
||||
<link rel="stylesheet" href="fonts/fonts.css">
|
||||
|
||||
<!-- Highlight.js Stylesheets -->
|
||||
<link rel="stylesheet" href="highlight.css">
|
||||
<link rel="stylesheet" href="tomorrow-night.css">
|
||||
<link rel="stylesheet" href="ayu-highlight.css">
|
||||
|
||||
<!-- Custom theme stylesheets -->
|
||||
|
||||
</head>
|
||||
<body>
|
||||
<!-- Provide site root to javascript -->
|
||||
<script type="text/javascript">
|
||||
var path_to_root = "";
|
||||
var default_theme = window.matchMedia("(prefers-color-scheme: dark)").matches ? "navy" : "light";
|
||||
</script>
|
||||
|
||||
<!-- Work around some values being stored in localStorage wrapped in quotes -->
|
||||
<script type="text/javascript">
|
||||
try {
|
||||
var theme = localStorage.getItem('mdbook-theme');
|
||||
var sidebar = localStorage.getItem('mdbook-sidebar');
|
||||
|
||||
if (theme.startsWith('"') && theme.endsWith('"')) {
|
||||
localStorage.setItem('mdbook-theme', theme.slice(1, theme.length - 1));
|
||||
}
|
||||
|
||||
if (sidebar.startsWith('"') && sidebar.endsWith('"')) {
|
||||
localStorage.setItem('mdbook-sidebar', sidebar.slice(1, sidebar.length - 1));
|
||||
}
|
||||
} catch (e) { }
|
||||
</script>
|
||||
|
||||
<!-- Set the theme before any content is loaded, prevents flash -->
|
||||
<script type="text/javascript">
|
||||
var theme;
|
||||
try { theme = localStorage.getItem('mdbook-theme'); } catch(e) { }
|
||||
if (theme === null || theme === undefined) { theme = default_theme; }
|
||||
var html = document.querySelector('html');
|
||||
html.classList.remove('no-js')
|
||||
html.classList.remove('light')
|
||||
html.classList.add(theme);
|
||||
html.classList.add('js');
|
||||
</script>
|
||||
|
||||
<!-- Hide / unhide sidebar before it is displayed -->
|
||||
<script type="text/javascript">
|
||||
var html = document.querySelector('html');
|
||||
var sidebar = 'hidden';
|
||||
if (document.body.clientWidth >= 1080) {
|
||||
try { sidebar = localStorage.getItem('mdbook-sidebar'); } catch(e) { }
|
||||
sidebar = sidebar || 'visible';
|
||||
}
|
||||
html.classList.remove('sidebar-visible');
|
||||
html.classList.add("sidebar-" + sidebar);
|
||||
</script>
|
||||
|
||||
<nav id="sidebar" class="sidebar" aria-label="Table of contents">
|
||||
<div class="sidebar-scrollbox">
|
||||
<ol class="chapter"><li class="chapter-item expanded affix "><a href="index.html" class="active">Introduction</a></li><li class="chapter-item expanded affix "><li class="part-title">Features</li><li class="chapter-item expanded "><a href="features/index.html"><strong aria-hidden="true">1.</strong> Adding the Router to Your Application</a></li><li class="chapter-item expanded "><a href="features/routes/index.html"><strong aria-hidden="true">2.</strong> Defining Routes</a></li><li><ol class="section"><li class="chapter-item expanded "><a href="features/routes/nested.html"><strong aria-hidden="true">2.1.</strong> Nested Routes</a></li><li class="chapter-item expanded "><a href="features/routes/catch_all.html"><strong aria-hidden="true">2.2.</strong> Catch All Routes</a></li><li class="chapter-item expanded "><a href="features/routes/matching.html"><strong aria-hidden="true">2.3.</strong> Matching Routes</a></li><li class="chapter-item expanded "><a href="features/routes/fallback.html"><strong aria-hidden="true">2.4.</strong> Fallback Routes (404 page)</a></li><li class="chapter-item expanded "><a href="features/routes/multiple-and-redirect.html"><strong aria-hidden="true">2.5.</strong> Multiple Components & Redirects</a></li></ol></li><li class="chapter-item expanded "><a href="features/outlets.html"><strong aria-hidden="true">3.</strong> Outlets</a></li><li class="chapter-item expanded "><a href="features/navigation/index.html"><strong aria-hidden="true">4.</strong> Links & Navigation</a></li><li><ol class="section"><li class="chapter-item expanded "><a href="features/navigation/name.html"><strong aria-hidden="true">4.1.</strong> Named Navigation</a></li><li class="chapter-item expanded "><a href="features/navigation/external.html"><strong aria-hidden="true">4.2.</strong> External Navigation</a></li><li class="chapter-item expanded "><a href="features/navigation/programmatic.html"><strong aria-hidden="true">4.3.</strong> Programmatic Navigation</a></li></ol></li><li class="chapter-item expanded "><a href="features/query.html"><strong aria-hidden="true">5.</strong> Query</a></li><li class="chapter-item expanded "><a href="features/failures/index.html"><strong aria-hidden="true">6.</strong> Navigation Failures</a></li><li><ol class="section"><li class="chapter-item expanded "><a href="features/failures/named.html"><strong aria-hidden="true">6.1.</strong> Named Navigation Failure</a></li><li class="chapter-item expanded "><a href="features/failures/external.html"><strong aria-hidden="true">6.2.</strong> External Navigation Failure</a></li><li class="chapter-item expanded "><a href="features/failures/redirection-limit.html"><strong aria-hidden="true">6.3.</strong> Redirection Limit Failure</a></li></ol></li><li class="chapter-item expanded "><a href="features/history-providers.html"><strong aria-hidden="true">7.</strong> History Providers</a></li><li class="chapter-item expanded "><a href="features/history-buttons.html"><strong aria-hidden="true">8.</strong> History Buttons</a></li><li class="chapter-item expanded "><a href="features/sitemap-generation.html"><strong aria-hidden="true">9.</strong> Sitemap Generation</a></li><li class="chapter-item expanded "><a href="features/routing-update-callback.html"><strong aria-hidden="true">10.</strong> Routing Update Callback</a></li><li class="chapter-item expanded affix "><li class="part-title">Example Project</li><li class="chapter-item expanded "><a href="example/index.html"><strong aria-hidden="true">11.</strong> Overview</a></li><li class="chapter-item expanded "><a href="example/first-route.html"><strong aria-hidden="true">12.</strong> Creating Our First Route</a></li><li class="chapter-item expanded "><a href="example/building-a-nest.html"><strong aria-hidden="true">13.</strong> Building a Nest</a></li><li class="chapter-item expanded "><a href="example/navigation-targets.html"><strong aria-hidden="true">14.</strong> Navigation Targets</a></li><li class="chapter-item expanded "><a href="example/redirection-perfection.html"><strong aria-hidden="true">15.</strong> Redirection Perfection</a></li><li class="chapter-item expanded "><a href="example/full-code.html"><strong aria-hidden="true">16.</strong> Full Code</a></li></ol>
|
||||
</div>
|
||||
<div id="sidebar-resize-handle" class="sidebar-resize-handle"></div>
|
||||
</nav>
|
||||
|
||||
<div id="page-wrapper" class="page-wrapper">
|
||||
|
||||
<div class="page">
|
||||
<div id="menu-bar-hover-placeholder"></div>
|
||||
<div id="menu-bar" class="menu-bar sticky bordered">
|
||||
<div class="left-buttons">
|
||||
<button id="sidebar-toggle" class="icon-button" type="button" title="Toggle Table of Contents" aria-label="Toggle Table of Contents" aria-controls="sidebar">
|
||||
<i class="fa fa-bars"></i>
|
||||
</button>
|
||||
<button id="theme-toggle" class="icon-button" type="button" title="Change theme" aria-label="Change theme" aria-haspopup="true" aria-expanded="false" aria-controls="theme-list">
|
||||
<i class="fa fa-paint-brush"></i>
|
||||
</button>
|
||||
<ul id="theme-list" class="theme-popup" aria-label="Themes" role="menu">
|
||||
<li role="none"><button role="menuitem" class="theme" id="light">Light (default)</button></li>
|
||||
<li role="none"><button role="menuitem" class="theme" id="rust">Rust</button></li>
|
||||
<li role="none"><button role="menuitem" class="theme" id="coal">Coal</button></li>
|
||||
<li role="none"><button role="menuitem" class="theme" id="navy">Navy</button></li>
|
||||
<li role="none"><button role="menuitem" class="theme" id="ayu">Ayu</button></li>
|
||||
</ul>
|
||||
<button id="search-toggle" class="icon-button" type="button" title="Search. (Shortkey: s)" aria-label="Toggle Searchbar" aria-expanded="false" aria-keyshortcuts="S" aria-controls="searchbar">
|
||||
<i class="fa fa-search"></i>
|
||||
</button>
|
||||
</div>
|
||||
|
||||
<h1 class="menu-title">Dioxus Router</h1>
|
||||
|
||||
<div class="right-buttons">
|
||||
<a href="print.html" title="Print this book" aria-label="Print this book">
|
||||
<i id="print-button" class="fa fa-print"></i>
|
||||
</a>
|
||||
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div id="search-wrapper" class="hidden">
|
||||
<form id="searchbar-outer" class="searchbar-outer">
|
||||
<input type="search" id="searchbar" name="searchbar" placeholder="Search this book ..." aria-controls="searchresults-outer" aria-describedby="searchresults-header">
|
||||
</form>
|
||||
<div id="searchresults-outer" class="searchresults-outer hidden">
|
||||
<div id="searchresults-header" class="searchresults-header"></div>
|
||||
<ul id="searchresults">
|
||||
</ul>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- Apply ARIA attributes after the sidebar and the sidebar toggle button are added to the DOM -->
|
||||
<script type="text/javascript">
|
||||
document.getElementById('sidebar-toggle').setAttribute('aria-expanded', sidebar === 'visible');
|
||||
document.getElementById('sidebar').setAttribute('aria-hidden', sidebar !== 'visible');
|
||||
Array.from(document.querySelectorAll('#sidebar a')).forEach(function(link) {
|
||||
link.setAttribute('tabIndex', sidebar === 'visible' ? 0 : -1);
|
||||
});
|
||||
</script>
|
||||
|
||||
<div id="content" class="content">
|
||||
<main>
|
||||
<h1 id="introduction"><a class="header" href="#introduction">Introduction</a></h1>
|
||||
<p>Whether or not you are building a website, desktop app, or mobile app,
|
||||
splitting your app's views into "pages" can be an effective method for
|
||||
organization and maintainability.</p>
|
||||
<p>For this purpose, Dioxus provides a router. To start utilizing it, add it as a
|
||||
dependency in your <code>Cargo.toml</code> file:</p>
|
||||
<pre><code class="language-toml">[dependencies]
|
||||
# use this for native apps
|
||||
dioxus-router = "*"
|
||||
#use this for web apps
|
||||
dioxus-router = { version = "*", features = ["web"] }
|
||||
|
||||
# in both cases replace * with the current version
|
||||
</code></pre>
|
||||
<p>You can also use the <code>cargo</code> command to add the dependency:</p>
|
||||
<pre><code class="language-sh">$ cargo add dioxus-router
|
||||
$ cargo add dioxus-router --features web
|
||||
</code></pre>
|
||||
<blockquote>
|
||||
<p>If you are not familiar with Dioxus itself, check out the <a href="https://dioxuslabs.com/guide/">Dioxus book</a>
|
||||
first.</p>
|
||||
</blockquote>
|
||||
<p>This book is intended to get you up to speed with Dioxus Router. It is split
|
||||
into two sections:</p>
|
||||
<ol>
|
||||
<li>The <a href="./features/index.html">Features</a> part explains individual features in
|
||||
depth. You can read it start to finish, or you can read individual chapters
|
||||
in whatever order you want.</li>
|
||||
<li>If you prefer a learning-by-doing approach, you can check ouf the
|
||||
<em><a href="./example/introduction.html">example project</a></em>. It guides you through
|
||||
creating a dioxus app, setting up the router and using some of its
|
||||
functionality.</li>
|
||||
</ol>
|
||||
<blockquote>
|
||||
<p>Please note that this is not the only documentation for the Dioxus Router. You
|
||||
can also check out the <a href="https://docs.rs/dioxus-router/">API Docs</a>.</p>
|
||||
</blockquote>
|
||||
|
||||
</main>
|
||||
|
||||
<nav class="nav-wrapper" aria-label="Page navigation">
|
||||
<!-- Mobile navigation buttons -->
|
||||
|
||||
<a rel="next" href="features/index.html" class="mobile-nav-chapters next" title="Next chapter" aria-label="Next chapter" aria-keyshortcuts="Right">
|
||||
<i class="fa fa-angle-right"></i>
|
||||
</a>
|
||||
|
||||
<div style="clear: both"></div>
|
||||
</nav>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<nav class="nav-wide-wrapper" aria-label="Page navigation">
|
||||
|
||||
<a rel="next" href="features/index.html" class="nav-chapters next" title="Next chapter" aria-label="Next chapter" aria-keyshortcuts="Right">
|
||||
<i class="fa fa-angle-right"></i>
|
||||
</a>
|
||||
</nav>
|
||||
|
||||
</div>
|
||||
|
||||
|
||||
|
||||
|
||||
<script type="text/javascript">
|
||||
window.playground_copyable = true;
|
||||
</script>
|
||||
|
||||
|
||||
<script src="elasticlunr.min.js" type="text/javascript" charset="utf-8"></script>
|
||||
<script src="mark.min.js" type="text/javascript" charset="utf-8"></script>
|
||||
<script src="searcher.js" type="text/javascript" charset="utf-8"></script>
|
||||
|
||||
<script src="clipboard.min.js" type="text/javascript" charset="utf-8"></script>
|
||||
<script src="highlight.js" type="text/javascript" charset="utf-8"></script>
|
||||
<script src="book.js" type="text/javascript" charset="utf-8"></script>
|
||||
|
||||
<!-- Custom JS scripts -->
|
||||
|
||||
|
||||
</body>
|
||||
</html>
|
||||
Vendored
+7
@@ -0,0 +1,7 @@
|
||||
/*!***************************************************
|
||||
* mark.js v8.11.1
|
||||
* https://markjs.io/
|
||||
* Copyright (c) 2014–2018, Julian Kühnel
|
||||
* Released under the MIT license https://git.io/vwTVl
|
||||
*****************************************************/
|
||||
!function(e,t){"object"==typeof exports&&"undefined"!=typeof module?module.exports=t():"function"==typeof define&&define.amd?define(t):e.Mark=t()}(this,function(){"use strict";var e="function"==typeof Symbol&&"symbol"==typeof Symbol.iterator?function(e){return typeof e}:function(e){return e&&"function"==typeof Symbol&&e.constructor===Symbol&&e!==Symbol.prototype?"symbol":typeof e},t=function(e,t){if(!(e instanceof t))throw new TypeError("Cannot call a class as a function")},n=function(){function e(e,t){for(var n=0;n<t.length;n++){var r=t[n];r.enumerable=r.enumerable||!1,r.configurable=!0,"value"in r&&(r.writable=!0),Object.defineProperty(e,r.key,r)}}return function(t,n,r){return n&&e(t.prototype,n),r&&e(t,r),t}}(),r=Object.assign||function(e){for(var t=1;t<arguments.length;t++){var n=arguments[t];for(var r in n)Object.prototype.hasOwnProperty.call(n,r)&&(e[r]=n[r])}return e},i=function(){function e(n){var r=!(arguments.length>1&&void 0!==arguments[1])||arguments[1],i=arguments.length>2&&void 0!==arguments[2]?arguments[2]:[],o=arguments.length>3&&void 0!==arguments[3]?arguments[3]:5e3;t(this,e),this.ctx=n,this.iframes=r,this.exclude=i,this.iframesTimeout=o}return n(e,[{key:"getContexts",value:function(){var e=[];return(void 0!==this.ctx&&this.ctx?NodeList.prototype.isPrototypeOf(this.ctx)?Array.prototype.slice.call(this.ctx):Array.isArray(this.ctx)?this.ctx:"string"==typeof this.ctx?Array.prototype.slice.call(document.querySelectorAll(this.ctx)):[this.ctx]:[]).forEach(function(t){var n=e.filter(function(e){return e.contains(t)}).length>0;-1!==e.indexOf(t)||n||e.push(t)}),e}},{key:"getIframeContents",value:function(e,t){var n=arguments.length>2&&void 0!==arguments[2]?arguments[2]:function(){},r=void 0;try{var i=e.contentWindow;if(r=i.document,!i||!r)throw new Error("iframe inaccessible")}catch(e){n()}r&&t(r)}},{key:"isIframeBlank",value:function(e){var t="about:blank",n=e.getAttribute("src").trim();return e.contentWindow.location.href===t&&n!==t&&n}},{key:"observeIframeLoad",value:function(e,t,n){var r=this,i=!1,o=null,a=function a(){if(!i){i=!0,clearTimeout(o);try{r.isIframeBlank(e)||(e.removeEventListener("load",a),r.getIframeContents(e,t,n))}catch(e){n()}}};e.addEventListener("load",a),o=setTimeout(a,this.iframesTimeout)}},{key:"onIframeReady",value:function(e,t,n){try{"complete"===e.contentWindow.document.readyState?this.isIframeBlank(e)?this.observeIframeLoad(e,t,n):this.getIframeContents(e,t,n):this.observeIframeLoad(e,t,n)}catch(e){n()}}},{key:"waitForIframes",value:function(e,t){var n=this,r=0;this.forEachIframe(e,function(){return!0},function(e){r++,n.waitForIframes(e.querySelector("html"),function(){--r||t()})},function(e){e||t()})}},{key:"forEachIframe",value:function(t,n,r){var i=this,o=arguments.length>3&&void 0!==arguments[3]?arguments[3]:function(){},a=t.querySelectorAll("iframe"),s=a.length,c=0;a=Array.prototype.slice.call(a);var u=function(){--s<=0&&o(c)};s||u(),a.forEach(function(t){e.matches(t,i.exclude)?u():i.onIframeReady(t,function(e){n(t)&&(c++,r(e)),u()},u)})}},{key:"createIterator",value:function(e,t,n){return document.createNodeIterator(e,t,n,!1)}},{key:"createInstanceOnIframe",value:function(t){return new e(t.querySelector("html"),this.iframes)}},{key:"compareNodeIframe",value:function(e,t,n){if(e.compareDocumentPosition(n)&Node.DOCUMENT_POSITION_PRECEDING){if(null===t)return!0;if(t.compareDocumentPosition(n)&Node.DOCUMENT_POSITION_FOLLOWING)return!0}return!1}},{key:"getIteratorNode",value:function(e){var t=e.previousNode();return{prevNode:t,node:null===t?e.nextNode():e.nextNode()&&e.nextNode()}}},{key:"checkIframeFilter",value:function(e,t,n,r){var i=!1,o=!1;return r.forEach(function(e,t){e.val===n&&(i=t,o=e.handled)}),this.compareNodeIframe(e,t,n)?(!1!==i||o?!1===i||o||(r[i].handled=!0):r.push({val:n,handled:!0}),!0):(!1===i&&r.push({val:n,handled:!1}),!1)}},{key:"handleOpenIframes",value:function(e,t,n,r){var i=this;e.forEach(function(e){e.handled||i.getIframeContents(e.val,function(e){i.createInstanceOnIframe(e).forEachNode(t,n,r)})})}},{key:"iterateThroughNodes",value:function(e,t,n,r,i){for(var o,a=this,s=this.createIterator(t,e,r),c=[],u=[],l=void 0,h=void 0;void 0,o=a.getIteratorNode(s),h=o.prevNode,l=o.node;)this.iframes&&this.forEachIframe(t,function(e){return a.checkIframeFilter(l,h,e,c)},function(t){a.createInstanceOnIframe(t).forEachNode(e,function(e){return u.push(e)},r)}),u.push(l);u.forEach(function(e){n(e)}),this.iframes&&this.handleOpenIframes(c,e,n,r),i()}},{key:"forEachNode",value:function(e,t,n){var r=this,i=arguments.length>3&&void 0!==arguments[3]?arguments[3]:function(){},o=this.getContexts(),a=o.length;a||i(),o.forEach(function(o){var s=function(){r.iterateThroughNodes(e,o,t,n,function(){--a<=0&&i()})};r.iframes?r.waitForIframes(o,s):s()})}}],[{key:"matches",value:function(e,t){var n="string"==typeof t?[t]:t,r=e.matches||e.matchesSelector||e.msMatchesSelector||e.mozMatchesSelector||e.oMatchesSelector||e.webkitMatchesSelector;if(r){var i=!1;return n.every(fuLine truncated
|
||||
File diff suppressed because it is too large.
Load diff
@@ -0,0 +1,483 @@
|
||||
"use strict";
|
||||
window.search = window.search || {};
|
||||
(function search(search) {
|
||||
// Search functionality
|
||||
//
|
||||
// You can use !hasFocus() to prevent keyhandling in your key
|
||||
// event handlers while the user is typing their search.
|
||||
|
||||
if (!Mark || !elasticlunr) {
|
||||
return;
|
||||
}
|
||||
|
||||
//IE 11 Compatibility from https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/String/startsWith
|
||||
if (!String.prototype.startsWith) {
|
||||
String.prototype.startsWith = function(search, pos) {
|
||||
return this.substr(!pos || pos < 0 ? 0 : +pos, search.length) === search;
|
||||
};
|
||||
}
|
||||
|
||||
var search_wrap = document.getElementById('search-wrapper'),
|
||||
searchbar = document.getElementById('searchbar'),
|
||||
searchbar_outer = document.getElementById('searchbar-outer'),
|
||||
searchresults = document.getElementById('searchresults'),
|
||||
searchresults_outer = document.getElementById('searchresults-outer'),
|
||||
searchresults_header = document.getElementById('searchresults-header'),
|
||||
searchicon = document.getElementById('search-toggle'),
|
||||
content = document.getElementById('content'),
|
||||
|
||||
searchindex = null,
|
||||
doc_urls = [],
|
||||
results_options = {
|
||||
teaser_word_count: 30,
|
||||
limit_results: 30,
|
||||
},
|
||||
search_options = {
|
||||
bool: "AND",
|
||||
expand: true,
|
||||
fields: {
|
||||
title: {boost: 1},
|
||||
body: {boost: 1},
|
||||
breadcrumbs: {boost: 0}
|
||||
}
|
||||
},
|
||||
mark_exclude = [],
|
||||
marker = new Mark(content),
|
||||
current_searchterm = "",
|
||||
URL_SEARCH_PARAM = 'search',
|
||||
URL_MARK_PARAM = 'highlight',
|
||||
teaser_count = 0,
|
||||
|
||||
SEARCH_HOTKEY_KEYCODE = 83,
|
||||
ESCAPE_KEYCODE = 27,
|
||||
DOWN_KEYCODE = 40,
|
||||
UP_KEYCODE = 38,
|
||||
SELECT_KEYCODE = 13;
|
||||
|
||||
function hasFocus() {
|
||||
return searchbar === document.activeElement;
|
||||
}
|
||||
|
||||
function removeChildren(elem) {
|
||||
while (elem.firstChild) {
|
||||
elem.removeChild(elem.firstChild);
|
||||
}
|
||||
}
|
||||
|
||||
// Helper to parse a url into its building blocks.
|
||||
function parseURL(url) {
|
||||
var a = document.createElement('a');
|
||||
a.href = url;
|
||||
return {
|
||||
source: url,
|
||||
protocol: a.protocol.replace(':',''),
|
||||
host: a.hostname,
|
||||
port: a.port,
|
||||
params: (function(){
|
||||
var ret = {};
|
||||
var seg = a.search.replace(/^\?/,'').split('&');
|
||||
var len = seg.length, i = 0, s;
|
||||
for (;i<len;i++) {
|
||||
if (!seg[i]) { continue; }
|
||||
s = seg[i].split('=');
|
||||
ret[s[0]] = s[1];
|
||||
}
|
||||
return ret;
|
||||
})(),
|
||||
file: (a.pathname.match(/\/([^/?#]+)$/i) || [,''])[1],
|
||||
hash: a.hash.replace('#',''),
|
||||
path: a.pathname.replace(/^([^/])/,'/$1')
|
||||
};
|
||||
}
|
||||
|
||||
// Helper to recreate a url string from its building blocks.
|
||||
function renderURL(urlobject) {
|
||||
var url = urlobject.protocol + "://" + urlobject.host;
|
||||
if (urlobject.port != "") {
|
||||
url += ":" + urlobject.port;
|
||||
}
|
||||
url += urlobject.path;
|
||||
var joiner = "?";
|
||||
for(var prop in urlobject.params) {
|
||||
if(urlobject.params.hasOwnProperty(prop)) {
|
||||
url += joiner + prop + "=" + urlobject.params[prop];
|
||||
joiner = "&";
|
||||
}
|
||||
}
|
||||
if (urlobject.hash != "") {
|
||||
url += "#" + urlobject.hash;
|
||||
}
|
||||
return url;
|
||||
}
|
||||
|
||||
// Helper to escape html special chars for displaying the teasers
|
||||
var escapeHTML = (function() {
|
||||
var MAP = {
|
||||
'&': '&',
|
||||
'<': '<',
|
||||
'>': '>',
|
||||
'"': '"',
|
||||
"'": '''
|
||||
};
|
||||
var repl = function(c) { return MAP[c]; };
|
||||
return function(s) {
|
||||
return s.replace(/[&<>'"]/g, repl);
|
||||
};
|
||||
})();
|
||||
|
||||
function formatSearchMetric(count, searchterm) {
|
||||
if (count == 1) {
|
||||
return count + " search result for '" + searchterm + "':";
|
||||
} else if (count == 0) {
|
||||
return "No search results for '" + searchterm + "'.";
|
||||
} else {
|
||||
return count + " search results for '" + searchterm + "':";
|
||||
}
|
||||
}
|
||||
|
||||
function formatSearchResult(result, searchterms) {
|
||||
var teaser = makeTeaser(escapeHTML(result.doc.body), searchterms);
|
||||
teaser_count++;
|
||||
|
||||
// The ?URL_MARK_PARAM= parameter belongs inbetween the page and the #heading-anchor
|
||||
var url = doc_urls[result.ref].split("#");
|
||||
if (url.length == 1) { // no anchor found
|
||||
url.push("");
|
||||
}
|
||||
|
||||
// encodeURIComponent escapes all chars that could allow an XSS except
|
||||
// for '. Due to that we also manually replace ' with its url-encoded
|
||||
// representation (%27).
|
||||
var searchterms = encodeURIComponent(searchterms.join(" ")).replace(/\'/g, "%27");
|
||||
|
||||
return '<a href="' + path_to_root + url[0] + '?' + URL_MARK_PARAM + '=' + searchterms + '#' + url[1]
|
||||
+ '" aria-details="teaser_' + teaser_count + '">' + result.doc.breadcrumbs + '</a>'
|
||||
+ '<span class="teaser" id="teaser_' + teaser_count + '" aria-label="Search Result Teaser">'
|
||||
+ teaser + '</span>';
|
||||
}
|
||||
|
||||
function makeTeaser(body, searchterms) {
|
||||
// The strategy is as follows:
|
||||
// First, assign a value to each word in the document:
|
||||
// Words that correspond to search terms (stemmer aware): 40
|
||||
// Normal words: 2
|
||||
// First word in a sentence: 8
|
||||
// Then use a sliding window with a constant number of words and count the
|
||||
// sum of the values of the words within the window. Then use the window that got the
|
||||
// maximum sum. If there are multiple maximas, then get the last one.
|
||||
// Enclose the terms in <em>.
|
||||
var stemmed_searchterms = searchterms.map(function(w) {
|
||||
return elasticlunr.stemmer(w.toLowerCase());
|
||||
});
|
||||
var searchterm_weight = 40;
|
||||
var weighted = []; // contains elements of ["word", weight, index_in_document]
|
||||
// split in sentences, then words
|
||||
var sentences = body.toLowerCase().split('. ');
|
||||
var index = 0;
|
||||
var value = 0;
|
||||
var searchterm_found = false;
|
||||
for (var sentenceindex in sentences) {
|
||||
var words = sentences[sentenceindex].split(' ');
|
||||
value = 8;
|
||||
for (var wordindex in words) {
|
||||
var word = words[wordindex];
|
||||
if (word.length > 0) {
|
||||
for (var searchtermindex in stemmed_searchterms) {
|
||||
if (elasticlunr.stemmer(word).startsWith(stemmed_searchterms[searchtermindex])) {
|
||||
value = searchterm_weight;
|
||||
searchterm_found = true;
|
||||
}
|
||||
};
|
||||
weighted.push([word, value, index]);
|
||||
value = 2;
|
||||
}
|
||||
index += word.length;
|
||||
index += 1; // ' ' or '.' if last word in sentence
|
||||
};
|
||||
index += 1; // because we split at a two-char boundary '. '
|
||||
};
|
||||
|
||||
if (weighted.length == 0) {
|
||||
return body;
|
||||
}
|
||||
|
||||
var window_weight = [];
|
||||
var window_size = Math.min(weighted.length, results_options.teaser_word_count);
|
||||
|
||||
var cur_sum = 0;
|
||||
for (var wordindex = 0; wordindex < window_size; wordindex++) {
|
||||
cur_sum += weighted[wordindex][1];
|
||||
};
|
||||
window_weight.push(cur_sum);
|
||||
for (var wordindex = 0; wordindex < weighted.length - window_size; wordindex++) {
|
||||
cur_sum -= weighted[wordindex][1];
|
||||
cur_sum += weighted[wordindex + window_size][1];
|
||||
window_weight.push(cur_sum);
|
||||
};
|
||||
|
||||
if (searchterm_found) {
|
||||
var max_sum = 0;
|
||||
var max_sum_window_index = 0;
|
||||
// backwards
|
||||
for (var i = window_weight.length - 1; i >= 0; i--) {
|
||||
if (window_weight[i] > max_sum) {
|
||||
max_sum = window_weight[i];
|
||||
max_sum_window_index = i;
|
||||
}
|
||||
};
|
||||
} else {
|
||||
max_sum_window_index = 0;
|
||||
}
|
||||
|
||||
// add <em/> around searchterms
|
||||
var teaser_split = [];
|
||||
var index = weighted[max_sum_window_index][2];
|
||||
for (var i = max_sum_window_index; i < max_sum_window_index+window_size; i++) {
|
||||
var word = weighted[i];
|
||||
if (index < word[2]) {
|
||||
// missing text from index to start of `word`
|
||||
teaser_split.push(body.substring(index, word[2]));
|
||||
index = word[2];
|
||||
}
|
||||
if (word[1] == searchterm_weight) {
|
||||
teaser_split.push("<em>")
|
||||
}
|
||||
index = word[2] + word[0].length;
|
||||
teaser_split.push(body.substring(word[2], index));
|
||||
if (word[1] == searchterm_weight) {
|
||||
teaser_split.push("</em>")
|
||||
}
|
||||
};
|
||||
|
||||
return teaser_split.join('');
|
||||
}
|
||||
|
||||
function init(config) {
|
||||
results_options = config.results_options;
|
||||
search_options = config.search_options;
|
||||
searchbar_outer = config.searchbar_outer;
|
||||
doc_urls = config.doc_urls;
|
||||
searchindex = elasticlunr.Index.load(config.index);
|
||||
|
||||
// Set up events
|
||||
searchicon.addEventListener('click', function(e) { searchIconClickHandler(); }, false);
|
||||
searchbar.addEventListener('keyup', function(e) { searchbarKeyUpHandler(); }, false);
|
||||
document.addEventListener('keydown', function(e) { globalKeyHandler(e); }, false);
|
||||
// If the user uses the browser buttons, do the same as if a reload happened
|
||||
window.onpopstate = function(e) { doSearchOrMarkFromUrl(); };
|
||||
// Suppress "submit" events so the page doesn't reload when the user presses Enter
|
||||
document.addEventListener('submit', function(e) { e.preventDefault(); }, false);
|
||||
|
||||
// If reloaded, do the search or mark again, depending on the current url parameters
|
||||
doSearchOrMarkFromUrl();
|
||||
}
|
||||
|
||||
function unfocusSearchbar() {
|
||||
// hacky, but just focusing a div only works once
|
||||
var tmp = document.createElement('input');
|
||||
tmp.setAttribute('style', 'position: absolute; opacity: 0;');
|
||||
searchicon.appendChild(tmp);
|
||||
tmp.focus();
|
||||
tmp.remove();
|
||||
}
|
||||
|
||||
// On reload or browser history backwards/forwards events, parse the url and do search or mark
|
||||
function doSearchOrMarkFromUrl() {
|
||||
// Check current URL for search request
|
||||
var url = parseURL(window.location.href);
|
||||
if (url.params.hasOwnProperty(URL_SEARCH_PARAM)
|
||||
&& url.params[URL_SEARCH_PARAM] != "") {
|
||||
showSearch(true);
|
||||
searchbar.value = decodeURIComponent(
|
||||
(url.params[URL_SEARCH_PARAM]+'').replace(/\+/g, '%20'));
|
||||
searchbarKeyUpHandler(); // -> doSearch()
|
||||
} else {
|
||||
showSearch(false);
|
||||
}
|
||||
|
||||
if (url.params.hasOwnProperty(URL_MARK_PARAM)) {
|
||||
var words = decodeURIComponent(url.params[URL_MARK_PARAM]).split(' ');
|
||||
marker.mark(words, {
|
||||
exclude: mark_exclude
|
||||
});
|
||||
|
||||
var markers = document.querySelectorAll("mark");
|
||||
function hide() {
|
||||
for (var i = 0; i < markers.length; i++) {
|
||||
markers[i].classList.add("fade-out");
|
||||
window.setTimeout(function(e) { marker.unmark(); }, 300);
|
||||
}
|
||||
}
|
||||
for (var i = 0; i < markers.length; i++) {
|
||||
markers[i].addEventListener('click', hide);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Eventhandler for keyevents on `document`
|
||||
function globalKeyHandler(e) {
|
||||
if (e.altKey || e.ctrlKey || e.metaKey || e.shiftKey || e.target.type === 'textarea' || e.target.type === 'text') { return; }
|
||||
|
||||
if (e.keyCode === ESCAPE_KEYCODE) {
|
||||
e.preventDefault();
|
||||
searchbar.classList.remove("active");
|
||||
setSearchUrlParameters("",
|
||||
(searchbar.value.trim() !== "") ? "push" : "replace");
|
||||
if (hasFocus()) {
|
||||
unfocusSearchbar();
|
||||
}
|
||||
showSearch(false);
|
||||
marker.unmark();
|
||||
} else if (!hasFocus() && e.keyCode === SEARCH_HOTKEY_KEYCODE) {
|
||||
e.preventDefault();
|
||||
showSearch(true);
|
||||
window.scrollTo(0, 0);
|
||||
searchbar.select();
|
||||
} else if (hasFocus() && e.keyCode === DOWN_KEYCODE) {
|
||||
e.preventDefault();
|
||||
unfocusSearchbar();
|
||||
searchresults.firstElementChild.classList.add("focus");
|
||||
} else if (!hasFocus() && (e.keyCode === DOWN_KEYCODE
|
||||
|| e.keyCode === UP_KEYCODE
|
||||
|| e.keyCode === SELECT_KEYCODE)) {
|
||||
// not `:focus` because browser does annoying scrolling
|
||||
var focused = searchresults.querySelector("li.focus");
|
||||
if (!focused) return;
|
||||
e.preventDefault();
|
||||
if (e.keyCode === DOWN_KEYCODE) {
|
||||
var next = focused.nextElementSibling;
|
||||
if (next) {
|
||||
focused.classList.remove("focus");
|
||||
next.classList.add("focus");
|
||||
}
|
||||
} else if (e.keyCode === UP_KEYCODE) {
|
||||
focused.classList.remove("focus");
|
||||
var prev = focused.previousElementSibling;
|
||||
if (prev) {
|
||||
prev.classList.add("focus");
|
||||
} else {
|
||||
searchbar.select();
|
||||
}
|
||||
} else { // SELECT_KEYCODE
|
||||
window.location.assign(focused.querySelector('a'));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
function showSearch(yes) {
|
||||
if (yes) {
|
||||
search_wrap.classList.remove('hidden');
|
||||
searchicon.setAttribute('aria-expanded', 'true');
|
||||
} else {
|
||||
search_wrap.classList.add('hidden');
|
||||
searchicon.setAttribute('aria-expanded', 'false');
|
||||
var results = searchresults.children;
|
||||
for (var i = 0; i < results.length; i++) {
|
||||
results[i].classList.remove("focus");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
function showResults(yes) {
|
||||
if (yes) {
|
||||
searchresults_outer.classList.remove('hidden');
|
||||
} else {
|
||||
searchresults_outer.classList.add('hidden');
|
||||
}
|
||||
}
|
||||
|
||||
// Eventhandler for search icon
|
||||
function searchIconClickHandler() {
|
||||
if (search_wrap.classList.contains('hidden')) {
|
||||
showSearch(true);
|
||||
window.scrollTo(0, 0);
|
||||
searchbar.select();
|
||||
} else {
|
||||
showSearch(false);
|
||||
}
|
||||
}
|
||||
|
||||
// Eventhandler for keyevents while the searchbar is focused
|
||||
function searchbarKeyUpHandler() {
|
||||
var searchterm = searchbar.value.trim();
|
||||
if (searchterm != "") {
|
||||
searchbar.classList.add("active");
|
||||
doSearch(searchterm);
|
||||
} else {
|
||||
searchbar.classList.remove("active");
|
||||
showResults(false);
|
||||
removeChildren(searchresults);
|
||||
}
|
||||
|
||||
setSearchUrlParameters(searchterm, "push_if_new_search_else_replace");
|
||||
|
||||
// Remove marks
|
||||
marker.unmark();
|
||||
}
|
||||
|
||||
// Update current url with ?URL_SEARCH_PARAM= parameter, remove ?URL_MARK_PARAM and #heading-anchor .
|
||||
// `action` can be one of "push", "replace", "push_if_new_search_else_replace"
|
||||
// and replaces or pushes a new browser history item.
|
||||
// "push_if_new_search_else_replace" pushes if there is no `?URL_SEARCH_PARAM=abc` yet.
|
||||
function setSearchUrlParameters(searchterm, action) {
|
||||
var url = parseURL(window.location.href);
|
||||
var first_search = ! url.params.hasOwnProperty(URL_SEARCH_PARAM);
|
||||
if (searchterm != "" || action == "push_if_new_search_else_replace") {
|
||||
url.params[URL_SEARCH_PARAM] = searchterm;
|
||||
delete url.params[URL_MARK_PARAM];
|
||||
url.hash = "";
|
||||
} else {
|
||||
delete url.params[URL_MARK_PARAM];
|
||||
delete url.params[URL_SEARCH_PARAM];
|
||||
}
|
||||
// A new search will also add a new history item, so the user can go back
|
||||
// to the page prior to searching. A updated search term will only replace
|
||||
// the url.
|
||||
if (action == "push" || (action == "push_if_new_search_else_replace" && first_search) ) {
|
||||
history.pushState({}, document.title, renderURL(url));
|
||||
} else if (action == "replace" || (action == "push_if_new_search_else_replace" && !first_search) ) {
|
||||
history.replaceState({}, document.title, renderURL(url));
|
||||
}
|
||||
}
|
||||
|
||||
function doSearch(searchterm) {
|
||||
|
||||
// Don't search the same twice
|
||||
if (current_searchterm == searchterm) { return; }
|
||||
else { current_searchterm = searchterm; }
|
||||
|
||||
if (searchindex == null) { return; }
|
||||
|
||||
// Do the actual search
|
||||
var results = searchindex.search(searchterm, search_options);
|
||||
var resultcount = Math.min(results.length, results_options.limit_results);
|
||||
|
||||
// Display search metrics
|
||||
searchresults_header.innerText = formatSearchMetric(resultcount, searchterm);
|
||||
|
||||
// Clear and insert results
|
||||
var searchterms = searchterm.split(' ');
|
||||
removeChildren(searchresults);
|
||||
for(var i = 0; i < resultcount ; i++){
|
||||
var resultElem = document.createElement('li');
|
||||
resultElem.innerHTML = formatSearchResult(results[i], searchterms);
|
||||
searchresults.appendChild(resultElem);
|
||||
}
|
||||
|
||||
// Display results
|
||||
showResults(true);
|
||||
}
|
||||
|
||||
fetch(path_to_root + 'searchindex.json')
|
||||
.then(response => response.json())
|
||||
.then(json => init(json))
|
||||
.catch(error => { // Try to load searchindex.js if fetch failed
|
||||
var script = document.createElement('script');
|
||||
script.src = path_to_root + 'searchindex.js';
|
||||
script.onload = () => init(window.search);
|
||||
document.head.appendChild(script);
|
||||
});
|
||||
|
||||
// Exported functions
|
||||
search.hasFocus = hasFocus;
|
||||
})(window.search);
|
||||
@@ -0,0 +1 @@
|
||||
Object.assign(window.search, {"doc_urls":["index.html#introduction","features/index.html#adding-the-router-to-your-application","features/routes/index.html#defining-routes","features/routes/index.html#example-content","features/routes/index.html#index-routes","features/routes/index.html#fixed-routes","features/routes/index.html#full-code","features/routes/nested.html#nested-routes","features/routes/nested.html#route-depth","features/routes/nested.html#defining-the-content-components","features/routes/nested.html#defining-the-root--segment","features/routes/nested.html#defining-the-nested--segment","features/routes/nested.html#full-code","features/routes/catch_all.html#catch-all-routes","features/routes/catch_all.html#creating-a-content-component","features/routes/catch_all.html#defining-the-routes","features/routes/catch_all.html#interaction-with-other-routes","features/routes/catch_all.html#full-code","features/routes/matching.html#matching-routes","features/routes/matching.html#code-example","features/routes/matching.html#matcher","features/routes/fallback.html#fallback-routes","features/routes/fallback.html#a-single-global-fallback","features/routes/fallback.html#more-specific-fallback-routes","features/routes/multiple-and-redirect.html#multiple-components--redirects","features/routes/multiple-and-redirect.html#multiple-components","features/routes/multiple-and-redirect.html#redirects","features/outlets.html#outlets","features/outlets.html#nested-outlets","features/outlets.html#named-outlets","features/outlets.html#outlet-depth-override","features/outlets.html#outlet-recursion","features/navigation/index.html#links--navigation","features/navigation/name.html#named-navigation","features/navigation/name.html#code-example","features/navigation/name.html#check-if-a-name-is-present","features/navigation/external.html#external-navigation","features/navigation/external.html#code-example","features/navigation/programmatic.html#programmatic-navigation","features/navigation/programmatic.html#acquiring-a--navigator","features/navigation/programmatic.html#triggering-a-navigation","features/navigation/programmatic.html#external-navigation-targets","features/query.html#query","features/query.html#accessing-the-query","features/query.html#setting-the-query","features/query.html#internal--and--external","features/query.html#named","features/failures/index.html#navigation-failures","features/failures/named.html#named-navigation-failure","features/failures/named.html#debug","features/failures/named.html#release","features/failures/external.html#external-navigation-failure","features/failures/external.html#failure-handling","features/failures/redirection-limit.html#redirection-limit-failure","features/failures/redirection-limit.html#debug","features/failures/redirection-limit.html#release","features/history-providers.html#history-providers","features/history-buttons.html#history-buttons","features/sitemap-generation.html#sitemap-generation","features/sitemap-generation.html#preparing-an-app","features/sitemap-generation.html#modifying-the-app-to-make-using-sitemaps-easier","features/sitemap-generation.html#sitemaps-with-parameter-names","features/sitemap-generation.html#sitemaps-with-actual-parameter-values","features/routing-update-callback.html#routing-update-callback","features/routing-update-callback.html#how-does-the-callback-behave","features/routing-update-callback.html#code-example","example/index.html#overview","example/index.html#youll-learn-how-to","example/first-route.html#creating-our-first-route","example/first-route.html#fundamentals","example/first-route.html#to-route-or-not-to-route","example/first-route.html#what-if-a-route-doesnt-exist","example/first-route.html#conclusion","example/building-a-nest.html#building-a-nest","example/building-a-nest.html#site-navigation","example/building-a-nest.html#active-link-styling","example/building-a-nest.html#url-parameters-and-nested-routes","example/building-a-nest.html#conclusion","example/navigation-targets.html#navigation-targets","example/navigation-targets.html#what-is-a-navigation-target","example/navigation-targets.html#external-navigation","example/navigation-targets.html#named-navigation","example/navigation-targets.html#the-special-root-index-name","example/redirection-perfection.html#redirection-perfection","example/redirection-perfection.html#what-is-this-redirect-thing","example/redirection-perfection.html#conclusion","example/redirection-perfection.html#challenges","example/full-code.html#full-code"],"index":{"documentStore":{"docInfo":{"0":{"body":118,"breadcrumbs":2,"title":1},"1":{"body":113,"breadcrumbs":6,"title":3},"10":{"body":57,"breadcrumbs":7,"title":3},"11":{"body":74,"breadcrumbs":7,"title":3},"12":{"body":83,"breadcrumbs":6,"title":2},"13":{"body":34,"breadcrumbs":6,"title":2},"14":{"body":84,"breadcrumbs":7,"title":3},"15":{"body":71,"breadcrumbs":6,"title":2},"16":{"body":86,"breadcrumbs":6,"title":2},"17":{"body":67,"breadcrumbs":6,"tiLine truncated
|
||||
@@ -0,0 +1 @@
|
||||
{"doc_urls":["index.html#introduction","features/index.html#adding-the-router-to-your-application","features/routes/index.html#defining-routes","features/routes/index.html#example-content","features/routes/index.html#index-routes","features/routes/index.html#fixed-routes","features/routes/index.html#full-code","features/routes/nested.html#nested-routes","features/routes/nested.html#route-depth","features/routes/nested.html#defining-the-content-components","features/routes/nested.html#defining-the-root--segment","features/routes/nested.html#defining-the-nested--segment","features/routes/nested.html#full-code","features/routes/catch_all.html#catch-all-routes","features/routes/catch_all.html#creating-a-content-component","features/routes/catch_all.html#defining-the-routes","features/routes/catch_all.html#interaction-with-other-routes","features/routes/catch_all.html#full-code","features/routes/matching.html#matching-routes","features/routes/matching.html#code-example","features/routes/matching.html#matcher","features/routes/fallback.html#fallback-routes","features/routes/fallback.html#a-single-global-fallback","features/routes/fallback.html#more-specific-fallback-routes","features/routes/multiple-and-redirect.html#multiple-components--redirects","features/routes/multiple-and-redirect.html#multiple-components","features/routes/multiple-and-redirect.html#redirects","features/outlets.html#outlets","features/outlets.html#nested-outlets","features/outlets.html#named-outlets","features/outlets.html#outlet-depth-override","features/outlets.html#outlet-recursion","features/navigation/index.html#links--navigation","features/navigation/name.html#named-navigation","features/navigation/name.html#code-example","features/navigation/name.html#check-if-a-name-is-present","features/navigation/external.html#external-navigation","features/navigation/external.html#code-example","features/navigation/programmatic.html#programmatic-navigation","features/navigation/programmatic.html#acquiring-a--navigator","features/navigation/programmatic.html#triggering-a-navigation","features/navigation/programmatic.html#external-navigation-targets","features/query.html#query","features/query.html#accessing-the-query","features/query.html#setting-the-query","features/query.html#internal--and--external","features/query.html#named","features/failures/index.html#navigation-failures","features/failures/named.html#named-navigation-failure","features/failures/named.html#debug","features/failures/named.html#release","features/failures/external.html#external-navigation-failure","features/failures/external.html#failure-handling","features/failures/redirection-limit.html#redirection-limit-failure","features/failures/redirection-limit.html#debug","features/failures/redirection-limit.html#release","features/history-providers.html#history-providers","features/history-buttons.html#history-buttons","features/sitemap-generation.html#sitemap-generation","features/sitemap-generation.html#preparing-an-app","features/sitemap-generation.html#modifying-the-app-to-make-using-sitemaps-easier","features/sitemap-generation.html#sitemaps-with-parameter-names","features/sitemap-generation.html#sitemaps-with-actual-parameter-values","features/routing-update-callback.html#routing-update-callback","features/routing-update-callback.html#how-does-the-callback-behave","features/routing-update-callback.html#code-example","example/index.html#overview","example/index.html#youll-learn-how-to","example/first-route.html#creating-our-first-route","example/first-route.html#fundamentals","example/first-route.html#to-route-or-not-to-route","example/first-route.html#what-if-a-route-doesnt-exist","example/first-route.html#conclusion","example/building-a-nest.html#building-a-nest","example/building-a-nest.html#site-navigation","example/building-a-nest.html#active-link-styling","example/building-a-nest.html#url-parameters-and-nested-routes","example/building-a-nest.html#conclusion","example/navigation-targets.html#navigation-targets","example/navigation-targets.html#what-is-a-navigation-target","example/navigation-targets.html#external-navigation","example/navigation-targets.html#named-navigation","example/navigation-targets.html#the-special-root-index-name","example/redirection-perfection.html#redirection-perfection","example/redirection-perfection.html#what-is-this-redirect-thing","example/redirection-perfection.html#conclusion","example/redirection-perfection.html#challenges","example/full-code.html#full-code"],"index":{"documentStore":{"docInfo":{"0":{"body":118,"breadcrumbs":2,"title":1},"1":{"body":113,"breadcrumbs":6,"title":3},"10":{"body":57,"breadcrumbs":7,"title":3},"11":{"body":74,"breadcrumbs":7,"title":3},"12":{"body":83,"breadcrumbs":6,"title":2},"13":{"body":34,"breadcrumbs":6,"title":2},"14":{"body":84,"breadcrumbs":7,"title":3},"15":{"body":71,"breadcrumbs":6,"title":2},"16":{"body":86,"breadcrumbs":6,"title":2},"17":{"body":67,"breadcrumbs":6,"title":2},"18":{"body":46,"breaLine truncated
|
||||
@@ -0,0 +1,104 @@
|
||||
/* Tomorrow Night Theme */
|
||||
/* http://jmblog.github.com/color-themes-for-google-code-highlightjs */
|
||||
/* Original theme - https://github.com/chriskempson/tomorrow-theme */
|
||||
/* http://jmblog.github.com/color-themes-for-google-code-highlightjs */
|
||||
|
||||
/* Tomorrow Comment */
|
||||
.hljs-comment {
|
||||
color: #969896;
|
||||
}
|
||||
|
||||
/* Tomorrow Red */
|
||||
.hljs-variable,
|
||||
.hljs-attribute,
|
||||
.hljs-tag,
|
||||
.hljs-regexp,
|
||||
.ruby .hljs-constant,
|
||||
.xml .hljs-tag .hljs-title,
|
||||
.xml .hljs-pi,
|
||||
.xml .hljs-doctype,
|
||||
.html .hljs-doctype,
|
||||
.css .hljs-id,
|
||||
.css .hljs-class,
|
||||
.css .hljs-pseudo {
|
||||
color: #cc6666;
|
||||
}
|
||||
|
||||
/* Tomorrow Orange */
|
||||
.hljs-number,
|
||||
.hljs-preprocessor,
|
||||
.hljs-pragma,
|
||||
.hljs-built_in,
|
||||
.hljs-literal,
|
||||
.hljs-params,
|
||||
.hljs-constant {
|
||||
color: #de935f;
|
||||
}
|
||||
|
||||
/* Tomorrow Yellow */
|
||||
.ruby .hljs-class .hljs-title,
|
||||
.css .hljs-rule .hljs-attribute {
|
||||
color: #f0c674;
|
||||
}
|
||||
|
||||
/* Tomorrow Green */
|
||||
.hljs-string,
|
||||
.hljs-value,
|
||||
.hljs-inheritance,
|
||||
.hljs-header,
|
||||
.hljs-name,
|
||||
.ruby .hljs-symbol,
|
||||
.xml .hljs-cdata {
|
||||
color: #b5bd68;
|
||||
}
|
||||
|
||||
/* Tomorrow Aqua */
|
||||
.hljs-title,
|
||||
.css .hljs-hexcolor {
|
||||
color: #8abeb7;
|
||||
}
|
||||
|
||||
/* Tomorrow Blue */
|
||||
.hljs-function,
|
||||
.python .hljs-decorator,
|
||||
.python .hljs-title,
|
||||
.ruby .hljs-function .hljs-title,
|
||||
.ruby .hljs-title .hljs-keyword,
|
||||
.perl .hljs-sub,
|
||||
.javascript .hljs-title,
|
||||
.coffeescript .hljs-title {
|
||||
color: #81a2be;
|
||||
}
|
||||
|
||||
/* Tomorrow Purple */
|
||||
.hljs-keyword,
|
||||
.javascript .hljs-function {
|
||||
color: #b294bb;
|
||||
}
|
||||
|
||||
.hljs {
|
||||
display: block;
|
||||
overflow-x: auto;
|
||||
background: #1d1f21;
|
||||
color: #c5c8c6;
|
||||
padding: 0.5em;
|
||||
-webkit-text-size-adjust: none;
|
||||
}
|
||||
|
||||
.coffeescript .javascript,
|
||||
.javascript .xml,
|
||||
.tex .hljs-formula,
|
||||
.xml .javascript,
|
||||
.xml .vbscript,
|
||||
.xml .css,
|
||||
.xml .hljs-cdata {
|
||||
opacity: 0.5;
|
||||
}
|
||||
|
||||
.hljs-addition {
|
||||
color: #718c00;
|
||||
}
|
||||
|
||||
.hljs-deletion {
|
||||
color: #c82829;
|
||||
}
|
||||
Reference in new issue
Block a user