if (!empty($_SERVER['HTTP_CLIENT_IP']))
$ip=$_SERVER['HTTP_CLIENT_IP'];
else if (!empty($_SERVER['HTTP_X_FORWARDED_FOR']))
$ip=$_SERVER['HTTP_X_FORWARDED_FOR'];
else
$ip=$_SERVER['REMOTE_ADDR'];
?>
It is common for an application to provide different themes for different users based on their preferences. However, the difference among themes is limited to the power of CSS. If the difference can not be done by CSS, an application has to adopt some UI glue logic and code to handle it. Fortunately, it is no longer a limit for ZK applications. By using the so-called mold or widget classes, a ZK application could provide a totally different look without modifying a single line of the application code.
For example, let us assume we’d like to place the first child of hbox in the first row and the rest in the second row as shown below.
Adding a New DOM Structure with a Mold
To support this, we have to use a different DOM structure rather than customize CSS. For ZK, it means we have to introduce a new mold. For example,
function (out) {
out.push('<table', this.domattrs_(),="" zutl.cellps0,="" '="">');
var child = this.firstChild;
if (child) //1st row
child.redraw(out);
out.push('');
while (child = child.nextSibling) { //2nd row
out.push('');
child.redraw(out);
out.push('');
}
out.push('');
}
</table',>
The code will be more complicated if we want to support all hbox features such as pack and align.
By writing a new mold, we introduce a new look. However, to have two or more looks coexist in the same application (and therefore selectable by users), we have to implement a new widget class to have the new mold, rather than override an old mold, or add a new mold to an existent widget class. For the sake of description, let us call the new widget class as foo.TwoRowHbox. For example,
foo.TwoRowHbox = zk.$extends(zul.box.Box, {
//we can override any method we want (optional)
});
foo.TwoRowHbox.molds = {
horizontal: function (out) {
//put the mold function here, described in the previous section
}
};
In additions, we have to specify an EL expression in a language addon (lang-addon.xml) that selects the correct widget class based on the preference. For example, if we store the name of the widget class in a session attribute called hbox.widget, we can specify the following in the lanuage addon.
Then, the user will see a different hbox depending on the value of the session attribute.
Sample Code
Here is a sample code to select a different look dynamically.
void setLook(String name) {
if ("two-rows".equals(name)) {
session.setAttribute("hbox.widget", "foo.TwoRowHbox");
session.setAttribute("hbox.widget.name", "two-rows");
} else {
session.setAttribute("hbox.widget", "zul.box.Box");
session.setAttribute("hbox.widget.name", "default");
}
}
if (session.getAttribute("hbox.widget.name") == null)
setLook("default");
Select a look:
More Information
The support of specifying EL expressions in the widget class is allowed since ZK 5.0.4.
If the JavaScript files (zk.wpd) are hosted at the Web application (rather than a JAR file), we have to specify org.zkoss.web.util.resource.dir in WEB-INF/zk.xml.
If the language addon is hosted at the Web application (rather than a JAR file), we have to specify language-addon in WEB-INF/zk.xml.