| <chapter id="wug.chapter2"> |
| <title>Hello World!</title> |
| <subtitle>Everyone's favorite example program</subtitle> |
| <sect1> |
| <title>A simple program</title> |
| <para>People learn best by example, and so this User’s Guide is example |
| driven. Our first example is the famous and traditional “Hello |
| World” program.</para> |
| <sect2> |
| <title>Building HelloWorld</title> |
| <para>Simply unzip your Wicket SDK archive somewhere on your hard |
| drive. Then go to |
| <filename>WICKET_HOME/examples/HelloWorld</filename> (where |
| <varname>WICKET_HOME</varname> is the folder where you unzipped |
| the Wicket SDK) and simply type "<command>ant</command>". You |
| should see this:</para> |
| <screen><![CDATA[C:\Wicket-SDK-0.5a\examples\HelloWorld>ant |
| Buildfile: build.xml |
| buildContext: |
| [delete] Deleting directory C:\Wicket-SDK-0.5a\build\examples\HelloWorld |
| buildClasses: |
| [mkdir] Created dir: C:\Wicket-SDK-0.5a\build\examples\HelloWorld\WEB-INF\classes |
| [javac] Compiling 2 source files to C:\Wicket-SDK-0.5a\build\examples\HelloWorld\WEBIN |
| F\classes |
| [copy] Copying 1 file to C:\Wicket-SDK-0.5a\build\examples\HelloWorld\WEB-INF\classes |
| [mkdir] Created dir: C:\Wicket-SDK-0.5a\build\examples\HelloWorld\WEB-INF\lib |
| [copy] Copying 1 file to C:\Wicket-SDK-0.5a\build\examples\HelloWorld\WEB-INF |
| [copy] Copying 21 files to C:\Wicket-SDK-0.5a\build\examples\HelloWorld\WEB-INF\lib |
| buildWar: |
| [war] Building war: C:\Wicket-SDK-0.5a\build\examples\HelloWorld\HelloWorld.war |
| buildAll: |
| BUILD SUCCESSFUL |
| Total time: 10 seconds]]></screen> |
| <para>The build process will create |
| <filename>WICKET_HOME/build/examples/HelloWorld</filename>. |
| This folder is a web application context, complete with the |
| standard <filename>WEB-INF</filename> folder structure and |
| <filename>web.xml</filename> file. You will also find a |
| <filename>HelloWorld.war</filename> file suitable for |
| deployment on any web application server.</para> |
| <mediaobject> |
| <imageobject> |
| <imagedata fileref="images/image001-explorer.png" |
| format="PNG"></imagedata> |
| </imageobject> |
| </mediaobject> |
| </sect2> |
| <sect2> |
| <title>Running HelloWorld</title> |
| <para>To run the HelloWorld web application, I suggest using the |
| Jetty application server because it is so easy to set up. |
| Simply download and unzip the latest Jetty web server (<ulink |
| url="http://jetty.mortbay.org"></ulink>). Then copy the |
| <filename>HelloWorld.war</filename> file from |
| <filename>WICKET_HOME/build/examples/HelloWorld</filename> to |
| the webapps folder under <varname>JETTY_HOME</varname>. Start |
| Jetty with "<command>java –jar start.jar</command>". Then go to |
| <ulink url="http://localhost:8080/HelloWorld" /> and you should |
| see this:</para> |
| <mediaobject> |
| <imageobject> |
| <imagedata fileref="images/image002-helloworld.png" |
| format="PNG"></imagedata> |
| </imageobject> |
| </mediaobject> |
| </sect2> |
| </sect1> |
| <sect1> |
| <title>The HelloWorld Source Code</title> |
| <para>The source code for HelloWorld consists of 4 files: the |
| <filename>web.xml</filename> descriptor, the |
| <filename>HelloWorldApplication.java</filename> servlet and the |
| <filename>HelloWorld.java</filename> page with its associated |
| markup file <filename>HelloWorld.html</filename>.</para> |
| <sect2> |
| <title>web.xml</title> |
| <para>The web.xml below defines a servlet called "HelloWorld" of |
| class <classname>helloworld.HelloWorldApplication</classname> |
| and maps all URLs in the web app context to this servlet. Since |
| <filename>HelloWorld.war</filename> is automatically deployed |
| on the HelloWorld context, the URL <ulink |
| url="http://localhost:8080/HelloWorld/" /> is mapped to the |
| HelloWorldApplication servlet.</para> |
| <programlisting><![CDATA[<?xml version="1.0" encoding="UTF-8"?> |
| <!DOCTYPE web-app |
| PUBLIC "-//Sun Microsystems, Inc.//DTD Web Application 2.3//EN" |
| "http://java.sun.com/dtd/web-app_2_3.dtd"> |
| <web-app> |
| <display-name>HelloWorld</display-name> |
| <servlet> |
| <servlet-name>HelloWorld</servlet-name> |
| <servlet-class>helloworld.HelloWorldApplication</servlet-class> |
| <load-on-startup>1</load-on-startup> |
| </servlet> |
| <servlet-mapping> |
| <servlet-name>HelloWorld</servlet-name> |
| <url-pattern>/*</url-pattern> |
| </servlet-mapping> |
| </web-app>]]></programlisting> |
| </sect2> |
| <sect2> |
| <title>HelloWorldApplication.java</title> |
| <para>The <filename>HelloWorldApplication.java</filename> file |
| looks like this:</para> |
| <programlisting><![CDATA[public class HelloWorldApplication extends WebApplication |
| { |
| public HelloWorldApplication() |
| { |
| getSettings().setHomePage(HelloWorld.class); |
| } |
| }]]></programlisting> |
| <para>All of the magic in Wicket comes from the |
| <classname>WebApplication</classname> class, which knows how to |
| deal with things like URLs, GET/POST requests and session |
| state. The only thing we need to do here is define the |
| <emphasis>home page</emphasis> for the application. When no |
| resource path is specified by a web page request, the |
| <classname>HelloWorldApplication</classname> servlet will |
| respond with the HelloWorld home page as a default.</para> |
| </sect2> |
| <sect2> |
| <title>HelloWorld.java</title> |
| <para>The actual HelloWorld page is a very simple class which |
| extends <classname>WebPage</classname> and takes a |
| <classname>PageParameters</classname> value in its |
| constructor.</para> |
| <programlisting><![CDATA[public class HelloWorld extends WebPage |
| { |
| public HelloWorld(final PageParameters parameters) |
| { |
| add(new Label("message", "Hello world!")); |
| } |
| }]]></programlisting> |
| <para>A page which has such a constructor can be invoked at any |
| time and is known as <emphasis>external</emphasis> since it can |
| be accessed from a browser that has not yet established a |
| session. Since it can be accessed at any time, an external page |
| is <emphasis>bookmarkable</emphasis>. Your home page must be |
| external (and therefore bookmarkable) since it will be accessed |
| before a session has been established!</para> |
| <para>All non-external pages in Wicket are not bookmarkable because |
| they will contain information in the URL (query parameters) |
| that refers to session information (which will not be available |
| at a later time). Accessing such a page (after it has expired) |
| via a bookmark will give the user a page that looks like |
| this:</para> |
| <mediaobject> |
| <imageobject> |
| <imagedata fileref="images/image003-pageexpired.png" |
| format="PNG"></imagedata> |
| </imageobject> |
| </mediaobject> |
| <para>Notice all the information in the URL? Those query parameters |
| refer to (expired) session information.</para> |
| </sect2> |
| </sect1> |
| <sect1> |
| <title>The Label Component</title> |
| <para>Getting back to the HelloWorld.java page, this line</para> |
| <programlisting><![CDATA[add(new Label("message", "Hello world!"));]]> |
| </programlisting> |
| <para>creates a Label component with the name "message" and the model |
| "Hello world!" The label component attaches to the associated |
| markup file <filename>HelloWorld.html</filename>.</para> |
| <programlisting><![CDATA[<html> |
| <body> |
| <span id = "wcn-message"/> |
| </body> |
| </html>]]></programlisting> |
| <sect2> |
| <title>Component names</title> |
| <para>It attaches to the <markup><![CDATA[<span>]]></markup> tag |
| with the Wicket component name attribute that matches the name |
| of the Label component. Wicket component names are specified in |
| three possible ways:</para> |
| <orderedlist> |
| <listitem> |
| <para>The component name can be specified using the |
| attribute <firstterm>"wcn"</firstterm> (for Wicket |
| component name). For example, <markup><![CDATA[<span wcn = "message">]]> |
| </markup>. The "wcn" attribute has the downside of |
| being an invalid HTML attribute that will be flagged by |
| validating HTML editor. On the upside, it should not |
| conflict with other attributes in your markup.</para> |
| </listitem> |
| <listitem> |
| <para>The component name can be specified as a value of the |
| id attribute prefixed by "wcn-" (for Wicket component |
| name). The use of the <emphasis>id</emphasis> attribute |
| allows Wicket HTML to validate correctly in validating |
| HTML editors. The "wcn-" prefix ensures that Wicket |
| knows which id attributes are being used for Wicket |
| component names and which are being used for other |
| purposes, such as CSS or JavaScript. This is necessary |
| because Wicket requires that all wicket component names |
| in a markup resource reference a Java component of the |
| same name. If this check fails, an exception is thrown. |
| This makes it easy to catch component wiring |
| problems.</para> |
| </listitem> |
| <listitem> |
| <para>You can specify your own attribute name using the |
| <classname>ApplicationSettings</classname> object |
| obtained in your WebApplication’s constructor:</para> |
| <programlisting><![CDATA[public class HelloWorldApplication extends WebApplication |
| { |
| public HelloWorldApplication() |
| { |
| getSettings().setHomePage(HelloWorld.class) |
| .setComponentNameAttribute("myAttributeName"); |
| } |
| }]]></programlisting> |
| </listitem> |
| </orderedlist> |
| <para>In the case of our HelloWorld example, the Wicket component |
| name is specified with the id attribute value "wcn-message". |
| This matches the name of the Label component ("message").</para> |
| <para>Although some other component types will attach to other |
| kinds of tags, Label components will <emphasis>only</emphasis> |
| attach to <markup><![CDATA[<span>]]> </markup> tags.</para> |
| <para>When the HelloWorld page renders, the Label component simply |
| replaces the body of its tag with the value of its model |
| (components and their models can be considerably more complex |
| than Label, which will we see later in this guide). The |
| resulting markup will look like this:</para> |
| <programlisting><![CDATA[<html> |
| <body> |
| <span id = "wcn-message">Hello world!</span> |
| </body> |
| </html>]]></programlisting> |
| </sect2> |
| <sect2> |
| <title>Previewability</title> |
| <para>Note that if we had wanted our HelloWorld.html to be more |
| previewable in an HTML editor or browser, we could have made it |
| look like this instead:</para> |
| <programlisting><![CDATA[<html> |
| <body> |
| <span id = "wcn-message">Message goes here!</span> |
| </body> |
| </html>]]></programlisting> |
| <para>The final rendered page would still look the same since the |
| body of the span tag will be replaced with the model |
| value.</para> |
| </sect2> |
| </sect1> |
| <sect1> |
| <title>Component Rendering and Tags</title> |
| <para>It’s also interesting to note that the <markup><![CDATA[<span>]]> |
| </markup> tag that our Label is attached to will retain any other |
| attributes it might have originally had. This makes it a natural |
| place to apply a CSS style attribute, for example.</para> |
| <para>In general, the following rules are observed by Wicket when |
| rendering components:</para> |
| <formalpara> |
| <title>Wicket components MAY:</title> |
| <para> |
| <itemizedlist> |
| <listitem> |
| <para>Add attributes to a tag</para> |
| </listitem> |
| <listitem> |
| <para>Overwrite well-documented and appropriate tag |
| attributes</para> |
| </listitem> |
| <listitem> |
| <para>Replace a tag’s body</para> |
| </listitem> |
| <listitem> |
| <para>Insert markup before or after a tag’s body or |
| (very rarely) after a tag</para> |
| </listitem> |
| </itemizedlist> |
| </para> |
| </formalpara> |
| <formalpara> |
| <title>Wicket components WILL NOT:</title> |
| <para> |
| <itemizedlist> |
| <listitem> |
| <para>Remove tags from your markup</para> |
| </listitem> |
| <listitem> |
| <para>Remove a tag body that holds nested components |
| (more on this later)</para> |
| </listitem> |
| <listitem> |
| <para>Change the name of a tag <footnote> <para>One |
| notable exception: a disabled Link component will |
| change the anchor tag’s name from “a” to “span” so |
| as to disable the linking behavior of the anchor |
| tag.</para> </footnote> </para> |
| </listitem> |
| </itemizedlist> |
| </para> |
| </formalpara> |
| <para>The fact that Wicket mostly leaves your markup tags and their |
| attributes alone is very important to graphic designers because it |
| means that they don’t have to worry about being stepped on by the |
| toolkit. They can style away and know that their tags won’t be |
| modified in inappropriate ways.</para> |
| </sect1> |
| </chapter> |