Skip to content

[Shop] Add twig hooks to product card template#17918

Merged
GSadee merged 3 commits intoSylius:2.0from
PiotrTulacz:SYL-4761/twig-hooks-to-product-card-template
May 5, 2025
Merged

[Shop] Add twig hooks to product card template#17918
GSadee merged 3 commits intoSylius:2.0from
PiotrTulacz:SYL-4761/twig-hooks-to-product-card-template

Conversation

@PiotrTulacz
Copy link
Copy Markdown

@PiotrTulacz PiotrTulacz commented Apr 30, 2025

Refactors the product_card Twig hook by introducing hooks. The goal is to make it easier to customize and extend the product card by allowing other templates or plugins to inject additional content without overriding the entire template. This improves flexibility and maintainability when adding features like badges, custom buttons, or additional information.

image
image

Summary by CodeRabbit

  • New Features
    • Introduced a modular, hook-based system for rendering product cards, allowing for greater customization and extension.
    • Added new template fragments for product card details, images, names, and prices, each rendered via dedicated hooks.
  • Refactor
    • Simplified the product card template to delegate all rendering to the new hook system.
  • Style
    • Enhanced product card image presentation for consistent aspect ratio and styling.
  • Chores
    • Removed unnecessary whitespace from configuration files.

@PiotrTulacz PiotrTulacz requested review from a team as code owners April 30, 2025 08:40
@probot-autolabeler probot-autolabeler bot added the Shop ShopBundle related issues and PRs. label Apr 30, 2025
@coderabbitai
Copy link
Copy Markdown

coderabbitai bot commented Apr 30, 2025

Important

Review skipped

Auto reviews are disabled on base/target branches other than the default branch.

Please check the settings in the CodeRabbit UI or the .coderabbit.yaml file in this repository. To trigger a single review, invoke the @coderabbitai review command.

You can disable this status message by setting the reviews.review_status to false in the CodeRabbit configuration file.

Walkthrough

This update refactors the product card rendering in the Sylius ShopBundle by replacing direct HTML and component usage in the product card template with a hook-based approach. Several new Twig templates and a YAML configuration file are introduced to define and structure the hook points for the product card, its details, and pricing sections. The new templates modularize the rendering of product images, names, and prices, while the YAML configuration specifies the hooks’ structure and priorities. Additionally, a minor whitespace cleanup is made in a product review hook configuration file.

Changes

File(s) Change Summary
src/Sylius/Bundle/ShopBundle/templates/product/common/card.html.twig Replaced all direct HTML and component rendering for product cards with a single hook invocation, delegating rendering to the hook system.
src/Sylius/Bundle/ShopBundle/Resources/config/app/twig_hooks/shared/product/card.yaml Added new YAML configuration defining hook points and priorities for product card, details, and prices, enabling modular rendering via hooks.
src/Sylius/Bundle/ShopBundle/templates/shared/product/card/details.html.twig Added a new Twig template to render a product details anchor with a hook for further details insertion.
src/Sylius/Bundle/ShopBundle/templates/shared/product/card/details/image.html.twig Added a new Twig template for rendering the main product image within the product card details.
src/Sylius/Bundle/ShopBundle/templates/shared/product/card/details/name.html.twig Added a new Twig template for rendering the product name within the product card details.
src/Sylius/Bundle/ShopBundle/templates/shared/product/card/prices.html.twig Added a new Twig template for rendering product prices, conditionally invoking a prices hook if enabled variants exist.
src/Sylius/Bundle/ShopBundle/Resources/config/app/twig_hooks/product_review/index.yaml Removed an extraneous trailing whitespace line after a priority entry; no functional or structural changes.

Sequence Diagram(s)

sequenceDiagram
    participant User
    participant ProductCardTemplate
    participant HookSystem
    participant DetailsTemplate
    participant ImageTemplate
    participant NameTemplate
    participant PricesTemplate

    User->>ProductCardTemplate: Request product card rendering
    ProductCardTemplate->>HookSystem: Invoke 'card' hook with product context
    HookSystem->>DetailsTemplate: Render 'details' hook
    DetailsTemplate->>HookSystem: Invoke 'details' sub-hooks
    HookSystem->>ImageTemplate: Render product image
    HookSystem->>NameTemplate: Render product name
    HookSystem->>PricesTemplate: Render prices if variants enabled
