6.6 KiB
Site Content Management System
This document explains how to manage site content (modals, rules, etc.) using the new database-driven system.
Overview
The site content management system allows administrators to modify:
- Modal content (welcome modal, rules, instructions)
- Help text (paint faster, map lagging)
- Footer links and contact information
- Site title and branding
- Any other text content on the site
Content is stored in MySQL and can be edited through an admin interface, supporting multiple locales (English, Chinese, etc.).
Architecture
Database Schema
Table: SiteContent
id: Auto-incrementing primary keykey: Unique string identifier (e.g.,modal.rules.title)value: Text contentlocale: Language code (en, zh, etc.)createdAt: Creation timestampupdatedAt: Last update timestamp
Backend API Endpoints
Public Endpoint:
GET /api/site-content?locale=en- Fetch all content for a locale (used by frontend)
Admin Endpoints (require authentication & admin role):
GET /api/admin/site-content- Get all content itemsPOST /api/admin/site-content- Create or update a single itemPOST /api/admin/site-content/bulk- Bulk update multiple itemsDELETE /api/admin/site-content/:key- Delete an itemPOST /api/admin/site-content/initialize- Initialize default content
Frontend Integration
File: frontend/_app/info.js
- Automatically loads content from API on page load
- Falls back to hardcoded defaults if API fails
- Uses MutationObserver to patch modals when they appear
- Supports locale switching
Setup Instructions
1. Database Migration
Run the Prisma migration to create the SiteContent table:
pnpm db:push
2. Initialize Default Content
After the database is set up, initialize the default content by making a POST request:
curl -X POST http://localhost:3000/api/admin/site-content/initialize \
-H "Cookie: j=YOUR_ADMIN_JWT_TOKEN"
Or use the admin UI (see below).
3. Access the Admin UI
Navigate to: http://localhost:3000/_app/admin-content-editor.html
Note: You must be logged in as an admin with a valid JWT token in cookies.
Using the Admin UI
Interface Features
- Locale Selector - Switch between languages (en, zh)
- Reload Button - Refresh content from database
- Add New Item - Create new content entries
- Initialize Defaults - Populate database with default content
- Save All Changes - Bulk save modified items
- Delete Button - Remove individual items
Content Keys
Content is organized using dot-notation keys:
Modal Content Keys
Overview Section:
modal.overview.title- "Overview" headingmodal.overview.videoUrl- YouTube embed URL
Paint Faster Section:
modal.paintFaster.title- Section headingmodal.paintFaster.mobile- Instructions for mobile usersmodal.paintFaster.desktop- Instructions for desktop users
Map Lagging Section:
modal.mapLagging.title- Section headingmodal.mapLagging.text- Help textmodal.mapLagging.link- Link to hardware acceleration guide
Rules Section:
modal.rules.title- "Rules" headingmodal.rules.badge- Badge text (e.g., "Important")modal.rules.item.0- First rule (with emoji)modal.rules.item.1- Second rulemodal.rules.item.N- Additional rules (add as needed)modal.rules.footer- Footer warning text
Footer Section:
modal.footer.email- Contact emailmodal.footer.discord.url- Discord invite URLmodal.footer.discord.text- Discord link textmodal.footer.github.url- GitHub organization URLmodal.footer.github.text- GitHub link textmodal.footer.instagram.url- Instagram URLmodal.footer.instagram.text- Instagram link textmodal.footer.terms.url- Terms of service URLmodal.footer.terms.text- Terms link textmodal.footer.privacy.url- Privacy policy URLmodal.footer.privacy.text- Privacy link text
Site-wide:
site.title- Site title/branding
Adding New Rules
To add a new rule to the rules modal:
- Click "Add New Item"
- Set key to
modal.rules.item.4(or next available number) - Set value to
🚀 Your new rule text here - Click "Add Item"
- Repeat for other locales (en, zh, etc.)
The frontend will automatically display all numbered rules in order.
Workflow Example
- Login as admin to your FurryPlace instance
- Navigate to
/_app/admin-content-editor.html - Select locale (e.g., English)
- Click "Initialize Defaults" (first time only)
- Edit content directly in the text fields
- Click "Save All Changes" to persist to database
- Refresh your main site - changes appear immediately!
Development Notes
Adding New Content Fields
To add new editable content:
- Choose a unique key (e.g.,
modal.newSection.title) - Add to the initialize defaults in
src/routes/site-content.ts - Update the monkey patch in
frontend/_app/info.jsto use the new key - Add documentation to this file
Locale Support
Currently supports:
en- Englishzh- Chinese
To add a new locale:
- Add option to locale selector in admin UI
- Initialize default content for that locale
- Update frontend locale detection in
info.js
Caching Considerations
- Frontend caches API response per page load
- No server-side caching (content always fresh from DB)
- Consider adding Redis/memory cache for production
Troubleshooting
Content Not Updating
- Check browser console for
[WPLACE_INFO]logs - Verify API endpoint returns data:
GET /api/site-content?locale=en - Clear browser cache and reload
- Check database for content entries:
SELECT * FROM SiteContent;
Admin UI Not Loading
- Verify you're logged in as admin
- Check browser cookies for
jJWT token - Verify
rolein User table is set toadmin - Check browser console for authentication errors
Default Content Missing
Run initialization endpoint:
curl -X POST http://localhost:3000/api/admin/site-content/initialize \
-H "Cookie: j=YOUR_JWT_TOKEN"
Security Notes
- Admin endpoints require authentication AND
role='admin' - Input validation prevents injection attacks
- Keys restricted to alphanumeric + dots + underscores
- No HTML rendering (XSS protection via text replacement)
Future Enhancements
- Add wysiwyg editor for formatted text
- Support for images/media uploads
- Version history and rollback
- Multi-tenant support (different content per domain)
- Import/export functionality (JSON/CSV)
- Preview changes before publishing
- Scheduled content changes
- Content approval workflow