Magnolia 4.5 reached end of life on June 30, 2016. This branch is no longer supported, see End-of-life policy.
Rendering is the process of merging templates with content. It generates a meaningful stream of HTML that can be displayed in a browser. This is the step where content becomes visible to the end user in page context.
Rendering is performed by the RenderingEngine . The engine generates HTML output based on templates. The RenderingFilter that is part of the filter chain submits a content node to the engine.
Since submission of content is handled through a filter, an independent servlet or Java application can also submit content to the Magnolia rendering engine (Freemarker only). You can trigger the rendering of any content node from Java code or template script. This is useful if you want to render a node that is not part of the page structure.
On submission of content to the engine, the following process kicks off:
templateScript
and the templating language used (FreeMarker, JSP).execute()
method is called. The model can execute any Java code to retrieve data from the JCR repository or from an external source. The return value of the execute
method is passed to the template script with the actionResult
object.templateScript
and passes the current content, the model and all context objects to it. Freemarker interpolations like ${content.title}
are replaced with actual values and directives like #list
are processed. The output of the merge process is HTML stream response that can be displayed in a browser.A renderer is a Java class library that understands a particular templating language and produces text output. For example,
FreemarkerRenderer
understands Freemarker tags and
JspRenderer
JSP taglibs and produces output in HTML, XML, RTF, Java source code and a few other formats. A renderer is not an end-user application but rather something programmers can embed into their products. You can register a renderer in your own module configuration under a renderers
folder.
Any renderer that knows how to call a Java method can theoretically be used to render authoring UI components. Velocity (similar to Freemarker but lighter) and ColdFusion are examples of popular templating languages that have been implemented successfully. For more information about templating see Template scripts.
See also Rendering empty areas.
Rendering of page content happens in a top-to-bottom fashion. Rendered HTML is sent to the output stream as soon as it gets rendered.
When a page template script calls an area, and the area in turn calls a component, the rendering engine follows referenced scripts down the rabbit hole until it finds the last script in the sequence. It then moves to the next element on the page, starting where it left off.
As a consequence, you cannot redirect in a component model as the request was already committed when the rendering of the page started. Any operations changing the HTTP response headers (redirects, setting cookies...) can only be executed in the page template's model.
Sometimes components need to be able to execute logic before page rendering starts. This is necessary for operations such as forwarding and redirecting.
Early execution is implemented using
ModelExecutionFilter
. This filter comes before page rendering in the Magnolia filter chain. A special request parameter mgnlModelExecutionUUID
contains the UUID of the component that should be executed. The component model can decide if it wants to output something special or continue with rendering normally. If the model implements
EarlyExecutionAware
interface, then the executeEarly
method is called. Otherwise the normal execute
method is called.
Possible special instructions are:
skip-rendering
causes the rendering engine to abort page rendering. The template is never rendered.redirect:<url>
sends a redirect HTTP header to the client and stops page rendering. The URL can be absolute or relative inside the Web application, that is, the context path is added by Magnolia.permanent:<url>
sends a permanent redirect (301) to the client and stops page rendering. The URL can be absolute or relative.forward:<url>
performs a forward to the returned URL. The URL can be absolute or relative.If the component model decides to continue normally, the already-executed model and its actionResult
are used instead of executing the model again.
Early execution proceeds like this:
ModelExecutionFilter
filter is configured before page
RenderingFilter
in the Magnolia filter chain. This filter listens for the request parameter mgnlModelExecutionUUID
which contains the UUID of a component that should be executed early.execute
method of the component's rendering model.actionResult
and the model as request attributes and passes them on to the rendering pipeline. The request attribute is stored with a name that includes the UUID.
AbstractRenderer
checks for attributes set by the filter for the component it is about to render. If they are present their values are used, otherwise the model is executed normally.You can render a component directly by URL. This is useful for example to render Magnolia content in a external system. The URL pattern follows the storage path in the JCR.
Here's the first promo component on the demo-project
page. In the JCR, it resides at path /demo-project/promos/0
. Use the JCR browser in Tools > JCR Browser (Website) to find the path.
To render the component directly, request it using the path in the URL.
4.5.9+. Freemarker only. Direct area rendering does not work in JSP because JspServlet uses its own output provider.
Direct area rendering allows you to render any area that has a node in the JCR. This is useful for example to render Magnolia content in a external system. To render an area, insert the mgnlArea
selector into the URL after the page name but before the .html
extension. Set the value to the area name.
Example:
~mgnlArea=<area name>~
Here's the opener
area of the /demo-project/about
page rendered by the URL http://localhost:8080/magnoliaAuthor/demo-project/about~mgnlArea=opener~.html
.
Notes:
logo
, search
and intro
and all parent areas cannot be rendered directly because no area node exists in the JCR. You can check the area nodes with the JCR browser. http://localhost:8080/magnoliaAuthor/demo-project/about~mgnlArea=NonExistingArea~.html
will render the /demo-project/about
page.You can populate the RenderingModel with request parameters. This is useful for reacting to URL information. For example, identify a visitor who comes from an email campaign and execute custom rendering logic for them. Here is an example of parameter that tells you the visitor clicked a Campaign Monitor email campaign.
http://www.demo-project.com/about.html?utm_source=CampaignMonitor
4.5.10+ You can enable the population of request parameters globally for all templates or for a specific template.
Globally:
/server/rendering/engine
autoPopulateFromRequest
and set its value to property true
. The default is true
.For a specific template definition, overriding the global setting:
/pages/<template definition>
autoPopulateFromRequest
and set its value to true
. The default value is null which means the global setting applies if you don't set a value.In your model class, implement a setSomeParameter(String)
method. The method will be called with the attribute value as the parameter.
class MyModel implements RenderingModel { private String someParameter; public void setSomeParameter(String someParameter) { this.someParameter = someParameter; } public String getSomeParameter() { return someParameter; } }
Populating the rendering model with request attributes impacts performance. The rendering calculation takes about 8% longer when population is enabled. Enable it only for templates where it is really needed.