Skip to content

Commit 18bd1bf

Browse files
committed
fix: made build paths possible on index page
I think there's one issue left here...
1 parent a329952 commit 18bd1bf

File tree

6 files changed

+54
-25
lines changed

6 files changed

+54
-25
lines changed

examples/core/basic/src/templates/index.rs

+6
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,7 @@ pub fn get_template<G: Html>() -> Template<G> {
1919
.build_state_fn(get_build_state)
2020
.template(index_page)
2121
.head(head)
22+
.build_paths_fn(build_paths)
2223
}
2324

2425
#[perseus::head]
@@ -37,3 +38,8 @@ pub async fn get_build_state(
3738
greeting: "Hello World!".to_string(),
3839
})
3940
}
41+
42+
#[perseus::build_paths]
43+
async fn build_paths() -> perseus::prelude::RenderFnResult<Vec<String>> {
44+
Ok(vec!["".to_string(), "a test".to_string()])
45+
}

packages/perseus/src/build.rs

+17-2
Original file line numberDiff line numberDiff line change
@@ -96,14 +96,25 @@ async fn gen_state_for_path(
9696
// save it as a file
9797
let full_path_without_locale = match template.uses_build_paths() {
9898
true => format!("{}/{}", &template_path, path),
99+
// // If we're using build paths on the root template, make sure we don't end up with `index/...`
100+
// true => if template_path == "index" {
101+
// path.to_string()
102+
// } else {
103+
// format!("{}/{}", &template_path, path)
104+
// },
99105
// We don't want to concatenate the name twice if we don't have to
100106
false => template_path.clone(),
101107
};
102-
// Strip trailing `/`s for the reasons described above
108+
// Strip leading/trailing `/`s for the reasons described above
109+
// Leading is to handle index pages with build paths
103110
let full_path_without_locale = match full_path_without_locale.strip_suffix('/') {
104111
Some(stripped) => stripped.to_string(),
105112
None => full_path_without_locale,
106113
};
114+
let full_path_without_locale = match full_path_without_locale.strip_prefix('/') {
115+
Some(stripped) => stripped.to_string(),
116+
None => full_path_without_locale,
117+
};
107118
// Add the current locale to the front of that and encode it as a URL so we can
108119
// store a flat series of files BUG: insanely nested paths won't work
109120
// whatsoever if the filename is too long, maybe hash instead?
@@ -287,11 +298,15 @@ pub async fn build_template_and_get_cfg(
287298
// Add each page that the template explicitly generated (ignoring ISR for now)
288299
for page in pages {
289300
let path = format!("{}/{}", &template_root_path, &page);
290-
// Remove any trailing `/`s for the reasons described above
301+
// Remove any leading/trailing `/`s for the reasons described above
291302
let path = match path.strip_suffix('/') {
292303
Some(stripped) => stripped.to_string(),
293304
None => path,
294305
};
306+
let path = match path.strip_prefix('/') {
307+
Some(stripped) => stripped.to_string(),
308+
None => path,
309+
};
295310
render_cfg.insert(path, template_root_path.clone());
296311
}
297312
// Now if the page uses ISR, add an explicit `/*` in there after the template

packages/perseus/src/router/get_subsequent_view.rs

+8-7
Original file line numberDiff line numberDiff line change
@@ -80,13 +80,14 @@ pub(crate) async fn get_subsequent_view(
8080
// We only have one part of the puzzle (or nothing at all), and no guarantee that the other
8181
// doesn't exist, so we'll have to check with the server to be safe
8282
PssContains::State | PssContains::Head | PssContains::None => {
83-
// If we're getting data about the index page, explicitly set it to that
84-
// This can be handled by the Perseus server (and is), but not by static
85-
// exporting
86-
let path_norm = match path.is_empty() {
87-
true => "index".to_string(),
88-
false => path.to_string(),
89-
};
83+
// // If we're getting data about the index page, explicitly set it to that
84+
// // This can be handled by the Perseus server (and is), but not by static
85+
// // exporting
86+
// let path_norm = match path.is_empty() {
87+
// true => "index".to_string(),
88+
// false => path.to_string(),
89+
// };
90+
let path_norm = path.to_string();
9091
// Get the static page data (head and state)
9192
let asset_url = format!(
9293
"{}/.perseus/page/{}/{}.json?template_name={}&was_incremental_match={}",

packages/perseus/src/router/match_route.rs

+11-11
Original file line numberDiff line numberDiff line change
@@ -9,22 +9,22 @@ use std::rc::Rc;
99
/// `Arc` and `Rc` versions.
1010
macro_rules! get_template_for_path {
1111
($raw_path:expr, $render_cfg:expr, $templates:expr) => {{
12-
let mut path = $raw_path;
13-
// If the path is empty, we're looking for the special `index` page
14-
if path.is_empty() {
15-
path = "index";
16-
}
12+
let path = $raw_path;
13+
// // If the path is empty, we're looking for the special `index` page
14+
// if path.is_empty() {
15+
// path = "index";
16+
// }
1717

1818
let mut was_incremental_match = false;
1919
// Match the path to one of the templates
20-
let mut template_name = String::new();
20+
let mut template_name = None;
2121
// We'll try a direct match first
2222
if let Some(template_root_path) = $render_cfg.get(path) {
23-
template_name = template_root_path.to_string();
23+
template_name = Some(template_root_path.to_string());
2424
}
2525
// Next, an ISR match (more complex), which we only want to run if we didn't get
2626
// an exact match above
27-
if template_name.is_empty() {
27+
if template_name.is_none() {
2828
// We progressively look for more and more specificity of the path, adding each
2929
// segment That way, we're searching forwards rather than backwards,
3030
// which is more efficient
@@ -36,20 +36,20 @@ macro_rules! get_template_for_path {
3636
// If we find something, keep going until we don't (maximize specificity)
3737
if let Some(template_root_path) = $render_cfg.get(&path_to_try) {
3838
was_incremental_match = true;
39-
template_name = template_root_path.to_string();
39+
template_name = Some(template_root_path.to_string());
4040
} else {
4141
break;
4242
}
4343
}
4444
}
4545
// If we still have nothing, then the page doesn't exist
46-
if template_name.is_empty() {
46+
if template_name.is_none() {
4747
return (None, was_incremental_match);
4848
}
4949

5050
// Return the necessary info for the caller to get the template in a form it
5151
// wants (might be an `Rc` of a reference)
52-
(template_name, was_incremental_match)
52+
(template_name.unwrap(), was_incremental_match)
5353
}};
5454
}
5555

packages/perseus/src/state/page_state_store.rs

+5-4
Original file line numberDiff line numberDiff line change
@@ -260,10 +260,11 @@ impl PageStateStore {
260260
// If we're getting data about the index page, explicitly set it to that
261261
// This can be handled by the Perseus server (and is), but not by static
262262
// exporting
263-
let path_norm = match path.is_empty() {
264-
true => "index".to_string(),
265-
false => path.to_string(),
266-
};
263+
// let path_norm = match path.is_empty() {
264+
// true => "index".to_string(),
265+
// false => path.to_string(),
266+
// };
267+
let path_norm = path.to_string();
267268
// Get the static page data (head and state)
268269
let asset_url = format!(
269270
"{}/.perseus/page/{}/{}.json?template_name={}&was_incremental_match={}",

packages/perseus/src/template/core.rs

+7-1
Original file line numberDiff line numberDiff line change
@@ -470,8 +470,14 @@ impl<G: Html> Template<G> {
470470
/// Gets the path of the template. This is the root path under which any
471471
/// generated pages will be served. In the simplest case, there will
472472
/// only be one page rendered, and it will occupy that root position.
473+
///
474+
/// Note that this will automatically transform `index` to an empty string.
473475
pub fn get_path(&self) -> String {
474-
self.path.clone()
476+
if self.path == "index" {
477+
String::new()
478+
} else {
479+
self.path.clone()
480+
}
475481
}
476482
/// Gets the interval after which the template will next revalidate.
477483
#[cfg(not(target_arch = "wasm32"))]

0 commit comments

Comments
 (0)