cobalt/cobalt_model/
collection.rs1use cobalt_config::Frontmatter;
2use cobalt_config::SortOrder;
3use liquid;
4
5use crate::error::Result;
6
7#[derive(Clone, Debug, PartialEq, Eq, serde::Serialize)]
8pub struct Collection {
9 pub title: liquid::model::KString,
10 pub slug: liquid::model::KString,
11 pub description: Option<liquid::model::KString>,
12 pub dir: cobalt_config::RelPath,
13 pub drafts_dir: Option<cobalt_config::RelPath>,
14 pub order: SortOrder,
15 pub rss: Option<cobalt_config::RelPath>,
16 pub jsonfeed: Option<cobalt_config::RelPath>,
17 pub publish_date_in_filename: bool,
18 pub default: Frontmatter,
19}
20
21impl Collection {
22 pub fn from_page_config(
23 config: cobalt_config::PageCollection,
24 site: &cobalt_config::Site,
25 common_default: &Frontmatter,
26 ) -> Result<Self> {
27 let mut config: cobalt_config::Collection = config.into();
28 config.title = Some(site.title.clone().unwrap_or_else(|| "".into()));
30 config.description = site.description.clone();
31 Self::from_config(config, "pages", false, common_default)
32 }
33
34 pub fn from_post_config(
35 config: cobalt_config::PostCollection,
36 site: &cobalt_config::Site,
37 include_drafts: bool,
38 common_default: &Frontmatter,
39 ) -> Result<Self> {
40 let mut config: cobalt_config::Collection = config.into();
41 if config.title.is_none() {
44 config.title = Some(site.title.clone().unwrap_or_else(|| "".into()));
45 }
46 if config.description.is_none() {
47 config.description = site.description.clone();
48 }
49 Self::from_config(config, "posts", include_drafts, common_default)
50 }
51
52 fn from_config(
53 config: cobalt_config::Collection,
54 slug: &str,
55 include_drafts: bool,
56 common_default: &Frontmatter,
57 ) -> Result<Self> {
58 let cobalt_config::Collection {
59 title,
60 description,
61 dir,
62 drafts_dir,
63 order,
64 rss,
65 jsonfeed,
66 default,
67 publish_date_in_filename,
68 } = config;
69
70 let title = title.ok_or_else(|| anyhow::format_err!("Collection is missing a `title`"))?;
71 let slug = liquid::model::KString::from_ref(slug);
72
73 let dir = dir.unwrap_or_else(|| cobalt_config::RelPath::from_unchecked(slug.as_str()));
74 let drafts_dir = if include_drafts { drafts_dir } else { None };
75
76 let default = default.merge(common_default).merge(&Frontmatter {
77 collection: Some(slug.clone()),
78 ..Default::default()
79 });
80
81 let new = Collection {
82 title,
83 slug,
84 description,
85 dir,
86 drafts_dir,
87 order,
88 rss,
89 jsonfeed,
90 publish_date_in_filename,
91 default,
92 };
93 Ok(new)
94 }
95
96 pub fn attributes(&self) -> liquid::Object {
97 let mut attributes: liquid::Object = vec![
98 (
99 "title".into(),
100 liquid::model::Value::scalar(self.title.clone()),
101 ),
102 (
103 "slug".into(),
104 liquid::model::Value::scalar(self.slug.clone()),
105 ),
106 (
107 "description".into(),
108 liquid::model::Value::scalar(self.description.clone().unwrap_or_default()),
109 ),
110 ]
111 .into_iter()
112 .collect();
113 if let Some(rss) = self.rss.as_ref() {
114 attributes.insert(
115 "rss".into(),
116 liquid::model::Value::scalar(rss.as_str().to_owned()),
117 );
118 }
119 if let Some(jsonfeed) = self.jsonfeed.as_ref() {
120 attributes.insert(
121 "jsonfeed".into(),
122 liquid::model::Value::scalar(jsonfeed.as_str().to_owned()),
123 );
124 }
125 attributes
126 }
127}