From 9908f5cfdef7dd81aa84fabf85b7c95aab40901f Mon Sep 17 00:00:00 2001 From: Jason Varga Date: Tue, 1 Sep 2026 17:18:10 -0400 Subject: [PATCH 01/11] Document multiple conditions targeting the same field Ref: statamic/cms#14593 --- content/collections/pages/conditional-fields.md | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/content/collections/pages/conditional-fields.md b/content/collections/pages/conditional-fields.md index c4b077334..18f0bc369 100644 --- a/content/collections/pages/conditional-fields.md +++ b/content/collections/pages/conditional-fields.md @@ -222,6 +222,15 @@ if_any: that_field: cheeseburger ``` +You may also define multiple conditions against the *same* field by providing an array of conditions. For example, the following will show the field when `age` is greater than `18` *__AND__* less than `65`: + +```yaml +if: + age: + - '> 18' + - '< 65' +``` + ## Nested fields You may use dot notation to access nested values when necessary. For example, maybe you would like to show a field when an `array` fieldtype's `country` value is `Canada`: From 8891733b8b8e4e5dd177880042cfe209336aaf66 Mon Sep 17 00:00:00 2001 From: Jason Varga Date: Tue, 1 Sep 2026 17:18:23 -0400 Subject: [PATCH 02/11] Document `icon` support for Dictionary items Ref: statamic/cms#15181 --- content/collections/pages/dictionaries.md | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/content/collections/pages/dictionaries.md b/content/collections/pages/dictionaries.md index 574c2e987..c0f77f48a 100644 --- a/content/collections/pages/dictionaries.md +++ b/content/collections/pages/dictionaries.md @@ -53,6 +53,14 @@ class States extends BasicDictionary In the example above, you can see that each item has a `label` and `value`. These will be used in the dropdown field. Any additional keys will be available within templates. +You may also provide an `icon`, which will be displayed alongside the item's label in the fieldtype: + +```php +['label' => 'Alabama', 'value' => 'AL', 'capital' => 'Montgomery', 'icon' => 'map-pin'], +``` + +The `icon` may be the name of one of Statamic's built-in icons, or an inline SVG string. Like `label`, it will not be available within templates, and won't be considered when [searching](#basic-search). + Here we are returning a hardcoded array. But in reality you may be getting options from somewhere like a file, database, or an API: ```php @@ -145,6 +153,7 @@ public function get(string $key): ?Item return new Item($key, $product->name, [ 'price' => $product->price, 'sku' => $product->sku, + 'icon' => 'tag', ]); } ``` From 751d4e60fe92954985ea21366d4a914b394bd743 Mon Sep 17 00:00:00 2001 From: Jason Varga Date: Tue, 1 Sep 2026 17:18:31 -0400 Subject: [PATCH 03/11] Document appending config sections to existing fieldtypes Ref: statamic/cms#13796 --- .../collections/pages/build-a-fieldtype.md | 19 +++++++++++++++++++ 1 file changed, 19 insertions(+) diff --git a/content/collections/pages/build-a-fieldtype.md b/content/collections/pages/build-a-fieldtype.md index 74e31253f..3d4433d3d 100644 --- a/content/collections/pages/build-a-fieldtype.md +++ b/content/collections/pages/build-a-fieldtype.md @@ -523,6 +523,25 @@ Text::appendConfigFields([ ]); ``` +You may also append an entire section of fields, rather than a single field, by passing an array without a string key. It should have a `display` and `fields`, just like a regular blueprint section. + +```php +Text::appendConfigFields([ + [ + 'display' => 'Extra section', + 'fields' => [ + 'more_options' => [ + 'type' => 'array', + 'display' => 'Options', + 'instructions' => 'Instructions for this field', + ], + ], + ], +]); +``` + +You may mix fields and sections in the same call. Anything with a string key will be treated as a single field, while anything without one will be treated as a section. + You can also append a config field to _all_ fieldtypes via the `Fieldtype` class: ```php From 38d1d3100bcaccef6a37e427aab2b31a92f3e51b Mon Sep 17 00:00:00 2001 From: Jason Varga Date: Tue, 1 Sep 2026 17:18:44 -0400 Subject: [PATCH 04/11] Document `saveQuietly` and `deleteQuietly` on CollectionTree Ref: statamic/cms#14879 --- content/collections/pages/events.md | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/content/collections/pages/events.md b/content/collections/pages/events.md index 36ffbd45a..105c71191 100644 --- a/content/collections/pages/events.md +++ b/content/collections/pages/events.md @@ -382,6 +382,13 @@ public function handle(CollectionTreeSaving $event) } ``` +You may suppress the `CollectionTreeSaving`, `CollectionTreeSaved`, and `CollectionTreeDeleted` events by using the `saveQuietly` and `deleteQuietly` methods on the tree, instead of `save` and `delete`. + +``` php +$tree->saveQuietly(); +$tree->deleteQuietly(); +``` + ### EntryBlueprintFound `Statamic\Events\EntryBlueprintFound` From df43550deefcb3cd3c43a2a5a55fc97a381ecc14 Mon Sep 17 00:00:00 2001 From: Jason Varga Date: Tue, 1 Sep 2026 17:18:51 -0400 Subject: [PATCH 05/11] Document live title generation when using a title format Ref: statamic/cms#15170 --- content/collections/pages/collections.md | 2 ++ 1 file changed, 2 insertions(+) diff --git a/content/collections/pages/collections.md b/content/collections/pages/collections.md index ce8463e1f..0f039a511 100644 --- a/content/collections/pages/collections.md +++ b/content/collections/pages/collections.md @@ -142,6 +142,8 @@ To use modifiers in title formats, make sure to use the `{{` Antlers syntax, lik ``` ::: +As you fill in the fields referenced by your title format, the entry's title (and therefore its slug) will update live in the Control Panel — you don't need to save first to see them. + ## Slugs Slugs are used in entry URLs. For an entry named `My Entry`, the slug would default to `my-entry` unless you edit it. From 66ead2e9302c739112cc467dea54f15ec18e9e62 Mon Sep 17 00:00:00 2001 From: Jason Varga Date: Tue, 1 Sep 2026 17:19:14 -0400 Subject: [PATCH 06/11] Use x-model.fill so Alpine forms prefill from field values Ref: statamic/cms#14706 --- content/collections/tags/form-create.md | 16 +++++++++------- 1 file changed, 9 insertions(+), 7 deletions(-) diff --git a/content/collections/tags/form-create.md b/content/collections/tags/form-create.md index adfa61159..d4b1934d8 100644 --- a/content/collections/tags/form-create.md +++ b/content/collections/tags/form-create.md @@ -403,7 +403,7 @@ This will generate an Alpine component, with automatic `x-data` handling that wi ### Wiring Up the Fields -Finally, you will need to wire up the fields. With Alpine, this is done using `x-model` on the input to keep it in sync with the component, as well as an `x-if` to conditionally render the input and its label. +Finally, you will need to wire up the fields. With Alpine, this is done using `x-model.fill` on the input to keep it in sync with the component, as well as an `x-if` to conditionally render the input and its label. ::tabs @@ -412,7 +412,7 @@ Finally, you will need to wire up the fields. With Alpine, this is done using `x ``` @@ -421,13 +421,15 @@ Finally, you will need to wire up the fields. With Alpine, this is done using `x ``` :: -The `x-model` should reference the field's handle, and the `x-if` should reference the appropriate `show_field` JS generated by Statamic; In this case, `x-model="name"` and `x-if="{{ show_field['name'] }}"` respectively. +The `x-model` should reference the field's handle, and the `x-if` should reference the appropriate `show_field` JS generated by Statamic; In this case, `x-model.fill="name"` and `x-if="{{ show_field['name'] }}"` respectively. + +The `.fill` modifier ensures the input's `value` attribute (such as old input, or the field's current value) is used to populate the Alpine model on load, rather than being overridden by it. For nested fields, you can get `show_field` JS by passing the whole dotted handle as the key, ie) `x-if="{{ show_field['field_group.nested_field']}}"`. @@ -461,7 +463,7 @@ If you are [dynamically rendering your fields](#dynamic-rendering) using the `fi ``` :: -The pre-rendered `{{ field }}` input will automatically render `x-model` for you, but you'll still need to wrap your input and its label with an `x-if="{{ show_field }}`, as shown above. +The pre-rendered `{{ field }}` input will automatically render `x-model.fill` for you, but you'll still need to wrap your input and its label with an `x-if="{{ show_field }}`, as shown above. ### Scoping Your Alpine Data @@ -494,7 +496,7 @@ If you are hardcoding your inputs, you will need adjust your `x-model` to follow ``` @@ -503,7 +505,7 @@ If you are hardcoding your inputs, you will need adjust your `x-model` to follow ``` From 4ee59a6990949d88715fe0804250069cb16776cc Mon Sep 17 00:00:00 2001 From: Jason Varga Date: Tue, 1 Sep 2026 17:19:28 -0400 Subject: [PATCH 07/11] Document array syntax and show-endpoint support for the fields param Ref: statamic/cms#15319 --- content/collections/pages/rest-api.md | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/content/collections/pages/rest-api.md b/content/collections/pages/rest-api.md index eba72dc99..5e6dc2f6b 100644 --- a/content/collections/pages/rest-api.md +++ b/content/collections/pages/rest-api.md @@ -218,6 +218,14 @@ You may specify which top level fields should be included in the response. /endpoint?fields=id,title,content ``` +You may also use array syntax: + +``` url +/endpoint?fields[]=id&fields[]=title&fields[]=content +``` + +On the [Entry](#entry) and [Asset](#asset) endpoints, `fields` will also be honored when fetching a single item, not just when listing them. + ## Pagination Results will be paginated into 25 items per page by default. You may specify the items per page and which page you are viewing with the `limit` and `page` parameters: From 2a307645e35210965b8faa5d80fc8614a774f7dd Mon Sep 17 00:00:00 2001 From: Jason Varga Date: Tue, 1 Sep 2026 17:20:01 -0400 Subject: [PATCH 08/11] Document the `site` query param on entries and taxonomy terms Ref: statamic/cms#15320 --- content/collections/pages/rest-api.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/content/collections/pages/rest-api.md b/content/collections/pages/rest-api.md index 5e6dc2f6b..79327b54e 100644 --- a/content/collections/pages/rest-api.md +++ b/content/collections/pages/rest-api.md @@ -280,7 +280,7 @@ Gets entries within a collection. ``` :::tip -If you are using [Multi-Site](/multi-site), the entries endpoint will serve from all sites at once. If needed, you can limit the fetched data to a specific site with a `site` [filter](#filtering) (ie. `&filter[site]=fr`). +If you are using [Multi-Site](/multi-site), the entries endpoint will serve from all sites at once. If needed, you can limit the fetched data to a specific site with the `site` query parameter (ie. `?site=fr`), or a `site` [filter](#filtering) (ie. `&filter[site]=fr`). ::: @@ -396,7 +396,7 @@ Gets terms in a taxonomy. ``` :::tip -If you are using [Multi-Site](/multi-site), you can select the site using a `site` [filter](#filtering) (ie. `&filter[site]=fr`). +If you are using [Multi-Site](/multi-site), you can select the site using the `site` query parameter (ie. `?site=fr`), or a `site` [filter](#filtering) (ie. `&filter[site]=fr`). ::: ## Taxonomy term From fb7afa3cd6cee33754b79718b00fa9c3f8f57d64 Mon Sep 17 00:00:00 2001 From: Jason Varga Date: Tue, 1 Sep 2026 17:20:06 -0400 Subject: [PATCH 09/11] Document resolving entries by slug on the Entry endpoint Ref: statamic/cms#15321 --- content/collections/pages/rest-api.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/content/collections/pages/rest-api.md b/content/collections/pages/rest-api.md index 79327b54e..784e104ac 100644 --- a/content/collections/pages/rest-api.md +++ b/content/collections/pages/rest-api.md @@ -288,7 +288,7 @@ If you are using [Multi-Site](/multi-site), the entries endpoint will serve from `GET` `/api/collections/{collection}/entries/{id}` -Gets a single entry. +Gets a single entry by ID or slug. If both an ID and a slug match, the entry matched by ID takes priority. When resolving by slug on a multi-site collection, the `site` query parameter will be used if provided, otherwise the collection's first configured site will be used. ``` json { From 0eba7cd1662991547d47a158c0cd13def2192667 Mon Sep 17 00:00:00 2001 From: Jason Varga Date: Tue, 1 Sep 2026 17:20:59 -0400 Subject: [PATCH 10/11] Document the ping and sites REST API endpoints Ref: statamic/cms#15317 --- content/collections/pages/rest-api.md | 40 +++++++++++++++++++++++++++ 1 file changed, 40 insertions(+) diff --git a/content/collections/pages/rest-api.md b/content/collections/pages/rest-api.md index 784e104ac..4f0436922 100644 --- a/content/collections/pages/rest-api.md +++ b/content/collections/pages/rest-api.md @@ -59,6 +59,8 @@ https://yourdomain.tld/api/{endpoint} ` You may send requests to the following endpoints: +- [Ping](#ping) +- [Sites](#sites) - [Entries](#entries) / [Entry](#entry) - [Collection Tree](#collection-tree) / [Navigation Tree](#navigation-tree) - [Taxonomy Terms](#taxonomy-terms) / [Taxonomy Term](#taxonomy-term) @@ -261,6 +263,44 @@ The response will contain your `data`, `links` to easily get next/previous URLs, --- +## Ping + +`GET` `/api/ping` + +A simple health check endpoint. It returns `pong`, and is available whenever the REST API is enabled, regardless of which resources are enabled. + +``` json +{ + "ping": "pong" +} +``` + +## Sites + +`GET` `/api/sites` + +Gets all configured sites. This resource is disabled by default. You can enable it with `resources.sites` in your `config/statamic/api.php` config: + +```php +'resources' => [ + 'sites' => true, +], +``` + +``` json +{ + "data": [ + { + "handle": "default", + "name": "Default", + "locale": "en_US", + "short_locale": "en", + "url": "http://example.com/" + } + ] +} +``` + ## Entries `GET` `/api/collections/{collection}/entries` From 9362829010450b9f40701b17b5246f2e3316c66f Mon Sep 17 00:00:00 2001 From: Jason Varga Date: Tue, 1 Sep 2026 17:21:27 -0400 Subject: [PATCH 11/11] Document collection, taxonomy, nav, and asset container metadata endpoints Ref: statamic/cms#15318 --- content/collections/pages/rest-api.md | 150 ++++++++++++++++++++++++++ 1 file changed, 150 insertions(+) diff --git a/content/collections/pages/rest-api.md b/content/collections/pages/rest-api.md index 4f0436922..d400f6764 100644 --- a/content/collections/pages/rest-api.md +++ b/content/collections/pages/rest-api.md @@ -61,9 +61,13 @@ You may send requests to the following endpoints: - [Ping](#ping) - [Sites](#sites) +- [Collections](#collections) / [Collection](#collection) - [Entries](#entries) / [Entry](#entry) - [Collection Tree](#collection-tree) / [Navigation Tree](#navigation-tree) +- [Navs](#navs) / [Nav](#nav) +- [Taxonomies](#taxonomies) / [Taxonomy](#taxonomy) - [Taxonomy Terms](#taxonomy-terms) / [Taxonomy Term](#taxonomy-term) +- [Asset Containers](#asset-containers) / [Asset Container](#asset-container) - [Assets](#assets) / [Asset](#asset) - [Globals](#globals) / [Global](#global) - [Forms](#forms) / [Form](#form) @@ -301,6 +305,46 @@ Gets all configured sites. This resource is disabled by default. You can enable } ``` +## Collections + +`GET` `/api/collections` + +Gets all collections. + +``` json +{ + "data": [ + { + "handle": "blog", + "title": "Blog", + "structure": null, + "mount": "9412926e-8d33-4f83-8db9-72cbc4c69bcf", + "api_url": "http://example.com/api/collections/blog" + } + ] +} +``` + +## Collection + +`GET` `/api/collections/{collection}` + +Gets a single collection. + +``` json +{ + "data": { + "handle": "blog", + "title": "Blog", + "structure": null, + "mount": "9412926e-8d33-4f83-8db9-72cbc4c69bcf", + "api_url": "http://example.com/api/collections/blog" + } +} +``` + +If the collection is structured, `structure` will contain its `max_depth` and `expects_root` values instead of `null`. + ## Entries `GET` `/api/collections/{collection}/entries` @@ -378,6 +422,44 @@ On this endpoint, the [fields](#selecting-fields) param will allow you to select ``` +## Navs + +`GET` `/api/navs` + +Gets all navigations. + +``` json +{ + "data": [ + { + "handle": "main", + "title": "Main Navigation", + "max_depth": null, + "expects_root": false, + "api_url": "http://example.com/api/navs/main" + } + ] +} +``` + +## Nav + +`GET` `/api/navs/{nav}` + +Gets a single navigation. + +``` json +{ + "data": { + "handle": "main", + "title": "Main Navigation", + "max_depth": null, + "expects_root": false, + "api_url": "http://example.com/api/navs/main" + } +} +``` + ## Navigation Tree `GET` `/api/navs/{nav}/tree` @@ -417,6 +499,40 @@ On this endpoint, the [fields](#selecting-fields) param will allow you to select ``` +## Taxonomies + +`GET` `/api/taxonomies` + +Gets all taxonomies. + +``` json +{ + "data": [ + { + "handle": "tags", + "title": "Tags", + "api_url": "http://example.com/api/taxonomies/tags" + } + ] +} +``` + +## Taxonomy + +`GET` `/api/taxonomies/{taxonomy}` + +Gets a single taxonomy. + +``` json +{ + "data": { + "handle": "tags", + "title": "Tags", + "api_url": "http://example.com/api/taxonomies/tags" + } +} +``` + ## Taxonomy Terms `GET` `/api/taxonomies/{taxonomy}/terms` @@ -584,6 +700,40 @@ Get a single user. } ``` +## Asset Containers + +`GET` `/api/asset-containers` + +Gets all asset containers. This uses the same `resources.assets` config as the [Assets](#assets) endpoint. + +``` json +{ + "data": [ + { + "handle": "main", + "title": "Main", + "api_url": "http://example.com/api/asset-containers/main" + } + ] +} +``` + +## Asset Container + +`GET` `/api/asset-containers/{container}` + +Gets a single asset container. + +``` json +{ + "data": { + "handle": "main", + "title": "Main", + "api_url": "http://example.com/api/asset-containers/main" + } +} +``` + ## Assets `GET` `/api/assets/{container}`