medienbaecker/kirby-modules

Easily add modules to your pages

Maintainers

Package info

github.com/medienbaecker/kirby-modules

Type:kirby-plugin

pkg:composer/medienbaecker/kirby-modules

Statistics

Installs: 5 304

Dependents: 1

Suggesters: 0

Stars: 87

Open Issues: 1

3.0.0 2025-12-13 18:57 UTC

README

Modular page building for Kirby using regular Kirby pages with their own blueprint and snippet, edited inline on the parent page.

Screenshot of the modules section with two modules, a text module with a textarea and a text with buttons module with both a textarea and a structure field for buttons

Licensing

Kirby Modules is a commercial plugin. You can use it for free on local environments but using it in production requires a valid licence. You can pay what you want, the suggested price being 99€ per project. Feel free to choose "0" when working on a purposeful project ❤️

Buy a licence

Features

  • Edit module fields inline on the parent page with a blocks-like UI
  • Draft previews for individual modules
  • Great performance with large numbers of modules
  • Robust multilanguage behaviour
  • Automatic container page creation, separating modules from regular subpages
  • Multiple modules sections per page
  • Sensible defaults in module blueprints

Installation

composer require medienbaecker/kirby-modules

Or download this repository and put it into site/plugins/kirby-modules.

What's a Module?

A module is a regular page, differentiated from other pages by being inside a modules container. This makes it possible to use pages as modules without sacrificing regular subpages.

Page
├── Subpage A
├── Subpage B
└── Modules
    ├── Module A
    └── Module B

Quick Start

Add a (or multiple) modules section to your page blueprint:

# site/blueprints/pages/default.yml
title: Default Page
sections:
  modules:
    type: modules

Create a module blueprint and snippet:

# site/blueprints/modules/text.yml
title: Text
fields:
  textarea:
    label: Text
// site/snippets/modules/text.php
<div id="<?= $module->slug() ?>">
  <?= $module->textarea()->kt() ?>
</div>

Or create both files using the CLI command:

kirby make:module gallery

In your snippet, $module is the module page and $page is the parent page. Variables from controllers are also available.

Module blueprints support the full Kirby blueprint layout, including columns and sections:

# site/blueprints/modules/images.yml
title: Images
icon: images
columns:
  - width: 1/2
    fields:
      title:
        label: Title
        type: text
      images:
        label: Images
        type: files
  - width: 1/2
    sections:
      files: true

Render in your template:

// site/templates/default.php
<?= $page->modules() ?>

Anchor Links

Use $module->slug() as the element ID in your module snippet:

<div id="<?= $module->slug() ?>">

The slug is editable in the Panel via the #anchor button on each module card or the "Change anchor" button in the toolbar's dropdown.

Drafts

Module status can be toggled between draft and listed with a single click. Drafts can be freely positioned between listed modules.

Each draft module gets a signed preview URL for authenticated frontend previews without Panel login. A preview button appears in the module's toolbar when the module is a draft.

Section Options

Option Type Description
default string First/pre-selected module type in create dialog
templates array Manually define available types instead of all
templatesIgnore array Hide specific module types
min int Minimum number of modules
max int Maximum number of modules
empty string Empty state text

Multiple Sections

Each section's name (YAML key) becomes the container slug:

sections:
  modules:
    type: modules
    default: text
  sidebar:
    type: modules
    templates:
      - module.cta
      - module.newsletter
// Default container for modules section called `modules`
<?= $page->modules() ?>

// Secondary container for modules section called `sidebar`
<?= $page->modules('sidebar') ?>

Config Options

// site/config/config.php
return [
  // Auto-publish new modules (default: draft)
  'medienbaecker.modules.create.status' => 'listed',

  // Redirect to module page after creation (default: false)
  'medienbaecker.modules.create.redirect' => true,
];

Template Methods

Method Description
$page->modules() All modules (default container)
$page->modules('sidebar') Modules from named container
$page->hasModules() Page has modules
$page->isModule() Page is a module
$module->moduleId() CSS class (e.g. module--text)
$module->moduleName() Blueprint title

Custom Models

Override the model for all module types via config:

// site/config/config.php
'medienbaecker.modules.model' => CustomModulePage::class,

Or override a single module type via site/models/ (as you would with any regular page):

// site/models/module.text.php
class ModuletextPage extends Medienbaecker\Modules\ModulePage {
  // your methods
}