No description
  • JavaScript 51%
  • Nunjucks 34.3%
  • Python 14.2%
  • Dockerfile 0.5%
Find a file
Rob Bouwmeester 8d96b6e923 added dockerfile
2026-09-21 16:35:09 +02:00
_includes/layouts bugfixes 2026-09-18 15:52:13 +02:00
content content aanpassing 2026-09-18 15:57:06 +02:00
docs init 2026-09-18 08:44:10 +02:00
.dockerignore added dockerfile 2026-09-21 16:35:09 +02:00
.gitignore .gitignore 2026-09-18 08:48:27 +02:00
add_tags.py working base 2026-09-18 15:30:09 +02:00
build-watch.js watch fixes 2026-09-18 11:49:58 +02:00
build.js bugfixes 2026-09-18 15:52:13 +02:00
build.js.backup working base 2026-09-18 15:30:09 +02:00
check_links.py Fix broken navigation links and post URLs 2026-09-18 10:32:09 +00:00
check_links_v2.py Fix broken navigation links and post URLs 2026-09-18 10:32:09 +00:00
dev-server.js watch fixes 2026-09-18 11:49:58 +02:00
docker-compose.yml added dockerfile 2026-09-21 16:35:09 +02:00
Dockerfile added dockerfile 2026-09-21 16:35:09 +02:00
fix_home_path.py Fix broken navigation links and post URLs 2026-09-18 10:32:09 +00:00
fix_home_path2.py Fix broken navigation links and post URLs 2026-09-18 10:32:09 +00:00
fix_nav_paths.py Fix broken navigation links and post URLs 2026-09-18 10:32:09 +00:00
fix_post_urls.py Fix broken navigation links and post URLs 2026-09-18 10:32:09 +00:00
fix_templates.py Fix broken navigation links and post URLs 2026-09-18 10:32:09 +00:00
nginx.conf added dockerfile 2026-09-21 16:35:09 +02:00
package.json package aanpassing 2026-09-18 16:04:32 +02:00
README.md init 2026-09-18 08:44:10 +02:00

alway.swill.be - Complete Architecture Documentation

A self-hosted, Docker-based static photography site with a browser editor. Fast gallery publishing (15×/month), 4 content types, responsive images.

Status: Documentation complete. Ready for implementation.


📋 DOCUMENTATION STRUCTURE

1. ARCHITECTURE.md

High-level tech stack overview. Answers "what?" and "why?"

  • Technology choices (11ty, Node.js, Docker, Forgejo, Sharp)
  • File organization (folder structure, content types)
  • Content formats (YAML galleries, Markdown posts, custom HTML)
  • Deployment model (self-hosted, Proxmox homelab)
  • Advantages vs. WordPress (speed, control, future-proof)

👉 Start here for context and understanding.


2. BUILD_SCRIPT.md

How the custom Node.js build system works.

  • File scanning and content parsing
  • Metadata extraction from folder paths
  • Template rendering with Nunjucks
  • Image processing with Sharp (5 responsive sizes)
  • Collections building and sorting
  • Complete build flow explanation

👉 Read this to understand how the build works.


Real example of gallery structure and rendering.

  • Input: YAML post.yaml file with galleries and images
  • Output: HTML as it appears on site
  • Template: Complete Nunjucks code for rendering galleries
  • Demonstrates: Dynamic captions, image paths, layout flexibility

👉 Reference this for gallery structure.


4. LAYOUT_ARCHITECTURE.md

How page layouts are organized and inherited.

  • Base layout (site header/footer, common structure)
  • Layout inheritance (photoblog.njk wraps base.njk)
  • Content-specific layouts (photoblog, text-post, project, page)
  • Conditional rendering (show/hide elements per layout)
  • Template includes (partials, components)

👉 Reference this when building Nunjucks layouts.


5. DIRECTORY_BASED_LAYOUTS.md

Automatic layout assignment from folder structure.

  • Pattern: directory.json per folder type
  • Eliminates repetition (layout/tags specified once)
  • Cascading data (file frontmatter overrides directory.json)
  • Examples for photoblog, lofi, writing, projects, pages

