Customizing Templates
Last updated
Last updated
About
Team© 2024 Sylius. All Rights Reserved
Sylius offers two primary template types: Shop and Admin. Furthermore, it allows you to create custom templates tailored to your specific needs, providing flexibility for unique requirements.
The main reason for modifying existing templates is to implement a unique layout that aligns with your brand. Even if you use Sylius's default layout, minor adjustments may be necessary to meet specific business needs, such as adding a logo.
There are three ways to customize Sylius templates:
Using Twig Hooks (Recommended Approach) Twig Hooks provide a flexible and efficient way to customize templates. They allow you to insert custom blocks into predefined hooks without duplicating the entire template. This makes them ideal for creating plugins and ensuring compatibility with future updates. With Twig Hooks, you can also hide existing blocks, reorder elements, or adjust the layout effortlessly, maintaining clean and modular code.
Overriding Templates (Not Recommended Approach)
Template overriding involves placing modified templates in the templates/bundles
directory of your project, following the Symfony convention. While this method allows full control over the template, it requires duplicating the original file, which can lead to maintenance challenges. This approach is particularly problematic in plugins, where multiple plugins might attempt to modify the same template. Such conflicts can result in unpredictable behavior, making updates and compatibility much harder to manage compared to the flexibility offered by Twig Hooks.
Implementing Sylius Themes Themes provide different designs for multiple channels within a Sylius instance. Although it requires a few additional steps, themes offer enhanced flexibility.
Twig Hooks is a robust and powerful feature that serves as an alternative to the Sonata Block Events and Sylius Template Events systems. In essence, Twig Hooks function as a hierarchical configuration system for defining template insertion points in Sylius. Each hook represents a specific location in the template where content can be injected. Hooks are organized in a tree-like structure, enabling clear modularity and prioritization of templates.
Twig hooks can be represented using the following simple graph:
Hook: A designated insertion point within a template.
Hookable: The content you want to insert into a specific hook. A single hook can include an unlimited number of hookables.
This implies that both hooks and hookables can contain template content that influences the visual aspects of a page. However, we recommend keeping hook templates as simple as possible. Whenever feasible, place the content inside hookables to maintain a clear separation of concerns and improve maintainability.
The configuration must be done using YAML.
It is recommended to place your custom configurations in the config/packages/sylius_twig_hooks.yaml
file, but it is not obligatory.
The basic example configuration could look like that:
To add, modify, or remove content from a specific, existing page, you first need to identify the relevant configuration responsible for generating the visual content. We recommend exploring Sylius's internal configurations, available at the following links:
These links point to the respective Twig Hooks configurations for the shop and admin sections.
Another way to identify the correct hook or hookable name is to use the Symfony profiler directly on the page, specifically in the Twig Hooks menu.
If you expand your layout beyond the predefined Sylius templates and hook configurations, it is most likely that you will need to add new hooks. This can be done within a Twig template using a template expression:
Then you need to define the respective configuration, which would look something like this:
Keep in mind that you now need to render the template with the hook_name hook. Here are two important cases you should be aware of.
Hooks inherit their parent names and append their own. Thanks to this mechanism, it is not necessary to write the entire composite name in the hook. If the hook is fired inside another hookable, the configuration must reflect that. For instance:
A hookable can also act as a hook, as long as its related template contains another hook
expression. Think of it in terms of a tree-like structure: only the deepest level of hookables are purely hookables, which, in the context of a tree structure, we would refer to as leaves.
Mechanizm described above can be controlled manually. If you need to set the hook name explicitly without merging ancesor's names:
And now the configuration should be like that:
This concept relies on Symfony UX. To understand the ideas behind the following information, refer to:
Depending on the complexity of the view you are building or customizing, it is recommended to move the heavy logic behind it to the PHP code. This can be achieved by setting up the hookable as a Twig Component instead of using it as a simple template. If you have the Symfony Maker Bundle installed (refer to Symfony Maker Bundle Documentation), you can use the following command::
provide a name and confirm. This will generate the class:
And the corresponding template:
Now, instead of configuring the hookable with a template, use a component and it's ID:
If you're unsure how to find the component name you need to set, run the following command:
It is possible to change the order of elements without rewriting the configuration. This is especially useful when customizing Sylius or plugin templates:
Now, the second_hookable_name
will be rendered before the first_hookable_name
, even though it is defined as the successor in the configuration order.
As a rule of thumb in Sylius, each hookable is configured as a multiple of 100. This approach leaves enough room to insert new content in between.
Let's say we'd like to customize our offer view and we'd like to add an information about estimated shipping time:
There're two way's of finding out the hook name you'd like to hook-in.
Profiler By Clicking the hooks option you'll be taken to the specific profiler page
Here, you have whole Call Graph regarding opened view, where you can search for specific element.
Browser Developer Tools
Another way to find the right spot is to use the key combination CTRL+SHIFT+C
on Windows/Linux or CMD+SHIFT+C
on macOS. Then, click on the element closest to the location where you’d like to hook in:
Here are comments with the hook and hookable names that wrap specific layout elements. In our example, we examined the element containing the price, as we want to inject our custom element right below it. Using the browser console, we can easily identify all the necessary information:
Hook name: sylius_shop.product.show.content.info.summary
Hookable name: sylius_shop.product.show.content.info.summary.prices
To learn more about the current configuration, the easiest way is to check the Sylius code directly. This code can be found in two directories: one for the Admin section and another for the Shop section.
When searching for the sylius_shop.product.show.content.info.summary
hook name in your project (including vendor files), you should find the following file, which defines both the hook and its hookables: product/show.yaml on GitHub
Now we have all the necessary information to hook into the process. Open the config/packages/sylius_twig_hooks.yaml
file and add the following configuration:
Next, create the template file and place it in the templates/shop/estimated_delivery_time.html.twig
directory.
Key points to note:
The estimated_delivery_time
hookable name is an example; feel free to use a descriptive name that suits your purpose.
The shop
part in the path is included for organizational purposes and does not affect the application’s functionality.
The template name does not need to match the hookable name, but it is good practice to use consistent names for clarity.
All templates for your application should be placed in the templates
directory, so the relative path for your new template will be templates/shop/estimated_delivery_time.html.twig
.
Finally, warm up the cache. You should see the following result:
As you can see, this is not the expected result yet. This happens because we haven’t specified the priority, and by default, it is set to 0, as you can confirm in the developer console.
If you look closely, the short_description
hookable also has a priority of 0. This behavior is due to the configuration merging order, where your application’s templates are merged last. However, you can override this by specifying the priority explicitly:
Warm up the cache again, and this time, the element should be placed in the correct spot:
To determine the template you need to override:
Navigate to the desired page.
In the Symfony toolbar, click on the route. The profiler will display the path in Request Attributes under _sylius
.
Shop Template Example: Login Page Customization
Default login template: @SyliusShopBundle/login.html.twig
Override path: templates/bundles/SyliusShopBundle/login.html.twig
Copy the original template to your path and customize it as needed. Example:
Clear the cache if changes aren't visible: php bin/console cache:clear
Read more in the Themes documentation in The Book and the bundle's documentation on GitHub.
Each of the Twig templates in Sylius is provided with the sylius
variable, that comes from the ShopperContext.
The ShopperContext is composed of ChannelContext
, CurrencyContext
, LocaleContext
and CustomerContext
. Therefore it has access to the current channel, currency, locale, and customer.
The variables available in Twig are:
Twig variable
ShopperContext method name
sylius.channel
getChannel()
sylius.currencyCode
getCurrencyCode()
sylius.localeCode
getLocaleCode()
sylius.customer
getCustomer()
You can check for example what is the current channel by dumping the sylius.channel
variable.
That’s it, this will dump the content of the current Channel object.