Loading

Suggested labels

UX, Frontend

Poem

A hop and a skip, the product cards gleam,
Modular hooks now power the theme.
Images and names, all tidy and neat,
Prices appear when variants compete.
With YAML and Twig, the structure is clear—
This rabbit’s delighted, let’s give a cheer!
🐇✨


Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share
🪧 Tips

Chat

There are 3 ways to chat with CodeRabbit:

  • Review comments: Directly reply to a review comment made by CodeRabbit. Example:
    • I pushed a fix in commit <commit_id>, please review it.
    • Generate unit testing code for this file.
    • Open a follow-up GitHub issue for this discussion.
  • Files and specific lines of code (under the "Files changed" tab): Tag @coderabbitai in a new review comment at the desired location with your query. Examples:
    • @coderabbitai generate unit testing code for this file.
    • @coderabbitai modularize this function.
  • PR comments: Tag @coderabbitai in a new PR comment to ask questions about the PR branch. For the best results, please provide a very specific query, as very limited context is provided in this mode. Examples:
    • @coderabbitai gather interesting stats about this repository and render them as a table. Additionally, render a pie chart showing the language distribution in the codebase.
    • @coderabbitai read src/utils.ts and generate unit testing code.
    • @coderabbitai read the files in the src/scheduler package and generate a class diagram using mermaid and a README in the markdown format.
    • @coderabbitai help me debug CodeRabbit configuration file.

Support

Need help? Create a ticket on our support page for assistance with any issues or questions.

Note: Be mindful of the bot's finite context window. It's strongly recommended to break down tasks such as reading entire modules into smaller chunks. For a focused discussion, use review comments to chat about specific files and their changes, instead of using the PR comments.

CodeRabbit Commands (Invoked using PR comments)

  • @coderabbitai pause to pause the reviews on a PR.
  • @coderabbitai resume to resume the paused reviews.
  • @coderabbitai review to trigger an incremental review. This is useful when automatic reviews are disabled for the repository.
  • @coderabbitai full review to do a full review from scratch and review all the files again.
  • @coderabbitai summary to regenerate the summary of the PR.
  • @coderabbitai generate docstrings to generate docstrings for this PR.
  • @coderabbitai generate sequence diagram to generate a sequence diagram of the changes in this PR.
  • @coderabbitai resolve resolve all the CodeRabbit review comments.
  • @coderabbitai configuration to show the current CodeRabbit configuration for the repository.
  • @coderabbitai help to get help.

Other keywords and placeholders

  • Add @coderabbitai ignore anywhere in the PR description to prevent this PR from being reviewed.
  • Add @coderabbitai summary to generate the high-level summary at a specific location in the PR description.
  • Add @coderabbitai anywhere in the PR title to generate the title automatically.

CodeRabbit Configuration File (.coderabbit.yaml)

  • You can programmatically configure CodeRabbit by adding a .coderabbit.yaml file to the root of your repository.
  • Please see the configuration documentation for more information.
  • If your editor has YAML language server enabled, you can add the path at the top of this file to enable auto-completion and validation: # yaml-language-server: $schema=https://coderabbit.ai/integrations/schema.v2.json

Documentation and Community

  • Visit our Documentation for detailed information on how to use CodeRabbit.
  • Join our Discord Community to get help, request features, and share feedback.
  • Follow us on X/Twitter for updates and announcements.

@github-actions
Copy link
Copy Markdown

github-actions bot commented Apr 30, 2025

❌ Preview Environment deleted from Bunnyshell

Available commands:

  • 🚀 /bns:deploy to redeploy the environment

Copy link
Copy Markdown

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 1

🧹 Nitpick comments (6)
src/Sylius/Bundle/ShopBundle/templates/product/common/product_card/details/image.html.twig (2)

4-5: Extract inline styles into a CSS class
Inlining style="aspect-ratio: 3/4; " leads to maintenance headaches and a trailing space. Consider moving the aspect-ratio rule into your stylesheet (e.g. .product-card__image-container { aspect-ratio: 3/4; }) and updating the markup accordingly.


5-5: Enhance accessibility by specifying an alt text
If the sylius_shop:main_image component supports an alt attribute, pass something meaningful (for example, alt: product.name) to improve screen-reader compatibility.

