Pages can be created via the Panel, directly in the file system, or programmatically. If you create a new page via the Panel, it is always created as a draft. In the file system, you can create pages with any state directly.
Before you can add new pages via the Panel, you have to set up a pages section in your page or site blueprint, with the status set to
Click on the "Add" button in the top right corner of a pages section. Every new page in the Panel is created as a draft first. This prevents accidental publishing of a page that is not ready yet.
Drafts are stored in a
_drafts subfolder for every page. These drafts are only accessible when you are logged in.
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 naming of these content files is important, because it 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 the 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 using Kirby's router.
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.
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 either logged in and have the necessary permissions for the action, or if you authenticate the user programmatically to perform the action Learn more about permissions and impersonating users.