diff --git a/.github/workflows/preview_comment.yaml b/.github/workflows/preview_comment.yaml new file mode 100644 index 0000000000..2ef2072f35 --- /dev/null +++ b/.github/workflows/preview_comment.yaml @@ -0,0 +1,70 @@ +name: "Post preview links for changed files" + +on: + pull_request: + paths: + - 'docs/**.md' + workflow_call: + inputs: + project: + description: 'The project to build (dev doc, user doc)' + default: '' + required: false + type: string + +jobs: + post-preview-links: + name: Post preview links for changed files + runs-on: ubuntu-latest + permissions: + # Needed to manage the comment + pull-requests: write + + steps: + - uses: actions/checkout@v4 + with: + fetch-depth: 0 + + - name: Create comment for changed files + run: | + file_limit=100 + build_url="https://ez-systems-developer-documentation--${{ github.event.pull_request.number }}.com.readthedocs.build/${{inputs.project}}en/${{ github.event.pull_request.number }}/" + + changed_files=$(git diff --name-only HEAD "origin/$GITHUB_BASE_REF" | grep -E ".md$" || [[ $? == 1 ]]) + number_of__changed_files=$(echo "$changed_files" | wc -l) + + if [[ $changed_files -eq "" ]] ; then + comment="Preview of modified files:: no markdown files changed, no preview needed." + elif [[ $number_of__changed_files -gt file_limit ]] ; then + comment="Preview of modified files: too many files modified in a single PR. Unable to post preview links, sorry!" + else + filenames=$(echo "$changed_files" | rev | cut -d / -f 1 | cut -d . -f 2- | rev) + + # Guess the URL based on Markdown file location. Remove the .md extension. + urls=$(echo "$changed_files" | cut -d / -f 2- | rev | cut -d '.' -f 2- | rev | sed -e "s ^ $build_url ") + + left=$(yes "+ [" | head -n "$number_of__changed_files" ) + middle=$(yes "](" | head -n "$number_of__changed_files" ) + right=$(yes ")\n" | head -n "$number_of__changed_files" ) + + comment=$(paste -d'\0' <(echo "$left") <(echo "$filenames") <(echo "$middle") <(echo "$urls") <(echo "$right")) + comment="Preview of modified files:\n\n$comment" + fi + + echo -e $comment > comment.md + + - name: Find comment + id: find-comment + uses: peter-evans/find-comment@v3 + with: + issue-number: ${{ github.event.pull_request.number }} + comment-author: 'github-actions[bot]' + body-includes: 'Preview of modified files' + + - name: Create or update comment + uses: peter-evans/create-or-update-comment@v4 + with: + comment-id: ${{ steps.find-comment.outputs.comment-id }} + issue-number: ${{ github.event.pull_request.number }} + body-path: comment.md + edit-mode: replace diff --git a/docs/administration/configuration/repository_configuration.md b/docs/administration/configuration/repository_configuration.md index cd496995d8..2378957430 100644 --- a/docs/administration/configuration/repository_configuration.md +++ b/docs/administration/configuration/repository_configuration.md @@ -80,7 +80,7 @@ ibexa: prefix: Ibexa\Bundle\Core\Entity ``` -For more information, see [DoctrineBundle documentation](https://symfony.com/doc/3.4/reference/configuration/doctrine.html). +For more information, see [DoctrineBundle documentation]([[= symfony_doc =]]/reference/configuration/doctrine.html). !!! note diff --git a/docs/api/rest_api/rest_api_usage/rest_requests.md b/docs/api/rest_api/rest_api_usage/rest_requests.md index a0cf722df4..14a6190351 100644 --- a/docs/api/rest_api/rest_api_usage/rest_requests.md +++ b/docs/api/rest_api/rest_api_usage/rest_requests.md @@ -157,7 +157,7 @@ When searching for content items (or locations), the query grammar is also parti ### Creating content with binary attachments -The example below is a command-line script to upload images. It's based on the [Symfony HttpClient](https://symfony.com/doc/5.4/http_client.html). +The example below is a command-line script to upload images. It's based on the [Symfony HttpClient]([[= symfony_doc =]]/http_client.html). This script: diff --git a/docs/api/rest_api/rest_api_usage/testing_rest_api.md b/docs/api/rest_api/rest_api_usage/testing_rest_api.md index 8c8f5c0c40..281bd165a7 100644 --- a/docs/api/rest_api/rest_api_usage/testing_rest_api.md +++ b/docs/api/rest_api/rest_api_usage/testing_rest_api.md @@ -24,7 +24,7 @@ For examples of using `curl`, refer to: ## PHP -You can use [Symfony HttpClient](https://symfony.com/doc/5.4/http_client.html) to test REST API. +You can use [Symfony HttpClient]([[= symfony_doc =]]/http_client.html) to test REST API. Open a PHP shell in a terminal with `php -a` and copy-paste this code into it: ``` php diff --git a/docs/commerce/storefront/extend_storefront.md b/docs/commerce/storefront/extend_storefront.md index 8b4ca37b6c..aaa245393e 100644 --- a/docs/commerce/storefront/extend_storefront.md +++ b/docs/commerce/storefront/extend_storefront.md @@ -89,7 +89,7 @@ It takes the following parameters: ## Generate custom product preview path By default, the `ProductRenderController` controller passes only the product object for rendering. -You can modify the controller file to make it pass parameters to the [`path`](https://symfony.com/doc/current/reference/twig_reference.html#path) Twig helper function, which is used by the `product_card.html.twig` and `product_card.html.twig` [templates](customize_storefront_layout.md) to generate the user path. +You can modify the controller file to make it pass parameters to the [`path`]([[= symfony_doc =]]/reference/twig_reference.html#path) Twig helper function, which is used by the `product_card.html.twig` and `product_card.html.twig` [templates](customize_storefront_layout.md) to generate the user path. After you modify the controller, it can also pass the following parameters: - `route` - the route, under which product preview is available. @@ -109,4 +109,4 @@ Refer to the code snippet below and create your own file, for example, `CustomPr 'is_relative' => true, ]); } -``` \ No newline at end of file +``` diff --git a/docs/content_management/field_types/field_type_reference/addressfield.md b/docs/content_management/field_types/field_type_reference/addressfield.md index acac7e3618..9f6d49e201 100644 --- a/docs/content_management/field_types/field_type_reference/addressfield.md +++ b/docs/content_management/field_types/field_type_reference/addressfield.md @@ -104,7 +104,7 @@ ibexa.address.field.tax_number.billing_address.DE #### Example event listener -An event listener can also provide validation by using either one of [constraints provided by Symfony](https://symfony.com/doc/current/validation.html#supported-constraints), +An event listener can also provide validation by using either one of [constraints provided by Symfony]([[= symfony_doc =]]/validation.html#supported-constraints), or a custom constraint. ```php diff --git a/docs/infrastructure_and_maintenance/cache/http_cache/http_cache_configuration.md b/docs/infrastructure_and_maintenance/cache/http_cache/http_cache_configuration.md index e087d374b9..02e0e99348 100644 --- a/docs/infrastructure_and_maintenance/cache/http_cache/http_cache_configuration.md +++ b/docs/infrastructure_and_maintenance/cache/http_cache/http_cache_configuration.md @@ -77,7 +77,7 @@ For example, to disable cache for the block, use `$event->getResponse()->setPriv ## When to use ESI -[Edge Side Includes](https://symfony.com/doc/current/http_cache/esi.html) (ESI) can be used to split out the different parts of a web page into separate fragments that can be freely reused as pieces by reverse proxy. +[Edge Side Includes]([[= symfony_doc =]]/http_cache/esi.html) (ESI) can be used to split out the different parts of a web page into separate fragments that can be freely reused as pieces by reverse proxy. In practice, with ESI, every sub-request is regenerated from application perspective. And while you can tune your system to reduce this, it always causes additional overhead in the following situations: diff --git a/docs/infrastructure_and_maintenance/cache/http_cache/reverse_proxy.md b/docs/infrastructure_and_maintenance/cache/http_cache/reverse_proxy.md index 3367b6e64d..c75593c178 100644 --- a/docs/infrastructure_and_maintenance/cache/http_cache/reverse_proxy.md +++ b/docs/infrastructure_and_maintenance/cache/http_cache/reverse_proxy.md @@ -73,7 +73,7 @@ Failing to configure reverse proxies correctly may introduce several problems, i ### Configure Symfony front controller -You need to consider your `TrustedProxy` configuration when you use Symfony [behind a load balancer or a reverse proxy](https://symfony.com/doc/5.1/deployment/proxies.html). +You need to consider your `TrustedProxy` configuration when you use Symfony [behind a load balancer or a reverse proxy]([[= symfony_doc =]]/deployment/proxies.html). To configure trusted proxies, use [Symfony semantic configuration]([[= symfony_doc =]]/deployment/proxies.html#solution-settrustedproxies) under the `framework.trusted_proxies` [configuration key](configuration.md#configuration-files), for example: @@ -84,7 +84,7 @@ framework: !!! caution "Careful when trusting dynamic IP that uses `REMOTE_ADDR` value or similar" - On Platform.sh, Varnish doesn't have a static IP, like with [AWS LB](https://symfony.com/doc/5.1/deployment/proxies.html#but-what-if-the-ip-of-my-reverse-proxy-changes-constantly). + On Platform.sh, Varnish doesn't have a static IP, like with [AWS LB]([[= symfony_doc =]]/deployment/proxies.html#but-what-if-the-ip-of-my-reverse-proxy-changes-constantly). For this reason, the `TRUSTED_PROXIES` env variable supports being set to value `REMOTE_ADDR`, which is equal to: ```php diff --git a/docs/infrastructure_and_maintenance/devops.md b/docs/infrastructure_and_maintenance/devops.md index ef851697dc..d796f82815 100644 --- a/docs/infrastructure_and_maintenance/devops.md +++ b/docs/infrastructure_and_maintenance/devops.md @@ -37,7 +37,7 @@ While all relevant cache is cleared for you on repository changes when using the ## Web Debug Toolbar -As of [[= product_name =]] v4.5, the [Symfony Web Debug Toolbar](https://symfony.com/doc/current/profiler.html) is no longer installed by default. +As of [[= product_name =]] v4.5, the [Symfony Web Debug Toolbar]([[= symfony_doc =]]/profiler.html) is no longer installed by default. To install it, run the following command: ``` diff --git a/docs/infrastructure_and_maintenance/request_lifecycle.md b/docs/infrastructure_and_maintenance/request_lifecycle.md index 19f2d7d15e..2827421d00 100644 --- a/docs/infrastructure_and_maintenance/request_lifecycle.md +++ b/docs/infrastructure_and_maintenance/request_lifecycle.md @@ -14,11 +14,11 @@ For an overview of what happens on a reverse proxy like Varnish or Fastly, see [ When arriving at a web server, the request is filtered by Apache virtual host, Nginx Server Blocks, or equivalent. There, requests of static resources are separated from requests to PHP interpreter. -As [[= product_name =]] is a Symfony application, the handling of requests starts like in Symfony (see [Symfony and HTTP Fundamentals](https://symfony.com/doc/current/introduction/http_fundamentals.html)). +As [[= product_name =]] is a Symfony application, the handling of requests starts like in Symfony (see [Symfony and HTTP Fundamentals]([[= symfony_doc =]]/introduction/http_fundamentals.html)). -If the HTTP request is to be treated by [[= product_name =]], it goes to the `public/index.php` of the [Symfony Front Controller](https://symfony.com/doc/current/configuration/front_controllers_and_kernel.html#the-front-controller). +If the HTTP request is to be treated by [[= product_name =]], it goes to the `public/index.php` of the [Symfony Front Controller]([[= symfony_doc =]]/configuration/front_controllers_and_kernel.html#the-front-controller). -The front controller transforms the HTTP request into a PHP [`Request` object](https://symfony.com/doc/current/introduction/http_fundamentals.html#symfony-request-object) and passes it to Symfony's Kernel to get a [`Response` object](https://symfony.com/doc/current/introduction/http_fundamentals.html#symfony-response-object) that is transformed and sent back as an HTTP response. +The front controller transforms the HTTP request into a PHP [`Request` object]([[= symfony_doc =]]/introduction/http_fundamentals.html#symfony-request-object) and passes it to Symfony's Kernel to get a [`Response` object]([[= symfony_doc =]]/introduction/http_fundamentals.html#symfony-response-object) that is transformed and sent back as an HTTP response. The schemas start with a regular `Request` object from a browser that enters Symfony and [[= product_name =]]. There is no ESI, no REST, and no GraphQL request performed. @@ -63,7 +63,7 @@ This schema is described below event by event. ## Kernel's request event -When the request enters the Symfony's kernel (and goes underneath the [`HttpKernel`](https://symfony.com/doc/current/components/http_kernel.html), `http_kernel`), a `kernel.request` event (`KernelEvents::REQUEST`) is dispatched. +When the request enters the Symfony's kernel (and goes underneath the [`HttpKernel`]([[= symfony_doc =]]/components/http_kernel.html), `http_kernel`), a `kernel.request` event (`KernelEvents::REQUEST`) is dispatched. Several listeners are called in decreasing priority. ### SiteAccess matching @@ -97,7 +97,7 @@ The `DefaultRouter` is always added to the collection with top priority (priorit #### `DefaultRouter` `DefaultRouter` (`router.default`): -The `DefaultRouter` tries to match the `semanticPathinfo` against routes, close to [the way pure Symfony does](https://symfony.com/doc/current/routing.html), by extending and using `Symfony\Component\Routing\Router`. +The `DefaultRouter` tries to match the `semanticPathinfo` against routes, close to [the way pure Symfony does]([[= symfony_doc =]]/routing.html), by extending and using `Symfony\Component\Routing\Router`. If a route matches, the controller associated with it is responsible for building a `View` or `Response` object. ### `UrlWildcardRouter` @@ -154,7 +154,7 @@ The `HttpKernel` then dispatches a `kernel.controller_arguments` (`KernelEvents: ## Controller execution The `HttpKernel` extracts from the request the controller and the arguments to pass to the controller. -[Argument resolvers](https://symfony.com/doc/5.4/controller/argument_value_resolver.html) work in a way similar to autowiring. +[Argument resolvers]([[= symfony_doc =]]/controller/argument_value_resolver.html) work in a way similar to autowiring. The `HttpKernel` executes the controller with those arguments. As a reminder, the controller and its argument can be: diff --git a/docs/personalization/enable_personalization.md b/docs/personalization/enable_personalization.md index b9b512deaa..7cb40b5fee 100644 --- a/docs/personalization/enable_personalization.md +++ b/docs/personalization/enable_personalization.md @@ -516,7 +516,7 @@ For example, to retrieve theĀ `rss` variation of the image, use: #### Logging -Most operations are logged by using the `ibexa-personalization` [Monolog channel](https://symfony.com/doc/5.4/logging/channels_handlers.html). +Most operations are logged by using the `ibexa-personalization` [Monolog channel]([[= symfony_doc =]]/logging/channels_handlers.html). To log everything about Personalization to `dev.recommendation.log`, add the following configuration: ``` yaml diff --git a/docs/release_notes/ez_platform_v2.5.md b/docs/release_notes/ez_platform_v2.5.md index 7dbc90eaf3..413dead819 100644 --- a/docs/release_notes/ez_platform_v2.5.md +++ b/docs/release_notes/ez_platform_v2.5.md @@ -27,7 +27,7 @@ For full description of the interface, see [content tree](https://doc.ibexa.co/p ### Webpack Encore -This release introduces [Webpack Encore](https://symfony.com/doc/4.3/frontend.html#webpack-encore) +This release introduces [Webpack Encore]([[= symfony_doc =]]/frontend.html#webpack-encore) as the preferred tool for asset management. This leads to [changes in requirements](#requirements-changes). diff --git a/docs/release_notes/ez_platform_v3.0.md b/docs/release_notes/ez_platform_v3.0.md index d741f25751..37614867da 100644 --- a/docs/release_notes/ez_platform_v3.0.md +++ b/docs/release_notes/ez_platform_v3.0.md @@ -26,7 +26,7 @@ The application now uses Symfony Events instead of SignalSlots. The application triggers two Events per operation: one before and one after the relevant thing happens (see for example [BookmarkService](https://github.com/ezsystems/ezplatform-kernel/blob/v1.0.0/eZ/Publish/Core/Event/BookmarkService.php)). -To use Symfony Events, create [Event Listeners](https://symfony.com/doc/5.0/event_dispatcher.html) in your code. +To use Symfony Events, create [Event Listeners]([[= symfony_doc =]]/event_dispatcher.html) in your code. ### New bundles @@ -271,7 +271,7 @@ For full list of deprecations and removals, see [eZ Platform v3.0 deprecations ### SignalSlots SignalSlots are removed from the application. -Use [Event Listeners](https://symfony.com/doc/5.0/event_dispatcher.html) in your code instead. +Use [Event Listeners]([[= symfony_doc =]]/event_dispatcher.html) in your code instead. ### Deprecated field types diff --git a/docs/release_notes/ez_platform_v3.0_deprecations.md b/docs/release_notes/ez_platform_v3.0_deprecations.md index 71ac9dc9ff..cb7f8aa158 100644 --- a/docs/release_notes/ez_platform_v3.0_deprecations.md +++ b/docs/release_notes/ez_platform_v3.0_deprecations.md @@ -474,7 +474,7 @@ Don't store the values globally. Every time the value is needed call `ConfigReso #### AbstractController The `eZ\Bundle\EzPublishCoreBundle\Controller` now extends `Symfony\Bundle\FrameworkBundle\Controller\AbstractController` instead of `Symfony\Bundle\FrameworkBundle\Controller\Controller` which has limited access to the [service container](https://doc.ibexa.co/en/latest/api/public_php_api/#service-container). -For details, see [Service Subscribers Locators](https://symfony.com/doc/5.0/service_container/service_subscribers_locators.html). +For details, see [Service Subscribers Locators]([[= symfony_doc =]]/service_container/service_subscribers_locators.html). The `Symfony\Bundle\FrameworkBundle\Command\ContainerAwareCommand` is deprecated, use `Symfony\Component\Console\Command\Command` instead. @@ -526,7 +526,7 @@ Deprecated `ezpublish.query_type` tag has been removed in favour of `ezplatform. ### Signal Slots -Signal Slots have been replaced by [Symfony Events and Event Listeners](https://symfony.com/doc/5.0/event_dispatcher.html). +Signal Slots have been replaced by [Symfony Events and Event Listeners]([[= symfony_doc =]]/event_dispatcher.html). The application triggers two Events per operation: one before and one after the relevant thing happens (see for example [Bookmark events](https://github.com/ezsystems/ezplatform-kernel/blob/v1.0.0/eZ/Publish/Core/Event/BookmarkService.php)). diff --git a/docs/release_notes/ibexa_dxp_v3.3.md b/docs/release_notes/ibexa_dxp_v3.3.md index a4bdf90782..4db97996a3 100644 --- a/docs/release_notes/ibexa_dxp_v3.3.md +++ b/docs/release_notes/ibexa_dxp_v3.3.md @@ -22,7 +22,7 @@ This release brings a completely reconstructed user interface of the Personaliza ### Symfony Flex -[[= product_name =]] is now installed using [Symfony Flex](https://symfony.com/doc/current/quick_tour/flex_recipes.html). +[[= product_name =]] is now installed using [Symfony Flex]([[= symfony_doc =]]/quick_tour/flex_recipes.html). See [the updated installation instruction](https://doc.ibexa.co/en/3.3/getting_started/install_ez_platform) for a new guide to installing the product. diff --git a/pim_feedbaxk b/pim_feedbaxk new file mode 100644 index 0000000000..3648e133a9 --- /dev/null +++ b/pim_feedbaxk @@ -0,0 +1,34 @@ +Attributes: +- Size ([XS, S, M, L, XL]) - a generic one +- Frame Shape/Features +- Material - a generic one +- Paint job/color - would probably require a couple of those (and a "Paints" attribute group) to take into account the various manufacturers and the parts +- + +Hi! + +I went through the PIM mnodeling exercise. + +I watch a couple of math youtube channels and they're sometimes doing what they call "building intuition" - going through a couple of handpicked examples so that the viewer understand what's going on under the hood and gains deeper knowledge of the subject. I think you're doing the same with the Product Types explanation - showing the implementation details so that the readers knows what's going on. Nicely done! + +About the modeling exercise: +- I've approached it in two phases: +1) Modeling attributes +2) Modeling Product Types + +About modelling attributes: +- It feels extremely tempting to model similar attributes as a single attribute. For example to have a single attribute for size: [XS, S, M, L, XL]. +But I think it's a trap - even though both the frame and the fork might be size XL, if at some point their actual dimensions might have to be displayed (like in tshirt, where you often get additional info when buying - chest diameter) then bundling these two would be a problem. + +Same for color - one manufacturer's red might be different from the red from another one. Bundling them together might be a problem (especially when one part comes in 5 colors and there's a million for the second one - it would be confusing for the PIM manager to choose the right one). + +About modelling product types: +- I didn't notice the series at first, so my initial idea was to model each model separately (Product Types: Fuji, Matterhorn, Annapurna, ...). I think it's mostly because the Series is not visible in the table - and started analyzing based on this :D +- Then I noticed the series: and I think the suggested solution makes sense, if the models in each series are similar to each other. + +I started to think how can the product type information be used. Let's assume: +- Series 4 might be targeted for families, and Series 5 might be targeted for semi-professionals + +My initial idea: +- so I'd use the product type to display the right templates etc. +