New stats section
Turn your dashboard into a smart report
Easy as 1-2-3
New table layout
Who said spreadsheets cannot be cool?
At a glance
New system view
Everything system related at a glance
Environment
Security
Plugins
New toggles field
Stylish options you will love
New section search
Speedy filtering of pages and files
Refined UI
A fresh new look for your Panel
Fresh & familiar
New icons
- archive
- badge
- brush
- discord
- discount
- folder-structure
- github
- money
- palette
- pen
- store
- ticket
New file icons
Changelog
Features
- Brand new statistics section
- New search option for pages and files sections https://kirby.nolt.io/14 #4316
- New field previews in tables for the tags, radio, select, multiselect, checkboxes, structure, blocks, layout, files, pages and users fields. #4294 #4195
- New system health checks to detect unintentionally exposed parts of your installation (Git repo, content folder, site folder, kirby folder)
$request->auth()
now also handles Kirby'sSession
auth type automatically #4264- The auth types for
$request->auth()
can now be extended by plugins #4264 - New
$kirby->response()->usesAuth()
and->usesCookie()
method to tell Kirby's automatic caching system about usedAuthorization
headers and cookies. These methods are called automatically when the KirbyRequest
andCookie
classes are used. - New
$kirby->request()->hasAuth()
method to check the existence of theAuthorization
header #4277 - New
$kirby->isNativeComponent($component)
method #4348 - New
k-table
component to create consistent tables easily - Styled preview for tags in tables
- New JS helper
$helpers.object.isEmpty(value)
New Str methods
Str::afterStart()
and Str::beforeEnd()
… to remove a substring only from the start or end of a string #4339
Str::camel()
and Str::studly()
… for case-altering of strings #4338
Str::increment()
… for appending a number -1
to a string or incrementing the ending number to allow -2
, -3
, etc. #4340
Str::wrap()
… for wrapping the string with the given strings.
New validators
V::json()
… to validate correctly formatted JSON strings.
V::empty()
and V::notEmpty()
To check for empty values in PHP is not as easy as it sounds like. empty()
is often giving wrong results. Especially if you pass 0
or '0'
. The new validators help with this task. They also serve as underlying logic for a better V::required()
validator. It can now be used in two ways:
With a reference array …
or just a value …
This makes the method more versatile and it can be used in V::value()
:
Enhancements
Custom helpers
Helpers can now be deactivated by setting a global constant named KIRBY_HELPER_*
, e.g. KIRBY_HELPER_DUMP
to false
#4018 Check out the documents.
In some cases, our global helper functions will collide with other tools' global functions if they use the same name, e.g. dump()
. If you are affected by this problem, you can now set the matching constant, e.g. KIRBY_HELPER_DUMP
, to false
and Kirby will not register its global helper.
To ensure that Kirby still functions properly, we moved all functionality from the helper functions to class methods (and the global helper functions are only aliases now). We recommend that plugin developers also start using these class methods to ensure that your code always uses Kirby's core helpers:
- New
Cms\App::csrf()
method with the functionality of thecsrf()
helper - New
Cms\App::image()
method with the functionality of theimage()
helper - New
Cms\Helpers::deprecated()
method with the functionality of thedeprecated()
helper - New
Cms\Helpers::size()
method with the functionality of thesize()
helper - New
Cms\Helpers::dump()
method with the functionality of thedump()
helper - New
Cms\Html::css()
method with the functionality of thecss()
helper - New
Cms\Html::js()
method with the functionality of thejs()
helper - New
Cms\Html::svg()
method with the functionality of thesvg()
helper - New
Filesystem\F::loadClasses()
method with the functionality of theload()
helper - New
Http\Router::execute()
method with the functionality of therouter()
helper - New
Http\Response::go()
method with the functionality of thego()
helper https://kirby.nolt.io/369 - New
Toolkit\Date::roundedTimestamp()
method with the functionality of thetimestamp()
helper - New
Toolkit\Str::esc()
method with the functionality of theesc()
helper - New
Toolkit\Str::uuid()
method with the functionality of theuuid()
helper - New
Toolkit\V::invalid()
method with the functionality of theinvalid()
helper - Extended
Cms\App::kirbytag()
method with the functionality of thekirbytag()
helper. Allows to pass an array as first parameter. - Extended
Cms\App::snippet()
method with the functionality of thesnippet()
helper. - Extended
Toolkit\Html::attr()
method with the functionality of theattr()
helper. Allows to pass$before
and$after
string.
Core
- Added Kirby’s PHP and extension dependencies to
composer.json
#4216 Toolkit\Xml::value()
now uses better logic to determine whether aCDATA
block is needed. #4335- Methods in Kirby's core now use the global environment object instead of
$_SERVER
wherever possible - JSON errors in debug mode now contain the file path relative to the document root for consistency with the API that already handles it like this.
- Kirby's response handling now automatically controls page and HTTP caching based on cookies, session and the
Authorization
request header used by the response. If any of these are used and also contained in the request, the response is considered private. If they are used but not contained in the request, the page is only cached for visitors without these cookies/session/auth. Manual sessions are always considered private. #3976 $pages->find()
can now find pages by their translated URI in secondary languages of multi-lang setups, even in collections without a parent (like$page->grandChildren()
)
Panel
Bug fixes
Core
- Fixed return type hints to include
null
as possible return value forCms\Pagination::firstPageUrl()
andCms\Pagination::lastPageUrl()
#4314 - Fixed a bug where field content was copied to secondary languages even though
translate: false
was set #2577 - Fixed a bug where fields with uppercase field names in virtual pages could not be searched #4142
- File permissions of all non-executable files in the Kirby repo have been set to
644
. #4336 - Editing a page title before the translation file had been created caused untranslatable fields to be copied to the translation file #2789
kirby->url()
no longer adds the wrong port or protocol on nginx / reverse proxy #4311- Url overwrite config now also overwrites protocol correctly #4234
file::url
component no longer breaks the preview URL in the Panel #4143- Fixed a regression that prevented page and HTTP caching when the session was accessed, even when the session was not active #3976
- The behavior of the
$pages->find()
,$pages->findById()
and$pages->findByUri()
methods in non-direct-child collections (e.g.$page->grandChildren()
) is now consistent between single-lang and multi-lang installations #4105
Panel
k-empty
now actually supports itstext
prop- Improved structure field columns on mobile #3638
- Structure field sticky header inside drawers #4242
- Fixed wrong draggable ghost element for structure field rows #4242
- Preview image from other page was not shown when the page is a child of site and status
published
was queried #4297 - Uploading multiple files now adds correct sorting numbers #4317
- Better responsiveness for Panel section headers #4316
- Fixed Copy & Paste in list blocks on the first try #3974
- The Panel and API now send the
Cache-Control: no-store, private
response header instead of justCache-Control: no-store
for better compatibility with caches like CloudFlare #4299
Refactoring
New Http\Environment
class
The new object-oriented Http\Environment
class replaces the former static Http\Server
class and takes over all its methods.
It takes care of detecting all necessary parts (host, port, https, etc.) and considers an optional allow list of URLs to validate the current environment:
I.e. if it finds to be running on the test.getkirby.com host from above, https is on and the port is 9999 and the subfolder also matches, you can get all those parts now correctly via:
We use this new class as foundational element in our $kirby
instance to construct absolute and relative URLs, roots and paths. You can access it and its methods with $kirby->environment()
. Kirby internally uses the Environment
class to set the site's base URL based on the url
option.
Core
- Improved internal usage of router callbacks #4260
- The Kirby core no longer uses Kirby's helper functions internally but calls the underlying methods directly. #4018
- Content field names are now always handled case-insensitively.
- Kirby's
composer.json
no longer pins thepsr/log
library to a specific version #4392
Panel
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 thefind()
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
andfiles
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 |
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.7.0.0 (major release 7 of Kirby 3)
Traditionally, we combine patch and minor releases though and only need the fourth versioning level for regression fixes.
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
andHttp\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 theKirby\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 theurl
option. page
helper now always only returns aKirby\Cms\Page
object ornull
, never a pages collection. Only allows passing a single id as parameter. #4335pages
helper now always only returns aKirby\Cms\Pages
collection ornull
, never single page object. #4335- Creating a
Kirby\Cms\File
object requires theparent
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()
ande()
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 theKIRBY_HELPER_*
contants. Check out how to do it. - The second argument of the
kirbytextinline()
andkti()
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
andk-structure-field
have been largely refactored. If you (or a plugin) extends these, stuff might break.k-pages-section
andk-files-section
have been modified extensively #4247Toolkit\Html::attr([], null)
now consistently returnsnull
instead of an empty string. #4018- Removed
builder
andeditor
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() |