ūüöÄ A new era: Kirby 4 Get to know
Skip to content

Kirby 3.6

Jungle Calumma


Now even more awesome

The blocks field we introduced in Kirby 3.5 has lifted Kirby’s editing experience to another level. Now we are even taking it a step further.

  • Copy & Paste

    It’s finally here! You can now copy and paste blocks between block and layout fields. Even HTML from websites, Word documents or other sources can be pasted to create beautiful, clean blocks.

  • Improved multi-select

    To copy multiple blocks, you can cmd+click or alt+click on all blocks you want to include in your selection. Delete them all at once or copy them with cmd+c or via the copy button.

  • New line block

    The new line block supports and automatically imports hr blocks from the old Editor plugin and hr elements from pasted HTML.

  • Privacy friendly video block

    The video block is now more privacy friendly as it creates embeds with the "do not track" option. No tracking in the Panel please!


A new way to present your content

While lists are great for dense information and cards are fantastic to highlight visual content, there’s often a gray zone in between. The new cardlets layout option gives you nice visual previews while your text content is still represented decently. Use them in pages and files sections as well as pages, files and users fields.

layout: cards
A screenshot of the cards layout
    type: pages
    template: colleague
    layout: cards
layout: cardlets
A screenshot of the cardlets layout
    type: pages
    template: colleague
    layout: cardlets
layout: list
A screenshot of the list layout
    type: pages
    template: colleague
    layout: list

WebP & AVIF Support

Serve smaller and better images

With increasingly better browser support for WebP and AVIF on the horizon, optimizing images has become a lot easier.

The performance benefits are obvious. WebP can produce high quality images with roughly 50% smaller files compared to JPEG and AVIF can go even lower than that.

Our image processing engine now supports both formats, and with the help of the <picture> element you can even make older browsers happy. Learn more ›

JPEG 176.01 KB
WebP 46.25 KB
AVIF 53.02 KB
  <source srcset="<?= $image->thumb(['format' => 'avif'])->url() ?>" type="image/avif">
  <source srcset="<?= $image->thumb(['format' => 'webp'])->url() ?>" type="image/webp">
  <img src="<?= $image->thumb(['format' => 'jpg'])->url() ?>" alt="A highly optimized image">

Image options

Improve your previews with custom queries

You can now set custom backgrounds, icons, images and more for your pages via blueprint settings. Per page, not just per section.

    headline: Recipes
    type: pages
    info: "{{ page.categoryLabel }}"

  icon: "{{ page.categoryIcon }}"
  query: false
  color: black
  back: "{{ page.categoryColor }}"
A list with pages with custom colors and icons for previews in the panel

System & Languages

Two completely new views

The settings view has been replaced by a new system view with all kinds of additional information about your Kirby installation and a brand new languages view.

System View

A screenshot of the new system view

The system view contains the version and license information from the previous settings view. But now it also features additional health information about your setup, which will be extended step by step in later releases. It also contains a list of your installed plugins.

Languages View

A screenshot of the new languages view

Manage languages through the new languages view. Add new languages, update existing ones and protect language management via the brand-new access permissions.


Our architecture for the future

We‚Äôve spent the last months working on a brand-new backend architecture for the Panel. Moving away from a single page application to a more traditional approach with a simplified server-rendered backend. The new architecture is inspired by Inertia.js and simplifies our Panel and Panel plugins in ways that we‚Äôve never dreamed of. Learn more about Fiber ‚Äļ

