feat: static documentation pages
This commit is contained in:
		
							parent
							
								
									fe1cf7ce8a
								
							
						
					
					
						commit
						7468aa20ab
					
				
					 6 changed files with 58 additions and 7 deletions
				
			
		|  | @ -21,3 +21,4 @@ | |||
| **/values.dev.yaml | ||||
| LICENSE | ||||
| README.md | ||||
| static-pages/* | ||||
|  |  | |||
|  | @ -12,6 +12,7 @@ | |||
| // | ||||
| // 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/>. | ||||
| using System.Text.RegularExpressions; | ||||
| using Foxnouns.Backend.Dto; | ||||
| using Foxnouns.Backend.Utils; | ||||
| using Microsoft.AspNetCore.Mvc; | ||||
|  | @ -19,7 +20,7 @@ using Microsoft.AspNetCore.Mvc; | |||
| namespace Foxnouns.Backend.Controllers; | ||||
| 
 | ||||
| [Route("/api/v2/meta")] | ||||
| public class MetaController : ApiControllerBase | ||||
| public partial class MetaController : ApiControllerBase | ||||
| { | ||||
|     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")] | ||||
|     public IActionResult BrewCoffee() => | ||||
|         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, | ||||
| }).disable(["heading", "lheading", "link", "table", "blockquote"]); | ||||
| 
 | ||||
| const unsafeMd = new MarkdownIt({ | ||||
| 	html: false, | ||||
| 	breaks: true, | ||||
| 	linkify: true, | ||||
| }); | ||||
| const unsafeMd = new MarkdownIt(); | ||||
| 
 | ||||
| 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