Skip to content

Custom templates

shiryaeva edited this page Dec 8, 2018 · 13 revisions

This section describes how to create custom templates and generate artifacts from them by CUBA CLI.

1. Templates basics

All user templates should be located in the $USER_HOME/.haulmont/cli/templates directory. The template itself is a directory with descriptor file template.xml and files used in generation, optionally divided by CUBA Platform version in separate version directories.

So, the template structure may be following:

.
+--template.xml
+--6.8.5
|  +--... // template files for CUBA Platform 6.8.5
+--6.9.0
   +--... // template files for CUBA Platform 6.9.0

or following:

.
+--template.xml
+--... // template files for any CUBA version

CUBA CLI uses Apache Velocity template engine. You can read about how to create Apache Velocity templates on its documentation.

2. template.xml structure

Basically, template.xml has following structure:

<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<template xmlns="http://schemas.haulmont.com/cuba/cli/template.xsd"
          name="mainWindow">
    <questions>
        <!-- Questions block. All answers will be stored to the CliContext
            and will be available to Apache Velocity by ${name.questionName}.-->
        <plain name="packageName" caption="Package Name"/>
        <plain name="welcomeMessage" caption="Welcome message"/>
    </questions>
    <operations>
        <!-- Template processing block. Operations may be of two types: transform and copy.

             Transform operations indicate that the part of the template, specified in the 'src'
             attribute, should be processed by Apache Velocity, and result stored in 'dst' directory.
             Absence of the 'dst' attribute means that result should be stored at project root.

             Copy operations do the same, without processing by the template engine. It may be necessary
             for such things as images or other resources that don't need to be processed by the template
             engine and may be accidentally corrupted by it.-->
        <transform src="modules"/>
    </operations>
    <register>
        <!-- This says CUBA CLI to register screen at web-screens.xml. All values from id, package and descriptor tags will be processed by Apache Velocity. -->
        <screen>
            <id>mainWindow</id>
            <package><![CDATA[${mainWindow.packageName}]]></package>
            <descriptor>ext-mainwindow</descriptor>
        </screen>
        <!-- You can also register CUBA services and entities
        <service>
            <name>yourapp_UserfullService</name>
            <package>${mainWindow.packageName}</package>
            <interface>UsefullService</interface>
        </service>
        <entity>
           <class><![CDATA[${mainWindow.packageName}.Customer]]></class>
           <persistent>false</persistent>
        </entity> -->
    </register>
</template>

3. Template example

Let's create our own template, that will be create CUBA main window with side panel. Inside ~/.haulmont/cli/templates directory create main-window directory. Then, in that directory create a file template.xml. Fill it with template.xml example from section 2.

Now lets create sub directories modules/web/src/$[mainWindow.packageName]. Pay attention on $[mainWindow.packageName]. The construction expects that specified variable (mainWindow.packageName) is a java package and will substitute it with corresponding directories hierarchy (com.company.project -> com/company/project).

Than, inside it, create following files.

ext-mainwindow.xml

<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<window xmlns="http://schemas.haulmont.com/cuba/window.xsd"
        caption="mainMsg://application.caption"
        class="${mainWindow.packageName}.ExtAppMainWindow"
        messagesPack="${mainWindow.packageName}"
        xmlns:main="http://schemas.haulmont.com/cuba/mainwindow.xsd">
    <layout>
        <hbox id="horizontalWrap"
              expand="workArea"
              height="100%"
              stylename="c-sidemenu-layout"
              width="100%">
            <vbox id="sideMenuPanel"
                  expand="sideMenu"
                  height="100%"
                  margin="false,false,true,false"
                  spacing="true"
                  stylename="c-sidemenu-panel"
                  width="250px">
                <hbox id="appTitleBox"
                      spacing="true"
                      stylename="c-sidemenu-title"
                      width="100%">
                    <label id="appTitleLabel"
                           align="MIDDLE_CENTER"
                           value="mainMsg://application.logoLabel"/>
                </hbox>
                <embedded id="logoImage"
                          align="MIDDLE_CENTER"
                          stylename="c-app-icon"
                          type="IMAGE"/>
                <hbox id="userInfoBox"
                      align="MIDDLE_CENTER"
                      expand="userIndicator"
                      margin="true"
                      spacing="true"
                      width="100%">
                    <main:userIndicator id="userIndicator"
                                        align="MIDDLE_CENTER"/>
                    <main:newWindowButton id="newWindowButton"
                                          description="mainMsg://newWindowBtnDescription"
                                          icon="app/images/new-window.png"/>
                    <main:logoutButton id="logoutButton"
                                       description="mainMsg://logoutBtnDescription"
                                       icon="app/images/exit.png"/>
                </hbox>
                <main:timeZoneIndicator id="timeZoneIndicator"
                                        align="MIDDLE_CENTER"/>
                <main:sideMenu id="sideMenu"
                               width="100%"/>
                <main:ftsField id="ftsField"
                               width="100%"/>
            </vbox>
            <main:workArea id="workArea"
                           height="100%">
                <main:initialLayout margin="true"
                                    spacing="true">
                    <label id="welcomeLabel"
                           align="MIDDLE_CENTER"
                           stylename="c-welcome-text"
                           value="msg://welcomeMessage"/>
                </main:initialLayout>
            </main:workArea>
        </hbox>
    </layout>
</window>

ExtAppMainWindow.java

package ${mainWindow.packageName};

import com.haulmont.cuba.gui.components.AbstractMainWindow;
import com.haulmont.cuba.gui.components.Embedded;
import com.haulmont.cuba.gui.components.mainwindow.FtsField;
import com.haulmont.cuba.gui.components.mainwindow.SideMenu;

import javax.inject.Inject;
import java.util.Map;

public class ExtAppMainWindow extends AbstractMainWindow {
    @Inject
    private FtsField ftsField;

    @Inject
    private Embedded logoImage;

    @Inject
    private SideMenu sideMenu;

    @Override
    public void init(Map<String, Object> params) {
        super.init(params);

        sideMenu.requestFocus();

        initLayoutAnalyzerContextMenu(logoImage);
        initLogoImage(logoImage);
        initFtsField(ftsField);
    }
}

messages.properties

welcomeMessage = ${mainWindow.welcomeMessage}

In terminal, go to your CUBA Platform project. Launch CLI.

To generate an artifact with your template, use command use-template templateName. For our case, the templateName will be main-window.