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}