155 lines
3.0 KiB
Markdown
155 lines
3.0 KiB
Markdown
|
|
# Static Pages / CMS - Sprint 14
|
|||
|
|
|
|||
|
|
## Scope
|
|||
|
|
|
|||
|
|
Sprint 14 adds configuration-driven CMS support for unlimited marketplace static pages.
|
|||
|
|
|
|||
|
|
Out of scope:
|
|||
|
|
- backend save endpoints
|
|||
|
|
- marketplace-specific content logic
|
|||
|
|
- hardcoded page names
|
|||
|
|
|
|||
|
|
## Feature Architecture
|
|||
|
|
|
|||
|
|
```text
|
|||
|
|
src/app/features/content-management/
|
|||
|
|
facade/
|
|||
|
|
services/
|
|||
|
|
models/
|
|||
|
|
pages/
|
|||
|
|
components/
|
|||
|
|
```
|
|||
|
|
|
|||
|
|
Main pieces:
|
|||
|
|
- `ContentPageService` normalizes bootstrap static page data
|
|||
|
|
- `ContentManagementFacade` exposes normalized pages and validation helpers
|
|||
|
|
- `StaticPagesEditorComponent` integrates CMS editing into Project Editor
|
|||
|
|
|
|||
|
|
## Bootstrap Structure
|
|||
|
|
|
|||
|
|
Static pages live under `bootstrap.staticPages`.
|
|||
|
|
|
|||
|
|
Supported properties per page:
|
|||
|
|
- `id`
|
|||
|
|
- `slug`
|
|||
|
|
- `title`
|
|||
|
|
- `showInFooter`
|
|||
|
|
- `showInHeader`
|
|||
|
|
- `showInSitemap`
|
|||
|
|
- `icon`
|
|||
|
|
- `order`
|
|||
|
|
- `visibility`
|
|||
|
|
- `requiresAuthentication`
|
|||
|
|
- `footerGroup`
|
|||
|
|
- `translations`
|
|||
|
|
- `html`
|
|||
|
|
- `seo`
|
|||
|
|
|
|||
|
|
## Translation Model
|
|||
|
|
|
|||
|
|
Content can be stored in `translations[locale]`:
|
|||
|
|
- `title`
|
|||
|
|
- `html`
|
|||
|
|
- `seo`
|
|||
|
|
|
|||
|
|
Legacy structures remain supported through normalization.
|
|||
|
|
|
|||
|
|
## Dynamic Routing
|
|||
|
|
|
|||
|
|
Frontend uses dynamic static page resolution instead of manual page registration.
|
|||
|
|
|
|||
|
|
Current route surface:
|
|||
|
|
- `/:lang/:staticPath`
|
|||
|
|
- legacy compatibility: `/:lang/page/:key`
|
|||
|
|
|
|||
|
|
Resolver maps route slug to bootstrap-configured page.
|
|||
|
|
|
|||
|
|
## Header Generation
|
|||
|
|
|
|||
|
|
Pages with `showInHeader: true` render in header navigation.
|
|||
|
|
|
|||
|
|
No hardcoded page list required.
|
|||
|
|
|
|||
|
|
## Footer Generation
|
|||
|
|
|
|||
|
|
Footer can render grouped static pages from bootstrap flags and metadata.
|
|||
|
|
|
|||
|
|
Supported grouping:
|
|||
|
|
- Company
|
|||
|
|
n- Customer
|
|||
|
|
- Legal
|
|||
|
|
- Support
|
|||
|
|
- Social
|
|||
|
|
|
|||
|
|
Social links come from footer bootstrap config.
|
|||
|
|
|
|||
|
|
## Rendering
|
|||
|
|
|
|||
|
|
`StaticPageComponent` now:
|
|||
|
|
- resolves content by slug or id
|
|||
|
|
- reloads content when language changes
|
|||
|
|
- updates document title/meta
|
|||
|
|
- supports RTL-ready `dir` switching
|
|||
|
|
- renders backend HTML safely through sanitization
|
|||
|
|
|
|||
|
|
## Editor Integration
|
|||
|
|
|
|||
|
|
Project Editor now includes `Static Pages` section.
|
|||
|
|
|
|||
|
|
Supported actions:
|
|||
|
|
- create page
|
|||
|
|
- delete page
|
|||
|
|
- enable footer/header/sitemap visibility
|
|||
|
|
- edit slug
|
|||
|
|
- edit icon
|
|||
|
|
- edit order
|
|||
|
|
- edit translations
|
|||
|
|
- edit HTML
|
|||
|
|
|
|||
|
|
## Validation
|
|||
|
|
|
|||
|
|
Current validation prevents:
|
|||
|
|
- duplicate slugs
|
|||
|
|
- empty titles
|
|||
|
|
|
|||
|
|
## Future Backend Endpoints
|
|||
|
|
|
|||
|
|
Recommended future endpoints:
|
|||
|
|
- `GET /builder/content-pages`
|
|||
|
|
- `PUT /builder/content-pages`
|
|||
|
|
- `POST /builder/content-pages/import`
|
|||
|
|
- `GET /builder/content-pages/export`
|
|||
|
|
- `POST /builder/content-pages/validate`
|
|||
|
|
|
|||
|
|
## Example Bootstrap
|
|||
|
|
|
|||
|
|
```json
|
|||
|
|
{
|
|||
|
|
"staticPages": {
|
|||
|
|
"about": {
|
|||
|
|
"id": "about",
|
|||
|
|
"slug": "about",
|
|||
|
|
"title": { "en": "About Us", "ru": "О нас" },
|
|||
|
|
"showInFooter": true,
|
|||
|
|
"showInHeader": true,
|
|||
|
|
"showInSitemap": true,
|
|||
|
|
"icon": "info",
|
|||
|
|
"order": 1,
|
|||
|
|
"requiresAuthentication": false,
|
|||
|
|
"footerGroup": "Company",
|
|||
|
|
"translations": {
|
|||
|
|
"en": {
|
|||
|
|
"title": "About Us",
|
|||
|
|
"html": "<h2>About</h2><p>Company story</p>"
|
|||
|
|
}
|
|||
|
|
},
|
|||
|
|
"seo": {
|
|||
|
|
"title": { "en": "About Us" },
|
|||
|
|
"description": { "en": "About our marketplace" },
|
|||
|
|
"canonical": "/about"
|
|||
|
|
}
|
|||
|
|
}
|
|||
|
|
}
|
|||
|
|
}
|
|||
|
|
```
|