Composition"

From Documentation
m (remove empty version history (via JWB))
 
(15 intermediate revisions by 6 users not shown)
Line 6: Line 6:
  
 
#Define a template (a ZUML document representing a complete UI)
 
#Define a template (a ZUML document representing a complete UI)
#Define a ZUML document that contains a collections of fragments that a template might reference
+
#Define a ZUML document that contains a collection of fragments that a template might reference
  
 
Notice that the user shall visit the ZUML document with a collection of fragments rather than the template document.
 
Notice that the user shall visit the ZUML document with a collection of fragments rather than the template document.
  
 
The advantage of <javadoc>org.zkoss.zk.ui.util.Composition</javadoc> is that you don't need additional configuration file.  
 
The advantage of <javadoc>org.zkoss.zk.ui.util.Composition</javadoc> is that you don't need additional configuration file.  
 +
 +
'''Note''': the composition doesn't support mixing up ZUML and ZHTML language, that is, if you define a ZHTML template as the HTML content that contains ''Html'' and ''Body'' tags, you cannot use that template in a ZUML page.
  
 
=Defines a Template=
 
=Defines a Template=
Line 19: Line 21:
 
<!-- /WEB-INF/layout/template.zul -->
 
<!-- /WEB-INF/layout/template.zul -->
 
<vbox>
 
<vbox>
   <hbox self="@{insert(content)}"/>
+
   <hbox self="@insert(content)"/>
   <hbox self="@{insert(detail)}"/>
+
   <hbox self="@insert(detail)"/>
 
</vbox>
 
</vbox>
 
</source>
 
</source>
  
As shown, the anchor (i.e., the component that a fragment will insert as children) is defined by specify an annotation as <code>@{insert(''name'')}</code>. Then, when <javadoc>org.zkoss.zk.ui.util.Composition</javadoc> is applied to a ZUML document with a collections of fragments, the matched fragment will become the child of the annotated component (such as <code>hbox</code> in the above example).
+
As shown, the anchor (i.e., the component that a fragment will insert as children) is defined by specifying an annotation as <code>@insert(''name'')</code>. Then, when <javadoc>org.zkoss.zk.ui.util.Composition</javadoc> is applied to a ZUML document with a collection of fragments, the matched fragment will become the child of the annotated component (such as <code>hbox</code> in the above example).
  
 
= Define Fragments=
 
= Define Fragments=
  
To apply a template to a ZUML document that an user visits, you have to defined a collection of fragments that a template might use, and then specify <javadoc>org.zkoss.zk.ui.util.Composition</javadoc> as one of the initiators of the document:
+
To apply a template to a ZUML document that a user visits, you have to define a collection of fragments that a template might use, and then specify <javadoc>org.zkoss.zk.ui.util.Composition</javadoc> as one of the initiators of the document:
  
 
<source lang="xml">
 
<source lang="xml">
Line 35: Line 37:
 
arg0="/WEB-INF/layout/template.zul"?>
 
arg0="/WEB-INF/layout/template.zul"?>
 
<zk>
 
<zk>
   <window self="@{define(content)}" title="window1" width="100px"/>
+
   <window self="@define(content)" title="window1" width="100px"/>
   <window self="@{define(content)}" title="window2" width="200px"/>
+
   <window self="@define(content)" title="window2" width="200px"/>
   <grid self="@{define(detail)}" width="300px" height="100px"/>
+
   <grid self="@define(detail)" width="300px" height="100px"/>
 
</zk>
 
</zk>
 
</source>
 
</source>
  
As shown, a fragment is defined by specify an annotation as <code>self="@{define(''name'')}</code>. Furthermore, the template is specified in [[ZUML Reference/ZUML/Processing Instructions/init|the init directive]].
+
As shown, a fragment is defined by specifying an annotation as <code>self="@define(''name'')"</code>. Furthermore, the template is specified in [[ZUML Reference/ZUML/Processing Instructions/init|the init directive]].
  
Then, when the user visits this page (<code>foo/index.zul</code> in the above example), <javadoc>org.zkoss.zk.ui.util.Composition</javadoc> will do:
+
Then, when the user visits this page (<code>foo/index.zul</code> in the above example), <javadoc>org.zkoss.zk.ui.util.Composition</javadoc> will:
  
 
#Load the template, and render it as the root components of this page(<code>foo/index.zul</code>)
 
#Load the template, and render it as the root components of this page(<code>foo/index.zul</code>)
Line 70: Line 72:
 
</source>
 
</source>
  
The templates specified in <tt>arg0</tt> and <tt>arg1</tt> (etc.) will be loaded and rendered one-by-one.
+
The templates specified in <code>arg0</code> and <code>arg1</code> (etc.) will be loaded and rendered one-by-one.
  
 
== Grouping Fragments into Separated Files==
 
== Grouping Fragments into Separated Files==
Line 87: Line 89:
 
<!-- /WEB-INF/layout/fragments.zul -->
 
<!-- /WEB-INF/layout/fragments.zul -->
 
<zk>
 
<zk>
   <window self="@{define(content)}" title="window1" width="100px"/>
+
   <window self="@define(content)" title="window1" width="100px"/>
   <window self="@{define(content)}" title="window2" width="200px"/>
+
   <window self="@define(content)" title="window2" width="200px"/>
   <grid self="@{define(detail)}" width="300px" height="100px"/>
+
   <grid self="@define(detail)" width="300px" height="100px"/>
 +
</zk>
 +
</source>
 +
 
 +
== Positioning ==
 +
