Understanding the Theming Subsystem"

From Documentation
m
Line 1: Line 1:
 
{{ZKDevelopersReferencePageHeader}}
 
{{ZKDevelopersReferencePageHeader}}
  
{{Template:UnderConstruction}}
+
The collection of the components' stylesheets and associated images is called a theme. Themes control the overall look and feel of a page composed of ZK components. For example, the components using the standard sapphire theme will all follow the same blue-ish color scheme.
 
 
== Overview ==
 
  
The collection of the components' stylesheets and associated images is called a theme. Themes control the overall look and feel of a page composed of ZK components. For example, the components using the standard sapphire theme will all follow the same blue-ish color scheme.
+
Starting from ZK 6.5.2, supporting different themes take a more modularized approach. '''Theme Support Subsystem''' breaks up into a few pluggable modules: '''ThemeRegistry''', '''ThemeResolver''', and '''ThemeProvider'''. ThemeRegistry keeps track of a list of available themes to use. ThemeResolver is responsible for setting and obtaining the current theme. ThemeProvider allows web developers to manipulate the CSS stylesheets actually employed to style the UI components. Customizing these modules enable web developers to modify any part of the theme processing pipeline to fit their particular requirement.
  
Starting from ZK 6.5.2, supporting different themes take a more modularized approach. '''Theme Support Subsystem''' breaks up into a few pluggable modules: '''ThemeRegistry''', '''ThemeResolver''', and '''ThemeProvider'''. Customizing these modules enable web developers to modify any part of the theme processing pipeline to fit their particular requirement.
+
'''Theme Support Subsystem''' is illustrated by the figure below. In addition to the three pluggable modules, there also exist facilities to encapsulate theme information and resolving URLs for locating theme resources.  
  
'''Theme Support Subsystem''' is illustrated by the figure below. In addition to the three pluggable modules, there also exist facilities to encapsulate theme information and resolving URLs for locating theme resources.
+
Please refer to the subsections for more information on the constituent parts.
  
 
[[File:ThemeSubsystem.png|900px]]
 
[[File:ThemeSubsystem.png|900px]]
 
== Information about a Theme ==
 
 
'''Available in ZK 6.5.2+'''
 
 
Apart from having a name, a theme could be associated with many attributes. Encapsulating theme-specific attributes is defined in <javadoc>org.zkoss.web.theme.Theme</javadoc>. Each theme should have at least a name, which helps the web application to identify it. Web developers should extend this class to define other attributes associated with concrete themes, such as file paths included in a theme, or variables that could be used to parameterize a theme.
 
 
Standard themes have additional attributes like a more descriptive name for displaying purposes, a priority value to help the system choose the theme to use, and a origin of the theme's resources (i.e. CSS and image files). Standard theme information is provided by <javadoc>org.zkoss.web.theme.StandardTheme</javadoc>
 
 
<source lang="java">
 
import org.zkoss.web.theme.Theme;
 
 
public class MyTheme extends Theme {
 
    // theme-specific attributes
 
    ...
 
    // getters/setters
 
    ...
 
}
 
</source>
 
 
== Registering your Theme ==
 
 
Before using a theme, it must be registered so that the system knows about its existence and where to retrieve its resources (from a jar file or from a folder). <javadoc>org.zkoss.zul.theme.Themes</javadoc> provides several static methods for registering your themes.
 
 
'''Available in ZK all editions'''
 
 
The simplest registration is to tell the web application about the name of the theme. It will be assumed that the theme is for desktop only, and its resources should be retrieved from a jar file. For example,
 
 
<source lang="java">
 
Themes.register("custom");
 
</source>
 
 
'''Available in ZK 6.5.2+ all editions'''
 
 
Starting from ZK 6.5.2, theme resources could also be placed inside a folder. To indicate that a theme is folder-based, please use the following form.
 
 
<source lang="java">
 
Themes.register("custom", ThemeOrigin.FOLDER);
 
