Liferay themes with a custom base theme

6 minuten lezen

When developing a Liferay theme, one of the first things to decide is which parent theme to base your theme off.
If you're coming from the 6.x era of Liferay development, you are probably used to the fact that you can only choose from _styled, _unstyled and classic.
But starting from 7.1 and Liferay Theme Tasks 8.x, you can now also use a different theme as the parent.
The documentation clearly states this, so that is the nice part. What the documentation does not say so clearly however, is how you should do this.
In this blog I will cover some of the characteristics of extending another theme than simply _styled or _unstyled.

Use gulp extend

Ever since 7.0, theme definition is mainly done in package.json (compared to liferay-look-and-feel.xml in 6.2 and before)
So this is also the place where the base theme relation is defined.
It might be tempting to simply edit package.json and change this:

"liferayTheme": {
  "baseTheme": "styled",

into this:

"liferayTheme": {
  "baseTheme": "my-parent",

However, this will fail miserably, because there are a few more required properties. Only by using gulp extend you will find out that these extra properties are set.
I'll include a complete example here, not to encourage you to copy-paste and use them manually anyway, but simply as an illustration what we are talking about.

"liferayTheme": {
	"screenshot": "",
	"templateLanguage": "ftl",
	"version": "7.2",
	"fontAwesome": false,
	"baseTheme": {
		"name": "my-parent",
		"version": "1.0.0",
		"liferayTheme": {
			"baseTheme": "styled",
			"fontAwesome": false,
			"screenshot": "",
			"templateLanguage": "ftl",
			"version": "7.2"
		}
	}
}

But this is not the only part that's added. Defining a base theme by only its name and version requires that NPM knows where to find this package. This is done by adding a reference in the dependencies{} section of package.json:

"dependencies": {
        "my-parent": "file:../../../my-parent"
}

Or

"dependencies": {
        "my-parent": "git+ssh://[email protected]:7999/themes/my-parent.git"
}

When using 'gulp extend' you probably do not get the reference to your base theme correct the first time. Run npm install to check whether the reference can be resolved, and then cycle through changing package.json manually and re-running npm install to verify.
This also brings us to the next topics.

Using a local referenced base theme

If the base theme is part of the same project and it might change regularly, it makes sense to use a locally referenced base theme. The advantages are:

  • changes in the base theme are applied immediately to the sub theme when the sub theme is built, without having to build/deploy the base theme first.
  • No need to have authorized git credentials (like an SSH key that is applied automatically to ssh git urls)

If the base theme is not actual part of your project but a generic company wide theme for example, it does not make as much sense to reference locally. I even advise against a local reference if the base theme is stored in another Git repo than the sub theme. This is because developers can clone different projects in different local locations, and a filesystem reference is too brittle then (on my workstation the base theme is at ../../my-parent while yours is at ../../themes/my-parent for example)

Anyway, the way to refer to a local theme is like this:

"dependencies": {
        "my-parent": "file:../../../my-parent"
}

After running npm install or npm update, NPM puts a reference in node_modules to the local directory, and it uses a symlink for that. That effectively makes changes to the base theme available to the sub theme immediately.

$ ls -al node_modules/my-parent
lrwxr-xr-x    1 g  staff     27 May 27 09:31 my-parent-theme -> ../../../my-parent

Using a Git referenced base theme

Instead of a local file reference, you can also use a Git URL that contains the base theme sources. Use it like this:

"dependencies": {
        "my-parent": "git+ssh://[email protected]:7999/themes/my-parent.git"
}

A few remarks here:

  • You cannot refer to a subpath within the repository. So if the Git repository contains multiple modules and/or themes, this will not work. The root directory of the git repository must contain the theme's package.json, so to speak.
  • Changes to the base theme must obviously be committed and pushed to the repository host that is used in the Git url.
  • The Git URL can handle branches/tags, like this: main-url#commit-ish. If not used, the branch master will be used by convention.
    Refer to the NPM documentation for exact usage of Git urls.

Using an NPM package URL

If you're running an NPM repository and publish your themes there, it is also possible to refer to a published version of the base theme there. As we ourselves are not using this, I will not dive into this here.

File collisions between base and child theme

You should 'namespace' the files you define in the base theme, because files from the base theme are used as a simple in-place copy; _custom.scss from base will be overridden by _custom.scss from the child theme for example. Using directory and file structures to work around this. Eat your heart out with SASS's @import statements to get this working in a way that suits your project best.

Meer weten

Geert van der Ploeg

Solution Architect[email protected]LinkedIn
Meer van Geert van der Ploeg

Meer artikelen

liferay
dxp
freemarker
fragments
webcontent

Using Liferay Fragments as modular webcontent templates

Danielle Ardon
9 minuten lezen
Lees het artikel Using Liferay Fragments as modular webcontent templates
liferay
freemarker
dxp

Preferences for embedded portlets in Freemarker

Geert van der Ploeg
4 minuten lezen
Lees het artikel Preferences for embedded portlets in Freemarker
drupal
decoupled

Decoupled Drupal — The holy grail! Or not!

Fabian de Rijk
18 minuten lezen
Lees het artikel Decoupled Drupal — The holy grail! Or not!