Serve the pages the panel publishes
The landing was one address. It now also answers on the pages the panel publishes -- "Sobre nosotros" and the like -- at the addresses the API itself chooses: `path` and `alternates` put the default language unprefixed and every other one under its code, so `/sobre-nosotros`, `/en/about-us`, `/ca/qui-som` are the routes. `core/api.ts#contentRoute` is the single rule for that shape, and `/es/…` is deliberately not one of them, so a page has one address rather than two. Two routes share one load function, because Analog wants a `.server.ts` beside each `.page.ts`: `[slug]` for the default language, and `[locale]/[slug]` for the rest. Whether a slug exists is the API's answer, not something the route table knows, so the 404 middleware lets page-shaped addresses through and `ui/content-page.ts` sets the status itself from `ngOnInit` -- the same `injectResponse()` the landing uses for its 503, and `ngOnInit` because an input has no value in the constructor. Body HTML comes from the panel's editor and goes through Angular's sanitiser. The header shows the featured pages beside the section anchors; the footer lists them all. On a page the language switcher follows the API's `alternates`, and a language with no translation leads to the landing in that language instead of a 404. Verified: lint, 20 unit tests, build, and 6 e2e -- including a new one that a page-shaped address the API does not know answers 404 with `robots: noindex`. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
This commit is contained in:
@@ -89,7 +89,8 @@ export interface Copy {
|
||||
error: string;
|
||||
closed: string;
|
||||
};
|
||||
footer: { rights: string };
|
||||
footer: { rights: string; pages: string };
|
||||
page: { back: string; skip: string };
|
||||
maintenance: { title: string; back: string; until: string };
|
||||
}
|
||||
|
||||
@@ -181,6 +182,11 @@ const es: Copy = {
|
||||
},
|
||||
footer: {
|
||||
rights: 'Todos los derechos reservados.',
|
||||
pages: 'Más sobre Pireon',
|
||||
},
|
||||
page: {
|
||||
back: 'Volver al inicio',
|
||||
skip: 'Saltar al contenido',
|
||||
},
|
||||
maintenance: {
|
||||
title: 'Estamos de mantenimiento',
|
||||
@@ -277,6 +283,11 @@ const en: Copy = {
|
||||
},
|
||||
footer: {
|
||||
rights: 'All rights reserved.',
|
||||
pages: 'More about Pireon',
|
||||
},
|
||||
page: {
|
||||
back: 'Back to home',
|
||||
skip: 'Skip to content',
|
||||
},
|
||||
maintenance: {
|
||||
title: 'We are under maintenance',
|
||||
@@ -373,6 +384,11 @@ const ca: Copy = {
|
||||
},
|
||||
footer: {
|
||||
rights: 'Tots els drets reservats.',
|
||||
pages: 'Més sobre Pireon',
|
||||
},
|
||||
page: {
|
||||
back: "Tornar a l'inici",
|
||||
skip: 'Salta al contingut',
|
||||
},
|
||||
maintenance: {
|
||||
title: 'Estem de manteniment',
|
||||
|
||||
Reference in New Issue
Block a user