Kirby 5 is here! Learn more
Skip to content

Breaking changes

Kirby 5

Breaking

Requirements

  • Kirby 5 requires at least PHP 8.2
  • Kirby 5 raises browser version requirements for the Panel:
    • Safari 16+
    • Mobile Safari 16+
    • Android Browser 126+
    • Chrome for Android 126+
    • (other browsers remain unchanged)

Core

Config options

  • Closures defined for the content.salt option will no longer receive a model when generating a salt for preview authentication tokens of drafts and versions as those tokens are now only based on the URI. The salt callback instead receives null and is expected to return a fixed model-independent salt in this case. When generating a salt for a file media token, the file object is still passed as model. #6836
  • The api.methodOverwrite option has been renamed to api.methodOverride
  • The content.fileRedirects option is now set to false by default. This protects uploaded file originals from unauthorized downloads. If you rely on the https://example.com/some/page/file.pdf or https://example.com/some-site-file.pdf routes, you can set the option to true or to a closure to control access dynamically per file.

Controllers

  • Data/variables from your site controller will now be passed to all templates #6412

Hooks

  • Model action before hooks: rules get applied before and after the hook runs

Collections

  • PHP type hints have been added to many collection methods. If you are extending Core classes, you might need to add the same to your own classes and methods.

Models

  • Kirby\Cms\HasMethods::callMethod() is now a protected method
  • Kirby\Cms\ModelWithContent::lock() will now always return a Kirby\Content\Lock object, even if the model is not currently locked. You can check for that case with ModelWithContent::lock()->isLocked()
  • Kirby\Cms\ModelWithContent::version() and Kirby\Cms\ModelWithContent::versions() are no longer available as direct field accessor. You need to use $model->content()->version()/$model->content()->versions() instead if you are using a field with the name version/versions.
  • Kirby\Cms\Page::modified(), Kirby\Cms\File::modifiedContent() and Kirby\Cms\User::modified() now use the current language instead of the default language.
  • Old model instances (objects that already were e.g. updated and returned a new model instance) can no longer modify their content. Calling actions on these old model instances will throw an exception. Use the new model instances instead.
  • All methods in *Rules classes are now marked to return void instead of a bool #6660

Content & Locking

  • Removed Kirby\Cms\ContentLock and Kirby\Cms\ContentLocks as well as Kirby\Cms\App::locks()
  • $kirby->contentToken() only accepts objectornull for the $model parameter instead of mixed. #6822
  • Renamed token query param for preview URLs to _token #6823

Pages

Users

  • User::create() does no longer accept null as argument.
  • Users without a role in their credentials file will now receive the default role (if exists), not the visitor role anymore #6656
  • Setting a name field in User::update() does no longer have any effect. Use User::changeName() instead.

Roles and Permissions

Media & Thumbnail generation

Plugins

Forms

  • Kirby\Form\Field::$formFields has been renamed to Kirby\Form\Field::$siblings
  • The $formField argument in Kirby\Form\Field::factory() has been renamed to $siblings
  • You can no longer pass a value to Kirby\Form\Field::isEmpty() Use Kirby\Form\Field::isEmptyValue($value) instead.
  • Kirby\Form\Form::fields() does no longer return null but an empty Kirby\Form\Fields collection if there are no fields.
  • Kirby\Form\Field::validate() returns an array of errors instead of void.
  • Removed protected Kirby\Form\Fields::$errors, Kirby\Form\Field::$errors and Kirby\Form\FieldClass::$errors properties #7131
  • The language argument in the protected internal Kirby\Form\Form::prepareForLanguage() method is no longer optional and must be a Language object. #7132
  • The Kirby\Form\Form class does no longer swallow errors in field classes on construction. This could be considered a breaking change or an debugging enhancement. #7167
  • When using the Kirby\Form\Form class, the disabled state of fields will no longer be overwritten on construction for secondary languages. Use Kirby\Form\Form::toProps() instead, to get the correct disabled state for each field. When using Kirby\Form\Form::toProps(), permissions will also be honored when the model cannot be updated by the user role. #7166
  • Kirby\Form\Form::$values has been removed #7166
  • Kirby\Form\Form::prepareFieldsForLanguage() has been removed #7166
  • The structure field ::form method does no longer have a $values parameter. Use $field->form()->fill() or $field->form()->submit() instead if you want to add values to the form. #7170

Filesystem

  • F::read() no longer supports requesting URLs with protocols such as http:// and https://. Please use the Remote class for this purpose. #7099
  • F::read() no longer silently returns false when the file exists but is not readable. Instead it triggers a PHP "Permission denied" warning. #7099

Toolkit

  • The Str::ucfirst() method no longer lowercases all but the first letter of the text, it only capitalizes the first letter. #6860
  • Str::camel(), Str::camelToKebab(), Str::float(), Str::kebab(), Str::kebabToCamel(), Str::length(), Str::lower(), Str::safeTemplate(), Str::short(), Str::slug(), Str::snake(), Str::studly(), Str::substr(), Str::template(), Str::ucfirst(), Str::ucwords(), Str::unhtml(), Str::upper() and Str::widont() can no longer be called without a value argument (passing a null value still works) #6401
  • Passing a single space as value to Xml::attr() won't render an empty value anymore but a single space. To render an empty value, please pass an empty string. #6803

