You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@isis.apache.org by da...@apache.org on 2018/02/22 22:55:36 UTC

[12/52] [abbrv] [partial] isis-site git commit: ISIS-1813: publishing 1.16.1 second pass

http://git-wip-us.apache.org/repos/asf/isis-site/blob/97af7e5f/content/versions/SNAPSHOT/guides/htg.html
----------------------------------------------------------------------
diff --git a/content/versions/SNAPSHOT/guides/htg.html b/content/versions/SNAPSHOT/guides/htg.html
new file mode 100644
index 0000000..d22b289
--- /dev/null
+++ b/content/versions/SNAPSHOT/guides/htg.html
@@ -0,0 +1,3341 @@
+<!doctype html>
+<html>
+ <head> 
+  <!--
+        Licensed to the Apache Software Foundation (ASF) under one
+        or more contributor license agreements.  See the NOTICE file
+        distributed with this work for additional information
+        regarding copyright ownership.  The ASF licenses this file
+        to you under the Apache License, Version 2.0 (the
+        "License"); you may not use this file except in compliance
+        with the License.  You may obtain a copy of the License at
+
+        http://www.apache.org/licenses/LICENSE-2.0
+
+        Unless required by applicable law or agreed to in writing,
+        software distributed under the License is distributed on an
+        "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+        KIND, either express or implied.  See the License for the
+        specific language governing permissions and limitations
+        under the License.
+    --> 
+  <meta http-equiv="Content-Type" content="text/html; charset=UTF-8"> 
+  <meta charset="utf-8"> 
+  <meta name="viewport" content="width=device-width, initial-scale=1.0"> 
+  <!-- No caching headers --> 
+  <meta http-equiv="cache-control" content="no-cache"> 
+  <meta http-equiv="pragma" content="no-cache"> 
+  <meta http-equiv="expires" content="-1"> 
+  <title>Hints &amp; Tips Guide</title> 
+  <link rel="icon" type="image/png" href="../../images/isis-favicon.png"> 
+  <!--
+        Based on DataNucleus' template,
+        that was in turn based on an earlier version of Apache Isis' template,
+        that was in turn based on Apache Deltaspike's template.
+
+        This template uses
+        * Bootstrap v3.3.7 (https://getbootstrap.com/) for navbar.
+        * Bootstrap TOC plugin v0.4.1 (https://afeld.github.io/bootstrap-toc/)
+          for the table of contents.
+        * jQuery (necessary for Bootstrap's JavaScript plugins)
+        * Font-Awesome for some icons used by Asciidoctor
+
+        Also:
+        * Bootswatch "flatly" theme for Bootstrap (https://bootswatch.com/flatly).
+        * slick.js (carousel)
+        * add a link to all headers (home-grown, adapted from blog posts)
+        * integration of elasticlunr.js (home-grown, adapted from blog posts)
+    --> 
+  <link href="https://cdnjs.cloudflare.com/ajax/libs/bootswatch/3.3.7/flatly/bootstrap.min.css" rel="stylesheet"> 
+  <link href="../../css/bootstrap-toc/0.4.1/bootstrap-toc.min.css" rel="stylesheet"> 
+  <link href="../../css/asciidoctor/foundation.css" rel="stylesheet"> 
+  <link href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/4.3.0/css/font-awesome.min.css" rel="stylesheet"> 
+  <link href="../../css/slick/1.5.0/slick.css" rel="stylesheet"> 
+  <link href="../../css/slick/1.5.0/slick-theme.css" rel="stylesheet"> 
+  <link href="../../css/search-panel/search-panel.css" rel="stylesheet"> 
+  <link href="../../css/header-links/header-links.css" rel="stylesheet"> 
+  <link href="../../css/sticky-header/sticky-header.css" rel="stylesheet"> 
+  <link href="../../css/customisations.css" rel="stylesheet"> 
+  <!-- Coderay syntax formatter --> 
+  <style type="text/css">
+        /* Stylesheet for CodeRay to match GitHub theme | MIT License | http://foundation.zurb.com */
+/*pre.CodeRay {background-color:#f7f7f8;}*/
+.CodeRay .line-numbers{border-right:1px solid #d8d8d8;padding:0 0.5em 0 .25em}
+.CodeRay span.line-numbers{display:inline-block;margin-right:.5em;color:rgba(0,0,0,.3)}
+.CodeRay .line-numbers strong{color:rgba(0,0,0,.4)}
+table.CodeRay{border-collapse:separate;border-spacing:0;margin-bottom:0;border:0;background:none}
+table.CodeRay td{vertical-align: top;line-height:1.45}
+table.CodeRay td.line-numbers{text-align:right}
+table.CodeRay td.line-numbers>pre{padding:0;color:rgba(0,0,0,.3)}
+table.CodeRay td.code{padding:0 0 0 .5em}
+table.CodeRay td.code>pre{padding:0}
+.CodeRay .debug{color:#fff !important;background:#000080 !important}
+.CodeRay .annotation{color:#007}
+.CodeRay .attribute-name{color:#000080}
+.CodeRay .attribute-value{color:#700}
+.CodeRay .binary{color:#509}
+.CodeRay .comment{color:#998;font-style:italic}
+.CodeRay .char{color:#04d}
+.CodeRay .char .content{color:#04d}
+.CodeRay .char .delimiter{color:#039}
+.CodeRay .class{color:#458;font-weight:bold}
+.CodeRay .complex{color:#a08}
+.CodeRay .constant,.CodeRay .predefined-constant{color:#008080}
+.CodeRay .color{color:#099}
+.CodeRay .class-variable{color:#369}
+.CodeRay .decorator{color:#b0b}
+.CodeRay .definition{color:#099}
+.CodeRay .delimiter{color:#000}
+.CodeRay .doc{color:#970}
+.CodeRay .doctype{color:#34b}
+.CodeRay .doc-string{color:#d42}
+.CodeRay .escape{color:#666}
+.CodeRay .entity{color:#800}
+.CodeRay .error{color:#808}
+.CodeRay .exception{color:inherit}
+.CodeRay .filename{color:#099}
+.CodeRay .function{color:#900;font-weight:bold}
+.CodeRay .global-variable{color:#008080}
+.CodeRay .hex{color:#058}
+.CodeRay .integer,.CodeRay .float{color:#099}
+.CodeRay .include{color:#555}
+.CodeRay .inline{color:#000}
+.CodeRay .inline .inline{background:#ccc}
+.CodeRay .inline .inline .inline{background:#bbb}
+.CodeRay .inline .inline-delimiter{color:#d14}
+.CodeRay .inline-delimiter{color:#d14}
+.CodeRay .important{color:#555;font-weight:bold}
+.CodeRay .interpreted{color:#b2b}
+.CodeRay .instance-variable{color:#008080}
+.CodeRay .label{color:#970}
+.CodeRay .local-variable{color:#963}
+.CodeRay .octal{color:#40e}
+.CodeRay .predefined{color:#369}
+.CodeRay .preprocessor{color:#579}
+.CodeRay .pseudo-class{color:#555}
+.CodeRay .directive{font-weight:bold}
+.CodeRay .type{font-weight:bold}
+.CodeRay .predefined-type{color:inherit}
+.CodeRay .reserved,.CodeRay .keyword {color:#000;font-weight:bold}
+.CodeRay .key{color:#808}
+.CodeRay .key .delimiter{color:#606}
+.CodeRay .key .char{color:#80f}
+.CodeRay .value{color:#088}
+.CodeRay .regexp .delimiter{color:#808}
+.CodeRay .regexp .content{color:#808}
+.CodeRay .regexp .modifier{color:#808}
+.CodeRay .regexp .char{color:#d14}
+.CodeRay .regexp .function{color:#404;font-weight:bold}
+.CodeRay .string{color:#d20}
+.CodeRay .string .string .string{background:#ffd0d0}
+.CodeRay .string .content{color:#d14}
+.CodeRay .string .char{color:#d14}
+.CodeRay .string .delimiter{color:#d14}
+.CodeRay .shell{color:#d14}
+.CodeRay .shell .delimiter{color:#d14}
+.CodeRay .symbol{color:#990073}
+.CodeRay .symbol .content{color:#a60}
+.CodeRay .symbol .delimiter{color:#630}
+.CodeRay .tag{color:#008080}
+.CodeRay .tag-special{color:#d70}
+.CodeRay .variable{color:#036}
+.CodeRay .insert{background:#afa}
+.CodeRay .delete{background:#faa}
+.CodeRay .change{color:#aaf;background:#007}
+.CodeRay .head{color:#f8f;background:#505}
+.CodeRay .insert .insert{color:#080}
+.CodeRay .delete .delete{color:#800}
+.CodeRay .change .change{color:#66f}
+.CodeRay .head .head{color:#f4f}
+    </style> 
+ </head> 
+ <body data-spy="scroll" data-target="#toc"> 
+  <div id="basedir" style="display:none;">
+   ../../
+  </div> 
+  <div id="docname" style="display:none;">
+   htg
+  </div> 
+  <div id="filetype" style="display:none;">
+   html
+  </div> 
+  <!-- Navbar --> 
+  <nav class="navbar navbar-default navbar-static-top header"> 
+   <div class="container"> 
+    <div class="navbar-header"> 
+     <!-- Three line menu button for use on mobile screens --> 
+     <button type="button" class="navbar-toggle collapsed" data-toggle="collapse" data-target="#navbar" aria-expanded="false" aria-controls="navbar"> <span class="sr-only">Toggle navigation</span> <span class="icon-bar"></span> <span class="icon-bar"></span> <span class="icon-bar"></span> </button> 
+     <a class="navbar-brand" href="../../index.html"> <img alt="Brand" src="../../images/isis-logo-48x48.png"> </a> 
+     <a class="navbar-brand" href="../../index.html">Apache Isis</a> 
+    </div> 
+    <!-- Navbar that will collapse on mobile screens --> 
+    <div id="navbar" class="navbar-collapse collapse"> 
+     <ul class="nav navbar-nav"> 
+      <li class="dropdown"> <a href="#" class="dropdown-toggle" data-toggle="dropdown" role="button" aria-haspopup="true" aria-expanded="false">Documentation<span class="caret"></span></a> 
+       <ul class="dropdown-menu"> 
+        <li><a href="../../documentation.html">Table of Contents</a></li> 
+        <li role="separator" class="divider"></li> 
+        <li class="dropdown-header">User Guides</li> 
+        <li><a href="../../guides/ugfun/ugfun.html">Fundamentals</a></li> 
+        <li><a href="../../guides/ugvw/ugvw.html">Wicket Viewer</a></li> 
+        <li><a href="../../guides/ugvro/ugvro.html">Restful Objects Viewer</a></li> 
+        <li><a href="../../guides/ugodn/ugodn.html">DataNucleus Object Store</a></li> 
+        <li><a href="../../guides/ugsec/ugsec.html">Security</a></li> 
+        <li><a href="../../guides/ugtst/ugtst.html">Testing</a></li> 
+        <li><a href="../../guides/ugbtb/ugbtb.html">Beyond the Basics</a></li> 
+        <li role="separator" class="divider"></li> 
+        <li class="dropdown-header">Reference Guides</li> 
+        <li><a href="../../guides/rgant/rgant.html">Annotations</a></li> 
+        <li><a href="../../guides/rgsvc/rgsvc.html">Domain Services</a></li> 
+        <li><a href="../../guides/rgcfg/rgcfg.html">Core Config' Properties</a></li> 
+        <li><a href="../../guides/rgcms/rgcms.html">Classes, Methods and Schema</a></li> 
+        <li><a href="../../guides/rgmvn/rgmvn.html">Maven plugin</a></li> 
+        <li><a href="../../guides/rgfis/rgfis.html">Framework Internal Services</a></li> 
+        <li role="separator" class="divider"></li> 
+        <li class="dropdown-header">Javadoc</li> 
+        <li><a href="http://javadoc.io/doc/org.apache.isis.core/isis-core-applib">Applib</a></li> 
+       </ul> </li> 
+      <li class="dropdown  hidden-sm hidden-md"> <a href="#" class="dropdown-toggle" data-toggle="dropdown" role="button" aria-haspopup="true" aria-expanded="false">Downloads<span class="caret"></span></a> 
+       <ul class="dropdown-menu"> 
+        <li class="dropdown-header">Maven archetypes</li> 
+        <li><a href="../../guides/ugfun/ugfun.html#_ugfun_getting-started_helloworld-archetype">helloworld</a></li> 
+        <li><a href="../../guides/ugfun/ugfun.html#_ugfun_getting-started_simpleapp-archetype">simpleapp</a></li> 
+        <li role="separator" class="divider"></li> 
+        <li><a href="../../downloads.html">Downloads</a></li> 
+        <li><a href="../../release-notes/release-notes.html">Release Notes</a></li> 
+        <li><a href="../../migration-notes/migration-notes.html">Migration Notes</a></li> 
+        <li role="separator" class="divider"></li> 
+        <li><a href="https://github.com/apache/isis">Github mirror</a></li> 
+       </ul> </li> 
+      <li class="dropdown  hidden-sm"> <a href="#" class="dropdown-toggle" data-toggle="dropdown" role="button" aria-haspopup="true" aria-expanded="false">Support<span class="caret"></span></a> 
+       <ul class="dropdown-menu"> 
+        <li class="dropdown-header">Guides</li> 
+        <li><a href="../../guides/dg/dg.html">Developers' Guide</a></li> 
+        <li><a href="../../guides/cgcom/cgcom.html">Committers' Guide</a></li> 
+        <li><a href="../../guides/htg.html">Hints-n-Tips Guide</a></li> 
+        <li role="separator" class="divider"></li> 
+        <li class="dropdown-header">Mailing Lists</li> 
+        <li><a href="../../support.html">How to subscribe</a></li> 
+        <li><a href="https://lists.apache.org/list.html?users@isis.apache.org">Archives (ASF Pony mail)</a></li> 
+        <li><a href="http://isis.markmail.org/search/?q=">Archives (Markmail)</a></li> 
+        <li role="separator" class="divider"></li> 
+        <li class="dropdown-header">Other Resources</li> 
+        <li><a href="https://issues.apache.org/jira/browse/ISIS">ASF JIRA</a></li> 
+        <li><a href="http://stackoverflow.com/questions/tagged/isis">Stack Overflow</a></li> 
+        <li><a href="../../help.html">Wiki, Fisheye etc.</a></li> 
+       </ul> </li> 
+      <li class="dropdown hidden-sm hidden-md"> <a href="#" class="dropdown-toggle" data-toggle="dropdown" role="button" aria-haspopup="true" aria-expanded="false">@ASF<span class="caret"></span></a> 
+       <ul class="dropdown-menu"> 
+        <li><a href="http://www.apache.org/">Apache Homepage</a></li> 
+        <li><a href="http://www.apache.org/licenses/">Licenses</a></li> 
+        <li><a href="http://www.apache.org/security/">Security</a></li> 
+        <li><a href="http://www.apache.org/foundation/sponsorship.html">Sponsorship</a></li> 
+        <li><a href="http://www.apache.org/foundation/thanks.html">Thanks</a></li> 
+        <li role="separator" class="divider"></li> 
+        <li><a href="https://whimsy.apache.org/board/minutes/Isis.html">PMC board minutes</a></li> 
+       </ul> </li> 
+     </ul> 
+     <div class="nav navbar-nav navbar-right"> 
+      <!-- 'style' added to fix height of input box. FIX THIS --> 
+      <form class="navbar-form" role="search" id="search-form" style="padding: 1px 15px;"> 
+       <div class="form-group"> 
+        <input class="form-control" id="search-field" type="text" size="30" placeholder="Search"> 
+       </div> 
+      </form> 
+     </div> 
+     <p class="nav navbar-text navbar-right small">v2.0.0-M1-SNAPSHOT</p> 
+    </div> 
+   </div> 
+  </nav> 
+  <div class="container"> 
+   <div class="row-fluid"> 
+    <div class="col-xs-12 col-sm-12 col-md-12 col-lg-9"> 
+     <div id="search-panel"> 
+      <div id="search-results"></div> 
+      <div> 
+       <br> 
+       <a href="#" id="search-results-clear">clear</a> 
+      </div> 
+     </div> 
+     <div class="page-title"> 
+      <h1>Hints &amp; Tips Guide</h1> 
+     </div> 
+     <div id="doc-content">
+      <div class="btn-group" style="float: right; font-size: small; padding: 6px;  ">
+       <button type="button" class="btn btn-xs btn-default" onclick="window.location.href=&quot;https://github.com/apache/isis/edit/master/adocs/documentation/src/main/asciidoc/guides/htg.adoc&quot;"><i class="fa fa-pencil-square-o"></i>&nbsp;Edit</button>
+       <button type="button" class="btn btn-xs btn-default dropdown-toggle" data-toggle="dropdown" aria-haspopup="true" aria-expanded="false"><span class="caret"></span><span class="sr-only">Toggle Dropdown</span></button>
+       <ul class="dropdown-menu">
+        <li><a href="https://github.com/apache/isis/edit/master/adocs/documentation/src/main/asciidoc/guides/htg.adoc" target="_blank"><i class="fa fa-pencil-square-o fa-fw" aria-hidden="true"></i>&nbsp; Edit</a></li>
+        <li><a href="https://github.com/apache/isis/commits/master/adocs/documentation/src/main/asciidoc/guides/htg.adoc" target="_blank"><i class="fa fa-clock-o fa-fw" aria-hidden="true"></i>&nbsp; History</a></li>
+        <li><a href="https://github.com/apache/isis/raw/master/adocs/documentation/src/main/asciidoc/guides/htg.adoc" target="_blank"><i class="fa fa-file-text-o fa-fw" aria-hidden="true"></i>&nbsp; Raw</a></li>
+        <li><a href="https://github.com/apache/isis/blame/master/adocs/documentation/src/main/asciidoc/guides/htg.adoc" target="_blank"><i class="fa fa-hand-o-right fa-fw" aria-hidden="true"></i>&nbsp; Blame</a></li>
+       </ul>
+      </div> 
+      <div id="preamble"> 
+       <div class="sectionbody"> 
+        <div class="paragraph"> 
+         <p>This document brings together the hints-n-tips chapters from the various user guides.</p> 
+        </div> 
+       </div> 
+      </div> 
+      <div class="sect1"> 
+       <h2 id="_fundamentals_ui_hints">1. Fundamentals (UI Hints)</h2> 
+       <div class="sectionbody"> 
+        <div class="paragraph"> 
+         <p>Hints and tips for the most commonly used techniques for customising the way that the framework renders domain objects in the user interface. Taken from the <a href="#ugfun/ugfun.adoc">Fundamentals</a> guide.</p> 
+        </div> 
+        <div class="sect2"> 
+         <h3 id="_ugfun_ui-hints_layout">1.1. Layout</h3> 
+         <div class="paragraph"> 
+          <p>The most significant aspect of the UI is the layout of the object’s members: its properties, collections and actions. These can be organized into columns, rows and tabs.</p> 
+         </div> 
+         <div class="paragraph"> 
+          <p>This can be accomplished using either annotations or through a separate file-based layout. Since this is a large topic, it has its own <a href="../ugvw/ugvw.html#_ugvw_layout">layout chapter</a> in the Wicket viewer guide.</p> 
+         </div> 
+        </div> 
+        <div class="sect2"> 
+         <h3 id="_ugfun_ui-hints_object-titles-and-icons">1.2. Object Titles and Icons</h3> 
+         <div class="paragraph"> 
+          <p>In Apache Isis every object is identified to the user by a title (label) and an icon. This is shown in several places: as the main heading for an object; as a link text for an object referencing another object, and also in tables representing collections of objects.</p> 
+         </div> 
+         <div class="paragraph"> 
+          <p>The icon is often the same for all instances of a particular class, but it’s also possible for an individual instance to return a custom icon. This could represent the state of that object (eg a shipped order, say, or overdue library book).</p> 
+         </div> 
+         <div class="paragraph"> 
+          <p>It is also possible for an object to provide a CSS class hint. In conjunction with <a href="../ugvw/ugvw.html#_ugvw_customisation_tweaking-css-classes">customized CSS</a> this can be used to apply arbitrary styling; for example each object could be rendered in a page with a different background colour.</p> 
+         </div> 
+         <div class="sect3"> 
+          <h4 id="_object_title">1.2.1. Object Title</h4> 
+          <div class="paragraph"> 
+           <p>The object title is a label to identify an object to the end-user. Generally the object title is a label to identify an object to the end-user. There is no requirement for it to be absolutely unique, but it should be "unique enough" to distinguish the object from other object’s likely to be rendered on the same page.</p> 
+          </div> 
+          <div class="paragraph"> 
+           <p>The title is always shown with an icon, so there is generally no need for the title to include information about the object’s type. For example the title of a customer object shouldn’t include the literal string "Customer"; it can just have the customer’s name, reference or some other meaningful business identifier.</p> 
+          </div> 
+          <div class="sect4"> 
+           <h5 id="_declarative_style">Declarative style</h5> 
+           <div class="paragraph"> 
+            <p>The <a href="../rgant/rgant.html#_rgant-Title"><code>@Title</code></a> annotation can be used build up the title of an object from its constituent parts.</p> 
+           </div> 
+           <div class="paragraph"> 
+            <p>For example:</p> 
+           </div> 
+           <div class="listingblock"> 
+            <div class="content"> 
+             <pre class="CodeRay highlight"><code data-lang="java"><span class="directive">public</span> <span class="type">class</span> <span class="class">Customer</span> {
+    <span class="annotation">@Title</span>(sequence=<span class="string"><span class="delimiter">"</span><span class="content">1</span><span class="delimiter">"</span></span>, append=<span class="string"><span class="delimiter">"</span><span class="content"> </span><span class="delimiter">"</span></span>)
+    <span class="directive">public</span> <span class="predefined-type">String</span> getFirstName() { ... }
+    <span class="annotation">@Title</span>(sequence=<span class="string"><span class="delimiter">"</span><span class="content">2</span><span class="delimiter">"</span></span>)
+    <span class="directive">public</span> Product getLastName() { ... }
+    ...
+}</code></pre> 
+            </div> 
+           </div> 
+           <div class="paragraph"> 
+            <p>might return "Arthur Clarke", while:</p> 
+           </div> 
+           <div class="listingblock"> 
+            <div class="content"> 
+             <pre class="CodeRay highlight"><code data-lang="java"><span class="directive">public</span> <span class="type">class</span> <span class="class">CustomerAlt</span> {
+    <span class="annotation">@Title</span>(sequence=<span class="string"><span class="delimiter">"</span><span class="content">2</span><span class="delimiter">"</span></span>, prepend=<span class="string"><span class="delimiter">"</span><span class="content">, </span><span class="delimiter">"</span></span>)
+    <span class="directive">public</span> <span class="predefined-type">String</span> getFirstName() { ... }
+
+    <span class="annotation">@Title</span>(sequence=<span class="string"><span class="delimiter">"</span><span class="content">1</span><span class="delimiter">"</span></span>)
+    <span class="directive">public</span> Product getLastName() { ... }
+    ...
+}</code></pre> 
+            </div> 
+           </div> 
+           <div class="paragraph"> 
+            <p>could return "Clarke, Arthur".</p> 
+           </div> 
+           <div class="paragraph"> 
+            <p>Note that the sequence is in Dewey Decimal Format. This allows a subclass to intersperse information within the title. For example (please forgive this horrible domain modelling (!)):</p> 
+           </div> 
+           <div class="listingblock"> 
+            <div class="content"> 
+             <pre class="CodeRay highlight"><code data-lang="java"><span class="directive">public</span> <span class="type">class</span> <span class="class">Author</span> <span class="directive">extends</span> Customer {
+    <span class="annotation">@Title</span>(sequence=<span class="string"><span class="delimiter">"</span><span class="content">1.5</span><span class="delimiter">"</span></span>, append=<span class="string"><span class="delimiter">"</span><span class="content">. </span><span class="delimiter">"</span></span>)
+    <span class="directive">public</span> <span class="predefined-type">String</span> getMiddleInitial() { ... }
+    ...
+}</code></pre> 
+            </div> 
+           </div> 
+           <div class="paragraph"> 
+            <p>could return "Arthur C. Clarke".</p> 
+           </div> 
+           <div class="admonitionblock tip"> 
+            <table> 
+             <tbody>
+              <tr> 
+               <td class="icon"> <i class="fa icon-tip" title="Tip"></i> </td> 
+               <td class="content"> 
+                <div class="paragraph"> 
+                 <p>Titles can sometimes get be long and therefore rather cumbersome in "parented" tables. If <code>@Title</code> has been used then the Wicket viewer will automatically exclude portions of the title belonging to the owning object.</p> 
+                </div> </td> 
+              </tr> 
+             </tbody>
+            </table> 
+           </div> 
+          </div> 
+          <div class="sect4"> 
+           <h5 id="_imperative_style">Imperative style</h5> 
+           <div class="paragraph"> 
+            <p>Alternatively, the title can be provided simply by implementing the <a href="../rgcms/rgcms.html#_rgcms_methods_reserved_title"><code>title()</code></a> reserved method.</p> 
+           </div> 
+           <div class="paragraph"> 
+            <p>For example:</p> 
+           </div> 
+           <div class="listingblock"> 
+            <div class="content"> 
+             <pre class="CodeRay highlight"><code data-lang="java"><span class="directive">public</span> <span class="type">class</span> <span class="class">Author</span> <span class="directive">extends</span> Customer {
+
+    <span class="directive">public</span> <span class="predefined-type">String</span> title() {
+        <span class="predefined-type">StringBuilder</span> buf = <span class="keyword">new</span> <span class="predefined-type">StringBuilder</span>();
+        buf.append(getFirstName());
+        <span class="keyword">if</span>(getMiddleInitial() != <span class="predefined-constant">null</span>) {
+            buf.append(getMiddleInitial()).append(<span class="string"><span class="delimiter">"</span><span class="content">. </span><span class="delimiter">"</span></span>);
+        }
+        buf.append(getLastName();
+        <span class="keyword">return</span> buf.toString();
+    }
+    ...
+}</code></pre> 
+            </div> 
+           </div> 
+           <div class="paragraph"> 
+            <p>A variation on this approach also supports localized names; see <a href="../ugbtb/ugbtb.html#_ugbtb_i18n">beyond-the-basics</a> guide for further details.</p> 
+           </div> 
+          </div> 
+          <div class="sect4"> 
+           <h5 id="_using_a_ui_subscriber">Using a UI subscriber</h5> 
+           <div class="paragraph"> 
+            <p>A third alternative is to move the responsibility for deriving the title into a separate subscriber object.</p> 
+           </div> 
+           <div class="paragraph"> 
+            <p>In the target object, we define an appropriate event type and use the <a href="../rgant/rgant.html#_rgant-DomainObjectLayout_titleUiEvent"><code>@DomainObjectLayout#titleUiEvent()</code></a> attribute to specify:</p> 
+           </div> 
+           <div class="listingblock"> 
+            <div class="content"> 
+             <pre class="CodeRay highlight"><code data-lang="java"><span class="annotation">@DomainObjectLayout</span>(
+    titleUiEvent = Author.TitleUiEvent.class
+)
+<span class="directive">public</span> <span class="type">class</span> <span class="class">Author</span> <span class="directive">extends</span> Customer {
+    <span class="directive">public</span> <span class="directive">static</span> <span class="type">class</span> <span class="class">TitleUiEvent</span>
+            <span class="directive">extends</span> org.apache.isis.applib.services.eventbus.TitleUiEvent&lt;Author&gt; {}
+    ...
+}</code></pre> 
+            </div> 
+           </div> 
+           <div class="paragraph"> 
+            <p>The subscriber can then populate this event:</p> 
+           </div> 
+           <div class="listingblock"> 
+            <div class="content"> 
+             <pre class="CodeRay highlight"><code data-lang="java"><span class="annotation">@DomainService</span>(nature=NatureOfService.DOMAIN)
+<span class="directive">public</span> <span class="type">class</span> <span class="class">AuthorSubscriptions</span> <span class="directive">extends</span> AbstractSubscriber {
+
+    <span class="annotation">@org</span>.axonframework.eventhandling.annotation.EventHandler
+    <span class="annotation">@com</span>.google.common.eventbus.Subscribe
+    <span class="directive">public</span> <span class="type">void</span> on(Author.TitleUiEvent ev) {
+        Author author = ev.getSource();
+        ev.setTitle(titleOf(author);
+    }
+
+    <span class="directive">private</span> <span class="predefined-type">String</span> titleOf(Author author) {
+        <span class="predefined-type">StringBuilder</span> buf = <span class="keyword">new</span> <span class="predefined-type">StringBuilder</span>();
+        buf.append(author.getFirstName());
+        <span class="keyword">if</span>(author.getMiddleInitial() != <span class="predefined-constant">null</span>) {
+            buf.append(author.getMiddleInitial()).append(<span class="string"><span class="delimiter">"</span><span class="content">. </span><span class="delimiter">"</span></span>);
+        }
+        buf.append(author.getLastName();
+        <span class="keyword">return</span> buf.toString();
+    }
+}</code></pre> 
+            </div> 
+           </div> 
+          </div> 
+         </div> 
+         <div class="sect3"> 
+          <h4 id="_object_icon">1.2.2. Object Icon</h4> 
+          <div class="paragraph"> 
+           <p>The icon is often the same for all instances of a particular class, and is picked up by convention.</p> 
+          </div> 
+          <div class="paragraph"> 
+           <p>It’s is also possible for an individual instance to return a custom icon, typically so that some significant state of that domain object is represented. For example, a custom icon could be used to represent a shipped order, say, or an overdue library loan.</p> 
+          </div> 
+          <div class="sect4"> 
+           <h5 id="_declarative_style_2">Declarative style</h5> 
+           <div class="paragraph"> 
+            <p>If there is no requirement to customize the icon (the normal case), then the icon is usually picked up as the <code>.png</code> file in the same package as the class. For example, the icon for a class <code>org.mydomain.myapp.Customer</code> will be <code>org/mydomain/myapp/Customer.png</code> (if it exists).</p> 
+           </div> 
+           <div class="paragraph"> 
+            <p>Alternatively, font-awesome icon can be used. This is specified using the <a href="../rgant/rgant.html#_rgant-DomainObjectLayout_cssClassFa"><code>@DomainObjectLayout#cssClassFa()</code></a> attribute.</p> 
+           </div> 
+           <div class="paragraph"> 
+            <p>For example:</p> 
+           </div> 
+           <div class="listingblock"> 
+            <div class="content"> 
+             <pre class="CodeRay highlight"><code data-lang="java"><span class="annotation">@DomainObjectLayout</span>(
+    cssClassFa=<span class="string"><span class="delimiter">"</span><span class="content">play</span><span class="delimiter">"</span></span>               <i class="conum" data-value="1"></i><b>(1)</b>
+)
+<span class="directive">public</span> <span class="type">class</span> <span class="class">InvoiceRun</span> {
+    ...
+}</code></pre> 
+            </div> 
+           </div> 
+           <div class="colist arabic"> 
+            <table> 
+             <tbody>
+              <tr> 
+               <td><i class="conum" data-value="1"></i><b>1</b></td> 
+               <td>will use the "fa-play" icon.</td> 
+              </tr> 
+             </tbody>
+            </table> 
+           </div> 
+          </div> 
+          <div class="sect4"> 
+           <h5 id="_imperative_style_2">Imperative style</h5> 
+           <div class="paragraph"> 
+            <p>To customise the icon on an instance-by-instance basis, we implement the reserved <a href="../rgcms/rgcms.html#_rgcms_methods_reserved_iconName"><code>iconName()</code></a> method.</p> 
+           </div> 
+           <div class="paragraph"> 
+            <p>For example:</p> 
+           </div> 
+           <div class="listingblock"> 
+            <div class="content"> 
+             <pre class="CodeRay highlight"><code data-lang="java"><span class="directive">public</span> <span class="type">class</span> <span class="class">Order</span> {
+    <span class="directive">public</span> <span class="predefined-type">String</span> iconName() {
+        <span class="keyword">return</span> isShipped() ? <span class="string"><span class="delimiter">"</span><span class="content">shipped</span><span class="delimiter">"</span></span>: <span class="predefined-constant">null</span>;
+    }
+    ...
+}</code></pre> 
+            </div> 
+           </div> 
+           <div class="paragraph"> 
+            <p>In this case, if the <code>Order</code> has shipped then the framework will look for an icon image named "Order-shipped.png" (in the same package as the class). Otherwise it will just use "Order.png", as normal.</p> 
+           </div> 
+          </div> 
+          <div class="sect4"> 
+           <h5 id="_using_a_ui_subscriber_2">Using a UI subscriber</h5> 
+           <div class="paragraph"> 
+            <p>As for title, the determination of which image file to use for the icon can be externalized into a UI event subscriber.</p> 
+           </div> 
+           <div class="paragraph"> 
+            <p>In the target object, we define an appropriate event type and use the <a href="../rgant/rgant.html#_rgant-DomainObjectLayout_iconUiEvent"><code>@DomainObjectLayout#iconUiEvent()</code></a> attribute to specify.</p> 
+           </div> 
+           <div class="paragraph"> 
+            <p>For example</p> 
+           </div> 
+           <div class="listingblock"> 
+            <div class="content"> 
+             <pre class="CodeRay highlight"><code data-lang="java"><span class="annotation">@DomainObjectLayout</span>(
+    iconUiEvent = Author.IconUiEvent.class
+)
+<span class="directive">public</span> <span class="type">class</span> <span class="class">Order</span> {
+    <span class="directive">public</span> <span class="directive">static</span> <span class="type">class</span> <span class="class">IconUiEvent</span>
+            <span class="directive">extends</span> org.apache.isis.applib.services.eventbus.IconUiEvent&lt;Order&gt; {}
+    ...
+}</code></pre> 
+            </div> 
+           </div> 
+           <div class="paragraph"> 
+            <p>The subscriber can then populate this event:</p> 
+           </div> 
+           <div class="listingblock"> 
+            <div class="content"> 
+             <pre class="CodeRay highlight"><code data-lang="java"><span class="annotation">@DomainService</span>(nature=NatureOfService.DOMAIN)
+<span class="directive">public</span> <span class="type">class</span> <span class="class">OrderSubscriptions</span> <span class="directive">extends</span> AbstractSubscriber {
+
+    <span class="annotation">@org</span>.axonframework.eventhandling.annotation.EventHandler
+    <span class="annotation">@com</span>.google.common.eventbus.Subscribe
+    <span class="directive">public</span> <span class="type">void</span> on(Order.IconUiEvent ev) {
+        Order order = ev.getSource();
+        ev.setIconName(iconNameOf(order);
+    }
+
+    <span class="directive">private</span> <span class="predefined-type">String</span> iconNameOf(Order order) {
+        <span class="predefined-type">StringBuilder</span> buf = <span class="keyword">new</span> <span class="predefined-type">StringBuilder</span>();
+        <span class="keyword">return</span> order.isShipped() ? <span class="string"><span class="delimiter">"</span><span class="content">shipped</span><span class="delimiter">"</span></span>: <span class="predefined-constant">null</span>;
+    }
+}</code></pre> 
+            </div> 
+           </div> 
+          </div> 
+         </div> 
+         <div class="sect3"> 
+          <h4 id="_object_css_styling">1.2.3. Object CSS Styling</h4> 
+          <div class="paragraph"> 
+           <p>It is also possible for an object to return a <a href="../rgcms/rgcms.html#_rgcms_methods_reserved_cssClass">CSS class</a>. In conjunction with <a href="../ugvw/ugvw.html#_ugvw_customisation_tweaking-css-classes">customized CSS</a> this can be used to apply arbitrary styling; for example each object could be rendered in a page with a different background colour.</p> 
+          </div> 
+          <div class="sect4"> 
+           <h5 id="_declarative_style_3">Declarative style</h5> 
+           <div class="paragraph"> 
+            <p>To render an object with a particular CSS, use <a href="../rgant/rgant.html#_rgant-DomainObjectLayout_cssClass"><code>@DomainObjectLayout#cssClass()</code></a>.</p> 
+           </div> 
+           <div class="paragraph"> 
+            <p>When the domain object is rendered on its own page, this CSS class will appear on a top-level <code>&lt;div&gt;</code>. Or, when the domain object is rendered as a row in a collection, then the CSS class will appear in a <code>&lt;div&gt;</code> wrapped by the <code>&lt;tr&gt;</code> of the row.</p> 
+           </div> 
+           <div class="paragraph"> 
+            <p>One possible use case would be to render the most important object types with a subtle background colour: <code>Customer</code>s shown in light green, or <code>Order</code>s shown in a light pink, for example.</p> 
+           </div> 
+          </div> 
+          <div class="sect4"> 
+           <h5 id="_imperative_style_3">Imperative style</h5> 
+           <div class="paragraph"> 
+            <p>To customise the icon on an instance-by-instance basis, we implement the reserved <a href="../rgcms/rgcms.html#_rgcms_methods_reserved_cssClass"><code>cssClass()</code></a> method.</p> 
+           </div> 
+           <div class="paragraph"> 
+            <p>For example:</p> 
+           </div> 
+           <div class="listingblock"> 
+            <div class="content"> 
+             <pre class="CodeRay highlight"><code data-lang="java"><span class="directive">public</span> <span class="type">class</span> <span class="class">Order</span> {
+    <span class="directive">public</span> <span class="predefined-type">String</span> cssClass() {
+        <span class="keyword">return</span> isShipped() ? <span class="string"><span class="delimiter">"</span><span class="content">shipped</span><span class="delimiter">"</span></span>: <span class="predefined-constant">null</span>;       <i class="conum" data-value="1"></i><b>(1)</b>
+    }
+    ...
+}</code></pre> 
+            </div> 
+           </div> 
+           <div class="colist arabic"> 
+            <table> 
+             <tbody>
+              <tr> 
+               <td><i class="conum" data-value="1"></i><b>1</b></td> 
+               <td>the implementation might well be the same as the <code>iconName()</code>.</td> 
+              </tr> 
+             </tbody>
+            </table> 
+           </div> 
+           <div class="paragraph"> 
+            <p>If non-null value is returned then the CSS class will be rendered <em>in addition</em> to any declarative CSS class also specified.</p> 
+           </div> 
+          </div> 
+          <div class="sect4"> 
+           <h5 id="_using_a_ui_subscriber_3">Using a UI subscriber</h5> 
+           <div class="paragraph"> 
+            <p>As for title and icon, the determination of which CSS class to render can be externalized into a UI event subscriber.</p> 
+           </div> 
+           <div class="paragraph"> 
+            <p>In the target object, we define an appropriate event type and use the <a href="../rgant/rgant.html#_rgant-DomainObjectLayout_cssClassUiEvent"><code>@DomainObjectLayout#cssClassUiEvent()</code></a> attribute to specify.</p> 
+           </div> 
+           <div class="paragraph"> 
+            <p>For example</p> 
+           </div> 
+           <div class="listingblock"> 
+            <div class="content"> 
+             <pre class="CodeRay highlight"><code data-lang="java"><span class="annotation">@DomainObjectLayout</span>(
+    cssClassUiEvent = Author.CssClassUiEvent.class
+)
+<span class="directive">public</span> <span class="type">class</span> <span class="class">Order</span> {
+    <span class="directive">public</span> <span class="directive">static</span> <span class="type">class</span> <span class="class">CssClassUiEvent</span>
+            <span class="directive">extends</span> org.apache.isis.applib.services.eventbus.CssClassUiEvent&lt;Order&gt; {}
+    ...
+}</code></pre> 
+            </div> 
+           </div> 
+           <div class="paragraph"> 
+            <p>The subscriber can then populate this event:</p> 
+           </div> 
+           <div class="listingblock"> 
+            <div class="content"> 
+             <pre class="CodeRay highlight"><code data-lang="java"><span class="annotation">@DomainService</span>(nature=NatureOfService.DOMAIN)
+<span class="directive">public</span> <span class="type">class</span> <span class="class">OrderSubscriptions</span> <span class="directive">extends</span> AbstractSubscriber {
+
+    <span class="annotation">@org</span>.axonframework.eventhandling.annotation.EventHandler
+    <span class="annotation">@com</span>.google.common.eventbus.Subscribe
+    <span class="directive">public</span> <span class="type">void</span> on(Order.CssClassUiEvent ev) {
+        Order order = ev.getSource();
+        ev.setIconName(iconNameOf(order);
+    }
+
+    <span class="directive">private</span> <span class="predefined-type">String</span> cssClassOf(Order order) {
+        <span class="predefined-type">StringBuilder</span> buf = <span class="keyword">new</span> <span class="predefined-type">StringBuilder</span>();
+        <span class="keyword">return</span> order.isShipped() ? <span class="string"><span class="delimiter">"</span><span class="content">shipped</span><span class="delimiter">"</span></span>: <span class="predefined-constant">null</span>;
+    }
+}</code></pre> 
+            </div> 
+           </div> 
+          </div> 
+         </div> 
+        </div> 
+        <div class="sect2"> 
+         <h3 id="_ugfun_ui-hints_action-icons-and-css">1.3. Action Icons and CSS</h3> 
+         <div class="paragraph"> 
+          <p>Apache Isis allows <a href="http://fortawesome.github.io/Font-Awesome/icons/">font awesome</a> icons to be associated with each action, and for <a href="http://getbootstrap.com/css/#buttons">Bootstrap CSS</a> to be applied to action rendered as buttons. These UI hints can be applied either to individual actions, or can be applied en-masse using pattern matching.</p> 
+         </div> 
+         <div class="paragraph"> 
+          <p>It is also possible to specify additional CSS for an object’s members (not just actions).</p> 
+         </div> 
+         <div class="sect3"> 
+          <h4 id="_icons">1.3.1. Icons</h4> 
+          <div class="paragraph"> 
+           <p>Action icons can be specified in several ways.</p> 
+          </div> 
+          <div class="paragraph"> 
+           <p>One option is to use the <a href="../rgant/rgant.html#_rgant-ActionLayout_cssClassFa"><code>@ActionLayout#cssClassFa()</code></a>. For example:</p> 
+          </div> 
+          <div class="listingblock"> 
+           <div class="content"> 
+            <pre class="CodeRay highlight"><code data-lang="java"><span class="annotation">@ActionLayout</span>(cssClassFa=<span class="string"><span class="delimiter">"</span><span class="content">refresh</span><span class="delimiter">"</span></span>)
+<span class="directive">public</span> <span class="type">void</span> renew() {
+    ...
+}</code></pre> 
+           </div> 
+          </div> 
+          <div class="paragraph"> 
+           <p>Alternatively, you can specify these hints dynamically in the <a href="../ugvw/ugvw.html#_ugvw_layout"><code>Xxx.layout.xml</code></a> for the entity:</p> 
+          </div> 
+          <div class="listingblock"> 
+           <div class="content"> 
+            <pre class="CodeRay highlight"><code data-lang="xml"><span class="tag">&lt;cpt:action</span> <span class="attribute-name">id</span>=<span class="string"><span class="delimiter">"</span><span class="content">renew</span><span class="delimiter">"</span></span> <span class="attribute-name">cssClassFa</span>=<span class="string"><span class="delimiter">"</span><span class="content">refresh</span><span class="delimiter">"</span></span><span class="tag">/&gt;</span></code></pre> 
+           </div> 
+          </div> 
+          <div class="paragraph"> 
+           <p>Rather than annotating every action with <a href="../rgant/rgant.html#_rgant-ActionLayout_cssClassFa"><code>@ActionLayout#cssClassFa()</code></a> and <a href="../rgant/rgant.html#_rgant-ActionLayout_cssClass"><code>@ActionLayout#cssClass()</code></a> you can instead specify the UI hint globally using regular expressions. Not only does this save a lot of boilerplate/editing, it helps ensure consistency across all actions.</p> 
+          </div> 
+          <div class="paragraph"> 
+           <p>To declare fa classes globally, use the <a href="../rgcfg/rgcfg.html#_rgcfg_configuring-core">configuration property</a> <code>isis.reflector.facet.cssClassFa.patterns</code> (a comma separated list of key:value pairs).</p> 
+          </div> 
+          <div class="paragraph"> 
+           <p>For example:</p> 
+          </div> 
+          <div class="listingblock"> 
+           <div class="content"> 
+            <pre class="CodeRay highlight"><code data-lang="ini">isis.reflector.facet.cssClassFa.patterns=\
+                        new.*:fa-plus,\
+                        add.*:fa-plus-square,\
+                        create.*:fa-plus,\
+                        renew.*:fa-refresh,\
+                        list.*:fa-list, \
+                        all.*:fa-list, \
+                        download.*:fa-download, \
+                        upload.*:fa-upload, \
+                        execute.*:fa-bolt, \
+                        run.*:fa-bolt</code></pre> 
+           </div> 
+          </div> 
+          <div class="paragraph"> 
+           <p>Here:</p> 
+          </div> 
+          <div class="ulist"> 
+           <ul> 
+            <li> <p>the key is a regex matching action names (eg <code>create.*</code>), and</p> </li> 
+            <li> <p>the value is a <a href="http://fortawesome.github.io/Font-Awesome/icons/">font-awesome</a> icon name</p> </li> 
+           </ul> 
+          </div> 
+          <div class="paragraph"> 
+           <p>For example, "fa-plus" is applied to all action members called "newXxx"</p> 
+          </div> 
+         </div> 
+         <div class="sect3"> 
+          <h4 id="_css">1.3.2. CSS</h4> 
+          <div class="paragraph"> 
+           <p>Similarly, a CSS class can be specified for object members:</p> 
+          </div> 
+          <div class="ulist"> 
+           <ul> 
+            <li> <p><a href="../rgant/rgant.html#_rgant-ActionLayout_cssClass"><code>@ActionLayout#cssClass()</code></a> for actions</p> </li> 
+            <li> <p><a href="../rgant/rgant.html#_rgant-PropertyLayout_cssClass"><code>@PropertyLayout#cssClass()</code></a> for properties, and</p> </li> 
+            <li> <p><a href="../rgant/rgant.html#_rgant-CollectionLayout_cssClass"><code>@CollectionLayout#cssClass()</code></a> for collections.</p> </li> 
+           </ul> 
+          </div> 
+          <div class="paragraph"> 
+           <p>Again, this CSS class will be attached to an appropriate containing <code>&lt;div&gt;</code> or <code>&lt;span&gt;</code> on the rendered page.</p> 
+          </div> 
+          <div class="paragraph"> 
+           <p>Possible use cases for this is to highlight the most important properties of a domain object.</p> 
+          </div> 
+          <div class="paragraph"> 
+           <p>It is also possible to specify CSS classes globally, using the <a href="../rgcfg/rgcfg.html#_rgcfg_configuring-core">configuration property</a> <code>isis.reflector.facet.cssClass.patterns</code> configuration property.</p> 
+          </div> 
+          <div class="paragraph"> 
+           <p>For example:</p> 
+          </div> 
+          <div class="listingblock"> 
+           <div class="content"> 
+            <pre class="CodeRay highlight"><code data-lang="ini">isis.reflector.facet.cssClass.patterns=\
+                        delete.*:btn-warning</code></pre> 
+           </div> 
+          </div> 
+          <div class="paragraph"> 
+           <p>where (again):</p> 
+          </div> 
+          <div class="ulist"> 
+           <ul> 
+            <li> <p>the key is a regex matching action names (eg <code>delete.*</code>), and</p> </li> 
+            <li> <p>the value is a <a href="http://getbootstrap.com/css/">Bootstrap</a> CSS button class (eg `btn-warning) to be applied</p> </li> 
+           </ul> 
+          </div> 
+         </div> 
+        </div> 
+        <div class="sect2"> 
+         <h3 id="_ugfun_ui-hints_names-and-descriptions">1.4. Names and Descriptions</h3> 
+         <div class="paragraph"> 
+          <p>The name of classes and class members are usually inferred from the Java source code directly. For example, an action method called <code>placeOrder</code> will be rendered as "Place Order", and a collection called <code>orderItems</code> is rendered as "Order Items".</p> 
+         </div> 
+         <div class="paragraph"> 
+          <p>Occasionally though the desired name is not possible; either the name is a Java reserved word (eg "class"), or might require characters that are not valid, for example abbreviations.</p> 
+         </div> 
+         <div class="paragraph"> 
+          <p>In such cases the name can be specified declaratively.</p> 
+         </div> 
+         <div class="paragraph"> 
+          <p>It is also possible to specify a description declaratively; this is used as a tooltip in the UI.</p> 
+         </div> 
+         <div class="paragraph"> 
+          <p>The table below summarizes the annotations available:</p> 
+         </div> 
+         <table class="tableblock frame-all grid-all spread"> 
+          <caption class="title">
+           Table 1. Names and descriptions
+          </caption> 
+          <colgroup> 
+           <col style="width: 33.3333%;"> 
+           <col style="width: 33.3333%;"> 
+           <col style="width: 33.3334%;"> 
+          </colgroup> 
+          <thead> 
+           <tr> 
+            <th class="tableblock halign-left valign-top">Feature</th> 
+            <th class="tableblock halign-left valign-top">Named</th> 
+            <th class="tableblock halign-left valign-top">Description</th> 
+           </tr> 
+          </thead> 
+          <tbody> 
+           <tr> 
+            <td class="tableblock halign-left valign-top">
+             <div>
+              <div class="paragraph"> 
+               <p>Class</p> 
+              </div>
+             </div></td> 
+            <td class="tableblock halign-left valign-top">
+             <div>
+              <div class="paragraph"> 
+               <p><a href="../rgant/rgant.html#_rgant-DomainObjectLayout_named"><code>@DomainObjectLayout#named()</code></a></p> 
+              </div>
+             </div></td> 
+            <td class="tableblock halign-left valign-top">
+             <div>
+              <div class="paragraph"> 
+               <p><a href="../rgant/rgant.html#_rgant-DomainObjectLayout_describedAs"><code>@DomainObjectLayout#describedAs()</code></a></p> 
+              </div>
+             </div></td> 
+           </tr> 
+           <tr> 
+            <td class="tableblock halign-left valign-top">
+             <div>
+              <div class="paragraph"> 
+               <p>Property</p> 
+              </div>
+             </div></td> 
+            <td class="tableblock halign-left valign-top">
+             <div>
+              <div class="paragraph"> 
+               <p><a href="../rgant/rgant.html#_rgant-PropertyLayout_named"><code>@PropertyLayout#named()</code></a></p> 
+              </div>
+             </div></td> 
+            <td class="tableblock halign-left valign-top">
+             <div>
+              <div class="paragraph"> 
+               <p><a href="../rgant/rgant.html#_rgant-PropertyLayout_describedAs"><code>@PropertyLayout#describedAs()</code></a></p> 
+              </div>
+             </div></td> 
+           </tr> 
+           <tr> 
+            <td class="tableblock halign-left valign-top">
+             <div>
+              <div class="paragraph"> 
+               <p>Collection</p> 
+              </div>
+             </div></td> 
+            <td class="tableblock halign-left valign-top">
+             <div>
+              <div class="paragraph"> 
+               <p><a href="../rgant/rgant.html#_rgant-CollectionLayout_named"><code>@CollectionLayout#named()</code></a></p> 
+              </div>
+             </div></td> 
+            <td class="tableblock halign-left valign-top">
+             <div>
+              <div class="paragraph"> 
+               <p><a href="../rgant/rgant.html#_rgant-CollectionLayout_describedAs"><code>@CollectionLayout#describedAs()</code></a></p> 
+              </div>
+             </div></td> 
+           </tr> 
+           <tr> 
+            <td class="tableblock halign-left valign-top">
+             <div>
+              <div class="paragraph"> 
+               <p>Action</p> 
+              </div>
+             </div></td> 
+            <td class="tableblock halign-left valign-top">
+             <div>
+              <div class="paragraph"> 
+               <p><a href="../rgant/rgant.html#_rgant-ActionLayout_named"><code>@ActionLayout#named()</code></a></p> 
+              </div>
+             </div></td> 
+            <td class="tableblock halign-left valign-top">
+             <div>
+              <div class="paragraph"> 
+               <p><a href="../rgant/rgant.html#_rgant-ActionLayout_describedAs"><code>@ActionLayout#describedAs()</code></a></p> 
+              </div>
+             </div></td> 
+           </tr> 
+           <tr> 
+            <td class="tableblock halign-left valign-top">
+             <div>
+              <div class="paragraph"> 
+               <p>Action Parameters</p> 
+              </div>
+             </div></td> 
+            <td class="tableblock halign-left valign-top">
+             <div>
+              <div class="paragraph"> 
+               <p><a href="../rgant/rgant.html#_rgant-ParameterLayout_named"><code>@ParameterLayout#named()</code></a></p> 
+              </div>
+             </div></td> 
+            <td class="tableblock halign-left valign-top">
+             <div>
+              <div class="paragraph"> 
+               <p><a href="../rgant/rgant.html#_rgant-ParameterLayout_describedAs"><code>@ParameterLayout#describedAs()</code></a></p> 
+              </div>
+             </div></td> 
+           </tr> 
+          </tbody> 
+         </table> 
+         <div class="admonitionblock tip"> 
+          <table> 
+           <tbody>
+            <tr> 
+             <td class="icon"> <i class="fa icon-tip" title="Tip"></i> </td> 
+             <td class="content"> 
+              <div class="paragraph"> 
+               <p>If you’re running on Java 8, then note that it’s possible to write Isis applications without using <code>@ParameterLayout(named=…​)</code> annotation. Support for this can be found in the (non-ASF) <a href="http://platform.incode.org" target="_blank">Incode Platform</a>'s paraname8 metamodel extension (non-ASF). (In the future we’ll fold this into core). See also our guidance on <a href="../../migration-notes/migration-notes.html#_migration-notes_1.8.0-to-1.9.0_upgrading-to-java8">upgrading to Java 8</a>.</p> 
+              </div> </td> 
+            </tr> 
+           </tbody>
+          </table> 
+         </div> 
+         <div class="paragraph"> 
+          <p>The framework also supports i18n: locale-specific names and descriptions. for more information, see the <a href="../ugbtb/ugbtb.html#_ugbtb_i18n">beyond-the-basics</a> guide.</p> 
+         </div> 
+        </div> 
+        <div class="sect2"> 
+         <h3 id="_ugfun_ui-hints_eager-rendering">1.5. Eager rendering</h3> 
+         <div class="paragraph"> 
+          <p>By default, parented collections all rendered lazily, in other words in a "collapsed" table view.</p> 
+         </div> 
+         <div class="paragraph"> 
+          <p>For the more commonly used collections we want to show the table expanded:</p> 
+         </div> 
+         <div class="imageblock"> 
+          <div class="content"> 
+           <a class="image" href="ugfun/images/programming-model/todoapp-Dashboard.png"><img src="ugfun/images/programming-model/todoapp-Dashboard.png" alt="todoapp Dashboard" width="px"></a> 
+          </div> 
+         </div> 
+         <div class="paragraph"> 
+          <p>For this we annotate the collection using <a href="../rgant/rgant.html#_rgant-CollectionLayout_defaultView"><code>@CollectionLayout#defaultView()</code></a>; for example</p> 
+         </div> 
+         <div class="listingblock"> 
+          <div class="content"> 
+           <pre class="CodeRay highlight"><code data-lang="java"><span class="annotation">@javax</span>.jdo.annotations.Persistent(table=<span class="string"><span class="delimiter">"</span><span class="content">ToDoItemDependencies</span><span class="delimiter">"</span></span>)
+<span class="directive">private</span> <span class="predefined-type">Set</span>&lt;ToDoItem&gt; dependencies = <span class="keyword">new</span> <span class="predefined-type">TreeSet</span>&lt;&gt;();
+<span class="annotation">@Collection</span>
+<span class="annotation">@CollectionLayout</span>(
+    defaultView = <span class="string"><span class="delimiter">"</span><span class="content">table</span><span class="delimiter">"</span></span>
+)
+<span class="directive">public</span> <span class="predefined-type">Set</span>&lt;ToDoItem&gt; getDependencies() {
+    <span class="keyword">return</span> dependencies;
+}</code></pre> 
+          </div> 
+         </div> 
+         <div class="admonitionblock note"> 
+          <table> 
+           <tbody>
+            <tr> 
+             <td class="icon"> <i class="fa icon-note" title="Note"></i> </td> 
+             <td class="content"> 
+              <div class="paragraph"> 
+               <p>The <code>defaultView()</code> attribute replaces the deprecated approach of using <a href="../rgant/rgant.html#_rgant-CollectionLayout_render"><code>@CollectionLayout#render()</code></a> eagerly.</p> 
+              </div> </td> 
+            </tr> 
+           </tbody>
+          </table> 
+         </div> 
+         <div class="paragraph"> 
+          <p>Alternatively, it can be specified the <code>Xxx.layout.xml</code> file:</p> 
+         </div> 
+         <div class="listingblock"> 
+          <div class="content"> 
+           <pre class="CodeRay highlight"><code data-lang="javascript">&lt;bs3:col span=<span class="string"><span class="delimiter">"</span><span class="content">5</span><span class="delimiter">"</span></span> cssClass=<span class="string"><span class="delimiter">"</span><span class="content">custom-padding-top-20</span><span class="delimiter">"</span></span>&gt;
+    <span class="tag">&lt;cpt:collection</span> <span class="attribute-name">id</span>=<span class="string"><span class="delimiter">"</span><span class="content">notYetComplete</span><span class="delimiter">"</span></span> <span class="attribute-name">defaultView</span>=<span class="string"><span class="delimiter">"</span><span class="content">table</span><span class="delimiter">"</span></span> <span class="tag">/&gt;</span>
+    <span class="tag">&lt;cpt:collection</span> <span class="attribute-name">id</span>=<span class="string"><span class="delimiter">"</span><span class="content">complete</span><span class="delimiter">"</span></span> <span class="attribute-name">defaultView</span>=<span class="string"><span class="delimiter">"</span><span class="content">table</span><span class="delimiter">"</span></span><span class="tag">/&gt;</span>
+&lt;<span class="regexp"><span class="delimiter">/</span><span class="content">bs3col&gt;</span></span></code></pre> 
+          </div> 
+         </div> 
+         <div class="paragraph"> 
+          <p>It might be thought that collections that are eagerly rendered should also be eagerly loaded from the database by enabling the <code>defaultFetchGroup</code> attribute:</p> 
+         </div> 
+         <div class="listingblock"> 
+          <div class="content"> 
+           <pre class="CodeRay highlight"><code data-lang="java"><span class="annotation">@javax</span>.jdo.annotations.Persistent(table=<span class="string"><span class="delimiter">"</span><span class="content">ToDoItemDependencies</span><span class="delimiter">"</span></span>, defaultFetchGroup=<span class="string"><span class="delimiter">"</span><span class="content">true</span><span class="delimiter">"</span></span>)
+<span class="directive">private</span> <span class="predefined-type">Set</span>&lt;ToDoItem&gt; dependencies = <span class="keyword">new</span> <span class="predefined-type">TreeSet</span>&lt;&gt;();
+...</code></pre> 
+          </div> 
+         </div> 
+         <div class="paragraph"> 
+          <p>While this can be done, it’s likely to be a bad idea, because doing so will cause DataNucleus to query for more data irrespective of how the object is used/rendered.</p> 
+         </div> 
+         <div class="paragraph"> 
+          <p>Of course, your mileage may vary, so do experiment.</p> 
+         </div> 
+        </div> 
+       </div> 
+      </div> 
+      <div class="sect1"> 
+       <h2 id="_wicket_viewer">2. Wicket Viewer</h2> 
+       <div class="sectionbody"> 
+        <div class="paragraph"> 
+         <p>Hints and tips for more advanced customisation of the UI. Taken from the <a href="#ugvw/ugvw.adoc">Wicket viewer</a> guide.</p> 
+        </div> 
+        <div class="sect2"> 
+         <h3 id="_ugvw_hints-and-tips_per-user-themes">2.1. Per-user Themes</h3> 
+         <div class="paragraph"> 
+          <p>From <a href="http://isis.markmail.org/thread/kb4442niwwbnghey">this thread</a> on the Apache Isis users mailing list:</p> 
+         </div> 
+         <div class="ulist"> 
+          <ul> 
+           <li> <p><em>Is it possible to have each of our resellers (using our Isis application) use there own theme/branding with their own logo and colors? Would this also be possible for the login page, possibly depending on the used host name?</em></p> </li> 
+          </ul> 
+         </div> 
+         <div class="paragraph"> 
+          <p>Yes, you can do this, by installing a custom implementation of the Wicket Bootstrap’s <code>ActiveThemeProvider</code>.</p> 
+         </div> 
+         <div class="paragraph"> 
+          <p>The <a href="http://github.com/isisaddons/isis-app-todoapp">Isis addons' todoapp</a> (non-ASF) actually <a href="https://github.com/isisaddons/isis-app-todoapp/tree/61b8114a8e01dbb3c380b31cf09eaed456407570">does this</a>, storing the info via the (non-ASF) <a href="http://platform.incode.org/modules/dom/settings/dom-settings.html">Incode Platform’s settings module</a> :</p> 
+         </div> 
+         <div class="listingblock"> 
+          <div class="title">
+           IActiveThemeProvider implementation
+          </div> 
+          <div class="content"> 
+           <pre class="CodeRay highlight"><code data-lang="java"><span class="directive">public</span> <span class="type">class</span> <span class="class">UserSettingsThemeProvider</span> <span class="directive">implements</span> ActiveThemeProvider {
+    ...
+    <span class="annotation">@Override</span>
+    <span class="directive">public</span> ITheme getActiveTheme() {
+        <span class="keyword">if</span>(IsisContext.getSpecificationLoader().isInitialized()) {
+            <span class="directive">final</span> <span class="predefined-type">String</span> themeName = IsisContext.doInSession(<span class="keyword">new</span> <span class="predefined-type">Callable</span>&lt;<span class="predefined-type">String</span>&gt;() {
+                <span class="annotation">@Override</span>
+                <span class="directive">public</span> <span class="predefined-type">String</span> call() <span class="directive">throws</span> <span class="exception">Exception</span> {
+                    <span class="directive">final</span> UserSettingsService userSettingsService =
+                        lookupService(UserSettingsService.class);
+                    <span class="directive">final</span> UserSetting activeTheme = userSettingsService.find(
+                            IsisContext.getAuthenticationSession().getUserName(),
+                            ACTIVE_THEME);
+                    <span class="keyword">return</span> activeTheme != <span class="predefined-constant">null</span> ? activeTheme.valueAsString() : <span class="predefined-constant">null</span>;
+                }
+            });
+            <span class="keyword">return</span> themeFor(themeName);
+        }
+        <span class="keyword">return</span> <span class="keyword">new</span> SessionThemeProvider().getActiveTheme();
+    }
+    <span class="annotation">@Override</span>
+    <span class="directive">public</span> <span class="type">void</span> setActiveTheme(<span class="directive">final</span> <span class="predefined-type">String</span> themeName) {
+        IsisContext.doInSession(<span class="keyword">new</span> <span class="predefined-type">Runnable</span>() {
+            <span class="annotation">@Override</span>
+            <span class="directive">public</span> <span class="type">void</span> run() {
+                <span class="directive">final</span> <span class="predefined-type">String</span> currentUsrName =
+                    IsisContext.getAuthenticationSession().getUserName();
+                <span class="directive">final</span> UserSettingsServiceRW userSettingsService =
+                        lookupService(UserSettingsServiceRW.class);
+                <span class="directive">final</span> UserSettingJdo activeTheme =
+                        (UserSettingJdo) userSettingsService.find(
+                                                currentUsrName, ACTIVE_THEME);
+                <span class="keyword">if</span>(activeTheme != <span class="predefined-constant">null</span>) {
+                    activeTheme.updateAsString(themeName);
+                } <span class="keyword">else</span> {
+                    userSettingsService.newString(
+                        currentUsrName, ACTIVE_THEME, <span class="string"><span class="delimiter">"</span><span class="content">Active Bootstrap theme for user</span><span class="delimiter">"</span></span>, themeName);
+                }
+            }
+        });
+    }
+    <span class="directive">private</span> ITheme themeFor(<span class="directive">final</span> <span class="predefined-type">String</span> themeName) {
+        <span class="directive">final</span> ThemeProvider themeProvider = settings.getThemeProvider();
+        <span class="keyword">if</span>(themeName != <span class="predefined-constant">null</span>) {
+            <span class="keyword">for</span> (<span class="directive">final</span> ITheme theme : themeProvider.available()) {
+                <span class="keyword">if</span> (themeName.equals(theme.name()))
+                    <span class="keyword">return</span> theme;
+            }
+        }
+        <span class="keyword">return</span> themeProvider.defaultTheme();
+    }
+    ...
+}</code></pre> 
+          </div> 
+         </div> 
+         <div class="paragraph"> 
+          <p>and</p> 
+         </div> 
+         <div class="listingblock"> 
+          <div class="title">
+           Using the ActiveThemeProvider
+          </div> 
+          <div class="content"> 
+           <pre class="CodeRay highlight"><code data-lang="java"><span class="annotation">@Override</span>
+<span class="directive">protected</span> <span class="type">void</span> init() {
+    <span class="local-variable">super</span>.init();
+
+    <span class="directive">final</span> IBootstrapSettings settings = Bootstrap.getSettings();
+    settings.setThemeProvider(<span class="keyword">new</span> BootswatchThemeProvider(BootswatchTheme.Flatly));
+
+    settings.setActiveThemeProvider(<span class="keyword">new</span> UserSettingsThemeProvider(settings));
+}</code></pre> 
+          </div> 
+         </div> 
+        </div> 
+        <div class="sect2"> 
+         <h3 id="_ugvw_hints-and-tips_i18n-label-in-wicket-viewer">2.2. How i18n the Wicket viewer?</h3> 
+         <div class="paragraph"> 
+          <p>From <a href="http://isis.markmail.org/thread/ctppmtcbsf4iskzi">this thread</a> on the Apache Isis users mailing list:</p> 
+         </div> 
+         <div class="ulist"> 
+          <ul> 
+           <li> <p><em>I am trying to internationalize the label descriptions of form actions, eg those in <code>ActionParametersFormPanel</code>. Referencing those via their message id inside a .po file didn’t work either. Can this be done?</em></p> </li> 
+          </ul> 
+         </div> 
+         <div class="paragraph"> 
+          <p>Yes, it <em>is</em> possible to internationalize both the Wicket viewer’s labels as well as the regular translations of the domain object metadata using the <code>.po</code> translation files as supported by the <a href="../rgsvc/rgsvc.html#_rgsvc_presentation-layer-spi_TranslationService"><code>TranslationService</code></a>.</p> 
+         </div> 
+         <div class="paragraph"> 
+          <p>Full details of the <code>msgId</code>s that must be added to the <code>translations.po</code> file can be found in <a href="../ugbtb/ugbtb.html#__ugbtb_i18n_wicket-viewer">i18n</a> section of the <a href="../ugbtb/ugbtb.html">beyond the basics</a> guide.</p> 
+         </div> 
+        </div> 
+        <div class="sect2"> 
+         <h3 id="_ugvw_hints-and-tips_highlight-current-row">2.3. Highlight Current Row</h3> 
+         <div class="paragraph"> 
+          <p>Demo App: Highlighting Current As a by-the-by, the demo app has one further "trick up its sleeve". If you run the app you’ll notice that the currently selected <code>DemoObject</code> is highlighted in the left-hand table of the <code>HomePageViewModel</code>.</p> 
+         </div> 
+         <div class="paragraph"> 
+          <p>This is accomplished by having the view model collaborate with a subscribing domain service that configures a CSS class.</p> 
+         </div> 
+         <div class="paragraph"> 
+          <p>We start by ensuring that the <code>DemoObject</code> emits an event for its CSS class:</p> 
+         </div> 
+         <div class="listingblock"> 
+          <div class="title">
+           DemoObject.java
+          </div> 
+          <div class="content"> 
+           <pre class="CodeRay highlight"><code data-lang="java"><span class="annotation">@DomainObjectLayout</span>(
+...
+cssClassUiEvent = DemoObject.CssClassUiEvent.class
+)
+<span class="directive">public</span> <span class="type">class</span> <span class="class">DemoObject</span> ... {
+
+<span class="directive">public</span> <span class="directive">static</span> <span class="type">class</span> <span class="class">CssClassUiEvent</span>
+<span class="directive">extends</span> org.apache.isis.applib.services.eventbus.CssClassUiEvent&lt;DemoObject&gt; {}
+...
+}</code></pre> 
+          </div> 
+         </div> 
+         <div class="paragraph"> 
+          <p>Next, we define the domain service to act as the subscriber:</p> 
+         </div> 
+         <div class="listingblock"> 
+          <div class="title">
+           HomePageViewModel.java
+          </div> 
+          <div class="content"> 
+           <pre class="CodeRay highlight"><code data-lang="java"><span class="directive">public</span> <span class="type">class</span> <span class="class">HomePageViewModel</span> ... {
+    <span class="annotation">@DomainService</span>(nature = NatureOfService.DOMAIN)
+    <span class="directive">public</span> <span class="directive">static</span> <span class="type">class</span> <span class="class">CssHighlighter</span> <span class="directive">extends</span> AbstractSubscriber {
+        <span class="annotation">@EventHandler</span>
+        <span class="annotation">@Subscribe</span>
+        <span class="directive">public</span> <span class="type">void</span> on(DemoObject.CssClassUiEvent ev) {
+            <span class="keyword">if</span>(getContext() == <span class="predefined-constant">null</span>) { <span class="keyword">return</span>; }
+            <span class="keyword">if</span>(ev.getSource() == getContext().getSelected()) {      <i class="conum" data-value="1"></i><b>(1)</b>
+                ev.setCssClass(<span class="string"><span class="delimiter">"</span><span class="content">selected</span><span class="delimiter">"</span></span>);
+            }
+        }
+        <span class="directive">private</span> HomePageViewModel getContext() {                    <i class="conum" data-value="2"></i><b>(2)</b>
+            <span class="keyword">return</span> (HomePageViewModel) scratchpad.get(<span class="string"><span class="delimiter">"</span><span class="content">context</span><span class="delimiter">"</span></span>);
+        }
+        <span class="type">void</span> setContext(<span class="directive">final</span> HomePageViewModel homePageViewModel) {
+            scratchpad.put(<span class="string"><span class="delimiter">"</span><span class="content">context</span><span class="delimiter">"</span></span>, homePageViewModel);
+        }
+        <span class="annotation">@Inject</span>
+        Scratchpad scratchpad;                                      <i class="conum" data-value="3"></i><b>(3)</b>
+    }
+}</code></pre> 
+          </div> 
+         </div> 
+         <div class="colist arabic"> 
+          <table> 
+           <tbody>
+            <tr> 
+             <td><i class="conum" data-value="1"></i><b>1</b></td> 
+             <td>If the domain object is the currently selected then set the CSS class</td> 
+            </tr> 
+            <tr> 
+             <td><i class="conum" data-value="2"></i><b>2</b></td> 
+             <td>Provide methods to set and get the current <code>HomePageViewModel</code> (acting as the context)</td> 
+            </tr> 
+            <tr> 
+             <td><i class="conum" data-value="3"></i><b>3</b></td> 
+             <td>Store the context using the <code>Scratchpad</code> domain service (request-scoped so thread-safe).</td> 
+            </tr> 
+           </tbody>
+          </table> 
+         </div> 
+         <div class="paragraph"> 
+          <p>The <code>HomePageViewModel</code> is responsible for setting itself as the context for the domain service:</p> 
+         </div> 
+         <div class="listingblock"> 
+          <div class="title">
+           HomePageViewModel.java
+          </div> 
+          <div class="content"> 
+           <pre class="CodeRay highlight"><code data-lang="java"><span class="directive">public</span> <span class="type">class</span> <span class="class">HomePageViewModel</span> ... {
+    ...
+    public TranslatableString title() {
+        cssHighlighter.setContext(<span class="local-variable">this</span>);        <i class="conum" data-value="1"></i><b>(1)</b>
+        ...
+    }
+    ...
+    <span class="annotation">@javax</span>.inject.Inject
+    CssHighlighter cssHighlighter;
+}</code></pre> 
+          </div> 
+         </div> 
+         <div class="colist arabic"> 
+          <table> 
+           <tbody>
+            <tr> 
+             <td><i class="conum" data-value="1"></i><b>1</b></td> 
+             <td>set the context on the domain service</td> 
+            </tr> 
+           </tbody>
+          </table> 
+         </div> 
+         <div class="paragraph"> 
+          <p>Finally we just need some CSS, in the <code>application.css</code> file:</p> 
+         </div> 
+         <div class="listingblock"> 
+          <div class="title">
+           application.css
+          </div> 
+          <div class="content"> 
+           <pre class="CodeRay highlight"><code data-lang="css"><span class="class">.selected</span> {
+    <span class="key">font-style</span>: <span class="value">italic</span>; <span class="key">font-weight</span>: <span class="value">bolder</span>;
+}</code></pre> 
+          </div> 
+         </div> 
+        </div> 
+        <div class="sect2"> 
+         <h3 id="_ugvw_hints-and-tips_svg-support">2.4. SVG Support</h3> 
+         <div class="paragraph"> 
+          <p>(As per <a href="https://issues.apache.org/jira/browse/ISIS-1604">ISIS-1604</a>), SVG images can be used:</p> 
+         </div> 
+         <div class="ulist"> 
+          <ul> 
+           <li> <p>as Logo in the upper left corner (Wicket Menubar)</p> </li> 
+           <li> <p>on the Login Page (<code>login.html</code>)</p> </li> 
+           <li> <p>as favicon (<code>image/svg+xml</code>, cf. <a href="https://issues.apache.org/jira/browse/ISIS-1115">ISIS-1115</a>)</p> </li> 
+          </ul> 
+         </div> 
+         <div class="paragraph"> 
+          <p>However, SVGs are not, by default, displayed on the welcome page. SVGs can be attached as <code>Blob</code>s, but they are displayed as bitmaps (by means of the Batik rasterizer) and do not scale. The rasterizer (of course) can not deal with animations (cf. attachment).</p> 
+         </div> 
+         <div class="paragraph"> 
+          <p>To fix this, you can add the following dependencies:</p> 
+         </div> 
+         <div class="listingblock"> 
+          <div class="content"> 
+           <pre class="CodeRay highlight"><code data-lang="xml"><span class="tag">&lt;dependency&gt;</span>
+    <span class="tag">&lt;groupId&gt;</span>com.twelvemonkeys.imageio<span class="tag">&lt;/groupId&gt;</span>
+    <span class="tag">&lt;artifactId&gt;</span>imageio-batik<span class="tag">&lt;/artifactId&gt;</span> <span class="comment">&lt;!-- svg --&gt;</span>
+    <span class="tag">&lt;version&gt;</span>3.3.2<span class="tag">&lt;/version&gt;</span>
+<span class="tag">&lt;/dependency&gt;</span>
+<span class="tag">&lt;dependency&gt;</span>
+    <span class="tag">&lt;groupId&gt;</span>com.twelvemonkeys.imageio<span class="tag">&lt;/groupId&gt;</span>
+    <span class="tag">&lt;artifactId&gt;</span>imageio-batik<span class="tag">&lt;/artifactId&gt;</span> <span class="comment">&lt;!-- svg --&gt;</span>
+    <span class="tag">&lt;version&gt;</span>3.3.2<span class="tag">&lt;/version&gt;</span>
+    <span class="tag">&lt;type&gt;</span>test-jar<span class="tag">&lt;/type&gt;</span>
+    <span class="tag">&lt;scope&gt;</span>test<span class="tag">&lt;/scope&gt;</span>
+<span class="tag">&lt;/dependency&gt;</span>
+<span class="tag">&lt;dependency&gt;</span>
+    <span class="tag">&lt;groupId&gt;</span>org.apache.xmlgraphics<span class="tag">&lt;/groupId&gt;</span>
+    <span class="tag">&lt;artifactId&gt;</span>batik-transcoder<span class="tag">&lt;/artifactId&gt;</span>
+    <span class="tag">&lt;version&gt;</span>1.8<span class="tag">&lt;/version&gt;</span>
+<span class="tag">&lt;/dependency&gt;</span></code></pre> 
+          </div> 
+         </div> 
+         <div class="paragraph"> 
+          <p>However, <strong>please note</strong> that these dependencies have high CVE values, and so may constitute a security risk.</p> 
+         </div> 
+         <div class="paragraph"> 
+          <p>Further discussion on <a href="https://lists.apache.org/thread.html/68f16dd0306a8101c1cde06e5e6309b8d1b81b388a1f59e123cfc2f3@%3Cusers.isis.apache.org%3E">this mailing list thread</a>.</p> 
+         </div> 
+        </div> 
+       </div> 
+      </div> 
+      <div class="sect1"> 
+       <h2 id="_restful_objects_viewer">3. Restful Objects Viewer</h2> 
+       <div class="sectionbody"> 
+        <div class="paragraph"> 
+         <p>Hints and tips for working with the REST API, for example when developing a custom application. Taken from the <a href="#ugvro/ugvro.adoc">Restful Objects viewer</a> guide.</p> 
+        </div> 
+        <div class="sect2"> 
+         <h3 id="_ugvro_hints-and-tips_using-chrome-devtools">3.1. Using Chrome Dev Tools</h3> 
+         <div class="paragraph"> 
+          <p>This <a href="https://www.youtube.com/watch?v=_-TOvVYWCHc">screencast</a> shows how to explore the Restful API using Chrome plugins/extensions, and how we use them to write end-2-end (TCK) tests for the Restful Objects viewer.</p> 
+         </div> 
+        </div> 
+        <div class="sect2"> 
+         <h3 id="_ugvro_hints-and-tips_angular-tips">3.2. Angular Tips</h3> 
+         <div class="paragraph"> 
+          <p>The hypermedia API exposed by Apache Isis' Restful Objects viewer is intended be support both bespoke custom-written viewers as well as generic viewers. Indeed, we expect most clients consuming the API will be bespoke, not generic.</p> 
+         </div> 
+         <div class="paragraph"> 
+          <p>This page captures one or two tips on using Angular to write such a bespoke client.</p> 
+         </div> 
+         <div class="sect3"> 
+          <h4 id="_invoking_a_get_link_eg_invoking_a_query_action">3.2.1. Invoking a GET link (eg invoking a query action)</h4> 
+          <div class="paragraph"> 
+           <p>Suppose you have a <code>CustomerService</code> providing a <code>findCustomer</code> action:</p> 
+          </div> 
+          <div class="listingblock"> 
+           <div class="content"> 
+            <pre class="CodeRay highlight"><code data-lang="java"><span class="directive">public</span> <span class="type">class</span> <span class="class">CustomerService</span> {
+    <span class="directive">public</span> <span class="predefined-type">String</span> id() { <span class="keyword">return</span> <span class="string"><span class="delimiter">"</span><span class="content">customers</span><span class="delimiter">"</span></span>; }
+    <span class="annotation">@Action</span>(semantics=SemanticsOf.SAFE)
+    <span class="directive">public</span> Customer findCustomer(
+            <span class="annotation">@ParameterLayout</span>(named=<span class="string"><span class="delimiter">"</span><span class="content">customerName</span><span class="delimiter">"</span></span>)
+            <span class="directive">final</span> <span class="predefined-type">String</span> customerName) {
+        ...
+    }
+}</code></pre> 
+           </div> 
+          </div> 
+          <div class="paragraph"> 
+           <p>Restful Objects will expose this as action with the following link that looks something like:</p> 
+          </div> 
+          <div class="listingblock"> 
+           <div class="content"> 
+            <pre class="CodeRay highlight"><code data-lang="javascript">{
+  <span class="key"><span class="delimiter">"</span><span class="content">rel</span><span class="delimiter">"</span></span> : <span class="string"><span class="delimiter">"</span><span class="content">urn:org.restfulobjects:rels/invoke</span><span class="delimiter">"</span></span>,
+  <span class="key"><span class="delimiter">"</span><span class="content">href</span><span class="delimiter">"</span></span> : <span class="string"><span class="delimiter">"</span><span class="content">http://localhost:8080/restful/services/customers/actions/findCustomer/invoke</span><span class="delimiter">"</span></span>,
+  <span class="key"><span class="delimiter">"</span><span class="content">method</span><span class="delimiter">"</span></span> : <span class="string"><span class="delimiter">"</span><span class="content">GET</span><span class="delimiter">"</span></span>,
+  <span class="key"><span class="delimiter">"</span><span class="content">type</span><span class="delimiter">"</span></span> : <span class="string"><span class="delimiter">"</span><span class="content">application/json;profile=</span><span class="char">\"</span><span class="content">urn:org.restfulobjects:repr-types/action-result</span><span class="char">\"</span><span class="delimiter">"</span></span>,
+  <span class="key"><span class="delimiter">"</span><span class="content">arguments</span><span class="delimiter">"</span></span> : {
+    <span class="key"><span class="delimiter">"</span><span class="content">customerName</span><span class="delimiter">"</span></span> : {
+      <span class="key"><span class="delimiter">"</span><span class="content">value</span><span class="delimiter">"</span></span> : <span class="predefined-constant">null</span>
+    }
+  }
+}</code></pre> 
+           </div> 
+          </div> 
+          <div class="paragraph"> 
+           <p>You can then invoke this using Angular' <code>$resource</code> service as follows.</p> 
+          </div> 
+          <div class="listingblock"> 
+           <div class="content"> 
+            <pre class="CodeRay highlight"><code data-lang="javascript"><span class="keyword">var</span> findCustomer = <span class="predefined">$resource</span>(<span class="string"><span class="delimiter">"</span><span class="content">http://localhost:8080/restful/services/customers/actions/findCustomer/invoke?:queryString</span><span class="delimiter">"</span></span>);
+<span class="keyword">var</span> findCustomerArgs = {
+  <span class="key"><span class="delimiter">"</span><span class="content">customerName</span><span class="delimiter">"</span></span>: {
+      <span class="key"><span class="delimiter">"</span><span class="content">value</span><span class="delimiter">"</span></span>: <span class="string"><span class="delimiter">"</span><span class="content">Fred</span><span class="delimiter">"</span></span>
+    }
+};
+findCustomer.get({<span class="key">queryString</span>: JSON.stringify(findCustomerArgs)}, <span class="keyword">function</span>(data) { ... } )</code></pre> 
+           </div> 
+          </div> 
+          <div class="paragraph"> 
+           <p>Here the <code>:queryString</code> placeholder in the initial <code>$resource</code> constructor is expanded with a stringified version of the JSON object representing the args. Note how the <code>findCustomerArgs</code> is the same as the <code>"arguments"</code> attribute in the original link (with a value provided instead of <code>null</code>).</p> 
+          </div> 
+         </div> 
+         <div class="sect3"> 
+          <h4 id="_invoking_a_put_or_post_link">3.2.2. Invoking a PUT or POST link</h4> 
+          <div class="paragraph"> 
+           <p>If the method is a PUT or a POST, then no <code>:queryString</code> placeholder is required in the URL, and the args are instead part of the body.</p> 
+          </div> 
+          <div class="paragraph"> 
+           <p>Use <code>$resource.put(…​)</code> or <code>$resource.post(…​)</code> instead.</p> 
+          </div> 
+         </div> 
+        </div> 
+        <div class="sect2"> 
+         <h3 id="_ugvro_hints-and-tips_pretty-printing">3.3. Pretty printing</h3> 
+         <div class="paragraph"> 
+          <p>The JSON representations generated by the Restful Objects viewer are in compact form if the <a href="../rgcfg/rgcfg.html#_rgcfg_deployment-types">deployment type</a> is SERVER (ie production), but will automatically be "pretty printed" (in other words indented) if the deployment type is PROTOTYPE.</p> 
+         </div> 
+        </div> 
+        <div class="sect2"> 
+         <h3 id="_ugvro_hints-and-tips_restful-image-property">3.4. How parse images in RO viewer?</h3> 
+         <div class="paragraph"> 
+          <p>From this <a href="http://markmail.org/message/4kcu7sml4ufdsah3">thread</a> on the Apache Isis users mailing list:</p> 
+         </div> 
+         <div class="ulist"> 
+          <ul> 
+           <li> <p><em>I am trying to display an image in a JavaScript client app, the image comes from an Isis RO web service as a string, but it won’t show. Is there something I should do to change the message?</em></p> </li> 
+          </ul> 
+         </div> 
+         <div class="paragraph"> 
+          <p>The RO viewer returns the image as a string, in the form:</p> 
+         </div> 
+         <div class="literalblock"> 
+          <div class="content"> 
+           <pre>"Tacos.jpg:image/jpeg:/9j//4AAQSkZJRgABAQEAlgCWAAD/  ...."</pre> 
+          </div> 
+         </div> 
+         <div class="paragraph"> 
+          <p>This is in the form:</p> 
+         </div> 
+         <div class="literalblock"> 
+          <div class="content"> 
+           <pre>(filename):(mime type):(binary data in base64)</pre> 
+          </div> 
+         </div> 
+         <div class="paragraph"> 
+          <p>This is basically the <a href="../rgcms/rgcms.html#_rgcms_classes_value-types_Blob"><code>Blob</code></a> value type, in string form.</p> 
+         </div> 
+         <div class="paragraph"> 
+          <p>To use, split the parts then format the mime type and base64 data correctly before using as source in an <code>&lt;img&gt;</code> tag.</p> 
+         </div> 
+        </div> 
+        <div class="sect2"> 
+         <h3 id="_ugvro_hints-and-tips_view-model-as-parameter">3.5. View Model as Parameter</h3> 
+         <div class="paragraph"> 
+          <p>As discussed <a href="https://lists.apache.org/thread.html/cbd18320bbf6e5c5e767283f9e675cf56e7f4692c109e1e79dbaa90a@%3Cusers.isis.apache.org%3E">on the mailing list</a>.</p> 
+         </div> 
+         <div class="sect3"> 
+          <h4 id="_query">3.5.1. Query</h4> 
+          <div class="paragraph"> 
+           <p>I must provide a REST service accepting more complex view model as input parameter.</p> 
+          </div> 
+          <div class="paragraph"> 
+           <p>My view model parameter would look like</p> 
+          </div> 
+          <div class="listingblock"> 
+           <div class="content"> 
+            <pre class="CodeRay highlight"><code data-lang="java"><span class="annotation">@DomainObject</span>(
+    nature = Nature.VIEW_MODEL,
+    objectType = <span class="string"><span class="delimiter">"</span><span class="content">OfferTemplateFilter</span><span class="delimiter">"</span></span>
+)
+<span class="annotation">@XmlRootElement</span>(name = <span class="string"><span class="delimit

<TRUNCATED>