Decorating our fragment
Our helloWorld page is actually kind of ugly. We can make it prettier by creating a "decorator" and wrapping it around our encountersToday fragment.
A decorator is just a fragment that, by convention, lives in the decorator subfolder of fragments, which counts on having the framework pass it a "content" config parameter.
Go ahead and create a simple one at yourmodule/omod/src/main/webapp/fragments/decorator/widget.gsp, like:
<div style="border: 1px black solid; margin: 0.5em;">
<div style="background-color: #e0e0e0">
<b>${ config.title }</b>
</div>
<div style="padding: 0.5em">
${ config.content }
</div>
</div>
There are two ways to wrap a decorator around a fragment. The first is to hardcode it into the fragment by putting something like the following at the top of encountersToday.gsp:
<% ui.decorateWith("yourmoduleid", "widget", [title: "Today's Encounters"]) %>
This tells the framework that after it renders the encountersToday fragment, it should wrap it in the "widget" decorator, passing a "title" fragment config parameter to the decorator.
The downside of decorating our fragment this way is that it means our fragment will always be decorated this way. Sometimes this is fine (for example in the emr module every page asks to be decorated with standardEmrPage), but often we would like the person that is including our fragment to decide whether or not to decorate it, and how. So there's also a way to allow the consumer to decorate a fragment. In helloWorld.gsp we can change the way we include our fragment to be like this:
${ ui.includeFragment("yourmoduleid", "encountersToday",
[ start: "2011-02-16",
end: "2011-02-16 23:59:59.999",
properties: ["location", "encounterDatetime"],
decoratorProvider: "yourmoduleid",
decorator: "widget",
decoratorConfig: [title: "Today's Encounters"]
]) }
Once you start adding lots of configuration to a parameter, especially including nested lists and maps, then you should add line breaks and indentation to keep things maximally legible. Remember, you will not be the only one looking at your code!
We have added three additional configuration parameters to our fragment include, "decoratorProvider" (which module our decorator comes from), "decorator" (the name of a decorator) and "decoratorConfig" (its optional fragment config). Whenever you do a fragment include, the UI framework looks for the "decorator" parameter, and decorates the fragment as requested by its consumer. Note that the fragment is only allowed to be decorated once--if a fragment requests decoration, and its consumer also asks for it to be decorated, the decoration requested by the fragment itself "wins".