Encodera

Thanks for reading!

Donate to the site — we work hard for you.

Contents

Themes, styles and scripts

A theme is a set of files responsible for the look of the storefront. A module brings default templates, and a theme can replace any of them and add its own styles without touching the module. Your own theme inherits from a ready one and changes only what it needs.

Where a theme lives

Storefront themes are in app/design/frontend/Vendor/theme. Let's create the Acme/simple theme:

app/design/frontend/Acme/simple/
├── registration.php
├── theme.xml
├── Acme_Hello/
│   └── templates/
│       └── greeting.phtml
└── web/
    └── css/
        └── source/
            └── _extend.less

Creating a theme

Both required files are created by hand:

// app/design/frontend/Acme/simple/registration.php
use Magento\Framework\Component\ComponentRegistrar;
 
ComponentRegistrar::register(ComponentRegistrar::THEME, 'frontend/Acme/simple', __DIR__);
<?xml version="1.0"?>
<!-- app/design/frontend/Acme/simple/theme.xml -->
<theme xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
       xsi:noNamespaceSchemaLocation="urn:magento:framework:Config/etc/theme.xsd">
    <title>Acme Simple</title>
    <parent>Magento/luma</parent>
</theme>

The parent tag names the parent theme: everything missing in your theme is taken from it. Run bin/magento setup:upgrade, then open Content → Design → Configuration in the admin panel, pick a store view and select the Acme Simple theme. The shop does not look different yet.

Overriding a template

To replace a module template, create a file with the same path in the theme, inside a folder named after the module:

Original templateFile in the theme
app/code/Acme/Hello/view/frontend/templates/greeting.phtmlAcme_Hello/templates/greeting.phtml
vendor/magento/module-catalog/view/frontend/templates/product/view/attribute.phtmlMagento_Catalog/templates/product/view/attribute.phtml

Copy the original file into the theme and change it. After bin/magento cache:clean the page uses the file from the theme. Layouts are extended the same way in the theme's Module/layout folder.

Theme styles

The Luma and Blank themes are written in LESS. Your own rules go into the web/css/source/_extend.less file:

/* app/design/frontend/Acme/simple/web/css/source/_extend.less */
.hello-greeting {
    padding: 20px;
    background: #f5f5f5;
}

Magento compiles this file together with the parent theme styles.

Styles from a module

A module can bring a plain CSS file. Put it into view/frontend/web/css and attach it in a layout, in the head section:

<!-- app/code/Acme/Hello/view/frontend/layout/hello_index_index.xml -->
<page xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
      xsi:noNamespaceSchemaLocation="urn:magento:framework:View/Layout/etc/page_configuration.xsd">
    <head>
        <css src="Acme_Hello::css/hello.css"/>
    </head>
</page>

The file app/code/Acme/Hello/view/frontend/web/css/hello.css is loaded only on the /hello page.

Scripts

Scripts in Magento are loaded by the RequireJS library: every file is a separate JavaScript module. Create view/frontend/web/js/hello.js:

// app/code/Acme/Hello/view/frontend/web/js/hello.js
define([], function () {
    'use strict';
 
    return function (config, element) {
        element.textContent = config.message;
    };
});

A script is bound to an element in a template with the data-mage-init attribute:

<!-- app/code/Acme/Hello/view/frontend/templates/greeting.phtml -->
<p data-mage-init='{"Acme_Hello/js/hello": {"message": "The script works"}}'></p>

After the page loads, the paragraph shows the text "The script works". The function receives the settings from the attribute and the element itself.

Refreshing static files

In developer mode styles and scripts are built on the first request and land in pub/static. If an edit is not visible, delete the contents of the pub/static/frontend and var/view_preprocessed folders and reload the page.

Common mistake

A template was put into the wrong theme folder: app/design/frontend/Acme/simple/templates/greeting.phtml without the module name. Magento does not find such a file and silently uses the original one. A path in a theme always starts with the module name: Acme_Hello/templates/....

Thanks for reading!

Donate to the site — we work hard for you.