Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
33 changes: 0 additions & 33 deletions docs/api/rest_api/rest_api_authentication.md
Original file line number Diff line number Diff line change
Expand Up @@ -276,39 +276,6 @@ See [JWT authentication](development_security.md#jwt-authentication) for configu

After you configure JWT authentication for REST, you can get the JWT token through the following request:

=== "XML"

```
POST /user/token/jwt HTTP/1.1
Host: <yourdomain>
Accept: application/vnd.ibexa.api.JWT+xml
Content-Type: application/vnd.ibexa.api.JWTInput+xml
```

Provide the username and password in the request body:

```xml
<JWTInput>
<username>admin</username>
<password>publish</password>
</JWTInput>
```

If credentials are valid, the server response contains a token:

```xml
<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.

```
GET /content/locations/1/5/children
Host: <yourdomain>
Authorization: Bearer eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9…-QBE4-6eKNjg
Accept: application/vnd.ibexa.api.LocationList+xml
```

=== "JSON"

```
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -126,24 +126,29 @@ It's already provided in `config/packages/security.yaml`, you only need to uncom
security:
firewalls:
ibexa_jwt_rest:
request_matcher: Ibexa\Contracts\Rest\Security\AuthorizationHeaderRESTRequestMatcher
request_matcher: Ibexa\Rest\Security\JWTTokenCreationRESTRequestMatcher
user_checker: Ibexa\Core\MVC\Symfony\Security\UserChecker
anonymous: ~
guard:
authenticators:
- lexik_jwt_authentication.jwt_token_authenticator
entry_point: lexik_jwt_authentication.jwt_token_authenticator
stateless: true
provider: ibexa
json_login:
check_path: ibexa.rest.create_token
username_path: JWTInput.username
password_path: JWTInput.password
success_handler: lexik_jwt_authentication.handler.authentication_success
failure_handler: lexik_jwt_authentication.handler.authentication_failure

ibexa_jwt_rest.api:
request_matcher: Ibexa\Rest\Security\AuthorizationHeaderRESTRequestMatcher
user_checker: Ibexa\Core\MVC\Symfony\Security\UserChecker
provider: ibexa
stateless: true
jwt: ~

ibexa_jwt_graphql:
request_matcher: Ibexa\GraphQL\Security\NonAdminGraphQLRequestMatcher
user_checker: Ibexa\Core\MVC\Symfony\Security\UserChecker
anonymous: ~
guard:
authenticators:
- lexik_jwt_authentication.jwt_token_authenticator
entry_point: lexik_jwt_authentication.jwt_token_authenticator
provider: ibexa
stateless: true
jwt: ~
```

Finish the setup by generating a [PEM encoded key pair](https://symfony.com/bundles/LexikJWTAuthenticationBundle/2.x/index.html#generate-the-ssl-keys) by using the command:
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,78 @@
---
description: Use existing controllers to render recommendations outside the Page Builder.
month_change: true
---

# Custom recommendation rendering

You can use existing controllers to render [recommendations](recommendation_blocks.md) outside the Page Builder.
The controllers responsible for rendering block recommendations on the front-end are independent and can be used to render recommendations for specific strategies.

Check notice on line 9 in docs/recommendations/raptor_integration/custom_recommendation_rendering.md

View workflow job for this annotation

GitHub Actions / vale

[vale] docs/recommendations/raptor_integration/custom_recommendation_rendering.md#L9

[Ibexa.Passive] Try to avoid passive tense, when possible.
Raw output
{"message": "[Ibexa.Passive] Try to avoid passive tense, when possible.", "location": {"path": "docs/recommendations/raptor_integration/custom_recommendation_rendering.md", "range": {"start": {"line": 9, "column": 106}}}, "severity": "INFO"}

Each controller can be used to retrieve and display recommendations within a Twig template as follows:

Check notice on line 11 in docs/recommendations/raptor_integration/custom_recommendation_rendering.md

View workflow job for this annotation

GitHub Actions / vale

[vale] docs/recommendations/raptor_integration/custom_recommendation_rendering.md#L11

[Ibexa.Passive] Try to avoid passive tense, when possible.
Raw output
{"message": "[Ibexa.Passive] Try to avoid passive tense, when possible.", "location": {"path": "docs/recommendations/raptor_integration/custom_recommendation_rendering.md", "range": {"start": {"line": 11, "column": 21}}}, "severity": "INFO"}

``` html+twig
{{ render(controller('<Controller name>', {
'limit': limit,
'template': '@ibexadesign/<your_template_path>.html.twig',
'<another_parameter>': parameter_value
})) }}
```

The controllers are placed in the `Ibexa\Bundle\ConnectorRaptor\Controller\Block` namespace.

Check notice on line 21 in docs/recommendations/raptor_integration/custom_recommendation_rendering.md

View workflow job for this annotation

GitHub Actions / vale

[vale] docs/recommendations/raptor_integration/custom_recommendation_rendering.md#L21

[Ibexa.Passive] Try to avoid passive tense, when possible.
Raw output
{"message": "[Ibexa.Passive] Try to avoid passive tense, when possible.", "location": {"path": "docs/recommendations/raptor_integration/custom_recommendation_rendering.md", "range": {"start": {"line": 21, "column": 17}}}, "severity": "INFO"}

Each controller always requires these two parameters:

- **limit** – the number of recommendations to render
- **template** – the path to the template

Any other required parameters are specific to each controller and are detailed in the **Parameters** column of the table below:

Check notice on line 28 in docs/recommendations/raptor_integration/custom_recommendation_rendering.md

View workflow job for this annotation

GitHub Actions / vale

[vale] docs/recommendations/raptor_integration/custom_recommendation_rendering.md#L28

[Ibexa.Passive] Try to avoid passive tense, when possible.
Raw output
{"message": "[Ibexa.Passive] Try to avoid passive tense, when possible.", "location": {"path": "docs/recommendations/raptor_integration/custom_recommendation_rendering.md", "range": {"start": {"line": 28, "column": 67}}}, "severity": "INFO"}

|Block name| Controller |Parameters|Recommendation item type|
|----------|---------------------------------------------------------------------------------------------|----------|------------------------|
|[Content that have been seen along with the item category]([[= user_doc =]]/personalization/raptor_integration/raptor_recommendation_blocks/#content-that-have-been-seen-along-with-the-item-category-block)| <nobr>`ContentBasedOnProductCategoryBlockController`</nobr><br><nobr>`::showAction()`</nobr> |<nobr>`categoryId` (integer),</nobr><br><nobr>`limit` (integer),</nobr><br><nobr>`template` (string)</nobr>|Content|
|[Most popular content]([[= user_doc =]]/personalization/raptor_integration/raptor_recommendation_blocks/#most-popular-content-block)| <nobr>`PopularContentBlockController`</nobr><br><nobr>`::showAction()`</nobr> |<nobr>`limit` (integer),</nobr><br><nobr>`template` (string)</nobr>|Content|
|[Most popular products]([[= user_doc =]]/personalization/raptor_integration/raptor_recommendation_blocks/#most-popular-products-block)| <nobr>`PopularItemsBlockController`</nobr><br><nobr>`::showAction()`</nobr> |<nobr>`showInStock` (boolean),</nobr><br><nobr>`limit` (integer),</nobr><br><nobr>`template` (string)</nobr>|Product|
|[Most popular products in category]([[= user_doc =]]/personalization/raptor_integration/raptor_recommendation_blocks/#most-popular-products-in-category-block)| <nobr>`PopularItemsInCategoryBlockController`</nobr><br><nobr>`::showAction()`</nobr> |<nobr>`categoryId` (integer),</nobr><br><nobr>`showInStock` (boolean),</nobr><br><nobr>`limit` (integer),</nobr><br><nobr>`template` (string)</nobr>|Product|
|[Other customers have also seen]([[= user_doc =]]/personalization/raptor_integration/raptor_recommendation_blocks/#other-customers-have-also-seen-block)| <nobr>`SimilarItemsBlockController`</nobr><br><nobr>`::showAction()`</nobr> |<nobr>`productCode` (string),</nobr><br><nobr>`showInStock` (boolean),</nobr><br><nobr>`limit` (integer),</nobr><br><nobr>`template` (string)</nobr>|Product|
|[Other customers have also seen this content]([[= user_doc =]]/personalization/raptor_integration/raptor_recommendation_blocks/#other-customers-have-also-seen-this-content-block)| <nobr>`SimilarContentBlockController`</nobr><br><nobr>`::showAction()`</nobr> |<nobr>`contentId` (integer),</nobr><br><nobr>`limit` (integer),</nobr><br><nobr>`template` (string)</nobr>|Content|
|[Other Customers Have also Purchased block]([[= user_doc =]]/personalization/raptor_integration/raptor_recommendation_blocks/#other-customers-have-also-purchased-block)| <nobr>`OtherCustomersAlsoPurchasedBlockController`</nobr><br><nobr>`::showAction()`</nobr> |<nobr>`productCode` (string),</nobr><br><nobr>`limit` (integer),</nobr><br><nobr>`template` (string)</nobr>|Product|
|[Personalized content recommendations]([[= user_doc =]]/personalization/raptor_integration/raptor_recommendation_blocks/#personalized-content-recommendations-block)| <nobr>`UserContentRecommendationsBlockController`</nobr><br><nobr>`::showAction()`</nobr> |<nobr>`limit` (integer),</nobr><br><nobr>`template` (string)</nobr>|Content|
|[The Personal Shopping Assistant]([[= user_doc =]]/personalization/raptor_integration/raptor_recommendation_blocks/#the-personal-shopping-assistant-block)| <nobr>`UserItemRecommendationsBlockController`</nobr><br><nobr>`::showAction()`</nobr> |<nobr>`productCode` (string),</nobr><br><nobr>`showInStock` (boolean),</nobr><br><nobr>`limit` (integer),</nobr><br><nobr>`template` (string)</nobr>|Product|
|[User's item history]([[= user_doc =]]/personalization/raptor_integration/raptor_recommendation_blocks/#users-item-history-block)| <nobr>`UserItemHistoryBlockController`</nobr><br><nobr>`::showAction()`</nobr> |<nobr>`showInStock` (boolean),</nobr><br><nobr>`limit` (integer),</nobr><br><nobr>`template` (string)</nobr>|Product|

Each template receives a `recommendations` Twig variable, which is a list containing either [`Ibexa\Contracts\ProductCatalog\Values\ProductInterface`](/api/php_api/php_api_reference/classes/Ibexa-Contracts-ProductCatalog-Values-ProductInterface.html) instances for product recommendations or [`Ibexa\Contracts\Core\Repository\Values\Content\Content`](/api/php_api/php_api_reference/classes/Ibexa-Contracts-Core-Repository-Values-Content-Content.html) instances for content recommendations.

Check notice on line 43 in docs/recommendations/raptor_integration/custom_recommendation_rendering.md

View workflow job for this annotation

GitHub Actions / vale

[vale] docs/recommendations/raptor_integration/custom_recommendation_rendering.md#L43

[Ibexa.SentenceLength] Keep your sentences to less than 30 words.
Raw output
{"message": "[Ibexa.SentenceLength] Keep your sentences to less than 30 words.", "location": {"path": "docs/recommendations/raptor_integration/custom_recommendation_rendering.md", "range": {"start": {"line": 43, "column": 1}}}, "severity": "INFO"}

Two generic templates are provided and can be used in `./templates/themes/<theme>` directory:

Check notice on line 45 in docs/recommendations/raptor_integration/custom_recommendation_rendering.md

View workflow job for this annotation

GitHub Actions / vale

[vale] docs/recommendations/raptor_integration/custom_recommendation_rendering.md#L45

[Ibexa.Passive] Try to avoid passive tense, when possible.
Raw output
{"message": "[Ibexa.Passive] Try to avoid passive tense, when possible.", "location": {"path": "docs/recommendations/raptor_integration/custom_recommendation_rendering.md", "range": {"start": {"line": 45, "column": 23}}}, "severity": "INFO"}

Check notice on line 45 in docs/recommendations/raptor_integration/custom_recommendation_rendering.md

View workflow job for this annotation

GitHub Actions / vale

[vale] docs/recommendations/raptor_integration/custom_recommendation_rendering.md#L45

[Ibexa.Passive] Try to avoid passive tense, when possible.
Raw output
{"message": "[Ibexa.Passive] Try to avoid passive tense, when possible.", "location": {"path": "docs/recommendations/raptor_integration/custom_recommendation_rendering.md", "range": {"start": {"line": 45, "column": 44}}}, "severity": "INFO"}

- `@ibexadesign/ibexa/recommendations/_content_list.html.twig` for content items:

``` html+twig
{% if recommendations is not empty %}
{% for content in recommendations %}
{% set location = content.contentInfo.mainLocation %}
{% if location %}
<p><a href="{{ ibexa_path(location) }}">{{ ibexa_content_name(content) }}</a></p>
{% else %}
<p>{{ ibexa_content_name(content) }}</p>
{% endif %}
{% endfor %}
{% endif %}
```

- `@ibexadesign/ibexa/recommendations/_product_list.html.twig` for products:

``` html+twig
{% if recommendations is not empty %}
<ul>
{% for product in recommendations %}
<li><a href="{{ ibexa_path(product) }}">{{ product.name }}</a></li>
{% endfor %}
</ul>
{% endif %}
```

To fetch recommendations for the remaining modules, you need to [create a custom controller](controllers.md) and use a method from [`Ibexa\Contracts\ConnectorRaptor\Recommendations\RecommendationsServiceInterface`](/api/php_api/php_api_reference/classes/Ibexa-Contracts-ConnectorRaptor-Recommendations-RecommendationsServiceInterface.html).

Using this method, recommendations can be displayed on any page, for example on a specific product page, as shown below:

Check notice on line 76 in docs/recommendations/raptor_integration/custom_recommendation_rendering.md

View workflow job for this annotation

GitHub Actions / vale

[vale] docs/recommendations/raptor_integration/custom_recommendation_rendering.md#L76

[Ibexa.ByUsingStartOfLine] Prefer 'by using' or 'with' to plain 'using'.
Raw output
{"message": "[Ibexa.ByUsingStartOfLine] Prefer 'by using' or 'with' to plain 'using'.", "location": {"path": "docs/recommendations/raptor_integration/custom_recommendation_rendering.md", "range": {"start": {"line": 76, "column": 1}}}, "severity": "INFO"}

Check notice on line 76 in docs/recommendations/raptor_integration/custom_recommendation_rendering.md

View workflow job for this annotation

GitHub Actions / vale

[vale] docs/recommendations/raptor_integration/custom_recommendation_rendering.md#L76

[Ibexa.Passive] Try to avoid passive tense, when possible.
Raw output
{"message": "[Ibexa.Passive] Try to avoid passive tense, when possible.", "location": {"path": "docs/recommendations/raptor_integration/custom_recommendation_rendering.md", "range": {"start": {"line": 76, "column": 40}}}, "severity": "INFO"}

![Custom rendering](custom_rendering.png)
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
2 changes: 2 additions & 0 deletions docs/release_notes/ibexa_dxp_v5.0_deprecations.md
Original file line number Diff line number Diff line change
Expand Up @@ -459,6 +459,8 @@ Support for facets in `ibexa/elasticsearch` has been dropped, use the `Aggregati
| `\Ibexa\Rest\Server\Controller\User::refreshSession` | `\Ibexa\Rest\Server\Controller\SessionController::refreshSessionAction` |
| `\Ibexa\Rest\Server\Controller\User::deleteSession` | `\Ibexa\Rest\Server\Controller\SessionController::refreshSessionAction` |

To create a [JWT token](rest_api_authentication.md#jwt-authentication), XML isn't supported anymore.

### ibexa/scheduler

| Old FQN | New FQN / Comment |
Expand Down
1 change: 1 addition & 0 deletions mkdocs.yml
Original file line number Diff line number Diff line change
Expand Up @@ -506,6 +506,7 @@ nav:
- Tracking functions: recommendations/raptor_integration/tracking_functions.md
- Tracking with PHP API: recommendations/raptor_integration/tracking_php_api.md
- Recommendations blocks: recommendations/raptor_integration/recommendation_blocks.md
- Custom recommendation rendering: recommendations/raptor_integration/custom_recommendation_rendering.md
- CDP (Customer Data Platform):
- Customer Data Platform: cdp/cdp.md
- CDP guide: cdp/cdp_guide.md
Expand Down
Loading