| <!-- |
| /*************************************************************************************************************************** |
| * 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. |
| ***************************************************************************************************************************/ |
| --> |
| |
| UI Customization |
| |
| <p> |
| The HTML views of POJOs can somewhat be considered a rudimentary User Interface. |
| In reality, a better term for them would be a Developer Interface as they're meant to be used |
| primarily by developers and not end users. |
| Despite that distinction, it is possible to 'brand' the HTML page to whatever you desire. |
| </p> |
| <p> |
| The sample root page below includes some default branding for Juneau and Apache: |
| </p> |
| <p class='bpcode w800'> |
| http://localhost:10000/helloWorld |
| </p> |
| <img class='bordered w800' src='doc-files/juneau-rest-server.UiCustomization.1.png'> |
| <p> |
| The Juneau REST framework does not provide specific branding support (i.e. there is no concept of a brand icon). |
| Instead, it just uses the existing open-ended API for defining branding via annotations on your REST classes. |
| </p> |
| <p class='bpcode w800'> |
| <ja>@Rest</ja>( |
| ... |
| <jc>// HTML-page specific settings</jc> |
| htmldoc=<ja>@HtmlDoc</ja>( |
| |
| <jc>// Default page header contents.</jc> |
| header={ |
| <js>"<h1>$R{resourceTitle}</h1>"</js>, <jc>// Use @Rest(title)</jc> |
| <js>"<h2>$R{methodSummary,resourceDescription}</h2>"</js>, <jc>// Use either @RestMethod(summary) or @Rest(description)</jc> |
| <js>"$C{REST/header}"</js> <jc>// Extra header HTML defined in external config file.</jc> |
| }, |
| |
| <jc>// Default stylesheet to use for the page. |
| // Can be overridden from external config file. |
| // Default is DevOps look-and-feel (aka Depression look-and-feel).</jc> |
| stylesheet=<js>"$C{REST/theme,servlet:/htdocs/themes/devops.css}"</js>, |
| |
| <jc>// Default contents to add to the <head> section of the HTML page. |
| // Use it to add a favicon link to the page.</jc> |
| head={ |
| <js>"<link rel='icon' href='$U{$C{REST/favicon}}'/>"</js> |
| }, |
| |
| <jc>// No default page footer contents. |
| // Can be overridden from external config file.</jc> |
| footer=<js>"$C{REST/footer}"</js> |
| ), |
| |
| <jc>// Optional external configuration file.</jc> |
| config=<js>"$S{juneau.configFile}"</js>, |
| |
| <jc>// These are static files that are served up by the servlet under the specified sub-paths. |
| // For example, "/servletPath/htdocs/javadoc.css" resolves to the file "[servlet-package]/htdocs/javadoc.css" |
| // By default, we define static files through the external configuration file.</jc> |
| staticFiles=<js>"$C{REST/staticFiles}"</js> |
| ) |
| <jk>public interface</jk> BasicRestConfig {} |
| </p> |
| <p class='bpcode w800'> |
| <ja>@Rest</ja>( |
| ... |
| htmldoc=<ja>@HtmlDoc</ja>( |
| htmldoc=<ja>@HtmlDoc</ja>( |
| <jc>// Basic page navigation links.</jc> |
| navlinks={ |
| <js>"up: request:/.."</js>, |
| <js>"options: servlet:/?method=OPTIONS"</js> |
| } |
| ) |
| ), |
| ... |
| ) |
| <jk>public abstract class</jk> BasicRestServlet <jk>extends</jk> RestServlet <jk>implements</jk> BasicRestConfig {...} |
| </p> |
| <p class='bpcode w800'> |
| <ja>@Rest</ja> |
| <jk>public abstract class</jk> BasicRestServletGroup <jk>extends</jk> BasicRestServlet {...} |
| </p> |
| <p class='bpcode w800'> |
| <ja>@Rest</ja>( |
| htmldoc=<ja>@HtmlDoc</ja>( |
| widgets={ |
| ContentTypeMenuItem.<jk>class</jk>, |
| ThemeMenuItem.<jk>class</jk> |
| }, |
| navlinks={ |
| <js>"options: ?method=OPTIONS"</js>, |
| <js>"$W{ContentTypeMenuItem}"</js>, |
| <js>"$W{ThemeMenuItem}"</js>, |
| <js>"source: $C{Source/gitHub}/org/apache/juneau/examples/rest/$R{servletClassSimple}.java"</js> |
| }, |
| aside={ |
| <js>"<div style='max-width:400px' class='text'>"</js>, |
| <js>" <p>This is an example of a 'router' page that serves as a jumping-off point to child resources.</p>"</js>, |
| <js>" <p>Resources can be nested arbitrarily deep through router pages.</p>"</js>, |
| <js>" <p>Note the <span class='link'>options</span> link provided that lets you see the generated swagger doc for this page.</p>"</js>, |
| <js>" <p>Also note the <span class='link'>sources</span> link on these pages to view the source code for the page.</p>"</js>, |
| <js>" <p>All content on pages in the UI are serialized POJOs. In this case, it's a serialized array of beans with 2 properties, 'name' and 'description'.</p>"</js>, |
| <js>" <p>Other features (such as this aside) are added through annotations.</p>"</js>, |
| <js>"</div>"</js> |
| } |
| ), |
| ... |
| ) |
| <jk>public class</jk> RootResources <jk>extends</jk> BasicRestServletGroup {...} |
| </p> |
| |
| <p> |
| The default annotation values use {@link oaj.config.vars.ConfigVar $C} variables to pull in values from an optional |
| external configuration file such as the one shown below: |
| </p> |
| <p class='bpcode w800'> |
| <cc>#======================================================================================================================= |
| # REST settings |
| #=======================================================================================================================</cc> |
| <cs>[REST]</cs> |
| |
| <ck>staticFiles</ck> = <cv>htdocs:files/htdocs</cv> |
| |
| <cc># Stylesheet to use for HTML views.</cc> |
| <ck>theme</ck> = <cv>servlet:/htdocs/themes/devops.css</cv> |
| |
| <ck>headerIcon</ck> = <cv>servlet:/htdocs/images/juneau.png</cv> |
| <ck>headerLink</ck> = <cv>http://juneau.apache.org</cv> |
| <ck>footerIcon</ck> = <cv>servlet:/htdocs/images/asf.png</cv> |
| <ck>footerLink</ck> = <cv>http://www.apache.org</cv> |
| |
| <ck>favicon</ck> = <cv>$C{REST/headerIcon}</cv> |
| <ck>header</ck> = |
| <cv><a href='$U{$C{REST/headerLink}}'></cv> |
| <cv><img src='$U{$C{REST/headerIcon}}' style='position:absolute;top:5;right:5;background-color:transparent;height:30px'/></cv> |
| <cv></a></cv> |
| <ck>footer</ck> = |
| <cv><a href='$U{$C{REST/footerLink}}'></cv> |
| <cv><img src='$U{$C{REST/footerIcon}}' style='float:right;padding-right:20px;height:32px'/></cv> |
| <cv></a></cv> |
| </p> |
| <p> |
| The take-away here is that the "User Interface" is open-ended, lets you define pretty much anything you want through arbitrary HTML, |
| and allows you either hardcode your interface inside annotations or pull them in via string variables from other places such as |
| external config files. |
| </p> |
| <ul class='seealso'> |
| <li class='link'>{@doc juneau-microservice-jetty.UiCustomization} |
| </ul> |