Quick Start 

This tutorial describes how to create OroCommerce storefront theme with basic styles and layout customizations. To create back-office themes, follow the Back-Office Theme Customization

Prerequisites 

OroCommerce is a Symfony-based application where all codes are organized in bundles. To create a theme, you need to create a bundle first. We recommend to create a new empty bundle for the new theme, but you can also create a theme in one of the existing bundles.

Create a Theme 

First, create a theme folder in Resources/views/layouts/. For example DemoBundle/Resources/views/layouts/first_theme/, where first_theme is the theme name. The theme definition should be placed in theme.yml in a theme folder, for example:

#DemoBundle/Resources/views/layouts/first_theme/theme.yml
label:  First Theme
parent: default
groups: [ commerce ]

See the theme definition topic for more details.

Activate the Theme 

Now, you can activate the storefront theme from the back-office.

To set a default storefront theme on the code level, add the following configuration to the config/config.yml file in your application:

#config/config.yml
oro_layout:
    active_theme: first_theme

Add Stylesheets with SCSS 

  • Create SCSS files with custom styles in Resources/public/ folder in a bundle.

  • Run bin/console assets:install --symlink to symlink SCSS files from bundles to public/bundles/ folder in your application.

  • Create the assets.yml file in a theme config/ folder and register all the new SCSS files in it.

    #DemoBundle/Resources/views/layouts/first_theme/config/assets.yml
    styles:
     inputs:
         - 'bundles/demobundle/first_theme/scss/settings/global-settings.scss'
         - 'bundles/demobundle/first_theme/scss/components/logo.scss'
     output: css/styles.css
    
  • Run the bin/console oro:assets:build first_theme --watch command to process and combine SCSS files in first_theme.

  • You can use SCSS source maps to find styles definition in a Browser and Oro Frontend Stylebook to check how updated styles affect the UI elements.

Change Existing Pages Structure 

The structure of all pages in OroCommerce storefront are defined by the Layout. To see the current page structure, open website in a dev environment, and in a Symfony Profiler, click the Layout icon:

Layout developer toolbar

To change the page structure, we need to modify the layout.

Layout is a tree representation of the page where each tree item is a layout block. To define and modify the layout tree, use actions organized into layout update Yaml files:

  • @add

  • @addTree

  • @remove

  • @move

  • etc.

  1. Let’s add a slogan block just after the header for all the existing pages:

#DemoBundle/Resources/views/layouts/first_theme/slogan.yml
layout:
     actions:
         - '@add':
             id: slogan
             parentId: page_main_content
             siblingId: page_main_header
             prepend: false
             blockType: text
             options:
                 text: Website Slogan!
  1. And change the structure of a product display page. Remove Related products, move block with title and SKU to another place and add a css class to the SKU attribute. To apply layout updates to a single page, we need to place them in a folder with the route name inside a theme. For a product display page, the route name is oro_product_frontend_product_view:

#DemoBundle/Resources/views/layouts/first_theme/oro_product_frontend_product_view/product.yml
layout:
    actions:
        - '@move':
              id: product_view_primary_container
              parentId: page_title_container
        - '@remove':
              id: product_view_related_products_container
        - '@setOption':
              id: product_view_attribute_group_general_attribute_text_sku
              optionName: attr.class
              optionValue: page-title

Change the HTML 

Each layout block is rendered with a Twig block. Twig blocks are organized into block theme twig files. For example, product_view_attribute_group_general_attribute_text_sku block from the previous section is rendered as follows:

{#ProductBundle/Resources/views/layouts/default/oro_product_frontend_product_view/layout.html.twig #}

{% block _product_view_attribute_group_general_attribute_text_sku_widget %}
 {% set attr = layout_attr_defaults(attr, {
     '~class': ' sku'
 }) %}
 <p {{ block('block_attributes') }}>
     {{ 'oro.product.frontend.index.item'|trans }} <span class="sku__code" itemprop="sku">{{ entity.sku|oro_html_strip_tags }}</span>
 </p>
{% endblock %}

To find out which Twig block is used for rendering a certain element on a page, you can use Twig Inspector. Activate it from a Symfony Profiler, click the Twig Inspector icon and then click the element you want to inspect on the page. The template will be automatically opened in an IDE.

To override the template, we need to create a block theme twig file in the same location in our bundle and apply it with the @setBlockTheme layout action. Let’s change the label of an SKU attribute to the default one.

 {#DemoBundle/Resources/views/layouts/default/oro_product_frontend_product_view/sku.html.twig #}

 {% block _product_view_attribute_group_general_attribute_text_sku_widget %}
  {% set attr = layout_attr_defaults(attr, {
      '~class': ' sku'
  }) %}
  <p {{ block('block_attributes') }}>
-   {{ 'oro.product.frontend.index.item'|trans }} <span class="sku__code" itemprop="sku">{{ entity.sku|oro_html_strip_tags }}</span>
+   {{ label|trans }}: <span class="sku__code" itemprop="sku">{{ entity.sku|oro_html_strip_tags }}</span>
  </p>
 {% endblock %}
#DemoBundle/Resources/views/layouts/first_theme/oro_product_frontend_product_view/product.yml
layout:
    actions:
        - '@setBlockTheme':
              themes: '@DemoBundle/layouts/first_theme/oro_product_frontend_product_view/product.html.twig'
        # ...