Upgrade to Pro — share decks privately, control downloads, hide ads and more …

Creating a Customizable Dynamic CAS Theme

Creating a Customizable Dynamic CAS Theme

At the University of California, Merced, during our upgrade to the latest general release 3.5.2, we expanded upon our customizable login theme. This presentation is intended for those who are interested in allowing departments a way to customize their login page both for the desktop and mobile view.
#apereo14

Benito Gonzalez

June 04, 2014
Tweet

More Decks by Benito Gonzalez

Other Decks in Technology

Transcript

  1. Benito Gonzalez 8 years CAS developer Chair of Planning Committee

    Director at White Whale Laura McCord 8 years CAS developer Member of Planning Committee IT Manager/Dev at UC Merced
  2. <?xml version="1.0"?> <xs:schema xmlns:xs="http://www.w3.org/2001/XMLSchema" targetNamespace="http://bardstale.ucmerced.edu/2009/CASSkinSchema" xmlns="http://bardstale.ucmerced.edu/2009/CASSkinSchema" elementFormDefault="qualified"> ! <xs:element name="skin">

    <xs:complexType> <xs:sequence> <xs:element name="title" type="xs:string" /> <xs:element name="logo-url" minOccurs= "0" type="xs:anyURI" /> <xs:element name="marketing-text" type="xs:string" /> <xs:element name="useful-link" minOccurs="0" maxOccurs="unbounded"> <xs:complexType> <xs:sequence> <xs:element name="title" type="xs:string" /> <xs:element name="url" type="xs:anyURI" /> </xs:sequence> </xs:complexType> </xs:element> <xs:element name="help" minOccurs="0" maxOccurs="unbounded"> <xs:complexType> <xs:sequence> <xs:element name="name" type="xs:string" /> <xs:element name="content" type="xs:anyType" /> </xs:sequence> </xs:complexType> </xs:element> </xs:sequence> </xs:complexType> </xs:element> ! </xs:schema>
  3. … <bean id="defaultThemeSource" class="org.springframework.ui.context.support.ResourceBundleThemeSource" /> ! <bean id="themeEhCache" class="org.springframework.cache.ehcache.EhCacheFactoryBean" p:cacheManager-ref="ehCacheManager"

    p:cacheName="themeCache"/> ! <bean id="themeSource" class="edu.ucmerced.cas.WebThemeSource" p:parentThemeSource-ref="defaultThemeSource" p:cache-ref="themeEhCache" /> ! …
  4. … /** * {@link HierarchicalThemeSource} implementation that pulls XML from

    a URL * to define a theme. The theme name is a URL that meets the schema * http://bardstale.ucmerced.edu/2009/CASSkinSchema. * * @author Benito J. Gonzalez */ public class WebThemeSource implements HierarchicalThemeSource { ! … ! public Theme getTheme(String themeName) { if (themeName == null) { return null; } Element el = themeCache.get(themeName); if (el == null) { el = cacheTheme(themeName); } return (Theme) (el != null ? el.getObjectValue() : null); }
  5. ! protected Element cacheTheme(String themeName) { Theme theme = createTheme(themeName);

    if (theme == null) { theme = parentThemeSource.getTheme(themeName); } Element el = null; if (theme != null) { el = new Element(themeName, theme); themeCache.put(el); if (log.isDebugEnabled()) { log.debug("Theme '" + themeName + "' created."); } } else { log.warn("Theme '" + themeName + "'cannot be found."); } return el; }
  6. ! protected Theme createTheme(String themeName) { if (themeName.startsWith("http")) { MessageSource

    msgSrc = createMessageSourceFromXmlStream(themeName); return msgSrc == null ? null : new SimpleTheme(themeName, msgSrc); } return null; }
  7. protected MessageSource createMessageSourceFromXmlStream(String xmlURL) { XMLThemeStreamContext ctx = new XMLThemeStreamContext();

    try { XMLInputFactory factory = XMLInputFactory.newInstance(); factory.setProperty(XMLInputFactory.IS_COALESCING, Boolean.TRUE); URL url = new URL(xmlURL); XMLEventReader eventReader = factory .createXMLEventReader(url.openStream()); while (eventReader.hasNext()) { XMLEvent event = eventReader.nextEvent(); if (!event.isStartElement()) { continue; } String nodeName = event.asStartElement().getName().getLocalPart(); event = eventReader.nextEvent(); String data = event.asCharacters().getData().trim(); ctx.addThemeDatumToMessageSource(nodeName, data); } ctx.addLinkCount(); return ctx.msgSrc; } catch (Exception e) { log.warn("Problem reading theme from " + xmlURL, e); return null; } }
  8. ! private class XMLThemeStreamContext { private String parentNodeName = null;

    private int links = 0; private int mobile = 0; private int accordion = 0; ! StaticMessageSource msgSrc = new StaticMessageSource(); ! public XMLThemeStreamContext() { addMessage("title", "UC Merced Single Sign On"); } ! public void addLinkCount() { addMessage("useful-link-count", Integer.toString(links)); addMessage("mobile-link-count", Integer.toString(mobile)); addMessage("accordion-link-count", Integer.toString(accordion)); } ! private void addThemeDatumToMessageSource(String nodeName, String data) { … } ! private void addMessage(String code, String txt) { msgSrc.addMessage(code, Locale.ENGLISH, txt); msgSrc.addMessage(code, Locale.US, txt); } } !
  9. private void addThemeDatumToMessageSource(String nodeName, String data) { if ("skin".equals(nodeName)) {

    parentNodeName = nodeName; } else if ("skin".equals(parentNodeName)) { if ("title".equals(nodeName) || "logo-url".equals(nodeName) || "marketing-text".equals(nodeName)) { addMessage(nodeName, data); } else if ("useful-link".equals(nodeName) || "help".equals(nodeName) || "mobile-link".equals(nodeName) || "accordion".equals(nodeName)) { parentNodeName = nodeName; } } else if ("useful-link".equals(parentNodeName)) { String prefix = parentNodeName + Integer.toString(links) + "-"; addMessage(prefix + nodeName, data); if ("url".equals(nodeName)) { links++; parentNodeName = "skin"; } } else if ("help".equals(parentNodeName)) { String prefix = parentNodeName + "-"; addMessage(prefix + nodeName, data); if ("content".equals(nodeName)) { parentNodeName = "skin"; } } else if("mobile-link".equals(parentNodeName)){ String prefix = parentNodeName + Integer.toString(mobile) + "-"; addMessage(prefix + nodeName, data); if ("url".equals(nodeName)) { mobile++; parentNodeName = "skin"; } } else if("accordion".equals(parentNodeName)){ String prefix = parentNodeName + Integer.toString(accordion) + "-"; addMessage(prefix + nodeName, data); if ("content".equals(nodeName)) { accordion++; parentNodeName = "skin"; } } }
  10. … ! <spring:theme code="help-name" var="helpName" /> <spring:theme code="help-content" var="helpContent" />

    <c:if test="${(! empty helpName) && (! empty helpContent) && (linkCount > 0)}"> <p class="boxStrut">&nbsp;</p> </c:if> <c:if test="${(! empty helpName) && (! empty helpContent)}"> <div id="applicationHelp"> <div class="applicationHelp"> <h3><spring:theme code="help-name"/></h3> <div><p><spring:theme code="help-content" /></p> <p><br /></p></div> </div> </div> <div> <p class="applicationHelpBottom">&nbsp;</p> </div> </c:if> ! … JSP Snippet
  11. Issue #2 locales before a single OS was used !

    private void addMessage(String code, String txt) { msgSrc.addMessage(code, Locale.ENGLISH, txt); msgSrc.addMessage(code, Locale.US, txt); }
  12. <marketing-text> <![CDATA[ <p style="font-size: 12px !important; text-indent:0 !important;padding-top:44px;"> PTR (Payroll

    Time Reporting) allows employees to: <ul style="font-size: 12px !important; text-indent:0 !important;"> <li style="font-size: 12px !important; text-indent:0 !important;">Easily submit hours worked and leave taken</li> <li style="font-size: 12px !important; text-indent:0 !important;">View/Update timesheets</li> <li style="font-size: 12px !important; text-indent:0 !important;">Email supervisors and log personal journal information</li> </ul> </p> <p style="font-size: 12px !important; text-indent:0 !important;"> To sign into PTR, you must have an active appointment in the Payroll Personnel System and an UC Merced Net ID (UCMNetID). </p> ]]> </marketing-text>
  13. <useful-link> <title>Contact us</title> <url>https://ptr.ucmerced.edu/contact.aspx</url> </useful-link> <useful-link> <title>About PTR</title> <url>https://ptr.ucmerced.edu/about.aspx</url> </useful-link>

    <useful-link> <title>PTR Help Central</title> <url>https://ptr.ucmerced.edu/help/nethelp/default.htm</url> </useful-link> <useful-link> <title>Payroll Services Website</title> <url>http://payroll.ucmerced.edu/</url> </useful-link>
  14. <help> <name>WARNING</name> <content> <![CDATA[ To protect systems from unauthorized use

    and to ensure that the system is functioning properly, activities on this system are monitored, recorded, and subject to audit. Use of this system is expressed consent to such monitoring and recording. Any unauthorized access or use of this system is prohibited and could be subject to criminal and civil penalties. ]]> </content> </help>
  15. <accordion> <header>About PTR</header> <content> <![CDATA[ <div style="line-height:1.7em; font-size:12px !important;"> <div

    style="font-size: 12px !important;"> PTR (Payroll Time Reporting) allows employees to: </div> <br /> <ul style="font-size: 12px !important;"> <li style="font-size: 12px !important;”> Easily submit hours worked and leave taken</li> <li style="font-size: 12px !important;”> View/Update timesheets</li> <li style="font-size: 12px !important;”> Email supervisors and log personal journal information</li> </ul> <br /> <div style="font-size: 12px !important;"> To sign into PTR, you must have an active appointment in the Payroll Personnel System and an UC Merced Net ID (UCMNetID). </div> </div> ]]> </content> </accordion>
  16. <accordion> <header>Desktop Browser Compatability</header> <content> <![CDATA[ <p style="font-size: 12px !important;

    color:red; line-height: 1.7em;"> Microsoft has recently released Internet Explorer version 10 for Windows 7 operating system. This version of the browser is currently incompatible with PTR. Until a solution has been found we ask that you please use <a href="https://www.google.com/intl/en/chrome/">Chrome</a>, <a href="http://www.mozilla.org/en-US/firefox/new/">Firefox</a>, <a href="http://www.apple.com/safari/">Safari</a> or <a href="http:// windows.microsoft.com/en-us/internet-explorer/downloads/ie-9/worldwide- languages">Internet Explorer version 9</a> browser to access the system. </p> ]]> </content> </accordion>
  17. <mobile-link> <title>Contact us</title> <url>https://ptr.ucmerced.edu/contact.aspx</url> </mobile-link> <mobile-link> <title>About PTR</title> <url>https://ptr.ucmerced.edu/about.aspx</url> </mobile-link>

    <mobile-link> <title>PTR Help Central</title> <url>https://ptr.ucmerced.edu/help/nethelp/default.htm</url> </mobile-link> <mobile-link> <title>Payroll Services Website</title> <url>http://payroll.ucmerced.edu/</url> </mobile-link> </skin>
  18. Other Customizations Encrypted passwords as release attributes Acceptable Use Policy

    verification Logout controller that handles old parameters