@@ -3,12 +3,7 @@ use std::path::{Path, PathBuf};
33use comrak:: { format_html_with_plugins, parse_document, Arena , ComrakPlugins } ;
44use lazy_static:: lazy_static;
55use markdown:: mdast:: Node ;
6- use rocket:: {
7- fs:: NamedFile ,
8- http:: { uri:: Origin , Status } ,
9- route:: Route ,
10- State ,
11- } ;
6+ use rocket:: { fs:: NamedFile , http:: uri:: Origin , route:: Route , State } ;
127use yaml_rust:: YamlLoader ;
138
149use crate :: {
@@ -39,11 +34,19 @@ pub struct Document {
3934}
4035
4136impl Document {
37+ pub fn new ( content : & str ) ->Document {
38+ Document {
39+ path : PathBuf :: new ( ) ,
40+ description : None ,
41+ image : None ,
42+ title : "404" . to_string ( ) ,
43+ toc_links : Vec :: new ( ) ,
44+ html : content. to_string ( ) ,
45+ }
46+ }
47+
4248pub async fn from_path ( path : & PathBuf ) -> anyhow:: Result < Document , std:: io:: Error > {
43- let contents =match tokio:: fs:: read_to_string ( & path) . await {
44- Ok ( contents) => contents,
45- Err ( _) =>String :: from ( "<h3>Failed to find your requested document!</h3>" ) ,
46- } ;
49+ let contents = tokio:: fs:: read_to_string ( & path) . await ?;
4750
4851let parts = contents. split ( "---" ) . collect :: < Vec < & str > > ( ) ;
4952
@@ -156,7 +159,7 @@ impl Collection {
156159mut path : PathBuf ,
157160cluster : & Cluster ,
158161origin : & Origin < ' _ > ,
159- ) ->Result < ResponseOk , Status > {
162+ ) ->Result < ResponseOk , crate :: responses :: NotFound > {
160163info ! ( "get_content: {} | {path:?}" , self . name) ;
161164
162165if origin. path ( ) . ends_with ( "/" ) {
@@ -273,17 +276,21 @@ impl Collection {
273276}
274277
275278// renders document in layout
276- async fn render < ' a > ( & self , path : & ' a PathBuf , cluster : & Cluster ) ->Result < ResponseOk , Status > {
279+ async fn render < ' a > (
280+ & self ,
281+ path : & ' a PathBuf ,
282+ cluster : & Cluster ,
283+ ) ->Result < ResponseOk , crate :: responses:: NotFound > {
284+ let user =if cluster. context . user . is_anonymous ( ) {
285+ None
286+ } else {
287+ Some ( cluster. context . user . clone ( ) )
288+ } ;
289+
277290match Document :: from_path ( & path) . await {
278291Ok ( doc) =>{
279292let index =self . open_index ( doc. path ) ;
280293
281- let user =if cluster. context . user . is_anonymous ( ) {
282- None
283- } else {
284- Some ( cluster. context . user . clone ( ) )
285- } ;
286-
287294let mut layout =crate :: templates:: Layout :: new ( & doc. title , Some ( cluster) ) ;
288295if let Some ( image) = doc. image {
289296 layout. image ( & config:: asset_url ( image. into ( ) ) ) ;
@@ -306,7 +313,30 @@ impl Collection {
306313) )
307314}
308315// Return page not found on bad path
309- _ =>Err ( Status :: NotFound ) ,
316+ _ =>{
317+ let mut layout =crate :: templates:: Layout :: new ( "404" , None ) ;
318+
319+ let doc =crate :: api:: cms:: Document :: new (
320+ r#"
321+ <div style='height: 80vh'>
322+ <h2>Oops, document not found!</h2>
323+ <p>The document you are searching for may have been moved or replaced with better content.</p>
324+ </div>"# ,
325+ ) ;
326+
327+ if let Some ( user) =& user{
328+ layout. user ( user) ;
329+ }
330+
331+ layout
332+ . nav_links ( & self . index )
333+ . nav_title ( & self . name )
334+ . footer ( cluster. context . marketing_footer . to_string ( ) ) ;
335+
336+ layout. render ( crate :: templates:: Article { content : doc. html } ) ;
337+
338+ Err ( crate :: responses:: NotFound ( layout. into ( ) ) )
339+ }
310340}
311341}
312342}
@@ -344,7 +374,7 @@ async fn get_blog(
344374path : PathBuf ,
345375cluster : & Cluster ,
346376origin : & Origin < ' _ > ,
347- ) ->Result < ResponseOk , Status > {
377+ ) ->Result < ResponseOk , crate :: responses :: NotFound > {
348378BLOG . get_content ( path, cluster, origin) . await
349379}
350380
@@ -353,7 +383,7 @@ async fn get_careers(
353383path : PathBuf ,
354384cluster : & Cluster ,
355385origin : & Origin < ' _ > ,
356- ) ->Result < ResponseOk , Status > {
386+ ) ->Result < ResponseOk , crate :: responses :: NotFound > {
357387CAREERS . get_content ( path, cluster, origin) . await
358388}
359389
@@ -362,7 +392,7 @@ async fn get_docs(
362392path : PathBuf ,
363393cluster : & Cluster ,
364394origin : & Origin < ' _ > ,
365- ) ->Result < ResponseOk , Status > {
395+ ) ->Result < ResponseOk , crate :: responses :: NotFound > {
366396DOCS . get_content ( path, cluster, origin) . await
367397}
368398
@@ -550,7 +580,7 @@ This is the end of the markdown
550580let rsp = req. dispatch ( ) . await ;
551581
552582assert ! (
553- rsp. status( ) ==Status :: Ok ,
583+ rsp. status( ) ==Status :: NotFound ,
554584"Returned status {:?}" ,
555585 rsp. status( )
556586) ;