Upgrading to 6.0.0

This document contains all the nitty-gritty details to help you upgrade from Enonic XP 5.x

Warning

In order to upgrade, you must use Enonic XP 5.3.1 or newer

Data Migration

Any data that was created in version 5.0 must be upgraded to conform to the repository changes in version 6.0.

The necessary changes to your data can be performed with the upgrade task in the provided Toolbox CLI.

To upgrade your 5.3.1 installation, execute the following steps:

  1. Dump your 5.3.1 installation with the toolbox dump tool, then stop the 5.3.1 instance.
  2. Upgrade the dump with the 6.0.0 toolbox upgrade.
  3. Start a new 6.0.0 instance of Enonic XP and load the upgraded dump with the toolbox load tool.

From Module to Application

There have been some changes regarding the module structure in 6.0 . A module is from now on called an application. In order to convert a 5.x XP module into a 6.0 XP application, follow the steps below:

Some of the files or paths inside an application must be renamed or moved:

  • Rename src/main/resources/cms folder to src/main/resources/site
  • Move and rename src/main/resources/module.xml to src/main/resources/site/site.xml
  • Rename page files /pages/<name>/page.xml to /pages/<name>/<name>.xml
  • Rename part files /parts/<name>/part.xml to /parts/<name>/<name>.xml
  • Rename layout files /layouts/<name>/layout.xml to /layouts/<name>/<name>.xml
  • Rename controller files /<type>/<name>/controller.js to /<type>/<name>/<name>.js
  • Rename content type files /content-types/<name>/content-type.xml to /content-types/<name>/<name>.xml
  • Rename content type thumbnails from /content-types/<name>/thumb.png to /content-types/<name>/<name>.png
  • Rename mixin files /mixins/<name>/mixin.xml to /mixins/<name>/<name>.xml

In addition, some XML element names must be renamed in the page, part, layout and site XML files:

  • Rename the <form-item-set> element name to <item-set>
  • Rename the <part-component> element name to <part>
  • Rename the <layout-component> element name to <layout>
  • Rename the <page-component> element name to <page>
  • Rename the <module> element name to <site> in site.xml

Some properties in the Content object, possibly used in JavaScript controllers, have also been renamed:

  • Usages of property moduleConfig of property data in content site should be replaced with siteConfig
  • Usages of property moduleKey of property siteConfig in content site should be replaced with applicationKey

Input Type changes

The SingleSelector input type has been removed. These may be found in XML files: site.xml, content types, and descriptors for parts, pages, layouts, and mixins.

  • Replace SingleSelector input types with either RadioButton or ComboBox.
  • Update the config elements of these inputs with the new format.
    • Remove the <selector-type> element.
    • Update the options format to the following: <option value="value">Label</option>
Version 5.x SingleSelector
<!-- 5.x SingleSelector dropdown -->
<input name="dorpdownSelector" type="SingleSelector">
  <label>Dropdown Selector</label>
  <occurrences minimum="0" maximum="0"/>
  <config>
    <options>
      <option>
        <label>My Option 1</label>
        <value>o1</value>
      </option>
      <option>
        <label>My Option 2</label>
        <value>o2</value>
      </option>
    </options>
    <selector-type>DROPDOWN</selector-type>
  </config>
</input>
Version 6.0 ComboBox
<!-- 6.0 ComboBox dropdown -->
<input name="dorpdownSelector" type="ComboBox">
  <label>Dropdown Selector</label>
  <occurrences minimum="0" maximum="1"/>
  <config>
    <option value="o1">My Option 1</option>
    <option value="o2">My Option 2</option>
  </config>
</input>

See ComboBox and RadioButton for more details.

Code Changes

Regions

In 5.x the regions in a page were identified by their position (1st, 2nd, 3rd...) inside the page or layout. This was unintentional, and has now been fixed.

Since 6.0, regions are identified by name. This makes Live Edit more robust and the page structure more flexible for developers, as they can now reorder the regions within the markup without breaking anything.

This change requires a minor update to the existing layout and page HTML view files (Thymeleaf, XSLT). The region definition in the XML file already had a name, and now the HTML generated in the view must contain an attribute data-portal-region with region name as value. Also, the attribute data-portal-component-type="region is now obsolete.

Version 5.x region example
<div data-portal-component-type="region">
    <!-- 5.x layout or page -->

    <!-- region components markup ... -->
