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 theDefaultVirtualUriMapping
class. -
_default-m5
- Same as_default
but 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-model
but based on the Magnolia 5 UI framework. -
regexp
– To create a virtual URI mapping configuration based on theRegexpVirtualUriMapping
class. -
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 comprehensive
command: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 └── webresources
Without 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 thefromUri
configuration in a virtual URI mapping. -
__toUri__
Replaced with the name of thetoUri
configuration 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
empty
variant provided by Magnolia. -
Uses the word Welcome as a
h1
header 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-prototypes
folder, go to thepage
folder and make a copy of the existingempty
subfolder in it. -
Rename the copy to
Front-Page
andcd
to it. -
Create the
webresources/css
subdirectory in it. Switch to thecss
subdirectory and create a new file called__name__.css
there.
In bash shell you can use the following command for this step:mkdir -p webresources/css; touch $_/__name__.css
-
Edit the
__name__.css
file to have the following content:h1 { font-family: Helvetica; color: #689600 }
-
Save the stylesheet file. The content of the
page
folder 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__.ftl
file 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-Page
template. 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
h1
header 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-Page
prototype variant. You may create it in a new light module, see thecreate-light-module
command for creating light module templates. -
You may also check that the
Front-Page
variant is available for thecreate-page
command. Do that by entering:mgnl help create-page
In the output of the command you should find a line showing the availability of the
Front-Page
variant: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-Page
The
templates/pages
andwebresources/css
folders of the light module now have new template files created from theFront-Page
prototype variant:├── templates │ └── pages │ ├── index.ftl │ └── index.yaml └── webresources └── css └── index.css
If you keep your light module in the directory observed by the
magnolia.resources.dir
property, the new page template and any subsequent changes to it are picked up by Magnolia instantly. The template is available under the nameindex
in the Pages app. You may now modify the page template by specifying areas in it and allowing components in them.