unreact/app/
routes.rs

1use std::path::Path;
2
3use crate::{Error, Object, Page, Unreact};
4
5/// Append shared documentation attributes to each function
6macro_rules! include_shared_docs {
7    (
8        $(
9            $( #[$attr:meta] )+
10            <::>
11            $item:item
12        )*
13    ) => {
14        $(
15            $( #[$attr] )+
16            /// # Examples
17            ///
18            /// ```,no_run
19            /// # use unreact::prelude::*;
20            /// # fn main() -> Result<(), Error> {
21            ///     # let mut app = Unreact::new(Config::default(), false, "https://example.com")?;
22            /// app
23            ///     // Create a route to '/some_path' with the template 'page.hbs' and a message
24            ///     .route("some_path", "page", object! {message: "this is at '/some_path'"})?
25            ///     // Create a route without a template (raw string)
26            ///     .route_raw("hello", "this is my hello page".to_string())
27            ///     // Create a route without data
28            ///     .route("article", "other/article", object! {})?
29            ///     // Index page with a message
30            ///     .index("page", object! {message: "World"})?
31            ///     // 404 page with no data
32            ///     .not_found("404", object! {})?;
33            /// # app.run()
34            /// # }
35            /// ```
36            ///
37            /// # Routing Methods
38            ///
39            /// - [`route`](struct.Unreact.html#method.route): Create a normal route
40            /// - [`route_raw`](struct.Unreact.html#method.route_raw): Create a route without a template
41            /// - [`route_raw_html`](struct.Unreact.html#method.route_raw_html): Create a HTML page route without a template
42            /// - [`index`](struct.Unreact.html#method.index): Create an index route (`/`)
43            /// - [`not_found`](struct.Unreact.html#method.not_found): Create a 404 route (`/404`)
44            $item
45        )*
46    };
47}
48
49impl<'a> Unreact<'a> {
50    include_shared_docs!(
51        /// Create a route
52        ///
53        /// **NOTE**: Route will only validate if template exists in production. In dev mode, this function **will always pass**, and error will occur during `run` function
54        ///
55        /// ## Parameters
56        ///
57        /// - `path`: The folder (relative to build directory) that file should be written in (`{build}/{path}/index.html`)
58        /// - `template`: The name of the template to use
59        /// - `data`: Data to pass into the template, as an `Object`
60        <::>
61        pub fn route(&mut self, path: &str, template: &str, data: Object) -> Result<&mut Self, Error> {
62            // Check file exists - only if NOT dev mode
63            if !self.is_dev{
64                let file_path = format!("{}/{}.hbs", self.config.templates, template);
65                if !Path::new(&file_path).exists() {
66                    return fail!(TemplateNotExist, template.to_string());
67                }
68            }
69
70            // Create route
71            self.routes.insert(
72                path.to_string(),
73                Page::Template {
74                    template: template.to_string(),
75                    data,
76                },
77            );
78
79            Ok(self)
80        }
81
82        /// Create a route, with raw page content instead of a template
83        ///
84        /// ## Parameters
85        ///
86        /// - `path`: The folder (relative to build directory) that file should be written in (`{build}/{path}/index.html`)
87        /// - `content`: The raw file contents to write to the file
88        <::>
89        pub fn route_raw(&mut self, path: &str, content: impl Into<String>) -> &mut Self {
90            self.routes.insert(path.to_string(), Page::Raw(content.into()));
91            self
92        }
93
94        /// Create a route, with raw page content instead of a template
95        ///
96        /// Adds HTML boilerplate around content (Unlike [`route_raw`](struct.Unreact.html#method.route_raw))
97        ///
98        /// ## Parameters
99        ///
100        /// - `path`: The folder (relative to build directory) that file should be written in (`{build}/{path}/index.html`)
101        /// - `content`: The raw file contents to write to the file
102        <::>
103        pub fn route_raw_html(&mut self, path: &str, content: impl Into<String>) -> &mut Self {
104            self.routes.insert(path.to_string(), Page::Raw(format!(include_str!("boilerplate.html"), CONTENT = content.into())));
105            self
106        }
107
108        /// Create the index route
109        ///
110        /// Alias of `app.route("", ...)`
111        ///
112        /// File is written to `{build}/index.html`
113        ///
114        /// **NOTE**: Route will only validate if template exists in production. In dev mode, this function **will always pass**, and error will occur during `run` function
115        ///
116        /// ## Parameters
117        ///
118        /// - `template`: The name of the template to use
119        /// - `data`: Data to pass into the template, as an `Object`
120        <::>
121        pub fn index(&mut self, template: &str, data: Object) -> Result<&mut Self, Error> {
122            self.route("", template, data)
123        }
124
125        /// Create the 404 route
126        ///
127        /// Alias of `app.route("404", ...)`.
128        /// Used as the 404 page, for a path not found
129        ///
130        /// File is written to `{build}/404/index.html`
131        ///
132        /// **NOTE**: Route will only validate if template exists in production. In dev mode, this function **will always pass**, and error will occur during `run` function
133        ///
134        /// ## Parameters
135        ///
136        /// - `template`: The name of the template to use
137        /// - `data`: Data to pass into the template, as an `Object`
138        <::>
139        pub fn not_found(&mut self, template: &str, data: Object) -> Result<&mut Self, Error> {
140            self.route("404", template, data)
141        }
142    );
143}