Extend the theme
Theme override is the mechanism allowing to extend, adapt, and rewrite almost everything contained in the base theme.
Understanding theme overrides
Front-Commerce web application is a fully featured e-commerce universal React application aimed at providing a sane base for your own theme. Even though you could reuse pages and components individually in a totally different theme, most of the time you might find easier and faster to start with the base theme and iterate from there.
Theme override is what allows you to:
- customize the base theme,
- customize how an extension is displayed,
- upgrade Front-Commerce and benefit from the latest component improvements,
- or create a slightly different theme for the Black Friday in confidence!
Having an understanding of themes in Magento, child themes in Wordpress / Prestashop, templates override in Drupal, themes in CakePHP will help you understand Front-Commerce’s theme overrides because they all share the same philosophy. If you have no previous experience with these other implementations, let’s see how it works!
Your own theme will be located in its own folder and will use default components from parent theme(s) — at least from Front-Commerce base theme. You would then copy the files you want to override in your theme folder by maintaining an identical file structure. Your component will then be used instead of the one in your parent theme(s).
This translates in those three steps:
- configure your custom theme and use it in your application
- copy the file (
js
,scss
orgql
) you want to override in thetheme
folder of your module - customize its content in your module directory
Configure your custom theme and use it in your application
First, we need to create a minimalist module that will contain your own theme by creating the following file structure (for instance at the root of your project):
my-module
└── web
└── theme
Then, we need to tell Front-Commerce that this module exists in your
.front-commerce.js
file. If the
module has been created at the root of your project, it would look like this:
module.exports = {
name: "Front Commerce",
url: "http://www.front-commerce.test",
- modules: ["./src"],
+ modules: ["./src", "./my-module"],
...
};
Restart the application. That’s it! You have successfully registered the module in your Front-Commerce application.
Override a component
Let's add the description of a Product
to a ProductItem
as an example of
overriding the base theme.
The original file is:
node_modules/front-commerce/src/web/theme/modules/ProductView/ProductItem/ProductItem.js
Please refer to the Front-Commerce’s folder structure documentation page to get a better understanding of how components are organized in the base theme.
- copy it to:
my-module/web/theme/modules/ProductView/ProductItem/ProductItem.js
- add the description after the
<ProductOverview />
component in yourProductItem
with{this.props.description}
.
But you are not done yet! The description
information is not included in
the GraphQL fields fetched by the application in the base theme. You will thus
need to update the fragment related to ProductItem
.
The original fragment file is collocated with the original component at:
-
copy the
original ProductItemFragment
to the equivalent location in your module. -
add the field
description
to the fragment.my-module/web/theme/modules/ProductView/ProductItem/ProductItemFragment.gqlfragment ProductItemFragment on Product {
imageUrl
+ description
...ProductOverviewFragment
...ProductItemActionsFragment
} -
restart the application
The data will now be fetched from GraphQL every time the ProductItem
is used
(product listings, upsells…) and will be available for you to render it as
wanted.
In development mode, you MIGHT need to restart the application for the override to be detected. The tools used to provide the override feature do not detect automatically that you're trying to override a file yet. This is an upcoming improvement, see #63 for further information.
Reuse the original component
Front-Commerce has been designed with small components having a single responsibility. We believe that theme overrides should cover most of your use cases. For some features though, it appeared that reusing the base component could be really useful. For instance, if you want to add a small feature or wrapper without changing the core feature of a component.
It is possible to import a component from the front-commerce
node module in a
standard way, as you would import components from other libraries.
Use with care! We don't think that this method should be the default one, because it can make your updates more painful.
In the file that we've created in the previous section, instead of copying the original source file you could set it up like this:
import React from "react";
// eslint-disable-next-line no-restricted-imports (ESLint rule added in 2.19.0)
import BaseProductItem from "front-commerce/src/web/theme/modules/ProductView/ProductItem/ProductItem.js";
const ProductItem = (props) => (
<div>
{/* Add your feature here */}
<BaseProductItem {...props} />
</div>
);
export default ProductItem;