src/Sylius/Bundle/ShopBundle/Resources/config/app/twig_hooks/product_review/create.yaml (2)

37-38: Consistent quoting style for template paths
Other entries in this file use single quotes around paths. To maintain consistency, switch these double quotes to single quotes. For example:

-    template: "@SyliusShop/product/common/product_card/details.html.twig"
+    template: '@SyliusShop/product/common/product_card/details.html.twig'

Also applies to: 40-41


45-46: Apply consistent quoting and remove trailing spaces

  • Change double quotes to single quotes on template values.
  • Remove any trailing whitespace on blank lines (e.g., lines 42 and 50).
-    template: "@SyliusShop/product/common/product_card/details/image.html.twig"
+    template: '@SyliusShop/product/common/product_card/details/image.html.twig'

-    template: "@SyliusShop/product/common/product_card/details/name.html.twig"
+    template: '@SyliusShop/product/common/product_card/details/name.html.twig'

Also applies to: 48-49

src/Sylius/Bundle/ShopBundle/Resources/config/app/twig_hooks/product_review/index.yaml (2)

38-41: Unify quoting style for template entries
Switch the new template declarations from double to single quotes to match the surrounding YAML:

-    template: "@SyliusShop/product/common/product_card/details.html.twig"
+    template: '@SyliusShop/product/common/product_card/details.html.twig'

44-47: Remove trailing spaces & adjust quoting

  • Remove any trailing whitespace on blank lines.
  • Convert double-quoted paths to single quotes for consistency:
-    template: "@SyliusShop/product/common/product_card/details/name.html.twig"
+    template: '@SyliusShop/product/common/product_card/details/name.html.twig'

Also applies to: 48-50

📜 Review details

Configuration used: CodeRabbit UI
Review profile: CHILL
Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between 6d5eb0d and f4df83c.

📒 Files selected for processing (7)
  • src/Sylius/Bundle/ShopBundle/Resources/config/app/twig_hooks/product_review/create.yaml (1 hunks)
  • src/Sylius/Bundle/ShopBundle/Resources/config/app/twig_hooks/product_review/index.yaml (1 hunks)
  • src/Sylius/Bundle/ShopBundle/templates/product/common/card.html.twig (1 hunks)
  • src/Sylius/Bundle/ShopBundle/templates/product/common/product_card/details.html.twig (1 hunks)
  • src/Sylius/Bundle/ShopBundle/templates/product/common/product_card/details/image.html.twig (1 hunks)
  • src/Sylius/Bundle/ShopBundle/templates/product/common/product_card/details/name.html.twig (1 hunks)
  • src/Sylius/Bundle/ShopBundle/templates/product/common/product_card/price.html.twig (1 hunks)
🧰 Additional context used
🪛 YAMLlint (1.35.1)
src/Sylius/Bundle/ShopBundle/Resources/config/app/twig_hooks/product_review/index.yaml

[error] 43-43: trailing spaces

(trailing-spaces)


[error] 51-51: trailing spaces

(trailing-spaces)

⏰ Context from checks skipped due to timeout of 90000ms (2)
  • GitHub Check: Static checks / PHP 8.3, Symfony ^7.2
  • GitHub Check: Static checks / PHP 8.2, Symfony ^6.4
🔇 Additional comments (8)
src/Sylius/Bundle/ShopBundle/templates/product/common/product_card/price.html.twig (1)

1-10: Good implementation of modular price display with proper context extraction

The template correctly retrieves product data from the hookable_metadata context and conditionally renders pricing components only when enabled variants exist. This modular approach aligns well with Sylius's component-based architecture.

Two suggestions for consideration:

  • Consider adding a comment explaining what each component does for easier maintenance
  • The empty div might be unnecessary when there are no enabled variants
src/Sylius/Bundle/ShopBundle/templates/product/common/product_card/details/name.html.twig (1)

1-5: Clean implementation with proper test attributes

The template properly extracts the product from context and renders the name with appropriate styling and test attributes. The use of text-break class is good for handling potentially long product names.

src/Sylius/Bundle/ShopBundle/templates/product/common/card.html.twig (1)

2-2: Excellent simplification using the hook system

