nerdcel/kirby-languagerelease

A Kirby CMS plugin to control the release status of language variants with frontend access control

Maintainers

Package info

github.com/nerdcel/kirby-languagerelease

Type:kirby-plugin

pkg:composer/nerdcel/kirby-languagerelease

Statistics

Installs: 49

Dependents: 0

Suggesters: 0

Stars: 2

Open Issues: 0

v1.2.0 2026-04-16 11:54 UTC

This package is auto-updated.

Last update: 2026-04-16 11:54:54 UTC


README

Version Kirby PHP License

A Kirby CMS plugin that provides granular control over language variant releases with frontend access control and preview capabilities.

Kirby Language Release Plugin

⚠️ Important Warning

This plugin changes the behavior of your multilingual site immediately after installation!

Once installed, all language variants (except the default language) will become inaccessible in the frontend until they are explicitly released through the Panel. This prevents visitors from accessing unfinished translations.

Before installing:

  • Back up your site
  • Review your current language variants
  • Plan which languages should be released immediately after installation

Editors can still access and preview all language variants through the Panel, regardless of their release status.

Features

  • Release Control: Individual release status for each language variant of a page
  • Frontend Access Control: Unreleased variants are blocked from public access
  • Preview Mode: Authenticated editors can preview unreleased variants via Panel
  • Flexible Behavior: Choose between 404, redirect, or default content for unreleased pages
  • Token Validation: Secure preview mode with session-based authentication
  • Multilingual Interface: Translations for DE, EN, ES, FR, IT, NL
  • Configurable Field Name: Use custom field names for the release status
  • Panel Integration: ViewButton with checkbox interface
  • Panel Section: Overview of all language variants and their release status
  • Page Tree Section: Hierarchical tree view of all pages with release status per language

Requirements

  • Kirby CMS: 5.0 or higher
  • PHP: 8.2 or higher

Installation

Via Composer (recommended)

composer require nerdcel/kirby-languagerelease

Manual Installation

  1. Download the latest release
  2. Extract the ZIP file
  3. Copy the languagerelease folder to /site/plugins/

Git Submodule

git submodule add https://github.com/nerdcel/kirby-languagerelease.git site/plugins/languagerelease

Quick Start

1. Add Field to Your Blueprints (optional)

Add the release field to your page blueprints:

fields:
  languageReleased:
    type: toggle
    label: Language Released
    default: false

2. Configure Plugin (Optional)

Create or update site/config/config.php:

return [
    'nerdcel.languagerelease' => [
        'autoIncludeButton' => true,
        'fieldName' => 'languageReleased', // Field name in your blueprint
        'behavior' => '404', // What to do with unreleased pages: '404', 'redirect', 'default-content'
    ],
];

3. Release Language Variants

In the Panel, open a page and switch to a non-default language. You'll see a button to release that language variant in the upper right area next to the language select button.

Panel Section

The plugin provides a custom Panel section that displays all language variants of a page and their current release status at a glance.

Add the Section to Your Blueprint

# site/blueprints/pages/default.yml
sections:
  languagerelease:
    type: languagerelease
    label: Language Release Status

The section shows a table with:

Column Description
Language The language name (e.g. "English", "Deutsch")
Code The language code (e.g. en, de)
Status Default, Released (green), or Unreleased (red)

The default language is always marked as "Default" since it does not require release.

Blueprint Examples

Sidebar Section

columns:
  - width: 2/3
    sections:
      content:
        type: fields
        fields:
          title:
            type: text
          text:
            type: textarea
  - width: 1/3
    sections:
      languagerelease:
        type: languagerelease
        label: Languages

Full-Width Section

sections:
  languagerelease:
    type: languagerelease
    label: Translation Status
  content:
    type: fields
    fields:
      # your fields...

Page Tree Section

The plugin also provides a tree section that displays all pages of the site (including drafts) in a hierarchical tree with their release status across all languages at a glance. This is useful for getting a bird's eye view of the entire site's translation status.

Add the Tree Section to Your Blueprint

The tree section is best suited for the site.yml blueprint or a dashboard-style page:

# site/blueprints/site.yml
sections:
  releasetree:
    type: languagerelease-tree
    label: Translation Overview

What the Tree Shows

The tree section renders a table with:

Column Description
Page Hierarchical page tree with expandable/collapsible children
Per Language One column per language with a colored dot indicating the status

Status indicators:

  • 🔘 Grey dot — Default language (always released)
  • 🟢 Green dot — Released
  • 🟡 Yellow dot — Translated but not yet released
  • 🔴 Red dot — No translation

Each page title links to its Panel page, and child pages can be expanded or collapsed.

Blueprint Examples

Site Blueprint (Recommended)

# site/blueprints/site.yml
columns:
  - width: 1/1
    sections:
      releasetree:
        type: languagerelease-tree
        label: Translation Overview

Combined with Per-Page Section

You can use both section types together — the tree for a global overview and the per-page section for the current page:

# site/blueprints/pages/default.yml
columns:
  - width: 2/3
    sections:
      content:
        type: fields
        fields:
          title:
            type: text
          text:
            type: textarea
  - width: 1/3
    sections:
      languagerelease:
        type: languagerelease
        label: This Page
      releasetree:
        type: languagerelease-tree
        label: All Pages

