Skip to content

feat!: replace DB-based templates/modules with native PHP classes#6487

Draft
gharlan wants to merge 2 commits into6.xfrom
refactor-templates-modules-actions
Draft

feat!: replace DB-based templates/modules with native PHP classes#6487
gharlan wants to merge 2 commits into6.xfrom
refactor-templates-modules-actions

Conversation

@gharlan
Copy link
Copy Markdown
Member

@gharlan gharlan commented Apr 13, 2026

Zusammenfassung

Templates, Module und Actions werden nicht mehr als PHP-Code-Text in der Datenbank gespeichert, sondern sind native PHP-Klassen. Die Klassen werden über ClassDiscovery automatisch erkannt — es ist keine manuelle Registrierung nötig.

Die Backend-Verwaltungsseiten für Templates, Module und Actions entfallen komplett.

Was entfällt

  • DB-Tabellen rex_template, rex_module, rex_action, rex_module_action
  • Backend-Seiten zur Verwaltung von Templates, Modulen und Actions

Was sich ändert

  • rex_article.template und rex_article_slice.module referenzieren nun per String-Key statt Integer-ID
  • Actions sind jetzt Lifecycle-Hooks direkt in der Modul-Klasse (onPreview, onPresave, onPostsave)

Beispiele

Template definieren

use Redaxo\Core\Content\AsTemplate;
use Redaxo\Core\Content\Template;
use Redaxo\Core\Content\ArticleContent;
use Redaxo\Core\Content\ContentSection;
use Redaxo\Core\Content\Category;
use Redaxo\Core\Content\Module;

#[AsTemplate('default', 'Standardtemplate')]
final class DefaultTemplate extends Template
{
    public function getContentSections(): array
    {
        return [
            new ContentSection(1, 'Hauptinhalt'),
            new ContentSection(2, 'Sidebar'),
        ];
    }

    // Optional: Template nur in bestimmten Kategorien erlauben
    public function isAllowedInCategory(?Category $category): bool
    {
        // null = Root-Ebene
        return null === $category || $category->getId() !== 5;
    }

    // Optional: Module pro Content-Section einschränken
    public function isModuleAllowed(ContentSection $section, Module $module): bool
    {
        if ($section->id === 2) {
            return in_array($module->key, ['text', 'image'], true);
        }

        return true;
    }

    public function render(ArticleContent $article): string
    {
        return '<html><body>' . $article->getArticle(1) . '</body></html>';
    }
}

Modul definieren

use Redaxo\Core\Content\AsModule;
use Redaxo\Core\Content\Module;
use Redaxo\Core\Content\ArticleSlice;
use Redaxo\Core\Content\ArticleSliceAction;
use Redaxo\Core\View\Fragment;

#[AsModule('text', 'Textmodul')]
final class TextModule extends Module
{
    public function input(ArticleSlice $slice): string
    {
        return (new Fragment('modules/text/input.php'))
            ->setVar('slice', $slice)
            ->parse();
    }

    public function output(ArticleSlice $slice): string
    {
        return (new Fragment('modules/text/output.php'))
            ->setVar('slice', $slice)
            ->parse();
    }

    // Optional: Lifecycle-Hooks (ersetzt bisherige Actions)
    public function onPresave(ArticleSliceAction $action): void
    {
        $email = $action->getValue(3);

        if ($email && !filter_var($email, FILTER_VALIDATE_EMAIL)) {
            $action->save = false;
            $action->addMessage('Ungültige E-Mail-Adresse');
        }
    }
}

Lookup

// Per Key
$template = Template::get('default');

// Per Klasse
$template = Template::get(DefaultTemplate::class);

// Alle Templates
$templates = Template::getAll();

// Templates für eine Kategorie
$templates = Template::getTemplatesForCategory($categoryId);

gharlan and others added 2 commits April 13, 2026 00:55
Templates, modules, and actions are no longer managed via the backend UI.
They will be defined as PHP classes in the project and addon code instead.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Templates and modules are no longer stored as PHP code text in the database
but as native PHP classes with attributes (#[AsTemplate], #[AsModule]).
Classes are discovered automatically via ClassDiscovery.

- Remove DB tables rex_template, rex_module, rex_action, rex_module_action
- rex_article.template and rex_article_slice.module reference by string key
- Template/module classes contain logic directly (render, input, output)
- Lifecycle hooks (onPreview, onPresave, onPostsave) in module instead of separate actions
- Remove backend management pages for templates/modules/actions
- ContentSection as value object for template content areas
- Locale-aware sorting via Collator
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

breaking feature Additional functionality

Development

Successfully merging this pull request may close these issues.

Templates/Module als direkt ausführbare Dateien, Abschaffung der Rex-Vars Modul aus Template ausschließen

2 participants