Panel

Uploads

  • Panel uploads can exceed PHP’s upload_max_filesize limit #6421. If you want to restrict the upload size, please use the file blueprint accept maxsize option

Fields

  • All fields: signature is no longer available as field property when loading fields from the Panel backend #6712
  • Textarea field: File drag texts in the Panel always use the file UUID, if UUIDs are not disabled #6948
  • Date field: Calendar dropdown input will show Sunday now as first day of the week (depending on the user's language). If you want to enforce Monday as first day of the week, you can set the date.weekday option to 1. #6635
  • Select field: empty prop was removed. Use combination of requiredplaceholder and default to replicate functionality #6459
  • Checkbox and Toggle fields: required: true now enforces that these fields need to be checked/toggled (active state)

Custom Panel CSS

  • CSS attribute selectors must be written fully qualified (e.g. [data-hidden="true"] as only [data-hidden] can start matching also elements where that attribute is false) #6109

Vue Components

  • <k-form> and <k-fieldset> as well as many fields and inputs don't emit an invalid event anymore. Use native HTML invalid state of elements instead. #6099
  • novalidate prop has been removed from all elements but <k-form> #6099
  • Removed hasErrors methods of <k-fieldset> #6173
  • <k-file-preview> got fully refactored. If you were replacing or extending it, your code likely will break. Check out the new custom file preview feature if you want to provide previews for specific files. #6578
  • <k-draggable>: the move callback function is receiving an event with an altered data structure
  • While <k-writer> is still included as alias for <k-writer-input>, some use cases where you accessed the <k-writer> component via the $refs of <k-writer-input> have to be adapted #6172
  • <k-item>: Removed data-only-option attributes
  • <k-dialog>: Removed data-has-footer attribute
  • <k-toggles-input>: Removed data-disabled attribute
  • <k-writer-input>: Removed data-toolbar-inline attribute
  • <k-bubble>: Removed data-has-text attribute
  • <k-header>: Removed data-has-buttons attribute
  • <k-tag>: Removed data-has-image and data-has-toggle attributes
  • <k-tree>: Removed data-has-subtree attribute

Panel JS API

  • panel.view.isLocked no longer exists. Use panel.content.isLocked() instead #6515
  • Vuex and the Vuex content module have been removed.
  • The following dialogs no longer send dispatch events via the backend. Dispatch events relied on Vuex.
    • page.changeTitle
    • page.delete
    • page.move
    • user.delete
  • The panel.api.users.changePassword() method now receives three arguments for the user ID, the new password to set and the current password of the acting user (new) #7186

API

  • The PATCH: account/password and PATCH: users/$user/password API routes require an additional currentPassword parameter with the password of the acting user unless in password reset mode of the current user #7186
  • Removed API routes:
    • GET: /api/(:all)/lock
    • PATCH: /api/(:all)/lock
    • DELETE: /api/(:all)/lock
    • PATCH: /api/(:all)/unlock
    • DELETE: /api/(:all)/unlock

Translations

  • copy.success has been renamed to copy.success.multiple

Removed deprecated code

Removed Use instead
<k-aspect-ratio> <k-frame>
<k-autocomplete> -
<k-bar>: left, right and center slots default slot
<k-breadcrumb>: view prop Add as first entry to crumbs prop
<k-button>: tooltip prop title prop
<k-button-disabled> <k-button :disabled="true">
<k-button-link> <k-button link="...">
<k-button-native> <k-button>
<k-dialog>: disabled, icon and theme props. submit-button prop
<k-dropdown> <k-dropdown-content> as standalone
<k-grid>: gutter prop style="gap: " or variant prop
<k-header>: left and right slots buttons slot
<k-header>: tabs prop standalone <k-tabs>
<k-headline>: size prop tag prop
<k-headline>: theme prop -
<k-icon>: removed support for other viewBox than 0 0 24 24 Wrap icon in an <svg> element with corresponding viewBox attribute
<k-inside> <k-panel-inside>
<k-loader> <k-icon type="loader" />
<k-outside> <k-panel-outside>
<k-plugin-view> -
<k-progress>: set method value prop
<k-text>: theme prop -
<k-upload> $panel.upload module
<k-view> -
$store.drawer $panel.drawer
$store.notification $panel.notification
$store.dialog() $panel.dialog.open()
$store.drag() $panel.drag.start(type, data)
$store.fatal() $panel.notification.fatal()
$store.isLoading() $panel.isLoading
$store.navigate() -
JS $events.$on, $events.$off, $events.$emit $events.on, $events.off, $events.emit
window.panel.$api window.panel.api
window.panel.$config window.panel.config
window.panel.$direction window.panel.direction
window.panel.$events window.panel.events
window.panel.$language window.panel.language
window.panel.$languages window.panel.languages
window.panel.$license window.panel.license
window.panel.$multilang window.panel.multilang
window.panel.$search window.panel.search
window.panel.$searches window.panel.searches
window.panel.$translation window.panel.translation
window.panel.$url window.panel.url
window.panel.$urls window.panel.urls
window.panel.$user window.panel.user
window.panel.$view window.panel.view
window.panel.$vue window.panel.app
this.$config this.$panel.config
this.$direction this.$panel.direction
this.$language this.$panel.language
this.$languages this.$panel.languages
this.$license this.$panel.license
this.$menu this.$panel.menu
this.$multilang this.$panel.multilang
this.$search this.$panel.search
this.$searches this.$panel.searches
this.$system this.$panel.system
this.$translation this.$panel.translation
this.$urls this.$panel.urls
this.$user this.$panel.user
this.$view this.$panel.view
Array.wrap() this.$helper.array.wrap()
Array.fromObject() this.$helper.array.fromObject()
myArray.split() this.$helper.array.split(myArray, delimiter)
myArray.sortBy() this.$helper.array.sortBy(myArray, sortBy)
Kirby\Content\ContentTranslation Kirby\Content\Translation
Kirby\Cms\Model -
Kirby\Cms\ModelWithContent::readContent() $model->version()->read()
Kirby\Cms\ModelWithContent::writeContent() $model->version()->write()
Kirby\Cms\Properties trait PHP native named properties
Kirby\Cms\File::contentFileDirectory() -
Kirby\Cms\File::contentFileName() -
Kirby\Cms\ModelWithContent::contentFile() $model->storage()->contentFile()
Kirby\Cms\ModelWithContent::contentFiles() $model->storage()->contentFiles()
Kirby\Cms\ModelWithContent::contentFileDirectory() -
Kirby\Cms\ModelWithContent::contentFileName() -
Kirby\Cms\ModelWithContent::contentFileExtension() -
Kirby\Cms\Page::contentFileName() -
Kirby\Cms\Site::contentFileName() -
Kirby\Cms\User::contentFileName() -
Kirby\Form\FieldClass::valueFromJson() Kirby\Data\Json::decode()
Kirby\Form\FieldClass::valueFromYaml() Kirby\Data\Yaml::decode()
Kirby\Form\FieldClass::valueToJson() Kirby\Data\Json::encode()
Kirby\Form\FieldClass::valueToYaml() Kirby\Data\Yaml::encode()

Deprecated

Core

Models

Plugins

Forms

Exceptions

  • Exception classes: passing $arg array will be removed in a future version. Use named arguments. #6618

Panel

Config options

  • panel.favicon option throws deprecation warnings for url option (use href instead) and for rel key (use rel option instead)

Fields

  • Color field: the text => value notation for options has been deprecated and will be removed in Kirby 6. Please rewrite your options as value => text. #6913

Custom Panel CSS

  • --color-backdrop CSS property has been deprecated. Use --overlay-color-back instead #6299

Vue components

Panel JS API

  • TextareaInput.restoreSelectionCallback() has been deprecated. Use TextareaInput.restoreSelection() instead.

Kirby 4

Breaking

Core

  • Kirby 4 requires at least PHP 8.1 and supports up to PHP 8.3.
  • When impersonating the almighty kirby user, any permission check will succeed even if permission has been disabled for regular admins.
  • The twitter icon, KirbyTag and helper have been removed. Use the legacy plugin if you still rely on these: legacy-twitter.zip
  • We have added more native PHP type hints throughout the system. When extending core classes, this might require you to update your method to include those type hints as well.
  • Users field doesn't automatically use the current user as default, add default: true to keep this functionality.
  • When thumb generation fails, the image API now throws an error and no longer loads the original image.
  • Files: manipulate is now a core method and focus a reserved field by the core. These names are no longer available for custom file methods. Previous content fields with these names can only be accessed via e.g. $file->content()->get('manipulate').
  • I18n::translate(): If $fallback is an array and neither the array $key nor the array $fallback have a matching entry for the locale, the first element of the $key array will now be returned (not anymore the one from $fallback). If $fallback is a string, it will be considered with priority over both of these.
  • If overwriting the hidden field, it must return 'hidden' => true now.
  • Removed deprecated DS constant. Use / instead.
  • When sanitizing DOM objects (e.g. in the writer field, but not during the sanitization/validation of uploaded files), host-relative URLs that point outside the site root are now allowed as the use of the HTML <base> element is assumed for sites in a subfolder. To revert to the old, strict behavior, set Sane's allowHostRelativeUrls option to false.
  • Renamed parameter of ::group() method of all collection classes to $caseInsensitive
  • Errors are no longer hidden when a Response is converted to a string.
  • The $translations->start() and $translations->stop() methods were no longer in use and have been removed. Content files are automatically converted by the Language class.
  • $languages->codes() now returns ['default'] for single language installations.
  • Kirby\Panel\Assets::custom() now returns an array.
  • Kirby\Uuid\Uuid is now an abstract class, child classes need to implement the id method.
  • Kirby\Uuid\Uuid::key() can now also return null if the new $generate parameter isn't passed as true and no UUID has yet been generated for the model.
  • Kirby\Cms\ModelWithContent doesn't extend Kirby\Cms\Model anymore.
  • Removed the ::clone() method from Kirby\Cms\Auth\Status, Kirby\Http\Uri, Kirby\Cms\FileVersion, Kirby\Filesystem\Asset, Kirby\Filesystem\File, Kirby\Image\Image, Kirby\Cms\Plugin, Kirby\Cms\Role, Kirby\Cms\StructureObject and Kirby\Cms\ContentTranslation classes
  • Removed the ::hardcopy() method from Kirby\Api\Api, Kirby\Cms\Api,Kirby\Email\Email, Kirby\Email\Body, Kirby\Cms\Auth\Status, Kirby\Toolkit\Pagination, Kirby\Http\Uri, Kirby\Cms\FileVersion, Kirby\Filesystem\Asset, Kirby\Filesystem\File, Kirby\Image\Image, Kirby\Cms\Role, Kirby\Cms\StructureObject and Kirby\Cms\ContentTranslation classes
  • Removed ::site() method from Kirby\Cms\Plugin, Kirby\Cms\Role and Kirby\Cms\StructureObject classes
  • Removed ::kirby() method from Kirby\Cms\Role and Kirby\Cms\StructureObject classes
  • Unauthenticated API and Panel calls now return a correct 401 HTTP code instead of 403.
  • Registering a default block model now needs to be done with the key default, not Kirby\Cms\Block.
  • new Kirby\Cms\Structure()/new Kirby\Cms\StructureObject() don't work anymore as before. Use Kirby\Cms\Structure::factory()/Kirby\Cms\StructureObject::factory() instead.
  • Kirby\Cms\Items::factory() and all inheriting classes throw an exception now if malformed data is passed.
  • Extending the internal $model->contentFile(), $model->contentFiles(), $model->contentFileDirectory(), $model->contentFileExtension(), $model->contentFileName(), $model->readContent() and $model->writeContent() methods in a page model will no longer have an effect as these methods are no longer called by the core. Please extend the new Kirby\Content\PlainTextContentStorageHandler class instead and return an instance of your custom class from $model->storage(). Please note that the interface of PlainTextContentStorageHandler is internal and may change in the future.
  • New $isExternal argument for the Kirby\Sane\Handler::sanitize() and Kirby\Sane\Handler::validate() methods that custom Sane handlers need to implement; it allows to differentiate between strings from external files that may be accessed directly and strings that will end up directly on the page.

Panel

  • Blocks: Removed keyboard shortcut to move block focus up/down
  • Removed road-sign icon
  • The icons circle, heart and star are now named circle-filled, heart-filled and star-filled.
  • Removed this.$config.search from Panel
  • Area search plugins receive two additional arguments for their query callback: $limit and $page to be used to paginate the results. They should then return an array with entries results and pagination. #5191
  • <k-header> doesn't include tabs anymore by default. Use <k-tabs> separately.
  • Defining the footer slot in <k-dialog> will no longer wrap the slot content in the <footer> element. This can now be more flexibly handled by using <k-dialog-footer> inside the slot.
  • The form drawer no longer automatically closes on submit. This is introducing the same behaviour as in dialogs. Auto-closing might often not be the intended result of submitting the form and it's easier to close it manually in a submit handler than to re-open it again.
  • this.$store.state.isLoading is no longer available. You can now use window.panel.isLoading or this.$panel.isLoading in Vue components to access the current loading state.
  • this.$store.state.dialog is no longer available. Use this.$panel.dialog instead.
  • Removed this.$store.state.drag, use window.panel.drag/this.$panel.drag instead.
  • <k-button> , <k-link><k-headline> and <k-content-item> only emit the click event. For other native events, use the .native event listener modifier.
  • Native events (e.g. clickdbclick) need the .native modifier now when used on <k-block> and <k-block-title>
  • Need to use .native modifier for all previous event listeners on <k-box and <k-image>
  • <k-pagination> doesn't support setting custom labels/titles via nextLabel, prevLabel or pageLabel
  • <k-range was removed and replaced by <k-alpha-range> and <k-hue-range>.
  • <k-choice> has been removed. Use <k-choice-input> instead.
  • The unused theme prop has been removed from <k-choice-input>.

Removed deprecated code

  • The Kirby\Form\OptionsKirby\Form\OptionsApi and Kirby\Form\OptionsQuery classes have been removed. Use Kirby\Option\OptionsKirby\Option\OptionsApi or Kirby\Option\OptionsQuery instead.
  • The Kirby\Toolkit\Query class has been removed. Use Kirby\Query\Query instead.
  • Passing the $slot or $slots variables to snippets was deprecated and support has now finally been removed.
  • Passing an empty string as value to Xml::attr() (deprecated in Kirby 3.9) no longer omits the attribute but generates an attribute with an empty value.

Deprecated

Core

  • Files in a plugin's assets directory are now always assumed to be public, independent of their file extension. If your plugin needs to store other files in the assets directory, please use the new assets extension to explicitly define the public assets.
  • Passing a single space as value to Xml::attr() (with the intention to generate an attribute with an empty value) has been deprecated in favor of passing an empty string.
  • Kirby\Cms\Model: Use Kirby\Cms\ModelWithContent instead
  • Kirby\Email\Email::clone() and Kirby\Email\Body::clone()
  • Page::isReadable(): Use Page::isAccessible() instead
  • The name query should not be used for custom API endpoints anymore, it will be used for the Kirby QL (KQL) plugin/core implementation
  • Internal $model->contentFile(), $model->contentFiles(), $model->contentFileDirectory(), $model->contentFileExtension() and $model->contentFileName() methods have been deprecated and will be removed in v5.

Panel

  • Custom icons using a 16x16 viewbox have been deprecated. In an upcoming version, Kirby will only support custom icons with a 24x24 viewbox by default. If you want to continue using icons with a different viewport, please wrap them in an <svg> element with the corresponding viewBox attribute.
  • Icons circle-outline, heart-outline and star-outline: Use circle, heart and star instead
  • this.$events: Use this.$panel.events instead
  • this.$panel.events.$on: Use this.$panel.events.on instead
  • this.$panel.events.$off: Use this.$panel.events.off instead
  • this.$panel.events.$emit: Use this.$panel.events.emit instead
  • this.$store.dispatch("isLoading"): Use this.$panel.isLoading instead
  • this.$translation: Use this.$panel.translation instead
  • this.$store.dispatch("dialog"): Use this.$panel.dialog.open and this.$panel.dialog.close instead
  • this.$store.dispatch("drag", drag): Use this.$panel.drag = drag instead
  • k-dropdown: Use k-dropdown-content as standalone instead
  • k-calendar was renamed to k-calendar-input; k-calendar is still available but only as deprecated alias.

Migration Guides

Kirby 3.9

Breaking

  • $kirby->impersonate() doesn't bind the app instance to the $callback closure anymore. You can access the app instance with Kirby\Cms\App::instance() or the kirby() helper. #4944
  • The snippet core component receives an additional parameter bool $slots and needs to return Kirby\Template\Snippetorstring for slot support. If you override the snippet component, please adapt the logic to the new core component. #4910
  • $kirby->snippet() and the snippet() helper return Kirby\Template\Snippetorstringornull #4910
  • Html::rel() now consistently returns null instead of an empty string when no rel attribute is needed #4948
  • A::missing() no longer treats an existing array key with a null value as missing #4942

Removed deprecated code

Deprecated

  • Manually passing $slot or $slots as data variables to snippets is deprecated. In a future Kirby version, those variables will be overridden with the Slot and Slots objects. #4963
  • The Toolkit\Query class has been deprecated and will be removed in a future version. Use Query\Query instead. #4944
  • Passing an empty string as value to Xml::attr() / Html::attr() has been deprecated and will throw a warning. In a future version, passing an empty string won't omit the attribute anymore but render it with an empty value. To omit the attribute, please pass null. #4934
  • The .k-offscreen CSS class has been deprecated. Use .sr-only instead. #4944

Kirby 3.8

Breaking

Panel

  • The multiselect field no longer displays the option value as info #4624

Core

  • Kirby 3.8.0 requires a minimum of PHP 8.0.
  • uuid and permalink cannot be used as field name or custom method for any page, file, user or site anymore. Content fields can only be accessed via e.g. $model->content()->get('permalink').
  • The first-level URL path @ is now blocked.
  • Kirby's upload sanitizer no longer checks XML files for external links because they can be pretty common in many XML-based formats; if you want to keep the strict behavior, set Kirby\Sane\Xml::$allowedDomains = [], set this property to a custom allowlist or write a custom Sane handler for your XML-based format #4553
  • Kirby now automatically loads the site/config/env.php file; if you already use this file path for a different purpose, please rename the file to a different name #4580
  • A::average() returns null when passed an empty array #4649
  • The default token fallback in Str::safeTemplate() changed from an empty string to null (which leaves invalid tokens in the output string). This behavior is consistent with Str::template().
  • $translation->exists() now returns true for translations without an actual content file but where an content array has been provided
  • The deprecated master branch of the Kirby repository was deleted. If you install Kirby via Git, e.g. as a submodule, please use the main branch instead.
  • Database queries: subsequent ->where() clauses don't support passing the mode (AND|OR) as last parameter anymore, but will interpret these as actual values to filter against. Use ->andWhere() or ->orWhere() instead. #4668
  • Helpers::handleErrors()'s 2nd parameter now only determines whether the error is suppressed, its 3rd parameter defines what is returned when an error is suppressed

Removed deprecated code #4478 #4515

Removed dump component. Disable dump() via KIRBY_HELPER_DUMP instead and create your own function.

PHP methods

Removed Use instead
$file->dragText() $file->panel()->dragText()
$file->panelIcon() $file->panel()->image()
$file->panelImage() $file->panel()->image()
$file->panelOptions() $file->panel()->options()
$file->panelPath() $file->panel()->path()
$file->panelUrl() $file->panel()->url()
$file->pickerData() $file->panel()->pickerData()
$files->findById() $files->find()
$page->dragText() $page->panel()->dragText()
$page->panelIcon() $page->panel()->image()
$page->panelId() $page->panel()->id()
$page->panelImage() $page->panel()->image()
$page->panelOptions() $page->panel()->options()
$page->panelPath() $page->panel()->path()
$page->panelUrl() $page->panel()->url()
$page->pickerData() $page->panel()->pickerData()
$pages->findById() $pages->find()
$pages->findByIdRecursive() $pages->find()
$pages->findByUri() $pages->find()
$site->panelIcon() $site->panel()->image()
$site->panelImage() $site->panel()->image()
$site->panelOptions() $site->panel()->options()
$site->panelPath() $site->panel()->path()
$site->panelUrl() $site->panel()->url()
$site->pickerData() $site->panel()->pickerData()
$user->panelIcon() $user->panel()->image()
$user->panelImage() $user->panel()->image()
$user->panelOptions() $user->panel()->options()
$user->panelPath() $user->panel()->path()
$user->panelUrl() $user->panel()->url()
$user->pickerData() $user->panel()->pickerData()
Kirby\Panel\Document::customCss() Kirby\Panel\Document::customAsset('panel.css')
Kirby\Panel\Document::customJs() Kirby\Panel\Document::customAsset('panel.js')
Kirby\Toolkit\Str::isUrl() Kirby\Toolkit\V::url()
Method Change Use instead
markdown component Removed $inline parameter $options['inline']
$kirby->kirbytext() Removed $inline parameter $options['markdown']['inline']
$kirby->markdown() Passing a boolean as second parameter isn't supported anymore. $options['inline']

Classes

Removed Use instead
Kirby\Http\Server Kirby\Http\Environment

Class Aliases

Removed
Server

API

Removed
page.next
page.prev

Deprecated

  • $kirby->impersonate($user, $callback): The $callback will not be bound anymore to the $kirby instance in Kirby 3.9.0, $this inside the callback will refer to the current context and not $kirby instead. Using $this as $kirby inside the callback will throw a deprecation warning in debug mode. #4498
  • Blueprints: The headline option for sections will be removed in a future Kirby version. Use label instead. #4515
  • $kirby->server() has been deprecated and will be removed in Kirby 3.9.0. Use $kirby->environment() instead. #4515
  • Kirby\Form\Options, Kirby\Form\OptionsApi, Kirby\Form\OptionsQuery have been deprecated and will be removed in Kirby 3.9. Use their Kirby\Option equivalents instead.

Kirby 3.7

Breaking

Composer installation

If you install Kirby using Composer, you may run into errors if your command line installation of PHP doesn’t have the extensions installed that Kirby requires. If you are sure that your web server fulfills the requirements, you can use Composer’s --ignore-platform-reqs or --ignore-platform-req=ext-* flags. #4216

Core

  • Http\Router::$beforeEach and Http\Router::$afterEach aren't static anymore. Pass them in an array as second argument to the constructor instead. #4260
  • Custom auth type classes in the Kirby\Http\Request\Auth\ namespace now need to be registered in the Kirby\Http\Request::$authTypes array. We also recommend to move the classes to your own namespace to avoid interference with core classes. #4264
  • Field names of virtual pages' content are now converted to lowercase. If your virtual page has two fields that only differ in capitalization, only the last defined one will be available.
  • The Server::hosts() method was removed. Please set the allowed URLs via the url option.
  • page helper now always only returns a Kirby\Cms\Page object or null, never a pages collection. Only allows passing a single id as parameter. #4335
  • pages helper now always only returns a Kirby\Cms\Pages collection or null, never single page object. #4335
  • Creating a Kirby\Cms\File object requires the parent property now. #4335
  • Toolkit\Str::toBytes() strictly only accepts a string as parameter now. #4335
  • The $pages->children(), $pages->drafts() and $pages->index() methods no longer set the $pages->parent() object as the collection items can have multiple different parents. This can change the behaviour when finding collection items in secondary languages and when merging collections. #4105
  • The dump() and e() helper function checks have been removed. If your plugins or dependencies have functions with these two names, you will get an error. You can override the conflicting functions by defining the KIRBY_HELPER_* contants. Check out how to do it.
  • The second argument of the kirbytextinline() and kti() helpers has been renamed from $data to $options

Removed methods

The following deprecated methods/parts have been removed #4335

Removed Use instead
Cms\App::setLocale() Toolkit\Locale::set()
Cms\Block::_key() Cms\Block::type()
Cms\Block::_uid() Cms\Block::id()
Toolkit\I18n::fallback() Toolkit\I18n::fallbacks()
Toolkit\Str::template(): $fallback, $start and $end parameters pass an array to the $options parameter

Panel

  • k-block-type-table and k-structure-field have been largely refactored. If you (or a plugin) extends these, stuff might break.
  • k-pages-section and k-files-section have been modified extensively #4247
  • Toolkit\Html::attr([], null) now consistently returns null instead of an empty string. #4018
  • Removed builder and editor field migration for blocks field.

API

The following deprecated methods/parts have been removed #4335

Removed Use instead
API fields page.panelIcon / file.panelIcon page.panelImage / file.panelImage
GET (:all)/lock API endpoint -
GET (:all)/unlock API endpoint -
GET pages/(:any)/children/blueprints API endpoint GET pages/(:any)/blueprints
GET site/children/blueprints API endpoint GET site/blueprints
JS API method files.rename() files.changeName()
JS API method pages.slug() pages.changeSlug()
JS API method pages.status() pages.changeStatus()
JS API method pages.template() pages.changeTemplate()
JS API method pages.title() pages.changeTitle()
JS API method site.title() site.changeTitle()
JS API method system.info() system.get()

Deprecated

  • The dump component was deprecated and superseded by the new feature to replace helpers (KIRBY_HELPER_DUMP constant). The component will be removed in Kirby 3.8.0. #4018
  • Http\Server class will be removed in 3.8.0
  • The constants in Http\Server:: are now deprecated and will be removed in 3.8.0. They are no longer needed.
  • The $pages->findById() and $pages->findByUri() methods have been deprecated and will be removed in 3.8.0. If you want to directly get a page by ID, use $pages->get(). If you want the previous fuzzy behaviour that queries both by ID and URI, use $pages->find().
  • The $pages->findByIdRecursive() method has been deprecated and will be removed in v3.8.0. Please use $pages->find() instead.
  • The $files->findById() method has been deprecated and will be removed in v3.8.0. Please use $files->find() instead.
  • The $pages->findByKey(), $files->findByKey() and $users->findByKey() methods have been marked as internal. Please use the find() methods instead.
  • The $inline parameter in $kirby->kirbytext() is deprecated. Use $options['markdown']['inline'] instead.
  • The $inline parameter in $kirby->markdown() is deprecated. Use $options['inline'] instead.
  • Blueprint presets page, pages and files are deprecated.

Deprecation warnings

The following deprecated methods/parts throw warnings in 3.7.0 and will be removed starting in 3.8.0 #4335

Methods

Deprecated Use instead Removed in
$file->dragText() $file->panel()->dragText() 3.8
$file->panelIcon() $file->panel()->icon() 3.8
$file->panelImage() $file->panel()->image() 3.8
$file->panelOptions() $file->panel()->options() 3.8
$file->panelPath() $file->panel()->path() 3.8
$file->panelUrl() $file->panel()->url() 3.8
$file->pickerData() $file->panel()->pickerData() 3.8
$files->findById() $files->find() 3.8
$kirby->server() $kirby->environment() 3.9
$page->dragText() $page->panel()->dragText() 3.8
$page->panelIcon() $page->panel()->icon() 3.8
$page->panelId() $page->panel()->id() 3.8
$page->panelImage() $page->panel()->image() 3.8
$page->panelOptions() $page->panel()->options() 3.8
$page->panelPath() $page->panel()->path() 3.8
$page->panelUrl() $page->panel()->url() 3.8
$page->pickerData() $page->panel()->pickerData() 3.8
$pages->findById() $pages->find() 3.8
$pages->findByIdRecursive() $pages->find() 3.8
$pages->findByUri() $pages->find() 3.8
$site->panelIcon() $site->panel()->icon() 3.8
$site->panelImage() $site->panel()->image() 3.8
$site->panelOptions() $site->panel()->options() 3.8
$site->panelPath() $site->panel()->path() 3.8
$site->panelUrl() $site->panel()->url() 3.8
$site->pickerData() $site->panel()->pickerData() 3.8
$user->panelIcon() $user->panel()->icon() 3.8
$user->panelImage() $user->panel()->image() 3.8
$user->panelOptions() $user->panel()->options() 3.8
$user->panelPath() $user->panel()->path() 3.8
$user->panelUrl() $user->panel()->url() 3.8
$user->pickerData() $user->panel()->pickerData() 3.8
Panel\Document::customCss() Panel\Document::customAsset('panel.css') 3.8
Panel\Document::customJs() Panel\Document::customAsset('panel.js') 3.8

API

Deprecated Use instead Removed in
API field page.next - 3.8
API field page.prev - 3.8

Kirby 3.6

Breaking

Breaking changes in minor releases? 3.6 is not a minor release. We follow the pattern {generation.major.minor.patch}

3.6.0.0 is the 6th major release for Kirby 3 and it's a really big and important step. We don't take breaking changes lightly but they sometimes have to happen in order to keep moving forward.

Panel

For all users

  • New minimum browser requirements (browsers with native ESM and dynamic import() support):

    • Firefox 67+
    • Chrome 63+
    • Edge 79+
    • Opera 50+
    • macOS Safari 11.1+
    • Safari iOS 11+
    • Android Browser 92+
    • Chrome for Android 92+
  • Several blueprint options that use the query syntax were updated to escape against raw HTML output that may lead to XSS attacks. HTML code directly in the blueprint option 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 >}"
  • 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

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.
  • 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-inside (authenticated) or k-outside (unauthenticated)
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
  • Changes in the Vuex store and store modules
    • content module doesn't handle content locking information anymore. This in now provided directly to the model views.
    • language module has been removed, use this.$language and this.$languages instead.
    • system module has been removed, use this.$system instead.
    • translation module has been removed, use this.$translation instead.
    • user module has been removed, use this.$user instead.
    • $store.dispatch('breadcrumb') and $store.dispatch('title')have been removed. Use Panel areas instead.
  • 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.
  • Removed outdated $api methods 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