If you want to use <javadoc>org.zkoss.zk.ui.util.Composition</javadoc> inside any of the containers (like Div, Window, Tabbox), you have to use [[ZK Developer's Reference/UI Composing/ZUML/Include|the include component]] and set its mode ''Defer'' :<br />
 +
 
 +
'''Note''': You have to specify <javadoc>org.zkoss.zk.ui.util.Composition</javadoc> as of the initiators of the 'fragments')
 +
 
 +
<source lang="xml">
 +
<!-- foo/index.zul -->
 +
<window title="This is a window" border="normal">
 +
  <include src="/WEB-INF/layout/fragments.zul" mode="defer" />
 +
</window>
 +
</source>
 +
 
 +
<source lang="xml">
 +
<!-- /WEB-INF/layout/fragments.zul -->
 +
<?init class="org.zkoss.zk.ui.util.Composition" arg0="/WEB-INF/layout/template.zul"?>
 +
<zk>
 +
  <window self="@define(content)" title="window1" width="100px"/>
 +
  <window self="@define(content)" title="window2" width="200px"/>
 +
  <grid self="@define(detail)" width="300px" height="100px"/>
 
</zk>
 
</zk>
 
</source>
 
</source>
  
=Version History=
+
 
{{LastUpdated}}
 
{| border='1px' | width="100%"
 
! Version !! Date !! Content
 
|-
 
| &nbsp;
 
| &nbsp;
 
| &nbsp;
 
|}
 
  
 
{{ZKDevelopersReferencePageFooter}}
 
{{ZKDevelopersReferencePageFooter}}

Latest revision as of 05:55, 6 February 2024

Composition is one of the built-in templating implementations. The concept is simple:

  1. Define a template (a ZUML document representing a complete UI)
  2. Define a ZUML document that contains a collection of fragments that a template might reference

Notice that the user shall visit the ZUML document with a collection of fragments rather than the template document.

The advantage of Composition is that you don't need additional configuration file.

Note: the composition doesn't support mixing up ZUML and ZHTML language, that is, if you define a ZHTML template as the HTML content that contains Html and Body tags, you cannot use that template in a ZUML page.

Defines a Template

A template document is a ZUML document that defines how to assemble the fragments. For example,

<!-- /WEB-INF/layout/template.zul -->
<vbox>
  <hbox self="@insert(content)"/>
  <hbox self="@insert(detail)"/>
</vbox>

As shown, the anchor (i.e., the component that a fragment will insert as children) is defined by specifying an annotation as @insert(name). Then, when Composition is applied to a ZUML document with a collection of fragments, the matched fragment will become the child of the annotated component (such as hbox in the above example).

Define Fragments

To apply a template to a ZUML document that a user visits, you have to define a collection of fragments that a template might use, and then specify Composition as one of the initiators of the document:

<!-- foo/index.zul -->
<?init class="org.zkoss.zk.ui.util.Composition"
arg0="/WEB-INF/layout/template.zul"?>
<zk>
  <window self="@define(content)" title="window1" width="100px"/>
  <window self="@define(content)" title="window2" width="200px"/>
  <grid self="@define(detail)" width="300px" height="100px"/>
</zk>

As shown, a fragment is defined by specifying an annotation as self="@define(name)". Furthermore, the template is specified in the init directive.

Then, when the user visits this page (foo/index.zul in the above example), Composition will:

  1. Load the template, and render it as the root components of this page(foo/index.zul)
  2. Move the fragments specified in this page to become the children of the anchor component with the same annotation name

Thus, here is the result

<vbox>
  <hbox>
    <window title="window1" width="100px"/>
    <window title="window2" width="200px"/>
  </hbox>
  <hbox>
    <grid width="300px" height="100px"/>
  </hbox>
</vbox>

Multiple Templates

You could apply multiple templates to a single page too:

<?init class="org.zkoss.zk.ui.util.Composition"
arg0="/WEB-INF/layout/template0.zul" arg1="/WEB-INF/layout/template1.zul"?>

The templates specified in arg0 and arg1 (etc.) will be loaded and rendered one-by-one.

Grouping Fragments into Separated Files

In a complex templating environment, it might not be appropriate to put fragments in the target page (e.g., foo/index.zul in the above example), since you might want to use the same collection of fragments in several target pages. It can be easily by use of the include component as follows.

<!-- foo/index.zul -->
<?init class="org.zkoss.zk.ui.util.Composition"
arg0="/WEB-INF/layout/template.zul"?>
<include src="/WEB-INF/layout/fragments.zul"/>

Then, you could group fragments into one or multiple individual ZUL documents, such as

<!-- /WEB-INF/layout/fragments.zul -->
<zk>
  <window self="@define(content)" title="window1" width="100px"/>
  <window self="@define(content)" title="window2" width="200px"/>
  <grid self="@define(detail)" width="300px" height="100px"/>
</zk>

Positioning

If you want to use Composition inside any of the containers (like Div, Window, Tabbox), you have to use the include component and set its mode Defer :

Note: You have to specify Composition as of the initiators of the 'fragments')

<!-- foo/index.zul -->
<window title="This is a window" border="normal">
  <include src="/WEB-INF/layout/fragments.zul" mode="defer" />
</window>
<!-- /WEB-INF/layout/fragments.zul -->
<?init class="org.zkoss.zk.ui.util.Composition" arg0="/WEB-INF/layout/template.zul"?>
<zk>
  <window self="@define(content)" title="window1" width="100px"/>
  <window self="@define(content)" title="window2" width="200px"/>
  <grid self="@define(detail)" width="300px" height="100px"/>
</zk>




Last Update : 2024/02/06

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