@@ -22,7 +22,7 @@ use serde::{Deserialize, Serialize};
2222use std:: fmt;
2323
2424lazy_static ! {
25- static ref BLOG : Collection = Collection :: new(
25+ pub static ref BLOG : Collection = Collection :: new(
2626 "Blog" ,
2727 true ,
2828 HashMap :: from( [
@@ -93,7 +93,7 @@ impl FromStr for DocType {
9393 }
9494}
9595
96- #[ derive( Debug , Serialize , Deserialize ) ]
96+ #[ derive( Debug , Serialize , Deserialize , Default ) ]
9797pub struct Document {
9898 /// The absolute path on disk
9999 pub path : PathBuf ,
@@ -110,10 +110,15 @@ pub struct Document {
110110 pub doc_type : Option < DocType > ,
111111 // url to thumbnail for social share
112112 pub thumbnail : Option < String > ,
113+ pub url : String ,
113114}
114115
115116// Gets document markdown
116117impl Document {
118+ pub fn new ( ) -> Document {
119+ Document { ..Default :: default ( ) }
120+ }
121+
117122 pub async fn from_path ( path : & PathBuf ) -> anyhow:: Result < Document , std:: io:: Error > {
118123 let doc_type = match path. strip_prefix ( config:: cms_dir ( ) ) {
119124 Ok ( path) => match path. into_iter ( ) . next ( ) {
@@ -151,11 +156,14 @@ impl Document {
151156 ( None , contents)
152157 } ;
153158
154- let default_image_path = BLOG
155- . asset_url_root
156- . join ( "blog_image_placeholder.png" )
157- . display ( )
158- . to_string ( ) ;
159+ let default_image_path = match doc_type {
160+ Some ( DocType :: Blog ) => BLOG
161+ . asset_url_root
162+ . join ( "blog_image_placeholder.png" )
163+ . display ( )
164+ . to_string ( ) ,
165+ _ => String :: from ( "/dashboard/static/images/careers_article_default.png" ) ,
166+ } ;
159167
160168 // parse meta section
161169 let ( description, image, featured, tags) = match meta {
@@ -166,15 +174,20 @@ impl Document {
166174 Some ( meta[ "description" ] . as_str ( ) . unwrap ( ) . to_string ( ) )
167175 } ;
168176
169- // For now the only images shown are blog images TODO: use doc_type to set asset path when working.
170177 let image = if meta[ "image" ] . is_badvalue ( ) {
171178 Some ( default_image_path. clone ( ) )
172179 } else {
173180 match PathBuf :: from_str ( meta[ "image" ] . as_str ( ) . unwrap ( ) ) {
174181 Ok ( image_path) => match image_path. file_name ( ) {
175182 Some ( file_name) => {
176183 let file = PathBuf :: from ( file_name) . display ( ) . to_string ( ) ;
177- Some ( BLOG . asset_url_root . join ( file) . display ( ) . to_string ( ) )
184+ match doc_type {
185+ Some ( DocType :: Docs ) => Some ( DOCS . asset_url_root . join ( file) . display ( ) . to_string ( ) ) ,
186+ Some ( DocType :: Careers ) => {
187+ Some ( CAREERS . asset_url_root . join ( file) . display ( ) . to_string ( ) )
188+ }
189+ _ => Some ( BLOG . asset_url_root . join ( file) . display ( ) . to_string ( ) ) ,
190+ }
178191 }
179192 _ => Some ( default_image_path. clone ( ) ) ,
180193 } ,
@@ -221,6 +234,34 @@ impl Document {
221234 let toc_links = crate :: utils:: markdown:: get_toc ( root) . unwrap ( ) ;
222235 let ( author, date, author_image) = crate :: utils:: markdown:: get_author ( root) ;
223236
237+ // convert author image relative url path to absolute url path
238+ let author_image = if author_image. is_some ( ) {
239+ let image = author_image. clone ( ) . unwrap ( ) ;
240+ let image = PathBuf :: from ( image) ;
241+ let image = image. file_name ( ) . unwrap ( ) ;
242+ match & doc_type {
243+ Some ( DocType :: Blog ) => Some ( BLOG . asset_url_root . join ( image. to_str ( ) . unwrap ( ) ) . display ( ) . to_string ( ) ) ,
244+ Some ( DocType :: Docs ) => Some ( DOCS . asset_url_root . join ( image. to_str ( ) . unwrap ( ) ) . display ( ) . to_string ( ) ) ,
245+ Some ( DocType :: Careers ) => Some (
246+ CAREERS
247+ . asset_url_root
248+ . join ( PathBuf :: from ( image. to_str ( ) . unwrap ( ) ) )
249+ . display ( )
250+ . to_string ( ) ,
251+ ) ,
252+ _ => None ,
253+ }
254+ } else {
255+ None
256+ } ;
257+
258+ let url = match doc_type {
259+ Some ( DocType :: Blog ) => BLOG . path_to_url ( & path) ,
260+ Some ( DocType :: Docs ) => DOCS . path_to_url ( & path) ,
261+ Some ( DocType :: Careers ) => CAREERS . path_to_url ( & path) ,
262+ _ => String :: new ( ) ,
263+ } ;
264+
224265 let document = Document {
225266 path : path. to_owned ( ) ,
226267 description,
@@ -235,6 +276,7 @@ impl Document {
235276 contents,
236277 doc_type,
237278 thumbnail,
279+ url,
238280 } ;
239281 Ok ( document)
240282 }
@@ -478,6 +520,25 @@ impl Collection {
478520 self . root_dir . join ( path_pb)
479521 }
480522
523+ // Convert a file path to a url
524+ pub fn path_to_url ( & self , path : & PathBuf ) -> String {
525+ let url = path. strip_prefix ( config:: cms_dir ( ) ) . unwrap ( ) ;
526+ let url = format ! ( "/{}" , url. display( ) . to_string( ) ) ;
527+
528+ let url = if url. ends_with ( "README.md" ) {
529+ url. replace ( "README.md" , "" )
530+ } else {
531+ url
532+ } ;
533+
534+ let url = if url. ends_with ( ".md" ) {
535+ url. replace ( ".md" , "" )
536+ } else {
537+ url
538+ } ;
539+ url
540+ }
541+
481542 // get all urls in the collection and preserve order.
482543 pub fn get_all_urls ( & self ) -> Vec < String > {
483544 let mut urls: Vec < String > = Vec :: new ( ) ;
@@ -524,35 +585,39 @@ impl Collection {
524585 ) -> Result < ResponseOk , crate :: responses:: NotFound > {
525586 match Document :: from_path ( & path) . await {
526587 Ok ( doc) => {
527- let mut layout = crate :: templates:: Layout :: new ( & doc. title , Some ( cluster) ) ;
528- if let Some ( image) = & doc. thumbnail {
529- layout. image ( & image) ;
530- }
531- if let Some ( description) = & doc. description {
532- layout. description ( description) ;
533- }
588+ let head = crate :: components:: layouts:: Head :: new ( )
589+ . title ( & doc. title )
590+ . description ( & doc. description . clone ( ) . unwrap_or_else ( || String :: new ( ) ) )
591+ . image ( & doc. thumbnail . clone ( ) . unwrap_or_else ( || String :: new ( ) ) )
592+ . canonical ( & canonical) ;
534593
535- let layout = layout . canonical ( canonical ) . toc_links ( & doc . toc_links ) ;
594+ let layout = Base :: from_head ( head , Some ( cluster ) ) . theme ( Theme :: Docs ) ;
536595
537- Ok ( ResponseOk (
538- layout. render ( crate :: templates:: Article { content : doc. html ( ) } ) ,
539- ) )
596+ let mut article = crate :: components:: pages:: article:: Index :: new ( & cluster)
597+ . document ( doc)
598+ . await ;
599+
600+ article = if self . name == "Blog" {
601+ article. is_blog ( )
602+ } else {
603+ article. is_careers ( )
604+ } ;
605+
606+ Ok ( ResponseOk ( layout. render ( article) ) )
540607 }
541608 // Return page not found on bad path
542609 _ => {
543- let mut layout = crate :: templates:: Layout :: new ( "404" , Some ( cluster) ) ;
544-
545- let doc = String :: from (
546- r#"
547- <div style='height: 80vh'>
548- <h2>Oops, document not found!</h2>
549- <p>The document you are searching for may have been moved or replaced with better content.</p>
550- </div>"# ,
551- ) ;
552-
553- Err ( crate :: responses:: NotFound (
554- layout. render ( crate :: templates:: Article { content : doc } ) . into ( ) ,
555- ) )
610+ let layout = Base :: new ( "404" , Some ( cluster) ) . theme ( Theme :: Docs ) ;
611+
612+ let mut article = crate :: components:: pages:: article:: Index :: new ( & cluster) . document_not_found ( ) ;
613+
614+ article = if self . name == "Blog" {
615+ article. is_blog ( )
616+ } else {
617+ article. is_careers ( )
618+ } ;
619+
620+ Err ( crate :: responses:: NotFound ( layout. render ( article) ) )
556621 }
557622 }
558623 }
0 commit comments