Core

  • 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.
  • Multi-language setup: slugs in content files of the default language will be ignored. The folder names decide the slugs for the default language.
  • Hidden blocks in the layout field will no longer be visible (as expected)
  • $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
  • 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.
  • Html::encode(): Single quotes now are also converted
  • Kirby\Image\Image::__toString() returns the HTML <img> tag instead of the root string
  • File hooks: the $upload parameter is now a Kirby\Filesystem\File object, before Kirby\Image\Image
  • The video embedding helpers and methods no longer throw exceptions if the provided URL is invalid, instead null is returned.
  • Kirby\Toolkit\File::header() now returns void instead of an empty string by default
  • F::niceSize() doesn't check anymore whether file exists
  • 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
  • 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.
  • 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
  • Some argument and property types are now more specific and therefore stricter #3282, #3241
  • In multi-lang setups, calling $pages->find(), $pages->findById() or $pages->findByUri() on a non-children collection (e.g. grandchildren) with just a slug no longer works. This makes the Pages class more consistent between single and multi language setups.

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.

Deprecated

Removed methods

The following methods have been marked as deprecated since Kirby 3.0.0 and are now removed.

Removed Use instead
$file->meta() $file->content()
$file->rename() $file->changeName()
$languages->findDefault() $languages->default()
$page->hasInvisibleChildren() $page->hasUnlistedChildren()
$page->hasNextVisible() $page->hasNextListed()
$page->hasNextInvisible() $page->hasNextUnlisted()
$page->hasPrevInvisible() $page->hasPrevUnlisted()
$page->hasPrevVisible() $page->hasPrevListed()
$page->hasVisibleChildren() $page->hasListedChildren()
$page->nextVisible() $page->nextListed()
$page->nextInvisible() $page->nextUnlisted()
$page->prevVisible() $page->prevListed()
$page->prevInvisible() $page->prevUnlisted()
$page->isInvisible() $page->isUnlisted()
$page->isVisible() $page->isListed()
$pages->invisible() $pages->unlisted()
$pages->visible() $pages->listed()
Deprecated methods

