The page editor is an optional plugin that adds a password-protected editor to the bottom of any page when ?editor=yourtoken is appended to the URL. It lets you edit page content and metadata, and create new pages, directly in the browser — with no database and no permanently exposed admin panel.
When $editorEnabled is set to false, zero editor code runs anywhere on the site. It is completely inert.
Installation
The editor plugin ships as three PHP files and one .htaccess file, all inside plugins/editor/. They are included in the framework repository. No additional setup is needed beyond configuration.
Configuration
All editor settings live in config/config.php inside the if ($loadplugins == true) block. There are three values to set:
$editorEnabled = true; $editorToken = 'your-random-token'; $editorPasswordHash = '$2y$10$...'; $editorSessionTimeout = 1800;
Generating a Password Hash
The editor uses a bcrypt password hash — you never store the plaintext password anywhere. To generate a hash:
Step 1. Create a new file anywhere in your site root — for example hash.php — containing exactly this:
<?php echo password_hash('yourpassword', PASSWORD_BCRYPT); ?>
Step 2. Visit that file in your browser: yoursite.com/hash.php
You will see a long string starting with $2y$10$ — something like:
$2y$10$92IXUNpkjO0rOQ5byMi.Ye4oKoEa3Ro9llC/.og/at2.uheWG/igi
Step 3. Copy that entire string and paste it as the value of $editorPasswordHash in config.php.
Step 4. Delete hash.php immediately. Do not leave it on your server.
If you ever want to change your password, repeat this process with the new password and replace the hash in config.php.
Setting the URL Token
The $editorToken is a secret string that must be present in the URL for the editor to appear at all. Anyone who doesn't know the token will see nothing — not even a login form. This keeps the editor's existence hidden from casual probing.
Choose something long and random. The easiest way is to generate one at the command line:
php -r "echo bin2hex(random_bytes(16));"
This produces a 32-character hex string like a3f8c2d1e4b7906f2a1d3c5e7b9f0d2e. Paste that as your token:
$editorToken = 'a3f8c2d1e4b7906f2a1d3c5e7b9f0d2e';
Alternatively, make up any string you like — just keep it long (16+ characters) and don't reuse a password or other credential.
Accessing the Editor
Once configured, append ?editor=yourtoken to any page URL:
https://yoursite.com/about?editor=a3f8c2d1e4b7906f2a1d3c5e7b9f0d2e https://yoursite.com/posts/my-post?editor=a3f8c2d1e4b7906f2a1d3c5e7b9f0d2e https://yoursite.com/documentation/introduction?editor=a3f8c2d1e4b7906f2a1d3c5e7b9f0d2e
If the token matches, a password prompt appears at the bottom of the page. Enter your password to unlock the editor. The session lasts for the duration set in $editorSessionTimeout (default 30 minutes) and expires automatically on inactivity.
If the token does not match, the page renders normally with no indication that an editor exists.
Using the Editor
Once authenticated, the editor appears below the page content with two tabs:
Edit this page
Shows the current page's metadata fields pre-populated — title, layout, type, date, author, image, excerpt, and keywords — along with a Summernote rich text editor loaded with the page's current content. Make your changes and click Save page. The file is written to disk immediately and the cache for that page is busted automatically.
New page
Provides the same metadata fields as a blank form, plus a content editor. The Page name / path field determines where the file will be created inside pages/:
aboutcreatespages/about.html, accessible at/aboutposts/my-postcreatespages/posts/my-post.html, accessible at/posts/my-postdocumentation/setup/myguidecreates the file in a subfolder, accessible at that path
Subfolders are created automatically if they don't exist. You cannot overwrite an existing page — if the file already exists you will get an error.
After a page is created the editor opens it automatically so you can continue editing straight away.
Session Timeout
$editorSessionTimeout controls how long an authenticated session lasts without activity, in seconds. The default is 1800 (30 minutes). Adjust it to suit your workflow:
$editorSessionTimeout = 3600; // 1 hour $editorSessionTimeout = 900; // 15 minutes
When a session expires you will be prompted to enter your password again.
Security Model
The editor uses several layers of protection:
| Layer | What it does |
|---|---|
| URL token | Hides the editor entirely from anyone who doesn't know the token. No login form is shown without it. |
| Password + bcrypt | Verifies identity on login. The plaintext password is never stored anywhere. |
| IP-based lockout | After 5 failed login attempts from the same IP address, the login form is disabled for 15 minutes. Persists across cookie resets. |
| Session regeneration | The session ID is rotated immediately on successful login, preventing session fixation attacks. |
| CSRF token | Every save, create, and logout action must include a cryptographically random token tied to the current session. Protects against cross-site request forgery. |
| Session timeout | Sessions expire automatically after the configured period of inactivity. |
| Secure cookie flags | The session cookie is flagged HttpOnly (no JavaScript access) and SameSite Strict. On HTTPS it is also flagged Secure. |
| Path validation | All file write operations validate that the target path resolves inside pages/. Path traversal attempts are rejected. |
Disabling the Editor
Set $editorEnabled = false in config.php. When false, the editor plugin is never included, no editor code runs on any page, and the ?editor query parameter is ignored entirely.