</div>
Version 6.0 region example
<div data-portal-region="myRegionName">
    <!-- 6.0 layout or page -->

    <!-- region components markup ... -->
</div>

Important

Each region HTML root element in pages and layouts must include the data-portal-region attribute with the region name.

URL functions

There is a new scale parameter in the image URL functions that is used for specifying some of the transformations that previously were indicated using the filter parameter. The filter options that apply some kind of scaling, are now scale parameters and they loose the “scale” prefix. Also note that the scale parameter is mandatory.

For example: filter: 'scalewidth(800); blur(5)' becomes scale: 'width(800)'; filter: 'blur(5)' - read more about available scaling effects and filters in Image Processor

Thymeleaf example:

<img src="img.png"
     data-th-src="${portal.imageUrl({'_id=' + data.myId, '_filter=scaleBlock(1024, 578, 0.5, 0)'})}"/>
<!-- 5.x Thymeleaf view -->
<img src="img.png"
     data-th-src="${portal.imageUrl({'_id=' + data.myId, '_scale=block(1024, 578, 0.5, 0)'})}"/>
<!-- 6.0 Thymeleaf view -->

JavaScript example:

// 5.x JavaScript controller
var imgUrl = execute('portal.imageUrl', {id: myImgContentId, filter: 'scaleWidth(800)'})
// 6.0 JavaScript controller
var imgUrl = portal.imageUrl({id: myImgContentId, scale: 'width(800)'})

Important

The new scale parameter in image URL functions is mandatory. To render an image URL with no scaling, use scale: '(1,1)'.

Finally, the parameter module has been renamed to application for the JavaScript and view (Thymeleaf, XSLT) functions assetUrl and serviceUrl

Building applications

An application requires some changes in the build.gradle file:

  • The gradle plugin has been renamed from com.enonic.xp.gradle.module to com.enonic.xp.app
  • From now on, the gradle build plugin must follow the XP version used (e.g. currently 6.0.0 ).
  • Since the Script commands have been replaced with libraries (see below JavaScript API) the gradle build must include the library dependencies that are needed.

Example of build.gradle file:

buildscript {
    repositories {
        mavenLocal()
        jcenter()
        maven {
            url 'http://repo.enonic.net/public'
        }
    }

    dependencies {
        classpath 'com.enonic.xp:gradle-plugin:6.0.0'
    }
}

apply plugin: 'com.enonic.xp.app'

app {
    name = 'com.enonic.app.sampleApp'
    displayName = 'Sample application'
    vendorName = 'Enonic AS'
    vendorUrl = 'http://enonic.com'
}

dependencies {
    include 'com.enonic.xp:lib-portal:6.0.0'
    include 'com.enonic.xp:lib-content:6.0.0'
    include 'com.enonic.xp:lib-thymeleaf:6.0.0'
}

JavaScript API

The Script commands used to access extra functions in the controllers have been replaced by libraries. The libraries that are needed can be made available for an application in the “dependencies” section of the build.gradle file (see step 1 below).

Script command calls in the form of execute('lib_name.func_name', params) should be replaced with calls to functions with the same name in the new corresponding library.

Below is just one example of how an “execute” command should be replaced with a “library” function:

// in 5.x, using 'portal.getSite' script command
var site = execute('portal.getSite');


// in 6.0, using 'portal' library and 'getSite' function
var portal = require('/lib/xp/portal'); // usually at the beginning of the file
// ...
var site = portal.getSite();

Important

Usages of Script commands in JavaScript controllers must be replaced with calls to functions in the corresponding libraries.

In order to upgrade 5.x controllers to 6.0 :

  1. Add dependencies for the libraries needed in the build.gradle of the app project, some or all of these:
dependencies {
        include 'com.enonic.xp:lib-portal:6.0.0'
        include 'com.enonic.xp:lib-thymeleaf:6.0.0'
        include 'com.enonic.xp:lib-xslt:6.0.0'
        include 'com.enonic.xp:lib-i18n:6.0.0'
        include 'com.enonic.xp:lib-content:6.0.0'
}
  1. Follow the steps below to use the functions in the different libraries.

Portal library

  • Search and replace the following calls in JavaScript controllers;

getComponent

Search: execute('portal.getComponent')

Replace: portal.getComponent()

getContent

Search: execute('portal.getContent')

Replace: portal.getContent()

getSite

Search: execute('portal.getSite')