👉 Use this pattern for all content folders.


6. EXTRACTED_METADATA.md

Deriving date and other metadata from file paths.

  • No date: field needed in frontmatter
  • Extract from folder: content/photoblog/2026-09-17/post.yaml
  • 11ty filters for date extraction
  • Handling multiple posts same day (2026-09-17-2)
  • Keeps files clean, DRY principle

👉 Reference for metadata extraction patterns.


7. IMAGE_PROCESSING_SIMPLE.md

Image processing pipeline (Sharp.js, JPEG only).

  • Why JPEG only (not WebP): simplicity, universal support
  • Processing workflow: 5 responsive sizes (300px → 2400px)
  • Quality 85 JPEG (professional photography standard)
  • Performance: 2-3 seconds for 300 images (4 workers)
  • Nginx caching: 365d TTL for images (immutable)
  • File size: ~720KB per image across 5 sizes

👉 Reference for image optimization strategy.


8. CUSTOM_HTML_PAGES.md

Mixed content: YAML galleries + Markdown posts + HTML experiments.

  • Three approaches: plain HTML, HTML with layout, Markdown + HTML blocks
  • Real examples: before/after slider, equipment list, timeline, comparison tool
  • Directory structure: experiments/, tools/, pages/
  • When to use each format

👉 Reference when building interactive pages.


9. EDITOR_UI_SPECIFICATION.md

Browser-based gallery editor with live preview.

  • Architecture: React/Vue frontend + Node.js/Express backend
  • Workflow: upload → arrange → caption → preview → publish
  • Features: drag-to-reorder, image management, live YAML preview
  • Validation: client-side + server-side
  • API endpoints: /api/upload, /api/preview, /api/draft, /api/publish
  • Settings page, draft management, mobile responsive
  • Deployment: Docker container, TLS/HTTPS

👉 Reference for editor implementation.


10. URL_ROUTING_PATTERNS.md

How folder structure generates URLs.

  • Photoblog: /photoblog/2026-09-17/
  • Lofi posts: /lofi/2026-09-17/
  • Writing: /writing/2026-09-10/
  • Projects: /projects/urbex/ (no date)
  • Static pages: /pages/about/
  • Experiments: /experiments/before-after-slider/
  • Collections sorting (chronological vs. manual)
  • Breadcrumbs, tag archives, pagination
  • Sitemap and RSS feeds

👉 Reference for URL structure and collections.


11. DEPLOYMENT_WORKFLOW.md

End-to-end: editor publish button → live site.

  • Architecture diagram: Editor → Git → Build → Deploy → Nginx
  • Editor backend API (/api/publish with validation)
  • Git hook that triggers build
  • Build script (bash): pulls, builds, deploys
  • Build trigger server (Node.js HTTP listener)
  • Docker Compose configuration (4 services)
  • Nginx reverse proxy + caching
  • Monitoring and error recovery
  • Timeline: 60 seconds from click to live

👉 Reference for deployment setup.


12. ELEVENTY_CONFIGURATION.md (Reference Only)

Original 11ty configuration kept for reference. Use BUILD_SCRIPT.md instead for the actual build system.

  • Shows previous approach with 11ty
  • Replaced by custom build.js for more control
  • Kept as reference if you want to compare approaches

👉 For reference only; use build.js instead.

🎯 IMPLEMENTATION ROADMAP

Phase 1: Core Infrastructure

  1. Set up Proxmox VM (2GB RAM, 10GB disk, Ubuntu 22.04)
  2. Install Docker, Docker Compose, Node.js 18+
  3. Create folder structure: /home/data/content/, /home/data/uploads/
  4. Set up HTTPS with Let's Encrypt

Phase 2: Build System Setup

  1. Initialize npm project in /home/data/content/
  2. Install dependencies: npm install sharp moment js-yaml nunjucks p-limit chokidar
  3. Copy build.js from this documentation
  4. Create folder structure: content/, _includes/, public/
  5. Copy build.js and build-watch.js scripts

