diff --git a/examples/.base/src/main.rs b/examples/.base/src/main.rs index 8718528ae7..87ed16df4a 100644 --- a/examples/.base/src/main.rs +++ b/examples/.base/src/main.rs @@ -6,6 +6,6 @@ use perseus::{Html, PerseusApp}; #[perseus::main(perseus_warp::dflt_server)] pub fn main() -> PerseusApp { PerseusApp::new() - .template(crate::templates::index::get_template) - .error_pages(crate::error_pages::get_error_pages) + .template(crate::templates::index::get_template()) + .error_pages(crate::error_pages::get_error_pages()) } diff --git a/examples/core/basic/src/main.rs b/examples/core/basic/src/main.rs index eee8b18aa3..02fdf9edfb 100644 --- a/examples/core/basic/src/main.rs +++ b/examples/core/basic/src/main.rs @@ -6,7 +6,7 @@ use perseus::{Html, PerseusApp}; #[perseus::main(perseus_warp::dflt_server)] pub fn main() -> PerseusApp { PerseusApp::new() - .template(crate::templates::index::get_template) - .template(crate::templates::about::get_template) - .error_pages(crate::error_pages::get_error_pages) + .template(crate::templates::index::get_template()) + .template(crate::templates::about::get_template()) + .error_pages(crate::error_pages::get_error_pages()) } diff --git a/examples/core/custom_server/src/main.rs b/examples/core/custom_server/src/main.rs index 8ad099b199..9f3143d522 100644 --- a/examples/core/custom_server/src/main.rs +++ b/examples/core/custom_server/src/main.rs @@ -55,7 +55,7 @@ pub async fn dflt_server< #[perseus::main(dflt_server)] pub fn main() -> PerseusApp { PerseusApp::new() - .template(crate::templates::index::get_template) - .template(crate::templates::about::get_template) - .error_pages(crate::error_pages::get_error_pages) + .template(crate::templates::index::get_template()) + .template(crate::templates::about::get_template()) + .error_pages(crate::error_pages::get_error_pages()) } diff --git a/examples/core/freezing_and_thawing/src/main.rs b/examples/core/freezing_and_thawing/src/main.rs index fe6874d611..f4b5c158f5 100644 --- a/examples/core/freezing_and_thawing/src/main.rs +++ b/examples/core/freezing_and_thawing/src/main.rs @@ -7,8 +7,8 @@ use perseus::{Html, PerseusApp}; #[perseus::main(perseus_warp::dflt_server)] pub fn main() -> PerseusApp { PerseusApp::new() - .template(crate::templates::index::get_template) - .template(crate::templates::about::get_template) - .error_pages(crate::error_pages::get_error_pages) + .template(crate::templates::index::get_template()) + .template(crate::templates::about::get_template()) + .error_pages(crate::error_pages::get_error_pages()) .global_state_creator(crate::global_state::get_global_state_creator()) } diff --git a/examples/core/global_state/src/main.rs b/examples/core/global_state/src/main.rs index fe6874d611..f4b5c158f5 100644 --- a/examples/core/global_state/src/main.rs +++ b/examples/core/global_state/src/main.rs @@ -7,8 +7,8 @@ use perseus::{Html, PerseusApp}; #[perseus::main(perseus_warp::dflt_server)] pub fn main() -> PerseusApp { PerseusApp::new() - .template(crate::templates::index::get_template) - .template(crate::templates::about::get_template) - .error_pages(crate::error_pages::get_error_pages) + .template(crate::templates::index::get_template()) + .template(crate::templates::about::get_template()) + .error_pages(crate::error_pages::get_error_pages()) .global_state_creator(crate::global_state::get_global_state_creator()) } diff --git a/examples/core/helper_build_state/src/main.rs b/examples/core/helper_build_state/src/main.rs index 8718528ae7..87ed16df4a 100644 --- a/examples/core/helper_build_state/src/main.rs +++ b/examples/core/helper_build_state/src/main.rs @@ -6,6 +6,6 @@ use perseus::{Html, PerseusApp}; #[perseus::main(perseus_warp::dflt_server)] pub fn main() -> PerseusApp { PerseusApp::new() - .template(crate::templates::index::get_template) - .error_pages(crate::error_pages::get_error_pages) + .template(crate::templates::index::get_template()) + .error_pages(crate::error_pages::get_error_pages()) } diff --git a/examples/core/i18n/src/main.rs b/examples/core/i18n/src/main.rs index bcd84fe050..d3d10c9fea 100644 --- a/examples/core/i18n/src/main.rs +++ b/examples/core/i18n/src/main.rs @@ -6,9 +6,9 @@ use perseus::{Html, PerseusApp}; #[perseus::main(perseus_warp::dflt_server)] pub fn main() -> PerseusApp { PerseusApp::new() - .template(crate::templates::index::get_template) - .template(crate::templates::about::get_template) - .template(crate::templates::post::get_template) - .error_pages(crate::error_pages::get_error_pages) + .template(crate::templates::index::get_template()) + .template(crate::templates::about::get_template()) + .template(crate::templates::post::get_template()) + .error_pages(crate::error_pages::get_error_pages()) .locales_and_translations_manager("en-US", &["fr-FR", "es-ES"]) } diff --git a/examples/core/idb_freezing/src/main.rs b/examples/core/idb_freezing/src/main.rs index fe6874d611..f4b5c158f5 100644 --- a/examples/core/idb_freezing/src/main.rs +++ b/examples/core/idb_freezing/src/main.rs @@ -7,8 +7,8 @@ use perseus::{Html, PerseusApp}; #[perseus::main(perseus_warp::dflt_server)] pub fn main() -> PerseusApp { PerseusApp::new() - .template(crate::templates::index::get_template) - .template(crate::templates::about::get_template) - .error_pages(crate::error_pages::get_error_pages) + .template(crate::templates::index::get_template()) + .template(crate::templates::about::get_template()) + .error_pages(crate::error_pages::get_error_pages()) .global_state_creator(crate::global_state::get_global_state_creator()) } diff --git a/examples/core/index_view/src/main.rs b/examples/core/index_view/src/main.rs index 21983b65a0..6410e6086f 100644 --- a/examples/core/index_view/src/main.rs +++ b/examples/core/index_view/src/main.rs @@ -6,9 +6,9 @@ use perseus::{Html, PerseusApp, PerseusRoot}; #[perseus::main(perseus_warp::dflt_server)] pub fn main() -> PerseusApp { PerseusApp::new() - .template(crate::templates::index::get_template) - .template(crate::templates::about::get_template) - .error_pages(crate::error_pages::get_error_pages) + .template(crate::templates::index::get_template()) + .template(crate::templates::about::get_template()) + .error_pages(crate::error_pages::get_error_pages()) .index_view(|cx| { sycamore::view! { cx, // We don't need a ``, that's added automatically by Perseus (though that can be overridden if you really want by using `.index_view_str()`) diff --git a/examples/core/js_interop/src/main.rs b/examples/core/js_interop/src/main.rs index 8718528ae7..87ed16df4a 100644 --- a/examples/core/js_interop/src/main.rs +++ b/examples/core/js_interop/src/main.rs @@ -6,6 +6,6 @@ use perseus::{Html, PerseusApp}; #[perseus::main(perseus_warp::dflt_server)] pub fn main() -> PerseusApp { PerseusApp::new() - .template(crate::templates::index::get_template) - .error_pages(crate::error_pages::get_error_pages) + .template(crate::templates::index::get_template()) + .error_pages(crate::error_pages::get_error_pages()) } diff --git a/examples/core/plugins/src/main.rs b/examples/core/plugins/src/main.rs index 006c26c0ef..66e6868f04 100644 --- a/examples/core/plugins/src/main.rs +++ b/examples/core/plugins/src/main.rs @@ -7,9 +7,9 @@ use perseus::{plugins::Plugins, Html, PerseusApp}; #[perseus::main(perseus_warp::dflt_server)] pub fn main() -> PerseusApp { PerseusApp::new() - .template(crate::templates::index::get_template) - .template(crate::templates::about::get_template) - .error_pages(crate::error_pages::get_error_pages) + .template(crate::templates::index::get_template()) + .template(crate::templates::about::get_template()) + .error_pages(crate::error_pages::get_error_pages()) .plugins(Plugins::new().plugin_with_client_privilege( plugin::get_test_plugin, plugin::TestPluginData { diff --git a/examples/core/preload/src/main.rs b/examples/core/preload/src/main.rs index eee8b18aa3..02fdf9edfb 100644 --- a/examples/core/preload/src/main.rs +++ b/examples/core/preload/src/main.rs @@ -6,7 +6,7 @@ use perseus::{Html, PerseusApp}; #[perseus::main(perseus_warp::dflt_server)] pub fn main() -> PerseusApp { PerseusApp::new() - .template(crate::templates::index::get_template) - .template(crate::templates::about::get_template) - .error_pages(crate::error_pages::get_error_pages) + .template(crate::templates::index::get_template()) + .template(crate::templates::about::get_template()) + .error_pages(crate::error_pages::get_error_pages()) } diff --git a/examples/core/router_state/src/main.rs b/examples/core/router_state/src/main.rs index eee8b18aa3..02fdf9edfb 100644 --- a/examples/core/router_state/src/main.rs +++ b/examples/core/router_state/src/main.rs @@ -6,7 +6,7 @@ use perseus::{Html, PerseusApp}; #[perseus::main(perseus_warp::dflt_server)] pub fn main() -> PerseusApp { PerseusApp::new() - .template(crate::templates::index::get_template) - .template(crate::templates::about::get_template) - .error_pages(crate::error_pages::get_error_pages) + .template(crate::templates::index::get_template()) + .template(crate::templates::about::get_template()) + .error_pages(crate::error_pages::get_error_pages()) } diff --git a/examples/core/rx_state/src/main.rs b/examples/core/rx_state/src/main.rs index eee8b18aa3..02fdf9edfb 100644 --- a/examples/core/rx_state/src/main.rs +++ b/examples/core/rx_state/src/main.rs @@ -6,7 +6,7 @@ use perseus::{Html, PerseusApp}; #[perseus::main(perseus_warp::dflt_server)] pub fn main() -> PerseusApp { PerseusApp::new() - .template(crate::templates::index::get_template) - .template(crate::templates::about::get_template) - .error_pages(crate::error_pages::get_error_pages) + .template(crate::templates::index::get_template()) + .template(crate::templates::about::get_template()) + .error_pages(crate::error_pages::get_error_pages()) } diff --git a/examples/core/set_headers/src/main.rs b/examples/core/set_headers/src/main.rs index 8718528ae7..87ed16df4a 100644 --- a/examples/core/set_headers/src/main.rs +++ b/examples/core/set_headers/src/main.rs @@ -6,6 +6,6 @@ use perseus::{Html, PerseusApp}; #[perseus::main(perseus_warp::dflt_server)] pub fn main() -> PerseusApp { PerseusApp::new() - .template(crate::templates::index::get_template) - .error_pages(crate::error_pages::get_error_pages) + .template(crate::templates::index::get_template()) + .error_pages(crate::error_pages::get_error_pages()) } diff --git a/examples/core/state_generation/src/main.rs b/examples/core/state_generation/src/main.rs index 4c5613ed58..92ccd202d5 100644 --- a/examples/core/state_generation/src/main.rs +++ b/examples/core/state_generation/src/main.rs @@ -6,12 +6,12 @@ use perseus::{Html, PerseusApp}; #[perseus::main(perseus_warp::dflt_server)] pub fn main() -> PerseusApp { PerseusApp::new() - .template(crate::templates::build_state::get_template) - .template(crate::templates::build_paths::get_template) - .template(crate::templates::request_state::get_template) - .template(crate::templates::incremental_generation::get_template) - .template(crate::templates::revalidation::get_template) - .template(crate::templates::revalidation_and_incremental_generation::get_template) - .template(crate::templates::amalgamation::get_template) - .error_pages(crate::error_pages::get_error_pages) + .template(crate::templates::build_state::get_template()) + .template(crate::templates::build_paths::get_template()) + .template(crate::templates::request_state::get_template()) + .template(crate::templates::incremental_generation::get_template()) + .template(crate::templates::revalidation::get_template()) + .template(crate::templates::revalidation_and_incremental_generation::get_template()) + .template(crate::templates::amalgamation::get_template()) + .error_pages(crate::error_pages::get_error_pages()) } diff --git a/examples/core/static_content/src/main.rs b/examples/core/static_content/src/main.rs index c4eac85941..c83b9bbebf 100644 --- a/examples/core/static_content/src/main.rs +++ b/examples/core/static_content/src/main.rs @@ -6,7 +6,7 @@ use perseus::{Html, PerseusApp}; #[perseus::main(perseus_warp::dflt_server)] pub fn main() -> PerseusApp { PerseusApp::new() - .template(crate::templates::index::get_template) - .error_pages(crate::error_pages::get_error_pages) + .template(crate::templates::index::get_template()) + .error_pages(crate::error_pages::get_error_pages()) .static_alias("/test.txt", "test.txt") } diff --git a/examples/core/unreactive/src/main.rs b/examples/core/unreactive/src/main.rs index eee8b18aa3..02fdf9edfb 100644 --- a/examples/core/unreactive/src/main.rs +++ b/examples/core/unreactive/src/main.rs @@ -6,7 +6,7 @@ use perseus::{Html, PerseusApp}; #[perseus::main(perseus_warp::dflt_server)] pub fn main() -> PerseusApp { PerseusApp::new() - .template(crate::templates::index::get_template) - .template(crate::templates::about::get_template) - .error_pages(crate::error_pages::get_error_pages) + .template(crate::templates::index::get_template()) + .template(crate::templates::about::get_template()) + .error_pages(crate::error_pages::get_error_pages()) } diff --git a/examples/demos/auth/src/main.rs b/examples/demos/auth/src/main.rs index fe6874d611..f4b5c158f5 100644 --- a/examples/demos/auth/src/main.rs +++ b/examples/demos/auth/src/main.rs @@ -7,8 +7,8 @@ use perseus::{Html, PerseusApp}; #[perseus::main(perseus_warp::dflt_server)] pub fn main() -> PerseusApp { PerseusApp::new() - .template(crate::templates::index::get_template) - .template(crate::templates::about::get_template) - .error_pages(crate::error_pages::get_error_pages) + .template(crate::templates::index::get_template()) + .template(crate::templates::about::get_template()) + .error_pages(crate::error_pages::get_error_pages()) .global_state_creator(crate::global_state::get_global_state_creator()) } diff --git a/examples/demos/fetching/src/main.rs b/examples/demos/fetching/src/main.rs index 8718528ae7..87ed16df4a 100644 --- a/examples/demos/fetching/src/main.rs +++ b/examples/demos/fetching/src/main.rs @@ -6,6 +6,6 @@ use perseus::{Html, PerseusApp}; #[perseus::main(perseus_warp::dflt_server)] pub fn main() -> PerseusApp { PerseusApp::new() - .template(crate::templates::index::get_template) - .error_pages(crate::error_pages::get_error_pages) + .template(crate::templates::index::get_template()) + .error_pages(crate::error_pages::get_error_pages()) } diff --git a/examples/demos/full_page_layout/src/main.rs b/examples/demos/full_page_layout/src/main.rs index 1107d07352..894587b724 100644 --- a/examples/demos/full_page_layout/src/main.rs +++ b/examples/demos/full_page_layout/src/main.rs @@ -8,9 +8,9 @@ use sycamore::prelude::view; #[perseus::main(perseus_warp::dflt_server)] pub fn main() -> PerseusApp { PerseusApp::new() - .template(crate::templates::index::get_template) - .template(crate::templates::long::get_template) - .error_pages(crate::error_pages::get_error_pages) + .template(crate::templates::index::get_template()) + .template(crate::templates::long::get_template()) + .error_pages(crate::error_pages::get_error_pages()) .index_view(|cx| { view! { cx, html { diff --git a/examples/website/app_in_a_file/src/main.rs b/examples/website/app_in_a_file/src/main.rs index 6823ac7be4..b24849c7b7 100644 --- a/examples/website/app_in_a_file/src/main.rs +++ b/examples/website/app_in_a_file/src/main.rs @@ -8,12 +8,12 @@ use sycamore::prelude::*; pub fn main() -> PerseusApp { PerseusApp::new() // Create a new template at `index`, which maps to our landing page - .template(|| { + .template( Template::new("index") .template_with_state(index_page) - .build_state_fn(get_index_build_state) - }) - .template(|| Template::new("about").template(about_page)) + .build_state_fn(get_index_build_state), + ) + .template(Template::new("about").template(about_page)) } // EXCERPT_START diff --git a/examples/website/i18n/src/main.rs b/examples/website/i18n/src/main.rs index fddca95c49..0f737fe0d2 100644 --- a/examples/website/i18n/src/main.rs +++ b/examples/website/i18n/src/main.rs @@ -4,7 +4,7 @@ use sycamore::prelude::*; #[perseus::main(perseus_warp::dflt_server)] pub fn main() -> PerseusApp { PerseusApp::new() - .template(|| Template::new("index").template(index_page)) + .template(Template::new("index").template(index_page)) // EXCERPT_START .locales_and_translations_manager( "en-US", // Default locale diff --git a/examples/website/state_generation/src/main.rs b/examples/website/state_generation/src/main.rs index 50a82af2c7..f8abca50bf 100644 --- a/examples/website/state_generation/src/main.rs +++ b/examples/website/state_generation/src/main.rs @@ -5,7 +5,7 @@ use sycamore::prelude::*; #[perseus::main(perseus_warp::dflt_server)] pub fn main() -> PerseusApp { - PerseusApp::new().template(|| { + PerseusApp::new().template( Template::new("post") .template_with_state(post_page) .build_paths_fn(get_build_paths) @@ -15,8 +15,8 @@ pub fn main() -> PerseusApp { // If the user requests a page we haven't created yet, still // pass it to `get_build_state()` and cache the output for // future users (lazy page building) - .incremental_generation() - }) + .incremental_generation(), + ) } // EXCERPT_START diff --git a/packages/perseus-cli/src/init.rs b/packages/perseus-cli/src/init.rs index 57027116d9..4426117a21 100644 --- a/packages/perseus-cli/src/init.rs +++ b/packages/perseus-cli/src/init.rs @@ -149,14 +149,13 @@ use perseus::{Html, PerseusApp}; #[perseus::main(perseus_warp::dflt_server)] pub fn main() -> PerseusApp { PerseusApp::new() - .template(crate::templates::index::get_template) + .template(crate::templates::index::get_template()) }"#; static DFLT_INIT_MOD_RS: &str = r#"pub mod index;"#; -static DFLT_INIT_INDEX_RS: &str = r#"use perseus::Template; -use sycamore::prelude::{view, Html, Scope, SsrNode, View}; +static DFLT_INIT_INDEX_RS: &str = r#"use perseus::prelude::*; +use sycamore::prelude::*; -#[perseus::template] -pub fn index_page(cx: Scope) -> View { +fn index_page(cx: Scope) -> View { view! { cx, // Don't worry, there are much better ways of styling in Perseus! div(style = "display: flex; flex-direction: column; justify-content: center; align-items: center; height: 95vh;") { @@ -170,8 +169,8 @@ pub fn index_page(cx: Scope) -> View { } } -#[perseus::head] -pub fn head(cx: Scope) -> View { +#[engine_only_fn] +fn head(cx: Scope) -> View { view! { cx, title { "Welcome to Perseus!" } } diff --git a/packages/perseus/src/build.rs b/packages/perseus/src/build.rs index 64c3720b67..c00758f614 100644 --- a/packages/perseus/src/build.rs +++ b/packages/perseus/src/build.rs @@ -3,7 +3,7 @@ use crate::errors::*; use crate::i18n::{Locales, TranslationsManager}; use crate::stores::{ImmutableStore, MutableStore}; -use crate::template::TemplateMap; +use crate::template::ArcTemplateMap; use crate::template::{BuildPaths, StateGeneratorInfo, Template, TemplateState}; use crate::translator::Translator; use crate::utils::minify; @@ -337,7 +337,7 @@ pub async fn build_template_and_get_cfg( /// for this. You should only build the most commonly used locales here (the /// rest should be built on demand). pub async fn build_templates_for_locale( - templates: &TemplateMap, + templates: &ArcTemplateMap, translator: &Translator, (immutable_store, mutable_store): (&ImmutableStore, &impl MutableStore), global_state: &TemplateState, @@ -374,7 +374,7 @@ pub async fn build_templates_for_locale( /// Gets a translator and builds templates for a single locale. pub async fn build_templates_and_translator_for_locale( - templates: &TemplateMap, + templates: &ArcTemplateMap, locale: String, (immutable_store, mutable_store): (&ImmutableStore, &impl MutableStore), translations_manager: &impl TranslationsManager, @@ -400,7 +400,7 @@ pub async fn build_templates_and_translator_for_locale( #[derive(Debug)] pub struct BuildProps<'a, M: MutableStore, T: TranslationsManager> { /// All the templates in the app. - pub templates: &'a TemplateMap, + pub templates: &'a ArcTemplateMap, /// The app's locales data. pub locales: &'a Locales, /// An immutable store. diff --git a/packages/perseus/src/engine/build.rs b/packages/perseus/src/engine/build.rs index 96df035f6e..b29c069c91 100644 --- a/packages/perseus/src/engine/build.rs +++ b/packages/perseus/src/engine/build.rs @@ -45,7 +45,7 @@ pub async fn build( // Build the site for all the common locales (done in parallel) // All these parameters can be modified by `PerseusApp` and plugins, so there's // no point in having a plugin opportunity here - let templates_map = app.get_templates_map(); + let templates_map = app.get_atomic_templates_map(); // We have to get the translations manager last, because it consumes everything let translations_manager = app.get_translations_manager().await; diff --git a/packages/perseus/src/engine/export.rs b/packages/perseus/src/engine/export.rs index f68f135c3d..85bc27de00 100644 --- a/packages/perseus/src/engine/export.rs +++ b/packages/perseus/src/engine/export.rs @@ -77,7 +77,7 @@ async fn build_and_export( return Err(err); } }; - let templates_map = app.get_templates_map(); + let templates_map = app.get_atomic_templates_map(); let index_view_str = app.get_index_view_str(); let root_id = app.get_root(); // This consumes `self`, so we get it finally diff --git a/packages/perseus/src/engine/export_error_page.rs b/packages/perseus/src/engine/export_error_page.rs index ef50dfb784..dd6a61b277 100644 --- a/packages/perseus/src/engine/export_error_page.rs +++ b/packages/perseus/src/engine/export_error_page.rs @@ -19,7 +19,7 @@ pub async fn export_error_page( ) -> Result<(), Rc> { let plugins = app.get_plugins(); - let error_pages = app.get_error_pages(); + let error_pages = app.get_atomic_error_pages(); // Prepare the HTML shell let index_view_str = app.get_index_view_str(); let root_id = app.get_root(); diff --git a/packages/perseus/src/engine/serve.rs b/packages/perseus/src/engine/serve.rs index 7206d0d7f1..8a61b7b82c 100644 --- a/packages/perseus/src/engine/serve.rs +++ b/packages/perseus/src/engine/serve.rs @@ -6,7 +6,6 @@ use crate::PerseusAppBase; use futures::executor::block_on; use std::env; use std::fs; -use std::sync::Arc; use sycamore::web::SsrNode; /// Gets the host and port to serve on based on environment variables, which are @@ -78,7 +77,7 @@ pub(crate) fn get_props( locales: app.get_locales(), root_id: app_root, snippets: "dist/pkg/snippets".to_string(), - error_pages: Arc::new(app.get_error_pages()), + error_pages: app.get_atomic_error_pages(), // This will be available directly at `/.perseus/static` static_dir: if fs::metadata(&static_dir_path).is_ok() { Some(static_dir_path) diff --git a/packages/perseus/src/error_pages.rs b/packages/perseus/src/error_pages.rs index 203bd46214..8a95c0f52f 100644 --- a/packages/perseus/src/error_pages.rs +++ b/packages/perseus/src/error_pages.rs @@ -102,8 +102,8 @@ impl ErrorPages { /// Adds a new page for the given status code. If a page was already defined /// for the given code, it will be updated by the mechanics of /// the internal `HashMap`. This differs from `.add_page()` in that it takes - /// an `Rc`, which can be useful for plugins. - pub fn add_page_rc( + /// a `Box`, which can be useful for plugins. + pub fn add_page_boxed( &mut self, status: u16, page: ErrorPageTemplate, diff --git a/packages/perseus/src/export.rs b/packages/perseus/src/export.rs index df7a2cb11f..c63124546f 100644 --- a/packages/perseus/src/export.rs +++ b/packages/perseus/src/export.rs @@ -3,7 +3,7 @@ use crate::i18n::{Locales, TranslationsManager}; use crate::page_data::PageDataPartial; use crate::server::{get_render_cfg, HtmlShell}; use crate::stores::ImmutableStore; -use crate::template::{TemplateMap, TemplateState}; +use crate::template::{ArcTemplateMap, TemplateState}; use crate::{page_data::PageData, SsrNode}; use futures::future::{try_join, try_join_all}; @@ -41,7 +41,7 @@ pub async fn get_static_page_data( #[derive(Debug)] pub struct ExportProps<'a, T: TranslationsManager> { /// All the templates in the app. - pub templates: &'a TemplateMap, + pub templates: &'a ArcTemplateMap, /// The HTML shell to use. pub html_shell: HtmlShell, /// The locales data for the app. @@ -134,7 +134,7 @@ pub async fn create_translation_file( #[allow(clippy::too_many_arguments)] pub async fn export_path( (path, template_path): (String, String), - templates: &TemplateMap, + templates: &ArcTemplateMap, locales: &Locales, html_shell: &HtmlShell, immutable_store: &ImmutableStore, diff --git a/packages/perseus/src/init.rs b/packages/perseus/src/init.rs index 56327b8e58..3a0a96b519 100644 --- a/packages/perseus/src/init.rs +++ b/packages/perseus/src/init.rs @@ -2,13 +2,16 @@ use crate::server::{get_render_cfg, HtmlShell}; use crate::stores::ImmutableStore; #[cfg(not(target_arch = "wasm32"))] +use crate::template::ArcTemplateMap; +#[cfg(target_arch = "wasm32")] +use crate::template::TemplateMap; +#[cfg(not(target_arch = "wasm32"))] use crate::utils::get_path_prefix_server; use crate::{ i18n::{Locales, TranslationsManager}, plugins::{PluginAction, Plugins}, state::GlobalStateCreator, stores::MutableStore, - template::TemplateMap, ErrorPages, Html, SsrNode, Template, }; use futures::Future; @@ -47,21 +50,6 @@ static DFLT_INDEX_VIEW: &str = r#" // TODO What's a sensible value here? static DFLT_PSS_MAX_SIZE: usize = 25; -// This is broken out for debug implementation ease -struct TemplateGetters(Vec Template>>); -impl std::fmt::Debug for TemplateGetters { - fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { - f.debug_struct("TemplateGetters").finish() - } -} -// This is broken out for debug implementation ease -struct ErrorPagesGetter(Box ErrorPages>); -impl std::fmt::Debug for ErrorPagesGetter { - fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { - f.debug_struct("ErrorPagesGetters").finish() - } -} - /// The different types of translations managers that can be stored. This allows /// us to store dummy translations managers directly, without holding futures. /// If this stores a full translations manager though, it will store it as a @@ -111,11 +99,15 @@ pub struct PerseusAppBase { /// A list of function that produce templates for the app to use. These are /// stored as functions so that they can be called an arbitrary number of /// times. - // From this, we can construct the necessary kind of template map (we can call the user-given - // functions an arbitrary number of times) - template_getters: TemplateGetters, + #[cfg(target_arch = "wasm32")] + templates: TemplateMap, + #[cfg(not(target_arch = "wasm32"))] + templates: ArcTemplateMap, /// The app's error pages. - error_pages: ErrorPagesGetter, + #[cfg(target_arch = "wasm32")] + error_pages: Rc>, + #[cfg(not(target_arch = "wasm32"))] + error_pages: Arc>, /// The maximum size for the page state store. pss_max_size: usize, /// The global state creator for the app. @@ -280,10 +272,10 @@ impl PerseusAppBase { root: "root".to_string(), // We do initialize with no templates, because an app without templates is in theory // possible (and it's more convenient to call `.template()` for each one) - template_getters: TemplateGetters(Vec::new()), + templates: HashMap::new(), // We do offer default error pages, but they'll panic if they're called for production // building - error_pages: ErrorPagesGetter(Box::new(ErrorPages::default)), + error_pages: Default::default(), pss_max_size: DFLT_PSS_MAX_SIZE, #[cfg(not(target_arch = "wasm32"))] global_state_creator: Arc::new(GlobalStateCreator::default()), @@ -324,10 +316,10 @@ impl PerseusAppBase { root: "root".to_string(), // We do initialize with no templates, because an app without templates is in theory // possible (and it's more convenient to call `.template()` for each one) - template_getters: TemplateGetters(Vec::new()), + templates: HashMap::new(), // We do offer default error pages, but they'll panic if they're called for production // building - error_pages: ErrorPagesGetter(Box::new(ErrorPages::default)), + error_pages: Default::default(), pss_max_size: DFLT_PSS_MAX_SIZE, // By default, we'll disable i18n (as much as I may want more websites to support more // languages...) @@ -373,21 +365,38 @@ impl PerseusAppBase { /// /// Usually, it's preferred to run `.template()` once for each template, /// rather than manually constructing this more inconvenient type. - pub fn templates(mut self, val: Vec Template>>) -> Self { - self.template_getters.0 = val; + pub fn templates(mut self, val: Vec>) -> Self { + for template in val.into_iter() { + #[cfg(target_arch = "wasm32")] + self.templates + .insert(template.get_path(), Rc::new(template)); + #[cfg(not(target_arch = "wasm32"))] + self.templates + .insert(template.get_path(), Arc::new(template)); + } self } /// Adds a single new template to the app (convenience function). This takes /// a *function that returns a template* (for internal reasons). /// /// See [`Template`] for further details. - pub fn template(mut self, val: impl Fn() -> Template + 'static) -> Self { - self.template_getters.0.push(Box::new(val)); + pub fn template(mut self, val: Template) -> Self { + #[cfg(target_arch = "wasm32")] + self.templates.insert(val.get_path(), Rc::new(val)); + #[cfg(not(target_arch = "wasm32"))] + self.templates.insert(val.get_path(), Arc::new(val)); self } /// Sets the app's error pages. See [`ErrorPages`] for further details. - pub fn error_pages(mut self, val: impl Fn() -> ErrorPages + 'static) -> Self { - self.error_pages = ErrorPagesGetter(Box::new(val)); + pub fn error_pages(mut self, val: ErrorPages) -> Self { + #[cfg(target_arch = "wasm32")] + { + self.error_pages = Rc::new(val); + } + #[cfg(not(target_arch = "wasm32"))] + { + self.error_pages = Arc::new(val); + } self } /// Sets the app's [`GlobalStateCreator`]. @@ -722,14 +731,10 @@ impl PerseusAppBase { html_shell } /// Gets the templates in an `Rc`-based `HashMap` for non-concurrent access. + #[cfg(target_arch = "wasm32")] pub fn get_templates_map(&self) -> TemplateMap { - let mut map = HashMap::new(); - - // Now add the templates the user provided - for template_getter in self.template_getters.0.iter() { - let template = template_getter(); - map.insert(template.get_path(), Rc::new(template)); - } + // One the browser-side, this is already a `TemplateMap` internally + let mut map = self.templates.clone(); // This will return a map of plugin name to a vector of templates to add let extra_templates = self @@ -751,14 +756,9 @@ impl PerseusAppBase { /// Gets the templates in an `Arc`-based `HashMap` for concurrent access. /// This should only be relevant on the server-side. #[cfg(not(target_arch = "wasm32"))] - pub fn get_atomic_templates_map(&self) -> crate::template::ArcTemplateMap { - let mut map = HashMap::new(); - - // Now add the templates the user provided - for template_getter in self.template_getters.0.iter() { - let template = template_getter(); - map.insert(template.get_path(), std::sync::Arc::new(template)); - } + pub fn get_atomic_templates_map(&self) -> ArcTemplateMap { + // One the engine-side, this is already an `ArcTemplateMap` internally + let mut map = self.templates.clone(); // This will return a map of plugin name to a vector of templates to add let extra_templates = self @@ -771,28 +771,21 @@ impl PerseusAppBase { // Turn that vector into a template map by extracting the template root paths as // keys for template in plugin_templates { - map.insert(template.get_path(), std::sync::Arc::new(template)); + map.insert(template.get_path(), Arc::new(template)); } } map } /// Gets the [`ErrorPages`] used in the app. This returns an `Rc`. - pub fn get_error_pages(&self) -> ErrorPages { - let mut error_pages = (self.error_pages.0)(); - let extra_error_pages = self - .plugins - .functional_actions - .settings_actions - .add_error_pages - .run((), self.plugins.get_plugin_data()); - for (_plugin_name, plugin_error_pages) in extra_error_pages { - for (status, error_page) in plugin_error_pages { - error_pages.add_page_rc(status, error_page.0, error_page.1); - } - } - - error_pages + #[cfg(target_arch = "wasm32")] + pub fn get_error_pages(&self) -> Rc> { + self.error_pages.clone() + } + /// Gets the [`ErrorPages`] used in the app. This returns an `Arc`. + #[cfg(not(target_arch = "wasm32"))] + pub fn get_atomic_error_pages(&self) -> Arc> { + self.error_pages.clone() } /// Gets the maximum number of pages that can be stored in the page state /// store before the oldest are evicted. diff --git a/packages/perseus/src/plugins/functional.rs b/packages/perseus/src/plugins/functional.rs index cc3668e038..5b44fb25f1 100644 --- a/packages/perseus/src/plugins/functional.rs +++ b/packages/perseus/src/plugins/functional.rs @@ -128,19 +128,6 @@ pub struct FunctionalPluginSettingsActions { /// generic about Sycamore rendering backends. Note that these have the /// power to override the user's templates. pub add_templates: FunctionalPluginAction<(), Vec>>, - /// Adds additional error pages. This must return a map of HTTP status codes - /// to error page templates. Note that these have the power to override - /// the user's error pages. - pub add_error_pages: FunctionalPluginAction< - (), - HashMap< - u16, - ( - crate::error_pages::ErrorPageTemplate, - crate::error_pages::ErrorPageHeadTemplate, - ), - >, - >, /// Actions pertaining to the HTML shell, in their own category for /// cleanliness (as there are quite a few). pub html_shell_actions: FunctionalPluginHtmlShellActions, @@ -150,7 +137,6 @@ impl Default for FunctionalPluginSettingsActions { Self { add_static_aliases: FunctionalPluginAction::default(), add_templates: FunctionalPluginAction::default(), - add_error_pages: FunctionalPluginAction::default(), html_shell_actions: FunctionalPluginHtmlShellActions::default(), } } diff --git a/packages/perseus/src/router/router_component.rs b/packages/perseus/src/router/router_component.rs index 37a5e45bad..59ab0b7526 100644 --- a/packages/perseus/src/router/router_component.rs +++ b/packages/perseus/src/router/router_component.rs @@ -108,7 +108,7 @@ async fn set_view<'a>( #[derive(Debug, Prop)] pub(crate) struct PerseusRouterProps { /// The error pages the app is using. - pub error_pages: ErrorPages, + pub error_pages: Rc>, /// The locales settings the app is using. pub locales: Locales, /// The templates the app is using. @@ -149,7 +149,7 @@ pub(crate) fn perseus_router( locales, // Pretty light templates, // Already has `Rc`s Rc::new(render_cfg), - Rc::new(error_pages), + error_pages, // Already in an `Rc` itself ) .set_ctx(cx);