Deprecated methods will be removed in a future version. Please update your code accordingly.

Deprecated Use instead
$page->sort() $page->changeSort()

Kirby 3.5

Breaking

Required PHP Version

With this release we drop support for PHP 7.2, which has reached end of life. But we also introduce support for the brand-new stable version of PHP 8.0, which has been released on December 1st.

Date field format option

3.5.0 is dropping the format option of the date field. This is a breaking change which we will reverse in 3.5.1.

accept option for file blueprints

If no custom accept restrictions are defined in the file blueprint, Kirby will now limit the accepted uploads to the types image, document, archive, audio and video by default. This protects your sites against unexpected uploads like code files that could be used to attack the server or the visitor's browsers.

You can customize the accepted file types in the file blueprint.

Deprecated

Removed methods

The following methods have been marked as deprecated since Kirby 3.0.0 and are now removed.

Removed Use instead
$file->meta() $file->content()
$file->rename() $file->changeName()
$languages->findDefault() $languages->default()
$page->hasInvisibleChildren() $page->hasUnlistedChildren()
$page->hasNextVisible() $page->hasNextListed()
$page->hasNextInvisible() $page->hasNextUnlisted()
$page->hasPrevInvisible() $page->hasPrevUnlisted()
$page->hasPrevVisible() $page->hasPrevListed()
$page->hasVisibleChildren() $page->hasListedChildren()
$page->nextVisible() $page->nextListed()
$page->nextInvisible() $page->nextUnlisted()
$page->prevVisible() $page->prevListed()
$page->prevInvisible() $page->prevUnlisted()
$page->isInvisible() $page->isUnlisted()
$page->isVisible() $page->isListed()
$pages->invisible() $pages->unlisted()
$pages->visible() $pages->listed()

