In Kirby, pages are represented by folders in
/content. For each page, there is a separate folder that contains the corresponding text and media files.
Pages can have 3 states:
- listed and
Pages can be created directly in the file system, via the Panel or programmatically. If you create a new page via the Panel, it is always created as a draft. In the file system, you are free to create either drafts or listed/unlisted pages directly.
Pages are stored as subfolders of the
/content folder. To create a new page manually, create a new folder and add a text file with the extension
.txt (default) or
.md (optional configuration setting).
A simple folder structure could look like this:
The name of this file defines which template is used to render the content.
|Content filename||Template filename|
Each page folder is accessible via its URL, e.g. you can access the projects folder by entering your domain name followed by the UID of the folder into your browser's address bar:
https://example.com/projects. If your projects folder contains subpages, the subpage project-a would therefore be accessible via
URLs can be modified via Kirby's router.
Before a user can add new pages via the Panel, you have to set up a pages section that has either the status
draft or the status
Drafts are stored in a
_drafts subfolder for every page. These drafts are not accessible when you are not logged in. Every new page in the Panel is created as a draft first. This prevents accidental publishing of a page that is not ready yet.
How to create a draft
In the Panel
Click on the "Add" button in the top right corner of a list of pages. Every new page is automatically added as a draft.
In the content folder
If you want to create a draft manually in the content folder you can create a
_drafts subfolder in the parent page folder (if it's not there yet) and inside create your draft page folder.
How to publish a draft
In the Panel
To publish a draft in the Panel, click on the "Draft" button with the red status icon in the toolbar or go to "Settings" > "Change status".
To publish a draft in the Panel, all required fields must be filled in and all validations must pass. Otherwise publishing the draft will fail.
In the content folder
To publish a draft manually in your content folder, drag it from the
_drafts folder to the parent directory:
You can apply additional sorting by prepending a number if wanted. Delete the
_drafts folder if it's no longer needed. Otherwise there's no harm in just leaving it there.
Drafts are not included in
$page->children() collections. If you have to access them in your templates, you can use the
Listed pages are public pages with a sorting number in your content folder.
For a normal menu, a list of projects or any other non-alphabetical list you often need manual sorting. This is done by prepending a number followed by an underscore:
For blogs, events or anything else that is date-based, the date can be prepended as the sorting number, also followed by an underscore:
To sort pages alphabetically, 0 is prepended as the sorting number in the file system:
Pages without a sorting number are unlisted pages. Unlisted pages are still accessible by anyone who knows the URL to the page. Unlisted pages are useful if you want to exclude them from menus or any kind of list. A typical example for an unlisted page would be the error page or maybe a new project that still needs to be reviewed by the client via URL, but not yet listed.
Pages can also be created via Kirby's API methods in a controller, template, plugin, hook etc. This is useful if you want to create pages from form data, external files (like an Excel or CSV file), or from an external API.
The basic syntax for creating a page with code looks like this:
<?php $content = [ 'title' => 'An interesting title', 'text' => 'Some great content here…' ]; $page->createChild([ 'content' => $content, 'slug' => 'test-article', 'template' => 'article' ]);
The above code only works if you are logged in, because it respects the permissions of the currently logged in user.
One way to go without authentication is to impersonate the special
kirby super user, which has full permissions:
<?php $kirby = kirby(); $kirby->impersonate('kirby'); page('blog')->createChild([ 'content' => ['title' => 'Test'], 'slug' => 'a-great-article', 'template' => 'article' ]);
The impersonation will only last for the current request.