Configuration Options

Field Name

Define which field stores the release status:

'nerdcel.languagerelease.fieldName' => 'languageReleased'

Behavior for Unreleased Pages

Choose what happens when visitors try to access unreleased language variants:

Option 1: 404 (Default, Recommended)

'nerdcel.languagerelease.behavior' => '404'

Shows a 404 error page. Best for SEO and clear communication to search engines.

Option 2: Redirect

'nerdcel.languagerelease.behavior' => 'redirect'

Redirects to the default language (302 redirect). User-friendly but may confuse search engines.

Option 3: Default Content

'nerdcel.languagerelease.behavior' => 'default-content'

Displays content from the default language while keeping the URL. May cause duplicate content issues.

Environment-Specific Configuration

'nerdcel.languagerelease' => [
    'autoIncludeButton' => true,
    'fieldName' => 'languageReleased',
    'behavior' => match (option('environment')) {
        'production' => '404',
        'staging' => 'redirect',
        default => 'default-content',
    },
],

How It Works

Frontend Access Control

Visitor requests: example.com/en/page
                        ↓
              Is language released?
                        ↓
        ┌───────────────┴───────────────┐
        ↓                               ↓
      YES ✅                          NO ❌
        ↓                               ↓
   Page displays                  Behavior option:
    normally                     404 / redirect / default

Preview Mode (Panel)

Editors can preview unreleased pages through the Panel's preview button. The plugin validates preview tokens to ensure only authenticated users can access unreleased content.

Preview URL Parameters:

  • ?_preview=true&_token=xxx
  • ?version=changes&_token=xxx

The token is validated server-side, ensuring security.

Panel Access

All language variants remain fully accessible in the Panel:

  • ✅ View all languages
  • ✅ Edit all languages
  • ✅ Preview unreleased languages
  • ✅ No restrictions for editors

Usage in Templates

Check Release Status

// Check if current language is released
if (isLanguageReleased($page)) {
    echo 'This page is released';
}

// Filter for released pages only
$pages = $site->children()->filter(fn($p) => isLanguageReleased($p));

Get Field Name

$fieldName = languageReleaseFieldName();
// Returns: 'languageReleased' (or your custom field name)

Helper Functions

The plugin provides two global helper functions:

languageReleaseFieldName(): string

Returns the configured field name.

$field = languageReleaseFieldName();

isLanguageReleased(Page $page): bool

Checks if a page's current language variant is released.

if (isLanguageReleased($page)) {
    // Language is released
}

isAuthenticatedPreview(): bool

Checks if the current request is an authenticated preview.

if (isAuthenticatedPreview()) {
    // User is previewing with valid user session
}

Translations

The plugin includes translations for:

  • 🇩🇪 German (de)
  • 🇬🇧 English (en)
  • 🇪🇸 Spanish (es)
  • 🇫🇷 French (fr)
  • 🇮🇹 Italian (it)
  • 🇳🇱 Dutch (nl)

All Panel texts automatically display in the user's selected language.

Security

  • ✅ Preview tokens are validated server-side
  • ✅ Only authenticated users can preview unreleased content
  • ✅ Session-based authentication
  • ✅ No bypass mechanisms for unauthenticated users

Troubleshooting

Issue: All language variants are blocked after installation

Solution: This is expected behavior. Release your language variants through the Panel:

  1. Open a page
  2. Switch to the language
  3. Check the "Release Language Variant" checkbox

Issue: Preview button doesn't work

Solution: Make sure you're logged into the Panel. The preview requires a valid session.

Issue: Language Release section is empty

Solution: The section loads its data asynchronously from the Kirby API using the section mixin. Make sure the built index.js is up to date by running npm run build. If developing locally, use npm run dev for automatic rebuilds.

Issue: 404 errors on released pages

Solution: Check that the field name in your configuration matches the field in your blueprints.

Example Configurations

Minimal Configuration (Uses Defaults)

// No configuration needed - uses 'languageReleased' field and '404' behavior

Custom Field Name

return [
    'nerdcel.languagerelease' => [
        'autoIncludeButton' => true,
        'fieldName' => 'isPublished',
        'behavior' => '404',
    ],
];

User-Friendly Redirects

return [
    'nerdcel.languagerelease' => [
        'autoIncludeButton' => true,
        'fieldName' => 'languageReleased',
        'behavior' => 'redirect',
    ],
];

Development

Local Development

git clone https://github.com/nerdcel/kirby-languagerelease.git
cd kirby-languagerelease
composer install

Frontend Build

npm run build       # Build production assets
npm run dev         # Watch mode for development

Running Tests

composer test

Releasing

composer release:patch   # Bugfix (1.0.1 → 1.0.2)
composer release:minor   # Feature (1.0.1 → 1.1.0)
composer release:major   # Breaking change (1.0.1 → 2.0.0)

Changelog

See CHANGELOG.md for version history.

Contributing

Contributions are welcome! Please feel free to submit a Pull Request.

License

MIT License - see LICENSE file for details.

Credits

Developed by Marcel Hieke

Support

Made with ❤️ for the Kirby CMS community