The template has been successfully refactored to use the Twig hook system, delegating all rendering to the 'product_card' hook. This change:

  • Increases modularity and flexibility
  • Makes it easier to extend or customize product cards
  • Reduces template complexity
  • Follows best practices for Sylius template architecture
src/Sylius/Bundle/ShopBundle/templates/product/common/product_card/details/image.html.twig (1)

1-2: Verify availability of hookable_metadata.context.product
Ensure that every Twig hook invocation into this template provides a product in the hookable_metadata.context. If there's any scenario where product might be missing or null, add a guard or default to avoid runtime errors.

src/Sylius/Bundle/ShopBundle/Resources/config/app/twig_hooks/product_review/create.yaml (2)

35-42: Approve: new product_card hook group
The addition of

'sylius.shop.product_review.create.content.sidebar.product_card':
    details:
        template: "@SyliusShop/product/common/product_card/details.html.twig"
        priority: 100
    price:
        template: "@SyliusShop/product/common/product_card/price.html.twig"
        priority: 0

correctly introduces a more granular hook for the sidebar card.


43-50: Approve: nested details hook for image & name
The nested group

'sylius.shop.product_review.create.content.sidebar.product_card.details':
    image:
        template: "@SyliusShop/product/common/product_card/details/image.html.twig"
        priority: 100
    name:
        template: "@SyliusShop/product/common/product_card/details/name.html.twig"
        priority: 0

correctly registers the image and name fragments under the parent details hook.

src/Sylius/Bundle/ShopBundle/Resources/config/app/twig_hooks/product_review/index.yaml (2)

36-42: Approve: new product_card hook group in index

'sylius.shop.product_review.index.content.sidebar.product_card':
    details:
        template: "@SyliusShop/product/common/product_card/details.html.twig"
        priority: 100
    price:
        template: "@SyliusShop/product/common/product_card/price.html.twig"
        priority: 0

This correctly mirrors the create-page configuration and enables the same modular rendering in the index sidebar.


43-50: Approve: nested hook for image & name in index

'sylius.shop.product_review.index.content.sidebar.product_card.details':
    image:
        template: "@SyliusShop/product/common/product_card/details/image.html.twig"
        priority: 100
    name:
        template: "@SyliusShop/product/common/product_card/details/name.html.twig"
        priority: 0

This aligns the index page with the create page’s hook structure.

🧰 Tools
🪛 YAMLlint (1.35.1)

[error] 43-43: trailing spaces

(trailing-spaces)

Comment on lines +1 to +5
{% set product = hookable_metadata.context.product %}

<a class="link-reset" href="{{ path('sylius_shop_product_show', {'slug': product.slug, '_locale': product.translation.locale}) }}" {{ sylius_test_html_attribute('product-content') }}>
{% hook 'details' %}
</a>
Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

💡 Verification agent

🧩 Analysis chain

Well-structured product link with nested hook

The template correctly creates a link to the product page with appropriate context and test attributes. The nested 'details' hook allows for further customization of content within the link.

One suggestion: Consider adding a fallback or empty state handling if the product is unavailable or has missing translation data, since accessing product.translation.locale could potentially cause issues if translations are not properly set up.


🏁 Script executed:

#!/bin/bash
# Check if there's any error handling for missing translations in other templates
rg -A 2 -B 2 "product\.translation" --type twig | grep -i "if\|empty\|null\|undefined"

Length of output: 251


Add fallback for missing product translations

To prevent potential errors when product.translation.locale is unavailable, guard or provide a default locale in the link:

  • File:
    src/Sylius/Bundle/ShopBundle/templates/product/common/product_card/details.html.twig (lines 1–5)

  • Change the href to use a default or conditional, for example:

    {% set locale = product.translation.locale|default(app.request.locale) %}
    <a
      class="link-reset"
      href="{{ path('sylius_shop_product_show', {
        'slug': product.slug,
        '_locale': locale
      }) }}"
      {{ sylius_test_html_attribute('product-content') }}
    >
        {% hook 'details' %}
    </a>

This ensures that, if a translation or its locale is missing, the current request locale is used as a fallback.

@PiotrTulacz PiotrTulacz changed the title [Shop] Add twig hooks to product card template in rewiews [Shop] Add twig hooks to product card template Apr 30, 2025
@bartek-sek bartek-sek force-pushed the SYL-4761/twig-hooks-to-product-card-template branch from 4601229 to 6dd58c7 Compare April 30, 2025 12:18
Copy link
Copy Markdown

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 0

