update cli and follow template extentions
This commit is contained in:
		
							parent
							
								
									aa18b587dd
								
							
						
					
					
						commit
						cc3e106145
					
				
							
								
								
									
										134
									
								
								src/main.rs
									
									
									
									
									
								
							
							
						
						
									
										134
									
								
								src/main.rs
									
									
									
									
									
								
							| @ -4,36 +4,75 @@ use minijinja::Environment; | |||||||
| mod render; | mod render; | ||||||
| use render::{Renderer, IndexItem, build_jinja_env, Template}; | use render::{Renderer, IndexItem, build_jinja_env, Template}; | ||||||
| 
 | 
 | ||||||
| const SRC_PATH: &'static str = "../src"; | const SRC_PATH: &'static str = "./src/"; | ||||||
| const OUT_PATH: &'static str = "./html/"; | const OUT_PATH: &'static str = "./html/"; | ||||||
| 
 | 
 | ||||||
| fn render_index(out_path: &Path, index: &IndexItem, cur_path: &Path, site_index: &Renderer, jinja_env: Option<&Environment>) { | fn render_index( | ||||||
|  |     out_path: &Path, | ||||||
|  |     index: &IndexItem, | ||||||
|  |     cur_path: &Path, | ||||||
|  |     site_index: &Renderer, | ||||||
|  |     templates: Option<Vec<Box<Template>>>, | ||||||
|  |     jinja_env: Option<&Environment> | ||||||
|  | ) { | ||||||
|     let dest_path: &Path = &cur_path.join(&index.friendly); |     let dest_path: &Path = &cur_path.join(&index.friendly); | ||||||
|     println!("dest_path: {:?}", dest_path); |     // println!("dest_path: {:?}", dest_path);
 | ||||||
|  | 
 | ||||||
|  |     let templates = match templates { | ||||||
|  |         Some(template) => template, | ||||||
|  |         None => Template::index(&site_index.path.join("templates")), | ||||||
|  |     }; | ||||||
| 
 | 
 | ||||||
|     let jinja_env = match jinja_env { |     let jinja_env = match jinja_env { | ||||||
|         Some(env) => env, |         Some(env) => env, | ||||||
|         None => &build_jinja_env(Template::index(&site_index.path.join("templates"))), |         None => &build_jinja_env(templates.clone()), | ||||||
|     }; |     }; | ||||||
| 
 | 
 | ||||||
|     match &index.src { |     match &index.src { | ||||||
|         Some(src) => { |         Some(src) => { | ||||||
|  |             // a source file is available. try to render it
 | ||||||
|  | 
 | ||||||
|             let friendly = match index.friendly.len() { |             let friendly = match index.friendly.len() { | ||||||
|                 0 => String::from("index"), |                 0 => String::from("index"), | ||||||
|                 _ => index.friendly.clone() |                 _ => index.friendly.clone() | ||||||
|             }; |             }; | ||||||
|             
 |             
 | ||||||
|             if !index.is_asset { |             if !index.is_asset { | ||||||
|                 let dest_path: &Path = &cur_path.join(format!("{}.{}", friendly, index.target_extention)); |                 // find template
 | ||||||
|  |                 let templ: Option<Template> = { | ||||||
|  |                     let mut out = None; | ||||||
|  |                     for templ in templates.clone() { | ||||||
|  |                         if let Some(templ) = templ.search(index.template.clone()) { | ||||||
|  |                             out = Some(templ); | ||||||
|  |                             break; | ||||||
|  |                         } | ||||||
|  |                     } | ||||||
|  |                     out | ||||||
|  |                 }; | ||||||
|  | 
 | ||||||
|  |                 // get output file extention
 | ||||||
|  |                 let extention = match index.target_extention.len() { | ||||||
|  |                     0 => match templ { | ||||||
|  |                         Some(templ) => templ.extention, | ||||||
|  |                         None => String::from("html") | ||||||
|  |                     } | ||||||
|  |                     _ => index.target_extention.clone() | ||||||
|  |                 }; | ||||||
|  |                 let dest_path: &Path = &cur_path.join(format!("{}.{}", friendly, extention)); | ||||||
|  |                 // render the content
 | ||||||
|  |                 println!("INFO: render {}", dest_path.to_str().unwrap()); | ||||||
|                 match site_index.render_page(index, &site_index.site, jinja_env) { |                 match site_index.render_page(index, &site_index.site, jinja_env) { | ||||||
|                     Some(html) => { |                     Some(content) => { | ||||||
|                         let _ = fs::write(dest_path, html); |                         let _ = fs::write(dest_path, content); | ||||||
|                     }, |                     }, | ||||||
|                     None => todo!(), |                     None => todo!(), | ||||||
|                 }; |                 }; | ||||||
|             } |             } | ||||||
|             else { |             else { | ||||||
|                 let _ = fs::copy(src, &cur_path.join(friendly)); |                 // file is an asset, no rendering done for assets
 | ||||||
|  |                 let dest_path: &Path = &cur_path.join(friendly); | ||||||
|  |                 println!("INFO: copy {}", dest_path.to_str().unwrap()); | ||||||
|  |                 let _ = fs::copy(src, dest_path); | ||||||
|             } |             } | ||||||
|         }, |         }, | ||||||
|         None => { |         None => { | ||||||
| @ -42,40 +81,83 @@ fn render_index(out_path: &Path, index: &IndexItem, cur_path: &Path, site_index: | |||||||
|     }; |     }; | ||||||
| 
 | 
 | ||||||
|     for page in &index.sub_pages { |     for page in &index.sub_pages { | ||||||
|         render_index(out_path, page, dest_path, &site_index, Some(&jinja_env)); |         render_index(out_path, page, dest_path, &site_index, Some(templates.clone()), Some(&jinja_env)); | ||||||
|     } |     } | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
|  | fn usage() { | ||||||
|  |     println!("webtemplate [--output=<dir>] [--src=<dir>]"); | ||||||
|  | } | ||||||
|  | 
 | ||||||
| fn main() { | fn main() { | ||||||
| 
 | 
 | ||||||
|     let mut src_path_str: String = SRC_PATH.to_string(); |     let mut src_path_str: String = SRC_PATH.to_string(); | ||||||
|     let mut out_path_str: String = OUT_PATH.to_string(); |     let mut out_path_str: String = OUT_PATH.to_string(); | ||||||
| 
 | 
 | ||||||
|     let mut i: u8 = 0; |  | ||||||
|     for arg in env::args() { |     for arg in env::args() { | ||||||
|         match i { |         if arg.starts_with("--") { | ||||||
|             0 => {} |             let mut parts = arg.split('='); | ||||||
|             1 => { |             let option: String = match parts.next() { | ||||||
|                 src_path_str = arg; |                 None => { | ||||||
|  |                     println!("WARN: argument parsing: faild to split argument"); | ||||||
|  |                     continue; | ||||||
|  |                 }, | ||||||
|  |                 Some(str) => { | ||||||
|  |                     let mut str = String::from(str); | ||||||
|  |                     str.remove(0); | ||||||
|  |                     str.remove(0); | ||||||
|  |                     str | ||||||
|  |                 } | ||||||
|  |             }; | ||||||
|  |             let value = match parts.next() { | ||||||
|  |                 None => None, | ||||||
|  |                 Some(str) => Some(String::from(str)) | ||||||
|  |             }; | ||||||
|  | 
 | ||||||
|  |             match option.as_str() { | ||||||
|  |                 "output" => { | ||||||
|  |                     if let Some(value) = value { | ||||||
|  |                         out_path_str = value; | ||||||
|  |                     } else { | ||||||
|  |                         println!("ERROR: no value given for output"); | ||||||
|  |                         usage(); | ||||||
|  |                         return; | ||||||
|  |                     } | ||||||
|  |                 } | ||||||
|  |                 "src" => { | ||||||
|  |                     if let Some(value) = value { | ||||||
|  |                         src_path_str = value; | ||||||
|  |                     } else { | ||||||
|  |                         println!("ERROR: no value given for output"); | ||||||
|  |                         usage(); | ||||||
|  |                         return; | ||||||
|  |                     } | ||||||
|  |                 } | ||||||
|  |                 "help" => { | ||||||
|  |                     usage(); | ||||||
|  |                 } | ||||||
|  |                 _ => { | ||||||
|  |                     println!("ERROR: invalid option {}", option); | ||||||
|  |                     usage(); | ||||||
|  |                     return; | ||||||
|  |                 } | ||||||
|             } |             } | ||||||
|             2 => { |  | ||||||
|                 out_path_str = arg; |  | ||||||
|             } |  | ||||||
|             _ => {} |  | ||||||
|         } |         } | ||||||
|         i += 1; |  | ||||||
|     } |     } | ||||||
| 
 | 
 | ||||||
|     let src_path = Path::new(&src_path_str); |     let src_path = Path::new(&src_path_str); | ||||||
|     let out_path = Path::new(&out_path_str); |     let out_path = Path::new(&out_path_str); | ||||||
| 
 | 
 | ||||||
|     let index = Renderer::index(src_path).unwrap(); |     // scan all pages, template, components, etc.
 | ||||||
| 
 |     let index = match Renderer::index(src_path) { | ||||||
| 
 |         Some(index) => index, | ||||||
|     println!(""); |         None => { | ||||||
|     println!("index:"); |             println!("ERROR: src directory not found ({})", src_path_str); | ||||||
|     println!("{:?}", index); |             return; | ||||||
|  |         }, | ||||||
|  |     }; | ||||||
| 
 | 
 | ||||||
|  |     // render website
 | ||||||
|     let _ = fs::create_dir_all(out_path); |     let _ = fs::create_dir_all(out_path); | ||||||
|     render_index(out_path, &index.site, out_path, &index, None); |     render_index(out_path, &index.site, out_path, &index, None, None); | ||||||
| } | } | ||||||
|  | |||||||
| @ -27,7 +27,7 @@ fn build_jinja_env_dir<'a>(templates: Vec<Box<indexer::Template>>) -> Environmen | |||||||
|                     if let Some(src) = plate.src { |                     if let Some(src) = plate.src { | ||||||
|                         let name = format!("{}/{}", template.name.clone(), plate.name.clone()); |                         let name = format!("{}/{}", template.name.clone(), plate.name.clone()); | ||||||
|                         match env.add_template_owned(name.clone(), src) { |                         match env.add_template_owned(name.clone(), src) { | ||||||
|                             Ok(_) => println!("template name: {name}"), |                             Ok(_) => {}, //println!("template name: {name}"),
 | ||||||
|                             Err(err) => println!("ERROR: failt to add template \"{name}\" ({err:?})"), |                             Err(err) => println!("ERROR: failt to add template \"{name}\" ({err:?})"), | ||||||
|                         } |                         } | ||||||
|                     } |                     } | ||||||
|  | |||||||
| @ -7,14 +7,23 @@ pub mod indexer { | |||||||
| 
 | 
 | ||||||
|     #[derive(Debug)] |     #[derive(Debug)] | ||||||
|     pub struct IndexItem { |     pub struct IndexItem { | ||||||
|  |         // path to source file. If none, it is a directory without an index page
 | ||||||
|         pub src: Option<String>, |         pub src: Option<String>, | ||||||
|  |         // if it is an asset file
 | ||||||
|         pub is_asset: bool, |         pub is_asset: bool, | ||||||
|  |         // url path with starting slash
 | ||||||
|         pub path: String, |         pub path: String, | ||||||
|  |         // the title of the page
 | ||||||
|         pub title: String, |         pub title: String, | ||||||
|  |         // url friendly name
 | ||||||
|         pub friendly: String, |         pub friendly: String, | ||||||
|  |         // if the page sould be in the site navigator
 | ||||||
|         pub public: bool, |         pub public: bool, | ||||||
|  |         // name of the remplate to use
 | ||||||
|         pub template: String, |         pub template: String, | ||||||
|  |         // list of sub pages
 | ||||||
|         pub sub_pages: Vec<Box<IndexItem>>, |         pub sub_pages: Vec<Box<IndexItem>>, | ||||||
|  |         // extention of the output file
 | ||||||
|         pub target_extention: String, |         pub target_extention: String, | ||||||
|     } |     } | ||||||
|     impl IndexItem { |     impl IndexItem { | ||||||
| @ -28,7 +37,7 @@ pub mod indexer { | |||||||
|                 public: false, |                 public: false, | ||||||
|                 sub_pages: Vec::new(), |                 sub_pages: Vec::new(), | ||||||
|                 template: String::from("default"), |                 template: String::from("default"), | ||||||
|                 target_extention: String::from("html"), |                 target_extention: String::from(""), | ||||||
|             } |             } | ||||||
|         } |         } | ||||||
| 
 | 
 | ||||||
| @ -199,7 +208,7 @@ pub mod indexer { | |||||||
|         } |         } | ||||||
|     } |     } | ||||||
| 
 | 
 | ||||||
|     #[derive(Debug)] |     #[derive(Debug, Clone)] | ||||||
|     pub struct Template { |     pub struct Template { | ||||||
|         pub name: String, |         pub name: String, | ||||||
|         pub extention: String, |         pub extention: String, | ||||||
| @ -218,14 +227,41 @@ pub mod indexer { | |||||||
|             } |             } | ||||||
|         } |         } | ||||||
| 
 | 
 | ||||||
|         pub fn index(path: &Path) -> Vec<Box<Template>> { |         pub fn search(&self, path: String) -> Option<Self> { | ||||||
|             match Template::scan_template(path) { |             let mut parts = path.split("/"); | ||||||
|  |             match parts.next() { | ||||||
|  |                 None => None, | ||||||
|  |                 Some(first) => { | ||||||
|  |                     if self.name == first { | ||||||
|  |                         let sub_path = parts.collect::<Vec<&str>>().join("/"); | ||||||
|  |                         if sub_path.len() == 0 { | ||||||
|  |                             return Some(self.clone()) | ||||||
|  |                         } | ||||||
|  |                         return self.search_sub(path) | ||||||
|  |                     } | ||||||
|  |                     None | ||||||
|  |                 } | ||||||
|  |             } | ||||||
|  |             
 | ||||||
|  |         } | ||||||
|  | 
 | ||||||
|  |         fn search_sub(&self, path: String) -> Option<Self> { | ||||||
|  |             for templ in self.sub_templates.clone() { | ||||||
|  |                 if let Some(templ) = templ.search(path.clone()) { | ||||||
|  |                     return Some(templ) | ||||||
|  |                 } | ||||||
|  |             } | ||||||
|  |             None | ||||||
|  |         } | ||||||
|  | 
 | ||||||
|  |         pub fn index(path: &Path) -> Vec<Box<Self>> { | ||||||
|  |             match Self::scan_template(path) { | ||||||
|                 Some(templates) => templates.sub_templates, |                 Some(templates) => templates.sub_templates, | ||||||
|                 None => Vec::new(), |                 None => Vec::new(), | ||||||
|             } |             } | ||||||
|         } |         } | ||||||
| 
 | 
 | ||||||
|         fn scan_template(path: &Path) -> Option<Template> { |         fn scan_template(path: &Path) -> Option<Self> { | ||||||
|             let mut item = Template::new(); |             let mut item = Template::new(); | ||||||
|             if let Some(file_name) = path.file_name() { |             if let Some(file_name) = path.file_name() { | ||||||
|                 if let Some(file_name) = file_name.to_str() { |                 if let Some(file_name) = file_name.to_str() { | ||||||
| @ -254,7 +290,7 @@ pub mod indexer { | |||||||
|                         let mut matches = re.captures_iter(&file_name); |                         let mut matches = re.captures_iter(&file_name); | ||||||
|                         if let Some(dot) = matches.next() { |                         if let Some(dot) = matches.next() { | ||||||
|                             let dot = dot.get(0).unwrap(); |                             let dot = dot.get(0).unwrap(); | ||||||
|                             item.extention = file_name.clone().drain(dot.start()..).collect(); |                             item.extention = file_name.clone().drain(dot.end()..).collect(); | ||||||
|                             item.name = file_name.clone().drain(..dot.start()).collect(); |                             item.name = file_name.clone().drain(..dot.start()).collect(); | ||||||
|                             return Some(item); |                             return Some(item); | ||||||
|                         } |                         } | ||||||
|  | |||||||
| @ -110,7 +110,7 @@ fn md_preprocessor(md: &String, jinja_env: &Environment) -> String { | |||||||
| } | } | ||||||
| 
 | 
 | ||||||
| fn render_component(component: &str, args: Value, jinja_env: &Environment) -> Option<String> { | fn render_component(component: &str, args: Value, jinja_env: &Environment) -> Option<String> { | ||||||
|     println!("  tag found: {component} <- {args}"); |     // println!("  tag found: {component} <- {args}");
 | ||||||
|     match jinja_env.get_template(&format!("components/{component}")) { |     match jinja_env.get_template(&format!("components/{component}")) { | ||||||
|         Ok(ding) => { |         Ok(ding) => { | ||||||
|             // match ding.render(context! { args => args }) {
 |             // match ding.render(context! { args => args }) {
 | ||||||
|  | |||||||
		Loading…
	
	
			
			x
			
			
		
	
		Reference in New Issue
	
	Block a user