Title: Themes Notice: 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. [TOC] ## Overview Custom themes can be created in VCL for each affiliation. This allows a multi-site installation of VCL to have themes that match each affiliation's primary web site theme. When a user logs in, the site will be displayed using the theme specified for that user's affiliation. Additionally, when using [LDAP authentication](/docs/ldapauth.html), the login page for the affiliation will be displayed with the theme matching that affiliation. ## File system structure The themes are in a **themes** directory in the web code. If you installed your web frontend under a directory named **vcl**, you would look in vcl/themes. Each VCL release comes with a **default** theme, which you should see at vcl/themes/default. Typically, you would set up the following directory structure for a new theme: * vcl/themes/mynewtheme * vcl/themes/mynewtheme/page.php * vcl/themes/mynewtheme/images * vcl/themes/mynewtheme/js * vcl/themes/mynewtheme/css The page.php file and css directory are the only ones that are required. After creating the directory structure, you will need to go to the themes directory and run the copydojocss.sh script, passing it the name of the directory containing your new theme as an argument: cd vcl/themes ./copydojocss.sh mynewtheme ## VCL HTML generation There are a few parts to how VCL generates the HTML for any given page. There are some important functions of which to be aware. The first two must be in the page.php file: * getHeader - generates all content up to and including the opening of a div element that will contain the main page content (typically what is to the right of the navigation menu); this div element must have an **id** of **content**; must have $refresh passed to it as an argument, which is then passed to getDojoHTML * getFooter - closes the div element containing the main page content and generates any remaining content to close out the HTML for the page These are functions that exist in utils.php that are available to be called from getHeader and getFooter: * getDojoHTML - returns a string of Dojo related style and javascript; needs to be called in the <head> part of the page; needs to be passed $refresh as an argument * getExtraCSS - returns an array of css files expected to exist in the vcl/css directory that need to be included for the current value of $mode; a link tag needs to be created for each of these files * getSelectLanguagePulldown - returns the html for a form that has a select element for changing the locale of the site * getNavMenu - returns a string of list items that make up the navigation part of the site; needs to be wrapped in <ul> tags; accepts 3 arguments: * $inclogout - 0/1 - should a **Logout** item be at the bottom of the navigation list * $inchome - 0/1 - should a **HOME** item be at the top of the navigation list * $homeurl - (optional) - if $inchome is 1, use this as the href of the HOME link; if $inchome is 1 and $homeurl is not specified, HOME from conf.php is used ## Understanding page.php As noted above, this file must contain getHeader and getFooter. **getHeader** must contain these elements, all of which can be seen in the default theme's page.php file: * opening html and head tags * stylesheet link to "css/vcl.css" * script tag with src="js/code.js" * script block setting the javascript variable *cookiedomain* to the php define *COOKIEDOMAIN* and setting usenls = 0 * a call to getDojoHTML($refresh) in the head section of the HTML * a call to getExtraCSS() with a foreach to add a stylesheet link for each file in the array returned by getExtraCSS() * closing head tag * body tag with its class set to the name of the theme * an unordered list wrapping the string returned by a call to getNavMenu() - this should be inside an if conditional checking for $authed to be true * must end with an opening div tag with an id of *content* **getFooter** must contain these elements: * closing div tag for the content div element * closing body and html tags ## Path references There are a few things to keep in mind with respect to path references. From a web browser's perspective, all HTML generated by getHeader and getFooter will be part of the vcl/index.php file. So, any paths referenced in getHeader and getFooter need to be relative to that - example: <img src="themes/mynewtheme/images/someimage.png">. Any files referenced in css files in the theme's css directory will be relative to that css file. So, if you were to include a reference to an image in the theme's image directory in a css file in the css directory, you would reference it relative to the css directory - example: url(../images/someimage.png) ## Example: bare minimal theme This example shows the bare minimum that must be included. For a more detailed example, look at the default theme include in each release. We'll call the theme "minimal". First, we create a directory under the themes directory for it: :::BashLexer mkdir vcl/themes/minimal Next, we create a css directory and run the copydojocss.sh script: :::BashLexer mkdir vcl/themes/minimal/css cd vcl/themes ./copydojocss.sh minimal Now, we create vcl/themes/minimal/page.php with this content: :::PhpLexer function getHeader($refresh) { global $user, $mode, $authed, $locale, $VCLversion; $rt = "\n"; $rt .= "\n"; $rt .= "\n"; $rt .= "VCL\n"; $rt .= "\n"; $rt .= "\n"; $rt .= "\n"; $rt .= "\n"; $rt .= getDojoHTML($refresh); $extracss = getExtraCSS(); foreach($extracss as $file) $rt .= "\n"; $rt .= "\n\n"; $rt .= "\n\n"; $rt .= "\n"; $rt .= "
\n"; return $rt; } function getFooter() { $year = date("Y"); $rt = "
\n"; $rt .= "\n"; $rt .= "\n"; return $rt; } Finally, we create a basic css file at vcl/themes/minimal/css/minimal.css: :::CssLexer #menulist { float: left; } #content { margin-left: 15em; } ## Using a new theme Themes are assigned on a per-affiliation basis in the affiliation table. This must be done directly in the database by setting the **affiliation.theme** field for an affiliation to the name of a theme in the themes directory. For example, to use our new *minimal* theme, you would set **affiliation.theme** to **minimal** for the desired affiliation. ## Tips and Tricks The VCL web site has some administrative pages that can generate very large tables. If you want them to be completely wrapped in your theme, you will probably need to use tables as part of you main layout instead of just using div elements and css. (Hopefully, all of those large tables will be converted to dojo grids like the Manage Groups page by the 2.4 release.) Mobile themes - If you would like to use a modified theme for mobile devices, you can add a section of code to the top of getHeader and getFooter that detects mobile devices based on $_SERVER['HTTP_USER_AGENT']. If a mobile browser is detected, you can then call a different function that generates mobile specific HTML and returns it to the calling function. Here is an example that could be used in getHeader: :::PhpLexer if(array_key_exists('HTTP_USER_AGENT', $_SERVER) && (eregi('iphone', $_SERVER['HTTP_USER_AGENT']) || eregi('android', $_SERVER['HTTP_USER_AGENT']))) return mobileHeader($refresh); mobileHeader would still need to meet all of the requirements of getHeader, but it would just generate mobile specific HTML. A similar block of code would then be added to getFooter, calling a function named something like mobileFooter.