</source>
 
 
'''Available in ZK EE 6.5.2+'''
 
 
In ZK EE 6.5.0+, components would appear differently when viewed on tablet devices. A theme could be applicable to desktop only, tablet only, or both. To signify that a theme also serves tablet devices, please attach a '''"tablet:"''' prefix in front of the theme name when registering. For example,
 
 
<source lang="java">
 
Themes.register("tablet:custom");
 
</source>
 
 
=== Creating Custom Theme Registration Service ===
 
 
'''Available in ZK 6.5.2+ all editions'''
 
 
<javadoc>org.zkoss.web.theme.ThemeRegistry</javadoc> defines the interface to create a repository of themes available to the web application. <javadoc>org.zkoss.zul.theme.DesktopThemeRegistry</javadoc> (for ZK CE/PE) and <javadoc>org.zkoss.zkmax.theme.ResponsiveThemeRegistry</javadoc> (for ZK EE) are the standard implementations that actually stores the registered themes.
 
 
Standard theme registries would accept all theme registrations. Duplicate registration would update theme information. Registered themes are available to all users. (For ZK EE, desktop clients would only have desktop themes available, and tablet clients would only have tablet themes available.) If you would like to modify any of these behaviors, please provide a custom ThemeRegistry.
 
 
For example, a custom ThemeRegistry could be created by implementing <javadoc>org.zkoss.web.theme.ThemeRegistry</javadoc> interface directly, or extending one of the standard implementations, depending on the ZK edition you are using.
 
 
<source lang="java">
 
package foo;
 
 
public class CustomThemeRegistry implements ThemeRegistry {
 
    ...
 
    @Override
 
    public boolean register(Theme theme) {
 
        ...
 
    }
 
 
    @Override
 
    public boolean deregister(Theme theme) {
 
        ...
 
    }
 
 
    @Override
 
    public Theme[] getThemes() {
 
        ...
 
    }
 
 
    @Override
 
    public Theme getTheme(String themeName) {
 
        ...
 
    }
 
 
    @Override
 
    public boolean hasTheme(String themeName) {
 
        ...
 
    }
 
 
}
 
</source>
 
 
And then, configure the custom ThemeRegistry in '''WEB-INF/zk.xml'''.
 
 
<source lang="xml">
 
<zk>
 
<desktop-config>
 
<theme-registry-class>foo.CustomThemeRegistry</theme-registry-class>
 
</desktop-config>
 
</zk>
 
</source>
 
 
To access the current theme registry, please refer to <javadoc class="true" method="getThemeRegistry()">org.zkoss.web.fn.ThemeFns</javadoc> and <javadoc class="true" method="setThemeRegistry(org.zkoss.web.theme.ThemeRegistry)">org.zkoss.web.fn.ThemeFns</javadoc>.
 
 
== Switching Themes ==
 
 
The user could switch to any registered themes by setting a cookie or a library property.
 
 
Standard theme resolution checks the theme settings in the following order.
 
 
# Cookies
 
# Library property
 
# Theme priority
 
 
=== Dynamically switching themes using Cookies ===
 
 
<source lang="java">
 
Themes.setTheme(Executions.getCurrent(), "custom");
 
Executions.sendRedirect();
 
</source>
 
 
Internally, <javadoc>org.zkoss.zul.theme.CookieThemeResolver</javadoc> provides this functionality.
 
 
=== Dynamically switching themes using Library Property ===
 
 
Library property could be used to assign a preferred theme when the current theme setting could not be obtained from Cookies.
 
 
'''Programmatically:'''
 
 
<source lang="java">
 
Library.setProperty("org.zkoss.theme.preferred", "custom");
 
Executions.sendRedirect();
 
</source>
 
 
'''Declaratively:''' in ('''WEB-INF/zk.xml''')
 
<source lang="xml">
 
<library-property>
 
<name>org.zkoss.theme.preferred</name>
 
    <value>breeze</value>
 