Replace: portal.getSite()

  • Add a require call for the “portal” library at the top of each JavaScript file where a “portal.*” command was used:
var portal = require('/lib/xp/portal');
  • Note that the property moduleConfigs of content site has been removed. The method portal.getSiteConfig(), which returns the site configuration for this app in the current site, should be used instead.
// in 5.x, using 'portal.getSite' script command and the attribute moduleConfigs
var site = execute('portal.getSite');
var config = site.moduleConfigs[module.name];


// in 6.0, using 'portal' library and 'getSiteConfig' function
var portal = require('/lib/xp/portal'); // usually at the beginning of the file
// ...
var config = portal.getSiteConfig();

Thymeleaf library

  • Search and replace the following calls in JavaScript controllers;

Search: execute('thymeleaf.render',

Replace: thymeleaf.render(

  • Note that the parameters to render are now 2 separate parameters instead of an object: thymeleaf.render(view, model) vs execute('thymeleaf.render', {view: view, model: params})
  • Add a require call for the “thymeleaf” library at the top of each JavaScript file where the “thymeleaf.render” command was used:
var thymeleaf = require('/lib/xp/thymeleaf');

Content library

  • Search and replace

Search: execute('content.*',

Replace: contentLib.*(

(We use a variable named contentLib to avoid conflicts with variables representing a Content instance, which are often named content)

  • Add require call for the “content” library at the top of each JavaScript file where a “content.*” command was used:
var contentLib = require('/lib/xp/content');
  • contents in query and getChildren has been renamed to hits.

Aggregation query

The ‘date_histogram’ and ‘date_range’ aggregation-types has changed name to ‘dateHistogram’ and ‘dateRange’

  • Search and replace in controllers:

Search: date_histogram

Replace: dateHistogram

  • Search and replace in controllers:

Search: date_range

Replace: dateRange

Aggregation result object

The ‘doc_count’ property of aggregation result objects has been renamed to ‘docCount’

  • Search and replace in controllers and html;

Search: doc_count

Replace: docCount

Xslt library

  • Search and replace the following calls in JavaScript controllers;

Search: execute('xslt.render',

Replace: xslt.render(

  • Note that the parameters to render are now 2 separate parameters instead of an object: xslt.render(view, model) vs execute('xslt.render', {view: view, model: params})
  • Add require call for the “xslt” library at the top of each JavaScript file where the “xslt.render” command was used:
var xslt = require('/lib/xp/xslt');

i18n library

  • Search and replace the following calls in JavaScript controllers;

Search: execute('i18n.localize',

Replace: i18n.localize(

  • Add require call for the “i18n” library at the top of each JavaScript file where the “i18n.localize” command was used:
var i18n = require('/lib/xp/i18n');

Content object structure

The structure of some content objects has changed from what they were in Enonic XP versions prior to 6.0.

Image content

Image content objects contained image-info prior to version 6.0.0. The values image-info and bytesize have been updated to camel case imageInfo and byteSize for consistency. The value type of imageHeight, imageWidth and bytesize has been updated from String to Number.

  • Search and replace in controllers:

Search: image-info

Replace: imageInfo

Search: bytesize

Replace: byteSize

Old image object structure:

...
"x": {
    "media": {
        "image-info": {
            "imageHeight": "695",
            "imageWidth": "2000",
            "contentType": "image/jpeg",
            "bytesize": "548842",
            "pixelSize": 1390000
        }
    }
},
"page": {}

Image object structure in 6.x:

...
"x": {
    "media": {
        "imageInfo": {
            "imageHeight": 695,
            "imageWidth": 2000,
            "contentType": "image/jpeg",
            "byteSize": 548842,
            "pixelSize": 1390000
        }
    }
},
"page": {}

Request object structure

Each handler function in a controller receives a Request object as a parameter. This request object had its uri attribute renamed to url and its formParams object renamed to params.

  • Search and replace in controllers:

Search: req.uri

Replace: req.url

When HTML forms are submitted with POST using x-www-form-urlencoded encoding, parameters are now inside the params object instead of the old formParams.

  • Search and replace in controllers:

Search: req.formParams

Replace: req.params

Module object renamed

The module global variable in 5.x has been renamed to app

var appName = app.name
var version = app.version
  • Search and replace in controllers:

Search: module.name

Replace: app.name

  • Search and replace in controllers:

Search: module.version

Replace: app.version