teensy_cms/config.rs
1//! Configuration for the CMS
2use serde::{Deserialize, Serialize};
3use std::path::PathBuf;
4
5/// Configuration for the application.
6///
7/// When it is loaded by [`crate::TeensyCms::from_config_path`], all paths are considered related
8/// to the config file itself.
9///
10/// In YAML format, the config would look like:
11///
12/// ```yaml
13/// ---
14/// pages:
15/// - path: about.html
16/// url: /about
17/// - title: Submenu
18/// pages:
19/// - path: sub/page.html
20/// url: sub/page
21/// template_extras:
22/// # directories
23/// - macros/
24/// # single files
25/// - layout.html
26/// # globs
27/// - helper/*.html
28/// ```
29#[derive(Deserialize, Debug)]
30pub struct Config {
31 /// A list of pages and submenus to include.
32 pub pages: Vec<MenuItemConfig>,
33 /// Extra templates to load into the rendering environment.
34 pub template_extras: Option<Vec<String>>,
35}
36
37/// Configurations for menu items.
38#[derive(Deserialize, Debug)]
39#[serde(untagged)]
40pub enum MenuItemConfig {
41 /// A singple page in the menu.
42 Page {
43 /// The path on the file system to the template file.
44 path: PathBuf,
45 /// A URL for this page. This will still be relative to the page base and not absolute across
46 /// the application.
47 url: String,
48 /// If and where the page will be visible.
49 #[serde(default = "Visibility::default")]
50 visibility: Visibility,
51 },
52 /// A grouping of menu items.
53 Menu {
54 /// Title of the menu group.
55 title: String,
56 /// A list of pages under the menu group.
57 pages: Vec<MenuItemConfig>,
58 },
59}
60
61/// Enum for a page's visiblity in menus.
62#[derive(Serialize, Deserialize, Debug, PartialEq, Eq, Clone, Copy)]
63#[serde(rename_all = "kebab-case")]
64pub enum Visibility {
65 /// Page is always visible in all menus.
66 Always,
67 /// Page is never visible in any menus.
68 Never,
69 /// Page is only visible in header menus.
70 HeaderOnly,
71 /// Page is only visible in footer menus.
72 FooterOnly,
73}
74
75impl Visibility {
76 pub fn show_in_header(&self) -> bool {
77 match self {
78 Self::Always => true,
79 Self::Never => false,
80 Self::HeaderOnly => true,
81 Self::FooterOnly => false,
82 }
83 }
84
85 pub fn show_in_footer(&self) -> bool {
86 match self {
87 Self::Always => true,
88 Self::Never => false,
89 Self::HeaderOnly => false,
90 Self::FooterOnly => true,
91 }
92 }
93}
94
95impl Default for Visibility {
96 fn default() -> Self {
97 Self::Always
98 }
99}