Phase 3: Templates & Layouts

  1. Create base layout: _includes/layouts/base.njk (header/footer)
  2. Create content layouts: photoblog.njk, text-post.njk, project.njk, page.njk
  3. Create gallery partial: _includes/partials/gallery.njk
  4. Create homepage template
  5. Test with sample post

Phase 4: Editor Application

  1. Create Express backend: server/routes/publish.js
  2. Create React/Vue frontend: image upload, drag-to-reorder, live preview
  3. Implement validation (title length, tags, images per gallery)
  4. Create authentication (password + optional 2FA)
  5. Test full workflow: upload → arrange → publish

Phase 5: Build & Deployment

  1. Build system ready: build.js (already created)
  2. Set up file watcher (optional): build-watch.js for auto-rebuild
  3. Configure cron (optional): for scheduled builds
  4. Configure Nginx reverse proxy (see DEPLOYMENT_WORKFLOW.md)
  5. Set up caching headers (365d images, 1h HTML)

Phase 6: Docker & Production

  1. Create Dockerfiles for editor, build server
  2. Write docker-compose.yml with all services
  3. Set up volume mounts for persistence
  4. Test full stack locally
  5. Deploy to Proxmox

Phase 7: Testing & Refinement

  1. Publish test gallery with 20 images
  2. Verify image processing (all 5 sizes generated)
  3. Test URL routing (correct paths for all content types)
  4. Stress test: publish 15 galleries in one day
  5. Performance tuning (build time, image compression)

Phase 8: Migration (Optional)

  1. Build WordPress import tool (reads WP database, generates YAML)
  2. Test import with 5-10 galleries
  3. Verify image downloads and captions
  4. Set up Nginx redirects for old WordPress URLs
  5. Gradually migrate galleries (or all at once)

🚀 QUICK START

Minimal setup for testing:

# 1. Clone/create project
mkdir alway-swill-be
cd alway-swill-be

# 2. Initialize npm
npm init -y
npm install sharp moment js-yaml nunjucks p-limit chokidar

# 3. Create folder structure
mkdir -p content/{photoblog,lofi,writing,projects,pages}
mkdir -p _includes/{layouts,partials}
mkdir -p public

# 4. Copy build system
# Copy build.js from documentation
# Copy build-watch.js for file watcher

# 5. Create sample post
mkdir -p content/photoblog/2026-09-17/images
# Add post.yaml and sample images

# 6. Create sample templates
mkdir -p _includes/layouts
# Add base.njk, photoblog.njk, etc.

# 7. Test build
node build.js

# 8. View output
# Check public/ folder - should see index.html, photoblog/2026-09-17/index.html, etc.

📊 CONTENT TYPES QUICK REFERENCE

Type Format Folder URL Date Rendered By
Gallery YAML photoblog/2026-09-17/ /photoblog/2026-09-17/ From folder photoblog.njk
Lofi Markdown lofi/2026-09-17/ /lofi/2026-09-17/ From folder text-post.njk
Writing Markdown writing/2026-09-10/ /writing/2026-09-10/ From folder text-post.njk
Project Markdown projects/urbex/ /projects/urbex/ None project.njk
Page Markdown pages/about.md /pages/about/ None page.njk

🎨 DESIGN PATTERNS

title: "Title"
description: "Description"
tags: [tag1, tag2]
galleries:
  - slug: gallery-1
    title: "Gallery Title"
    images:
      - filename: image-001.jpg
        caption: "Optional caption"

Folder organization

content/
├── photoblog/2026-09-17/
│   ├── post.yaml
│   └── images/
├── lofi/2026-09-17/
│   └── post.md
├── pages/
│   └── about.md
└── experiments/
    └── demo.html

Layout hierarchy

base.njk (header/footer/common)
  ├── photoblog.njk (galleries)
  ├── text-post.njk (articles)
  ├── project.njk (projects)
  ├── page.njk (static)
  └── homepage.njk (latest posts)

