(Quick Reference)
9 Creating Custom UI Sets - Reference Documentation
Authors: Marc Palmer (marc@grailsrocks.com)
Version: 1.0.RC2
9 Creating Custom UI Sets
If you cannot find an existing UI Set that generates markup compatible with your chosen or in-house JS/CSS framework, you can create your own. Search the
Grails plugin repository for plugins that provide UI Sets.
Creating a UI Set is significantly more work than creating a theme because you need to supply the structural markup for all the UI tags.
However you can create a UI Set based on the
_default
provided by Platform UI, or fork a UI Set that already exists in your application i.e. one provided by a plugin you have installed. See the
create-ui-set and
fork-ui-set script documentation.
9.1 UI Set Resources
UI Sets typically rely on some resources for styling and functionality.
The current UI Set's resources are included in a page using the
resources tag - although you do not need to do this if using Themes, as the theme's UI Set resources will be included automatically.
To declare resources for the UI Set you just define a resource module with the name convention
"ui.<uisetname>"
:
modules = {
// Resources for your custom UI Set
'ui.Bootstrap' {
dependsOn 'jquery', 'bootstrap'
resource id:'styling', url:[plugin:'bootstrap-ui', dir:'css', file:'ui-styling.css']
resource id:'hooks', url:[plugin:'bootstrap-ui', dir:'js', file:'bootstrap-hooks.js']
}
}
9.2 CSS Classes
Sometimes the structural markup for a UI Set is semantically compatible with what you want to achieve, but an application developer may want to change the CSS class names used for some elements to achieve the styling they want, while still using your UI Set.
They may for example want to use custom CSS and override your UI Set CSS resources and change class names for a table to avoid a clash with some other CSS library they use.
To enable this, UI Tags resolve CSS classes for the common UI elements in such a way that the UI Set developer can provide defaults, and the application developer can override these in Config.
The CSS class name is resolved for you by the UI Tags and is passed into the GSP template used for the UI element. As UI Set developer it is your responsibility to use this class name variable on the correct element.
The CSS Class configuration is performed using Platform Core namespaced config, and here is an example for a plugin that might configure a Bootstrap UI Set for the correct Bootstrap CSS classes:
def doWithConfig = { config ->
platformUi {
ui.Bootstrap.actions.cssClass = 'form-actions'
ui.Bootstrap.button.cssClass = 'btn'
ui.Bootstrap.tab.cssClass = 'tab-pane'
ui.Bootstrap.tabs.cssClass = 'nav nav-tabs'
ui.Bootstrap.field.cssClass = ''
ui.Bootstrap.input.cssClass = 'input-xlarge'
ui.Bootstrap.invalid.cssClass = 'invalid'
ui.Bootstrap.table.cssClass = 'table table-striped'
ui.Bootstrap.tr.cssClass = ''
ui.Bootstrap.trOdd.cssClass = ''
ui.Bootstrap.trEven.cssClass = ''
ui.Bootstrap.th.cssClass = ''
ui.Bootstrap.carousel.cssClass = 'carousel'
ui.Bootstrap.slide.cssClass = 'item'
ui.Bootstrap.form.cssClass = 'form-horizontal'
}
}
You can see here for example that the default input field CSS class is "input-xlarge" to create large input fields. The application developer can trivially override this in their application Config to get different sized fields:
plugin.platformUi.ui.Bootstrap.input.cssClass = 'input-large'
9.3 Configuration
UI Sets can change their behaviour based on configuration.
Config paths must be named according to Platform Core namespaced plugin config, within the namespace of the plugin that supplies the UI Set
You can add and declare any configuration options you wish, and for example you could provide more options for CSS Class customisation, or a global switch to change default colours or colour schemes.
In addition there are some Platform UI configuration options that affect UI Sets:
Path | Type | Description |
---|
ui.set | String | The default UI Set to use if none is specified on the request or implied by the request Theme. Defaults to "_default" to use the "demo" UI Set that comes shipped in Platform UI |
9.4 UI Set GSP Template Reference
The GSP templates used to create a UI Set are detailed in this section. This guide is intended for developers creating their own UI Sets or themes.
Resolution of templates
Templates for UI Set tags are resolved to the following view path within your plugin or application:
/grails-app/views/_ui/<UiSetName>/_<uiTagName>.gsp
Sometimes you may need to work around a problem in a UI Set used by your application, where that UI Set is provided by another plugin or theme. You can do this easily by putting your own GSP in the correct location.
NOT IMPLEMENTED CORRECTLY YET: Themes override the UI set templates by specifying replacement templates in /grails-app/views/_themes/<ThemeName>/_ui/<UiSetName>/_<uiTagName>.gsp
. Current implementation is wrong.
Contract for GSP Templates
The sections that follow set out the requirements for each UI tag's GSP template in terms of expected behaviour and the information supplied to the GSP template via the model.
Attributes
All UI tag attributes that are part of the UI Tag contracts are extracted and passed to the GSP template model. Any remaining attributes are passed to the model in the "attrs" variable.
Use of such attributes is typically to pass them through to underlying implementation tags such as
g:form
, but can be used for specific customisations over and above the UI Set specifications provided the core contract for each UI Tag's attributes is honoured.
9.4.1 The Avatar template
The
_avatar.gsp
template is used to render the
avatar tag.
Contract
The avatar template must render an avatar image for the given user identity.
The template can use any avatar provider. The default implementation uses Gravatar.
The user identity could be any string - but is typically an email address. For example an avatar template implementation that supports local application avatars for account user ids
and public internet Gravatars could sense the presence of the email address and switch its behaviour for user ids.
Variables available
Name | Description |
---|
avatarClass | The CSS class to use for the avatar container. Value comes from UI Set config |
classes | A string containing the list of CSS classes to apply to the outer container |
user | The id of the user for whom you wish to render an avatar. Often an email address, but depends on avatar service used by UI Set |
defaultSrc | The absolute URL of the default avatar image |
size | The size in pixels of the avatar to retrieve, i.e. "30" |
attrs | The attributes to pass through to the image tag. |
Example template implementation
<g:set var="_gravatarURL" value="https://secure.gravatar.com/avatar/"/>
<g:set var="_gravatarArgs" value="${user.encodeAsMD5()}?d=${defaultSrc?.encodeAsURL()}"/>
<img src="${_gravatarURL}${_gravatarArgs}"
class="${p.joinClasses(values:[avatarClass,classes])}"
${ui.attributes(exclude:'src')}/>
9.4.2 The Block template
The
_block.gsp
template is used to render the
block tag.
Contract
The block template
should render a container around the contents of the tag body.
It is often the case that such blocks will be separated visually from the surrounding content, for example with a border or similar.
Variables available
Name | Description |
---|
blockClass | The CSS class to use for the block container. Value comes from UI Set config |
classes | A string containing the list of CSS classes to apply to the outer container |
bodyContent | The content of the actions section, the markup provided by the caller |
attrs | The attributes to pass through to the tag that is the container for the actions |
Example template implementation
<div class="${p.joinClasses(values:[blockClass, classes])}">
${bodyContent}
</div>
9.4.3 The Carousel template
The
_carousel.gsp
template is used to render the
carousel tag.
Contract
A carousel is a UI element typically used on home pages to rotate through a list of content panels, usually by sliding
slides on and off or fading in and out.
The style of the animation, whether there are any UI elements to pause or advance the slides are not sepcified in any way.
This GSP template must simply render the correct structural markup and take care of any requirements of the JS code required, and render the various slides contained within the
ui:carousel
tag appropriately.
Usually frameworks simply use a list of divs and selectively show and hide them, much like tabs.
Slides
must be shown in the following order:
- The slide marked "active" first
- All other slides, in order they were defined in the
slides
variable
Variables available
Name | Description |
---|
id | The id for the outermost element supplied by the developer or auto-generated |
carouselClass | The CSS class to use for the carousel container. Value comes from UI Set config |
classes | A string containing the list of CSS classes to apply to the outer container |
slides | A list of the slides to include, each with properties id , active , bodyContent |
attrs | The attributes to pass through to the container tag. |
Example template implementation
<div id="${id}" class="${p.joinClasses(values:[carouselClass, classes])}">
<div class="carousel-inner">
<g:each in="${slides}" var="s">${s.bodyContent}</g:each>
</div>
<a class="carousel-control left" href="#${id}"
data-slide="prev">‹</a>
<a class="carousel-control right" href="#${id}"
data-slide="next">›</a>
</div>
9.4.4 The Slide template
The
_slide.gsp
template is used to render the
slide tag.
Contract
This template must render the markup required to encapsulate a single slide for a
carousel component.
Typically a container div will be required with some kind of indicator class or HTML5-data attribute.
The output of the slide template is collected together and passed to the template for the
carousel tag.
Variables available
Name | Description |
---|
id | Unique slide id - will be passed in by the user or auto generated for you |
slideClass | The CSS class to apply for slides, from UI Set config |
classes | A string containing the list of CSS classes to apply to the outer container |
bodyContent | The body of the slide |
attrs | The attributes to pass through to the outermost container element. |
Example template implementation
<div id="slide_${id}" class="${p.joinClasses(
values:[slideClass, active ? ' active' : '', classes])}"${ui.attributes()}>
${bodyContent}
</div>
The
_form.gsp
template is used to render the
form tag.
Contract
This template must render an HTML form using the standard attributes supported by the Grails
g:form
tag.
It can apply any structural HTML or decoration that it desires. It may for example apply special CSS classes to toggle between vertical or horizontal label and field layout, and it could even use Config to toggle between these so that the application developer can change the look and feel across their app in one place.
Variables available
Name | Description |
---|
formClass | The CSS class to use for the primary container of the form HTML, obtained from UI Set config. |
classes | A string containing the list of CSS classes to apply to the outer container |
bodyContent | The body of the form to be rendered |
attrs | The attributes to pass through to the g:form tag. The form is expected to support the standard g:form attributes but need not call g:form as long as it is compatible with the standard g:form attributes. |
Example template implementation
<p:callTag tag="g:form" class="${p.joinClasses(values:[formClass,classes])}"
attrs="${attrs}" bodyContent="${bodyContent}"/>
This example simply delegates to g:form.
9.4.6 The Actions template
The
_actions.gsp
template is used to render the
actions tag.
Contract
The actions template must render the block of form actions supplied in the body of the tag.
The caller uses the
ui:actions
tag to demarcate the part of a
ui:form
that contains the actions the user
can perform - such as "Save or cancel" button and links, or perhaps other data navigation buttons etc.
Sometimes this is separated visually from the rest of the form, and sometimes it is repeated at the top and bottom of forms.
This is entirely up to the UI Set implementation however.
ui:actions
is to be called only once or not at all
in each
ui:form
.
Variables available
Name | Description |
---|
actionsClass | The CSS class to use for the actions container. Value comes from UI Set config |
classes | A string containing the list of CSS classes to apply to the outer container |
bodyContent | The content of the actions section, the markup provided by the caller |
attrs | The attributes to pass through to the tag that is the container for the actions |
Example template implementation
<div class="${p.joinClasses(values:[actionsClass, classes])}">
${bodyContent}
</div>
9.4.7 The Field template
The
_field.gsp
template is used to render the
field tag.
Contract
This GSP template must render all the structural markup required to render a label, input widget and optionally field errors and hints.
The rendering of fields is rather complex. There are various approaches to rendering the markup of input fields, such as Bean Fields and the preferred Grails Fields plugin. This template however is only responsible for the structural layout of the various field elements, not the input itself. For the details of how inputs are actually rendered see the
input template reference.
There are several contractual considerations in this template.
Your implementation must support:
- The ability for developers to customize the various elements using
ui:fieldLabel
, ui:fieldHint
, ui:fieldErrors
and ui:fieldInput
. These nested tags that can be used within ui:field
simply capture the relevant body markup which is passed in to this tempalte as customXXXX
variables
- Support for rendering multiple errors inline if the UI Set is rendering field errors inline
The
ui:field
tag handles most of the complexity around this for you. Each inner element of the field (label/errors/input/hint) that is not provided via a nested tag will be resolved as appropriate. For example label, hint and error text is resolved using standard Platform UI i18n rules.
Variables available
Name | Description |
---|
id | The HTML id to apply to the input, and for the label to reference |
attrs | Any extra attributes to pass through to be applied to the outermost container |
fieldClass | The CSS class to use for the primary container of the field HTML, obtained from UI Set config. |
invalidClass | The CSS class to use for the primary container of the form HTML, in the event of a value being invalid, obtained from UI Set config - in addition to the fieldClass value |
classes | A string containing the list of CSS classes to apply to the outer container |
label | The label text for the label, already resolved against i18n. |
hint | An optional hint string to render with the field, already resolved against i18n. |
invalid | If value is Groovy true, indicates that the field isn't valid. |
required | If value is Groovy true, indicates that the field is required. |
name | The name of the field and/or name of the bean property of the field. |
beanObject | The original root bean supplying the value, if any. |
value | The value of the field to use if a the bean property value is differentx |
type | The explicit type override for the field (see input tag) if any |
errors | The list of field error messages, already resolved against i18n. Groovy false if there are no errors. |
input | The markup to use for the input field, if customInput has no value |
customLabel | The custom label markup to use. If defined, must be used as the full markup for the <label>, but still contained within the structural markup required by the UI Set |
customHint | The custom hint markup to use. If defined, must be used as the full markup for the hint, but still contained within the structural markup required by the UI Set |
customInput | The custom input markup to use. If defined, must be used as the full markup for the input widget, but still contained within the structural markup required by the UI Set |
customErrors | The custom error markup to use. If defined, must be used as the full markup for the errors, but still contained within the structural markup required by the UI Set |
Example template implementation
<div class="${p.joinClasses(values:[fieldClass, classes])}">
<g:if test="${customLabel}">
${customLabel}
</g:if>
<g:else>
<label for="${id.encodeAsHTML()}">${label.encodeAsHTML()}</label>
</g:else>
<g:if test="${customInput}">
${customInput}
</g:if>
<g:else>
${input}
</g:else>
<g:if test="${customHint}">
${customHint}
</g:if>
<g:elseif test="${hint}">
<span class="${hintClass}">${hint.encodeAsHTML()}</span>
</g:elseif>
<g:if test="${customErrors}">
${customErrors}
</g:if>
<g:elseif test="${errors}">
<g:each in="${errors}" var="err">
<span class="${errorClass}">${err.encodeAsHTML()}</span>
</g:each>
</g:elseif>
</div>
The
_input.gsp
template is used to render the
input tag.
Contract
This GSP template must render just the input widget for a single field.
This template must be smart: when rendering a field for a bean property it must attempt to automatically work out the correct field type to use, and to apply relevant constraints from the command or domain class.
These tasks are normally performed using a plugin such as Bean Fields or the preferred Grails Fields.
This template should, where possible, delegate to such a library to avoid reinventing the wheel. However this is not a requirement and you can provide any alternative implementation as long as this contract is honoured.
This is probably the most complicated UI Set template to implement. If possible use an existing implementation.
Your implementation should support:
- Rendering arbitrary fields
- Auto-sensing an appropriate field type for the current field value
- Manual field type overrides
- Rendering fields for an arbitrary property path starting at a root bean
- Relevant user input constraints based on the constraints of the bean (if any)
- Giving a visual indication of whether or not a field is required
- Giving a visual indication of whether there is an error on the field
The
ui:field
tag handles most of the complexity around this for you.
Variables available
Name | Description |
---|
id | The HTML id to apply to the input, and for the label to reference |
attrs | Any extra attributes to pass through to be applied to the outermost container |
inputClass | The CSS class to use for the input element, obtained from UI Set config. |
invalidClass | The CSS class to use for the primary container of the form HTML, in the event of a value being invalid, obtained from UI Set config - in addition to the fieldClass value |
classes | A string containing the list of CSS classes to apply to the outer container |
invalid | If value is Groovy true, indicates that the field isn't valid. |
required | If value is Groovy true, indicates that the field is required. |
name | The name of the field and/or name of the bean property of the field. |
beanObject | The original root bean supplying the value, if any. |
value | The value of the field to use if a the bean property value is differentx |
type | The explicit type override for the field (see input tag) if any |
Example template implementation
<g:if test="${beanObject}">
<g:set var="value" value="${beanObject[name]}"/>
</g:if>
<g:if test="$">
<input id="${id}" name="${name.encodeAsHTML()}"
class="${p.joinClasses(values:[inputClass, classes])}"
type="${type}" value="${value?.encodeAsHTML()}"/>
</g:if>
<g:elseif test="${type == 'select'}">
<g:select id="${id}" name="${name}" value="${value}"
noSelection="[null:'No value']" from="${[ [value:value] ]}"/>
</g:elseif>
<g:elseif test="${type == 'textarea'}">
<textarea id="${id}" name="${name}">${value?.encodeAsHTML()}</textarea>
</g:elseif>
<g:elseif test="${type == 'datepicker'}">
<g:datePicker id="${id}" name="${name}" value="${value}"/>
</g:elseif>
This naïve example does not attempt to support bean properties, and does nothing with required or invalid indications. Here is an example using Bean Fields:
<bean:inputTemplate>
${field}
</bean:inputTemplate>
<bean:selectTemplate>
${field}
</bean:selectTemplate>
<bean:checkBoxTemplate>
${field}
</bean:checkBoxTemplate>
<bean:radioTemplate>
${field}
</bean:radioTemplate>
<bean:textAreaTemplate>
${field}
</bean:textAreaTemplate>
<g:if test="${beanObject}">
<g:if test="${type == 'password'}">
<bean:field type="password" beanName="dummy"
bean="${beanObject}" property="${name}" noLabel="${true}"/>
</g:if>
<g:else>
<bean:field beanName="dummy" bean="${beanObject}"
property="${name}" noLabel="${true}"/>
</g:else>
</g:if>
<g:else>
<input id="${id}" class="
${p.joinClasses(values:[classes, invalid ? invalidClass : ''])}"
type="${type}" name="${name}" value="${value}"/>
</g:else>
This is again somewhat naïve as for non-bean fields it assumes <input> will cover all the cases, which it obviously will not.
9.4.9 The Field Group template
The
_fieldGroup.gsp
template is used to render the
fieldGroup tag.
Contract
The fieldGroup template must render a container around the contents of the tag body.
Sometimes groups of fields will be separated visually from the surrounding content, for example with a border or similar. Usually this is achieved with a <fieldset> tag but this is not always the case, so the template has the flexibility to use any markup it requires.
Variables available
Name | Description |
---|
fieldGroupClass | The CSS class to use for the field group container. Value comes from UI Set config |
classes | A string containing the list of CSS classes to apply to the outer container |
bodyContent | The content of the actions section, the markup provided by the caller |
attrs | The attributes to pass through to the tag that is the container for the actions |
Example template implementation
<fieldset class="${p.joinClasses(values:[fieldGroupClass,classes])}"
${ui.attributes(attrs:attrs)}>
${bodyContent}
</fieldset>
9.4.10 The Image template
The
_image.gsp
template is used to render the
image tag.
Contract
This template needs to render an inline image, such as a photo or illustration on the site. Images such as these may support zooming via a lightbox or similar UI, or other decoration such as a frame that would not be applied to other
<img>
tags.
The template must render the image using the same attribute contract as the Resources
r:img
tag - i.e. the attributes will contain either a
uri
or a
dir
/
file
pair.
Variables available
Name | Description |
---|
title | Title for the image (if any), resolved from an i18n message code if available. The template might render this with special formatting |
imageClass | The CSS class to use for the primary container of the image HTML, obtained from UI Set config. |
classes | A string containing the list of CSS classes to apply to the outer container |
attrs | The attributes to pass through to the g:form tag. The form is expected to support the standard g:form attributes but need not call g:form as long as it is compatible. |
Example template implementation
<div class="${p.joinClasses(values:[imageClass,classes])}">
<p:callTag tag="r:img"
attrs="${attrs}" title="${title.encodeAsHTML()}"/>
</div>
This example simply delegates to r:img and passes through any classes, after applying a container.
9.4.11 The Logo template
The
_logo.gsp
template is used by the
logo tag.
Contract
This template must render the application logo as an inline image.
The logo should include a link to the site's primary URL.
Themes that use pure CSS for logos using e.g. background-image should follow the same conventions for the logo file name and location as per the
logo tag definition.
Variables available
Name | Description |
---|
logoUri | URI of the logo to use |
classes | String of CSS classes supplied |
logoClass | Class to apply to the logo element |
width | Width of the logo or empty |
height | Height of the logo or empty |
Example template implementation
<a href="${p.siteURL().encodeAsHTML()}">
<r:img uri="${logoUri.encodeAsHTML()}"
class="${p.joinClasses(values:[classes, logoClass])}"
alt="${p.siteName()}"
width="${width}" height="${height}"/></a>
9.4.12 The Message template
The
_message.gsp
template is used to render the
message tag.
Contract
This template must render out a UI message which is essentially a block of unstyled text resolved via i18n, with a message type associated with it.
Variables available
Name | Description |
---|
messageClass | A string containing the CSS class to apply to the outermost container element |
classes | A string containing the list of CSS classes to apply to the outer container |
type | The kind of message to use. See messagefor the |
bodyContent | The body of the message, without formatting |
attrs | The attributes to pass through to the outermost containing element. |
Example template implementation
<div class="${p.joinClasses(values:[messageClass, classes])}"${ui.attributes()}>
<p>${bodyContent}</p>
</div>
9.4.13 The Paginate template
The
_paginate.gsp
template is used to render the
paginate tag.
Contract
This template is responsible for rendering the multi-page navigation controls used for reports, search results and so on.
The
paginate tag implementation takes care of the hard parts related to calculating links, what options should be available to the user etc, and this template must simply render the correct markup using the information provided.
Variables available
Name | Description |
---|
paginateClass | A string containing the CSS class to apply to the outer container |
classes | A string containing the list of CSS classes to apply to the outer container |
next | The information for the "next" link |
prev | The information for the "previous" link |
earlier | The information for the "earlier" link, to the list of pages before the current start page number |
later | The information for the "later" link, to the list of pages after the last page number listed |
items | The list of page items to show UI for, each with properties "link", "active" and "text" |
attrs | Any extra attributes the use passed in. Usage of this is undefined across UI Sets |
Example template implementation
<ul class="${p.joinClasses(values:[paginateClass, classes])}">
<g:if test="${prev}">
<li><a href="${prev.link}" class="prev">${prev.text}</a></li>
</g:if>
<g:if test="${earlier}">
<li><a href="${earlier.link}" class="earlier">${earlier.text}</a></li>
</g:if>
<g:each in="${items}" var="i">
<li><g:if test="${i.active}">
${i.text}
</g:if>
<g:else>
<a href="${i.link}">${i.text}</a>
</g:else>
</li>
</g:each>
<g:if test="${later}">
<li><a href="${later.link}" class="later">${later.text}</a></li>
</g:if>
<g:if test="${next}">
<li><a href="${next.link}" class="next">${next.text}</a></li>
</g:if>
</ul>
9.4.14 The Primary Navigation template
The
_primaryNavigation.gsp
template is used to render the
primaryNavigation tag.
Contract
This template must render the primary navigation items for the application.
The primary navigation is the top-level site navigation, which typically includes highlighting the current active top level item.
Only the top level items of the default site navigation must be rendered.
The
primaryNavigation tag is typically only called from Theme layouts to render the site navigation menu.
See
navigation template documentation for details of adherence to Navigation API.
Variables available
Name | Description |
---|
primaryNavigationClass | A string containing the CSS class to apply to the outermost container element |
classes | A string containing the list of CSS classes to apply to the outer container |
attrs | The attributes to pass through to the outermost containing element. |
Example template implementation
<p:callTag tag="nav:primary" attrs="${attrs +
[class:p.joinClasses(values:[primaryNavigationClass, classes])]}"/>
9.4.15 The Secondary Navigation template
The
_secondaryNavigation.gsp
template is used to render the
secondaryNavigation tag.
Contract
This template must render the secondary navigation items for the application.
The secondary navigation is the set of navigation items that apply to the currently active primary navigation item.
Only the top level secondary items must be rendered.
The
secondaryNavigation tag is typically only called from Theme layouts to render the site navigation menu.
See
navigation template documentation for details of adherence to Navigation API.
Variables available
Name | Description |
---|
secondaryNavigationClass | A string containing the CSS class to apply to the outermost container element |
classes | A string containing the list of CSS classes to apply to the outer container |
attrs | The attributes to pass through to the outermost containing element. |
Example template implementation
<p:callTag tag="nav:secondary" attrs="${attrs +
[class:p.joinClasses(values:[secondaryNavigationClass, classes])]}"/>
9.4.16 The navigation template
The
_navigation.gsp
template is used to render the
navigation tag.
Contract
This template must render the navigation items from the supplied scope, or default the default application navigation scope if no scope is supplied.
Only the top level items at the scope supplied must be rendered, nested item rendering is not permitted.
An example use case: a plugin may expose a page that lists a set of administration options that are below secondary navigation level, such as:
<theme:zone name="body">
<ui:block title="Email Confirmation Administration">
<p>Choose from the following options:</p>
<ui:navigation scope="plugin/emailconfirmation.admin"/>
</ui:block>
</theme:zone>
Variables available
Name | Description |
---|
navigationClass | A string containing the CSS class to apply to the outermost container element |
scope | A string identifying the navigation scope to render |
classes | A string containing the list of CSS classes to apply to the outer container |
attrs | The attributes to pass through to the outermost containing element. |
Example template implementation
<p:callTag tag="nav:menu" attrs="${attrs +
[class:p.joinClasses(values:[navigationClass, classes]), scope:scope]}"/>
9.4.17 The Table template
The
_table.gsp
template is used to render the
table tag.
Contract
This template is used to render tables. Typically this would use HTML
<table>
but this is not a concrete requirement - just that it is represented to the user as a columnar table.
The nested
ui:tr
and
ui:th
calls allow this template to apply extra logic.
Variables available
Name | Description |
---|
tableClass | The CSS class to use for the primary container of the table HTML, obtained from UI Set config. |
classes | A string containing the list of CSS classes to apply to the outer container |
bodyContent | The body of the table |
attrs | The attributes to pass through to the outermost container element. |
Example template implementation
<table class="${p.joinClasses(values:[tableClass, classes])}"${ui.attributes()}>
${bodyContent}
</table>
9.4.18 The Table Row template
The
_tr.gsp
template is used to render the
tr tag.
Contract
This template is used to render table rows for the
tr tag.
This can be used to render extra decoration.
Variables available
Name | Description |
---|
trClass | CSS class to use for the element, from UI Set config |
oddEvenClass | The CSS class to use for the row, to indicate if it is even/odd. Value comes from UI Set config |
classes | A string containing the list of CSS classes to apply to the outer container |
row | The current row index in the table (zero based) |
bodyContent | The body of the row |
attrs | The attributes to pass through to the outermost element. |
Example template implementation
<tr class="${p.joinClasses(values:[trClass, oddEvenClass, classes])}"${ui.attributes()}>
${bodyContent}
</tr>
9.4.19 The Table Heading template
The
_th.gsp
template is used to render the
th tag.
Contract
This template is used to render table header cells for the
th tag.
This can be used to render out metadata or extra elements for e.g. sortable columns, and uses Platform UI conventions to resolve i18n heading text.
Variables available
Name | Description |
---|
thClass | CSS class to use for the element, from UI Set config |
classes | A string containing the list of CSS classes to apply to the outer container |
bodyContent | The body of the heading |
attrs | The attributes to pass through to the outermost element |
Example template implementation
<th class="${p.joinClasses(values:[thClass, classes])}"${ui.attributes()}>
${bodyContent}
</th>
9.4.20 The Tabs template
The
_tabs.gsp
template is used to render the
tabs tag.
Contract
This template renders the markup requires to define a set of tabs.
Tabs have a title for each tab, and can either link to a new URL or hide and display different tabs of content embedded in the page.
The tabs are provided in a model variable, having been collected from the
tab template used to implement the
tab tag.
Variables available
Name | Description |
---|
id | The id of the outermost element supplied by application developer or auto-generated |
tabsClass | The CSS class to use for the tabs container. Value comes from UI Set config |
classes | A string containing the list of CSS classes to apply to the outer container |
tabs | The list of tabs, each with active , id and bodyContent properties |
attrs | The attributes to pass through to the outermost container element. |
Example template implementation
<ul class="${p.joinClasses(values:[tabsClass, classes])}" ${ui.attributes()}>
<g:each in="${tabs}" var="t">
<li ${t == active ? 'class="active"' : ''}>
<a href="${t.link ?: ('#'+t.id).encodeAsHTML()}">${t.title.encodeAsHTML()}</a>
</li>
</g:each>
</ul>
<div class="tabBodies">
<g:each in="${tabs}" var="t">
${t.bodyContent}
</g:each>
</div>
This example renders a
<ul>
list containing the tabs and links, and then a set of
<div>
containing the tab contents.
9.4.21 The Tab template
The
_tab.gsp
template is used to render the
tab tag.
Contract
This template must render the markup required to define a tab within the context of a
tabs tag.
The
tabs template collects all the outputs of each
tab invocation rendered by this template, and the
tabs
template then iterates over them to render the necessary markup.
Variables available
Name | Description |
---|
id | Unique id of the tab in this page. Supplied by user or auto generated |
tabClass | CSS class to apply to the outermost container element, from UI Set config |
classes | A string containing the list of CSS classes to apply to the outer container |
bodyContent | The tab content |
active | True if the tab is currently the active tab |
title | Title text for the tab, resolved from i18n |
link | Target link for the tab if it is a link to another URL, may be null |
attrs | The attributes to pass through to the outermost container element. |
Example template implementation
<g:if test="$">
<div id="tab_${id}" class="${p.joinClasses(
values:[active ? ' active' : '', tabClass, classes])}"
${ui.attributes()}>
${bodyContent}
</div>
</g:if>
There are a set of utility tags and functions provided to make it easier to implement UI Set tag templates.
Documentation will be improved in future, but for now see:
attributes tag
cssClass tag
listSets tag
Also see the Platform Core TagLibUtils class javadocs for a set of useful methods.