New design
Not just some fresh paint
- New menu
- Full-width layout
- A11y improvements
- New button design
- New color scheme
- New icons
- Redesigned save bar
- Better responsiveness
- Refreshed UI components
- New UI plugin options
Link field
Link to anything
Page creation dialogs
Faster, better page creation
title: Product
create:
title:
label: Product name
fields:
- price
- brand
redirect: false
status: listed
Moving pages
I like to move it, move it
Section filters
Filter pages and files
Filter pages and files by any criteria: The pages and files sections now come with support for our powerful query string syntax.
expensive:
extends: sections/products
label: Expensive
query: page.childrenAndDrafts.filter('price', '>', '99')
cheap:
extends: sections/products
label: Cheap
query: page.childrenAndDrafts.filter('price', '<=', '99')
Color field
Color me surprised
Color in all its facets: Multiple color notations, color picker, pre-defined colors, custom color names and transparency. You can't get more color than that.
color:
type: color
options:
"Sunny rays": "#F8B195"
"First-love blush": "#F67280"
"Cherry blossom": "#C06C84"
"Morning gloom": "#6C5B7B"
"Midnight rain": "#355C7D"
Image focus
Focus Pocus
Never cut off the most important part of your images again. Set a focus point and let your images shine in all their beauty.
Uploader
Uploading files the smart way
Screenshot-123.jpg? With the preview and edit options in the new upload dialog, meaningless file names are now a thing of the past. Use the new blueprint options to optimize uploads before they land on the server.
title: Image
# Optimize on upload
create:
width: 500
height: 500
crop: true
Block field improvements
Our best field is now 25% bester
fields:
blocks:
type: blocks
fieldsets:
demo:
wysiwyg: true
preview: fields
tabs:
main:
fields:
title:
type: text
subtitle:
type: text
description:
type: writer
settings:
label: Settings
fields: # ...
Display and edit headings level inline
New toggles inside the drawer
Block splitting
- Split and merge text, list and headings
- New option buttons to split or merge
- Press enter at the end of a headline to append a new text block
- Text block with
inline: true
for text field will split directly on Enter (Shift + Enter
creates a hard line break) - Custom blocks can support splitting by implementing a
split
method
Minimized blocks while dragging
New Keyboard shortcuts
Action | Shortcut |
---|---|
Remove block | Ctrl + Backspace |
Move focus up | Ctrl + ↑ |
Move focus down | Ctrl + ↓ |
Move block up | Ctrl + Shift + ↑ |
Move block down | Ctrl + Shift + ↓ |
Extend selection up | Ctrl + Alt + ↑ |
Extend selection down | Ctrl + Alt + ↓ |
Split block | Ctrl + Enter |
Merge block | Ctrl + J |
Layout field improvements
Copy & Change
More flexibility: Easily change a layout, and copy one or all layouts into other layout fields.
Time-based, one-time passwords
Making your Panel even more secure
Kirby now supports time-based one-time codes (TOTP), offering more secure ways to sign into the Panel. When two-factor authentication is activated, one-time codes from your authenticator app will be used instead of codes via email.
Each user can set up TOTP in the account view in the Panel, adding their secret key to their authenticator app.
return [
'auth' => [
'methods' => [
'password' => ['2fa' => true]
]
]
];
Language editor
No longer lost in translation
Each language got its own view now. Easily configure your languages or edit language variables right from the Panel. Easy, right?
Search view
Deliver results
The larger your website, the more important becomes search. With Kirby's new search view, searching in the Panel has become a breeze.
Changeable file templates
Change is in the air
Change file templates to any allowed template defined by its parent in a files section or field.
Writer field improvements
Writing in style
With custom marks and nodes for your own style, customizable heading levels and a character counter, you have full control about your writing.
Link to internal pages & files with our new link field in the link dialog. No more guessing of URLs.
fields:
text:
type: writer
toolbar:
inline: false
marks:
- bold
- "|"
- link
fields:
text:
type: writer
headings:
- 2
- 3
- 4
fields:
text:
type: writer
marks:
- sub
- sup
- clear
fields:
text:
type: writer
minlength: 10
maxlength: 360
counter: false
Writer Plugins
You need a block or inline format that’s not available? Create your own marks and nodes with our brand new extension API for Writer plugins.
panel.plugin("acme/writer", {
writerNodes: {
blockquote: {
// ...
},
}
writerMarks: {
mention: {
// ...
},
},
};
Default page model
Set a new page standard
<?php
use Kirby\Cms\Page;
class DefaultPage extends Page
{
/**
* This method is now available for all pages
* unless they have their own page model.
*/
public function myCustomMethod(): string
{
return 'Hello world';
}
}
The default page model kicks in when there is no specific model for a page.
Of course, other models can extend the default page model, too.
Panel JavaScript API
Remote control
Our new Panel JavaScript API gives you access to the most important Panel features. Control dialogs, drawers, notifications and more from your plugins, your custom panel.js or even the console.
PHP 8.3
PHP moves forward, we do too
New Versioning Scheme
Semantic Versioning
{generation} | {major} | {minor} | {patch} |
---|---|---|---|
3 | 9 | 0 | 0 |
3 | 10 | 0 | 0 |
3 | 11 | 0 | 0 |
{major} | {minor} | {patch} | |
---|---|---|---|
3 | 9 | 0 | |
4 | 0 | 0 | |
5 | 0 | 0 |
Key points
- Kirby now follows semantic versioning
- Major versions will be released on a yearly cycle to bring continuity and planning security.
- Licenses include three years of feature updates
Example roadmap
- 4.0.0: late 2023
- 5.0.0: late 2024
- 6.0.0: late 2025
Changelog
Ch-ch-ch-changes
Core improvements
QR Code generation
Kirby's new Kirby\Image\QrCode
class, qr()
helper function and ->toQrCode()
field method allow you to create QR Codes right out of the box:
$qr = new Kirby\Image\QrCode('https://getkirby.com');
$qr->toSvg(color: '#ff00ff');
$qr->toDataUri(color: '#ff00ff');
qr('https://getkirby.com')->toSvg();
$page->myLinkField()->toQrCode()->toSvg();
Support for UUIDs and permalinks in URL helper
You can now pass a page UUID, a file UUID or a permalink to the url()
helper and it will be converted to the actual URL:
<?= url('page://abcd') ?>
<?= url('file://abcd') ?>
<?= url('/@/page/abcd') ?>
<?= url('/@/file/abcd') ?>
This will also work for other URL methods like $field->toUrl()
, Url:to()
, etc.
Support for UUIDs in API calls
You can now use UUIDs in API calls to request pages and files. #4769
/api/pages/@$pageUUID
The UUIDs must be passed without scheme, but a prefixed @
. I.e.:
// Nope
/api/pages/page://abcd
// Yes
/api/pages/@abcd
File routes can also handle file UUIDs for files and parents:
/api/pages/@$pageUUID/files/$filename
/api/pages/@$pageUUID/files/@$fileUUID
In addition to that there are new direct UUID file routes:
/api/files/@$fileUUID
Better plugin asset handling
- New
assets
plugin extension that allows plugins to specify assets from custom paths and with a wider range of extensions than previously supported - New
Kirby\Cms\Plugin::assets()
andKirby\Cms\Plugin::asset($assetName)
methods - New
Kirby\Cms\PluginAsset
object with many methods, e.g.$plugin->asset('styles.css')->url()
- Plugin asset media url contains a modification timestamp to easily cachebust (e.g.
/media/plugins/getkirby/test-plugin/2375797551-472389240/styles.css
) css()
andjs()
helpers support passing plugin and plugin assets objects to include all assets of the plugin:
css([
'assets/css/index.css',
$kirby->plugin('foo/bar')
]);
css([
'assets/css/index.css',
$kirby->plugin('foo/bar')->assets(),
]);
css([
'assets/css/index.css',
$kirby->plugin('foo/bar')->asset('styles.css'),
]);
New SymmetricCrypto
class
Kirby\Toolkit\SymmetricCrypto
is a user-friendly and safe abstraction for symmetrical authenticated encryption using the PHP sodium
extension:
use Kirby\Toolkit\SymmetricCrypto;
// encryption/decryption with a password
$crypto = new SymmetricCrypto(password: 'super secure');
$ciphertext = $crypto->encrypt('a very confidential string');
$plaintext = $crypto->decrypt($ciphertext);
// encryption with a random key
$crypto = new SymmetricCrypto();
$ciphertext = $crypto->encrypt('a very confidential string');
$secretKey = $crypto->secretKey();
// encryption/decryption with a previously generated key
$crypto = new SymmetricCrypto(secretKey: $secretKey);
$ciphertext = $crypto->encrypt('a very confidential string');
$plaintext = $crypto->decrypt($ciphertext);
New LazyValue
class
Kirby\Toolkit\LazyValue
allows to protect a closure function from being called by other code that is testing for instanceof Closure
:
$value = new LazyValue(fn ($a, $b, $c) => 'please protect me');
// ...
if ($value instanceof Closure) {
// we would hate if our value gets unwrapped here,
// that's why we cannot use a normal closure but LazyValue
$value = $value();
}
// ...
// finally we want to unwrap our protected closure
if ($value instanceof LazyValue) {
$value = $value->resolve($a, $b, $c);
}
More improvements
- New
$field->permalinksToUrls()
method for writer fields - Extensions to add custom methods for structures and structure objects
- New
Kirby\Toolkit\Str::camelToKebab()
method Str::template()
supports single and double curly braces as start/end delimiters by defaultXml::attr()
: Support passing an empty string as value to generate an attribute with an empty value- New
Kirby\Cms\App::models()
method that returns a generator for each model (site, files, pages and users) of the site - New
Kirby\Cms\File::blueprints()
method that collects valid blueprints from the files sections and files fields of the parent model - Fields can now define
'hidden' => true
(component notation) or::isHidden(): bool
(class-based) to make them non-rendering - New
languages.variables
config option to disable managing translations in the Panel - New
Kirby\Cms\File::changeTemplate()
method - New file permissions for
changeTemplate
,access
andlist
- New
file.changeTemplate
hooks - New
Kirby\Filesystem\F::safeExtension()
method - New
Kirby\Filesystem\F::safeBasename()
method Kirby\Toolkit\Str::date()
and its dependents (e.g.Kirby\Filesystem\F::modified()
,Kirby\Filesystem\File::modified()
,Kirby\Filesystem\Dir::modified()
) now respect the globally configured date handler- New
$date->formatWithHandler()
method for Kirby date objects that allows to use different date handlers or even the globally configured one (default). - New
Kirby\Email\Email::toArray()
andKirby\Email\Body::toArray()
methods - New
Kirby\Exception\AuthException
class - Dom: New
allowHostRelativeUrls
sanitization option (true
by default) to perform less strict checks when the HTML<base>
element is used - Dom: Custom sanitization callbacks for attributes, elements and the doctype now also receive the
$options
array - Sane: New
$isExternal
mode specifically for external files that may be accessed directly - More detailed security policy for GitHub
Panel improvements
Dialogs for fields
Fields can now define their own dialogs on the backend:
- Fields with array definition:
return [ 'props' => [ // ... ], 'dialogs' => function () { return [ [ 'pattern' => 'delete', 'load' => function () {}, 'submit' => function () {}, ] ]; } ];
- Field classes:
class MyField extends FieldClass { public function dialogs(): array { return [ [ 'pattern' => 'delete', 'load' => function () {}, 'submit' => function () {}, ] ]; } }
The route patterns for field dialogs are automatically prefixed with the following scheme:
dialogs/$modelPath/fields/$fieldName/$pattern
Here's an example:
dialogs/pages/blog/fields/blocks/delete
In a field component, the dialog can be opened by using the field endpoint:
this.$dialog(this.endpoints.field + "/delete")
Customization of the layout selector
The layout selector is now customizable with the size
(small
, medium
, large
, huge
) and columns
options via the new selector
prop:
layout:
type: layout
layouts:
...
selector:
# `small`, `medium`, `large` or `huge`
size: huge
columns: 6
More improvements
- Disabled buttons can receive focus (tab) which allows them to be read out by screenreaders.
- Structure fields don’t disregard content changes anymore when clicking outside the form (now drawer).
- Correct autofocus handling for blocks, layout, structure, picker fields and dropdowns
- Improved focus styles for links and the flag preview in tables
- All minified panel assets now add
.min
to the filename. This will avoid auto-minification in Cloudflare and possibly other environments. - Improved text overflow behavior for links in tables
- Increase the font size for help text in sections and fields
- The multiselect and tag dropdowns now offer more space to not cut off longer options.
- Slug field: respect custom slug allowlist from the
Str
class - Pages section: new
templatesIgnore
option #5322 - Users field: set
default: true
to always use the currently logged in user as default - New items size
full
New Icons
We've added new icons to our Panel iconset: anchor
, clear
, lab
, merge
and split
.
New Components
<k-alpha-input>
<k-browser>
<k-code>
<k-color-frame>
<k-coloroptions-input>
<k-colorname-input>
<k-dialog-body>
<k-dialog-box>
<k-dialog-buttons>
<k-dialog-fields>
<k-dialog-footer>
<k-dialog-form>
<k-dialog-notification>
<k-dialog-search>
<k-dialog-text>
<k-drawer-body>
<k-drawer-fields>
<k-drawer-header>
<k-drawer-notification>
<k-drawer-tabs>
<k-file-browser>
<k-frame>
,<k-icon-frame>
and<k-image-frame>
<k-hue-input>
<k-navigate>
<k-notification>
<k-page-tree>
<k-search-input>
<k-stat>
<k-text-drawer>
<k-tree>
New helpers
$helper.focus(element)
$helper.object.length(object)
$helper.string.isEmpty(string)
$helper.url.base
$helper.url.buildQuery
$helper.url.buildUrl
$helper.url.isAbsolute
$helper.url.isSameOrigin
$helper.url.isUrl
$helper.url.makeAbsolute
$helper.url.toObject
$library.colors
New JS error classes
RequestError
JsonRequestError
And so much more
We've tweaked the Panel extensively with too many improvements to name them all. But here are some more:
- Load Panel area views dynamically with the new
when
prop - Each Panel area can now define additional requests for simple data endpoints or actions
- Syntax highlighting in the
k-code
with Prism - Text fields: new
font: monospace
option panel.css
andpanel.js
config options now also support arrays with multiple entries as well as absolute URLsk-pagination
can always be navigated by keys (no extra prop needed anymore)- Notifications: support for custom icons
k-tag
supports an image/icon frame- New
disabled
property for thek-options-dropdown
component - New
selected
property fork-button
to set thearia-selected
attribute
Bug fixes
- Removed flickering from
k-pagination
when navigating - Fixed name of default blueprints to
pages/default
andfiles/default
- Blocks: batch selection allows deselecting blocks
- Blocks: batch selection gets deselected on Escape key
- Fixed i18n translate issues, e.g. for the user blueprint title #4869
- Writer field: Email mark toolbar button title is properly translated now
- Empty required Writer field now shows proper invalid styling in Panel
- UUIDs are less often generated when not needed to be generated
- Kirby queries now differentiate between integers and floats as arguments
- Kirby no longer hides errors in the response class when the response is converted to a string #5027
- Files field upload: use
upload.parent
for mime check #5245 $field->toUrl()
will returnnull
on empty fields #5259- Users field does not use a default anymore if none set
- The "Session ... is currently read-only because it was accessed via an old session" error is circumvented when the PHP
sodium
extension is available - Removed the error boundary from
<k-fieldset>
; the error boundary kills the entire field/input if an error occurs, which is way too aggressive and also makes it more difficult to handle errors properly. App::multilang()
andApp::defaultLanguage()
are correctly updated on changes to language data #5342- Prevent unnecessary runs in
Language::update()
when updating the default language - Block title: certain HTML characters are now properly unescaped in the label #5346
Refactoring
Core
- Throw proper errors when thumbnails cannot be generated
- Removed
config/blueprints
directory with dead block blueprints and moved default blueprints for site, page and file to in-code arrays inKirby\Cms\Core::blueprints()
- Removed
Kirby\Toolkit\Properties
trait fromKirby\Api\Api
,Kirby\Cms\Api
,Kirby\Email\Email
,Kirby\Email\Body
,Kirby\Cms\Auth\Status
,Kirby\Cms\App
,Kirby\Cms\ContentTranslation
,Kirby\Cms\ModelWithContent
,Kirby\Toolkit\Pagination
,Kirby\Http\Uri
,Kirby\Cms\FileVersion
,Kirby\Filesystem\Asset
,Kirby\Filesystem\File
,Kirby\Image\Image
classes andKirby\Filesystem\IsFile
trait Kirby\Cms\Language
,Kirby\Cms\Plugin
,Kirby\Cms\Role
andKirby\Cms\StructureObject
don't extendKirby\Cms\Model
(and thus also don't use theKirby\Toolkit\Properties
trait) anymoreKirby\Cms\Structure
extendsKirby\Cms\Items
andKirby\Cms\StructureObject
extendsKirby\Cms\Item
- New
Content
namespace- Moved the
Content
,ContentTranslation
andField
classes into the new namespace (compatibility aliases are provided for now) - New internal
ContentStorage
class that currently holds more of the storage related business logic - New internal
ContentStorageHandler
interface and internalPlainTextContentStorageHandler
class to bundle all low-level content logic in one place
- Moved the
- Whoops is now generally disabled during PHPUnit test runs to reduce memory usage during tests
Panel
- More frontend unit tests
- Cleaned up
k-toolbar
component - New drawer component structure:
<k-overlay type="drawer"> <form class="k-drawer" method="dialog"> <k-drawer-notification /> <k-drawer-header /> <k-drawer-body> <k-drawer-fields /> </k-drawer-body> </form> </k-overlay>
- Portals: Dialogs, Drawers and other Overlays are now separated into different portals. This is done by setting the overlay type:
<k-overlay type="dialog">
<k-overlay type="drawer">
<k-overlay>
An overlay without a type will use the default overlay portal. Separating them into different portals gives us more control overz-index
and layering of elements.
- Removed
v-model
fromk-form
andk-fieldset
- Removed
$listeners
usage fromk-draggable
,k-button
and subcomponents,k-link
,k-headline
,k-form
,k-block
,k-block-title
,k-box
,k-image
,k-content-item
- Made
k-bubble
more flexible - Use the Vue object syntax for dynamic
:style
attributes to enhance the robustness and security - Reduce JS forEach usage
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 newassets
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
: UseKirby\Cms\ModelWithContent
insteadKirby\Email\Email::clone()
andKirby\Email\Body::clone()
Page::isReadable()
: UsePage::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 correspondingviewBox
attribute. - Icons
circle-outline
,heart-outline
andstar-outline
: Usecircle
,heart
andstar
instead this.$events
: Usethis.$panel.events
insteadthis.$panel.events.$on
: Usethis.$panel.events.on
insteadthis.$panel.events.$off
: Usethis.$panel.events.off
insteadthis.$panel.events.$emit
: Usethis.$panel.events.emit
insteadthis.$store.dispatch("isLoading")
: Usethis.$panel.isLoading
insteadthis.$translation
: Usethis.$panel.translation
insteadthis.$store.dispatch("dialog")
: Usethis.$panel.dialog.open
andthis.$panel.dialog.close
insteadthis.$store.dispatch("drag", drag)
: Usethis.$panel.drag = drag
insteadk-dropdown
: Usek-dropdown-content
as standalone insteadk-calendar
was renamed tok-calendar-input
;k-calendar
is still available but only as deprecated alias.
Breaking changes
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 andfocus
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'sallowHostRelativeUrls
option tofalse
. - 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 theLanguage
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 theid
method.Kirby\Uuid\Uuid::key()
can now also returnnull
if the new$generate
parameter isn't passed astrue
and no UUID has yet been generated for the model.Kirby\Cms\ModelWithContent
doesn't extendKirby\Cms\Model
anymore.- Removed the
::clone()
method fromKirby\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
andKirby\Cms\ContentTranslation
classes - Removed the
::hardcopy()
method fromKirby\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
andKirby\Cms\ContentTranslation
classes - Removed
::site()
method fromKirby\Cms\Plugin
,Kirby\Cms\Role
andKirby\Cms\StructureObject
classes - Removed
::kirby()
method fromKirby\Cms\Role
andKirby\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
, notKirby\Cms\Block
. new Kirby\Cms\Structure()
/new Kirby\Cms\StructureObject()
don't work anymore as before. UseKirby\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 newKirby\Content\PlainTextContentStorageHandler
class instead and return an instance of your custom class from$model->storage()
. Please note that the interface ofPlainTextContentStorageHandler
is internal and may change in the future. - New
$isExternal
argument for theKirby\Sane\Handler::sanitize()
andKirby\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
andstar
are now namedcircle-filled
,heart-filled
andstar-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 usewindow.panel.isLoading
orthis.$panel.isLoading
in Vue components to access the current loading state.this.$store.state.dialog
is no longer available. Usethis.$panel.dialog
instead.- Removed
this.$store.state.drag
, usewindow.panel.drag
/this.$panel.drag
instead. <k-button>
,<k-link>
,<k-headline>
and<k-content-item>
only emit theclick
event. For other native events, use the.native
event listener modifier.- Native events (e.g.
click
,dbclick
) 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 vianextLabel
,prevLabel
orpageLabel
<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\Options
,Kirby\Form\OptionsApi
andKirby\Form\OptionsQuery
classes have been removed. UseKirby\Option\Options
,Kirby\Option\OptionsApi
orKirby\Option\OptionsQuery
instead. - The
Kirby\Toolkit\Query
class has been removed. UseKirby\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.
QR Code® is a registered trademark of DENSO WAVE INCORPORATED.
Migration from previous versions
Kirby 4 is a major release and requires some changes to existing sites. To ease the transition, we have compiled everything you need to know in a handy guide: