@@ -22,7 +22,7 @@ use serde::{Deserialize, Serialize};
22
22
use std:: fmt;
23
23
24
24
lazy_static ! {
25
- static refBLOG : Collection =Collection :: new(
25
+ pub static refBLOG : Collection =Collection :: new(
26
26
"Blog" ,
27
27
true ,
28
28
HashMap :: from( [
@@ -93,7 +93,7 @@ impl FromStr for DocType {
93
93
}
94
94
}
95
95
96
- #[ derive( Debug , Serialize , Deserialize ) ]
96
+ #[ derive( Debug , Serialize , Deserialize , Default ) ]
97
97
pub struct Document {
98
98
/// The absolute path on disk
99
99
pub path : PathBuf ,
@@ -110,10 +110,15 @@ pub struct Document {
110
110
pub doc_type : Option < DocType > ,
111
111
// url to thumbnail for social share
112
112
pub thumbnail : Option < String > ,
113
+ pub url : String ,
113
114
}
114
115
115
116
// Gets document markdown
116
117
impl Document {
118
+ pub fn new ( ) ->Document {
119
+ Document { ..Default :: default ( ) }
120
+ }
121
+
117
122
pub async fn from_path ( path : & PathBuf ) -> anyhow:: Result < Document , std:: io:: Error > {
118
123
let doc_type =match path. strip_prefix ( config:: cms_dir ( ) ) {
119
124
Ok ( path) =>match path. into_iter ( ) . next ( ) {
@@ -151,11 +156,14 @@ impl Document {
151
156
( None , contents)
152
157
} ;
153
158
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
+ } ;
159
167
160
168
// parse meta section
161
169
let ( description, image, featured, tags) =match meta{
@@ -166,15 +174,20 @@ impl Document {
166
174
Some ( meta[ "description" ] . as_str ( ) . unwrap ( ) . to_string ( ) )
167
175
} ;
168
176
169
- // For now the only images shown are blog images TODO: use doc_type to set asset path when working.
170
177
let image =if meta[ "image" ] . is_badvalue ( ) {
171
178
Some ( default_image_path. clone ( ) )
172
179
} else {
173
180
match PathBuf :: from_str ( meta[ "image" ] . as_str ( ) . unwrap ( ) ) {
174
181
Ok ( image_path) =>match image_path. file_name ( ) {
175
182
Some ( file_name) =>{
176
183
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
+ }
178
191
}
179
192
_ =>Some ( default_image_path. clone ( ) ) ,
180
193
} ,
@@ -221,6 +234,34 @@ impl Document {
221
234
let toc_links =crate :: utils:: markdown:: get_toc ( root) . unwrap ( ) ;
222
235
let ( author, date, author_image) =crate :: utils:: markdown:: get_author ( root) ;
223
236
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
+
224
265
let document =Document {
225
266
path : path. to_owned ( ) ,
226
267
description,
@@ -235,6 +276,7 @@ impl Document {
235
276
contents,
236
277
doc_type,
237
278
thumbnail,
279
+ url,
238
280
} ;
239
281
Ok ( document)
240
282
}
@@ -478,6 +520,25 @@ impl Collection {
478
520
self . root_dir . join ( path_pb)
479
521
}
480
522
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
+
481
542
// get all urls in the collection and preserve order.
482
543
pub fn get_all_urls ( & self ) ->Vec < String > {
483
544
let mut urls: Vec < String > =Vec :: new ( ) ;
@@ -524,35 +585,39 @@ impl Collection {
524
585
) ->Result < ResponseOk , crate :: responses:: NotFound > {
525
586
match Document :: from_path ( & path) . await {
526
587
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) ;
534
593
535
- let layout =layout . canonical ( canonical ) . toc_links ( & doc . toc_links ) ;
594
+ let layout =Base :: from_head ( head , Some ( cluster ) ) . theme ( Theme :: Docs ) ;
536
595
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) ) )
540
607
}
541
608
// Return page not found on bad path
542
609
_ =>{
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) ) )
556
621
}
557
622
}
558
623
}