|
All checks were successful
Deploy / Build and Deploy to Production (push) Successful in 16s
Implement complete custom CSS management system: - Separate base CSS (readonly) and custom CSS (editable) - Save custom CSS to Kirby backend per narrative - Visual save button with state indicators (dirty/saving/success/error) - CSRF-protected API endpoint for CSS operations - Dual-editor StylesheetViewer (base + custom with edit mode toggle) - Auto-format custom CSS with Prettier on edit mode exit Backend changes: - Add web2print Kirby plugin with POST/GET routes - Add customCss field to narrative blueprint - Add CSRF token meta tag in header - Include customCss and modified timestamps in JSON template - Install code-editor plugin for Kirby panel Frontend changes: - Refactor stylesheet store with baseCss/customCss refs - Make content a computed property (baseCss + customCss) - Add helper methods: replaceBlock, replaceInCustomCss, setCustomCss - Update all components to use new store API - Create SaveButton component with FAB design - Redesign StylesheetViewer with collapsable sections - Initialize store from narrative data on app mount File changes: - Rename stylesheet.css → stylesheet.print.css - Update all references to new filename Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com> |
||
|---|---|---|
| .forgejo/workflows | ||
| .vscode | ||
| public | ||
| src | ||
| .gitignore | ||
| claude.md | ||
| Dockerfile.ci | ||
| index.html | ||
| package-lock.json | ||
| package.json | ||
| README.md | ||
| vite.config.js | ||
GeoProject - Web-to-Print Interface
A web-to-print application for creating printable narratives with real-time layout editing.
Overview
GeoProject is a sophisticated web-to-print platform that combines:
- Kirby CMS for content management
- Vue 3 for interactive editing interface
- PagedJS for print-ready rendering
The application allows users to create and edit multi-page narratives with dynamic layouts, supporting various content blocks (text, images, videos, maps) and custom page templates.
Tech Stack
- Frontend: Vue 3 (Composition API) + Vite
- Print Engine: PagedJS (CSS Paged Media)
- CMS: Kirby 5 (headless, flat-file)
- Backend: PHP 8.1+
- State Management: Pinia
- Styling: CSS with CSS Variables
Project Structure
/src # Vue 3 SPA
├── main.js # Vue bootstrap
├── App.vue # Root component + PagedJS init
├── components/
│ ├── blocks/ # Content block components (HeadingBlock, TextBlock, etc.)
│ ├── editor/ # Editor panels (PageSettings, TextSettings, etc.)
│ ├── ui/ # Reusable UI components (InputWithUnit, MarginEditor, etc.)
│ └── *.vue # Core components (PagedJsWrapper, ElementPopup, etc.)
├── composables/ # Vue composables (useCssSync, useCssUpdater, etc.)
├── stores/ # Pinia stores (narrative.js, stylesheet.js)
└── utils/ # JavaScript utilities
/public # Kirby CMS + static assets
├── site/
│ ├── blueprints/ # Content schemas
│ ├── templates/ # PHP templates
│ ├── snippets/ # PHP snippets
│ └── plugins/ # Kirby plugins
├── content/ # Markdown content files
└── assets/ # Static assets (CSS, fonts, SVG)
/.forgejo/workflows # CI/CD pipeline
Key Features
Content Types
- Narratives: Main story containers with cover, author, introduction
- Geoformats: Structured content sections with chapters
- Chapters: Individual chapters with rich content blocks
- Maps: Special map-based content pages
Content Blocks
- Text blocks with rich formatting
- Headings with customizable levels
- Images with captions and positioning
- Lists (ordered and unordered)
- Blockquotes with citations
- Video embeds
- Interactive maps
Print Features
- Real-time preview with PagedJS rendering
- Custom @page rules for different templates
- Interactive element and page editing
- CSS variable-based theming
- Print-optimized output
Getting Started
Development
# Install dependencies
npm install
# Start Vite dev server
npm run dev
# Start PHP server for Kirby (separate terminal)
php -S localhost:8000 -t public
The Vue app will be served at http://localhost:5173 and Kirby at http://localhost:8000.
Production Build
# Build for production
npm run build
Builds are output to /public/assets/dist/.
Data Flow
- Kirby CMS stores and manages content as flat files
- PHP Templates render the HTML structure and inject Vue
- Vue App provides the interactive editing interface
- PagedJS transforms content into print-ready pages
API
Narrative JSON Endpoint
GET /projet/{narrative-slug}.json
Returns the complete narrative data structure including all child pages, blocks, and metadata.
Naming Conventions
- Vue Components: PascalCase (e.g.,
PagedJsWrapper.vue) - Composables: Prefixed with
use(e.g.,useCssSync) - Stores: camelCase files, PascalCase store names (e.g.,
useNarrativeStore) - Code Language: English preferred for all code, comments, and identifiers
English-French Dictionary
The codebase uses English naming conventions, but some French terms remain in content and templates for compatibility. Here's a reference guide:
Core Concepts
| English | French | Context |
|---|---|---|
| narrative | récit | Main content container type |
| chapter | chapitre | Chapter/section within a geoformat |
| map | carte | Map-based content page |
| cover | couverture | Cover page/image |
| author | auteur | Narrative author(s) |
| introduction | introduction | Introductory text |
| impression | Print/output functionality |
Template Types
| English | French | File/Template Name |
|---|---|---|
| narrative | recit | narrative.php, narrative.json.php |
| chapter | chapitre | chapitre.php |
| map | carte | carte.php |
| geoformat | geoformat | geoformat.php |
UI Elements
| English | French | Notes |
|---|---|---|
| settings | paramètres | Editor panel settings |
| page | page | Page template/type |
| block | bloc | Content block |
| edit | éditer | Edit action |
| preview | aperçu | Preview mode |
Technical Terms
| English | French | Notes |
|---|---|---|
| store | magasin | Pinia store (use English 'store') |
| template | template/modèle | Page template |
| blueprint | schéma | Kirby content schema |
| field | champ | Form/content field |
Code Examples
Store naming:
// Correct
import { useNarrativeStore } from './stores/narrative';
// Old (deprecated)
import { useRecitStore } from './stores/recit';
Template references:
// Check for narrative template
if (item.template === 'narrative') { /* ... */ }
// Check for chapter template
if (item.template === 'chapitre') { /* ... */ }
CSS classes:
/* Narrative cover page */
.narrative-cover { /* ... */ }
/* Chapter content */
.chapitre { /* ... */ }
CI/CD
The project uses Forgejo Actions for continuous deployment:
- Code is pushed to Forgejo repository
- Workflow builds the Vue app
- Files are deployed via FTP to production server
See .forgejo/workflows/deploy.yml for details.
Contributing
For detailed development guidelines, see CLAUDE.md.