johannschopplich/kirby-locked-pages

Password-protect pages for the Kirby CMS

Maintainers

Package info

github.com/johannschopplich/kirby-locked-pages

Homepage

Type:kirby-plugin

pkg:composer/johannschopplich/kirby-locked-pages

Transparency log

Statistics

Installs: 3 965

Dependents: 0

Suggesters: 0

Stars: 40

Open Issues: 0

3.0.0 2026-07-04 06:56 UTC

This package is auto-updated.

Last update: 2026-07-14 12:30:50 UTC


README

Kirby Locked Pages logo

Kirby Locked Pages

Password-protect a page – and its entire subtree – behind a login form, for the Kirby CMS.

FeaturesOptionsSecurity Scope

When to Use

I want to… Use
Password-protect a page and its children fields/locked-pages blueprint group
Give visitors a logout link locked-pages.logout hook
Restyle the password form site/templates/locked-pages-login.php
Check lock state from my own code Guard::isLocked($page)
Change the login slug, title, or error messages johannschopplich.locked-pages options

Features

🔒 Password Protection

Toggle protection on any page through a globally registered blueprint field group. Visitors are redirected to a login form until they enter the correct password, and the grant is then stored in their session.

sections:
  access:
    type: fields
    fields:
      protection: fields/locked-pages

The group adds a lockedPagesEnable toggle and a lockedPagesPassword field. Drafts and the error page are never locked, even when the fields are set.

🌳 Subtree Inheritance

Locking a page locks its whole subtree – you only add the field group at the subtree root. Unlocking the parent grants access to every descendant, keyed by the page's language-independent ID, so one unlock covers all translations. Content representations (.json, .xml, .rss, …) are locked alongside the page.

🚪 Logout Hook

Clear a visitor's grants by triggering the locked-pages.logout hook. Wire it to a route, then show a logout link only while the session holds a grant.

// config.php
return [
    'routes' => [
        [
            'pattern' => 'logout',
            'action' => function () {
                kirby()->trigger('locked-pages.logout');
                go('/');
            }
        ]
    ]
];
<?php use JohannSchopplich\LockedPages\Guard; ?>

<?php if (kirby()->session()->data()->get(Guard::SESSION_KEY)): ?>
  <a href="<?= url('logout') ?>">Logout</a>
<?php endif ?>

🎨 Custom Login Template

The plugin ships a self-contained login template. Drop your own locked-pages-login.php into site/templates/ and Kirby uses it automatically – the bundled template is a good starting point.

Requirements

  • Kirby 5
  • PHP 8.3+

Installation

Composer (Recommended)

composer require johannschopplich/kirby-locked-pages

Manual Installation

Download and copy this repository to /site/plugins/kirby-locked-pages.

Options

All options are namespaced under johannschopplich.locked-pages:

Option Default Description
slug locked Slug of the login form, relative to the site URL.
template locked-pages-login Template name for the login form.
title Page locked Title rendered on the login form.
longSession true Keep grants in a long (2-week) session with no idle timeout. false for a 2-hour one.
error.password The password is incorrect Message shown after a wrong password.
error.csrf The CSRF token is invalid Message shown when the CSRF token fails.

Example config.php:

return [
    'johannschopplich.locked-pages' => [
        'slug' => 'geschuetzt',
        'title' => 'Geschützte Seite',
        'error' => [
            'password' => 'Das Passwort ist nicht korrekt',
            'csrf' => 'Der CSRF-Token ist nicht korrekt'
        ]
    ]
];

Security Scope

This plugin gates page rendering – nothing else. Know its limits before relying on it:

  • Files are not protected. Anything under /media/pages/... is served statically by the web server, and the URL hash is not a secret – a locked page's images and downloads stay reachable by direct URL. To gate files, serve them through your own route that checks Guard::isLocked($page) before streaming. Kirby's files firewall cookbook covers the approach; adapt it to this plugin's session instead of a Panel login.
  • Passwords are stored in plaintext in the page's content file, as an editor-visible shared secret. Treat a locked page as hidden from casual visitors, not as a vault.
  • Grants last up to two weeks by default. Shorten them with longSession => false, or clear them through the logout hook.

Credits

Inspired by kirby-securedpages.

License

MIT License © 2021-PRESENT Johann Schopplich