# Cohesivo Developer Documentation > Developer documentation for Cohesivo — architecture, APIs, templating, and extensibility for building and customizing Ibexa DXP projects. # Cohesivo Developer Documentation # Cohesivo by Ibexa > For the complete documentation index, see [llms.txt](https://doc.ibexa.co/en/saas/llms.txt). Cohesivo is a headless SaaS content management system. You model, author, and administer content, products, and customers in a hosted back office, and you retrieve everything over HTTP to render in the front end that you build. ## How to start? [Go through the First steps](https://doc.ibexa.co/en/saas/getting_started/first_steps/index.md) [Explore the APIs](https://doc.ibexa.co/en/saas/api/api/index.md) [Read the Product guides](https://doc.ibexa.co/en/saas/product_guides/product_guides/index.md) ## What's new in Cohesivo Cohesivo is delivered as a service, so new capabilities reach you without an upgrade project. The release notes list what has been delivered. [Release notes](https://doc.ibexa.co/en/saas/release_notes/index.md) ## Looking for the on-premise product? Cohesivo is also available as an on-premise, self-hosted product that you install and extend yourself. It has its own documentation. [About on-premise Cohesivo](https://doc.ibexa.co/en/saas/on_premise/index.md) ## What Cohesivo does ### [Content](https://doc.ibexa.co/en/saas/content_management/content_management/index.md) - [Content model](https://doc.ibexa.co/en/saas/content_management/content_model/index.md) - [Pages](https://doc.ibexa.co/en/saas/content_management/pages/pages/index.md) - [Forms](https://doc.ibexa.co/en/saas/content_management/forms/forms/index.md) - [RichText and Online Editor](https://doc.ibexa.co/en/saas/content_management/rich_text/rich_text/index.md) - [Images](https://doc.ibexa.co/en/saas/content_management/images/images/index.md) - [Taxonomy](https://doc.ibexa.co/en/saas/content_management/taxonomy/taxonomy/index.md) - [Editorial workflow](https://doc.ibexa.co/en/saas/content_management/workflow/workflow/index.md) ### [Sites and administration](https://doc.ibexa.co/en/saas/administration/administration/index.md) - [Multisite](https://doc.ibexa.co/en/saas/multisite/multisite/index.md) - [Site Factory](https://doc.ibexa.co/en/saas/multisite/site_factory/site_factory/index.md) - [Languages and translations](https://doc.ibexa.co/en/saas/multisite/languages/languages/index.md) - [URL management](https://doc.ibexa.co/en/saas/content_management/url_management/url_management/index.md) - [Back office](https://doc.ibexa.co/en/saas/administration/back_office/back_office/index.md) - [Users](https://doc.ibexa.co/en/saas/users/users/index.md) - [Permissions](https://doc.ibexa.co/en/saas/permissions/permissions/index.md) ### [Products and customers](https://doc.ibexa.co/en/saas/product_catalog/product_catalog/index.md) - [Products](https://doc.ibexa.co/en/saas/product_catalog/products/index.md) - [Catalogs](https://doc.ibexa.co/en/saas/product_catalog/catalogs/index.md) - [Prices](https://doc.ibexa.co/en/saas/product_catalog/prices/index.md) - [Quable integration](https://doc.ibexa.co/en/saas/product_catalog/quable/quable/index.md) - [Customer Portal](https://doc.ibexa.co/en/saas/customer_management/customer_portal/index.md) - [Data collection with Qualifio](https://doc.ibexa.co/en/saas/qualifio/qualifio/index.md) ### [APIs, search, and AI](https://doc.ibexa.co/en/saas/api/api/index.md) - [REST API](https://doc.ibexa.co/en/saas/api/api/index.md) - [REST API authentication](https://doc.ibexa.co/en/saas/api/rest_api/rest_api_authentication/index.md) - [Search](https://doc.ibexa.co/en/saas/search/search/index.md) - [AI Actions](https://doc.ibexa.co/en/saas/ai/ai_actions/ai_actions/index.md) - [MCP servers](https://doc.ibexa.co/en/saas/ai/mcp/mcp/index.md) - [Recommendations](https://doc.ibexa.co/en/saas/recommendations/raptor_integration/raptor_connector/index.md) - [Customer Data Platform](https://doc.ibexa.co/en/saas/raptor_cdp/raptor_cdp/index.md) ## Most popular pages - [RichText and Online Editor](https://doc.ibexa.co/en/saas/content_management/rich_text/rich_text/index.md) - [Content model](https://doc.ibexa.co/en/saas/content_management/content_model/index.md) - [Images](https://doc.ibexa.co/en/saas/content_management/images/images/index.md) - [Page blocks](https://doc.ibexa.co/en/saas/content_management/pages/page_blocks/index.md) # On-premise Cohesivo # On-premise Cohesivo > For the complete documentation index, see [llms.txt](https://doc.ibexa.co/en/saas/llms.txt). An on-premise, self-hosted version of Cohesivo also exists, with its own documentation. Besides the SaaS product documented here, Cohesivo is also available as an on-premise, self-hosted product. Refer to the [on-premise Cohesivo documentation](https://doc.ibexa.co/en/latest/) for details. # Getting started # Getting started > For the complete documentation index, see [llms.txt](https://doc.ibexa.co/en/saas/llms.txt). Get started working with Cohesivo by taking your first steps after you log in. To get started working with Cohesivo, see what first steps to take to familiarize yourself with the platform. - [First steps](https://ez-systems-developer-documentation--3403.com.readthedocs.build/en/3403/getting_started/first_steps/): Take your first steps in Cohesivo after you log in to the back office. # First steps > For the complete documentation index, see [llms.txt](https://doc.ibexa.co/en/saas/llms.txt). Take your first steps in Cohesivo after you log in to the back office. This page lists first steps you can take after you log in to Cohesivo for the first time. These steps are the most common actions you may need to take in a new site. ## Add a content type 1. In your browser, log in to the back office. 2. In the upper-right corner, click the avatar icon and in the drop-down menu disable the [Focus mode](https://doc.ibexa.co/projects/userguide/en/6.0/getting_started/discover_ui/#focus-mode). 3. Select content and go to content types. 4. Enter the content group and create a new content type. ![Creating a content type](https://doc.ibexa.co/en/saas/getting_started/img/first-steps-create-ct.png) 5. Input the content type's name, for example "Blog Post", and identifier: `blog_post`. 6. Below, add a field definition of the type Text Line. Name it "Title" and give it identifier `title`. 7. Add another field definition: Text (type Rich text) with identifier `text`. > **Note: Note** > > Make sure all fields are marked as *Translatable*. This setting is required to enable [content translation](#add-a-language-and-translate-content) for all fields in the created content type. 8. Save the content type. For more information, see [Content model](https://doc.ibexa.co/en/saas/content_management/content_model/index.md). ## Create content 1. Go to the back office, select **Content** -> **Content structure**, and create a new content item by clicking **Create content**. ![Creating a Blog Post](https://doc.ibexa.co/en/saas/getting_started/img/first-steps-create-content.png) 2. Select a Blog Post content type. Fill in the content item and publish it. Cohesivo is headless, so the published content item is delivered over HTTP rather than rendered by the platform. You can now fetch it with the REST API and display it in your own front end. For more information, see [REST API](https://doc.ibexa.co/en/saas/api/api/index.md) and [REST API authentication](https://doc.ibexa.co/en/saas/api/rest_api/rest_api_authentication/index.md). ## SiteAccesses A SiteAccess is a named context in which a request is served. By using more than one SiteAccess you can serve several sites, or several versions of one site, from the same content. Each incoming request is assigned to a SiteAccess based on matching rules, for example on the host name or on part of the URI. SiteAccesses can be gathered in groups, and many settings are SiteAccess-aware, which means that they can have a different value for each SiteAccess, and fall back to the value set for the group or for all SiteAccesses. For more information, see [Multisite](https://doc.ibexa.co/en/saas/multisite/multisite/index.md), [SiteAccess](https://doc.ibexa.co/en/saas/multisite/siteaccess/siteaccess/index.md), and [SiteAccess matching](https://doc.ibexa.co/en/saas/multisite/siteaccess/siteaccess_matching/index.md). ## Add a language and translate Content One of the most common use cases for SiteAccesses is having different language versions of a site. 1. Go to the back office and select **Admin** > **Languages**. Add a new language called "German", with the language code `ger-DE`. Make sure it's enabled. ![Creating a language](https://doc.ibexa.co/en/saas/getting_started/img/first-steps-create-language.png) 2. Next, go to the **Content structure** and open the blog post you had created earlier. Switch to the **Translations** tab and add a new translation. ![Adding a translation](https://doc.ibexa.co/en/saas/getting_started/img/first-steps-add-translation.png) 3. Select German as the target language and base the translation on the English source text. Edit the content item and publish it. The content item now exists in two languages. Which one a visitor gets depends on the languages set for the SiteAccess that serves the request. For more information, see [Languages](https://doc.ibexa.co/en/saas/multisite/languages/languages/index.md) and [Set up translation SiteAccess](https://doc.ibexa.co/en/saas/multisite/set_up_translation_siteaccess/index.md). ## Set up permissions To allow a group of users to edit only a specific content type (in this example, blog posts), you need to set up permissions for them. Users and user groups are assigned roles. A role can contain a number of policies, which are rules that permit the user to perform a specific function. Policies can be additionally restricted by limitations. 1. Go to **Admin** -> **Users**. Create a new user group (the same way you create regular content). Call the group "Bloggers". 2. In the new group create a user. Remember their username and password. Mark the user as "Enabled". ![Creating a User](https://doc.ibexa.co/en/saas/getting_started/img/first-steps-create-user.png) 3. Go to **Admin** -> **Roles**. Create a new role called "Blogger". 4. Add the following policies to ensure the user can log in and access content: - `User/Login` - `Content/Read` - `Content/Versionread` - `Section/View` - `Content/Reverserelatedlist` When creating these policies, don't add any limitations and click **Save** to proceed. 5. Now add policies that allow the user to create and publish content, limited to Blog Posts: - `Content/Create` with limitation for content type Blog Post - `Content/Edit` with limitation for content type Blog Post - `Content/Publish` with limitation for content type Blog Post ![Adding limitations to a policy](https://doc.ibexa.co/en/saas/getting_started/img/first-steps-policy-limitations.png) 6. In the **Assignments** tab assign the "Blogger" role to the "Bloggers" group. ![Assigning a role](https://doc.ibexa.co/en/saas/getting_started/img/first-steps-assign-roles.png) You can now log out and log in again as the new user. You're able to create Blog Posts only. For more information, see [Permissions](https://doc.ibexa.co/en/saas/permissions/permissions/index.md). # API # API > For the complete documentation index, see [llms.txt](https://doc.ibexa.co/en/saas/llms.txt). Cohesivo is an API-first product and provides APIs to handle content and repository information. Cohesivo is an API-first product and provides a REST API to handle content and repository information. - [REST API usage](https://ez-systems-developer-documentation--3403.com.readthedocs.build/en/3403/api/rest_api/rest_api_usage/rest_api_usage/): The REST API covers objects in the Cohesivo Repository with regular and custom HTTP methods, such as GET or PUBLISH, and HTTP headers. - [MCP Servers](https://ez-systems-developer-documentation--3403.com.readthedocs.build/en/3403/ai/mcp/mcp/): Overview of MCP resources in Cohesivo # REST API usage > For the complete documentation index, see [llms.txt](https://doc.ibexa.co/en/saas/llms.txt). The REST API covers objects in the Cohesivo Repository with regular and custom HTTP methods, such as GET or PUBLISH, and HTTP headers. The REST API in Cohesivo allows you to interact with the Cohesivo installation by using the HTTP protocol, following a [REST](https://en.wikipedia.org/wiki/Representational_state_transfer) interaction model. Each resource (URI) interacts with a part of the system (like content, users or search). Every interaction with the repository that you can do from the back office can also be done with the REST API. The REST API uses HTTP methods (such as `GET` and `PUBLISH`), and HTTP headers to specify the type of request. ## OpenAPI support The REST API is built on top of [API Platform](https://api-platform.com/docs/symfony/) and meets the [OpenAPI](https://www.openapis.org/) standard. You can download the OpenAPI specification in: - [YAML format](https://doc.ibexa.co/en/saas/api/rest_api/rest_api_reference/openapi.yaml) - [JSON format](https://doc.ibexa.co/en/saas/api/rest_api/rest_api_reference/openapi.json) Use the specification file with [available OpenAPI tools](https://tools.openapis.org/) to work faster with the API, for example, by generating libraries and clients for the API. ## URIs The REST API is designed in such a way that the client can explore the Repository without constructing any URIs to resources. Starting from the [root resource](#rest-root), every response includes further links (`href`) to related resources. ### URI prefix [REST reference](https://doc.ibexa.co/en/saas/api/rest_api/rest_api_reference/rest_api_reference.html), for the sake of readability, uses no prefixes in the URIs. In practice, the `/api/ibexa/v2` prefixes all REST hrefs. This prefix immediately follows the domain, and you can't use the [`URIElement` SiteAccess matcher](https://doc.ibexa.co/en/saas/multisite/siteaccess/siteaccess_matching/#urielement). If you need to the select a SiteAccess, see the [`X-Siteaccess` HTTP header](https://doc.ibexa.co/en/saas/api/rest_api/rest_api_usage/rest_requests/#siteaccess). ### URI parameters URI parameters (query string) can be used on some resources. They usually serve as options or filters for the requested resource. As an example, the request below would paginate the results and return the first 5 relations for version 3 of the content item 59: ```http GET /content/objects/59/versions/3/relations?limit=5 HTTP/1.1 Accept: application/vnd.ibexa.api.RelationList+xml ``` #### Working with value objects IDs Resources that accept a reference to another resource expect the reference to be given as a REST URI, not a single ID. For example, the URI requesting a list of user groups assigned to the role with ID 1 is: ```http GET /api/ibexa/v2/user/groups?roleId=/api/ibexa/v2/user/roles/1 HTTP/1.1 ``` ### REST root The `/` root route is answered by a reference list with the main resource routes and media-types. It's presented in XML by default, but you can also switch to JSON output. ```bash curl https://api.example.com/api/ibexa/v2/ curl -H "Accept: application/json" https://api.example.com/api/ibexa/v2/ ``` ### Country list Alongside regular Repository interactions, there is a REST service providing a list of countries with their names, [ISO-3166](https://en.wikipedia.org/wiki/ISO_3166) codes and International Dialing Codes (IDC). You can use it when presenting a country options list from any application. This country list's URI is `/services/countries`. The ISO-3166 country codes can be represented as: - two-letter code (alpha-2) — recommended as the general purpose code - three-letter code (alpha-3) — related to the country name - three-digit numeric code (numeric-3) — use it if you need to avoid using Latin script For details, see the [ISO-3166 glossary](https://www.iso.org/glossary-for-iso-3166.html). ## REST communication summary - A REST route (URI) leads to a REST controller action. A REST route is composed of the root prefix (`ibexa.rest.path_prefix: /api/ibexa/v2`) and a resource path (for example, `/content/objects/{contentId}`). - This controller action returns an `Ibexa\Rest\Value` descendant. - This controller action might use the `Request` to build its result according to, for example, GET parameters, the `Accept` HTTP header, or the request payload and its `Content-Type` HTTP header. - This controller action might wrap its return in a `CachedValue` which contains caching information for the reverse proxies. - The `Ibexa\Bundle\Rest\EventListener\ResponseListener` attached to the `kernel.view event` is triggered, and passes the request and the controller action's result to the `AcceptHeaderVisitorDispatcher`. - The `AcceptHeaderVisitorDispatcher` matches one of the `regexps` of an `ibexa.rest.output.visitor` service (an `Ibexa\Contracts\Rest\Output\Visitor`). The role of this `Output\Visitor` is to transform the value returned by the controller into XML or JSON output format. To do so, it combines an `Output\Generator` corresponding to the output format and a `ValueObjectVisitorDispatcher`. This `Output\Generator` is also adding the `media-type` attributes. - The matched `Output\Visitor` uses its `ValueObjectVisitorDispatcher` to select the right `ValueObjectVisitor` according to the fully qualified class name (FQCN) of the controller result. A `ValueObjectVisitor` is a service tagged `ibexa.rest.output.value_object.visitor` and this tag has a property `type` pointing a FQCN. - `ValueObjectVisitor`s recursively help to transform the controller result thanks to the abstraction layer of the `Generator`. - The `Output\Visitor` returns the `Response` to send back to the client. # REST requests > For the complete documentation index, see [llms.txt](https://doc.ibexa.co/en/saas/llms.txt). REST API requests can have a generic or a custom header. It defines additional options in the request, such as the accepted content type of response. ## Request method Depending on the HTTP method used, different actions are possible on the same resource. Example: | Action | Description | | --------------------------------------- | ------------------------------------------------------------------ | | `GET /content/objects/2/versions/3` | Fetches data about version #3 of content item #2 | | `PATCH /content/objects/2/versions/3` | Updates the version #3 draft of content item #2 | | `DELETE /content/objects/2/versions/3` | Deletes the (draft or archived) version #3 from content item #2 | | `COPY /content/objects/2/versions/3` | Creates a new draft version of content item #2 from its version #3 | | `PUBLISH /content/objects/2/versions/3` | Promotes the version #3 of content item #2 from draft to published | | `OPTIONS /content/objects/2/versions/3` | Lists all the methods usable with this resource, the 5 ones above | The following list of available methods gives an overview of the kind of action a method triggers on a resource, if available. For method action details per resource, see the [REST API reference](https://doc.ibexa.co/en/saas/api/rest_api/rest_api_reference/rest_api_reference.html). | HTTP method | Status | Description | Safe | | -------------------------------------------------------------------- | -------- | ---------------------- | ---- | | [OPTIONS](https://datatracker.ietf.org/doc/html/rfc2616#section-9.2) | Standard | List available methods | Yes | | [GET](https://datatracker.ietf.org/doc/html/rfc2616#section-9.3) | Standard | Collect data | Yes | | [HEAD](https://datatracker.ietf.org/doc/html/rfc2616#section-9.4) | Standard | Check existence | Yes | | [POST](https://datatracker.ietf.org/doc/html/rfc2616#section-9.5) | Standard | Create an item | No | | [PATCH](https://datatracker.ietf.org/doc/html/rfc5789) | Custom | Update an item | No | | COPY | Custom | Duplicate an item | No | | [MOVE](https://datatracker.ietf.org/doc/html/rfc2518) | Custom | Move an item | No | | SWAP | Custom | Swap two locations | No | | PUBLISH | Custom | Publish an item | No | | [DELETE](https://datatracker.ietf.org/doc/html/rfc2616#section-9.7) | Standard | Remove an item | No | > **Note: Caution with custom HTTP methods** > > Using custom HTTP methods can cause issues with several HTTP proxies, network firewall/security solutions and simpler web servers. To avoid such issuess, REST API allows you to set these by using the HTTP header `X-HTTP-Method-Override` alongside the standard `POST` method instead of using a custom HTTP method. For example: `X-HTTP-Method-Override: PUBLISH` > > If applicable, both methods are always mentioned in the specifications. Unsafe methods require a CSRF token if [session-based authentication](https://doc.ibexa.co/en/saas/api/rest_api/rest_api_authentication/#session-based-authentication) is used. ### OPTIONS method Any REST API URI responds to an `OPTIONS` request. The response contains an [`Allow` header](https://www.rfc-editor.org/rfc/rfc9110.html#name-allow), which lists the methods accepted by the resource. ```bash curl -IX OPTIONS https://api.example.com/api/ibexa/v2/content/objects/1 ``` ```http OPTIONS /content/objects/1 HTTP/1.1 Host: api.example.com ``` ```http HTTP/1.1 200 OK Allow: PATCH,GET,DELETE,COPY ``` ```bash curl -IX OPTIONS https://api.example.com/api/ibexa/v2/content/locations/1/2 ``` ```http OPTIONS /content/locations/1/2 HTTP/1.1 Host: api.example.com ``` ```http HTTP/1.1 200 OK Allow: GET,PATCH,DELETE,COPY,MOVE,SWAP ``` ## Request headers You can use the following HTTP headers with a REST request: - [`Accept`](https://datatracker.ietf.org/doc/html/rfc2616#section-14.1) describing the desired response type and format - [`Content-Type`](https://datatracker.ietf.org/doc/html/rfc2616#section-14.17) describing the payload type and format - [`X-Siteaccess`](#siteaccess) specifying the target SiteAccess - `X-HTTP-Method-Override` allowing to pass a custom method while using `POST` method as previously seen in [HTTP method](#request-method) - [`Destination`](#destination) specifying where to move an item - [`X-Expected-User`](#expected-user) specifying the user needed for the request execution Other headers related to authentication methods can be found in [REST API authentication](https://doc.ibexa.co/en/saas/api/rest_api/rest_api_authentication/index.md). ### SiteAccess To specify a SiteAccess when communicating with the REST API, provide a custom `X-Siteaccess` header. Otherwise, the default SiteAccess is used. The following example shows what could be a SiteAccess called `restapi` dedicated to REST API accesses: ```http GET / HTTP/1.1 Host: api.example.com Accept: application/vnd.ibexa.api.Root+json X-Siteaccess: restapi ``` One of the principles of REST is that the same resource (such as content item, location, content type) should be unique. It allows caching your REST API with a reverse proxy such as Varnish. If the same resource is available in multiple locations, cache purging is noticeably more complex. This is why SiteAccess matching with REST isn't enabled at URL level (or domain). ### Media types On top of methods, HTTP request headers allow you to personalize the request's behavior. On every resource, you can use the `Accept` header to indicate which format you want to communicate in, JSON or XML. This header is also used to specify the response type you want the server to send when multiple types are available. - `Accept: application/vnd.ibexa.api.Content+xml` to get `Content` (full data, fields included) as **[XML](https://www.w3.org/XML/)** - `Accept: application/vnd.ibexa.api.ContentInfo+json` to get `ContentInfo` (metadata only) as **[JSON](https://www.json.org/)** Media types are also used with the [`Content-Type` header](https://doc.ibexa.co/en/saas/api/rest_api/rest_api_usage/rest_responses/#content-type-header) to characterize a [request body](#request-body) or a [response body](https://doc.ibexa.co/en/saas/api/rest_api/rest_api_usage/rest_responses/#response-body). See [Creating content with binary attachments](#creating-content-with-binary-attachments) below. Also see [Creating session](https://doc.ibexa.co/en/saas/api/rest_api/rest_api_authentication/#creating-session) examples. If the resource only returns one media type, it's also possible to skip it and to specify the format with `application/xml` or `application/json`. A response indicates `href`s to related resources and their media types. ### Destination The `Destination` request header is the request counterpart of the `Location` response header. It's used for a `COPY`, `MOVE` or `SWAP` operation to indicate where the resource should be moved, copied to or swapped with by using the ID of the parent or target location. Examples of such requests are: - [copying a Content](https://doc.ibexa.co/en/saas/api/rest_api/rest_api_reference/rest_api_reference.html#managing-content-copy-content) - [moving a Location and its subtree](https://doc.ibexa.co/en/saas/api/rest_api/rest_api_reference/rest_api_reference.html#managing-content-move-subtree) - [swapping a Location with another](https://doc.ibexa.co/en/saas/api/rest_api/rest_api_reference/rest_api_reference.html#managing-content-swap-location) ### Expected user The `X-Expected-User` header specifies the user needed for the request execution. With this header, if the current username on server side isn't equal to `X-Expected-User` value, a `401 Unauthorized` error is returned. Without this header, the request is executed with the current user who might be unexpected (like the Anonymous user if a previous authentication has expired) and an ambiguous response might be returned as a success not informing about a wrong user. For example, it prevents a Content request to be executed with Anonymous user in the case of an expired authentication, and the response being a `200 OK` but missing content items due to access rights difference with the expected user. ## Request body You can pass some short scalar parameters in the URIs or as GET parameters, but other resources need heavier structured payloads passed in the request body, in particular the ones to create (`POST`) or update (`PATCH`) items. In the [REST API reference](https://doc.ibexa.co/en/saas/api/rest_api/rest_api_reference/rest_api_reference.html), request payload examples are given when needed. One example is the [creation of an authentication session](https://doc.ibexa.co/en/saas/api/rest_api/rest_api_authentication/#establishing-session). When creating a content item, a special payload is needed if the content type has some [Image](https://doc.ibexa.co/en/saas/content_management/field_types/field_type_reference/imagefield/index.md) or [BinaryFile](https://doc.ibexa.co/en/saas/content_management/field_types/field_type_reference/binaryfilefield/index.md) fields as files need to be attached. See the example of a [script uploading images](#creating-content-with-binary-attachments) below. When searching for content items (or locations), the query grammar is also particular. See the [Search section](#search-views) below. ### Creating content with binary attachments To create content with a binary attachment, such as an image, post the content data to [`/content/objects`](https://doc.ibexa.co/en/saas/api/rest_api/rest_api_reference/rest_api_reference.html#tag/Objects/operation/api_contentobjects_post) to create a draft, then publish it through [`/content/objects/{contentId}/versions/{versionNo}`](https://doc.ibexa.co/en/saas/api/rest_api/rest_api_reference/rest_api_reference.html#managing-content-publish-a-content-version). Authenticate the requests as described in [HTTP basic authentication](https://doc.ibexa.co/en/saas/api/rest_api/rest_api_authentication/#http-basic-authentication). ### Search (`/views`) The `/views` route allows you to [search in the repository](https://doc.ibexa.co/en/saas/search/search/index.md). The model allows combining criteria using the logical operators `AND`, `OR` and `NOT`. Most [Search Criteria](https://doc.ibexa.co/en/saas/search/criteria_reference/search_criteria_reference/#search-criteria) are available in REST API. The suffix `Criterion` is added when used with REST API. Most [Sort Clauses](https://doc.ibexa.co/en/saas/search/sort_clause_reference/sort_clause_reference/#sort-clauses) are available too. They require no additional prefix or suffix. The search request has a `Content-Type: application/vnd.ibexa.api.ViewInput+xml` or `+json` header to specify the format of its body's payload. The root node is `` and it has two mandatory children: `` and ``. You can add `version=1.1` to the `Content-Type` header to support the distinction between `ContentQuery` and `LocationQuery` instead of `Query` which implicitly looks only for content items. The following examples search for `article` and `news` typed content items everywhere or for content items of all types directly under location `123`. All those content items must be in the `standard` section. **XML** ```http POST /views HTTP/1.1 Content-Type: application/vnd.ibexa.api.ViewInput+xml ``` ```xml test article news 123 standard 10 0 ascending ``` **XML; 1.1** ```http POST /views HTTP/1.1 Content-Type: application/vnd.ibexa.api.ViewInput+xml; version=1.1 ``` ```xml test article news 123 standard 10 0 ascending ``` **JSON** ```http POST /views HTTP/1.1 Content-Type: application/vnd.ibexa.api.ViewInput+json ``` ```json { "ViewInput": { "identifier": "test", "Query": { "Filter": { "AND": { "OR": { "ContentTypeIdentifierCriterion": [ "article", "news" ], "ParentLocationIdCriterion": 123 }, "SectionIdentifierCriterion": "standard" } }, "limit": "10", "offset": "0", "SortClauses": { "ContentName": "ascending" } } } } ``` **JSON; 1.1** ```http POST /views HTTP/1.1 Content-Type: application/vnd.ibexa.api.ViewInput+json; version=1.1 ``` ```json { "ViewInput": { "identifier": "test", "ContentQuery": { "Filter": { "AND": { "OR": { "ContentTypeIdentifierCriterion": [ "article", "news" ], "ParentLocationIdCriterion": 123 }, "SectionIdentifierCriterion": "standard" } }, "limit": "10", "offset": "0", "SortClauses": { "ContentName": "ascending" } } } } ``` > **Note: Note** > > In JSON, the structure for `ContentTypeIdentifierCriterion` with multiple values has a slightly different format as keys must be unique. In JSON, if there is only one item in `SortClauses`, it can be passed directly without an array to wrap it. You can omit logical operators. If Criteria are of mixed types, they're wrapped in an implicit `AND`. If they're of the same type, they're wrapped in an implicit `OR`. For example, the `AND` operator from previous example's `Filter` could be removed. **XML ExplicitAND** ```xml article news 123 standard ``` **XML ImplicitAND** ```xml article news 123 standard ``` **JSON ExplicitAND** ```json "Filter": { "AND": { "OR": { "ContentTypeIdentifierCriterion": [ "article", "news" ], "ParentLocationIdCriterion": 123 }, "SectionIdentifierCriterion": "standard" } }, ``` **JSON ImplicitAND** ```json "Filter": { "OR": { "ContentTypeIdentifierCriterion": [ "article", "news" ], "ParentLocationIdCriterion": 123 }, "SectionIdentifierCriterion": "standard" }, ``` # REST Responses > For the complete documentation index, see [llms.txt](https://doc.ibexa.co/en/saas/llms.txt). REST API response code defines the status of the received response. ## Response code The following list of available HTTP response status codes gives an overview of the meaning of each code. For code details per resource, see the [REST API reference](https://doc.ibexa.co/en/saas/api/rest_api/rest_api_reference/rest_api_reference.html). | Code | Message | Description | | ----- | ---------------------- | ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | | `200` | OK | The resource has been found. | | `201` | Created | The request to create a new item has succeeded. The response `Location` header indicates where you can find the created item. | | `204` | No Content | The request has succeeded and there is no additional information in the response header or body (for example when publishing or deleting). | | `301` | Moved Permanently | The resource shouldn't be accessed this way. The response `Location` header indicates the proper way. | | `307` | Temporary Redirect | The resource is available at another URL considered as its main. The response `Location` header indicates this main URL. | | `400` | Bad Request | The input (payload) doesn't have the proper schema for the resource. | | `401` | Unauthorized | The user doesn't have the permission to make this request. | | `403` | Forbidden | The user has the permission but action can't be performed because of Repository logic (for example, when trying to create an item with an already existing ID or identifier, when attempting to update a version in another state than draft). | | `404` | Not Found | The requested object (or a request data like the parent of a new item) hasn't been found. | | `405` | Method Not Allowed | The requested resource doesn't support the HTTP verb that was used. | | `406` | Not Acceptable | The request's `Accept` header isn't supported. | | `409` | Conflict | The request is in conflict with another part of the repository (for example, trying to create a new item with an identifier already used). | | `415` | Unsupported Media Type | The request payload media type doesn't match the media type specified in the request header. | | `500` | Internal Server Error | The server encountered an unexpected condition, usually an exception, which prevents it from fulfilling the request, like database down, permissions or configuration error. | | `501` | Not Implemented | Returned when the requested method hasn't yet been implemented. For Cohesivo, most of users, user groups, content items, locations and content types have been implemented. Some of their methods, and other features, may return a 501. | ## Response headers A resource's response may contain metadata in its HTTP headers. > **Note: Note** > > For information about the `Allow` response header, see the [`OPTIONS` method](https://doc.ibexa.co/en/saas/api/rest_api/rest_api_usage/rest_requests/#options-method). ### Content-Type header When a response contains an actual HTTP body, the `Content-Type` header specifies what the body contains. The `Content-Type` header's value is a [media type](https://doc.ibexa.co/en/saas/api/rest_api/rest_api_usage/rest_requests/#media-types), like with the request `Accept` and `Content-Type` headers. For example, the first following request without an `Accept` header returns a default format indicated in the response `Content-Type` header, while the second request shows that the response is in the requested format. ```http GET /content/objects/52 HTTP/1.1 ``` ```http HTTP/1.1 200 OK Content-Type: application/vnd.ibexa.api.ContentInfo+xml ``` ```http GET /content/objects/52 HTTP/1.1 Accept: application/vnd.ibexa.api.Content+json ``` ```http HTTP/1.1 200 OK Content-Type: application/vnd.ibexa.api.Content+json ``` ### Accept-Patch header When available, the `Accept-Patch` tells how the received item could be modified with `PATCH`. The following examples also shows that the format (XML or JSON) is adapted: ```http GET /content/objects/52 HTTP/1.1 ``` ```http HTTP/1.1 200 OK Content-Type: application/vnd.ibexa.api.ContentInfo+xml Accept-Patch: application/vnd.ibexa.api.ContentUpdate+xml ``` ```http GET /content/objects/52 HTTP/1.1 Accept: application/vnd.ibexa.api.Content+json ``` ```http HTTP/1.1 200 OK Content-Type: application/vnd.ibexa.api.Content+json Accept-Patch: application/vnd.ibexa.api.ContentUpdate+json ``` Those example `Accept-Path` headers above indicate that the content could be modified by sending a ContentUpdateStruct in XML or JSON. ### Location header For example, [creating content](https://doc.ibexa.co/en/saas/api/rest_api/rest_api_reference/rest_api_reference.html#managing-content-create-content-type) and [getting a content item's current version](https://doc.ibexa.co/en/saas/api/rest_api/rest_api_reference/rest_api_reference.html#tag/Objects/operation/api_contentobjects_contentIdcurrentversion_get) both send a `Location` header to provide you with the requested resource's ID. Those particular headers generally match a specific list of HTTP response codes. `Location` is mainly sent alongside `201 Created`, `301 Moved permanently`, `307 Temporary redirect responses`. In the following example, the content item's remote ID 34720ff636e1d4ce512f762dc638e4ac corresponds to the ID 52: ```http GET /content/objects?remoteId=34720ff636e1d4ce512f762dc638e4ac" HTTP/1.1 ``` ```http HTTP/1.1 307 Temporary Redirect Location: /content/objects/52 ``` In the following example, an erroneous slash has been added to demonstrate the 301 case: ```http GET /content/objects?remoteId=34720ff636e1d4ce512f762dc638e4ac" HTTP/1.1 ``` ```http HTTP/1.1 301 Moved Permanently Location: /content/objects?remoteId=34720ff636e1d4ce512f762dc638e4ac ``` cURL can follow those redirections. On CLI, there is the `--location` option (or its shorthand `-L`). In PHP, you can achieve the same effect with `CURLOPT_FOLLOWLOCATION`. The following command-line example follows the two redirections above and the `Accept` header is propagated: ```bash curl --head --location --header "Accept: application/vnd.ibexa.api.Content+json" "https://api.example.com/api/ibexa/v2/content/objects/?remoteId=34720ff636e1d4ce512f762dc638e4ac" ``` ```http HTTP/1.1 200 OK Content-Type: application/vnd.ibexa.api.Content+json ``` ### Cross-origin [Cross-Origin Resource Sharing (CORS)](https://en.wikipedia.org/wiki/Cross-origin_resource_sharing) can allow the REST API to be reached from a page on another domain. For more information about CORS, see [WHATWG's CORS Protocol specification](https://fetch.spec.whatwg.org/#cors-protocol) and [Overview of CORS on developer.mozilla.org](https://developer.mozilla.org/en-US/docs/Web/HTTP/Guides/CORS). CORS support is provided by the third party [nelmio/cors-bundle](https://packagist.org/packages/nelmio/cors-bundle). You can read more about it in [NelmioCorsBundle's README](https://github.com/nelmio/NelmioCorsBundle/blob/master/README.md). Using CORS isn't limited to REST API resources and can be used for any resource of the platform. The CORS bundle adds an `Access-Control-Allow-Origin` header to the response. #### Configuration Allowed origins are controlled by the `CORS_ALLOW_ORIGIN` setting, which takes a regular expression matching the domains that may call the API, for example `^https?://example\.com`. For the full set of options, such as several domains, filtering on URIs, or restricting the allowed methods, see the [NelmioCorsBundle configuration documentation](https://symfony.com/bundles/NelmioCorsBundle/current/index.html#configuration). ## Response body The Response body is often a serialization in XML or JSON of an object as it could be retrieved using the Public PHP API. For example, the resource `/content/objects/52` with the `Accept: application/vnd.ibexa.api.ContentInfo+xml` header returns a serialized version of a ContentInfo object. ```bash curl https://api.example.com/content/objects/52 --header 'Accept: application/vnd.ibexa.api.ContentInfo+xml'; ``` ```xml Ibexa Digital Experience Platform Ibexa Digital Experience Platform
2015-09-17T09:22:23+00:00 2015-09-17T09:22:23+00:00 eng-GB 1 true false PUBLISHED ``` The response body XML can contain two types of nodes: - Final nodes that fully give an information as a scalar value - Reference nodes which link to `href` where a new resource of a given `media-type` can be explored if you need to know more # Testing REST API > For the complete documentation index, see [llms.txt](https://doc.ibexa.co/en/saas/llms.txt). You can test operations in the REST API by using command line, PHP or JS code. A standard web browser isn't sufficient to fully test the API. You can, however, try opening the root resource with it, using the session authentication: `http://example.com/api/ibexa/v2/`. Depending on how your browser understands XML, it either downloads the XML file, or opens it in the browser. The following examples show how to interrogate the REST API with cURL, PHP or JS. ## CLI For examples of using `curl`, refer to: - [REST root](https://doc.ibexa.co/en/saas/api/rest_api/rest_api_usage/rest_api_usage/#rest-root) - [OPTIONS method](https://doc.ibexa.co/en/saas/api/rest_api/rest_api_usage/rest_requests/#options-method) - [Location header](https://doc.ibexa.co/en/saas/api/rest_api/rest_api_usage/rest_responses/#location-header) - [ContentInfo body](https://doc.ibexa.co/en/saas/api/rest_api/rest_api_usage/rest_responses/#response-body) ## JS The REST API can help you implement JavaScript / AJAX interaction. The following example of an AJAX call retrieves `ContentInfo` (that is, metadata) for a content item. To test it, copy-paste this code into your browser console alongside a page from your website (to share the domain): **Fetch API** ```javascript const resource = '/api/ibexa/v2/content/objects/52'; fetch(resource, { headers: {'Accept': 'application/vnd.ibexa.api.ContentInfo+json'}, }).then((response) => { console.log(...response.headers); return response.json(); }).then((data) => { console.log(data); }); ``` **XMLHttpRequest** ```javascript const resource = '/api/ibexa/v2/content/objects/52'; const request = new XMLHttpRequest(); request.open('GET', resource, true); request.setRequestHeader('Accept', 'application/vnd.ibexa.api.ContentInfo+json'); request.onload = function () { console.log(request.getAllResponseHeaders(), JSON.parse(request.responseText)); }; request.send(); ``` On a freshly installed Cohesivo, `52` is the Content ID of the home page. If necessary, substitute `52` with the Content ID of an item from your database. You can edit the `resource` URI to address another domain, but [cross-origin requests](https://doc.ibexa.co/en/saas/api/rest_api/rest_api_usage/rest_responses/#cross-origin) must be allowed first. # REST API authentication > For the complete documentation index, see [llms.txt](https://doc.ibexa.co/en/saas/llms.txt). To authenticate REST API communication you can use session (default), JWT, basic, OAuth and client certificate (SSL) authentication. This page refers to [REST API reference](https://doc.ibexa.co/en/saas/api/rest_api/rest_api_reference/rest_api_reference.html), where you can find detailed information about REST API resources and endpoints. Five authentication methods are currently supported: session (default), JWT, basic, OAuth, and client certificate (SSL). You can only use one of those methods at the same time. Using HTTPS for authenticated traffic is highly recommended. For other security related subjects, see: - [Cross-origin requests](https://doc.ibexa.co/en/saas/api/rest_api/rest_api_usage/rest_responses/#cross-origin) - [`access_control`](https://symfony.com/doc/7.4/security/access_control.html) > **Caution: SiteAccess login** > > The anonymous user is used to perform authentification requests. Therefore, the "Anonymous" role must have `user/login` permission on the SiteAccess that matches the REST domain or is passed through the [`X-Siteaccess` header](https://doc.ibexa.co/en/saas/api/rest_api/rest_api_usage/rest_requests/#siteaccess). ## Session-based authentication This authentication method requires a session cookie to be sent with each request. If you use this authentication method with a web browser, this session cookie is automatically available as soon as your visitor logs in. Add it as a cookie to your REST requests to authenticate the user. Sessions are created to re-authenticate the user only (and perform authorization), not to hold session state in the service. Because of that, you can use this method as supporting AJAX-based applications even if it violates the principles of RESTful services. ### Configuration Session is the default method and is already enabled, so no configuration required. Enabling any other method disables session. ### Usage examples You can create a session for a visitor even if they're not logged in by sending the **`POST`** request to `/user/sessions`. To log out, use the **`DELETE`** request on the same resource. #### Establishing session ##### Creating session To create a session, execute the following REST request: **XML** ```http POST /user/sessions HTTP/1.1 Host: www.example.net Accept: application/vnd.ibexa.api.Session+xml Content-Type: application/vnd.ibexa.api.SessionInput+xml ``` ```xml admin publish ``` ```http HTTP/1.1 201 Created Location: /user/sessions/go327ij2cirpo59pb6rrv2a4el2 Set-Cookie: IBX_SESSION_ID98defd6ee70dfb1dea416=go327ij2cirpo59pb6rrv2a4el2; domain=.example.net; path=/; expires=Wed, 13-Jan-2021 22:23:01 GMT; HttpOnly Content-Type: application/vnd.ibexa.api.Session+xml ``` ```xml IBX_SESSION_ID98defd6ee70dfb1dea416 go327ij2cirpo59pb6rrv2a4el2 23lk.neri34ijajedfw39orj-3j93 ``` **JSON** ```http POST /user/sessions HTTP/1.1 Host: www.example.net Accept: application/vnd.ibexa.api.Session+json Content-Type: application/vnd.ibexa.api.SessionInput+json ``` ```json { "SessionInput": { "login": "admin", "password": "publish" } } ``` ```http HTTP/1.1 201 Created Location: /user/sessions/go327ij2cirpo59pb6rrv2a4el2 Set-Cookie: IBX_SESSION_ID98defd6ee70dfb1dea416=go327ij2cirpo59pb6rrv2a4el2; domain=.example.net; path=/; expires=Wed, 13-Jan-2021 22:23:01 GMT; HttpOnly Content-Type: application/vnd.ibexa.api.Session+xml ``` ```json { "Session": { "_media-type": "application\/vnd.ibexa.api.Session+json", "_href": "\/api\/ibexa\/v2\/user\/sessions\/jg1nhinvepsb9ivd10hbjbdp4l", "name": "IBX_SESSION_ID98defd6ee70dfb1dea416", "identifier": "go327ij2cirpo59pb6rrv2a4el2", "csrfToken": "23lk.neri34ijajedfw39orj-3j93", "User": { "_media-type": "application\/vnd.ibexa.api.User+json", "_href": "\/api\/ibexa\/v2\/user\/users\/14" } } } ``` ##### Logging in with active session Logging in is similar to session creation, with one important detail: the CSRF token obtained in the previous step is added to the new request through the `X-CSRF-Token` header. **XML** ```http POST /user/sessions HTTP/1.1 Host: www.example.net Accept: application/vnd.ibexa.api.Session+xml Content-Type: application/vnd.ibexa.api.SessionInput+xml Cookie: IBX_SESSION_ID98defd6ee70dfb1dea416=go327ij2cirpo59pb6rrv2a4el2 X-CSRF-Token: 23lk.neri34ijajedfw39orj-3j93 ``` ```xml admin publish ``` ```http HTTP/1.1 200 OK Content-Type: application/vnd.ibexa.api.Session+xml ``` ```xml IBX_SESSION_ID98defd6ee70dfb1dea416 go327ij2cirpo59pb6rrv2a4el2 23lk.neri34ijajedfw39orj-3j93 ``` **JSON** ```http POST /user/sessions HTTP/1.1 Host: www.example.net Accept: application/vnd.ibexa.api.Session+json Content-Type: application/vnd.ibexa.api.SessionInput+json Cookie: IBX_SESSION_ID98defd6ee70dfb1dea416=go327ij2cirpo59pb6rrv2a4el2 X-CSRF-Token: 23lk.neri34ijajedfw39orj-3j93 ``` ```xml { "SessionInput": { "login": "admin", "password": "publish" } } ``` ```http HTTP/1.1 200 OK Content-Type: application/vnd.ibexa.api.Session+json ``` ```xml { "Session": { "_media-type": "application\/vnd.ibexa.api.Session+json", "_href": "\/api\/ibexa\/v2\/user\/sessions\/jg1nhinvepsb9ivd10hbjbdp4l", "name": "IBX_SESSION_ID98defd6ee70dfb1dea416", "identifier": "go327ij2cirpo59pb6rrv2a4el2", "csrfToken": "23lk.neri34ijajedfw39orj-3j93", "User": { "_media-type": "application\/vnd.ibexa.api.User+json", "_href": "\/api\/ibexa\/v2\/user\/users\/14" } } } ``` #### Using session ##### Session cookie You can now add the previously set cookie to requests to be executed with the logged-in user. ```http GET /content/locations/1/5 HTTP/1.1 Host: www.example.net Accept: Accept: application/vnd.ibexa.api.Location+xml Cookie: IBX_SESSION_ID98defd6ee70dfb1dea416=go327ij2cirpo59pb6rrv2a4el2 ``` ##### CSRF token It can be important to keep the CSRF token (`csrfToken`) for the duration of the session, because you must send this token in every request that uses [unsafe HTTP methods](https://doc.ibexa.co/en/saas/api/rest_api/rest_api_usage/rest_requests/#request-method) (others than the safe GET or HEAD or OPTIONS) when a session has been established. It should be sent with an `X-CSRF-Token` header. Only three built-in routes can accept unsafe methods without CSRF, the sessions routes starting with `/user/sessions` to create, refresh or delete a session. ```http DELETE /content/types/32 HTTP/1.1 Host: www.example.net Cookie: IBX_SESSION_ID98defd6ee70dfb1dea416=go327ij2cirpo59pb6rrv2a4el2 X-CSRF-Token: 23lk.neri34ijajedfw39orj-3j93 ``` If an unsafe request is missing the CSRF token, or the token has incorrect value, an error is returned: `401 Unauthorized`. ##### Rich client application security concerns The purpose of CSRF protection is to prevent users from accidentally running harmful operations by being tricked into executing an HTTP(S) request against a web applications they're logged into. In browsers this action is blocked by lack of CSRF token. However, if you develop a rich client application (for example, JavaScript, JAVA, iOS, or Android), that is: - Registering itself as a protocol handler: - Exposes unsafe methods in any way - Authenticates using either: - Session-based authentication - "Client side session" by remembering user login/password Then, you have to make sure to confirm with the user if they want to perform an unsafe operation. Example: A rich JavaScript/web application uses `navigator.registerProtocolHandler()` to register "web+ez:" links to go against REST API. It uses a session-based authentication, and it's in widespread use across the net, or/and it's used by everyone within a company. A person with minimal insight into this application and the company can easily send out the following link to all employees in that company in email: `latest reports`. #### Logging out from session To log out is to `DELETE` the session using its ID (like in the cookie). As this is an unsafe method, the CSRF token must be presented. ```http DELETE /user/sessions/go327ij2cirpo59pb6rrv2a4el2 HTTP/1.1 Host: www.example.net Cookie: IBX_SESSION_ID98defd6ee70dfb1dea416=go327ij2cirpo59pb6rrv2a4el2 X-CSRF-Token: 23lk.neri34ijajedfw39orj-3j93 ``` ## JWT authentication JWT authentication is available for the REST API. ### Usage example You can get the JWT token through the following request: ```http POST /user/token/jwt HTTP/1.1 Host: Accept: application/vnd.ibexa.api.JWT+json Content-Type: application/vnd.ibexa.api.JWTInput+json ``` Provide the username and password in the request body: ```json { "JWTInput": { "username": "admin", "password": "publish" } } ``` If credentials are valid, the server response contains a token: ```json { "JWT": { "_media-type": "application/vnd.ibexa.api.JWT+xml", "_token": "eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9…-QBE4-6eKNjg" } } ``` You can then use this token in your request instead of username and password. ```http GET /content/locations/1/5/children Host: Authorization: Bearer eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9…-QBE4-6eKNjg Accept: application/vnd.ibexa.api.LocationList+json ``` #### JWT token obtained through REST documentation To obtain a JWT token with REST, you can use the live API documentation that is available on your development installation. This documentation is only accessible when `kernel.debug` is set to `true`, similarly to a development environment. - open REST API live doc (for example at `http://localhost/api/ibexa/v2/doc`) - go to **User Token** section's **POST /user/token/jwt** resource (for example, at `http://localhost/api/ibexa/v2/doc#/User%20Token/api_usertokenjwt_post`) - click the **Try it out** button - fill in the following adapted payload with the user credentials - click the **Execute** button to get a token ![REST API live documentation with a JWTInput payload](https://doc.ibexa.co/en/saas/api/rest_api/img/jwt-rest-doc-request.png "REST doc JWT token request") ![REST API live documentation with a JWTInput payload](https://doc.ibexa.co/en/saas/api/rest_api/img/jwt-rest-doc-response.png "REST doc JWT token response") ## HTTP basic authentication For more information, see [HTTP Authentication: Basic and Digest Access Authentication](https://datatracker.ietf.org/doc/html/rfc2617). ### Configuration If the installation has a dedicated host for REST, you can enable HTTP basic authentication only on this host by setting a firewall like in the following example before the `ibexa_front` one: ```yaml security: firewalls: # ... ibexa_rest: host: ^api\.example\.com$ http_basic: realm: Cohesivo REST API #ibexa_front: # ... ``` > **Caution: Back office uses REST API** > > Back office uses the REST API too (for some parts like the Location tree or the Calendar) on its own domain. > > - If the back office SiteAccess matches `//admin.example.com` (through `Map\Host`, `HostElement` or `HostText`), it calls the REST API under `//admin.example.com/api/ibexa/v2`; > - If the back office SiteAccess matches `//localhost/admin` (through `URIElement`, `Map\URI` or `Regex\URI`), it calls the REST API under `//localhost/api/ibexa/v2` because SiteAccess matching with REST isn't enabled at URL level. > > If you enable basic authentication for `pattern: ^/api/ibexa/v2` to use it in your front office across both production and development environments, your development environment's back office cannot work correctly. This back office tries to access REST through the same URL as the front office. Even when logged in back office and using the [X-SiteAccess header](https://doc.ibexa.co/en/saas/api/rest_api/rest_api_usage/rest_requests/#siteaccess), the firewall blocks access to REST as you're not logged through basic authentification. Therefore, some back office features don't work. > > If basic authentication is used only for REST API, it's better to have a dedicated domain even on a development environment. For example, map an `api.localhost` in your `hosts` file and set the firewall for `host: ^api\.(example\.com|localhost)$`. ### Usage example Basic authentication requires the username and password to be sent *(username:password)*, base64 encoded, with each request. For details, see [RFC 2617](https://datatracker.ietf.org/doc/html/rfc2617). Most HTTP client libraries and REST libraries support this method. [Creating content with binary attachments](https://doc.ibexa.co/en/saas/api/rest_api/rest_api_usage/rest_requests/#creating-content-with-binary-attachments) is an example of using basic authentication with [cURL](https://www.php.net/manual/en/book.curl.php) and its `CURLOPT_USERPWD`. See the following raw HTTP request with basic authentication example: ```http GET / HTTP/1.1 Host: api.example.com Accept: application/vnd.ibexa.api.Root+json Authorization: Basic QWxhZGRpbjpvcGVuIHNlc2FtZQ== ``` ## OAuth For more information, see [OAuth 2.0 protocol for authorization](https://oauth.net/2/). ## SSL client authentication The REST API provides authentication of a user by a subject in a client certificate delivered by the web server configured as SSL endpoint. # Administration # Administration > For the complete documentation index, see [llms.txt](https://doc.ibexa.co/en/saas/llms.txt). Administer and configure your Cohesivo installation. Administer and configure your Cohesivo installation. - [Admin panel](https://ez-systems-developer-documentation--3403.com.readthedocs.build/en/3403/administration/admin_panel/admin_panel/): Cohesivo back office contains managements options for permissions, users, languages, content types, and system information. - [Configuration](https://ez-systems-developer-documentation--3403.com.readthedocs.build/en/3403/administration/configuration/configuration/): In Cohesivo you store and manage configuration in project files, typically in YAML format. - [Back office](https://ez-systems-developer-documentation--3403.com.readthedocs.build/en/3403/administration/back_office/back_office/): Back office holds the administrator and editor interface and allows creating, publishing and managing content, users, settings, and more. # Configure default dashboard > For the complete documentation index, see [llms.txt](https://doc.ibexa.co/en/saas/llms.txt). Configure default dashboard. You can configure default dashboard under the `ibexa.system..admin_group` [configuration key](https://doc.ibexa.co/en/saas/administration/configuration/configuration/#configuration-files). The following example configuration defines default dashboard: ```yaml ibexa: system: admin_group: dashboard: container_remote_id: dashboard_container default_dashboard_remote_id: default_dashboard users_container_remote_id: user_dashboards predefined_container_remote_id: predefined_dashboards section_identifier: dashboard content_type_identifier: dashboard_landing_page container_content_type_identifier: folder ``` Configuration can be set per [SiteAccess](https://doc.ibexa.co/en/saas/multisite/multisite_configuration/#siteaccess-configuration) or [SiteAccess group](https://doc.ibexa.co/en/saas/multisite/multisite_configuration/#siteaccess-groups). All the settings in the configuration are reflected in the back office. ## Container remote ID Defines starting location container for all the dashboards, including customized and predefined ones. You can see it in the **Admin** panel, **Dashboards** section, **Dashboards** folder in the content tree. In the **Technical details** tab, it is defined as **Location remote ID**. ![Container remote ID](https://doc.ibexa.co/en/saas/administration/img/dashboard_container_remote_id.png) ## Default dashboard remote ID Specifies default predefined dashboard. All the users can see this dashboard as a starting dashboard in the back office. You can see it in the **Admin** panel, **Dashboards** section, **Default dashboard** folder inside of **Predefined dashboards** container in the content tree. In the **Technical details** tab, it's defined as **Location remote ID**. ## Users container remote ID Defines a container for users folders, which contain all customized dashboards. You can see it in the **Admin** panel, **Dashboards** section, **User dashboards** folder inside of main **Dashboards** container in the content tree. In the **Technical details** tab, it's defined as **Location remote ID**. ## Predefined container remote ID Defines a container that contains all predefined dashboards created by Administrator. You can see it in the **Admin** panel, **Dashboards** section, **Predefined dashboards** folder inside of main **Dashboards** container in the content tree. In the **Technical details** tab, it's defined as **Location remote ID**. ## Section identifier Specifies the name of the [Section](https://doc.ibexa.co/en/saas/administration/content_organization/sections/index.md). ## Content type identifier It is an identifier that represents dashboard content type. You can find it in the **Admin** panel, **Dashboard content Type** section, **View/Global properties** tab. ![Content type identifier](https://doc.ibexa.co/en/saas/administration/img/dashboard_content_type_identifier.png) ## Container content type identifier Determines the content type identifier of the container for dashboards and lets you create additional structure for the predefined dashboards. By default all the dashboards containers are set as a folders. ![Container content type](https://doc.ibexa.co/en/saas/administration/img/dashboard_container_type.png) If the `folder` content type doesn't exist or is modified, you can use another one, for example: ```yaml ibexa: system: default: dashboard: container_content_type_identifier: user_dashboard_container ``` The custom content type should be a container and needs to have a field type with `name` identifier. # Admin panel > For the complete documentation index, see [llms.txt](https://doc.ibexa.co/en/saas/llms.txt). Cohesivo back office contains managements options for permissions, users, languages, content types, and system information. Once you set up your environment you can start your work as an administrator. You can find key tools in **Admin** panel. To access **Admin** panel, click the icon: ![Admin panel Icon](https://doc.ibexa.co/en/saas/administration/img/admin_panel_icon.png). - [Users](https://ez-systems-developer-documentation--3403.com.readthedocs.build/en/3403/administration/admin_panel/users_admin_panel/): You can access all users and user groups in the Users tab. - [Roles](https://ez-systems-developer-documentation--3403.com.readthedocs.build/en/3403/administration/admin_panel/roles_admin_panel/): To give users an access to your website you need to assign them roles in the Admin Panel. - [URL Management](https://ez-systems-developer-documentation--3403.com.readthedocs.build/en/3403/administration/admin_panel/url_management_admin_panel/): URL Management lets you manage external URL addresses and URL wildcards. - [Languages](https://ez-systems-developer-documentation--3403.com.readthedocs.build/en/3403/administration/admin_panel/languages_admin_panel/): Cohesivo offers the ability to create multiple translations of your website. - [Segments](https://ez-systems-developer-documentation--3403.com.readthedocs.build/en/3403/administration/admin_panel/segments_admin_panel/): You can use segments to display specific content to specific users. - [Corporate](https://ez-systems-developer-documentation--3403.com.readthedocs.build/en/3403/administration/admin_panel/corporate_admin_panel/): You can manage companies profiles in the Admin Panel. - [Workflow](https://ez-systems-developer-documentation--3403.com.readthedocs.build/en/3403/administration/admin_panel/workflow_admin_panel/): The workflow functionality passes a content item version through a series of stages. - [System Information](https://ez-systems-developer-documentation--3403.com.readthedocs.build/en/3403/administration/admin_panel/system_information_admin_panel/): System information provides basic system information such as versions of all installed packages. # Users > For the complete documentation index, see [llms.txt](https://doc.ibexa.co/en/saas/llms.txt). You can access all users and user groups in the Users tab. [Users](https://doc.ibexa.co/en/saas/users/users/index.md) in Cohesivo are treated the same way as content items. They're organized in groups such as *Guests*, *Editors*, *Anonymous*, which makes it easier to manage them and their permissions. You can access all users and user groups in the **Admin** panel by selecting **Users**. ![Users and user groups](https://doc.ibexa.co/en/saas/administration/img/admin_panel_users.png "Users and user groups") > **Caution: Caution** > > Be careful not to delete an existing user account. If you do this, content created by this user can be broken and the application can face malfunction. # Roles > For the complete documentation index, see [llms.txt](https://doc.ibexa.co/en/saas/llms.txt). To give users an access to your website you need to assign them roles in the Admin Panel. To give users an access to your website you need to assign them roles in the **Admin** panel. ![Roles](https://doc.ibexa.co/en/saas/administration/img/admin_panel_roles.png "Roles") Each role consists of: ## Policies ![Policies](https://doc.ibexa.co/en/saas/administration/img/admin_panel_policies.png "Policies") Policies are the rules that give users access to different function in a module. You can restrict what user can do with limitations. The available limitations depend on the chosen policy. When policy has more than one limitation, all of them have to apply. See [example use case](https://doc.ibexa.co/en/saas/permissions/permission_use_cases/#restrict-editing-to-part-of-the-tree). > **Note: Note** > > Limitation specifies what a user can do, not what they can't do. A `Location` limitation, for example, gives the user access to content with a specific location, not prohibits it. > > For more information, see [Limitation reference](https://doc.ibexa.co/en/saas/permissions/limitation_reference/index.md). ## Assignments ![Assignments](https://doc.ibexa.co/en/saas/administration/img/admin_panel_assignments.png "Assignments") After you created all policies, you can assign the role to users and/or user groups with possible additional limitations. Every user or user group can have multiple roles. A user can also belong to many groups, for example, Administrators, Editors, Subscribers. Best practice is to avoid assigning roles to users directly. Model your content (for example, content types, sections, or locations) in a way that can be accessed by generic roles. That way system is be more secure and easier to manage. This approach also improves performance. Role assignments and policies are taken into account during search/load queries. For more information, see [Permissions overview](https://doc.ibexa.co/en/saas/permissions/permissions/index.md) and [Permission use cases](https://doc.ibexa.co/en/saas/permissions/permission_use_cases/index.md). # URL Management > For the complete documentation index, see [llms.txt](https://doc.ibexa.co/en/saas/llms.txt). URL Management lets you manage external URL addresses and URL wildcards. You can manage external URL addresses and URL wildcards in the **Admin** panel. Configure URL aliases to have human-readable URL addresses throughout your system. For more information, see [URL management](https://doc.ibexa.co/en/saas/content_management/url_management/url_management/index.md). ![URL Management](https://doc.ibexa.co/en/saas/administration/img/admin_panel_url_management.png "URL Management") # Languages > For the complete documentation index, see [llms.txt](https://doc.ibexa.co/en/saas/llms.txt). Cohesivo offers the ability to create multiple translations of your website. Cohesivo offers the ability to create multiple translations of your website. Which version is shown to a visitor depends on the way your installation is set up. You can add a new language version for the website in the [Admin Panel](https://doc.ibexa.co/en/saas/administration/admin_panel/admin_panel/index.md) in the **Languages** tab. Every new language must have a name and a language code, written in the `xxx-XX` format, for example `eng-GB`. ![Languages](https://doc.ibexa.co/en/saas/administration/img/admin_panel_languages.png "Languages") The multilanguage system operates based on a global translation list that contains all languages available in the installation. After adding a language you may have to reload the application to be able to use it. Depending on your set up, additional configuration may be necessary for the new language to work properly, especially with SiteAccesses. See [Languages](https://doc.ibexa.co/en/saas/multisite/languages/languages/index.md) for further information. # Segments > For the complete documentation index, see [llms.txt](https://doc.ibexa.co/en/saas/llms.txt). You can use segments to display specific content to specific users. You can use segments to display specific content to specific [users](https://doc.ibexa.co/en/saas/users/users/index.md). They're used out of the box in the Targeting block in the page. You can collect segments in segment groups: ![Segment groups](https://doc.ibexa.co/en/saas/administration/img/admin_panel_segment_groups.png) Each segment group can contain segments that you can target content for. ![Segment](https://doc.ibexa.co/en/saas/administration/img/admin_panel_segment.png) You can assign users to segments over the REST API. # Corporate > For the complete documentation index, see [llms.txt](https://doc.ibexa.co/en/saas/llms.txt). You can manage companies profiles in the Admin Panel. You can manage companies profiles in the **Admin** panel. There, in the **Corporate** section, you can find basic information about existing companies, for example, details, versions, locations, translations, a list of members, billing addresses, and technical details regarding the organization, such as visibility, IDs, or relations. ![Corporate section](https://doc.ibexa.co/en/saas/administration/img/admin_panel_corporate.png "Corporate section") For more information, see [Customer management](https://doc.ibexa.co/projects/userguide/en/6.0/customer_management/manage_customers/). # Workflow > For the complete documentation index, see [llms.txt](https://doc.ibexa.co/en/saas/llms.txt). The workflow functionality passes a content item version through a series of stages. The workflow functionality passes a content item version through a series of stages. Each workflow consists of stages and transitions between them. For more information, see [Workflow](https://doc.ibexa.co/en/saas/content_management/workflow/workflow/index.md). ![Workflow](https://doc.ibexa.co/en/saas/administration/img/admin_panel_workflow.png "Workflow") # System Information > For the complete documentation index, see [llms.txt](https://doc.ibexa.co/en/saas/llms.txt). System information provides basic system information such as versions of all installed packages. The System Information panel in the back office is sourced in the [`ibexa/system-info` repository](https://github.com/ibexa/system-info). There you can also find basic system information such as versions of all installed packages. ![System Information](https://doc.ibexa.co/en/saas/administration/img/admin_panel_system_info.png "System Information") # Sections > For the complete documentation index, see [llms.txt](https://doc.ibexa.co/en/saas/llms.txt). Sections are used to divide content items in the tree. Sections are used to divide content items in the tree into groups that are more manageable by content editors. Division into sections allows you, among others, to set [permissions](https://doc.ibexa.co/en/saas/permissions/permission_overview/index.md) for only a part of the tree. ![Sections screen](https://doc.ibexa.co/en/saas/administration/img/admin_panel_sections.png "Sections screen") Technically, a section is a number, a name, and an identifier. Content items are placed in sections by being assigned the section ID. One item can be in only one section. When a new content item is created, its section ID is set to the default section (which is usually Standard). When the item is published it is assigned to the same section as its parent. Because content must always be in a section, unassigning happens by choosing a different section to move it into. If a content item has multiple location assignments then it is always the section ID of the item referenced by the parent of the main location that is used. In addition, if the main location of a content item with multiple location assignments is changed then the section ID of that item is updated. When content is moved to a different location, the item itself and all of its subtree are assigned to the section of the new location. It works only for copy and move. Assigning a new section to a parent content item doesn't affect the subtree, meaning that subtree cannot currently be updated this way. Sections can only be removed if no content items are assigned to them. Even then, it should be done carefully. When a section is deleted, it's only its definition itself that is removed. Other references to the section remain and thus the system most likely loses consistency. > **Caution: Caution** > > Removing sections may corrupt permission settings, template output and other things in the system. Section ID numbers aren't recycled. If a section is removed, its ID number cannot be reused when a new section is created. # Content types > For the complete documentation index, see [llms.txt](https://doc.ibexa.co/en/saas/llms.txt). A content type is a base for new content items. A content type is a base for new content items. It defines what fields are available in the content item. ![Content types](https://doc.ibexa.co/en/saas/administration/img/admin_panel_content_types.png "Content types") For example, a new content type called *Article* can have fields such as title, author, body, or image. Based on this content type, you can create any number of content items. Content types are organized into groups. ![Content type groups](https://doc.ibexa.co/en/saas/administration/img/admin_panel_content_type_groups.png "Content type groups") You can add your own groups here to keep your content types in better order. For a full tutorial, see [Add a content type](https://doc.ibexa.co/en/saas/getting_started/first_steps/#add-a-content-type) or follow [User Documentation](https://doc.ibexa.co/projects/userguide/en/6.0/content_management/create_edit_content_types/). For a detailed overview of the content model, see [Content model overview](https://doc.ibexa.co/en/saas/content_management/content_model/index.md). ## Content type metadata Each content type is characterized by a set of metadata which define the general behavior of its instances: **Name** – a user-friendly name that describes the content type. This name is used in the interface, but not internally by the system. It can consist of letters, digits, spaces, and special characters (it's mandatory and the maximum length is 255 characters). > **Note: Note** > > Even if your content type defines a field intended as a name for the content item (for example, a title of an article or product name), don't confuse it with this Name, which is a piece of metadata, not a field. **Identifier** – an identifier for internal use in configuration, for example, files, templates, or PHP code. It must be unique, can only contain lowercase letters, digits, and underscores (it's mandatory and the maximum length is 50 characters). **Description** – a detailed description of the content type (optional). **Content name pattern** – a pattern that defines what name a new content item based on this content type gets. The pattern usually consists of field identifiers that tell the system which fields it should use when generating the name of a content item. Each field identifier has to be surrounded with angle brackets. Text outside the angle brackets is included literally. If no pattern is provided, the system automatically uses the first field (optional). **URL alias name pattern** – a pattern which controls how the virtual URLs of the locations are generated when content items are created based on this content type. Only the last part of the virtual URL is affected. The pattern works in the same way as the content name pattern. Text outside the angle brackets is converted with the selected method of URL transformation. If no pattern is provided, the system automatically uses the name of the content item itself (optional). > **Tip: Changing URL alias and content name patterns** > > If you change the content name pattern or the URL alias name pattern, existing content items cannot be modified automatically. The new pattern is only applied after you modify the content item and save a new version. > > The old URL aliases continue to redirect to the same content items. **Container** – a flag which indicates if content items based on this content type are allowed to have sub-items or not (mainly relevant for actions via the UI, not validated by every PHP API). > **Note: Note** > > This flag was added for convenience and only affects the interface. In other words, it doesn't control any actual low-level logic, it simply controls the way the graphical user interface behaves. **Sort children by default by** – rule for sorting sub-items. If the instances of this content type can serve as containers, their children are sorted according to what is selected here. **Sort children by default in order** – another rule for sorting sub-items. This decides the sort order for the criterion chosen above. **Make content available even with missing translations** – a flag which indicates if content items of this content type should be available even without a corresponding language version. See [Content availability](https://doc.ibexa.co/en/saas/content_management/content_availability/index.md). ![Creating a new content type](https://doc.ibexa.co/en/saas/content_management/img/admin_panel_new_content_type.png) ## Field definitions Aside from the metadata, a content type may contain any number of field definitions (but has to contain at least one). They determine what fields of what field types are included in all content items based on this content type. ![Field definitions](https://doc.ibexa.co/en/saas/administration/img/admin_panel_field_definitions.png) ![Diagram of an example content type](https://doc.ibexa.co/en/saas/content_management/img/content_model_type_diagram.png) > **Note: Note** > > You can assign each field defined in a content type to a group by selecting one of the groups in the Category drop-down. > **Caution: Caution** > > In case of content types containing many field types you should be aware of possible memory-related issues with publishing/editing. They're caused by the limitation of how many `$_POST` input variables can be accepted. > > The easiest way to fix them is by increasing the `max_input_vars` value in the `php.ini` configuration file. This solution isn't universally recommended and you're proceeding on your own risk. > > Setting the limit inappropriately may damage your project or cause other issues. You may also experience performance problems with such large content types, in particular when you have many content items. If you're experincing too many issues, consider rearranging your project to avoid them. ## Modifying content types A content type and its field definitions can be modified after creation, even if there are already content items based on it in the system. When a content type is modified, each of its instances are changed as well. If a new field definition is added to a content type, this field appears (empty) in every relevant content item. If a field definition is deleted from the content type, all the corresponding fields are removed from content items of this type. ## Removing content types System content types are by default used for the File Uploads and removing them can cause errors. If you decide to remove a `file` or `image` content type, or change their identifiers, you need to change the configuration, so it reflects the available content types. Example configuration: ```yaml parameters: ibexa.multifile_upload.location.default_mappings: # Image - mime_types: - image/jpeg - image/jpg - image/pjpeg - image/pjpg - image/png - image/bmp - image/gif - image/tiff - image/x-icon - image/webp content_type_identifier: custom_image_contenttype content_field_identifier: image name_field_identifier: name # File - mime_types: - image/svg+xml - application/msword - application/vnd.openxmlformats-officedocument.wordprocessingml.document - application/vnd.ms-excel - application/vnd.openxmlformats-officedocument.spreadsheetml.sheet - application/vnd.ms-powerpoint - application/vnd.openxmlformats-officedocument.presentationml.presentation - application/pdf content_type_identifier: custom_file_contenttype content_field_identifier: file name_field_identifier: name ibexa.multifile_upload.fallback_content_type: content_type_identifier: custom_file_contenttype content_field_identifier: file name_field_identifier: name ``` # Object states > For the complete documentation index, see [llms.txt](https://doc.ibexa.co/en/saas/llms.txt). Object states are user-defined states that can be assigned to content items. Object states are user-defined states that can be assigned to content items. They're contained in groups. ![Object State group](https://doc.ibexa.co/en/saas/administration/img/admin_panel_object_state_groups.png "Object state group") If a state group contains any states, each content item is automatically assigned a state from this group. You can assign states to content in the back office in the content item's **Technical details** tab. ![Assigning an object state to a content item](https://doc.ibexa.co/en/saas/administration/img/assigning_an_object_state.png "Assigning an object state to a content item") By default, Cohesivo contains one object state group: **Lock**, with states **Locked** and **Not locked**. ![Lock Object state](https://doc.ibexa.co/en/saas/administration/img/object_state_lock.png "Lock object state") Object states can be used in conjunction with [permissions](https://doc.ibexa.co/en/saas/permissions/permission_overview/index.md), in particular with the [object state limitation](https://doc.ibexa.co/en/saas/permissions/limitation_reference/#object-state-limitation). Their specific use cases depend on your needs and the setup of your permission system. # Configuration > For the complete documentation index, see [llms.txt](https://doc.ibexa.co/en/saas/llms.txt). In Cohesivo you store and manage configuration in project files, typically in YAML format. Cohesivo configuration is delivered by means of a number of dedicated configuration files. It contains everything from selecting the content repository to SiteAccesses to language settings. ## Configuration format The recommended configuration format is YAML. It's used by default in the kernel (and in examples throughout the documentation). However, you can also use XML or PHP formats for configuration. ## Configuration files Configuration files are located in the `config` folder. Configuration is provided per package in the `config/packages` folder, and routes are defined per package in `config/routes`. `config/packages/ibexa.yaml` contains basic configuration. It stores, among others, [SiteAccess](https://doc.ibexa.co/en/saas/multisite/multisite/index.md) information and content view config. Other configuration is provided in respective files, for example, `config/packages/ibexa_admin_ui.yaml`, `config/packages/ibexa_http_cache.yaml`. You can make configuration environment-specific by using separate folders for each environment. These files contain additional settings and point to the general (not environment-specific) configuration that is applied in other cases. > **Note: New configuration files** > > It's good practice to provide your own configuration in separate files. Any YAML files placed in the `config/packages` folder is automatically included in the system configuration. > **Tip: Tip** > > Read more about [how configuration is handled in Symfony](https://symfony.com/doc/7.4/best_practices.html#configuration). > **Caution: Special characters** > > Avoid using special characters in your configuration files. More specifically, don't use Unicode characters from the ["Other" (`C`) categories](https://en.wikipedia.org/wiki/Unicode#General_Category_property), such as control or format characters. > > Make sure your IDE displays them. > > Be careful when copy-pasting text from a word processing software or a PDF, because it might contain hidden characters like the [soft hyphen](https://en.wikipedia.org/wiki/Soft_hyphen). ## Configuration handling > **Note: Note** > > Configuration is tightly related to the [service container](https://symfony.com/doc/7.4/service_container.html). To fully understand it, you must be familiar with the service container and [its configuration](https://symfony.com/doc/7.4/service_container.html#service-container-parameters). Basic configuration handling in Cohesivo is similar to what is commonly possible with Symfony. You can define key/value pairs in your configuration files. Internally and by convention, keys follow a *dot syntax*, where the different segments follow your configuration hierarchy. Keys are usually prefixed by a *namespace* corresponding to your application. All kinds of values are accepted, including arrays and deep hashes. For configuration that is meant to be exposed to an end-user (or end-developer), it's usually a good idea to also [implement semantic configuration](https://symfony.com/doc/7.4/components/config/definition.html). Settings can also be [SiteAccess-aware](https://doc.ibexa.co/en/saas/multisite/siteaccess/siteaccess_aware_configuration/index.md), taking a different value per SiteAccess, SiteAccess group, or globally. For example: ```yaml parameters: myapp.parameter.name: someValue myapp.boolean.param: true myapp.some.hash: foo: bar an_array: [apple, banana, pear] ``` ## Configuration settings For specific configuration settings, see: - [Back office configuration](https://doc.ibexa.co/en/saas/administration/back_office/back_office_configuration/index.md) - [Multisite configuration](https://doc.ibexa.co/en/saas/multisite/multisite_configuration/index.md) - [Image variations](https://doc.ibexa.co/en/saas/content_management/images/images/#configuring-image-variations) # Dynamic configuration > For the complete documentation index, see [llms.txt](https://doc.ibexa.co/en/saas/llms.txt). Use the ConfigResolver to inject dynamic configuration into your services. ## ConfigResolver Dynamic configuration is handled by the `ConfigResolverInterface`. It exposes the `hasParameter()` and `getParameter()` methods. You can use them to check the different *scopes* available for a given *namespace* to find the appropriate parameter. To work with the ConfigResolver, your dynamic settings must have the following name format: `..parameter.name`. ```yaml parameters: # Internal configuration ibexa.site_access.config.default.content.default_ttl: 60 ibexa.site_access.config.site_group.content.default_ttl: 3600 # Here "myapp" is the namespace, followed by the SiteAccess name as the parameter scope # Parameter "my_param" will have a different value in site_group and admin_group myapp.site_group.my_param: value myapp.admin_group.my_param: another value # Defining a default value, for other SiteAccesses myapp.default.my_param: Default value ``` Inside a controller extending the `Ibexa\Core\MVC\Symfony\Controller\Controller` class, in `site_group` SiteAccess, you can use the parameters in the following way (the same applies for `hasParameter()`): > **Tip: Tip** > > To learn more about scopes, see [SiteAccess documentation](https://doc.ibexa.co/en/saas/multisite/multisite_configuration/#scope). Both `getParameter()` and `hasParameter()` can take three arguments: 1. `$paramName` - the name of the parameter 2. `$namespace` - your application namespace, `myapp` in the previous example. If null, the default namespace is used, which is `ibexa.site_access.config` by default. 3. `$scope` - a SiteAccess name. If null, the current SiteAccess is used. # Back office > For the complete documentation index, see [llms.txt](https://doc.ibexa.co/en/saas/llms.txt). Back office holds the administrator and editor interface and allows creating, publishing and managing content, users, settings, and more. The back office is the web interface where editors and administrators work with content. Additionally, it uses React-based modules that make each part of the UI extensible, and Bootstrap for styling. The interface is accessible in your browser at `http:///admin`. > **Note: String translations** - [Back office configuration](https://ez-systems-developer-documentation--3403.com.readthedocs.build/en/3403/administration/back_office/back_office_configuration/): Configure default upload locations, pagination limits, and more settings for the back office. - [Content tree](https://ez-systems-developer-documentation--3403.com.readthedocs.build/en/3403/administration/back_office/content_tree/): Configure SiteAccess, displayed content items, depth and root location for the content tree. - [Sub-items list](https://ez-systems-developer-documentation--3403.com.readthedocs.build/en/3403/administration/back_office/subitems_list/): Inject a sub-items list into your back office customizations or customize the view. - [Integrated help](https://ez-systems-developer-documentation--3403.com.readthedocs.build/en/3403/administration/back_office/integrated_help/): Integrated help provides quick access to documentation, training, and support resources. - [Product tour](https://ez-systems-developer-documentation--3403.com.readthedocs.build/en/3403/administration/back_office/product_tour/): Product tours provide interactive guided walkthroughs to help users learn Cohesivo features. # Back office configuration > For the complete documentation index, see [llms.txt](https://doc.ibexa.co/en/saas/llms.txt). Configure default upload locations, pagination limits, and more settings for the back office. ## Pagination limits Default pagination limits for different sections of the back office can be defined through respective settings in [`ezplatform_default_settings.yaml`](https://github.com/ibexa/admin-ui/blob/6.0/src/bundle/Resources/config/ezplatform_default_settings.yaml#L7). You can set the pagination limit for user settings under the `ibexa.system..pagination_user` [configuration key](https://doc.ibexa.co/en/saas/administration/configuration/configuration/#configuration-files): ```yaml ibexa: system: : pagination_user: user_settings_limit: 6 ``` You can configure the following settings to manage the pagination limits for the product catalog: ```yaml ibexa: system: : product_catalog: pagination: attribute_definitions_limit: 10 attribute_groups_limit: 10 currencies_limit: 10 customer_groups_limit: 10 customer_group_users_limit: 10 products_limit: 10 product_types_limit: 10 product_view_custom_prices_limit: 10 regions_limit: 10 catalogs_limit: 10 ``` ## Subtree operations ### Copy subtree limit Copying large subtrees can cause performance issues, so you can limit the number of content items that can be copied at once by setting the `ibexa.system..subtree_operations.copy_subtree.limit` [configuration key](https://doc.ibexa.co/en/saas/administration/configuration/configuration/#configuration-files). The limit applies only to the UI of the back office and disables the "Copy subtree" operation. The default value is `100`. You can set it to `-1` for no limit, or to `0` to completely disable copying subtrees. ### Query subtree limit When working with large content trees, counting child items or calculating subtree sizes can cause significant performance degradation due to unbounded database queries. You can limit these count operations by setting the `ibexa.system..subtree_operations.query_subtree.limit` [configuration key](https://doc.ibexa.co/en/saas/administration/configuration/configuration/#configuration-files): ```yaml ibexa: system: : subtree_operations: copy_subtree: limit: 100 query_subtree: limit: 500 ``` The default value for `query_subtree.limit` is `500`. You can set it to `-1` to disable the limit. This limit applies in some cases when the back office needs to determine if a location has children or calculate the number of items in a subtree. The limit does not affect the sub-items list, which still displays all child elements in a paginated way. When a limit is set, the query stops after finding the specified number of items instead of performing a full count. This significantly improves performance on locations with large numbers of children. The resulting count is displayed with a `+` sign, indicating that the result is not exact. ![Example of subtree count with exceeded limit](https://doc.ibexa.co/en/saas/administration/back_office/img/query_subtree_limit_locations_tab.png "Example of subtree count with exceeded limit") ## Default locations Default location IDs for [content structure, Media, and users](https://doc.ibexa.co/en/saas/content_management/locations/#top-level-locations) in the menu are configured with the `ibexa.system..location_ids` [configuration key](https://doc.ibexa.co/en/saas/administration/configuration/configuration/#configuration-files): ```yaml ibexa: system: : location_ids: content_structure: 2 media: 43 users: 5 ``` # Content tree > For the complete documentation index, see [llms.txt](https://doc.ibexa.co/en/saas/llms.txt). Configure SiteAccess, displayed content items, depth and root location for the content tree. With this configuration you can: - define configuration for a SiteAccess or a SiteAccess group - decide how many content items are displayed in the tree - set maximum depth of expanded tree - hide content types - set a tree root location - override content tree's root for specific locations ```yaml ibexa: system: # any SiteAccess or SiteAccess group admin_group: content_tree_module: # defines how many children are shown after expanding parent load_more_limit: 15 # users won't be able to load more children than that children_load_max_limit: 200 # maximum depth of expanded tree tree_max_depth: 10 # content types to display in content tree, value of '*' allows all CTs to be displayed allowed_content_types: '*' # content tree won't display these content types, can be used only when 'allowed_content_types' is set to '*' ignored_content_types: - post - article # ID of Location to use as tree root. If omitted - content.tree_root.location_id setting is used. tree_root_location_id: 2 # list of Location IDs for which content tree's root Location is changed contextual_tree_root_location_ids: - 2 # Home (Content structure) - 5 # Users - 43 # Media ``` # Add anchor menu to content type edit screen > For the complete documentation index, see [llms.txt](https://doc.ibexa.co/en/saas/llms.txt). Add anchor menu to the content type configuration screen, to make field type settings of your choice more prominent. With the anchor menu you can increase visibility of certain [field types](https://doc.ibexa.co/en/saas/content_management/field_types/field_types/index.md), which provide more complex functionality, by separating them from the [field definitions](https://doc.ibexa.co/en/saas/administration/content_organization/content_types/#field-definitions) section in [content type](https://doc.ibexa.co/en/saas/administration/content_organization/content_types/index.md) configuration screen. One example of such field type would be [SEO](https://doc.ibexa.co/projects/userguide/en/6.0/search_engine_optimization/work_with_seo/), because it handles functionality that applies to all content items of the content type. You can use the anchor menu feature with other field types. See the following example to learn how you can add a field type as an anchor menu. ## Modify YAML configuration Modify the field type visibility under the `ibexa.system..admin_ui_forms.content_type_edit.field_types` [configuration key](https://doc.ibexa.co/en/saas/administration/configuration/configuration/#configuration-files): ```yaml ibexa: system: admin_group: admin_ui_forms: content_type_edit: field_types: : meta: true position: 100 ``` Where keys have the following meaning: - `field_type_identifier` - replace this key with an identifier of the field type that you want to make more prominent. In case of SEO, this key is `ibexa_seo`. - `meta` - when this flag is set to `true`, it separates the field type from the **Field definitions** section and puts it in an anchor menu - `position` - decides about the field type's position on the content type edit screen and in the content item, in relation to other field types Additionally, setting `meta` to `true` adds a toggle for enabling or disabling the field type. In case of SEO, it adds the **Enable SEO for this content type** toggle. Enable the toggle to display the SEO section on the content item edit page. ![SEO anchor menu](https://doc.ibexa.co/en/saas/administration/img/content_type_edit_screen_anchor_menu.png) > **Note: Note** > > If you add multiple field types as anchor menus, they're automatically displayed as separate sections. # Sub-items list > For the complete documentation index, see [llms.txt](https://doc.ibexa.co/en/saas/llms.txt). Inject a sub-items list into your back office customizations or customize the view. The Sub-items List module is meant to be used as a part of the editorial interface of Cohesivo. It provides an interface for listing the sub-items of any location. ## Create custom sub-items list view You can extend the Sub-items List module to replace an existing view or add your own. The example below adds a new timeline view to highlight the modification date. ![Sub-items List module using the new Timeline view](https://doc.ibexa.co/en/saas/administration/back_office/img/subitems/timeline_view.png "Sub-items List module using the new Timeline view") To recreate it, start by creating the components responsible for rendering the new view. You can create two files: - `assets/js/timeline.view.component.js` responsible for rendering the whole view ```js import React from 'react'; import PropTypes from 'prop-types'; import TimelineViewItemComponent from './timeline.view.item.component'; const TimelineViewComponent = ({ items, generateLink }) => { const groupByDate = (items) => { return items.reduce((groups, item) => { const date = new Date(item.content._info.modificationDate.timestamp * 1000); const dateKey = date.toISOString().split('T')[0]; if (!groups[dateKey]) { groups[dateKey] = []; } groups[dateKey].push(item); return groups; }, {}); }; const groupedItems = groupByDate(items); return (
{Object.entries(groupedItems).map(([date, dateItems]) => (

{new Date(date).toLocaleDateString()}

{dateItems.map((item) => ( ))}
))}
); }; TimelineViewComponent.propTypes = { items: PropTypes.array.isRequired, generateLink: PropTypes.func.isRequired, }; export default TimelineViewComponent; ``` - `assets/js/timeline.view.item.component.js` responsible for rendering a single item ```js import React from 'react'; import PropTypes from 'prop-types'; import Icon from '@ibexa-admin-ui-modules/common/icon/icon'; const { ibexa } = window; const TimelineViewItemComponent = ({ item, generateLink }) => { const { content } = item; const contentTypeIdentifier = content._info.contentType.identifier; const contentTypeIconUrl = ibexa.helpers.contentType.getContentTypeIconUrl(contentTypeIdentifier); const time = new Date(content._info.modificationDate.timestamp * 1000).toLocaleTimeString(); return (
{time}
{content._name}
{content._info.contentType.name}
); }; TimelineViewItemComponent.propTypes = { item: PropTypes.object.isRequired, generateLink: PropTypes.func.isRequired, }; export default TimelineViewItemComponent; ``` Provide the necessary styling in `assets/scss/timeline.view.scss`. The example below uses Cohesivo's SCSS variables for consistency with the rest of the back office interface. ```scss @use '@ibexa-admin-ui/src/bundle/Resources/public/scss/custom.scss' as *; .app-timeline-view { padding: calculateRem(16px); &__group { position: relative; margin-bottom: calculateRem(32px); } &__date { display: flex; align-items: center; margin-bottom: calculateRem(16px); h3 { margin: 0; font-size: $ibexa-text-font-size-large; color: $ibexa-color-dark; } } &__date-marker { width: calculateRem(12px); height: calculateRem(12px); border-radius: 50%; background: $ibexa-color-primary; margin-right: calculateRem(16px); } &__items { margin-left: calculateRem(6px); padding-left: calculateRem(32px); border-left: calculateRem(2px) solid $ibexa-color-light; } } .app-timeline-view-item { display: flex; align-items: flex-start; padding: calculateRem(16px); margin-bottom: calculateRem(8px); text-decoration: none; color: inherit; background: $ibexa-color-light-300; border-radius: $ibexa-border-radius; transition: background-color 0.2s $ibexa-admin-transition; &:hover { background: $ibexa-color-light-400; } &__time { color: $ibexa-color-dark-400; margin-right: calculateRem(16px); min-width: calculateRem(80px); } &__content { display: flex; align-items: center; } &__icon { margin-right: calculateRem(16px); } &__name { font-weight: $ibexa-font-weight-bold; margin-bottom: calculateRem(4px); } &__type { font-size: $ibexa-text-font-size-small; color: $ibexa-color-dark-400; display: flex; align-items: center; gap: calculateRem(8px); } &__type-name { line-height: calculateRem(16px); } } ``` The last step is adding the view module to the list of available views in the system, by using the provided `registerView` function. You can create a new view by providing an unique identifier, or replace an existing one by reusing its identifier. The existing view identifiers are defined as JavaScript constants in the `@ibexa-admin-ui-modules/sub-items/constants` module: - Grid view: `VIEW_MODE_GRID` constant - Table view: `VIEW_MODE_TABLE` constant Create a file called `assets/js/registerTimelineView.js`: ```js import TimelineViewComponent from './timeline.view.component.js'; import { registerView } from '@ibexa-admin-ui-modules/sub-items/services/view.registry'; // Use the existing constants to replace a view import { VIEW_MODE_GRID, VIEW_MODE_TABLE } from '@ibexa-admin-ui-modules/sub-items/constants'; registerView('timeline', { component: TimelineViewComponent, iconName: 'timeline', label: 'Timeline view', }); ``` And include it into the back office using Webpack Encore, together with your custom styles. ```js const ibexaConfigManager = require('./ibexa.webpack.config.manager.js'); //... ibexaConfigManager.add({ ibexaConfig, entryName: 'ibexa-admin-ui-layout-js', newItems: [ path.resolve(__dirname, './assets/js/registerTimelineView.js') ], }); ibexaConfigManager.add({ ibexaConfig, entryName: 'ibexa-admin-ui-layout-css', newItems: [ path.resolve(__dirname, './assets/scss/timeline.view.scss'), ], }); ``` ## Use sub-items list > **Caution: Caution** > > If you want to load the Sub-items module from your custom code, you need to load the JS code for it in your view, as it's not available by default. With plain JS: ```js const containerNode = document.querySelector('#sub-items-container'); ReactDOM.render( React.createElement(ibexa.modules.SubItems, { parentLocationId: { Number }, restInfo: { token: { String }, siteaccess: { String }, }, }), containerNode, ); ``` With JSX: ```jsx const attrs = { parentLocationId: {Number}, restInfo: { token: {String}, siteaccess: {String} } }; ``` ## Properties list The `` module can handle additional properties. There are two types of properties: **required** and **optional**. All of them are listed below. ### Required props Without all the following properties the Sub-items module cannot work. - **parentLocationId** *{Number}* - parent location ID - **restInfo** *{Object}* - backend config object: - **token** *{String}* - CSRF token - **siteaccess** *{String}* - SiteAccess identifier - **handleEditItem** *{Function}* - callback to handle edit content action - **generateLink** *{Function}* - callback to handle view content action ### Optional properties Optionally, Sub-items module can take a following list of props: - **loadContentInfo** *{Function}* - loads content item info. Takes two params: - **contentIds** *{Array}* - list of content IDs - **callback** *{Function}* - a callback invoked when content info is loaded - **loadContentTypes** *{Function}* - loads content types. Takes one param: - **callback** *{Function}* - callback invoked when content types are loaded - **loadLocation** *{Function}* - loads location. Takes four params: - **restInfo** *{Object}* - REST info params: - **token** *{String}* - the user token - **siteaccess** *{String}* - the current SiteAccess - **queryConfig** *{Object}* - query config: - **locationId** *{Number}* - location ID - **limit** *{Number}* - content item limit - **offset** *{Number}* - items offset - **sortClauses** *{Object}* - the Sort Clauses, for example, {LocationPriority: 'ascending'} - **callback** *{Function}* - callback invoked when location is loaded - **updateLocationPriority** - updates item location priority. Takes two params: - **params** *{Object}* - parameters hash containing: - **priority** *{Number}* - priority value - **location** *{String}* - REST location ID - **token** *{String}* - CSRF token - **siteaccess** *{String}* - SiteAccess identifier - **callback** *{Function}* - callback invoked when location priority is updated - **activeView** *{String}* - active list view identifier - **extraActions** *{Array}* - list of extra actions. Each action is an object containing: - **component** *{Element}* - React component class - **attrs** *{Object}* - additional component properties - **items** *{Array}* - list of location's sub-items - **limit** *{Number}* - items limit count - **offset** *{Number}* - items limit offset - **labels** *{Object}* - list of module labels, see [sub.items.module.js](https://github.com/ibexa/admin-ui/blob/6.0/src/bundle/ui-dev/src/modules/sub-items/sub.items.module.js) for details. Contains definitions for sub components: - **subItems** *{Object}* - list of sub-items module labels - **tableView** *{Object}* - list of table view component labels - **tableViewItem** *{Object}* - list of table item view component labels - **loadMore** *{Object}* - list of load more component labels - **gridViewItem** *{Object}* - list of grid item view component labels - **languageContainerSelector** *{String}* - selector where the language selector should be rendered ## Reuse Sub-items list To add a Sub-items list on a page that doesn't have the (right) action sidebar, you need to do one of the following things: - add a `
` element with the `.ibexa-extra-actions-container` selector - change the selector in the Sub-items settings by sending the `languageContainerSelector` prop which takes the selector for the element that renders the `languageSelector`. # Integrated help > For the complete documentation index, see [llms.txt](https://doc.ibexa.co/en/saas/llms.txt). Integrated help provides quick access to documentation, training, and support resources. Integrated help brings documentation, training resources, and product roadmap-related information into the back office, together with user onboarding capabilities. With this feature installed, users can click the ![Help icon](https://doc.ibexa.co/en/saas/administration/back_office/img/about-info.png) icon to access relevant content straight from the UI. ![Integrated help menu](https://doc.ibexa.co/en/saas/administration/back_office/img/5_0_integrated_help_menu.png) Integrated help is contextual, therefore, apart from user documentation, release notes, and partner guidelines, which are available to editors and store managers, developers can access API references or the support portal. ## Product tours Product tours are interactive guided walkthroughs that help back office users discover Cohesivo features, available starting with Cohesivo v4.6.29. They provide step-by-step guidance directly within the application interface, accelerating user adoption and reducing training time. Developers can create custom onboarding journeys tailored to specific client implementations, user roles, or business processes. For more information, see [Product tour](https://doc.ibexa.co/en/saas/administration/back_office/product_tour/index.md). The help center is enabled by default for all back office users. If needed, they can [disable it in user settings](https://doc.ibexa.co/projects/userguide/en/6.0/getting_started/discover_ui/#disable-help-center). # Product tour > For the complete documentation index, see [llms.txt](https://doc.ibexa.co/en/saas/llms.txt). Product tours provide interactive guided walkthroughs to help users learn Cohesivo features. Product tour is an in-app onboarding tool that helps back office contributors discover Cohesivo features through interactive, step-by-step guided walkthroughs. Unlike static documentation, product tours provide real-time, contextual guidance directly within the application interface. With product tours, you can create customized onboarding journeys tailored to specific client implementations, user roles, or business processes. This accelerates user adoption, reduces training time, and helps users confidently navigate the platform. Product tour functionality is available from versions 4.6.29 and 5.0.7 as part of the Integrated help package. To use product tours, you must first enable [Integrated help](https://doc.ibexa.co/en/saas/administration/back_office/integrated_help/index.md). ## Key concepts Product tour consists of three main elements: - **Scenario** - a complete onboarding scenario containing multiple steps that guide users through a specific feature or workflow - **Step** - an individual instruction or explanation within a scenario, containing blocks, displayed as an overlay or tooltip - **Block** - a content element within a step, such as text, images, videos, or links that provide information to the user ## Scenario types Cohesivo supports two types of scenarios, each designed for different use cases: ### General scenarios General tours display information in centered modals without targeting specific UI elements. These tours provide an overview of features or concepts and do not require interaction with particular interface elements. General tours are ideal for: - Introducing new users to the platform - Explaining high-level concepts or feature overviews - Welcoming users with customizable background images and branding ![General scenario type](https://doc.ibexa.co/en/saas/administration/back_office/img/product_tour/general_scenario.png "General scenario type") ### Targetable scenarios Targetable scenarios highlight specific UI elements on the page and guide users through interactive workflows. Each step targets a particular element by using a CSS selector, and can draw attention to buttons, navigation elements, or other interface components. Targetable scenarios are ideal for: - Demonstrating specific features or workflows - Guiding users through multi-step processes - Teaching users how to interact with particular UI elements The steps building the scenario support three interaction modes: - **Standard** - Users navigate between steps by clicking **Previous** and **Next** buttons - **Clickable** - Users must click the highlighted element to proceed to the next step - **Draggable** - Users must drag and drop an element to continue the scenario ![Targetable scenario type](https://doc.ibexa.co/en/saas/administration/back_office/img/product_tour/targetable_scenario.png "Targetable scenario type") ## Scenario lifecycle Depending on scenario configuration, they automatically appear to users when they first log in or visit a specific page. Each scenario appears only once for each user. Users can complete a tour with one of the following actions: - by finishing all steps - by skipping it with the **Skip** button in general tours and **Exit tour** in targetable tours - by skipping it with the **Escape** key For **Standard** scenario steps, users can move freely between the previous and next steps. For **Clickable** and **Draggable** steps, users can't go back to the previous step without restarting the scenario and starting from the beginning. At any time, users can manually restart completed tours from their [user settings](https://doc.ibexa.co/projects/userguide/en/6.0/getting_started/get_started/#user-settings). To start building your custom onboarding scenarios, see [Configure product tour](https://doc.ibexa.co/en/saas/administration/back_office/configure_product_tour/index.md). # Configure product tour scenarios > For the complete documentation index, see [llms.txt](https://doc.ibexa.co/en/saas/llms.txt). Configure custom product tour scenarios with steps, blocks, and interaction modes. You can configure the product tour scenarios to adapt it to your project needs, covering different onboarding scenarios. Product tour scenarios are configured with YAML configuration files. Configuration is SiteAccess-aware, allowing you to create separate onboarding experiences for different back offices in [multisite setups](https://doc.ibexa.co/en/saas/multisite/multisite/index.md). Use the default provided configuration as a starting point that you can adjust to your needs. ## Configuration structure You configure product tour scenarios under the `ibexa.system..product_tour` key. Each scenario has a unique identifier and contains steps, which in turn contain blocks. The basic configuration structure of a scenario is as follows: ```yaml ibexa: system: >: # For example, admin or admin_group product_tour: : type: scenario_title_translation_key: # Optional user_groups_excluded: [, ...] # Optional steps: : # Scenario step, unique within a scenario step_title_translation_key: background_image: # Only for general type, optional target: # Only for targetable type, required interaction_mode: # Only for targetable type, optional blocks: - type: params: # Block-specific parameters # ... ``` The product tour scenarios are meant to be translatable. Ibexa recommends using translation keys instead of literal values in the YAML configuration, and providing the translations separately. Use the `ibexa_integrated_help` translation domain. For all the examples below, you can provide the translations by creating a `translations/ibexa_integrated_help.en.yaml` file with the following content: ```yaml tour.my_general_scenario.title: "My general scenario" title: "Welcome!" subtitle: "This is the subtitle" tour.step.description: "This is the description of the step, you can use it to explain what to do in this step." tour.link.documentation: "Documentation link" tour.list.title: "This is the list title" tour.list.item1: "First item" tour.list.item2: "Second item" tour.list.item3: "Third item" ``` To insert a line break into a translation, HTML encode the `
` entities to `<br/>`. ## Scenario configuration Each scenario must specify its type and can optionally restrict access by user groups. ### Scenario display order The order of scenarios in the configuration file determines the order in which they are evaluated and, if the right conditions are met, displayed. There are two [scenario types](https://doc.ibexa.co/en/saas/administration/back_office/product_tour/#scenario-types): - `general` scenarios appear at the earliest opportunity (on any page after logging in), with an exception of the user settings area - `targetable` scenarios begin if their `target` element is found in the DOM when the page is loaded. Targetable scenarios don't trigger in the user settings area as well. To control where a targetable tour appears, ensure that the first step targets an element unique to that specific page. You can target elements that appear after a user action, for example, modals like the content browser, but the first step's target must be present in the DOM when the page is loaded. Once a scenario ends, the system evaluates the next scenario from the configuration and, if applicable, displays it. ### Scenario title Use the optional `scenario_title_translation_key` field to provide a human-readable label for a scenario. This label is displayed in the user settings page where users can reset their product tour progress. ```yaml product_tour: welcome_tour: type: general scenario_title_translation_key: tour.welcome_tour.title ``` If the translation key is not set, the raw scenario identifier is used as the label. Translations must be provided in the `ibexa_integrated_help` translation domain, for example, in `translations/ibexa_integrated_help.en.yaml`. ### User group restrictions Restrict scenario visibility by excluding specific user groups by using their content remote IDs: ```yaml product_tour: my_scenario: user_groups_excluded: ['user_group_content_remote_id_1', 'user_group_content_remote_id_2'] # Exclude specific user groups ``` When creating new [back office user groups](https://doc.ibexa.co/en/saas/users/user_registration/#user-types), decide whether the existing product tour scenarios should be available for these new user groups. If not, add the new group to the exclusion list. > **Caution: Caution** > > If a scenario contains information meant only for specific group of users, always use the `user_groups_excluded` setting to exclude other groups. Don't rely only on UI access restrictions to control the access to scenarios, as a malicious internal user could trigger and preview them outside of the intended place. ## Step configuration Steps define individual instructions within a scenario. The configuration differs based on scenario type: ### General scenario steps General scenario steps display centered modals and support the `background_image` setting, allowing you to set a shared background image for each step. For the background, you can use an absolute URL or place your image in the `public` directory and provide the path relative to it. To resolve the path relative to the site root, [prefix it with `/`](https://developer.mozilla.org/en-US/docs/Web/API/URL_API/Resolving_relative_references#root_relative). ```yaml ibexa: system: admin_group: product_tour: my_general_scenario: type: 'general' scenario_title_translation_key: tour.my_general_scenario.title steps: welcome_step: step_title_translation_key: title background_image: /public/img/background.jpg blocks: - type: title params: ``` ### Targetable tour steps Targetable tour steps highlight specific UI elements by using CSS selectors. You can select a specific element by using the `target` setting. ```yaml ibexa: system: admin_group: product_tour: targetable_dashboard_scenario: type: 'targetable' scenario_title_translation_key: tour.targetable_dashboard_scenario.title steps: dashboard_options: step_title_translation_key: Open Dashboard options target: ".ibexa-db-header__more" # No interaction_mode specified or the value is set to null blocks: - type: text params: ``` If a step's target element doesn't exist on the page, the step isn't displayed and the scenario is stopped. Ensure your configuration matches the actual DOM structure to avoid broken scenarios. Use unique selectors to avoid triggering your scenarios on other pages. #### Interaction modes Select how the scenario step interacts with the target element by using the `interaction_mode` setting. Targetable steps support [three interaction modes](https://doc.ibexa.co/en/saas/administration/back_office/product_tour/#targetable-scenarios): > **Note: Note** > > Clickable and draggable modes are designed for single actions only (buttons, links). You can't select an entire form. If the interaction with the highlighted element results in redirection to a new page or opening a modal window where the previous target element can't be found, the "Previous" navigation button won't be displayed. **Standard mode**: The default value. A tooltip attached to a specific element on the page is displayed. Users continue the scenario with **Previous**/**Next** buttons: ```yaml dashboard_options: step_title_translation_key: Open Dashboard options target: ".ibexa-db-header__more" # No interaction_mode specified or the value is set to null blocks: - type: text params: text_translation_key: Learn how to customize the blocks displayed on your dashboard ``` ![Standard interaction mode](https://doc.ibexa.co/en/saas/administration/back_office/img/product_tour/standard_mode.png "Standard interaction mode") **Clickable mode**: A tooltip attached to a specific element on the page is displayed. Users continue the scenario by clicking the highlighted element. ```yaml open_dashboard_options: step_title_translation_key: Open Dashboard options target: '.ibexa-db-header__more' interaction_mode: clickable blocks: - type: text params: text_translation_key: Click here to customize your dashboard ``` ![Clickable interaction mode](https://doc.ibexa.co/en/saas/administration/back_office/img/product_tour/clickable_mode.png "Clickable interaction mode") **Draggable mode**: A tooltip attached to a specific element on the page is displayed. Users continue the scenario by [dragging](https://developer.mozilla.org/en-US/docs/Web/API/HTML_Drag_and_Drop_API#draggable_items) the highlighted element. ```yaml drag_and_drop_step: step_title_translation_key: Drag-and-drop blocks target: ".c-pb-toolbox-blocks-group__blocks > * .c-pb-toolbox-block__content:first-of-type" interaction_mode: draggable blocks: - type: text params: text_translation_key: Drag-and-drop blocks from the sidebar to the dashboard to customize it ``` You can use this mode only with HTML elements that have the [`draggable` attribute](https://developer.mozilla.org/en-US/docs/Web/HTML/Reference/Global_attributes/draggable) set to `true`. ![Draggable interaction mode](https://doc.ibexa.co/en/saas/administration/back_office/img/product_tour/draggable_mode.png "Draggable interaction mode") ## Block types Blocks are content elements that make up each step, available both for `general` and `targetable` scenarios. Seven block types are available for building step content, and a scenario step must contain at least one. If multiple blocks are defined for a step, they are displayed one after the other. ### Title block Display bold, prominent titles: ```yaml - type: title params: text_translation_key: subtitle ``` ### Text block Display regular text content: ```yaml - type: text params: text_translation_key: tour.step.description ``` ### Link block Add external or internal links: ```yaml - type: link params: url: https://doc.ibexa.co text_translation_key: tour.link.documentation ``` ### List block Create bulleted lists with title: ```yaml - type: list params: title_translation_key: tour.list.title items_translation_keys: - tour.list.item1 - tour.list.item2 - tour.list.item3 ``` The `title_translation_key` property is optional. ### Media blocks To provide data to the media block, provide absolute URLs or place your image or video files in the `public` directory and provide the path relative to it. To resolve the path relative to the site root, [prefix it with `/`](https://developer.mozilla.org/en-US/docs/Web/API/URL_API/Resolving_relative_references#root_relative). #### Image block Embed images inside the step. You can provide alternative text by using the `alt_translation_key` property. Assuming a `public/img/diagram.jpg` image exists, set the configuration value to `/img/diagram.jpg`. ```yaml - type: image params: src: /public/img/diagram.jpg alt_translation_key: tour.image.alt ``` #### Video block Embed video content by using the [`video` HTML element](https://developer.mozilla.org/en-US/docs/Web/HTML/Reference/Elements/video): ```yaml - type: video params: # 'Big Buck Bunny' licensed under CC 3.0 by the Blender foundation. Hosted by archive.org url: https://archive.org/download/BigBuckBunny_124/Content/big_buck_bunny_720p_surround.mp4 ``` ## Configuration examples ### Example 1: General welcome tour The following example showcases all the built-in block types for a `general` scenario consisting of a single step. ```yaml ibexa: system: admin_group: product_tour: my_general_scenario: type: 'general' scenario_title_translation_key: tour.my_general_scenario.title steps: welcome_step: step_title_translation_key: title background_image: /public/img/background.jpg blocks: - type: title params: text_translation_key: subtitle - type: text params: text_translation_key: tour.step.description - type: link params: url: https://doc.ibexa.co text_translation_key: tour.link.documentation - type: image params: src: /public/img/diagram.jpg alt_translation_key: tour.image.alt - type: video params: # 'Big Buck Bunny' licensed under CC 3.0 by the Blender foundation. Hosted by archive.org url: https://archive.org/download/BigBuckBunny_124/Content/big_buck_bunny_720p_surround.mp4 - type: list params: title_translation_key: tour.list.title items_translation_keys: - tour.list.item1 - tour.list.item2 - tour.list.item3 - type: twig_template params: template: custom_template.html.twig ``` ### Example 2: Targetable feature tour with interactive steps The following example showcases how the three interaction modes of a `targetable` scenario can be used to build an onboarding tour for the dashboard: ```yaml ibexa: system: admin_group: product_tour: targetable_dashboard_scenario: type: 'targetable' scenario_title_translation_key: tour.targetable_dashboard_scenario.title steps: dashboard_options: step_title_translation_key: Open Dashboard options target: ".ibexa-db-header__more" # No interaction_mode specified or the value is set to null blocks: - type: text params: text_translation_key: Learn how to customize the blocks displayed on your dashboard open_dashboard_options: step_title_translation_key: Open Dashboard options target: '.ibexa-db-header__more' interaction_mode: clickable blocks: - type: text params: text_translation_key: Click here to customize your dashboard customize_dashboard: step_title_translation_key: Customize Dashboard target: '.ibexa-db-actions-popup-menu' interaction_mode: clickable blocks: - type: text params: text_translation_key: Choose "Customize dashboard" drag_and_drop_step: step_title_translation_key: Drag-and-drop blocks target: ".c-pb-toolbox-blocks-group__blocks > * .c-pb-toolbox-block__content:first-of-type" interaction_mode: draggable blocks: - type: text params: text_translation_key: Drag-and-drop blocks from the sidebar to the dashboard to customize it ``` # Recent activity > For the complete documentation index, see [llms.txt](https://doc.ibexa.co/en/saas/llms.txt). Log and monitor activity through UI, PHP API and REST API. Recent activity log displays last actions in the repository (whatever their origin is, for example, back office, REST, migration, CLI, or CRON). ![Recent activity](https://doc.ibexa.co/en/saas/administration/img/admin_panel_recent_activity.png) To learn more about its back office usage and the actions logged by default, see [Recent activity in User Documentation](https://doc.ibexa.co/projects/userguide/en/6.0/recent_activity/recent_activity/). ## Configuration With some configuration, you can customize the log length in the database or on screen, or disable the logging completely. A command maintains the log size in database, it should be scheduled through CRON. ### Log retention The `ibexa.repositories..activity_log.truncate_after_days` setting sets the number of days a log entry is kept before it's deleted by the `ibexa:activity-log:truncate` command (default value: 30 days). For example, the following configuration sets 15 days of life to the log entries on the `default` repository: ```yaml ibexa: repositories: default: activity_log: truncate_after_days: 15 ``` To automate a regular truncation, you must schedule the command `ibexa:activity-log:truncate`. To minimize the number of entries to delete, it's recommended that you execute the command more than one time a day. ### Display limit The `ibexa.system..activity_log.pagination.activity_logs_limit` setting sets the number of log items shown per page in the back office (default value: 25). For example, the following configuration sets 20 context groups per page for the `admin_group` SiteAccess group: ```yaml ibexa: system: admin_group: activity_log: pagination: activity_logs_limit: 20 ``` A log item is a group of entries, or an entry without group. ### Disable activity log The `ibexa.repositories..activity_log.enabled` setting can disable activity log entirely for a given repository. For example, to disable the activity log for the `default` repository: ```yaml ibexa: repositories: default: activity_log: enabled: false ``` ## Permission and security The [`activity_log/read`](https://doc.ibexa.co/en/saas/permissions/policies/#activity-log) policy gives a role the access to the **Admin** -> **Activity list**, the dashboard's **Recent activity** block, and the user profile's **Recent activity**. It can be limited to "Only own logs" ([`ActivityLogOwner`](https://doc.ibexa.co/en/saas/permissions/limitation_reference/#activity-log-owner-limitation)). The policy should be given to every roles having access to the back office, at least with the `ActivityLogOwner` owner limitation, to allow them to use the "Recent activity" block in the [default dashboard](https://doc.ibexa.co/en/saas/administration/dashboard/configure_default_dashboard/index.md). This policy is required to view [activity log in user profile](https://doc.ibexa.co/projects/userguide/en/6.0/getting_started/get_started/#view-and-edit-user-profile), if the user profile is enabled. > **Caution: Caution** > > Don't assign `activity_log/read` permission to the Anonymous role, even with the owner limitation, because this role is shared among all unauthenticated users. ## User privacy > **Caution: Caution** > > A username of the User who performs the action is logged. When acting through the web server, the User's IP address is also logged. Other access, such as console commands, doesn't log an IP. Your Data Protection Officer or GDPR representative should be aware of this, so they can ensure users are informed if needed, depending on your use case, jurisdiction, and company policy. > > For example, if a content edition feature, such as reader's comments, is available in the front office, the recent activity log records the front users' IPs. ## REST API You can browse activity logs with REST API. For more information, see the [REST API reference](https://doc.ibexa.co/en/saas/api/rest_api/rest_api_reference/rest_api_reference.html#tag/Activity-Log). # Content management # Content management > For the complete documentation index, see [llms.txt](https://doc.ibexa.co/en/saas/llms.txt). Manage content in Cohesivo by learning about the content model, field types, pages, forms, workflows, and more. - [Content management product guide](https://ez-systems-developer-documentation--3403.com.readthedocs.build/en/3403/content_management/content_management_guide/): Read the content management product guide and learn how to create, modify, and display information to the target audience. - [Content model](https://ez-systems-developer-documentation--3403.com.readthedocs.build/en/3403/content_management/content_model/): Cohesivo's content model relies on content items that are instances of content types and contain content fields. - [Locations](https://ez-systems-developer-documentation--3403.com.readthedocs.build/en/3403/content_management/locations/): Locations hold published content items and can be used to control visibility. - [Field type reference](https://ez-systems-developer-documentation--3403.com.readthedocs.build/en/3403/content_management/field_types/field_type_reference/field_type_reference/): Cohesivo offers a range of built-in field types that cover most common needs when creating content. - [Pages](https://ez-systems-developer-documentation--3403.com.readthedocs.build/en/3403/content_management/pages/pages/): Pages are block-based special types of content that editors can create and modify by using a visual drag-and-drop editor. - [Forms](https://ez-systems-developer-documentation--3403.com.readthedocs.build/en/3403/content_management/forms/forms/): Forms are a type of content item that you can use to improve the functionality of your website. - [Taxonomy](https://ez-systems-developer-documentation--3403.com.readthedocs.build/en/3403/content_management/taxonomy/taxonomy/): A taxonomy uses tags to categorize and organize content - [Workflow](https://ez-systems-developer-documentation--3403.com.readthedocs.build/en/3403/content_management/workflow/workflow/): Workflow controls how content items pass between stages and allows setting up editorial flows, for example for reviews and proofreading. # Content management product guide > For the complete documentation index, see [llms.txt](https://doc.ibexa.co/en/saas/llms.txt). Read the content management product guide and learn how to create, modify, and display information to the target audience. ## What is content management The term “content management” covers all the tasks that you need to perform to create, edit and present content to its intended audience. The content management model applied in Cohesivo lies at the foundation of the entire system. A system that relies on roles and permissions controls access to content items and is granular and powerful enough to be used in managing user accounts, corporate accounts, products, or process definitions. ## Availability Content management capabilities are available in Cohesivo. ## How does it work Cohesivo revolves around content management. Many things here are content items, including: - sites - folders - pages - articles or posts - products - forms - media (for example, images or videos) - user accounts You can set up content structure, define the templates to be filled with content, and assign different areas of the structure to your editors. Next steps would be to create the actual content, and then classify content items, and organize them as necessary. You can then publish the content directly, by building a website or a web store, or by using external systems together with a [headless CMS](https://developers.ibexa.co/headless-cms) that relies on the Cohesivo technology. ## Content structure All content in Cohesivo is organized hierarchically, into what is called a [**content tree**](https://doc.ibexa.co/en/saas/administration/back_office/content_tree/index.md). This tree-like structure repeats throughout the system, and applies to content, taxonomies, categories, and the like. Traditional as the structure may look, with relations and multiple location support, a single content item can be referenced by another content item and accessed from different places of the tree, which allows you to build complex architectures with multiple locales and output channels. ![Content structure in a Content Browser](https://doc.ibexa.co/en/saas/content_management/img/content_tree.png) ## Content model A structure of elements that *store* content information is referred to as the **content model**. Cohesivo comes with a predefined content model that includes a broad set of various field types and several content types. You can customize and adapt the content model to your organization's needs and the type of output channel that you use. Content managers or even editors can then apply such field types when they modify existing or create new content types. The editing interface lets all users, including those with no coding experience, create or modify certain areas of the content model. For technical details, see [a Content model](https://doc.ibexa.co/en/saas/content_management/content_model/#content-model). ### Field types [Field types](https://doc.ibexa.co/en/saas/content_management/field_types/field_types/index.md) are the smallest elements of the content model’s structure. Cohesivo comes with many built-in field types that cover most common needs, for example, Text line, RichText, Integer, Measurement, or Map location. Their role is to: - store data - validate input data - make the data searchable - display fields of a given field type For a complete list of available field types, see [field type reference](https://doc.ibexa.co/en/saas/content_management/field_types/field_type_reference/field_type_reference/index.md). ![Field types and fields](https://doc.ibexa.co/en/saas/content_management/img/field_types.png) ### Fields Once you use a field type to design and build a content type definition, and define its settings, it becomes a field. Fields can be as simple as Name, based on a Text line field type, or as complex as page, based on a landing page field type, with multiple options to set and choose from: ![Landing page field settings](https://doc.ibexa.co/en/saas/content_management/img/fields.png) ### Content types Life gets easier when you have templates to fill in with content. Content types are such templates, which editors use to create content items. Content types define what fields are available in the content item. Cohesivo comes with several basic content types, and creating new ones, editing, and deleting them is done by using a visual interface, with no coding skills needed. ![Content types vs. content items](https://doc.ibexa.co/en/saas/content_management/img/content_types.png) ### Content items Content items are pieces of content, such as, for example, products, articles, blog posts, or media. In Cohesivo, everything is a content item — not only pages, articles or products, but also all media (for example, images or videos) or even user accounts. Each content item, apart from its name and identifier, contains a composition of fields, which differs depending on the type of content. For example, articles might have for example, a title, an author, a body, and an image, while products may have, for example, a name, category, price, size, or color. ### Forms Forms could be seen as a special kind of content items, because their role is to gather information from website users and not present it. You create them from basic form fields available in Cohesivo. By adding forms to the website, you can increase the website’s functionality and improve user experience. Cohesivo comes with a visual [Form Builder](https://doc.ibexa.co/projects/userguide/en/6.0/content_management/work_with_forms/). ## Content management capabilities Each content item has at least one location within the content tree, and can have several versions and multiple translations. It can also have related assets, such as images or other media, and assigned keywords, or tags. You can use these characteristics in combination with system features to create the most comprehensive and functional digital presence for your organization. ### Content characteristics #### Locations When a content item is created and published, it's assigned a place in the content tree, designated by a location ID. A single content item can have more than one location ID, which means that the same content can be found on different branches of the tree. However, a single location can have only one content item assigned to it. ![Locations](https://doc.ibexa.co/en/saas/content_management/img/locations.png) Locations can be used to control the availability of content items to end users: you can [hide specific locations](https://doc.ibexa.co/projects/userguide/en/6.0/content_management/content_organization/manage_locations_urls/#hide-locations) of a content item, while others remain available. By [swapping locations](https://doc.ibexa.co/projects/userguide/en/6.0/content_management/content_organization/manage_locations_urls/#swap-locations), you can immediately replace an obsolete version of a content item with an updated one. #### Versions Content items can have several [versions](https://doc.ibexa.co/projects/userguide/en/6.0/content_management/content_versions/). By default, there are three version statuses available: draft, published, and archived. Before they're published, drafts can be routed between different user roles for review and approval. ![Versions](https://doc.ibexa.co/en/saas/content_management/img/versions.png) Editors can [compare different content item versions](https://doc.ibexa.co/projects/userguide/en/6.0/content_management/workflow_management/work_with_versions/#compare-versions) by using the Compare versions feature. #### Translations Content items can have more than one [translation](https://doc.ibexa.co/projects/userguide/en/6.0/content_management/translate_content/). If a website has different fronts, for different locales, and different language versions of content exist, Cohesivo serves the one that matches the locale. ![Translations](https://doc.ibexa.co/en/saas/content_management/img/translations.png) Editors can compare different translations of the same content items with the Compare versions feature mentioned above. #### Relations A [relation](https://doc.ibexa.co/en/saas/content_management/content_relations/index.md) can exist between any two content items in the content tree. For example, blog posts featured in the website's main page are in a relation with the page that they're embedded in. Or, instead of direct attachments, an article can use images that are separate content items outside the article, and are referenced through a relation. ## Content arrangement In Cohesivo, content items can be moved and copied between branches of the content tree. These operations, like in your computer’s file system, can apply both to individual content items and folders or groups. ![Content organization operations](https://doc.ibexa.co/en/saas/content_management/img/content_arrangement.png) Content items can be hidden when necessary, for example, until a certain event, like a Holiday Sale, or Board announcement comes. Hidden content items aren't visible to website visitors and are greyed out in the content tree. ![Hidden content item](https://doc.ibexa.co/en/saas/content_management/img/hidden_content_item.png) Editors can also move obsolete content items to Trash, and ultimately delete them. ![Delete confirmation dialog box](https://doc.ibexa.co/en/saas/content_management/img/delete_confirmation.png) ## Content classification There are multiple tools within Cohesivo that help content managers classify content or restrict access to content to certain recipients. ### Taxonomy With taxonomy you can create tags or keywords within a tree structure and assign them to content items. This way you can classify content and make it easier for end users to find the content they need, or browse and view content from a category that suits them best. ![Taxonomy principles](https://doc.ibexa.co/en/saas/content_management/img/taxonomy.png) ### Access control When your Cohesivo instance has multiple contributors and visitors, administrators can give them access to different areas of the website and different capabilities. It's done by creating roles, with each role having a different set of [permissions](https://doc.ibexa.co/en/saas/permissions/permission_overview/index.md), the most fitting example being the `content/edit` permission limited to an `Articles/BookReviews/Historical` subtree of the content tree. In the next steps, after you create user groups, you’d assign roles to these groups, and add individual users to each of such groups. For more technical information about permissions and limitations, see [Permission use cases](https://doc.ibexa.co/en/saas/permissions/permission_use_cases/index.md). There are, however, mechanisms to control access to content with even more convenience. ### Sections You can divide your content tree into nominal parts to better organize it. Once you have defined sections, for example, Media or Forms, and assigned them to content items, you can decide which roles have access to which section of the tree. The setting is inherited, which means that a child content item inherits a value of this setting from its parent. Changing a section setting doesn't result in moving a content item to a different location within a content tree. ![Members of the Media Section](https://doc.ibexa.co/en/saas/content_management/img/sections.png) ### Object states While reviewing the details of each individual content item in your content tree, you can assign a state to it, for example, “Locked” or “Not locked”. Then you can set a permission that allows or denies users access to content items in a specific state. This setting isn't inherited. ![Object states in content item’s Details](https://doc.ibexa.co/en/saas/content_management/img/object_states.png) ### User segments Although segments aren't meant to classify content, they could fall into this category, because their role is about targeting users, and not controlling their access to content. With segments, you can reach specific groups, or categories, of visitors with specific information about content or products that could be of their interest. For example, you can build Pages that contain different recommendations, depending on who is visiting them. ![A segment group with two user segments](https://doc.ibexa.co/en/saas/content_management/img/user_segments.png) ## How to get started With your Cohesivo instance ready, you can employ the content management features to good use. Since content management is an ongoing process, and, in your implementation, you might prefer focusing on other areas of configuration, the order of operations below is by all means conventional. **1. Create a content model** Any content that you might want to deliver to a viewer can be structured and split into smaller elements. Reverse-engineer the intended concepts into individual fields, which can be categorized, and then picked from categories and combined into content items. Reuse existing field types, then [create content types](https://doc.ibexa.co/projects/userguide/en/6.0/content_management/create_edit_content_items/). **2. Define permissions** Although this step isn't directly related to content management, it's a good time to [set up user roles and permissions](https://doc.ibexa.co/projects/userguide/en/6.0/permission_management/work_with_permissions/), which users would need to work with content. **3. Author content** [Create various content items](https://doc.ibexa.co/projects/userguide/en/6.0/content_management/create_edit_content_items/), such as pages, articles, forms, or media. While you fill fields with content, several actions are there to help you with your task. You can pause and resume the work, preview the results, or send content for review. ![Send to review](https://doc.ibexa.co/en/saas/content_management/img/send_to_review.png) **4. Publish** Again, this isn't part of content management, but at this point you can [publish](https://doc.ibexa.co/projects/userguide/en/6.0/content_management/publish_instantly/) it right away or [schedule content for publication](https://doc.ibexa.co/projects/userguide/en/6.0/content_management/schedule_publishing/). **5. Organize content** Organize the content of your website by copying or moving content items, [controlling Locations and URL addresses](https://doc.ibexa.co/projects/userguide/en/6.0/content_management/content_organization/manage_locations_urls/). Then work with Tags, sections and object states to [classify](https://doc.ibexa.co/projects/userguide/en/6.0/content_management/content_organization/classify_content/#sections) it. ## Benefits The most important benefits of using Content management capabilities of Cohesivo can be gathered into the following groups: 1. Content management capabilities help reduce the effort required to maintain, administer, and distribute digital content, so that you can focus on business operations. 2. Segmentation, translations, and taxonomy make it possible to assist and target visitors from different backgrounds and markets. 3. Granular access control ensures that no content in your control lands before the unauthorized eyes. ## Use cases Cohesivo’s capabilities prove indispensable in many applications. ### Corporate website The most common use case for a comprehensive content management system like Cohesivo would be creating and maintaining a multinational company’s digital presence, with both public and intranet channels, multiple websites with overlapping content structures, and business partners and end-customers alike wanting to connect through different channels to access public and classified content. ### B2C web store Content management could lie at a foundation of a successful global web store, where customers connect through localized websites and branded mobile apps: individual products can have multiple variants with differing related assets, product descriptions must be available in multiple language versions, and access to certain areas of the store depends on both a country and a segment that the customer comes from. ### B2B store Extensive content management capabilities would prove themselves in a setting, where multiple buyers from different partner companies connect to an industry leader’s trading website, and they expect to find well organized product code (SKU) catalogs that contain basic product information. From there they would like to access detailed specifications, white papers and application notes. The same products could come with different brands and at different price points, depending on the customer segment or origin. # Content model > For the complete documentation index, see [llms.txt](https://doc.ibexa.co/en/saas/llms.txt). Cohesivo's content model relies on content items that are instances of content types and contain content fields. ## Content model overview The content structure in Cohesivo is based on content items. A content item represents a single piece of content, for example, an article, a blog post, an image, or a product. Each content item is an instance of a content type. > **Tip: Tip** > > An introduction to the content model for non-developer users is available in [User Documentation](https://doc.ibexa.co/projects/userguide/en/6.0/content_management/content_model/). ## Content items A content item consists of: - [Content information](#content-information) - [Fields](#fields), defined by the [content type](https://doc.ibexa.co/en/saas/administration/content_organization/content_types/index.md). The fields can cover data ranging from single variables and text lines to media files or blocks of formatted text. ### Content information General information about a content item is stored in a `ContentInfo` object. `ContentInfo` doesn't include fields. It contains following information: **`id`** - the unique ID of the Content object. These numbers aren't recycled, so if an item is deleted, its ID isn't reused when a new one is created. **`contentTypeId`** - the unique numerical ID of the content type, on which the content item is based. **`name`** - the name is generated automatically based on a [pattern specified in the content type definition](https://doc.ibexa.co/en/saas/administration/content_organization/content_types/#content-name-pattern). The name is in the main language of the content item. > **Note: Note** > > `name` is always searchable, even if the field(s) used to generate it aren't. **`sectionId`** - the unique number of the section to which the content item belongs. New content items are placed in the Standard section by default. This behavior can be changed, but content must always belong to some section. For more information, see [Sections](https://doc.ibexa.co/en/saas/administration/content_organization/sections/index.md). **`currentVersionNo`** - current version number is the number of the published version or of a newly created draft (which is 1). **`published`** - true if a published version exists, otherwise false. **`ownerId`** - ID of the user who initially created the content item. It's set by the system the first time the content item is published. The ownership of an item cannot be modified and doesn't change even if the owner is removed from the system. **`modificationDate`** - date and time when the content item was last modified. It's set by the system and cannot be modified manually, but changes every time the item is published again. **`publishedDate`** - date and time when the content item was published for the first time. It's set by the system and cannot be modified. **`alwaysAvailable`** - indicates if the content item is shown in the main language when it's not present in another requested language. It's [set per content type](https://doc.ibexa.co/en/saas/content_management/content_availability/index.md). **`remoteId`** - a global unique ID of the content item. Accepts up to 100 characters. Cannot contain non-printable characters and control sequences (anything in ASCII range `\x00` - `\x1F`). It's recommended to either let this value be generated by the Public PHP API as an MD5 hash, or at least to generate it as a hash (for example, one from SHA family). **`mainLanguageCode`** - the main language code of the content item. If the `alwaysAvailable` flag is set to true, the content item is shown in this language when the requested language doesn't exist. **`mainLocationId`** - identifier of the content item's main [location](https://doc.ibexa.co/en/saas/content_management/locations/index.md). **`status`** - status of the content item. It can have three statuses: 0 – *draft*, 1 – *published* and 2 – *archived*. When an item is created, its status is set to *draft*. After publishing the status changes to *published*. When a published content item is moved to Trash, the item becomes *archived*. If a published item is removed from the Trash (or removed without being put in the Trash first), it's permanently deleted. ![Diagram of an example content item](https://doc.ibexa.co/en/saas/content_management/img/content_model_item_diagram.png) The fields of a content item are defined by the content type to which the content item belongs. ## Fields A field is the smallest unit of storage in the content model and the building block of all content items. Every field belongs to a field type. ### Field value validation The values entered in a field may undergo validation, which means the system makes sure that they're correct for the chosen field type and can be used without a problem. Validation depends on the settings of a particular field type. It cannot be turned off for a field if its field type supports it. ### Field details Aside from the field type, the field definition in a content type provides the following information: **Name** – a user-friendly name that describes the field. This name is used in the interface, but not internally by the system. It can consist of letters, digits, spaces, and special characters (the maximum length is 255 characters). If no name is provided, a unique one is automatically generated. **Identifier** – an identifier for internal use, for example, in configuration files, templates, or PHP code. It can only contain lowercase letters, digits and underscores (the maximum length is 50 characters). This identifier is also used in name patterns for the content type. **Description** – a detailed description of the field. **Required** – a flag which indicates if the field is required for the system to accept the content item. By default, if a field is flagged as Required, a user isn't able to publish a content item without filling in this field. > **Note: Note** > > You can use the `ContentService::validate()` method to decide whether the required fields or whole content items are checked for completeness at other stages of the editing process. > > The Required flag is in no way related to field validation. A field's value is validated whether the field is set as required or not. **[Searchable](https://doc.ibexa.co/en/saas/search/search/index.md)** – a flag which indicates if the value of the field is indexed for searching. The Searchable flag isn't available for some fields, because some field types don't allow searching through their values. **[Translatable](https://doc.ibexa.co/en/saas/multisite/languages/languages/index.md)** – a flag which indicates if the value of the field can be translated. It's independent of the field type, which means that even fields such as "Float" or "Image" can be set as translatable. Depending on the field type, there may also be other, specific information to fill in. For example, the "Country" field type allows you to select the default country, and to allow selecting multiple countries at the same time. ![Diagram of content model](https://doc.ibexa.co/en/saas/content_management/img/content_model_diagram.png) ## Content versions Each content item can have multiple versions. Each version has one of the following statuses: *draft*, *archived* or *published*. A new version is created every time a content item is edited. The previous published version isn't modified. Only one version can be published at the same time. When you publish a new version, the previous published version changes its status to Archived. The number of preserved archived versions is set in `ibexa.repositories.default.options.default_version_archive_limit`. By default it's set to 5. A new version is also created when a new [language](https://doc.ibexa.co/en/saas/multisite/languages/languages/index.md) is added to the content item. ## Products Products are a special type of content that holds products you can manage with the product catalog capabilities. For more information, see [Product catalog](https://doc.ibexa.co/en/saas/product_catalog/product_catalog/index.md). # Locations > For the complete documentation index, see [llms.txt](https://doc.ibexa.co/en/saas/llms.txt). Locations hold published content items and can be used to control visibility. When a new content item is published, it's automatically placed in a new location. All locations form a tree which is the basic way of organizing content in the system. Every published content item has a location and, as a consequence, also a place in this tree. ![Content tree - locations](https://doc.ibexa.co/en/saas/content_management/img/content_management_tree_locations.png "Content tree - locations") A content item receives a location only once it has been published. This means that a new unpublished draft doesn't have a location yet. You can find drafts in the **Drafts** tab in the **Content** menu. ![Drafts](https://doc.ibexa.co/en/saas/content_management/img/content_management_drafts.png "Drafts") A content item can have more than one location. It's then present in two or more places in the tree. For example, an article can be at the same time under "Local news" and "Sports news". Even in such a case, one of these places is always the main location. You can change the main location in the back office in the **Locations** tab. ![Locations](https://doc.ibexa.co/en/saas/content_management/img/content_management_locations.png "Locations") ## Top level locations The content tree is hierarchical. It has an empty root location at the top and a structure of dependent locations below it. Every location (aside from the root) has one parent location and can have any number of children. Top level locations are direct children of the root of the tree. The root has location ID 1, isn't related to any content items and should not be used directly. Under this root there are preset top level locations in each installation which cannot be deleted. ### Content The top level location for the actual contents of a site can be viewed by selecting the **Content structure** tab in the Content mode interface. ![Content structure](https://doc.ibexa.co/en/saas/content_management/img/content_management_tree.png "Content structure") This part of the tree is typically used, for example, for organizing folders, articles, or information pages. The default ID number of this location is 2. It contains a Folder content item. ### Media **Media** is the top level location which stores and organizes information that is frequently used by content items located below the **Content** node. ![Media](https://doc.ibexa.co/en/saas/content_management/img/content_management_media.png "Media") It usually contains images, animations, documents and other files. The default ID number of the **Media** location is 43. It contains a Folder content item. ### Users **Users** is the top level location that contains the built-in system for managing user accounts. ![Users in Admin panel](https://doc.ibexa.co/en/saas/administration/img/admin_panel_users.png "Users in Admin panel") A user is simply a content item of the user account content type. The users are organized within user group content items below this location. In other words, the **Users** location contains the actual users and user groups, which can be viewed by selecting the **Users** tab in the **Admin** Panel. The default ID number of the **Users** location is 5. It contains user group content items. ### Forms **Forms** is the top level location that is intended for Forms created using the [Form Builder](https://doc.ibexa.co/projects/userguide/en/6.0/content_management/work_with_forms/#create-forms). ![Forms](https://doc.ibexa.co/en/saas/content_management/img/content_management_forms.png "Forms") ### Other top level locations You should not add any more content directly below location 1, but instead store any content under one of those top-level locations. ## Location visibility Location visibility allows you to control which parts of the content tree are available on the front page. ![Location visibility](https://doc.ibexa.co/en/saas/content_management/img/content_management_visibility.png "Location visibility") Once a content item is published, it cannot be un-published. When the location of a content item is hidden, the system doesn't display it on the website. > **Caution: Visibility and permissions** > > The [visibility switcher](https://doc.ibexa.co/en/saas/content_management/locations/#location-visibility) is a convenient feature for withdrawing content from the frontend. It acts as a filter in the frontend by default. You can choose to respect it or ignore it in your code. It isn't permission-based, and **doesn't restrict access to content**. Hidden content can be read through other means, like the REST API. > > If you need to restrict access to a given content item, you could create a role that grants read access for a given [**Section**](https://doc.ibexa.co/en/saas/administration/content_organization/sections/index.md) or [**Object State**](https://doc.ibexa.co/en/saas/administration/content_organization/object_states/index.md), and set a different section or object state for the given content. Or use other permission-based [**Limitations**](https://doc.ibexa.co/en/saas/permissions/limitations/index.md). If a content item is hidden, it's invisible in all its locations. If a location is hidden, all of its descendants in the tree are hidden as well. This means that there are three different visibility statuses: - Visible - Hidden - Hidden by superior All locations and content items are visible by default. If a location is made invisible manually, its status is set to Hidden. All locations under it change status to Hidden by superior. A content item is Hidden by superior only in locations in which it has a parent location with the Hidden status. In the following example, the **Content item 1** is Hidden by superior in the **Location A** while still visible in the **Location B**. ![Visibility in two locations](https://doc.ibexa.co/en/saas/content_management/img/locations_visibility.png) From the visitor's perspective a location behaves the same whether its status is Hidden or Hidden by superior – it's unavailable on the front page. The difference is that a location Hidden by superior cannot be revealed separately from their parent(s). It only becomes visible once all of its parent locations are made visible again. A Hidden by superior status doesn't override a Hidden status. This means that if a location is Hidden manually and later one of its ancestors is hidden as well, the first location's status doesn't change – it remains Hidden (not Hidden by superior). If the ancestor location is made visible again, the first location still remains hidden. The way visibility works can be illustrated using the following scenarios: ### Hiding a visible location ![Hiding a visible location](https://doc.ibexa.co/en/saas/content_management/img/node_visibility_hide.png) When you hide a location that was visible before, it gets the status Hidden. Its child locations are Hidden by superior. The visibility status of child locations that were already Hidden or Hidden by superior doesn't change. ### Hiding a location which is Hidden by superior ![Hiding a location which is Hidden by superior](https://doc.ibexa.co/en/saas/content_management/img/node_visibility_hide_invisible.png) When you explicitly hide a location which was Hidden by superior, it gets the status Hidden. Since the underlying locations are already either Hidden or Hidden by superior, their visibility status doesn't changed. ### Revealing a location with a visible ancestor ![Revealing a location with a visible ancestor](https://doc.ibexa.co/en/saas/content_management/img/node_visibility_unhide1.png) When you reveal a location which has a visible ancestor, this location and its children become visible. However, child locations that were explicitly hidden by a user keep their Hidden status (and their children remain Hidden by superior). ### Revealing a location with a Hidden ancestor ![Revealing a location with a Hidden ancestor](https://doc.ibexa.co/en/saas/content_management/img/node_visibility_unhide2.png) When you reveal a location that has a Hidden ancestor, it **doesn't** become Visible itself. Because it still has invisible ancestors, its status changes to Hidden by superior. > **Tip: In short** > > A location can only be Visible when all of its ancestors are Visible as well. ### Visibility mechanics The visibility mechanics are controlled by two flags: Hidden flag and Invisible flag. The Hidden flag informs whether the node has been hidden by a user or not. A raised Invisible flag means that the node is invisible either because it was hidden by a user or by the system. Together, the flags represent the three visibility statuses: | Hidden flag | Invisible flag | Status | | ----------- | -------------- | ------------------------------------------------------------------------------------------------------------------------ | | - | - | The location is visible. | | 1 | 1 | The location is invisible and it was hidden by a user (Hidden). | | - | 1 | The location is invisible and it was hidden by the system because its ancestor is hidden/invisible (Hidden by superior). | > **Note: Note** > > Displaying visible or hidden locations in governed by the [`Visibility` Search Criterion](https://doc.ibexa.co/en/saas/search/criteria_reference/visibility_criterion/index.md) # Content Relations > For the complete documentation index, see [llms.txt](https://doc.ibexa.co/en/saas/llms.txt). Content Relations control links between different content items, either created explicitly or by linking inside RichText fields. Content items are located in a tree structure through the locations they're placed in. However, content items themselves can also be related to one another. ![Content Relations](https://doc.ibexa.co/en/saas/content_management/img/content_management_relations.png "Content Relations") A **Relation** can exist between any two content items in the repository. For example, images are linked to news articles they're used in. Instead of using a fixed set of image attributes, the images are stored as separate content items outside the article. In the system you can find different types of Relations. Content can have Relations on item or on field level. *Relations at field level* are created using one of two special field types: Content relation (single) and Content relations (multiple). These fields allow you to select one or more other content items in the field value, which are linked to these fields. *Relations at content item level* can be of three different types: - *Common Relations* are created between two content items using the public PHP API. - *RichText linked Relations* are created using a field of the RichText type. When an internal link (a link to another location or content item) is placed in a RichText field, the system automatically creates a Relation. The Relation is automatically removed from the system when the link is removed from the content item. - *RichText embedded Relations* also use a RichText field. When an Embed element is placed in a RichText field, the system automatically creates a Relation between the embedded content item and the one with the RichText field. The Relation is automatically removed from the system when the link is removed from the content item. # Content availability > For the complete documentation index, see [llms.txt](https://doc.ibexa.co/en/saas/llms.txt). Control the availability of content items with relation to translations by using the Default content availability flag. The Default content availability flag enables you to control whether content is available when its translation is missing. You can set the flag in content type definition by checking the "Make content available even with missing translations" option. It's automatically applied to any new content item of this Type. ![Default content availability](https://doc.ibexa.co/en/saas/content_management/img/availability_flag.png "Default content availability") A content item with this flag is available in its main language even if it's not translated into the language of the current SiteAccess. Without the flag, a content item isn't available at all if it doesn't have a language version corresponding to the current SiteAccess. > **Note: Note** > > There is currently no way in the back office to edit the Content availability flag for an already published content item. The Default availability flag is used for the out-of-the box content types representing content that should always be visible to the user, such as media files or user content items. You can also use it for organizational content types. For example, you can assign the flag to a Blog content type which is intended to contain Blog Posts in multiple languages. If the Blog is in English only, it would not be visible for readers using the Norwegian or German SiteAcceses. However, if you set the default availability flag for the Blog content type, it's displayed to them in English (if it's set as a main language) and enables the users to browse individual posts in other languages. # Taxonomy > For the complete documentation index, see [llms.txt](https://doc.ibexa.co/en/saas/llms.txt). A taxonomy uses tags to categorize and organize content Taxonomies (**Tags**) allow you to organize content to make it easy for your site users to browse and to deliver content appropriate for them. Taxonomies are classifications of logical relationships between content. In Cohesivo you can create many taxonomies, each with many tags. The platform mechanism enables creating any entities with a tree structure and assign them to a content item. The default tag configuration is as follows. The associated content type is `tag`. ```yaml ibexa_taxonomy: taxonomies: tags: parent_location_remote_id: taxonomy_tags_folder content_type: tag field_mappings: identifier: identifier parent: parent name: name ``` ## Configuration keys - `ibexa_taxonomies` - section responsible for taxonomy structure where you can [configure other taxonomies](#customize-taxonomy-structure) - `ibexa_taxonomies.tags.parent_location_remote_id` - Remote ID for location where new content items representing tags are created - `ibexa_taxonomies.tags.content_type` - Content type identifier which stands for the tags - `ibexa_taxonomies.tags.field_mappings` - field types map of a content type which taxonomy receives information about the tag from. Three fields are available: `identifier`, `parent` and `name`. The identifiers correspond to field names defined in the content type. The `name` field is used to automatically generate an identifier. ## Customize taxonomy structure You can create other taxonomies than the one predefined in the system, for example a Content category. To do it, first, create a new container to store the new taxonomy's items, for example a folder named "Content categories". Next, under the `ibexa_taxonomy.taxonomies` [key](https://doc.ibexa.co/en/saas/administration/configuration/configuration/#configuration-files) add the following configuration: ```yaml ibexa_taxonomy: taxonomies: # existing keys content_categories: parent_location_remote_id: content_type: content_category field_mappings: identifier: category_identifier parent: parent_category name: name ``` Replace `` with the new container's location remote ID. Translate the configuration identifier in the `ibexa_taxonomy` domain by, for example, creating a `translations/ibexa_taxonomy.en.yaml` file containing the following: ```yaml taxonomy.content_categories: 'Content categories' ``` Then, create a content type with `content_category` identifier and include the following field definitions: - `name` of `ibexa_string` type and required. Use this field, as ``, for content name pattern. - `category_identifier` of `ibexa_string` type and required. - `parent_category` of `ibexa_taxonomy_entry` type and not required. In its Taxonomy drop-down menu, select Content categories (or `taxonomy.content_categories` if no translation has been provided). Finish taxonomy setup by creating a new Content category named Root with identifier `content_categories_root` under the previously created container folder named Content categories. To use this new taxonomy, add an `ibexa_taxonomy_entry_assignement` field to a content type and select Content categories (or `taxonomy.content_categories`) in its Taxonomy drop-down setting. ### Hide Content tab The **Content** tab in taxonomy objects, for example, tags and categories, lists all Content assigned to the current taxonomy. You can hide the **Content** tab in the **Categories** view. In configuration add `assigned_content_tab` with the flag `false` (for other taxonomies this flag is by default set to `true`): ```yaml ibexa_taxonomy: taxonomies: # existing keys content_categories: parent_location_remote_id: content_type: content_category field_mappings: identifier: category_identifier parent: parent_category name: name assigned_content_tab: false ``` ### Hide menu item By default, for each taxonomy, a menu item is added to the main menu. You can hide this menu item by setting a value of the `register_main_menu` configuration key: ```yaml ibexa_taxonomy: taxonomies: # existing keys content_categories: # existing keys register_main_menu: false ``` For more information about available functionalities of tags, see [User Documentation](https://doc.ibexa.co/projects/userguide/en/6.0/content_management/taxonomy/taxonomy/). ## Hide delete button on large subtree The **Delete** button can be hidden when a taxonomy entry has many children. By default, the button is hidden when there are 100 children or more. The `delete_subtree_size_limit` configuration is [SiteAccess-aware](https://doc.ibexa.co/en/saas/multisite/siteaccess/siteaccess_aware_configuration/index.md), and can be set per SiteAccess, per SiteAccess group, or globally per default. For example: ```yaml ibexa: system: default: # or a SiteAccess, or a SiteAccess group taxonomy: admin_ui: delete_subtree_size_limit: 20 ``` ## Taxonomy suggestions Once the feature is [enabled](#enable-taxonomy-suggestions), with taxonomy suggestions, editors can pick from suggestions generated by an AI service based on selected fields like the product's or content item's name and description instead of having to manually browse through taxonomy trees and selecting [product categories](https://doc.ibexa.co/projects/userguide/en/6.0/product_catalog/work_with_product_categories/#assign-product-categories-by-editing-product-details) or [tags](https://doc.ibexa.co/projects/userguide/en/6.0/content_management/create_edit_content_items/#add-taxonomy-entries). Taxonomy suggestions build on existing [AI Actions](https://doc.ibexa.co/en/saas/ai/ai_actions/ai_actions_guide/index.md) functionality. The `TaxonomyEmbeddingFieldProviderInterface` service uses an existing taxonomy tree as reference, generating an embedding for each path in the taxonomy tree and storing it in the search index. For performance reasons, embeddings for the taxonomy tree entries are generated only in two cases: - when the search engine is reindexed, for example, right after you enable the feature - when an individual taxonomy entry is created or modified, it's embedding is updated When the editor creates or edits a content item or a product, they can request that the application suggests tags or product categories to be associated with the item. When it happens, the `Ibexa\Taxonomy\ActionHandler\TextToTaxonomyActionHandler` requests that an embedding is generated based on selected fields such as, for example, name and description. > **Note: Field selection** > > You select the actual text fields, whose values are used as source for the embedding generation, when you create an [AI action](https://doc.ibexa.co/projects/userguide/en/6.0/ai_actions/work_with_ai_actions/#create-ai-actions-that-use-ibexa-connect) that uses the `text-to-taxonomy` handler. The search engine then compares the generated embedding with the taxonomy path embeddings stored in its index. By default, it selects the three best-matching taxonomy paths and presents them to the editor as suggestions. The user can accept the suggestions, reject them, or request a new set of suggestions directly from the user interface. ### Enable Taxonomy suggestions Taxonomy suggestions are built into the product and do not require additional installation. However, before you can enable it, make sure the following prerequisites have been fulfilled: - Search engine: Taxonomy suggestions require a search engine that supports vector search. The feature has been tested to work with Elasticsearch or Solr 9.8.1+. - [AI Actions](https://doc.ibexa.co/en/saas/ai/ai_actions/ai_actions/index.md): To be able to process embeddings, Taxonomy suggestions require that you have the AI Actions configured to support the default [OpenAI](https://doc.ibexa.co/en/saas/ai/ai_actions/configure_ai_actions/#configure-access-to-openai) or the optional [Google Gemini](https://doc.ibexa.co/en/saas/ai/ai_actions/configure_ai_actions/#configure-google-gemini-connector) service. > **Note: Alternative embeddings provider** > > To use Google Gemini as an alternative embeddings provider, you must also modify the default [taxonomy suggestions settings](https://doc.ibexa.co/en/saas/content_management/taxonomy/taxonomy/#change-embeddings-provider-to-google-gemini). #### Enable taxonomy embedding indexing Enable embedding indexing for taxonomy branches by changing the default setting from `false` to `true`. Toggle this setting at any time to enable or disable indexing of taxonomy embeddings. ```yaml ibexa: system: default: taxonomy: search: index_embeddings: true default_embedding_model: 'text-embedding-ada-002' ``` #### Configure AI action Once you enable the Taxonomy suggestions feature, you must [configure an AI action](https://doc.ibexa.co/projects/userguide/en/6.0/ai_actions/work_with_ai_actions/#create-ai-actions-that-control-taxonomy-suggestions) that handles the generation of embeddings for newly created or edited content items or products. That's where you decide which exact fields from which content type should be used as input for embedding generation, how many suggestions are being presenter to the editor, and so on. After you do it, your users are be able to assign tags and/or product categories by using suggestions provided by an AI engine. ### Customize Taxonomy suggestions You can modify the default behavior of the Taxonomy suggestions model by changing various settings. #### Change default number of suggestions By default, the system returns three suggestions. You can change the default number if needed by altering the following setting: ```yaml ibexa_taxonomy: text_to_taxonomy: default_suggested_taxonomies_limit: 5 ``` You can also override this setting per AI action by editing its configuration. #### Change default fields parsed when generating suggestions The following setting decides which fields are used to generate suggestions by default. You can change the default setting, if needed. ```yaml ibexa: system: default: content_type_field_type_groups: configurations: vectorizable_fields: - ibexa_string - ibexa_text - ibexa_richtext ``` This way you can limit field selection to meaningful text fields and avoid unsupported field types. Like in the case of the number of suggestions, you can override this setting per AI action by editing its configuration. > **Tip: Tip** > > When selecting the input data for embedding creation, it's recommended to include only the essential information and limit the number of tokens sent. Otherwise, the embedding models can generate values that don't correspond closely to the actual meaning of the input. ### Change embedding generation models or embedding provider By default, the system comes with a set of OpenAI models that can be used for embedding generation. The following example shows these models listed in system configuration, together with a setting that controls what model is used when the editor requests taxonomy suggestions for an item. Also, here is where you can change the name of the model used by the provider, the embedding's dimensions, and other settings. ```yaml ibexa: system: default: embedding_models: text-embedding-3-small: name: 'text-embedding-3-small' dimensions: 1536 field_suffix: '3small' embedding_provider: 'ibexa_openai' text-embedding-3-large: name: 'text-embedding-3-large' dimensions: 3072 field_suffix: '3large' embedding_provider: 'ibexa_openai' text-embedding-ada-002: name: 'text-embedding-ada-002' dimensions: 1536 field_suffix: 'ada002' embedding_provider: 'ibexa_openai' default_embedding_model: 'text-embedding-ada-002' ``` > **Caution: Change both embedding generation models** > > When you change the default suggestions generation model, ensure that you update the `ibexa.system.default.taxonomy.search.default_embedding_model` setting that is used for taxonomy indexing purposes. Otherwise the taxonomy suggestions feature fails to find matching entries. #### Change embeddings provider to Google Gemini Once you have configured the [Google Gemini connector](https://doc.ibexa.co/en/saas/ai/ai_actions/configure_ai_actions/#configure-google-gemini-connector), you can modify the default configuration to use the `ibexa_gemini` embedding provider and one of the [supported models](https://ai.google.dev/gemini-api/docs/embeddings): ```yaml ibexa: system: default: embedding_models: gemini_embedding_001_1536: name: 'gemini-embedding-001' dimensions: 1536 field_suffix: 'gemini_embedding_001_1536_dv' embedding_provider: 'ibexa_gemini' gemini_embedding_001_3072: name: 'gemini-embedding-001' dimensions: 3072 field_suffix: 'gemini_embedding_001_3072_dv' embedding_provider: 'ibexa_gemini' default_embedding_model: 'gemini_embedding_001_1536' # ... taxonomy: search: index_embeddings: true default_embedding_model: 'gemini_embedding_001_1536' ``` After you make the change, ensure that the search index field definitions match the dimensions (for example, 1536 or 3072) and the suffixes that you defined above. # Images > For the complete documentation index, see [llms.txt](https://doc.ibexa.co/en/saas/llms.txt). Manage image assets by using DAM systems, configuring image variations, optimizing and using placeholders. Images are an integral part of any website. They can serve as decoration and convey information. In Cohesivo, you can reuse them, normalize their file names, generate different size variations, resize images programmatically, or even define placeholders for missing ones. ## Images from DAM systems If your installation is connected to a DAM system, you can use images directly from a DAM system in your content. Specific [DAM configuration](https://doc.ibexa.co/en/saas/content_management/images/add_image_asset_from_dam/#dam-configuration) depends on the system that the installation uses. ## Reuse images You can store images in the media library as independent content items of a generic Image [content type](https://doc.ibexa.co/en/saas/administration/content_organization/content_types/index.md) to reuse them across the system. You do this by uploading images to an [ImageAsset](https://doc.ibexa.co/en/saas/content_management/field_types/field_type_reference/imageassetfield/index.md) field type. For an ImageAsset field to be reused, you must publish it. Only then is notification triggered, which states that an image has been published under the location and can now be reused. After you establish a media library, you can create [Relations](https://doc.ibexa.co/en/saas/content_management/content_relations/index.md) between the image content item and the main content item that uses it. ## Configuring image variations With image variations (image aliases) you can define and use different versions of the same image. You generate variations based on filters that modify aspects such as size and proportions, quality or effects. Image variations are generated with [LiipImagineBundle](https://github.com/liip/LiipImagineBundle), by using the underlying [Imagine library](https://imagine.readthedocs.io/en/latest/). The LiipImagineBundle bundle supports GD (default), Imagick or Gmagick PHP extensions, and enables you to define flexible filters in PHP. Image files are stored by using the `IOService,` and are completely independent from the Image field type. They're generated only once and cleared on demand, for example, on content removal). LiipImagineBundle only works on image blobs, so no command line tool is needed. For more information, see the [bundle's documentation](https://symfony.com/bundles/LiipImagineBundle/current/configuration.html). > **Caution: Code injection in images** > > Images must be treated like any other user-submitted data - as potentially malicious. > > - EXIF metadata of an image may contain for example, HTML, JavaScript, or PHP code. Cohesivo itself doesn't parse EXIF metadata, but third-party bundles must be secured against this eventuality. Make sure that metadata is properly escaped before use. > - Images may contain specially crafted flaws that exploit vulnerabilities in common image libraries like GD or Imagick, leading to code execution. It's important to keep these libraries up to date with security updates. ## Generating placeholder images With a placeholder generator you can download or generate placeholder images for any missing image. It proves useful when you're working on an existing database and are unable to download uploaded images to your local development environment, due to, for example, a large size of files. If the original image cannot be resolved, the `PlaceholderAliasGenerator::getVariation` method generates a placeholder by delegating it to the implementation of the [PlaceholderProvider](https://github.com/ibexa/core/blob/6.0/src/bundle/Core/Imagine/PlaceholderProvider.php) interface, and saves it under the original path. In Cohesivo, there are two implementations of the `PlaceholderProvider` interface: - [GenericProvider](#genericprovider) - [RemoteProvider](#remoteprovider) ### GenericProvider The [`GenericProvider`](https://github.com/ibexa/core/blob/6.0/src/bundle/Core/Imagine/PlaceholderProvider.php) package generates placeholders with basic information about the original image (see [example 1](#configuration-examples)). ![Placeholder image GenericProvider](https://doc.ibexa.co/en/saas/content_management/img/placeholder_info.jpg "Example of a generic placeholder image") ![Placeholder GenericProvider](https://doc.ibexa.co/en/saas/content_management/img/placeholder_generic_provider.png "Generic placeholder images on a page") | Option | Default value | Description | Required? | | ---------- | --------------------------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------- | --------- | | fontpath | n/a | Path to the font file (\*.ttf). | Yes | | text | "IMAGE PLACEHOLDER %width%x%height%\\n(%id%)" | Text which is displayed in the image placeholder. %width%, %height%, %id% in it's replaced with width, height and ID of the original image. | | | fontsize | 20 | Size of the font in the image placeholder. | | | foreground | #000000 | Foreground color of the placeholder. | | | secondary | #CCCCCC | Secondary color of the placeholder. | | | background | #EEEEEE | Background color of the placeholder. | | ### RemoteProvider With the [`RemoteProvider`](https://github.com/ibexa/core/blob/6.0/src/bundle/Core/Imagine/PlaceholderProvider/RemoteProvider.php) you can download placeholders from: - remote sources, for example, (see [example 2](#configuration-examples)) - live version of a site (see [example 3](#configuration-examples)) ![Placeholder RemoteProvider - placecats.com](https://doc.ibexa.co/en/saas/content_management/img/placeholder_remote_provider.jpg "Remote placeholder images on a page") | Option | Default value | Description | | ----------- | ------------- | ------------------------------------------------------------------------------------------------------ | | url_pattern | '' | URL pattern. %width%, %height%, %id% in it's replaced with width, height and ID of the original image. | | timeout | 5 | Period of time before timeout, measured in seconds. | ### Semantic configuration Placeholder generation can be configured for each [`binary_handler`](https://doc.ibexa.co/en/saas/content_management/file_management/file_management/#handling-binary-files) under the `ibexa.image_placeholder` [configuration key](https://doc.ibexa.co/en/saas/administration/configuration/configuration/#configuration-files): ```yaml ibexa: # ... image_placeholder: : provider: options: ``` If there is no configuration assigned to the `binary_handler`, the placeholder generation is disabled. #### Configuration examples ##### Example 1 - placeholders with basic information about original image ```yaml ibexa: image_placeholder: default: provider: generic options: fontpath: '%kernel.project_dir%/src/Resources/font/font.ttf' background: '#EEEEEE' foreground: '#FF0000' text: 'MISSING IMAGE %%width%%x%%height%%' ``` ##### Example 2 - placeholders from remote source ```yaml ibexa: image_placeholder: default: provider: remote options: url_pattern: 'https://placecats.com/%%width%%/%%height%%' ``` ##### Example 3 - placeholders from live version of a site ```yaml ibexa: image_placeholder: default: provider: remote options: url_pattern: 'http://example.com/var/site/storage/%%id%%' ``` ## Image optimization JPEG images are optimized using the ImageMagic library, which is available out of the box. If you use other formats, such a PNG, SVG, GIF, or WEBP, and you use the Image Editor, to prevent images increasing in size when you modify them in the editor, you need to install additional image handling libraries. | Image format | Library | | ------------ | ---------------------------- | | JPEG | JpegOptim | | PNG | Either OptiPNG or Pngquant 2 | | SVG | SVGO 1 | | GIF | Gifsicle | | WEBP | cwebp | Install these libraries using your package manager, for example: ```bash sudo apt-get install optipng ``` ## Embedding images in Rich Text The [RichText](https://doc.ibexa.co/en/saas/content_management/field_types/field_type_reference/richtextfield/index.md) field allows you to embed other content items within the field. Content items that are identified as images are rendered in the Rich Text field by using a dedicated template. You can determine content types that are treated as images and rendered. You do this by overriding the `ibexa.content_view.image_embed_content_types_identifiers` parameter, for example: ```yaml parameters: ibexa.content_view.image_embed_content_types_identifiers: [image, photo, banner] ``` You can set the template that is used when rendering embedded images in the `ibexa.default_view_templates.content.embed_image` container parameter: ```yaml parameters: ibexa.default_view_templates.content.embed_image: '@ibexadesign/content/view/embed/image.html.twig' ``` # Configure Image Editor > For the complete documentation index, see [llms.txt](https://doc.ibexa.co/en/saas/llms.txt). Configure image editor to crop, flip, and modify images. When a content item contains fields of the [`ibexa_image`](https://doc.ibexa.co/en/saas/content_management/field_types/field_type_reference/imageassetfield/index.md) type, users can perform basic image editing functions with the Image Editor. For more information, see [User Documentation](https://doc.ibexa.co/projects/userguide/en/6.0/image_management/edit_images/). > **Note: Note** > > The Image Editor doesn't support images that come from a Digital Asset Management (DAM) system. > **Note: Note** > > If you intend to modify images in formats other than JPEG in image editor, consider [adding a library to optimize them](https://doc.ibexa.co/en/saas/content_management/images/images/#image-optimization). ## Configuration You can modify the default settings to change the appearance or behavior of the Image Editor. You can also expand the default set of parameters to create buttons that may be required by custom features that you add by extending the Image Editor, for example, to enable changes to the color palette of an image. To do this, under the `ibexa.system..image_editor` [configuration key](https://doc.ibexa.co/en/saas/administration/configuration/configuration/#configuration-files) add a settings tree similar to the following example. The settings tree can contain one or more action groups. You can control the order of actions within a group by setting the `priority` parameter. You can also toggle the visibility of actions within the user interface. Image Editor settings are [SiteAccess-aware](https://doc.ibexa.co/en/saas/administration/configuration/dynamic_configuration/index.md). The following example sets the aspect ratio values and label names for buttons used by the Crop feature. ```yaml ibexa: system: default: image_editor: action_groups: default: id: default label: Default actions: crop: id: crop priority: 1 visible: true buttons: 1-1: label: 1:1 ratio: x: 1 y: 1 3-4: label: 3:4 ratio: x: 3 y: 4 4-3: label: 4:3 ratio: x: 4 y: 3 16-9: label: 16:9 ratio: x: 16 y: 9 custom: label: Custom ``` ### Image file size optimization #### Image quality You can configure the quality of the images modified in the Image Editor with the following configuration. The setting accepts values between 0 and 1, which corresponds to the compression level, with 0 being the strongest compression. The default quality is 0.92: ```yaml ibexa: system: default: image_editor: image_quality: 0.8 ``` #### Gaussian blur strength You can configure the gaussian blur strength applied during image optimization with the following configuration. ```yaml ibexa: system: default: image_editor: gaussian_blur_strength: 0.05 ``` The setting accepts float values between 0 and 10.0, where higher values increase blur and reduce file size, while lower values maintain sharpness. The default value is 0.05. Processing large images with high blur values (above 5) can be time-consuming and may result in request timeouts. Keep this in mind when configuring blur strength for environments that handle high-resolution images, and adjust [PHP's `max_execution_time`](https://www.php.net/manual/en/info.configuration.php#ini.max-execution-time) if needed. ### Additional information Each image can be accompanied by additional information that isn't visible to the user. By default, additional information stores the coordinates of the [focal point](https://doc.ibexa.co/projects/userguide/en/6.0/image_management/edit_images/#focal-point), but you can use this extension point to pass various parameters of custom features that you add by extending the Image Editor. # Add Image Asset from Digital Asset Management > For the complete documentation index, see [llms.txt](https://doc.ibexa.co/en/saas/llms.txt). Configure a Digital Asset Management connector. With the Digital Asset Management (DAM) system connector you can use assets such as images directly from the DAM in your content. ## DAM configuration You can configure a connection with a Digital Asset Management (DAM) system under the `ibexa.system..content.dam` [configuration key](https://doc.ibexa.co/en/saas/administration/configuration/configuration/#configuration-files). ```yaml ibexa: system: default: content: dam: [ dam_name ] ``` The configuration for each connector depends on the requirements of the specific DAM system. Cohesivo provides a connector for [Unsplash](https://unsplash.com/). ## Add Image Asset in Page Builder To add Image Assets directly in the Page Builder, you can do it by using the Embed block. The example below shows how to add images from [Unsplash](https://unsplash.com/). Every image variation that the connector may request must be declared for the connector. In your [configuration file](https://doc.ibexa.co/en/saas/administration/configuration/configuration/#configuration-files) add the following configuration: ```yaml dam_unsplash: application_id: utm_source: variations: 770px: fm: jpg q: 80 w: 770 fit: max ``` You can customize the parameters according to your needs. The `770px` variation declared above is an `unsplash`-specific image variation. For more information about supported parameters, see the [Unsplash documentation](https://unsplash.com/documentation#dynamically-resizable-images). In the back office, go to **Admin** > **Content types**. In the **Content** group, create a content type for DAM images, which includes the ImageAsset field. Now, when you use the Embed block in the Page Builder, you should see a DAM Image. For more information about block configuration, see [Page blocks](https://doc.ibexa.co/en/saas/content_management/pages/page_blocks/index.md). # Fastly Image Optimizer (Fastly IO) > For the complete documentation index, see [llms.txt](https://doc.ibexa.co/en/saas/llms.txt). Configure Fastly Image Optimizer. The Fastly Image Optimizer (Fastly IO) is an external service that provides real-time image optimization for multiple input and output formats. It serves and caches image requests from your origin server, making your website faster and more efficient. To be able to configure this feature, you need [Fastly IO subscription](https://www.fastly.com/documentation/guides/full-site-delivery/image-optimization/about-fastly-image-optimizer/). ## Enable shielding To use Fastly Image Optimizer, you first need a working setup of Cohesivo and Fastly with shielding enabled. To enable shielding, follow the steps in [Fastly Developer Documentation](https://www.fastly.com/documentation/guides/concepts/shielding/#enabling-and-disabling-shielding). Remember to choose a shield location from the **Shielding** menu, as described in [Fastly User Documentation](https://www.fastly.com/documentation/guides/getting-started/hosts/shielding/#enabling-shielding). ## VCL configuration To manipulate your Fastly VCL configuration directly from the command line, you need to: - [install Fastly CLI](https://www.fastly.com/documentation/reference/tools/cli/#installing), - define `FASTLY_SERVICE_ID` and `FASTLY_KEY` environmental variables, - set optimizer restrictions by using the `ibexa_image_optimizer.vcl` file: ```vcl # Restrict optimizer by file path and extension if (req.url.ext ~ "(?i)^(gif|png|jpe?g|webp)$") { if (req.url.path ~ "^/var/([a-zA-Z0-9_-]+)/storage/images") { set req.http.x-fastly-imageopto-api = "fastly"; } } ``` You can customize what image formats are included, for example: `gif|png|jpe?g|webp`, and which paths should be used as a source of images, for example: `^/var/([a-zA-Z0-9_-]+)/storage/images`. For more configuration options, see [Enabling image optimization](https://www.fastly.com/documentation/reference/io/#enabling-image-optimization). To apply your modifications or use the default configuration as-is, you can upload the `.vcl` file from the command line: ```bash fastly vcl snippet create --name="Ibexa Image Optimizer" --version=active --autoclone --type recv --content=vendor/ibexa/fastly/fastly/ibexa_image_optimizer.vcl fastly service-version activate --version=latest ``` ## Define SiteAccess for Fastly IO Fastly IO configuration is SiteAccess aware. You can define what handler should be used for a specific SiteAccess under `variation_handler_identifier` [configuration key](https://doc.ibexa.co/en/saas/administration/configuration/configuration/#configuration-files). You need to set it up as `fastly`, so Fastly IO can generate all image links. By default, it's set as `alias`, and it points to a built-in image optimizer. You can also set up a custom handler if your setup requires it. ```yaml ibexa: system: my_siteaccess: variation_handler_identifier: 'fastly' ``` ## Image configuration When you define image variation keys for Fastly IO, keep in mind that they should reflect variations in your original setup. The built-in image optimizer serves as backup to Fastly IO in case of misconfiguration, so it needs to be able to serve the same image variations. Fastly IO image filters aren't compatible with Ibexa built-in filters, so you aren't able to reflect your original filters accurately with Fastly. The script below helps you find replacement filters within Fastly configuration for the basic filters. For more optimization options on Fastly side, see [Fastly IO reference](https://www.fastly.com/documentation/reference/io/). The following configuration defines the same variations for Fastly IO: ```yaml ibexa: system: default: fastly_variations: reference: reference: original configuration: width: 600 height: 600 fit: bounds small: reference: reference configuration: width: 100 height: 100 fit: bounds tiny: reference: reference configuration: width: 30 height: 30 fit: bounds medium: reference: reference configuration: width: 200 height: 200 fit: bounds large: reference: reference configuration: width: 300 height: 300 fit: bounds gallery: reference: original configuration: { } ezplatform_admin_ui_profile_picture_user_menu: reference: reference configuration: width: 30 height: 30 fit: bounds crop: '30,30,x0,y0' ``` You can select defined image variations during content item creation in the image options. Variations can include different sizing options and other filters that are applied to the image. ![Fastly image variations](https://doc.ibexa.co/en/saas/content_management/img/fastly_variations.png) # RichText > For the complete documentation index, see [llms.txt](https://doc.ibexa.co/en/saas/llms.txt). RichText is a type of field that you add in any content item in Cohesivo and edit in Online Editor. RichText is a type of field that you add in any content item in Cohesivo and edit in Online Editor. - [Online Editor product guide](https://ez-systems-developer-documentation--3403.com.readthedocs.build/en/3403/content_management/rich_text/online_editor_guide/): Learn how to use the Online Editor, a tool that allows you to edit RichText Fields in any content item in Cohesivo. # Online Editor product guide > For the complete documentation index, see [llms.txt](https://doc.ibexa.co/en/saas/llms.txt). Learn how to use the Online Editor, a tool that allows you to edit RichText Fields in any content item in Cohesivo. ## What is Online Editor Online Editor is the interface for editing RichText fields in any content item in Cohesivo. It offers standard editing capabilities and extensibility points to customize the editing experience and the available elements. Online Editor is based on [CKEditor 5](https://ckeditor.com/ckeditor-5/). ## Availability Online Editor is available in all supported Cohesivo versions. ## How to get started Online Editor is the default editing interface for all RichText fields. To start using it, create any content item with a RichText field (for example, based on the built-in Article content type) and edit this field. ## Capabilities ### Rich Text editor Online Editor covers all fundamental formatting options for rich text, such as headings, lists, tables, inline text formatting, anchors, and links. It also allows embedding other content from the repository, but also from Facebook, Twitter, or YouTube. #### Links All links added to a RichText field by using the link element are listed and can be managed in the [Link manager](https://doc.ibexa.co/en/saas/content_management/url_management/url_management/index.md). #### Distraction free mode While editing Rich Text fields, you can switch to distraction free mode that expands the workspace to full screen. ![Distraction free mode](https://doc.ibexa.co/en/saas/content_management/img/distraction_free_mode.png) For more information, see [Distraction free mode](https://doc.ibexa.co/projects/userguide/en/6.0/content_management/create_edit_content_items/#distraction-free-mode). ### Custom tags Custom tags are customizable RichText elements for which you can specify attributes and render them with custom templates. Custom tags can be created by means of specifying two things only: - YAML configuration - relevant Twig templates The YAML configuration defines a custom tag’s attributes, the template used to render it, and where in the toolbar the tag is available. ### Custom styles Custom styles allow specifying custom predefined templates for specific RichText elements. Custom styles differ from custom tags in that they don't have attributes configured. A custom style requires YAML configuration that points to a template used to render an elements with this style. ### Custom data attributes and CSS classes For each RichText element type, you can configure custom data attributes or CSS classes that the user can select when working in Online Editor. Custom data attributes allow adding new attributes to existing Rich Text elements, such as headings or lists, which are added in the form of `data-ezattribute-=""`. Custom CSS classes work in a similar way, giving editor a choice of classes to add to any type of element. ### Plugins Online Editor is based on CKEditor 5. ## Benefits ### Familiar editing tools Online editor offers rich text editing tools familiar to most editors and contributors, which allows quick adoption to the editorial flow. ![Familiar editing tools](https://doc.ibexa.co/en/saas/content_management/rich_text/img/familiar_editing_tools.png) The editor's toolbars can be customized and reorganized to for the specific project's needs. ### Customizable text elements The range of available text elements can be extended by offering custom elements and custom formatting options. Custom formatting options can be offered either as custom CSS classes that editors can add to specific elements, or as custom styles which can have their own templates. More extensive customization is available via custom tags: - completely custom RichText elements that you can fully configure - custom CKEditor 5 plugins ## Use cases ### Customizable Call to action buttons Online Editor extensibility offers a simple way to create custom elements such as Call to action (CTA) buttons. Creating a CTA custom tag lets you use a template to construct a button element. Then, you can add a link attribute to provide target for the button, and a style attribute with different presets to style its look. ![Call to action buttons](https://doc.ibexa.co/en/saas/content_management/rich_text/img/call_to_action_buttons.png) ### Product marketing campaigns With the Online Editor, editors can embed products from the product catalog directly into RichText fields. Products can be embedded as block-level or inline elements. You can use it to weave marketing content around your product data, showcasing your product capabilities and bringing it closer to your customers. See [Embed products in content](https://doc.ibexa.co/en/saas/product_catalog/products/#embed-products-in-content) for details. ### Embed external resources Custom tags allow embedding content from external resources inside RichText fields. The built-in elements offer embedding of Twitter or Facebook posts, but you can extend the capability by embedding other resources. These can be, for example, 3D product, or real estate viewers. # File management > For the complete documentation index, see [llms.txt](https://doc.ibexa.co/en/saas/llms.txt). Configurations and management of binary files. ## Handling binary files Cohesivo supports multiple binary file handling mechanisms by means of an `IOHandler` interface. This feature is used by the [BinaryFile](https://doc.ibexa.co/en/saas/content_management/field_types/field_type_reference/imagefield/index.md) field types. ### Native IO handler The IO API is organized around two types of handlers, both used by the IOService: - `Ibexa\Core\IO\IOMetadataHandler`: stores and reads metadata (such as validity or size) - `Ibexa\Core\IO\IOBinarydataHandler`: stores and reads the actual binary data You can configure IO handlers using semantic configuration. IO handlers are configurable per SiteAccess. See the default configuration: ```yaml ibexa: system: default: io: metadata_handler: dfs binarydata_handler: nfs ``` The adapter is the *driver* used by Flysystem v2 to read/write files. Adapters are declared using `oneup_flysystem`. Metadata and binary data handlers are configured under `ibexa_io`. See below the configuration for the default handlers. It declares a metadata handler and a binary data handler, both labeled `default`. Both handlers are of type `flysystem`, and use the same Flysystem v2 adapter, labeled `default` as well. ```yaml ibexa_io: binarydata_handlers: nfs: flysystem: adapter: nfs_adapter metadata_handlers: dfs: legacy_dfs_cluster: connection: doctrine.dbal.dfs_connection ``` The `nfs_adapter`'s directory is based on your site settings, and is automatically set to `$var_dir$/$storage_dir$` (for example, `/path/to/ibexa/public/var/site/storage`). #### Permissions of generated files You can configure permissions of generated files under the `ibexa.system..io.permissions` [configuration key](https://doc.ibexa.co/en/saas/administration/configuration/configuration/#configuration-files). ```yaml ibexa: system: default: io: permissions: files: 0750 #default is 0644 directories: 0640 #default is 0755 ``` Both `files` and `directories` are optional. Default values: - 0644 for files - 0755 for directories > **Note: Note** > > Make sure to configure permissions using a number and **not** a string. "0644" is **not** interpreted by PHP as an octal number, and unexpected permissions can be applied. > **Note: Note** > > As SiteAccess configuration Flysystem's v2 native Local NFS adapter isn't supported, the following configuration should be used: > > ```yaml > oneup_flysystem: > adapters: > nfs_adapter: > custom: > service: ibexa.io.nfs.adapter.site_access_aware > ``` ### Native Flysystem v2 handler Cohesivo uses it as the default way to read and write content in form of binary files. Flysystem v2 can use the `local` filesystem, but is also able to read/write to `sftp`, `zip` or cloud filesystems (`azure`, `rackspace`, `S3`). [league/flysystem](https://flysystem.thephpleague.com/docs/) (along with [FlysystemBundle](https://github.com/1up-lab/OneupFlysystemBundle/)) is an abstract file handling library. #### Handler options ##### Adapter To be able to rely on dynamic SiteAccess-aware paths, you need to use Ibexa custom `nfs_adapter`. A basic configuration might look like the following: ```yaml oneup_flysystem: adapters: nfs_adapter: custom: service: ibexa.io.nfs.adapter.site_access_aware ``` To learn how to configure other adapters, see the [bundle's online documentation](https://github.com/1up-lab/OneupFlysystemBundle/blob/main/doc/index.md#step3-configure-your-filesystems). > **Note: Note** > > Only the adapters are used here, not the filesystem configuration described in this documentation. ### DFS Cluster handler For clustering, the platform provides a custom metadata handler that stores metadata about your assets in the database. This is faster than accessing the remote NFS or S3 instance to read metadata. # Binary and Media download > For the complete documentation index, see [llms.txt](https://doc.ibexa.co/en/saas/llms.txt). Create route to to enable binary and media files download. You can restrict files stored in BinaryFile or Media fields to certain user roles. These files aren't publicly downloadable from disk, and are instead served by a route that runs the necessary checks. This route is automatically generated as the `url` property for those field values. ## REST API: `uri` property The `uri` property of Binary fields in REST contains a valid download URL, prefixed with the same host as the REST Request. For [more information about REST API see the documentation](https://doc.ibexa.co/en/saas/api/rest_api/rest_api_usage/rest_api_usage/index.md). # File URL handling > For the complete documentation index, see [llms.txt](https://doc.ibexa.co/en/saas/llms.txt). Manage files URL. ## IO URL decoration By default, images and binary files that are referenced by the content are served from the same server as the application, for example `/var/site/storage/images/3/6/4/6/6463-1-eng-GB/kidding.png`. This is the default semantic configuration: ```yaml ibexa: system: default: io: url_prefix: '$var_dir$/$storage_dir$' ``` `$var_dir$` and `$storage_dir$` are dynamic, [SiteAccess-aware settings](https://doc.ibexa.co/en/saas/multisite/siteaccess/siteaccess_aware_configuration/index.md), and are replaced by their values in the execution context. ## Serving images with nginx One common use case is to use an optimized nginx to serve images in an optimized way. The previous example image could be made available as `http://static.example.com/var/site/storage/images/3/6/4/6/6463-1-eng-GB/kidding.png` by setting up a separate server that maps the `/path/to/ibexa/public/var` directory. The configuration would be as follows: ```yaml ibexa: system: default: io: url_prefix: 'https://static.example.com/$var_dir$/$storage_dir$' ``` > **Caution: Caution** > > For security reasons, don't map `/path/to/ibexa/public/` as Document Root of the static server. Map the `/var/` directory directly to `/path/to/ibexa/public/var` instead. ## `io.url_prefix` Any BinaryFile returned by the public PHP API is prefixed with the value of this setting, internally stored as `ibexa.site_access.config..io.url_prefix`. ### `io.url_prefix` dynamic service container setting Default value: `$var_dir$/$storage_dir$` Example: `/var/site/storage` You can use `io.url_prefix` to configure the default URL decorator service (`ibexa.core.io.default_url_decorator`), used by all binary data handlers to generate the URI of loaded files. It's always interpreted as an absolute URI, meaning that unless it contains a scheme (`http://`, `ftp://`), is prepended with a `/`. This setting is SiteAccess-aware. ### Services #### URL decorators A `Ibexa\Core\IO\UrlDecorator` decorates and undecorates a specified string (URL). It has two mirror methods: `decorate` and `undecorate`. Two implementations are provided: `Prefix`, and `AbsolutePrefix`. They both add a prefix to a URL, but `AbsolutePrefix` ensures that unless the prefix is an external URL, the result is prepended with `/`. Three URL decorator services are introduced: - `Ibexa\Core\IO\UrlDecorator\AbsolutePrefix` used by the binary data handlers to decorate all URIs sent out by the API. Uses `AbsolutePrefix`. - `Ibexa\Core\IO\UrlDecorator\Prefix` used through the `UrlRedecorator` by various legacy elements (for example, converter or storage gateway) to generate its internal storage format for URIs. Uses a `Prefix`, not an `AbsolutePrefix`, meaning that no leading `/` is added. In addition, a URL redecorator service, `Ibexa\Core\IO\UrlDecorator\Prefix`, uses both previously mentioned decorators to convert URIs between what is used on the new stack, and what format legacy expects (relative URLs from the project root). # Pages > For the complete documentation index, see [llms.txt](https://doc.ibexa.co/en/saas/llms.txt). Pages are block-based special types of content that editors can create and modify by using a visual drag-and-drop editor. Pages are block-based special types of content that editors can create and modify by using a visual drag-and-drop editor. - [Page Builder product guide](https://ez-systems-developer-documentation--3403.com.readthedocs.build/en/3403/content_management/pages/page_builder_guide/): Read about the Page Builder - a powerful tool for creating and modifying pages in Cohesivo. - [Page blocks](https://ez-systems-developer-documentation--3403.com.readthedocs.build/en/3403/content_management/pages/page_blocks/): Use blocks to customize the content of a Page with dynamic content. - [Page block attributes](https://ez-systems-developer-documentation--3403.com.readthedocs.build/en/3403/content_management/pages/page_block_attributes/): Page blocks can contain multiple attributes, of both built-in and custom types. - [Page block validators](https://ez-systems-developer-documentation--3403.com.readthedocs.build/en/3403/content_management/pages/page_block_validators/): Set up rules for validating Page block content. # Page Builder product guide > For the complete documentation index, see [llms.txt](https://doc.ibexa.co/en/saas/llms.txt). Read about the Page Builder - a powerful tool for creating and modifying pages in Cohesivo. ## What is page [Page](https://doc.ibexa.co/en/saas/content_management/pages/pages/index.md) is a block-based type of content. You can create and modify it with a visual drag-and-drop editor - Page Builder. Page is divided into zones into which you can drop various dynamic blocks. By editing pages you can customize the layout and content of your website. ### Create page To create a new page: 1. In the main menu, go to **Content**. 2. Select **Content structure**. 3. On the right-side toolbar, click **Create content**. 4. From the list of content items select **Landing Page**. 5. Select the layout and click **Create**. ![Create page](https://doc.ibexa.co/en/saas/content_management/img/create_page.png) ### Edit page You can edit any existing page with the Page Builder. To do it, in the back office go to **Content** and select **Content structure**. Then, from the content tree choose the page and click **Edit**. ## What is Page Builder Page Builder is a visual tool that allows you to create and edit any page in Cohesivo. It's more than managing: it's about building pages, creating customized content and fully-targeted landing pages. Creating pages in Page Builder involves composing content from ready-to-use elements - blocks, properly configured and customized. It's also important to choose a layout - it determines the arrangement of drop zones that contain content elements. ![Page Builder - diagram](https://doc.ibexa.co/en/saas/content_management/img/page_builder_diagram.png) ### Availability Page Builder is available in Cohesivo. ### How does Page Builder work #### Page Builder interface Page Builder has plain and intuitive interface. You can create a Page without having advanced technical skills. ![Page Builder interface](https://doc.ibexa.co/en/saas/content_management/img/page_builder_interface.png) Page Builder user interface consists of: A. Drop zone B. Page blocks / Structure view toolbar C. Settings toolbar (including Fields, Visibility and Schedule settings) D. Mode toolbar (including PC, tablet and mobile mode) E. Buttons: | Button | Description | | ----------------------- | --------------------------------------------------------------------------------------------------------------------------- | | Edit and preview switch | Access main properties of the page, like title and description. | | Preview segments | Access preview of the page for a given segment. | | Timeline button | Access the timeline to preview how the page changes with time. You can also view the list of all upcoming scheduled events. | | View toggler | Toggle through to see how the page is rendered on different devices. | | Page blocks menu | Move Page blocks / Structure view to the other side of the screen. | | Undo | Undo latest change. | | Redo | Redo latest change. | F. Saving options | Option | Description | | ----------------------- | -------------------------------------------------- | | Close | Close the page without saving it. | | Send to review | Save the page and send it to review. | | Publish / Publish later | Publish the page or schedule publishing for later. | | Save draft | Save the page draft\*. | | Delete draft | Delete the page draft. | \*To help you preserve your work, system saves drafts of content items automatically. For more information, see [Autosave](https://doc.ibexa.co/projects/userguide/en/6.0/content_management/content_versions/#autosave). Page Builder has two main views that you can use while creating a page: - Page blocks toolbar - consists of all available elements that you can use by dragging them and dropping on a drop zone. ![Page blocks](https://doc.ibexa.co/en/saas/content_management/img/page_blocks_toolbar.png) - Structure view - shows a structure of the page, including its division into zones and the blocks that it contains. It follows the behavior of the content tree. Structure view has ability to reorder blocks using drag and drop. ![Structure view](https://doc.ibexa.co/en/saas/content_management/img/structure_view.png) ##### Choose layout For newly created Page you can choose a [layout](https://doc.ibexa.co/projects/userguide/en/6.0/content_management/configure_ct_field_settings/#available-page-layouts) which defines the available zones. Applying a layout divides the Page into the defined zones. The zones are placeholders for content items. On the Page creation modal, select the layout and click **Create draft**. Now you're ready to add blocks of content to the Page. The page layouts that an editor has access to are up to you to choose. In the `Select layouts` section, you can select layouts that you want to be available for the Page. ![Switch layout](https://doc.ibexa.co/en/saas/content_management/img/switch_layout_window.png) The default, built-in Page layout has only one zone, but developers can create other layouts in configuration. #### Add blocks To customize your page in Page Builder you need to add blocks. To do it, access Page blocks toolbar, drag page block that you want to use, and drop it on the empty place on a drop zone. When you add a new block to the drop zone, drop it in the blue highlighted area. Before you drop it, a bold line appears - it helps you see the position of the newly added block in relation to other, already added blocks. ![Drop zone line](https://doc.ibexa.co/en/saas/content_management/img/drop_zone_line.png) Ready-to-use blocks available in Cohesivo have their own, unique functions. All available tools and settings, that Page Builder comes with, enable you to customize the content appearing on the page. You can check all ready-to-use blocks available in Page Builder in User Documentation, [Block reference page](https://doc.ibexa.co/projects/userguide/en/6.0/content_management/block_reference/). #### Work with blocks Working with blocks is intuitive. You don't have to worry about placing blocks in the proper place from the start - you can reorder them at any time. You can reorder blocks in a few ways: - drag and drop block in the desired location on a drop zone - select block and use up and down arrow on the keyboard - access Structure view and use 'Move up' and 'Move down' function in the settings of the block or drag and drop to change the position in the structure ![Structure view - drag and drop](https://doc.ibexa.co/en/saas/content_management/img/structure_view_drag_drop.png) You can manage each block by accessing its settings. To do it, click settings icon next to the block's name. ![Block settings](https://doc.ibexa.co/en/saas/content_management/img/block_settings.png) Available settings are: - Move up - allows you to change position of the block on the page by moving it up - Move down - allows you to change position of the block on the page by moving it down - Configuration - allows you to access configuration window - Duplicate - duplicates a block with its settings, by creating a copy of it that appears below the original block - Refresh - refreshes preview of the block - Delete - deletes existing block #### Distraction free mode While configuring blocks that include Rich Text section, for example, Text block, you can switch to distraction free mode that expands the workspace to full screen. ![Distraction free mode](https://doc.ibexa.co/en/saas/content_management/img/distraction_free_mode.png) For more information, see [Distraction free mode](https://doc.ibexa.co/projects/userguide/en/6.0/content_management/create_edit_content_items/#distraction-free-mode). #### Schedule content Page Builder comes with a Scheduler, it allows you to schedule content appearance. You can schedule content to be revealed, or hidden in Page Builder in two ways with: - **Scheduler tab** - it's available in the configuration of all Page blocks. In this tab you can set the date and time when the block becomes visible and when it disappears from a Page. ![Scheduler tab](https://doc.ibexa.co/en/saas/content_management/img/scheduler_tab.png) - **Content Scheduler** - it's one of the blocks available in Page Builder Page blocks menu. To proceed with the schedule, go to **Basic** tab of the block, then click **Select content** and confirm your choice. Then set date and time in the **Content airtime settings** window. ![Content Scheduler](https://doc.ibexa.co/en/saas/content_management/img/content_scheduler.png) For more information, see [Schedule publication](https://doc.ibexa.co/projects/userguide/en/6.0/content_management/schedule_publishing/). ## Benefits ### Manage your pages without technical skills Thanks to intuitive and plain Page Builder interface, you can create and manage your website without the need of having advanced technical skills. Page blocks toolbar, visible page zones and Structure view - these are the elements that make working with Page Builder really intuitive and quick. ### Self schedule content, special offers and campaigns One of the most important tools that Page Builder offers, is a Scheduler. It allows you to set and schedule a specific date and time for the content to be published or hidden. As a result, you can manage timeline of publications, without the need of manual publishing, or hiding each of them. ### Create high-converting and fully-targeted landing pages Page Builder allows you to create highly customizable websites. You can build modifiable and targeted landing pages that meet your needs. Each dynamic blocks has its own settings, properties and design that you can set up in your way to customize the content appearing on the page. Additionally, if you feel comfortable with your technical skills, you can configure your own elements, for example, a new customized layout, or block. ### Increase sales with highly personalized campaigns Personalized campaigns are one of the factors that can increase your sales. With Page Builder you can achieve it, by using customization and time Scheduler. Anytime you can edit your page and change a position of a block to enhance visibility. Additionally, Page Builder offers you a selection of ready-to-use page blocks that can help you to create content tailored to each individual customer: A. **Default** blocks: - Targeting - embeds a content item based on the segment the user belongs to. B. **PIM** blocks: - Catalog - displays products from a specific catalog to a selected customer group. - Product collection - displays a list of specifically selected products. - Product embed - displays a specific product. C. [**Recommendations** blocks](https://doc.ibexa.co/en/saas/recommendations/raptor_integration/recommendation_blocks/index.md) - presents content recommendations delivered by Raptor integration. # Page blocks > For the complete documentation index, see [llms.txt](https://doc.ibexa.co/en/saas/llms.txt). Use blocks to customize the content of a Page with dynamic content. Page blocks are configured in YAML files, under the `ibexa_fieldtype_page` key. Keep in mind that Page block configuration isn't SiteAccess-aware. Cohesivo ships with a number of page blocks. For a list of all page blocks that are available out-of-the-box, see [Page block reference](https://doc.ibexa.co/projects/userguide/en/6.0/content_management/block_reference/). ## Block configuration Each configured block has an identifier and the following settings: | Setting | Description | | ------------------------ | ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | | `name` | Name of the block used in the Page Builder interface. Translatable using the `ibexa_page_fieldtype` translation domain. Also accepts a [`help` key](#block-name-and-help-text) that adds a helper text under the **Name** field in the block configuration form. | | `category` | Category in the Page Builder **Page blocks** toolbox that the block is shown in. Translatable using the `ibexa_page_fieldtype` translation domain. | | `thumbnail` | Thumbnail used in the Page Builder **Page blocks** toolbox. | | `views` | Available [templates for the block](#block-templates). | | `visible` | (Optional) Toggles the block's visibility in the Page Builder **Page blocks** toolbox. Remove the block from the layout before you publish another version of the page. | | `attributes` | (Optional) List of [block attributes](https://doc.ibexa.co/en/saas/content_management/pages/page_block_attributes/index.md). | | `cacheable_query_params` | (Optional) List of query parameters the block's ESI HTTP cache varies on. For example, if the block is paginated using `?page=ℕ` from the page URL, add `page` to this list. | For example: ```yaml ibexa_fieldtype_page: blocks: event: name: event_block.name category: custom_category.name thumbnail: /bundles/ibexaadminuiassets/vendors/ids-assets/dist/img/all-icons.svg#calendar views: default: template: '@ibexadesign/blocks/event/template.html.twig' name: event_block.view.default priority: -255 attributes: # ... ``` ### Block name and help text The `name` setting accepts either a single translation key, a hard coded string of text that won't be translated, or an object with `text` and `help` property keys. Both `text` and `help` are translatable using the `ibexa_page_fieldtype` translation domain. Scalar form: ```yaml ibexa_fieldtype_page: blocks: my_block: name: my_block.name.key ``` Structured form with a helper text: ```yaml ibexa_fieldtype_page: blocks: my_block: name: text: my_block.name.key help: my_block.name.help.key ``` - `text` - corresponds to the block name. - `help` - is an optional translation key whose translation is rendered as a helper text under the **Name** field in the block configuration form. ![Help text](https://doc.ibexa.co/en/saas/content_management/img/help_text.png) The same format is available for [React App blocks](https://doc.ibexa.co/en/saas/content_management/pages/react_app_block/index.md). ### Overwriting existing blocks You can overwrite the following properties in the existing blocks: - `name` - `category` - `thumbnail` - `views` ## Block templates Page blocks can have multiple templates. This allows you to create different styles for each block and let the editor choose them when adding the block from the UI. They names are translatable using the `ibexa_page_builder_block_config` translation domain. ```yaml ibexa_fieldtype_page: blocks: event: views: default: template: '@ibexadesign/blocks/event/template.html.twig' name: event_block.view.default priority: -255 featured: template: '@ibexadesign/blocks/event/featured_template.html.twig' name: event_block.view.featured priority: 50 ``` `priority` defines the order of block views on the block configuration screen. The highest number shows first on the list. > **Tip: Tip** > > Default views have a `priority` of -255. It's good practice to keep the value between -255 and 255. # Page block attributes > For the complete documentation index, see [llms.txt](https://doc.ibexa.co/en/saas/llms.txt). Page blocks can contain multiple attributes, of both built-in and custom types. A block has attributes that the editor fills in when adding the block to a Page. Each block can have the following properties: | Attribute | Description | | ------------ | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | | `type` | Attribute type. | | `name` | (Optional) The displayed name for the attribute. You can omit it, block identifier is then used as the name. Translatable using the `ibexa_page_builder_block_config` translation domain. | | `value` | (Optional) The default value for the attribute. | | `category` | (Optional) The tab where the attribute is displayed in the block edit modal. | | `validators` | (Optional) [Validators](https://doc.ibexa.co/en/saas/content_management/pages/page_block_validators/index.md) checking the attribute value. | | `options` | (Optional) Additional options, dependent on the attribute type. | ## Block attribute types The following attribute types are available: | Type | Description | Options | | --------------------------------------------------------------------------------------------------------------- | ----------------------------------------- | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | | `integer` | Integer value | - | | `string` | String | - | | `url` | URL | - | | `text` | Text block | - | | `richtext` | Rich text block | - | | `embed` | Embedded content item | `udw_config_name`: name of the Universal Discovery Widget's configuration | | `embedvideo` | Embedded content item | `udw_config_name`: name of the Universal Discovery Widget's configuration | | `select` | Drop-down with options to select | - `choices` lists the available options in `label: value` form - `multiple`, when set to true, allows selecting more than one option | | `checkbox` | Checkbox | Selects available option if `value: true`. Checkbox appearance in block configuration forms [can be configured](#configure-checkbox-appearance) | | `multiple` | Checkbox(es) | `choices` lists the available options in `label: value` form. | | `radio` | Radio buttons | `choices` lists the available options in `label: value` form. | | `locationlist` | Location selection | `udw_config_name`: name of the Universal Discovery Widget's configuration | | `contenttypelist` | List of content types | - | | `schedule_events`, `schedule_snapshots`, `schedule_initial_items`, `schedule_slots`, `schedule_loaded_snapshot` | Used in the Content Scheduler block | - | | `nested_attribute` | Defines a group of attributes in a block. | - `attributes` - a list of attributes in the group. The attributes in the group are [configured](#page-block-attributes) as regular attributes - `multiple`, when set to true. New groups are added dynamically with the **+ Add** button | When you define attributes, you can omit most keys as long as you use simple types that don't require additional options: ```yaml attributes: first_field: text second_field: string third_field: integer ``` The `embed`, `embedvideo`, and `locationlist` attribute types use the Universal Discovery Widget (UDW). When creating a block with these types you can use the `udw_config_name` option to configure the UDW behavior. ## Nested attribute configuration The `nested_attribute` attribute is used when you want to create a group of attributes. First, make sure you have configured the attributes you want to use in the group. Next, provide the configuration. See the example: ```yaml ibexa_fieldtype_page: blocks: block_name: category: default thumbnail: 'path/icons.svg' views: default: { name: 'Default block layout', template: 'template.html.twig', priority: -255 } attributes: group: name: Group name type: nested_attribute options: attributes: attribute_1: name: Name 1 type: string attribute_2: name: Name 2 type: string multiple: true ``` To set validation for each nested attribute: ```yaml name: Group name type: nested_attribute options: attributes: attribute_1: name: Name 1 type: string validators: not_blank: message: 'Provide a value' ``` Validators can be also set on a parent attribute (group defining level), it means all validators apply to each nested attribute: ```yaml name: Group name type: nested_attribute options: attributes: attribute_1: name: Name 1 type: string attribute_2: name: Name 2 type: string multiple: true validators: not_blank: message: 'Provide a value' ``` > **Caution: Moving attributes between groups** > > If you move an attribute between groups or add an ungrouped attribute to a group, the block values are removed. ## Help messages for form fields With the `help`, `help_attr`, and `help_html` field options, you can define help messages for fields in the Page block. You can set options with the following configuration: ```yaml ibexa_fieldtype_page: blocks: block_name: attributes: attribute_name: options: help: text: 'Some example text' html: true|false attr: class: 'class1 class2' ``` - `help.text` - defines a help message which is rendered below the field (maps to [`help`](https://symfony.com/doc/7.4/reference/forms/types/form.html#help)) - `help.attr` - sets the HTML attributes for the element which displays the help message (maps to [`help_attr`](https://symfony.com/doc/7.4/reference/forms/types/form.html#help-attr)) - `help.html` - enable (default) / disable (set to `true`) escaping the contents of the `help.text` option when rendering in the template (maps to [`help_html`](https://symfony.com/doc/7.4/reference/forms/types/form.html#help-html)) ### Help message in nested attributes You can set the options for root or nested attribute, see the example configuration: ```yaml ibexa_fieldtype_page: blocks: slider: category: default thumbnail: '/bundles/ibexaadminuiassets/vendors/ids-assets/dist/img/all-icons.svg#edit' views: default: { name: 'Default block layout', template: 'themes/blocks/slider.html.twig', priority: -255 } attributes: group: name: Group name type: nested_attribute options: help: text: 'Root class text' html: true # true|false attr: class: 'root-class-1 root-class-2' attributes: integer: name: Age type: integer validators: not_blank: message: 'Provide a value' options: help: text: 'Nested attribute text' html: true attr: class: 'nested-1 nested-2' string: name: Name type: string validators: not_blank: message: 'Provide a value' ``` ![Help message](https://doc.ibexa.co/en/saas/content_management/img/page_block_help_message.png "Help message") ## Configure checkbox appearance For blocks with an attribute of `checkbox` type, you can change the look of the checkbox in block configuration forms. You can do it by adding the `block_prefix: block_configuration_attribute_checkbox_toggle` option in the block configuration as follows: ```yaml : name: type: checkbox options: block_prefix: block_configuration_attribute_checkbox_toggle ``` This setting changes the checkbox appearance to a toggle widget. ![Toggle widget](https://doc.ibexa.co/en/saas/content_management/img/toggle_widget.png) If you remove the above setting from the configuration, the attribute reverts to the default checkbox appearance. # Page block validators > For the complete documentation index, see [llms.txt](https://doc.ibexa.co/en/saas/llms.txt). Set up rules for validating Page block content. Validators check values passed to Page block attributes. The following block validators are available: - `required` - checks whether the attribute is provided - `regexp` - validates attribute according to the provided regular expression - `not_blank` - checks whether the attribute isn't left empty - `not_blank_richtext` - checks whether a `richtext` attribute isn't left empty - `content_type` - checks whether the selected content types match the provided values - `content_container` - checks whether the selected content item is a container > **Note: Note** > > Don't use the `required` and `not_blank` validators for `richtext` attributes. Instead, use `not_blank_richtext`. For each validator you can provide a message that displays in the Page Builder when an attribute field doesn't fulfill the criteria. Additionally, for some validators you can provide settings under the `ibexa_fieldtype_page.blocks..validators.regexp.options` [configuration key](https://doc.ibexa.co/en/saas/administration/configuration/configuration/#configuration-files), for example: ```yaml email: type: string name: E-mail address validators: regexp: options: pattern: '/^\S+@\S+\.\S+$/' message: Provide a valid e-mail address ``` # React App block > For the complete documentation index, see [llms.txt](https://doc.ibexa.co/en/saas/llms.txt). Create a block that allows an editor to embed a preconfigured React component into a page. React App block allows an editor to embed a preconfigured React application into a page. It's configured in YAML files, under the `ibexa_fieldtype_page` key. Page block configuration isn't SiteAccess-aware. ## React App Block configuration React App blocks are regular [Page blocks](https://doc.ibexa.co/en/saas/content_management/pages/page_blocks/index.md) and can be configured on field definition level as any other block. Their configuration has exactly the same structure as regular [block configuration](https://doc.ibexa.co/en/saas/content_management/pages/page_blocks/#block-configuration), except: - additional `component` attribute which binds Page Builder block with React App - `views` attribute is removed Each configured React app block has an identifier and the following settings: | Setting | Description | | ------------ | ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | | `name` | Name of the block used in the Page Builder interface. Also accepts a [`help` key](https://doc.ibexa.co/en/saas/content_management/pages/page_blocks/#block-name-and-help-text) that adds a helper text under the **Name** field in the block configuration form. | | `category` | Category in the Page Builder **Page blocks** toolbox that the block is shown in. | | `thumbnail` | Thumbnail used in the Page Builder **Page blocks** toolbox. | | `component` | Name of the React app component that this block is bound to. | | `visible` | (Optional) Toggles the block's visibility in the Page Builder **Page blocks** toolbox. Remove the block from the layout before you publish another version of the page. | | `attributes` | (Optional) List of [block attributes](https://doc.ibexa.co/en/saas/content_management/pages/page_block_attributes/index.md). | For example: ```yaml ibexa_fieldtype_page: react_blocks: calculator: name: Calculator category: Demo thumbnail: /bundles/ibexaadminuiassets/vendors/ids-assets/dist/img/all-icons.svg#calendar component: Calculator attributes: a: type: integer b: integer ``` Each entry below `react_blocks` adds one block to the Page Builder with the defined name, category and thumbnail. Both name and attributes support a short syntax and a long one for specifics. `Attributes` defined without sub-keys use the key as the identifier and name, and the value as the type: ```yaml attributes: b: integer ``` Sub-keys can be used to specify any of the usual [attributes configuration](https://doc.ibexa.co/en/saas/content_management/pages/page_block_attributes/index.md) key: ```yaml attributes: a: name: Attribute A type: string options: ... ``` # Ibexa Connect scenario block > For the complete documentation index, see [llms.txt](https://doc.ibexa.co/en/saas/llms.txt). Work with Ibexa Connect scenario block that retrieves and displays data from an Ibexa Connect webhook. Ibexa Connect scenario block retrieves and displays data from an Ibexa Connect webhook. Scenario block is a regular [Page block](https://doc.ibexa.co/en/saas/content_management/pages/page_blocks/index.md) and can be configured on field definition level as any other block. ## Configure Ibexa Connect scenario block in Page Builder To use the Ibexa Connect scenario block, in your Page add the Ibexa Connect block by dragging it from the menu to a drop zone and enter block settings. - In the **Basic** tab in **Webhook link** field, provide a link to an Ibexa Connect webhook, for example, `https://connect.ibexa.co/3/scenarios/688/edit`: ![Ibexa Connect Basic tab](https://doc.ibexa.co/en/saas/content_management/img/ibexa_connect_basic_tab.png) - In the **Design** tab, extend the drop-down list in the **View** field and choose one of the [views configured for the block](https://doc.ibexa.co/en/saas/content_management/pages/page_blocks/#block-templates). ![Ibexa Connect Design tab](https://doc.ibexa.co/en/saas/content_management/img/ibexa_connect_design_tab.png) Click **Submit** button to confirm. After submitting the block, page refreshes and Ibexa Connect block displays data from provided Ibexa Connect webhook. ![Ibexa Connect webhook preview](https://doc.ibexa.co/en/saas/content_management/img/ibexa_connect_webhook_preview.png) # Forms > For the complete documentation index, see [llms.txt](https://doc.ibexa.co/en/saas/llms.txt). Forms are a type of content item that you can use to improve the functionality of your website. Forms are a type of content item that you can use to improve the functionality of your website. - [Form Builder product guide](https://ez-systems-developer-documentation--3403.com.readthedocs.build/en/3403/content_management/forms/form_builder_guide/): See the Form Builder product guide and learn how to create various forms to increase the functionality of your website. - [Forms](https://ez-systems-developer-documentation--3403.com.readthedocs.build/en/3403/content_management/forms/work_with_forms/): Form Builder enables creating dynamic forms to use in surveys, questionnaires, sign-up forms and others. # Form Builder product guide > For the complete documentation index, see [llms.txt](https://doc.ibexa.co/en/saas/llms.txt). See the Form Builder product guide and learn how to create various forms to increase the functionality of your website. ## What is Form Builder Form Builder is a tool that lets you build forms consisting of different fields. By adding forms on the website, you can increase its functionality and improve user experience. Use Form Builder to create various forms, such as survey, questionnaire, sign-up form, using basic form fields available in the Form Builder. You can also manage your forms and review the results gathered from the website users. ## Availability Form Builder is available in Cohesivo. ## How does Form Builder work ### Form Builder interface Form Builder user interface consists of: A. Drop zone B. Form fields toolbar C. Save button D. Search bar E. Discard button ![Form Builder interface](https://doc.ibexa.co/en/saas/content_management/forms/img/form_builder_interface.png) ### Form fields To create forms, you can use available form fields or create custom ones. The available basic form fields are: | Field name | Icon | Description | | ------------------- | ------------------- | -------------------------------------------------------------------------- | | Single line input | Single line input | Single line field for short text. | | Multiple line input | Multiple line input | Multiple line field for longer text. | | Number | Number | Field to set up a number using arrows. | | Checkbox | Checkbox | Single checkbox element with one option value available. | | Checkboxes | Checkboxes | Multiple checkboxes with more than one option values available. | | Radio | Radio | List with multiple option values available and visible. | | Dropdown | Dropdown | Dropdown list with multiple option values available. | | Email | Email | Field to insert an email address. | | Date | Date | Field to insert a date. | | URL | URL | Field to insert an URL address. | | File | File | Interactive field to upload file. | | Captcha | Captcha | Field with captcha and additional blank line to rewrite it. | | Button | Button | Form submit button. | | Hidden field | Hidden field | Field used to submit metadata that should not be visible in rendered form. | ### Create a form Editors can use the created form anywhere on the website. Forms can be used in page blocks, embedded in the online editor or even used as a field relation. The same form can be placed at multiple locations on the website. To learn more, see [Work with forms](https://doc.ibexa.co/projects/userguide/en/6.0/content_management/work_with_forms/). ### Forms management [Form](https://doc.ibexa.co/en/saas/content_management/forms/work_with_forms/index.md) is one of available [content items](https://doc.ibexa.co/projects/userguide/en/6.0/content_management/content_items/) that you can find in the platform. You can work with it as with other regular items, for example, create new one, edit existing one, or move. You can manage all the existing forms. To do it, in a selected place of the content tree find your form and click on it. In this window you can see all the information about your form, view submissions, create versions, and more Using the buttons in the right corner, you can also edit, move, copy, hide, or send your form to the trash. ![Forms management](https://doc.ibexa.co/en/saas/content_management/forms/img/forms_management.png) ### View results You can preview the results of each published form. To do it, go to **Submissions** tab in the content item view: ![View results](https://doc.ibexa.co/en/saas/content_management/forms/img/view_results.png) Here you can view the details of each submission or delete any of them. The **Download submissions** button enables you to download all the submissions in a .CSV (comma-separated value) file. ## Benefits ### General overview With Form Builder you're allowed to build an unlimited number of forms. These forms can be used anywhere on the website and are ready to start collecting information. Form Builder interface is plain, which makes the creation of forms fast and intuitive. ### Forms management Forms can be managed simply and effectively: you can copy them, move, organize into folders, create versions, and delete if necessary. Each field can be configured so that the form collects the exact details that you need. ### Custom Form fields With Form Builder you can use existing Form fields, but also you can extend it by adding new or modifying existing ones. This allows you to create forms that fit your needs. ### Analytic tool All the submissions can are visible in **Submissions** tab. You can download them as a .CSV file for additional analysis. # Forms > For the complete documentation index, see [llms.txt](https://doc.ibexa.co/en/saas/llms.txt). Form Builder enables creating dynamic forms to use in surveys, questionnaires, sign-up forms and others. You can build forms consisting of different fields in the Form Builder. > **Caution: Known limitation** > > To have multiple instances of the same form on one page, create several identical form blocks. Otherwise, you may encounter issues with submitting data from all forms at the same time. ## Existing Form fields ### Captcha field The Captcha Form field is based on [Gregwar/CaptchaBundle](https://github.com/Gregwar/CaptchaBundle). ![Captcha field](https://doc.ibexa.co/en/saas/content_management/img/extending_form_builder_captcha_default.png) You can customize the field by adding configuration under the `gregwar_captcha` key: ```yaml gregwar_captcha: as_url: true width: 150 invalid_message: Code does not match, please retry. reload: true ``` The example configuration above resizes the Captcha image (line 3), changes the error message (line 4), and enables the user to reload the code (line 5). ![Custom captcha field](https://doc.ibexa.co/en/saas/content_management/img/extending_form_builder_captcha_result.png) For information about available options, see [Gregwar/CaptchaBundle's documentation](https://github.com/Gregwar/CaptchaBundle#options). ## Form-uploaded files You can use Forms to enable the user to upload files. The default location for files uploaded in this way is `/Media/Files/Form Uploads`. You can change it with the following configuration: ```yaml ibexa: system: default: form_builder: upload_location_id: 54 ``` This applies only if no specific location is defined in the Form itself. # Workflow > For the complete documentation index, see [llms.txt](https://doc.ibexa.co/en/saas/llms.txt). Workflow controls how content items pass between stages and allows setting up editorial flows, for example for reviews and proofreading. The workflow functionality passes a content item version through a series of stages. For example, an editorial workflow can pass a content item from draft stage through design and proofreading. By default, Cohesivo comes pre-configured with a Quick Review workflow. You can disable the default workflow and define different workflows in configuration. Workflows are permission-aware. ## Workflow configuration Each workflow consists of stages and transitions between them. The following example configuration defines a workflow where you can optionally pass a draft to be checked by the legal team. ![Diagram of custom workflow](https://doc.ibexa.co/en/saas/content_management/img/workflow_custom_diagram.png) ```yaml ibexa: system: default: workflows: custom_workflow: name: Custom Workflow matchers: content_type: [article, folder] content_status: [draft] stages: draft: label: Draft color: '#f15a10' legal: label: Legal color: '#5a10f1' actions: notify_reviewer: ~ done: label: Done color: '#301203' last_stage: true initial_stage: draft transitions: to_legal: from: [draft] to: [legal] label: To legal color: '#8888ba' icon: '/bundles/ibexaadminuiassets/vendors/ids-assets/dist/img/all-icons.svg#alert-error' reviewers: required: true user_group: 13 back_to_draft: reverse: to_legal label: Back to draft color: '#cb8888' icon: '/bundles/ibexaadminuiassets/vendors/ids-assets/dist/img/all-icons.svg#arrow-left' approved_by_legal: from: [legal] to: [done] label: Approved by legal color: '#88ad88' icon: '/bundles/ibexaadminuiassets/vendors/ids-assets/dist/img/all-icons.svg#form-checkbox' actions: publish: ~ done: from: [draft] to: [done] label: Done color: '#88ad88' icon: '/bundles/ibexaadminuiassets/vendors/ids-assets/dist/img/all-icons.svg#form-checkbox' actions: publish: ~ ``` ### Matchers Matchers define when the workflow is used. Their configuration is optional. `content_type` contains an array of content type identifiers that use this workflow. `content_status` lists the statuses of content items which fall under this workflow. The available values are: `draft` and `published`. If set to `draft`, applies for new content (newly created). If set to `published`, applies for content that has already been published (for example, edit after the content was published). ```yaml matchers: content_type: [article, folder] content_status: [draft] ``` ### Stages Each stage in the workflow has an identifier and can have a label and a color. The optional `last_stage` key indicates that content in this stage doesn't appear on the dashboard or in Review Queue. One stage, listed under `initial_stage`, is the one that the workflow starts with. ```yaml stages: draft: label: Draft color: '#f15a10' legal: label: Legal color: '#5a10f1' actions: notify_reviewer: ~ done: label: Done color: '#301203' last_stage: true initial_stage: draft ``` ### Transitions Each transition has an identifier and can have a label, a color, and an icon. A transition must state between which stages it transitions (lines 3-4), or be `reverse` to a different transition (line 9). ```yaml transitions: to_legal: from: [draft] to: [legal] label: To legal color: '#8888ba' icon: '/bundles/ibexaadminuiassets/vendors/ids-assets/dist/img/all-icons.svg#alert-error' back_to_draft: reverse: to_legal label: Back to draft color: '#cb8888' icon: '/bundles/ibexaadminuiassets/vendors/ids-assets/dist/img/all-icons.svg#arrow-left' ``` ### Reviewers When moving a content item through a transition, the user can select a reviewer. Assigning a reviewer is mandatory if you set `reviewers.required` to `true` for this transition. You can restrict who can review the content item by setting `reviewers.user_group` to a location ID of the user group. To be able to search for users for review, the user must have the `content/read` policy without any limitation, or with a limitation that allows reading users. This means that, in addition to your own settings for this policy, you must add the /Users subtree to the limitation and add users in the [content type limitation](https://doc.ibexa.co/en/saas/permissions/limitation_reference/#content-type-limitation). ```yaml transitions: to_legal: from: [draft] to: [legal] label: To legal color: '#8888ba' icon: '/bundles/ibexaadminuiassets/vendors/ids-assets/dist/img/all-icons.svg#alert-error' reviewers: required: true ``` #### Notifications To ensure that the assigned reviewers get a notification of a transition, configure the `actions.notify_reviewer` action for a stage. ```yaml legal: label: Legal color: '#5a10f1' actions: notify_reviewer: ~ ``` The notification is displayed in the user menu: ![Notification about content to review](https://doc.ibexa.co/en/saas/content_management/img/workflow_notification.png) #### Draft locking You can configure draft assignment in a way that when a user sends a draft to review, only the first editor of the draft can either edit the draft or unlock it for editing, and no other user can take it over. Use the [Version Lock limitation](https://doc.ibexa.co/en/saas/permissions/limitation_reference/#version-lock-limitation), set to "Assigned only", together with the `content/edit` and `content/unlock` policies to prevent users from editing and unlocking drafts that are locked by another user. ### Content publishing You can automatically publish a content item once it goes through a specific transition. To do so, configure the `publish` action for the transition: ```yaml done: from: [draft] to: [done] label: Done color: '#88ad88' icon: '/bundles/ibexaadminuiassets/vendors/ids-assets/dist/img/all-icons.svg#form-checkbox' actions: publish: ~ ``` ### Disable Quick Review You can disable the default workflow, for example, if your project doesn't use workflows, or Quick Review entries clog your database: ```yaml ibexa: system: default: workflows: quick_review: name: Quick Review matchers: content_type: [] ``` ## Workflow event timeline Workflow event timeline displays workflow transitions. ## Permissions You can limit access to workflows at stage and transition level. The `workflow/change_stage` policy grants permission to change stages in a specific workflow. You can limit this policy with the [Workflow Transition limitation](https://doc.ibexa.co/en/saas/permissions/limitation_reference/#workflow-transition-limitation) to only allow sending content in the selected transition. For example, by using the example above, a `workflow/change_stage` policy with `WorkflowTransitionLimitation` set to `Approved by legal` allows a legal team to send content forward after they're done with their review. You can also use the [Workflow Stage Limitation](https://doc.ibexa.co/en/saas/permissions/limitation_reference/#workflow-stage-limitation) together with the `content/edit` and `content/publish` Policies to limit the ability to edit content in specific stages. For example, you can use it to only allow a legal team to edit content in the `legal` stage. ## Validation ### Validate form before workflow transition By default, sending content to the next stage of the workflow doesn't validate the form in UI, so with the publish action, the form isn't verified for errors in UI. However, during the publish action, the sent form is validated in the service. Therefore, if there are any errors in the form, you return to the edit page but errors aren't triggered, which can be confusing when you have two or more tabs. To enable form validation in UI before sending it to the next stage of the workflow, add `validate: true` to the transitions of the stage. In the example below the form is validated in two stages: `to_legal` and `done`: ```yaml transitions: to_legal: from: [draft] to: [legal] label: To legal color: '#8888ba' icon: '/bundles/ibexaadminuiassets/vendors/ids-assets/dist/img/all-icons.svg#alert-error' reviewers: required: true user_group: 13 actions: legal_transition_action: data: message: "Sent to the legal department" validate: true back_to_draft: reverse: to_legal label: Back to draft color: '#cb8888' icon: '/bundles/ibexaadminuiassets/vendors/ids-assets/dist/img/all-icons.svg#arrow-left' from: [draft] to: [done] label: Done color: '#88ad88' icon: '/bundles/ibexaadminuiassets/vendors/ids-assets/dist/img/all-icons.svg#form-checkbox' actions: publish: ~ validate: true ``` You can check validation for a particular stage of the workflow even if the stage doesn't have any actions. # URL management > For the complete documentation index, see [llms.txt](https://doc.ibexa.co/en/saas/llms.txt). Manage URL aliases and wildcards, and validate external URLs. You can manage external URL addresses and URL wildcards in the back office, **Admin** tab, the **URL Management** node. Configure URL aliases to have human-readable URL addresses throughout your system. ## Link manager When developing a site, users can enter links to external websites in either RichText or URL fields. Each such link is then displayed in the URL table. You can view and update all external links that exist within the site, without having to modify and re-publish the individual content items. The **Link manager** tab contains all the information about each link, including its status (valid or invalid) and the time the system last attempted to validate the URL address. Click an entry in the list to display its details and check which content items use this link. Edit the entry to update the URL address in all the occurrences throughout the website. > **Note: Note** > > When you edit the details of an entry to update the URL address, the status automatically changes to valid. ## External URL validation You can validate all the addresses from the URL table by executing the `ibexa:check-urls` command. It validates the links by accessing them one by one and updates the value in the Last checked field. If a broken link is found, its status is set to "invalid". The following protocols are currently supported: - `http` - `https` - `mailto` ### Enabling automatic URL validation To enable automatic URL validation, set up a scheduled task to run the `ibexa:check-urls` command periodically. ### Configuration The configuration of external URLs validation is SiteAccess-aware and is stored under the `ibexa.system..url_checker` [configuration key](https://doc.ibexa.co/en/saas/administration/configuration/configuration/#configuration-files), for example: ```yaml ibexa: system: default: url_checker: handlers: http: enabled: true batch_size: 64 https: enabled: true ignore_certificate: false mailto: enabled: false ``` Available options are protocol-specific. For details, see the tables below. #### http/https protocol | Option | Description | Default value | | ------------------ | -------------------------------------------------------------------------------------------- | ------------- | | enabled | Enables link validation. | true | | timeout | Defines the time that the request is allowed to take (in seconds). | 10 | | connection_timeout | Defines the time that the connect phase is allowed to take (in seconds). | 5 | | batch_size | Defines a maximum number of asynchronous requests. | 10 | | ignore_certificate | Decides if the peer's SSL certificate or the certificate name are verified against the host. | false | #### mailto protocol | Option | Description | Default value | | ------- | ------------------------ | ------------- | | enabled | Enables link validation. | true | For more information about Ibexa configuration, see [Configuration](https://doc.ibexa.co/en/saas/administration/configuration/configuration/index.md). ### Custom protocol support You can extend the external URL address validation with a custom protocol. To do this, you must provide a service that implements the [`Ibexa\Bundle\Core\URLChecker\URLHandlerInterface`](https://github.com/ibexa/core/blob/5.0/src/bundle/Core/URLChecker/URLHandlerInterface.php) interface. Then you must register the service with an `ibexa.url_checker.handler` tag, like in the following example: ```yaml app.url_checker.handler.custom: class: 'App\URLChecker\Handler\CustomHandler' tags: - { name: ibexa.url_checker.handler, scheme: custom } ``` The `scheme` attribute is mandatory and has to correspond to the name of the protocol, for instance, `ftp`. ## URL aliases You can define URL aliases for individual content items, for example, when you reorganize the content, and want to provide users with continuity. For each URL alias definition the history of changes is preserved, so that users who have bookmarked the URL addresses of content items can still find the information they desire. > **Note: Note** > > Make sure that you correctly define languages used by the site in the configuration (under the `ibexa.system..languages` key). Otherwise, redirections for the renamed Content with translations in multiple languages may fail to work properly. > **Caution: Legacy storage engine limitation** > > URL aliases that initially had the same name in multiple languages aren't archived. URL aliases aren't SiteAccess-aware. When creating an alias, you can select a SiteAccess to base it on. If the SiteAccess root path (configured in `content.tree_root.location_id`) is different than the default, the prefix path that results from the configured content root is prepended to the final alias path. ### URL alias pattern configuration You can configure how Cohesivo generates URL aliases. The configuration is stored under the `ibexa.url_alias.slug_converter` [configuration key](https://doc.ibexa.co/en/saas/administration/configuration/configuration/#configuration-files), for example: ```yaml ibexa: url_alias: slug_converter: transformation: example_group separator: dash transformation_groups: example_group: commands: - space_normalize - hyphen_normalize - apostrophe_normalize - doublequote_normalize - your_custom_command cleanup_method: url_cleanup ``` | Option | Description | | ----------------------- | --------------------------------------------------------------------------------------------------------- | | `transformation` | Indicates which pattern is used by default. | | `separator` | Decides what separator is used. There are three types of separator available: dash, underscore and space. | | `transformation_groups` | Contains the available patterns for URL generation. | A transformation group consists of an array of commands (see [all available commands](https://github.com/ibexa/core/tree/6.0/src/lib/Resources/slug_converter/transformations)) and a [`cleanupText`](https://github.com/ibexa/core/blob/6.0/src/lib/Persistence/Legacy/Content/UrlAlias/SlugConverter.php#L286). You can make use of pre-defined transformation groups. You can also add your own, with your own set of commands. To add commands to an existing group, provide the group name and list the commands that you want to add. ## URL wildcards With wildcards, you can change the URL address for many content items at the same time, by replacing a portion of the destination's URL address. For example, you might want to shorten the path, or make the path meaningful. For each URL wildcard definition you set the wildcard pattern and its destination. Also, you can decide whether the user sees the content at the address that uses wildcards (Direct type), or is redirected to the original URL address of the destination (Forward type). For example, a URL wildcard called `pictures/*/*` can use `media/images/{1}/{2}` as destination. In this case, accessing `/pictures/home/photo/` loads `/media/images/home/photo/`. You can configure URL wildcards either in the back office, or with the public PHP API. Before you configure URL wildcards, you must enable the feature in configuration: ```yaml ibexa: url_wildcards: enabled: true ``` ### Configuring URL wildcards in the back office The **URL wildcards** tab contains all the information about each URL wildcard. You can delete or modify existing entries, or create new ones. > **Note: Note** > > To be able to modify wildcard support settings in the user interface, you must have the `content/urltranslator` policy. For more information about permissions, see [Permissions](https://doc.ibexa.co/en/saas/permissions/permissions/index.md). # User-generated content > For the complete documentation index, see [llms.txt](https://doc.ibexa.co/en/saas/llms.txt). You can enable users to create new content in the repository by using forms available in the front end of the site. Cohesivo comes with content edition features via the Symfony stack. They're meant to allow the implementation of user-generated content from the front end, without entering the back office. ## Creating a new draft The `content/create/draft` route enables you to create a new draft for the selected content item. Pass the ID of the content item as an argument. For example, `content/create/draft/59` creates a new draft of the content item with ID 59. ## Creating a content item without using a draft The `/content/edit/nodraft` route shows a content item creation form for a given content type: | Argument | Type | Description | | ----------------------- | --------- | -------------------------------------------------------------------------- | | `contentTypeIdentifier` | `string` | The identifier of the content type to create. Example: `folder`, `article` | | `languageCode` | `string` | Language code the content item must be created in. Example: `eng-GB` | | `parentLocationId` | `integer` | ID of the location the content item must be created in. Example: `2` | This means that `/content/create/nodraft/folder/eng-GB/2` enables you to create a Folder in English as a child of location with ID 2. A limited subset of field types is supported: - `TextLine` - `TextBlock` - `Selection` - `Checkbox` - `User` - `Date` - `DateAndTime` - `Time` - `Integer` - `Float` - `URL` ## Editing a content item To edit an existing draft, use the `/content/edit/draft/` route, with the following arguments: | Argument | Type | Description | | -------------- | --------- | ------------------------------------------------------------------------ | | `contentId` | `integer` | ContentId of the item to edit. | | `versionNo` | `integer` | Number of the version to edit. The version must be an unpublished draft. | | `languageCode` | `string` | Language code of the version. Example: `eng-GB` | For example, `/content/edit/draft/1/5/eng-GB` enables you to edit draft 5 of content item 1 in English. # Field types > For the complete documentation index, see [llms.txt](https://doc.ibexa.co/en/saas/llms.txt). Field types define the fields that a content item is built of. Field types are the smallest building blocks of content. Cohesivo comes with many [built-in field types](https://doc.ibexa.co/en/saas/content_management/field_types/field_type_reference/field_type_reference/#available-field-types) that cover most common needs, for example, Text line, Email address, Author list, Content relation, Map location, or Float. Field types are responsible for: - Storing data, either using the native storage engine mechanisms or specific means - Validating input data - Making the data searchable (if applicable) - Displaying fields of this type # Field type reference > For the complete documentation index, see [llms.txt](https://doc.ibexa.co/en/saas/llms.txt). Cohesivo offers a range of built-in field types that cover most common needs when creating content. A field type is the underlying building block of the content model. It consists of two entities: field value and field definition. Field value is determined by values entered into the content field. Field definition is provided by the content type, and holds any user defined rules used by field type to determine how a field value is, for example, validated, stored, retrieved, or formatted. Cohesivo comes with a collection of field types that can be used to build powerful and complex content structures. In addition, it's possible to extend the system by creating custom types for special needs. > **Tip: Tip** > > For general field type documentation, see [field type](https://doc.ibexa.co/en/saas/content_management/field_types/field_types/index.md). Custom field types have to be programmed in PHP. However, the built-in field types are usually enough for typical scenarios. The following table gives an overview of the supported field types that come with Cohesivo. ## Available field types | Field type | Description | Searchable in Legacy Storage engine | Searchable with Solr/Elasticsearch | | ------------------------------------------------------------------------------------------------------------------------------------------------- | --------------------------------------------------------------------------------------------------------- | --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | ---------------------------------- | | [Address](https://doc.ibexa.co/en/saas/content_management/field_types/field_type_reference/addressfield/index.md) | Stores an address. | No | No | | [Author](https://doc.ibexa.co/en/saas/content_management/field_types/field_type_reference/authorfield/index.md) | Stores a list of authors, each consisting of author name and author email. | No | Yes | | [BinaryFile](https://doc.ibexa.co/en/saas/content_management/field_types/field_type_reference/binaryfilefield/index.md) | Stores a file. | Yes | Yes | | [Checkbox](https://doc.ibexa.co/en/saas/content_management/field_types/field_type_reference/checkboxfield/index.md) | Stores a boolean value. | Yes | Yes | | [Content query](https://doc.ibexa.co/en/saas/content_management/field_types/field_type_reference/contentqueryfield/index.md) | Maps an executable repository query to a field. | No | No | | [Country](https://doc.ibexa.co/en/saas/content_management/field_types/field_type_reference/countryfield/index.md) | Stores country names as a string. | Yes[1](#1-note-on-legacy-search-engine) | Yes | | [Customer group](https://doc.ibexa.co/en/saas/content_management/field_types/field_type_reference/customergroupfield/index.md) | Stores customer group to which a user belongs. | Yes, in [Search](https://doc.ibexa.co/en/saas/search/criteria_reference/customergroupid_criterion/index.md) and [Price Search](https://doc.ibexa.co/en/saas/search/criteria_reference/price_customergroup_criterion/index.md) | Yes | | [DateAndTime](https://doc.ibexa.co/en/saas/content_management/field_types/field_type_reference/dateandtimefield/index.md) | Stores a full date including time information. | Yes | Yes | | [Date](https://doc.ibexa.co/en/saas/content_management/field_types/field_type_reference/datefield/index.md) | Stores date information. | Yes | Yes | | [EmailAddress](https://doc.ibexa.co/en/saas/content_management/field_types/field_type_reference/emailaddressfield/index.md) | Validates and stores an email address. | Yes | Yes | | [Float](https://doc.ibexa.co/en/saas/content_management/field_types/field_type_reference/floatfield/index.md) | Validates and stores a floating-point number. | No | Yes | | [Form](https://doc.ibexa.co/en/saas/content_management/field_types/field_type_reference/formfield/index.md) | Stores a form. | No | Yes | | [Image](https://doc.ibexa.co/en/saas/content_management/field_types/field_type_reference/imagefield/index.md) | Validates and stores an image. | No | Yes | | [ImageAsset](https://doc.ibexa.co/en/saas/content_management/field_types/field_type_reference/imageassetfield/index.md) | Stores images in independent content items of a generic Image content type. | No | Yes | | [Integer](https://doc.ibexa.co/en/saas/content_management/field_types/field_type_reference/integerfield/index.md) | Validates and stores an integer value. | Yes | Yes | | [ISBN](https://doc.ibexa.co/en/saas/content_management/field_types/field_type_reference/isbnfield/index.md) | Handles International Standard Book Number (ISBN) in 10-digit or 13-digit format. | Yes | Yes | | [Keyword](https://doc.ibexa.co/en/saas/content_management/field_types/field_type_reference/keywordfield/index.md) | Stores keywords. | Yes[1](#1-note-on-legacy-search-engine) | Yes | | [MapLocation](https://doc.ibexa.co/en/saas/content_management/field_types/field_type_reference/maplocationfield/index.md) | Stores map coordinates. | Yes, with [`MapLocationDistance` Criterion](https://doc.ibexa.co/en/saas/search/criteria_reference/maplocationdistance_criterion/index.md) | Yes | | [Matrix](https://doc.ibexa.co/en/saas/content_management/field_types/field_type_reference/matrixfield/index.md) | Represents and handles a table of rows and columns of data. | No | No | | [Measurement](https://doc.ibexa.co/en/saas/content_management/field_types/field_type_reference/measurementfield/index.md) | Validates and stores a unit of measure, and either a single measurement value, or a pair of range values. | Yes | Yes | | [Media](https://doc.ibexa.co/en/saas/content_management/field_types/field_type_reference/mediafield/index.md) | Validates and stores a media file. | No | Yes | | [Null](https://doc.ibexa.co/en/saas/content_management/field_types/field_type_reference/nullfield/index.md) | Used as fallback for missing field types and for testing purposes. | N/A | N/A | | [Page](https://doc.ibexa.co/en/saas/content_management/field_types/field_type_reference/pagefield/index.md) | Stores a Page with a layout consisting of multiple zones. | N/A | N/A | | [ProductSpecification](https://doc.ibexa.co/en/saas/content_management/field_types/field_type_reference/productspecificationfield/index.md) | Stores product attributes and VAT | Yes but only with [Product Search](https://doc.ibexa.co/en/saas/search/criteria_reference/product_search_criteria/index.md) | Yes | | [Relation](https://doc.ibexa.co/en/saas/content_management/field_types/field_type_reference/relationfield/index.md) | Validates and stores a relation to a content item. | Yes, with both [`Field`](https://doc.ibexa.co/en/saas/search/criteria_reference/field_criterion/index.md) and [`FieldRelation`](https://doc.ibexa.co/en/saas/search/criteria_reference/fieldrelation_criterion/index.md) Criteria | Yes | | [RelationList](https://doc.ibexa.co/en/saas/content_management/field_types/field_type_reference/relationlistfield/index.md) | Validates and stores a list of relations to content items. | Yes, with [`FieldRelation` Criterion](https://doc.ibexa.co/en/saas/search/criteria_reference/fieldrelation_criterion/index.md) | Yes | | [RichText](https://doc.ibexa.co/en/saas/content_management/field_types/field_type_reference/richtextfield/index.md) | Validates and stores structured rich text in XML. | Yes[1](#1-note-on-legacy-search-engine) | Yes | | [Selection](https://doc.ibexa.co/en/saas/content_management/field_types/field_type_reference/selectionfield/index.md) | Validates and stores a single selection or multiple choices from a list of options. | Yes[1](#1-note-on-legacy-search-engine) | Yes | | [TaxonomyEntry](https://doc.ibexa.co/en/saas/content_management/field_types/field_type_reference/taxonomyentryfield/index.md) | Stores information about the Taxonomy tree. | No | Yes | | [TaxonomyEntryAssignment](https://doc.ibexa.co/en/saas/content_management/field_types/field_type_reference/taxonomyentryassignmentfield/index.md) | Makes content taggable by Taxonomy. | No | Yes | | [TextBlock](https://doc.ibexa.co/en/saas/content_management/field_types/field_type_reference/textblockfield/index.md) | Validates and stores a larger block of text. | Yes[1](#1-note-on-legacy-search-engine) | Yes | | [TextLine](https://doc.ibexa.co/en/saas/content_management/field_types/field_type_reference/textlinefield/index.md) | Validates and stores a single line of text. | Yes | Yes | | [Time](https://doc.ibexa.co/en/saas/content_management/field_types/field_type_reference/timefield/index.md) | Stores time information. | Yes | Yes | | [Url](https://doc.ibexa.co/en/saas/content_management/field_types/field_type_reference/urlfield/index.md) | Stores a URL / address. | No | Yes | | [User](https://doc.ibexa.co/en/saas/content_management/field_types/field_type_reference/userfield/index.md) | Validates and stores information about a user. | No | No | **[1] Note on Legacy Search Engine** Legacy Search/Storage Engine index is limited to 255 characters in database design, so formatted and unformatted text blocks only index the first part. In case of multiple selection field types like, for example, Keyword, Selection, or Country, only the first choices are indexed. they're indexed only as a text blob separated by string separator. # Address field type > For the complete documentation index, see [llms.txt](https://doc.ibexa.co/en/saas/llms.txt). This field represents and handles address fields. It allows you to customize address fields per country. | Name | Internal name | Expected input | | --------- | --------------- | --------------------------- | | `Address` | `ibexa_address` | `string`, `string`, `array` | The Address field type is available via the Address Bundle provided by the `ibexa/fieldtype-address` package. ## Inputs | Type | Description | Example | | -------- | --------------------------------------------- | ----------------- | | `string` | Name of the address. | `My home address` | | `string` | Country code in ISO 3166-1 alpha-2 format. | `PL` | | `array` | Additional fields, defined by address format. | see below | ## Validation This field type validates whether `Country` and `Name` fields have been filled out. ### Properties | Property | Type | Description | | ---------- | -------- | --------------------------------------------- | | `$name` | `string` | Name of the address. | | `$country` | `string` | Country code in ISO 3166-1 alpha-2 format. | | `$fields` | `array` | Additional fields, defined by address format. | ## Formats The following default configuration defines default fields for `personal` address type: ```yaml formats: personal: country: default: - region - locality - street - postal_code ``` ### Modifying field configuration ```yaml formats: billing_address: country: DE: - tax_number - city - address - postal_code ``` Adds (or alters) an address format for `DE` country of `billing_address` type. ## Field form types By default, each field is a simple text input with a label made of field identifier. To change the type of field, you need to listen to a specific event. For each field below events are dispatched (in order): ```yaml ibexa.address.field.{FIELD_IDENTIFIER} ibexa.address.field.{FIELD_IDENTIFIER}.{ADDRESS_TYPE} ibexa.address.field.{FIELD_IDENTIFIER}.{ADDRESS_TYPE}.{COUNTRY_CODE} ``` ### Example ```yaml ibexa.address.field.tax_number ibexa.address.field.tax_number.billing_address ibexa.address.field.tax_number.billing_address.DE ``` # Author field type > For the complete documentation index, see [llms.txt](https://doc.ibexa.co/en/saas/llms.txt). This field type allows the storage and retrieval of one or more authors. For each author, it can handle a name and an email address. It's typically used to store information about additional authors who have written/created different parts of a content item. | Name | Internal name | Expected input | Output | | -------- | -------------- | -------------- | -------- | | `Author` | `ibexa_author` | mixed | `string` | ## Properties | Attribute | Type | Description | Example | | --------- | --------------------------------------- | ---------------- | --------- | | `authors` | `\Ibexa\Core\FieldType\Author\Author[]` | List of authors. | See below | Example: ## Hash format The hash format mostly matches the value object. It has the following key `authors`. Example ## Validation This field type doesn't perform any special validation of the input value. ## Settings The Field definition of this field type can be configured with a single option: | Name | Type | Default value | Description | | --------------- | ------- | --------------------------- | --------------------------------------------------------------------------------------------------------------------------------------- | | `defaultAuthor` | `mixed` | `Type::DEFAULT_VALUE_EMPTY` | One of the `DEFAULT_*` constants, used by the administration interface for setting the default Field value. See below for more details. | Following `defaultAuthor` default value options are available as constants in the `Ibexa\Core\FieldType\Author\Type` class: | Constant | Description | | ---------------------- | ----------------------------------------- | | `DEFAULT_VALUE_EMPTY` | Default value is empty. | | `DEFAULT_CURRENT_USER` | Default value uses currently logged user. | # BinaryFile field type > For the complete documentation index, see [llms.txt](https://doc.ibexa.co/en/saas/llms.txt). This field type represents and handles a single binary file. It also counts the number of times the file has been downloaded from the `content/download` module. It's capable of handling virtually any file type and is typically used for storing legacy document types, for example, PDF files, Word documents, or spreadsheets. The maximum allowed file size is determined by the "Max file size" class attribute edit parameter and the `upload_max_filesize` directive in the main PHP configuration file (`php.ini`). | Name | Internal name | Expected input | Output | | ------------ | ------------------ | -------------- | ------ | | `BinaryFile` | `ibexa_binaryfile` | mixed | mixed | ## Properties Both `BinaryFile` and `Media` Value and Type inherit from the `BinaryBase` abstract field type, and share common properties. `Ibexa\Core\FieldType\BinaryFile\Value` offers the following properties: | Attribute | Type | Description | Example | | --------------- | ------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ | -------------------------- | | `id` | string | Binary file identifier. This ID depends on the IO Handler that is being used. With the native, default handlers (FileSystem and Legacy), the ID is the file path, relative to the binary file storage root dir (`var//storage/original` by default). | application/63cd472dd7.pdf | | `fileName` | string | The human-readable file name, as exposed to the outside. Used when sending the file for download to name the file. | 20130116_whitepaper.pdf | | `fileSize` | int | File size, in bytes. | 1077923 | | `mimeType` | string | The file's MIME type. | application/pdf | | `uri` | string | The binary file's `content/download` URI. If the URI doesn't include a host or protocol, it applies to the request domain. | /content/download/210/2707 | | `downloadCount` | integer | Number of times the file was downloaded | 0 | | `inputUri` | string | Path to a local file when creating a field value, `null` when reading a field value | `path/to/document.pdf` | ## REST API specifics Used in the REST API, a BinaryFile field mostly serializes the hash described above. However there are a couple specifics worth mentioning. ### Reading content: `url` property When reading the contents of a field of this type, an extra key is added: `url`. This key gives you the absolute file URL, protocol and host included. Example: `http://example.com/var/ezdemo_site/storage/original/application/63cd472dd7819da7b75e8e2fee507c68.pdf` ### Creating content: `data` property When creating BinaryFile content with the REST API, it's possible to provide data as a base64 encoded string, by using the `data` fieldValue key: ```xml file eng-GB My file.pdf 17589 ``` # Checkbox field type > For the complete documentation index, see [llms.txt](https://doc.ibexa.co/en/saas/llms.txt). The Checkbox field type stores the current status for a checkbox input, checked or unchecked, by storing a boolean value. | Name | Internal name | Expected input type | | ---------- | --------------- | ------------------- | | `Checkbox` | `ibexa_boolean` | `boolean` | ## Properties The Value class of this field type contains the following properties: | Property | Type | Default value | Description | | -------- | --------- | ------------- | ------------------------------------------------------------------------------ | | `$bool` | `boolean` | `false` | This property is used for the checkbox status, represented by a boolean value. | # Content query field type > For the complete documentation index, see [llms.txt](https://doc.ibexa.co/en/saas/llms.txt). This field type maps an executable repository query to a field. | Name | Internal name | Expected input | | ------- | --------------------- | -------------- | | `Query` | `ibexa_content_query` | `string` | The Content query field type is available via the Query field type Bundle provided by the [fieldtype-query](https://github.com/ibexa/fieldtype-query) package. # Country field type > For the complete documentation index, see [llms.txt](https://doc.ibexa.co/en/saas/llms.txt). This field type represents one or multiple countries. | Name | Internal name | Expected input | | --------- | --------------- | -------------- | | `Country` | `ibexa_country` | `array` | ## Input expectations Example array: When you set an array directly on a content field you don't need to provide all this information, the field type assumes it's a hash and in this case accepts a simplified structure described below under [Hash format](#hash-format). ## Validation This field type validates whether multiple countries are allowed by the field definition, and whether the [Alpha2](https://www.iso.org/iso-3166-country-codes.html) is valid according to the countries configured in Cohesivo. ## Settings The field definition of this field type can be configured with one option: | Name | Type | Default value | Description | | ------------ | --------- | ------------- | ------------------------------------------------------------------------------------------ | | `isMultiple` | `boolean` | `false` | This setting allows (if true) or prohibits (if false) the selection of multiple countries. | ## Hash format The format used for serialization is simpler than the full format. It's also available when setting value on the content field, by setting the value to an array instead of the value object. Example of that shown below: The format used by the toHash method is the Alpha2 value, however the input is capable of accepting either Name, Alpha2, or Alpha3 value as shown below in the value object section. ### Properties The Value class of this field type contains the following properties: | Property | Type | Description | | ------------ | --------- | ------------------------------------------------------------------------------------- | | `$countries` | `array[]` | This property is used for the country selection provided as input, as its attributes. | # Customer group field > For the complete documentation index, see [llms.txt](https://doc.ibexa.co/en/saas/llms.txt). This field type represents a customer group that a user belongs to. | Name | Internal name | Expected input type | | ---------------- | ---------------------- | ------------------- | | `Customer group` | `ibexa_customer_group` | `int` or null | ## Properties The Value class of this field type contains the following properties: | Property | Type | Description | | -------- | ----- | ------------------------- | | `$id` | `int` | ID of the customer group. | # DateAndTime field type > For the complete documentation index, see [llms.txt](https://doc.ibexa.co/en/saas/llms.txt). This field type represents a full date and time information. | Name | Internal name | Expected input type | | ------------- | ---------------- | ------------------- | | `DateAndTime` | `ibexa_datetime` | mixed | ## Input expectations If input value is of type `string` or `integer`, it's passed directly to the [PHP's built-in `\DateTime` class constructor](https://www.php.net/manual/en/datetime.construct.php), therefore the same input format expectations apply. It's also possible to directly pass an instance of `\DateTime`. | Type | Example | | ----------- | ---------------------------------- | | `integer` | `"2017-08-28 12:20 Europe/Berlin"` | | `integer` | `1346149200` | | `\DateTime` | `new \DateTime()` | ### Properties The Value class of this field type contains the following properties: | Property | Type | Description | | -------- | ----------- | ------------------------------------------------------ | | `$value` | `\DateTime` | The date and time value as an instance of `\DateTime`. | ## Hash format Hash value of this field type is an array with two keys: | Key | Type | Description | Example | | ----------- | --------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------ | --------------------------------------- | | `timestamp` | `integer` | Time information in [Unix format timestamp](https://en.wikipedia.org/wiki/Unix_time). | `1400856992` | | `rfc850` | `string` | Time information as a string in [RFC 850 date format](https://datatracker.ietf.org/doc/html/rfc850). As input, this has precedence over the timestamp value. | `"Friday, 23-May-14 14:56:14 GMT+0000"` | ## Validation This field type doesn't perform any special validation of the input value. ## Settings The field definition of this field type can be configured with several options: | Name | Type | Default value | Description | | -------------- | ---------------- | --------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | | `useSeconds` | `boolean` | `false` | Used to control displaying of seconds in the output. | | `defaultType` | `mixed` | `Type::DEFAULT_EMPTY` | One of the `DEFAULT_*` constants, used by the administration interface for setting the default field value. See below for more details. | | `dateInterval` | `?\DateInterval` | `null` | This setting complements `defaultType` setting and can be used only when the latter is set to `Type::DEFAULT_CURRENT_DATE_ADJUSTED`. In that case the default input value when using administration interface is adjusted by the given `\DateInterval`. | Following `defaultType` default value options are available as constants in the `Ibexa\Core\FieldType\DateAndTime\Type` class: | Constant | Description | | ------------------------------- | -------------------------------------------------------------------------------------------- | | `DEFAULT_EMPTY` | Default value is empty. | | `DEFAULT_CURRENT_DATE` | Default value uses current date. | | `DEFAULT_CURRENT_DATE_ADJUSTED` | Default value uses current date, adjusted by the interval defined in `dateInterval` setting. | # Date field type > For the complete documentation index, see [llms.txt](https://doc.ibexa.co/en/saas/llms.txt). This field type represents a date without time information. | Name | Internal name | Expected input type | | ------ | ------------- | ------------------- | | `Date` | `ibexa_date` | mixed | ## Input expectations If input value is in `string` or `integer` format, it's passed directly to [PHP's built-in `\DateTime` class constructor](https://www.php.net/manual/en/datetime.construct.php), therefore the same input format expectations apply. It's also possible to directly pass an instance of `\DateTime`. | Type | Example | | ----------- | ---------------------------------- | | `string` | `"2012-08-28 12:20 Europe/Berlin"` | | `integer` | `1346149200` | | `\DateTime` | `new \DateTime()` | Time information is **not stored**. Before storing, the provided input value is set to the beginning of the day in the given or the environment timezone. ### Properties The Value class of this field type contains the following properties: | Property | Type | Description | | -------- | ----------- | ------------------------------------------- | | `$date` | `\DateTime` | This property is used for the text content. | ## Hash format Hash value of this field type is an array with two keys: | Key | Type | Description | Example | | ----------- | --------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------- | --------------------------------------- | | `timestamp` | `integer` | Time information in [Unix format timestamp](https://en.wikipedia.org/wiki/Unix_time). | `1400856992` | | `rfc850` | `string` | Time information as a string in [RFC 850 date format](https://datatracker.ietf.org/doc/html/rfc850). As input, this has higher precedence over the timestamp value. | `"Friday, 23-May-14 14:56:14 GMT+0000"` | ## Validation This field type doesn't perform any special validation of the input value. ## Settings The field definition of this field type can be configured with a single option: | Name | Type | Default value | Description | | ------------- | ------- | --------------------- | --------------------------------------------------------------------------------------------------------------------------------------- | | `defaultType` | `mixed` | `Type::DEFAULT_EMPTY` | One of the `DEFAULT_*` constants, used by the administration interface for setting the default field value. See below for more details. | Following `defaultType` default value options are available as constants in the `Ibexa\Core\FieldType\Date\Type` class: | Constant | Description | | ---------------------- | -------------------------------- | | `DEFAULT_EMPTY` | Default value is empty. | | `DEFAULT_CURRENT_DATE` | Default value uses current date. | # EmailAddress field type > For the complete documentation index, see [llms.txt](https://doc.ibexa.co/en/saas/llms.txt). The EmailAddress field type represents an email address, in the form of a string. | Name | Internal name | Expected input type | | -------------- | ------------- | ------------------- | | `EmailAddress` | `ibexa_email` | `string` | ## Properties The `Value` class of this field type contains the following properties: | Property | Type | Description | | -------- | -------- | --------------------------------------------------------------------- | | `$email` | `string` | This property is used for the input string provided as email address. | ## Hash format Hash value for this field type's Value is simply the email address as a string. Example: `someuser@example.com` ## Validation This field type uses the `EmailAddressValidator` validator as a resource which tests the string supplied as input against a pattern, to make sure that a valid email address has been provided. If the validations fail, a `ValidationError` is thrown, specifying the error message. ## Settings This field type doesn't support settings. # Float field type > For the complete documentation index, see [llms.txt](https://doc.ibexa.co/en/saas/llms.txt). This field type stores numeric values which are provided as floats. | Name | Internal name | Expected input | | ------- | ------------- | -------------- | | `Float` | `ibexa_float` | `float` | ## Input expectations The field type expects a number as input. Both decimal and integer numbers are accepted. | Type | Example | | ------- | ------------ | | `float` | `194079.572` | | `int` | `144` | ### Properties The Value class of this field type contains the following properties: | Property | Type | Description | | -------- | ------- | ------------------------------------------------------------- | | `$value` | `float` | This property is used to store the value provided as a float. | ## Validation This field type supports `FloatValueValidator`, defining maximum and minimum float value: | Name | Type | Default value | Description | | --------------- | ------- | ------------- | --------------------------------------------------------------------------------- | | `minFloatValue` | `float` | \`null | This setting defines the minimum value this field type which is allowed as input. | | `maxFloatValue` | `float` | \`null | This setting defines the maximum value this field type which is allowed as input. | ## Settings This field type doesn't support settings. # Form field type > For the complete documentation index, see [llms.txt](https://doc.ibexa.co/en/saas/llms.txt). The Form field type stores a Form consisting of one or more form fields. | Name | Internal name | | ------ | ------------- | | `Form` | `ibexa_form` | For more information about working with Forms, see [Forms](https://doc.ibexa.co/en/saas/content_management/forms/work_with_forms/index.md). # Image field type > For the complete documentation index, see [llms.txt](https://doc.ibexa.co/en/saas/llms.txt). The Image field type allows you to store an image file. | Name | Internal name | | ------- | ------------- | | `Image` | `ibexa_image` | A **variation service** handles the conversion of the original image into different formats and sizes through a set of preconfigured named variations, for example, large, small, medium, or black and white thumbnail. ## Field value The `value` property of an Image field returns an `Ibexa\Core\FieldType\Image\Value` object with the following properties: ### Properties | Property | Type | Example | Description | | ----------------- | ------ | ---------------------------------------------------------------- | -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | | `id` | string | `0/8/4/1/1480-1-eng-GB/image.png` | The image's unique identifier. Usually the path, or a part of the path. To get the full path, use the `uri` property. | | `alternativeText` | string | `Picture of an apple.` | The alternative text, as entered in the field's properties. This property is optional. It's recommended that you require the alternative text for an image when you add the Image field to a content type, by selecting the "Alternative text is required" checkbox. | | `fileName` | string | `image.png` | The original image's filename, without the path. | | `fileSize` | int | `37931` | The original image's size, in bytes. | | `uri` | string | `var/ezdemo_site/storage/images/0/8/4/1/1480-1-eng-GB/image.png` | The original image's URI. | | `imageId` | string | `240-1480` | A special image ID, used by REST. | | `inputUri` | string | `var/storage/images/test/199-2-eng-GB/image.png` | Input image file URI. | | `width` | int | `960` | Original image width in pixels. | | `height` | int | `540` | Original image height in pixels. | ## Settings This field type doesn't support settings. ## Image variations Using the variation Service, variations of the original image can be obtained. They're `Ibexa\Contracts\Core\Variation\Values\ImageVariation` objects with the following properties: | Property | Type | Example | Description | | -------------- | -------- | ------------------------------------------------ | ------------------------------------------------------------------------------------------------------------------------------------------ | | `width` | int | `200` | The variation's width in pixels. | | `height` | int | `112` | The variation's height in pixels. | | `name` | string | `medium` | The variation's identifier, name of the image variation. | | `info` | mixed | n/a | Extra information about the image, depending on the image type, such as EXIF data. If there is no information, the `info` value is `null`. | | `fileSize` | int | `31010` | Size (in byte) of current variation. | | `mimeType` | string | `image/png` | The MIME type. | | `fileName` | string | `my_image.png` | The name of the file. | | `dirPath` | string | `var/storage/images/test/199-2-eng-GB` | The path to the file. | | `uri` | string | `var/storage/images/test/199-2-eng-GB/apple.png` | The variation's URI. Complete path with a name of image file. | | `lastModified` | DateTime | `"2017-08-282 12:20 Europe/Berlin"` | When the variation was last modified. | ## Field Definition options The Image field type supports one `FieldDefinition` option: the maximum size for the file. > **Note: Note** > > Maximum size is 10MB. We recommend setting the `upload_max_filesize` key in the `php.ini` configuration file to a value equal to or higher than that. It prevents validation errors while editing content types. ## Using an Image field To read more about handling images and image variations, see the [Images documentation](https://doc.ibexa.co/en/saas/content_management/images/images/index.md). ### With the REST API Image Fields within REST are exposed by the `application/vnd.ibexa.api.Content` media-type. An Image field looks like this: ```xml 1480 image eng-GB /var/ezdemo_site/storage/images/0/8/4/1/1480-1-eng-GB/kidding.png kidding.png 37931 240-1480 /var/ezdemo_site/storage/images/0/8/4/1/1480-1-eng-GB/kidding.png /api/ibexa/v2/content/binary/images/240-1480/variations/articleimage /api/ibexa/v2/content/binary/images/240-1480/variations/articlethumbnail ``` Children of the `fieldValue` node list the general properties of the field's original image (for example, `fileSize`, `fileName`, or `inputUri`), and its variations. For each variation, a URI is provided. Requested through REST, this resource generates the variation if it doesn't exist yet, and list the variation details: ```xml /var/ezdemo_site/storage/images/0/8/4/1/1480-1-eng-GB/kidding_tiny.png image/png 30 30 1361 ``` ### From REST The REST API expects field values to be provided in a hash-like structure. Those keys are identical to those expected by the `Image\Value` constructor: `fileName`, `alternativeText`. In addition, image data can be provided using the `data` property, with the image's content encoded as base64. #### Creating an Image field ```xml 247 image eng-GB rest-rocks.jpg HTTP ``` ### Updating an Image field Updating an Image field requires that you re-send existing data. This can be done by re-using the field obtained via REST, **removing the variations key**, and updating `alternativeText`, `fileName` or `data`. If you don't want to change the image itself, don't provide the `data` key. ```xml 247 image eng-GB media/images/507-1-eng-GB/Existing-image.png Updated alternative text Updated-filename.png ``` # ImageAsset field type > For the complete documentation index, see [llms.txt](https://doc.ibexa.co/en/saas/llms.txt). Image Asset field type enables storing images in independent content items of a generic Image content type, in the media library. It makes them reusable across system. | Name | Internal name | | ------------ | ------------------- | | `ImageAsset` | `ibexa_image_asset` | ## Input expectations Example array: | Type | Description | Example | | ------------------------------------------------------------ | ----------------------------------------------- | ---------- | | `Ibexa\Core\FieldType\ImageAsset\Value` | Image Asset field type value object. | See below. | | `Ibexa\Contracts\Core\Repository\Values\Content\ContentInfo` | ContentInfo instance of the Asset content item. | n/a | | `string` | ID of the Asset content item. | `"150"` | | `integer` | ID of the Asset content item. | `150` | ### Properties Value object of `ibexa_image_asset` contains the following properties: | Property | Type | Description | | ---------------------- | -------- | ---------------------------------------------------------------- | | `destinationContentId` | `int` | Related content ID. | | `alternativeText` | `string` | The alternative image text (for example "Picture of an apple."). | ### Validation This field type validates if: - `destinationContentId` points to a content item which has correct content type ## Configuration ImageAsset field type allows configuring the following options: | Name | Description | Default value | | -------------------------- | -------------------------------------- | ------------- | | `content_type_identifier` | Content type used to store assets. | `image` | | `content_field_identifier` | Field identifier used for asset data. | `image` | | `name_field_identifier` | Field identifier used for asset name. | `name` | | `parent_location_id` | Location where the assets are created. | `51` | Example configuration: ```yaml ibexa: system: default: fieldtypes: ibexa_image_asset: content_type_identifier: photo content_field_identifier: image name_field_identifier: title parent_location_id: 106 ``` ## Generating image variation from the Image Asset Thanks to the `Ibexa\Bundle\Core\Imagine\ImageAsset` decorator you can work with `Ibexa\Contracts\Core\Variation` in the same way as with [Image field type](https://doc.ibexa.co/en/saas/content_management/field_types/field_type_reference/imagefield/index.md). # Integer field type > For the complete documentation index, see [llms.txt](https://doc.ibexa.co/en/saas/llms.txt). This field type represents an integer value. | Name | Internal name | Expected input | | --------- | --------------- | -------------- | | `Integer` | `ibexa_integer` | `integer` | ## Input expectations | Type | Example | | --------- | ------- | | `integer` | `2397` | ### Properties The Value class of this field type contains the following properties: | Property | Type | Description | | -------- | ----- | ---------------------------------------------------------------- | | `$value` | `int` | This property is used to store the value provided as an integer. | ### Hash format Hash value of this field type is an integer value as a string. Example: `"8"` ## Validation This field type supports `IntegerValueValidator`, defining maximum and minimum float value: | Name | Type | Default value | Description | | ----------------- | ----- | ------------- | --------------------------------------------------------------------------------- | | `minIntegerValue` | `int` | `0` | This setting defines the minimum value this field type which is allowed as input. | | `maxIntegerValue` | `int` | `null` | This setting defines the maximum value this field type which is allowed as input. | ## Settings This field type doesn't support settings. # ISBN field type > For the complete documentation index, see [llms.txt](https://doc.ibexa.co/en/saas/llms.txt). This field type represents an ISBN string either an ISBN-10 or ISBN-13 format. | Name | Internal name | Expected input type | | ------ | ------------- | ------------------- | | `ISBN` | `ibexa_isbn` | `string` | ## Properties The Value class of this field type contains the following properties: | Property | Type | Description | | -------- | -------- | ------------------------------------------ | | `$isbn` | `string` | This property is used for the ISBN string. | ## Validation The input passed into this field type is subject of ISBN validation depending on the field settings in its FieldDefinition stored in the content type. An example of this field setting is shown below and controls if input is validated as ISBN-13 or ISBN-10: # Keyword field type > For the complete documentation index, see [llms.txt](https://doc.ibexa.co/en/saas/llms.txt). This field type stores one or several comma-separated keywords as a string or array of strings. | Name | Internal name | Expected input | | --------- | --------------- | ---------------------- | | `Keyword` | `ibexa_keyword` | `string[]` or `string` | ## Input expectations | Type | Example | | ---------- | --------------------------------------------------------- | | `string` | `"documentation"` | | `string` | `"php, Ibexa Platform, html5"` | | `string[]` | `[ "Ibexa", "Enterprise", "User Experience Management" ]` | ### Properties The Value class of this field type contains the following properties: | Property | Type | Description | | --------- | ---------- | -------------------------------------- | | `$values` | `string[]` | Holds an array of keywords as strings. | # MapLocation field type > For the complete documentation index, see [llms.txt](https://doc.ibexa.co/en/saas/llms.txt). This field type represents a geographical location. As input it expects three values: - two float values latitude and longitude, - a string value, corresponding to the name or address of the location. | Name | Internal name | Expected input | | ------------- | --------------------- | -------------- | | `MapLocation` | `ibexa_gmap_location` | `mixed` | ## Input expectations | Type | Example | | ------- | ------------------------------------------------------------------------------------- | | `array` | `[ 'latitude' => 59.928732, 'longitude' => 10.777888, 'address' => "Ibexa Nordics" ]` | ### Properties The Value class of this field type contains the following properties: | Property | Type | Description | | ------------ | -------- | ----------------------------------------------------------------------- | | `$latitude` | `float` | This property stores the latitude value of the map location reference. | | `$longitude` | `float` | This property stores the longitude value of the map location reference. | | `$address` | `string` | This property stores the address of map location. | # Matrix field type > For the complete documentation index, see [llms.txt](https://doc.ibexa.co/en/saas/llms.txt). This field represents and handles a table of rows and columns of data. | Name | Internal name | Expected input | | -------- | -------------- | -------------- | | `Matrix` | `ibexa_matrix` | `array` | The Matrix field type is available via the Matrix Bundle provided by the [ibexa/fieldtype-matrix](https://github.com/ibexa/fieldtype-matrix) package. ## Input expectations | Type | Description | Example | | ------- | -------------------------------------------------------------------------------------- | --------- | | `array` | array of `Ibexa\FieldTypeMatrix\FieldType\Value\Row` objects which contain column data | see below | Example of input: ## Field value `Ibexa\FieldTypeMatrix\FieldType\Value` offers the following properties: | Property | Type | Description | | -------- | ---------------- | ------------------------------------------------------------------------------------------------------------------------- | | `rows` | `RowsCollection` | Array of `Row` objects containing an array of cells (`Row::getCells()` returns array `['col1' => 'Value 1', /* ... */]`). | ## Validation The minimum number of rows is set on content type level for each field. Validation checks for empty rows. A row is considered empty if it contains only empty cells (or cells containing only spaces). Empty rows are removed. If, after removing empty rows, the number of rows doesn't fulfill the configured `Minimum number of rows`, the field doesn't validate. # Measurement field type > For the complete documentation index, see [llms.txt](https://doc.ibexa.co/en/saas/llms.txt). The Measurement field type represents measurement information. It stores the unit of measure, and either a single measurement value, or a pair of top and bottom values that defines a range. | Name | Internal name | Expected input type | | ------------- | ------------------- | -------------------------------------------------- | | `Measurement` | `ibexa_measurement` | `Ibexa\Contracts\Measurement\Value\ValueInterface` | ## Input expectations To create a value, you use a service that implements `Ibexa\Contracts\Measurement\MeasurementServiceInterface`. You must inject the service directly with [dependency injection](https://symfony.com/doc/7.4/service_container.html). The service contains the following API endpoints: - `buildSimpleValue` that is used to handle a single value - `buildRangeValue` that is used to handle a range Assuming that the service exists as `$measurementService`, the expected input examples are as follows: | Type | Example | | --------------------------------------------------------- | -------------------------------------------------------------------- | | `\Ibexa\Contracts\Measurement\Value\SimpleValueInterface` | `$measurementService->buildSimpleValue('length', 2.5, 'centimeter')` | | `\Ibexa\Contracts\Measurement\Value\RangeValueInterface` | `$measurementService->buildRangeValue('length', 1.2, 4.5, 'inch')` | ### Properties The Value class of this field type contains the following properties: | Property | Type | Description | | -------- | -------------------------------------------------- | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | | `$value` | `Ibexa\Contracts\Measurement\Value\ValueInterface` | Stores the Measurement API Value, which can be either an instance of `Ibexa\Contracts\Measurement\Value\SimpleValueInterface` or `Ibexa\Contracts\Measurement\Value\RangeValueInterface`. | ## Validation The Measurement field type validates measurement types and units passed within the value object against a list of the ones that the system supports, which can be found in the `vendor/ibexa/measurement/src/bundle/Resources/config/builtin_units.yaml` file. ## Modify and add Measurement types and units You can extend the default list of Measurement types and units by modifying the existing entries or adding new ones. To do this, you modify the YAML configuration. To override an existing designation of the unit of measure by changing the symbol that corresponds to a nautical unit of speed, and to add a rotational speed unit, add the following lines to your [YAML configuration](https://doc.ibexa.co/en/saas/administration/configuration/configuration/#configuration-files): ```yaml ibexa_measurement: types: speed: knot: { symbol: kt } revolutions per minute: { symbol: RPM } ibexa: system: default: measurement: types: speed: - revolutions per minute ``` To add a new Measurement type with its own new units, add the following lines to your YAML configuration: ```yaml ibexa_measurement: types: my_type: my_unit: { symbol: my, is_base_unit: true } ibexa: system: default: measurement: types: my_type: - my_unit ``` The configuration also requires that exactly one unit needs to be marked as `is_base_unit` as in highlighted line above. > **Note: Note** > > To be available for selection in the back office, each new Measurement type or unit must be enabled for the back office SiteAccess. Next, you need to define how the new unit should be converted under the `ibexa.system..ibexa_measurement` [configuration key](https://doc.ibexa.co/en/saas/administration/configuration/configuration/#configuration-files): ```yaml ibexa_measurement: conversion: formulas: - { source_unit: foo, target_unit: bar, formula: 'value / 100' } types: length: foo: { symbol: foo } bar: { symbol: bar } ``` > **Tip: Tip** > > The `target_unit` must be an existing unit, for example meter, otherwise the conversion results in an error. # Media field type > For the complete documentation index, see [llms.txt](https://doc.ibexa.co/en/saas/llms.txt). This field type represents and handles a media (audio/video) binary file. It's capable of handling the following types of files: - Apple QuickTime - Adobe Flash - Microsoft Windows Media - Real Media - Silverlight - HTML5 Video - HTML5 Audio | Name | Internal name | Expected input | | ------- | ------------- | -------------- | | `Media` | `ibexa_media` | mixed | ## Input expectations | Type | Description | Example | | ---------------------------------- | ---------------------------------------------------------------------------------------- | ----------------------------- | | `string` | Path to the media file. | `/Users/jane/butterflies.mp4` | | `Ibexa\Core\FieldType\Media\Value` | Media field type value object with path to the media file as the value of `id` property. | See below. | ### Properties `Ibexa\Core\FieldType\Media\Value` offers the following properties. Both `Media` and `BinaryFile` Value and Type inherit from the `BinaryBase` abstract field type and share common properties. | Property | Type | Description | Example | | --------------- | ------- | --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | ---------------------------------------------------------------------------------- | | `id` | string | Media file identifier. This ID depends on the IO Handler that is being used. With the native, default handlers (FileSystem and Legacy), the ID is the file path, relative to the binary file storage root dir (`var//storage/original` by default). | application/63cd472dd7819da7b75e8e2fee507c68.mp4 | | `fileName` | string | The human-readable file name, as exposed to the outside. Used to name the file when sending it for download. | butterflies.mp4 | | `fileSize` | int | File size, in bytes. | 1077923 | | `mimeType` | string | The file's MIME type. | video/mp4 | | `uri` | string | The binary file's HTTP URI. If the URI doesn't include a host or protocol, it applies to the request domain. **The URI is not publicly readable, and must NOT be used to link to the file for download.** Use `ibexa_render_field` to generate a valid link to the download controller. | /var/ezdemo_site/storage/original/application/63cd472dd7819da7b75e8e2fee507c68.mp4 | | `hasController` | boolean | Whether the media has a controller when being displayed. | true | | `autoplay` | boolean | Whether the media should be automatically played. | true | | `loop` | boolean | Whether the media should be played in a loop. | false | | `height` | int | Height of the media. | 300 | | `width` | int | Width of the media. | 400 | | `path` | string | **deprecated** | | ## Hash format The hash format mostly matches the value object. It has the following keys: - `id` - `path` (for backwards compatibility) - `fileName` - `fileSize` - `mimeType` - `uri` - `hasController` - `autoplay` - `loop` - `height` - `width` ## Validation The field type supports `FileSizeValidator`, defining maximum size of media file in bytes: | Name | Type | Default value | Description | | ------------- | ----- | ------------- | ---------------------------------- | | `maxFileSize` | `int` | `false` | Maximum size of the file in bytes. | ## Settings The field type supports the `mediaType` setting, defining how the media file should be handled in output. | Name | Type | Default value | Description | | ----------- | ----- | ------------------------ | ----------------------------------------------------------- | | `mediaType` | mixed | `Type::TYPE_HTML5_VIDEO` | Type of the media, accepts one of the predefined constants. | List of all available `mediaType` constants is defined in the `Ibexa\Core\FieldType\Media\Type` class: | Name | Description | | ------------------- | ----------------------- | | `TYPE_FLASH` | Adobe Flash | | `TYPE_QUICKTIME` | Apple QuickTime | | `TYPE_REALPLAYER` | Real Media | | `TYPE_SILVERLIGHT` | Silverlight | | `TYPE_WINDOWSMEDIA` | Microsoft Windows Media | | `TYPE_HTML5_VIDEO` | HTML5 Video | | `TYPE_HTML5_AUDIO` | HTML5 Audio | # Null field type > For the complete documentation index, see [llms.txt](https://doc.ibexa.co/en/saas/llms.txt). This field type is used as fallback for migration scenarios, and for testing purposes. | Name | Internal name | Expected input type | | ------ | ------------- | ------------------- | | `Null` | (variable) | mixed | ## Description The Null field type aids when migrating from eZ Publish Platform and earlier legacy versions. It's a dummy for legacy field types that aren't implemented in Cohesivo. Null field type accepts anything provided as a value and is usually combined with: - NullConverter: Makes it not store anything to the legacy storage engine (database), nor it reads any data. - Unindexed: Indexable class making sure nothing is indexed to configured search engine. This field type doesn't have its own fixed internal name. Its identifier is instead configured as needed by passing it as an argument to the constructor. ### Example for usage of Null field type The following example shows how an `example` field type could be configured as a Null field type: ```yaml # Null Fieldtype example configuration services: ibexa.field_type.example: class: Ibexa\Core\FieldType\Null\Type arguments: [example] tags: [{name: ibexa.field_type, alias: example}] ibexa.field_type.example.converter: class: Ibexa\Core\Persistence\Legacy\Content\FieldValue\Converter\NullConverter tags: [{name: ibexa.field_type.storage.legacy.converter, alias: example}] ibexa.field_type.example.indexable: class: Ibexa\Core\FieldType\Unindexed tags: [{name: ibexa.field_type.indexable, alias: example}] ``` # Page field type > For the complete documentation index, see [llms.txt](https://doc.ibexa.co/en/saas/llms.txt). Page field type represents a page with a layout consisting of multiple zones. Each zone can in turn contain blocks. Page field type is only used in the page content type that is included in Cohesivo. | Name | Internal name | Expected input | | ------------- | -------------------- | --------------- | | `LandingPage` | `ibexa_landing_page` | `string` (JSON) | > **Caution: Page Builder** > > If you create content type with both `ibexa_landing_page` and `ibexa_user` field types, you aren't redirected to Page Builder after selecting `Edit` or `Create`. This is caused by `ibexa_user` field type which requires separate handling. You're redirected to the standard back office edit or create mode. # Product specification field type > For the complete documentation index, see [llms.txt](https://doc.ibexa.co/en/saas/llms.txt). This field represents and handles [product attributes](https://doc.ibexa.co/en/saas/product_catalog/products/#product-attributes) and [VAT](https://doc.ibexa.co/en/saas/product_catalog/prices/#vat). Consider it as internal to the [product catalog](https://doc.ibexa.co/en/saas/product_catalog/product_catalog/index.md). | Name | Internal name | Expected input | | ---------------------- | ----------------------------- | -------------- | | `ProductSpecification` | `ibexa_product_specification` | mixed | > **Caution: Caution** > > The presence of a specification (`ibexa_product_specification`) field distincts product types from content types. Don't remove this field from a product type (or it becomes a unreachable hidden content type). Don't add such field to a content type (or it becomes an uneditable unusable product type). # Relation field type > For the complete documentation index, see [llms.txt](https://doc.ibexa.co/en/saas/llms.txt). This field type makes it possible to store and retrieve the value of a relation to another content item. | Name | Internal name | Expected input | | ---------- | ----------------------- | -------------- | | `Relation` | `ibexa_object_relation` | mixed | ## Input expectations | Type | Example | | --------- | ------- | | `string` | `"150"` | | `integer` | `150` | ### Properties The Value class of this field type contains the following properties: | Property | Type | Description | | ----------------------- | -------------------------- | ---------------------------------------------------------------------------------------- | | `$destinationContentId` | `string`, `int`, or `null` | This property is used to store the value provided, which represents the related content. | ## Validation This field type validates whether the provided relation exists, but before that it checks that the value is either a string or an int. ## Settings The field definition of this field type can be configured with three options: | Name | Type | Default value | Description | | ----------------------- | -------- | --------------------------------- | ------------------------------------------------------------------------------ | | `selectionMethod` | `int` | `Relation\Type::SELECTION_BROWSE` | *This setting is not implemented yet, only one selection method is available.* | | `selectionRoot` | `string` | `null` | This setting defines the selection root. | | `selectionContentTypes` | `array` | `[]` | An array of content type IDs that are allowed for related Content. | # RelationList field type > For the complete documentation index, see [llms.txt](https://doc.ibexa.co/en/saas/llms.txt). This field type makes it possible to store and retrieve values of a relation to other content items. | Name | Internal name | Expected input | | -------------- | ---------------------------- | -------------- | | `RelationList` | `ibexa_object_relation_list` | `mixed` | ## Input expectations | Type | Description | Example | | ------------------------------------------------------------ | ------------------------------------------- | ------------ | | `int` or `string` | ID of the related content item | `42` | | `array` | An array of related Content IDs | `[ 24, 42 ]` | | `Ibexa\Contracts\Core\Repository\Values\Content\ContentInfo` | ContentInfo instance of the related Content | n/a | | `Ibexa\Core\FieldType\RelationList\Value` | RelationList field type value object | See below. | ### Properties `Ibexa\Core\FieldType\RelationList\Value` contains the following properties: | Property | Type | Description | Example | | ----------------------- | ------- | ------------------------------- | ------------ | | `destinationContentIds` | `array` | An array of related Content IDs | `[ 24, 42 ]` | ## Validation This field type validates if: - the `selectionMethod` specified is `\Ibexa\Core\FieldType\RelationList\Type::SELECTION_BROWSE` or `\Ibexa\Core\FieldType\RelationList\Type::SELECTION_DROPDOWN`. A validation error is thrown if the value doesn't match. - the `selectionDefaultLocation` specified is `null`, `string` or `integer`. If the type validation fails a validation error is thrown. - the value specified in `selectionContentTypes` is an `array`. If not, a validation error in given. - the number of content items selected in the field isn't greater than the `selectionLimit`. > **Note: Note** > > The dropdown selection method isn't implemented yet. ## Settings The field definition of this field type can be configured with the following options: | Name | Type | Default value | Description | | -------------------------- | --------------------- | ------------------ | ------------------------------------------------------------------------------- | | `selectionMethod` | `mixed` | `SELECTION_BROWSE` | Method of selection in the back-end interface. | | `selectionDefaultLocation` | `string` or `integer` | `null` | ID of the default Location for the selection when using the back-end interface. | | `selectionContentTypes` | `array` | `[]` | An array of content type IDs that are allowed for related Content. | Following selection methods are available: | Name | Description | | -------------------- | --------------------------- | | `SELECTION_BROWSE` | Selection uses browse mode. | | `SELECTION_DROPDOWN` | *Not implemented yet* | ## Validators | Name | Type | Default value | Description | | -------------------------------------------- | --------- | ------------- | --------------------------------------------------------------------------------------------------------- | | `RelationListValueValidator[selectionLimit]` | `integer` | `0` | The number of content items that can be selected in the field. When set to 0, any number can be selected. | # RichText field type > For the complete documentation index, see [llms.txt](https://doc.ibexa.co/en/saas/llms.txt). The RichText field type is available via the RichText field type Bundle provided by the [ibexa/fieldtype-richtext](https://github.com/ibexa/fieldtype-richtext) package. This field type validates and stores structured rich text in [DocBook](https://docbook.org/) XML format, and exposes it in several formats. | Name | Internal name | Expected input | | ---------- | ---------------- | -------------- | | `RichText` | `ibexa_richtext` | mixed | ## Field value `Ibexa\FieldTypeRichText\FieldType\RichText\Value` offers the following properties: | Property | Type | Description | | -------- | ------------- | ------------------------------------------------------ | | `xml` | `DOMDocument` | Internal format value as an instance of `DOMDocument`. | ## Input expectations | Type | Description | | -------------------------------------------------- | -------------------------------------------------------------------------------- | | `string` | XML document in one of the field type's input formats as a string. | | `DOMDocument` | XML document in one of the field type's input formats as a `DOMDocument` object. | | `Ibexa\FieldTypeRichText\FieldType\RichText\Value` | An instance of the field type's `Value` object. | ## Input formats The field type expects an XML value as input, in the form of a string, `DOMDocument` object, or field type's `Value` object. The field type's `Value` object must hold the value in the field type's [internal format](#internal-format). For a string of a `DOMDocument` object, if the input doesn't conform to this format, it's converted into it. ### Internal format As its internal format, the RichText field type uses a [custom flavor of the DocBook format](#custom-docbook-format). ```xml
This is a title. This is a paragraph.
``` ### XHTML5 edit format The XHTML5 format is used by the Online Editor. ```xml

This is a title.

This is a paragraph.

``` ## Custom DocBook format > **Caution: Caution** > > The custom DocBook format described below is subject to change and isn't covered by backwards compatibility promise. You can use the Ibexa flavor of the DocBook format in REST API requests by providing the DocBook content as a string. When creating RichText content with the REST API, use the `xml` key of the `fieldValue` tag: ```xml <?xml version="1.0" encoding="UTF-8"?> <section xmlns="http://docbook.org/ns/docbook" xmlns:xlink="http://www.w3.org/1999/xlink" xmlns:ezxhtml="http://ibexa.co/xmlns/dxp/docbook/xhtml" xmlns:ezcustom="http://ibexa.co/xmlns/dxp/docbook/custom" version="5.0-variant ezpublish-1.0"> <title ezxhtml:level="2">This is a title.</title> </section> ``` ### DocBook elements The RichText format enriches [DocBook](https://docbook.org/) with the following custom elements: - `section` - main element of a RichText field - `ezembed` - holds embedded images - `ezembedinline` - holds embedded content items - `eztemplate` - holds custom tags, including built-in custom tags for embedded Facebook, Twitter, and YouTube content - `eztemplateinline` - holds inline custom tags - `ezconfig` - contains configuration for custom tags and other elements - `ezvalue` - contains values for other elements, such as `ezconfig` or `ezembed` - `ezattribute` - contains attributes for other elements, such as `ezconfig` or `ezembed` > **Note: Unsupported DocBook elements** > > Some DocBook elements aren't supported by RichText. Refer to [`ezpublish.rng`](https://github.com/ibexa/fieldtype-richtext/blob/6.0/src/bundle/Resources/richtext/schemas/docbook/ezpublish.rng#L137) for a full list. ### Online Editor elements Elements of the Online Editor correspond to the following sample DocBook code blocks. #### Text formatting ```xml Anchor text Center aligned Left aligned bold italic underlined subscript superscript crossed out
This is a block quote.
``` #### Heading ```xml My heading ``` #### Code block ```xml ``` #### Unordered list ```xml 1st level bullet point 1st level bullet point 2nd level bullet point 2nd level bullet point ``` #### Ordered list ```xml 1st level numbered point 1st level numbered point 2nd level numbered point ``` #### Embedded content ```xml ``` #### Inline embedded content ```xml embed inline ``` #### Image ```xml medium ``` #### Table ```xml This is a merged table cell ``` #### YouTube ```xml https://youtu.be/Y-1d5zdeg9A false ``` #### Twitter ```xml https://twitter.com/BBCSpringwatch/status/1401622026973032452 light 500 en true ``` #### Facebook ```xml https://www.facebook.com/bbcnews/posts/10158930827817217?__tn__=-R 120 ``` # Selection field type > For the complete documentation index, see [llms.txt](https://doc.ibexa.co/en/saas/llms.txt). The Selection field type stores single selections or multiple choices from a list of options, by populating a hash with the list of selected values. | Name | Internal name | Expected input type | | ----------- | ----------------- | ------------------- | | `Selection` | `ibexa_selection` | mixed | ## Input expectations | Type | Example | | ------- | ---------- | | `array` | `[ 1, 2 ]` | ### Properties The Value class of this field type contains the following properties: | Property | Type | Description | | ------------ | ------- | ----------------------------------------------------------------------------------------------------------------- | | `$selection` | `int[]` | This property is used for the list of selections, which is a list of integer values, or one single integer value. | ### Hash format Hash format of this field type is the same as value object's `selection` property. ## Validation This field type validates the input, verifying if all selected options exist in the field definition and checks if multiple selections are allowed in the field definition. If any of these validations fail, a `ValidationError` is thrown, specifying the error message. When option validation fails, a list with the invalid options is also presented. ## Settings | Name | Type | Default value | Description | | ------------ | --------- | ------------- | ------------------------------------------------------------------ | | `isMultiple` | `boolean` | `false` | Used to allow or prohibit multiple selection from the option list. | | `options` | `hash` | `[]` | Stores the list of options defined in the field definition. | # TaxonomyEntry field type > For the complete documentation index, see [llms.txt](https://doc.ibexa.co/en/saas/llms.txt). TaxonomyEntry is a field type that stores information about the parent entry in the taxonomy tree, placing the taxonomy entry (tag or product category) in the taxonomy structure. | Name | Internal name | Expected input | | --------------- | ---------------------- | -------------- | | `TaxonomyEntry` | `ibexa_taxonomy_entry` | `array` | ## Input expectations A `TaxonomyEntry` field accepts an array with an `Ibexa\Contracts\Taxonomy\Value\TaxonomyEntry` object. | Type | Description | Example | | ------- | -------------------------------------------------------------------------------------------------- | --------- | | `array` | array with an `Ibexa\Contracts\Taxonomy\Value\TaxonomyEntry` object under the `taxonomy_entry` key | see below | Example using an `Ibexa\Taxonomy\FieldType\TaxonomyEntry\Value` object: Example using array: ### Properties | Property | Type | Description | | --------------- | ----------------------------------------------- | ------------------------------- | | `taxonomyEntry` | `?Ibexa\Contracts\Taxonomy\Value\TaxonomyEntry` | Stores selected taxonomy entry. | ### Hash format An array with `taxonomy_entry` key containing `Ibexa\Contracts\Taxonomy\Value\TaxonomyEntry` object or `null`. ### Validation No validation. ### Settings The field definition of this field type can be configured with the following options: | Name | Type | Default value | Description | | ---------- | -------- | ------------- | ---------------------------------------- | | `taxonomy` | `string` | `null` | Taxonomy from which you choose an entry. | # TaxonomyEntryAssignment field type > For the complete documentation index, see [llms.txt](https://doc.ibexa.co/en/saas/llms.txt). `TaxonomyEntryAssignment` field is used to integrate content with the Taxonomy module. It allows you to select tags or categories and assign them to content. This field type assigns tags to the content in the data action, so then you can use `TaxonomyService` on this content item. > **Caution: Duplicate taxonomy fields** > > Because tags are assigned per content item, not per field, you cannot use two **Taxonomy Entry Assignment** fields with the same taxonomy type in one content type. To be able to assign tags to the content, first, you need to add a `TaxonomyEntryAssignment` field to the content type definition. | Name | Internal name | Expected input | | ------------------------- | --------------------------------- | ------------------------------------------------ | | `TaxonomyEntryAssignment` | `ibexa_taxonomy_entry_assignment` | array with `taxonomyEntries` and `taxonomy` keys | ## Input expectations | Type | Description | Example | | ------- | ------------------------------------------------------------------------------------------------------------------------------------------- | --------- | | `array` | array with `Ibexa\Contracts\Taxonomy\Value\TaxonomyEntry` objects under `taxonomy_entries` key and Taxonomy identifier under `taxonomy` key | see below | Example using an `Ibexa\Taxonomy\FieldType\TaxonomyEntryAssignment\Value` object: Example using array: ### Properties | Property | Type | Description | | --------------- | ------------------------------------------------------- | ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | | `taxonomyEntry` | array of `Ibexa\Contracts\Taxonomy\Value\TaxonomyEntry` | Stores selected taxonomy entry. | | `taxonomy` | `string` | Stores the taxonomy identifier, all `taxonomyEntries` have to be assigned to this taxonomy and the identifier has to match the settings of the field type in content type configuration. | ### Hash format An array of: - `taxonomy_entries` with numerical IDs of entries. - `taxonomy` string identifier of a taxonomy. ### Validation The field type validates if all Taxonomy Entries from the value are assigned to the configured taxonomy. ### Settings | Name | Type | Default value | Description | | ---------- | -------- | ------------- | ------------------------------------ | | `taxonomy` | `string` | `null` | Taxonomy from which entry is chosen. | # TextBlock field type > For the complete documentation index, see [llms.txt](https://doc.ibexa.co/en/saas/llms.txt). The field type handles a block of multiple lines of unformatted text. It's capable of handling up to 16,777,216 characters. | Name | Internal name | Expected input type | | ----------- | ------------- | ------------------- | | `TextBlock` | `ibexa_text` | `string` | ## Input expectations | Type | Example | | -------- | --------------------------------------- | | `string` | `"This is a block of unformatted text"` | ### Properties The Value class of this field type contains the following properties: | Property | Type | Description | | -------- | -------- | ------------------------------------------- | | `$text` | `string` | This property is used for the text content. | ## Validation This field type doesn't perform any special validation of the input value. ## Settings Settings contain only one option: | Name | Type | Default value | Description | | ---------- | --------- | ------------- | ------------------------------------------------------------- | | `textRows` | `integer` | `10` | Number of rows for the editing box in the back-end interface. | # TextLine field type > For the complete documentation index, see [llms.txt](https://doc.ibexa.co/en/saas/llms.txt). This field type makes possible to store and retrieve a single line of unformatted text. It's capable of handling up to 255 characters. | Name | Internal name | Expected input type | | ---------- | -------------- | ------------------- | | `TextLine` | `ibexa_string` | `string` | ## Properties The Value class of this field type contains the following properties: | Property | Type | Description | | -------- | -------- | ------------------------------------------- | | `$text` | `string` | This property is used for the text content. | ## Validation The input passed into this field type is subject to validation by the `StringLengthValidator`. The length of the string provided must be between the minimum length defined in `minStringLength` and the maximum defined in `maxStringLength`. The default value for both properties is 0, which means that the validation is disabled by default. To set the validation properties, the `validateValidatorConfiguration()` method needs to be inspected, which receives an array with `minStringLength` and `maxStringLength` like in the following representation: # Time field type > For the complete documentation index, see [llms.txt](https://doc.ibexa.co/en/saas/llms.txt). This field type represents time information. Date information is **not stored**. What is stored is the number of seconds, calculated from the beginning of the day in the given or the environment timezone. | Name | Internal name | Expected input type | | ------ | ------------- | ------------------- | | `Time` | `ibexa_time` | mixed | ## Input expectations If input value is of type `string` or `integer`, it's passed directly to the [PHP's built-in `\DateTime` class](https://www.php.net/manual/en/datetime.construct.php) constructor, therefore the same input format expectations apply. It's also possible to directly pass an instance of `\DateTime`. | Type | Example | | ----------- | ---------------------------------- | | `string` | `"2012-08-28 12:20 Europe/Berlin"` | | `integer` | `1346149200` | | `\DateTime` | `new \DateTime()` | ### Properties The Value class of this field type contains the following properties: | Property | Type | Description | | -------- | ------------------- | --------------------------------------------------------------------------------- | | `$time` | `integer` or `null` | Holds the time information as a number of seconds since the beginning of the day. | ### Hash format Value in hash format is an integer representing a number of seconds since the beginning of the day. Example: `36000` ## Validation This field type doesn't perform validation of the input value. ## Settings The Field definition of this field type can be configured with several options: | Name | Type | Default value | Description | | ------------- | ------------------------------------------------ | --------------------- | --------------------------------------------------------------------------------- | | `useSeconds` | `boolean` | `false` | Used to control displaying of seconds in the output. | | `defaultType` | `Type::DEFAULT_EMPTY Type::DEFAULT_CURRENT_TIME` | `Type::DEFAULT_EMPTY` | The constant used here defines default input value when using back-end interface. | # URL field type > For the complete documentation index, see [llms.txt](https://doc.ibexa.co/en/saas/llms.txt). This field type makes it possible to store and retrieve a URL. It's formed by the combination of a link and the respective text. | Name | Internal name | Expected input | | ----- | ------------- | -------------- | | `Url` | `ibexa_url` | `string` | ## Input expectations | Type | Description | Example | | -------- | --------------------------------------------- | ------------------------ | | `string` | Link content provided to the value. | "" | | `string` | Text content that represents the stored link. | "Ibexa" | ### Properties The Value class of this field type contains the following properties: | Property | Type | Description | | -------- | -------- | ---------------------------------------------------------------------------------------------------- | | `$link` | `string` | This property stores the link provided to the value of this field type. | | `$text` | `string` | This property stores the text to represent the stored link provided to the value of this field type. | ## Hash format | Key | Type | Description | Example | | ------ | -------- | ------------- | ------------------------- | | `link` | `string` | Link content. | "" | | `text` | `string` | Text content. | "Ibexa" | ## Validation This field type doesn't perform validation. But some validation can be made afterward, see [External URL validation](https://doc.ibexa.co/en/saas/content_management/url_management/url_management/#external-url-validation) for more information. ## Settings This field type doesn't have settings. # User field type > For the complete documentation index, see [llms.txt](https://doc.ibexa.co/en/saas/llms.txt). This field type validates and stores information about a user. | Name | Internal name | Expected input | | ------ | ------------- | -------------- | | `User` | `ibexa_user` | ignored | ## Field value | Property | Type | Description | Example | | ------------------ | ----------------- | ------------------------------------------------------------------------------------------------------------------------------------------------ | --------------------------------- | | `hasStoredLogin` | `boolean` | Denotes if user has stored login. | `true` | | `contentId` | `int` or `string` | ID of the content item corresponding to the user. | `42` | | `login` | `string` | Username. | `john` | | `email` | `string` | The user's email address. | `john@smith.com` | | `passwordHash` | `string` | Hash of the user's password. | `1234567890abcdef` | | `passwordHashType` | `mixed` | Algorithm user for generating password hash as a `PASSWORD_HASH_*` constant defined in `Ibexa\Contracts\Core\Repository\Values\User\User` class. | `User::PASSWORD_HASH_PHP_DEFAULT` | | `maxLogin` | `int` | Maximum number of concurrent logins. | `1000` | ### Available password hash types | Constant | Description | | ----------------------------------------------------------------------------- | ------------------------------------------------------------------------- | | `Ibexa\Contracts\Core\Repository\Values\User\User::DEFAULT_PASSWORD_HASH` | Default password hash, used when none is specified, may change over time. | | `Ibexa\Contracts\Core\Repository\Values\User\User::PASSWORD_HASH_PHP_DEFAULT` | Passwords hashed by PHP's default algorithm, which may change over time. | | `Ibexa\Contracts\Core\Repository\Values\User\User::PASSWORD_HASH_BCRYPT` | Bcrypt hash of the password. | # AI # Artificial Intelligence > For the complete documentation index, see [llms.txt](https://doc.ibexa.co/en/saas/llms.txt). AI interactions with Cohesivo Cohesivo includes built-in AI capabilities. For example, it can provide recommendations to product customers and content readers with the [Raptor connector](https://doc.ibexa.co/en/saas/recommendations/raptor_integration/raptor_connector_guide/index.md), and assist editors in the back office with [AI Actions](https://doc.ibexa.co/en/saas/ai/ai_actions/ai_actions_guide/index.md). The platform is also open to external AI integrations through [MCP (Model Context Protocol) servers](https://doc.ibexa.co/en/saas/ai/mcp/mcp_guide/index.md), which allow AI agents to interact with the system in a standardized way. You can also expose [new MCP server capabilities](https://doc.ibexa.co/en/saas/ai/mcp/mcp_usage/index.md). AI integration goes even further: - Some AI agents can learn how to use the [REST](https://doc.ibexa.co/en/saas/api/rest_api/rest_api_usage/rest_api_usage/index.md) API. - [AI Actions](https://ez-systems-developer-documentation--3403.com.readthedocs.build/en/3403/ai/ai_actions/ai_actions/): AI Actions help editors by automating repetitive tasks. - [MCP Servers](https://ez-systems-developer-documentation--3403.com.readthedocs.build/en/3403/ai/mcp/mcp/): Overview of MCP resources in Cohesivo # AI Actions > For the complete documentation index, see [llms.txt](https://doc.ibexa.co/en/saas/llms.txt). AI Actions help editors by automating repetitive tasks. AI Actions enhance the usability and flexibility of Cohesivo by automating various tasks. After you configure it, it can generate alt text for images or transform text passages. ## Getting Started - [AI Actions product guide](https://ez-systems-developer-documentation--3403.com.readthedocs.build/en/3403/ai/ai_actions/ai_actions_guide/): AI Actions help editors by automating repetitive tasks. - [Configure AI Actions](https://ez-systems-developer-documentation--3403.com.readthedocs.build/en/3403/ai/ai_actions/configure_ai_actions/): Configure AI Actions. - [Taxonomy suggestions](https://ez-systems-developer-documentation--3403.com.readthedocs.build/en/3403/content_management/taxonomy/taxonomy/#taxonomy-suggestions): Learn how to use AI to suggest tags and categories - [Policies](https://ez-systems-developer-documentation--3403.com.readthedocs.build/en/3403/permissions/policies/#ai-actions): Learn about the available AI Actions policies - [Work with AI Actions](https://doc.ibexa.co/projects/userguide/en/6.0/ai_actions/work_with_ai_actions/): Create new AI actions or modify existing ones to work faster and increase creativity. ## Development - [REST API Reference](https://doc.ibexa.co/en/6.0/api/rest_api/rest_api_reference/rest_api_reference.html#tag/Connector-AI): See the available endpoints for AI Actions - [Action Configuration Search Criterion reference](https://ez-systems-developer-documentation--3403.com.readthedocs.build/en/3403/search/ai_actions_search_reference/action_configuration_criteria/): Search Criteria available for Action Configuration search - [Action Configuration Search Sort Clauses reference](https://ez-systems-developer-documentation--3403.com.readthedocs.build/en/3403/search/ai_actions_search_reference/action_configuration_sort_clauses/): Sort Clauses available for Action Configuration search # AI Actions product guide > For the complete documentation index, see [llms.txt](https://doc.ibexa.co/en/saas/llms.txt). AI Actions help editors by automating repetitive tasks. ## What are AI Actions Wherever you look, artificial intelligence becomes more and more important by enhancing user interaction and automating complex processes. Cohesivo is equipped with the AI Actions feature, which harnesses AI's potential to automate time-consuming editorial tasks. AI Actions is an extensible solution for integrating features provided by AI services into your workflows, all managed through a user-friendly interface. Out-of-the-box, AI Actions solution includes two essential components: a framework package and an OpenAI connector package. AI Actions can integrate with [Ibexa Connect](https://doc.ibexa.co/projects/connect/en/latest/general/ibexa_connect/), to give you an opportunity to build complex data transformation workflows without having to rely on custom code. From the developer's perspective, the integration removes the burden of maintaining third-party AI handlers, and accelerates the deployment of AI-based solutions. AI Actions solution comes pre-configured with the following action types: - [Refine text](#refining-text): Rewrite existing text according to instructions set in a prompt - [Generate alternative text](#generating-alternative-text): Generate alt text for images for accessibility purposes - [Suggest taxonomy entries](#suggesting-taxonomy-entries): Generate tag or product category suggestions based on content fields ![AI Actions schematic](https://doc.ibexa.co/en/saas/ai/ai_actions/img/guide_ai_actions.png) You can extend the solution's capabilities beyond the default setup by creating custom connector modules, allowing users to take advantage of additional AI services, or customize the way data is processed and interpreted. For example, it could transform images, or generate illustrations for your articles based on their contents. The possibilities are endless and you're not limited to a specific AI service, avoiding vendor lock-in. ## Availability AI Actions are available in Cohesivo. To begin using AI Actions, you must first [perform the initial configuration](https://doc.ibexa.co/en/saas/ai/ai_actions/configure_ai_actions/index.md). ### Prerequisites Connectors with external AI services delivered by Ibexa require that you first install them, and [configure other settings, such as an API key and billing method](https://doc.ibexa.co/en/saas/ai/ai_actions/configure_ai_actions/index.md). Integration with Ibexa Connect requires that you first [get the credentials](https://doc.ibexa.co/projects/connect/en/latest/general/ibexa_connect/#access-ibexa-connect) to your account, and the [API token](https://doc.ibexa.co/en/saas/ai/ai_actions/configure_ai_actions/#create-token). > **Note: Ibexa Connect Availability** > > Ibexa Connect comes with all contracts signed from 2023. If you signed your contract earlier, contact your customer success manager to use Ibexa Connect. ## How it works AI Actions rely on an extensible AI framework, which is responsible for gathering information from various sources, such as AI action types, AI action configurations, and contextual details like SiteAccess, user details, locale settings, and more. This data can then be combined with user input. It's then passed to a service connector, such as the default OpenAI connector or the Ibexa Connect connector, for final processing on Cohesivo side. The service connector wraps all data into a prompt or another suitable format and sends it to an external service. When the external service returns a response, the response goes back through the service connector and passes to the framework. It can then be presented to the user in any way necessary. ### Core concepts #### AI service AI service is a third party platform that provides access to artificial intelligence tools and capabilities. It executes tasks that it receives through a service connector. #### Action Actions are tasks or functions that are executed by an external AI service. Each action is a combination of an AI action type and an AI action configuration. Action types define what kind of task the AI service performs, while AI action configurations specify how the task should be executed. This clear separation allows for a flexible system where actions can be created, managed, and customized with minimal effort. #### AI action type AI action types are high level templates predefined by developers. AI action types correspond to tasks that users intend to perform when they interact with the interface. Each AI action type defines the structure and nature of the task that the AI service performs, and is interpreted by a handler. Action type definitions specify the following information: - an identifier - a set of input parameters - a set of output fields - a category of action, for example, "text to image", "video to text" AI action types could be designed, for example, to generate alternative text based on an image, translate a selected passage of text, or generate a video clip based on a description provided in the field. By defining AI action types, developers can create a wide range of functionalities that can be deployed within the application. #### AI action configuration AI action configurations store detailed parameters needed to generate AI actions based on AI action types. Website administrators manage AI action configurations in the [**Admin** panel](https://doc.ibexa.co/en/saas/administration/admin_panel/admin_panel/index.md), where they customize and fine-tune the behavior of each AI action. It might involve setting specific parameters used by the AI service, a response length, an expense limit, or configuring how the output should be handled. By making such adjustments, administrators can ensure that the actions are tailored to meet the needs of your organization. #### Model Once an AI action is defined and configured, it must be executed, and this is where models come into play. Each model is designed to work with a specific AI service and AI action type pair. Pieces of PHP code that are responsible for resolving a model are called handlers. They may include hardcoded prompts for conversational AI services like ChatGPT, or operate without prompts in the case of other types of AI. Handlers take parameters defined in the AI action type and configuration, combine it with user input and any predefined settings or prompts, and pass this information to the AI service for processing. ### Triggering actions from the UI Among other elements, AI Actions include UI components that are used in: - AI action management in the **Admin** panel - text modification in online editor - alt-text generation in the image management modal These areas are user-friendly and well integrated with the existing application’s UI. Administrators can manage action configurations with ease, while editors can trigger actions with a click of a button. Procedures are straightforward and intuitive, ensuring that users can quickly achieve their desired outcomes. ### Triggering actions programmatically AI Actions feature exposes a REST API interface that allows for programmatic execution of AI actions. With the API, developers can automate tasks and execute actions on batches of content by integrating them into workflows. For more information, see the [AI actions section in the REST API Reference](https://doc.ibexa.co/en/saas/api/rest_api/rest_api_reference/rest_api_reference.html#ai-actions-execute-ai-action). ## Capabilities ### Management Users with the appropriate permissions, governed by role-based [policies](https://doc.ibexa.co/en/saas/permissions/policies/#ai-actions), can control the lifecycle of AI actions by creating, editing, executing, and deleting them. Additionally, AI action configurations can be enabled or disabled depending on the organization's needs. ![Configurations management screen](https://doc.ibexa.co/en/saas/ai/ai_actions/img/ai_actions_list.png) An intuitive AI Actions interface within the **Admin** panel displays a list of all available AI actions. Here, you can search for specific actions and filter them by type or status. By accessing the detailed view of individual AI actions, you can quickly review all their parameters. ## Use cases Out of the box, after you configure access to the OpenAI service, AI Actions come with two action types that can help your organization with the following tasks. ### Refining text Content editors can benefit from using AI capabilities to [enhance or modify text](https://doc.ibexa.co/projects/userguide/en/6.0/content_management/create_edit_content_items/#ai-assistant). With a few clicks, they can improve content quality or reduce the workload. While working on content, editors can request that AI performs specific actions such as: adjusting the length of the text, changing the tone, or correcting linguistic errors. ![AI Assistant](https://doc.ibexa.co/en/saas/ai/ai_actions/img/ai_assistant.png) This functionality is available in content types that include RichText, Text line, Text Block fields, and certain Page Builder blocks. ### Generating alternative text Media managers and content editors can benefit from employing AI to [generate alt text for images](https://doc.ibexa.co/projects/userguide/en/6.0/image_management/upload_images/#ai), which results in improved accessibility and SEO. Once the feature is configured, editors can generate alt text for images they upload to the system by clicking one button. ![Alt text generation](https://doc.ibexa.co/en/saas/ai/ai_actions/img/alt_text_use_ai.png) With some customization, administrators could use the API to run a batch process against a larger collection of illustrations. ### Suggesting taxonomy entries Content editors and product managers can use [taxonomy suggestions](https://doc.ibexa.co/en/saas/content_management/taxonomy/taxonomy/#taxonomy-suggestions) when assigning tags or product categories to content items and products. Instead of manually browsing through extensive taxonomy trees, editors can request suggestions based on the content's text fields, such as name and description. > **Note: Alternative suggestion provider** > > By default, embeddings used by the taxonomy suggestions feature are generated with OpenAI. If you configure the [Google Gemini connector](https://doc.ibexa.co/en/saas/ai/ai_actions/configure_ai_actions/#configure-google-gemini-connector), you can modify the [taxonomy suggestions settings](https://doc.ibexa.co/en/saas/content_management/taxonomy/taxonomy/#change-embeddings-provider-to-google-gemini) and use Google Gemini as an alternative embeddings provider. ### Performing advanced image to text analysis With some additional customization, store managers could benefit from automating part of product management by integrating their Cohesivo with Google Cloud Vision and the [product catalog](https://doc.ibexa.co/en/saas/product_catalog/product_catalog_guide/index.md) by using Ibexa Connect. Instead of manually selecting and linking images stored in a [DAM](https://doc.ibexa.co/en/saas/content_management/images/add_image_asset_from_dam/index.md) solution to their products, they could use of a no-code workflow where an AI service, for example, Google Cloud Vision, extracts text and attributes from product images, which are then matched with existing items in a product catalog. This would enable automatic product identification, tagging, and catalog updates, resulting in less manual work and more efficient product management. # Configure AI Actions > For the complete documentation index, see [llms.txt](https://doc.ibexa.co/en/saas/llms.txt). Configure AI Actions. AI Actions are available in Cohesivo. To use this feature you must first configure the built-in service connectors. Once the framework is configured, before you can start using AI Actions, you can configure access to Ibexa-made service connectors by following the instructions below. Once the connectors are configured, you can start [working with the AI Actions feature](https://doc.ibexa.co/projects/userguide/en/6.0/ai_actions/work_with_ai_actions/). > **Note: Taxonomy suggestions** > > The default OpenAI or the optional Google Gemini connectors can used by the [Taxonomy suggestions](https://doc.ibexa.co/en/saas/content_management/taxonomy/taxonomy/#taxonomy-suggestions) feature to generate embeddings for suggesting tags and product categories. After you configure the OpenAI connector, or set up the optional Google Gemini connector and [modify the default taxonomy suggestions settings](https://doc.ibexa.co/en/saas/content_management/taxonomy/taxonomy/#change-embeddings-provider-to-google-gemini), you can [create AI actions that use the Text to Taxonomy action type](https://doc.ibexa.co/projects/userguide/en/6.0/ai_actions/work_with_ai_actions/#create-ai-actions-that-control-taxonomy-suggestions). ## Configure access to OpenAI To use the built-in connector with the OpenAI service, you need to create an OpenAI account, [get an API key](https://help.openai.com/en/articles/4936850-where-do-i-find-my-openai-api-key), and make sure that you [set up a billing method](https://help.openai.com/en/articles/9038407-how-can-i-set-up-billing-for-my-account). Provide the API key in your instance's OpenAI connector settings. ### Sample OpenAI action configurations The AI actions come with sample AI action configurations to quickly get you started on using the feature. Based on these examples, which reflect the most common use cases, you can learn to configure your own AI actions with greater ease. ## Configure Anthropic connector The Anthropic connector adds basic handlers that let you refine text or generate alternative text for images. To use the connector with the Anthropic services, you need to create an account, make sure that you [set up a billing method](https://support.claude.com/en/articles/8325618-paid-plan-billing-faqs), and get an API key. 1. Log in to your [Anthropic Claude console](https://platform.claude.com/login). 2. Go to **API keys** and click **Create Key**. 3. Select the workspace, enter a **Key Name** and click **Add**. 4. Take a note of the API key, because it is displayed only once. Provide the API key in your instance's Anthropic connector settings. By default, when reaching out for responses, the Anthropic connector uses the [Claude Sonnet 4](https://platform.claude.com/docs/en/about-claude/models/overview) model. Users can override this setting at runtime when they [edit or create an AI action](https://doc.ibexa.co/projects/userguide/en/6.0/ai_actions/work_with_ai_actions/#edit-existing-ai-actions). You can also change the default values globally. To do it, add configuration similar to this example: ```yaml ibexa_connector_anthropic: text_to_text: default_model: claude-sonnet-4-6 default_temperature: 0.8 default_max_tokens: 2045 models: claude-haiku-4-5-20251001: 'Claude Haiku 4.5 (fast, cost-efficient)' claude-sonnet-4-6: 'Claude Sonnet 4.6 (recommended)' claude-opus-4-6: 'Claude Opus 4.6 (advanced reasoning)' claude-opus-4-7: 'Claude Opus 4.7 (most capable)' ``` You can now use the Anthropic connector in your project. > **Note: Current model availability** > > Anthropic regularly releases new models and deprecates older ones. Before you configure the connector, check the [Anthropic models overview](https://platform.claude.com/docs/en/about-claude/models/overview) for the current list of supported model identifiers. ## Configure Google Gemini connector The Google Gemini connector adds basic handlers that let you refine text or generate alternative text for images. ### Get API key To use the connector with the Gemini services, you need to create an account, set up billing, enable Gemini API and get an API key. #### Create the Google Cloud project 1. Sign in to the [Google Cloud Console](https://console.cloud.google.com/). 2. In the top bar, click **Default Gemini Project** to open a project picker. 3. Click **New project** and provide project details: 1. Add project name, for example, "My project". 2. Modify the automatically generated **Project ID** if necessary. 3. Select location: choose your organization. 4. Click **Create**. #### Configure billing 1. Navigate to the Google Cloud Console's **Billing** page. 2. If you do not have one, click **Add billing account** and add a payment method. 3. In **Your projects** tab, locate your project, and in its line, from the **Actions** menu, select **Change billing**. 4. Select your active billing account, and click **Set account**. #### Enable the Gemini API 1. Navigate to the Google Cloud Console's **APIs & Services** page. 2. From the left-hand menu, select **Library** and search for the Generative Language API. 3. In the API's details page, click **Enable**. #### Generate the API key 1. Go to [Google AI Studio](https://aistudio.google.com/app/api-keys)'s **API keys** page, and click **Create API key**. 2. Provide a name for the API key, select "My project" from a list of projects and click **Create key**. 3. Back in the **API keys** list, in your project's line, copy the API key. ### Set API key in configuration Provide the API key in your instance's Google Gemini connector settings. > **Note: Different API keys for different SiteAccesses** > > If there are multiple SiteAccesses in your installation, you can set different API keys for each SiteAccess. To do it, set the keys under the `ibexa.system.` [configuration key](https://doc.ibexa.co/en/saas/administration/configuration/configuration/#configuration-files), like so: > > ```yaml > ibexa: > system: > default: > connector_gemini: > gemini: > api_key: '%env(GEMINI_API_KEY)%' > base_url: 'https://generativelanguage.googleapis.com/v1beta/' # Google Gemini's API endpoint > ``` ### Configure default models By default, when reaching out for responses, the Gemini connector uses the Gemini Pro [model](https://ai.google.dev/gemini-api/docs/models) for text refinement and Gemini Flash model for alternative text generation. Users can override this setting at runtime when they [edit or create an AI action](https://doc.ibexa.co/projects/userguide/en/6.0/ai_actions/work_with_ai_actions/#edit-existing-ai-actions). You can also change the default values globally. To do it, add configuration similar to this example: ```yaml ibexa_connector_gemini: text_to_text: models: gemini-pro-latest: label: 'Gemini Pro Latest' max_tokens: 4096 gemini-flash-latest: label: 'Gemini Flash Latest' max_tokens: 4096 default_model: gemini-pro-latest default_max_tokens: 4096 # Must be <= the model’s max_tokens default_temperature: 0.8 image_to_text: models: gemini-flash-latest: label: 'Gemini Flash Latest' max_tokens: 4096 default_model: gemini-flash-latest default_max_tokens: 4096 default_temperature: 1.0 ``` When setting up models, make sure that you follow these rules: - `default_model` must reference a configured model - `default_max_tokens` must not exceed the model’s limit - If you use the same model for different action types, settings must be consistent > **Note: Google Gemini and taxonomy suggestions** > > To use Google Gemini for generating taxonomy suggestions, ensure that you [change the embeddings provider and model setting accordingly](https://doc.ibexa.co/en/saas/content_management/taxonomy/taxonomy/#change-embeddings-provider-to-google-gemini). You can now use the Gemini connector in your project. ## Configure access to Ibexa Connect First, get the credentials by contacting [Ibexa Support](https://support.ibexa.co). ### Create team In Ibexa Connect, set up the account, and [create a team](https://doc.ibexa.co/projects/connect/en/latest/access_management/teams/#creating-teams). Navigate to the team details page and note down the numerical value of the **Team id** variable. Creating a team matters, because [scenarios](https://doc.ibexa.co/projects/connect/en/latest/scenarios/creating_a_scenario/) that process data coming from your AI action are associated with a team. This way, if your organization has more than one Cohesivo project, each project can be linked to a different team and so can be scenarios used in those projects. If specific users from the team are supposed to modify scenario settings, you must [assign the right roles](https://doc.ibexa.co/projects/connect/en/latest/access_management/teams/#managing-teams) to them. ### Create token Navigate to your Ibexa Connect user's profile, and on the **API ACCESS** tab, create a new token. Select the following scopes to set permissions needed to enable the integration of platforms: - `custom-property-structures:read` - `custom-property-structures:write` - `hooks:read` - `hooks:write` - `scenarios:read` - `scenarios:write` - `team-variables:read` - `team-variables:write` - `teams:write` - `templates:read` - `templates:write` - `udts:read` - `udts:write` ![Creating an API token](https://doc.ibexa.co/en/saas/ai/ai_actions/img/connect_api_token.png) Copy the token code that appears on the tokens list, next to the label. ### Set up credentials Provide the token that you got from Ibexa Connect and the team ID in your instance's Ibexa Connect integration settings. ### Customize templates Return to the Ibexa Connect dashboard and modify the **Template for connect...handler** [templates](https://doc.ibexa.co/projects/connect/en/latest/scenarios/scenario_templates/) by defining the logic needed to process the data. Once the templates are ready, you can build scenarios from them, either directly in Ibexa Connect or in [Cohesivo's user interface](https://doc.ibexa.co/projects/userguide/en/6.0/ai_actions/work_with_ai_actions/#create-new-ai-actions). # MCP Servers > For the complete documentation index, see [llms.txt](https://doc.ibexa.co/en/saas/llms.txt). Overview of MCP resources in Cohesivo The Model Context Protocol (MCP) and MCP Servers allow AI agents to interact with the system in a structured way. - [MCP Servers product guide](https://ez-systems-developer-documentation--3403.com.readthedocs.build/en/3403/ai/mcp/mcp_guide/): MCP servers expose tools, specialized prompts, and resources to AI agents. - [Configure MCP Servers](https://ez-systems-developer-documentation--3403.com.readthedocs.build/en/3403/ai/mcp/mcp_config/): Configure an MCP server that exposes built-in and custom tools, prompts, and resources. - [Work with MCP servers](https://ez-systems-developer-documentation--3403.com.readthedocs.build/en/3403/ai/mcp/mcp_usage/): Create custom capabilities for your MCP servers and test them. # MCP Servers product guide > For the complete documentation index, see [llms.txt](https://doc.ibexa.co/en/saas/llms.txt). MCP servers expose tools, specialized prompts, and resources to AI agents. ## What is MCP Servers MCP ([Model Context Protocol](https://modelcontextprotocol.io/docs/2025-11-25/getting-started/intro)) is a protocol that standardizes how AI systems interact with external systems. While [AI actions](https://doc.ibexa.co/en/saas/ai/ai_actions/ai_actions_guide/index.md) integrate AI with the back office, Cohesivo's [MCP Servers](https://modelcontextprotocol.io/docs/2025-11-25/learn/server-concepts) offer an API that can be used by AI agents from the outside of the system. Because MCP is a standard protocol, many agents are already trained to use it. They can interact directly with the REST API if their users provide detailed instructions through prompts, skill files, etc. However, when facing a specific REST API, an agent may misunderstand the purpose of endpoints, hallucinate paths, or send incorrectly structured parameters. MCP servers make the discovery of available capabilities much easier. They help AI agents translate natural language prompts into concrete actions on the system. ![MCP communication diagram showing AI agent client connecting to MCP server within Cohesivo.](https://doc.ibexa.co/en/saas/ai/mcp/img/mcp-com-diagram.png) An MCP server allows the agent to discover available tools, inspect their parameters, learn how to use them, and select the correct action. ## Capabilities With the MCP Servers feature, you can: - create MCP servers [by using YAML configuration](https://doc.ibexa.co/en/saas/ai/mcp/mcp_config/#mcp-server-configuration) - assign different tools, prompts, and resources to different MCP servers, varying them for each site and purpose - use [built-in tools](https://doc.ibexa.co/en/saas/ai/mcp/mcp_config/#built-in-tools) included in the package MCP servers are defined specifically for each repository and assigned to individual [SiteAccesses](https://doc.ibexa.co/en/saas/multisite/siteaccess/siteaccess/index.md) scopes. This way you can build flexible configurations that match different contexts. # Configure MCP Servers > For the complete documentation index, see [llms.txt](https://doc.ibexa.co/en/saas/llms.txt). Configure an MCP server that exposes built-in and custom tools, prompts, and resources. With Cohesivo's MCP Servers, you can expose [MCP servers](https://doc.ibexa.co/en/saas/ai/mcp/mcp_guide/index.md) to external AI agents. MCP Servers feature comes with [built-in tools](#built-in-tools) but doesn't come with a default configuration. You have to create your own MCP servers by providing [their configuration](#mcp-server-configuration) and [enable JWT authentication for them](#jwt-mcp-firewall). ## Configure authentication ### JWT MCP firewall AI agents use JWT authentication against Cohesivo's MCP servers. The `authorization_header` token extractor must be enabled, so that a JWT token bearer can be sent in the `Authorization` header. Two firewalls are involved: - `ibexa_jwt_rest` enables requesting JWT tokens through the REST API. - `ibexa_jwt_mcp` allows the use of JWT authentication against MCP servers. ```yaml security: firewalls: # … ibexa_jwt_mcp: request_matcher: Ibexa\Mcp\Security\McpRequestMatcher user_checker: Ibexa\Core\MVC\Symfony\Security\UserChecker provider: ibexa stateless: true jwt: ~ ``` > **Note: Authentication for the APIs** > > You don't need to activate JWT authentication for the REST API. > > For sample JWT token requests, see [REST JWT authentication](https://doc.ibexa.co/en/saas/api/rest_api/rest_api_authentication/#jwt-authentication) and [cURL test of MCP server](https://doc.ibexa.co/en/saas/ai/mcp/mcp_usage/#perform-curl-test). ### Repository user The AI agents authenticate against the MCP server with a JWT token generated for a specific repository user account. This repository user can be: - an individual user account (for example, of an editor or administrator) - a dedicated account created specifically for AI integrations The repository user can generate a JWT token with their own account, or a secondary dedicated account, and pass the token to the MCP client. A gateway could use a dedicated shared repository user to generate a JWT token and establish the connection. ## MCP server configuration You define MCP servers within a repository configuration and then assign those servers to specific SiteAccess scopes. ```yaml ibexa: repositories: : mcp: : path: enabled: true # Server options… discovery_cache: session: type: # Session options… allowed_hosts: - '' system: : mcp: servers: - ``` Servers are automatically registered as services with an ID following the pattern `ibexa.mcp.server..`. Routes are built automatically from MCP server `path` configs. Those routes are identified as `ibexa.mcp.`. ### MCP server options | Option | Type | Required | Default | Description | | --------------------------------------------------------------------------------------------------------------- | ------- | -------- | ----------------------------------------------- | ---------------------------------------------------------------- | | `path` | string | Yes | | MCP server endpoint path (appended to SiteAccess-aware base URL) | | `enabled` | boolean | No | `false` | Server state: decides whether it is enabled or disabled | | `version` | string | No | `1.0.0` | MCP server version | | [`description`](https://modelcontextprotocol.io/specification/2025-11-25/schema#implementation-description) | string | No | `null` | Server implementation description | | [`instructions`](https://modelcontextprotocol.io/specification/2025-11-25/schema#initializeresult-instructions) | string | No | `null` | Prompt-like instructions provided to the AI agent | | [`tools`](#tool-configuration) | array | No | `[]` | List of tool classes | | [`discovery_cache`](#discovery-cache) | string | Yes | | PSR-6 or PSR-16 cache pool service identifier | | [`session`](#session-storage) | object | No | `{ type: psr16,` `service: ibexa.cache_pool }` | Session storage configuration | | [`allowed_hosts`](#allowed-hosts) | array | No | `[` `'localhost',` `'127.0.0.1',` `'[::1]'` `]` | Accepted `Host` headers | > **Note: New servers are disabled by default** > > After you define a server, it remains disabled until you explicitly enable it. ### Tool configuration The main capabilities of an MCP server are called [tools](https://modelcontextprotocol.io/specification/2025-11-25/server/tools). They are the actions that an AI agent can invoke on the system. > **Note: MCP server design best practices** > > Avoid creating MCP servers with large tool sets. Too many tools make it more difficult for the AI agent to select the appropriate action. Instead, create multiple MCP servers with specific sets of tools dedicated to specific contexts or use cases. When designing MCP servers, focus on the needs and tasks of the human user who actually interacts with the AI agent rather than exploring every technical capability. There are two ways to associate tools with a server: - By listing PHP classes (FQCNs) in the server's configuration `tools`. All tools marked with the `McpTool` attribute in those classes are automatically associated with the server (for example, for [built-in](#built-in-tools) or third party tools). - By using the `servers` argument in [`McpTool` attribute](https://doc.ibexa.co/en/saas/ai/mcp/mcp_usage/#tools) to explicitly associate a specific tool with MCP servers. #### Built-in tools MCP Servers come with the following **experimental** built-in tools: - `Ibexa\Mcp\Tool\ContentType\ContentTypeTools` - `get_content_type` - gets a content type by its ID. - `get_content_type_by_identifier` - gets a content type by its identifier. - `get_content_type_list` - gets content types by their IDs. - `create_content_type` - creates a draft for a new content type. - `create_content_type_draft` - creates a draft for an existing content type. - `get_content_type_draft` - gets a content type draft by content type ID. - `publish_content_type_draft` - publishes a content type draft by content type ID. - `Ibexa\Mcp\Tool\ContentType\FieldDefinitionTools` - `add_field_definition` - adds a field definition to a content type draft. - `update_field_definition` - updates a field definition in a content type draft. - `remove_field_definition` - removes a field definition from a content type draft. - `Ibexa\Mcp\Tool\ContentType\ContentTypeGroupTools` - `get_content_type_groups` - gets all content type groups. - `Ibexa\Mcp\Tool\TranslationTools` - `list_languages` - lists all languages in the current SiteAccess. - `list_content_languages` - lists languages which have translations for a given content item. - `list_non_translated_content_ids` - lists IDs of content which have missing translations for a given language code. - `Ibexa\Mcp\Tool\SeoTools` - `get_non_seo_content_ids` - returns IDs of content items that are missing SEO optimization (no meta title tag). Useful for identifying content that needs SEO attention. ```yaml mcp: : path: enabled: true tools: - Ibexa\Mcp\Tool\TranslationTools - Ibexa\Mcp\Tool\SeoTools # … ``` > **Caution: Experimental tools** > > The built-in tools are experimental and may change in future releases. They are provided as examples of how to implement tools and how to configure them in an MCP server. As-is, they may not cover all your needs or may not be practical to all AI agents. If you use them, be prepared to update your MCP server configuration and tool usage when upgrading to a new version of Cohesivo. > > See how to build your own tools in [Work with MCP servers](https://doc.ibexa.co/en/saas/ai/mcp/mcp_usage/index.md). ### Discovery cache Discovery is cached to avoid scanning for capabilities on every request. You must provide a PSR-6 or PSR-16 cache pool for this caching. For example, you could set up a dedicated Redis/Valkey: ```yaml discovery_cache: cache.redis.mcp ``` For a production cluster, it's recommended to use a Redis/Valkey cache pool so the cache can be shared by all nodes. > **Tip: Tip** > > Use `ibexa.cache_pool` as service identifier to have the default cache service. It can be set to `null` to disable caching to ease development, which isn't recommended for production environment. See another example of configuration in [Work with MCP servers](https://doc.ibexa.co/en/saas/ai/mcp/mcp_usage/#configure-mcp-server). ### Session storage MCP servers store session data in their own way. #### Options | Option | Type | Default | Description | | ----------- | ------- | ------------------ | -------------------------------------------------------------- | | `type` | enum | `psr16` | Session store type: [`psr16`](#psr-16) or [`file`](#file) | | `service` | string | `ibexa.cache_pool` | PSR-16 or PSR-6 cache service ID for the `psr16` session store | | `prefix` | string | `mcp_` | Key prefix for the `psr16` session store | | `directory` | string | `null` | Directory path for the `file` session store | | `ttl` | integer | `3600` | Session TTL in seconds | In production, it’s recommended to use [`psr16`](#psr-16) with Redis/Valkey. #### PSR-16 Sessions are stored with a PSR-16 or PSR-6 compatible cache implementation. It requires that a `service` option points to a valid cache service ID. Optionally, you could use a more specific `prefix` option than the default `mcp_` to avoid key collisions with other cache usages. Such setup is suitable for production environments. ```yaml session: type: psr16 service: cache.redis.mcp prefix: 'mcp__' services: cache.redis.mcp: public: true class: Symfony\Component\Cache\Adapter\RedisTagAwareAdapter parent: cache.adapter.redis tags: - name: cache.pool clearer: cache.app_clearer provider: 'redis://mcp.redis:6379' namespace: 'mcp' ``` #### File Sessions are stored on the filesystem. This requires that you configure a directory. Such setup is suitable for development environments. In this example, sessions are stored in the `var/cache//mcp/sessions/` directory (for example, `var/cache/dev/mcp/session/` for the `dev` environment, and `var/cache/prod/mcp/sessions/` for the `prod` environment): ```yaml session: type: file directory: '%kernel.cache_dir%/mcp/sessions' ``` ### Allowed hosts This parameter lists the domains, the `Host` headers, accepted by the MCP server. The port is not part of the matching. There is no wildcard character, all cases must be listed. As item, you can use a hostname, an IP, or an IPv6. IPv6 addresses must be bracketed, for example `[::1]`. In this example, only requests from `www.example.com` domain, or from 127.0.0.1 IP are accepted: ```yaml allowed_hosts: - 'www.example.com' - '127.0.0.1' ``` # Work with MCP servers > For the complete documentation index, see [llms.txt](https://doc.ibexa.co/en/saas/llms.txt). Create custom capabilities for your MCP servers and test them. The MCP Servers feature includes several [built-in tools](https://doc.ibexa.co/en/saas/ai/mcp/mcp_config/#built-in-tools). Additionally, you can create your own capabilities (tools, prompts, and resources) to expose custom features to AI agents through your MCP servers. ## MCP server capabilities The Cohesivo MCP server framework (`ibexa/mcp`) is built on top of the [official PHP SDK for MCP (`mcp/sdk`)](https://github.com/modelcontextprotocol/php-sdk). A PHP class that implements MCP server capabilities such as tools, prompts, or resources must: - implement `Ibexa\Contracts\Mcp\McpCapabilityInterface` so that it can be scanned for capabilities - use attributes from the `Ibexa\Contracts\Mcp\Attribute` namespace to declare capabilities ### Tools The `Ibexa\Contracts\Mcp\Attribute\McpTool` attribute declares a method as an MCP tool. It accepts the following optional arguments: - `servers` - array of server identifiers the tool is assigned to For more information, see [tools configuration](https://doc.ibexa.co/en/saas/ai/mcp/mcp_config/#tool-configuration). - `name` - tool codename - if not set, the function name is used - `title` - tool title for user interfaces - if not set, the `name` is used - `description` - tool description, used by AI agents to understand the tool's purpose - `icons` - array of [`Mcp\Schema\Icon`](https://github.com/modelcontextprotocol/php-sdk/blob/main/src/Schema/Icon.php) instances For more information, see the [`icons` specification](https://modelcontextprotocol.io/specification/2025-11-25/basic/index#icons). - `outputSchema` - associative array describing a JSON object response - `annotations` - [`Mcp\Schema\ToolAnnotations`](https://github.com/modelcontextprotocol/php-sdk/blob/main/src/Schema/ToolAnnotations.php) instance For more information, see the [`ToolAnnotations` specification](https://modelcontextprotocol.io/specification/2025-11-25/schema#toolannotations). - `meta` - free-form array for additional metadata For more information, see the [`_meta` specification](https://modelcontextprotocol.io/specification/2025-11-25/basic/index#_meta). The framework automatically builds an `inputSchema` from the method arguments and their types. To customize or extend the generated schema, you can: - add descriptions with DocBlock `@param` tags - use the [`Schema` attribute](https://github.com/php-mcp/server#-schema-generation-and-validation) If an argument is an [enum](https://www.php.net/manual/en/language.types.enumerations.php), its possible values are listed in the schema ([`UntitledSingleSelectEnumSchema`](https://modelcontextprotocol.io/specification/2025-11-25/schema#untitledsingleselectenumschema)). ### Prompts MCP servers can also provide [prompt templates](https://modelcontextprotocol.io/specification/2025-11-25/server/prompts) to help users interact with AI agents connected to the server. Methods that return a prompt are marked with the `Ibexa\Contracts\Mcp\Attribute\McpPrompt` attribute. It accepts several arguments that describe how the prompt is used: - `servers` - array of server identifiers exposing this prompt - required for prompts - `name` (optional) - prompt codename - if not set, the method name is used - `title` (optional) - prompt title - if not set, `name` is used - `description` (optional) - human-readable prompt description - `icons` (optional) - array of [`Mcp\Schema\Icon`](https://github.com/modelcontextprotocol/php-sdk/blob/main/src/Schema/Icon.php) instances For more information, see the [`icons` specification](https://modelcontextprotocol.io/specification/2025-11-25/basic/index#icons). - `meta` (optional) - rarely used free-form array for additional metadata For more information, see the [`_meta` specification](https://modelcontextprotocol.io/specification/2025-11-25/basic/index#_meta). The framework automatically builds the `arguments` array from the method arguments and their types. Prompt method arguments must be strings to comply with the [`GetPromptRequestParams` schema](https://modelcontextprotocol.io/specification/2025-11-25/schema#getpromptrequestparams). To add argument descriptions, use DocBlock `@param` tags, which are mapped to the `description` defined by the [`PromptArgument` schema](https://modelcontextprotocol.io/specification/2025-11-25/schema#promptargument). ## Example To keep the example focused on MCP server configuration and capability creation, it doesn't interact with the Cohesivo repository. ### Create user account In this example, the MCP server uses JWT tokens created with a dedicated user account. In Cohesivo's back office, create a user in the **Guest accounts** user group, with login `ibexa-example` and password `Ibexa-3xample`. ### Configure MCP server This example introduces an MCP server named `example`, with a single tool called `greet`. The server: - is enabled on the default repository - is available in all SiteAccesses - is accessible with the path `/mcp/example` For example: - `http://localhost/mcp/example` - `http://localhost/admin/mcp/example` - uses file storage for both discovery cache and sessions > **Note: Storage choice recommendations** > > Filesystem storage is convenient for the sake of this example and for testing. For production, it's recommended that you use Redis or Valkey to share cache among the cluster and improve performance. > > For development, you can set `discovery_cache: ~` to avoid clearing the cache after each change. This example uses the filesystem storage to illustrate that you have to clear the cache pool to refresh the available capabilities, exactly as when deploying into production. Define a new MCP server for the `default` repository and assign it to all SiteAccesses: ```yaml ibexa: repositories: default: mcp: example: path: /mcp/example enabled: true description: 'Example MCP Server' instructions: 'Use this server to greet someone.' discovery_cache: cache.tagaware.filesystem session: type: psr16 service: cache.tagaware.filesystem allowed_hosts: - '127.0.0.1' system: default: mcp: servers: - example ``` Adapt the `allowed_hosts` to your case, for example, if you want to use a domain name instead of the equivalent `127.0.0.1` address. The server is automatically registered as a service with the ID `ibexa.mcp.server.default.example`, and an `ibexa.mcp.example` route becomes available. ### Perform `curl` test To test the `example` MCP server, a sequence of `curl` commands is used to simulate the communication between an AI client and the MCP server. - Ask for a [JWT token through REST](https://doc.ibexa.co/en/saas/api/rest_api/rest_api_reference/rest_api_reference.html#tag/User-Token/operation/api_usertokenjwt_post). - Initialize a connection to the MCP server. - Validate the MCP Session ID. - List the available tools. - Call a tool. `jq`, `grep`, and `sed` are also used to parse or display outputs. First, use the shell script to set the Cohesivo's base URL, user credentials, and MCP server URL as variables for easier reuse: ```bash baseUrl='http://localhost' # Adapt to your test case username='ibexa-example' password='Ibexa-3xample' mcpServer="$baseUrl/mcp/example" ``` Before you can communicate with the MCP server, you must first request a JWT token through the REST API: ```bash curl -s -X 'POST' \ "$baseUrl/api/ibexa/v2/user/token/jwt" \ -H 'Content-Type: application/vnd.ibexa.api.JWTInput+json' \ -H 'Accept: application/vnd.ibexa.api.JWT+json' \ -d "{ \"JWTInput\": { \"_media-type\": \"application/vnd.ibexa.api.JWTInput+json\", \"username\": \"$username\", \"password\": \"$password\" } }" > response.tmp.txt cat response.tmp.txt | jq jwtToken=$(cat response.tmp.txt | jq -r .JWT.token) rm response.tmp.txt ``` ```json { "JWT": { "_media-type": "application/vnd.ibexa.api.JWT+json", "_token": "1234567890ABCDEFGHIJKLMNOPQRSTUVWXYZ.abcdefghijklmnopqrstuvwxyz1234567890ABCDEFGHIJKLMNOPQRSTUVWXYZ1234567890abcdefghijklmnopqrstuvwxyz1234567890ABCD.EFGHIJKL-MNOPQRSTUVWXYZ12345678901234567890", "token": "1234567890ABCDEFGHIJKLMNOPQRSTUVWXYZ.abcdefghijklmnopqrstuvwxyz1234567890ABCDEFGHIJKLMNOPQRSTUVWXYZ1234567890abcdefghijklmnopqrstuvwxyz1234567890ABCD.EFGHIJKL-MNOPQRSTUVWXYZ12345678901234567890" } } ``` Then, perform [initialization](https://modelcontextprotocol.io/specification/2025-11-25/basic/lifecycle#initialization) to get an MCP session ID: ```bash cat response.tmp.txt | jq jwtToken=$(cat response.tmp.txt | jq -r .JWT.token) rm response.tmp.txt curl -s -i -X 'POST' "$mcpServer" \ -H "Authorization: Bearer $jwtToken" \ -d '{ "jsonrpc": "2.0", "id": 1, "method": "initialize", "params": { "protocolVersion": "2025-03-26", "capabilities": {}, "clientInfo": { "name": "test-curl-client", "version": "1.0.0" } } }' > response.tmp.txt sed '$d' response.tmp.txt tail -n 1 response.tmp.txt | jq mcpSessionId=$(cat response.tmp.txt | grep -i 'Mcp-Session-Id:' | sed 's/Mcp-Session-Id: \([0-9a-f-]*\).*/\1/i') rm response.tmp.txt ``` ```http HTTP/1.1 200 OK Access-Control-Allow-Headers: Content-Type, Mcp-Session-Id, Mcp-Protocol-Version, Last-Event-ID, Authorization, Accept Access-Control-Allow-Methods: GET, POST, DELETE, OPTIONS Access-Control-Allow-Origin: * Access-Control-Expose-Headers: Mcp-Session-Id Cache-Control: no-cache, private Content-Type: application/json Date: Tue, 28 Apr 2026 09:53:27 GMT Mcp-Session-Id: 12345678-9abc-def0-1234-56789abcdef0 ``` ```json { "jsonrpc": "2.0", "id": 1, "result": { "protocolVersion": "2025-06-18", "capabilities": { "logging": {}, "completions": {}, "prompts": { "listChanged": true }, "resources": { "listChanged": true }, "tools": { "listChanged": true } }, "serverInfo": { "name": "example", "version": "1.0.0", "description": "Example MCP Server" }, "instructions": "Use this server to greet someone." } } ``` Validate the initialization: ```bash curl -s -i -X 'POST' "$mcpServer" \ -H "Authorization: Bearer $jwtToken" \ -H "Mcp-Session-Id: $mcpSessionId" \ -d '{ "jsonrpc": "2.0", "method": "notifications/initialized" }' ``` ```http HTTP/1.1 202 Accepted Access-Control-Allow-Headers: Content-Type, Mcp-Session-Id, Mcp-Protocol-Version, Last-Event-ID, Authorization, Accept Access-Control-Allow-Methods: GET, POST, DELETE, OPTIONS Access-Control-Allow-Origin: * Access-Control-Expose-Headers: Mcp-Session-Id ``` Get the [list of tools](https://modelcontextprotocol.io/specification/2025-11-25/server/tools#listing-tools): ```bash curl -s -X 'POST' "$mcpServer" \ -H "Authorization: Bearer $jwtToken" \ -H "Mcp-Session-Id: $mcpSessionId" \ -d '{ "jsonrpc": "2.0", "id": 2, "method": "tools/list" }' | jq ``` ```json { "jsonrpc": "2.0", "id": 2, "result": { "tools": [ { "name": "greet", "inputSchema": { "type": "object", "properties": { "name": { "type": "string", "description": "The name of the person to greet" } }, "required": [ "name" ] }, "description": "Greet a user by name", "annotations": { "readOnlyHint": true, "destructiveHint": false, "idempotentHint": true, "openWorldHint": false }, "icons": [ { "src": "https://openmoji.org/data/color/svg/1F44B.svg" } ], "outputSchema": { "type": "object", "properties": { "general": { "type": "string", "description": "the safe way to greet someone" }, "close": { "type": "string", "description": "when you're close to the person, like friends or relatives" }, "morning": { "type": "string", "description": "when it's in the morning" }, "afternoon": { "type": "string", "description": "when it's the afternoon" }, "evening": { "type": "string", "description": "when it's late in the day" } } } } ] } } ``` [Call](https://modelcontextprotocol.io/specification/2025-11-25/server/tools#calling-tools) the `greet` tool: ```bash curl -s -X 'POST' "$mcpServer" \ -H "Authorization: Bearer $jwtToken" \ -H "Mcp-Session-Id: $mcpSessionId" \ -d '{ "jsonrpc": "2.0", "id": 3, "method": "tools/call", "params": { "name": "greet", "arguments": { "name": "World" } } }' | jq ``` ```json { "jsonrpc": "2.0", "id": 3, "result": { "content": [ { "type": "text", "text": "{\n \"general\": \"Hello, World!\",\n \"close\": \"Hey, World!\",\n \"morning\": \"Good morning, World!\",\n \"afternoon\": \"Good afternoon, World!\",\n \"evening\": \"Good evening, World!\"\n}" } ], "isError": false, "structuredContent": { "general": "Hello, World!", "close": "Hey, World!", "morning": "Good morning, World!", "afternoon": "Good afternoon, World!", "evening": "Good evening, World!" } } } ``` Get the [list of prompts](https://modelcontextprotocol.io/specification/2025-11-25/server/prompts#listing-prompts): ```bash curl -s -X 'POST' "$mcpServer" \ -H "Authorization: Bearer $jwtToken" \ -H "Mcp-Session-Id: $mcpSessionId" \ -d '{ "jsonrpc": "2.0", "id": 4, "method": "prompts/list" }' | jq ``` ```json { "jsonrpc": "2.0", "id": 4, "result": { "prompts": [ { "name": "greet", "description": "Prompt to be greeted by the `greet` tool", "arguments": [ { "name": "name", "description": "The name you want to be greeted by", "required": true } ], "icons": [ { "src": "https://openmoji.org/data/color/svg/1F91D.svg" } ] } ] } } ``` [Get the prompt](https://modelcontextprotocol.io/specification/2025-11-25/server/prompts#getting-a-prompt) of the `greet` method: ```bash curl -s -X 'POST' "$mcpServer" \ -H "Authorization: Bearer $jwtToken" \ -H "Mcp-Session-Id: $mcpSessionId" \ -d '{ "jsonrpc": "2.0", "id": 5, "method": "prompts/get", "params": { "name": "greet", "arguments": { "name": "Firstname Lastname" } } }' | jq ``` ```json { "jsonrpc": "2.0", "id": 5, "result": { "messages": [ { "role": "user", "content": { "type": "text", "text": "Hi. My name is Firstname Lastname. Please, greet me." } } ] } } ``` ### Perform MCP Inspector test You can test your server with the [MCP Inspector](https://modelcontextprotocol.io/docs/tools/inspector). You still need to ask for a JWT token through the REST API, and use it in the MCP Inspector configuration to connect to the server. You can use a web interface to obtain the JWT token: - [REST live documentation](https://doc.ibexa.co/en/saas/api/rest_api/rest_api_authentication/#jwt-token-obtained-through-rest-documentation) #### MCP server settings In this example, the settings needed to use the MCP Inspector are as follows: - Transport Type: Streamable HTTP - URL: actual domain and server `path`, for example `http://localhost/mcp/example` - Connection Type: Via Proxy - Authentication: - Custom Headers: - ☑ `Authorization` - `Bearer ` - OAuth 2.0 Flow: left unedited ![Left panel of MCP Inspector with connection settings for MCP server](https://doc.ibexa.co/en/saas/ai/mcp/img/mcp-inspector-config.png "MCP Inspector connection settings") #### Test MCP server within MCP Inspector In the right panel, in the **Tools** tab, click **List Tools** in the left column. The `greet` tool appears, preceded by its icon. You can select and test it in the right column. ![Right panel of MCP Inspector with a list of tools obtained from MCP server, and the test of the greet tool](https://doc.ibexa.co/en/saas/ai/mcp/img/mcp-inspector-greet-tool.png "MCP Inspector greet tool test") In the **Prompts** tab, in the left column, click **List Prompts**. The `greet` prompt appears, preceded by its icon. You can select and test it in the right column. ![Right panel of MCP Inspector with a list of prompts obtained from the MCP server, and the test of the greet prompt](https://doc.ibexa.co/en/saas/ai/mcp/img/mcp-inspector-greet-prompt.png "MCP Inspector greet prompt test") ### Perform Copilot or Claude Code test You can test your MCP server with [Copilot CLI](https://docs.github.com/en/copilot/concepts/agents/copilot-cli/about-copilot-cli) or [Claude Code CLI](https://code.claude.com/docs/en/overview), as illustrated here, or with any other agent or interface. #### Add MCP server to agent CLI For the sake of the agent test, in this example, you configure the MCP server in an `.mcp.json` file at the Cohesivo project root. This way, it is only available for a session opened from there. You can handle the JWT token for this test in the following ways: - [Hard-code the JWT token](#hard-coded-variant) into the configuration and update it at every expiration. - [Wrap a JWT token request and an MCP server call into a script](#fully-scripted-variant). ##### Hard-coded variant The hard-coded JWT token configuration in `.mcp.json` looks as follows: ```json { "mcpServers": { "ibexa-example": { "type": "http", "url": "http://localhost/mcp/example", "headers": { "Authorization": "Bearer " }, "tools": ["*"] } } } ``` The `.mcp.json` file must be edited to update the JWT token each time it expires. You can request a token by using the GraphiQL web interface or a `curl` command, and then edit the file manually. Alternatively, you can configure a shell script to request the JWT token, extract it from the response, and replace it in the file. When Copilot or Claude Code complains that it can't communicate with the MCP server: **Copilot CLI** - Update the JWT token in the `.mcp.json` file. - Reload the MCP servers in Copilot CLI with one of these methods: - Run `/mcp reload` command to reload all MCP servers. - Run `/mcp disable ibexa-example` and `/mcp enable ibexa-example` to only reload the `ibexa-example` server. > **Note: Reloading multiple MCP servers** > > If you have several MCP servers enabled globally, reloading all of them at the same time can be time-consuming. Consider reloading them one by one. **Claude Code CLI** - Update the JWT token in the `.mcp.json` file. - Run `/mcp reconnect ibexa-example` command to reconnect the `ibexa-example` MCP server. ##### Fully scripted variant The wrapping script configuration in `.mcp.json` looks as follows: ```json { "mcpServers": { "ibexa-example": { "type": "stdio", "command": "bash", "args": ["mcp-ibexa-example-wrapper.sh"], "tools": ["*"] } } } ``` `mcp-ibexa-example-wrapper.sh` is a script that requests a JWT token and establishes a connection with the MCP server. For example, thanks to [`npx`](https://www.npmjs.com/package/npx), you can do it with [Supergateway](https://www.npmjs.com/package/supergateway) without a local installation: ```bash #!/bin/bash set -e baseUrl='http://localhost' # Adapt to your test case mcpServer="$baseUrl/mcp/example" jwtToken=$(curl -s -X 'POST' \ "$baseUrl/api/ibexa/v2/user/token/jwt" \ -H 'Content-Type: application/vnd.ibexa.api.JWTInput+json' \ -H 'Accept: application/vnd.ibexa.api.JWT+json' \ -d '{ "JWTInput": { "_media-type": "application/vnd.ibexa.api.JWTInput+json", "username": "ibexa-example", "password": "Ibexa-3xample" } }' | jq -r .JWT.token) exec npx -y supergateway \ --streamableHttp "$mcpServer" \ --oauth2Bearer "$jwtToken" \ --logLevel none ``` When the agent complains that it can't communicate with the MCP server, reload it: **Copilot CLI** Reload the MCP servers in Copilot CLI with one of these methods: - Run `/mcp reload` command to reload all MCP servers. - Run `/mcp disable ibexa-example` and `/mcp enable ibexa-example` to only reload the `ibexa-example` server. > **Note: Reloading multiple MCP servers** > > If you have several MCP servers enabled globally, reloading all of them at the same time can be time-consuming. Consider reloading them one by one. **Claude Code CLI** Run `/mcp reconnect ibexa-example` command to reconnect the `ibexa-example` MCP server. #### Run MCP server test with Copilot CLI or Claude Code CLI Launch the agent CLI at the project root, where the `.mcp.json` file is located: **Copilot CLI** ```bash cd /path/to/project copilot ``` **Claude Code CLI** ```bash cd /path/to/project claude ``` If prompted, confirm that you trust the files in this folder. You may choose to have your choice remembered for the future. You can check the MCP server status and details with the `/mcp` command: **Copilot CLI** Run the `/mcp show ibexa-example` command to check the MCP server status and details: ```text MCP Server: ibexa-example Type: stdio Command: bash Status: ✓ Connected Source: /path/to/project/.mcp.json Tools (1/1 enabled): ✓ greet: Greet a user by name (70 tokens) ``` **Claude Code CLI** Run the `/mcp` command and select ibexa-example to check the MCP server status and details: ```text Ibexa-example MCP Server Status: ✔ connected Command: bash Args: mcp-ibexa-example-wrapper.sh Config location: /path/to/project/.mcp.json Capabilities: tools Tools: 1 tool ``` You can prompt the agent to greet you. It should use the `greet` tool to do so. - You can ask it "Please, greet me." and it might respond with a request for your name if it doesn't already know it. - You can also give it another name to greet, as shown in the prompt template. During a morning session, the interaction could look like this: **Copilot CLI** ```text ❯ Hi. Please, greet me. ◐ The user wants to be greeted. I'll use the ibexa-example-greet tool, but I don't know their name. Let me ask them first... actually, the tool requires a name. Let me ask the user for their name. Wait, actually I can just greet them without knowing their name using a general greeting, but the tool requires a name parameter. Let me ask for their name. ● Asked user What's your name? └ Pulley ● Greet a user (MCP: ibexa-example) · name: "Pulley" └ {"general":"Hello, Pulley!","close":"Hey, Pulley!","morning":"Good morning, P... ● Good morning, Pulley! ☀️ ❯ Hi. Please, greet me. We're close friends. ◐ The user wants a close friend greeting. From the previous response, I can see the "close" greeting is "Hey, Pulley!" ● Greet a user (MCP: ibexa-example) · name: "Pulley" └ {"general":"Hello, Pulley!","close":"Hey, Pulley!","morning":"Good morning, P... ● Hey, Pulley! 😄 ❯ Please, greet someone named "ElePHPant" in a general way (so I could reuse it at any time) ◐ The user wants a general greeting for someone named "ElePHPant". ● greet (MCP: ibexa-example) · name: "ElePHPant" └ {"general":"Hello, ElePHPant!","close":"Hey, ElePHPant!","morning":"Good morn... ● Hello, ElePHPant! 🐘 ❯ Please, greet someone named "ElePHPant" like it's 22:30 ◐ 22:30 is evening time, so I'll use the evening greeting. ● greet (MCP: ibexa-example) · name: "ElePHPant" └ {"general":"Hello, ElePHPant!","close":"Hey, ElePHPant!","morning":"Good morn... ● Good evening, ElePHPant! 🌙 ``` **Claude Code CLI** ```text ❯ Hi. Please, greet me. ⏺ What's your name? ✻ Worked for 3s ❯ Pulley Called ibexa-example ⏺ Hello, Pulley! 👋 ✻ Churned for 4s ❯ Hi. Please, greet me. We're close friends now. Called ibexa-example ⏺ Hey, Pulley! 👋 ✻ Baked for 4s ❯ Please, greet someone named "ElePHPant" in a general way (so I could reuse it at any time) Called ibexa-example ⏺ Hello, ElePHPant! ✻ Brewed for 5s ❯ Please, greet someone named "ElePHPant" like it's 22:30 ⏺ That falls under the "evening" variant: Good evening, ElePHPant! ✻ Sautéed for 2s ``` The agent's reflections, reaction times, and final responses, including the improvised emojis, may differ from those examples. The key point is that the agent decides to use the `greet` tool, calls it with the right argument, and then uses the call result in its final output. You can fine-tune the prompt, or remove unnecessary variants if needed. For example, you could instruct the agent to always use the time-of-day variants, or simply remove the `general` and `close` variants. Removing what's unnecessary is more efficient than extending the instructions. # Product catalog # Product Catalog > For the complete documentation index, see [llms.txt](https://doc.ibexa.co/en/saas/llms.txt). Cohesivo provides product catalog capabilities for managing products, product types, variants, attributes, pricing, and catalogs. The Product Catalog provides comprehensive capabilities for managing products offered in your digital commerce experience, including their specifications, pricing, and organization. Cohesivo offers robust product catalog infrastructure that can be used standalone. You can also use [Quable](https://doc.ibexa.co/en/saas/product_catalog/quable/quable/index.md) add-on that fully integrates into the Ibexa ecosystem, or the [Remote PIM](https://doc.ibexa.co/en/saas/product_catalog/add_remote_pim_support/index.md) to add integration with any external PIM system. - [Product catalog guide](https://ez-systems-developer-documentation--3403.com.readthedocs.build/en/3403/product_catalog/product_catalog_guide/): The product catalog guide provides a full description of the features and capabilities for managing products, their specifications, variants, pricing, and organization. - [Quable Integration](https://ez-systems-developer-documentation--3403.com.readthedocs.build/en/3403/product_catalog/quable/quable/): Quable integration with Cohesivo - [Products](https://ez-systems-developer-documentation--3403.com.readthedocs.build/en/3403/product_catalog/products/): Products are characterized by attributes describing their characteristics. You can create product variants and add assets to each product and variant. - [Catalogs](https://ez-systems-developer-documentation--3403.com.readthedocs.build/en/3403/product_catalog/catalogs/): Catalogs enable filtering out a selection of products from the Product catalog. - [Product catalog configuration](https://ez-systems-developer-documentation--3403.com.readthedocs.build/en/3403/product_catalog/product_catalog_configuration/): Configure product catalog settings per repository, with different catalog engines and VAT configurations. - [Prices](https://ez-systems-developer-documentation--3403.com.readthedocs.build/en/3403/product_catalog/prices/): The price engine calculates product prices taking into account customer groups, currencies and taxes. # Product catalog guide > For the complete documentation index, see [llms.txt](https://doc.ibexa.co/en/saas/llms.txt). The product catalog guide provides a full description of the features and capabilities for managing products, their specifications, variants, pricing, and organization. ## What is product catalog The product catalog is a comprehensive set of capabilities for managing products in Cohesivo that can be used standalone. It lets you create, configure, and manage products, their specifications, assets, variants, and prices, and group products into categories and catalogs. ## Availability Product catalog capabilities are available in Cohesivo. ## How does product catalog work Products in Cohesivo’s product catalog have underlying content items enriched with product-specific information such as attributes, assets, prices, and others. The product catalog lets you group products into categories and catalogs. Catalogs are collections of products selected by using configurable filters. They're specific to each of your sites or storefronts and only contain the products in them that you wish to sell in their associated storefronts. Catalogs contain a complete list of related products that can be displayed on a store site. You can have as many catalogs as required. ![How does product catalog work](https://doc.ibexa.co/en/saas/product_catalog/img/how_pim_works.png) ## Capabilities ### Product specifications Product specifications rely on product attributes. Available attributes are defined per product type. ### Product attributes Each product has its own, specific attributes. You can describe a product in technical terms, define its physical characteristics such as size, color, or shape, or functional characteristics (for example, for a laptop it could be the operating system, amount of memory, or available ports). Product attributes can belong to one of existing types, for example, numbers, selection, or checkout. Attributes are used as criteria for filtering and searching for products. You can also configure selected product attributes to be used as a basis for variants. ![Product attributes](https://doc.ibexa.co/en/saas/product_catalog/img/product_attributes.png) For more information, see [Product attributes](https://doc.ibexa.co/en/saas/product_catalog/products/#product-attributes) and [Work with product attributes](https://doc.ibexa.co/projects/userguide/en/6.0/product_catalog/work_with_product_attributes/) ### Product variants One product can have multiple versions, for example, there can be a t-shirt in different colors. You can create variants of products, differing in some characteristics, based on product attributes. ![Product variants](https://doc.ibexa.co/en/saas/product_catalog/img/product_attributes.png) ### Product assets Each product or product variant can have assets in a form of images. They can be assigned to the base product or per one or more of its variants. For easier management you can create collections - by using them you can group assets that correspond to specific values of attributes. Created collection is automatically assigned to the variant or variants that have these attribute values. ![Products assets](https://doc.ibexa.co/en/saas/product_catalog/img/product_assets.png) ### Availability Product availability defines whether a product is available in the catalog. For each product you can [set availability](https://doc.ibexa.co/projects/userguide/en/6.0/product_catalog/manage_availability_and_stock/) per variant or per base product. When a product is available, it can have numerical stock defined, that you can set. The stock can also be set to infinite, for example, for digital, downloadable products. A product can only be ordered when it has either positive stock, or stock set to infinite. ### Product categories Product categories help you to organize your products within the product catalog and also create relationships between them. Each product can belong to multiple categories of, depending on user’s choice, different or similar character. Category can also be assigned to multiple products. One of the reasons for applying product categories is assisting users in searching for products. Before you can assign categories to products, you need to [enable product categories](https://doc.ibexa.co/projects/userguide/en/6.0/product_catalog/work_with_product_categories/#enable-product-categories). ![Product categories](https://doc.ibexa.co/en/saas/product_catalog/img/product_categories.png) ### Virtual and physical products Product types in Cohesivo can be either virtual or physical: - **Physical products** are tangible items that require shipping (for example: books, clothing, electronics). - **Virtual products** are items that don't require physical delivery (for example: software licenses, e-books, online courses, digital downloads, additional warranty, tickets for an event). This product type property can affect the checkout process. For example, a cart of only virtual products can skip the shipping step during checkout. To learn more about working with virtual products, see [Virtual products](https://doc.ibexa.co/projects/userguide/en/6.0/product_catalog/create_virtual_product/) in the User Documentation. ### Currencies Currencies are used when calculating product price. In the system you can find a list of available currencies, but you can also create custom ones by providing its code. ### Regions Each product or product type can have different regional pricing and regional VAT rate. You can configure regions in [YAML configuration](https://doc.ibexa.co/en/saas/product_catalog/enable_purchasing_products/#region-and-currency). ### VAT For each product you can configure VAT rate. You can set it globally (per SiteAccess) or individually for each product type and product. To set up different VAT rates for different regions (countries),you need to first configure them in [YAML configuration](https://doc.ibexa.co/en/saas/product_catalog/enable_purchasing_products/#vat-rates). ### Base price For each product or product variant you can set a base price. If you use more than one currency, in the product’s page you can see base price per currency. ### Custom price You can set up different prices depending on customer group or currency. Each customer group can have a default price discount that applies to all products. For example, you can offer a 10% discount for all products in the catalog to users who belong to the Resellers customer group. You can also set different prices for specific products or product variants for different customer groups. ### Product completeness Created product has its own list of the tasks required for product configuration: attributes, assets, content, prices, availability, and more. You can check how complete the configuration is in the product’s view. When you create or edit a product, under the product name, you can see visual indication of what part of product information (tasks) you have completed, and what part is still missing. Product completeness doesn't impact product availability or visibility on the storefront. It is intended to help you ensure that product data is properly populated. As long as your product meets [basic requirements](https://doc.ibexa.co/en/saas/product_catalog/enable_purchasing_products/index.md), it can be published and made available for purchase regardless of its completeness score. ### Catalogs With catalogs you can create product lists for special purposes, for example, for B2B and B2C uses, for retailers and distributors, or for different regions. Catalogs contain a sub-set of products from the system. You can copy existing catalogs, for example, to create a variant version of an offer with slightly differing filters. You can then modify the copied catalog and save the updated version. ### Catalog filters and custom filter When you create a new catalog, all products are included in it by default. To have a better overview for a specific group of products, you can filter the list by: - price (Solr or Elasticsearch only) - product attributes - product type - product code - availability - product category - the date when the product was created Catalog filters let you narrow down the products from the product catalog that are available in the given catalog. ### Remote PIM support Cohesivo provides flexible product catalog infrastructure that works with external PIM systems. In Cohesivo, products are created and maintained by using the REST API or the back office, and their data is stored in a local database. However, in your project or organization, you might have an existing product database, or be specifically concerned about product information security. To address such needs, Cohesivo provides remote PIM support. You can install and configure a readily available [Quable integration](https://doc.ibexa.co/en/saas/product_catalog/quable/quable/index.md) add-on, or build a custom one to connect to a remote PIM or ERP system, pull product data and present it on your website. ![Remote PIM](https://doc.ibexa.co/en/saas/product_catalog/img/remote_pim_support.png) An example implementation is delivered as an optional package that you can [install and customize](https://doc.ibexa.co/en/saas/product_catalog/add_remote_pim_support/index.md) to fulfill your requirements. #### Capabilities With remote PIM support, you can take advantage of the following capabilities: ##### Product marketing Use the product information coming from another system in your marketing campaigns to promote certain products or brands. By embedding the products within content items and landing pages, you can leverage Cohesivo marketing capabilities to showcase products. ##### Pricing, stock and availability A product can only be ordered when it has defined [availability](https://doc.ibexa.co/projects/userguide/en/6.0/product_catalog/manage_availability_and_stock/), stock and [pricing information](https://doc.ibexa.co/projects/userguide/en/6.0/product_catalog/manage_prices/). By default, such information is held in the Cohesivo's local database. In your specific scenario, you can implement the support for availability and pricing information coming from an external source as well, by using a price/availability matching strategy that is an extension point exposed in the Product catalog module. #### Limitations The limitation of remote PIM depend on implementation details of specific integration and may arise in areas relying on [content model](https://doc.ibexa.co/en/saas/content_management/content_model/index.md). To see the limitations of the Quable integration add-on, see [Quable known limitations](https://doc.ibexa.co/en/saas/product_catalog/quable/quable_guide/#known-limitations). ##### Searching Filtering and pagination function the same as with the product catalog, relying on product attributes for effective organization of product data. However, criteria and sort clauses within product catalog relying on Cohesivo's content model are not supported. Depending on your source of product information, you might need to adjust the implementation to be compatible with your data format. For reference, you could review the [`CriterionVisitor` class](https://github.com/ibexa/example-in-memory-product-catalog/blob/main/src/lib/PIM/InMemory/CriterionVisitor.php) that is part of the example implementation described in [Add Remote PIM support](https://doc.ibexa.co/en/saas/product_catalog/add_remote_pim_support/index.md). For more information about product search, see [Product Search Criteria reference](https://doc.ibexa.co/en/saas/search/criteria_reference/product_search_criteria/index.md) and [Product Sort Clauses](https://doc.ibexa.co/en/saas/search/sort_clause_reference/product_sort_clauses/index.md). ##### Catalogs Depending on the implementation, creating [catalogs](#catalogs) might be supported, but the criteria for filtering can be limited. The default implementation, which serves as a basis for the example remote PIM package, has some limitations: certain functionalities either don't operate or operate within defined constraints. Therefore, if your specific requirements aren't met, you may need to extend Cohesivo. ##### Editing product types, products and product attributes Editing product type, product and product attribute information stored in the remote PIM is impossible due to their read-only status. This means that, functionally speaking, communication with PIM is uni-directional, and information is pulled from a remote source but cannot be updated. ##### Content-model-based features The following features rely on Cohesivo's content model capabilities, which aren't supported by the default implementation of remote PIM support. Therefore, if your specific requirements aren't met, you must extend the application by using extension points exposed in the product catalog module. - Assets - Product variants - Product categories - Taxonomy - URL aliases ##### Simplified presentation of product-related blocks and views Enabling Remote PIM impacts a number of application views and blocks, such as Product view, Product list, Catalog, and Product Collection. They're simplified, for example, they don't include thumbnails and other assets, or refer to URL aliases. You can customize them by extending the default implementation. ##### Limited HTTP Caching In the context of remote PIM, it's impossible to use content-aware HTTP caching with `ibexa_http_cache_tag_relation_ids`. ## How to get started To start working with the products, you need to enable purchasing from the catalog. For this, the following configuration is required: - at least one region and one currency added in the shop, - VAT rates set for the product type, - at least one price added for the product, - availability of the product set with positive or infinitive stock. Next, follow steps from [product management in User Documentation](https://doc.ibexa.co/projects/userguide/en/6.0/persona_paths/manage_products/). ## Benefits ### Product technical and marketing information Products added in the shop have both technical and marketing information. You can see all the attributes, specification and variants in a very detailed way, which helps you to manage and present all the products in the technical way. In addition, each product and its variants may have assets in the form of images and a description. Products have underlying content items, which means you can customize the content structure to contain all the marketing information about the product that you need. ### Detailed specification with multiple attribute types Product attributes help you to create products with detailed, complicated specification. Thanks to this, you can create product variants based on multiple product attributes that include different information about a product. Additionally, product attributes are collected in groups so they're easier to manage. ![Multiple attribute types](https://doc.ibexa.co/en/saas/product_catalog/img/product_attribute_types.png) ### Multiple-level variants Product variants enable you to have multiple versions of one product, differing in some characteristics. Each product can have more than one variant on one or more levels. It makes it possible to have multiple-level variants of the products complicated in terms of specifications, such as laptops. ![Multiple-level variants](https://doc.ibexa.co/en/saas/product_catalog/img/multilevel_variants.png) ### Extensible availability By default, you can configure products with specific number in stock, or with infinite availability. You can also extend the availability mechanism to cover other use cases, such as pre-orders. ### Regional pricing including regional VAT rates Each product type can have different regional pricing and regional VAT rate. What is more, you can configure VAT rate globally or set it individually. Thanks to this, the management of the products that can be sold to various markets is easier and more intuitive. ![Regional pricing](https://doc.ibexa.co/en/saas/product_catalog/img/regional_vat.png) ### Customer group-based pricing You can set up different prices depending on customer group - it means that you can have a default price discount for different customer groups that applies to all the products or specific products or product variants. ![Customer group-based pricing](https://doc.ibexa.co/en/saas/product_catalog/img/group_base_pricing.png) ### Product taxonomy The [taxonomy mechanism](https://doc.ibexa.co/en/saas/content_management/taxonomy/taxonomy/index.md) enables creating tags or categories with a tree structure and assign them to a content item, for example, Products. Thanks to this mechanism product categories can be organized into a Category tree to make it easy for the users to browse and to deliver content appropriate for them. ### Grouping products into catalogs You can group all the products into smaller catalogs. They contain subsets of the whole product list and you can use them to build special catalogs, for example, for retailers and distributors, or for different regions. ![Grouping products into catalogs](https://doc.ibexa.co/en/saas/product_catalog/img/grouping_products.png) ### General and variant-specific assets Products and product variants can have their image assets. You can set up general assets — it means that the product has an asset visible in the main product view. Additionally, you can assign assets to product variants and place them in a collection. ![General and variant-specific assets](https://doc.ibexa.co/en/saas/product_catalog/img/general_assets.png) # Quable Integration > For the complete documentation index, see [llms.txt](https://doc.ibexa.co/en/saas/llms.txt). Quable integration with Cohesivo Cohesivo integrates with [Quable](https://www.quable.com/en) to provide product information management as part of the Ibexa orchestration platform. Quable is Ibexa’s PIM solution for managing complex product catalogs and serves as the single source of truth, available as an add-on for Cohesivo. Once you install and configure it, the integration performs an initial synchronization of product data, followed by ongoing updates via webhooks. Products can be viewed, selected, and embedded in Cohesivo, while all product management operations remain handled in Quable. ## Getting started - [Quable product guide](https://ez-systems-developer-documentation--3403.com.readthedocs.build/en/3403/product_catalog/quable/quable_guide/): The Quable product guide describes how you can use the product data from Quable in Cohesivo to create marketing campaigns built around your products. - [Quable PIM integration](https://doc.ibexa.co/projects/userguide/en/6.0/product_catalog/quable_pim_integration/): Quable PIM integration allows you to use products managed in Quable as the source of product data in Ibexa DXP. - [Quable - PIM solution for product data management](https://www.quable.com/en): Manage your product data and accelerate sales with Quable. Discover the new PIM platform that revolutionizes the product experience - [Quable resources](https://docs.quable.com/): Find all PIM, DAM, and Portal resources: user guides, training content, product documentation, technical documentation, and the PIM API for developers. ## Development - [Set up Quable synchronization](https://ez-systems-developer-documentation--3403.com.readthedocs.build/en/3403/product_catalog/quable/install_quable/): Configure the Quable connector for Cohesivo - [Configure Quable connector](https://ez-systems-developer-documentation--3403.com.readthedocs.build/en/3403/product_catalog/quable/configure_quable_connector/): Quable connector configuration reference for Cohesivo - [Quable technical documentation](https://developers.quable.com/): Explore Quable's technical documentation # Quable product guide > For the complete documentation index, see [llms.txt](https://doc.ibexa.co/en/saas/llms.txt). The Quable product guide describes how you can use the product data from Quable in Cohesivo to create marketing campaigns built around your products. ## Overview Quable integration connects Cohesivo with [Quable](https://www.quable.com/en), making Quable the authoritative source of product information for every website powered by Cohesivo. Quable serves as the single source of truth for all product data, including attributes, classifications, variants, and translations. Cohesivo consumes this data and makes it available for use in content and digital experiences. This approach eliminates the need to manage product data in multiple systems, while preserving a clear separation of responsibilities between product management and content usage. ## Availability The integration with Quable is available as an add-on for Cohesivo. Before installing and enabling the add-on, ensure that you have an active Quable instance with defined products, classifications, and channels. Then, [perform the initial configuration](https://doc.ibexa.co/en/saas/product_catalog/quable/install_quable/index.md). ## How does Quable integration work The integration is built on Cohesivo's [Remote PIM framework](https://doc.ibexa.co/en/saas/product_catalog/add_remote_pim_support/index.md), which enables connection to external product data sources. Once configured, the system performs: - an initial synchronization of product data from Quable - ongoing updates via webhooks (near real-time) Product data is mapped to the Cohesivo's product data model, including variants, attributes and [product categories](https://doc.ibexa.co/en/saas/product_catalog/product_catalog_guide/#product-taxonomy). This data is then available in the back office, content editing tools like [Online Editor](https://doc.ibexa.co/en/saas/content_management/rich_text/online_editor_guide/index.md) and [Page Builder](https://doc.ibexa.co/en/saas/content_management/pages/page_builder_guide/index.md), and APIs. All product management operations remain handled in Quable. Cohesivo can be used to manage pricing and availability for products sourced from Quable, including support for market-specific configurations such as regions and currencies. ## Capabilities ### Single source of truth Quable is the authoritative system for product data, including attributes, classifications, variants, and translations. Cohesivo consumes this data and makes it available for use within content and back office interfaces, enabling editorial teams to enrich content by reusing product information. ## Use cases ### Multi-market operations A retailer operating across multiple markets can manage product data in Quable using channels and localized languages. Cohesivo connects to the relevant channel and makes localized product information available for use in content and back office interfaces, ensuring consistency across markets from a single Quable instance. ## Faster campaign execution Product data defined in Quable can be immediately used in Cohesivo for building content and campaigns. Marketing teams can create pages and enrich content using up-to-date product information, without the need to duplicate or manually synchronize data. ## Known limitations The integration with Quable has the following known limitations: - [Catalogs](https://doc.ibexa.co/en/saas/product_catalog/product_catalog_guide/#catalogs) can't be created from Quable products. - [Product assets](https://doc.ibexa.co/en/saas/product_catalog/product_catalog_guide/#product-assets) are not fully synchronized. Only the main product thumbnail from Quable is used. - [Product-level access restrictions](https://doc.ibexa.co/en/saas/permissions/policies/#products) based on product type are not supported. - You can't define prices and availability for products with product codes exceeding 64 characters. # Set up Quable synchronization > For the complete documentation index, see [llms.txt](https://doc.ibexa.co/en/saas/llms.txt). Configure the Quable connector for Cohesivo To integrate Cohesivo with Quable, you need to configure the connection and set up synchronization. ## Create Quable instance Before configuring the Quable connector, ensure you have access to a [Quable instance](https://www.quable.com). ## Get API credentials To connect to Quable, you need an API token: 1. Log in to your Quable instance, for example, `https://example.quable.com`. 2. Navigate to the [API Tokens](https://docs.quable.com/v5-EN/docs/api-tokens) section. 3. Create a new **Read Access Token** for use in the configuration. ## Configure Quable connector Specify the configuration for the Quable connector: ```yaml ibexa_connector_quable: instance_url: 'https://example.quable.com' api_token: '' channel_code: '' ``` Replace `` with the Read Access API token you obtained from Quable in the previous step. [Quable's channels](https://docs.quable.com/v5-EN/docs/content-channels) allow you to distribute your product information to defined recipients, for example e-commerce platforms. Select the Quable channel that you want to integrate within Cohesivo. For all available configuration options, see [Configure Quable](https://doc.ibexa.co/en/saas/product_catalog/quable/configure_quable_connector/index.md). ## Configure product catalog engine To use Quable as a product data source, configure Cohesivo's [product catalog](https://doc.ibexa.co/en/saas/product_catalog/product_catalog_guide/index.md) to use the Quable engine. ### Define Quable engine Add a new engine configuration: ```yaml ibexa_product_catalog: engines: local: type: local options: root_location_remote_id: ibexa_product_catalog_root product_type_group_identifier: product quable: type: quable options: taxonomy: quable root_location_remote_id: ibexa_product_catalog_root product_type_group_identifier: product ``` This configuration defines two engines: the default `local` engine and the new `quable` engine, allowing you to work with products defined within Quable. To learn more about product catalog configuration, see [Product catalog configuration](https://doc.ibexa.co/en/saas/product_catalog/product_catalog_configuration/index.md). The Quable integration add-on comes with a new [taxonomy](https://doc.ibexa.co/en/saas/content_management/taxonomy/taxonomy/index.md) called `quable`. By setting the `ibexa_product_catalog.engines.quable.options.taxonomy` key to `quable`, you configure the engine to use it for storing product categories. ### Set Quable as default engine In your repository configuration, configure the product catalog to use the Quable engine as the product data source: ```yaml ibexa: repositories: default: storage: ~ search: engine: '%search_engine%' connection: default product_catalog: engine: quable regions: default: ~ ``` ## Set up languages To use the products from Quable within Cohesivo content, make sure the [data languages](https://docs.quable.com/v5-EN/docs/data-languages) in Quable have corresponding [languages](https://doc.ibexa.co/en/saas/multisite/languages/languages/index.md) in Cohesivo. Configure the `language_map` setting, mapping each Cohesivo language code to its Quable locale code as in the following example: ```yaml ibexa_connector_quable: # ... language_map: eng-GB: en_GB fre-FR: fr_FR ``` The system uses the language map to retrieve data in the correct language from Quable. ## Set up real-time synchronization Quable can notify Cohesivo about product data and classification changes in real-time by using webhooks. This invalidates the cache kept in Cohesivo, ensuring that product information stays up to date. Webhook configuration must be set up in both Quable and Cohesivo. ### Create webhook in Quable 1. Create a new [webhook in Quable](https://docs.quable.com/v5-EN/docs/webhook). 2. Set the webhook code (used as the webhook name). 3. Provide the URL to your Cohesivo instance suffixed by `/webhook/quable`, for example: `https://example.com/webhook/quable`. 4. Mark it as **Activated**. 5. Enter a secret value for the **Authorization Header**. 6. Choose the following scopes: - Products: created, updated, deleted - Classifications: created, updated, deleted The **Authorization Header** value is a secret that must be kept secure. > **Note: Note** > > For local development and testing, you can consider using one of the available [tunnel providers](https://github.com/anderspitman/awesome-tunneling) to make your local instance accessible from the internet. ### Configure webhook in Cohesivo Specify the configuration for the Quable connector: ```yaml ibexa_connector_quable: # ... webhook_secret: '' ``` > **Caution: Caution** > > [Quable uses dynamic IP addresses](https://faq.quable.com/en/articles/8250056-what-are-the-ip-addresses-of-quable-to-add-to-the-whitelist) to connect to Cohesivo. If your Cohesivo instance is protected by a firewall, make sure your configuration allows connections from changing IP addresses. Cohesivo webhook processes Quable's classification change events and queues them to be processed asynchronously in the background. # Configure Quable connector > For the complete documentation index, see [llms.txt](https://doc.ibexa.co/en/saas/llms.txt). Quable connector configuration reference for Cohesivo You can customize the behavior of the Quable integration add-on by using the following [configuration](https://doc.ibexa.co/en/saas/administration/configuration/configuration/index.md). ## Configuration example Specify your configuration by using the `ibexa_connector_quable` key: ```yaml ibexa_connector_quable: enabled: true instance_url: 'https://example.quable.com' api_token: '' channel_code: '' webhook_secret: '' # Needed for webhook authentication language_map: eng-GB: en_GB fre-FR: fr_FR throw_on_invalid_criteria: '%kernel.debug%' throw_on_invalid_mapping: '%kernel.debug%' cache: enabled: true attribute: true attribute_group: true product: true product_type: true ``` ## Configuration options | Parameter | Default value | Description | | --------------------------- | ---------------- | ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | | `enabled` | `false` | Enables the connector. | | `instance_url` | string | Base URL of your Quable instance, for example `https://example.quable.com`. | | `api_token` | string | [Read Access API token](https://docs.quable.com/v5-EN/docs/api-tokens) used to authenticate requests to Quable. | | `channel_code` | string | Code of the [Quable channel](https://docs.quable.com/v5-EN/docs/content-channels) used as the source of product data. | | `webhook_secret` | string | Secret expected in the [webhook](https://docs.quable.com/v5-EN/docs/webhook) authorization header. | | `language_map` | Empty | Maps Cohesivo language codes (for example, `eng-GB`) to Quable locale codes (for example, `en_GB`). For more information, see [Set up Quable languages](https://doc.ibexa.co/en/saas/product_catalog/quable/install_quable/#set-up-languages). | | `throw_on_invalid_criteria` | `%kernel.debug%` | Controls behavior for unsupported search criteria: `true` throws an exception, `false` only logs unsupported criteria. | | `throw_on_invalid_mapping` | `%kernel.debug%` | Controls behavior for mapping errors during data transformation: `true` throws an exception, `false` only logs mapping errors. | | `cache.enabled` | `true` | Global cache switch for the connector. When set to `false`, only in-memory cache is used. When set to `true`, [Symfony's `cache.app` cache pool](https://symfony.com/doc/7.4/cache.html#system-cache-and-application-cache) is used. | | `cache.attribute` | `true` | Enables caching for attribute definition requests. | | `cache.` `attribute_group` | `true` | Enables caching for attribute group requests. | | `cache.` `product` | `true` | Enables caching for product requests. | | `cache.` `product_type` | `true` | Enables caching for product type requests. | In production environments, it's recommended to: - keep the `api_token` and the `webhook_secret` secure - enable caching for better performance, by using Redis or Valkey as persistence cache - disable `throw_on_invalid_criteria` and `throw_on_invalid_mapping` to prevent non-critical errors from causing application crashes # Product catalog configuration > For the complete documentation index, see [llms.txt](https://doc.ibexa.co/en/saas/llms.txt). Configure product catalog settings per repository, with different catalog engines and VAT configurations. You can configure the product catalog per Repository. Under `ibexa.repositories..product_catalog` [configuration key](https://doc.ibexa.co/en/saas/administration/configuration/configuration/#configuration-files), indicate the catalog engine to use: ```yaml ibexa: repositories: default: storage: ~ search: engine: '%search_engine%' connection: default product_catalog: engine: 'default' ``` The `default` engine is available out of the box, and configured under `ibexa_product_catalog`: ```yaml ibexa_product_catalog: engines: default: type: local options: root_location_remote_id: e5ce2e391bd94e26a5cd88746f24ecce product_type_group_identifier: 'product' ``` The `local` type is the built-in type of catalog based on the content repository. With [Quable integration](https://doc.ibexa.co/en/saas/product_catalog/quable/quable_guide/index.md) add-on installed and configured, by using the `quable` type you can retrieve product data coming from Quable. You can use a single engine across all repositories, or assign different ones per repository. Each repository can use only one product catalog engine. Under `options.product_type_group_identifier` you can define the identifier of the content type Group used for storing products. `root_location_remote_id` indicates the remote ID of the location where products are stored. ## VAT rates To set up different VAT rates for different regions (countries), you can use the following configuration under the `ibexa.repositories..product_catalog.regions` [configuration key](https://doc.ibexa.co/en/saas/administration/configuration/configuration/#configuration-files), for example: ```yaml ibexa: repositories: : product_catalog: engine: default regions: : vat_categories: standard: value: 18 extras: : reduced: value: 6 zero: value: 0 none: value: ~ ``` VAT rates configuration accepts additional flags under the `extras` key. It's an extension point that you can build upon to add custom functionalities. You can use it, for example, to pass additional information to the UI or define region-specific exclusions when calculating the tax values. For each VAT category value, setting a value to "null" (~) is equal to making the following setting: ```yaml none: value: 0 extras: not_applicable: true ``` ## Code generation strategy Product codes for variants are generated automatically based on the selected strategy. The following strategies are available: - `incremental` (default) - variant code consists of base product code plus index, for example: `ErgoDesk-1`, `ErgoDesk-2`. - `random` - variant code consists of base product code plus random string of characters, for example: `ErgoDesk-62E7B3379AEB4`, `ErgoDesk-62E7B3379AFBC` You can choose the strategy with the following configuration: ```yaml ibexa_product_catalog: engines: default: type: local options: root_location_remote_id: ibexa_product_catalog_root product_type_group_identifier: 'product' variant_code_generator_strategy: 'random' ``` ## Catalogs ### Catalog filters You can configure which [catalog filters](https://doc.ibexa.co/en/saas/product_catalog/catalogs/index.md) are applied by default with the following configuration: ```yaml ibexa: system: admin: product_catalog: catalogs: default_filters: - product_code - product_availability ``` The order of filters in this configuration reflects the order in which they're displayed in the back office. # Products > For the complete documentation index, see [llms.txt](https://doc.ibexa.co/en/saas/llms.txt). Products are characterized by attributes describing their characteristics. You can create product variants and add assets to each product and variant. Products are a special type of content that contains typical content Fields and additional product information. Each product belongs to a product type (similar to how a content item belongs to a content type). Each product has a unique identifying product code. Product code can have up to 64 characters. It can contain only letters, numbers, underscores, and dashes. ## Product types Product types represent categories that a product can belong to. A product type can be, for example, a sofa, or a keyboard. Product types, like content types, define the global properties of products and fields a product consists of. A product type also defines the attributes that all products of this type can have. You can choose between two available types: `physical` and `virtual`: - `physical` - tangible products with assigned stock. They can use measurement attributes. They require shipment in the online purchase process. Examples: heaters, laptops, phones. - `virtual` - non-tangible items. They can be sold individually, or as part of a product bundle. They don't require shipment in the online process. Examples: memberships, services, warranties. ## Product attributes Product attributes provide different information about a product and can be used to create [product variants](#product-variants). Typical product attribute examples are: length, weight, color, format, and more. The following attribute types are available: | Name | Identifier | Description | | ------------------------------------------------------------------------------------------------ | ----------- | ------------------------------------------------------------------------------------------------ | | Checkbox | `checkbox` | Boolean attribute with a true/false value. | | Color | `color` | Color value stored as a hex code. | | [Date and time](https://doc.ibexa.co/en/saas/product_catalog/attributes/date_and_time/index.md) | `datetime` | Date and time value with configurable accuracy levels. | | Float | `float` | Decimal number value. | | Integer | `integer` | Integer number value. | | Selection | `selection` | A value selected from a predefined list of labeled options. | | [Symbol](https://doc.ibexa.co/en/saas/product_catalog/attributes/symbol_attribute_type/index.md) | `symbol` | String value with an enforced format, suitable for standardized identifiers such as EAN or ISBN. | Product attributes are collected in groups. An example of an attribute group can be dimensions (length, width, height). You can assign both whole attribute groups or individual attributes to a product type. > **Note: Attribute translations** > > Product attributes are not translatable. Unlike content fields, product attribute values cannot differ between languages. > > For the information that is intended to be displayed, consider using [TextLine](https://doc.ibexa.co/en/saas/content_management/field_types/field_type_reference/textlinefield/index.md) fields for short text, [RichText](https://doc.ibexa.co/en/saas/content_management/field_types/field_type_reference/richtextfield/index.md) fields for longer text that may require formatting, and product attributes for precise product properties or specifications. ## Product variants Product variants represent different versions of a product, for example, clothes in different colors, or laptops with different amounts of RAM. You can create product variants automatically based on attributes that have the "Used for product variants" flag enabled in the product type definition. You can create variants for any combination of values of selected attributes. In the back office you can automatically generate all possible variants for a product. Codes for product variants are generated automatically based on the [selected strategy](https://doc.ibexa.co/en/saas/product_catalog/product_catalog_configuration/#code-generation-strategy). Each product variant has separate availability and stock information. Each variant can also have separate price rules. If a variant doesn't have separate price rules, it uses the price of its base product. ## Product assets Product assets are images that are assigned to products and their specific variants. You can group assets in collections which correspond to specific values of attributes. A collection is assigned to the variant or variants that have these attribute values. ## Embed products in content You can embed products directly into content, including the [landing pages](https://doc.ibexa.co/en/saas/content_management/pages/pages/index.md), by using the [Online Editor](https://doc.ibexa.co/en/saas/content_management/rich_text/online_editor_guide/index.md). Use it to build marketing campaigns directly around the products, bridging product marketing and product data together. ## Product availability and stock Product availability defines whether a product is available in the catalog. You set product availability per variant or per base product: - if a product cannot have variants (has no attributes with the "Used for product variants" flag), you set availability per base product - if a product can have variants (even if no variants are configured yet), you set availability per variant. When a product is set as available, it can have numerical stock defined. The stock can also be set to infinite (for example, in case of digital products). ### Availability and computed availability Setting a product as available doesn't automatically mean that it can be ordered. For example, a product can be set as available, but have zero stock. The product catalog distinguishes between two types of availability: - Availability as a value set per product or variant Availability represents whether the product was set as **Available**, for example in the [back office **Availability** tab](https://doc.ibexa.co/projects/userguide/en/6.0/product_catalog/manage_availability_and_stock/#set-product-availability). - Computed availability Computed availability represents whether the product can actually be ordered. By default, a product can only be ordered when it's set as available and has either positive or infinite stock. # Date and time attributes > For the complete documentation index, see [llms.txt](https://doc.ibexa.co/en/saas/llms.txt). Date and time attribute type allows you to store product information related to time, like an expiration date or date of manufacturing. The date and time [attribute type](https://doc.ibexa.co/en/saas/product_catalog/products/#product-attributes) allows you to represent date and time values as part of the product specification in the [product catalog](https://doc.ibexa.co/en/saas/product_catalog/product_catalog_guide/index.md). You can use it to store, for example, manufacturing dates, expiration dates, or event dates, all with specified accuracy. ## Usage You can manage the date and time attribute type through the back office, REST, or through the PHP API. It also supports [searching](https://doc.ibexa.co/en/saas/search/criteria_reference/product_search_criteria/index.md) by using [DateTimeAttribute](https://doc.ibexa.co/en/saas/search/criteria_reference/datetimeattribute_criterion/index.md) and [DateTimeAttributeRange](https://doc.ibexa.co/en/saas/search/criteria_reference/datetimeattributerange_criterion/index.md) criteria. !\[Creating a product using a date and time attribute with "trimester" accuracy level\](../img/datetime.png "Creating a product using a date and time attribute with "trimester" accuracy level") When creating an attribute based on the date and time attribute type you can select the accuracy level to match your needs: | Accuracy | Example | Limitations | | --------- | ------------------- | ---------------------------- | | Year | 2025 | Number between 1000 and 9999 | | Trimester | Q3 2025 | | | Month | July 2025 | | | Day | 2025-07-06 | | | Minute | 2025-07-06 11:15 | | | Second | 2025-07-06 11:15:37 | | # Symbol attribute type > For the complete documentation index, see [llms.txt](https://doc.ibexa.co/en/saas/llms.txt). Create a symbol attribute type that enables for the efficient representation of string-based values while enforcing their format in product specifications. In product specifications, the symbol attribute type enables the efficient representation of string-based data and enforces their format. This feature allows you to store standard product identifiers (such as EAN or ISBN) in the [product catalog](https://doc.ibexa.co/en/saas/product_catalog/product_catalog_guide/index.md). ## Build-in symbol attribute formats The built-in symbol attribute formats in `ibexa/product-catalog-symbol-attribute` are listed below: | Name | Description | Example | | -------------------------------------- | ----------------------------------------------------------------------------------------- | ----------------- | | Generic | Accepts any string value | #FR1.2 | | Generic (alphabetic characters only) | Accepts any string value that contains only letters | ABCD | | Generic (digits only) | Accepts any string value that contains only digits | 123456 | | Generic (alphanumeric characters only) | Accepts any string value that contains only letters or digits | 2N6405G | | Generic (hexadecimal digits only) | Accepts any string value that contains only hexadecimal digits (digits or A-F characters) | DEADBEEF | | EAN-8 | European Article Number (8 characters) | 96385074 | | EAN-13 | European Article Number (13 characters) | 5023920187205 | | EAN-14 | European Article Number (14 characters) | 12345678901231 | | ISBN-10 | International Standard Book Number (10 characters) | 0-19-852663-6 | | ISBN-13 | International Standard Book Number (13 characters) | 978-1-86197-876-9 | > **Caution: Caution** > > Maximum length of the symbol value is 160 characters. ## Search for products with given symbol attribute You can use `SymbolAttribute` Search Criterion to find products by symbol attribute: For more information, see [SymbolAttribute Criterion](https://doc.ibexa.co/en/saas/search/criteria_reference/symbolattribute_criterion/index.md). # Catalogs > For the complete documentation index, see [llms.txt](https://doc.ibexa.co/en/saas/llms.txt). Catalogs enable filtering out a selection of products from the Product catalog. You can create multiple catalogs containing subsets of the whole product list. Use them, for example, to build special catalogs for B2B and B2C uses, for retailers and distributors, or for different regions. When creating a catalog, all products are included by default, but you can filter the list by: - price (Solr or Elasticsearch only) - product attributes - product type - product code - availability - product category - the date when the product was created ![List of filters for selecting products for a catalog](https://doc.ibexa.co/en/saas/product_catalog/img/catalogs_filters.png) # Enable purchasing products > For the complete documentation index, see [llms.txt](https://doc.ibexa.co/en/saas/llms.txt). Ensure your product catalog is ready for use with full configuration of products that enables purchasing them in the frontend shop. To enable adding product to cart and purchasing from the catalog, the following configuration is required: - at least [one region and one currency for the shop](#region-and-currency) - [VAT rates per region](#vat-rates) and for each product type - at least one [price](https://doc.ibexa.co/en/saas/product_catalog/prices/index.md) for the product - [availability](https://doc.ibexa.co/en/saas/product_catalog/products/#product-availability-and-stock) with positive or infinite stock for the product or product variant > **Note: Configuring products in the UI** > > After you configure the region, currency and VAT rates for regions in settings, the store manager must set up the remaining parameters in the UI, such as, [VAT rates per product type](https://doc.ibexa.co/projects/userguide/en/6.0/product_catalog/create_product_types/#vat), descriptions, attributes, assets, [prices](https://doc.ibexa.co/projects/userguide/en/6.0/product_catalog/manage_prices/), and [availability](https://doc.ibexa.co/projects/userguide/en/6.0/product_catalog/manage_availability_and_stock/) per product. > > For more information, see [User Documentation](https://doc.ibexa.co/projects/userguide/en/6.0/product_catalog/products/#product-completeness). ## Region and currency All currencies available in the system must be enabled in the back office under **Product Catalog** -> **Currencies**. Additionally, you must configure currencies valid for specific SiteAccesses under the `ibexa.system..product_catalog.currencies` [configuration key](https://doc.ibexa.co/en/saas/administration/configuration/configuration/#configuration-files): ```yaml ibexa: system: default: product_catalog: currencies: - EUR - GBP - PLN regions: - germany - uk - poland ``` In the `ibexa_storefront.yaml` file, under the `ibexa.system..product_catalog.regions` configuration key, regions are set with `default` value. Remember to either exclude this element or extend it by [configuring other regions](https://doc.ibexa.co/en/saas/product_catalog/enable_purchasing_products/#configuring-other-regions-and-currencies). ```yaml ibexa: system: storefront_group: product_catalog: currencies: - EUR - PLN regions: - germany - poland another_storefront_group: product_catalog: currencies: - GBP regions: - uk ``` This example uses the currencies and regions set in the [VAT rates' example below](#vat-rates). ### Configuring other regions and currencies By default, the system always uses the first currency and the first region configured. To implement a different logic, for example a switcher for preferred currencies and regions, you need to subscribe to `Ibexa\Contracts\ProductCatalog\Events\CurrencyResolveEvent` and `Ibexa\Contracts\ProductCatalog\Events\RegionResolveEvent` in your customization. ## VAT rates You set up VAT percentage values corresponding to VAT rates in configuration: ```yaml ibexa: repositories: default: product_catalog: engine: default regions: germany: # Shorthand VAT configuration format vat_categories: standard: 19 reduced: 7 none: ~ poland: # Current VAT configuration format vat_categories: standard: value: 23 reduced: value: 8 zero: value: 0 none: value: 0 extras: not_applicable: true ``` > **Note: Note** > > The above example presents two acceptable formats of VAT configuration. For each VAT category, setting a value to "null" (`~`) is equal to making the following setting: > > ```yaml > none: > value: 0 > extras: > not_applicable: true > ``` You can then assign VAT rates that apply to every product type in each of the supported regions. To do it, in the back office, [open the product type for editing](https://doc.ibexa.co/projects/userguide/en/6.0/product_catalog/create_product_types/#vat), and navigate to the **VAT rates** area. ![Assigning VAT rates to a product type](https://doc.ibexa.co/en/saas/product_catalog/img/catalog_vat_rates.png "Assigning VAT rates to a product type") # Prices > For the complete documentation index, see [llms.txt](https://doc.ibexa.co/en/saas/llms.txt). The price engine calculates product prices taking into account customer groups, currencies and taxes. The price engine is responsible for calculating prices for products in the [product catalog](https://doc.ibexa.co/en/saas/product_catalog/product_catalog/index.md). ## Custom pricing You can set up basic price rules depending on [customer groups](https://doc.ibexa.co/en/saas/users/customer_groups/index.md). Use this option to globally manage custom prices, for example for your resellers. Each customer group can have a default price discount that applies to all products. ### Assign prices dynamically You could create a customer group resolver that provides custom price logic, for example, by retrieving user address from the customer profile, and assigning a customer group to the customer based on the address. Such resolver must implement the `Ibexa\Contracts\ProductCatalog\CustomerGroupResolverInterface` interface. You must then register it as a service with the `ibexa.product_catalog.customer_group.resolver` tag. ## Currency Cohesivo ships with a list of available currencies, and you can also add custom currencies. To use currencies in your shop, you need to first enable them in the back office. ## VAT You can [configure VAT rate globally](https://doc.ibexa.co/en/saas/product_catalog/product_catalog_configuration/#vat-rates) (per SiteAccess), or set it individually for each product type and product. # Add Remote PIM support > For the complete documentation index, see [llms.txt](https://doc.ibexa.co/en/saas/llms.txt). Configure a custom Remote PIM integration for the product catalog. Cohesivo provides flexible product catalog infrastructure that works with external Product Information Management (PIM) systems. For advanced product data management without custom development, you can use the readily available [Quable integration](https://doc.ibexa.co/en/saas/product_catalog/quable/quable/index.md) with Cohesivo. To implement [Remote PIM support](https://doc.ibexa.co/en/saas/product_catalog/product_catalog_guide/#remote-pim-support) for a custom integration, you can build upon a foundation provided by Ibexa. While doing so, you must implement services that process data coming from the remote PIM. Before you create your own solution, you can use the `ibexa/example-in-memory-product-catalog` example implementation and modify it to connect to your external data source. ## Implement services To connect to your remote PIM, provide your implementation of the following services that process product data: - AssetService, used to get assets assigned to a product. - AttributeDefinitionService, used to get information about product attributes. - AttributeGroupService, used to get information about product attribute groups. - ProductService, used to get product information. - ProductTypeService, used to work with product types. ## Switch to the new product catalog engine To inform the application that the product catalog engine has been replaced by an external one, set the new product catalog engine, for example: ```yaml ibexa_product_catalog: engines: : type: options: root_location_remote_id: ibexa_product_catalog_root ``` Then configure the application to use the engine defined above as the default product data repository: ```yaml ibexa: repositories: : # ... product_catalog: engine: ``` > **Note: Enabling the remote PIM support** > > By default, the `ibexa.repositories..product_catalog.engine.type` key is set to `local`, which informs Cohesivo that the built-in product catalog capabilities are used. By changing this setting and the `ibexa.repositories..product_catalog.engine` setting from `default` to your custom value, you inform Cohesivo that you're using a remote PIM. # Customer management # Customer Portal > For the complete documentation index, see [llms.txt](https://doc.ibexa.co/en/saas/llms.txt). Customer Portal allows your business clients to create and manage their company accounts. A Customer Portal serves as a central entry point to your services and products. It helps you provide a unique user experience with a single point of access to any relevant self-service options for your products and services. Cohesivo Customer Portal and customer management that ships with it let you create and handle business accounts and communicate with your partners in a personalized space. With this feature, your customers can self-register, edit their organization information, invite and view members, check their order history, and more. - [Customer Portal product guide](https://ez-systems-developer-documentation--3403.com.readthedocs.build/en/3403/customer_management/customer_portal_guide/): Check all the capabilities and advantages that the Customer Portal offers to the clients by reading the Customer Portal product guide. - [Customer Portal configuration](https://ez-systems-developer-documentation--3403.com.readthedocs.build/en/3403/customer_management/cp_configuration/): Configure Customer Portal to fit the needs of your business. - [Customer Portal applications](https://ez-systems-developer-documentation--3403.com.readthedocs.build/en/3403/customer_management/cp_applications/): Customization of an approval process for new companies applications. - [Inviting users](https://ez-systems-developer-documentation--3403.com.readthedocs.build/en/3403/users/invitations/): Manage user invitations to create an account in the frontend or the back office. - [Create Customer Portal](https://ez-systems-developer-documentation--3403.com.readthedocs.build/en/3403/customer_management/cp_page_builder/): Create unique Customer Portals for your clients with Page Builder. # Customer Portal product guide > For the complete documentation index, see [llms.txt](https://doc.ibexa.co/en/saas/llms.txt). Check all the capabilities and advantages that the Customer Portal offers to the clients by reading the Customer Portal product guide. ## What is Customer Portal A Customer Portal serves as a central entry point to your services and products. It helps you provide a unique user experience with a single point of access to any relevant self-service options for your products and services. Cohesivo Customer Portal and customer management that ships with it let you create and handle business accounts and communicate with your partners in a personalized space. With this feature, your customers can self-register, edit their organization information, invite and view members, check their order history, and more. ## Availability Customer Portal is available in Cohesivo. It's also compatible with Product catalog and Ibexa Connect. ## How does Customer Portal work? Customer Portal is a component based on content types. This means that Cohesivo provides containers, user management, content management, so you can focus on business logic and general outlook of the portal for your B2B clients. ### Customer Portal The Customer Portal allows company members to log in and manage their profiles and order history. With user differentiation, company buyers can only purchase products while company admins can invite and manage members and change company information, such as billing addresses. ![Customer Portal dashboard](https://doc.ibexa.co/en/saas/customer_management/img/cp_dashboard_customer_portal.png) ### Editable in Page Builder Custom Customer Portal can be created and edited in Page Builder to meet the needs of each business type, company, or market they operate on. To create a new Customer Portal, go to **Content** and, from the menu, select **Content structure**. There, navigate to the root container for your Customer Portals and select **Customer Portal Page**. In the Page Builder creation box, you see the Customer Portal layout where you can add a dedicated Customer Portal block, Sales Representative, or choose from a selection of blocks available to your Cohesivo version. If the built-in page blocks aren't sufficient to fulfill your needs, you can add your own. ![Editable in Page Builder](https://doc.ibexa.co/en/saas/customer_management/img/cp_edit_in_page_builder.png) You can allow company members to see multiple versions of Customer Portal on a single page by adding them under one Customer Portal container and combining SiteAccess matchers. This setup is recommended for global markets or company-specific portals, where each portal is designed specifically for its customers and their needs. ![Multiple portals](https://doc.ibexa.co/en/saas/customer_management/img/cp_2_page_view.png) ### Company management The main company management takes place in the back office where each company has its own profile where sales representative can find: - summary with basic information and order history - company profile with billing information and contact person - list of members and pending invitations - address book with multiple shipping addresses ![Companies section in back office](https://doc.ibexa.co/en/saas/customer_management/img/cp_back_office.png) From there, they can activate and deactivate the company, edit its information, invite members, manage their roles, and edit their basic information. In the roles section, you can define policies for each user group, for example, a Company buyer. You can also set up policies for every user who has a business account by editing a Corporate Access role. ### Members Company members aren't standard users. They belong to a separate category called Corporate Accounts. This category is located in **Admin** -> **Corporate** -> **Corporate Accounts**. There, you can find a list of companies and their members. This feature comes with a set of new roles: - Member — users who are members of a company - Corporate Access — users who can log into Customer Portal - Company Admin — users who can edit company's details - Company Buyer — users who can buy in company's name All roles and policies associated with them can be fully customized to fit your business needs. ### Invitations Members can be invited to the organization from: - the back office: go to **Customers** -> **Companies** -> **Select your company** -> **Invitations** -> **Invite member** - the Customer Portal: go to your company admin profile, select **Members** -> **Invite members** Then, in a pop-up fill out email addresses one by one, or use drag and drop to upload a file with a list of emails. You also have to assign a role to each new member from a drop-down list. Click **Send** to send out invitations. ![Invitations](https://doc.ibexa.co/en/saas/customer_management/img/cp_invitations.png) Invited users receive an email message with a registration link. With it, they can register and create their account in the Customer Portal. ![Create account](https://doc.ibexa.co/en/saas/customer_management/img/cp_create_account.png) ### Company self-registration Self-registration allows business customers to take charge and apply for a business account by themselves. Applications go through the approval process in the back office where they can be accepted, rejected or put on hold. If they're accepted, the business partner receives an invitation link to the Customer Portal, where they can set up their team and manage their account. To apply for a business account, a company needs to provide their basic information, contact information and billing address in an application. ![Company self-registration](https://doc.ibexa.co/en/saas/customer_management/img/cp_registration.png) The approval process is customizable. You can decide which user has approval rights by granting them `Company Application/Workflow` policy, you can also decide between which states the user may move applications: - on hold - accept - reject If built-in statuses aren't sufficient, you can add custom ones. You can also edit or add reasons for not accepting the company application. Finally, you can customize the registration site itself. ### REST API Customer Portal comes with [REST API](https://doc.ibexa.co/en/saas/api/rest_api/rest_api_reference/rest_api_reference.html#tag/Corporate-Account) for interacting with corporate accounts from the context of the Ibexa Connect app. ## Capabilities ### Company management Sales representatives can manage details for companies they're associated with, such as contact persons, billing addresses, and more by accessing back office. Company admins are also able to manage the company's details in the Customer Portal interface. By giving users power to manage their own accounts, you reduce the need for administrative interventions. ### Self registration Self-registration allows your customers to take control of their business accounts. This not only improves customer satisfaction but also reduces the administrative burden on your team. With the ability to integrate with Ibexa Connect, you're able to fully automate the process. ### Address book Use of an address book allows you to add many shipping addresses to one company for clients with multiple locations. ### Custom prices You can offer special prices and additional discounts dedicated for Customer groups containing company members with verified accounts. ### Available in segments Corporate accounts are available in segments, which means you can assign companies to different recommendation groups based on gathered data, and deliver recommendations. It allows you to make use of customer targeting of the segments and create personalized experience for each company. ## Benefits ### General overview The overall benefit of customer portals is the help they provide to retain customers and increase loyalty, while freeing up customer service employees time for higher-level work. They can achieve that by providing customers with up-to-date information about their orders and deliveries, personalize shopping experience, offer special deals available only to B2B partners, and do that in one, accessible space. Currently, Customer Portals are a standard in global sites such as Amazon. They're the level of quality that customers expect, and all businesses strive for. ### Simplified shopping process Business account helps streamline the B2B shopping process with all the paperwork, payment, and other administrative tasks converted into a few steps with prefilled forms, billing addresses, shipping addresses, and more. Making your site a go-to place for company orders. ### Better customer experience In the era of internet, customers expect quick, accessible and excellent quality service, and user experience from every business they associate with. Customer portals offer a seamless self-service experience by providing complete 24/7 access to relevant, up-to-date information and customer support. ### Client encouragement Price strategies are a great way to build and maintain strong relationships with your trading partners. With special prices available to B2B clients, you can offer the best deals in highly competitive markets. Those discounts may be a great encouragement to convince big buyers to choose your business over other options. Competitive prices impact not only the size of the customer base, they affect every customer’s purchasing strategy, including the diversity, frequency, and volume of their orders. ### Cost benefits Customer portals help you to automate tasks that otherwise would be done by your employees manually, such as customer services, checking shipment status. An additional benefit of customer portals is their availability 24/7. Thus, reducing the need to allocate resources to extend working hours or hire more employees. ### Localization and recommendations The use of Page Builder in the Customer Portal creation process enables you to create unique experiences for each business customer based on their location, business type, company, or market they operate on. # Customer Portal configuration > For the complete documentation index, see [llms.txt](https://doc.ibexa.co/en/saas/llms.txt). Configure Customer Portal to fit the needs of your business. You can overwrite the default configuration of the Customer Portal to fit its capabilities to the unique needs of your business. ## `corporate` SiteAccess The predefined `corporate` SiteAccess in `corporate_group` serves the Customer Portal. If you need a multisite setup with multiple Customer Portals, add any additional SiteAccesses to `corporate_group`. ## Customer identifier `ibexa_default_settings.yaml` contains a setting that indicates what content types should be treated like Users in terms of, for example, usage in `UserService`: ```yaml ibexa: system: default: user_content_type_identifier: ['user', 'customer'] ``` ## Roles and policies You can add custom roles to your installation by listing them under the `ibexa.site_access.config.default.corporate_accounts.roles` [configuration](https://doc.ibexa.co/en/saas/administration/configuration/configuration/#configuration-files). This key overwrites the default list set in `vendor/ibexa/corporate-account/src/bundle/Resources/config/default_settings.yaml` (the following example redeclares them for clarity): ```yaml parameters: ibexa.site_access.config.default.corporate_accounts.roles: admin: Company Admin buyer: Company Buyer custom_role: Company Assistant ``` You can do it per SiteAccess or SiteAccess group by using [SiteAccess-aware configuration](https://doc.ibexa.co/en/saas/multisite/siteaccess/siteaccess_aware_configuration/index.md). ## Content type names You can change names of default content types by assigning what content types should be used to describe `Company` and `Member` in the back office. Proceed only if you already have a `Company` content type in your system, and you don't want to change its identifier. Configuration for content type names is placed under the `ibexa_corporate_account` key, like shown in `Ibexa\Bundle\CorporateAccount\DependencyInjection\Configuration`. To change content type names, adjust corporate account configuration in the following way: ```yaml ibexa_corporate_account: content_type_mappings: company: your_ct_identifier ``` > **Caution: Migration** > > If you decide to change deafult names of content types, during migration you have to adjust files accordingly. ## Registration You can define what fields are required in the Customer Portal registration form. To do so, see [Registration form field configuration](https://doc.ibexa.co/en/saas/users/user_registration/#registration-form-field-configuration). ## Address With the Address field type, you can customize address fields and configure them per country. To learn more, see [Address field type documentation](https://doc.ibexa.co/en/saas/content_management/field_types/field_type_reference/addressfield/index.md). ## Order management Reviewing pending and past orders in Customer Portal requires that you configure all currencies that any of the customers may use under the `ibexa.system..product_catalog.currencies` key. The first currency from the list is then used for filtering the orders list and calculating the **Average order** and **Total amount** values. For more information, see [Enable purchasing products](https://doc.ibexa.co/en/saas/product_catalog/enable_purchasing_products/index.md). # Create Customer Portal > For the complete documentation index, see [llms.txt](https://doc.ibexa.co/en/saas/llms.txt). Create unique Customer Portals for your clients with Page Builder. On this page, you can learn how to configure the Customer Portal feature to be editable with Page Builder. If you already configured Customer Portal, you can learn how to build it with a Page Builder in [User Documentation](https://doc.ibexa.co/projects/userguide/en/6.0/customer_management/build_customer_portal/). First, you need to decide if you want to create and configure [one portal](#create-and-configure-one-portal) or [multiple portals](#create-and-configure-multiple-portals) setup. ## Create and configure one portal This setup is recommended for use cases with one Customer Portal for all markets. If you plan to expand your portal portfolio in the future, see [multiple portal configuration](#create-and-configure-multiple-portals). ### Configure Page Builder access to Customer Portal First, create a Customer Portal page, its location ID needs to be later specified in the configuration. To do it, go to **Content** -> **Content structure**, and select **Customer Portal Page**. For now, you only need to add a name and a description in the field view, you can find it in the upper toolbar on the left side. Next, click **Publish** to see the page in the content tree. ![Add name and description to Customer Portal](https://doc.ibexa.co/en/saas/customer_management/img/cp_name_description.png) To be able to see the Customer Portal site template in the Page Builder you need to add `custom_portal` SiteAccess to the configuration. First, under the `ibexa.siteaccess` [configuration key](https://doc.ibexa.co/en/saas/administration/configuration/configuration/#configuration-files) add `custom_portal` to the SiteAccess `list` and to `corporate_group`. Next, add configuration for `corporate_group` and `custom_portal` under `ibexa.system`. Remember to specify `location_id` of your Customer Portal, you can find it under the **Technical details** tab of your new page. ```yaml ibexa: siteaccess: list: - import - site - admin - corporate - custom_portal groups: site_group: [import, site] storefront_group: [site] corporate_group: [corporate, custom_portal] system: corporate_group: languages: [eng-GB] custom_portal: languages: [ eng-GB ] content: tree_root: location_id: 12345 # location_id_of_customer_portal excluded_uri_prefixes: [ /media/, /images/ ] ``` Next, under the `ibexa.system.admin.page_builder` [configuration key](https://doc.ibexa.co/en/saas/administration/configuration/configuration/#configuration-files), add `custom_portal` to [the SiteAccess list available to Page Builder](https://doc.ibexa.co/en/saas/multisite/multisite_configuration/#siteaccesses-and-page-builder): ```yaml ibexa: system: admin: page_builder: siteaccess_list: - site - corporate - custom_portal ``` Now, you can go to your Customer Portal landing page and edit it in Page Builder. ![Edit Customer Portal in Page Builder](https://doc.ibexa.co/en/saas/customer_management/img/cp_edit_in_page_builder.png) ### Grant permissions to customers You need to grant the following permissions to company members, so they can view custom Customer Portal: - `user/login` to `custom_portal` SiteAccess - `content/read` to the Customer Portal ![Single Customer Portal permissions](https://doc.ibexa.co/en/saas/customer_management/img/single_cp_permissions.png) If members of the company don't have sufficient permissions for any Customer Portal, they're redirected to the default Customer Portal view. > **Note: Note** > > Customer Portal is only available to users that are members of the company. Even if a user has all the sufficient permissions but isn't a member of a company, this user cannot see the Customer Portal. ## Create and configure multiple portals This setup is recommended for global markets or company specific portals, where each portal is design specifically for its users and their needs. ### Customer Portal container First, you need to create a root folder for Customer Portals, its location ID needs to be later specified in the configuration as [a tree root](https://doc.ibexa.co/en/saas/multisite/multisite_configuration/#location-tree). To do it, go to **Content** -> **Content structure**, and select **Create content**. There you can see two possibilities **Customer Portal** and **Customer Portal Page**. ![Create content tab](https://doc.ibexa.co/en/saas/customer_management/img/cp_portal_vs_page.png) The first one is a separate content type used as a container for your Customer Portal pages. Customer Portals containers should be used to sort Customer Portal pages and any other content types used by them, such as articles, inside the root folder. It's recommended that you use them instead of folders to divide and store your portals. Select **Customer Portal**, define its name and publish. ![Customer Portals folder](https://doc.ibexa.co/en/saas/customer_management/img/cp_folder_for_portals.png) ### Configure Page Builder access to Customer Portal To be able to see Customer Portal site template in the Page Builder you need to add `custom_portal` SiteAccess to the configuration. First, under the `ibexa.siteaccess` [configuration key](https://doc.ibexa.co/en/saas/administration/configuration/configuration/#configuration-files), add `custom_portal` to the SiteAccess `list` and to `corporate_group`. Next, add configuration for `corporate_group` and `custom_portal` under `ibexa.system`. Remember to specify `location_id` of the root folder for Customer Portals, you can find it under the **Technical details** tab. ```yaml ibexa: siteaccess: list: - import - site - admin - corporate - custom_portal groups: site_group: [import, site] storefront_group: [site] corporate_group: [corporate, custom_portal] system: corporate_group: languages: [eng-GB] custom_portal: languages: [ eng-GB ] content: tree_root: location_id: 12345 # location_id_of_customer_portals_root_folder excluded_uri_prefixes: [ /media/, /images/ ] ``` Next, under the `ibexa.system.admin.page_builder` [configuration key](https://doc.ibexa.co/en/saas/administration/configuration/configuration/#configuration-files), add `custom_portal` to [the SiteAccess list available to Page Builder](https://doc.ibexa.co/en/saas/multisite/multisite_configuration/#siteaccesses-and-page-builder): ```yaml ibexa: system: admin: page_builder: siteaccess_list: - site - corporate - custom_portal ``` Now, you can go back to your Customer Portal's container. All landing pages that you create in it use Customer Portal template. ### Assign portal to Customer group You can assign multiple Customer Portal containers or Pages to a specific Customer group. First, you need to grant the following permissions to company members from the Customer group: - `user/login` to `custom_portal` SiteAccess - `content/read` to selected Customer Portals ![Customer Portal permissions](https://doc.ibexa.co/en/saas/customer_management/img/cp_permissions.png) If members of the Customer group don't have sufficient permissions for any Customer Portal assigned to them, they're redirected to the default Customer Portal view. > **Note: Note** > > Customer Portal is only available to users that are members of the company. Even if user has all the sufficient permissions but isn't a member of a company, this user cannot see the Customer Portal. #### Build-in portal mapping Now, you need to assign your custom portals to Customer groups. Add portal mapping configuration: ```yaml parameters: ibexa.corporate_account.customer_portal.customer_group_to_portal_map: eu: - 6bd4c938f9b3f668057c7e20987fac6c - 7bf85988a77ee859f2466av2b42bd909 us: - 6ce85480aeaeed59f7431a12b46bc869 ``` There, you can specify which Customer Portals should be available to which Customer group by adding: - Customer group identifier. You can find it in the **Summary** section of the Company. - Location remote ID of Customer Portal container or Customer Portal page. You can find it in the **Details** section. Portals are displayed to the Customer group in order specified in the configuration based on company member's permissions. ### Multiple portals on single page You can allow company members to see multiple versions of Customer Portal on a single page by [combining SiteAccess matchers](https://doc.ibexa.co/en/saas/multisite/siteaccess/siteaccess_matching/#custom-matchers) with `Compound\LogicalAnd`: ```yaml ibexa: siteaccess: match: Compound\LogicalAnd: custom_portal: matchers: Map\Port: eu: true Map\Host: example.com: true match: custom_portal Map\Host: admin.example.com: site_admin ``` ![Multiple portals in one view](https://doc.ibexa.co/en/saas/customer_management/img/cp_2_page_view.png) # Customer Portal applications > For the complete documentation index, see [llms.txt](https://doc.ibexa.co/en/saas/llms.txt). Customization of an approval process for new companies applications. New business customers can apply for a company account. Applications go through the approval process in the back office where they can be accepted, rejected or put on hold. If they're accepted, the business partner receives an invitation link to the Customer Portal, where they can set up their team and manage their account. For more information on company self-registration, see [user guide documentation](https://doc.ibexa.co/projects/userguide/en/6.0/customer_management/company_self_registration/). If provided options are too limited, you can customize an approval process by yourself. ## Roles and policies Any user can become application approver, as long as they have the `Company Application/Workflow` policy assigned to their role. There, you can define between which states the user may move applications. For example, the assistant can put new applications on hold, or reject them, and only the manager can accept them. ![Company Application policy](https://doc.ibexa.co/en/saas/customer_management/img/cp_company_application_policy.png) ## Customer Portal application configuration Below, you can find possible configurations for Customer Portal applications. ### Reasons for rejecting application The reasons offered when an application isn't accepted are listed under the SiteAccess-scoped `corporate_accounts.reasons` setting, separately for the `reject` and the `on_hold` outcome: ```yaml reject: [Malicious intent / Spam] on_hold: [Verification in progress] ``` ### Timeout Registration form locks for 5 minutes after unsuccessful registration, if the user, for example, tried to use an email address that already exists in a Customer Portal clients database. This duration is controlled by the `corporate_account_application` rate limiter. ## Customization of an approval process You can add a new status to the approval process of business account application. To do it, under the `ibexa.system..corporate_accounts.application.states` add a `verify` status to the [configuration](https://doc.ibexa.co/en/saas/administration/configuration/configuration/#configuration-files): ```yaml ibexa: system: default: corporate_accounts: application: states: [ 'new', 'accept', 'on_hold', 'reject', 'verify' ] ``` To check the progress, go to **Members** -> **Applications** and inspect the application review view. # Data collection # Qualifio integration > For the complete documentation index, see [llms.txt](https://doc.ibexa.co/en/saas/llms.txt). Use Qualifio to collect customer data by creating interactive content. Qualifio is a data collection tool. It gives you the ability to use the [Qualifio](https://qualifio.com/) tools to engage your audiences. You can use interactive content to build relationships and collect important data, for example, a list of recent orders, or personal information about customers. You can also integrate Qualifio with Ibexa Connect to create workflows. To use Qualifio, you must make arrangements with Cohesivo to define the initial configuration. Ibexa team creates and provides a user account. An invitation link is sent during the setup process. For more information, see [Qualifio in User Documentation](https://doc.ibexa.co/projects/userguide/en/6.0/qualifio/qualifio/#request-access). - [Create Qualifio campaign](https://ez-systems-developer-documentation--3403.com.readthedocs.build/en/3403/qualifio/create_campaign/): Create a campaign with Qualifio. - [Integrate with Ibexa Connect](https://ez-systems-developer-documentation--3403.com.readthedocs.build/en/3403/qualifio/integrate_ibexa_connect/): Integrate Qualifio with Ibexa Connect. # Create Qualifio campaign > For the complete documentation index, see [llms.txt](https://doc.ibexa.co/en/saas/llms.txt). Create a campaign with Qualifio. [Campaign](https://doc.ibexa.co/projects/userguide/en/6.0/qualifio/qualifio/#campaign) is a set of concepts, divided into steps, that the user can configure. It can contain, for example, a welcome screen, an interaction element, a form step, and an exit screen. To create new campaign, you need to use Qualifio Manager. You can use Qualifio's existing templates and interactive elements, such as quizzes, pools, and forms, to create visually appealing, customized campaigns. Users can configure the backgrounds, themes, or designs, and set up a specific time frame for each campaign. Technically, each campaign has a unique campaign ID, that is automatically defined by the Qualifio platform when it's created. For more information about creating and managing campaigns, see [Qualifio documentation](https://support.qualifio.com/hc/en-us/categories/202280638-Campaigns). ## Publication channels Each campaign includes a minimum of one publication channel that you can choose from the three options the platform provides for publishing a campaign. For more information about publication channels, see [Publication channel](https://doc.ibexa.co/projects/userguide/en/6.0/qualifio/qualifio/#publication-channel) in User Documentation. ## Use Campaign block in Page Builder You can add [Campaign block](https://doc.ibexa.co/projects/userguide/en/6.0/content_management/block_reference/#campaign-block) in Page Builder to display campaign on the landing page. To select campaign, go to **Properties** tab. From the **Campaign** drop-down, choose campaign. This list includes all campaigns available on user's Qualifio account which are active or scheduled to launch in the future. You can set the dimensions of the field in which the campaign is displayed. To do it, insert width and height values in the proper fields. If size fields are blank, the system sets default template values. It's recommended to adjust them for better results. ![Campaign block](https://doc.ibexa.co/en/saas/qualifio/img/campaign_block.png "Campaign block") ## Embed campaign in the Rich text field You can embed campaign in the Rich text field with Campaign custom tag. To do it, insert **Campaign** content item in the Rich Text Field and choose campaign from the drop-down list. This list includes all campaigns available on user's Qualifio account which are active or scheduled to launch in the future. You can set the dimensions of the field in which the campaign is displayed. To do it, select units, and provide width and height values in the proper fields. If size fields are blank, the system sets default template values. It's recommended to adjust them for better results. ![Campaign custom tag](https://doc.ibexa.co/en/saas/qualifio/img/campaign_custom_tag.png "Campaign custom tag") # Integrate with Ibexa Connect > For the complete documentation index, see [llms.txt](https://doc.ibexa.co/en/saas/llms.txt). Integrate Qualifio with Ibexa Connect. You can use [Ibexa Connect](https://doc.ibexa.co/projects/connect/en/latest/general/ibexa_connect/) to create workflows. Qualifio collects user data and passes it directly to Ibexa Connect. With this data, you can create scenarios, for example, to add a user to newsletter, or to specific user segment group. For more information, see [Ibexa Connect documentation](https://doc.ibexa.co/projects/connect/en/latest/). ## Use Ibexa Connect Webhooks provide a powerful way to transfer data between applications in real-time. You can use webhooks to connect Qualifio with Ibexa Connect - integration platform (iPaaS). This integration allows to collect data using Qualifio and then push it to another systems, such as CRMs, CDP, Marketing Automation platforms, or more. ### Get the webhook URL Use Qualifio App and scenario to get the webhook URL from Ibexa Connect. To set up a webhook in Ibexa Connect, follow the steps: 1. Log in to your Ibexa Connect account. 2. Go to **Scenarios** and click the plus button to create a new scenario. 3. Select **Receive participation data**. ![Create a scenario](https://doc.ibexa.co/en/saas/qualifio/img/create_scenario.png "Create a scenario") 4. Click **Create a webhook** and provide a name for the new webhook. 5. Click **Copy address to clipboard** to save the URL. ![Create a webhook](https://doc.ibexa.co/en/saas/qualifio/img/create_webhook.png "Create a webhook") ### Configure Qualifio The next step is to configure Qualifio. When a form submission event takes place, data can be sent through the obtained webhook URL. To do it, perform the following actions:: 1. Log in to your Qualifio account. 2. Go to **Engage** -> **Integrations** -> **Integrations** and select **Webhook**. 3. Paste the URL from the clipboard into **Webhook Host** field and click **Save**. ![Configure Qualifio](https://doc.ibexa.co/en/saas/qualifio/img/configure_qualifio.png "Configure Qualifio") 4. Then, go to **Engage** -> **Integrations** -> **Push rules** to define the default or specific rules for new campaign or website. Select the created webhook. # Multisite # Multisite > For the complete documentation index, see [llms.txt](https://doc.ibexa.co/en/saas/llms.txt). Multisite enables hosting multiple websites with different content, templates and configuration by using one repository. A multisite setup enables you to create more than one site in one installation of Cohesivo. Multisite configuration is done using [SiteAccesses](https://doc.ibexa.co/en/saas/multisite/siteaccess/siteaccess/index.md). To quickly set up new sites with predefined site templates, use [Site Factory](https://doc.ibexa.co/en/saas/multisite/site_factory/site_factory/index.md). - [SiteAccess](https://ez-systems-developer-documentation--3403.com.readthedocs.build/en/3403/multisite/siteaccess/siteaccess/): SiteAccesses enable you to provide separate configuration for each site in a multisite setup. - [Set up campaign SiteAccess](https://ez-systems-developer-documentation--3403.com.readthedocs.build/en/3403/multisite/set_up_campaign_siteaccess/): Create a special SiteAccess to host a campaign site with different content subtree. - [Set up translation SiteAccess](https://ez-systems-developer-documentation--3403.com.readthedocs.build/en/3403/multisite/set_up_translation_siteaccess/): Set up SiteAccesses to hold different language versions of a site. - [Multisite configuration](https://ez-systems-developer-documentation--3403.com.readthedocs.build/en/3403/multisite/multisite_configuration/): Configure SiteAccesses to serve different content in different layouts. - [Site Factory](https://ez-systems-developer-documentation--3403.com.readthedocs.build/en/3403/multisite/site_factory/site_factory/): Site Factory allows creating multiple sites (SiteAccesses) from the back office. - [Site Factory configuration](https://ez-systems-developer-documentation--3403.com.readthedocs.build/en/3403/multisite/site_factory/site_factory_configuration/): Configure Site Factory, including site skeletons. # Multisite configuration > For the complete documentation index, see [llms.txt](https://doc.ibexa.co/en/saas/llms.txt). Configure SiteAccesses to serve different content in different layouts. You can configure the available SiteAccesses under the `ibexa.siteaccess` [configuration key](https://doc.ibexa.co/en/saas/administration/configuration/configuration/#configuration-files). ## SiteAccess configuration ```yaml ibexa: siteaccess: list: [site, event] groups: site_group: [site] event_group: [event] default_siteaccess: site match: URIElement: 1 ``` ### SiteAccess groups `ibexa.siteaccess.groups` defines which groups SiteAccesses belong to. ```yaml ibexa: siteaccess: groups: site_group: [site] event_group: [event] ``` You can use groups when you want to use common settings for several SiteAccesses and avoid duplicating configuration. SiteAccess groups act like regular SiteAccesses as far as configuration is concerned. A SiteAccess can be part of several groups. SiteAccess configuration has always precedence over group configuration. #### `admin` SiteAccess The predefined `admin` SiteAccess in `admin_group` serves the back office. Don't remove this group. If you need a multisite setup with multiple back offices, add any additional administration SiteAccesses to `admin_group`. In cases where the sites are on separate databases, each needs its own repository (including their own storage and search connection), var dir, cache pool, and ideally also separate Varnish/Fastly configuration. > **Caution: Caution** > > Different SiteAccesses can only have different `var_dir` if they also have different repositories. Make sure there are no special or Unicode characters in your `var_dir` values. ### Default SiteAccess The `default_siteaccess` setting identifies which SiteAccess is used by default when no other SiteAccess matches. ```yaml ibexa: siteaccess: default_siteaccess: site ``` ### SiteAccess matching The `match` setting defines the rule or set of rules by which SiteAccesses are matched. For more information, see [SiteAccess matching](https://doc.ibexa.co/en/saas/multisite/siteaccess/siteaccess_matching/index.md). ```yaml ibexa: siteaccess: match: URIElement: 1 ``` ### SiteAccess name To create a better editorial experience, you can replace the SiteAccess code in the back office with a human-readable name of the website, for example `Company site` or `Summer Sale`. You can also translate SiteAccess names. Displayed names depend on the current back office language. To define translations or SiteAccess names, place them in YAML file with correct language code, for example `translations/ibexa_siteaccess.en.yaml`: ```yaml en: Company site fr: Company site France ``` ## Scope All SiteAccess-aware configuration is resolved depending on scope. The available scopes are: 1. `global` 2. SiteAccess 3. SiteAccess group 4. `default` `global` overrides all other scopes. If `global` isn't defined, the configuration then tries to match a SiteAccess, and then a SiteAccess group. Finally, if no other scope is matched, `default` is applied. In short: if you want a match that always applies, regardless of SiteAccesses, use `global`. To define a fallback, use `default`. ```yaml ibexa: system: global: # If set, this value is used regardless of any other configuration site: # This is used for the 'site' SiteAccess site_group: # This is overwritten by the SiteAccess above, since the SiteAccess has precedence default: # This value is only used if there is no setting for global scope, SiteAccess or SiteAccess group ``` `global` and `default` scopes include the `admin` SiteAccess, which is responsible for the back office. For example, the following configuration defines both the front template for articles and the template used in the back office, unless you configure other templates for a specific SiteAccess or SiteAccess group: ```yaml ibexa: system: default: content_view: full: article: template: full/article.html.twig match: Identifier\ContentType: [article] ``` ### SiteAccesses and Page Builder To define which SiteAccesses are available in the submenu in Page Builder, use the following configuration: ```yaml ibexa: system: admin: page_builder: siteaccess_list: [site, de, fr, no] de: page_builder: siteaccess_list: [site, de] ``` If you're using multiple domains, list all domains for an admin SiteAccess under `siteaccess_hosts`: ```yaml ibexa: system: admin: page_builder: siteaccess_list: [site, de, fr, no] siteaccess_hosts: - my_domain.com - another_domain.org ``` > **Caution: SiteAccess with separate admin domain** > > If an admin SiteAccess in your installation uses a different domain than the front SiteAccesses, be sure to use SSL (https protocol). Otherwise, you cannot preview content in Page Builder from the back office. #### SiteAccess switching in Page Builder If you need to change between SiteAccesses in Site mode, don't use any functions in the page itself (for example, a language switcher). This may cause unexpected errors. Instead, switch between SiteAccesses with the SiteAccess bar above the page. ## Location tree You can restrict SiteAccesses to different parts of the content tree. When you do it, only the selected location and its descendants are reachable from this SiteAccess. Configure this under the `ibexa.systems..content.tree_root` [configuration key](https://doc.ibexa.co/en/saas/administration/configuration/configuration/#configuration-files), for example: ```yaml ibexa: system: : content: tree_root: location_id: 42 excluded_uri_prefixes: [/media/, /images/] index_page: /EventFrontPage ``` - `location_id` defines the location ID of the content root for the SiteAccess. - `excluded_uri_prefixes` defines which URIs ignore the root limit set by using `location_id`. In the example above, to access the Media and Images folders, you can use their own URI, even though they're outside the location provided in `content.tree_root.location_id`. It's an array of prefixes. So, for example, `[/media]` would also exclude `/mediation` from root limit. - `index_page` is the page shown when you access the root index `/`. > **Note: Note** > > Prefixes aren't case sensitive. Leading slashes (`/`) are automatically trimmed internally, so they can be ignored. > **Tip: Tip** > > For an example of a multisite configuration, see [Set up campaign SiteAccess](https://doc.ibexa.co/en/saas/multisite/set_up_campaign_siteaccess/index.md). # SiteAccess > For the complete documentation index, see [llms.txt](https://doc.ibexa.co/en/saas/llms.txt). SiteAccesses enable you to provide separate configuration for each site in a multisite setup. A SiteAccess is a set of configuration settings that the application uses when you access the site through a specific address. When the user visits the site, the system analyzes the URI and compares it to rules specified in the configuration. If it finds a set of fitting rules, this SiteAccess is used. Each SiteAccess can have different: - templates and designs - [languages](https://doc.ibexa.co/en/saas/multisite/set_up_translation_siteaccess/index.md) - [tree roots](https://doc.ibexa.co/en/saas/multisite/multisite_configuration/#location-tree) - repositories - [recommendations](https://doc.ibexa.co/en/saas/recommendations/raptor_integration/connector_installation_configuration/#siteaccess-aware-configuration) Many other settings in the application are also configured per SiteAccess (also known as "SiteAccess-aware"). > **Tip: Tip** > > When possible, always use semantic (SiteAccess-aware) configuration. Manually editing internal settings is possible, but at your own risk, as unexpected behavior can occur. - [SiteAccess matching](https://ez-systems-developer-documentation--3403.com.readthedocs.build/en/3403/multisite/siteaccess/siteaccess_matching/): Use SiteAccess matchers to control which site is served when and to which user. - [SiteAccess-aware configuration](https://ez-systems-developer-documentation--3403.com.readthedocs.build/en/3403/multisite/siteaccess/siteaccess_aware_configuration/): Make sure your custom development's configuration can be used with SiteAccesses. # SiteAccess matching > For the complete documentation index, see [llms.txt](https://doc.ibexa.co/en/saas/llms.txt). Use SiteAccess matchers to control which site is served when and to which user. To be usable, every SiteAccess must be matched by one of configured matchers. By default, all SiteAccesses are matched using `URIElement: 1`. You can configure SiteAccess matchers under the `ibexa.siteaccess.match` [configuration key](https://doc.ibexa.co/en/saas/administration/configuration/configuration/#configuration-files): ```yaml ibexa: siteaccess: list: [site, event] groups: site_group: [site, event] default_siteaccess: site match: Map\URI: site: site campaign: event ``` `ibexa.siteaccess.match` can contain multiple matchers. The first matcher succeeding always wins, so be careful when using catch-all matchers like `URIElement`. In the following example, `Compound\LogicalAnd` is placed before the `Map\Host` for `my.site/corporate` to be reachable: ```yaml ibexa: siteaccess: match: Compound\LogicalAnd: corporate: matchers: Map\URI: corporate: true Map\Host: my.site: true match: corporate Map\Host: my.site: mysite ``` If the matcher class doesn't start with a backslash (`\`), it's relative to `Ibexa\Core\MVC\Symfony\SiteAccess\Matcher` (for example, `Map\URI` refers to `Ibexa\Core\MVC\Symfony\SiteAccess\Matcher\Map\URI`) You can specify [custom matchers](#custom-matchers) by using a fully qualified class name (for example, `\My\SiteAccess\Matcher`) or a service identifier (for example, `@my_matcher_service`). In the case of a fully qualified class name, the matching configuration is passed in the constructor. In the case of a service, it must implement `Ibexa\Bundle\Core\SiteAccess\Matcher`. The matching configuration is passed to `setMatchingConfiguration()`. ## Available SiteAccess matchers - [`URIElement`](#urielement) - [`URIText`](#uritext) - [`HostElement`](#hostelement) - [`HostText`](#hosttext) - [`Map\Host`](#maphost) - [`Map\URI`](#mapuri) - [`Map\Port`](#mapport) - [`Ibexa\SiteFactory\SiteAccessMatcher`](#ibexasitefactorysiteaccessmatcher) ### `URIElement` Maps a URI element to a SiteAccess. In configuration, provide the element number you want to match (starting from 1). ```yaml ibexa: siteaccess: match: URIElement: 2 ``` > **Note: Note** > > When you use a value > 1, the matcher concatenates the elements with `_`. Example URI `/my_site/company/pages` matches SiteAccess `my_site_company`. ### `URIText` Matches URI using prefix and suffix sub-strings in the first URI segment. In configuration, provide the prefix and/or suffix (neither is required). ```yaml ibexa: siteaccess: match: URIText: prefix: main- suffix: /company ``` Example URI `/main-event/company/page` matched SiteAccess `event`. ### `HostElement` Maps an element in the host name to a SiteAccess. In configuration, provide the element number you want to match (starting from 1). ```yaml ibexa: siteaccess: match: HostElement: 2 ``` Example host name `www.example.com` matches SiteAccess `example`. ### `HostText` Matches a SiteAccess in the host name, using pre and/or post sub-strings. In configuration, provide the prefix and/or suffix (none are required). ```yaml ibexa: siteaccess: match: HostText: prefix: www. suffix: .com ``` Example host name `www.example.com` matches SiteAccess `example`. ### `Map\Host` Maps a host name to a SiteAccess. In configuration, provide a hash map of host/SiteAccess. ```yaml ibexa: siteaccess: match: Map\Host: www.page.com: event adm.another-page.fr: event_admin ``` Example host name `www.page.com` matches SiteAccess `event`. > **Note: Note** > > If you encounter problems with the `Map\Host` matcher, make sure that your installation is properly configured to use token-based authentication. ### `Map\URI` Maps a URI to a SiteAccess. In configuration, provide a hash map of URI/SiteAccess. ```yaml ibexa: siteaccess: match: Map\URI: campaign: event site: site ``` Example URI `/campaign/general/articles` matches SiteAccess `event`. ### `Map\Port` Maps a port to a SiteAccess. In configuration, provide a hash map of Port/SiteAccess. ```yaml ibexa: siteaccess: match: Map\Port: 80: event 8080: site ``` Example URL `http://my_site.com:8080/content` matches SiteAccess `site`. ### `Ibexa\SiteFactory\SiteAccessMatcher` Enables the use of [Site Factory](https://doc.ibexa.co/en/saas/multisite/site_factory/site_factory/index.md). Doesn't take any parameters in configuration: ```yaml ibexa: siteaccess: match: '@Ibexa\SiteFactory\SiteAccessMatcher': ~ ``` ## Custom matchers Beside the built-in matchers, you can also use your own services to match SiteAcceses: ```yaml ibexa: siteaccess: list: [site] groups: site_group: [site] default_siteaccess: site match: '@App\Matcher\MySiteaccessMatcher': ~ ``` The service must be tagged with `ibexa.site_access.matcher` and must implement `Ibexa\Bundle\Core\SiteAccess\Matcher` (and `Ibexa\Core\MVC\Symfony\SiteAccess\VersatileMatcher` if you want to use compound logical matchers). ## Combining SiteAccess matchers You can combine more than one SiteAccess matcher to match more complex situations, for example: - `http://example.com/en` matches `site_en` (match host example.com and the `en` URI element) - `http://example.com/fr` matches `site_fr` (match host example.com and the `fr` URI element) - `http://admin.example.com` matches `site_admin` (match host admin.example.com) To combine matchers, use compound logical matchers: - `Compound\LogicalAnd` - `Compound\LogicalOr` Each compound matcher specifies two or more sub-matchers. A rule applies if all the matchers combined with the logical matcher are positive. To get the result above, you need to combine `Map\Host` and `Map\Uri` using `LogicalAnd`. When both the URI and host match, the SiteAccess configured with `match` is used. ```yaml ibexa: siteaccess: match: Compound\LogicalAnd: # You don't need to specify matching values (true is enough). site_en: matchers: Map\URI: en: true Map\Host: example.com: true match: site_en site_fr: matchers: Map\URI: fr: true Map\Host: example.com: true match: site_fr Map\Host: admin.example.com: site_admin ``` When using `Compound\LogicalAnd`, all inner matchers must match. All matchers must implement `VersatileMatcher`. When using `Compound\LogicalOr`, the first inner matcher succeeding wins. ## Matching by request header You can define which SiteAccess to use by setting an `X-Siteaccess` header in your request. This can be useful for REST requests. In such a case, `X-Siteaccess` must be the SiteAccess name (for example, `site` or `en`). ## Matching by environment variable You can also define which SiteAccess to use directly by using the `EZPUBLISH_SITEACCESS` environment variable. This is recommended if you want to get performance gain since no matching logic is done in this case. You can define this environment variable directly in web server configuration: ```vcl # This configuration assumes that mod_env is activated DocumentRoot "/path/to/ibexa/web/folder" ServerName example.com ServerAlias www.example.com SetEnv EZPUBLISH_SITEACCESS demo_site ``` > **Tip: Tip** > > You can configure the variable by using the PHP-FPM configuration file. For more information, see [PHP-FPM documentation](https://www.php.net/manual/en/install.fpm.configuration.php). > **Note: Precedence** > > The precedence order for SiteAccess matching is the following (the first matched wins): > > 1. Request header > 1. Environment variable > 1. Configured matchers # SiteAccess-aware configuration > For the complete documentation index, see [llms.txt](https://doc.ibexa.co/en/saas/llms.txt). Make sure your custom development's configuration can be used with SiteAccesses. The [Symfony Config component](https://symfony.com/doc/7.4/components/config.html) makes it possible to define semantic configuration, exposed to the end developer. This configuration is validated by rules you define, for example, validating type (string, array, integer, boolean, and more). Usually, after it's validated and processed, this semantic configuration is then mapped to internal *key/value* parameters stored in the service container. Cohesivo uses this for its core configuration, but adds another configuration level, the SiteAccess. For each defined SiteAccess, you need to be able to use the same configuration tree to define SiteAccess-specific config. These settings then need to be mapped to SiteAccess-aware internal parameters that you can retrieve with the [ConfigResolver](https://doc.ibexa.co/en/saas/administration/configuration/dynamic_configuration/#configresolver). For this, internal keys need to follow the format `..`. where: - `namespace` is specific to your app or bundle - `scope` is the SiteAccess, SiteAccess group, `default` or `global` - `parameter_name` is the actual setting *identifier* For more information about the ConfigResolver, namespaces and scopes, see [configuration basics](https://doc.ibexa.co/en/saas/administration/configuration/configuration/index.md). # Set up campaign SiteAccess > For the complete documentation index, see [llms.txt](https://doc.ibexa.co/en/saas/llms.txt). Create a special SiteAccess to host a campaign site with different content subtree. The following example shows how to set up a special `campaign` SiteAccess. This SiteAccess serves a site devoted to a special campaign, separate from the main company website (`site` SiteAccess). The `campaign` site uses a different part of the content tree than the main site, but shares some media files with it. ## Configure SiteAccesses First, in SiteAccess configuration, add the `campaign` SiteAccess to the list under the `ibexa.siteaccess` [configuration key](https://doc.ibexa.co/en/saas/administration/configuration/configuration/#configuration-files): ```yaml ibexa: siteaccess: list: [site, campaign] groups: site_group: [site, campaign] default_siteaccess: site match: Map\URI: summer-sale: campaign site: site ``` The `match` setting ensures that when a visitor accesses the `/summer-sale` URI, they see the `campaign` SiteAccess. ## Set root folder Next, with the following content structure, you need to separate the "Campaign" folder as root for the new site: ![Content structure](https://doc.ibexa.co/en/saas/multisite/img/config_content_structure.png "Content structure") To do it, set the root level for `campaign` to access the "Campaign" Location and its sub-items only: ```yaml ibexa: system: campaign: content: tree_root: # LocationId of "Campaign" location_id: 57 ``` Thanks to this configuration, you can access `/campaign/Articles/Article2`, but not `/campaign/General/Articles/Article1`. ## Reuse content Finally, reuse some content between sites, for example "Logos" from "Images/Media". You can allow the `campaign` site to access them, even though they're in a different part of the tree, via [`excluded_uri_prefixes`](https://doc.ibexa.co/en/saas/multisite/multisite_configuration/#location-tree): ```yaml ibexa: system: campaign: content: tree_root: location_id: 57 excluded_uri_prefixes: [ /media/images/logos/ ] ``` Now, when you use the `campaign` SiteAccess, you can reach `/campaign/Media/Images/Logos`, despite the fact that it's not a sub-item of the "Campaign" location. As a next step, you can configure different designs for the two SiteAccesses. # Set up translation SiteAccess > For the complete documentation index, see [llms.txt](https://doc.ibexa.co/en/saas/llms.txt). Set up SiteAccesses to hold different language versions of a site. One of common uses for multisite installations is serving different language versions of a website. To do this, set up multiple SiteAccesses, each corresponding to one language. Proper configuration means avoiding duplicate content that could affect SEO. ## Add a language First, add a new language for the whole installation. > **Tip: Tip** > > For more details, see [Languages](https://doc.ibexa.co/en/saas/multisite/languages/languages/index.md). 1. In the back office, go to **Admin** -> **Languages**. 2. Click **Create a new language** and provide the language name and code (examples below use French with `fre-FR`). ## Configure SiteAccesses Next, configure a new SiteAccess to match the newly-configured language. The most typical setup for a site with translated content is to map the base of the domain to one language and use the first segment of the URI to match to translations. For example: - `www.mysite.com` for English site - `www.mysite.com/fr` for French site To achieve this you need to create a new SiteAccess in configuration under the `ibexa.siteaccesses` [configuration key](https://doc.ibexa.co/en/saas/administration/configuration/configuration/#configuration-files). Add the `fr` SiteAccess to list of all SiteAccesses and it to the common `site_group`. This group is used for sharing settings such as API keys, cache locations, and more. ```yaml ibexa: siteaccess: list: [site, fr] groups: site_group: [site, fr] ``` Under the `ibexa.system` key, add the new SiteAccess. Indicate that they're meant for translations under `site_group.translation_siteaccesses`: ```yaml ibexa: system: site_group: # ... translation_siteaccesses: [fr] fr: languages: [fre-FR, eng-GB] site: languages: [eng-GB] ``` With this configuration, the main English site displays content in English and ignores French content. The French site displays content in French, but also in English, if it doesn't exist in French. ## Set permissions By default, the Anonymous user role doesn't have permissions for new SiteAccesses. As a next step, allow Anonymous users to read content on the new SiteAccesses: 1. In the back office, go to **Admin** -> **Roles**. 2. Click the **Anonymous** role. 3. Edit the **Limitations** of the module `user`, select both SiteAccesses and click **Update**. You can now start translating content. When you reload the site, access a translated content item through both SiteAccesses to see the difference, for example: `/` and `/fr/`. # Site Factory > For the complete documentation index, see [llms.txt](https://doc.ibexa.co/en/saas/llms.txt). Site Factory allows creating multiple sites (SiteAccesses) from the back office. Site Factory is a site management interface, integrated with the back office. It enables you to configure new sites without editing [YAML-based SiteAccess configuration](https://doc.ibexa.co/en/saas/multisite/multisite_configuration/index.md). > **Note: Note** > > A SiteAccess that you define for a site by following the [configuration](https://doc.ibexa.co/en/saas/multisite/multisite_configuration/index.md) is always treated with higher priority than a SiteAccess created by using the Site Factory. For example, if you define a French site within a YAML file, and then create a site that uses the `fr` path in Site Factory, matchers ignore the second site. Site Factory is disabled by default. If you plan to use Site Factory, you need to [enable and configure it](#enable-site-factory). ## Enable Site Factory To enable Site Factory, set the `ibexa_site_factory.enabled` [configuration key](https://doc.ibexa.co/en/saas/administration/configuration/configuration/#configuration-files) to `true`. ### Configure designs Next, configure Site Factory by adding empty SiteAccess groups. At least one empty group is required. The number of empty SiteAccess groups must be equal to the number of templates that you want to have when you create the new site. In this example, you add two SiteAccess groups (`example_site_factory_group_1` and `example_site_factory_group_2`) that correspond to the two templates (`site1` and `site2`) that you add in the next step. Add the groups under the `ibexa.siteaccess` [configuration key](https://doc.ibexa.co/en/saas/administration/configuration/configuration/#configuration-files): ```yaml ibexa: siteaccess: # ... groups: site_group: [import, site] storefront_group: [site] corporate_group: [corporate] example_site_factory_group_1: [ ] example_site_factory_group_2: [ ] system: example_site_factory_group_1: example_site_factory_group_2: ``` Uncomment the SiteAccess matcher (`Ibexa\SiteFactory\SiteAccessMatcher`): ```yaml ibexa: siteaccess: match: '@Ibexa\SiteFactory\SiteAccessMatcher': ~ ``` Next, add the design engine configuration for new specific designs and their theme lists: ```yaml ibexa_design_engine: design_list: example_1: [example_1_theme] example_2: [example_2_theme] ``` Finally, configure designs for empty SiteAccess groups: ```yaml ibexa: system: example_site_factory_group_1: design: example_1 example_site_factory_group_2: design: example_2 ``` ### Add site template configuration Add thumbnails and names for your site templates: ```yaml ibexa_site_factory: templates: site1: siteaccess_group: example_site_factory_group_1 name: Example site 1 thumbnail: /path/to/image/example-thumbnail_1.png site2: siteaccess_group: example_site_factory_group_2 name: Example site 2 thumbnail: /path/to/image/example-thumbnail_2.png ``` You can check the results of your work in the back office by going to **Site management** and selecting **Sites**. There, you should be able to add a new site and choose a design for it. ### Define site directory You can adjust the place where the directory of the new site is created (location with ID 2 by default). To do it, go to configuration files and under the `ibexa.system..site_factory` [configuration key](https://doc.ibexa.co/en/saas/administration/configuration/configuration/#configuration-files) add the following parameter: ```yaml ibexa: system: default: site_factory: sites_location_id: 42 ``` Now, all new directories are created under "Cohesivo". ### Provide access The Site Factory is set up, now you can provide sufficient permissions to the users. Set the below policies to allow users to: - `site/view` - enter the Site Factory interface - `site/create` - create sites - `site/edit` - edit sites - `site/change_status` - change status of the public accesses to `Live` or `Offline` - `site/delete` - delete sites For full documentation on how permissions work and how to set them up, see [the permissions section](https://doc.ibexa.co/en/saas/permissions/permissions/index.md). To learn how to use Site Factory, see [User Documentation](https://doc.ibexa.co/projects/userguide/en/6.0/website_organization/work_with_sites/). # Site Factory configuration > For the complete documentation index, see [llms.txt](https://doc.ibexa.co/en/saas/llms.txt). Configure Site Factory, including site skeletons. ## Parent location When working with the [Site Factory](https://doc.ibexa.co/en/saas/multisite/site_factory/site_factory/index.md), you can define the parent location for a new site in the configuration. Each new site is created in the designated location. To define a parent location, add a new configuration key to the site template definition. Each template is assigned to its own location. This can be either a location ID (for example, `62`), or a recommended remote location ID (for example, `1548b8cd8dd4c6b5082e566615d45e91`). Add the configuration key to your template under the `ibexa_site_factory` [configuration key](https://doc.ibexa.co/en/saas/administration/configuration/configuration/#configuration-files): ```yaml ibexa_site_factory: templates: site1: siteaccess_group: example_site_factory_group_1 name: example_site_1 thumbnail: /path/to/image/example-thumbnail_1.png parent_location_id: 62 site2: siteaccess_group: example_site_factory_group_2 name: example_site_2 thumbnail: /path/to/image/example-thumbnail_2.png parent_location_remote_id: 1548b8cd8dd4c6b5082e566615d45e91 ``` Now, you can see the path to the new site's parent location under design selection. If you have sufficient permissions, you can change the defined location during site creation. If the parent location isn't defined, you have to choose it from Universal Discovery Widget. ## Site skeletons The Site skeleton enables you to copy an entire content structure of the site design to the defined location. Site skeleton copying is a one-off operation, it only happens during the site creation process. After that, you cannot copy the Site skeleton again, for example in the edit view. You can create as many skeletons as you need and assign them to templates. Remember that one template can only have one Site skeleton. If the design doesn't have a defined Site skeleton, a directory of the new site is created in a standard Site Factory process. To define a Site skeleton, add the `site_skeleton_id` or `site_skeleton_remote_id` key to the site template definition. This can be either a location ID (for example, `5966`), or a remote location ID (for example, `3bed95afb1f8126f06a3c464e461e1ae66`). ```yaml ibexa_site_factory: templates: site1: siteaccess_group: example_site_factory_group_1 name: example_site_1 thumbnail: /path/to/image/example-thumbnail_1.png site_skeleton_id: 5966 site2: siteaccess_group: example_site_factory_group_2 name: example_site_2 thumbnail: /path/to/image/example-thumbnail_2.png site_skeleton_remote_id: 3bed95afb1f8126f06a3c464e461e1ae66 ``` Now, you can choose a design with a defined Site skeleton, and decide if you want to use its skeleton by toggling **Generate site using site skeleton**. ## User group skeletons With user group skeletons you can define policies and limitations that apply to selected groups of users who can access the site. You can create many user group skeletons and associate them with many templates. One template can have many user group skeletons assigned. To create a user group skeleton, first go to **Admin** -> **Site skeletons** and add a user group to the list of available skeletons. Then, review the detailed information of the newly created user group skeleton, copy the location ID or the Location remote ID, and add a configuration key to the site template definition: ```yaml ibexa_site_factory: templates: : # ... user_group_skeleton_ids: [ , , ... ] user_group_skeleton_remote_ids: [ , , ... ] ``` Manage the permissions associated to the user group skeleton by [assigning roles](https://doc.ibexa.co/projects/userguide/en/6.0/permission_management/work_with_permissions/#assign-a-role-to-users). Make sure that the roles that you assign to the user group skeleton don't contain location-based limitations. User group skeletons cannot contain individual user content items either. User group skeletons are retained after deleting the site. ## Automatic update of roles Role definitions can contain user/login policies with limitations that limit user access to certain sites. To avoid the need to add the new SiteAccess to limitations for all roles, you can decide that the roles you select are automatically updated when the site is created, updated, or deleted. Under the `ibexa_site_factory` [configuration key](https://doc.ibexa.co/en/saas/administration/configuration/configuration/#configuration-files), add a list of roles which should have access to the frontend when a site is created in Site Factory, for example: ```yaml ibexa_site_factory: # ... enabled: true update_roles: [Anonymous, Administrator] ``` For more information about roles and policies, see [Permissions](https://doc.ibexa.co/en/saas/permissions/permissions/index.md). # Languages > For the complete documentation index, see [llms.txt](https://doc.ibexa.co/en/saas/llms.txt). You can create multiple language versions (translations) of content and serve different language versions of your site with the help of SiteAccesses. ## Language versions Cohesivo offers the ability to create multiple language versions (translations) of a content item. Translations are created per version of the item, so each version of the content can have a different set of translations. A version always has at least one translation which by default is the *initial/main* translation. Further versions can be added, but only for languages that have previously been [added to the global translation list](#adding-available-languages), that is a list of all languages available in the system. The maximum number of languages in the system is 62. Different translations of the same content item can be edited separately. This means that different users can work on translations into different languages at the same time. Each version, including a draft, contains all the existing translations. However, even if work on a draft takes time and other translations are updated in the meantime, publishing the draft doesn't overwrite later modifications. ### Adding available languages The multilanguage system operates based on a global translation list that contains all languages available in the installation. Languages can be [added to this list from the **Admin** panel](https://doc.ibexa.co/projects/userguide/en/6.0/content_management/translate_content/) in the back office. **The new language must then be added to the [SiteAccess](https://doc.ibexa.co/en/saas/multisite/multisite/index.md) configuration**. Once this is done, any user with proper permissions can create content item versions in these languages in the user interface. ### Translatable and untranslatable fields Language versions consist of translated values of the content item's fields. In the content type definition every field is set to be Translatable or not. Cohesivo doesn't decide by itself which fields can be translated and which cannot. For some field values the need for a translation can be obvious, for example for the body of an article. In other cases, for instance images without text, integer numbers, or email addresses, translation is usually unnecessary. Despite that, Cohesivo gives you the possibility to mark any field as translatable regardless of its field type. It's only your decision to exclude the translation possibility for those fields where it makes no sense. When a field isn't flagged as Translatable, its value is copied from the initial/main translation when a new language version is created. This copied value cannot be modified. When a field is Translatable, you have to enter its value in a new language version manually. For example, let's say that you need to store information about marathon contestants and their results. You build a "contestant" content type that includes the following fields: name, photo, age, nationality, finish time. Allowing the translation of anything other than nationality would be pointless, since the values stored by the other fields are the same regardless of the language used to describe the contestant. In other words, the name, photo, age and finish time would be the same in, for example, both English and Norwegian. ### Access control You can control whether a user or user group is able to translate content or not. You do this by adding a [Language limitation](https://doc.ibexa.co/en/saas/permissions/limitation_reference/#language-limitation) to policies that allow creating or editing content. This limitation enables you to define which role can work with which languages in the system. For more information of the permissions system, see [Permissions](https://doc.ibexa.co/en/saas/permissions/permissions/index.md). In addition, you can also control the access to the global translation list by using the `Content/Translations` policy. This policy allows users to add and remove languages from the global translation list. ## Using SiteAccesses for handling translations If you want to have completely separate versions of the website, each with content in its own language, you can [use SiteAccesses](#using-siteaccesses-for-handling-translations). Depending on the URI used to access the website, a different site opens, with a language set in configuration settings. All content items are then displayed in this language. For details, see [Multi-language SiteAccesses](https://doc.ibexa.co/en/saas/multisite/set_up_translation_siteaccess/index.md). ### Explicit translation SiteAccesses Configuration isn't mandatory, but can help to distinguish which SiteAccesses can be considered translation SiteAccesses. ```yaml ibexa: siteaccess: default_siteaccess: eng list: - site - eng - fre - site_admin groups: frontend_group: - site - eng - fre # ... system: # Specifying which SiteAccesses are used for translation frontend_group: translation_siteaccesses: [fre, eng] eng: languages: [eng-GB] fre: languages: [fre-FR, eng-GB] site: languages: [eng-GB] ``` > **Note: Note** > > The top prioritized language is always used the SiteAccess language reference (for example, `fre-FR` for `fre` SiteAccess in the example above). If several translation SiteAccesses share the same language reference, **the first declared SiteAccess always applies**. #### Custom locale configuration If you need to use a custom locale, you can configure it in `ibexa.yaml`, adding it to the *conversion map*: ```yaml ibexa: # Locale conversion map between eZ Publish format (e.g. fre-FR) to POSIX (e.g. fr_FR). # The key is the eZ Publish locale. Check locale.yaml in IbexaCore to see natively supported locales. locale_conversion: eng-DE: en_DE ``` A locale *conversion map* example [can be found in `ibexa/core`, in `locale.yaml`](https://github.com/ibexa/core/blob/6.0/src/bundle/Core/Resources/config/locale.yml). ### More complex translation setup There are some cases where your SiteAccesses share settings (for example, repository or content settings), but you don't want all of them to share the same `translation_siteaccesses` setting. This can be for example the case when you use separate SiteAccesses for mobile versions of a website. The solution is defining new groups: ```yaml ibexa: siteaccess: default_siteaccess: eng list: - site - eng - fre - mobile_eng - mobile_fre - site_admin groups: # This group can be used for common front settings common_group: - site - eng - fre - mobile_eng - mobile_fre frontend_group: - site - eng - fre mobile_group: - mobile_eng - mobile_fre # ... system: # Translation SiteAccesses for regular frontend frontend_group: translation_siteaccesses: [fre, eng] # Translation SiteAccesses for mobile frontend mobile_group: translation_siteaccesses: [mobile_fre, mobile_eng] eng: languages: [eng-GB] fre: languages: [fre-FR, eng-GB] site: languages: [eng-GB] mobile_eng: languages: [eng-GB] mobile_fre: languages: [fre-FR, eng-GB] ``` ### Using implicit *related SiteAccesses* If the `translation_siteaccesses` setting isn't provided, implicit *related SiteAccesses* is used instead. SiteAccesses are considered *related* if they share: - The same repository - The same root `location_id` (see [Multisite](https://doc.ibexa.co/en/saas/multisite/multisite/index.md)) ### Fallback languages and missing translations When setting up SiteAccesses with different language versions, you can specify a list of preset languages for each SiteAccess. When this SiteAccess is used, the system goes through this list. If a content item is unavailable in the first (prioritized) language, it attempts to use the next language in the list, and more. Thanks to this you can have a fallback in case of a lacking translation. You can also assign a Default content availability flag to content types (available in the **Admin** panel). When this flag is assigned, content items of this type are available even when they don't have a language version in any of the languages configured for the current SiteAccess. If a language isn't provided in the list of prioritized languages and it's not the content item's first language, the URL alias for this content in this language isn't generated. # Back office translations > For the complete documentation index, see [llms.txt](https://doc.ibexa.co/en/saas/llms.txt). The language of the back office is selected automatically based on browser language, or you can choose it manually in user settings. ## Enabling back office languages All translations are available as a part of Cohesivo. To enable back office translations, use the following configuration: ```yaml ibexa: ui: translations: enabled: true ``` Now you can reload your Cohesivo back office. If your browser language is set to French, the back office is displayed in French. > **Tip: Checking browser language** > > To make sure that a language is set in your browser, check if it's sent as an accepted language in the `Accept-Language` header. > **Tip: Tip** > > You can also manually add the necessary .xliff files to an existing project. > > Add the language to an array under `ibexa.system..user_preferences.additional_translations`, for example: > > `ibexa.system..user_preferences.additional_translations: ['pl_PL', 'fr_FR']` ### Selecting back office language Once you have language packages enabled, you can switch the language of the back office in the **User Settings** menu. Otherwise, the language is selected based on the browser language. If you don't have a language defined in the browser, the language is selected based on the `parameters.locale_fallback` setting. # Translations management > For the complete documentation index, see [llms.txt](https://doc.ibexa.co/en/saas/llms.txt). Translations management brings multiple features that help managers, developers and localization teams automate multilingual content delivery. Translations management helps Cohesivo developers and editors deliver automated content item and product translations. - [Translations management product guide](https://ez-systems-developer-documentation--3403.com.readthedocs.build/en/3403/multisite/translations_management/translations_management_guide/): Translations management helps managers, developers and localization teams with multilingual content delivery. - [Configure translations management](https://ez-systems-developer-documentation--3403.com.readthedocs.build/en/3403/multisite/translations_management/configure_translations_management/): Configure translation providers, language pairs, and more for translations management. # Translations management product guide > For the complete documentation index, see [llms.txt](https://doc.ibexa.co/en/saas/llms.txt). Translations management helps managers, developers and localization teams with multilingual content delivery. ## What is Translations management Content managers, editors, translators, and proofreaders who work with multilingual content in Cohesivo often face a common set of challenges: - context is lost when the source text isn't visible alongside the translation - translating long and complex content items is time-consuming - quality assurance is slow and error-prone without a direct comparison view - switching between tools or tabs to cross-reference languages disrupts focus and slows down publishing The Translations management package addresses these pain points through a side-by-side view, machine translation and the ability to invite reviewers to collaborate on the translation of content items or products. The package integrates with the [AI Actions framework](https://doc.ibexa.co/en/saas/ai/ai_actions/ai_actions_guide/index.md) to support machine translation providers such as Google Translate and DeepL, and AI-powered translation services like OpenAI, Anthropic, and Google Gemini. Administrators can manage providers and configure default provider-to-language-pair mappings directly in Cohesivo's back office, while editors can trigger machine translation from the content editing interface. ## How it works Before the translation flow can happen, an administrator sets up the translation providers and assigns language pairs to them. Then, when an editor opens a content item or product and requests a new machine translation, the system resolves which provider to use. If no language-pair rule matches, it falls back to the user's manual selection. The system then extracts the translatable fields from the source language version of a content item and sends them to the configured provider's API. The system writes the translated strings into a target-language draft of the content item or a target-language version of a product, and opens it in a side-by-side view for the editor to review and refine. The editor can save the result of content item translation as a draft, share it with a reviewer or publish it. Product translations are published when the editor closes the view without rejecting it. ![Translations management flow for content item translation](https://doc.ibexa.co/en/saas/multisite/img/translations_management_flow.png "Translations management flow for content item translation") ## Capabilities ### Translation provider management Administrators can manage translation providers and configure translation provider/language combination assignments ([language pairs](https://doc.ibexa.co/en/saas/multisite/translations_management/configure_translations_management/#define-language-pairs)). This allows administrators to define which provider handles which language combination. Editors see the configured provider pre-selected when creating a new translation, but can override it if needed. ![Creating a language pair](https://doc.ibexa.co/en/saas/multisite/img/translations_management_language_pairs.png "Creating a language pair") The package provides integrations with several translation providers, including REST API-based services such as Google Translate and DeepL, and AI-powered services through the [AI Actions](https://doc.ibexa.co/en/saas/ai/ai_actions/ai_actions_guide/index.md). ### Side-by-side translation view Translations management introduces a [side-by-side translation view](https://doc.ibexa.co/projects/userguide/en/6.0/content_management/translate_content/#side-by-side-translation-view) that displays the read-only source language content next to an editable target language form. In this view, editors can provide and review translations in context, without having to leave the content editing interface. ![Side-by-side translation view](https://doc.ibexa.co/en/saas/multisite/img/managing_translations_sxs_view.png "Side-by-side translation view") Editors can: - access the side-by-side view when creating a new translation, reviewing an existing one, or editing a draft - compare source and target content field by field while editing - copy all content from the source column to the target column with a single action - provide localized versions of media assets and their alternative text - use the distraction-free mode for focused editing of individual fields, with AI actions available inline - choose whether the source column appears on the left or right in user settings > **Note: Excluded content types** > > Content types that are editable in [Page builder](https://doc.ibexa.co/en/saas/content_management/pages/page_builder_guide/index.md) or [Form builder](https://doc.ibexa.co/en/saas/content_management/forms/form_builder_guide/index.md) are excluded from side-by-side editing. > > Products are editable in the side-by-side view, but [product attributes aren't translatable](https://doc.ibexa.co/en/saas/product_catalog/products/#product-attributes). ### Translation review When a draft translation of a content item or product is created by going through the automatic translation process in the back office, the system creates a review status record and marks the draft as "For review". Editors can [accept or reject the translation](https://doc.ibexa.co/projects/userguide/en/6.0/content_management/translate_content/#review-automatic-translation) directly in the side-by-side view. Accepted drafts are marked as "Translated". When the editor rejects the translation, the status doesn't change, but the system records that the draft translation required corrections for statistical purposes. A draft translation in the "Translated" state can't be rejected anymore. The `ibexa_auto_translation_review` workflow is separate from the [editorial workflow](https://doc.ibexa.co/en/saas/content_management/workflow/workflow/index.md). Accepting or rejecting draft translations does not trigger editorial workflow transitions or notifications. > **Note: No review for human translations** > > Draft translations that were created by a human don't have a review status. ## Benefits ### Streamlined translation process Translations management reduces the time needed to create and publish multilingual content. Editors can initiate machine translation directly from the content editing interface and work on the result immediately in the side-by-side translation view, without having to switch contexts or use another translation tool. ### Better translation quality and consistency Machine-translated drafts are marked for review, allowing editors to accept or reject them directly in the side-by-side translation view. This eliminates the need for a separate workflow or tool. With the side-by-side translation view, editors can conveniently compare source and target content while editing. Seeing the translation in context makes it easier to identify omissions, inconsistencies, and translation errors. ### Flexible support for different translation providers Regardless of technical and conceptual differences, the experience of working with various translation providers is the same. Administrators can assign providers to specific language pairs and editors can override the assignment when needed. ### Readiness for automated processing The CLI command enables integration with automated processes, which can help you reduce manual effort for large content volumes. # Configure translations management > For the complete documentation index, see [llms.txt](https://doc.ibexa.co/en/saas/llms.txt). Configure translation providers, language pairs, and more for translations management. `ibexa/translations-management` extends Cohesivo's built-in language management tools that editors use for content item and product translation. It introduces a plugin that handles automatic translations through the translation provider system by connecting to REST APIs and AI services. By using the new [side-by-side editing interface](#side-by-side-translation-view), editors can compare source and target values, provide content item and product translations in a single view, and reject or approve translations. > **Note: Translation limitations** > > The following limitations apply to automatic translation: > > - Content types that contain the `ibexa_form` or `ibexa_landing_page` fields don't support the side-by-side translation view and open in the single-language editor instead. > - For `ibexa_landing_page` fields, translatable attributes of block content are sent to the translation provider, while layout, zones, and non-translatable block attributes are preserved. > - The value of `ibexa_form` field type is not translated. > > Also, [product attributes](https://doc.ibexa.co/en/saas/product_catalog/products/#product-attributes) remain non-translatable and are inactive in the side-by-side translation view. ## Configure translation providers Translation providers are the services that perform the actual text translation. If you fail to configure them, the automatic translation feature is disabled in the editor's UI, and a message is displayed that prompts the user to contact the administrator. The Translations management package comes with two types of translation services: - **REST API-based providers** - call a translation service such as Google Translate or DeepL directly by using an API key. - **AI-based providers** - send translation requests through the [AI Actions](https://doc.ibexa.co/en/saas/ai/ai_actions/configure_ai_actions/index.md) framework, relying on the same model selection and policy controls as other AI features in Cohesivo. > **Note: Prerequisites for the default translation providers** > > Before you can configure translation providers, you must meet the following prerequisites: > > - For the REST API-based translation providers, obtain API keys from the machine translation services and provide them in your instance's translation provider settings. > - For the AI-based translation providers, [configure AI Actions and the corresponding connectors](https://doc.ibexa.co/en/saas/ai/ai_actions/configure_ai_actions/index.md). Out of the box, Translations management can support the following translation providers: | Provider | Type | | ------------------ | ---------- | | Google Translate | REST API | | DeepL | REST API | | OpenAI | AI Actions | | Anthropic (Claude) | AI Actions | | Google Gemini | AI Actions | ### Built-in AI providers If you meet the above prerequisites, Translations management automatically provides AI Action Configurations for OpenAI (`auto_translate_openai`), Google Gemini (`auto_translate_gemini`), and Anthropic Claude (`auto_translate_anthropic`). You can use them directly in provider configuration: | Action Configuration identifier | Handler | Default model | | ------------------------------- | ------------------------ | -------------------------- | | `auto_translate_openai` | `openai-text-to-text` | `gpt-5` | | `auto_translate_gemini` | `gemini-text-to-text` | `gemini-pro-latest` | | `auto_translate_anthropic` | `anthropic-text-to-text` | `claude-sonnet-4-20250514` | You can then [customize these configurations in the UI](https://doc.ibexa.co/projects/userguide/en/6.0/ai_actions/work_with_ai_actions/#edit-existing-ai-actions). ### Add YAML configuration You configure the providers in the SiteAccess-aware `translations_management` namespace. ```yaml ibexa: system: default: translations_management: auto_translate: providers: google: apiKey: '%env(GOOGLE_TRANSLATE_API_KEY)%' deepl: apiKey: '%env(DEEPL_API_KEY)%' openai: actionConfigurationIdentifier: 'auto_translate_openai' anthropic: actionConfigurationIdentifier: 'auto_translate_anthropic' gemini: actionConfigurationIdentifier: 'auto_translate_gemini' ``` The `apiKey` values must reference the API key values configured for the tenant. The `actionConfigurationIdentifier` values must reference existing Action Configurations. If a value is missing or empty, the provider doesn't appear in the UI as a selectable option. #### Advanced translation provider options In addition to their required authentication keys, all providers support two optional ones: - `supportedLanguageCodes` - overrides the default list of language codes that this provider accepts - `languageCodesMap` - maps language codes used by Cohesivo, for example, `eng-GB`, to the provider-specific codes the API expects REST API-based providers come with their own language code lists and mappings, therefore both settings are optional. If configured, they replace the built-in defaults, so use them to restrict available languages or override mappings. AI-based providers don't provide built-in language code lists or mappings. If `supportedLanguageCodes` is not configured, all enabled languages are used, converted to POSIX format. If `languageCodesMap` is not configured, the system automatically tries to match Cohesivo language codes to the one supported by the provider by trying different format variants, for example, `eng-GB`, `en-GB`, or `en`. If no match is found, an `UnsupportedLanguageException` is thrown at runtime. Therefore, for AI-based providers, it's recommended that you explicitly configure both options. ```yaml ibexa: system: default: translations_management: auto_translate: providers: # ... openai: actionConfigurationIdentifier: 'auto_translate_openai' supportedLanguageCodes: - 'eng-GB' - 'ger-DE' - 'fre-FR' languageCodesMap: eng-GB: 'en' ger-DE: 'de' fre-FR: 'fr' ``` The `supportedLanguageCodes` setting controls which languages are available when creating [language pairs](#define-language-pairs) for this provider. > **Note: Identifier normalization** > > Provider identifiers are normalized from hyphens to underscores during configuration processing. Use one format consistently. If you mix `my-provider` and `my_provider` for the same provider, it results in an exception. ## Define language pairs Language pair definitions decide which provider handles each source-to-target language combination by default. For example, you can decide that English to French translations should use DeepL. When an editor [opens the translation modal](https://doc.ibexa.co/projects/userguide/en/6.0/content_management/translate_content/#add-new-translation) and selects a matching language combination, the provider that you chose is pre-selected in the dropdown. The editor can override the pre-selection. The list of languages available when creating a language pair is determined by what each provider supports. You can only select the languages that are present in a provider's [supported list](#advanced-translation-provider-options) for that provider's pairs. You [manage language pairs in the back office](https://doc.ibexa.co/projects/userguide/en/6.0/content_management/translate_content/#manage-translation-services-and-language-pairs). ## Side-by-side translation view The [side-by-side translation view](https://doc.ibexa.co/projects/userguide/en/6.0/content_management/translate_content/#side-by-side-translation-view) is a two-column content editing interface where the source column is read-only and the target column is an editable form. Content types that contain the `ibexa_landing_page` or `ibexa_form` fields can't be opened in the side-by-side translation view. Editors can open them in the standard single-language editor. > **Note: Meta fields** > > Fields marked with `meta: true` and fields that belong to groups listed in `admin_ui_forms.content_edit.meta_field_groups_list` aren't rendered in the side-by-side translation view. For a description of the side-by-side view and its functions from the editor's perspective, see [User Documentation](https://doc.ibexa.co/projects/userguide/en/6.0/content_management/translate_content/#side-by-side-translation-view). ### User settings The Translations management package adds preferences that editors can configure under their [user settings](https://doc.ibexa.co/projects/userguide/en/6.0/getting_started/get_started/#user-settings). Each editor can configure them independently, and they don't affect other users. For example, editors can choose whether the target language column appears on the left or right in the side-by-side translation view. By default, the target is on the right, and each editor can override this default. You can change the system-wide default in configuration: ```yaml parameters: ibexa.site_access.config.default.translations_management.default_side_by_side_column_order: source_right_target_left ``` The accepted values are `source_left_target_right` (default) and `source_right_target_left`. # Permissions # Permissions > For the complete documentation index, see [llms.txt](https://doc.ibexa.co/en/saas/llms.txt). Use granular permission system to grant access to various parts of the system by using roles, policies, and limitations. The permission system of Cohesivo enables you to control in detail which users have access to which parts of the system, both the back office's administrative and editorial features, and the content of the website front. - [Permission overview](https://ez-systems-developer-documentation--3403.com.readthedocs.build/en/3403/permissions/permission_overview/): The permission system is based on policies that you assign to users or user groups in the form of roles. - [Policies](https://ez-systems-developer-documentation--3403.com.readthedocs.build/en/3403/permissions/policies/): Policies are the main building block of the permissions system which lets you define the accesses for specific user roles. - [Permission use cases](https://ez-systems-developer-documentation--3403.com.readthedocs.build/en/3403/permissions/permission_use_cases/): Set up permission sets for common use cases. - [Limitations](https://ez-systems-developer-documentation--3403.com.readthedocs.build/en/3403/permissions/limitations/): Control access to parts of the system by fine-tuning permissions with the use of Limitations. # Permission overview > For the complete documentation index, see [llms.txt](https://doc.ibexa.co/en/saas/llms.txt). The permission system is based on policies that you assign to users or user groups in the form of roles. A new user doesn't have permissions for any part of the system, unless they're explicitly given access. To get access they need to inherit roles, typically assigned to the user group they belong to. Each role can contain one or more **Policies**. A policy is a rule that gives access to a single **function** in a **module**. For example, a `section/assign` policy allows the user to assign content to sections. When you add a policy to a role, you can also restrict it using one or more **Limitations**. A policy with a limitation only applies when the condition in the limitation is fulfilled. For example, a `content/publish` policy with a `ContentType` limitation on the "Blog Post" content type allows the user to publish only Blog Posts, and not other content. A limitation, like a policy, specifies what a user *can* do, not what they *can't do*. A `Section` limitation, for example, *gives* the user access to the selected section, not *prohibits* it. For more information, see [Limitation reference](https://doc.ibexa.co/en/saas/permissions/limitation_reference/index.md) and [Permission use cases](https://doc.ibexa.co/en/saas/permissions/permission_use_cases/index.md). ## Assigning roles to users Every user or user group can have many roles. A user can also belong to many groups, for example, Administrators, Editors, Subscribers. It's best practice to avoid assigning roles to users directly. Instead, try to organize your content so that it can be covered with general roles assigned to user groups. Using groups is easier to manage and more secure. It also improves system performance. The more role assignments and complex policies you add for a given user, the more complex the search/load queries are, because they always take permissions into account. # Permission use cases > For the complete documentation index, see [llms.txt](https://doc.ibexa.co/en/saas/llms.txt). Set up permission sets for common use cases. Here are a few examples of sets of policies that you can use to get some common permission configurations. ## Enter back office To allow the user to enter the back office interface and view all content, set the following policies: - `user/login` - `content/read` - `content/versionread` - `section/view` - `content/reverserelatedlist` These policies are necessary for all other cases below that require access to the content structure. ## Create content without publishing You can use this option together with Cohesivo's content review options. Users assigned with these policies can create content, but cannot publish it. To publish, they must send the content for review to another User with proper permissions (for example, senior editor or proofreader). - `content/create` - `content/edit` ## Create and publish content To create and publish content, users must additionally have the following policies: - `content/create` - `content/edit` - `content/publish` This also lets the user copy and move content, and add new locations to a content item (but not remove them). ## Move content To move a content item or a subtree to another location, the user must have the following policies: - `content/read` - on the source location - `content/create` - on the target location ## Remove content To send content to Trash, the user needs to have the `content/remove` policy. If content has more than one language, the user must have access to all the languages. That is, the `content/remove` policy must have either no limitation, or a limitation for all languages of the content item. To remove an archived version of content, the user must have the `content/versionremove` policy. Further manipulation of Trash requires the `content/restore` policy to restore items from Trash, and `content/cleantrash` to completely delete all content from the Trash. > **Caution: Caution** > > With the `content/cleantrash` policy, the user can empty the Trash even if they don't have access to the trashed content, for example, because it belonged to a Section that the user doesn't have permissions for. ## Restrict editing to part of the tree If you want to let the User create or edit content, but only in one part of the content tree, use limitations. Three limitations that you could use here are `Section` limitation, `Location` limitation and `Subtree of Location` limitation. ### Section limitation Let's assume you have two Folders under your Home: Blog and Articles. You can let a user create content for the blogs, but not in Articles, by adding a `Section` limitation to the Blog content item. This allows the User to publish content anywhere under this location in the structure. Section doesn't have to belong to the same subtree of location in the content structure, any locations can be assigned to it. ### Location limitation If you add a `Location` limitation and point to the same location, the user is able to publish content directly under the selected location, but not anywhere deeper in its subtree of location. ### Subtree of location limitation To limit the user's access to a subtree, use the `Subtree of Location` limitation. You do it by creating two new roles for a user group: 1. Role with a `Subtree` limitation for the User 2. Role with a `Location` limitation for the subtree Follow the example below to learn how to do that. **Cookbook**, **Dinner recipes** and **Dessert recipes** containers aren't accessible in the frontend. Edit access to them in the **Admin** panel. ![Subtree file structure](https://doc.ibexa.co/en/saas/permissions/img/subtree_usability_notes_1.png) To give the vegetarian editors access only to the **Vegetarian** dinner recipes section, create a new role, for example, *EditorVeg*. Next, add to it a `content/read` policy with the `Subtree` limitation for `Cookbook/Dinner recipes/Vegetarian`. Assign the role to the vegetarian editors user group. It allows users from that group to access the **Vegetarian** container but not **Cookbook** and **Dinner recipes**. To give users access to **Cookbook** and **Dinner recipes** containers, create a new role, for example, *EditorVegAccess*. Next, add to it a `content/read` policy with the `Location` limitations **Cookbook** and **Dinner recipes**. Assign the new role to the vegetarian editors user group as well. Only then the limitations are combined with `AND`, resulting in an empty set. The vegetarian editors should now see the following content tree: ![Limited subtree file structure](https://doc.ibexa.co/en/saas/permissions/img/subtree_usability_notes_2.png) When a policy has more than one limitation, all of them have to apply, or the policy doesn't work. For example, a `Location` limitation on location `1/2` and `Subtree of Location` limitation on `1/2/55` cannot work together, because no location can satisfy both those requirements at the same time. To combine more than one limitation with the *or* relation, not *and*, you can split your policy in two, each with one of these limitations. ## Manage locations To add a new location to a content item, the policies required for publishing content are enough. To allow the user to remove a location, grant them the following policies: - `content/remove` - `content/manage_locations` Hiding and revealing location requires one more policy: `content/hide`. ## Editorial workflows You can control which stages in an editorial workflow the user can work with. Do this by adding the `WorkflowStageLimitation` to `content` policies such as `content/edit` or `content/publish`. You can also control which transitions the user can pass content through. Do this by using the `workflow/change_stage` policy together with the `WorkflowTransitionLimitation`. For example, to enable the user to edit only content in the "Design" stage and to pass it after creating design to the "Proofread stage", use following permissions: - `content/edit` with `WorkflowStageLimitation` set to "Design". - `workflow/change_stage` with `WorkflowTransitionLimitation` set to `to_proofreading` ## Multi-file upload Creating content through multi-file upload is treated in the same way as regular creation. To enable upload, you need you set the following permissions: - `content/create` - `content/read` - `content/publish` You can control what content items can be uploaded and where by using imitations on the `content/create` and `content/publish` policies. A location limitation limits the uploading to a specific location in the tree. A content type limitation controls the content types that are allowed. For example, you can set the location limitation on a **Pictures** Folder, and add a content type limitation that only allows content items of type **Image**. This ensures that only files of type `image` can be uploaded, and only to the **Pictures** Folder. ## Taxonomies You can control which users or user groups can work with taxonomies. To let users create and assign taxonomy entries, set the following permissions: - `taxonomy/assign` to allow user to tag and untag content - `taxonomy/read` to see the Taxonomy interface - `taxonomy/manage` to create, edit and delete tags With limitations, you can configure whether permissions apply to Tags, product categories, or both. ## Register users To allow anonymous users to register through the `/register` route, grant the `user/register` policy to the Anonymous user group. ## Admin To access the [administration panel](https://doc.ibexa.co/en/saas/administration/admin_panel/admin_panel/index.md) in the back office, the User must have the `setup/administrate` policy. This allows the User to view the languages and content types. Additional policies are needed for each section of the Admin. ### System Information - `setup/system_info` to view the System Information tab ### Sections - `section/view` to see and access the section list - `section/edit` to add and edit sections - `section/assign` to assign sections to content ### Languages - `content/translations` to add and edit languages ### Content types/action - `content type/create`, `content type/update`, `content type/delete` to add, modify and remove content types ### Object states - `state/administrate` to view a list of object states, add and edit them - `state/assign` to assign Objects states to content ### Roles - `role/read` to view the list of roles in Admin - `role/create`, `role/update`, `role/assign` and `role/delete` to manage roles ### Users - `content/view` to view the list of users Users are treated like other content, so to create and modify them, the user needs to have the same permissions as for managing other content items. ## Product catalog You can control to what extend users can access the product catalog and all its related parts. ### Product type To create or edit product types, a user needs to have access to attributes and attribute groups. Set the following permissions to allow such access: - `product_type/create` - `product_type/view` - `product_type/edit` ### Product item When a product is created, a product item and a content item are also generated. Permissions for the product catalog override permissions for content, therefore, users without permissions for content can still manage products. - `product/create` - `product/view` - `product/edit` # Policies > For the complete documentation index, see [llms.txt](https://doc.ibexa.co/en/saas/llms.txt). Policies are the main building block of the permissions system which lets you define the accesses for specific user roles. Policies are the main building block of the permissions system. Each role you assign to user or user group consists of policies which define, which parts of the application or website the user has access to. ## Available policies ### Access to all functions | Module | Function | Effect | Possible limitations | | ------ | -------- | ----------------------------------------------------------- | -------------------- | | `*` | `*` | all modules, all functions: grant all available permissions | | > **Tip: Tip** > > For each module, all functions can be given without limitation. For example, `content/*` gives access to all functions of the `content` module, even future ones. ### Administration and user management #### Activity log | Module | Function | Effect | Possible Limitations | | -------------- | -------- | -------------------- | ---------------------------------------------------------------------------------------------------------------- | | `activity_log` | `read` | access activity list | [ActivityLogOwner](https://doc.ibexa.co/en/saas/permissions/limitation_reference/#activity-log-owner-limitation) | #### AI actions | Module | Function | Effect | Possible Limitations | | ---------------------- | --------- | ---------------------- | -------------------- | | `action_configuration` | `view` | view AI Action | | | | `create` | create a new AI action | | | | `edit` | edit an AI action | | | | `delete` | delete an AI action | | | | `execute` | execute an AI action | | #### Customer groups | Module | Function | Effect | Possible limitations | | ---------------- | -------- | ----------------------- | -------------------- | | `customer_group` | `create` | create a customer group | | | | `delete` | delete a customer group | | | | `edit` | edit a customer group | | | | `view` | view customer groups | | #### Roles | Module | Function | Effect | Possible limitations | | ------ | -------- | -------------------------------------------------------------------------- | -------------------- | | `role` | `assign` | assign roles to users and user groups | | | | `create` | create new roles | | | | `delete` | delete roles | | | | `read` | view the roles list in Admin. Required for all other role-related policies | | | | `update` | modify existing roles | | #### Segments | Module | Function | Effect | Possible limitations | | --------- | ---------------- | ------------------------ | -------------------------------------------------------------------------------------------------------- | | `segment` | `assign_to_user` | assign segments to users | [Segment Group](https://doc.ibexa.co/en/saas/permissions/limitation_reference/#segment-group-limitation) | | | `create` | create segments | [Segment Group](https://doc.ibexa.co/en/saas/permissions/limitation_reference/#segment-group-limitation) | | | `read` | load segment information | [Segment Group](https://doc.ibexa.co/en/saas/permissions/limitation_reference/#segment-group-limitation) | | | `remove` | remove segments | [Segment Group](https://doc.ibexa.co/en/saas/permissions/limitation_reference/#segment-group-limitation) | | | `update` | update segments | [Segment Group](https://doc.ibexa.co/en/saas/permissions/limitation_reference/#segment-group-limitation) | #### Segment groups | Module | Function | Effect | Possible limitations | | --------------- | -------- | ------------------------------ | -------------------- | | `segment_group` | `create` | create segment groups | | | | `read` | load segment group information | | | | `remove` | remove segment groups | | | | `update` | update segment groups | | #### Setup | Module | Function | Effect | Possible limitations | | ------- | -------------- | -------------------------------------------- | -------------------- | | `setup` | `administrate` | access Admin | | | | `install` | unused | | | | `setup` | unused | | | | `system_info` | view the **System Information** tab in Admin | | #### Sites | Module | Function | Effect | Possible limitations | | ------ | --------------- | ---------------------------------------------------------------------------------------- | -------------------- | | `site` | `change_status` | change status of the public accesses of sites to `Live` or `Offline` in the Site Factory | | | | `create` | create sites in the Site Factory | | | | `delete` | delete sites from the Site Factory | | | | `edit` | edit sites in the Site Factory | | | | `update` | update sites in the Site Factory | | | | `view` | view the "Sites" in the top navigation | | #### Users | Module | Function | Effect | Possible limitations | | ------ | ------------- | ------------------------------------------------ | -------------------- | | `user` | `activation` | unused | | | | `invite` | create and send invitations to create an account | | | | `login` | log in to the application | | | | `password` | unused | | | | `preferences` | access and set user preferences | | | | `register` | register using the `/register` route | | | | `selfedit` | unused | | ### Content management #### Content | Module | Function | Effect | Possible limitations | | --------- | -------------------- | --------------------------------------------------------------------------------------------------------------------------------------- | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | | `content` | `cleantrash` | empty the Trash (even when the User doesn't have access to individual content items) | | | | `create` | create new content. Note: even without this policy the user is able to enter edit mode, but cannot finalize work with the content item. | [Content type](https://doc.ibexa.co/en/saas/permissions/limitation_reference/#content-type-limitation) [Section](https://doc.ibexa.co/en/saas/permissions/limitation_reference/#section-limitation) [Location](https://doc.ibexa.co/en/saas/permissions/limitation_reference/#location-limitation) [Subtree](https://doc.ibexa.co/en/saas/permissions/limitation_reference/#subtree-limitation) [Language](https://doc.ibexa.co/en/saas/permissions/limitation_reference/#language-limitation) [Owner of Parent](https://doc.ibexa.co/en/saas/permissions/limitation_reference/#owner-of-parent-limitation) [Content type Group of Parent](https://doc.ibexa.co/en/saas/permissions/limitation_reference/#content-type-group-of-parent-limitation) [Content type of Parent](https://doc.ibexa.co/en/saas/permissions/limitation_reference/#content-type-of-parent-limitation) [Parent Depth](https://doc.ibexa.co/en/saas/permissions/limitation_reference/#parent-depth-limitation) [Field Group](https://doc.ibexa.co/en/saas/permissions/limitation_reference/#field-group-limitation) [Change Owner](https://doc.ibexa.co/en/saas/permissions/limitation_reference/#change-owner-limitation) | | | `diff` | unused | | | | `edit` | edit existing content | [Content type](https://doc.ibexa.co/en/saas/permissions/limitation_reference/#content-type-limitation) [Section](https://doc.ibexa.co/en/saas/permissions/limitation_reference/#section-limitation) [Owner](https://doc.ibexa.co/en/saas/permissions/limitation_reference/#owner-limitation) [Content type Group](https://doc.ibexa.co/en/saas/permissions/limitation_reference/#content-type-group-limitation) [Location](https://doc.ibexa.co/en/saas/permissions/limitation_reference/#location-limitation) [Subtree](https://doc.ibexa.co/en/saas/permissions/limitation_reference/#subtree-limitation) [Language](https://doc.ibexa.co/en/saas/permissions/limitation_reference/#language-limitation) [Object State](https://doc.ibexa.co/en/saas/permissions/limitation_reference/#object-state-limitation) [Workflow Stage](https://doc.ibexa.co/en/saas/permissions/limitation_reference/#workflow-stage-limitation) [Field Group](https://doc.ibexa.co/en/saas/permissions/limitation_reference/#field-group-limitation) [Version Lock](https://doc.ibexa.co/en/saas/permissions/limitation_reference/#version-lock-limitation) [Change Owner](https://doc.ibexa.co/en/saas/permissions/limitation_reference/#change-owner-limitation) | | | `hide` | hide and reveal content locations | [Content type](https://doc.ibexa.co/en/saas/permissions/limitation_reference/#content-type-limitation) [Section](https://doc.ibexa.co/en/saas/permissions/limitation_reference/#section-limitation) [Owner](https://doc.ibexa.co/en/saas/permissions/limitation_reference/#owner-limitation) [Content type Group](https://doc.ibexa.co/en/saas/permissions/limitation_reference/#content-type-group-limitation) [Location](https://doc.ibexa.co/en/saas/permissions/limitation_reference/#location-limitation) [Subtree](https://doc.ibexa.co/en/saas/permissions/limitation_reference/#subtree-limitation) [Language](https://doc.ibexa.co/en/saas/permissions/limitation_reference/#language-limitation) | | | `manage_locations` | remove locations and send content to Trash | [Content type](https://doc.ibexa.co/en/saas/permissions/limitation_reference/#content-type-limitation) [Section](https://doc.ibexa.co/en/saas/permissions/limitation_reference/#section-limitation) [Owner](https://doc.ibexa.co/en/saas/permissions/limitation_reference/#owner-limitation) [Subtree](https://doc.ibexa.co/en/saas/permissions/limitation_reference/#subtree-limitation) [Object State](https://doc.ibexa.co/en/saas/permissions/limitation_reference/#object-state-limitation) | | | `pendinglist` | unused | | | | `publish` | publish content. Without this Policy, the User can only save drafts or send them for review | [Content type](https://doc.ibexa.co/en/saas/permissions/limitation_reference/#content-type-limitation) [Section](https://doc.ibexa.co/en/saas/permissions/limitation_reference/#section-limitation) [Owner](https://doc.ibexa.co/en/saas/permissions/limitation_reference/#owner-limitation) [Content type Group](https://doc.ibexa.co/en/saas/permissions/limitation_reference/#content-type-group-limitation) [Location](https://doc.ibexa.co/en/saas/permissions/limitation_reference/#location-limitation) [Subtree](https://doc.ibexa.co/en/saas/permissions/limitation_reference/#subtree-limitation) [Language](https://doc.ibexa.co/en/saas/permissions/limitation_reference/#language-limitation) [Object State](https://doc.ibexa.co/en/saas/permissions/limitation_reference/#object-state-limitation) [Workflow Stage](https://doc.ibexa.co/en/saas/permissions/limitation_reference/#workflow-stage-limitation) | | | `read` | view the content both in front and back end | [Content type](https://doc.ibexa.co/en/saas/permissions/limitation_reference/#content-type-limitation) [Section](https://doc.ibexa.co/en/saas/permissions/limitation_reference/#section-limitation) [Owner](https://doc.ibexa.co/en/saas/permissions/limitation_reference/#owner-limitation) [Content type Group](https://doc.ibexa.co/en/saas/permissions/limitation_reference/#content-type-group-limitation) [Location](https://doc.ibexa.co/en/saas/permissions/limitation_reference/#location-limitation) [Subtree](https://doc.ibexa.co/en/saas/permissions/limitation_reference/#subtree-limitation) [Object State](https://doc.ibexa.co/en/saas/permissions/limitation_reference/#object-state-limitation) | | | `remove` | remove locations and send content to Trash | [Content type](https://doc.ibexa.co/en/saas/permissions/limitation_reference/#content-type-limitation) [Section](https://doc.ibexa.co/en/saas/permissions/limitation_reference/#section-limitation) [Owner](https://doc.ibexa.co/en/saas/permissions/limitation_reference/#owner-limitation) [Location](https://doc.ibexa.co/en/saas/permissions/limitation_reference/#location-limitation) [Subtree](https://doc.ibexa.co/en/saas/permissions/limitation_reference/#subtree-limitation) [Object State](https://doc.ibexa.co/en/saas/permissions/limitation_reference/#object-state-limitation) [Language](https://doc.ibexa.co/en/saas/permissions/limitation_reference/#language-limitation) | | | `restore` | restore content from Trash | | | | `reverserelatedlist` | see all content that a content item relates to (even when the User isn't allowed to view it as an individual content items) | [Content type](https://doc.ibexa.co/en/saas/permissions/limitation_reference/#content-type-limitation) [Section](https://doc.ibexa.co/en/saas/permissions/limitation_reference/#section-limitation) | | | `translate` | unused | [Content type](https://doc.ibexa.co/en/saas/permissions/limitation_reference/#content-type-limitation) [Section](https://doc.ibexa.co/en/saas/permissions/limitation_reference/#section-limitation) [Owner](https://doc.ibexa.co/en/saas/permissions/limitation_reference/#owner-limitation) [Location](https://doc.ibexa.co/en/saas/permissions/limitation_reference/#location-limitation) [Subtree](https://doc.ibexa.co/en/saas/permissions/limitation_reference/#subtree-limitation) [Language](https://doc.ibexa.co/en/saas/permissions/limitation_reference/#language-limitation) | | | `translations` | manage the language list in Admin | | | | `unlock` | unlock drafts locked to a user for performing actions | [Owner](https://doc.ibexa.co/en/saas/permissions/limitation_reference/#owner-limitation) [Content type Group](https://doc.ibexa.co/en/saas/permissions/limitation_reference/#content-type-group-limitation) [Subtree](https://doc.ibexa.co/en/saas/permissions/limitation_reference/#subtree-limitation) [Language](https://doc.ibexa.co/en/saas/permissions/limitation_reference/#language-limitation) [Version Lock](https://doc.ibexa.co/en/saas/permissions/limitation_reference/#version-lock-limitation) | | | `urltranslator` | manage URL aliases of a content item | | | | `versionread` | view content after publishing, and to preview any content in the Site mode | [Content type](https://doc.ibexa.co/en/saas/permissions/limitation_reference/#content-type-limitation) [Section](https://doc.ibexa.co/en/saas/permissions/limitation_reference/#section-limitation) [Owner](https://doc.ibexa.co/en/saas/permissions/limitation_reference/#owner-limitation) Status [Location](https://doc.ibexa.co/en/saas/permissions/limitation_reference/#location-limitation) [Subtree](https://doc.ibexa.co/en/saas/permissions/limitation_reference/#subtree-limitation) [Object State](https://doc.ibexa.co/en/saas/permissions/limitation_reference/#object-state-limitation) | | | `versionremove` | remove archived content versions | [Content type](https://doc.ibexa.co/en/saas/permissions/limitation_reference/#content-type-limitation) [Section](https://doc.ibexa.co/en/saas/permissions/limitation_reference/#section-limitation) [Owner](https://doc.ibexa.co/en/saas/permissions/limitation_reference/#owner-limitation) Status [Location](https://doc.ibexa.co/en/saas/permissions/limitation_reference/#location-limitation) [Subtree](https://doc.ibexa.co/en/saas/permissions/limitation_reference/#subtree-limitation) [Object State](https://doc.ibexa.co/en/saas/permissions/limitation_reference/#object-state-limitation) | | | `view_embed` | view content embedded in another content item (even when the User isn't allowed to view it as an individual content item) | [Content type](https://doc.ibexa.co/en/saas/permissions/limitation_reference/#content-type-limitation) [Section](https://doc.ibexa.co/en/saas/permissions/limitation_reference/#section-limitation) [Owner](https://doc.ibexa.co/en/saas/permissions/limitation_reference/#owner-limitation) [Location](https://doc.ibexa.co/en/saas/permissions/limitation_reference/#location-limitation) [Subtree](https://doc.ibexa.co/en/saas/permissions/limitation_reference/#subtree-limitation) | #### Content types | Module | Function | Effect | Possible limitations | | ------- | -------- | ------------------------------------------------------------------------ | -------------------- | | `class` | `create` | create new content types. Also required to edit exiting content types | | | | `delete` | delete content types | | | | `update` | modify existing content types. Also required to create new content types | | #### Sections | Module | Function | Effect | Possible limitations | | --------- | -------- | -------------------------------------------------------------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | | `section` | `assign` | assign Sections to content | [content type](https://doc.ibexa.co/en/saas/permissions/limitation_reference/#content-type-limitation) [Section](https://doc.ibexa.co/en/saas/permissions/limitation_reference/#section-limitation) [Owner](https://doc.ibexa.co/en/saas/permissions/limitation_reference/#owner-limitation) [New Section](https://doc.ibexa.co/en/saas/permissions/limitation_reference/#new-section-limitation) | | | `edit` | edit existing Sections and create new ones | | | | `view` | view the Sections list in Admin. Required for all other section-related policies | | #### Object States | Module | Function | Effect | Possible limitations | | ------- | -------------- | ------------------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | | `state` | `assign` | assign object states to content items | [Content type](https://doc.ibexa.co/en/saas/permissions/limitation_reference/#content-type-limitation) [Section](https://doc.ibexa.co/en/saas/permissions/limitation_reference/#section-limitation) [Owner](https://doc.ibexa.co/en/saas/permissions/limitation_reference/#owner-limitation) [Content type Group](https://doc.ibexa.co/en/saas/permissions/limitation_reference/#content-type-group-limitation) [Location](https://doc.ibexa.co/en/saas/permissions/limitation_reference/#location-limitation) [Subtree](https://doc.ibexa.co/en/saas/permissions/limitation_reference/#subtree-limitation) [Object State](https://doc.ibexa.co/en/saas/permissions/limitation_reference/#object-state-limitation) [New State](https://doc.ibexa.co/en/saas/permissions/limitation_reference/#new-state-limitation) | | | `administrate` | view, add and edit object states | | #### Taxonomy | Module | Function | Effect | Possible limitations | | ---------- | -------- | ----------------------------- | -------------------- | | `taxonomy` | `assign` | tag or untag content | | | | `manage` | create, edit, and delete tags | | | | `read` | view the Taxonomy interface | | #### Workflow and version comparison | Module | Function | Effect | Possible limitations | | ------------ | -------------- | -------------------------------------- | -------------------------------------------------------------------------------------------------------------------- | | `comparison` | `view` | view version comparison | | | `workflow` | `change_stage` | change stage in the specified workflow | [Workflow Transition](https://doc.ibexa.co/en/saas/permissions/limitation_reference/#workflow-transition-limitation) | ### Product catalog #### Catalogs | Module | Function | Effect | Possible limitations | | --------- | -------- | ---------------- | -------------------- | | `catalog` | `create` | create a catalog | | | | `delete` | delete a catalog | | | | `edit` | edit a catalog | | | | `view` | view catalogs | | #### Currencies and regions | Module | Function | Effect | Possible limitations | | ---------- | ---------- | ----------------- | -------------------- | | `commerce` | `currency` | manage currencies | | | | `region` | manage regions | | #### Products | Module | Function | Effect | Possible limitations | | --------- | -------- | ------------------------------------------- | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | | `product` | `create` | create a product | [Product Type](https://doc.ibexa.co/en/saas/permissions/limitation_reference/#product-type-limitation) [Language](https://doc.ibexa.co/en/saas/permissions/limitation_reference/#language-limitation) | | | `delete` | delete a product | [Product Type](https://doc.ibexa.co/en/saas/permissions/limitation_reference/#product-type-limitation) | | | `edit` | edit a product | [Product Type](https://doc.ibexa.co/en/saas/permissions/limitation_reference/#product-type-limitation) [Language](https://doc.ibexa.co/en/saas/permissions/limitation_reference/#language-limitation) | | | `view` | view products listed in the product catalog | [Product Type](https://doc.ibexa.co/en/saas/permissions/limitation_reference/#product-type-limitation) | > **Caution: Caution** > > The `ProductType` limitation can't be used when using [Quable](https://doc.ibexa.co/en/saas/product_catalog/quable/quable/index.md). #### Product types | Module | Function | Effect | Possible limitations | | -------------- | -------- | ---------------------------------------------------------------------------------------------------------------- | ------------------------------------------------------------------------------------------------------ | | `product_type` | `create` | create a product type, a new attribute, a new attribute group, and add translation to product type and attribute | [Product Type](https://doc.ibexa.co/en/saas/permissions/limitation_reference/#product-type-limitation) | | | `delete` | delete a product type, attribute, attribute group | | | | `edit` | edit a product type, attribute, attribute group | [Product Type](https://doc.ibexa.co/en/saas/permissions/limitation_reference/#product-type-limitation) | | | `view` | view product types, attributes and attribute groups | | > **Caution: Caution** > > The `ProductType` limitation can't be used when using [Quable](https://doc.ibexa.co/en/saas/product_catalog/quable/quable/index.md). ## Combining policies Policies on one role are connected with the *and* relation, not *or*, so when policy has more than one limitation, all of them have to apply. If you want to combine more than one limitation with the *or* relation, not *and*, you can split your policy in two, each with one of these limitations. # Limitations > For the complete documentation index, see [llms.txt](https://doc.ibexa.co/en/saas/llms.txt). Control access to parts of the system by fine-tuning permissions with the use of Limitations. Limitations are part of the permissions system. They limit the access granted to users by [policies](https://doc.ibexa.co/en/saas/permissions/permission_overview/index.md). While a policy grants the user access to a function, Limitations narrow it down by different criteria. Limitations consist of two parts: - `Limitation` (Value) - `LimitationType` Certain limitations also serve as role limitations, which means they can be used to limit the rights of a role assignment. Currently, this covers [subtree of location](https://doc.ibexa.co/en/saas/permissions/limitation_reference/#subtree-limitation) and [Section](https://doc.ibexa.co/en/saas/permissions/limitation_reference/#section-limitation). `Limitation` represents the value, while `LimitationType` deals with the business logic surrounding how it actually works and is enforced. `LimitationTypes` have two modes of operation in regard to permission logic (see `Ibexa\Contracts\Core\Limitation` interface for more info): | Method | Use | | -------------- | --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | | `evaluate` | Evaluates if the User has access to a given object in a certain context (for instance the context can be locations when the object is `Content`), under the condition of the `Limitation` value(s). | | `getCriterion` | Generates a `Criterion` based on `Limitation` value and current user which `SearchService` by default applies to Search Criteria for filtering search based on permissions. | ## Limitation reference See [Limitation reference](https://doc.ibexa.co/en/saas/permissions/limitation_reference/index.md) for detailed information about individual limitations. # Limitation reference > For the complete documentation index, see [llms.txt](https://doc.ibexa.co/en/saas/llms.txt). Limitations let you fine-tune the permission system by specifying limits to roles granted to users. ## Blocking limitation A generic limitation type to use when no other limitation has been implemented. Without any limitation assigned, a `LimitationNotFoundException` is thrown. It's called "blocking" because it always informs the permissions system that the user doesn't have access to any policy the limitation is assigned to, making the permissions system move on to the next policy. ### Possible values | Value | UI value | Description | | --------- | --------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------ | | `` | `` | This is a generic limitation which doesn't validate the values provided to it. Make sure that you validate the values passed to this limitation in your own logic. | ### Configuration As this is a generic limitation, you can configure your custom limitations to use it. Out of the box FunctionList uses it in the following way: ```yaml # FunctionList is an ezjscore limitation, it only applies to ezjscore policies not used by # API/platform stack, so configure to use Blocking limitation to avoid LimitationNotFoundException ibexa.api.role.limitation_type.function_list: class: Ibexa\Core\Limitation\BlockingLimitationType arguments: ['FunctionList'] tags: - {name: ibexa.permissions.limitation_type, alias: FunctionList} ``` ## Activity log Owner limitation The Activity log Owner (`ActivityLogOwner`) limitation specifies if a user can see only their own [recent activity](https://doc.ibexa.co/en/saas/administration/recent_activity/recent_activity/index.md) log entries, and not entries from other users. | Value | UI value | Description | | ----- | --------------- | ------------------------------------------------------------ | | `1` | "Only own logs" | Current user can only access their own activity log entries. | ## Change Owner limitation The Change Owner (`ChangeOwner`) limitation specifies whether the user can change the owner of a content item. ### Possible values | Value | UI value | Description | | ----- | -------- | ---------------------------------------------- | | `1` | "Forbid" | The user cannot change owner of a content item | ## Content type Group limitation The Content Type Group (`UserGroup`) limitation specifies that only users with at least one common *direct* user group with the owner of content get the selected access right. ### Possible values | Value | UI value | Description | | ----- | -------- | -------------------------------------------------------------------------------------- | | `1` | "self" | Only a user who has at least one common *direct* user group with the owner gets access | ## Content type Group of Parent limitation The Content Type Group of Parent (`ParentUserGroupLimitation`) limitation specifies that only Users with at least one common *direct* user group with the owner of the parent location of a content item get a certain access right, used by `content/create` permission. ### Possible values | Value | UI value | Description | | ----- | -------- | --------------------------------------------------------------------------------------------------------- | | `1` | "self" | Only a user who has at least one common *direct* user group with owner of the parent location gets access | ## Content type limitation The Content Type (`ContentType`) limitation specifies whether the user has access to content with a specific content type. ### Possible values | Value | UI value | Description | | ------------------ | -------------------- | ------------------------------------------------- | | `` | `` | All valid content type IDs can be set as value(s) | ## Content type of Parent limitation The Content Type of Parent (`ParentContentType`) limitation specifies whether the user has access to content whose parent location contains a specific content type, used by `content/create`. This limitation combined with `ContentType` limitation allows you to define business rules like allowing users to create "Blog Post" within a "Blog." If you also combine it with `Owner of Parent` limitation, you effectively limit access to create Blog Posts in the users' own Blogs. ### Possible values | Value | UI value | Description | | ------------------ | -------------------- | ------------------------------------------------- | | `` | `` | All valid content type IDs can be set as value(s) | ## Field Group limitation A Field Group (`FieldGroup`) limitation specifies whether the user can work with content fields belonging to a specific group. A user with this limitation is allowed to edit fields belonging to the indicated group. Otherwise, the fields are inactive and filled with the default value (if set). ### Possible values | Value | UI value | Description | | ------------------------- | ------------------------- | -------------------------------------------------------- | | `` | `` | All valid field group identifiers can be set as value(s) | ## Language limitation A Language (`Language`) limitation specifies whether the user has access to work on the specified translation. A user with this limitation is allowed to: - Create new content with the given translation(s) only. This only applies to creating the first version of a content item. - Edit content by adding a new translation or modifying an existing translation. - Publish content only when it results in adding or modifying an allowed translation. - Delete content only when it contains a translation into the specified language. ### Possible values | Value | UI value | Description | | ----------------- | --------------------- | ----------------------------------------------- | | `` | `` | All valid language codes can be set as value(s) | ## Location limitation A location (`Location`) limitation specifies whether the user has access to content with a specific location, in case of `content/create` the parent location is evaluated. ### Possible values | Value | UI value | Description | | --------------- | ----------------- | --------------------------------------------- | | `` | `` | All valid location IDs can be set as value(s) | ## New Section limitation A New Section (`NewSection`) limitation specifies whether the user has access to assigning content to a given section. In the `section/assign` policy you can combine this with section limitation to limit both from and to values. ### Possible values | Value | UI value | Description | | -------------- | ---------------- | -------------------------------------------- | | `` | `` | All valid session IDs can be set as value(s) | ## New State limitation A New State (`NewObjectState`) limitation specifies whether the user has access to (assigning) a given object state to content. In the `state/assign` policy you can combine this with State limitation to limit both from and to values. ### Possible values | Value | UI value | Description | | ------------ | -------------- | ------------------------------------------ | | `` | `` | All valid state IDs can be set as value(s) | ## Object State limitation The Object State (`ObjectState`) limitation specifies whether the user has access to content with a specific object state. ### Possible values | Value | UI value | Description | | ------------------ | -------------------- | ------------------------------------------------- | | `` | `` | All valid Object state IDs can be set as value(s) | ## Owner limitation The Owner (`Owner`) limitation specifies that only the owner of the content item gets the selected access right. ### Possible values | Value | UI value | Description | | ----- | --------- | ----------------------------------------------------------------------------------------------------- | | `1` | "self" | Only the user who is the owner gets access | | `2` | "session" | Deprecated and works exactly like "self" in public PHP API since it has no knowledge of user Sessions | ## Owner of Parent limitation The Owner of Parent (`ParentOwner`) limitation specifies that only the users who own all parent locations of a content item get a certain access right, used for `content/create` permission. ### Possible values | Value | UI value | Description | | ----- | --------- | ----------------------------------------------------------------------------------------------------- | | `1` | "self" | Only the user who is the owner of all parent locations gets access | | `2` | "session" | Deprecated and works exactly like "self" in public PHP API since it has no knowledge of user Sessions | ## Parent Depth limitation The Parent Depth (`ParentDepth`) limitation specifies whether the user has access to creating content under a parent location within a specific depth of the tree, used for `content/create` permission. ### Possible values | Value | UI value | Description | | ------- | -------- | ----------------------------------------- | | `` | `` | All valid integers can be set as value(s) | ## Product Type limitation The Product Type (`ProductType`) limitation specifies whether the user has access to products belonging to a specific product type. > **Caution: Caution** > > The `ProductType` limitation can't be used when using [Quable](https://doc.ibexa.co/en/saas/product_catalog/quable/quable/index.md). ### Possible values | Value | UI value | Description | | ------------------ | -------------------- | ------------------------------------------------- | | `` | `` | All valid content type IDs can be set as value(s) | ## Section limitation The Section (`Section`) limitation specifies whether the user has access to content within a specific section. This limitation can be used as a role limitation. ### Possible values | Value | UI value | Description | | -------------- | ---------------- | -------------------------------------------- | | `` | `` | All valid session IDs can be set as value(s) | ## Segment group limitation The segment group (`SegmentGroup`) limitation specifies whether the user has access segments within a specific segment group. This limitation can be used as a role limitation. ### Possible values | Value | UI value | Description | | -------------------- | ---------------------- | --------------------------------------------------- | | `` | `` | All valid segment group IDs can be set as value(s). | ## SiteAccess limitation The SiteAccess (`SiteAccess`) limitation specifies to which SiteAccesses a certain permission applies, used by `user/login`. ### Possible values | Value | UI value | Description | | ------------------- | ------------------- | -------------------------------------------------------------------------------------------------------------------- | | `` | `` | Hash is calculated in the following way in legacy in default 64bit mode: `sprintf( '%u', crc32( $siteAccessName ) )` | ### Legacy compatibility notes `SiteAccess` limitation is deprecated and isn't used actively in public PHP API, but is allowed for being able to read / create limitations for legacy. ## Subtree limitation The subtree (`Subtree`) limitation specifies whether the user has access to content within a specific subtree of location, in case of `content/create` the parent subtree of location is evaluated. This limitation can be used as a role limitation. ### Possible values | Value | UI value | Description | | ----------------------- | ----------------- | ------------------------------------------------------- | | `` | `` | All valid location `pathStrings` can be set as value(s) | ### Usage notes For more information on how to restrict user's access to part of the subtree, see [the example in the Admin management section](https://doc.ibexa.co/en/saas/permissions/permission_use_cases/#restrict-editing-to-part-of-the-tree). ## Taxonomy limitation The taxonomy (`Taxonomy`) limitation specifies with which [taxonomies](https://doc.ibexa.co/en/saas/content_management/taxonomy/taxonomy/index.md) (tags, product categories, or custom ones) user can interact. The supported policies are: - `taxonomy/read` - `taxonomy/manage` - `taxonomy/assign` ### Possible values | Value | UI value | Description | | -------------------- | -------------- | -------------------------- | | Taxonomy identifiers | Taxonomy names | List of allowed taxonomies | ## Taxonomy Subtree limitation The taxonomy subtree (`TaxonomySubtree`) limitation specifies whether the user has access to a specific subtree within the [taxonomy](https://doc.ibexa.co/en/saas/content_management/taxonomy/taxonomy/index.md) tree. Once a tag is selected, user can interact with it and all the child tags below it in the taxonomy tree. In addition, it grants read-only access to all the parent tags (up to the taxonomy root) so that the user can see the context. The supported policies are: - `taxonomy/read` - `taxonomy/manage` - `taxonomy/assign` ### Possible values | Value | UI value | Description | | ------- | ------------- | ----------------------------- | | Tag IDs | Selected tags | All valid Tag IDs are allowed | ## Version Lock limitation The Version Lock (`VersionLock`) limitation specifies whether the user can perform actions, for example, edit or unlock, on content items that are in a workflow. This limitation can be used as a role limitation. ### Possible values | Value | UI value | Description | | -------- | --------------- | ----------------------------------------------------------------------------------------------------------- | | `userId` | "Assigned only" | Users can perform actions only on content items that are assigned to them or not assigned to anybody. | | `null` | none | Users can perform actions on all drafts, regardless of the assignments or whether drafts are locked or not. | ## Workflow Stage limitation The Workflow Stage (`WorkflowStage`) limitation specifies whether the user can edit content in a specific workflow stage. ### Possible values The limitation takes as values stages configured for the workflow. ## Workflow Transition limitation The Workflow Transition (`WorkflowTransition`) limitation specifies whether the user can move the content in a workflow through a specific transition. ### Possible values The limitation takes as values transitions between stages configured for the workflow. # Users # Users > For the complete documentation index, see [llms.txt](https://doc.ibexa.co/en/saas/llms.txt). Users in Cohesivo refer to all kinds of user accounts, such as administrators, editors, managers or shop customers. Users in Cohesivo refer to all kinds of user accounts: administrators, editors, managers, or shop customers. All such user accounts have the same underlying mechanism and enable you to control access to the application, both the back office and the website front, by using the [permission system](https://doc.ibexa.co/en/saas/permissions/permissions/index.md). ## Invite and manage users - [User management product guide](https://ez-systems-developer-documentation--3403.com.readthedocs.build/en/3403/users/user_management_guide/): Find out what's user management and check what functions Cohesivo offers in this area to effectively manage the digital ecosystem. - [Inviting users](https://ez-systems-developer-documentation--3403.com.readthedocs.build/en/3403/users/invitations/): Manage user invitations to create an account in the frontend or the back office. - [Register new users](https://ez-systems-developer-documentation--3403.com.readthedocs.build/en/3403/users/user_registration/): Register new users. ## Authenticate users - [Login methods](https://ez-systems-developer-documentation--3403.com.readthedocs.build/en/3403/users/login_methods/): Set up user login methods. - [Passwords](https://ez-systems-developer-documentation--3403.com.readthedocs.build/en/3403/users/passwords/): Set up user password rules. ## Group users - [Customer groups](https://ez-systems-developer-documentation--3403.com.readthedocs.build/en/3403/users/customer_groups/): Assigning users to customer groups allows defining user-specific pricing rules. # User management product guide > For the complete documentation index, see [llms.txt](https://doc.ibexa.co/en/saas/llms.txt). Find out what's user management and check what functions Cohesivo offers in this area to effectively manage the digital ecosystem. User management is a fundamental aspect of any system. Cohesivo offers a comprehensive and feature-rich user management system that allows organizations to efficiently manage their digital ecosystem. ## What is user management User management refers to the process of granting, configuring, and controlling access for users by administrators. This encompasses the creation of user accounts, assigning roles and permissions, setting authentication methods, and managing user-related data. ## Availability User management is available in all Cohesivo versions. ## How does user management work Cohesivo simplifies user management with an intuitive and powerful system of accounts, roles, permissions, groups, and segments. You can find all user groups and users in the **Admin** panel by selecting **Users**. Here, you can manage users, their relations, roles, and policies. ![User's section](https://doc.ibexa.co/en/saas/users/img/users_section.png) Here's how it works: - User accounts - create and manage user accounts. This includes capturing user information, such as name, email, and profile details. - Roles and permissions - define roles and assign permissions to them. This ensures that users have appropriate access to content and functionalities. Roles can be customized to match the organization's specific needs. - Authentication methods - enable multiple authentication methods, including traditional username and password, OAuth, and external service logins. This flexibility allows organizations to adapt to various user authentication requirements. - User segmentation - segment users based on criteria such as demographics, behavior, or preferences. This segmentation enables personalized content delivery and targeted marketing. - Invitations - invite users to join a platform streamlining an onboarding process, sending invitations for exclusive content or events. - Customer groups - organize users into customer groups, which helps in delivering tailored experiences and content to specific segments. ![User management](https://doc.ibexa.co/en/saas/users/img/user_management.png) ## Capabilities The detailed capabilities of Ibexa user management, which provide organizations with the tools they need to deliver personalized, secure, and efficient user experiences while ensuring that user access and content delivery align with their business goals and strategies. ### User roles and permissions Ibexa allows you to define custom user [roles with granular permissions](https://doc.ibexa.co/en/saas/permissions/permission_overview/index.md), ensuring that users have access to only the specific parts of the system they need. Furthermore, you can create user groups to simplify Permission management. Assign multiple users to a group to ensure consistency and ease of access control. This helps maintain effortless security and control. To help you understand further the role each element serves, here's a brief summary: - Role - represents a collection of Permissions that can be assigned to users or user groups. Roles streamline permission management by grouping related Permissions together. - Permission - defines a specific action or access level that can be granted or denied within the system. - Policy - is a set of rules or conditions that determine under what circumstances a specific permission is granted or denied by applying limitations. Policies allow for fine-grained control of access based on various factors, such as user attributes or system states. ### Limitations [Implement limitations](https://doc.ibexa.co/en/saas/permissions/limitations/index.md) on user actions based on specific criteria, such as time-based restrictions or geographic locations. ### Authentication methods Ibexa offers flexibility in authentication methods to cater to different user bases and security requirements. ![Log in via Google](https://doc.ibexa.co/en/saas/users/img/log_in_via_google.png) Available options: - [Username and password](https://doc.ibexa.co/en/saas/users/passwords/index.md) - ideal for most users, this traditional method offers a secure login process with username and password. ### Invitations The [invitation system](https://doc.ibexa.co/en/saas/users/invitations/index.md) streamlines user onboarding and engagement. Track the status of invitations, including when they were sent, whether they were accepted, and the actions taken by users who accepted them. ![Invitations](https://doc.ibexa.co/en/saas/users/img/users_invitation.png) ### User segmentation and recommendations Ibexa's segmentation and recommendations features allow organizations to deliver customized user experiences. Track user behavior, such as page views, search queries, and interactions, to create segments and segment groups for users who share similar behaviors. ![Segment groups](https://doc.ibexa.co/en/saas/administration/img/admin_panel_segment_groups.png) Possible uses: - Demographics - segment users based on demographic data such as age, location, and gender to personalize content, promotions, and recommendations. - Behavior - tailor content based on user behavior, such as frequent content consumption, shopping patterns, or search history, ensuring users see what they're interested in. - Preferences - utilize user preferences to offer a customized experience, from language preferences to content type preferences. ### Customer groups The customer group functionality allows for targeted content delivery and service offerings. Set specific permissions for customer groups to control who can access and edit certain content to get respective recommendations. Possible uses: - Product recommendations - create customer groups based on product preferences and offer tailored product recommendations. - Content access control - restrict access to premium or specialized content to specific customer groups, such as paid subscribers or loyal customers. ## Benefits ### Improved user experience With role-based access control and personalized content, users have a more engaging and relevant experience on your platform. ### Enhanced security The flexible authentication methods and permission management help safeguard sensitive data and maintain security. With the ability to define and manage user roles and permissions, clients can ensure that sensitive data and actions are protected. User management helps prevent unauthorized access. ### Efficient user onboarding Invitations and account creation streamline the process of onboarding new users. ### Targeted marketing Customer groups and user segmentation capabilities allow for targeted and effective marketing campaigns. ### Content governance Clients can enforce content governance by controlling who can edit and publish content. This ensures quality and consistency in their digital properties. ### Content relevance By delivering content that resonates with different user segments, clients can increase user engagement and retention. ### Customizability Clients can adapt the user management system to their unique needs. Custom policies and limitations enable tailored solutions that align with their specific use cases. # Inviting users > For the complete documentation index, see [llms.txt](https://doc.ibexa.co/en/saas/llms.txt). Manage user invitations to create an account in the frontend or the back office. Cohesivo allows you to create and send invitations to create an account in the frontend as a customer, the back office as an employee, or the Corporate Portal as an organisation member. You can send invitations to individual users or in bulk. ## Roles and policies To invite other members to the site or the back office, a user needs to have the `User:Invite` permission added to their role. You can limit the ability to invite other members to specific user groups, such as Editors, or to the specific roles within the group, for example: Admin, Buyer. ## Creating and sending invitations Invitations are sent by email. The invitation contains a link with a unique hash that lets the recipient create their account. ## Invitation expiration The expiration time for the invitation link is set under the `user_invitation` [configuration key](https://doc.ibexa.co/en/saas/administration/configuration/configuration/#configuration-files). You might also set a SiteAccess under `scope`, to which the new user is invited. If the SiteAccess isn't set, it falls back to the default `site` value. ```yaml ibexa: system: : user_invitation: hash_expiration_time: P7D ``` If a user doesn't click the invitation link sent to them in time, you can refresh the invitation. Refresh resets the time limit and changes the hash in the invitation link. # Register new users > For the complete documentation index, see [llms.txt](https://doc.ibexa.co/en/saas/llms.txt). Register new users. You can allow your users to create accounts by using the `/register` route. This route leads to a registration form that, when filled in, creates a new user content item in the repository. To give anonymous users the possibility to register themselves, grant the anonymous user the `user` / `register` [policy](https://doc.ibexa.co/en/saas/permissions/policies/index.md). ## User types There are two user types defined: `users` and `customers`. `users` are back office users that are involved in creating the page such as editors, and `customers` are frontend users. To decide where the user should be registered to, you need to specify their user type under the `ibexa.system..user_type_identifier` [configuration key](https://doc.ibexa.co/en/saas/administration/configuration/configuration/#configuration-files). ```yaml ibexa: system: : user_registration: user_type_identifier: user ``` ## User groups By default, new users generated in this way are placed in the Guest accounts group. You can select a different default group in the following section of configuration: ```yaml ibexa: system: default: user_registration: group_remote_id: ``` ## Registration form field configuration To modify the registration form template, add or remove fields under the `allowed_field_definitions_identifiers` [configuration key](https://doc.ibexa.co/en/saas/administration/configuration/configuration/#configuration-files): ```yaml ibexa: system: : user_registration: user_type_identifier: user form: allowed_field_definitions_identifiers: - first_name - last_name - user_account ``` # Login methods > For the complete documentation index, see [llms.txt](https://doc.ibexa.co/en/saas/llms.txt). Set up user login methods. Two login methods are available: with user name or with email. Providers for these two methods are `ibexa.security.user_provider.username` and `ibexa.security.user_provider.email`. You can configure which method is allowed under the `security` [configuration key](https://doc.ibexa.co/en/saas/administration/configuration/configuration/#configuration-files): ```yaml security: providers: ibexa: chain: providers: [ibexa_username, ibexa_email] ibexa_username: id: ibexa.security.user_provider.username ibexa_email: id: ibexa.security.user_provider.email firewalls: #... ibexa_front: # ... provider: ibexa ``` You can customize per user field whether the email address used as a login method must be unique or not. To check that all existing user accounts have unique emails, run the `ibexa:user:audit-database` command. It lists all user accounts with duplicate emails. > **Caution: Caution** > > Because logging in with email was not available until version v3.0, you can come across issues if you use the option on an existing database. > > This may happen if more than one account uses the same email address. Login through the user name is still available. > > To resolve the issues, run `ibexa:user:audit-database` and manually modify accounts that have duplicate emails. ## Login rules You can set the rules for allowed user names in the back office per user field. The rules are set by using regular expressions. For example, to ensure that user names can only contain lowercase letters, set `[a-z]+$` as **Username pattern**: ![Setting a user name pattern](https://doc.ibexa.co/en/saas/users/img/username_pattern.png) To check that all existing user accounts have names that fit the current pattern, run the `ibexa:user:audit-database` command. It checks all user accounts in the database and lists those that don't fit the pattern. # Passwords > For the complete documentation index, see [llms.txt](https://doc.ibexa.co/en/saas/llms.txt). Set up user password rules. ## Changing and recovering passwords The user may request to change their password, or may forget it and ask to have it reset. To change password, the user must have the `user/password` permission. When the user requests a reset of a forgotten password, an email is sent to them with a token. It allows them to create a new password. The validity of the password recovery token can be set by using the `ibexa.system..security.token_interval_spec` parameter. By default, it's set to `PT1H` (one hour). ## Password rules You can customize the password policy in your project. Each password setting is customizable per user field type. You can change the [password attributes](#password-attributes) or [password expiration settings](#password-expiration), and determine the rules for [repeating passwords](#repeating-passwords). To access the password settings: 1. In the back office, go to **Content** -> **Content types**. 2. In the **Content type groups** table, click **Users**. 3. Edit the **User** content type. 4. In the **Field definitions** list, view the settings for **User account (ibexa_user)**. > **Tip: Tip** > > There can be other content types that function as users, beyond the built-in user content type. ## Password attributes In the **User account (ibexa_user)** Field definition, you can determine if the password must contain at least: - One uppercase letter - One lowercase letter - One number - One non-alphanumeric character You can also set the minimum password length. ## Password expiration In the **User account (ibexa_user)** field definition, you can set password expiration rules, which forces users to change their passwords periodically. ![Password expiry settings](https://doc.ibexa.co/en/saas/users/img/password_expiry.png) You can also decide when the user is notified that they need to change their password. The notification is displayed in the back office after login and in the user content item's preview. ## Repeating passwords You can set a rule that the password cannot be reused. You set it for the user content type in the **User account (ibexa_user)** field type's settings. When this is set, the user cannot type in the same password when it expires. It has to be changed to a new one. This only checks the new password against the current one. A password that has been used before can be used again. This rule is valid by default when password expiration is set. ## Breached passwords You can set a rule that prevents using passwords which have been exposed in a public breach. To do this, in the **User account (ibexa_user)** field definition, select "Password must not be contained in a public breach". ![Protection against using breached passwords](https://doc.ibexa.co/en/saas/users/img/password_breached.png) This rule checks the password against known password dumps by using the API. It doesn't check existing passwords, so it doesn't block login for anyone. It applies only to new passwords when users change them. > **Note: Note** > > The password itself isn't sent to the API, which makes this check secure. > > For more information on how that is possible, see [Validating Leaked Passwords with k-Anonymity](https://blog.cloudflare.com/validating-leaked-passwords-with-k-anonymity/). # Customer groups > For the complete documentation index, see [llms.txt](https://doc.ibexa.co/en/saas/llms.txt). Assigning users to customer groups allows defining user-specific pricing rules. You can assign users to different customer groups to enable [custom pricing](https://doc.ibexa.co/en/saas/product_catalog/prices/index.md). This enables you to give specific prices or price discounts (global or per product) to specific groups of users. For example, you can offer a 10% discount for all products in the catalog to users who belong to the Resellers customer group. > **Tip: Tip** > > Customer groups aren't the same as [user groups](https://doc.ibexa.co/en/saas/users/user_registration/#user-groups). User groups concern all users in the system and can be used, for example, to handle permissions. Customer groups refer specifically to the product catalog functionalities and enable handling prices. ## Enabling customer groups To enable the use of customer groups, you need to modify the user content type's definition by adding a [customer group field](https://doc.ibexa.co/en/saas/content_management/field_types/field_type_reference/customergroupfield/index.md). With this field you can add a user to any of the predefined customer groups. # Recommendations # Raptor integration > For the complete documentation index, see [llms.txt](https://doc.ibexa.co/en/saas/llms.txt). Step-by-step activation procedure of setting up the Raptor connector. The [Raptor](https://www.raptorservices.com/) integration is an add-on that provides a seamless integration between Cohesivo and Raptor recommendation engine. Its primary goal is to enable editors and managers to deliver personalized experiences across digital channels, which helps increase conversion rates, drive sales, and improve user engagement. By combining content management capabilities with advanced recommendation features, the connector allows teams to build and manage personalized experiences across integrated tools. The connector ensures a smooth and unified integration layer, enabling: - event tracking through the tracking API - personalized delivery of content and product recommendations through the Recommendations API - flexible, SiteAccess-aware configuration This approach reduces integration complexity while providing a scalable foundation for personalization use cases across multiple sites and markets. To configure the integration with Raptor, follow a step-by-step procedure that allows you to activate the Raptor connector. Activation includes [configuration](https://doc.ibexa.co/en/saas/recommendations/raptor_integration/connector_installation_configuration/index.md), adding tracking scripts and events, and using [Page Builder](https://doc.ibexa.co/en/saas/content_management/pages/page_builder_guide/index.md) blocks. For more information about tracking, check the Raptor documentation: [Implementing tracking](https://content.raptorservices.com/help-center/data-management#implementing-tracking). - [Configure Raptor](https://ez-systems-developer-documentation--3403.com.readthedocs.build/en/3403/recommendations/raptor_integration/connector_installation_configuration/): To configure the Raptor integration, follow the step-by-step procedure described below. - [Recommendation blocks in Page Builder](https://ez-systems-developer-documentation--3403.com.readthedocs.build/en/3403/recommendations/raptor_integration/recommendation_blocks/): Recommendation blocks in Page Builder # Raptor integration product guide > For the complete documentation index, see [llms.txt](https://doc.ibexa.co/en/saas/llms.txt). Discover Raptor integration - an add-on focused on recommendations and tracking customer behaviors. Discover [Raptor](https://www.raptorservices.com/) integration - an add-on that is focused on recommendations and tracking customer behaviors. It includes the connector with tracking scripts and events that are used to track and analyze customer behaviors, and a set of Recommendation blocks. ## What is Raptor integration The [Raptor integration](https://doc.ibexa.co/en/saas/recommendations/raptor_integration/raptor_connector/index.md) provides a seamless integration between Cohesivo and the Raptor recommendation engine. Its primary goal is to enable editors and managers to deliver personalized experiences across digital channels, which helps to increase conversion rates, drive sales, and improve user engagement. By bringing content and recommendations together, the connector makes it easy to build and manage personalized experiences. It provides a seamless integration layer that supports: - event tracking of user interactions through the Tracking API - personalized delivery of content and product recommendations through the Recommendations API - flexible SiteAccess-aware configuration adapted to different sites and contexts This approach simplifies integration while supporting personalization across different sites and markets. ## Availability Raptor integration elements, such as tracking, Twig functions, and public API, are available in Cohesivo starting from v5.0.7 version. Recommendation blocks are available in Page Builder. ## How does Raptor tracking work To start [tracking](https://content.raptorservices.com/help-center/introduction-to-tracking-documentation) user interactions, the tracking script needs to be added to the website’s layout. Tracking can be set up either on the client-side, server-side, or using hybrid mode, depending on how you want to capture and process the events. The tracking works differently depending on the mode you choose. In server-side mode, tracking happens on the server, handling all events without loading scripts in the browser. In client-side mode, it inserts script tags so tracking runs directly in the browser. In hybrid mode, the browser loads a first-party [shim]() that forwards tracking events to a same-origin proxy endpoint instead of the Raptor SaaS script, helping prevent ad blockers from blocking tracking. You can switch between tracking modes at any time by changing the tracking type to fit your setup and needs. ## Capabilities ### Tracking Raptor tracking allows you to collect data about how users interact with your products and content. You can track product visits to better understand what users are viewing. Provided Twig functions simplify the implementation, allowing developers to quickly add tracking to templates without complex setup. This gives you the data you need to better understand user behavior, improve recommendations, and support personalization. ### Recommendation blocks The Raptor integration add-on provides a set of ready-to-use recommendation blocks that can be added directly in the [Page Builder](https://doc.ibexa.co/en/saas/content_management/pages/page_builder_guide/index.md). These blocks can be configured to adjust how they work and what they display. Content, Product, and Commerce recommendations can be placed on landing pages using these components. Editors can use these blocks to display tailored product recommendations, promote related content, and highlight items that are trending or recently viewed. Recommendation blocks are organized into dedicated categories, each grouping blocks based on the type of recommendation they provide: - **Recommendations: Content** - presents content recommendations: - [Content that has been seen along with the item category](https://doc.ibexa.co/projects/userguide/en/6.0/recommendations/raptor_integration/raptor_recommendation_blocks/#content-that-has-been-seen-along-with-the-item-category-block) - [Merchandising content sorted by personal preferences and popularity](https://doc.ibexa.co/projects/userguide/en/6.0/recommendations/raptor_integration/raptor_recommendation_blocks/#merchandising-content-sorted-by-personal-preferences-and-popularity) - [Most popular content](https://doc.ibexa.co/projects/userguide/en/6.0/recommendations/raptor_integration/raptor_recommendation_blocks/#most-popular-content-block) - [Other customers have also seen this content](https://doc.ibexa.co/projects/userguide/en/6.0/recommendations/raptor_integration/raptor_recommendation_blocks/#other-customers-have-also-seen-this-content-block) - [Personalized content recommendations](https://doc.ibexa.co/projects/userguide/en/6.0/recommendations/raptor_integration/raptor_recommendation_blocks/#personalized-content-recommendations-block) - [User’s content history](https://doc.ibexa.co/projects/userguide/en/6.0/recommendations/raptor_integration/raptor_recommendation_blocks/#users-content-history-block) - **Recommendations: Product** - displays product suggestions based on visitors’ browsing history: - [Items associated with the given Content](https://doc.ibexa.co/projects/userguide/en/6.0/recommendations/raptor_integration/raptor_recommendation_blocks/#items-associated-with-the-given-content-block) - [Items of Customized Feeds sorted by personal preferences and popularity or trendiness](https://doc.ibexa.co/projects/userguide/en/6.0/recommendations/raptor_integration/raptor_recommendation_blocks/#items-of-customized-feeds-sorted-by-personal-preferences-and-popularity-or-trendiness) - [Most popular products](https://doc.ibexa.co/projects/userguide/en/6.0/recommendations/raptor_integration/raptor_recommendation_blocks/#most-popular-products-block) - [Most popular products in category](https://doc.ibexa.co/projects/userguide/en/6.0/recommendations/raptor_integration/raptor_recommendation_blocks/#most-popular-products-in-category-block) - [Other customers have also seen](https://doc.ibexa.co/projects/userguide/en/6.0/recommendations/raptor_integration/raptor_recommendation_blocks/#other-customers-have-also-seen-block) - **Recommendations: Commerce** - shows recommendations based on visitors' purchase history (buy and basket events): - [Other customers have also purchased block](https://doc.ibexa.co/projects/userguide/en/6.0/recommendations/raptor_integration/raptor_recommendation_blocks/#other-customers-have-also-purchased-block) - [The Personal Shopping Assistant](https://doc.ibexa.co/projects/userguide/en/6.0/recommendations/raptor_integration/raptor_recommendation_blocks/#the-personal-shopping-assistant-block) - [The Personal Shopping Assistant (additional sales)](https://doc.ibexa.co/projects/userguide/en/6.0/recommendations/raptor_integration/raptor_recommendation_blocks/#the-personal-shopping-assistant-additional-sales-block) - [The Personal Shopping Assistant (conversion)](https://doc.ibexa.co/projects/userguide/en/6.0/recommendations/raptor_integration/raptor_recommendation_blocks/#the-personal-shopping-assistant-conversion-block) - [User's item history](https://doc.ibexa.co/projects/userguide/en/6.0/recommendations/raptor_integration/raptor_recommendation_blocks/#users-item-history-block) ![Recommendation blocks](https://doc.ibexa.co/en/saas/recommendations/raptor_integration/img/recommendation_blocks.png) For a complete description of Recommendation blocks see [Recommendation blocks in User Documentation](https://doc.ibexa.co/projects/userguide/en/6.0/recommendations/raptor_integration/raptor_recommendation_blocks/). ## Benefits ### Understand user behavior Thanks to tracking functions, you can capture how users interact with your products and content, giving you valuable insights into their behavior. It helps you make data-driven decisions to improve engagement and personalize the user experience. ### Highlight recommendations Use recommendation blocks on your websites to highlight content targeted at your customers. Deliver relevant content and build trust in your brand. ### Suggest content to boost retention Help users find content of their interest quicker. Showing visitors content and products that match their interests helps keep them engaged and encourages them to come back. ### Meet customer expectations and increase engagement Recommendation blocks highlight products that match customers' interests. Tailored content boosts engagement by showing visitors information and products that align with their interests and fulfill their needs. This strengthens the connection between your brand and your audience, encouraging them to spend more time on your site and return more often. ### Increase average order value Use tracking for predictive analysis and find out what motivates users to put extra items into their carts. Start building predictions of their behaviors and suggest products your visitors are willing to buy. ### Track performance and increase conversions Use the Raptor service in your Commerce shop and see how recommendations drive sales. Keep track of which recommendations are shown to visitors and measure conversion rates to evaluate their effectiveness against your goals. ### Flexible tracking with PHP API Tracking using PHP API gives you full control over how events are recorded and processed. You can use it for complex scenarios, so tracking can be adapted to your specific needs or business requirements. # Configure Raptor > For the complete documentation index, see [llms.txt](https://doc.ibexa.co/en/saas/llms.txt). To configure the Raptor integration, follow the step-by-step procedure described below. To configure the [Raptor](https://www.raptorservices.com/) integration add-on, follow the step-by-step procedure below. ## SiteAccess-aware configuration To configure the Raptor connector, use the `ibexa.system..connector_raptor` [configuration key](https://doc.ibexa.co/en/saas/administration/configuration/configuration/#configuration-files): ```yaml ibexa: system: : connector_raptor: enabled: true customer_id: "12345" # Required tracking_type: client # One of: "client", "server", or "hybrid" # Raptor Recommendations API key recommendations_api_key: "your_api_key_here" # Required # Raptor Recommendations API URI, optional, set by default recommendations_api_uri: '%ibexa.connector.raptor.recommendations.api_uri%' # Cookie lifetime in days for server-side tracking identifier # Default: 365 days. Minimum: 1 day. cookie_id_lifetime_days: 365 ``` - `enabled` - enables or disables the connector for a given scope. Default value: `true`. If set to `false`, no tracking or recommendation requests are executed. - `customer_id` - an identifier used to authenticate requests to the recommendation engine. You can find this value as ["Account number"](https://doc.ibexa.co/en/saas/recommendations/raptor_integration/connector_installation_configuration/#customer-id) in Raptor Control Panel. - `tracking_type` - defines how user events are sent to the tracking API. Default value: `client`. Possible values: - `client` - tracking is executed in the browser using JavaScript snippets generated by the Twig functions and included in the templates. This approach may be blocked by ad blockers. - `server` - tracking is handled on the backend, with events sent directly to the tracking API. It's not affected by ad blockers. - `hybrid` - tracking is executed in the browser by a first-party JavaScript provided by Cohesivo instead of Raptor and then forwarded by the Cohesivo server to the Raptor SaaS. - `recommendations_api_key` - an API key used to authenticate requests to the Recommendations API. This key allows the connector to retrieve personalized recommendations from the recommendation engine. You can find this value as ["API key"](https://doc.ibexa.co/en/saas/recommendations/raptor_integration/connector_installation_configuration/#recommendations-api-key) in Raptor Control Panel. - `recommendations_api_uri` (optional) - overrides the default Raptor address, do not set it unless a custom endpoint is required. - `cookie_id_lifetime_days` (optional) - the lifetime in days of the server-side tracking identifier cookies. Default value: `365` days. Minimum value: `1` day. By default, `tracking_type` is set to `client` as client-side tracking is the standard Raptor mode. To understand the differences between client and server tracking types, including their advantages and disadvantages, refer to the [Raptor documentation](https://content.raptorservices.com/help-center/client-side-vs.-server-side-tracking). > **Note: Note** > > Only one tracking mode can be enabled at a time. Client-side and server-side tracking cannot be used together. ### Customer ID To find the value for the `customer_id` identifier, log in to Raptor Control Panel, and look for "Account number": A. In the top-left corner, above the account name, you can find the account number for the currently active account. B. Click the arrow icon in the top-left corner to expand the window. There you can see a list of all your accounts, with their numbers shown in the “Account number” column on the right. This way, if you have multiple accounts, you can locate and copy the number of any of your accounts, not just the active one. ![Account number](https://doc.ibexa.co/en/saas/recommendations/raptor_integration/img/account_number.png) ### Recommendations API key To find the value for the `recommendations_api_key`, log in to Raptor Control Panel, and look for "API key". To do it, in the left panel, open the **Recommendations** section, and select **Website**. Next, click on the Web module you’re interested in. In the top-right corner, click the three-dot icon and select **API information**. A new window appears, where you can find the "API key" value. Click **Show API information** and copy the value. ![API key](https://doc.ibexa.co/en/saas/recommendations/raptor_integration/img/api_key.png) ## Global configuration (non-SiteAccess-aware) The following settings are global and apply to the entire application (they are not scoped per SiteAccess): - `strict_exceptions` – when enabled, tracking exceptions are thrown instead of being silently handled. Default value: `%kernel.debug%`. - `hybrid_tracking_proxy_path` - by default, it's set to `/raptor/track`. The client-side shim sends tracking events to this same-origin endpoint, which forwards them to Raptor asynchronously. This value can be overridden in the connector configuration, for example: ```yaml ibexa: system: : connector_raptor: enabled: true customer_id: "12345" # Required tracking_type: client # One of: "client", "server", or "hybrid" # Raptor Recommendations API key recommendations_api_key: "your_api_key_here" # Required # Raptor Recommendations API URI, optional, set by default recommendations_api_uri: '%ibexa.connector.raptor.recommendations.api_uri%' # Cookie lifetime in days for server-side tracking identifier # Default: 365 days. Minimum: 1 day. cookie_id_lifetime_days: 365 ibexa_connector_raptor: # When enabled, tracking exceptions are thrown instead of being silently handled strict_exceptions: true hybrid_tracking_proxy_path: '/raptor/track' ``` # Recommendation blocks in Page Builder > For the complete documentation index, see [llms.txt](https://doc.ibexa.co/en/saas/llms.txt). Recommendation blocks in Page Builder One of the Raptor Integration elements is the introduction of recommendation blocks available in the [Page Builder](https://doc.ibexa.co/en/saas/content_management/pages/page_builder_guide/index.md). Content, Product, and Commerce recommendations can be added to a landing page using the blocks. Editors can configure these blocks to display: - personalized product recommendations - related articles or content - recently viewed or popular items In the toolbar, corresponding categories for recommendation blocks are available, containing sets of blocks depending on the recommendation type: - **Recommendations: Content** - presents content recommendations: - [Content that has been seen along with the item category](https://doc.ibexa.co/projects/userguide/en/6.0/recommendations/raptor_integration/raptor_recommendation_blocks/#content-that-has-been-seen-along-with-the-item-category-block) - [Merchandising content sorted by personal preferences and popularity](https://doc.ibexa.co/projects/userguide/en/6.0/recommendations/raptor_integration/raptor_recommendation_blocks/#merchandising-content-sorted-by-personal-preferences-and-popularity) - [Most popular content](https://doc.ibexa.co/projects/userguide/en/6.0/recommendations/raptor_integration/raptor_recommendation_blocks/#most-popular-content-block) - [Other customers have also seen this content](https://doc.ibexa.co/projects/userguide/en/6.0/recommendations/raptor_integration/raptor_recommendation_blocks/#other-customers-have-also-seen-this-content-block) - [Personalized content recommendations](https://doc.ibexa.co/projects/userguide/en/6.0/recommendations/raptor_integration/raptor_recommendation_blocks/#personalized-content-recommendations-block) - [User’s content history](https://doc.ibexa.co/projects/userguide/en/6.0/recommendations/raptor_integration/raptor_recommendation_blocks/#users-content-history-block) - **Recommendations: Product** - displays product suggestions based on visitors’ browsing history: - [Items associated with the given Content](https://doc.ibexa.co/projects/userguide/en/6.0/recommendations/raptor_integration/raptor_recommendation_blocks/#items-associated-with-the-given-content-block) - [Items of Customized Feeds sorted by personal preferences and popularity or trendiness](https://doc.ibexa.co/projects/userguide/en/6.0/recommendations/raptor_integration/raptor_recommendation_blocks/#items-of-customized-feeds-sorted-by-personal-preferences-and-popularity-or-trendiness) - [Most popular products](https://doc.ibexa.co/projects/userguide/en/6.0/recommendations/raptor_integration/raptor_recommendation_blocks/#most-popular-products-block) - [Most popular products in category](https://doc.ibexa.co/projects/userguide/en/6.0/recommendations/raptor_integration/raptor_recommendation_blocks/#most-popular-products-in-category-block) - [Other customers have also seen](https://doc.ibexa.co/projects/userguide/en/6.0/recommendations/raptor_integration/raptor_recommendation_blocks/#other-customers-have-also-seen-block) - **Recommendations: Commerce** - shows recommendations based on visitors' purchase history (buy and basket events): - [Other customers have also purchased block](https://doc.ibexa.co/projects/userguide/en/6.0/recommendations/raptor_integration/raptor_recommendation_blocks/#other-customers-have-also-purchased-block) - [The Personal Shopping Assistant](https://doc.ibexa.co/projects/userguide/en/6.0/recommendations/raptor_integration/raptor_recommendation_blocks/#the-personal-shopping-assistant-block) - [The Personal Shopping Assistant (additional sales)](https://doc.ibexa.co/projects/userguide/en/6.0/recommendations/raptor_integration/raptor_recommendation_blocks/#the-personal-shopping-assistant-additional-sales-block) - [The Personal Shopping Assistant (conversion)](https://doc.ibexa.co/projects/userguide/en/6.0/recommendations/raptor_integration/raptor_recommendation_blocks/#the-personal-shopping-assistant-conversion-block) - [User's item history](https://doc.ibexa.co/projects/userguide/en/6.0/recommendations/raptor_integration/raptor_recommendation_blocks/#users-item-history-block) ![Recommendation blocks](https://doc.ibexa.co/en/saas/recommendations/raptor_integration/img/recommendation_blocks.png) After opening the settings of a recommendation block, a link is available at the bottom of the window. It leads to the [Raptor Control Panel](https://controlpanel.raptorsmartadvisor.com/) (opens in a separate tab), where you can configure advanced settings and fine-tune the recommendation strategy. ![Advanced settings](https://doc.ibexa.co/en/saas/recommendations/raptor_integration/img/advanced_settings.png) For a complete description of Recommendation blocks see [Recommendation blocks](https://doc.ibexa.co/projects/userguide/en/6.0/recommendations/raptor_integration/raptor_recommendation_blocks/). For the list of all page blocks that are available in Page Builder, see [Block reference page](https://doc.ibexa.co/projects/userguide/en/6.0/content_management/block_reference/). # Customer Data Platform # Raptor CDP integration > For the complete documentation index, see [llms.txt](https://doc.ibexa.co/en/saas/llms.txt). Raptor CDP is a software system designed to collect and organize customer data from multiple sources to build comprehensive customer profiles. ## What is Raptor CDP Raptor CDP (Customer Data Platform) helps you solve one of the hardest challenges facing business world today: building unique experiences for your customers. With Raptor CDP you're able to track and aggregate data of your customers' activity on multiple channels. It allows you to create individual customer profiles that enable you to personalize their experience on your platform. ![Raptor CDP control panel](https://doc.ibexa.co/en/saas/raptor_cdp/img/raptor_cdp_control_panel.png) ## How it works Raptor CDP unifies customer data across your organization to help you activate your users and provide them with real-time engagement. With defined audiences you can target your user segments at the right time, through the most used channel, with the relevant message, content, or products. The customer data are collected through the system of trackers embedded in different parts of your page. For more information on activation and trackers, see [CDP activation documentation](https://doc.ibexa.co/en/saas/raptor_cdp/raptor_cdp_activation/raptor_cdp_activation/index.md). ## Getting access If you decide to acquire Raptor CDP, contact your sales representative to receive a registration link. After registration, you get access to a separate instance where you can find the data required for configuring, activating, and using this feature. # Raptor CDP product guide > For the complete documentation index, see [llms.txt](https://doc.ibexa.co/en/saas/llms.txt). The Raptor CDP product guide describes all the possibilities that the Customer Data Platform offers to help you build great customer experiences. ## What is Raptor CDP Raptor CDP (Customer Data Platform) module helps you build unique and memorable experiences for your customers. By using Raptor CDP you can monitor and compile data about your customers' activity on multiple channels. It also allows you to create individual customer profiles so you can customize their experience on your platform. With Raptor CDP you can store and manage large volumes of customer data in a structured manner. This central data storage supports business growth with a scalable infrastructure, helping to futureproof your business. You can get customer data from both online and offline data sources. It includes first, second, and third-party data from multiple sources such as transactional systems, website tracking, and behavior, POS, CRM, and others. ## Availability Raptor CDP is available in Cohesivo. ## How does Raptor CDP work Raptor CDP unifies customer data throughout your whole organization. It helps you activate your users and give them real-time interaction. You can target certain user segments with the appropriate message, content, or products at the right time through the most used channels by using specified audiences. Customer data is gathered through a system of trackers embedded in various areas of your website. ![CDP - how does it work](https://doc.ibexa.co/en/saas/raptor_cdp/img/cdp.png) ### Getting started To start using Raptor CDP, first you need to contact your sales representative, who provides you with a link to register your Raptor CDP account. When you're done with registration process, you're able to access a separate instance with the data needed to configure, activate, and use this feature. Last step is to go through the [configuration process](https://doc.ibexa.co/en/saas/raptor_cdp/raptor_cdp_activation/raptor_cdp_configuration/index.md). ### Customer profile In Raptor CDP you can build 360° customer profiles. It unifies customer data from different sources to help you understand your prospects and customer needs. After you get customer data, you can unify and match customer profiles based on their preferences and habits. You can create and analyze complete, 360° customer profiles based on demographics, interactions, behaviors, and transactional data. This approach helps you create a single customer view. ![Customer profile](https://doc.ibexa.co/en/saas/raptor_cdp/img/customer_profile.png) ### Segment groups To create a personalized customer experience, you need to group your clients into specified audiences. Cohesivo comes with a ready solution - segment groups. Segment group information is reused by various Cohesivo functionalities, such as [Recommendations](https://doc.ibexa.co/en/saas/recommendations/raptor_integration/raptor_connector_guide/index.md) or content targeting. You can [create a segment group](https://doc.ibexa.co/en/saas/administration/admin_panel/segments_admin_panel/index.md) in the back office of Cohesivo. It serves as a container for all segments data generated by Raptor CDP. When you create a segment group, you need to provide its name and identifier. Be careful while doing so, as after you create the segment group in the back office and connect it to Raptor CDP, you cannot change it in any way, including edit its name. Remember to add a segment group identifier to the configuration, under the `segment_group_identifier` field. ## Capabilities ### Data export Configuration in Raptor CDP allows you to automate the process of exporting content, users, and products. An `ibexa_cdp.data_export` configuration key includes the `schedule` setting where you can find separate sections for exporting user, content, and product. Structure of each section is exactly the same and includes `interval` and `options` elements: - `interval` - sets the frequency at which the command is invoked, uses cron expressions, for example, '\*/30 * * * \*' means "every 30 minutes", '0 \*/12 * * \*' means "every 12th hour" - `options` - allows you to add arguments that have to be passed to the export command This configuration allows you to provide multiple export workflows with parameters. It's important, because all the types of content/product must have their own parameters on the CDP side, where each has a different Stream ID key and different required values configured per data source. Regarding data export, currently, only Stream File transport is supported and can be initialized from the configuration. For more information, see [CDP data export](https://doc.ibexa.co/en/saas/raptor_cdp/raptor_cdp_activation/raptor_cdp_data_export/index.md). ### Data customization ​You can customize content and product data exported to Raptor CDP and control what field type information you want to export. With Raptor CDP, you can export field types and field type values. They're exported with metadata and attributes, for example, ID, field definition name, type, or value. ### Client-side Tracking The final step is setting up a tracking script. For more information, see [CDP add client-side tracking](https://doc.ibexa.co/en/saas/raptor_cdp/raptor_cdp_activation/raptor_cdp_add_tracking/index.md) and [Introduction to tracking in Raptor documentation](https://content.raptorservices.com/help-center/introduction-to-tracking-documentation). ### Audience Builder In the Audience Builder, you can create audiences - groups of users that meet the assumed conditions. You can choose specific conditions: `did`, `did not`, or `have`. The conditions `did` and `did not` allow you to use events like buy, visit or add to a cart from online tracking. The `have` conditions are tied to personal characteristics and can be used to track the sum of all buys or top-visited categories. You can also connect created audiences to the activations. ![Audience Builder](https://doc.ibexa.co/en/saas/raptor_cdp/img/audience_builder.png) ### Anonymous user segmentation Raptor CDP can build audiences for anonymous users, enabling personalised experiences for not logged-in visitors. When an anonymous visitor accesses your site, Raptor starts building an [anonymous profile](https://content.raptorservices.com/help-center/introduction-to-person-identifiers-and-profile-unification). You can segment these anonymous profiles into different audiences, exactly as in case of logged-in users, and use this information in Cohesivo to provide personalized experiences. ## Benefits ### Personalized user experience With Raptor CDP you can build unique and memorable experience for your customers and create individual customer profiles. By using 360° client profiles, you can connect with the right customer at the right moment, in the right place. Build extensive customer profiles that include their interactions, habits, and preferences from several touchpoints. ### Segment groups Provide a personalized customer experience, group your clients into specified audiences, and provide recommendations depending on the user data. Create segment groups to deliver personalized campaigns to boost engagement and conversion rates. ### Audience Builder Create user groups - audiences - based on conditions and events. ### Data export Export data regarding content, users, and products. Data export includes automatic file mapping. Analyze customer data, track campaigns, and discover the most effective strategies to boost performance. ### Data customization Customize data to control what field type information you want to export. ### Real-time action Deliver relevant interactions in the right place at the right time for optimal results thanks to dynamic, real-time data updates. Take advantage of event-triggered communications which are aligned with your customers immediate interests. # Activate Raptor CDP > For the complete documentation index, see [llms.txt](https://doc.ibexa.co/en/saas/llms.txt). Step-by-step activation procedure of Raptor CDP. Follow a step-by-step procedure that allows you to activate Raptor CDP. Activation includes configuration, data export and adding tracking. - [Configure Raptor CDP](https://ez-systems-developer-documentation--3403.com.readthedocs.build/en/3403/raptor_cdp/raptor_cdp_activation/raptor_cdp_configuration/): Step-by-step configuration procedure of Raptor CDP. - [Export Raptor CDP data](https://ez-systems-developer-documentation--3403.com.readthedocs.build/en/3403/raptor_cdp/raptor_cdp_activation/raptor_cdp_data_export/): Step-by-step data export procedure in Raptor CDP. - [Track with Raptor CDP](https://ez-systems-developer-documentation--3403.com.readthedocs.build/en/3403/raptor_cdp/raptor_cdp_activation/raptor_cdp_add_tracking/): Adding tracking in Raptor CDP. # Configure Raptor CDP > For the complete documentation index, see [llms.txt](https://doc.ibexa.co/en/saas/llms.txt). Step-by-step configuration procedure of Raptor CDP. To configure Raptor CDP, use the `ibexa.system..cdp` [configuration key](https://doc.ibexa.co/en/saas/administration/configuration/configuration/#configuration-files): ```yaml ibexa: system: default: cdp: account_number: 123456 data_export: user_data: transport: stream_file stream_file: stream_id: 00000000-00000000-00000000-00000000 content_data: transport: stream_file stream_file: stream_id: 00000000-00000000-00000000-00000000 product_data: transport: stream_file stream_file: stream_id: 00000000-00000000-00000000-00000000 activations: - client_id: '%env(CDP_ACTIVATION_CLIENT_ID)%' client_secret: '%env(CDP_ACTIVATION_CLIENT_SECRET)%' segment_group_identifier: example_segment_group_identifier membership: # For anonymous user segmentation activation_id: '%env(CDP_MEMBERSHIP_ACTIVATION_ID)%' api_key: '%env(CDP_MEMBERSHIP_API_KEY)%' base_url: 'https://cdp-api.raptorsmartadvisor.com' timeout: 5 ``` - `account_number` - a [number](#account-number) obtained from Accounts settings in Raptor CDP dashboard - `stream_id` - stream ID generated when importing data from the stream file in Data Manage - `activations` - activation details. You can configure multiple activations. They have to be of type `Ibexa` in Cohesivo dashboard - `client_id` and `client_secret` - client credentials are used to authenticate against the Webhook endpoint. Make sure they're random and secure - `segment_group_identifier` - a [location](#segment-group) to which CDP data is imported - `membership` - configuration that enables support for [anonymous user segmentation](#anonymous-user-segmentation) - `membership.activation_id` and `membership.api_key` - credentials for the CDP Membership API, required for [anonymous user segmentation](#anonymous-user-segmentation) - `membership.base_url` - base URL of the CDP Membership API (default: `https://cdp-api.raptorsmartadvisor.com`) - `membership.timeout` - timeout in seconds for Membership API requests (default: `5`) ## Account number Now, fill in the account number. Log in to Raptor CDP and in the top right corner, select available accounts. ![List of available accounts](https://doc.ibexa.co/en/saas/raptor_cdp/img/raptor_cdp_accounts.png) A pop-up window displays a list of all available accounts and their numbers. ![Account number](https://doc.ibexa.co/en/saas/raptor_cdp/img/raptor_cdp_account_number.png) ## Segment group Create a segment group in the back office. It serves as a container for all segments data generated by Raptor CDP. Go to **Admin** -> **Segments** and select **Create**. Fill in name and identifier for a segment group. Choose wisely, as once connected to CDP segment group cannot be changed. > **Caution: Raptor CDP segment group** > > After you create the segment group in the back office and connect it to Raptor CDP, you cannot change it in any way, including edit its name. ![Creating a new segment group](https://doc.ibexa.co/en/saas/raptor_cdp/img/raptor_cdp_create_segment_group.png) Next, add a segment group identifier to the configuration. ## Anonymous user segmentation To set up [segmentation for anonymous users](https://doc.ibexa.co/en/saas/raptor_cdp/raptor_cdp_guide/#anonymous-user-segmentation), take the following steps: ### Set up CDP API activation Create an activation of type "CDP API" in the Raptor dashboard. For instructions, see [CDP API activations](https://content.raptorservices.com/help-center/cdp/activations/cdp-api) in Raptor documentation. ### Configure website tracking dataflow Set up a "Website tracking" dataflow with `coid` (cookie ID) as the person identifier so that Raptor can use the tracking data in the CDP. For more information, see [Website tracking dataflow](https://content.raptorservices.com/help-center/tools/datamanager/introduction-to-the-data-manager) in Raptor documentation. ### Configuration Add the `membership.activation_id` and `membership.api_key` credentials to your [`ibexa.system..cdp` configuration](#configuration), using the credentials for [CDP API activation](#set-up-cdp-api-activation). To control for how long resolved segment memberships are cached per visitor, use the `ibexa_segmentation.anonymous.cache` configuration key: ```yaml ibexa_segmentation: anonymous: cache: enabled: true # default; set to false to disable ttl: 300 # cache lifetime in seconds, default 300 (5 minutes) pool: 'ibexa.cache_pool' # Symfony cache pool service ID, default ibexa.cache_pool ``` - `enabled` - whether to cache CDP segment results per visitor cookie. Disabling this causes an additional API call to Raptor on every request - `ttl` - how long resolved segment results are cached per visitor (in seconds) - `pool` - the Symfony cache pool used to store the results # Export Raptor CDP data > For the complete documentation index, see [llms.txt](https://doc.ibexa.co/en/saas/llms.txt). Step-by-step data export procedure in Raptor CDP. You need to specify a source of the user data that Raptor CDP connects to. To do so, go to **Data Manager** in **Tools** section and select **Create new dataflow**. It takes you to a Dataflow Creator, where in five steps you can set up a data streaming. ## General Information In the **General Information** section, specify dataflow name, choose **Stream File** as a source of user data and **CDP** as a destination, where they're sent for processing. Currently, only Stream File transport is supported and can be initialized from the configuration. ## Download In the **Download** section, select **Stream file**. Copy generated steam ID and paste it into the configuration file under `stream_id`. It allows you to establish a datastream from the Streaming API into the Data Manager. User, product and content data is then streamed to the Data Manager. Draft data is sent first, so that you can validate it in the **Activation** section before a full export. You can extend exported user data with custom fields from your user content, such as date of birth, preferences, or other profile information. Next, go back to Raptor CDP and select **Validate & download**. If the file passes, you can see a confirmation message. Now, you can go to the **File mapping** section. ## File mapping Mapping is completed automatically, the system fills all required information and shows available columns with data points on the right. You can change their names if needed or disallow empty fields by checking **Mandatory**. If the provided file contains empty values, this option isn't available. If provided file isn't recognized, the system requires you to fill in the parsing-options manually or select an appropriate format. If you make any alterations, select the **Parse File** to generate columns with new data. ## Transform & Map In the **Transform & Map** section you transform data and map it to a schema. At this point, you can map **email** to **email** and **id** to **integer** fields to get custom columns. If user data export has been extended with custom fields, those fields appear as additional columns in this section. Make sure to add them to your schema in Raptor so they can be used for segmentation and recommendations. Next, select **Create schema based on the downloaded columns**. It moves you to Schema Creator. There, choose **PersonalData** as a parent and name the schema. ![Create new schema](https://doc.ibexa.co/en/saas/raptor_cdp/img/raptor_cdp_create_new_schema.png) Next, select all the columns and set Person Identifier as **userid**. ![Person Identifier](https://doc.ibexa.co/en/saas/raptor_cdp/img/raptor_cdp_person_identifier.png) If you used PersonData or Catalog type schemas, the system requires specifying the Write Mode that is applied to them. **Append** (default one) allows new data to overwrite the old one but leaves existing entries unaffected. All entries are stored in the dataset, unchanged by updating dataflow. For example, if a customer unsubscribes a newsletter, their email remains in the system. **Overwrite** completely removes the original dataset and replaces it with the new one every time the dataflow runs. Next, select **userid** from a **Schema columns section** on the right and map it to **id**. ![Map userid to id](https://doc.ibexa.co/en/saas/raptor_cdp/img/raptor_cdp_userid_mapid.png) ## Activation In this section you can test the dataflow with provided test user data. If everything passes, production data is exported and you can run and activate the dataflow. ## Build new Audience/Segment Go to the **Audience Builder** and select **Build new audience**. When naming the audience remember, you need to find it in a drop-down list during activation. There, you can choose conditions from `did`, `did not` or `have`. The conditions `did` and `did not` allow you to use events like buy, visit or add to a cart from online tracking. - `have` conditions are tied to personal characteristics and can be used to track the sum of all buys or top-visited categories. In the Audience Builder, you can also connect created audiences to the activations. ## Activation Activation synchronises data from Raptor CDP to Cohesivo. When you specify a segment, you can activate it on multiple communication channels, such as newsletters or commercials. You can configure multiple activations based data flows. First, from the menu bar, select **Activations** and create a new **Ibexa** activation. Specify name of your activation, select `userid` as **Person Identifier** and click **Next**. ![General Information - Activation](https://doc.ibexa.co/en/saas/raptor_cdp/img/raptor_cdp_activation_general_info.png) Next, you can fill in **Ibexa information** they must match the ones provided in the YAML configuration: - **Client Secret** and **Client ID** - are used to authenticate against Webhook endpoint. They must match the credentials configured for the webhook. - **Segment Group Identifier** - identifier of the segment group in Cohesivo. It points to a segment group where all the CDP audiences are stored. - **Base URL** - URL of your instance with added `/cdp/webhook` at the end. ![Ibexa Information - Activation](https://doc.ibexa.co/en/saas/raptor_cdp/img/raptor_cdp_activation_ibexa_info.png) Finally, you can specify the audiences you wish to include. > **Note: CDP requests** > > All CDP requests are logged in with `debug` severity. ### Ibexa Messenger support for large batches of data CDP uses Ibexa Messenger to process incoming data from [Raptor](https://www.raptorservices.com/). This approach improves performance and reliability when processing large amounts of CDP user records. By using Messenger while working with large batches of data, requests are queued instead of being processed synchronously: - queuing items starts automatically once a certain number of actions is reached (below this number, items are processed in a single request, using the standard synchronous behavior) - every single data is recorded in the database - a background worker retrieves records from the queue, processing them one by one or in batches, depending on the [Messenger](https://symfony.com/doc/7.4/messenger.html) configuration - processing happens at set intervals to avoid timeouts and keep the system stable 1. Make sure that the transport layer is defined properly in Ibexa Messenger configuration. 2. Add the `bulk_async_threshold` setting to the CDP configuration: ```bash ibexa_cdp: bulk_async_threshold: 100 # Default: 100 items ``` Available options: - `bulk_async_threshold` (integer, default: 100) - minimum number of items required to trigger asynchronous processing - below threshold - items are processed immediately in a single request, using the standard synchronous behavior - at/above threshold - items are automatically dispatched to the asynchronous queue for background processing ### CDP Monolog channel CDP Monolog channel handles webhook logs for easier separation of logs. ```bash - { name: monolog.logger, channel: ibexa.cdp.webhook } ``` It's possible to configure `ibexa.cdp.webhook` Monolog channel to direct all logs to specific stream, file, or service. This allows webhook logs to be stored separately from the main application logs for easier debugging and analysis. To do it, define a new logging handler for the `ibexa.cdp.webhook` channel that directs CDP webhook events to a separate file. It can be configured in both `dev` and `prod` environments, for example: ```yaml monolog: handlers: cdp_webhook: type: stream path: "%kernel.logs_dir%/cdp_webhook_%kernel.environment%.log" level: debug channels: [ 'ibexa.cdp.webhook' ] ``` If you want to avoid redundant or duplicate entries in the other logs, exclude the webhook channel by: ```yaml channels: ["!ibexa.cdp.webhook"] ``` # Track with Raptor CDP > For the complete documentation index, see [llms.txt](https://doc.ibexa.co/en/saas/llms.txt). Adding tracking in Raptor CDP. The final step is setting up a tracking script that identifies visitors and records their interactions. You can set it up in two ways: - with Raptor's built in tracking functions - manually, with tracking scripts ## Set up tracking with built-in Raptor tracking functions If your project uses the [Raptor connector](https://doc.ibexa.co/en/saas/recommendations/raptor_integration/raptor_connector/index.md), use the built-in Raptor tracking. This recommended approach supports both client-side and server-side tracking, handles cookie consent, and sets the tracking cookie required for [anonymous user segmentation](https://doc.ibexa.co/en/saas/raptor_cdp/raptor_cdp_activation/raptor_cdp_configuration/#anonymous-user-segmentation). ## Manually set up tracking with tracking scripts If you aren't using the Raptor connector, you can set up tracking manually. It requires a head tracking script between the `` tags on your website, a main script after the head script, and cookie consent. For more information about setting up a tracking script manually, see [Raptor documentation](https://content.raptorservices.com/help-center/client-side-tracking). Now, you need to add a tracker to specific places in your website where you want to track users. For example, add this tracker to the landing page template to track various user activities: - user entrances ```js raptor.trackEvent('visit', ..., ...); ``` - user purchases ```js //Parameters for Product 1 raptor.trackEvent('buy', ..., ...); //Parameters for Product 2 raptor.trackEvent('buy', ..., ...); ``` For tracking to be effective, you also need to send ID of a logged-in user in the same way. Add the user ID information of logged-in users by using below script: ```js raptor.push("setRuid","USER_ID_HERE") ``` For anonymous visitors, Raptor's tracking script automatically sets an `rsa` cookie that uniquely identifies the visitor, without calling the `setRuid` method. For more information on tracking events, see [Raptor documentation](https://content.raptorservices.com/help-center/tracking-events-parameters-reference). # Search # Search > For the complete documentation index, see [llms.txt](https://doc.ibexa.co/en/saas/llms.txt). Cohesivo search functionalities allow running complex and precise queries about content and products. Cohesivo exposes a powerful search capability, allowing both full-text search and querying the content repository by using several built-in Search Criteria and Sort Clauses. You build a query by combining [Search Criteria](https://doc.ibexa.co/en/saas/search/criteria_reference/search_criteria_reference/index.md), which select the content to return, with [Sort Clauses](https://doc.ibexa.co/en/saas/search/sort_clause_reference/sort_clause_reference/index.md), which order the results. [Aggregations](https://doc.ibexa.co/en/saas/search/aggregation_reference/aggregation_reference/index.md) group the results into categories, and [embeddings](https://doc.ibexa.co/en/saas/search/embeddings_reference/embeddings_reference/index.md) enable semantic similarity search. You run queries over the REST API by using the `/views` resource. - [Search Criteria and Sort Clauses](https://ez-systems-developer-documentation--3403.com.readthedocs.build/en/3403/search/search_criteria_and_sort_clauses/): Search Criteria and Sort Clauses help you fine-tune searches done by using the Search API. - [Search Criteria reference](https://ez-systems-developer-documentation--3403.com.readthedocs.build/en/3403/search/criteria_reference/search_criteria_reference/): Search Criteria help define and fine-tune search queries for content and locations. - [Sort Clause reference](https://ez-systems-developer-documentation--3403.com.readthedocs.build/en/3403/search/sort_clause_reference/sort_clause_reference/): Sort Clauses help fine-tune sorting order when searching for content and locations. - [Aggregation reference](https://ez-systems-developer-documentation--3403.com.readthedocs.build/en/3403/search/aggregation_reference/aggregation_reference/): Aggregations help fine-tune search for content and Locations by grouping results into categories. - [Embeddings search reference](https://ez-systems-developer-documentation--3403.com.readthedocs.build/en/3403/search/embeddings_reference/embeddings_reference/): Embedding queries, embedding configuration, providers, and embedding search fields - [Search in trash reference](https://ez-systems-developer-documentation--3403.com.readthedocs.build/en/3403/search/search_in_trash_reference/): Trash Search Criteria and Sort Clauses help define and fine-tune search queries for content in trash. # Search Criteria and Sort Clauses > For the complete documentation index, see [llms.txt](https://doc.ibexa.co/en/saas/llms.txt). Search Criteria and Sort Clauses help you fine-tune searches done by using the Search API. Search Criteria and Sort Clauses are the building blocks of a search query: Criteria select which content is returned, and Sort Clauses order the results. Cohesivo provides a number of standard Search Criteria and Sort Clauses that cover the majority of use cases. For the full list, see the [Search Criteria reference](https://doc.ibexa.co/en/saas/search/criteria_reference/search_criteria_reference/index.md) and the [Sort Clause reference](https://doc.ibexa.co/en/saas/search/sort_clause_reference/sort_clause_reference/index.md). ## Content and Location search There are two basic types of search: you can search for content items, or for locations. All Criteria and Sort Clauses are accepted by Location search, but not all of them can be used with Content search. The reason is that while one location always has exactly one content item, one content item can have several locations. In that context some Criteria and Sort Clauses would produce ambiguous queries, so Content search refuses the Criteria and Sort Clauses that apply specifically to locations. ## Search using a custom Field Criterion REST search can be performed by calling the `POST /views` method with a custom `FieldCriterion`. This allows you to build custom content logic queries with nested logical operators OR/AND/NOT. ### Example of custom Content Query ```json "ContentQuery":{ "Query":{ "OR":[ { "AND":[ { "Field":{ "name":"name", "operator":"CONTAINS", "value":"foo" } }, { "Field":{ "name":"info", "operator":"CONTAINS", "value":"bar" } } ] }, { "AND":[ { "Field":{ "name":"name", "operator":"CONTAINS", "value":"barfoo" } }, { "Field":{ "name":"info", "operator":"CONTAINS", "value":"baz" } } ] } ] } } ``` # Search Criteria reference > For the complete documentation index, see [llms.txt](https://doc.ibexa.co/en/saas/llms.txt). Search Criteria help define and fine-tune search queries for content and locations. Search Criteria are filters for content and location Search. Criteria can take some of the following arguments: - `target` - when the Criterion supports targeting a specific field, example: `FieldDefinition` or Metadata identifier - `value` - the value(s) to filter on, typically a scalar or array of scalars - `operator` - constants on `Ibexa\Contracts\Core\Repository\Values\Content\Query\Criterion\Operator`: `IN`, `EQ`, `GT`, `GTE`, `LT`, `LTE`, `LIKE`, `BETWEEN`, `CONTAINS`. Most Criteria don't expose this and select `EQ` or `IN` depending on whether the value is scalar or an array. `IN` and `BETWEEN` always act on an array of values, while the other operators act on single scalar value - `valueData` - additional value data, required by some Criteria, for instance `MapLocationDistance` Support and capabilities of individual Criteria can depend on the search engine. In the Legacy search engine, the field index/sort key column is limited to 255 characters by design. Due to this storage limitation, searching content using the Country field type or Keyword when there are multiple values selected may not return all the expected results. ## Search Criteria | Search Criterion | Search based on | Content Search | Location Search | Filtering | Trash | | -------------------------------------------------------------------------------------------------------------------------- | ------------------------------------------------------------------------------------------- | -------------- | --------------- | --------- | ----- | | [Ancestor](https://doc.ibexa.co/en/saas/search/criteria_reference/ancestor_criterion/index.md) | Whether the content item is an ancestor of the provided location | Yes | Yes | Yes | | | [ContentId](https://doc.ibexa.co/en/saas/search/criteria_reference/contentid_criterion/index.md) | Content item's ID | Yes | Yes | Yes | | | [ContentName](https://doc.ibexa.co/en/saas/search/criteria_reference/contentname_criterion/index.md) | Content item's name | Yes | Yes | Yes | Yes | | [ContentTypeGroupId](https://doc.ibexa.co/en/saas/search/criteria_reference/contenttypegroupid_criterion/index.md) | ID of the content item's content type group | Yes | Yes | Yes | | | [ContentTypeId](https://doc.ibexa.co/en/saas/search/criteria_reference/contenttypeid_criterion/index.md) | ID of the content item's content type | Yes | Yes | Yes | Yes | | [ContentTypeIdentifier](https://doc.ibexa.co/en/saas/search/criteria_reference/contenttypeidentifier_criterion/index.md) | Identifier of the content item's content type | Yes | Yes | Yes | | | [CurrencyCodeCriterion](https://doc.ibexa.co/en/saas/search/criteria_reference/currencycode_criterion/index.md) | Currency code | Yes | Yes | Yes | | | [CustomField](https://doc.ibexa.co/en/saas/search/criteria_reference/customfield_criterion/index.md) | Custom field | Yes | Yes | | | | [DateMetadata](https://doc.ibexa.co/en/saas/search/criteria_reference/datemetadata_criterion/index.md) | The date when content was created or last modified | Yes | Yes | Yes | Yes | | [Depth](https://doc.ibexa.co/en/saas/search/criteria_reference/depth_criterion/index.md) | Location depth in the content tree | | Yes | Yes | | | [Field](https://doc.ibexa.co/en/saas/search/criteria_reference/field_criterion/index.md) | Content of one of content item's fields | Yes | Yes | | | | [FieldRelation](https://doc.ibexa.co/en/saas/search/criteria_reference/fieldrelation_criterion/index.md) | Content items the content in question has Relations to | Yes | Yes | | | | [FullText](https://doc.ibexa.co/en/saas/search/criteria_reference/fulltext_criterion/index.md) | Full text content of a content item's fields | Yes | Yes | | | | [Image](https://doc.ibexa.co/en/saas/search/criteria_reference/image_criterion/index.md) | Image by specified image attributes | Yes | Yes | | | | [ImageDimensions](https://doc.ibexa.co/en/saas/search/criteria_reference/imagedimensions_criterion/index.md) | Image dimensions: height and width | Yes | Yes | | | | [ImageFileSize](https://doc.ibexa.co/en/saas/search/criteria_reference/imagefilesize_criterion/index.md) | Image size in MB | Yes | Yes | | | | [ImageHeight](https://doc.ibexa.co/en/saas/search/criteria_reference/imageheight_criterion/index.md) | Image height in pixels | Yes | Yes | | | | [ImageMimeType](https://doc.ibexa.co/en/saas/search/criteria_reference/imagemimetype_criterion/index.md) | Image type | Yes | Yes | | | | [ImageOrientation](https://doc.ibexa.co/en/saas/search/criteria_reference/imageorientation_criterion/index.md) | Image orientation | Yes | Yes | | | | [ImageWidth](https://doc.ibexa.co/en/saas/search/criteria_reference/imagewidth_criterion/index.md) | Image width in pixels | Yes | Yes | | | | [IsBookmarked](https://doc.ibexa.co/en/saas/search/criteria_reference/isbookmarked_criterion/index.md) | Whether a location is bookmarked or not | | Yes | Yes | | | [IsContainer](https://doc.ibexa.co/en/saas/search/criteria_reference/iscontainer_criterion/index.md) | Whether a content item is a container (can contain other content items) | Yes | Yes | Yes | | | [IsCurrencyEnabledCriterion](https://doc.ibexa.co/en/saas/search/criteria_reference/iscurrencyenabled_criterion/index.md) | Whether a specified currency is enabled in the system | | | | | | [IsFieldEmpty](https://doc.ibexa.co/en/saas/search/criteria_reference/isfieldempty_criterion/index.md) | Whether a specified field of a content item is empty or not | Yes | Yes | | | | [IsMainLocation](https://doc.ibexa.co/en/saas/search/criteria_reference/ismainlocation_criterion/index.md) | Whether a location is the main location of a content item | | Yes | Yes | | | [IsProductBased](https://doc.ibexa.co/en/saas/search/criteria_reference/isproductbased_criterion/index.md) | Whether content represents a product | Yes | Yes | Yes | | | [IsUserBased](https://doc.ibexa.co/en/saas/search/criteria_reference/isuserbased_criterion/index.md) | Whether content represents a User account | Yes | Yes | Yes | | | [IsUserEnabled](https://doc.ibexa.co/en/saas/search/criteria_reference/isuserenabled_criterion/index.md) | Whether a User account is enabled | Yes | Yes | Yes | | | [LanguageCode](https://doc.ibexa.co/en/saas/search/criteria_reference/languagecode_criterion/index.md) | Whether a content item is translated into the selected language | Yes | Yes | Yes | | | [LocationId](https://doc.ibexa.co/en/saas/search/criteria_reference/locationid_criterion/index.md) | Location ID | Yes | Yes | Yes | | | [LocationRemoteId](https://doc.ibexa.co/en/saas/search/criteria_reference/locationremoteid_criterion/index.md) | Location remote ID | Yes | Yes | Yes | | | [MapLocationDistance](https://doc.ibexa.co/en/saas/search/criteria_reference/maplocationdistance_criterion/index.md) | Distance between the location contained in a MapLocation field and the provided coordinates | Yes | Yes | | | | [MatchAll](https://doc.ibexa.co/en/saas/search/criteria_reference/matchall_criterion/index.md) | Returns all search results | Yes | Yes | Yes | Yes | | [MatchNone](https://doc.ibexa.co/en/saas/search/criteria_reference/matchnone_criterion/index.md) | Returns no search results | Yes | Yes | Yes | Yes | | [ObjectStateId](https://doc.ibexa.co/en/saas/search/criteria_reference/objectstateid_criterion/index.md) | Object state ID | Yes | Yes | Yes | | | [ObjectStateIdentifier](https://doc.ibexa.co/en/saas/search/criteria_reference/objectstateidentifier_criterion/index.md) | Object state Identifier | Yes | Yes | Yes | | | [ParentLocationId](https://doc.ibexa.co/en/saas/search/criteria_reference/parentlocationid_criterion/index.md) | Location ID of a content item's parent | Yes | Yes | Yes | | | [ParentLocationRemoteId](https://doc.ibexa.co/en/saas/search/criteria_reference/parentlocationremoteId_criterion/index.md) | Location remote ID of a content item's parent | Yes | Yes | | | | [Priority](https://doc.ibexa.co/en/saas/search/criteria_reference/priority_criterion/index.md) | Location priority | | Yes | Yes | | | [RemoteId](https://doc.ibexa.co/en/saas/search/criteria_reference/remoteid_criterion/index.md) | Remote content ID | Yes | Yes | Yes | | | [SectionId](https://doc.ibexa.co/en/saas/search/criteria_reference/sectionid_criterion/index.md) | ID of the Section content is assigned to | Yes | Yes | Yes | Yes | | [SectionIdentifier](https://doc.ibexa.co/en/saas/search/criteria_reference/sectionidentifier_criterion/index.md) | Identifier of the Section content is assigned to | Yes | Yes | Yes | | | [Sibling](https://doc.ibexa.co/en/saas/search/criteria_reference/sibling_criterion/index.md) | Locations that are children of the same parent | Yes | Yes | Yes | | | [Subtree](https://doc.ibexa.co/en/saas/search/criteria_reference/subtree_criterion/index.md) | Location subtree | Yes | Yes | Yes | | | [TaxonomyEntryId](https://doc.ibexa.co/en/saas/search/criteria_reference/taxonomy_entry_id/index.md) | Content tagged with Entry ID | Yes | Yes | Yes | | | [TaxonomyNoEntries](https://doc.ibexa.co/en/saas/search/criteria_reference/taxonomy_no_entries/index.md) | Content with no entries assigned from a given taxonomy | Yes | Yes | Yes | | | [TaxonomySubtree](https://doc.ibexa.co/en/saas/search/criteria_reference/taxonomy_subtree/index.md) | Content assigned to a taxonomy entry or any of its descendants | Yes | Yes | | | | [UserEmail](https://doc.ibexa.co/en/saas/search/criteria_reference/useremail_criterion/index.md) | Email address of a User account | Yes | Yes | Yes | | | [UserId](https://doc.ibexa.co/en/saas/search/criteria_reference/userid_criterion/index.md) | User ID | Yes | Yes | Yes | | | [UserLogin](https://doc.ibexa.co/en/saas/search/criteria_reference/userlogin_criterion/index.md) | User login | Yes | Yes | Yes | | | [UserMetadata](https://doc.ibexa.co/en/saas/search/criteria_reference/usermetadata_criterion/index.md) | The creator or modifier of a content item | Yes | Yes | Yes | Yes | | [Visibility](https://doc.ibexa.co/en/saas/search/criteria_reference/visibility_criterion/index.md) | Whether the content item is visible or not | Yes | Yes | Yes | | ### Logical operators All Logical operators are supported by Content and Location Search. | Search Criterion | Search based on | | -------------------------------------------------------------------------------------------------- | ----------------------------------------------------------------------------------------------- | | [LogicalAnd](https://doc.ibexa.co/en/saas/search/criteria_reference/logicaland_criterion/index.md) | Implements a logical AND Criterion. It matches if ALL of the provided Criteria match. | | [LogicalNot](https://doc.ibexa.co/en/saas/search/criteria_reference/logicalnot_criterion/index.md) | Implements a logical NOT Criterion. It matches if the provided Criterion doesn't match. | | [LogicalOr](https://doc.ibexa.co/en/saas/search/criteria_reference/logicalor_criterion/index.md) | Implements a logical OR Criterion. It matches if at least one of the provided Criteria matches. | # Ancestor Criterion > For the complete documentation index, see [llms.txt](https://doc.ibexa.co/en/saas/llms.txt). Ancestor Search Criterion The `Ancestor` Search Criterion searches for content that is an ancestor of the provided location, including this location. ## Arguments - `value` - array of location pathStrings ## Example **XML** ```xml /81/82/ ``` **JSON** ```json "Query": { "Filter": { "AncestorCriterion": "/81/82/" } } ``` ## Use case You can use the `Ancestor` Search Criterion to create a list of breadcrumbs leading to a location, because it matches every ancestor of that location, including the location itself. # ContentId Criterion > For the complete documentation index, see [llms.txt](https://doc.ibexa.co/en/saas/llms.txt). ContentId Search Criterion The `ContentId` Search Criterion searches for content by its ID. ## Arguments - `value` - int(s) representing the Content ID(s) ## Example **XML** ```xml 1,52 ``` **JSON** ```json "Query": { "Filter": { "ContentIdCriterion": "1,52" } } ``` # ContentName Criterion > For the complete documentation index, see [llms.txt](https://doc.ibexa.co/en/saas/llms.txt). ContentName Search Criterion The [`ContentName` Search Criterion](https://github.com/ibexa/core/blob/6.0/src/contracts/Repository/Values/Content/Query/Criterion/ContentName.php) searches for content by its name. ## Arguments - `value` - string representing the content name, the wildcard character `*` can be used for partial search ## Example **XML** ```xml *phone ``` **JSON** ```json "Query": { "Filter": { "ContentNameCriterion": "*phone" } } ``` # ContentTypeGroupId Criterion > For the complete documentation index, see [llms.txt](https://doc.ibexa.co/en/saas/llms.txt). ContentTypeGroupId Search Criterion The `ContentTypeGroupId` Search Criterion searches for content based on the ID of its content type group. ## Arguments - `value` - int(s) representing the content type group ID(s) ## Example **XML** ```xml 1 ``` **JSON** ```json "Query": { "Filter": { "ContentTypeGroupIdCriterion": [1, 2] } } ``` ## Use case You can use the `ContentTypeGroupId` Criterion to query all Media content items. The default ID for the Media content type group is 3. # ContentTypeId Criterion > For the complete documentation index, see [llms.txt](https://doc.ibexa.co/en/saas/llms.txt). ContentTypeId Search Criterion The `ContentTypeId` Search Criterion searches for content based on the ID of its content type. ## Arguments - `value` - int(s) representing the content type ID(s) ## Example **XML** ```xml 44 ``` **JSON** ```json "Query": { "Filter": { "ContentTypeIdCriterion": 44 } } ``` # ContentTypeIdentifier Criterion > For the complete documentation index, see [llms.txt](https://doc.ibexa.co/en/saas/llms.txt). ContentTypeIdentifier Search Criterion The `ContentTypeIdentifier` Search Criterion searches for content based on the identifier of its content type. ## Arguments - `value` - string(s) representing the content type identifier(s) ## Example **XML** ```xml article ``` **JSON** ```json "Query": { "Filter": { "ContentTypeIdentifierCriterion": "article" } } ``` # CurrencyCode Criterion > For the complete documentation index, see [llms.txt](https://doc.ibexa.co/en/saas/llms.txt). CurrencyCode Search Criterion The `CurrencyCodeCriterion` Search Criterion searches for currencies by their codes. ## Arguments - `code` - string representing the currency code ## Limitations The `CurrencyCodeCriterion` Criterion isn't available in Solr or Elasticsearch engines. # Custom Field Criterion > For the complete documentation index, see [llms.txt](https://doc.ibexa.co/en/saas/llms.txt). Custom Field Search Criterion The `CustomField` Search Criterion searches for content or locations based on the contents of the search index fields. The allowed syntax and operator support might differ between search engines and the type of queried field. ## Arguments - `target` - string representing the identifier of the search index field - `operator` - one of Operator constants - `value` - the value to query for # CustomerGroupId Criterion > For the complete documentation index, see [llms.txt](https://doc.ibexa.co/en/saas/llms.txt). CustomerGroupId Search Criterion The `CustomerGroupId` Search Criterion searches for content based on the ID of its customer group. ## Arguments - `value` - int(s) representing the customer group ID(s) # DateMetadata Criterion > For the complete documentation index, see [llms.txt](https://doc.ibexa.co/en/saas/llms.txt). DateMetadata Search Criterion The `DateMetadata` Search Criterion searches for content based on the date when it was created or last modified. ## Arguments - `target` - indicating if publication or modification date should be queried, either `DateMetadata::CREATED` or `DateMetadata::PUBLISHED` (both with the same functionality), or `DateMetadata::MODIFIED` - `operator` - Operator constant (IN, EQ, GT, GTE, LT, LTE, BETWEEN) - `value` - indicating the date(s) that should be matched, provided as a UNIX timestamp (or array of timestamps) ## Example **XML** ```xml modified 1675681020 gte ``` **JSON** ```json "Query": { "Filter": { "DateMetadataCriterion": { "Target": "modified", "Value": 1675681020, "Operator": "gte" } } } ``` ## Use case You can use the `DateMetadata` Criterion to search for blog posts that have been created within the last week, by combining it with a content type Criterion and the `GTE` operator. # Depth Criterion > For the complete documentation index, see [llms.txt](https://doc.ibexa.co/en/saas/llms.txt). Depth Search Criterion The `Location\Depth` Search Criterion searches for locations based on their depth in the content tree. This Criterion is available only for Location Search. ## Arguments - `operator` - Operator constant (IN, EQ, GT, GTE, LT, LTE, BETWEEN) - `value` - int(s) representing the location depth(s) The `value` argument requires: - a list of ints for `Operator::IN` - exactly two ints for `Operator::BETWEEN` - a single int for other Operators # Field Criterion > For the complete documentation index, see [llms.txt](https://doc.ibexa.co/en/saas/llms.txt). Field Search Criterion The `Field` Search Criterion searches for content based on the content of one of its fields. ## Arguments - `target` - string representing the identifier of the field to query - `operator` - operator constant (IN, EQ, GT, GTE, LT, LTE, LIKE, BETWEEN, CONTAINS) - `value` - the value to query for The `LIKE` operator works together with wildcards (`*`). Without a wildcards its results are the same as for the `EQ` operator. The `CONTAINS` operator works with collection fields like the Country field type, enabling you to retrieve results when the query value is one of the values of the collection. Querying for a collection with the `EQ` operator returns result only when the whole collection equals the query values. ## Example **XML** ```xml name CONTAINS Platform ``` **JSON** ```json { "Query": { "Filter": { "Field": { "name": "name", "operator": "CONTAINS", "value": "Platform" } } } } ``` ## Use case You can use the `Field` Criterion to search for articles whose `name` field contains the word "Featured", by combining it with a content type Criterion and the `CONTAINS` operator. # FieldRelation Criterion > For the complete documentation index, see [llms.txt](https://doc.ibexa.co/en/saas/llms.txt). FieldRelation Search Criterion The `FieldRelation` Search Criterion searches for content based on the content items it has Relations to. ## Arguments - `target` - string representing the identifier of the Field containing Relations - `operator` - Operator constant (IN, EQ, GT, GTE, LT, LTE, BETWEEN) - `value` - array of ints representing the Relation content IDs to search for Use of IN means the Relation needs to have one of the provided IDs, while CONTAINS implies it needs to have all provided IDs. # Full-Text Criterion > For the complete documentation index, see [llms.txt](https://doc.ibexa.co/en/saas/llms.txt). Full-Text Search Criterion The `FullText` Search Criterion searches for content based on the full text content of its fields. ## Arguments - `value` - string to search for ## Supported syntax | Feature | Elasticsearch | Apache Solr | Legacy Search Engine (SQL) | | --------------------------------- | ------------- | ----------- | -------------------------- | | Boolean operators: AND (&&), OR ( | | ), NOT (!) | No\* | | Require/exclude operators: +, - | No | Yes | No | | Grouping with parentheses | No | Yes | No | | Phrase search with double quotes | No | Yes | No | | Asterisks (\*) as wildcards | No | Yes | Yes, limited\*\*\* | \* When using the Elasticsearch search engine, a full text query performs an OR query by default, while the OR and AND operators return unexpected results. \*\* When using the Legacy search engine, a full text query performs an OR query. \*\*\* Asterisk may only be located at the beginning or end of a query. ## Limitations When using the Legacy search engine, a full text query performs an OR query by default, and supports asterisks as wildcards located at the beginning or end of a query. When using the Elasticsearch search engine, a full text query performs an OR query by default, while the OR and AND operators return unexpected results. ## Example **XML** ```xml victory ``` **JSON** ```json "Query": { "Filter": { "FullTextCriterion": "victory" } } ``` ## Use cases Assume a full-text search for `(cup AND ba*ball) "breaking news"`, which combines grouping, the `AND` operator, a wildcard, and a quoted phrase. It returns content containing phrases such as "Breaking news", "Baseball world cup", "Basketball cup", or "Breaking news: Baseball world cup victory". It doesn't return content with phrases such as "Football world cup" or "Breaking sports news". # Image Criterion > For the complete documentation index, see [llms.txt](https://doc.ibexa.co/en/saas/llms.txt). Image Search Criterion The `Image` Search Criterion searches for image by specified image attributes. ## Arguments - `fieldDefIdentifier` - string representing the identifier of the field - `imageCriteriaData` - array representing image attributes. All attributes are optional. ## Example **XML** ```xml image image/png 0 2 100 1000 500 1500 portrait ``` **JSON** ```json "Query": { "Filter": { "ImageCriterion": { "fieldDefIdentifier": "image", "mimeTypes": "image/png", "size": { "max": 1.5 }, "width": { "max": 1000 }, "height": { "max": 1500 }, "orientation": "portrait" } } } OR "Query": { "Filter": { "ImageCriterion": { "fieldDefIdentifier": "image", "mimeTypes": [ "image/png", "image/jpeg" ], "size": { "min": 0, "max": 2 }, "width": { "min": 100, "max": 1000 }, "height": { "min": 500, "max": 1500 }, "orientation": [ "portrait", "landscape" ] } } } ``` # Image Dimension Criterion > For the complete documentation index, see [llms.txt](https://doc.ibexa.co/en/saas/llms.txt). Image Dimensions Search Criterion The `Dimensions` Search Criterion searches for image with specified dimensions. ## Arguments - `fieldDefIdentifier` - string representing the identifier of the field - `imageCriteriaData` - an array representing minimum and maximum values for width and height, expressed in pixels ## Example **XML** ```xml image 100 1000 500 1500 ``` **JSON** ```json "Query": { "Filter": { "ImageDimensionsCriterion": { "fieldDefIdentifier": "image", "width": { "min": 100, "max": 1000 }, "height": { "min": 500, "max": 1500 } } } } ``` # Image FileSize Criterion > For the complete documentation index, see [llms.txt](https://doc.ibexa.co/en/saas/llms.txt). Image FileSize Search Criterion The `FileSize` Search Criterion searches for image with specified size. ## Arguments - `fieldDefIdentifier` - string representing the identifier of the field - (optional) `minValue` - numeric representing minimum file size expressed in MB, default: 0 - (optional) `maxValue` - numeric representing maximum file size expressed in MB, default: `null` ## Example **XML** ```xml image 0 1.5 ``` **JSON** ```json "Query": { "Filter": { "ImageFileSizeCriterion":{ "fieldDefIdentifier": "image", "size": { "min": 0, "max": 1.5 } } } } ``` # Image Height Criterion > For the complete documentation index, see [llms.txt](https://doc.ibexa.co/en/saas/llms.txt). Image Height Search Criterion The `Height` Search Criterion searches for image with specified height. ## Arguments - `fieldDefIdentifier` - string representing the identifier of the field - (optional) `minValue` - int representing minimum file height expressed in pixels, default: 0 - (optional) `maxValue` - int representing maximum file height expressed in pixels, default: `null` # Image MimeType Criterion > For the complete documentation index, see [llms.txt](https://doc.ibexa.co/en/saas/llms.txt). Image MimeType Search Criterion The `MimeType` Search Criterion searches for image with specified mime type(s). ## Arguments - `fielDefIdentifier` - string representing the identifier of the field - `type` - string(s) representing mime type(s) ## Example **XML** ```xml image image/png ``` **JSON** ```json "Query": { "Filter": { "ImageMimeTypeCriterion": { "fieldDefIdentifier": "image", "type": "image/png" } } } OR "Query": { "Filter": { "ImageMimeTypeCriterion": { "fieldDefIdentifier": "image", "type": ["image/png", "image/jpeg"] } } } ``` # Image Orientation Criterion > For the complete documentation index, see [llms.txt](https://doc.ibexa.co/en/saas/llms.txt). Image Orientation Search Criterion The `Orientation` Search Criterion searches for image with specified orientation(s). Supported orientation values: landscape, portrait and square. ## Arguments - `fielDefIdentifier` - string representing the identifier of the field - `orientation` - strings representing orientations ## Example **XML** ```xml image landscape ``` **JSON** ```json "Query": { "Filter": { "ImageOrientationCriterion": { "fieldDefIdentifier": "image", "orientation": "landscape" } } } OR "Query": { "Filter": { "ImageOrientationCriterion": { "fieldDefIdentifier": "image", "orientation": ["portrait", "landscape"] } } } ``` # Image Width Criterion > For the complete documentation index, see [llms.txt](https://doc.ibexa.co/en/saas/llms.txt). Image Width Search Criterion The `Width` Search Criterion searches for image with specified width. ## Arguments - `fieldDefIdentifier` - string representing the identifier of the field - (optional) `minValue` - int representing minimum file width expressed in pixels, default: 0 - (optional) `maxValue` - int representing maximum file width expressed in pixels, default: `null` # IsBookmarked Criterion > For the complete documentation index, see [llms.txt](https://doc.ibexa.co/en/saas/llms.txt). IsBookmarked Search Criterion The `IsBookmarked` Search Criterion searches for location based on whether it's bookmarked or not. It works with current user reference. This Criterion is available only for location Search. ## Arguments - `value` - bool representing whether to search for bookmarked location (default `true`) or not bookmarked location (`false`) ## Example **XML** ```xml true ``` **JSON** ```json "Query": { "Filter": { "IsBookmarkedCriterion": true } } ``` # IsContainer Criterion > For the complete documentation index, see [llms.txt](https://doc.ibexa.co/en/saas/llms.txt). IsContainer Search Criterion The `IsContainer` Search Criterion searches for content items based on whether they are containers (i.e., can contain other content items). ## Arguments - `value` – boolean (optional, default: `true`). If `true`, searches for content that is a container. If `false`, searches for content that is not a container. # IsCurrencyEnabledCriterion Criterion > For the complete documentation index, see [llms.txt](https://doc.ibexa.co/en/saas/llms.txt). IsCurrencyEnabledCriterion Search Criterion The `IsCurrencyEnabledCriterion` Search Criterion searches for currencies that are enabled in the system. ## Arguments - (optional) `enabled` - bool representing whether to search for enabled (default `true`), or disabled Currencies (`false`) ## Limitations The `IsCurrencyEnabledCriterion` Criterion isn't available in Solr or Elasticsearch engines. # IsFieldEmpty Criterion > For the complete documentation index, see [llms.txt](https://doc.ibexa.co/en/saas/llms.txt). IsFieldEmpty Search Criterion The `IsFieldEmpty` Search Criterion searches for content based on whether a specified field is empty or not. ## Arguments - `fieldDefinitionIdentifier` - string representing the identifier of the field - (optional) `value` - bool representing whether to search for empty (default `true`), or non-empty fields (`false`) ## Limitations The Richtext field type (`ibexa_richtext`) isn't searchable in the Legacy search engine. The `IsFieldEmpty` criterion doesn't work for [Taxonomy entry assignment](https://doc.ibexa.co/en/saas/content_management/field_types/field_type_reference/taxonomyentryassignmentfield/index.md) fields. For this use case, use [`TaxonomyNoEntries`](https://doc.ibexa.co/en/saas/search/criteria_reference/taxonomy_no_entries/index.md) instead. ## Use case You can use the `IsFieldEmpty` Criterion to search for articles that don't have an image, by combining it with a content type Criterion and targeting the `image` field. # IsMainLocation Criterion > For the complete documentation index, see [llms.txt](https://doc.ibexa.co/en/saas/llms.txt). IsMainLocation Search Criterion The `IsMainLocation` Search Criterion searches for locations based on whether they're the main location of a content item or not. This Criterion is available only for Location Search. ## Arguments - `value` - `IsMainLocation::MAIN` (0) or `IsMainLocation::NOT_MAIN` (1), representing whether to search for a main or not main location # IsProductBased Criterion > For the complete documentation index, see [llms.txt](https://doc.ibexa.co/en/saas/llms.txt). IsProductBased Search Criterion The `IsProductBased` Search Criterion searches for content that plays the role of a Product. # IsUserBased Criterion > For the complete documentation index, see [llms.txt](https://doc.ibexa.co/en/saas/llms.txt). IsUserBased Search Criterion The `IsUserBased` Search Criterion searches for content that plays the role of a User account. > **Note: Note** > > In the default setup only the user content type is treated as user accounts. ## Arguments - (optional) `value` - bool representing whether to search for User-based (default `true`) or non-User-based content ## Limitations The `IsUserBased` Criterion isn't available in Solr or Elasticsearch engines. ## Example **XML** ```xml false ``` **JSON** ```json "Query": { "Filter": { "IsUserBasedCriterion": "false" } } ``` # IsUserEnabled Criterion > For the complete documentation index, see [llms.txt](https://doc.ibexa.co/en/saas/llms.txt). IsUserEnabled Search Criterion The `IsUserEnabled` Search Criterion searches for user accounts that are enabled or disabled. ## Arguments - (optional) `value` - bool representing whether to search for enabled (default `true`) or disabled user accounts ## Example **XML** ```xml true ``` **JSON** ```json "Query": { "Filter": { "IsUserEnabledCriterion": "true" } } ``` # LanguageCode Criterion > For the complete documentation index, see [llms.txt](https://doc.ibexa.co/en/saas/llms.txt). LanguageCode Search Criterion The `LanguageCode` Search Criterion searches for content based on whether it's translated into the selected language. ## Arguments - `value` - string(s) representing the language codes to search for - (optional) `matchAlwaysAvailable` - bool representing whether content with the `alwaysAvailable` flag should be returned even if it doesn't contain the selected language (default `true`) ## Example **XML** ```xml eng-GB ``` **JSON** ```json "Query": { "Filter": { "LanguageCodeCriterion": "eng-GB" } } ``` ## Use case You can use the `LanguageCode` Criterion to search for articles that are lacking a translation into a specific language, by negating it and setting `matchAlwaysAvailable` to `false`. # LocationId Criterion > For the complete documentation index, see [llms.txt](https://doc.ibexa.co/en/saas/llms.txt). LocationId Search Criterion The `LocationId` Search Criterion searches for content based in the location ID. ## Arguments - `value` - int(s) representing the location ID(s) ## Example **XML** ```xml 62 ``` **JSON** ```json "Query": { "Filter": { "LocationIdCriterion": "62" } } ``` # LocationRemoteId Criterion > For the complete documentation index, see [llms.txt](https://doc.ibexa.co/en/saas/llms.txt). LocationRemoteId Search Criterion The `LocationRemoteId` Search Criterion searches for content based in the location remote ID. ## Arguments - `value` - string(s) representing the location remote ID(s) ## Example **XML** ```xml 3aaeefdb0ae573ac91f6d6ea78d230b7 ``` **JSON** ```json "Query": { "Filter": { "LocationRemoteIdCriterion": "3aaeefdb0ae573ac91f6d6ea78d230b7" } } ``` # MapLocationDistance Criterion > For the complete documentation index, see [llms.txt](https://doc.ibexa.co/en/saas/llms.txt). MapLocationDistance Search Criterion The `MapLocationDistance` Search Criterion searches content based on the distance between the location contained in a MapLocation field and the provided coordinates. ## Arguments - `target` - string representing the field definition identifier - `operator` - Operator constant (IN, EQ, GT, GTE, LT, LTE, BETWEEN) - `distance` - float(s) representing the distances between the map location in the field and the location provided in `latitude` and `longitude` arguments - `latitude` - float representing the latitude of the location to calculate distance to - `longitude` - float representing the longitude of the location to calculate distance to The `distance` argument requires: - a list of floats for `Operator::IN` or `Operator::BETWEEN` - a single float for other Operators # MatchAll Criterion > For the complete documentation index, see [llms.txt](https://doc.ibexa.co/en/saas/llms.txt). MatchAll Search Criterion The `MatchAll` content and `MatchAll` product search criteria are auxiliary criteria that returns all search results. They're used internally when no filter or query is provided on a Query object. The criteria take no arguments. # MatchNone Criterion > For the complete documentation index, see [llms.txt](https://doc.ibexa.co/en/saas/llms.txt). MatchNone Search Criterion The `MatchNone` Search Criterion is an auxiliary Criterion that returns no search results. It's used internally when no filter or query is provided on a Query object. The Criterion takes no arguments. # ObjectStateId Criterion > For the complete documentation index, see [llms.txt](https://doc.ibexa.co/en/saas/llms.txt). ObjectStateId Search Criterion The `ObjectStateId` Search Criterion searches for content based on its object state ID. ## Arguments - `value` - int(s) representing the object state ID(s) ## Example **XML** ```xml 1 ``` **JSON** ```json "Query": { "Filter": { "ObjectStateIdCriterion": "1" } } ``` # ObjectStateIdentifier Criterion > For the complete documentation index, see [llms.txt](https://doc.ibexa.co/en/saas/llms.txt). ObjectStateIdentifier Search Criterion The `ObjectStateIdentifier` Search Criterion searches for content based on its object state identifier. ## Arguments - `value` - string(s) representing the object state identifier(s) - `target` (optional for PHP) - string representing the object state group ## Example **XML** ```xml not_locked ibexa_lock ``` **JSON** ```json { "Query": { "Filter": { "ObjectStateIdentifierCriterion": { "value": "not_locked", "target": "ibexa_lock" } } } } ``` # ParentLocationId Criterion > For the complete documentation index, see [llms.txt](https://doc.ibexa.co/en/saas/llms.txt). ParentLocationId Search Criterion The `ParentLocationId` Search Criterion searches for content based on the Location ID of its parent. ## Arguments - `value` - int(s) representing the parent location IDs ## Example **XML** ```xml [81, 82] ``` **JSON** ```json "Query": { "Filter": { "ParentLocationIdCriterion": [69, 72] } } ``` ## Use case You can use the `ParentLocationId` Search Criterion to list blog posts contained in a blog, by combining it with the `Visibility` Criterion so that hidden posts are excluded. # ParentLocationRemoteId Criterion > For the complete documentation index, see [llms.txt](https://doc.ibexa.co/en/saas/llms.txt). ParentLocationRemoteId Search Criterion The `ParentLocationRemoteId` Search Criterion searches for content based on the location remote ID of its parent. ## Arguments - `value` - int(s) representing the parent location remote IDs ### REST API **XML** ```xml abab615dcf26699a4291657152da4337 ``` **JSON** ```json "Query": { "Filter": { "ParentLocationRemoteIdCriterion": "abab615dcf26699a4291657152da4337" } } ``` # Priority Criterion > For the complete documentation index, see [llms.txt](https://doc.ibexa.co/en/saas/llms.txt). Priority Search Criterion The `Location\Priority` Search Criterion searches for locations based on their priority. This Criterion is available only for Location Search. ## Arguments - `operator`- Operator constant (GT, GTE, LT, LTE, BETWEEN) - `value` - int(s) representing the priority The `value` argument requires: - a list of ints for `Operator::BETWEEN` - a single int for other Operators # RemoteId / ContentRemoteId Criterion > For the complete documentation index, see [llms.txt](https://doc.ibexa.co/en/saas/llms.txt). RemoteId / ContentRemoteId Search Criterion The `RemoteId` / `ContentRemoteId` Search Criterion searches for content based on its remote content ID. ## Arguments - `value` - string(s) representing the remote IDs ## Example **XML** ```xml abab615dcf26699a4291657152da4337 ``` **JSON** ```json "Query": { "Filter": { "ContentRemoteIdCriterion": "abab615dcf26699a4291657152da4337" } } ``` # SectionId Criterion > For the complete documentation index, see [llms.txt](https://doc.ibexa.co/en/saas/llms.txt). SectionId Search Criterion The `SectionId` Search Criterion searches for content based on the ID of the Section it's assigned to. ## Arguments - `value` - int(s) representing the IDs of the Section(s) ## Example **XML** ```xml 3 ``` **JSON** ```json "Query": { "Filter": { "SectionIdCriterion": "3" } } ``` # SectionIdentifier Criterion > For the complete documentation index, see [llms.txt](https://doc.ibexa.co/en/saas/llms.txt). SectionIdentifier Search Criterion The `SectionIdentifier` Search Criterion searches for content based on the identifier of the Section it's assigned to. ## Arguments - `value` - string(s) representing the identifiers of the Section(s) ## Example **XML** ```xml sports ``` **JSON** ```json "Query": { "Filter": { "SectionIdentifierCriterion": "sports" } } ``` # Sibling Criterion > For the complete documentation index, see [llms.txt](https://doc.ibexa.co/en/saas/llms.txt). Sibling Search Criterion The `Sibling` Search Criterion searches for content under the same parent as the indicated location. ## Arguments - `locationId` - int representing the location ID - `parentLocationId` - int representing the parent location ID ## Example **XML** ```xml 85 81 ``` **JSON** ```json "Query": { "Filter": { "SiblingCriterion": { "locationId": 85, "parentLocationId": 81 } } } ``` # Subtree Criterion > For the complete documentation index, see [llms.txt](https://doc.ibexa.co/en/saas/llms.txt). Subtree Search Criterion The `Subtree` Search Criterion searches for content based on its location ID subtree path. It returns the content item and all the content items below it in the subtree. ## Arguments - `value` - string(s) representing the pathstring(s) to search for ## Example **XML** ```xml /1/2/71/ ``` **JSON** ```json "Query": { "Filter": { "SubtreeCriterion": "/1/2/71/" } } ``` # TaxonomyEntryId Criterion > For the complete documentation index, see [llms.txt](https://doc.ibexa.co/en/saas/llms.txt). TaxonomyEntryId Search Criterion The `TaxonomyEntryId` Search Criterion searches for content based on the ID of the Taxonomy Entry it's assigned to. ## Arguments - `value` - int(s) representing the IDs of the Tag(s) # TaxonomyNoEntries Criterion > For the complete documentation index, see [llms.txt](https://doc.ibexa.co/en/saas/llms.txt). TaxonomyNoEntries Search Criterion The `TaxonomyNoEntries` Search Criterion searches for content that has no entries assigned from the specified [taxonomy](https://doc.ibexa.co/en/saas/content_management/taxonomy/taxonomy/index.md). Use it when you need to find content items to which no taxonomy entries have been assigned (for example, articles without tags). It's available for all supported search engines. ## Arguments - `taxonomy` - `string` representing the identifier of the taxonomy (for example, `tags` or `categories`) # TaxonomySubtree Criterion > For the complete documentation index, see [llms.txt](https://doc.ibexa.co/en/saas/llms.txt). TaxonomySubtree Search Criterion The `TaxonomySubtree` Search Criterion searches for content assigned to the specified [taxonomy](https://doc.ibexa.co/en/saas/content_management/taxonomy/taxonomy/index.md) entry or any of its descendants. ## Arguments - `taxonomyEntryId` - `int` representing the ID of the taxonomy entry that is the root of the subtree # UserEmail Criterion > For the complete documentation index, see [llms.txt](https://doc.ibexa.co/en/saas/llms.txt). UserEmail Search Criterion The `UserEmail` Search Criterion searches for content based on the email assigned to the user account. ## Arguments - `value` - string(s) representing the User email(s) - (optional) `operator` - operator constant (IN, EQ, LIKE) ## Limitations Solr search engine and Elasticsearch support IN and EQ operators only. ## Example **XML** ```xml j.black* ``` **JSON** ```json "Query": { "Filter": { "UserEmailCriterion": "j.black*" } } ``` # UserId Criterion > For the complete documentation index, see [llms.txt](https://doc.ibexa.co/en/saas/llms.txt). UserId Search Criterion The `UserId` Search Criterion searches for content based on the User ID. ## Arguments - `value` - int(s) representing the User ID(s) ## Example **XML** ```xml 14 ``` **JSON** ```json "Query": { "Filter": { "UserIdCriterion": "14" } } ``` # UserLogin Criterion > For the complete documentation index, see [llms.txt](https://doc.ibexa.co/en/saas/llms.txt). UserLogin Search Criterion The `UserLogin` Search Criterion searches for content based on the User ID. ## Arguments - `value` - string(s) representing the User logins(s) - (optional) `operator` - operator constant (IN, EQ, LIKE) ## Limitations Solr search engine and Elasticsearch support IN and EQ operators only. ## Example **XML** ```xml johndoe ``` **JSON** ```json "Query": { "Filter": { "UserLoginCriterion": "johndoe" } } ``` # UserMetadata Criterion > For the complete documentation index, see [llms.txt](https://doc.ibexa.co/en/saas/llms.txt). UserMetadata Search Criterion The `UserMetadata` Search Criterion searches for content based on its creator or modifier. ## Arguments - `target` - UserMetadata constant (OWNER, GROUP, MODIFIER); GROUP means the user group of the content item's creator - `operator` - Operator constant (EQ, IN) - `value` - int(s) representing the User IDs or user group IDs (in case of the UserMetadata::GROUP target) ## Example **XML** ```xml GROUP EQ 12 ``` **JSON** ```json { "Query": { "Filter": { "UserMetadataCriterion": { "target": "GROUP", "operator": "EQ", "value": 12 } } } } ``` ## Use case You can use the `UserMetadata` Criterion to search for blog posts created by a specific user group, such as Contributor, by using the `GROUP` target with the `EQ` operator. # Visibility Criterion > For the complete documentation index, see [llms.txt](https://doc.ibexa.co/en/saas/llms.txt). Visibility Search Criterion The `Visibility` Search Criterion searches for content based on whether it's visible or not. This Criterion takes into account both hiding content and hiding locations. When used with Content Search, the Criterion takes into account all assigned locations. This means that hidden content is returned if it has at least one visible location. Use Location Search to avoid this. ## Arguments - `value` - Visibility constant (VISIBLE, HIDDEN) ## Example **XML** ```xml HIDDEN ``` **JSON** ```json "Query": { "Filter": { "VisibilityCriterion": "HIDDEN" } } ``` # LogicalAnd Criterion > For the complete documentation index, see [llms.txt](https://doc.ibexa.co/en/saas/llms.txt). LogicalAnd Search Criterion The `LogicalAnd` Search Criterion matches content if all provided Criteria match. When querying for products, use LogicalAnd instead. ## Arguments - `criterion` - a set of Criteria combined by the logical operator ## Example **XML** ```xml article news ``` **JSON** ```json { "Query": { "Filter": { "AND": { "ContentTypeIdentifierCriterion": "article", "SectionIdentifierCriterion": "news" } } } } ``` # LogicalNot Criterion > For the complete documentation index, see [llms.txt](https://doc.ibexa.co/en/saas/llms.txt). LogicalNot Search Criterion The `LogicalNot` Search Criterion matches content URL if the provided Criterion doesn't match. It takes only one Criterion in the array parameter. ## Arguments - `criterion` - represents the Criterion that should be negated ## Example **XML** ```xml article ``` **JSON** ```json { "Query": { "Criterion": { "LogicalNotCriterion": { "ContentTypeIdentifierCriterion": "article" } } } } ``` # LogicalOr Criterion > For the complete documentation index, see [llms.txt](https://doc.ibexa.co/en/saas/llms.txt). LogicalOr Search Criterion The `LogicalOr` Search Criterion matches content if at least one of the provided Criteria matches. When querying for products, use LogicalOr instead. ## Arguments - `criterion` - a set of Criteria combined by the logical operator ## Example **XML** ```xml article news ``` **JSON** ```json { "Query": { "Filter": { "OR": { "ContentTypeIdentifierCriterion": "article", "SectionIdentifierCriterion": "news" } } } } ``` # Content Type Search Criteria reference > For the complete documentation index, see [llms.txt](https://doc.ibexa.co/en/saas/llms.txt). Content Type Search Criteria help define and fine-tune search queries for content types. | Criterion | Description | | ------------------------- | ----------------------------------------------------------------------------------------------- | | ContainsFieldDefinitionId | Matches content types that contain a field definition with the specified ID. | | ContentTypeGroupId | Matches content types by their assigned group ID. | | ContentTypeGroupName | Matches content types by the name of their assigned group. | | ContentTypeId | Matches content types by their ID. | | ContentTypeIdentifier | Matches content types by their identifier. | | IsSystem | Matches content types based on whether the group they belong to is system or not. | | LogicalAnd | Implements a logical AND Criterion. It matches if ALL of the provided Criteria match. | | LogicalOr | Implements a logical OR Criterion. It matches if at least one of the provided Criteria matches. | | LogicalNot | Implements a logical NOT Criterion. It matches if the provided Criterion doesn't match. | # Product Search Criteria reference > For the complete documentation index, see [llms.txt](https://doc.ibexa.co/en/saas/llms.txt). Product Search Criteria Product Search Criteria are supported by product and product variant search. - `ProductServiceInterface::findProducts()` - `ProductServiceInterface::findProductVariants()` - `ProductServiceInterface::findVariants()` Search Criterion let you filter product by specific attributes, for example, color, availability, or price. ## Product Search Criteria To query for products coming from Quable, see [Quable](https://doc.ibexa.co/en/saas/product_catalog/quable/quable/index.md) for details about the integration. | Search Criterion | Search based on | Local product catalog | Quable | | ---------------------------------------------------------------------------------------------------------------------------------------------- | ---------------------------------------------------------------------- | --------------------- | ------ | | [AttributeGroupIdentifier](https://doc.ibexa.co/en/saas/search/criteria_reference/attributegroupidentifier_criterion/index.md) | Value of product's attribute group identifier | Yes | | | [AttributeName](https://doc.ibexa.co/en/saas/search/criteria_reference/attributename_criterion/index.md) | Value of product's attribute name | Yes | | | [BasePrice](https://doc.ibexa.co/en/saas/search/criteria_reference/baseprice_criterion/index.md) | Product's base price | Yes | | | [CatalogIdentifier](https://doc.ibexa.co/en/saas/search/criteria_reference/catalogidentifier_criterion/index.md) | Catalog's identifier | Yes | | | [CatalogName](https://doc.ibexa.co/en/saas/search/criteria_reference/catalogname_criterion/index.md) | Catalog's name | Yes | | | [CatalogStatus](https://doc.ibexa.co/en/saas/search/criteria_reference/catalogstatus_criterion/index.md) | Catalog's status | Yes | | | [CheckboxAttribute](https://doc.ibexa.co/en/saas/search/criteria_reference/checkboxattribute_criterion/index.md) | Value of product's checkbox attribute | Yes | | | [ColorAttribute](https://doc.ibexa.co/en/saas/search/criteria_reference/colorattribute_criterion/index.md) | Value of product's color attribute | Yes | | | [CreatedAt](https://doc.ibexa.co/en/saas/search/criteria_reference/createdat_criterion/index.md) | Date and time when product was created | Yes | Yes | | [CreatedAtRange](https://doc.ibexa.co/en/saas/search/criteria_reference/createdatrange_criterion/index.md) | Date and time range when product was created | Yes | | | [CustomPrice](https://doc.ibexa.co/en/saas/search/criteria_reference/customprice_criterion/index.md) | Product's custom price | Yes | | | [DateTimeAttribute](https://doc.ibexa.co/en/saas/search/criteria_reference/datetimeattribute_criterion/index.md) | Value of product's date and time attribute | Yes | | | [DateTimeAttributeRange](https://doc.ibexa.co/en/saas/search/criteria_reference/datetimeattributerange_criterion/index.md) | Value of product's date and time attribute and given time range | Yes | | | [FloatAttribute](https://doc.ibexa.co/en/saas/search/criteria_reference/floatattribute_criterion/index.md) | Value of product's float attribute | Yes | | | [FloatAttributeRange](https://doc.ibexa.co/en/saas/search/criteria_reference/floatattributerange_criterion/index.md) | Value of product's float attribute | Yes | | | [IntegerAttribute](https://doc.ibexa.co/en/saas/search/criteria_reference/integerattribute_criterion/index.md) | Value of product's integer attribute | Yes | | | [IntegerAttributeRange](https://doc.ibexa.co/en/saas/search/criteria_reference/integerattributerange_criterion/index.md) | Value of product's integer attribute | Yes | | | [IsVirtual](https://doc.ibexa.co/en/saas/search/criteria_reference/isvirtual_criterion/index.md) | Product type (virtual or physical) | Yes | | | [LogicalAnd](https://doc.ibexa.co/en/saas/search/criteria_reference/logicaland_criterion/index.md) | Composite criterion to group multiple criteria using the AND condition | Yes | Yes | | [LogicalOr](https://doc.ibexa.co/en/saas/search/criteria_reference/logicalor_criterion/index.md) | Composite criterion to group multiple criteria using the OR condition | Yes | | | [MatchAll](https://doc.ibexa.co/en/saas/search/criteria_reference/matchall_criterion/index.md) | All products | Yes | Yes | | [ProductAvailability](https://doc.ibexa.co/en/saas/search/criteria_reference/productavailability_criterion/index.md) | Product's availability | Yes | | | [ProductCategory](https://doc.ibexa.co/en/saas/search/criteria_reference/productcategory_criterion/index.md) | Product category assigned to product | Yes | Yes | | [ProductCategorySubtree](https://doc.ibexa.co/en/saas/search/criteria_reference/productcategorysubtree_criterion/index.md) | Product category subtree assigned to product | Yes | Yes | | [ProductCode](https://doc.ibexa.co/en/saas/search/criteria_reference/productcode_criterion/index.md) | Product's code | Yes | Yes | | [ProductName](https://doc.ibexa.co/en/saas/search/criteria_reference/productname_criterion/index.md) | Product's name | Yes | Yes | | [ProductStock](https://doc.ibexa.co/en/saas/search/criteria_reference/productstock_criterion/index.md) | Product's numerical stock | Yes | | | [ProductStockRange](https://doc.ibexa.co/en/saas/search/criteria_reference/productstockrange_criterion/index.md) | Product's numerical stock | Yes | | | [ProductType](https://doc.ibexa.co/en/saas/search/criteria_reference/producttype_criterion/index.md) | Product type | Yes | Yes | | [RangeMeasurementAttributeMaximum](https://doc.ibexa.co/en/saas/search/criteria_reference/rangemeasurementattributemaximum_criterion/index.md) | Maximum value of product's measurement range attribute | Yes | | | [RangeMeasurementAttributeMinimum](https://doc.ibexa.co/en/saas/search/criteria_reference/rangemeasurementattributeminimum_criterion/index.md) | Minimum value of product's measurement range attribute | Yes | | | [SelectionAttribute](https://doc.ibexa.co/en/saas/search/criteria_reference/selectionattribute_criterion/index.md) | Value of product's selection attribute | Yes | | | [SimpleMeasurementAttribute](https://doc.ibexa.co/en/saas/search/criteria_reference/simplemeasurementattribute_criterion/index.md) | Value of product's single measurement attribute | Yes | | | [SymbolAttribute](https://doc.ibexa.co/en/saas/search/criteria_reference/symbolattribute_criterion/index.md) | Value of product's symbol attribute | Yes | | | [UpdatedAt](https://doc.ibexa.co/en/saas/search/criteria_reference/updated_at_criterion/index.md) | Product modification date | Yes | Yes | | [UpdatedAtRange](https://doc.ibexa.co/en/saas/search/criteria_reference/updated_at_range_criterion/index.md) | Product modification date range | Yes | | # AttributeName Criterion > For the complete documentation index, see [llms.txt](https://doc.ibexa.co/en/saas/llms.txt). AttributeName Search Criterion The `AttributeName` Search Criterion searches for products by the value of their attribute name. ## Arguments - `value` - string representing the attribute's name ## Example **XML** ```xml measure ``` **JSON** ```json { "AttributeQuery": { "Query": { "AttributeNameCriterion": "measure" } } } ``` # AttributeGroupIdentifier Criterion > For the complete documentation index, see [llms.txt](https://doc.ibexa.co/en/saas/llms.txt). AttributeGroupIdentifier Search Criterion The `AttributeGroupIdentifier` Search Criterion searches for products by the value of their attribute group identifier. ## Arguments - `value` - string representing the attribute's identifier ## Example **XML** ```xml attribute_group ``` **JSON** ```json { "AttributeQuery": { "Query": { "AttributeGroupIdentifier": "attribute_group" } } } ``` # BasePrice Criterion > For the complete documentation index, see [llms.txt](https://doc.ibexa.co/en/saas/llms.txt). BasePrice Search Criterion The `BasePrice` Search Criterion searches for products by their base price. ## Arguments - `value` - a `Money\Money` object representing the price in a specific currency - (optional) `operator` - Operator constant (EQ, GT, GTE, LT, LTE, default EQ) ## Limitations The `BasePrice` Criterion isn't available in the Legacy Search engine. # CatalogIdentifier Criterion > For the complete documentation index, see [llms.txt](https://doc.ibexa.co/en/saas/llms.txt). CatalogIdentifier Search Criterion The `CatalogIdentifier` Search Criterion searches for a catalog by the value of its identifier. ## Arguments - `value` - string representing the catalog's identifier ## Example **XML** ```xml catalog_1 ``` **JSON** ```json { "CatalogQuery": { "Query": { "CatalogIdentifierCriterion": "catalog_1", } } } ``` # CatalogName Criterion > For the complete documentation index, see [llms.txt](https://doc.ibexa.co/en/saas/llms.txt). CatalogName Search Criterion The `CatalogName` Search Criterion searches for catalogs by the value of their name. ## Arguments - `value` - string representing the catalog's name ## Example **XML** ```xml Furniture ``` **JSON** ```json { "CatalogQuery": { "Query": { "CatalogNameCriterion": "Furniture" } } } ``` # CatalogStatus Criterion > For the complete documentation index, see [llms.txt](https://doc.ibexa.co/en/saas/llms.txt). CatalogStatus Search Criterion The `CatalogStatus` Search Criterion searches for catalogs by the value of their status. ## Arguments - `value` - string representing the catalog's status ## Example **XML** ```xml published ``` **JSON** ```json { "CatalogQuery": { "Query": { "CatalogStatusCriterion": "published" } } } ``` # CheckboxAttribute Criterion > For the complete documentation index, see [llms.txt](https://doc.ibexa.co/en/saas/llms.txt). CheckboxAttribute Search Criterion The `CheckboxAttribute` Search Criterion searches for products by the value of their checkbox attribute. ## Arguments - `identifier` - string representing the attribute - `value` - bool representing the attribute value # ColorAttribute Criterion > For the complete documentation index, see [llms.txt](https://doc.ibexa.co/en/saas/llms.txt). ColorAttribute Search Criterion The `ColorAttribute` Search Criterion searches for products by the value of their color attribute. ## Arguments - `identifier` - string representing the attribute - `value` - array of strings representing the attribute values ## Example **XML** ```xml color #000000 ``` **JSON** ```json { "AttributeQuery": { "Query": { "ColorAttributeCriterion": { "identifier": "color", "value": ["#000000"] }, } } } ``` # CreatedAt Criterion > For the complete documentation index, see [llms.txt](https://doc.ibexa.co/en/saas/llms.txt). CreatedAt Search Criterion The `CreatedAt` Search Criterion searches for products based on the date when they were created. ## Arguments - `createdAt` (PHP), `created_at` (REST) - indicating the date that should be matched, provided as a `DateTimeInterface` object in PHP, or as a string acceptable by `DateTime` constructor in REST - `operator` - Operator constant (EQ, GT, GTE, LT, LTE) in PHP or its value in REST ## Example **XML** ```xml 2023-06-12 >= ``` **JSON** ```json { "ProductQuery": { "Filter": { "CreatedAtCriterion": { "created_at": "2023-06-12", "operator": ">=" } } } } ``` # CreatedAtRange Criterion > For the complete documentation index, see [llms.txt](https://doc.ibexa.co/en/saas/llms.txt). CreatedAtRange Search Criterion The `CreatedAtRange` Search Criterion searches for products based on the date range when they were created. ## Arguments - `min` - indicating the beginning of the date range, provided as a `DateTimeInterface` object - `max` - indicating the end of the date range, provided as a `DateTimeInterface` object ## Example **XML** ```xml 2023-06-12 2023-06-20 ``` **JSON** ```json { "ProductQuery": { "Filter": { "CreatedAtRange": { "min": "2023-06-12", "max": "2023-06-20" } } } } ``` # CustomPrice Criterion > For the complete documentation index, see [llms.txt](https://doc.ibexa.co/en/saas/llms.txt). CustomPrice Search Criterion The `CustomPrice` Search Criterion searches for products by their custom price for a specific customer group. ## Arguments - `value` - a `Money\Money` object representing the price in a specific currency - (optional) `operator` - Operator constant (EQ, GT, GTE, LT, LTE, default EQ) - (optional) `customerGroup` - a `CustomerGroupInterface` object representing the customer group to show prices for. If you don't provide a customer group, the query uses the group related to the current user. ## Limitations The `CustomPrice` Criterion isn't available in the Legacy Search engine. # DateTimeAttribute criterion > For the complete documentation index, see [llms.txt](https://doc.ibexa.co/en/saas/llms.txt). DateTimeAttribute Criterion The `DateTimeAttribute Search Criterion` searches for products by value of a specified attribute, based on the [date and time attribute](https://doc.ibexa.co/en/saas/product_catalog/attributes/date_and_time/index.md) type. ## Arguments - `identifier` - attribute's identifier (string) - `value` - searched value ([DateTimeImmutable](https://www.php.net/manual/en/class.datetimeimmutable.php)) ## Operators The following operators are supported: - `FieldValueCriterion::COMPARISON_EQ` - `FieldValueCriterion::COMPARISON_NEQ` - `FieldValueCriterion::COMPARISON_LT` - `FieldValueCriterion::COMPARISON_LTE` - `FieldValueCriterion::COMPARISON_GT` - `FieldValueCriterion::COMPARISON_GTE` # DateTimeAttributeRange criterion > For the complete documentation index, see [llms.txt](https://doc.ibexa.co/en/saas/llms.txt). DateTimeAttributeRange Criterion The `DateTimeAttributeRange Search Criterion` searches for products by value of a specified attribute, which must be based on the [date and time attribute](https://doc.ibexa.co/en/saas/product_catalog/attributes/date_and_time/index.md) type. ## Arguments - `identifier` - attribute's identifier (string) - `min` - lower range value (inclusive) of [DateTimeImmutable](https://www.php.net/manual/en/class.datetimeimmutable.php) type. Optional. - `max` - upper range value (inclusive) of [DateTimeImmutable](https://www.php.net/manual/en/class.datetimeimmutable.php) type. Optional. # FloatAttribute Criterion > For the complete documentation index, see [llms.txt](https://doc.ibexa.co/en/saas/llms.txt). FloatAttribute Search Criterion The `FloatAttribute` Search Criterion searches for products by the value of their float attribute. ## Arguments - `identifier` - string representing the attribute - `value` - string representing the attribute value ## Example **XML** ```xml length 16.5 ``` **JSON** ```json { "AttributeQuery": { "Query": { "FloatAttributeCriterion": { "identifier": "length", "value": 16.5 } } } } ``` # FloatAttributeRange Criterion > For the complete documentation index, see [llms.txt](https://doc.ibexa.co/en/saas/llms.txt). FloatAttributeRange Search Criterion The `FloatAttributeRange` Search Criterion searches for products by the range of values of their float attribute. ## Arguments - `identifier` - string representing the attribute - `min` - indicating the beginning of the range - `max` - indicating the end of the date range ## Example **XML** ```xml length 16.5 25 ``` **JSON** ```json { "AttributeQuery": { "Query": { "FloatAttributeRangeCriterion": { "identifier": "length", "min": 16.5, "max": 25 } } } } ``` # IntegerAttribute Criterion > For the complete documentation index, see [llms.txt](https://doc.ibexa.co/en/saas/llms.txt). IntegerAttribute Search Criterion The `IntegerAttribute` Search Criterion searches for products by the value of their integer attribute. ## Arguments - `identifier` - string representing the attribute - `value` - string representing the attribute value ## Example **XML** ```xml size 38 ``` **JSON** ```json { "AttributeQuery": { "Query": { "IntegerAttributeCriterion": { "identifier": "size", "value": 38 } } } } ``` # IntegerAttributeRange Criterion > For the complete documentation index, see [llms.txt](https://doc.ibexa.co/en/saas/llms.txt). IntegerAttributeRange Search Criterion The `IntegerAttributeRange` Search Criterion searches for products by the range of values of their integer attribute. ## Arguments - `identifier` - string representing the attribute - `min` - indicating the beginning of the range - `max` - indicating the end of the date range ## Example **XML** ```xml length 16 25 ``` **JSON** ```json { "AttributeQuery": { "Query": { "IntegerAttributeRangeCriterion": { "identifier": "length", "min": 16, "max": 25 } } } } ``` # IsVirtual Criterion > For the complete documentation index, see [llms.txt](https://doc.ibexa.co/en/saas/llms.txt). IsVirtual Search Criterion The `IsVirtual` Search Criterion searches for virtual or physical products. ## Arguments - (optional) `isVirtual` - bool representing whether to search for virtual (default `true`) or physical (`false`) products. ## Example **XML** ```xml true ``` **JSON** ```json "ProductQuery": { "Filter": { "IsVirtualCriterion": true } } ``` # ProductAvailability Criterion > For the complete documentation index, see [llms.txt](https://doc.ibexa.co/en/saas/llms.txt). ProductAvailability Search Criterion The `ProductAvailability` Search Criterion searches for products by the availability flag, the boolean value set per product or variant. To search for products that can be ordered, recreate the availability conditions with [existing product search criteria](https://doc.ibexa.co/en/saas/search/criteria_reference/product_search_criteria/index.md), for example LogicalAnd, LogicalOr, and [`ProductStock`](https://doc.ibexa.co/en/saas/search/criteria_reference/productstock_criterion/index.md). For more information, see [Availability and computed availability](https://doc.ibexa.co/en/saas/product_catalog/products/#availability-and-computed-availability). ## Arguments - (optional) `productAvailability` - bool representing whether the product is available (default `true`) ## Example **XML** ```xml false ``` **JSON** ```json { "ProductQuery": { "Filter": { "ProductAvailabilityCriterion": false } } } ``` # ProductStock Criterion > For the complete documentation index, see [llms.txt](https://doc.ibexa.co/en/saas/llms.txt). ProductStock Search Criterion The `ProductStock` Search Criterion searches for products by their numerical stock. ## Arguments - `value` - the numerical stock to search for - (optional) `operator` - operator string (`=` `<` `<=` `>` `>=`) # ProductStockRange Criterion > For the complete documentation index, see [llms.txt](https://doc.ibexa.co/en/saas/llms.txt). ProductStockRange Search Criterion The `ProductStockRange` Search Criterion searches for products by their numerical stock. ## Arguments - `min` - minimum stock - `max` - maximum stock # ProductCategory Criterion > For the complete documentation index, see [llms.txt](https://doc.ibexa.co/en/saas/llms.txt). ProductCategory Search Criterion The `ProductCategory` Search Criterion searches for products by the category they're assigned to. ## Arguments - `taxonomyEntries` - array of ints representing category IDs ## Example **XML** ```xml [2, 3] ``` **JSON** ```json { "ProductQuery": { "Filter": { "ProductCategoryCriterion": [ 2, 3 ] } } } ``` # ProductCategorySubtree Criterion > For the complete documentation index, see [llms.txt](https://doc.ibexa.co/en/saas/llms.txt). ProductCategorySubtree Search Criterion The `ProductCategorySubtree` Search Criterion searches for products assigned to a given product category or any of its subcategories. Unlike the [`ProductCategory` criterion](https://doc.ibexa.co/en/saas/search/criteria_reference/productcategory_criterion/index.md), which matches products assigned to specific category IDs, `ProductCategorySubtree` matches the entire subtree rooted at the provided category, including all descendant categories. ## Arguments - `taxonomyEntryId` - int representing the ID of the root taxonomy entry (product category) of the subtree to search within # ProductCode Criterion > For the complete documentation index, see [llms.txt](https://doc.ibexa.co/en/saas/llms.txt). ProductCode Search Criterion The `ProductCode` Search Criterion searches for products by their codes. ## Arguments - `productCode` - array of strings representing the product codes(s) ## Example **XML** ```xml ski snowboard ``` **JSON** ```json { "ProductQuery": { "Filter": { "ProductCodeCriterion": [ "ski", "snowboard" ] } } } ``` # ProductName Criterion > For the complete documentation index, see [llms.txt](https://doc.ibexa.co/en/saas/llms.txt). ProductName Search Criterion The `ProductName` Search Criterion searches for products by their names. ## Arguments - `productName` - string representing the Product name, with `*` as wildcard ## Example **XML** ```xml sofa* ``` **JSON** ```json { "ProductQuery": { "Filter": { "ProductNameCriterion": "sofa*" } } } ``` # ProductType Criterion > For the complete documentation index, see [llms.txt](https://doc.ibexa.co/en/saas/llms.txt). ProductType Search Criterion The `ProductType` Search Criterion searches for products by their codes. ## Arguments - `productType` - array of strings representing the product type(s) ## Example **XML** ```xml desk ``` **JSON** ```json { "ProductQuery": { "Filter": { "ProductTypeCriterion": "desk" } } } ``` # RangeMeasurementAttributeMinimum Criterion > For the complete documentation index, see [llms.txt](https://doc.ibexa.co/en/saas/llms.txt). RangeMeasurementAttributeMinimum Search Criterion The `RangeMeasurementAttributeMinimum` Search Criterion searches for products by the minimum value of their measurement (range) attribute. ## Arguments - `identifier` - string representing the attribute - `value` - `\Ibexa\Contracts\Measurement\Value\SimpleValueInterface` object representing the minimum attribute value # RangeMeasurementAttributeMaximum Criterion > For the complete documentation index, see [llms.txt](https://doc.ibexa.co/en/saas/llms.txt). RangeMeasurementAttributeMaximum Search Criterion The `RangeMeasurementAttributeMaximum` Search Criterion searches for products by the maximum value of their measurement (range) attribute. ## Arguments - `identifier` - string representing the attribute - `value` - `\Ibexa\Contracts\Measurement\Value\SimpleValueInterface` object representing the maximum attribute value # SimpleMeasurementAttribute Criterion > For the complete documentation index, see [llms.txt](https://doc.ibexa.co/en/saas/llms.txt). SimpleMeasurementAttribute Search Criterion The `SimpleMeasurementAttribute` Search Criterion searches for products by the value of their measurement (single) attribute. ## Arguments - `identifier` - string representing the attribute - `value` - `Ibexa\Contracts\Measurement\Value\SimpleValueInterface` object representing the attribute value # SelectionAttribute Criterion > For the complete documentation index, see [llms.txt](https://doc.ibexa.co/en/saas/llms.txt). SelectionAttribute Search Criterion The `SelectionAttribute` Search Criterion searches for products by the value of their selection attribute. ## Arguments - `identifier` - string representing the attribute - `value` - array of strings representing the attribute values ## Example **XML** ```xml fabric_type [cotton] ``` **JSON** ```json { "AttributeQuery": { "Query": { "SelectionAttributeCriterion": { "identifier": "fabric_type", "value": [ "cotton" ] } } } } ``` # SymbolAttributeCriterion > For the complete documentation index, see [llms.txt](https://doc.ibexa.co/en/saas/llms.txt). SymbolAttribute Criterion The `SymbolAttribute` Search Criterion searches for products by [symbol attribute](https://doc.ibexa.co/en/saas/product_catalog/attributes/symbol_attribute_type/index.md). ## Arguments - `identifier` - identifier of the format - `value` - array with the values to search for # UpdatedAt Criterion > For the complete documentation index, see [llms.txt](https://doc.ibexa.co/en/saas/llms.txt). UpdatedAt Search Criterion The `UpdatedAt` Search Criterion searches for products based on the date when they were last updated. ## Arguments - `date` - indicating the date that should be matched, provided as a [`DateTimeInterface`](https://www.php.net/manual/en/class.datetimeinterface.php) object in PHP, or as a string acceptable by `DateTimeInterface` constructor in REST - `operator` - Operator constant (EQ, GT, GTE, LT, LTE) in PHP or its value in REST ## Operators | Operator | Value | Description | | --------------- | ----- | ------------------------------------------------------------ | | `Operator::EQ` | `=` | Matches products updated exactly on the given date (default) | | `Operator::GT` | `>` | Matches products updated after the given date | | `Operator::GTE` | `>=` | Matches products updated on or after the given date | | `Operator::LT` | `<` | Matches products updated before the given date | | `Operator::LTE` | `<=` | Matches products updated on or before the given date | ## Example **XML** ```xml 2023-06-12 >= ``` **JSON** ```json { "ProductQuery": { "Filter": { "UpdatedAtCriterion": { "updated_at": "2023-06-12", "operator": ">=" } } } } ``` # UpdatedAtRange Criterion > For the complete documentation index, see [llms.txt](https://doc.ibexa.co/en/saas/llms.txt). UpdatedAtRange Search Criterion The `UpdatedAtRange` Search Criterion searches for products based on the date range when they were last updated. ## Arguments - `min` - the start of the date range (inclusive), provided as a [`DateTimeInterface`](https://www.php.net/manual/en/class.datetimeinterface.php) object in PHP, or as a string acceptable by `DateTimeInterface` constructor in REST - `max` - the end of the date range (inclusive), provided as a [`DateTimeInterface`](https://www.php.net/manual/en/class.datetimeinterface.php) object in PHP, or as a string acceptable by `DateTimeInterface` constructor in REST At least one of `min` or `max` must be provided. ## Example **XML** ```xml 2023-06-12 2023-06-20 ``` **JSON** ```json { "ProductQuery": { "Filter": { "UpdatedAtRangeCriterion": { "min": "2023-06-12", "max": "2023-06-20" } } } } ``` # Price Search Criteria reference > For the complete documentation index, see [llms.txt](https://doc.ibexa.co/en/saas/llms.txt). Price Search Criteria Price Search Criteria are only supported by price search. With these Criteria you can filter prices by currency, customer group, product, and more. ## Price Search Criteria | Search Criterion | Search based on | | -------------------------------------------------------------------------------------------------------------- | ---------------------------------------------------------------------------------- | | [Currency](https://doc.ibexa.co/en/saas/search/criteria_reference/price_currency_criterion/index.md) | Currency | | [CustomerGroup](https://doc.ibexa.co/en/saas/search/criteria_reference/price_customergroup_criterion/index.md) | A customer group that the price applies to | | [IsBasePrice](https://doc.ibexa.co/en/saas/search/criteria_reference/price_isbaseprice_criterion/index.md) | Boolean that indicates whether the price is a base price | | [IsCustomPrice](https://doc.ibexa.co/en/saas/search/criteria_reference/price_iscustomprice_criterion/index.md) | Boolean that indicates whether the price is a custom price | | [LogicalAnd](https://doc.ibexa.co/en/saas/search/criteria_reference/price_logicaland_criterion/index.md) | Logical AND criterion that matches if all the provided Criteria match | | [LogicalOr](https://doc.ibexa.co/en/saas/search/criteria_reference/price_logicalor_criterion/index.md) | Logical OR criterion that matches if at least one of the provided Criteria matches | | [Product](https://doc.ibexa.co/en/saas/search/criteria_reference/price_product_criterion/index.md) | Product code | # Price Currency Criterion > For the complete documentation index, see [llms.txt](https://doc.ibexa.co/en/saas/llms.txt). Price Currency Search Criterion The `Currency` Search Criterion searches for prices based on the given currency. ## Arguments - `currency` - a single object or an array of `CurrencyInterface` objects that represent the currency (`Ibexa\Contracts\ProductCatalog\Values\CurrencyInterface`) # Price CustomerGroup Criterion > For the complete documentation index, see [llms.txt](https://doc.ibexa.co/en/saas/llms.txt). Price CustomerGroup Search Criterion The `CustomerGroup` Search Criterion searches for prices based on the customer group. ## Arguments - `customer_group` - a single object or an array or `CustomerGroupInterface` objects that represent the customer group (`Ibexa\Contracts\ProductCatalog\Values\CustomerGroupInterface`) # Price IsBasePrice Criterion > For the complete documentation index, see [llms.txt](https://doc.ibexa.co/en/saas/llms.txt). Price IsBasePrice Search Criterion The `IsBasePrice` Search Criterion searches for prices that are base prices. ## Arguments This Criterion takes no arguments. ## Limitations The `IsBasePrice` Criterion isn't available in Solr or Elasticsearch engines. # Price IsCustomPrice Criterion > For the complete documentation index, see [llms.txt](https://doc.ibexa.co/en/saas/llms.txt). Price IsCustomPrice Search Criterion The `IsCustomPrice` Search Criterion searches for prices that are custom prices. ## Arguments This Criterion takes no arguments. ## Limitations The `IsCustomPrice` Criterion isn't available in Solr or Elasticsearch engines. # Price LogicalAnd Criterion > For the complete documentation index, see [llms.txt](https://doc.ibexa.co/en/saas/llms.txt). Price LogicalAnd Search Criterion The `LogicalAnd` Search Criterion matches prices if all provided Criteria match. ## Arguments - `criterion` - a set of Criteria combined by the logical operator # Price LogicalOr Criterion > For the complete documentation index, see [llms.txt](https://doc.ibexa.co/en/saas/llms.txt). Price LogicalOr Search Criterion The `LogicalOr` Search Criterion matches prices if at least one of the provided Criteria matches. ## Arguments - `criterion` - a set of Criteria combined by the logical operator # Price Product Criterion > For the complete documentation index, see [llms.txt](https://doc.ibexa.co/en/saas/llms.txt). Price Product Search Criterion The `Product` Search Criterion searches for prices based on product codes. ## Arguments - `product_code` - a string that represents a product code or an array of codes # URL Search Criteria reference > For the complete documentation index, see [llms.txt](https://doc.ibexa.co/en/saas/llms.txt). URL Search Criteria help define and fine-tune search queries for URLs. | URL criteria | URL based on | | ---------------------------------------------------------------------------------------------------------------------- | --------------------------------------------------------------------------------------------- | | [LogicalAnd](https://doc.ibexa.co/en/saas/search/url_search_reference/logicaland_url_criterion/index.md) | Implements a logical AND Criterion. It matches if ALL of the provided Criteria match. | | [LogicalNot](https://doc.ibexa.co/en/saas/search/url_search_reference/logicalnot_url_criterion/index.md) | Implements a logical NOT Criterion. It matches if the provided Criterion doesn't match. | | [LogicalOr](https://doc.ibexa.co/en/saas/search/url_search_reference/logicalor_url_criterion/index.md) | Implements a logical OR Criterion. It matches if at least one of the provided Criteria match. | | [MatchAll](https://doc.ibexa.co/en/saas/search/url_search_reference/matchall_url_criterion/index.md) | Returns all URL results. | | [MatchNone](https://doc.ibexa.co/en/saas/search/url_search_reference/matchnone_url_criterion/index.md) | Returns no URL results. | | [Pattern](https://doc.ibexa.co/en/saas/search/url_search_reference/pattern_url_criterion/index.md) | Matches URLs that contain a pattern. | | [SectionId](https://doc.ibexa.co/en/saas/search/url_search_reference/sectionid_url_criterion/index.md) | Matches URLs from content placed in the Section with the specified ID. | | [SectionIdentifier](https://doc.ibexa.co/en/saas/search/url_search_reference/sectionidentifier_url_criterion/index.md) | Matches URLs from content placed in Sections with the specified identifiers. | | [Validity](https://doc.ibexa.co/en/saas/search/url_search_reference/validity_url_criterion/index.md) | Matches URLs based on validity flag. | | [VisibleOnly](https://doc.ibexa.co/en/saas/search/url_search_reference/visibleonly_url_criterion/index.md) | Matches URLs from published content. | # MatchAll Criterion > For the complete documentation index, see [llms.txt](https://doc.ibexa.co/en/saas/llms.txt). MatchAll Criterion The `MatchAll` URL Criterion is an auxiliary Criterion that returns all search results. It's used internally when no filter or query is provided on a Query object. The Criterion takes no arguments. # MatchNone Criterion > For the complete documentation index, see [llms.txt](https://doc.ibexa.co/en/saas/llms.txt). MatchNone Criterion The `MatchNone` URL Criterion is an auxiliary Criterion that returns no search results. It's used internally when no filter or query is provided on a Query object. The Criterion takes no arguments. # Pattern Criterion > For the complete documentation index, see [llms.txt](https://doc.ibexa.co/en/saas/llms.txt). Pattern Criterion The `Pattern` URL Criterion matches URLs that contain the provided pattern. ## Arguments - `pattern` - string representing the pattern that needs to be a part of the URL # SectionId Criterion > For the complete documentation index, see [llms.txt](https://doc.ibexa.co/en/saas/llms.txt). SectionId Criterion The `SectionId` URL Criterion matches URLs based on the ID of the related content Section. ## Arguments - `sectionIds` - array of ints representing the IDs of the related content Sections # SectionIdentifier Criterion > For the complete documentation index, see [llms.txt](https://doc.ibexa.co/en/saas/llms.txt). SectionIdentifier Criterion The SectionIdentifier URL Criterion matches URLs related to the content placed in a specified section identifier. ## Arguments - `sectionIdentifiers` - string(s) representing the identifiers of the Section(s) # Validity Criterion > For the complete documentation index, see [llms.txt](https://doc.ibexa.co/en/saas/llms.txt). Validity Criterion The Validity URL Criterion matches URLs based on a validity flag. ## Arguments - `isValid` - bool representing whether the matcher selects only valid URLs # VisibleOnly Criterion > For the complete documentation index, see [llms.txt](https://doc.ibexa.co/en/saas/llms.txt). VisibleOnly Criterion The `VisibleOnly` URL Criterion matches URLs from the published content. The Criterion takes no arguments. # LogicalAnd Criterion > For the complete documentation index, see [llms.txt](https://doc.ibexa.co/en/saas/llms.txt). LogicalAnd Criterion The `LogicalAnd` URL Criterion matches a URL if all provided Criteria match. ## Arguments - `criterion` - the set of Criteria combined by the logical operator # LogicalNot Criterion > For the complete documentation index, see [llms.txt](https://doc.ibexa.co/en/saas/llms.txt). LogicalNot Criterion The `LogicalNot` URL Criterion matches a URL if the provided Criterion doesn't match. It takes only one Criterion in the array parameter. ## Arguments - `criterion` - represents the Criterion that should be negated # LogicalOr Criterion > For the complete documentation index, see [llms.txt](https://doc.ibexa.co/en/saas/llms.txt). LogicalOr Criterion The `LogicalOr` URL Criterion matches a URL if at least one of the provided Criteria match. ## Arguments - `criterion` - the set of Criteria combined by the logical operator # Activity Log Search Criteria reference > For the complete documentation index, see [llms.txt](https://doc.ibexa.co/en/saas/llms.txt). Activity Log Search Criteria Activity Log Search Criteria are found in the `Ibexa\Contracts\ActivityLog\Values\ActivityLog\Criterion` namespace. Those Criteria are to be used with `Ibexa\Contracts\ActivityLog\Values\ActivityLog\Query` for `Ibexa\Contracts\ActivityLog\ActivityLogServiceInterface::find`. They're applied to log entry groups. For example, with the criterion `ActionCriterion`, you get log entry groups that have at least one entry with this action (and possibly other actions as well). See [Recent activity](https://doc.ibexa.co/en/saas/administration/recent_activity/recent_activity/#rest-api) for how to browse the activity log over the REST API. ## Value-based criteria | Search Criterion | Search based on | | ------------------------------------------------------------------------------------------------------------------------- | ------------------------------------------------------------ | | [`ActionCriterion`](https://doc.ibexa.co/en/saas/search/activity_log_search_reference/action_criterion/index.md) | Performed action name(s) | | [`LoggedAtCriterion`](https://doc.ibexa.co/en/saas/search/activity_log_search_reference/logged_at_criterion/index.md) | Before, after or at a given date and time | | [`ObjectCriterion`](https://doc.ibexa.co/en/saas/search/activity_log_search_reference/object_criterion/index.md) | Manipulated object's class name, and optionally objects' IDs | | [`ObjectNameCriterion`](https://doc.ibexa.co/en/saas/search/activity_log_search_reference/object_name_criterion/index.md) | Manipulated object's name, in whole or in part | | [`UserCriterion`](https://doc.ibexa.co/en/saas/search/activity_log_search_reference/user_criterion/index.md) | User performing the action | ## Logical criteria | Search Criterion | Description | | ---------------- | ----------------------------------------------------------------------------------- | | `LogicalNot` | Logical NOT criterion that matches if the provided Criteria don't match. | | `LogicalAnd` | Logical AND criterion that matches if all the provided Criteria match. | | `LogicalOr` | Logical OR criterion that matches if at least one of the provided Criteria matches. | # Action Criterion > For the complete documentation index, see [llms.txt](https://doc.ibexa.co/en/saas/llms.txt). The `ActionCriterion` Activity Log Criterion matches activity log group that has a log entry with one of the given actions. ## Argument - `actions` - list of action name strings. A set of built-in names is available as `ActivityLogServiceInterface`'s `ACTION_` prefixed constants. # LoggedAt Criterion > For the complete documentation index, see [llms.txt](https://doc.ibexa.co/en/saas/llms.txt). The `LoggedAtCriterion` Activity Log Criterion matches activity log group that has a log entry created before or after a given date time. ## Arguments - `dateTime` - a [`DateTimeInterface`](https://www.php.net/manual/en/class.datetimeinterface.php) object, like [`DateTime`](https://www.php.net/manual/en/class.datetime.php) - `comparison` - string that represents a comparison sign. Available signs can be found as constant in the `LoggedAtCriterion` class itself | Comparison | Value | Constant | | --------------------- | ----- | ------------------------ | | Equal | `=` | `LoggedAtCriterion::EQ` | | Not equal | `<>` | `LoggedAtCriterion::NEQ` | | Less than | `<` | `LoggedAtCriterion::LT` | | Less than or equal | `<=` | `LoggedAtCriterion::LTE` | | Greater than | `>` | `LoggedAtCriterion::GT` | | Greater than or equal | `>=` | `LoggedAtCriterion::GTE` | # Object Criterion > For the complete documentation index, see [llms.txt](https://doc.ibexa.co/en/saas/llms.txt). The `ObjectCriterion` Activity Log Criterion matches log group with a log entry about the given class name, and eventually one of the given IDs. ## Arguments - `objectClass` - a class of the object concerned by the searched log entries - `ids` - an optional list of object IDs # Object Name Criterion > For the complete documentation index, see [llms.txt](https://doc.ibexa.co/en/saas/llms.txt). The `ObjectNameCriterion` Activity Log Criterion matches log groups that have a log entry with an object having a given string as name, or part of their name. ## Arguments - `query` - string representing the object name - `operator` - constant representing how to compare log names with the query - `ObjectNameCriterion::OPERATOR_CONTAINS` - `ObjectNameCriterion::OPERATOR_STARTS_WITH` - `ObjectNameCriterion::OPERATOR_ENDS_WITH` - `ObjectNameCriterion::OPERATOR_EQUALS` # User Criterion > For the complete documentation index, see [llms.txt](https://doc.ibexa.co/en/saas/llms.txt). The `UserCriterion` Activity Log Criterion matches log groups that have an activity by one of the users given by their IDs. ## Argument - `ids` - list of user IDs # Action Configuration Search Criterion reference > For the complete documentation index, see [llms.txt](https://doc.ibexa.co/en/saas/llms.txt). Search Criteria available for Action Configuration search Search criteria are found in the `Ibexa\Contracts\ConnectorAi\ActionConfiguration\Query\Criterion` namespace, implementing the CriterionInterface interface: | Criterion | Description | | ---------- | ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | | Name | Find Action Configurations matching given name. Use FieldValueCriterion's constants like `FieldValueCriterion::COMPARISON_CONTAINS` or `FieldValueCriterion::COMPARISON_STARTS_WITH` to specify the matching condition | | Enabled | Find enabled or disabled Action Configurations | | Identifier | Find Action Configuration having the exact given identifier | | LogicalAnd | Composite criterion to group multiple criteria using the AND condition | | LogicalOr | Composite criterion to group multiple criteria using the OR condition | | Type | Find Action Configuration having the exact given type | # Notification Search Criteria reference > For the complete documentation index, see [llms.txt](https://doc.ibexa.co/en/saas/llms.txt). Notification Search Criteria Notification Search Criteria are only supported by Notification Search (`NotificationService::findNotifications`). With these Criteria you can filter notifications by their notification creation date, notification status, and notification type. ## Notification Search Criteria | Search Criterion | Search based on | | ----------------------------------------------------------------------------------------------------------------- | ------------------------------------------- | | [DateCreated](https://doc.ibexa.co/en/saas/search/criteria_reference/notification_datecreated_criterion/index.md) | Date and time when notification was created | | [Status](https://doc.ibexa.co/en/saas/search/criteria_reference/notification_status_criterion/index.md) | Status of the notification | | [Type](https://doc.ibexa.co/en/saas/search/criteria_reference/notification_type_criterion/index.md) | Type of the notification | # Notification DateCreated Criterion > For the complete documentation index, see [llms.txt](https://doc.ibexa.co/en/saas/llms.txt). Notification DateCreated Search Criterion The `DateCreated` Search Criterion searches for notifications based on the date when they were created. ## Arguments - `created` - date to be matched, provided as a `DateTimeInterface` object - `operator` - optional operator string (GTE, LTE) # Notification Status Criterion > For the complete documentation index, see [llms.txt](https://doc.ibexa.co/en/saas/llms.txt). Notification Status Search Criterion The `Status` Search Criterion searches for notifications based on notification status. ## Arguments - `status` - Boolean value that represents the status of the notification # Type Criterion > For the complete documentation index, see [llms.txt](https://doc.ibexa.co/en/saas/llms.txt). Type Search Criterion The `Type` Search Criterion searches for notifications by their types. ## Arguments - `type` - string that represents the type of the notification, takes values defined in notification workflow # Sort Clause reference > For the complete documentation index, see [llms.txt](https://doc.ibexa.co/en/saas/llms.txt). Sort Clauses help fine-tune sorting order when searching for content and locations. Sort Clauses are the sorting options for Content and Location Search. Capabilities of individual Sort Clauses can depend on the search engine. All Sort Clauses can take the following optional argument: - `sortDirection` - the direction of the sorting, either `Query::SORT_ASC` (default) or `Query::SORT_DESC` ## Sort Clauses | Sort Clause | Sorting based on | Content Search | Location Search | Filtering | Trash | | ----------------------------------------------------------------------------------------------------------------------------- | ------------------------------------------------------------------------------------------- | -------------- | --------------- | --------- | ----- | | [ContentId](https://doc.ibexa.co/en/saas/search/sort_clause_reference/contentid_sort_clause/index.md) | Content items' ID | Yes | Yes | Yes | | | [ContentName](https://doc.ibexa.co/en/saas/search/sort_clause_reference/contentname_sort_clause/index.md) | Content names | Yes | Yes | Yes | Yes | | [ContentTranslatedName](https://doc.ibexa.co/en/saas/search/sort_clause_reference/contenttranslatedname_sort_clause/index.md) | Translated content names | Yes | Yes | | | | [ContentTypeName](https://doc.ibexa.co/en/saas/search/sort_clause_reference/contenttypename_sort_clause/index.md) | Content items' content type name | | | | Yes | | [CustomField](https://doc.ibexa.co/en/saas/search/sort_clause_reference/customfield_sort_clause/index.md) | Raw search index fields | Yes | Yes | | | | [DateModified](https://doc.ibexa.co/en/saas/search/sort_clause_reference/datemodified_sort_clause/index.md) | The date when content was last modified | Yes | Yes | Yes | | | [DatePublished](https://doc.ibexa.co/en/saas/search/sort_clause_reference/datepublished_sort_clause/index.md) | The date when content was created | Yes | Yes | Yes | | | [DateTrashed](https://doc.ibexa.co/en/saas/search/sort_clause_reference/datetrashed_sort_clause/index.md) | The date when content was sent to trash | | | | Yes | | [Depth](https://doc.ibexa.co/en/saas/search/sort_clause_reference/depth_sort_clause/index.md) | Location depth in the content tree | | Yes | Yes | Yes | | [Field](https://doc.ibexa.co/en/saas/search/sort_clause_reference/field_sort_clause/index.md) | Content of one of content item's fields | Yes | Yes | | | | [Id](https://doc.ibexa.co/en/saas/search/sort_clause_reference/id_sort_clause/index.md) | Location ID | | Yes | Yes | | | [IsMainLocation](https://doc.ibexa.co/en/saas/search/sort_clause_reference/ismainlocation_sort_clause/index.md) | Whether a location is the main location of a content item | | Yes | | | | [MapLocationDistance](https://doc.ibexa.co/en/saas/search/sort_clause_reference/maplocationdistance_sort_clause/index.md) | Distance between the location contained in a MapLocation field and the provided coordinates | Yes | Yes | | | | [Path](https://doc.ibexa.co/en/saas/search/sort_clause_reference/path_sort_clause/index.md) | PathString of the Location | | Yes | Yes | Yes | | [Priority](https://doc.ibexa.co/en/saas/search/sort_clause_reference/priority_sort_clause/index.md) | Location priority | | Yes | Yes | Yes | | [Random](https://doc.ibexa.co/en/saas/search/sort_clause_reference/random_sort_clause/index.md) | Random seed | Yes | Yes | | | | [Score](https://doc.ibexa.co/en/saas/search/sort_clause_reference/score_sort_clause/index.md) | Score of the search result | Yes | Yes | | | | [SectionIdentifier](https://doc.ibexa.co/en/saas/search/sort_clause_reference/sectionidentifier_sort_clause/index.md) | ID of the Section content is assigned to | Yes | Yes | Yes | | | [SectionName](https://doc.ibexa.co/en/saas/search/sort_clause_reference/sectionname_sort_clause/index.md) | Name of the Section content is assigned to | Yes | Yes | Yes | Yes | | [UserLogin](https://doc.ibexa.co/en/saas/search/sort_clause_reference/userlogin_sort_clause/index.md) | Login of the content item's creator | | | | Yes | | [Visibility](https://doc.ibexa.co/en/saas/search/sort_clause_reference/visibility_sort_clause/index.md) | Whether the location is visible or not | | Yes | Yes | | # ContentId Sort Clause > For the complete documentation index, see [llms.txt](https://doc.ibexa.co/en/saas/llms.txt). ContentId Sort Clause The `ContentId` Sort Clause sorts search results by the content items' IDs. ## Arguments - (optional) `sortDirection` - Query or LocationQuery constant, either `Query::SORT_ASC` or `Query::SORT_DESC` # ContentName Sort Clause > For the complete documentation index, see [llms.txt](https://doc.ibexa.co/en/saas/llms.txt). ContentName Sort Clause The `ContentName` Sort Clause sorts search results by the content items' names. ## Arguments - (optional) `sortDirection` - Query or LocationQuery constant, either `Query::SORT_ASC` or `Query::SORT_DESC` # ContentTranslatedName Sort Clause > For the complete documentation index, see [llms.txt](https://doc.ibexa.co/en/saas/llms.txt). ContentTranslatedName Sort Clause The `ContentTranslatedName` Sort Clause sorts search results by the content items' translated names. ## Arguments - (optional) `sortDirection` - Query or LocationQuery constant, either `Query::SORT_ASC` or `Query::SORT_DESC` # ContentTypeName Sort Clause > For the complete documentation index, see [llms.txt](https://doc.ibexa.co/en/saas/llms.txt). ContentTypeName Sort Clause The `ContentTypeName` Sort Clause sorts the results of searching in Trash by the name of the content item's content type. ## Arguments - (optional) `sortDirection` - Query constant, either `Query::SORT_ASC` or `Query::SORT_DESC` # CustomField Sort Clause > For the complete documentation index, see [llms.txt](https://doc.ibexa.co/en/saas/llms.txt). CustomField Sort Clause The `CustomField` Sort Clause sorts search results by raw search index fields. ## Arguments - `field` - string representing the search index field name - (optional) `sortDirection` - Query or LocationQuery constant, either `Query::SORT_ASC` or `Query::SORT_DESC` ## Limitations > **Caution: Caution** > > To keep your project search engine independent, don't use the `CustomField` Sort Clause in production code. Valid use cases are: testing, or temporary (one-off) tools. # DateModified Sort Clause > For the complete documentation index, see [llms.txt](https://doc.ibexa.co/en/saas/llms.txt). DateModified Sort Clause The `DateModified` Sort Clause sorts search results by the date and time of the last modification of a content item. ## Arguments - (optional) `sortDirection` - Query or LocationQuery constant, either `Query::SORT_ASC` or `Query::SORT_DESC` # DatePublished Sort Clause > For the complete documentation index, see [llms.txt](https://doc.ibexa.co/en/saas/llms.txt). DatePublished Sort Clause The `DatePublished` Sort Clause sorts search results by the date and time of the first publication of a content item. ## Arguments - (optional) `sortDirection` - Query or LocationQuery constant, either `Query::SORT_ASC` or `Query::SORT_DESC` # DateTrashed Sort Clause > For the complete documentation index, see [llms.txt](https://doc.ibexa.co/en/saas/llms.txt). DateTrashed Sort Clause The `DateTrashed` Sort Clause sorts the results of searching in Trash by the date and time when the content item was sent to trash. ## Arguments - (optional) `sortDirection` - Query constant, either `Query::SORT_ASC` or `Query::SORT_DESC` # Depth Sort Clause > For the complete documentation index, see [llms.txt](https://doc.ibexa.co/en/saas/llms.txt). Depth Sort Clause The `Location\Depth` Sort Clause sorts search results by the depth of the location in the content tree. ## Arguments - (optional) `sortDirection` - Query or LocationQuery constant, either `Query::SORT_ASC` or `Query::SORT_DESC` # Field Sort Clause > For the complete documentation index, see [llms.txt](https://doc.ibexa.co/en/saas/llms.txt). Field Sort Clause The `Field` Sort Clause sorts search results by the value of one of the content items' fields. Search results of the provided content type are sorted in field value order. Results of the query that don't belong to the content type are ranked lower. ## Arguments - `typeIdentifier` - string representing the identifier of the content type to which the field belongs - `fieldIdentifier` - string representing the identifier of the field to sort by - (optional) `sortDirection` - Query or LocationQuery constant, either `Query::SORT_ASC` or `Query::SORT_DESC` # Id Sort Clause > For the complete documentation index, see [llms.txt](https://doc.ibexa.co/en/saas/llms.txt). Id Sort Clause The `Location\Id` Sort Clause sorts search results by the ID of the location. ## Arguments - (optional) `sortDirection` - Query or LocationQuery constant, either `Query::SORT_ASC` or `Query::SORT_DESC` # IsMainLocation Sort Clause > For the complete documentation index, see [llms.txt](https://doc.ibexa.co/en/saas/llms.txt). IsMainLocation Sort Clause The `Location\IsMainLocation` Sort Clause sorts search results by whether their location is the main location of the content item. Locations that aren't main locations are ranked as lower values (for example, with ascending order they're returned first). ## Arguments - (optional) `sortDirection` - Query or LocationQuery constant, either `Query::SORT_ASC` or `Query::SORT_DESC` # MapLocationDistance Sort Clause > For the complete documentation index, see [llms.txt](https://doc.ibexa.co/en/saas/llms.txt). MapLocationDistance Sort Clause The `MapLocationDistance` Sort Clause sorts search results by the distance of the indicated MapLocation field to the provided location. ## Arguments - `typeIdentifier` - string representing the identifier of the content type to which the MapLocation field belongs - `fieldIdentifier` - string representing the identifier of the MapLocation field to sort by - `latitude` - float representing the latitude of the location to calculate distance to - `longitude`- float representing the longitude of the location to calculate distance to - (optional) `sortDirection` - Query or LocationQuery constant, either `Query::SORT_ASC` or `Query::SORT_DESC` # Path Sort Clause > For the complete documentation index, see [llms.txt](https://doc.ibexa.co/en/saas/llms.txt). Path Sort Clause The `Location\Path` Sort Clause sorts search results by the pathString of the location. > **Note: Note** > > Solr search engine uses dictionary sorting with the `Location/Path` Sort Clause. ## Arguments - (optional) `sortDirection` - Query or LocationQuery constant, either `Query::SORT_ASC` or `Query::SORT_DESC` # Priority Sort Clause > For the complete documentation index, see [llms.txt](https://doc.ibexa.co/en/saas/llms.txt). Priority Sort Clause The `Location\Priority` Sort Clause sorts search results by the priority of the location. ## Arguments - (optional) `sortDirection` - Query or LocationQuery constant, either `Query::SORT_ASC` or `Query::SORT_DESC` # Random Sort Clause > For the complete documentation index, see [llms.txt](https://doc.ibexa.co/en/saas/llms.txt). Random Sort Clause The `Random` Sort Clause orders search results randomly. ## Arguments - (optional) `seed` - int representing the random seed - (optional) `sortDirection` - Query or LocationQuery constant, either `Query::SORT_ASC` or `Query::SORT_DESC` ## Limitations In Elasticsearch engine, you cannot combine the `Random` Sort Clause with any other Sort Clause. # Score Sort Clause > For the complete documentation index, see [llms.txt](https://doc.ibexa.co/en/saas/llms.txt). Score Sort Clause The `Score` Sort Clause orders search results by their score. ## Arguments - (optional) `sortDirection` - Query or LocationQuery constant, either `Query::SORT_ASC` or `Query::SORT_DESC` # SectionIdentifier Sort Clause > For the complete documentation index, see [llms.txt](https://doc.ibexa.co/en/saas/llms.txt). SectionIdentifier Sort Clause The `SectionIdentifier` Sort Clause sorts search results by the Section IDs of the content items. ## Arguments - (optional) `sortDirection` - Query or LocationQuery constant, either `Query::SORT_ASC` or `Query::SORT_DESC` > **Note: Note** > > Solr search engine uses the `Query::SORT_DESC` sort direction by default. # SectionName Sort Clause > For the complete documentation index, see [llms.txt](https://doc.ibexa.co/en/saas/llms.txt). SectionName Sort Clause The `SectionName` Sort Clause sorts search results by the Section name of the content items. ## Arguments - (optional) `sortDirection` - Query or LocationQuery constant, either `Query::SORT_ASC` or `Query::SORT_DESC` # UserLogin Sort Clause > For the complete documentation index, see [llms.txt](https://doc.ibexa.co/en/saas/llms.txt). UserLogin Sort Clause The `UserLogin` Sort Clause sorts the results of searching in Trash by the login of the content item's creator. ## Arguments - (optional) `sortDirection` - Query constant, either `Query::SORT_ASC` or `Query::SORT_DESC` # Visibility Sort Clause > For the complete documentation index, see [llms.txt](https://doc.ibexa.co/en/saas/llms.txt). Visibility Sort Clause The `Location\Visibility` Sort Clause sorts search results by whether the location is visible or not. Locations that aren't visible are ranked as higher values (for example, with ascending order they're returned last). ## Arguments - (optional) `sortDirection` - Query or LocationQuery constant, either `Query::SORT_ASC` or `Query::SORT_DESC` # Content Type Search Sort Clauses > For the complete documentation index, see [llms.txt](https://doc.ibexa.co/en/saas/llms.txt). Content Type Search Sort Clauses Content Type Search Sort Clauses are the sorting options for content types. Sort Clauses are found in the `Ibexa\Contracts\Core\Repository\Values\ContentType\Query\SortClause` namespace: | Name | Description | | ---------- | --------------------------------- | | Id | Sort by content type's id | | Identifier | Sort by content type's identifier | | Name | Sort by content type's name | # Product Sort Clauses > For the complete documentation index, see [llms.txt](https://doc.ibexa.co/en/saas/llms.txt). Product Sort Clauses Product Sort Clauses are only supported by product search. By using Sort Clause you can filter product by specific attributes, for example: price, code, or availability. To sort products coming from Quable, see [Quable](https://doc.ibexa.co/en/saas/product_catalog/quable/quable/index.md) for details about the add-on. | Sort Clause | Sorting based on | Local product catalog | Quable | | ------------------------------------------------------------------------------------------------------------------------- | ------------------------------------------ | --------------------- | ------ | | [BasePrice](https://doc.ibexa.co/en/saas/search/sort_clause_reference/baseprice_sort_clause/index.md) | Base product price | Yes | | | [CreatedAt](https://doc.ibexa.co/en/saas/search/sort_clause_reference/createdat_sort_clause/index.md) | Date and time of the creation of a product | Yes | Yes | | [CustomPrice](https://doc.ibexa.co/en/saas/search/sort_clause_reference/customprice_sort_clause/index.md) | Custom product price | Yes | | | [ProductAvailability](https://doc.ibexa.co/en/saas/search/sort_clause_reference/productavailability_sort_clause/index.md) | Product's availability | Yes | | | [ProductCode](https://doc.ibexa.co/en/saas/search/sort_clause_reference/productcode_sort_clause/index.md) | Product's code | Yes | Yes | | [ProductName](https://doc.ibexa.co/en/saas/search/sort_clause_reference/productname_sort_clause/index.md) | Product's name | Yes | Yes | # BasePrice Sort Clause > For the complete documentation index, see [llms.txt](https://doc.ibexa.co/en/saas/llms.txt). BasePrice Sort Clause The `BasePrice` Sort Clause sorts search results by the product's base price. ## Arguments - `currency` - a `CurrencyInterface` object representing the currency to check price for - (optional) `sortDirection` - ProductQuery constant, either `ProductQuery::SORT_ASC` or `ProductQuery::SORT_DESC` ## Limitations The `BasePrice` Sort Clause isn't available in the Legacy Search engine. # CreatedAt Sort Clause > For the complete documentation index, see [llms.txt](https://doc.ibexa.co/en/saas/llms.txt). CreatedAt Sort Clause The `CreatedAt` Sort Clause sorts search results by the date and time of the creation of a product. ## Arguments - (optional) `sortDirection` - `CreatedAt` constant, either `CreatedAt::SORT_ASC` or `CreatedAt::SORT_DESC` # CustomPrice Sort Clause > For the complete documentation index, see [llms.txt](https://doc.ibexa.co/en/saas/llms.txt). CustomPrice Sort Clause The `CustomPrice` Sort Clause sorts search results by the product's custom price for a selected customer group. ## Arguments - `currency` - a `CurrencyInterface` object representing the currency to check price for - (optional) `sortDirection` - Query or LocationQuery constant, either `Query::SORT_ASC` or `Query::SORT_DESC` - (optional) `customerGroup` - a `CustomerGroupInterface` object representing the customer group to check prices for. If you don't provide a customer group, the query uses the group related to the current user. ## Limitations The `CustomPrice` Sort Clause isn't available in the Legacy Search engine. # ProductAvailability Sort Clause > For the complete documentation index, see [llms.txt](https://doc.ibexa.co/en/saas/llms.txt). ProductAvailability Sort Clause The `ProductAvailability` Sort Clause sorts search results by whether they have availability or not. ## Arguments - (optional) `sortDirection` - Query or LocationQuery constant, either `Query::SORT_ASC` or `Query::SORT_DESC` # ProductCode Sort Clause > For the complete documentation index, see [llms.txt](https://doc.ibexa.co/en/saas/llms.txt). ProductCode Sort Clause The `ProductCode` Sort Clause sorts search results by the product code. ## Arguments - (optional) `sortDirection` - Query or LocationQuery constant, either `Query::SORT_ASC` or `Query::SORT_DESC` # ProductName Sort Clause > For the complete documentation index, see [llms.txt](https://doc.ibexa.co/en/saas/llms.txt). ProductName Sort Clause The `ProductName` Sort Clause sorts search results by the Product code. ## Arguments - (optional) `sortDirection` - Query or LocationQuery constant, either `Query::SORT_ASC` or `Query::SORT_DESC` # URL Sort Clauses > For the complete documentation index, see [llms.txt](https://doc.ibexa.co/en/saas/llms.txt). URL Sort Clauses URL Sort Clauses are the sorting options for URLs. All URL Sort Clauses can take the following optional argument: - `sortDirection` - the direction of the sorting, either `\Ibexa\Contracts\Core\Repository\Values\URL\Query\SortClause::SORT_ASC` (default) or `\Ibexa\Contracts\Core\Repository\Values\URL\Query\SortClause::SORT_DESC` | Sort Clause | Sorting based on | | -------------------------------------------------------------------------------------------- | ---------------- | | [Id](https://doc.ibexa.co/en/saas/search/url_search_reference/id_url_sort_clause/index.md) | URL ID | | [URL](https://doc.ibexa.co/en/saas/search/url_search_reference/url_url_sort_clause/index.md) | URL address | # Id Sort Clause > For the complete documentation index, see [llms.txt](https://doc.ibexa.co/en/saas/llms.txt). Id Sort Clause The `SortClause\Id` Sort Clause sorts search results by the ID of the URL. ## Arguments - `sortDirection` (optional) - the direction of the sorting, either `\Ibexa\Contracts\Core\Repository\Values\URL\Query\SortClause::SORT_ASC` (default) or `\Ibexa\Contracts\Core\Repository\Values\URL\Query\SortClause::SORT_DESC` # URL Sort Clause > For the complete documentation index, see [llms.txt](https://doc.ibexa.co/en/saas/llms.txt). URL Sort Clause The `SortClause\Url` Sort Clause sorts search results by the URLs. ## Arguments - `sortDirection` - the direction of the sorting, either `\Ibexa\Contracts\Core\Repository\Values\URL\Query\SortClause::SORT_ASC` (default) or `\Ibexa\Contracts\Core\Repository\Values\URL\Query\SortClause::SORT_DESC` # Activity Log Search Sort Clauses reference > For the complete documentation index, see [llms.txt](https://doc.ibexa.co/en/saas/llms.txt). See [Recent activity](https://doc.ibexa.co/en/saas/administration/recent_activity/recent_activity/#rest-api) for how to browse the activity log over the REST API. Sort Clauses are found in the `Ibexa\Contracts\ActivityLog\Values\ActivityLog\SortClause` namespace. - `LoggedAtSortClause`: Sort Activity Log entries by their date and time, descending or ascending. # Action Configuration Search Sort Clauses reference > For the complete documentation index, see [llms.txt](https://doc.ibexa.co/en/saas/llms.txt). Sort Clauses available for Action Configuration search Sort Clauses are found in the `Ibexa\Contracts\ConnectorAi\ActionConfiguration\Query\SortClause` namespace, implementing the SortClauseInterface interface: - Enabled - Id - Identifier # Aggregation reference > For the complete documentation index, see [llms.txt](https://doc.ibexa.co/en/saas/llms.txt). Aggregations help fine-tune search for content and Locations by grouping results into categories. Aggregation is used to group search results into categories. There are three types of aggregations: - Term aggregations group by value and count object in each group - Range aggregations count values in specified ranges - Stats aggregations compute stats over numeric fields: minimum, average and maximum value, count, and sum of values > **Tip: Tip** > > Aggregations aren't available in the Legacy Search engine. ## Content aggregations | Name | Type | Based on | | -------------------------------------------------------------------------------------------------------------------------------------- | ----- | ------------------------------------- | | [ContentTypeTermAggregation](https://doc.ibexa.co/en/saas/search/aggregation_reference/contenttypeterm_aggregation/index.md) | Term | Content type | | [ContentTypeGroupTermAggregation](https://doc.ibexa.co/en/saas/search/aggregation_reference/contenttypegroupterm_aggregation/index.md) | Term | Content type group | | [DateMetadataRangeAggregation](https://doc.ibexa.co/en/saas/search/aggregation_reference/datemetadatarange_aggregation/index.md) | Range | Date metadata | | [LanguageTermAggregation](https://doc.ibexa.co/en/saas/search/aggregation_reference/languageterm_aggregation/index.md) | Term | Content language | | [LocationChildrenTermAggregation](https://doc.ibexa.co/en/saas/search/aggregation_reference/locationchildrenterm_aggregation/index.md) | Term | Children on a Location | | [ObjectStateTermAggregation](https://doc.ibexa.co/en/saas/search/aggregation_reference/objectstateterm_aggregation/index.md) | Term | Object state | | [RawRangeAggregation](https://doc.ibexa.co/en/saas/search/aggregation_reference/rawrange_aggregation/index.md) | Range | Search index field | | [RawStatsAggregation](https://doc.ibexa.co/en/saas/search/aggregation_reference/rawstats_aggregation/index.md) | Stats | Search index field | | [RawTermAggregation](https://doc.ibexa.co/en/saas/search/aggregation_reference/rawterm_aggregation/index.md) | Term | Search index field | | [SectionTermAggregation](https://doc.ibexa.co/en/saas/search/aggregation_reference/sectionterm_aggregation/index.md) | Term | Section | | [SubtreeTermAggregation](https://doc.ibexa.co/en/saas/search/aggregation_reference/subtreeterm_aggregation/index.md) | Term | Location subtree path | | [TaxonomyEntryIdAggregation](https://doc.ibexa.co/en/saas/search/aggregation_reference/taxonomyentryid_aggregation/index.md) | Term | Taxonomy entry | | [UserMetadataTermAggregation](https://doc.ibexa.co/en/saas/search/aggregation_reference/usermetadataterm_aggregation/index.md) | Term | Content owner/owner group or modifier | | [VisibilityTermAggregation](https://doc.ibexa.co/en/saas/search/aggregation_reference/visibilityterm_aggregation/index.md) | Term | Content/Location visibility | ## Field aggregations | Name | Type | Based on field | | ------------------------------------------------------------------------------------------------------------------------ | ----- | ---------------------------------------------------------------------------------------------------------------------- | | [AuthorTermAggregation](https://doc.ibexa.co/en/saas/search/aggregation_reference/authorterm_aggregation/index.md) | Term | [Author](https://doc.ibexa.co/en/saas/content_management/field_types/field_type_reference/authorfield/index.md) | | [CheckboxTermAggregation](https://doc.ibexa.co/en/saas/search/aggregation_reference/checkboxterm_aggregation/index.md) | Term | [Checkbox](https://doc.ibexa.co/en/saas/content_management/field_types/field_type_reference/checkboxfield/index.md) | | [CountryTermAggregation](https://doc.ibexa.co/en/saas/search/aggregation_reference/countryterm_aggregation/index.md) | Term | [Country](https://doc.ibexa.co/en/saas/content_management/field_types/field_type_reference/countryfield/index.md) | | [DateRangeAggregation](https://doc.ibexa.co/en/saas/search/aggregation_reference/daterange_aggregation/index.md) | Range | [Date](https://doc.ibexa.co/en/saas/content_management/field_types/field_type_reference/datefield/index.md) | | [DateTimeRangeAggregation](https://doc.ibexa.co/en/saas/search/aggregation_reference/datetimerange_aggregation/index.md) | Range | [DateTime](https://doc.ibexa.co/en/saas/content_management/field_types/field_type_reference/dateandtimefield/index.md) | | [FloatRangeAggregation](https://doc.ibexa.co/en/saas/search/aggregation_reference/floatrange_aggregation/index.md) | Range | [Float](https://doc.ibexa.co/en/saas/content_management/field_types/field_type_reference/floatfield/index.md) | | [FloatStatsAggregation](https://doc.ibexa.co/en/saas/search/aggregation_reference/floatstats_aggregation/index.md) | Stats | [Float](https://doc.ibexa.co/en/saas/content_management/field_types/field_type_reference/floatfield/index.md) | | [IntegerRangeAggregation](https://doc.ibexa.co/en/saas/search/aggregation_reference/integerrange_aggregation/index.md) | Range | [Integer](https://doc.ibexa.co/en/saas/content_management/field_types/field_type_reference/integerfield/index.md) | | [IntegerStatsAggregation](https://doc.ibexa.co/en/saas/search/aggregation_reference/integerstats_aggregation/index.md) | Stats | [Integer](https://doc.ibexa.co/en/saas/content_management/field_types/field_type_reference/integerfield/index.md) | | [KeywordTermAggregation](https://doc.ibexa.co/en/saas/search/aggregation_reference/keywordterm_aggregation/index.md) | Term | [Keyword](https://doc.ibexa.co/en/saas/content_management/field_types/field_type_reference/keywordfield/index.md) | | [SelectionTermAggregation](https://doc.ibexa.co/en/saas/search/aggregation_reference/selectionterm_aggregation/index.md) | Term | [Selection](https://doc.ibexa.co/en/saas/content_management/field_types/field_type_reference/selectionfield/index.md) | | [TimeRangeAggregation](https://doc.ibexa.co/en/saas/search/aggregation_reference/timerange_aggregation/index.md) | Range | [Time](https://doc.ibexa.co/en/saas/content_management/field_types/field_type_reference/timefield/index.md) | ## Product aggregations | Name | Type | Based on | | --------------------------------------------------------------------------------------------------------------------------------- | ------------ | ------------------------ | | [Product attribute](https://doc.ibexa.co/en/saas/search/aggregation_reference/product_attribute_aggregations/index.md) | Term / Range | Product attribute values | | [BasePriceStats](https://doc.ibexa.co/en/saas/search/aggregation_reference/basepricestats_aggregation/index.md) | Stats | Product base price | | [CustomPriceStats](https://doc.ibexa.co/en/saas/search/aggregation_reference/custompricestats_aggregation/index.md) | Stats | Product custom price | | [ProductAvailabilityTerm](https://doc.ibexa.co/en/saas/search/aggregation_reference/productavailabilityterm_aggregation/index.md) | Term | Product availability | | [ProductStockRange](https://doc.ibexa.co/en/saas/search/aggregation_reference/productstockrange_aggregation/index.md) | Range | Product stock | | [ProductPriceRange](https://doc.ibexa.co/en/saas/search/aggregation_reference/productpricerange_aggregation/index.md) | Range | Product price | | [ProductTypeTerm](https://doc.ibexa.co/en/saas/search/aggregation_reference/producttypeterm_aggregation/index.md) | Term | Product type | | [TaxonomyEntryIdAggregation](https://doc.ibexa.co/en/saas/search/aggregation_reference/taxonomyentryid_aggregation/index.md) | Term | Product category | # ContentTypeTermAggregation > For the complete documentation index, see [llms.txt](https://doc.ibexa.co/en/saas/llms.txt). ContentTypeTermAggregation The ContentTypeTermAggregation aggregates search results by the content item's content type. ## Arguments - `name` - name of the Aggregation object # ContentTypeGroupTermAggregation > For the complete documentation index, see [llms.txt](https://doc.ibexa.co/en/saas/llms.txt). ContentTypeGroupTermAggregation The ContentTypeGroupTermAggregation aggregates search results by the content item's content type group. ## Arguments - `name` - name of the Aggregation object # DateMetadataRangeAggregation > For the complete documentation index, see [llms.txt](https://doc.ibexa.co/en/saas/llms.txt). DateMetadataRangeAggregation The DateMetadataRangeAggregation aggregates search results by the value of the content items' date metadata. ## Arguments - `name` - name of the Aggregation object - `type` - string representing the type of the Aggregation (`MODIFIED` or `PUBLISHED`) - `ranges` - array of Range objects that define the borders of the specific range sets # LanguageTermAggregation > For the complete documentation index, see [llms.txt](https://doc.ibexa.co/en/saas/llms.txt). LanguageTermAggregation The LanguageTermAggregation aggregates search results by the content item's language. ## Arguments - `name` - name of the Aggregation object # LocationChildrenTermAggregation > For the complete documentation index, see [llms.txt](https://doc.ibexa.co/en/saas/llms.txt). LocationChildrenTermAggregation The LocationChildrenTermAggregation aggregates search results by the number of children of a location. ## Arguments - `name` - name of the Aggregation object # ObjectStateTermAggregation > For the complete documentation index, see [llms.txt](https://doc.ibexa.co/en/saas/llms.txt). ObjectStateTermAggregation The ObjectStateTermAggregation aggregates search results by the content item's object state. ## Arguments - `name` - name of the Aggregation object - `objectStateGroupIdentifier` - string representing the identifier of the object state group to aggregate results by # RawRangeAggregation > For the complete documentation index, see [llms.txt](https://doc.ibexa.co/en/saas/llms.txt). RawRangeAggregation The RawRangeAggregation aggregates search results by the value of the selected search index field. ## Arguments - `name` - name of the Aggregation object - `field` - string representing the search index field - `ranges` - array of Range objects that define the borders of the specific range sets ## Limitations > **Caution: Caution** > > To keep your project search engine independent, don't use the `RawRangeAggregation` Aggregation in production code. Valid use cases are: testing, or temporary (one-off) tools. # RawStatsAggregation > For the complete documentation index, see [llms.txt](https://doc.ibexa.co/en/saas/llms.txt). RawStatsAggregation The RawStatsAggregation aggregates search results by the value of the selected search index field and provides statistical information for the values. You can use the provided getters to access the values: - sum (`getSum()`) - count of values (`getCount()`) - minimum value (`getMin()`) - maximum value (`getMax()`) - average (`getAvg()`) ## Arguments - `name` - name of the Aggregation object - `field` - string representing the search index field ## Limitations > **Caution: Caution** > > To keep your project search engine independent, don't use the `RawStatsAggregation` Aggregation in production code. Valid use cases are: testing, or temporary (one-off) tools. # RawTermAggregation > For the complete documentation index, see [llms.txt](https://doc.ibexa.co/en/saas/llms.txt). RawTermAggregation The RawTermAggregation aggregates search results by the value of the selected search index field. ## Arguments - `name` - name of the Aggregation object - `field` - string representing the search index field ## Limitations > **Caution: Caution** > > To keep your project search engine independent, don't use the `RawTermAggregation` Aggregation in production code. Valid use cases are: testing, or temporary (one-off) tools. # SectionTermAggregation > For the complete documentation index, see [llms.txt](https://doc.ibexa.co/en/saas/llms.txt). SectionTermAggregation The SectionTermAggregation aggregates search results by the content item's section. ## Arguments - `name` - name of the Aggregation object # SubtreeTermAggregation > For the complete documentation index, see [llms.txt](https://doc.ibexa.co/en/saas/llms.txt). SubtreeTermAggregation The SubtreeTermAggregation aggregates search results by the location's subtree path. ## Arguments - `name` - name of the Aggregation object - `pathString` - string representing the pathstring to aggregate results by # TaxonomyEntryIdAggregation > For the complete documentation index, see [llms.txt](https://doc.ibexa.co/en/saas/llms.txt). TaxonomyEntryIdAggregation The `TaxonomyEntryIdAggregation` aggregates search results by the content item's taxonomy entry or a product's category. ## Arguments - `name` - name of the Aggregation object - `taxonomyIdentifier` - identifier of the taxonomy to aggregate results by # UserMetadataTermAggregation > For the complete documentation index, see [llms.txt](https://doc.ibexa.co/en/saas/llms.txt). UserMetadataTermAggregation The UserMetadataTermAggregation aggregates search results by the User content item's metadata. ## Arguments - `name` - name of the Aggregation object # VisibilityTermAggregation > For the complete documentation index, see [llms.txt](https://doc.ibexa.co/en/saas/llms.txt). VisibilityTermAggregation The VisibilityTermAggregation aggregates search results by the content item's visibility. ## Arguments - `name` - name of the Aggregation object # AuthorTermAggregation > For the complete documentation index, see [llms.txt](https://doc.ibexa.co/en/saas/llms.txt). AuthorTermAggregation The field-based AuthorTermAggregation aggregates search results by the value of the Author field. ## Arguments - `name` - name of the Aggregation - `contentTypeIdentifier` - string representing the content type identifier - `fieldDefinitionIdentifier` - string representing the Field Definition identifier # CheckboxTermAggregation > For the complete documentation index, see [llms.txt](https://doc.ibexa.co/en/saas/llms.txt). CheckboxTermAggregation The field-based CheckboxTermAggregation aggregates search results by the value of the Checkbox field. ## Arguments - `name` - name of the Aggregation - `contentTypeIdentifier` - string representing the content type identifier - `fieldDefinitionIdentifier` - string representing the Field Definition identifier # CountryTermAggregation > For the complete documentation index, see [llms.txt](https://doc.ibexa.co/en/saas/llms.txt). CountryTermAggregation The field-based CountryTermAggregation aggregates search results by the value of the Country field. ## Arguments - `name` - name of the Aggregation - `contentTypeIdentifier` - string representing the content type identifier - `fieldDefinitionIdentifier` - string representing the Field Definition identifier # DateRangeAggregation > For the complete documentation index, see [llms.txt](https://doc.ibexa.co/en/saas/llms.txt). DateRangeAggregation The field-based DateRangeAggregation aggregates search results by the value of the Date, DateTime, or Time field. ## Arguments - `name` - name of the Aggregation - `contentTypeIdentifier` - string representing the content type identifier - `fieldDefinitionIdentifier` - string representing the Field Definition identifier - `ranges` - array of Range objects that define the borders of the specific range sets # DateTimeRangeAggregation > For the complete documentation index, see [llms.txt](https://doc.ibexa.co/en/saas/llms.txt). DateTimeRangeAggregation The field-based DateTimeRangeAggregation aggregates search results by the value of the Date, DateTime, or Time field. ## Arguments - `name` - name of the Aggregation - `contentTypeIdentifier` - string representing the content type identifier - `fieldDefinitionIdentifier` - string representing the Field Definition identifier - `ranges` - array of Range objects that define the borders of the specific range sets # FloatRangeAggregation > For the complete documentation index, see [llms.txt](https://doc.ibexa.co/en/saas/llms.txt). FloatRangeAggregation The field-based FloatRangeAggregation aggregates search results by the value of the Float field. ## Arguments - `name` - name of the Aggregation - `contentTypeIdentifier` - string representing the content type identifier - `fieldDefinitionIdentifier` - string representing the Field Definition identifier - `ranges` - array of Range objects that define the borders of the specific range sets # FloatStatsAggregation > For the complete documentation index, see [llms.txt](https://doc.ibexa.co/en/saas/llms.txt). FloatStatsAggregation The field-based FloatStatsAggregation aggregates search results by the value of the Float field and provides statistical information for the values. You can use the provided getters to access the values: - sum (`getSum()`) - count of values (`getCount()`) - minimum value (`getMin()`) - maximum value (`getMax()`) - average (`getAvg()`) ## Arguments - `name` - name of the Aggregation - `contentTypeIdentifier` - string representing the content type identifier - `fieldDefinitionIdentifier` - string representing the Field Definition identifier # IntegerRangeAggregation > For the complete documentation index, see [llms.txt](https://doc.ibexa.co/en/saas/llms.txt). IntegerRangeAggregation The field-based IntegerRangeAggregation aggregates search results by the value of the Integer field. ## Arguments - `name` - name of the Aggregation - `contentTypeIdentifier` - string representing the content type identifier - `fieldDefinitionIdentifier` - string representing the Field Definition identifier - `ranges` - array of Range objects that define the borders of the specific range sets # IntegerStatsAggregation > For the complete documentation index, see [llms.txt](https://doc.ibexa.co/en/saas/llms.txt). IntegerStatsAggregation The field-based IntegerStatsAggregation aggregates search results by the value of the Integer field and provides statistical information for the values. You can use the provided getters to access the values: - sum (`getSum()`) - count of values (`getCount()`) - minimum value (`getMin()`) - maximum value (`getMax()`) - average (`getAvg()`) ## Arguments - `name` - name of the Aggregation - `contentTypeIdentifier` - string representing the content type identifier - `fieldDefinitionIdentifier` - string representing the Field Definition identifier # KeywordTermAggregation > For the complete documentation index, see [llms.txt](https://doc.ibexa.co/en/saas/llms.txt). KeywordTermAggregation The field-based KeywordTermAggregation aggregates search results by the value of the Keyword field. ## Arguments - `name` - name of the Aggregation - `contentTypeIdentifier` - string representing the content type identifier - `fieldDefinitionIdentifier` - string representing the Field Definition identifier # SelectionTermAggregation > For the complete documentation index, see [llms.txt](https://doc.ibexa.co/en/saas/llms.txt). SelectionTermAggregation The field-based SelectionTermAggregation aggregates search results by the value of the Selection field. ## Arguments - `name` - name of the Aggregation - `contentTypeIdentifier` - string representing the content type identifier - `fieldDefinitionIdentifier` - string representing the Field Definition identifier # TimeRangeAggregation > For the complete documentation index, see [llms.txt](https://doc.ibexa.co/en/saas/llms.txt). TimeRangeAggregation The field-based TimeRangeAggregation aggregates search results by the value of the Date, DateTime, or Time field. ## Arguments - `name` - name of the Aggregation - `contentTypeIdentifier` - string representing the content type identifier - `fieldDefinitionIdentifier` - string representing the Field Definition identifier - `ranges` - array of Range objects that define the borders of the specific range sets # Product attribute aggregations > For the complete documentation index, see [llms.txt](https://doc.ibexa.co/en/saas/llms.txt). Product attribute aggregations aggregate search results by the value of the product's attributes. Product attribute aggregations aggregate search results by the value of the product's attributes. Depending on attribute type, the following aggregations are available: - `ProductAttributeBooleanAggregation` - `ProductAttributeColorAggregation` - `ProductAttributeFloatAggregation` - `ProductAttributeFloatRangeAggregation` - `ProductAttributeIntegerAggregation` - `ProductAttributeIntegerRangeAggregation` - `ProductAttributeSelectionAggregation` ## Arguments - `name` - name of the Aggregation - `attributeDefinitionIdentifier` - identifier of the attribute Range aggregations (`ProductAttributeFloatRangeAggregation` and `ProductAttributeIntegerRangeAggregation`) additionally take: - `ranges` - array of Range objects that define the borders of the specific range sets # BasePriceStatsAggregation > For the complete documentation index, see [llms.txt](https://doc.ibexa.co/en/saas/llms.txt). BasePriceStatsAggregation The BasePriceStatsAggregation aggregates search results by the value of the product's price can provides statistical information for the values. You can use the provided getters to access the values: - sum (`getSum()`) - count of values (`getCount()`) - minimum value (`getMin()`) - maximum value (`getMax()`) - average (`getAvg()`) ## Arguments - `name` - name of the Aggregation - `\Ibexa\Contracts\ProductCatalog\Values\CurrencyInterface` - currency of the price # CustomPriceStatsAggregation > For the complete documentation index, see [llms.txt](https://doc.ibexa.co/en/saas/llms.txt). CustomPriceStatsAggregation The CustomPriceStatsAggregation aggregates search results by the value of the custom product's price and provides statistical information for the values. You can use the provided getters to access the values: - sum (`getSum()`) - count of values (`getCount()`) - minimum value (`getMin()`) - maximum value (`getMax()`) - average (`getAvg()`) ## Arguments - `name` - name of the Aggregation - `\Ibexa\Contracts\ProductCatalog\Values\CurrencyInterface` - currency of the price - `\Ibexa\Contracts\ProductCatalog\Values\CustomerGroupInterface|null` - customer group that defines custom pricing, by default it's the one assigned to current user # ProductAvailabilityTerm > For the complete documentation index, see [llms.txt](https://doc.ibexa.co/en/saas/llms.txt). ProductAvailabilityTerm The ProductAvailabilityTermAggregation aggregates search results by product availability (available/unavailable). ## Arguments - `name` - name of the Aggregation object # ProductStockRangeAggregation > For the complete documentation index, see [llms.txt](https://doc.ibexa.co/en/saas/llms.txt). ProductStockRangeAggregation The ProductStockRangeAggregation aggregates search results by products' numerical stock. ## Arguments - `name` - name of the Aggregation - `ranges` - array of Range objects that define the borders of the specific range sets # ProductPriceRangeAggregation > For the complete documentation index, see [llms.txt](https://doc.ibexa.co/en/saas/llms.txt). ProductPriceRangeAggregation The ProductPriceRangeAggregation aggregates search results by the value of the product's price. ## Arguments - `name` - name of the Aggregation - `currencyCode` - currency code of the price - `ranges` - array of Range objects that define the borders of the specific range sets # ProductTypeTerm > For the complete documentation index, see [llms.txt](https://doc.ibexa.co/en/saas/llms.txt). ProductTypeTerm The ProductTypeTermAggregation aggregates search results by the product type. ## Arguments - `name` - name of the Aggregation object # Embeddings search reference > For the complete documentation index, see [llms.txt](https://doc.ibexa.co/en/saas/llms.txt). Embedding queries, embedding configuration, providers, and embedding search fields Embeddings provide vector representations of content or text, enabling semantic similarity search. Foundational abstractions are provided for embedding-based search, while embedding providers generate vector representations. Searching with embeddings is designed for use with the [Taxonomy suggestions](https://doc.ibexa.co/en/saas/content_management/taxonomy/taxonomy/#taxonomy-suggestions) feature. The `Ibexa\Contracts\Taxonomy\Search\Query\Value\TaxonomyEmbedding` class allows embedding queries to target taxonomy data. > **Note: Feature support** > > Searching with embeddings requires a search engine that supports it, such as Elasticsearch or Solr 9.8.1+. ## Core query objects ### EmbeddingQuery - `Ibexa\Contracts\Core\Repository\Values\Content\EmbeddingQuery` represents a semantic similarity search request. It encapsulates an [Embedding](#embedding) instance and supports pagination, aggregations, and result counting through the same API as standard content queries. > **Note: Embedding query properties** > > Embedding queries do not use criteria for similarity, but for additional filtering applied through the query filter. Also, embedding queries do not allow standard Query properties supported by search engines other than the Legacy Search, such as `query`, `sortClauses`, or `spellcheck`. - EmbeddingQueryBuilder is a builder for constructing `EmbeddingQuery` instances. It helps construct queries consistently and integrates embedding queries with the search query pipeline. You must provide the required embedding value by using the `withEmbedding` method ### Embedding - `Ibexa\Contracts\Core\Repository\Values\Content\Query\Embedding` represents the vector input used for similarity search. It stores embedding values as float arrays, while providers generate those vectors from text input ## Query execution Embedding queries are executed by the search engine by using the configured embedding model and provider. At runtime, the system resolves the appropriate embedding provider and ensures that the embedding vector is compatible with the configured model. Runtime validation includes validating vector dimensionality and selecting the correct indexed field for similarity search. Field selection is determined by the configured embedding model and backend specific query mapping, while vector dimensionality is validated when the query reaches the search engine. ## Embedding providers Embedding providers implement the contract for generating vector representations of input data. Out of the box, embedding search integration is provided for `TaxonomyEmbedding`. If you use a custom embedding value type, implement matching embedding visitors for your search engine. Otherwise, query execution may fail due to no visitor available. - `Ibexa\Contracts\Core\Search\Embedding\EmbeddingProviderInterface` generates embeddings for the provided text or other input - `Ibexa\Contracts\Core\Search\Embedding\EmbeddingProviderRegistryInterface` lists available embedding providers or gets one by its identifier - `Ibexa\Contracts\Core\Search\Embedding\EmbeddingProviderResolverInterface` determines the embedding provider to be used for generating embeddings based on the system configuration, or a demand passed through the `resolveByModelIdentifier` method ## Configuration Models used to resolve embedding queries must be configured per SiteAccess in [system configuration](https://doc.ibexa.co/en/saas/administration/configuration/configuration/index.md). Each entry defines the model's name, vector dimensionality, the field suffix, and the embedding provider that generates vectors. Field suffixes assigned to the models must be unique, as they become part of the indexed field name. You select the default model by setting a value in the `default_embedding_model` key. ```yaml ibexa: system: default: embedding_models: text-embedding-3-small: name: 'text-embedding-3-small' dimensions: 1536 field_suffix: '3small' embedding_provider: 'ibexa_openai' default_embedding_model: text-embedding-ada-002 ``` For a real-life example of embedding models configuration, see [Taxonomy suggestions](https://doc.ibexa.co/en/saas/content_management/taxonomy/taxonomy/#change-embedding-generation-models-or-embedding-provider). - EmbeddingConfigurationInterface allows access to the embedding model configuration in the system (for example, list of available models, default model name, default provider, field suffix, and so on) ## Embedding fields Embedding vectors are stored in dedicated search fields. These fields can be used by the search engine to perform vector similarity comparisons when embedding queries are executed. - `Ibexa\Contracts\Core\Search\FieldType\EmbeddingFieldFactory` creates dedicated search fields that store embedding vectors ## Validation - `Ibexa\Contracts\Core\Repository\Values\Content\QueryValidatorInterface` validates embedding query structure before execution # Search in trash reference > For the complete documentation index, see [llms.txt](https://doc.ibexa.co/en/saas/llms.txt). Trash Search Criteria and Sort Clauses help define and fine-tune search queries for content in trash. When you search for content items that are held in trash, you can apply only a limited subset of Search Criteria and Sort Clauses which can be used by `Ibexa\Contracts\Core\Repository\TrashService::findTrashItems`. Some sort clauses are exclusive to trash search. ## Search Criteria - [ContentName](https://doc.ibexa.co/en/saas/search/criteria_reference/contentname_criterion/index.md) - [ContentTypeId](https://doc.ibexa.co/en/saas/search/criteria_reference/contenttypeid_criterion/index.md) - [DateMetadata](https://doc.ibexa.co/en/saas/search/criteria_reference/datemetadata_criterion/index.md) (which can use the additional exclusive target `DateMetadata::TRASHED`) - [MatchAll](https://doc.ibexa.co/en/saas/search/criteria_reference/matchall_criterion/index.md) - [MatchNone](https://doc.ibexa.co/en/saas/search/criteria_reference/matchnone_criterion/index.md) - [SectionId](https://doc.ibexa.co/en/saas/search/criteria_reference/sectionid_criterion/index.md) - [UserMetadata](https://doc.ibexa.co/en/saas/search/criteria_reference/usermetadata_criterion/index.md) ## Logical operators - [LogicalAnd](https://doc.ibexa.co/en/saas/search/criteria_reference/logicaland_criterion/index.md) - [LogicalNot](https://doc.ibexa.co/en/saas/search/criteria_reference/logicalor_criterion/index.md) - [LogicalOr](https://doc.ibexa.co/en/saas/search/criteria_reference/logicalor_criterion/index.md) ## Sort Clauses - [ContentName](https://doc.ibexa.co/en/saas/search/sort_clause_reference/contentname_sort_clause/index.md) - [ContentTypeName](https://doc.ibexa.co/en/saas/search/sort_clause_reference/contenttypename_sort_clause/index.md) - [DateTrashed](https://doc.ibexa.co/en/saas/search/sort_clause_reference/datetrashed_sort_clause/index.md) - [Depth](https://doc.ibexa.co/en/saas/search/sort_clause_reference/depth_sort_clause/index.md) - [Path](https://doc.ibexa.co/en/saas/search/sort_clause_reference/path_sort_clause/index.md) - [Priority](https://doc.ibexa.co/en/saas/search/sort_clause_reference/priority_sort_clause/index.md) - [SectionName](https://doc.ibexa.co/en/saas/search/sort_clause_reference/sectionname_sort_clause/index.md) - [UserLogin](https://doc.ibexa.co/en/saas/search/sort_clause_reference/userlogin_sort_clause/index.md) # Product guides # Product guides > For the complete documentation index, see [llms.txt](https://doc.ibexa.co/en/saas/llms.txt). Discover various Cohesivo features. Cohesivo comes with a variety of features. Discover the primary ones with the help of product guides. Condensed content allows you to quickly learn about their capabilities and benefits. - [User management product guide](https://ez-systems-developer-documentation--3403.com.readthedocs.build/en/3403/users/user_management_guide/): Find out what's user management and check what functions Cohesivo offers in this area to effectively manage the digital ecosystem. - [Content management product guide](https://ez-systems-developer-documentation--3403.com.readthedocs.build/en/3403/content_management/content_management_guide/): Read the content management product guide and learn how to create, modify, and display information to the target audience. - [Online Editor product guide](https://ez-systems-developer-documentation--3403.com.readthedocs.build/en/3403/content_management/rich_text/online_editor_guide/): Learn how to use the Online Editor, a tool that allows you to edit RichText Fields in any content item in Cohesivo. - [Page Builder product guide](https://ez-systems-developer-documentation--3403.com.readthedocs.build/en/3403/content_management/pages/page_builder_guide/): Read about the Page Builder - a powerful tool for creating and modifying pages in Cohesivo. - [Form Builder product guide](https://ez-systems-developer-documentation--3403.com.readthedocs.build/en/3403/content_management/forms/form_builder_guide/): See the Form Builder product guide and learn how to create various forms to increase the functionality of your website. - [Customer Portal](https://ez-systems-developer-documentation--3403.com.readthedocs.build/en/3403/customer_management/customer_portal/): Customer Portal allows your business clients to create and manage their company accounts. - [Product catalog guide](https://ez-systems-developer-documentation--3403.com.readthedocs.build/en/3403/product_catalog/product_catalog_guide/): The product catalog guide provides a full description of the features and capabilities for managing products, their specifications, variants, pricing, and organization. - [Quable product guide](https://ez-systems-developer-documentation--3403.com.readthedocs.build/en/3403/product_catalog/quable/quable_guide/): The Quable product guide describes how you can use the product data from Quable in Cohesivo to create marketing campaigns built around your products. - [Raptor CDP product guide](https://ez-systems-developer-documentation--3403.com.readthedocs.build/en/3403/raptor_cdp/raptor_cdp_guide/): The Raptor CDP product guide describes all the possibilities that the Customer Data Platform offers to help you build great customer experiences. - [Raptor integration product guide](https://ez-systems-developer-documentation--3403.com.readthedocs.build/en/3403/recommendations/raptor_integration/raptor_connector_guide/): Discover Raptor integration - an add-on focused on recommendations and tracking customer behaviors. - [AI Actions product guide](https://ez-systems-developer-documentation--3403.com.readthedocs.build/en/3403/ai/ai_actions/ai_actions_guide/): AI Actions help editors by automating repetitive tasks. - [MCP Servers product guide](https://ez-systems-developer-documentation--3403.com.readthedocs.build/en/3403/ai/mcp/mcp_guide/): MCP servers expose tools, specialized prompts, and resources to AI agents. # Release notes # Cohesivo release notes > For the complete documentation index, see [llms.txt](https://doc.ibexa.co/en/saas/llms.txt). Cohesivo release notes list the new features and improvements delivered to the platform. ## TODO: Release notes for SaaS (New feature) Release date: 2026-07-01 ### Highlights - ASD - QWE