Model
A template model provides properties and methods which can be accessed in the corresponding template script.
The model can be implemented in Java or - since Magnolia 5.5.6 it can also be written in JavaScript following Light development approach - thus enabling fast development and deployment without the need for Java, Maven or WAR deployment.
This page covers Java based models. For the JS based models please read How to work with JavaScript models.
This is an advanced topic.
It is not necessary to use a model in Magnolia templating, but it is useful. If you are starting out with Magnolia use templating functions instead of a model. Model classes cannot be added to light modules because light modules cannot contain their own Java classes. However, a light module can reference a component model from another module such as MTE.
A model can execute any Java code to retrieve data from the JCR repository or from an external source.
How does a model work?
During the
rendering
process, the renderer calls the model’s execute()
before it calls the
template script. The return value of the execute
method is passed to
the template script with the actionResult
object.
The model class:
-
Is instantiated for each rendering process.
-
Is provided to the respective script as an object model.
-
Is provided the current content, the current page definition and any parent model.
All of the model’s public methods can be accessed by the template script.
Benefits of using a model
There are a number of benefits to using a model:
-
Provides a clean separation between script rendering and business logic. You can change business logic without changing rendering logic.
-
Different page, area and component templates can use the same business logic.
-
Interaction between template scripts and their models can be predefined during the conceptual project phase.
-
Model classes and template scripts can be developed independently,
-
Because the model is a Java class, you can use all Magnolia Java components.
-
Model classes are reusable and can be subclassed.
-
You can retain control of the business logic by preventing changes by front-end script developers.
Referencing a model
All templates can use a model class. The model class is referenced in
the modelClass
property in the
template
definition.
Example: A home page template that uses a model class
/my-module/templates/pages/home.yaml
renderType: freemarker
templateScript: /my-module/templates/pages/home.ftl
dialog: my-module:pages/homePageProperties
modelClass: com.example.templates.HomePageModel
Using model methods
Model classes provide their own methods. You can use any public
method
in your templates. The methods are exposed using the
model.<method name>
notation.
All getters without parameters can be accessed without the `get' part of the method name and without the method brackets. Methods that expect parameters can only be called by the full method declaration. |
Example: How to use model methods in your templates
Model class method
Usage in a template script
public String getName()
${model.name} ${model.getName()}
public Collection getLatestNews()
${model.latestNews} ${model.getLatestNews()}
public boolean isArchivedNews()
if] ${model.archivedNews?string} ${model.isArchivedNews()?string}
public String getContact(String contactName)
${model.getContact("marilyn")}
Model constructor
These following objects are passed into the constructor of a model:
-
current content: The content of the current rendered template.
-
current definition: The template definition of the current rendered template.
-
parent model: Is the parent model of the last render cycle.
The constructor of a model uses Java Generics. The used definition can be defined by generics. No casts are needed. |
public class NavigationComponentModel<RD extends ConfiguredTemplateDefinition> extends RenderingModelImpl<ConfiguredTemplateDefinition> {
public NavigationComponentModel(Node content, ConfiguredTemplateDefinition definition, RenderingModel<?> parent) throws PathNotFoundException, RepositoryException {
super(content, definition, parent);
}
}