feat: static documentation pages
This commit is contained in:
		
							parent
							
								
									fe1cf7ce8a
								
							
						
					
					
						commit
						7468aa20ab
					
				
					 6 changed files with 58 additions and 7 deletions
				
			
		|  | @ -20,4 +20,5 @@ | ||||||
| **/secrets.dev.yaml | **/secrets.dev.yaml | ||||||
| **/values.dev.yaml | **/values.dev.yaml | ||||||
| LICENSE | LICENSE | ||||||
| README.md | README.md | ||||||
|  | static-pages/* | ||||||
|  |  | ||||||
|  | @ -12,6 +12,7 @@ | ||||||
| // | // | ||||||
| // You should have received a copy of the GNU Affero General Public License | // You should have received a copy of the GNU Affero General Public License | ||||||
| // along with this program.  If not, see <https://www.gnu.org/licenses/>. | // along with this program.  If not, see <https://www.gnu.org/licenses/>. | ||||||
|  | using System.Text.RegularExpressions; | ||||||
| using Foxnouns.Backend.Dto; | using Foxnouns.Backend.Dto; | ||||||
| using Foxnouns.Backend.Utils; | using Foxnouns.Backend.Utils; | ||||||
| using Microsoft.AspNetCore.Mvc; | using Microsoft.AspNetCore.Mvc; | ||||||
|  | @ -19,7 +20,7 @@ using Microsoft.AspNetCore.Mvc; | ||||||
| namespace Foxnouns.Backend.Controllers; | namespace Foxnouns.Backend.Controllers; | ||||||
| 
 | 
 | ||||||
| [Route("/api/v2/meta")] | [Route("/api/v2/meta")] | ||||||
| public class MetaController : ApiControllerBase | public partial class MetaController : ApiControllerBase | ||||||
| { | { | ||||||
|     private const string Repository = "https://codeberg.org/pronounscc/pronouns.cc"; |     private const string Repository = "https://codeberg.org/pronounscc/pronouns.cc"; | ||||||
| 
 | 
 | ||||||
|  | @ -48,7 +49,23 @@ public class MetaController : ApiControllerBase | ||||||
|             ) |             ) | ||||||
|         ); |         ); | ||||||
| 
 | 
 | ||||||
|  |     [HttpGet("page/{page}")] | ||||||
|  |     public async Task<IActionResult> GetStaticPageAsync(string page, CancellationToken ct = default) | ||||||
|  |     { | ||||||
|  |         if (!PageRegex().IsMatch(page)) | ||||||
|  |         { | ||||||
|  |             throw new ApiError.BadRequest("Invalid page name"); | ||||||
|  |         } | ||||||
|  | 
 | ||||||
|  |         string path = Path.Join(Directory.GetCurrentDirectory(), "static-pages", $"{page}.md"); | ||||||
|  |         string text = await System.IO.File.ReadAllTextAsync(path, ct); | ||||||
|  |         return Ok(text); | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|     [HttpGet("/api/v2/coffee")] |     [HttpGet("/api/v2/coffee")] | ||||||
|     public IActionResult BrewCoffee() => |     public IActionResult BrewCoffee() => | ||||||
|         Problem("Sorry, I'm a teapot!", statusCode: StatusCodes.Status418ImATeapot); |         Problem("Sorry, I'm a teapot!", statusCode: StatusCodes.Status418ImATeapot); | ||||||
|  | 
 | ||||||
|  |     [GeneratedRegex(@"^[a-z\-_]+$")]
 | ||||||
|  |     private static partial Regex PageRegex(); | ||||||
| } | } | ||||||
|  |  | ||||||
							
								
								
									
										1
									
								
								Foxnouns.Backend/static-pages/.gitignore
									
										
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										1
									
								
								Foxnouns.Backend/static-pages/.gitignore
									
										
									
									
										vendored
									
									
										Normal file
									
								
							|  | @ -0,0 +1 @@ | ||||||
|  | * | ||||||
|  | @ -7,11 +7,7 @@ const md = new MarkdownIt({ | ||||||
| 	linkify: true, | 	linkify: true, | ||||||
| }).disable(["heading", "lheading", "link", "table", "blockquote"]); | }).disable(["heading", "lheading", "link", "table", "blockquote"]); | ||||||
| 
 | 
 | ||||||
| const unsafeMd = new MarkdownIt({ | const unsafeMd = new MarkdownIt(); | ||||||
| 	html: false, |  | ||||||
| 	breaks: true, |  | ||||||
| 	linkify: true, |  | ||||||
| }); |  | ||||||
| 
 | 
 | ||||||
| export const renderMarkdown = (src: string | null) => (src ? sanitize(md.render(src)) : null); | export const renderMarkdown = (src: string | null) => (src ? sanitize(md.render(src)) : null); | ||||||
| 
 | 
 | ||||||
|  |  | ||||||
							
								
								
									
										14
									
								
								Foxnouns.Frontend/src/routes/page/[page]/+page.server.ts
									
										
									
									
									
										Normal file
									
								
							
							
						
						
									
										14
									
								
								Foxnouns.Frontend/src/routes/page/[page]/+page.server.ts
									
										
									
									
									
										Normal file
									
								
							|  | @ -0,0 +1,14 @@ | ||||||
|  | import { baseRequest } from "$api"; | ||||||
|  | import ApiError from "$api/error"; | ||||||
|  | 
 | ||||||
|  | export const load = async ({ fetch, params }) => { | ||||||
|  | 	const resp = await baseRequest("GET", `/meta/page/${params.page}`, { fetch }); | ||||||
|  | 	if (resp.status < 200 || resp.status > 299) { | ||||||
|  | 		const err = await resp.json(); | ||||||
|  | 		if ("code" in err) throw new ApiError(err); | ||||||
|  | 		else throw new ApiError(); | ||||||
|  | 	} | ||||||
|  | 
 | ||||||
|  | 	const pageText = await resp.text(); | ||||||
|  | 	return { page: params.page, text: pageText }; | ||||||
|  | }; | ||||||
							
								
								
									
										22
									
								
								Foxnouns.Frontend/src/routes/page/[page]/+page.svelte
									
										
									
									
									
										Normal file
									
								
							
							
						
						
									
										22
									
								
								Foxnouns.Frontend/src/routes/page/[page]/+page.svelte
									
										
									
									
									
										Normal file
									
								
							|  | @ -0,0 +1,22 @@ | ||||||
|  | <script lang="ts"> | ||||||
|  | 	import { renderUnsafeMarkdown } from "$lib/markdown"; | ||||||
|  | 	import type { PageData } from "./$types"; | ||||||
|  | 
 | ||||||
|  | 	type Props = { data: PageData }; | ||||||
|  | 	let { data }: Props = $props(); | ||||||
|  | 
 | ||||||
|  | 	let md = $derived(renderUnsafeMarkdown(data.text)); | ||||||
|  | 	let title = $derived.by(() => { | ||||||
|  | 		let title = data.text.split("\n")[0]; | ||||||
|  | 		if (title.startsWith("# ")) title = title.substring("# ".length); | ||||||
|  | 		return title; | ||||||
|  | 	}); | ||||||
|  | </script> | ||||||
|  | 
 | ||||||
|  | <svelte:head> | ||||||
|  | 	<title>{title} • pronouns.cc</title> | ||||||
|  | </svelte:head> | ||||||
|  | 
 | ||||||
|  | <div class="container"> | ||||||
|  | 	{@html md} | ||||||
|  | </div> | ||||||
		Loading…
	
	Add table
		Add a link
		
	
		Reference in a new issue