Deprecated methods

Deprecated methods will be removed in a future version. Please update your code accordingly.

Deprecated Use instead
$page->sort() $page->changeSort()

Kirby 3.4

Breaking

To ensure proper nesting, Kirby relies on the plugin option default values defined in the plugin using the options extension. If your plugin uses a nested structure in the option defaults, the defaults need to be changed to use the dot notation.

Only options registered in that way can be set in all supported ways (dot notation, fully or partially nested) in the site config. You can read more about this in the reference.

Kirby 3.3

Breaking

  • The pagination object is now immutable and all setters are disabled by default #1887
  • The Vuex form store module in the panel has been refactored and is now called content. If your panel plugin works with the form store module, please check out the refactored module. Conversion won't be difficult. We made lots of thinks a lot cleaner. But you need to rename the actions or getters that you use from the old module.
  • The v-tab directive is no longer available. Tabbable elements should use the tab mixin

Deprecated

Deprecated methods

We've also added deprecation warnings to additional core methods. You will run into an exception if the debug mode is active. You can keep those methods for now in production (with disabled debug mode), but we recommend to convert them as soon as possible. Here are the deprecated methods and how to replace them:

  • File::meta (use File::content instead)
  • File::rename (use File::changeName instead)
  • Languages::findDefault (use Languages::default() instead)
  • Page::hasInvisibleChildren (use Page::hasUnlistedChildren instead)
  • Page::hasNextInvisible (use Page::hasNextUnlisted instead)
  • Page::hasNextVisible (use Page::hasNextListed instead)
  • Page::hasPrevInvisible (use Page::hasPrevUnlisted instead)
  • Page::hasPrevVisible (use Page::hasPrevListed instead)
  • Page::hasVisibleChildren (use Page::hasListedChildren instead)
  • Page::nextInvisible (use Page::nextUnlisted instead)
  • Page::nextVisible (use Page::nextListed instead)
  • Page::prevInvisible (use Page::prevUnlisted instead)
  • Page::prevVisible (use Page::prevListed instead)
  • Page::isInvisible (use Page::isUnlisted instead)
  • Page::isVisible (use Page::isListed instead)
  • Site::hasInvisibleChildren (use Site::hasUnlistedChildren instead)
  • Site::hasVisibleChildren (use Site::hasListedChildren instead)

Kirby 3.2

Breaking

  • Translations root deprecated and will be removed in 3.3. Use i18n:translations instead
  • File::model() does no longer return the parent model. Use File::parent() instead