Foreign Templating Framework"
m ((via JWB)) |
|||
(34 intermediate revisions by 3 users not shown) | |||
Line 2: | Line 2: | ||
=Employment/Purpose= | =Employment/Purpose= | ||
− | Here | + | Here we describe how to make a ZUL page to be assembled at the client by using Ajax to request ZUL pages separately in a foreign templating framework<ref>[http://tiles.apache.org/ Apache Tiles] is a typical templating framework and allows developers to assemble UI at both server and client.</ref>. |
− | |||
− | ZK supports many powerful layout components, such as portallayout, borderlayout, tablelayout, columnlayout and so on<ref>For more information, please refer to [[ZK Component Reference]].</ref>. | + | You could skip this chapter if you'd like to use ZK's templating technology, such as [[ZK Developer's Reference/UI Patterns/Templating/Composition|Templating: composition]], [[ZK Developer's Reference/UI Composing/ZUML/Include|Servlet's inclusion]] (javax.servlet.RequestDispatcher's include) and [[ZK Developer's Reference/UI Composing/Macro Component|macro components]]. |
+ | |||
+ | ZK also supports many powerful layout components, such as portallayout, borderlayout, tablelayout, columnlayout and so on<ref>For more information, please refer to [[ZK Component Reference]].</ref>. You could use them to have similar or better effect, and skip this chapter. | ||
<blockquote> | <blockquote> | ||
Line 12: | Line 13: | ||
</blockquote> | </blockquote> | ||
− | =DOCTYPE= | + | =Prerequisite= |
+ | ==DOCTYPE== | ||
To use ZK components correctly, the templating page must specify DOCTYPE as follows. | To use ZK components correctly, the templating page must specify DOCTYPE as follows. | ||
Line 22: | Line 24: | ||
<html> | <html> | ||
... | ... | ||
+ | </source> | ||
+ | |||
+ | ==Browser Cache== | ||
+ | |||
+ | Though optional, it is suggested to disable the browser to cache the result page. It can be done as follows. | ||
+ | |||
+ | <source lang="xml"> | ||
+ | <html xmlns="http://www.w3.org/1999/xhtml"> | ||
+ | <head> | ||
+ | <meta http-equiv="Pragma" content="no-cache" /> | ||
+ | <meta http-equiv="Expires" content="-1" /> | ||
</source> | </source> | ||
=Make a ZUL page as a fragment= | =Make a ZUL page as a fragment= | ||
+ | ==Include a ZUL page when receiving a request== | ||
By default, if a ZUL page is requested by the browser directly, it will generate a complete HTML structure, including HTML, HEAD and BODY tags. On the other hand, if the assembling is done by inclusion (javax.servlet.RequestDispatcher's include), a ZUL page will be generated as a HTML fragment without HTML, HEAD, and BODY. For example, if a ZUL page is included by <code>jsp:include</code>, then it won't generate HTML/HEAD/BODY, such that the following JSP page will be rendered correctly. | By default, if a ZUL page is requested by the browser directly, it will generate a complete HTML structure, including HTML, HEAD and BODY tags. On the other hand, if the assembling is done by inclusion (javax.servlet.RequestDispatcher's include), a ZUL page will be generated as a HTML fragment without HTML, HEAD, and BODY. For example, if a ZUL page is included by <code>jsp:include</code>, then it won't generate HTML/HEAD/BODY, such that the following JSP page will be rendered correctly. | ||
Line 45: | Line 59: | ||
</blockquote> | </blockquote> | ||
− | == | + | ==Load a ZUL page with an Ajax request== |
− | + | As described above, if a ZUL page is requested by the browser directly, it will, by default, generate a complete HTML structure, including HTML, HEAD and BODY tags. To disable it, you could specify a special parameter called <code>zk.redrawCtrl=page</code>. For example, you might have a HTML page that loads a ZUL page at the client with jQuery as follows. | |
− | + | <source lang="xml" highlight="10"> | |
− | + | <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"> | |
+ | <html> | ||
+ | <head> | ||
+ | <title>Mash-up of ZUML apges</title> | ||
+ | <script src="http://code.jquery.com/jquery-1.4.2.min.js"> | ||
+ | </script> | ||
+ | </head> | ||
+ | <body> | ||
+ | <div id="anchor"></div> | ||
+ | <button onclick="$('#anchor').load('foo.zul?zk.redrawCtrl=page')">Load the fragment</button> | ||
+ | </body> | ||
+ | </html> | ||
+ | </source> | ||
+ | |||
+ | The <code>zk.redrawCtrl</code> parameter is used to control how a ZUL page is specified. In this case, since <code>page</code> is specified, the generation of HTML, HEAD and BODY tags are disabled. | ||
+ | |||
+ | ===Alternative: using the request-scoped attribute called <code>org.zkoss.zk.ui.page.redrawCtrl</code>=== | ||
+ | If a ZUL page is always loaded as a fragment by the client, you could specify the request-scoped attribute called <code>org.zkoss.zk.ui.page.redrawCtrl</code> (<javadoc method="PAGE_REDRAW_CONTROL">org.zkoss.zk.ui.sys.Attributes</javadoc>) with <code>page</code>, such that the generation of HTML, HEAD and BODY tags are always disabled no matter if the <code>zk.redrawCtrl</code> parameter is specified or not. | ||
For example, | For example, | ||
− | <source lang="xml"> | + | <source lang="xml" highlight="2"> |
− | < | + | <window title="whatever content you want"/> |
− | < | + | <custom-attributes scope="request" org.zkoss.zk.ui.page.redrawCtrl="page"/> |
− | |||
... | ... | ||
− | + | </window> | |
</source> | </source> | ||
− | + | Then, you don't need to specify the <code>zk.redrawCtl</code> parameter when loading it at the client (e.g., <code>$('#anchor').load('foo.zul')</code>). | |
Of course, if the fragment itself is a JSP page and then use inclusion to include a ZUL page (or use ZK JSP Tags), then the generated HTML structure is already a correct HTML fragment (and you don't need to anything described above). | Of course, if the fragment itself is a JSP page and then use inclusion to include a ZUL page (or use ZK JSP Tags), then the generated HTML structure is already a correct HTML fragment (and you don't need to anything described above). | ||
+ | |||
+ | ===Server-side memory optimization: turn off browser cache=== | ||
+ | As described in [[http://books.zkoss.org/wiki/ZK_Developer%27s_Reference/Integration/Use_ZK_in_JSP#Browser_Cache|Use ZK in JSP]], the memory footprint at the server can be improved by turning off the browser cache for the HTML page that will load ZUL pages later. For example, we could add <code>no-cache</code> and <code>expires</code> as follows (line 4 and 5): | ||
+ | |||
+ | <source lang="xml" highlight="10" highlight="4,5"> | ||
+ | <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"> | ||
+ | <html> | ||
+ | <head> | ||
+ | <meta http-equiv="Pragma" content="no-cache" /> | ||
+ | <meta http-equiv="Expires" content="-1" /> | ||
+ | <title>Mash-up of ZUML apges</title> | ||
+ | <script src="http://code.jquery.com/jquery-1.4.2.min.js"> | ||
+ | </script> | ||
+ | </head> | ||
+ | <body> | ||
+ | <div id="anchor"></div> | ||
+ | <button onclick="$('#anchor').load('foo.zul')">Load the fragment</button> | ||
+ | </body> | ||
+ | </html> | ||
+ | </source> | ||
+ | |||
+ | In addition, we have to specify a request-scoped attribute called <code>org.zkoss.zk.desktop.nocache</code> in the ZUL page being loaded as follows: | ||
+ | |||
+ | <source lang="xml" highlight="2"> | ||
+ | <window title="whatever content you want"/> | ||
+ | <custom-attributes scope="request" org.zkoss.zk.desktop.nocache="true" | ||
+ | org.zkoss.zk.ui.page.redrawCtrl="page"/> | ||
+ | ... | ||
+ | </window> | ||
+ | </source> | ||
+ | |||
+ | <blockquote> | ||
+ | ---- | ||
+ | '''Note:''' since 5.0.8, assigning <code>page</code> to the <code>zk.redrawCtrl</code> parameter implies ''no-cache'', i.e., <code>zk.redrawCtrl=page</code> implies <code>org.zkoss.zk.desktop.nocache="true"</code>. | ||
+ | </blockquote> | ||
+ | |||
+ | ==ID Generator== | ||
+ | |||
+ | Each ZUL page we request by Ajax as described above will be an independent desktop. It means the browser window will have several desktops, if we assemble UI this way. Thus, the component's UUID must be unique across different desktops (of the same session<ref>In short, component's UUID must be unquie in the same session. It is OK to be duplicated in different session.</ref>). The default ID generator can handle it well. | ||
+ | |||
+ | However, if you use a customized <javadoc type="interface">org.zkoss.zk.ui.sys.IdGenerator</javadoc>, you have to generate component's UUID (<javadoc method="nextComponentUuid(org.zkoss.zk.ui.Desktop, org.zkoss.zk.ui.Component)" type="interface">org.zkoss.zk.ui.sys.IdGenerator</javadoc>) correctly. A typical trick is to encode desktop's ID as part of component's UUID. | ||
+ | |||
+ | <blockquote> | ||
+ | ---- | ||
+ | <references/> | ||
+ | </blockquote> | ||
+ | |||
+ | =Communicate among ZUL pages= | ||
+ | |||
+ | If a ZUL page is loaded separately with Ajax, an independent desktop is created. For example, the following HTML page will create three desktops. | ||
+ | |||
+ | <source lang="xml" highlight="24,30,36"> | ||
+ | <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" | ||
+ | "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"> | ||
+ | <html xmlns="http://www.w3.org/1999/xhtml"> | ||
+ | <head> | ||
+ | <meta http-equiv="Pragma" content="no-cache" /> | ||
+ | <meta http-equiv="Expires" content="-1" /> | ||
+ | <script type="text/javascript" | ||
+ | src="http://code.jquery.com/jquery-1.4.2.js"></script> | ||
+ | |||
+ | <title>Assembling at the client with Ajax</title> | ||
+ | </head> | ||
+ | <body> | ||
+ | <table> | ||
+ | <tr> | ||
+ | <td id="top" colspan="2">top</td> | ||
+ | </tr> | ||
+ | <tr> | ||
+ | <td id="left">left</td> | ||
+ | <td id="right">right</td> | ||
+ | </tr> | ||
+ | </table> | ||
+ | <script> | ||
+ | $(function() { | ||
+ | $.get("/frags/banner.zul", | ||
+ | {width : "600px"}, | ||
+ | function(response) { | ||
+ | $("#top").html(response); | ||
+ | } | ||
+ | ); | ||
+ | $.get("/frags/leftside.zul", | ||
+ | {width : "300px"}, | ||
+ | function(response) { | ||
+ | $("#left").html(response); | ||
+ | } | ||
+ | ); | ||
+ | $.get("/frags/rightside.zul", | ||
+ | {width : "300px"}, | ||
+ | function(response) { | ||
+ | $("#right").html(response); | ||
+ | } | ||
+ | ); | ||
+ | }); | ||
+ | </script> | ||
+ | </body> | ||
+ | </html> | ||
+ | </source> | ||
+ | |||
+ | Since they are in different desktops, you have to use the ''group-scoped'' event queue<ref>The group-scoped event queue is available only in ZK EE. For ZK CE, you have to use the session-scoped event queue.</ref> if you want to send events from one desktop (such as leftside.zul) to another (such as rightside.zul). For more information, please refer to [[ZK_Developer%27s_Reference/Event_Handling/Event_Queues|Event Queues]]. | ||
+ | |||
+ | <blockquote> | ||
+ | ---- | ||
+ | <references/> | ||
+ | </blockquote> | ||
=Version History= | =Version History= | ||
− | {| | + | {| class='wikitable' | width="100%" |
! Version !! Date !! Content | ! Version !! Date !! Content | ||
|- | |- |
Latest revision as of 07:33, 8 July 2022
Employment/Purpose
Here we describe how to make a ZUL page to be assembled at the client by using Ajax to request ZUL pages separately in a foreign templating framework[1].
You could skip this chapter if you'd like to use ZK's templating technology, such as Templating: composition, Servlet's inclusion (javax.servlet.RequestDispatcher's include) and macro components.
ZK also supports many powerful layout components, such as portallayout, borderlayout, tablelayout, columnlayout and so on[2]. You could use them to have similar or better effect, and skip this chapter.
- ↑ Apache Tiles is a typical templating framework and allows developers to assemble UI at both server and client.
- ↑ For more information, please refer to ZK Component Reference.
Prerequisite
DOCTYPE
To use ZK components correctly, the templating page must specify DOCTYPE as follows.
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"
"http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html>
...
Browser Cache
Though optional, it is suggested to disable the browser to cache the result page. It can be done as follows.
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
<meta http-equiv="Pragma" content="no-cache" />
<meta http-equiv="Expires" content="-1" />
Make a ZUL page as a fragment
Include a ZUL page when receiving a request
By default, if a ZUL page is requested by the browser directly, it will generate a complete HTML structure, including HTML, HEAD and BODY tags. On the other hand, if the assembling is done by inclusion (javax.servlet.RequestDispatcher's include), a ZUL page will be generated as a HTML fragment without HTML, HEAD, and BODY. For example, if a ZUL page is included by jsp:include
, then it won't generate HTML/HEAD/BODY, such that the following JSP page will be rendered correctly.
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"
"http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<%-- a JSP page --%>
<html>
<body>
<jsp:include page="frag.zul"/>
...
In other words, if the result page is assembled when the request is received, you don't need to do anything specially[1]. However, if the assembling is done at the client side by using Ajax to request fragments after loaded, you have to read the following section.
- ↑ You might take a look at Use ZK in JSP for more information.
Load a ZUL page with an Ajax request
As described above, if a ZUL page is requested by the browser directly, it will, by default, generate a complete HTML structure, including HTML, HEAD and BODY tags. To disable it, you could specify a special parameter called zk.redrawCtrl=page
. For example, you might have a HTML page that loads a ZUL page at the client with jQuery as follows.
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html>
<head>
<title>Mash-up of ZUML apges</title>
<script src="http://code.jquery.com/jquery-1.4.2.min.js">
</script>
</head>
<body>
<div id="anchor"></div>
<button onclick="$('#anchor').load('foo.zul?zk.redrawCtrl=page')">Load the fragment</button>
</body>
</html>
The zk.redrawCtrl
parameter is used to control how a ZUL page is specified. In this case, since page
is specified, the generation of HTML, HEAD and BODY tags are disabled.
Alternative: using the request-scoped attribute called org.zkoss.zk.ui.page.redrawCtrl
If a ZUL page is always loaded as a fragment by the client, you could specify the request-scoped attribute called org.zkoss.zk.ui.page.redrawCtrl
(Attributes.PAGE_REDRAW_CONTROL) with page
, such that the generation of HTML, HEAD and BODY tags are always disabled no matter if the zk.redrawCtrl
parameter is specified or not.
For example,
<window title="whatever content you want"/>
<custom-attributes scope="request" org.zkoss.zk.ui.page.redrawCtrl="page"/>
...
</window>
Then, you don't need to specify the zk.redrawCtl
parameter when loading it at the client (e.g., $('#anchor').load('foo.zul')
).
Of course, if the fragment itself is a JSP page and then use inclusion to include a ZUL page (or use ZK JSP Tags), then the generated HTML structure is already a correct HTML fragment (and you don't need to anything described above).
Server-side memory optimization: turn off browser cache
As described in [ZK in JSP], the memory footprint at the server can be improved by turning off the browser cache for the HTML page that will load ZUL pages later. For example, we could add no-cache
and expires
as follows (line 4 and 5):
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html>
<head>
<meta http-equiv="Pragma" content="no-cache" />
<meta http-equiv="Expires" content="-1" />
<title>Mash-up of ZUML apges</title>
<script src="http://code.jquery.com/jquery-1.4.2.min.js">
</script>
</head>
<body>
<div id="anchor"></div>
<button onclick="$('#anchor').load('foo.zul')">Load the fragment</button>
</body>
</html>
In addition, we have to specify a request-scoped attribute called org.zkoss.zk.desktop.nocache
in the ZUL page being loaded as follows:
<window title="whatever content you want"/>
<custom-attributes scope="request" org.zkoss.zk.desktop.nocache="true"
org.zkoss.zk.ui.page.redrawCtrl="page"/>
...
</window>
Note: since 5.0.8, assigning
page
to thezk.redrawCtrl
parameter implies no-cache, i.e.,zk.redrawCtrl=page
impliesorg.zkoss.zk.desktop.nocache="true"
.
ID Generator
Each ZUL page we request by Ajax as described above will be an independent desktop. It means the browser window will have several desktops, if we assemble UI this way. Thus, the component's UUID must be unique across different desktops (of the same session[1]). The default ID generator can handle it well.
However, if you use a customized IdGenerator, you have to generate component's UUID (IdGenerator.nextComponentUuid(Desktop, Component)) correctly. A typical trick is to encode desktop's ID as part of component's UUID.
- ↑ In short, component's UUID must be unquie in the same session. It is OK to be duplicated in different session.
Communicate among ZUL pages
If a ZUL page is loaded separately with Ajax, an independent desktop is created. For example, the following HTML page will create three desktops.
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"
"http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
<meta http-equiv="Pragma" content="no-cache" />
<meta http-equiv="Expires" content="-1" />
<script type="text/javascript"
src="http://code.jquery.com/jquery-1.4.2.js"></script>
<title>Assembling at the client with Ajax</title>
</head>
<body>
<table>
<tr>
<td id="top" colspan="2">top</td>
</tr>
<tr>
<td id="left">left</td>
<td id="right">right</td>
</tr>
</table>
<script>
$(function() {
$.get("/frags/banner.zul",
{width : "600px"},
function(response) {
$("#top").html(response);
}
);
$.get("/frags/leftside.zul",
{width : "300px"},
function(response) {
$("#left").html(response);
}
);
$.get("/frags/rightside.zul",
{width : "300px"},
function(response) {
$("#right").html(response);
}
);
});
</script>
</body>
</html>
Since they are in different desktops, you have to use the group-scoped event queue[1] if you want to send events from one desktop (such as leftside.zul) to another (such as rightside.zul). For more information, please refer to Event Queues.
- ↑ The group-scoped event queue is available only in ZK EE. For ZK CE, you have to use the session-scoped event queue.
Version History
Version | Date | Content |
---|---|---|
5.0.5 | October, 2010 | ZUL page is able to be generated as a HTML fragment. |