Module development in OXID eShop 6 – benefit from the new features

OXID eShop 6 introduced several improvements to the OXID eShop environment. These changes also have reached the module system, which leads to some new features for developers. Unfortunately new things often look like barriers, but if you know how to work with it, you will also see the great benefits. So let’s start and talk about metadata 2.0, composer.json, composer.lock and Composer itself. In the following examples the module “Example Module” by OXID Support (oxs) will be used.

metadata 2.0

Compatible metadata versions for OXID eShop 6 are 1.0, 1.1 and the new version 2.0. If you already have developed an OXID module, you don’t have to learn many new things. Significant changes are the controllers array on the one hand, which replaces the files array (namespaces has to be used!), and the ability to define templates and blocks for individual themes on the other.

All possible data as well as the changes compared to the older metadata versions are listed in our online documentation.

The metadata.php should be filled precisely with all important tags. However, the minimal content would be:

$sMetadataVersion = '2.0';
  $aModule = array(
    'id' => 'oxsexamplemodule',
    'title' => 'Example Module',
);

Even the title tag could be removed, but actually you can’t choose the module in a proper way at the shop admin. Hence the activation might become tricky. The id tag is mandatory to identify the module at numerous parts in OXID eShop.

composer.json

Besides metadata.php, composer.json ist the most important file when developing a module with OXID eShop 6. It contains essential information about the installation of the module as well as necessary autoloading data.

The first and absolutely essential content is the name tag. It’s a combination of the vendor and the project separated by a slash: vendorname/projectname, e.g. oxs/oxsexamplemodule. The structure in the vendor directory is based on the name tag as well. You will also need a type tag. The type tag is easy: it’s always oxideshop-module if you’re talking about OXID module development. Actually not needed but also important is the version tag. This tag often leads to issues at the installation process as it collides with the minimum stability of your shop, which is defined in the shop composer.json (the one besides vendor and source directory). The default value for tag minimum-stability is stable, whereas a module without any version specified is considered as dev-master. The result is a failing installation. No problem, writing a fake version 1.0.0 to your composer.json will make the module stable – but wait, although this is a possible solution, it’s not advised to do so (bad practice!). Recommendation is to set your minimum stability to dev while in developing state.

There are many other (optional) tags you can and also you should define in composer.json. Anyway they are not necessary to install a module. Most important tags are extra->oxideshop->target-directory and autoload->psr-4. So the minimum content of a more or less reasonable module composer.json would be:

{
  "name": "oxs/oxsexamplemodule",
  "type": "oxideshop-module",
  "extra": {
    "oxideshop": {
      "target-directory": "oxs/oxsexamplemodule"
    }
  },
  "autoload": {
    "psr-4": {
      "OxidEsales\\OxidSupport\\ExampleModule\\":"../../../source/modules/oxs/oxsexamplemodule"
    }
  }
}

The extra->oxideshop->target-directory specifies a directory inside the /source/modules directory for storing the module. Typically /vendorname/projectname is being used (recommended). Nevertheless you may use any path you want, e.g. /i/am/the/greatest/vendor/ever/oxsexamplemodule. If no target directory is defined, the module will be automatically copied to /vendorname/projectname, but to say it again, it’s advisable to add the extra tag (with a meaningful path) to your composer.json file.

As mentioned previously it’s absolutely recommended to use namespaces in OXID eShop 6. To define and register your namespace, you have to add the autoload->psr-4 tag. First part is the namespace itself, while second part is the relative path to the module in /source/modules starting from the location of the composer.json file lying in the vendor directory – sounds complicated, but with that in mind, path always starts with …/…/…/source/modules/ followed by your defined target directory in extra->oxideshop. Your Namespace could be everything you want, e.g. *This\Is\The\Greatest\Namespace\Of\All\Time* – but as always, a reasonable construct sounds much better: *OxidEsales\OxidSupport\ExampleModule*.

composer.lock

composer.lock stores all dependencies. Sometimes this leads to unexpected effects, e.g. if you remove the version tag from your module composer.json it’s likely that it is stored in composer.lock file and your change hasn’t any effect. If you encounter such things, simply delete the composer.lock. The file will be re-written every time a composer update is executed.

Installation with Composer

Composer newbies often think it’s hard to use Composer, but if you understand what to do and do it precisely, you will learn to love Composer! First thing to know: It is always recommended to use the commands instead of manually change the shop composer.json file.

Step 1: Configure the repository (not always required, see exception)

  • Use composer config or add the information manually to the shop composer.json.
  • Mostly a GitHub repository is used but local repositories are also possible (see below for more information).

Exception: The standard repository is Packagist. If you use this, it’s not necessary to configure the repository by yourself. Composer always looks for modules in the self-configured repositories first. If the module can’t be located, composer checks Packagist.

Example:

composer config repositories.oxs path extensions/oxs/oxsexamplemodule

will add the following to the shop composer.json:

"repositories": {
  (...)
  "oxs": {
    "type": "path",
    "url": "extensions/oxs/oxsexamplemodule"
  }
}

Step 2: Require the module

  • Use composer require or add the information manually to the shop composer.json.
  • composer require automatically runs composer update.
  • Parameter –no-update prevents this behavior.
  • Version can be defined by composer require, e.g. “1.0.0”.
  • If version isn’t specified, composer uses dev-master.

Example:

composer require oxs/examplemodule:"1.0.0"

will add the following to the shop composer.json:

"require": {
  (...)
  "oxs/examplemodule":"1.0.0"
}

Step 3: Update the dependencies (not always required, see exception)

  • Run composer update.
  • Copys module data to vendor and source directories.
  • Registers autoloader functionality.

Exception: This step is only required if you use composer require –no-update or manually add the information to the require array. If not, composer update is triggered by composer require.

Step 4: Activate the module in the shop admin

That’s it! So basically you need only one to two commands to install a module in OXID eShop 6 – easy, isn’t it?

Location to store the files

At the end there’s only one big question that confronts many OXID developers: Where to store the module files in developing state? First, let’s talk about the phase after developing to make it better understandable. In the real world, your module is committed to a remote repository, e.g. GitHub. In that case, the user only has to execute a composer config and composer require. Even better is storing the project on Packagist, because then the composer config command isn’t required. Anyway, while developing it would be a very painful scenario to do so, because every change has to be committed to the repository and every time composer update has to be executed – no developer wants to do that, right?

Luckily there’s another easy way to store the module files, which was mentioned here before: local repositories. OXID eShop 6 and Composer can handle local repositories simply by adding the type path together with the local path to the files on your machine to the composer config repository command (as you may seen in the example above, Step 1: Configure the repository).

Using this method, the files can be stored anywhere on your computer and it’s close to a real repository. The separation of the module project and the OXID eShop project is also met. Unfortunately you have to run composer update every time you make changes in the code as well. The trick is to store the files in /source/modules, probably like you’ve done it before with previous OXID eShop versions. Then you can do changes, which are directly visible in the shop. Sure, this isn’t a „perfectly clean“ way because the separation will get lost, but don’t worry: we recommend it anyway while developing – it’s not bad practice, so don’t be ashamed to do so.

Any questions left? Feel free to comment on this blog post or discuss in our forums. We love to share!