Routing
use vertigo::{dom, router::Router}; #[derive(Clone, PartialEq)] enum Route { Main, Post(String), NotFound(String), } impl std::fmt::Display for Route { fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { match self { Route::Main => write!(f, "/main"), Route::Post(slug) => write!(f, "/post/{slug}"), Route::NotFound(x) => write!(f, "{x}"), } } } impl From<String> for Route { fn from(value: String) -> Self { if value == "/main" { return Self::Main; } else if value.starts_with("/post") { if let Some(slug) = value.split('/').nth(1) { return Self::Post(slug.to_string()); } } Self::NotFound(value) } } let routing = Router::new_history_router(); let page = routing.route.render_value(|route| match route { Route::Main => dom! { <main>"Main Page"</main> }, Route::Post(slug) => dom! { <main>"Post with slug " {slug}</main> }, Route::NotFound(path) => dom! { <main>"Page " {path} " not found"</main> }, }); dom! { <div> {page} </div> }
Matching against current route
use vertigo::{Computed, dom, router::Router}; #[derive(Clone, PartialEq)] enum Route { Main, Post(String), NotFound(String), } impl Route { pub fn matches(self, current: &Computed<Self>) -> Computed<bool> { current.map(move |current| self == current) } } impl std::fmt::Display for Route { fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { match self { Route::Main => write!(f, "/main"), Route::Post(slug) => write!(f, "/post/{slug}"), Route::NotFound(x) => write!(f, "{x}"), } } } impl From<String> for Route { fn from(value: String) -> Self { if value == "/main" { return Self::Main; } else if value.starts_with("/post") { if let Some(slug) = value.split('/').nth(1) { return Self::Post(slug.to_string()); } } Self::NotFound(value) } } let routing = Router::new_history_router(); // Will generate Some(<p>) only if Main is the current route. let main_page_info = Route::Main.matches(&routing.route) .render_value_option(|is_active| is_active.then(|| dom! { <p>"You're in the main menu!"</p> }) ); let page = routing.route.render_value(|route| match route { Route::Main => dom! { <main>"Main Page"</main> }, Route::Post(slug) => dom! { <main>"Post with slug " {slug}</main> }, Route::NotFound(path) => dom! { <main>"Page " {path} " not found"</main> }, }); dom! { <div> {main_page_info} {page} </div> }