forked from fediversity/fediversity
		
	make page templates granularly overridable
This commit is contained in:
		
							parent
							
								
									ef5594d963
								
							
						
					
					
						commit
						00e3cfcb52
					
				
					 8 changed files with 49 additions and 51 deletions
				
			
		|  | @ -1,13 +1,14 @@ | |||
| { config, lib, ... }: | ||||
| let | ||||
|   inherit (config) pages; | ||||
|   cfg = config; | ||||
| in | ||||
| { | ||||
|   imports = lib.nixFiles ./.; | ||||
| 
 | ||||
|   collections.news.type = config.content-types.article; | ||||
|   collections.news.type = cfg.content-types.article; | ||||
| 
 | ||||
|   pages.index = { link, ... }: { | ||||
|   pages.index = { config, link, ... }: { | ||||
|     title = "Fediversity"; | ||||
|     description = "Fediversity web site"; | ||||
|     summary = '' | ||||
|  | @ -52,12 +53,19 @@ in | |||
| 
 | ||||
|       ${ | ||||
|         let | ||||
|           sorted = with lib; reverseList (sortOn (entry: entry.date) config.collections.news.entry); | ||||
|           sorted = with lib; reverseList (sortOn (entry: entry.date) cfg.collections.news.entry); | ||||
|         in | ||||
|         lib.join "\n" (map (article: '' | ||||
|           - ${article.date} [${article.title}](${link article}) | ||||
|         '') sorted) | ||||
|       } | ||||
|     ''; | ||||
|     outputs.html = (cfg.templates.html.page config).override { | ||||
|       html.body.content = lib.mkForce [ | ||||
|         # don't show the page title as a heading | ||||
|         (cfg.menus.main.outputs.html config) | ||||
|         (cfg.templates.html.markdown { inherit (config) name body; }) | ||||
|       ]; | ||||
|     }; | ||||
|   }; | ||||
| } | ||||
|  |  | |||
|  | @ -1,5 +1,8 @@ | |||
| { lib }: | ||||
| rec { | ||||
|   template = g: f: x: | ||||
|     (g (f x)) // { override = o: g (lib.recursiveUpdate (f x) o); }; | ||||
| 
 | ||||
|   /** | ||||
|     Recursively replace occurrences of `from` with `to` within `string` | ||||
| 
 | ||||
|  |  | |||
|  | @ -21,7 +21,7 @@ in | |||
|       description = '' | ||||
|         Collection of named helper functions for conversion different structured representations which can be rendered to a string | ||||
|       ''; | ||||
|       type = recursiveAttrs (with types; functionTo (coercedTo attrs toString str)); | ||||
|       type = recursiveAttrs (with types; functionTo (either str attrs)); | ||||
|     }; | ||||
| 
 | ||||
|   options.files = mkOption { | ||||
|  |  | |||
|  | @ -4,19 +4,21 @@ let | |||
|     mkOption | ||||
|     types | ||||
|     ; | ||||
|   # TODO: optionally run the whole thing through the validator | ||||
|   # https://github.com/validator/validator | ||||
|   render-html = document: | ||||
|     let | ||||
|       eval = lib.evalModules { | ||||
|         class = "DOM"; | ||||
|         modules = [ document (import ./dom.nix) ]; | ||||
|       }; | ||||
|     in | ||||
|     toString eval.config; | ||||
| in | ||||
| { | ||||
|   config.templates.html = { | ||||
|     dom = document: | ||||
|       let | ||||
|         eval = lib.evalModules { | ||||
|           class = "DOM"; | ||||
|           modules = [ document (import ./dom.nix) ]; | ||||
|         }; | ||||
|       in | ||||
|       { | ||||
|         __toString = _: toString eval.config; | ||||
|         value = eval.config; | ||||
|       }; | ||||
| 
 | ||||
|     markdown = { name, body }: | ||||
|       let | ||||
|         commonmark = pkgs.runCommand "${name}.html" | ||||
|  |  | |||
|  | @ -5,14 +5,6 @@ let | |||
|     types | ||||
|     ; | ||||
|   cfg = config; | ||||
|   render-html = document: | ||||
|     let | ||||
|       eval = lib.evalModules { | ||||
|         class = "DOM"; | ||||
|         modules = [ document (import ../presentation/dom.nix) ]; | ||||
|       }; | ||||
|     in | ||||
|     toString eval.config; | ||||
| in | ||||
| { | ||||
|   content-types.article = { config, collection, ... }: { | ||||
|  | @ -35,7 +27,7 @@ in | |||
|       }; | ||||
|     }; | ||||
|     config.name = lib.slug config.title; | ||||
|     config.outputs.html = lib.mkForce (render-html { | ||||
|     config.outputs.html = lib.mkForce (cfg.templates.html.dom { | ||||
|       html = { | ||||
|         head = { | ||||
|           title.text = config.title; | ||||
|  |  | |||
|  | @ -68,7 +68,7 @@ in | |||
|     in | ||||
|     with lib; foldl | ||||
|       (acc: elem: acc // { | ||||
|         "${head elem.locations}.html" = builtins.toFile "${elem.name}.html" elem.outputs.html; | ||||
|         "${head elem.locations}.html" = builtins.toFile "${elem.name}.html" "${elem.outputs.html}"; | ||||
|       }) | ||||
|       { } | ||||
|       collections; | ||||
|  |  | |||
|  | @ -53,13 +53,11 @@ in | |||
|         #       names is soft. | ||||
|         default = target: with lib; "${relativePath (head config.locations) (head target.locations)}.html"; | ||||
|       }; | ||||
|       outputs.html = mkOption { | ||||
|         # TODO: make this of type DOM and convert to string at the output. | ||||
|         #       the output aggregator then only needs something string-coercible | ||||
|       outputs = mkOption { | ||||
|         description = '' | ||||
|           Representations of the document in different formats | ||||
|         ''; | ||||
|         type = with types; str; | ||||
|         type = with types; attrsOf (either str attrs); | ||||
|       }; | ||||
|     }; | ||||
|   }; | ||||
|  |  | |||
|  | @ -5,14 +5,6 @@ let | |||
|     types | ||||
|     ; | ||||
|   cfg = config; | ||||
|   render-html = document: | ||||
|     let | ||||
|       eval = lib.evalModules { | ||||
|         class = "DOM"; | ||||
|         modules = [ document (import ../presentation/dom.nix) ]; | ||||
|       }; | ||||
|     in | ||||
|     toString eval.config; | ||||
| in | ||||
| { | ||||
|   # TODO: enable i18n, e.g. via a nested attribute for language-specific content | ||||
|  | @ -27,7 +19,7 @@ in | |||
|       (acc: elem: acc // { | ||||
|         # TODO: create static redirects from `tail page.locations` | ||||
|         # TODO: the file name could correspond to the canonical location in the HTML representation | ||||
|         "${head elem.locations}.html" = builtins.toFile "${elem.name}.html" elem.outputs.html; | ||||
|         "${head elem.locations}.html" = builtins.toFile "${elem.name}.html" "${elem.outputs.html}"; | ||||
|       }) | ||||
|       { } | ||||
|       (attrValues config.pages); | ||||
|  | @ -59,19 +51,22 @@ in | |||
|         type = types.str; | ||||
|       }; | ||||
|     }; | ||||
|     config.outputs.html = render-html { | ||||
|       html = { | ||||
|         head = { | ||||
|           title.text = config.title; | ||||
|           meta.description = config.description; | ||||
|           link.canonical = lib.head config.locations; | ||||
|         }; | ||||
|         body.content = [ | ||||
|           (cfg.menus.main.outputs.html config) | ||||
|           { section.heading.content = config.title; } | ||||
|           (cfg.templates.html.markdown { inherit (config) name body; }) | ||||
|         ]; | ||||
|       }; | ||||
|     }; | ||||
| 
 | ||||
|     config.outputs.html = cfg.templates.html.page config; | ||||
|   }; | ||||
| 
 | ||||
|   config.templates.html.page = lib.template cfg.templates.html.dom (page: { | ||||
|     html = { | ||||
|       head = { | ||||
|         title.text = page.title; | ||||
|         meta.description = page.description; | ||||
|         link.canonical = lib.head page.locations; | ||||
|       }; | ||||
|       body.content = [ | ||||
|         (cfg.menus.main.outputs.html page) | ||||
|         { section.heading.content = page.title; } | ||||
|         (cfg.templates.html.markdown { inherit (page) name body; }) | ||||
|       ]; | ||||
|     }; | ||||
|   }); | ||||
| } | ||||
|  |  | |||
		Loading…
	
	Add table
		
		Reference in a new issue
	
	 Valentin Gagarin
							Valentin Gagarin