FΓΆrtroendemannaregister is a wordpress theme for municipalities presenting their elected politicians and their assignments.

Installs: 2

Dependents: 0

Suggesters: 0

Security: 0

Stars: 0

Watchers: 0

Forks: 0

Type:wordpress-theme

pkg:composer/alingsas-kommun/fmr

1.0.1 2025-11-26 00:05 UTC

This package is auto-updated.

Last update: 2025-11-26 00:06:11 UTC


README

WordPress theme that converts your wordpress installation to a register of elected politicians

Features

  • πŸ”§ Clean, efficient theme templating with Laravel Blade
  • ⚑️ Modern front-end development workflow powered by Vite
  • 🎨 A clean starting point for theme styles using Sass
  • πŸš€ Harness the power of Laravel with Acorn integration
  • 🎯 Structured namespace-based organization
  • πŸ”Œ Service provider pattern for clean code organization
  • 🧩 Component-based architecture with Blade and Livewire

Requirements

Make sure all dependencies have been installed before moving on:

Project Architecture

FMR is built on Roots Sage, a modern WordPress starter theme, enhanced with Laravel Acorn to bring Laravel's powerful features to WordPress.

Framework Stack

  • WordPress Theme: Roots Sage
  • Laravel Integration: Acorn (Laravel for WordPress)
  • PHP Standard: PSR12
  • Autoloading: PSR4
  • Namespace Root: App\

Key Concepts

This theme uses Laravel's service container and service providers pattern. All Laravel commands must be run through WordPress CLI using wp acorn instead of php artisan. The theme follows a structured, namespace-based organization where different types of functionality are separated into logical folders and namespaces.

⚠️ Important: Always use wp acorn instead of php artisan for all Laravel commands.

# βœ… Correct
wp acorn make:livewire Search
wp acorn tinker

# ❌ Incorrect
php artisan make:livewire Search  # This won't work!

Theme Structure

themes/fmr/   # β†’ Root of your fmr based theme
β”œβ”€β”€ app/                                # β†’ Theme PHP (autoloaded classes)
β”‚   β”œβ”€β”€ Core/                           # β†’ WP integration layer (post types, taxonomies, admin)
β”‚   β”‚   β”œβ”€β”€ Admin/                      # β†’ Custom list/edit scaffolding
β”‚   β”‚   β”œβ”€β”€ PostTypes/                  # β†’ CPT registrations
β”‚   β”‚   β”œβ”€β”€ Taxonomies/                 # β†’ Custom taxonomies
β”‚   β”‚   └── Theme.php                   # β†’ Core bootstrap
β”‚   β”œβ”€β”€ Http/                           # β†’ Controllers & middleware
β”‚   β”‚   β”œβ”€β”€ Controllers/                # β†’ Web + API controllers
β”‚   β”‚   └── Middleware/                 # β†’ HTTP middleware (API keys etc.)
β”‚   β”œβ”€β”€ Livewire/                       # β†’ Livewire component controllers
β”‚   β”œβ”€β”€ Models/                         # β†’ Eloquent models targeting WP tables + customs
β”‚   β”œβ”€β”€ Providers/                      # β†’ Service providers
β”‚   β”‚   β”œβ”€β”€ ThemeServiceProvider.php
β”‚   β”‚   β”œβ”€β”€ AdminServiceProvider.php
β”‚   β”‚   β”œβ”€β”€ CoreServiceProvider.php
β”‚   β”‚   β”œβ”€β”€ DatabaseServiceProvider.php
β”‚   β”‚   └── ServiceProvider.php
β”‚   β”œβ”€β”€ Services/                       # β†’ Domain services (exports, field groups, etc.)
β”‚   β”œβ”€β”€ Utilities/                      # β†’ Global theme utilities/helpers
β”‚   └── View/                           # β†’ Blade view components & composers
β”œβ”€β”€ config/                             # β†’ Config files (database, prettify, routes)
β”œβ”€β”€ database/                           # β†’ Laravel-style migrations & seeders
β”‚   β”œβ”€β”€ migrations/                     # β†’ Custom tables (assignments, decision authorities, …)
β”‚   └── seeders/                        # β†’ `wp acorn db:seed`
β”œβ”€β”€ resources/                          # β†’ Theme assets and templates
β”‚   β”œβ”€β”€ css/                            # β†’ Tailwind + admin SCSS
β”‚   β”œβ”€β”€ js/                             # β†’ Alpine components (frontend/admin)
β”‚   β”œβ”€β”€ lang/                           # β†’ PHP + JSON translations
β”‚   └── views/                          # β†’ Blade templates (admin, public, Livewire)
β”œβ”€β”€ routes/                             # β†’ Route definitions
β”‚   β”œβ”€β”€ api.php                         # β†’ API routes guarded by API keys
β”‚   └── web.php                         # β†’ Public site routes
β”œβ”€β”€ scripts/                            # β†’ Utility scripts (translations, etc.)
β”œβ”€β”€ public/build/                       # β†’ Built assets (generated by Vite)
β”œβ”€β”€ helpers.php                         # β†’ Global helper functions
β”œβ”€β”€ functions.php                       # β†’ Theme bootloader
β”œβ”€β”€ theme.json                          # β†’ WP block/theme settings
β”œβ”€β”€ composer.json                       # β†’ PHP dependencies + autoload
β”œβ”€β”€ package.json                        # β†’ Node scripts/dependencies
β”œβ”€β”€ vite.config.js                      # β†’ Vite configuration file
└── vendor/                             # β†’ Composer packages (never edit manually)

