Snippets with slots
Templating on another level
$slots
variable. Snippets can have multiple slots and you can even combine slots with data variables.
Structure field improvements
New row & delete all buttons
PHP 8.2 support
PHP moves forward, we do too
Satellite Releases
Ecosystem improvements
Kirby CLI 1.1.0
Kirby KQL 2.0.0
Staticache 1.0.0
Staticache is our alternative page cache plugin for Kirby that stores responses as fully static files. This helps you to increase your site performance even more.
With version 1.0.0 it is finally ready for prime time for a lot of common site setups. It now comes with support for multi-language sites and content representations as well as with a new mode that caches custom HTTP response headers as well.
Eleventykit 🎈
The Eleventykit is a very simple (unstyled) example for a site, built with Kirby and 11ty.
Kirby’s query language (KQL) is used to fetch articles from our KQL playground: https://kql.getkirby.com
Use your own Kirby installation with the KQL plugin to provide a powerful headless CMS for your static 11ty site.
Changelog
Features
Enhancements
Image\Image
uses its model'salt
content field as fallback for rendering thealt
attribute to better provide accessible defaults (we already did it for direct image objects, but now it also works for thumbs etc.) #4915- Pages section: the status flag button’s tooltip now includes the non-customised label of the current status for better accessibility #4928
- The license registration dialog now displays an info field for which domain the license will be registered, including a warning when registering a local domain #4930
Dimensions::forSvg()
supports percentages and better viewport fallbacks #4921Xml::attr()
andHtml::attr()
accept non-associative values (e.g.Xml::attr(['attrA'])
), which get rendered like passingtrue
(e.g.attrA="attrA"
/attrA
) #4935- The
Dir::copy()
method now supportsfalse
as the argument for$ignore
. In this mode, all files are copied, including those listed in the globalDir::$ignore
list. #4872 F::move()
now ensures that the parent directory exists, which is consistent withF::copy()
#4943File::create()
,$parent->createFile()
and$file->replace()
support a new mode that moves the source file instead of copying it #4943- Sensitive information like passwords is redacted in logs when using PHP 8.2+ #4945
Bug fixes
- Dynamic options for the select field (from API or query) are no longer displayed with double-escaping in the Panel #4974
- Options from API in options fields (e.g. select, checkboxes) now support simple key/value data like
{"key": "value"}
again #4987 - Using options from API in options fields (e.g. select, checkboxes) also works without the
query
setting again #4985 - Writer: links now fully wrap inline styling instead of generating multiple link parts #4866
- Kirby queries: optional chaining on non-null values now works properly #4901
- Escaping quotes inside query arguments with
\"
and\'
now behaves like it does in PHP (only the same type of quote used for the string can be escaped) #4976 - Uploaded files are deleted from the temporary directory after they have been successfully stored in the content directory. #2476
- Fixed focus for checkboxes and radio input with no options #4917
- Fixed
undefined
error when paginating the structure field #5000 - The
page.changeSlug
hook now receives the correct$languageCode
#4983 - Files field: for
store: id
only the name is stored again when the current model is the file's parent #4870 - Fixed prepending redundant
mailto:
ink-link
#4882 Toolkit\Xml::attr()
is case-sensitive now #4911- Now treating paths with trailing dot as non-existing content representation #4920
- Fixed console errors for failed
lock
request when deleting page with unsaved changes #4919 - Fixed error message for missing field type #4929
->words()
field method works as expected onnull
values #4905- Fixed false-positive blocked requests by ModSecurity (OWASP rules) #4933
- Panel: load development icons file when in dev mode #4900
- I18n: English translation had
February
set toFeburary
#4903
Refactoring
- Improvements for
Toolkit\Locale
code quality #4926 - Improvements for
Toolkit\Escape
code quality #4925 - Improvements for
Toolkit\Obj
code quality #4923 - Improvements for
Toolkit\A
code quality #4942 - Improvements for
Toolkit\I18n
code quality #4939 - Improvements for
Toolkit\Silo
code quality #4922 - Improvements for
Toolkit\Controller
code quality #4937 - Improvements for
Toolkit\Iterator
code quality #4938 - Improvements for
Toolkit\Html
andToolkit\Xml
code quality #4959 - Improvements for
Toolkit\Str
code quality #4961 - Improvements for
Text
code quality #4956 - Improvements for
Blueprint
andOption
code quality #4974 - Upgraded to Vite 4 and some other JS dependencies #4912
- Updated Composer dependencies #4946
- PHP 8.2 prep: Fix dynamic properties in search component #4888
- PHP 8.2 prep: Fix
mb_convert_encoding()
deprecation in Parsedown #4887 - The
Kirby\Cms\Template
class moved toKirby\Template\Template
. An alias has been added. #4910 - Our unit tests now always trigger our own deprecation warnings, which allows us to find uses of deprecated code in our own code. #4948
- Use of the null coalescing assignment operator
??=
where possible #4957 - Use of
instanceof
, the.=
operator,array_key_exists()
and property defaults where possible #4958 - Nested
if
statements have been combined/removed #4958 - More of our PHPUnit tests use a temporary directory now to prevent tests from creating a stray
site
directory in the top-level of the project #4973 - Fixed type hints and docblocks throughout the codebase #4971
- Fixed broken link in the contribution guide #4960
- Our PHPUnit tests consistently use
assertSame
instead ofassertEquals
where possible and use more specific assertions (e.g.assertTrue
,assertNull
,assertFileExists
,assertArrayHasKey
) #4975 - Fixed ghost output during PHPUnit test runs #4964
Deprecated
- Manually passing
$slot
or$slots
as data variables to snippets is deprecated. In a future Kirby version, those variables will be overridden with theSlot
andSlots
objects. #4963 - The
Toolkit\Query
class has been deprecated and will be removed in a future version. UseQuery\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 passnull
. #4934 - The
.k-offscreen
CSS class has been deprecated. Use.sr-only
instead. #4944
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 3.9.0.0 (major release 9 of Kirby 3)
Traditionally, we combine patch and minor releases though and only need the fourth versioning level for regression fixes.
$kirby->impersonate()
doesn't bind the app instance to the$callback
closure anymore. You can access the app instance withKirby\Cms\App::instance()
or thekirby()
helper. #4944- The
snippet
core component receives an additional parameterbool $slots
and needs to returnKirby\Template\Snippet
|string
for slot support. If you override thesnippet
component, please adapt the logic to the new core component. #4910 $kirby->snippet()
and thesnippet()
helper returnKirby\Template\Snippet
|string
|null
#4910Html::rel()
now consistently returnsnull
instead of an empty string when norel
attribute is needed #4948A::missing()
no longer treats an existing array key with anull
value as missing #4942
Removed deprecated code
- Deprecated method
Kirby\Cms\App::server()
has been removed. UseKirby\Cms\App::environment()
instead. #4944
Migration from Kirby 3.8.x
There are not many steps needed to migrate from Kirby 3.8 to Kirby 3.9. To ease the transition, we have compiled everything you need to know in migration guides:
Migration guide for site developers →
Migration guide for plugin developers →