Panel view definition in PHP
  'pattern' => 'todos',
  'action'  => function () {
    return [
      'component' => 'k-todo-view',
      'props' => [
        'title' => 'Todos',
        'todos' => [
          'Buy milk',
          'Try Kirby 3.6'

View component in Vue.js
  <k-header>{{ title }}</k-header>
    <li v-for="(todo, index) in todos" :key="index">
      {{ todo }}

export default {
  props: {
    title: String,
    todos: Array
  • Drastically reduced bundle size

    With the move to Fiber, we massively reduced the complexity and bundle size of the Panel. We shaved off more than 100 KB of uncompressed JavaScript. ūü§Į

  • Super simple plugins

    Panel plugins were already extremely powerful, but quite complex to build. With the new backend architecture, we handle many tasks on the server. Building views, dialogs and more is therefore far easier now. No need to be a Vue.js expert anymore.

  • Better performance

    With the smaller bundle size and fewer requests, the Panel becomes more performant for everyone, and will stay fast and lean even with a growing number of features and plugins. New views and dialogs no longer add to the bundle size. It’s the JS diet we’ve been looking for.

  • Future proof

    The new architecture paves the way for many fantastic features that have not been possible before.

Kirby 3.5.8

Total: 808.50 KB

457.04 KB
351.46 KB

Kirby 3.6.0

Total: 697.15 KB

385.04 KB
312.11 KB
-111.35 KB
less uncompressed JS

Panel areas

The plugin API you‚Äôve been dreaming of

Our new Fiber architecture splits the Panel in areas: site area, users area, system area, etc. You can create your own areas and build entire applications on top of the Panel. Learn more ›

Kirby::plugin('yourname/todos', [
  'areas' => [
    'todos' => function () {
      return [
        'label' => 'Todos',
        'icon'  => 'check',
        'menu'  => true
        'dialogs' => [
          'todos/create' => [
            'load' => function () { ... },
            'submit' => function () { ... }
        'views' => [
            'pattern' => 'todos',
            'action' => function () { ... }
  • Custom routes

    Building custom views with your own routes is now as simple as routing for your Kirby site. Define props for your view components and don't worry about API endpoints, state management or any other complex stuff. Just start building.

  • Your own dialogs in seconds

    Dialogs can now also be defined in PHP and opened with a simple JS call $dialog("my-dialog"). Create form dialogs, text dialogs or confirmation dialogs to delete entries. It’s so much fun.

  • Access control made simple

    You want your own permissions for your shiny new Panel area? No problem. It’s automatically handled for you. Deny access for individual roles and the Panel will make sure to keep those users out.

  • No more API endpoint hassle

    With Fiber, you return exactly the data you need for your Panel components. Goodbye to multiple API calls or custom API routes. Write some PHP and be done.

Shiny new icons

Improve your fields, tabs and more

  • audio
  • crop
  • display
  • flag
  • food
  • grid
  • grid-bottom
  • grid-bottom-left
  • grid-bottom-right
  • grid-full
  • grid-left
  • grid-right
  • grid-top
  • grid-top-right
  • grid-top-left
  • h1
  • h2
  • h3
  • h4
  • h5
  • h6
  • heart-outline
  • info
  • images
  • mobile
  • order-alpha-asc
  • order-alpha-desc
  • order-num-asc
  • order-num-desc
  • paragraph
  • paypal
  • pin
  • pipette
  • play
  • print
  • qr-code
  • server
  • shuffle
  • sitemap
  • star-outline
  • sun
  • table
  • tablet
  • text-center
  • text-justify
  • text-left
  • text-right
  • tiktok

This release is big

  • → 7 months of work
  • → 1293 commits
  • → 471 closed issues and pull requests
  • → And the update from Kirby 3.5 is free!

Ready to read the full changelog?
Here we go …




  • Cardlets: While lists are great for dense information and cards are fantastic if you want to highlight visual content, there's often a gray zone in between. The new cardlets layout option gives you nice visual previews while your text content is still representend decently. Use them in pages and files sections as well as pages, files and users fields.
  • New icons by popular demand (full list)
  • Set your own favicon(s) for the Panel ‚Äď the last step to a full white-label solution.


  • Copy & paste for blocks: It's finally here! You can now copy and paste blocks between block fields and even create blocks from pasted HTML and text.
  • New line block, which automatically supports and imports hr blocks from the old Editor plugin.


  • New slug field: perfect if you want to create sanitized strings for IDs, URL paths, CSS class names, etc. Learn more ›
  • New formats for the writer field: Our writer field is getting more powerful with headings and lists. Learn more ›
  • Email dialog for the writer field


  • Image options on steriods:
    • Support for Kirby's query language
    • Custom colors: back¬†and¬†color¬†options now support shorthands for core CSS colors as well as HEX codes or other native CSS color properties (e.g. even gradients)
    • Per blueprint: The image options for pages, files and users can now be defined directly in their own blueprint. You can still set image settings in sections the good old way if needed.
  • navigation option: The previous/next item navigation in the Panel is a very effective way for editors to move between content. We've drastically improved the usability of the navigation for your users with additional options to customize the links.
  • home option for users: When a user logs in to the Panel, they normally get redirected to the last view they were on before they were logged out, or the Site view. When you work with permissions, you might want to block the Site view or redirect the user to a completely different view instead. This is now possible with the new home option for user blueprints.


We have two brand new translations:

  • Icelandic (thanks to @herrajon)
  • Esperanto (thanks to @kirbyzone)

Thank you to our wonderful translators for keeping the other translations updated as well.

More …

  • Improved duplicate dialog, which now also accepts a title for the new page.
  • The settings view has been replaced by a new system view with all kinds of additional information about your Kirby installation and a brand new languages view.
  • The system view contains the version and license information from the previous settings view. But now it also features additional health information about your setup, which will be extended step by step in later releases. It also contains a list of your installed plugins.




  • The loading indicator of the Panel is now located in the breadcrumb.
  • Enhanced CSS support for RTL Panel interface #3556
  • The offline warning is now translatable with error.offline and has a new design.
  • Improved badge positioning on tabs¬†#3805


  • Improved parsing content from Word documents to create blocks #3770
  • Multiselect with Cmd/Ctrl keys for blocks field #3748
  • Blocks without fields don't open an empty drawer anymore (e.g. with the new line block).
  • Blocks are now always selected in the original order, independent of the order in which they were selected.
  • The video block is now more privacy friendly by creating embeds with the "do not track" option.


  • Writer field: marks (floating toolbar buttons) now show tooltips.
  • The files field can now accept new files via drag & drop.
  • The¬†toggle¬†field now supports the query syntax in the¬†text¬†property.


  • The file view now uses the stable preview link for files (instead of the media folder URL). #3575
  • File uploads now check for duplicates via SHA1 hashes. This leads to a better upload experience because when you upload the exact same file twice, the upload is simply ignored.
  • New files automatically store the sort attribute on upload if the files section is sortable. #2886


  • The page position field is hidden from dialogs when only one option is available (except when in¬†debug¬†mode).
  • Sorting pages is disabled in the page dropdown when only one option would be available.

More …

  • The license code is now only displayed to admins.
  • Canonical language URLs in the Panel #3759

Bug fixes


  • Fixed rotating loader in Firefox
  • Fixed jump to the top of the page at ESC keydown in an overlay #3387
  • cover option fixed for all models and list layout in section #3226
  • Fixed version number in settings view in RTL interface #3581
  • Fixed layout issue in the mobile version of the settings view #3789


  • The video block now displays domain-restricted clips in the Panel. #3257
  • Fixed blocks field sort handle on hover #3538
  • Fixed autofocus option for the blocks field #3681
  • Fixed opening blocks that have no fields or are not editable #3686
  • Fixed parsing logic for entire documents and breaks when pasting blocks #3735
  • Fixed nested blocks drawer breadcrumb issue¬†#3871


  • Fixed writer field RTL support idea 322
  • Fixed writer field email title #3630
  • Fixed multi-line placeholder for writer field #3470
  • Support for multi-line tags #3614
  • Fixed saving nested structure fields when the nested OK button was not clicked #2550


  • Fixed manual file sorting via changePosition dialog #3589
  • Account files are now fully accessible through the account view, even if the user doesn't have permissions for the users area. #2580


  • Changing the page title no longer causes errors with slug autocorrection (e.g. from underscores to dashes) if the user does not have permissions to change the slug
  • Top-level pages with a slug called files will no longer cause havoc. #3187
  • It's no longer possible to switch from draft to unlisted page if there are page errors.¬†#3781

More …

  • The Panel now sets the correct default language in multi language projects. #3647
  • Confirming an empty password dialog no longer throws an error. #3716
  • Login with invalid password now sends a HTTP 401 in debug mode. #2856

Breaking changes

We try to avoid breaking changes as much as we can. But we also put a lot of effort in keeping our technical debt in Kirby as low as possible. Sometimes such breaking changes are necessary to move forward with a clean code base.

You might wonder why there are breaking changes in a minor release according to Semantic Versioning.

We stick to the following versioning scheme:


This release is Kirby (major release 6 of Kirby 3)

Traditionally, we combine patch and minor releases though and only need the fourth versioning level for regression fixes.

New minimum browser requirements

Browsers with native ESM and dynamic import() support:

Browser OS Version
Android Browser Android 92+
Chrome Android 92+
Chrome iOS 95+
Chrome Win, macOS, Linux 63+
Edge Win, macOS, Linux 79+
Firefox Android 92+
Firefox iOS 34+
Firefox Win, macOS, Linux 67+
Opera Win, macOS, Linux 50+
Safari iOS 11+
Safari macOS 11.1+

Other browsers and versions might be compatible depending on their JS engine and CSS rendering capabilities.


  • Direct URLs for tabs have changed, e.g. now¬†/panel/site/?tab=yourTabName.
  • Direct URLs for the users view have changed, e.g. now¬†/panel/users/?role=yourRole.



Fiber - a whole new way of Panel extensions

We‚Äôve spent the last months working on a brand new backend architecture for the Panel. Moving away from a single page application to a more traditional approach with a simplified server-rendered backend. The new architecture is inspired by Inertia.js and simplifies our Panel and Panel plugins in ways that we‚Äôve never dreamed of. Learn more about Fiber ›

Supercharge blocks & layouts

Dynamic blueprints

Craft your own things for the Panel



Custom CSS properties

With 3.6 we leave SCSS behind and fully embrace modern CSS with custom properties in the Panel.

Logical CSS properties

Our RTL support is now powered by CSS logical properties, for now with fallback code for older browsers.

We encourage all plugin developers to look into logical properties for their Panel plugins. The fallback handling is natively supported by the kirbyup builder.


  • New theme property for k-dropdown-content to switch between dark (default) and light dropdowns
  • New¬†$store.dispatch("content/clear")¬†Vuex action that removes all unsaved changes from localStorage
  • New JS helper to deep-merge objects (helpers/object.js)
  • New $helper.clipboard helper handling reading from/writing to the clipboard
  • New $helper.color helper for turning a string into a valid CSS color value
  • $t() JS helper now supports a fallback value as third parameter
  • New v-direction directive to set the dir attribute based on the current content translation #3568
  • The¬†RadioInput¬†component now supports (escaped) HTML in the¬†info¬†property for radio options.
  • The k-dropdown-content component is now compatible with our dynamic Fiber dropdowns. You can pass a string for the options prop and the component will automatically load the matching Fiber dropdown defined in PHP.
  • Moved offline warning to new k-offline-warning component.
  • Default block previews can now be overridden. #3776
  • Add¬†data-id¬†for drawer and blocks
  • Updated inline docs for the writer field

More …

  • Improved plugin asset resolver #2422

Bug fixes

  • Extending a non-existing Vue component is ignored now instead of throwing a console error and breaking the Panel.
  • this.$helper.upload now correctly uses the method parameter.
  • k-progress now updates correctly when the prop value changes.
  • Added fallbacks for deprecated CSS classes #3706

Breaking changes

Custom Panel views

  • Using custom Panel views (incl. routing, breadcrumbs...) in plugins has changed fundamentally. You will have to use the new Panel areas extension now.
  • Accordingly, the frontend extension¬†panel.plugin({ view: [...] })¬†has been removed. Use Panel areas instead.

Kirby\Panel namespace related

  • If you have modified the ->panel*() methods in custom models, you now need to return a custom Panel model (based on Kirby\Panel\Model) at $page->panel() which then takes care of all Panel-related functions, e.g. if you had customized $page->panelImage() you need a custom Kirby\Panel\Page to then customize $page->panel()->image().
  • Use $model->panel()->image() instead of $model->panel()->icon().
  • $model->panel()->image() doesn't return cards and list keys anymore. Instead, src and srcset keys at the top level that correspond to the new $layout parameter.

Vue component changes

Removed Use instead
k-app k-panel, optionally k-inside to include topbar
k-cards k-items with layout: cards
k-card k-item with layout: cards
k-list k-items with layout: list
k-list-item k-item with layout: list
k-browser-view -
k-custom-view -
  • Removed icon prop from k-card and k-list-item. Pass data as part of the image prop instead to new k-item component.
  • If the cover option is not defined for a section, it is disabled by default.
  • The¬†<k-box text="..." />¬†property is now rendered as plain text by default instead of as HTML code. For the previous behavior use¬†<k-box text="..." :html="true" />.

Helpers & libraries

  • vue-router¬†has been completely removed, use Panel areas to define custom Panel routes.
  • The previewThumb helper has been removed. k-item-image takes care of processing the image data correctly inside k-item.


  • The following methods from vuex-i18n are no longer available in the new custom implementation: $tc, $tlang, $i18n.localeExists, $i18n.keyExists. Translation strings cannot be added dynamically anymore, only through our official extension.
  • The content¬†module doesn't handle content locking information anymore. This in now provided directly to the model views.
  • The language¬†module has been removed, use¬†this.$language¬†and¬†this.$languages¬†instead.
  • The system¬†module has been removed, use¬†this.$system¬†instead.
  • The translation¬†module has been removed, use¬†this.$translation¬†instead.
  • The user¬†module has been removed, use¬†this.$user¬†instead.
  • $store.dispatch('breadcrumb') and $store.dispatch('title') have been removed. Use Panel areas instead.

API methods

The following outdated $api methods have been removed in Vue:

  • $api.pages.breadcrumb
  • $api.files.breadcrumb
  • $api.users.breadcrumb
  • $api.site.breadcrumb
  • $api.site.options
  • $api.roles.options
  • $api.translations.options

CSS Selectors

  • .k-panel[data-translation]¬†is now¬†.k-panel[data-language].
  • .k-panel[data-translation-default]¬†is now¬†.k-panel[data-language-default].
  • CSS class .k-block-handle has been replaced with .k-sort-handle.




  • Added server-side sanitization in the writer field on field changes for extra security against XSS attacks
  • New¬†Kirby\Toolkit\Dom¬†class to parse, modify and sanitize DOM-based documents (XML and HTML)
  • New¬†Kirby\Sane\Html¬†class for validating and sanitizing HTML files or HTML snippets


  • The default block snippet for the image block now escapes the content output from the source, alt and link fields. This protects against XSS attacks against site visitors.
  • Str::safeTemplate($string, $data), which escapes HTML from all regular query placeholders and allows HTML with the new¬†{< site.myMethodWithHtml >}¬†syntax.
  • Safe templates are now also available for the Page, User, File and Site classes with the new $model->toSafeString()¬†method.

Sane classes

  • Improved error messages for file validation/sanitization errors (Sane¬†classes)
  • The¬†Sane¬†classes now have proper XML namespace support so that custom namespace prefixes are properly detected.
  • All Sane classes now support sanitization next to validation. We will integrate this into more places in the Panel (fields and file uploads) in future releases.

Remote requests

  • The Remote class now by default prefers the system certificate authority bundle (CA bundle) for verifying remote TLS connections if a bundle is configured in php.ini (curl.cainfo option). If no bundle is configured, Kirby will still use its internal CA bundle. You can override this behavior with the remote.ca option as before.


Code Quality

  • Updated npm dependencies #3744

Breaking changes


  • Several blueprint options that use the query syntax were updated to escape raw HTML output that may lead to XSS attacks. HTML code directly in the blueprint option (e.g. for formatting) still works as normal. If queries need to return HTML, you can use the new¬†{< >}¬†syntax. In this case you need to ensure manually that the returned HTML code is safe. With the¬†{{ }}¬†syntax, Kirby performs the escaping for you.
# works as normal
info: "This is <strong>{{ page.important }}</strong>"

# custom site method returns HTML, new `{< >}` syntax needed
info: "via {< site.myMethodWithHtml >}"


  • The public static configuration attributes of the¬†Sane¬†classes have been renamed for consistency with the new¬†Toolkit\Dom¬†class.
  • The¬†Sane\Svg::$allowedNamespaces¬†attribute now expects namespace reference names as the array keys instead of full attribute names (so¬†xmlns:xlink¬†should become just¬†xlink¬†and¬†xmlns¬†should become an empty string).
  • The¬†Sane\Svg::$allowedTags¬†attribute (before¬†$allowedElements) now is an associative array with the allowed attributes for this tag as the value. Attributes defined in $allowedAttrs are allowed globally and don't need to be copied to each tag.



Image formats

  • WebP & AVIF support: With increasingly better browser support for WebP and AVIF on the horizon, optimizing images has become a lot easier. Our image processing engine now supports both formats. Learn more ›
<?= $image->thumb(['width' => 200, 'format' => 'webp']) ?>
<?= $image->thumb(['width' => 200, 'format' => 'avif']) ?>

More powerful config options




  • The video embedding helpers and methods now use a much more robust URL parser with support for local and remote URLs. The same parser is used in the Panel for consistency. #3074
  • The video helper now allows custom <iframe> attributes


  • The avif file extension is now considered viewable. #2877
  • Invalid media URLs now render the full error page instead of a simple error to avoid information leaks and to allow overriding the error behavior with custom code on the error page. #3202
  • F::relativepath() now supports file paths with an unrelated base by prefixing ../ to build a relative path. #3267
  • F::size() and F::niceSize() accept an array of file paths.
  • Dir::size() has a new $recursive parameter to calculate the total size of the directory.


  • Improved API error paths when using a custom directory setup


  • The new license root allows to store the license outside of the config dir for easier deployments and multi-site setups.

Code quality

  • Improved docblocks for the HasChildren trait #3791
  • Additional unit tests for Filesystem, Cms, Form, Image and Panel classes
  • Cleaner solution to ignore entire files from code coverage

More …

Bug fixes


  • Hidden blocks are no longer visible in layouts.¬†#3857


  • Changing the slug of a page with an irrelevant .lock file no longer causes PHP to completely hang. #2516


  • Fixed unstable links/hashes for media files #3646
  • Fixed filename collision for cropped image files¬†#3418
  • The¬†image/svg¬†MIME type is now recognized by the¬†Sane¬†classes


  • Fixed inconsistent return types between the Query class insert method and shortcut Db::$queries['insert'] #3140
  • Fixed inner join queries #2501


  • Str::accepted always returns a float as¬†quality¬†value (before default¬†1¬†as int, all actual quality values as string, e.g.¬†'0.7') #3393
  • Str::pool(): The passed¬†$type¬†parameter is now treated case-insensitively. #3393
  • Str::pool()¬†now also returns a string (if set via the second argument) if an array of types is passed as first argument #3393

More …

  • The $field->replace() method no longer returns the model ID for empty fields, instead an empty string is returned as expected. #3652
  • User::changeEmail() and System::register() now convert the provided email address to lowercase for better reliability. #3307
  • Fixed return type for Kirby\Cms\App::translation() in DocBlock #3383
  • Fixed tc() helper docblock and parameter typing #3474
  • Fixed validation code for the Kirby\Form\FieldClass class

Breaking changes


  • Kirby no longer supports PHP 7.3, which will reach its¬†end-of-life date¬†soon. We will add support for PHP 8.1 to Kirby as soon as possible after the official release of PHP 8.1.


  • The video embedding helpers and methods no longer throw exceptions if the provided URL is invalid, instead null is returned.
  • Hidden blocks in the layout field will no longer be visible (as expected).
  • Html::encode(): Single quotes now are also converted.


  • All API endpoints for content locking/unlocking don't display an exception anymore when content locking isn't supported.


  • The crop keyword is now always present in filenames for cropped files. All center cropped files need to be regenerated.
  • File hooks: the¬†$upload¬†parameter is now a¬†Kirby\Filesystem\File¬†object, before¬†Kirby\Image\Image.
  • Kirby\Image\Image::__toString() returns the HTML <img> tag instead of the root string.
  • Kirby\Filesystem\File::header()¬†now returns¬†void¬†instead of an empty¬†string¬†by default.
  • F::modified()¬†does no longer calculate a maximum between mtime and ctime for file changes. This could in theory lead to different timestamps in some scenarios. Very unlikely though.
  • F::niceSize() doesn't check anymore whether the file exists.

Code Quality

  • Some argument and property types are now more specific and therefore stricter. #3282, #3241

Deprecated code that has been removed with 3.6.0

Removed Use instead
Kirby\Cms\Asset::alt() -
Kirby\Cms\Page::sort() Kirby\Cms\Page::changeSort()
Kirby\Cms\KirbyTags::$tagClass You cannot set the class for KirbyTag objects to be created via KirbyTags::parse() anymore.

Slugs in multi-language setups

  • Slugs in content files of the default language will be ignored. The slugs for the default language are now only decided by the folder names.

To check if you are affected by this, you can use our migration plugin. Place it in site/plugins and visit any frontend page of your Kirby site to check if you need to migrate some of your pages. We have tested the plugin in Kirby 3.5 and 3.6, so you can use it before or after the upgrade.

More …

  • $files->add() and $users->add() now throw exceptions when something other than a File/User object, a Files/Users object or a file/user ID is passed to them. Empty values (null, false and true) are silently ignored. #3248
  • Cms\Collection::has(): 1st parameter got renamed to $key.
  • Cms\Collection::indexOf(): 1st parameter got renamed to $needle.
  • Cms\Collection::query(): 1st parameter got renamed to $arguments.


Namespace changes

We refactored many file-related classes and started to gather all of them in the new Kirby\Filesystem namespace:

Before 3.6 In 3.6 Description
Kirby\Toolkit\File Kirby\Filesystem\File Everything related to a file in the filesystem - takes over a lot of functionality that was previously part of Kirby\Image\Image even for non-images.
Kirby\Image\Image Kirby\Image\Image Now extends Kirby\Filesystem\File and adds image-related methods (e.g. dimensions, exif).
Kirby\Cms\FileFoundation Kirby\Filesystem\IsFile Adds method-proxying to an asset object - either to Kirby\Filesystem\File or Kirby\Image\Image depending on the file type of the $root property.
Kirby\Cms\Asset Kirby\Filesystem\Asset
Kirby\Cms\Filename Kirby\Filesystem\Filename
Kirby\Toolkit\Dir Kirby\Filesystem\Dir
Kirby\Toolkit\F Kirby\Filesystem\F
Kirby\Toolkit\Mime Kirby\Filesystem\Mime

We also moved and merged some more classes to simplify the class setup:

Before 3.6 In 3.6 Reference
Kirby\Cms\Form Kirby\Form\Form #3312
Kirby\Cms\KirbyTag Kirby\Text\KirbyTag #3296
Kirby\Cms\KirbyTags Kirby\Text\KirbyTags #3296

For all these changes, we have added class aliases that we will keep around for the coming versions. This will make sure that your class references continue to work. We still encourage you to refactore your own code if you use one of those classes.

New Kirby\Panel classes

We've overhauled our Panel-specific code and moved everything into a new Kirby\Panel namespace. The new namespace contains classes that handle Panel-specific model logic in classes like Kirby\Panel\Page or Kirby\Panel\File.

We added a new ->panel() method to all models to access the Panel objects, so $page->panelImage() is now $page->panel()->image().

Before 3.6 In 3.6
$page->dragText() $page->panel()->dragText()
$page->panelId() $page->panel()->id()
$page->panelImage() $page->panel()->image()
$page->panelOptions() $page->panel()->options()
$page->panelPath() $page->panel()->path()
$page->panelPickerData() $page->panel()->pickerData()
$page->panelUrl() $page->panel()->url()

The old methods will keep working for now, but will be removed eventually.

In addition, we moved and merged some other classes to streamline the setup:

Before 3.6 In 3.6
Kirby\Cms\Panel Kirby\Panel\Panel
Kirby\Cms\PanelPlugins Kirby\Panel\Plugins



As part of modernizing our code base, we have marked some parts as deprecated in 3.6. Most of these parts will throw a deprecation warning when you are still using them. They will be removed in a future release. Let's point you towards the alternatives you can use instead:

API Endpoints

Deprecated Use instead Throws warning Removed in
GET pages/(:any)/children/blueprints GET pages/(:any)/blueprints yes 3.7.0
GET site/children/blueprints GET site/blueprints yes 3.7.0
GET (:all)/lock - yes 3.7.0
GET (:all)/unlock - yes 3.7.0

API Fields

Deprecated Use instead Throws warning Removed in
page.panelIcon page.panelImage yes 3.7.0
file.panelIcon file.panelImage yes 3.7.0


Deprecated Use instead Removed in
Users settings access permission system and languages 3.7.0

PHP Methods

Deprecated Use instead Throws warning Removed in
Kirby\Cms\App::setLocale() Kirby\Toolkit\Locale::set() yes 3.7.0
Kirby\Cms\Block::_key() Kirby\Cms\Block::type() yes 3.7.0
Kirby\Cms\Block::_uid() Kirby\Cms\Block::id() yes 3.7.0
Kirby\Toolkit\I18n::fallback() Kirby\Toolkit\I18n::fallbacks()[0] yes 3.7.0
$model->dragText() $model->panel()->dragText() 3.7.0 3.8.0
$model->panelIcon() $model->panel()->image() 3.7.0 3.8.0
$model->panelImage() $model->panel()->image() 3.7.0 3.8.0
$model->panelImageSource() $model->panel()->imageSource() 3.7.0 3.8.0
$model->panelPath() $model->panel()->path() 3.7.0 3.8.0
$model->panelPickerData() $model->panel()->pickerData() 3.7.0 3.8.0
$model->panelOptions() $model->panel()->options() 3.7.0 3.8.0
$model->panelUrl() $model->panel()->url() 3.7.0 3.8.0
Kirby\Toolkit\Str::isUrl() Kirby\Toolkit\V::url() 3.7.0 3.8.0

Vue code

Deprecated Use instead Throws warning Removed in
Vuex heartbeat module - yes 3.7.0
<k-text align="right"> <k-text align="end"> - 3.7.0

More …

  • The page() helper¬†now throws a deprecation warning if multiple IDs get passed. Will be enforced in 3.7.0 by only returning the first page. Use pages() for multiple pages instead.
  • pages()¬†will now throw a deprecation warning if a single ID gets passed. Will be enforced in 3.7.0 by always returning a Pages collection. Use page() for a single page instead.
  • Str::template(): the parameters $fallback, $start and $end have been deprecated and throw a deprecation warning. Use an $options array with fallback, start and/or end keys as third parameter instead.
  • Creating a Kirby\Cms\File without a parent property has been deprecated and throws a warning. Starting in 3.7.0 the property will be required and cause a breaking error if not passed. #3372
  • Use Tailwind sr-only utility instead of k-offscreen. The old class name is still available to avoid a breaking change.


Get started