Field Methods
toResolvedBlocks()
The toResolvedBlocks()
method is a wrapper around Kirby's toBlocks()
method. It resolves fields in blocks to the desired output by running them through resolver functions.
For example, the toBlocks()
method returns UUIDs for the files
and pages
fields. To leave these UUIDs as they are would require you to resolve them in your frontend application. Instead, you can use the toResolvedBlocks()
method to resolve these UUIDs into file and page objects on the server. This way, you can access the properties of these objects directly in your frontend.
When using toBlocks()
, a single block as part of the blocks JSON response might look like this:
{
"content": {
"image": ["file://BYXR0pvumEbfTknP"],
"alt": "Staring at stars"
},
"id": "a1c0f653-2e36-4b07-a7fa-d22ef27dd114",
"isHidden": false,
"type": "image"
}
Instead, when using toResolvedBlocks()
, the same block would look as follows. Note that the image
field is now resolved to a file object:
{
"content": {
"alt": "Staring at stars",
"image": [
{
"url": "http://cacao-kit-backend.test/media/pages/notes/exploring-the-universe/a6c422e141-1714659501/tent-in-the-woods.jpg",
"width": 1024,
"height": 683
}
]
},
"id": "a1c0f653-2e36-4b07-a7fa-d22ef27dd114",
"isHidden": false,
"type": "image"
}
You can define which fields of which blocks need resolving in your config.php
. To simplify files
and pages
resolving, Kirby Headless comes with default resolvers for these fields. You can also define custom resolvers for specific fields in specific blocks.
For a production-ready boilerplate, you can use the 🍫 Cacao Kit frontend which uses this field method.
Files and Pages Resolver
In most cases, you want to resolve the files
and pages
fields in your blocks. To do so, you can define which fields of which blocks should be resolved in your config.php
:
return [
'blocksResolver' => [
// Define which fields of which blocks should be resolved
'files' => [
// Resolve the `image` field in the `intro` block as a file
'intro' => ['image']
],
'pages' => [
// Resolve the `link` field in the `note` block as a page
'note' => ['link']
]
]
];
Now, all files
and pages
fields in the intro
and note
blocks will be resolved to file and page objects, respectively.
You can customize the resolver output by defining a custom resolver (overriding the default resolvers) for the files
and pages
fields in your config.php
. Both resolver options accept a closure that takes the File
or Page
model as its argument and returns an array of properties, just like the default resolver.
For reference, the default values for the files
and pages
resolvers are:
return [
'blocksResolver' => [
'defaultResolvers' => [
'files' => fn (\Kirby\Cms\File $image) => [
'url' => $image->url(),
'width' => $image->width(),
'height' => $image->height(),
'srcset' => $image->srcset(),
'alt' => $image->alt()->value()
],
'pages' => fn (\Kirby\Cms\Page $page) => [
'uri' => $page->uri(),
'title' => $page->title()->value()
]
]
]
];
Custom Resolvers
Default resolvers are probably not enough for your use case. If you need a custom resolver for links, structures, or any other field in a particular block, you can use the blocksResolver.resolvers
option. It takes an array of resolvers, where the key is {blockName}:{fieldName}
and the value is a closure that takes the field and block as its arguments and returns an array of properties.
You have complete control over the output of the resolved fields. For example, you can resolve the link
field of the intro
block to a custom output:
use Kirby\Cms\Block;
use Kirby\Content\Field;
return [
'blocksResolver' => [
'resolvers' => [
// Resolve the field `link` of the block `intro` to a custom output
'intro:link' => fn (Field $field, Block $block) => [
'value' => $field->value(),
'uri' => $field->toPage()?->uri()
]
// Resolve the KirbyText of the field `text` of the `note` block
'note:text' => function (Field $field, Block $block) {
return $field->kirbytext()->value()
}
]
]
];
Replace Field Values
By default, resolved fields will replace the source field values in the given block. If you want to keep the source field values and store the resolved content in a separate key, you can set the resolvedKey
option to a custom key:
return [
'blocksResolver' => [
'resolvedKey' => 'resolved'
]
];
With this configuration, all resolved fields will be stored in a key named resolved
, leaving the original field values untouched. A resolved block might look like this:
{
"content": {
"alt": "Staring at stars",
"image": ["file://BYXR0pvumEbfTknP"],
"resolved": {
"image": {
"url": "http://cacao-kit-backend.test/media/pages/notes/exploring-the-universe/a6c422e141-1714659501/tent-in-the-woods.jpg",
"width": 1024,
"height": 683
}
}
},
"id": "a1c0f653-2e36-4b07-a7fa-d22ef27dd114",
"isHidden": false,
"type": "image"
}
resolvePermalinks()
permalinksToUrls()
method, but supports a custom URL parser.This field method resolves page and file permalinks to their respective URLs. It is primarily intended for usage with KQL queries, since the value of writer
fields contains permalink URLs such as /@/page/nDvVIAwDBph4uOpm
. But the method works with any field values that contains permalinks in href
or src
attributes.
For headless usage, you may want to remove the origin from the URL and just return the path. You can do this by defining a custom URL parser in your config.php
:
return [
'permalinksResolver' => [
// Strip the origin from the URL
'urlParser' => function (string $url, \Kirby\Cms\App $kirby) {
$path = parse_url($url, PHP_URL_PATH);
return $path;
}
]
];
Or in multi-language setups, you may want to remove a language prefix like /de
from the URL:
return [
'permalinksResolver' => [
// Strip the language code prefix from German URLs
'urlParser' => function (string $url, \Kirby\Cms\App $kirby) {
$path = parse_url($url, PHP_URL_PATH);
if (str_starts_with($path, '/de')) {
return substr($path, 3);
}
return $path;
}
]
];
toResolvedLayouts()
The toResolvedLayouts()
method is a wrapper around Kirby's toLayouts()
method. Under the hood, it uses the toResolvedBlocks()
method to resolve fields in blocks. You can use the same files
, pages
, and custom resolvers as with the toResolvedBlocks()
method.