Folder Structure & Namespaces

App Folder Organization

The app/ folder contains all autoloading classes organized by namespace. Each namespace serves a specific purpose:

App\View\Composers

Location: app/View/Composers/
Purpose: Provides data to views
Usage: Each composer specifies which templates should receive the data
Best Practice: Use for passing data to post type archive and single pages

Example: A composer that provides data to all single post templates

App\Livewire

Location: app/Livewire/
Purpose: Livewire component controllers for reactive functionality
Usage:

  • Components like Search and AdvancedSearch proxy heavy logic to HTTP controllers (SearchController) while keeping the UI reactive.
  • Scaffold new components via wp acorn make:livewire {ComponentName} and render them in Blade with <livewire:component-name />. Extension Tips: Keep component state serializable, reuse existing services/controllers, and wrap permission toggles with helpers such as setting() when needed.

App\Utilities

Location: app/Utilities/
Purpose: Global theme utilities usable throughout the theme
Examples:

  • AttributeFactory.php - Build HTML attributes
  • ClassFactory.php - Build CSS class names
  • General.php - General utility functions

App\Models

Location: app/Models/
Purpose: Eloquent facades over WordPress core tables (posts, users, terms) plus bespoke tables (assignments, decision_authority).
Usage:

  • Reuse scopes like Post::type('board')->published() to keep queries expressive.
  • Keep model logic thin; delegate complex flows to Services.
    Extension Tips: Extend Illuminate\Database\Eloquent\Model, set $table, $primaryKey, and $timestamps explicitly for WordPress tables, and follow PSR-4 naming.

App\Services

Location: app/Services/
Purpose: Encapsulate domain workflows such as exports (AssignmentExportService), anniversaries, and shared field group helpers.
Usage: Resolve via dependency injection (app(AssignmentExportService::class)) or type-hint in controllers. Each service should own one workflow so controllers stay thin.
Extension Tips: Register new services inside ThemeServiceProvider (or a dedicated provider) when they require bindings, and keep side effects (files, emails, etc.) here rather than in controllers.

App\Http\Controllers

Location: app/Http/Controllers/, with admin-specific controllers under App\Http\Controllers\Admin and API controllers under App\Http\Controllers\Api.
Purpose: Serve web, admin, and API requests. API controllers are intentionally read-only unless protected by additional auth layers and reuse shared transformers/services for consistent JSON.
Extension Tips: Duplicate the established patternβ€”inject the relevant model/service, return JSON via response()->json() for APIs, and register routes inside routes/api.php or routes/web.php. Update ApiKeyMiddleware if authentication rules change.

Service Providers

Service providers handle registration and booting of classes. They follow Laravel's service provider pattern.

Main Service Provider

App\Providers\ThemeServiceProvider

  • Registered in functions.php
  • Registers other service providers:
    • AdminServiceProvider

Other Service Providers

  • AdminServiceProvider: Registers classes in App\Admin namespace

Core Admin Abstracts

The App\Core\Admin\Abstracts namespace provides reusable building blocks for WordPress-like list/add/edit experiences that sit on top of custom database tables:

  • EditPage: Wraps add_submenu_page, meta box registration, nonce handling, and saving logic for CRUD screens. Child classes (for assignments, decision authorities, etc.) only implement initializeProperties(), getCurrentObject(), and handleSave() to work with their specific models or tables.
  • OptionsPage: Similar to EditPage, but geared toward configuration screens that store data in the WordPress options table. It delegates the actual fields to field groups and ensures consistent save feedback.
  • FieldGroup: Declarative meta box builder for post types. It wires nonce handling, tabbed layouts, relation pickers, and save hooks into WordPress' post edit screens so custom fields remain consistent across CPTs.
  • OptionsFieldGroup: Mirrors FieldGroup but persists values via the settings helper (setSetting()/setting()). Used by options pages to render reusable panels.
  • MetaBox: Base class used by admin modules to add contextual meta boxes (for example, assignment details). It centralizes rendering helpers so each meta box stays small.
  • RelationHandler: Encapsulates syncing logic between a custom record and related WordPress content (posts, taxonomies, or pivot tables). Admin edit pages call these handlers during handleSave() to keep relationships consistent.

