Custom Themes

Introduction

In map.apps 4, a new way of layout-theme compilation was introduced. It provides a modern live compiling which makes it unnecessary to process resources manually each time a file was changed. In addition, the app’s theme configuration was simplified. Therefore some slight changes are necessary to get a map.apps 3.x theme running in a map.apps 4.x build. The following guide explains the steps needed in detail. This guide has a technical scope and does not cover the design perspective because a custom theme can have many unpredictable changes that cannot be foreseen or covered in such a guide.

In general there are three use-cases for customizing map.apps themes:

  • theme-bundle - customizing colors and adding styles for custom bundles

  • theme-extension - custom theme that ships the styles for custom bundles only matching to another theme from another bundle

  • multi-theme-extension - custom theme bundle that ships multiple themes for custom bundles matching to multiple other themes - not supported yet

Prerequisites

To complete this guide, you only need your map.apps 3.x project with one or more custom themes (based on map.apps remote sample project) and the latest mapapps-4-developers project .

Step 1: Copy theme from remote project to mapapps-4-developers

Locate the main folder of map.apps remote sample project (the folder where the pom.xml is located) which is called [RemoteProjectMain] and the main folder of the mapapps-4-developers which is called [mapapps-4-developers] on your hard drive.

Typically, the structure of a bundle providing one or more themes in map.apps 3.x looks like the following:

theme3

It is best practice to split up each theme (myTheme-A and myTheme-B in the preceding sample) in a separate bundle. To do so, create a new folder called theme-a/styles under [mapapps-4-developers]/src/main/js/bundles. Copy the contents of [RemoteProjectMain]/src/main/js/bundles/sample_themes/mytheme-A to the theme-a/styles folder you have created.

Remove the file theme-a/sytles/mytheme-a.less. With map.apps 4 this file is generated automatically after Step 5. It is called styles.less now. This file represents the main entry point for CSS. When removing, check the file carefully for any customizations.

Next, replace the content of [mapapps-4-developers]/src/main/js/bundles/theme-a/manifest.json with the following content:

manifest.json
{
    "name": "theme-a",
    "version": "0.0.1",
    "main": "",
    "layer": "",
    "i18n": [],
    "startLevel": 1,
    "bundle": true,
    "dependencies": {
        "font-mapapps": "^4.7.1"
    },
    "CSS-Themes": [{
        "name": "a",
        "files": ["font-mapapps:/fonts/fonts.css", "styles/styles.css"]
    }]
}

The dependency font-mapapps is needed to ensure that all fonts, especially the one providing mapapps Iconfont, are loaded, because they are provided in a separate bundle in map.apps 4. By looking at the manifest you can notice that a theme is no longer different from other functional map.apps bundles. The 'CSS-Themes' block states that there is a theme provided, called a which loads all files listed inside the files array. It is crucial that this name matches the variable @themeName inside the themeSettings.less file.

Inside [mapapps-4-developers]src\main\js\bundles\theme-a\styles\themeSettings.less replace the line

themeSettings.less
@import "../common/crossBrowserSettings.less";

with

themeSettings.less
@import "../../theme-common/styles/crossBrowserSettings.less";

The map.apps 4 theme should now look similar to the following image:

theme4

Step 2: Adjust Gulpfile

In contrast to map.apps 3.x, in map.apps 4.x the whole theme compile configuration is done in [mapapps-4-developers]/gulpfile.js which is simpler than editing the pom.xml. The theme has to be added inside the themes and themeChangeTargets array:

gulpfile.js
...

mapapps.registerTasks({
    /* A detailed description of available setting is available at https://www.npmjs.com/package/ct-mapapps-gulp-js */
    /* a list of themes inside this project */
    themes: ['theme-a'],
    /* state that the custom theme is depending on map.apps everlasting theme that provides the base styles */
    hasBaseThemes: true,
    /* state that vuetify components are suppored and therefore vuetify core styles are needed */
    hasVuetify: true,
    themeChangeTargets: {
        "vuetify": [
            "theme-a"
        ]
    }
});

...

Step 3: Add missing less variables

themeSettings.less
/*
* map.apps 4 - new Props
*
*/
@ct-header-logo-background-color: @dialog-titlebar-background-color;
@ct-base-font-size: 15px;

