blob: fd076b104ee93098139719668cf0803f4e0d47f4 [file] [log] [blame]
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width,initial-scale=1">
<title>Features/end-user usage :: Apache Isis</title>
<link rel="canonical" href="https://isis.apache.org/vw/2.0.0-M3/features.html">
<meta name="generator" content="Antora 2.2.0">
<link rel="stylesheet" href="../../_/css/site.css">
<link rel="stylesheet" href="../../_/css/site-custom.css">
<link href="https://fonts.googleapis.com/css?family=Open+Sans:300,300i,400,400i,700,700i|Raleway:300,400,500,700,800|Montserrat:300,400,700" rel="stylesheet">
<link rel="home" href="https://isis.apache.org" title="Apache Isis">
<link rel="next" href="security.html" title="Security">
<link rel="prev" href="configuration-properties.html" title="Configuration Properties">
</head>
<body class="article">
<header class="header">
<nav class="navbar">
<div class="navbar-brand">
<a class="navbar-item" href="https://isis.apache.org">
<span class="icon">
<img src="../../_/img/isis-logo-48x48.png"></img>
</span>
<span>Apache Isis</span>
</a>
<button class="navbar-burger" data-target="topbar-nav">
<span></span>
<span></span>
<span></span>
</button>
</div>
<div id="topbar-nav" class="navbar-menu">
<a class="navbar-end">
<div class="navbar-item has-dropdown is-hoverable">
<a class="navbar-link" href="#">Quick Start</a>
<div class="navbar-dropdown">
<span class="navbar-item navbar-heading">Starter Apps</span>
<a class="navbar-item" href="../../docs/latest/starters/helloworld.html">Hello World</a>
<a class="navbar-item" href="../../docs/latest/starters/simpleapp.html">Simple App</a>
<hr class="navbar-divider"/>
<span class="navbar-item navbar-heading">Demos &amp; Tutorials</span>
<a class="navbar-item" href="../../docs/latest/demo/about.html">Demo App</a>
<a class="navbar-item" href="https://danhaywood.gitlab.io/isis-petclinic-tutorial-docs/petclinic/1.16.2/intro.html">Petclinic (tutorial)</a>
<hr class="navbar-divider"/>
<span class="navbar-item navbar-heading">Resources</span>
<a class="navbar-item" href="../../docs/latest/resources/cheatsheet.html">Cheatsheet</a>
<a class="navbar-item" href="../../docs/latest/resources/icons.html">Icons</a>
</div>
</div>
<div class="navbar-item has-dropdown is-hoverable">
<a class="navbar-link" href="#">Guides</a>
<div class="navbar-dropdown">
<span class="navbar-item navbar-heading">Development</span>
<a class="navbar-item" href="../../setupguide/latest/about.html">Setup Guide</a>
<hr class="navbar-divider"/>
<span class="navbar-item navbar-heading">Core</span>
<a class="navbar-item" href="../../userguide/latest/about.html">User Guide</a>
<a class="navbar-item" href="../../refguide/latest/about.html">Reference Guide</a>
<a class="navbar-item" href="../../testing/latest/about.html">Testing Guide</a>
</div>
</div>
<div class="navbar-item has-dropdown is-hoverable">
<a class="navbar-link" href="#">Libraries</a>
<div class="navbar-dropdown">
<span class="navbar-item navbar-heading">For Use in Apps</span>
<a class="navbar-item" href="../../subdomains/latest/about.html">Subdomain Libraries</a>
<a class="navbar-item" href="../../valuetypes/latest/about.html">Value Types</a>
<hr class="navbar-divider"/>
<span class="navbar-item navbar-heading">Integrate between Apps</span>
<a class="navbar-item" href="../../mappings/latest/about.html">Bounded Context Mapping Libraries</a>
<hr class="navbar-divider"/>
<span class="navbar-item navbar-heading">Other</span>
<a class="navbar-item" href="../../incubator/latest/about.html">Incubator</a>
<a class="navbar-item" href="../../legacy/latest/about.html">Legacy</a>
</div>
</div>
<div class="navbar-item has-dropdown is-hoverable">
<a class="navbar-link" href="#">Components</a>
<div class="navbar-dropdown">
<span class="navbar-item navbar-heading">Viewers</span>
<a class="navbar-item" href="../../vw/latest/about.html">Wicket UI</a>
<a class="navbar-item" href="../../vro/latest/about.html">Restful Objects (REST)</a>
<hr class="navbar-divider"/>
<span class="navbar-item navbar-heading">Security</span>
<a class="navbar-item" href="../../security/latest/about.html">Security Guide</a>
<hr class="navbar-divider"/>
<span class="navbar-item navbar-heading">Persistence</span>
<a class="navbar-item" href="../../pjdo/latest/about.html">DataNucleus (JDO)</a>
<hr class="navbar-divider"/>
<span class="navbar-item navbar-heading">Extensions</span>
<a class="navbar-item" href="../../extensions/latest/about.html">Extensions Catalog</a>
</div>
</div>
<div class="navbar-item has-dropdown is-hoverable">
<a class="navbar-link" href="#">Support</a>
<div class="navbar-dropdown">
<span class="navbar-item navbar-heading">Contact</span>
<a class="navbar-item" href="../../docs/latest/support/slack-channel.html">Slack</a>
<a class="navbar-item" href="../../docs/latest/support/mailing-list.html">Mailing Lists</a>
<a class="navbar-item" href="https://issues.apache.org/jira/browse/ISIS">JIRA</a>
<a class="navbar-item" href="https://stackoverflow.com/questions/tagged/isis">Stack Overflow</a>
<hr class="navbar-divider"/>
<span class="navbar-item navbar-heading">Releases</span>
<a class="navbar-item" href="../../docs/latest/downloads/how-to.html">Downloads</a>
<a class="navbar-item" href="../../relnotes/latest/about.html">Release Notes</a>
<a class="navbar-item" href="../../docs/latest/archive/1-x.html">Archive (1.x)</a>
<hr class="navbar-divider"/>
<span class="navbar-item navbar-heading">Framework</span>
<a class="navbar-item" href="../../conguide/latest/about.html">Contributors' Guide</a>
<a class="navbar-item" href="../../comguide/latest/about.html">Committers' Guide</a>
<a class="navbar-item" href="../../core/latest/about.html">Core Design</a>
</div>
</div>
<div class="navbar-item has-dropdown is-hoverable">
<a class="navbar-link" href="#">ASF</a>
<div class="navbar-dropdown">
<a class="navbar-item" href="http://www.apache.org/">Apache Homepage</a>
<a class="navbar-item" href="https://www.apache.org/events/current-event">Events</a>
<a class="navbar-item" href="https://www.apache.org/licenses/">Licenses</a>
<a class="navbar-item" href="https://www.apache.org/security/">Security</a>
<a class="navbar-item" href="https://www.apache.org/foundation/sponsorship.html">Sponsorship</a>
<a class="navbar-item" href="https://www.apache.org/foundation/thanks.html">Thanks</a>
<hr class="navbar-divider"/>
<a class="navbar-item" href="https://whimsy.apache.org/board/minutes/Isis.html">PMC board minutes</a>
</div>
</div>
<a class="navbar-item" href="../../docs/latest/about.html">
<span class="icon">
<img src="../../_/img/home.png"></img>
</span>
</a>
</div>
</div>
</nav>
</header>
<div class="body ">
<div class="nav-container" data-component="vw" data-version="2.0.0-M3">
<aside class="nav">
<div class="panels">
<div class="nav-panel-pagination">
<a class="page-previous" rel="prev" href="configuration-properties.html" title="Configuration Properties"><span></span></a>
<a class="page-next" rel="next"
href="security.html" title="Security"><span></span></a>
<!--
page.parent doesn't seem to be set...
<a class="page-parent disabled" rel="prev" href="" title="Configuration Properties"><span></span></a>
-->
</div>
<div class="nav-panel-menu is-active" data-panel="menu">
<nav class="nav-menu">
<h3 class="title"><a href="about.html">Wicket Viewer</a></h3>
<ul class="nav-list">
<li class="nav-item" data-depth="0">
<ul class="nav-list">
<li class="nav-item" data-depth="1">
<a class="nav-link" href="configuration-properties.html">Configuration Properties</a>
</li>
<li class="nav-item is-current-page" data-depth="1">
<a class="nav-link" href="features.html">End-user Features</a>
</li>
<li class="nav-item" data-depth="1">
<a class="nav-link" href="security.html">Security</a>
</li>
<li class="nav-item" data-depth="1">
<a class="nav-link" href="customisation.html">Customisation</a>
</li>
<li class="nav-item" data-depth="1">
<a class="nav-link" href="extending.html">Extending</a>
</li>
<li class="nav-item" data-depth="1">
<a class="nav-link" href="hints-and-tips.html">Hints-n-Tips</a>
</li>
<li class="nav-item" data-depth="1">
<button class="nav-item-toggle"></button>
<span class="nav-text">Extensions</span>
<ul class="nav-list">
<li class="nav-item" data-depth="2">
<a class="nav-link" href="exceldownload/about.html">Excel Download</a>
</li>
<li class="nav-item" data-depth="2">
<a class="nav-link" href="fullcalendar/about.html">fullcalendar</a>
</li>
<li class="nav-item" data-depth="2">
<a class="nav-link" href="gmap3/about.html">GMap3</a>
</li>
<li class="nav-item" data-depth="2">
<a class="nav-link" href="pdfjs/about.html">pdf.js</a>
</li>
</ul>
</li>
</ul>
</li>
</ul>
</nav>
</div>
<div class="nav-panel-explore" data-panel="explore">
<div class="context">
<span class="title">Wicket Viewer</span>
<span class="version">2.0.0-M3</span>
</div>
<ul class="components">
<li class="component">
<span class="title"> </span>
<ul class="versions">
<li class="version is-latest">
<a href="../../docs/2.0.0-M3/about.html">2.0.0-M3</a>
</li>
</ul>
</li>
<li class="component">
<span class="title">BC Mappings Catalog</span>
<ul class="versions">
<li class="version is-latest">
<a href="../../mappings/2.0.0-M3/about.html">2.0.0-M3</a>
</li>
</ul>
</li>
<li class="component">
<span class="title">Committers' Guide</span>
<ul class="versions">
<li class="version is-latest">
<a href="../../comguide/2.0.0-M3/about.html">2.0.0-M3</a>
</li>
</ul>
</li>
<li class="component">
<span class="title">Contributors' Guide</span>
<ul class="versions">
<li class="version is-latest">
<a href="../../conguide/2.0.0-M3/about.html">2.0.0-M3</a>
</li>
</ul>
</li>
<li class="component">
<span class="title">Core Framework</span>
<ul class="versions">
<li class="version is-latest">
<a href="../../core/2.0.0-M3/about.html">2.0.0-M3</a>
</li>
</ul>
</li>
<li class="component">
<span class="title">Extensions Catalog</span>
<ul class="versions">
<li class="version is-latest">
<a href="../../extensions/2.0.0-M3/about.html">2.0.0-M3</a>
</li>
</ul>
</li>
<li class="component">
<span class="title">Incubator Catalog</span>
<ul class="versions">
<li class="version is-latest">
<a href="../../incubator/2.0.0-M3/about.html">2.0.0-M3</a>
</li>
</ul>
</li>
<li class="component">
<span class="title">JDO/DataNucleus</span>
<ul class="versions">
<li class="version is-latest">
<a href="../../pjdo/2.0.0-M3/about.html">2.0.0-M3</a>
</li>
</ul>
</li>
<li class="component">
<span class="title">Legacy Catalog</span>
<ul class="versions">
<li class="version is-latest">
<a href="../../legacy/2.0.0-M3/about.html">2.0.0-M3</a>
</li>
</ul>
</li>
<li class="component">
<span class="title">Reference Guide</span>
<ul class="versions">
<li class="version is-latest">
<a href="../../refguide/2.0.0-M3/about.html">2.0.0-M3</a>
</li>
</ul>
</li>
<li class="component">
<span class="title">Release Notes</span>
<ul class="versions">
<li class="version is-latest">
<a href="../../relnotes/2.0.0-M3/about.html">2.0.0-M3</a>
</li>
</ul>
</li>
<li class="component">
<span class="title">Restful Objects Viewer</span>
<ul class="versions">
<li class="version is-latest">
<a href="../../vro/2.0.0-M3/about.html">2.0.0-M3</a>
</li>
</ul>
</li>
<li class="component">
<span class="title">Security Guide</span>
<ul class="versions">
<li class="version is-latest">
<a href="../../security/2.0.0-M3/about.html">2.0.0-M3</a>
</li>
</ul>
</li>
<li class="component">
<span class="title">Setup Guide</span>
<ul class="versions">
<li class="version is-latest">
<a href="../../setupguide/2.0.0-M3/about.html">2.0.0-M3</a>
</li>
</ul>
</li>
<li class="component">
<span class="title">Subdomains Catalog</span>
<ul class="versions">
<li class="version is-latest">
<a href="../../subdomains/2.0.0-M3/about.html">2.0.0-M3</a>
</li>
</ul>
</li>
<li class="component">
<span class="title">Testing Guide</span>
<ul class="versions">
<li class="version is-latest">
<a href="../../testing/2.0.0-M3/about.html">2.0.0-M3</a>
</li>
</ul>
</li>
<li class="component">
<span class="title">User Guide</span>
<ul class="versions">
<li class="version is-latest">
<a href="../../userguide/2.0.0-M3/about.html">2.0.0-M3</a>
</li>
</ul>
</li>
<li class="component">
<span class="title">Value Types Catalog</span>
<ul class="versions">
<li class="version is-latest">
<a href="../../valuetypes/2.0.0-M3/about.html">2.0.0-M3</a>
</li>
</ul>
</li>
<li class="component is-current">
<span class="title">Wicket Viewer</span>
<ul class="versions">
<li class="version is-current is-latest">
<a href="about.html">2.0.0-M3</a>
</li>
</ul>
</li>
</ul>
</div>
</div>
</aside>
</div>
<main role="main">
<div class="toolbar" role="navigation">
<button class="nav-toggle"></button>
<a href="../../docs/2.0.0-M3/about.html" class="home-link"></a>
<nav class="breadcrumbs" aria-label="breadcrumbs">
<ul>
<li><a href="about.html">Wicket Viewer</a></li>
<li><a href="features.html">End-user Features</a></li>
</ul>
</nav>
<div class="edit-this-page"><a href="https://github.com/apache/isis/edit/2.0.0-M3/viewers/wicket/adoc/modules/ROOT/pages/features.adoc">Edit</a></div>
</div>
<article class="doc">
<a name="section-top"></a>
<h1 class="page">Features/end-user usage</h1>
<div id="preamble">
<div class="sectionbody">
<div class="admonitionblock warning">
<table>
<tr>
<td class="icon">
<i class="fa icon-warning" title="Warning"></i>
</td>
<td class="content">
TODO: this content has not yet been reviewed/updated for v2.0
</td>
</tr>
</table>
</div>
<div class="paragraph">
<p>This chapter highlights a number of features of the wicket viewer from the perspective of an end-user actually using your Apache Isis application.</p>
</div>
</div>
</div>
<div class="sect1">
<h2 id="sidebar-vs-modal-dialogs"><a class="anchor" href="#sidebar-vs-modal-dialogs"></a>Sidebar vs Modal Dialogs</h2>
<div class="sectionbody">
<div class="paragraph">
<p>The Wicket viewer supports two different styles of dialog prompts for actions that have parameters:</p>
</div>
<div class="ulist">
<ul>
<li>
<p>the first is a (movable) modal dialog.</p>
<div class="paragraph">
<p>This was the only style available for 1.16.x and earlier versions.</p>
</div>
</li>
<li>
<p>the second is as sidebar</p>
<div class="paragraph">
<p>This is available (and the default) for 1.17+.</p>
</div>
</li>
</ul>
</div>
<div class="paragraph">
<p>The benefit of the sidebar dialog mode compared to the modal dialog is that it doesn&#8217;t obscure the rest of the information shown on the page; it also doesn&#8217;t interrupt the end-user&#8217;s context so much (they are more likely to remember why they invoked the action).
For these reasons the sidebar mode is now the default.</p>
</div>
<div class="paragraph">
<p>For example, here&#8217;s what invoking an action (to create a new object) looks like using the original modal dialog:</p>
</div>
<div class="imageblock">
<div class="content">
<a class="image" href="_images/dialog-mode/modal.png"><img src="_images/dialog-mode/modal.png" alt="modal" width="800px"></a>
</div>
</div>
<div class="paragraph">
<p>And here&#8217;s what it looks like with the sidebar dialog:</p>
</div>
<div class="imageblock">
<div class="content">
<a class="image" href="_images/dialog-mode/sidebar.png"><img src="_images/dialog-mode/sidebar.png" alt="sidebar" width="800px"></a>
</div>
</div>
<div class="paragraph">
<p>However, the original modal dialog can still be be used if end-users prefer that style, by setting the <code>isis.viewer.wicket.dialog</code> <a href="configuration-properties.html#presentation" class="page">configuration property</a>.</p>
</div>
</div>
</div>
<div class="sect1">
<h2 id="recent-pages"><a class="anchor" href="#recent-pages"></a>Recent pages (drop down)</h2>
<div class="sectionbody">
<div class="paragraph">
<p>The Wicket viewer provides a recent pages drop-down that acts as a breadcrumb trail.
Using it, the user can quickly open a recently accessed domain object.</p>
</div>
<div class="sect2">
<h3 id="screenshots"><a class="anchor" href="#screenshots"></a>Screenshots</h3>
<div class="paragraph">
<p>The following screenshot, taken from the <a href="https://github.com/estatio/estatio">Estatio</a> application, shows the recent pages drop-down after a number of pages have been accessed.</p>
</div>
<div class="imageblock">
<div class="content">
<a class="image" href="_images/features/recent-pages/recent-pages.png"><img src="_images/features/recent-pages/recent-pages.png" alt="recent pages" width="800px"></a>
</div>
</div>
<div class="paragraph">
<p>This screenshot is based on v1.7.x of the <a href="about.html" class="page">Wicket viewer</a> UI.</p>
</div>
</div>
<div class="sect2">
<h3 id="domain-code"><a class="anchor" href="#domain-code"></a>Domain Code</h3>
<div class="paragraph">
<p>The recent pages drop-down is automatically populated; no changes need to be made to the domain classes.</p>
</div>
</div>
<div class="sect2">
<h3 id="user-experience"><a class="anchor" href="#user-experience"></a>User Experience</h3>
<div class="paragraph">
<p>Selecting the domain object from the list causes the viewer to automatically navigate to the page for the selected object.</p>
</div>
</div>
<div class="sect2">
<h3 id="related-functionality"><a class="anchor" href="#related-functionality"></a>Related functionality</h3>
<div class="paragraph">
<p>The <a href="#bookmarked-pages">bookmarked pages</a> (sliding panel) also provides links to recently visited objects, but only those explicitly marked as <code>@DomainObject(bookmarking=&#8230;&#8203;)</code>. The bookmarks panel also nests related objects together hierarchically (the recent pages drop-down does not).</p>
</div>
</div>
<div class="sect2">
<h3 id="configuration"><a class="anchor" href="#configuration"></a>Configuration</h3>
<div class="paragraph">
<p>The number of objects is hard-coded as 10; it cannot currently be configured.</p>
</div>
</div>
</div>
</div>
<div class="sect1">
<h2 id="bookmarked-pages"><a class="anchor" href="#bookmarked-pages"></a>Bookmarked pages</h2>
<div class="sectionbody">
<div class="paragraph">
<p>The Wicket viewer supports the bookmarking of both domain objects and query-only (<a href="../../refguide/2.0.0-M3/applib-ant/Action.html#semantics" class="page">@Action(semantics=&#8230;&#8203;)</a>) actions.</p>
</div>
<div class="paragraph">
<p>Domain objects, if bookmarkable, can be nested.</p>
</div>
<div class="paragraph">
<p>Bookmarking is automatic; whenever a bookmarkable object/action is visited, then a bookmark is created.
To avoid the number of bookmarks from indefinitely growing, bookmarks that have not been followed after a whle are automatically removed (an MRU/LRU algorithm).
The number of bookmarks to preserve can be configured.</p>
</div>
<div class="sect2">
<h3 id="screenshots-2"><a class="anchor" href="#screenshots-2"></a>Screenshots</h3>
<div class="paragraph">
<p>The following screenshot (nb: using a pre 1.8.0 version of the <a href="about.html" class="page">Wicket viewer</a> UI), taken from <a href="https://github.com/apache/isis-app-todoapp">Isisaddons example todoapp</a> (not ASF), shows how the bookmarks are listed in a sliding panel.</p>
</div>
<div class="imageblock">
<div class="content">
<a class="image" href="_images/bookmarked-pages/panel.png"><img src="_images/bookmarked-pages/panel.png" alt="panel" width="800px"></a>
</div>
</div>
<div class="paragraph">
<p>Note how the list contains both domain objects and an action ("not yet complete").</p>
</div>
<div class="paragraph">
<p>Bookmarks can also form a hierarchy.
The following screenshot, also taken from the <a href="https://github.com/estatio/estatio">Estatio</a> application, shows a variety of different bookmarked objects with a nested structure:</p>
</div>
<div class="imageblock">
<div class="content">
<a class="image" href="_images/bookmarked-pages/panel-estatio.png"><img src="_images/bookmarked-pages/panel-estatio.png" alt="panel estatio" width="800px"></a>
</div>
</div>
<div class="paragraph">
<p>Some - like <code>Property</code>, <code>Lease</code> and <code>Party</code> - are root nodes.
However, <code>LeaseItem</code> is bookmarkable as a child of <code>Lease</code>, and <code>LeaseTerm</code> is bookmarkable only as a child of <code>LeaseItem</code>.
This parent/child relationship is reflected in the layout.</p>
</div>
</div>
<div class="sect2">
<h3 id="domain-code-2"><a class="anchor" href="#domain-code-2"></a>Domain Code</h3>
<div class="paragraph">
<p>To indicate a class is bookmarkable, use the <a href="../../refguide/2.0.0-M3/applib-ant/DomainObjectLayout.html" class="page">@DomainObjectLayout</a> annotation:</p>
</div>
<div class="listingblock">
<div class="content">
<pre class="highlightjs highlight"><code class="language-java hljs" data-lang="java">@DomainObjectLayout(
bookmarking=BookmarkPolicy.AS_ROOT
)
public class Lease { /* ... */ }</code></pre>
</div>
</div>
<div class="paragraph">
<p>To indicate a class is bookmarkable but only as a child of some parent bookmark, specify the bookmark policy:</p>
</div>
<div class="listingblock">
<div class="content">
<pre class="highlightjs highlight"><code class="language-java hljs" data-lang="java">@DomainObjectLayout(
bookmarking=BookmarkPolicy.AS_CHILD
)
public class LeaseItem { /* ... */ }</code></pre>
</div>
</div>
<div class="paragraph">
<p>To indicate that a safe (query only) action is bookmarkable, use the <a href="../../refguide/2.0.0-M3/applib-ant/ActionLayout.html" class="page">@ActionLayout</a> annotation:</p>
</div>
<div class="listingblock">
<div class="content">
<pre class="highlightjs highlight"><code class="language-java hljs" data-lang="java">public class ToDoItem ... {
@Action(
semantics=SemanticsOf.SAFE
)
@ActionLayout(
bookmarking=BookmarkPolicy.AS_ROOT
)
public List&lt;ToDoItem&gt; notYetComplete() { /* ... */ }
...
}</code></pre>
</div>
</div>
<div class="admonitionblock note">
<table>
<tr>
<td class="icon">
<i class="fa icon-note" title="Note"></i>
</td>
<td class="content">
<div class="paragraph">
<p>The BookmarkPolicy.AS_CHILD does not have a meaning for actions; if the <code>bookmarking</code> attribute is set to any other value, it will be ignored.</p>
</div>
</td>
</tr>
</table>
</div>
</div>
<div class="sect2">
<h3 id="user-experience-2"><a class="anchor" href="#user-experience-2"></a>User Experience</h3>
<div class="paragraph">
<p>The sliding panel appears whenever the mouse pointer hovers over the thin blue tab (to the left of the top header region).</p>
</div>
<div class="paragraph">
<p>Alternatively, <code>alt+[</code> will toggle open/close the panel; it can also be closed using <code>Esc</code> key.</p>
</div>
<div class="sect3">
<h4 id="related-functionality-2"><a class="anchor" href="#related-functionality-2"></a>Related functionality</h4>
<div class="paragraph">
<p>The <a href="#recent-pages">Recent Pages</a> also lists recently visited pages, selected from a drop-down.</p>
</div>
</div>
</div>
<div class="sect2">
<h3 id="configuration-2"><a class="anchor" href="#configuration-2"></a>Configuration</h3>
<div class="paragraph">
<p>By default, the bookmarked pages panel will show a maximum of 15 'root' pages.
This can be overridden using the <a href="../../refguide/2.0.0-M3/config/sections/isis.viewer.wicket.html#isis.viewer.wicket.bookmarked-pages.max-size" class="page"><code>isis.viewer.wicket.bookmarked-pages.max-size</code></a> configuration property, for example:</p>
</div>
<div class="listingblock">
<div class="content">
<pre class="highlightjs highlight"><code class="language-ini hljs" data-lang="ini">isis.viewer.wicket.bookmarked-pages.max-size=20</code></pre>
</div>
</div>
</div>
</div>
</div>
<div class="sect1">
<h2 id="hints-and-copy-url"><a class="anchor" href="#hints-and-copy-url"></a>Hints and copy URL</h2>
<div class="sectionbody">
<div class="paragraph">
<p>While the user can often copy the URL of a domain object directly from the browser&#8217;s address bar, the Wicket viewer also allows the URL of domain objects to be easily copied from a dialog.</p>
</div>
<div class="paragraph">
<p>More interestingly, this URL can also contain hints capturing any sorting or page numbering, or hiding/viewing of collections. End-users can therefore share these URLs as a form of deep linking into a particular view on a domain object.</p>
</div>
<div class="paragraph">
<p>The copy URL and hinting is automatic.</p>
</div>
<div class="sect2">
<h3 id="screenshots-3"><a class="anchor" href="#screenshots-3"></a>Screenshots</h3>
<div class="paragraph">
<p>The following screenshots are taken from the <a href="https://github.com/estatio/estatio">Estatio</a> application.</p>
</div>
<div class="sect3">
<h4 id="copy-url"><a class="anchor" href="#copy-url"></a>Copy URL</h4>
<div class="paragraph">
<p>This screenshot (nb: using a pre 1.8.0 version of the <a href="about.html" class="page">Wicket viewer</a> UI) shows the copy URL button (top right):</p>
</div>
<div class="imageblock">
<div class="content">
<a class="image" href="_images/copy-link/010-copy-link-button.png"><img src="_images/copy-link/010-copy-link-button.png" alt="010 copy link button" width="800px"></a>
</div>
</div>
<div class="paragraph">
<p>Clicking on this button brings up a dialog with the URL preselected:</p>
</div>
<div class="imageblock">
<div class="content">
<a class="image" href="_images/copy-link/020-copy-link-dialog.png"><img src="_images/copy-link/020-copy-link-dialog.png" alt="020 copy link dialog" width="800px"></a>
</div>
</div>
<div class="paragraph">
<p>The URL in this case is something like:</p>
</div>
<div class="literalblock">
<div class="content">
<pre>http://localhost:8080/wicket/entity/org.estatio.dom.lease.Lease:0</pre>
</div>
</div>
<div class="paragraph">
<p>The user can copy the link (eg <code>ctrl+C</code>) into the clipboard, then hit <code>OK</code> or <code>Esc</code> to dismiss the dialog.</p>
</div>
</div>
<div class="sect3">
<h4 id="hints"><a class="anchor" href="#hints"></a>Hints</h4>
<div class="paragraph">
<p>Using the viewer the user can hide/show collection tables, can sort the tables by header columns:</p>
</div>
<div class="imageblock">
<div class="content">
<a class="image" href="_images/copy-link/030-hints.png"><img src="_images/copy-link/030-hints.png" alt="030 hints" width="800px"></a>
</div>
</div>
<div class="paragraph">
<p>Also, if the collection spans multiple pages, then the individual page can be selected.</p>
</div>
<div class="paragraph">
<p>Once the view has been customised, the URL shown in the copy URL dialog is in an extended form:</p>
</div>
<div class="imageblock">
<div class="content">
<a class="image" href="_images/copy-link/040-copy-link-with-hints.png"><img src="_images/copy-link/040-copy-link-with-hints.png" alt="040 copy link with hints" width="800px"></a>
</div>
</div>
<div class="paragraph">
<p>The URL in this case is something like:</p>
</div>
<div class="literalblock">
<div class="content">
<pre>http://localhost:8080/wicket/entity/org.estatio.dom.lease.Lease:0?hint-1:collectionContents-view=3&amp;hint-1:collectionContents:collectionContents-3:table-DESCENDING=value&amp;hint-1:collectionContents:collectionContents-3:table-pageNumber=0&amp;hint-2:collectionContents-view=0&amp;hint-2:collectionContents:collectionContents-2:table-pageNumber=0&amp;hint-3:collectionContents-view=2&amp;hint-3:collectionContents:collectionContents-2:table-pageNumber=0&amp;hint-4:collectionContents-view=3&amp;hint-4:collectionContents:collectionContents-3:table-ASCENDING=exerciseDate&amp;hint-4:collectionContents:collectionContents-3:table-pageNumber=0&amp;hint-5:collectionContents-view=0&amp;hint-5:collectionContents:collectionContents-3:table-pageNumber=0</pre>
</div>
</div>
</div>
<div class="sect3">
<h4 id="copy-url-from-title"><a class="anchor" href="#copy-url-from-title"></a>Copy URL from title</h4>
<div class="paragraph">
<p>When the user invokes an action on the object, the URL (necessarily) changes to indicate that the action was invoked. This URL is specific to the user&#8217;s session and cannot be shared with others.</p>
</div>
<div class="paragraph">
<p>A quick way for the user to grab a shareable URL is simply by clicking on the object&#8217;s title:</p>
</div>
<div class="imageblock">
<div class="content">
<a class="image" href="_images/copy-link/050-title-url.png"><img src="_images/copy-link/050-title-url.png" alt="050 title url" width="800px"></a>
</div>
</div>
</div>
</div>
<div class="sect2">
<h3 id="user-experience-3"><a class="anchor" href="#user-experience-3"></a>User Experience</h3>
<div class="paragraph">
<p>The copy URL dialog is typically obtained by clicking on the icon.</p>
</div>
<div class="paragraph">
<p>Alternatively, <code>alt+]</code> will also open the dialog. It can be closed with either <code>OK</code> or the <code>Esc</code> key.</p>
</div>
</div>
</div>
</div>
<div class="sect1">
<h2 id="where-am-i"><a class="anchor" href="#where-am-i"></a>Where am I</h2>
<div class="sectionbody">
<div class="paragraph">
<p>The Wicket viewer provides a secondary navigation scheme that allows users to quickly access domain objects, that are organized in a hierarchical manner.</p>
</div>
<div class="paragraph">
<p>This hierarchy can be understood as a navigable tree-structure, where the navigable tree-nodes are either domain objects or domain views.
Domain objects that take part in such a navigable-tree-structure need to declare their actual navigable parent within this hierarchy.
That&#8217;s all the framework needs, in order to build a navigable-tree.
With version 2.0 we introduced the <code>Navigable</code> enum to use with the <code>@PropertyLayout</code> annotation to allow declarative specification of a domain object&#8217;s navigable parent.</p>
</div>
<div class="paragraph">
<p>In other words: a domain object or view may declare its parent (with respect to the navigable tree-structure it is part of) via use of a <code>@PropertyLayout(navigable=Navigable.PARENT)</code> annotation.</p>
</div>
<div class="sect2">
<h3 id="screenshots-4"><a class="anchor" href="#screenshots-4"></a>Screenshots</h3>
<div class="paragraph">
<p>The following screenshot shows the navigation links below the top menu bar.</p>
</div>
<div class="imageblock">
<div class="content">
<a class="image" href="_images/where-am-i/hello_grey_bg.png"><img src="_images/where-am-i/hello_grey_bg.png" alt="hello grey bg" width="720px"></a>
</div>
</div>
</div>
<div class="sect2">
<h3 id="domain-code-3"><a class="anchor" href="#domain-code-3"></a>Domain Code</h3>
<div class="paragraph">
<p>To declare a domain object&#8217;s (or view&#8217;s) navigable parent, add a <code>@PropertyLayout(navigable=Navigable.PARENT)</code> annotation to a field (that has an associated getter) or a no-arg method, that returns the parent object:</p>
</div>
<div class="listingblock">
<div class="content">
<pre class="highlightjs highlight"><code class="language-java hljs" data-lang="java">@DomainObject
public class Company { /* ... */ }
@DomainObject
public class Employee {
@PropertyLayout(navigable=Navigable.PARENT) // annotated field with e.g. lombok provided getter
@Getter
Company myCompany;
}
@DomainObject
public class PhoneNumber {
@PropertyLayout(navigable=Navigable.PARENT) // annotated no-arg supplier
Employee employee(){
return ...
}
}</code></pre>
</div>
</div>
<div class="paragraph">
<p>This results in a navigable tree-structure &#8230;&#8203;</p>
</div>
<div class="paragraph">
<p>Company &gt; Employee &gt; PhoneNumber</p>
</div>
<div class="sect3">
<h4 id="how-to-use-navigable-parent"><a class="anchor" href="#how-to-use-navigable-parent"></a>How to use <code>Navigable.PARENT</code></h4>
<div class="olist arabic">
<ol class="arabic">
<li>
<p>Any use of <code>@PropertyLayout(navigable=Navigable.PARENT)</code> with Java interfaces is simply ignored.
These do not contribute to the domain meta model.</p>
</li>
<li>
<p>Any class (abstract or concrete) may at most have one <code>@PropertyLayout</code> annotation, having <code>navigable=Navigable.PARENT</code> 'flag' set (on either a method or a field); otherwise meta-model validation will fail.</p>
</li>
<li>
<p>The annotated member (method or field), when &#8230;&#8203;</p>
<div class="olist loweralpha">
<ol class="loweralpha" type="a">
<li>
<p>... a method: then must be a no-arg method returning a non-primitive type (e.g. a getter)</p>
</li>
<li>
<p>... a field: then the field must be of non-primitive type and must also have a getter (as specified by the Java Beans Standard, particularly to allow <code>@PropertyLayout(navigable=Navigable.PARENT)</code> annotations on fields that use the lombok <code>@Getter</code> annotation)</p>
</li>
</ol>
</div>
</li>
<li>
<p>Starting from the current domain-object, we search the object&#8217;s class inheritance hierarchy (super class, super super class, &#8230;&#8203;), until we find the first class that has a <code>@PropertyLayout(navigable=Navigable.PARENT)</code> annotation.
That&#8217;s the one we use to resolve the current domain-object&#8217;s navigable parent.</p>
</li>
</ol>
</div>
</div>
</div>
<div class="sect2">
<h3 id="user-experience-4"><a class="anchor" href="#user-experience-4"></a>User Experience</h3>
<div class="paragraph">
<p>When viewing a domain object that is part of a hierarchical structure, one can easily navigate to any parent of this object.
Horizontally arranged text links separated by the 'greater than' symbol (&gt;) are provided below the main menu.
(Traditionally called breadcrumbs.)</p>
</div>
</div>
<div class="sect2">
<h3 id="related-functionality-3"><a class="anchor" href="#related-functionality-3"></a>Related functionality</h3>
<div class="paragraph">
<p>The navigable tree-structure, as provided by the 'Where am I' feature, is declared at compile-time (predefined by the programmer), whereas related features (<a href="#recent-pages">Recent Pages</a> and <a href="#bookmarked-pages">Bookmarked Pages</a>) are populated at runtime only after user interaction.</p>
</div>
</div>
</div>
</div>
<div class="sect1">
<h2 id="titles-in-tables"><a class="anchor" href="#titles-in-tables"></a>Titles in Tables</h2>
<div class="sectionbody">
<div class="paragraph">
<p>Object titles can often be quite long if the intention is to uniquely identify the object.
While this is appropriate for the object view, it can be cumbersome within tables.</p>
</div>
<div class="paragraph">
<p>If an object&#8217;s title is specified with from <code>@Title</code> annotation then the Wicket viewer will (for parented collections) automatically "contextualize" a title by excluding the part of the title corresponding to a reference to the owning (parent) object.</p>
</div>
<div class="paragraph">
<p>In other words, suppose we have:</p>
</div>
<div class="imageblock">
<div class="content">
<a class="image" href="_images/how-tos/ui-hints/object-titles-and-icons/cust-order-product.png"><img src="_images/how-tos/ui-hints/object-titles-and-icons/cust-order-product.png" alt="cust order product" width="579px"></a>
</div>
</div>
<div class="paragraph">
<p>so that <code>Customer</code> has a collection of `Order`s:</p>
</div>
<div class="listingblock">
<div class="content">
<pre class="highlightjs highlight"><code class="language-java hljs" data-lang="java">public class Customer {
public Set&lt;Order&gt; getOrders() { /* ... */ }
...
}</code></pre>
</div>
</div>
<div class="paragraph">
<p>and <code>Product</code> also has a collection of `Order`s (please forgive the suspect domain modelling in this example (!)):</p>
</div>
<div class="listingblock">
<div class="content">
<pre class="highlightjs highlight"><code class="language-java hljs" data-lang="java">public class Product {
public Set&lt;Order&gt; getOrders() { /* ... */ }
...
}</code></pre>
</div>
</div>
<div class="paragraph">
<p>and where the <code>Order</code> class references both <code>Customer</code> and <code>Product</code>.</p>
</div>
<div class="paragraph">
<p>The <code>Order</code>'s might involve each of these:</p>
</div>
<div class="listingblock">
<div class="content">
<pre class="highlightjs highlight"><code class="language-java hljs" data-lang="java">public class Order {
@Title(sequence="1")
public Customer getCustomer() { /* ... */ }
@Title(sequence="2")
public Product getProduct() { /* ... */ }
@Title(sequence="3")
public String getOtherInfo() { /* ... */ }
...
}</code></pre>
</div>
</div>
<div class="paragraph">
<p>In this case, if we view a <code>Customer</code> with its collection of <code>Order</code>s, then in that parented collection&#8217;s table the customer&#8217;s property will be automatically excluded from the title of the <code>Order</code> (but it would show the product).
Conversely, if a <code>Product</code> is viewed then its collection of <code>Order</code>s would suppress product (but would show the customer).</p>
</div>
<div class="admonitionblock tip">
<table>
<tr>
<td class="icon">
<i class="fa icon-tip" title="Tip"></i>
</td>
<td class="content">
<div class="paragraph">
<p>This feature is a close cousin of the <code>@PropertyLayout(hidden=Where.REFERENCES_PARENT)</code> annotation, which will cause the property itself to be hidden as a column in the table.
An Apache Isis idiom is therefore:</p>
</div>
<div class="listingblock">
<div class="content">
<pre class="highlightjs highlight"><code class="language-java hljs" data-lang="java">public class Order {
@Title(sequence="1")
@PropertyLayout(hidden=Where.REFERENCES_PARENT)
public Customer getCustomer() { /* ... */ }
...
}</code></pre>
</div>
</div>
</td>
</tr>
</table>
</div>
<div class="paragraph">
<p>The above annotations mean that titles usually "just work", altering according to the context in which they are viewed.</p>
</div>
<div class="admonitionblock tip">
<table>
<tr>
<td class="icon">
<i class="fa icon-tip" title="Tip"></i>
</td>
<td class="content">
<div class="paragraph">
<p>It is also possible to configure the Wicket viewer to <a href="configuration-properties.html#presentation." class="page">abbreviate titles or suppress them</a> completely.</p>
</div>
</td>
</tr>
</table>
</div>
</div>
</div>
<div class="sect1">
<h2 id="blob-attachments"><a class="anchor" href="#blob-attachments"></a>File upload/download</h2>
<div class="sectionbody">
<div class="paragraph">
<p>The Apache Isis application library provides the <a href="#refguide:applib-cm:classes/value-types.adoc#Blob" class="page unresolved">Blob</a> value type (binary large objects) and also the <a href="#refguide:applib-cm:classes/value-types.adoc#Clob" class="page unresolved">Clob</a>
value type (character large object), each of which also includes metadata about the data (specifically the filename and mime type).</p>
</div>
<div class="paragraph">
<p>A class can define a property using either of these types, for example:</p>
</div>
<div class="sect2">
<h3 id="screenshots-5"><a class="anchor" href="#screenshots-5"></a>Screenshots</h3>
<div class="paragraph">
<p>The following screenshots are taken from the example <a href="https://github.com/apache/isis-app-todoapp">TodoApp</a>:</p>
</div>
<div class="sect3">
<h4 id="view-mode-empty"><a class="anchor" href="#view-mode-empty"></a>View mode, empty</h4>
<div class="paragraph">
<p><code>Blob</code> field rendered as attachment (with no data):</p>
</div>
<div class="imageblock">
<div class="content">
<a class="image" href="_images/blob-attachments/010-attachment-field.png"><img src="_images/blob-attachments/010-attachment-field-940.png" alt="010 attachment field 940" width="800px"></a>
</div>
</div>
<div class="paragraph">
<p>Note that this screenshot show an earlier version of the <a href="about.html" class="page">Wicket viewer</a> UI (specifically, pre 1.8.0).</p>
</div>
</div>
<div class="sect3">
<h4 id="edit-mode"><a class="anchor" href="#edit-mode"></a>Edit mode</h4>
<div class="paragraph">
<p>Hit edit; 'choose file' button appears:</p>
</div>
<div class="imageblock">
<div class="content">
<a class="image" href="_images/blob-attachments/020-edit-choose-file.png"><img src="_images/blob-attachments/020-edit-choose-file-940.png" alt="020 edit choose file 940" width="800px"></a>
</div>
</div>
</div>
<div class="sect3">
<h4 id="choose-file"><a class="anchor" href="#choose-file"></a>Choose file</h4>
<div class="paragraph">
<p>Choose file using the regular browser window:</p>
</div>
<div class="imageblock">
<div class="content">
<a class="image" href="_images/blob-attachments/030-choose-file-using-browser.png"><img src="_images/blob-attachments/030-choose-file-using-browser-520.png" alt="030 choose file using browser 520" width="520px"></a>
</div>
</div>
<div class="paragraph">
<p>Chosen file is indicated:</p>
</div>
<div class="imageblock">
<div class="content">
<a class="image" href="_images/blob-attachments/040-edit-chosen-file-indicated.png"><img src="_images/blob-attachments/040-edit-chosen-file-indicated-940.png" alt="040 edit chosen file indicated 940" width="800px"></a>
</div>
</div>
</div>
<div class="sect3">
<h4 id="image-rendered"><a class="anchor" href="#image-rendered"></a>Image rendered</h4>
<div class="paragraph">
<p>Back in view mode (ie once hit OK) if the <code>Blob</code> is an image, then it is shown:</p>
</div>
<div class="imageblock">
<div class="content">
<a class="image" href="_images/blob-attachments/050-ok-if-image-then-rendered.png"><img src="_images/blob-attachments/050-ok-if-image-then-rendered-940.png" alt="050 ok if image then rendered 940" width="800px"></a>
</div>
</div>
</div>
<div class="sect3">
<h4 id="download"><a class="anchor" href="#download"></a>Download</h4>
<div class="paragraph">
<p><code>Blob</code> can be downloaded:</p>
</div>
<div class="imageblock">
<div class="content">
<a class="image" href="_images/blob-attachments/060-download.png"><img src="_images/blob-attachments/060-download-940.png" alt="060 download 940" width="800px"></a>
</div>
</div>
</div>
<div class="sect3">
<h4 id="clear"><a class="anchor" href="#clear"></a>Clear</h4>
<div class="paragraph">
<p>Back in edit mode, can choose a different file or clear (assuming property is not mandatory):</p>
</div>
<div class="imageblock">
<div class="content">
<a class="image" href="_images/blob-attachments/070-edit-clear.png"><img src="_images/blob-attachments/070-edit-clear-940.png" alt="070 edit clear 940" width="800px"></a>
</div>
</div>
</div>
</div>
<div class="sect2">
<h3 id="domain-code-4"><a class="anchor" href="#domain-code-4"></a>Domain Code</h3>
<div class="paragraph">
<p>To define a <code>Blob</code>, use:</p>
</div>
<div class="listingblock">
<div class="content">
<pre class="highlightjs highlight"><code class="language-java hljs" data-lang="java">private Blob attachment;
@javax.jdo.annotations.Persistent(defaultFetchGroup="false")
@javax.jdo.annotations.Persistent(defaultFetchGroup="false", columns = {
@javax.jdo.annotations.Column(name = "attachment_name"),
@javax.jdo.annotations.Column(name = "attachment_mimetype"),
@javax.jdo.annotations.Column(name = "attachment_bytes", jdbcType = "BLOB", sqlType = "BLOB")
})
@Property(
domainEvent = AttachmentDomainEvent.class,
optionality = Optionality.OPTIONAL
)
public Blob getAttachment() { return attachment; }
public void setAttachment(final Blob attachment) { this.attachment = attachment; }</code></pre>
</div>
</div>
<div class="paragraph">
<p>To define a <code>Clob</code>, use:</p>
</div>
<div class="listingblock">
<div class="content">
<pre class="highlightjs highlight"><code class="language-java hljs" data-lang="java">private Clob doc;
@javax.jdo.annotations.Persistent(defaultFetchGroup="false", columns = {
@javax.jdo.annotations.Column(name = "doc_name"),
@javax.jdo.annotations.Column(name = "doc_mimetype"),
@javax.jdo.annotations.Column(name = "doc_chars", jdbcType = "CLOB", sqlType = "CLOB")
})
@Property(
optionality = Optionality.OPTIONAL
)
public Clob getDoc() { return doc; }
public void setDoc(final Clob doc) { this.doc = doc; }</code></pre>
</div>
</div>
<div class="paragraph">
<p>The <code>Blob</code> and <code>Clob</code> types can also be used as parameters to actions.</p>
</div>
</div>
</div>
</div>
<div class="sect1">
<h2 id="user-registration"><a class="anchor" href="#user-registration"></a>User Registration</h2>
<div class="sectionbody">
<div class="paragraph">
<p>The Wicket viewer provides the ability for users to sign-up by providing a valid email address:</p>
</div>
<div class="ulist">
<ul>
<li>
<p>from the login page the user can instead follow a link to take them to a sign-up page, where they enter their email address.</p>
</li>
<li>
<p>a verification email is sent using this service; the email includes a link back to the running application.</p>
</li>
<li>
<p>the user then completes the registration process by choosing a user name and password.</p>
</li>
<li>
<p>the Wicket viewer then creates an account for them and logs them in.</p>
</li>
</ul>
</div>
<div class="paragraph">
<p>In a similar way, if the user has forgotten their password then they can request a reset link to be sent to their email, again by providing their email address.</p>
</div>
<div class="paragraph">
<p>To support this the framework requires three services to be registered and configured:</p>
</div>
<div class="ulist">
<ul>
<li>
<p>the <a href="../../refguide/2.0.0-M3/applib-svc/UserRegistrationService.html" class="page">user registration service</a>, which provides an API to create the user account</p>
</li>
<li>
<p>the <a href="../../refguide/2.0.0-M3/applib-svc/EmailNotificationService.html" class="page">email notification service</a>, which provides an API for to send the verification emails</p>
</li>
<li>
<p>the <a href="../../refguide/2.0.0-M3/applib-svc/EmailService.html" class="page">email service</a>, that is used by the email notification service to actually send the email.</p>
</li>
</ul>
</div>
<div class="paragraph">
<p>The Apache Isis core framework provides a default implementation of both the email notification service and the email service.
The <a href="../../security/2.0.0-M3/about.html" class="page">Security Manager</a> extension provides a partial implementation of <a href="../../refguide/2.0.0-M3/applib-svc/UserRegistrationService.html" class="page">user registration service</a> that you can complete for your own applications.</p>
</div>
<div class="sect2">
<h3 id="screenshots-6"><a class="anchor" href="#screenshots-6"></a>Screenshots</h3>
<div class="paragraph">
<p>The user is presented with a login page:</p>
</div>
<div class="imageblock">
<div class="content">
<a class="image" href="_images/user-registration/login-page-default.png"><img src="_images/user-registration/login-page-default.png" alt="login page default" width="300px"></a>
</div>
</div>
<div class="paragraph">
<p>Navigate to the sign up page. Complete the page, and verify:</p>
</div>
<div class="imageblock">
<div class="content">
<a class="image" href="_images/user-registration/sign-up-page.png"><img src="_images/user-registration/sign-up-page.png" alt="sign up page" width="300px"></a>
</div>
</div>
<div class="paragraph">
<p>Back to the login page:</p>
</div>
<div class="imageblock">
<div class="content">
<a class="image" href="_images/user-registration/sign-up-login-page-after-sign-up.png"><img src="_images/user-registration/sign-up-login-page-after-sign-up.png" alt="sign up login page after sign up" width="300px"></a>
</div>
</div>
<div class="paragraph">
<p>Email arrives, with link:</p>
</div>
<div class="imageblock">
<div class="content">
<a class="image" href="_images/user-registration/sign-up-email-with-verification-link.png"><img src="_images/user-registration/sign-up-email-with-verification-link.png" alt="sign up email with verification link" width="500px"></a>
</div>
</div>
<div class="paragraph">
<p>Follow the link, complete the page:</p>
</div>
<div class="imageblock">
<div class="content">
<a class="image" href="_images/user-registration/sign-up-registration-page.png"><img src="_images/user-registration/sign-up-registration-page.png" alt="sign up registration page" width="300px"></a>
</div>
</div>
<div class="paragraph">
<p>Automatically logged in:</p>
</div>
<div class="imageblock">
<div class="content">
<a class="image" href="_images/user-registration/sign-up-after-registration.png"><img src="_images/user-registration/sign-up-after-registration.png" alt="sign up after registration" width="800px"></a>
</div>
</div>
</div>
<div class="sect2">
<h3 id="configuration-3"><a class="anchor" href="#configuration-3"></a>Configuration</h3>
<div class="paragraph">
<p>There are two prerequisites:</p>
</div>
<div class="ulist">
<ul>
<li>
<p>register an implementation of the <a href="../../refguide/2.0.0-M3/applib-svc/UserRegistrationService.html" class="page">user registration service</a> (eg by using the <a href="../../security/2.0.0-M3/about.html" class="page">SecMan extension</a>)</p>
</li>
<li>
<p>configure the <a href="../../refguide/2.0.0-M3/applib-svc/EmailService.html" class="page">email service</a></p>
</li>
</ul>
</div>
<div class="paragraph">
<p>The latter is required if you are using the default email notification service and email service. If you are using your own alternative implementation of the email notification service then it may be omitted (and configure your own alternative implementation as required).</p>
</div>
<div class="paragraph">
<p>It is also possible to configure the Wicket viewer to suppress the sign-up page link and/or the password reset page, see <a href="configuration-properties.html#sign-in" class="page">here</a> for further details.</p>
</div>
</div>
</div>
</div>
</article>
<aside class="article-aside toc" role="navigation">
<p class="toc-title">On this page</p>
<div id="article-toc"></div>
</aside>
</main>
</div>
<footer class="footer">
<div class="content">
<div class="copyright">
<p>
Copyright © 2010~2020 The Apache Software Foundation, licensed under the Apache License, v2.0.
<br/>
Apache, the Apache feather logo, Apache Isis, and the Apache Isis project logo are all trademarks of The Apache Software Foundation.
</p>
</div>
<div class="revision">
<p>Revision: SNAPSHOT</p>
</div>
</div>
</footer>
<script src="../../_/js/site.js"></script>
<script async src="../../_/js/vendor/highlight.js"></script>
<script src="../../_/js/vendor/jquery-3.4.1.min.js"></script>
<script src="../../_/js/vendor/jquery-ui-1.12.1.custom.widget-only.min.js"></script>
<script src="../../_/js/vendor/jquery.tocify.min.js"></script>
<script>
$(function() {
$("#article-toc").tocify( {
showEffect: "slideDown",
hashGenerator: "pretty",
hideEffect: "slideUp",
selectors: "h2, h3",
scrollTo: 120,
smoothScroll: true,
theme: "jqueryui",
highlightOnScroll: true
} );
});
</script>
</body>
</html>