Developers/Themes/Adapt existing themes

From Aimeos documentation

Developers
Other languages:
English 100%

If you would like to use one of the default themes as base for your own shop, chances are high that you also want to adapt it to your needs. Modifying a theme is possible without touching the existing CSS and Javascript files by simply overwriting the parts that should be different in your shop.

In both cases, for CSS and JS files, you need to create a new file in one of the directories of your web site and which is accessible via the browser. The preferred location depends on the application or framework you are using. Please have a look into their documentation for advices where they should be located. The basic directory structure should be:

  • ./mytheme/ (directory named after your theme or project)
    • aimeos.js (Javascript file that contains new code or overwrites existing ones)
    • aimeos.css (CSS file that contains new styles or overwrites existing ones)

These files must be included in your HTML template after the files from the theme so their content can overwrite the original one. The articles about adapting the templates in Laravel and Symfony show you where this should be done.

Cascading Style Sheets

Overwriting existing CSS styles is done by using the same CSS selector and applying different values to the existing instructions or by adding new instructions. For example, if you would like to change the style for a product name

  1. .catalog-detai-basic .name {
  2.     font-size: 110%;
  3.     color: #B0A060;
  4.     margin: 1em 0.5em;
  5. }

to a bigger one with another color that floats left, then use the same CSS selector and

  1. .catalog-detai-basic .name {
  2.     font-size: 125%;
  3.     color: #003050;
  4.     float: left;
  5. }

Modern browsers are able to support you by their web development tools that can inspect HTML nodes and show the CSS styles that are attached to these nodes and which style overwrites another. The CSS reference from w3schools is also a good source that explains the instructions supported by different browsers.

Javascript

As you can see in the article about theme fundamentals, each component has its own Javascript object with methods that are applied automatically to the HTML nodes if they are present.

Sometimes you don't want that one of the default actions is executed. In this case you can replace the existing method with an empty function, e.g.

  1. AimeosCatalogDetail.setupBlockPriceSlider = function() {}

In the same way you can completely replace the existing method with a new one:

  1. AimeosCatalogDetail.setupBlockPriceSlider = function() {
  2.     // new Javascript code
  3. }

Most of the time you may add additional instructions to the existing ones. By overwriting the complete method you would have to duplicate the existing code, which is a bad idea. Fortunately, the decorator pattern can also be used in Javascript to encapsulate an existing method by your own one. This could also be used multiple times if necessary:

  1. AimeosCatalogDetail.setupBlockPriceSlider = (function(obj) {
  2.     fcn = AimeosCatalogDetail.setupBlockPriceSlider.bind(obj);
  3.     return function(/* param1, param2, ... */) {
  4.         // do something before
  5.         fcn(/* param1, param2, ... */);
  6.         // do something afterwards
  7.     }
  8. })(AimeosCatalogDetail);

This example assigns a function to the "setupBlockPriceSlider" method of the "AimeosCatalogDetail" object like before by replacing the existing method. But before this is done, the method itself is handed over as parameter "fcn" which can be used inside your anonymous function that is returned. The "(function(fnc) {...})(...)" construct executes the outer function immediately in fact the inner anonymous function is assigned to "AimeosCatalogDetail.setupBlockPriceSlider".

Within your anonymous function - which should use the same parameters as the original one - you can call the handed over original function at any time. You are also free to add code before and/or after the original function is executed.

This way of extending methods is especially handy for the init() methods of all object because you can first execute the original function and then call your new methods.

An example would be:

  1. AimeosCatalogDetail.init = (function(obj) {
  2.     init = AimeosCatalogDetail.init.bind(obj);
  3.     return function() {
  4.         obj.setupYourMethod();
  5.         init();
  6.     };
  7. })(AimeosCatalogDetail);