Repository: wicket
Updated Branches:
  refs/heads/grails-maven-integration 721927ef3 -> d1fc97313


Added chapter on component queuing from Igor's blog post


Project: http://git-wip-us.apache.org/repos/asf/wicket/repo
Commit: http://git-wip-us.apache.org/repos/asf/wicket/commit/d1fc9731
Tree: http://git-wip-us.apache.org/repos/asf/wicket/tree/d1fc9731
Diff: http://git-wip-us.apache.org/repos/asf/wicket/diff/d1fc9731

Branch: refs/heads/grails-maven-integration
Commit: d1fc97313f600e8e9ba2c4ef2e3127aff8c07f35
Parents: 721927e
Author: Andrea Del Bene <[email protected]>
Authored: Tue Mar 31 21:59:39 2015 +0200
Committer: Andrea Del Bene <[email protected]>
Committed: Tue Mar 31 21:59:39 2015 +0200

----------------------------------------------------------------------
 wicket-user-guide/grails-app/conf/Config.groovy |   2 +-
 .../src/docs/guide/componentQueueing.gdoc       |   2 +
 .../componentQueueing/componentQueueing_1.gdoc  | 159 +++++++++++++++++++
 .../componentQueueing/componentQueueing_2.gdoc  |  23 +++
 .../componentQueueing/componentQueueing_3.gdoc  |   5 +
 .../componentQueueing/componentQueueing_4.gdoc  |  31 ++++
 .../componentQueueing/componentQueueing_5.gdoc  |   1 +
 wicket-user-guide/src/docs/guide/toc.yml        |   7 +
 8 files changed, 229 insertions(+), 1 deletion(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/wicket/blob/d1fc9731/wicket-user-guide/grails-app/conf/Config.groovy
----------------------------------------------------------------------
diff --git a/wicket-user-guide/grails-app/conf/Config.groovy 
b/wicket-user-guide/grails-app/conf/Config.groovy
index fd46c0e..d49fb22 100644
--- a/wicket-user-guide/grails-app/conf/Config.groovy
+++ b/wicket-user-guide/grails-app/conf/Config.groovy
@@ -95,7 +95,7 @@ log4j = {
 grails.doc.title = "Apache Wicket User Guide"
 grails.doc.version = "7.0"
 grails.doc.subtitle = "Free Online Guide for Apache Wicket framework"
-grails.doc.authors = "Andrea Del Bene, Martin Grigorov, Carsten Hufe, 
Christian Kroemer, Daniel Bartl, Paul Borș, Tobias Soloschenko"
+grails.doc.authors = "Andrea Del Bene, Martin Grigorov, Carsten Hufe, 
Christian Kroemer, Daniel Bartl, Paul Borș, Tobias Soloschenko, Igor Vaynberg"
 grails.doc.images = new File("src/docs/img")
 grails.doc.css = new File("src/docs/css")
 grails.doc.logo = """<a href="/" target="_blank"><img height="80px" 
src="http://wicket.apache.org/guide/img/apache-wicket.png"/></a>"""

http://git-wip-us.apache.org/repos/asf/wicket/blob/d1fc9731/wicket-user-guide/src/docs/guide/componentQueueing.gdoc
----------------------------------------------------------------------
diff --git a/wicket-user-guide/src/docs/guide/componentQueueing.gdoc 
b/wicket-user-guide/src/docs/guide/componentQueueing.gdoc
new file mode 100644
index 0000000..7f3669b
--- /dev/null
+++ b/wicket-user-guide/src/docs/guide/componentQueueing.gdoc
@@ -0,0 +1,2 @@
+So far to build component hierarchy we have explicitly added each component 
and container in accordance with the corresponding markup. This necessary step 
can involve repetitive and boring code which must be change every time we 
decide to change markup hierarchy. 
+Component queueing is a new feature in Wicket 7 that solves this problem 
allowing Wicket to build component hierarchy in Java automatically making your 
code simpler and more maintainable. This chapter should serve as a short 
introduction to what Component Queueing is and what problems it is trying to 
solve.

http://git-wip-us.apache.org/repos/asf/wicket/blob/d1fc9731/wicket-user-guide/src/docs/guide/componentQueueing/componentQueueing_1.gdoc
----------------------------------------------------------------------
diff --git 
a/wicket-user-guide/src/docs/guide/componentQueueing/componentQueueing_1.gdoc 
b/wicket-user-guide/src/docs/guide/componentQueueing/componentQueueing_1.gdoc
new file mode 100644
index 0000000..62e3a8f
--- /dev/null
+++ 
b/wicket-user-guide/src/docs/guide/componentQueueing/componentQueueing_1.gdoc
@@ -0,0 +1,159 @@
+With Wicket as developers we use to define the hierarchy of components in the 
markup templates:
+
+{code:html}
+<form wicket:id='customer'>
+    <input wicket:id='first' type='text'/>
+    <input wicket:id='last' type='text'/>
+    <div wicket:id="child">
+        <input wicket:id='first' type='text'/>
+        <input wicket:id='last' type='text'/>
+        <input wicket:id='dob' type='date'/>
+    </div>
+</form>
+{code}
+
+and then we repeat the same hierarchy in Java code:
+
+{code}
+Form form=new Form("customer");
+add(form);
+ 
+form.add(new TextField("first"));
+form.add(new TextField("last"));
+ 
+WebMarkupContainer child=new WebMarkupContainer("child");
+form.add(child);
+ 
+child.add(new TextField("first"));
+child.add(new TextField("last"));
+child.add(new TextField("dob"));
+{code}
+
+The need for the hierarchy in the markup is obvious, it is simply how the 
markup works. On the Java side of things it may not be immediately apparent. 
After all, why can we not write the code like this?
+
+{code}
+add(new Form("customer"));
+add(new TextField("first"));
+add(new TextField("last"));
+WebMarkupContainer child=new WebMarkupContainer("child");
+add(child);
+add(new TextField("first"));
+add(new TextField("last"));
+add(new TextField("dob"));
+{code}
+
+There are a couple of reasons:
+
+* Ambiguities that happen with duplicate ids
+* Inheriting state from parent to child
+
+We will examine these below.
+
+h3. Markup Id Ambiguities
+
+In the example above we have a form that collects the name of a customer along 
with the name of their child and the child’s date of birth. We mapped the 
name of the customer and child to form components with wicket ids @first@ and 
@last@. If we were to add all the components to the same parent we would get an 
error because we cannot have two components with the same wicket id under the 
same parent (two components with id @first@ and two with id @last@). 
+Without hierarchy in Java we would have to make sure that all wicket ids in a 
markup file are unique, no small feat in a non-trivial page or panel. But, with 
hierarchy on the Java side we just have to make sure that no parent has two 
children with the same id, which is trivial.
+
+h3. Inheriting State From Parents
+
+Suppose we wanted to hide form fields related to the child in the example 
above when certain conditions are met. Without hierarchy we would have to 
modify the @first@, @last@, and @dob@ fields to implement the visibility check. 
Worse, whenever we would add a new child related field we would have to 
remember to implement the same check; this is a maintenance headache. With 
hierarchy this is easy, simply hide the parent container and all children will 
be hidden as well — the code lives in one place and is automatically 
inherited by all descendant components. Thus, hierarchy on the Java side allows 
us to write succinct and maintainable code by making use of the parent-child 
relationship of components.
+
+h3. Pain Points of the Java-Side Hierarchy
+
+While undeniably useful, the Java-side hierarchy can be a pain to maintain. It 
is very common to get requests to change things because the designer needs to 
wrap some components in a @div@ with a dynamic style or class attribute. 
Essentially we want to go from:
+
+{code:html}
+<form wicket:id='customer'>
+    <input wicket:id='first' type='text'/>
+    <input wicket:id='last' type='text'/>
+{code}
+
+To:
+
+{code}
+<form wicket:id='customer'>
+    <div wicket:id='container'>
+        <input wicket:id='first' type='text'/>
+        <input wicket:id='last' type='text'/>
+    </div>
+{code}
+
+Seems simple enough, but to do so we need to create the new container, find 
the code that adds all the components that have to be relocated and change it 
to add to the new container instead. This code:
+
+{code}
+Form form=new Form("customer");
+add(form);
+ 
+form.add(new TextField("first"));
+form.add(new TextField("last"));
+{code}
+
+Will become:
+
+{code}
+Form form=new Form("customer");
+add(form);
+ 
+WebMarkupContainer container=new WebMarkupContainer("container");
+form.add(container);
+ 
+container.add(new TextField("first"));
+container.add(new TextField("last"));
+{code}
+
+Another common change is to tweak the nesting of markup tags. This is 
something a designer should be able to do on their own if the change is purely 
visual, but cannot if it means Wicket components will change parents.
+
+In large pages with a lot of components these kinds of simple changes tend to 
cause a lot of annoyance for the developers.
+
+h3. Component Queueing To The Rescue
+
+The idea behind component queueing is simple: instead of adding components to 
their parents directly, the developer can queue them in any ancestor and have 
Wicket automatically ‘dequeue’ them to the correct parent using the 
hierarchy defined in the markup. This will give us the best of both worlds: the 
developer only has to define the hierarchy once in markup, and have it 
automatically constructed in Java land.
+
+That means we can go from code like this:
+
+{code}
+Form form=new Form("customer");
+add(form);
+ 
+form.add(new TextField("first"));
+form.add(new TextField("last"));
+ 
+WebMarkupContainer child=new WebMarkupContainer("child");
+form.add(child);
+ 
+child.add(new TextField("first"));
+child.add(new TextField("last"));
+child.add(new TextField("dob"));
+{code}
+
+To code like this:
+
+{code}
+queue(new Form("customer"));
+queue(new TextField("first"));
+queue(new TextField("last"));
+ 
+WebMarkupContainer child=new WebMarkupContainer("child");
+queue(child);
+child.queue(new TextField("first"));
+child.queue(new TextField("last"));
+child.queue(new TextField("dob"));
+{code}
+
+{note}
+Note that we had to queue child’s @first@ and @last@ name fields to the 
@child@ container in order to disambiguate their wicket ids.
+{note}
+
+
+The code above does not look shorter or that much different, so where is the 
advantage?
+
+Suppose our designer wants us to wrap the customer’s first and last name 
fields with a @div@ that changes its styling based on some condition. We saw 
how to do that above, we had to create a container and then reparent the two 
@TextField@ components into it. Using queueing we can skip the second step, all 
we have to do is add the following line:
+
+{code}
+queue(new WebMarkupContainer("container"));
+{code}
+
+When dequeueing Wicket will automatically reparent the first and last name 
fields into the container for us.
+
+If the designer later wanted to move the first name field out of the @div@ we 
just added for them they could do it all by themselves without requiring any 
changes in the Java code. Wicket would dequeue the first name field into the 
form and the last name field into the container div.
+

http://git-wip-us.apache.org/repos/asf/wicket/blob/d1fc9731/wicket-user-guide/src/docs/guide/componentQueueing/componentQueueing_2.gdoc
----------------------------------------------------------------------
diff --git 
a/wicket-user-guide/src/docs/guide/componentQueueing/componentQueueing_2.gdoc 
b/wicket-user-guide/src/docs/guide/componentQueueing/componentQueueing_2.gdoc
new file mode 100644
index 0000000..6f0f91d
--- /dev/null
+++ 
b/wicket-user-guide/src/docs/guide/componentQueueing/componentQueueing_2.gdoc
@@ -0,0 +1,23 @@
+Auto components, such as Enclosure, are a very useful feature of Wicket, but 
they have always been a pain to implement and use.
+
+Suppose we have:
+
+{code:xml}
+<wicket:enclosure childId="first">
+    <input wicket:id="first" type="text"/>
+    <input wicket:id="last" type="text"/>
+</wicket:enclosure>
+{code}
+
+Together with:
+
+{code}
+add(new TextField("first").setRequired(true).setVisible(false));
+add(new TextField("last").setRequired(true));
+{code}
+
+When developing auto components the biggest pain point is in figuring out who 
the children of the auto component are. In the markup above the enclosure is a 
parent of the text fields, but in Java it would be a sibling because auto 
components do not modify the java-side hierarchy. So when the Enclosure is 
looking for its children it has to parse the markup to figure out what they 
are. This is not a trivial task.
+
+Because auto components do not insert themselves properly into the Java 
hierarchy they are also hard for users to use. For example, the documentation 
of Enclosure does not recommend it to be used to wrap form components like we 
have above. When the page renders the enclosure will be hidden because @first@ 
component is not visible. However, when we submit the form, @last@ component 
will raise a required error. This is because @last@ is not made a child of the 
hidden enclosure and therefore does not know its hidden — so it will try to 
process its input and raise the error.
+
+Had we used @queue@ instead of @add@ in the code above, everything would work 
as expected. As part of Queueing implementation Wicket will properly insert 
auto components into the Java hierarchy. Furthermore, auto components will 
remain in the hierarchy instead of being added before render and removed 
afterwords. This is a big improvement because developers will no longer have to 
parse markup to find the children components — since children will be added 
to the enclosure by the dequeueing. Likewise, user restrictions are removed as 
well; the code above would work as expected.

http://git-wip-us.apache.org/repos/asf/wicket/blob/d1fc9731/wicket-user-guide/src/docs/guide/componentQueueing/componentQueueing_3.gdoc
----------------------------------------------------------------------
diff --git 
a/wicket-user-guide/src/docs/guide/componentQueueing/componentQueueing_3.gdoc 
b/wicket-user-guide/src/docs/guide/componentQueueing/componentQueueing_3.gdoc
new file mode 100644
index 0000000..d88c237
--- /dev/null
+++ 
b/wicket-user-guide/src/docs/guide/componentQueueing/componentQueueing_3.gdoc
@@ -0,0 +1,5 @@
+Once you call @queue()@, when are the components dequeued into the page 
hierarchy? When is it safe to call @getParent()@ or use methods such as 
@isVisibleInHierarchy()@ which rely on component’s position in hierarchy?
+
+The components are dequeued as soon as a path is available from @Page@ to the 
component they are queued into. The dequeue operation needs access to markup 
which is only available once the Page is known (because the @Page@ object 
controls the extension of the markup).
+
+If the @Page@ is known at the time of the @queue()@ call (eg if its called 
inside @onInitialize()@) the components are dequeued before @queue()@ returns.

http://git-wip-us.apache.org/repos/asf/wicket/blob/d1fc9731/wicket-user-guide/src/docs/guide/componentQueueing/componentQueueing_4.gdoc
----------------------------------------------------------------------
diff --git 
a/wicket-user-guide/src/docs/guide/componentQueueing/componentQueueing_4.gdoc 
b/wicket-user-guide/src/docs/guide/componentQueueing/componentQueueing_4.gdoc
new file mode 100644
index 0000000..6a60d41
--- /dev/null
+++ 
b/wicket-user-guide/src/docs/guide/componentQueueing/componentQueueing_4.gdoc
@@ -0,0 +1,31 @@
+h3. Ancestors
+
+Suppose on a user profile panel we have the following code:
+
+{code}
+queue(new Label("first"));
+queue(new Label("last"));
+ 
+WebMarkupContainer secure=new WebMarkupContainer("secure") {
+    void onConfigure() {
+       super.onConfigure();
+       setVisible(isViewingOwnProfile());
+    }
+};
+ 
+queue(secure);
+secure.queue(new Label("creditCardNumber"));
+secure.queue(new Label("creditCardExpiry"));
+{code}
+
+What is to prevent someone with access to markup from moving the 
@creditCardNumber@ label out of the @secure@ div, causing a big security 
problem for the site?
+
+Wicket will only dequeue components either to the component they are queued to 
or any of its descendants.
+
+In the code above this is the reason why we queued the @creditCardNumber@ 
label into the @secure@ container. That means it can only be dequeued into the 
@secure@ container’s hierarchy.
+
+This restriction allows developers to enforce certain parent-child 
relationships in their code.
+
+h3. Regions
+
+Dequeuing of components will not happen across components that implement the 
@org.apache.wicket.IQueueRegion@ interface. This interface is implemented by 
all components that provide their own markup such as: @Page@, @Panel@, 
@Border@, @Fragment@. This is done so that if both a page and panel contain a 
component with id @foo@ the one queued into the page will not be dequeued into 
the panel. This minimizes confusion and debugging time. The rule so far is that 
if a component provides its own markup only components queued inside it will be 
dequeued into it.

http://git-wip-us.apache.org/repos/asf/wicket/blob/d1fc9731/wicket-user-guide/src/docs/guide/componentQueueing/componentQueueing_5.gdoc
----------------------------------------------------------------------
diff --git 
a/wicket-user-guide/src/docs/guide/componentQueueing/componentQueueing_5.gdoc 
b/wicket-user-guide/src/docs/guide/componentQueueing/componentQueueing_5.gdoc
new file mode 100644
index 0000000..ba8f0fd
--- /dev/null
+++ 
b/wicket-user-guide/src/docs/guide/componentQueueing/componentQueueing_5.gdoc
@@ -0,0 +1 @@
+Component queueing is a new and improved way of creating the component 
hierarchy in Wicket 7. By having to define the hierarchy only once in markup we 
can make the Java-side code simpler and more maintainable.

http://git-wip-us.apache.org/repos/asf/wicket/blob/d1fc9731/wicket-user-guide/src/docs/guide/toc.yml
----------------------------------------------------------------------
diff --git a/wicket-user-guide/src/docs/guide/toc.yml 
b/wicket-user-guide/src/docs/guide/toc.yml
index c67911d..b0489c1 100644
--- a/wicket-user-guide/src/docs/guide/toc.yml
+++ b/wicket-user-guide/src/docs/guide/toc.yml
@@ -99,6 +99,13 @@ repeaters:
   repeaters_3: The RefreshingView Component
   repeaters_4: Pageable repeaters 
   repeaters_5: Summary
+componentQueueing:
+  title: Component queueing
+  componentQueueing_1: Markup hierarchy and code
+  componentQueueing_2: Improved auto components
+  componentQueueing_3: When are components dequeued?
+  componentQueueing_4: Restrictions of queueing
+  componentQueueing_5: Summary
 i18n:
   title: Internationalization with Wicket
   i18n_1: Localization

Reply via email to