From 923f6434df934bfae89f4c7a91e4d9ff6fda6b06 Mon Sep 17 00:00:00 2001 From: Jonathan Bailey <1441856+zecozephyr@users.noreply.github.com> Date: Wed, 12 Jan 2022 05:27:14 -0800 Subject: [PATCH] Support named wildcards when deriving Routable. (#2345) --- packages/yew-router-macro/src/routable_derive.rs | 4 +++- .../tests/routable_derive/valid-pass.rs | 12 ++++++++++-- packages/yew-router/src/switch.rs | 9 ++++++++- website/docs/concepts/router.mdx | 5 ++++- 4 files changed, 25 insertions(+), 5 deletions(-) diff --git a/packages/yew-router-macro/src/routable_derive.rs b/packages/yew-router-macro/src/routable_derive.rs index 8f5f049f6..992736e42 100644 --- a/packages/yew-router-macro/src/routable_derive.rs +++ b/packages/yew-router-macro/src/routable_derive.rs @@ -172,8 +172,10 @@ impl Routable { for field in fields.iter() { // :param -> {param} + // *param -> {param} // so we can pass it to `format!("...", param)` - right = right.replace(&format!(":{}", field), &format!("{{{}}}", field)) + right = right.replace(&format!(":{}", field), &format!("{{{}}}", field)); + right = right.replace(&format!("*{}", field), &format!("{{{}}}", field)); } quote! { diff --git a/packages/yew-router-macro/tests/routable_derive/valid-pass.rs b/packages/yew-router-macro/tests/routable_derive/valid-pass.rs index fa1dd5e06..7b85e1794 100644 --- a/packages/yew-router-macro/tests/routable_derive/valid-pass.rs +++ b/packages/yew-router-macro/tests/routable_derive/valid-pass.rs @@ -6,11 +6,19 @@ enum Routes { One, #[at("/two/:id")] Two { id: u32 }, - #[at("/:a/:b")] - Three { a: u32, b: u32 }, + #[at("/:a/:b/*rest")] + Three { a: u32, b: u32, rest: ::std::string::String }, #[at("/404")] #[not_found] NotFound, } +#[derive(Debug, PartialEq, Clone, ::yew_router::Routable)] +enum MoreRoutes { + #[at("/subpath/*rest")] + Subpath { rest: ::std::string::String }, + #[at("/*all")] + CatchAll { all: ::std::string::String }, +} + fn main() {} diff --git a/packages/yew-router/src/switch.rs b/packages/yew-router/src/switch.rs index 900457cf5..9792d68f5 100644 --- a/packages/yew-router/src/switch.rs +++ b/packages/yew-router/src/switch.rs @@ -47,6 +47,8 @@ where { /// Callback which returns [`Html`] to be rendered for the current route. pub render: RenderFn, + #[prop_or_default] + pub pathname: Option, } #[doc(hidden)] @@ -93,7 +95,12 @@ where } fn view(&self, ctx: &Context) -> Html { - let route = ctx.link().route::(); + let route = ctx + .props() + .pathname + .as_ref() + .and_then(|p| R::recognize(p)) + .or_else(|| ctx.link().route::()); let children = match &route { Some(ref route) => (ctx.props().render.0)(route), diff --git a/website/docs/concepts/router.mdx b/website/docs/concepts/router.mdx index 61a1bab22..a426d4f8b 100644 --- a/website/docs/concepts/router.mdx +++ b/website/docs/concepts/router.mdx @@ -102,7 +102,7 @@ fn app() -> Html { ### Path Segments -It is also possible to extract information from a route. +It is also possible to extract information from a route using dynamic and named wildcard segments. You can then access the post's id inside `` and forward it to the appropriate component via properties. ```rust @@ -115,12 +115,15 @@ enum Route { Home, #[at("/post/:id")] Post { id: String }, + #[at("/*path")] + Misc { path: String }, } fn switch(route: &Route) -> Html { match route { Route::Home => html! {

{ "Home" }

}, Route::Post { id } => html! {

{format!("You are looking at Post {}", id)}

}, + Route::Misc { path } => html! {

{format!("Matched some other path: {}", path)}

}, } } ```