Together these abstractions make it easy to scaffold new admin list/edit pages: extend EditPage, compose any number of FieldGroup/MetaBox classes, and optionally plug in RelationHandler helpers to keep bespoke tables in sync with WordPress data without rewriting the boilerplate each time.

Asset Building

Build Tool: Vite

Assets are built using Vite, configured in vite.config.js.

Entry Points

  • resources/css/app.css - Main theme styles (Tailwind)
  • resources/js/app.js - Main frontend JavaScript (Alpine.js)
  • resources/css/admin.scss - Admin styles
  • resources/js/admin.js - Admin JavaScript

Build Commands

# Development build with hot reload
npm run dev

# Production build
npm run build

Output

Built assets are output to public/build/ directory.

Localization

Translation Files

Translation files are located in resources/lang/:

  • fmr.pot - Translation template (source)
  • sv_SE.po - Swedish translations
  • sv_SE.mo - Compiled translations
  • fmr-sv_SE-app-js.json - JavaScript translations (app)
  • fmr-sv_SE-editor-js.json - JavaScript translations (editor)

Translation Commands

# Generate translation template
npm run translate:pot

# Update translation files
npm run translate:update

# Generate JavaScript translations
npm run translate:js

# Compile all translations
npm run translate:compile

Usage in Code

PHP/Blade:

__('Text to translate', 'fmr')
_e('Text to translate', 'fmr')

JavaScript:

// Translations are available via wp.i18n
wp.i18n.__('Text to translate', 'fmr')

Theme Development

Initial Setup

  1. Run npm install from the theme directory to install dependencies
  2. Update vite.config.js with your local dev URL if needed
  3. Run composer install to install PHP dependencies

Development Workflow

  1. Start development server:

    npm run dev

    This compiles assets when file changes are made and starts a Browsersync session.

  2. Build for production:

    npm run build

    This compiles and minifies assets for production.

5. Indentation

Always use 4 spaces for indentation across all file types:

  • PHP
  • Blade templates
  • JavaScript/JSX
  • SCSS/CSS

6. Code Style

  • PHP: PSR12 standard
  • JavaScript: Single quotes, 4 spaces, semicolons
  • SCSS: 4 spaces, single quotes

7. Dark Mode

Never add dark: classes - Dark mode is handled by an automatic color swapping system. The theme will automatically handle dark mode without explicit dark mode classes.

8. Testing Workflow

  1. Write code
  2. Test in wp acorn tinker
  3. Verify functionality
  4. Commit changes

9. Asset Management

  • Use Vite for all asset building
  • Keep entry points organized
  • Use npm scripts for build commands

10. Localization

  • Always use translation functions for user-facing text
  • Run translation commands after adding new translatable strings
  • Keep translation keys consistent

Quick Reference

Common Commands

# Livewire
wp acorn make:livewire {ComponentName}

# Testing
wp acorn tinker

# Translations
npm run translate:pot
npm run translate:update
npm run translate:js

# Assets
npm run dev
npm run build

File Locations

  • PHP Classes: app/{Namespace}/
  • Blade Views: resources/views/
  • JavaScript: resources/js/
  • Styles: resources/css/
  • Translations: resources/lang/
  • Built Assets: public/build/

Backend Building Blocks

Database Migrations & Seeders

  • Location: database/migrations/*.php, database/seeders/DatabaseSeeder.php
  • Purpose: Create and evolve custom tables such as decision_authority and assignments while respecting WordPress foreign keys.
  • Usage:
    • Create: wp acorn make:migration create_example_table
    • Run: wp acorn migrate
    • Rollback: wp acorn migrate:rollback
    • Seed: wp acorn db:seed
  • Extension tips: Mirror the existing migrations for index/foreign-key patterns, and keep table names snake_cased. When altering WordPress core tables, always guard with Schema::hasColumn checks.

Routes (Web + API)

  • Web routes live in routes/web.php and are resolved via the normal WordPress front controller (e.g., Route::get('/', HomeController::class)). Use helpers like General::getRouteSlug() so slugs stay configurable.
  • API routes live in routes/api.php, grouped behind App\Http\Middleware\ApiKeyMiddleware. Controllers return JSON resources for assignments, persons, parties, boards, and decision authorities.
  • Extend by adding new route groups or endpoints inside the respective file and binding them to controllers. Remember to register new controllers in a service provider if they need container bindings.

Documentation

Summary

This theme follows a structured, Laravel-inspired architecture within WordPress. Key principles:

  1. Always use wp acorn instead of php artisan
  2. Use commands for scaffolding - never manually create boilerplate
  3. Respect namespace organization - keep code in appropriate folders
  4. Use service providers for registration
  5. Test with Tinker - don't create test files
  6. 4 spaces indentation everywhere
  7. Follow PSR12 for PHP code style

When in doubt, check this README or use the appropriate wp acorn command to scaffold what you need.