⚡ PERFORMANCE TARGETS

  • Build time: 30-60 seconds (including image processing)
  • Image processing: 2-3 seconds for 300 images (4 workers)
  • File sizes: ~720KB per image across 5 responsive sizes
  • JPEG quality: 85 (imperceptible loss, professional standard)
  • Caching: 365 days for images, 1 hour for HTML
  • Images per gallery: 1-25
  • Publishing frequency: 15 galleries/month
  • Total disk usage: ~10GB for one year of content

🔒 SECURITY CONSIDERATIONS

  • File validation: Check file types (JPEG/PNG), sizes (max 50MB)
  • YAML sanitization: Prevent injection attacks
  • Authentication & Encryption: Handled at reverse proxy level (your responsibility)
  • File permissions: Editor runs as specific user with limited access
  • Path validation: Prevent directory traversal attacks
  • Input sanitization: Validate all form inputs before processing

📝 FILE CHECKLIST

Documentation files (these files):

  • README.md (this file)
  • ARCHITECTURE.md
  • GALLERY_TEMPLATE_EXAMPLE.md
  • LAYOUT_ARCHITECTURE.md
  • DIRECTORY_BASED_LAYOUTS.md
  • EXTRACTED_METADATA.md
  • IMAGE_PROCESSING_SIMPLE.md
  • CUSTOM_HTML_PAGES.md
  • EDITOR_UI_SPECIFICATION.md
  • URL_ROUTING_PATTERNS.md
  • ELEVENTY_CONFIGURATION.md
  • DEPLOYMENT_WORKFLOW.md

Configuration files (to create):

  • .eleventy.js
  • package.json
  • docker-compose.yml
  • nginx.conf
  • /home/build/build.sh

Layout templates (to create):

  • _includes/layouts/base.njk
  • _includes/layouts/photoblog.njk
  • _includes/layouts/text-post.njk
  • _includes/layouts/project.njk
  • _includes/layouts/page.njk
  • _includes/partials/gallery.njk

❓ FAQ

Q: Can I keep WordPress and try this alongside? A: Yes. Set up new site on different domain (staging.alway.swill.be), test thoroughly, then switch DNS.

Q: How do I migrate from WordPress? A: Use the WordPress import tool to read your WP database and generate YAML galleries + download images. See EDITOR_UI_SPECIFICATION.md for details. Set up Nginx redirects for old URLs if needed.

Q: What if I want to edit posts after publishing? A: Edit post.yaml directly in /content/ folder, then trigger a rebuild. Or add an edit button in the editor UI to modify galleries after publish.

Q: Can I run this on shared hosting? A: No, requires Docker and root access. Self-hosted only (Proxmox, VPS with root, or bare metal).

Q: What happens if build fails? A: Previous version stays live. Editor shows error. Check build logs. Fix issue. Retry publish. See DEPLOYMENT_WORKFLOW.md error recovery.

Q: How do I add a new content type? A: Create folder (e.g., content/videos/), create directory.json with layout, create layout template, add collection in .eleventy.js. Document it.

Q: How do I version control the content? A: Separately if needed (Git, Forgejo, etc.). The editor writes directly to filesystem without requiring version control. You can add Git separately if you want version history.

Q: Is there a mobile app? A: No, editor is web-based (responsive design). Works on iPad/tablet.

Q: Can I schedule posts? A: Not in current spec. Could add this as v2 feature (scheduled_publish time).


📞 NEXT STEPS

  1. Read ARCHITECTURE.md for full context
  2. Choose implementation phase (start with Phase 1-2)
  3. Copy ELEVENTY_CONFIGURATION.md to .eleventy.js
  4. Follow DEPLOYMENT_WORKFLOW.md for setup
  5. Test with sample gallery before going live
  6. Migrate content gradually or all at once

📚 REFERENCES


📄 LICENSE

This architecture and documentation is for alway.swill.be photography site.

Last updated: September 17, 2026


Status: Documentation Complete ✓

All architectural decisions documented. Ready for implementation whenever you are.