Skip to content

Commit 810ae1b

Browse files
committed
feat(templates): ✨ added template macro to automate template fn creation
This makes Perseus significantly more ergonomic. Partially addresses #57.
1 parent 4364d99 commit 810ae1b

File tree

21 files changed

+365
-113
lines changed

21 files changed

+365
-113
lines changed

examples/basic/src/templates/about.rs

+6-11
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
use perseus::Template;
22
use sycamore::prelude::{component, template, GenericNode, Template as SycamoreTemplate};
33

4+
#[perseus::template(AboutPage)]
45
#[component(AboutPage<G>)]
56
pub fn about_page() -> SycamoreTemplate<G> {
67
template! {
@@ -9,15 +10,9 @@ pub fn about_page() -> SycamoreTemplate<G> {
910
}
1011

1112
pub fn get_template<G: GenericNode>() -> Template<G> {
12-
Template::new("about")
13-
.template(|_| {
14-
template! {
15-
AboutPage()
16-
}
17-
})
18-
.head(|_| {
19-
template! {
20-
title { "About Page | Perseus Example – Basic" }
21-
}
22-
})
13+
Template::new("about").template(about_page).head(|_| {
14+
template! {
15+
title { "About Page | Perseus Example – Basic" }
16+
}
17+
})
2318
}

examples/basic/src/templates/index.rs

+2-7
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,7 @@ pub struct IndexPageProps {
1010
pub greeting: String,
1111
}
1212

13+
#[perseus::template(IndexPage)]
1314
#[component(IndexPage<G>)]
1415
pub fn index_page(props: IndexPageProps) -> SycamoreTemplate<G> {
1516
template! {
@@ -21,13 +22,7 @@ pub fn index_page(props: IndexPageProps) -> SycamoreTemplate<G> {
2122
pub fn get_template<G: GenericNode>() -> Template<G> {
2223
Template::new("index")
2324
.build_state_fn(get_build_props)
24-
.template(|props: Option<String>| {
25-
template! {
26-
IndexPage(
27-
serde_json::from_str::<IndexPageProps>(&props.unwrap()).unwrap()
28-
)
29-
}
30-
})
25+
.template(index_page)
3126
.head(|_| {
3227
template! {
3328
title { "Index Page | Perseus Example – Basic" }

examples/i18n/src/templates/about.rs

+2-5
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
use perseus::{is_server, t, Template};
22
use sycamore::prelude::{component, template, GenericNode, Template as SycamoreTemplate};
33

4+
#[perseus::template(AboutPage)]
45
#[component(AboutPage<G>)]
56
pub fn about_page() -> SycamoreTemplate<G> {
67
template! {
@@ -18,9 +19,5 @@ pub fn about_page() -> SycamoreTemplate<G> {
1819
}
1920

2021
pub fn get_template<G: GenericNode>() -> Template<G> {
21-
Template::new("about").template(|_| {
22-
template! {
23-
AboutPage()
24-
}
25-
})
22+
Template::new("about").template(about_page)
2623
}

examples/i18n/src/templates/index.rs

+2-5
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
use perseus::{link, t, Template};
22
use sycamore::prelude::{component, template, GenericNode, Template as SycamoreTemplate};
33

4+
#[perseus::template(IndexPage)]
45
#[component(IndexPage<G>)]
56
pub fn index_page() -> SycamoreTemplate<G> {
67
let username = "User";
@@ -13,9 +14,5 @@ pub fn index_page() -> SycamoreTemplate<G> {
1314
}
1415

1516
pub fn get_template<G: GenericNode>() -> Template<G> {
16-
Template::new("index").template(|_| {
17-
template! {
18-
IndexPage()
19-
}
20-
})
17+
Template::new("index").template(index_page)
2118
}

examples/i18n/src/templates/post.rs

+2-7
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,7 @@ pub struct PostPageProps {
88
content: String,
99
}
1010

11+
#[perseus::template(PostPage)]
1112
#[component(PostPage<G>)]
1213
pub fn post_page(props: PostPageProps) -> SycamoreTemplate<G> {
1314
let title = props.title;
@@ -29,13 +30,7 @@ pub fn get_template<G: GenericNode>() -> Template<G> {
2930
Template::new("post")
3031
.build_paths_fn(get_static_paths)
3132
.build_state_fn(get_static_props)
32-
.template(|props| {
33-
template! {
34-
PostPage(
35-
serde_json::from_str::<PostPageProps>(&props.unwrap()).unwrap()
36-
)
37-
}
38-
})
33+
.template(post_page)
3934
}
4035

4136
pub async fn get_static_props(path: String, _locale: String) -> RenderFnResultWithCause<String> {

examples/plugins/src/templates/about.rs

+6-11
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@ use perseus::Template;
22
use sycamore::prelude::{component, template, GenericNode, Template as SycamoreTemplate};
33

44
// This page will actually be replaced entirely by a plugin!
5+
#[perseus::template(AboutPage)]
56
#[component(AboutPage<G>)]
67
pub fn about_page() -> SycamoreTemplate<G> {
78
template! {
@@ -10,15 +11,9 @@ pub fn about_page() -> SycamoreTemplate<G> {
1011
}
1112

1213
pub fn get_template<G: GenericNode>() -> Template<G> {
13-
Template::new("about")
14-
.template(|_| {
15-
template! {
16-
AboutPage()
17-
}
18-
})
19-
.head(|_| {
20-
template! {
21-
title { "About Page | Perseus Example – Plugins" }
22-
}
23-
})
14+
Template::new("about").template(about_page).head(|_| {
15+
template! {
16+
title { "About Page | Perseus Example – Plugins" }
17+
}
18+
})
2419
}
+6-11
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
use perseus::{GenericNode, Template};
22
use sycamore::prelude::{component, template, Template as SycamoreTemplate};
33

4+
#[perseus::template(IndexPage)]
45
#[component(IndexPage<G>)]
56
pub fn index_page() -> SycamoreTemplate<G> {
67
template! {
@@ -10,15 +11,9 @@ pub fn index_page() -> SycamoreTemplate<G> {
1011
}
1112

1213
pub fn get_template<G: GenericNode>() -> Template<G> {
13-
Template::new("index")
14-
.template(|_| {
15-
template! {
16-
IndexPage()
17-
}
18-
})
19-
.head(|_| {
20-
template! {
21-
title { "Index Page | Perseus Example – Plugins" }
22-
}
23-
})
14+
Template::new("index").template(index_page).head(|_| {
15+
template! {
16+
title { "Index Page | Perseus Example – Plugins" }
17+
}
18+
})
2419
}
+2-5
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
use perseus::Template;
22
use sycamore::prelude::{component, template, GenericNode, Template as SycamoreTemplate};
33

4+
#[perseus::template(AboutPage)]
45
#[component(AboutPage<G>)]
56
pub fn about_page() -> SycamoreTemplate<G> {
67
template! {
@@ -9,9 +10,5 @@ pub fn about_page() -> SycamoreTemplate<G> {
910
}
1011

1112
pub fn get_template<G: GenericNode>() -> Template<G> {
12-
Template::new("about").template(|_| {
13-
template! {
14-
AboutPage()
15-
}
16-
})
13+
Template::new("about").template(about_page)
1714
}

examples/showcase/src/templates/amalgamation.rs

+2-7
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,7 @@ pub struct AmalagamationPageProps {
77
pub message: String,
88
}
99

10+
#[perseus::template(AmalgamationPage)]
1011
#[component(AmalgamationPage<G>)]
1112
pub fn amalgamation_page(props: AmalagamationPageProps) -> SycamoreTemplate<G> {
1213
template! {
@@ -19,13 +20,7 @@ pub fn get_template<G: GenericNode>() -> Template<G> {
1920
.build_state_fn(get_build_state)
2021
.request_state_fn(get_request_state)
2122
.amalgamate_states_fn(amalgamate_states)
22-
.template(|props| {
23-
template! {
24-
AmalgamationPage(
25-
serde_json::from_str::<AmalagamationPageProps>(&props.unwrap()).unwrap()
26-
)
27-
}
28-
})
23+
.template(amalgamation_page)
2924
}
3025

3126
pub fn amalgamate_states(states: States) -> RenderFnResultWithCause<Option<String>> {

examples/showcase/src/templates/index.rs

+2-7
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,7 @@ pub struct IndexPageProps {
77
pub greeting: String,
88
}
99

10+
#[perseus::template(IndexPage)]
1011
#[component(IndexPage<G>)]
1112
pub fn index_page(props: IndexPageProps) -> SycamoreTemplate<G> {
1213
template! {
@@ -17,13 +18,7 @@ pub fn index_page(props: IndexPageProps) -> SycamoreTemplate<G> {
1718
pub fn get_template<G: GenericNode>() -> Template<G> {
1819
Template::new("index")
1920
.build_state_fn(get_static_props)
20-
.template(|props| {
21-
template! {
22-
IndexPage(
23-
serde_json::from_str::<IndexPageProps>(&props.unwrap()).unwrap()
24-
)
25-
}
26-
})
21+
.template(index_page)
2722
}
2823

2924
pub async fn get_static_props(_path: String, _locale: String) -> RenderFnResultWithCause<String> {

examples/showcase/src/templates/ip.rs

+3-8
Original file line numberDiff line numberDiff line change
@@ -7,8 +7,9 @@ pub struct IpPageProps {
77
ip: String,
88
}
99

10+
#[perseus::template(IpPage)]
1011
#[component(IpPage<G>)]
11-
pub fn dashboard_page(props: IpPageProps) -> SycamoreTemplate<G> {
12+
pub fn ip_page(props: IpPageProps) -> SycamoreTemplate<G> {
1213
template! {
1314
p {
1415
(
@@ -21,13 +22,7 @@ pub fn dashboard_page(props: IpPageProps) -> SycamoreTemplate<G> {
2122
pub fn get_template<G: GenericNode>() -> Template<G> {
2223
Template::new("ip")
2324
.request_state_fn(get_request_state)
24-
.template(|props| {
25-
template! {
26-
IpPage(
27-
serde_json::from_str::<IpPageProps>(&props.unwrap()).unwrap()
28-
)
29-
}
30-
})
25+
.template(ip_page)
3126
}
3227

3328
pub async fn get_request_state(
+2-5
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
use perseus::Template;
22
use sycamore::prelude::{component, template, GenericNode, Template as SycamoreTemplate};
33

4+
#[perseus::template(NewPostPage)]
45
#[component(NewPostPage<G>)]
56
pub fn new_post_page() -> SycamoreTemplate<G> {
67
template! {
@@ -9,9 +10,5 @@ pub fn new_post_page() -> SycamoreTemplate<G> {
910
}
1011

1112
pub fn get_template<G: GenericNode>() -> Template<G> {
12-
Template::new("post/new").template(|_| {
13-
template! {
14-
NewPostPage()
15-
}
16-
})
13+
Template::new("post/new").template(new_post_page)
1714
}

examples/showcase/src/templates/post.rs

+2-7
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,7 @@ pub struct PostPageProps {
1010
content: String,
1111
}
1212

13+
#[perseus::template(PostPage)]
1314
#[component(PostPage<G>)]
1415
pub fn post_page(props: PostPageProps) -> SycamoreTemplate<G> {
1516
let title = props.title;
@@ -29,13 +30,7 @@ pub fn get_template<G: GenericNode>() -> Template<G> {
2930
.build_paths_fn(get_static_paths)
3031
.build_state_fn(get_static_props)
3132
.incremental_generation()
32-
.template(|props| {
33-
template! {
34-
PostPage(
35-
serde_json::from_str::<PostPageProps>(&props.unwrap()).unwrap()
36-
)
37-
}
38-
})
33+
.template(post_page)
3934
}
4035

4136
pub async fn get_static_props(path: String, _locale: String) -> RenderFnResultWithCause<String> {

examples/showcase/src/templates/time.rs

+2-7
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,7 @@ pub struct TimePageProps {
99
pub time: String,
1010
}
1111

12+
#[perseus::template(TimePage)]
1213
#[component(TimePage<G>)]
1314
pub fn time_page(props: TimePageProps) -> SycamoreTemplate<G> {
1415
template! {
@@ -18,13 +19,7 @@ pub fn time_page(props: TimePageProps) -> SycamoreTemplate<G> {
1819

1920
pub fn get_template<G: GenericNode>() -> Template<G> {
2021
Template::new("timeisr")
21-
.template(|props| {
22-
template! {
23-
TimePage(
24-
serde_json::from_str::<TimePageProps>(&props.unwrap()).unwrap()
25-
)
26-
}
27-
})
22+
.template(time_page)
2823
// This page will revalidate every five seconds (to illustrate revalidation)
2924
.revalidate_after("5s".to_string())
3025
.incremental_generation()

examples/showcase/src/templates/time_root.rs

+2-7
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,7 @@ pub struct TimePageProps {
77
pub time: String,
88
}
99

10+
#[perseus::template(TimePage)]
1011
#[component(TimePage<G>)]
1112
pub fn time_page(props: TimePageProps) -> SycamoreTemplate<G> {
1213
template! {
@@ -16,13 +17,7 @@ pub fn time_page(props: TimePageProps) -> SycamoreTemplate<G> {
1617

1718
pub fn get_template<G: GenericNode>() -> Template<G> {
1819
Template::new("time")
19-
.template(|props| {
20-
template! {
21-
TimePage(
22-
serde_json::from_str::<TimePageProps>(&props.unwrap()).unwrap()
23-
)
24-
}
25-
})
20+
.template(time_page)
2621
// This page will revalidate every five seconds (to illustrate revalidation)
2722
// Try changing this to a week, even though the below custom logic says to always revalidate, we'll only do it weekly
2823
.revalidate_after("5s".to_string())

0 commit comments

Comments
 (0)