@ct-button-border-width: 2px;
@button-focused-border-color: (#fff - @container-background-color);

//shadow levels.
Higher levels simulate that the object is raised:
.shadow-0(){box-shadow: none;}
.shadow-1(){box-shadow: rgba(0, 0, 0, .12) 0 1px 6px, rgba(0, 0, 0, .12) 0 1px 4px;}
.shadow-2(){box-shadow: rgba(0, 0, 0, .16) 0 3px 10px, rgba(0, 0, 0, .22) 0 3px 10px;}
.shadow-3(){box-shadow: rgba(0, 0, 0, .19) 0 10px 30px, rgba(0, 0, 0, .22) 0 6px 10px;}
.shadow-4(){box-shadow: rgba(0, 0, 0, .25) 0 14px 45px, rgba(0, 0, 0, .22) 0 10px 18px;}
.shadow-5(){box-shadow: rgba(0, 0, 0, .3) 0 19px 60px, rgba(0, 0, 0, .22) 0 15px 20px;}

Step 4: App Configuration

Make sure that there is no extra configuration of the bundle called themes inside the app configuration file app.json. Add the bundle providing your theme (theme-a in this case) to the app and remove the themes' bundle configuration if necessary

Step 5: Start jetty:server

Run the jetty server as usual with

> mvn jetty:run -Pwatch all

If you are unsure what to do, refer to the Readme.md inside the mapapps-4-developers project repository.

+ If all steps before were done correctly, the application should now run and use the theme. If not, refer to the next section.

Possible errors while or after starting jetty server

Errors can appear during startup of jetty:server (Step 5) or while accessing the app using your theme.

During Jetty startup

The console log says something similar to:
mvn jetty:run
[INFO] [17:25:34] Error in plugin "gulp-less"
[INFO] Message:
[INFO]     variable @container-background-color is undefined in file C:\themeMigration\mapapps-4-developers\target\webapp\js\bundles\theme-a\styles\themeSettings.less line no. 12
[INFO] Details:
[INFO]     type: Name
[INFO]     filename: C:\themeMigration\mapapps-4-developers\target\webapp\js\bundles\theme-a\styles\themeSettings.less

The third row gives already a good hint that a less variable is missing from step 3

The console log says something similar to:
jetty:run
[INFO] [17:29:24] Error: ENOENT: no such file or directory, open 'C:\themeMigration\mapapps-4-developers\target\webapp\js\bundles\theme-a\styles\themeSettings.less'

This is in most cases a erroneous configuration inside gulpfile.js. Make sure that the values added to themes array and themeChangeTargets correspond to your theme’s main folder name.

During app launch or while viewing the app in a web browser

The app launches but the browser’s console states an 404 error similar to the following:

404

Chances are good that there is an error in the theme bundle’s manifest.json file. Ensure that the theme’s main CSS file style.css is listed inside the files array:

manifest.json
"CSS-Themes": [{
    "name": "a",
    "files": ["font-mapapps:/fonts/fonts.css", "styles/styles.css"]
}]
The app launches without errors but theme isn’t applied to app

In most cases this happens due to a mismatch between the theme bundle’s manifest.json file and the property @themeName. Ensure @themeName matches the name defined inside the CSS-Themes array of manifest.json.

Step 5 (optional): Import styles for custom developed bundles

If you have created LESS/CSS files for custom bundles in the past, these files need to be imported, too. By default only map.apps default bundles and styles are loaded with the theme.

From [mapapps-4-developers]/target/webapp/js/bundles/theme-custom/styles/ copy the file styles.less to your theme at [mapapps-4-developers]/src/webapp/js/bundles/theme-custom/styles/. Now you need to add the CSS @import statements for custom bundles/styles. Ideally they are imported right after the map.apps bundles.

Step 6 (advanced): Renaming of CSS classes

With map.apps 4 a lot of effort was spent to reduce the amount and the efficency of delivered CSS. Most of the CSS classnames given by map.apps are named after BEM Methodology . If you have defined a lot of overwrites directly by adding new CSS rules to map.apps classes, it is recommended to check the following table and adjust the custom rules accordingly.

old classname new classname

General

.header

.ct-application-header

.logo

.ct-application-header__logo

.appTitle

.ct-application-header__app-title

.footer

.ct-application-footer

.footer_left

.ct-application-footer__container-left

.footer_right

.ct-application-footer__container-right

OmniSearch

.ctOmniSearchUI

.ct-omnisearch

.ctOmniSearchInput

.ct-omnisearch__input-field

.ctOmniSearchLoading

.ct-omnisearch__loading

.ctOmniSearchReset

.ct-omnisearch__reset

.ctOmniSearchSettings

.ct-omnisearch__settings-button

.ctSettingsVisible

.ct-omnisearch__settings-button—​settings-visible

.ctOmniSearchSettingsPopup

.ct-omnisearch__settingsPopup

.ctOmniSearchSettings

.ct-omnisearch__settings

.ctOmniSearchDropDown

.ct-omnisearch__result-list

DataView

.ctDataViewToolBar

.ct-data-view__toolbar

.toolbar

.ct-data-view__tools

.ctPager

.ct-data-view__pager

.ctScopedFilter

.ct-data-view__filter

.ctDataViewViewPane

.ct-data-view__view-pane

Notifier

.ctNotifier

.ct-notifier

.ctNotifierStickyContent

.ct-notifier—​sticky

.ctNotifierMessage

.ct-notifier__content

.ctNotifier .Warning .ctNotifierIcon:before

ct-notifier__icon—​warning

Banner

.ctBanner

.ct-banner

.ctBanner a

.ct-banner__link

.ctBanner span

.ct-banner__text

.ctBanner img

.ct-banner__image

Map

.ctMapLoadingInfo

.map__loading-info

.ctMapLoadingInfo.ctLoading

.map__loading-info—​is-loading