</library-property>
 
</source>
 
 
=== Theme of the last resort ===
 
 
If the previous two check points do not yield any result, the theme with the highest priority would be chosen. Theme priorities are usually assigned using the theme registration as well, but could also be changed dynamically.
 
 
Please refer to <javadoc>org.zkoss.zul.theme.Themes</javadoc> for its family of register() methods.
 
 
=== Customize the Theme Resolution Process ===
 
 
Web developers could also add other ways for setting the current theme by writing a custom ''<javadoc>org.zkoss.web.theme.ThemeResolver</javadoc>'''.
 
 
If you would like to communicate theme name via session instead, you would a class like the following:
 
 
<source lang="java">
 
package foo;
 
 
public class SessionThemeResolver implements ThemeResolver {
 
    @Override
 
    public String getTheme(HttpServletRequest request) {
 
        Session sess = request.getSession();
 
        if (sess != null) {
 
            return sess.getAttribute("mytheme");
 
        }
 
    }
 
 
    @Override
 
    public void setTheme(HttpServletRequest request, HttpServletResponse response, String themeName) {
 
        Session sess = request.getSession();
 
        if (sess != null) {
 
            sess.setAttribute("mytheme", themeName);
 
        }
 
    }
 
}
 
</source>
 
 
and configure the custom ThemeResolver in '''WEB-INF/zk.xml'''.
 
 
<source lang="xml">
 
<zk>
 
    <desktop-config>
 
        <theme-resolver-class>foo.ServletThemeResolver</theme-resolver-class>
 
    </desktop-config>
 
</zk>
 
</source>
 
 
To access the current theme resolver, please refer to <javadoc class="true" method="getThemeResolver()">org.zkoss.web.fn.ThemeFns</javadoc> and <javadoc class="true" method="setThemeResolver(org.zkoss.web.theme.ThemeRegistry)">org.zkoss.web.fn.ThemeFns</javadoc>.
 
 
== Providing Theme Resources ==
 
 
After switching to another theme, ThemeProvider is responsible for getting the correct stylesheets to the client. This is done by manipulating the list of widget stylesheets comprising the theme. Web developers could create a custom ThemeProvider to change the caching for the widget stylesheets, inject additional widget stylesheets, reject unwanted widget stylesheets, and/or replace some widget stylesheets with another set.
 
 
== Resolving Theme URLs ==
 
Themes comprises of stylesheets and images. The URLs for those resources must be resolved once the theme changes. There are utility methods created for this purpose.
 
  
 
{{ZKDevelopersReferenceHeadingToc}}
 
{{ZKDevelopersReferenceHeadingToc}}
  
 
{{ZKDevelopersReferencePageFooter}}
 
{{ZKDevelopersReferencePageFooter}}

Revision as of 17:09, 7 April 2013


Understanding the Theming Subsystem


The collection of the components' stylesheets and associated images is called a theme. Themes control the overall look and feel of a page composed of ZK components. For example, the components using the standard sapphire theme will all follow the same blue-ish color scheme.

Starting from ZK 6.5.2, supporting different themes take a more modularized approach. Theme Support Subsystem breaks up into a few pluggable modules: ThemeRegistry, ThemeResolver, and ThemeProvider. ThemeRegistry keeps track of a list of available themes to use. ThemeResolver is responsible for setting and obtaining the current theme. ThemeProvider allows web developers to manipulate the CSS stylesheets actually employed to style the UI components. Customizing these modules enable web developers to modify any part of the theme processing pipeline to fit their particular requirement.

Theme Support Subsystem is illustrated by the figure below. In addition to the three pluggable modules, there also exist facilities to encapsulate theme information and resolving URLs for locating theme resources.

Please refer to the subsections for more information on the constituent parts.

ThemeSubsystem.png





Last Update : 2013/04/07

Copyright © Potix Corporation. This article is licensed under GNU Free Documentation License.