folderweb/app/README.md
Ruben 36a3221dbb Add default templates for list views
Add default language files for English and Norwegian

Add list-card-grid template for card-based content display

Add list-faq template for FAQ-style content display

Add list-grid template for grid-based content display
2025-11-01 16:11:33 +01:00

7.8 KiB

Framework Documentation

This directory contains the core framework for the file-based CMS. It provides a minimal, extensible foundation that can be customized via the /custom/ directory.

Architecture

The framework is a lightweight PHP-based routing system that:

  • Converts URLs to filesystem paths
  • Resolves language-specific content and slugs
  • Applies templates to render content
  • Serves static assets (styles, fonts, images)

Directory Structure

app/
├── router.php           # Main routing logic
├── static.php           # Static asset server for /app/* resources
├── config.ini           # Default framework configuration
├── vendor/              # Third-party dependencies
│   └── Parsedown/       # Markdown parser
└── default/             # Default templates and styles (fallback)
    ├── templates/
    │   ├── base.php     # Base HTML structure
    │   ├── page.php     # Single page/article template
    │   └── list.php     # Directory listing template
    └── styles/
        └── base.css     # Default base styles

Core Components

router.php

The main request router that handles all content requests. Key responsibilities:

  1. Language Detection: Extracts language from URL path (/no/, /en/)
  2. Slug Resolution: Converts language-specific slugs to directory names using metadata
  3. Path Resolution: Maps URLs to filesystem paths in /content/
  4. Content Loading: Reads content files (.md, .html, .php)
  5. Template Application: Applies appropriate template based on content type
  6. Rendering: Outputs final HTML with base template

Key Functions:

  • resolveLanguageSlugToName() - Translates slugs to directory names
  • findContentFile() - Locates content files with language variants
  • renderPage() - Renders content with templates
  • parseMetadata() - Parses INI metadata files

static.php

Serves static assets from /app/ directory. Handles requests for:

  • /app/styles/* - Framework CSS files
  • /app/fonts/* - Framework fonts
  • /app/default-styles/* - Default stylesheet aliases

Includes security checks to prevent path traversal attacks.

config.ini

Default configuration for the framework:

[languages]
default = "no"           # Default language
available = "no,en"      # Available languages

Can be overridden by /custom/config.ini.

vendor/

Third-party dependencies:

  • Parsedown: Markdown-to-HTML parser library

default/

Fallback templates and styles used when custom templates are not provided.

Request Flow

1. User requests URL (e.g., /no/artikler/pasientinfo)
   ↓
2. Apache routes to /content/index.php
   ↓
3. index.php includes router.php
   ↓
4. router.php:
   - Extracts language: "no"
   - Resolves slug "artikler" → "artikler" directory
   - Resolves slug "pasientinfo" → "pasientinfo" directory
   - Checks if path exists in /content/
   - Determines content type (file or directory)
   ↓
5. For single article:
   - Loads metadata.ini
   - Loads article.no.md (or article.md)
   - Applies /custom/templates/page.php (or default)
   - Wraps with /custom/templates/base.php
   ↓
6. For directory listing:
   - Scans directory for subdirectories
   - Loads metadata.ini for each item
   - Applies list template specified in metadata
   - Wraps with base.php
   ↓
7. Outputs final HTML to browser

Template System

Templates can be overridden by placing files in /custom/templates/:

Base Template (base.php)

Wraps all content with HTML structure, header, footer, navigation.

Variables available:

  • $title - Page title
  • $content - Rendered page content
  • $language - Current language code
  • $metadata - Page metadata array

Page Template (page.php)

Renders single articles/pages.

Variables available:

  • $contentHtml - Parsed HTML content
  • $metadata - Article metadata
  • $language - Current language code
  • $parentMetadata - Parent directory metadata

List Templates

Render directory listings. Multiple variants:

  • list.php - Simple list
  • list-grid.php - Grid layout
  • list-card-grid.php - Card grid with images
  • list-faq.php - Expandable FAQ view

Variables available:

  • $items - Array of child items with metadata
  • $metadata - Directory metadata
  • $language - Current language code

Customization

The framework is designed to be minimal and extensible. All customization should happen in /custom/:

Override Templates

Create files in /custom/templates/ with the same name as default templates.

Override Configuration

Create /custom/config.ini to override default settings.

Add Custom Styles

Place CSS in /custom/styles/ and reference in custom templates.

Add Custom Fonts

Place font files in /custom/fonts/ and reference in CSS.

Add Translations

Create or edit /custom/languages/[lang].ini files.

Metadata System

Content is configured via metadata.ini files placed in each directory.

Common Metadata Fields

[metadata]
title[no] = "Norwegian Title"
title[en] = "English Title"
slug[no] = "norwegian-slug"
slug[en] = "english-slug"
summary[no] = "Norwegian summary"
summary[en] = "English summary"
date = "2024-10-15"
category = "Category Name"
tags = "tag1,tag2,tag3"
template = "list-card-grid"  # For directories
show_in_menu = true
menu_order = 10

Metadata Inheritance

Child items inherit parent metadata when not specified.

Content File Resolution

The router looks for content files in this order:

  1. article.[language].md (e.g., article.no.md)
  2. article.[language].html
  3. article.[language].php
  4. article.md (fallback)
  5. article.html (fallback)
  6. article.php (fallback)
  7. page.[language].md (for directory index)
  8. page.md (fallback)

Language System

URL Structure

  • Norwegian: /no/artikler/pasientinfo
  • English: /en/articles/patient-info

Slug Translation

Slugs are resolved using metadata:

slug[no] = "pasientinfo"
slug[en] = "patient-info"

The router automatically translates URLs to filesystem paths regardless of language.

Translation Files

Located in /custom/languages/:

  • no.ini - Norwegian translations
  • en.ini - English translations

Format:

key = "Translated text"
another_key = "More text"

Access in templates: $translations['key']

Security Considerations

  • Path Traversal Protection: static.php validates paths to prevent directory traversal
  • Input Sanitization: URLs are sanitized before filesystem operations
  • Template Isolation: Templates run in controlled scope with specific variables
  • No Database: File-based system eliminates SQL injection risks

Performance

  • No Caching: Content is rendered on each request (suitable for low-traffic sites)
  • Performance Tracking: Page generation time is measured and displayed
  • Static Assets: Served directly by Apache when possible

Extending the Framework

To add new features:

  1. Custom Functions: Add helper functions in custom templates
  2. New Template Types: Create new template files in /custom/templates/
  3. Metadata Fields: Add new fields to metadata.ini files
  4. Custom Routes: Extend router.php (requires modifying framework)

Debugging

Enable error reporting in content/index.php:

ini_set('display_errors', 1);
error_reporting(E_ALL);

View page generation time at bottom of each page.

Requirements

  • PHP 8.3 or higher
  • Apache with mod_rewrite enabled
  • Write permissions on content directories (for future admin features)

Limitations

  • No built-in caching (regenerates pages on each request)
  • No built-in admin interface (content edited via filesystem)
  • No user authentication system
  • No built-in search functionality
  • Performance may degrade with very large content libraries