🧹 Nitpick comments (2)
src/Sylius/Bundle/ShopBundle/templates/shared/product/card/prices.html.twig (2)

3-7: Consider adding semantic HTML and CSS classes to the wrapper div.

The div wrapper lacks any classes or identifiers. For better maintainability and styling flexibility, consider adding appropriate CSS classes (e.g., class="sylius-product-card__prices") and semantic attributes.

-<div>
+<div class="sylius-product-card__prices">

5-5: Consider passing product as an explicit parameter to the hook.

While the current implementation works because the product is available in the template context, passing it explicitly to the hook would make the dependency clearer for developers implementing hook extensions.

-        {% hook 'price' %}
+        {% hook 'price' with {'product': product} %}
📜 Review details

Configuration used: CodeRabbit UI
Review profile: CHILL
Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between 4601229 and 6dd58c7.

📒 Files selected for processing (9)
  • src/Sylius/Bundle/ShopBundle/Resources/config/app/twig_hooks/product_review/index.yaml (1 hunks)
  • src/Sylius/Bundle/ShopBundle/Resources/config/app/twig_hooks/shared/product/card.yaml (1 hunks)
  • src/Sylius/Bundle/ShopBundle/templates/product/common/card.html.twig (1 hunks)
  • src/Sylius/Bundle/ShopBundle/templates/shared/product/card/details.html.twig (1 hunks)
  • src/Sylius/Bundle/ShopBundle/templates/shared/product/card/details/image.html.twig (1 hunks)
  • src/Sylius/Bundle/ShopBundle/templates/shared/product/card/details/name.html.twig (1 hunks)
  • src/Sylius/Bundle/ShopBundle/templates/shared/product/card/prices.html.twig (1 hunks)
  • src/Sylius/Bundle/ShopBundle/templates/shared/product/card/prices/catalog_promotions.html.twig (1 hunks)
  • src/Sylius/Bundle/ShopBundle/templates/shared/product/card/prices/price.html.twig (1 hunks)
✅ Files skipped from review due to trivial changes (3)
  • src/Sylius/Bundle/ShopBundle/Resources/config/app/twig_hooks/product_review/index.yaml
  • src/Sylius/Bundle/ShopBundle/templates/shared/product/card/prices/catalog_promotions.html.twig
  • src/Sylius/Bundle/ShopBundle/templates/shared/product/card/prices/price.html.twig
🚧 Files skipped from review as they are similar to previous changes (5)
  • src/Sylius/Bundle/ShopBundle/templates/shared/product/card/details/name.html.twig
  • src/Sylius/Bundle/ShopBundle/templates/product/common/card.html.twig
  • src/Sylius/Bundle/ShopBundle/templates/shared/product/card/details.html.twig
  • src/Sylius/Bundle/ShopBundle/templates/shared/product/card/details/image.html.twig
  • src/Sylius/Bundle/ShopBundle/Resources/config/app/twig_hooks/shared/product/card.yaml
🔇 Additional comments (1)
src/Sylius/Bundle/ShopBundle/templates/shared/product/card/prices.html.twig (1)

1-7: Well-structured template with clear hook integration.

This new template correctly implements the Twig hook system for product pricing, aligning with the PR's goal of enhancing template flexibility. The conditional check for enabled variants ensures prices are only displayed when relevant.

@bartek-sek bartek-sek force-pushed the SYL-4761/twig-hooks-to-product-card-template branch from 6dd58c7 to 46f48c0 Compare April 30, 2025 12:21
Copy link
Copy Markdown
Member

@GSadee GSadee left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Change the base branch to 2.0

@bartek-sek bartek-sek changed the base branch from 2.1 to 2.0 May 5, 2025 05:40
@bartek-sek bartek-sek force-pushed the SYL-4761/twig-hooks-to-product-card-template branch from 5f97b47 to 17b89ef Compare May 5, 2025 10:58
@@ -0,0 +1,7 @@
{% set product = hookable_metadata.context.product %}

<div>
Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Is this div needed?

@GSadee GSadee merged commit c558487 into Sylius:2.0 May 5, 2025
48 of 49 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

Shop ShopBundle related issues and PRs.

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants