Prototypes in CLI v4
This page describes how you can use and define a prototype variant in Magnolia CLI v4 to create a new app, block, component, content type, light module, page and virtual URI definition.
Prototypes and prototype variants
Magnolia CLI v4 comes with the following prototypes:
-
App
-
Block
-
Component
-
Content type
-
Light module
-
Page
-
Virtual URI
Most of these prototypes comes in two or three pre-configured variants
one of which is applied when executing the create command. The variants speed up the creation of a light module or
its components. You can tweak each of the variants according to your
needs or even create your own variants. They are stored in the
mgnl-cli-prototypes folder of your
Magnolia CLI installation.
Please be aware that the installation can reflect either a local or a
global configuration, see
Global
and local configurations for more information.
Upon a clean installation of CLI v4, the folder has the following structure:
mgnl-cli-prototypes
├── app
│ ├── _default
│ └── _default-m5
├── block
│ ├── _default
│ └── empty
├── component
│ ├── _default
│ ├── _default-m5
│ ├── empty
│ ├── with-js-model
│ └── with-js-model-m5
├── contentType
│ └── _default
├── light-module
│ ├── comprehensive
│ └── _default
├── page
│ ├── _default
│ ├── _default-m5
│ ├── empty
│ ├── with-js-model
│ └── with-js-model-m5
└── virtual-uri
├── _default
├── empty
└── regexp
The level 2 directory names in the prototypes folder correspond with the
following prototypes variants. You can refer to a variant by the name
attached to the -P option in the create commands:
-
_default– To create a default structure for the given element. Same as not specifying a prototype variant at all. If you use this variant to create a virtual URI mapping configuration, the URI mapping is based on theDefaultVirtualUriMappingclass. -
_default-m5- Same as_defaultbut based on the Magnolia 5 UI framework. -
empty– To create a minimalistic structure of the element. If you use this variant to create a virtual URI mapping configuration, no URI mapping class is specified in the configuration. -
with-js-model– To create a page or a component utilizing the JavaScript Models class. See also How to work with JavaScript models. -
with-js-model-m5- Same aswith-js-modelbut based on the Magnolia 5 UI framework. -
regexp– To create a virtual URI mapping configuration based on theRegexpVirtualUriMappingclass. -
comprehensive– To create a light module with the most complete (=comprehensive) structure. The following structure is created when issuing themgnl create-light-module fooModule -P comprehensivecommand:fooModule ├── apps ├── blocks ├── contentTypes ├── decorations ├── dialogs │ ├── components │ └── pages ├── i18n │ └── fooModule-messages_en.properties ├── includes │ └── README.txt ├── messageViews ├── README.md ├── restEndpoints ├── templates │ ├── components │ └── pages ├── themes ├── virtualUriMappings └── webresourcesWithout specifying the prototype or, alternatively, by adding
-P _default, the structure looks like this:fooModule ├── decorations ├── dialogs │ ├── components │ └── pages ├── i18n │ └── fooModule-messages_en.properties ├── includes │ └── README.txt ├── README.md ├── templates │ ├── components │ └── pages └── webresources
Prototype variant root folder
The root folder of a prototype variant is like the root folder of a light module folder. Whatever is added into the root of a prototype variant folder is added also to the corresponding level(s) of the light module folder when you execute a specific create command. You can add custom files to prototype variants according to your needs (see the example below).
Placeholder variables in prototype files
In a prototype variant and even in its filename you can use the following placeholder variables:
-
__lightDevModuleFolder__Replaced with the name of the current light module. -
__dialog__Replaced with the dialog definition ID (see referencing dialogs). -
__fromUri__Replaced with the name of thefromUriconfiguration in a virtual URI mapping. -
__toUri__Replaced with the name of thetoUriconfiguration in a virtual URI mapping. -
__template__Replaced with the template definition ID in block, page and component prototypes (see referencing templates). -
__templateScript__Replaced with the name and path of a template script. -
__name__Replaced with the name of the item being generated, for instance the name of a page template. -
__modelName__Same as__name__but converted into UpperCamelCase to be a valid object name in a JavaScript model.
Example
The stock Magnolia page template prototype variant called
with-js-model contains also a pre-configured prototype file
__name__.js. The prototype file has the following content (the
multiline comment at the beginning was removed intentionally):
var __modelName__ = function () {
var System = Java.type("java.lang.System");
/**
* Outputs 'Hello, world!' greeting into Tomcat catalina logfile.
*/
this.greet = function () {
System.out.println("Hello, world!");
}
/**
* Returns random number.
*/
this.getRandomNumber = function () {
return Math.random();
}
};
new __modelName__();
After executing, for example, the command
mgnl create-page visitor-counter -P with-js-model, the prototype file
is used to create a new file called visitor-counter.js in the page
template folder of your light module. The newly created file has the
following content:
- Created JS file
var VisitorCounter = function () {
var System = Java.type("java.lang.System");
/**
* Outputs 'Hello, world!' greeting into Tomcat catalina logfile.
*/
this.greet = function () {
System.out.println("Hello, world!");
}
/**
* Returns random number.
*/
this.getRandomNumber = function () {
return Math.random();
}
};
new VisitorCounter();
Notice the change happening at lines 1 and 20: using the __modelName__
variable in the prototype file takes the name visitor-counter from the
create command and turns it to UpperCamelCase when creating the target
file.
Using prototype variants
A prototype variant is applied any time you use one of the following CLI commands:
Listing the available variants
The variants that are available for use with a create command can be
listed via the help command, for example:
mgnl help create-page
In the stock installation of Magnolia CLI v4, the command lists these variants: _default, _default-m5, empty, with-js-model and with-js-model-m5. If you create a new variant and attach it to a given prototype, the new variant also
appears in the output of the help command.
Applying a variant
To create a new item from a prototype variant, use a create comand and
append -P (or --prototype) followed by the name of a variant. For
example:
mgnl create-page fooPage -P empty
This command wil create a page template from the empty page prototype
variant.
Be careful not to confuse -P and -p in the create
commands. The first one is used to specify a prototype, the second is
used to specify the path.
|
If unsure, use the long versions: --prototype and --path. They are
easier to remember.
If you do not specify a prototype variant, or, alternatively, if you
append -P _default to a create command, Magnolia CLI applies the
_default prototype variant and creates the item from the _default
subdirectory of the given item in the mgnl-cli-prototypes folder. The
output of the following two example commands is then the same.
Commands:
mgnl create-light-module fooModule
mgnl create-light-module fooModule -P _default
Output:
fooModule ├── decorations ├── dialogs │ ├── components │ └── pages ├── i18n │ └── fooModule-messages_en.properties ├── includes │ └── README.txt ├── README.md ├── templates │ ├── components │ └── pages └── webresources
Creating a custom variant
You can create a custom prototype variant and add it to one of the five
prototypes to create a new block, component, light module, page or a
virtual URI configuration. The short tutorial below shows how to create
a new page prototype variant called Front-Page that:
-
Is based on the
emptyvariant provided by Magnolia. -
Uses the word Welcome as a
h1header on the page. -
Has the header styled by a stylesheet (CSS) file and the stylesheet linked to the template script via two CLI variables.
Remember that the root folder of a prototype variant is like the root folder of a light-module folder. Whatever is added into the root a prototype variant folder is added to the corresponding levels of the light module folder when you execute the specific create command.
Tip: Do not edit or add prototypes in the
global
configuration. Create it in a local configuration which you can set up
with the
customize-local-config
command.
Example: Front-Page variant
To create the Front-Page prototype variant:
-
In the
mgnl-cli-prototypesfolder, go to thepagefolder and make a copy of the existingemptysubfolder in it. -
Rename the copy to
Front-Pageandcdto it. -
Create the
webresources/csssubdirectory in it. Switch to thecsssubdirectory and create a new file called__name__.cssthere.
In bash shell you can use the following command for this step:mkdir -p webresources/css; touch $_/__name__.css -
Edit the
__name__.cssfile to have the following content:h1 { font-family: Helvetica; color: #689600 } -
Save the stylesheet file. The content of the
pagefolder now looks like this:├── _default │ ├── dialogs │ │ └── pages │ │ └── __name__.yaml │ └── templates │ └── pages │ ├── __name__.ftl │ └── __name__.yaml ├── _default-m5 │ ├── dialogs │ │ └── pages │ │ └── __name__.yaml │ └── templates │ └── pages │ ├── __name__.ftl │ └── __name__.yaml ├── empty │ └── templates │ └── pages │ ├── __name__.ftl │ └── __name__.yaml ├── Front-Page │ ├── templates │ │ └── pages │ │ ├── __name__.ftl │ │ └── __name__.yaml │ └── webresources │ └── css │ └── __name__.css ├── with-js-model │ ├── dialogs │ │ └── pages │ │ └── __name__.yaml │ └── templates │ └── pages │ ├── __name__.ftl │ ├── __name__.js │ └── __name__.yaml └── with-js-model-m5 ├── dialogs │ └── pages │ └── __name__.yaml └── templates └── pages ├── __name__.ftl ├── __name__.js └── __name__.yaml -
Open the
../Front-Page/templates/pages/__name__.ftlfile for editing and save it with the following content:<!DOCTYPE html> <html> <head> <link rel="stylesheet" type="text/css" href="${ctx.contextPath}/.resources/__lightDevModuleFolder__/webresources/css/__name__.css" media="all" /> </head> <body> <h1>Welcome</h1> </body> </html>Notes:
Line 4: The link to the style definition of your
Front-Pagetemplate. There are two CLI variables in the link that make sure the style definition is linked correctly with your page:The
__lightDevModuleFolder__variable in the path generates a part of the path to the light module in which you create the page.The
__name__variable generates a matching name for the stylesheet file.Line 7: The element that displays the
h1header on your page.
The next series of steps shows how to create a new page template
based on the Front-Page prototype variant.
-
Go to the light module in which you want to create a page from the new
Front-Pageprototype variant. You may create it in a new light module, see thecreate-light-modulecommand for creating light module templates. -
You may also check that the
Front-Pagevariant is available for thecreate-pagecommand. Do that by entering:mgnl help create-pageIn the output of the command you should find a line showing the availability of the
Front-Pagevariant:Available prototypes are: [Front-Page, _default, _default-m5, empty, with-js-model, with-js-model-m5]. -
Finally, create a page template by entering the following command:
mgnl create-page index -P Front-PageThe
templates/pagesandwebresources/cssfolders of the light module now have new template files created from theFront-Pageprototype variant:├── templates │ └── pages │ ├── index.ftl │ └── index.yaml └── webresources └── css └── index.cssIf you keep your light module in the directory observed by the
magnolia.resources.dirproperty, the new page template and any subsequent changes to it are picked up by Magnolia instantly. The template is available under the nameindexin the Pages app. You may now modify the page template by specifying areas in it and allowing components in them.