レベルエンター山本大のブログ

面白いプログラミング教育を若い人たちに

BLOCKVROCKリファレンス目次はこちら

Wicket Examples ■Navomatic

WicketのNavomaticサンプルのチュートリアル

オートマティックナビゲーション、ナボマティック ??

Navomatic
The Navomatic application shows the use of border components and links to create a navigation component that can easily be dropped into any web page.
ナボマティック
ナボマティック アプリケーションは、境界線コンポーネントの使い方と、ナビゲーションコンポーネントのためにつくられたリンクの使い方を例示します。
このナビゲーションコンポーネントは、どのようなWebページにでも簡単に設置できます。


In all the Wicket examples, you have to put all files in the same package directory.
This means putting the markup files and the java files next to one another.
It is possible to alter this behavior, but that is beyond the scope of this example.
The only exception is the oblibatory web.xml file which should reside in the WEB-INF/ directory of your web application root folder.

すべてのWicket サンプルは、同じパッケージディレクトリにおいてください。
つまり、マークアップ(HTML)ファイルとJavaファイルを隣合うようにおきます。
(HTMLの配置は)他にも方法はありますが、それを説明するのはこのサンプルの範囲外です。
例外として、web.xmlファイルはアプリケーションのルートフォルダ以下にあるWEB-INF/ディレクトリにおくべきだと義務づけられています。

The link in the navigation to the current page is automatically turned into italic text to indicate to the user what page they are on.
The first screen capture shows the Page1 page with the Page1 link in italics.

ナビゲーションのなかで現在のページを表すリンクは、ユーザーにページを指し示すテキストが自動的にイタリック体になっています。
最初の画面キャプチャは、Page1というページでありPage1のリンクがイタリック体になっています。


When you click on the Page2 link, you get the following screen.
Page2をクリックしたら次の画面のようになります。


As you can see, Page1 has no special style anymore, and Page2 is now displayed in italics.
Also the message box shows that we are viewing Page2 instead of Page1.

お分かりの通り、Page1には特別なスタイルは全く指定していませんが、こちらの画像ではPage2はイタリック体になっています。
また、メッセージボックスにはPage2がPage1のかわりに表示されていることが表されています。

Navigation component
To create a reusable navigation component we are going to use a wicket.markup.html.border.
Border component. From the Border Javadoc:

ナビゲーションコンポーネント
再利用可能なナビゲーションコンポーネントを作るためには「wicket.markup.html.border.Border」コンポーネントを使います。
BorderクラスのJavaDocでは以下のように書かれています。


A border component has associated markup which is drawn and determines placement of any markup and/or components nested within the border component.
ボーター(境界線)コンポーネントは、マークアップに関連づけられます。
このボーダーコンポーネントに関連づけられたマークアップは、「描画されたマークアップ」および「いくつかのマークアップ( および/または コンポーネント)の配置を決めるマークアップ」を子要素として含みます。

The portion of the border's associated markup file which is to be used in rendering the border is denoted by a <wicket:border> tag.
The children of the border component instance are then inserted into this markup, replacing the first <wicket:body/> tag in the border's associated markup.


ボーダー(オブジェクト)が関連づけられたマークアップファイルは、描画結果の中では境界線として用いられます。
そのボーダーオブジェクトが関連づけられたマークアップファイルの一部は、<wicket:border>タグで表されます。
ボーダーコンポーネントインスタンスの子要素は、結果として、このマークアップの<wicket:border>タグの中の最初の<wicket:body/>タグに置き換えられます。

For example, here is markup for a simple Border subclass, a usage of that border, and the markup which would be output on rendering:

例えば、次に表すのは「シンプルボーダーサブクラス」と「そのボーダーを利用している側」のマークアップ、それから描画されたときに出力されるマークアップです。

Border markup
(境界線マークアップ)
Border usage
(境界線が使われている側)
Rendered markup
(書き出されたマークアップ
<html>
<body>
  <wicket:border>
      First <wicket:body/> Last
  </wicket:border>
</body>
</html>
<html>
<body>
  <span wicket:id = "myBorder">
      Middle
  </span>
</body>
</html>
<html>
<body>
      First Middle Last
</body>
</html>


In other words, the markup around the <wicket:body/> tag in the border component is sort of "wrapped around" the body of the <span> tag where the border is used.
This seems simple in this example, but keep in mind that nested components and even nested borders can appear anywhere in either markup file.
This can be used to create quite complex effects with relatively little code.


言葉をかえれば、ボーダーコンポネントの<wicket:body>タグのまわりのマークアップは、ボーダーが使われている側の<span>タグの内容を”包み込む”ようなものです。
このサンプルではシンプルに見えると思いますが、ネストされたコンポーネントやネストされたボーダーでさえ、どちらのマークアップファイルの中のどこにでも記述することができるのを覚えておいて下さい。
これによって、比較的少ないコードでかなり複雑な効果を引き起こすことができます。

NavomaticApplication.java
Just as in the Hello World! example, we need to define our application. In this case, we set Page1 to be our home page.

NavomaticApplication.java
HelloWorldサンプルと同じで、アプリケーションオブジェクトを定義する必要があります。
このケースでは、Page1をホームページとしています。


package wicket.examples.navomatic;

import wicket.protocol.http.WebApplication;

public class NavomaticApplication extends WebApplication
{
    public NavomaticApplication()
    {
    }
    
    public Class getHomePage()
    {
        return Page1.class;
    }
}

Page1.java
The Page1 Java and HTML files look like this:


Page1のJavaとHTMLファイルは、以下のようになります。


package wicket.examples.navomatic;

import wicket.markup.html.WebPage;

public class Page1 extends WebPage
{
    public Page1()
    {
        add(new NavomaticBorder("navomaticBorder"));
    }
}

Page1.html


<html>
<body>
    <span wicket:id = "navomaticBorder">
        You are viewing Page1
    </span>
</body>
</html>

Notice that the NavomaticBorder component is attached to the <span> tag
because the name of the component in the Java code is "navomaticBorder" and the <span> tag's wicket:id attribute is set to "navomaticBorder".
Because the two names match, Wicket associates the NavomaticBorder Java component with the <span> tag.


NavomaticBorderコンポーネントが<span>タグに結びついていることに注目してください。
なぜなら、Javaコードでのコンポーネントの名前は、”navomaticBorder”であり、<span>タグのwicket:id属性は”navomaticBorder”と設定されているからです。
この2つの名前がマッチでしているために、WicketはNavomaticBorderというJavaコンポーネントと<span>タグを関連づけます。

Page2.java
The Page2 Java and HTML files look almost identical (and we'll omit the sources for Page3 altogether because it follows the same pattern):


Page2のJavaとHTMLファイルは、ほとんど同じです。(また、Page3のソースコードも同じようなパターンなので省略します。)


public class Page2 extends WebPage
{
    public Page2()
    {
        add(new NavomaticBorder("navomaticBorder"));
    }
}


Page2.html


<html>
<body>
    <span wicket:id = "navomaticBorder">
        You are viewing Page2
    </span>
</body>
</html>
So how does NavomaticBorder work? Glad you asked.
The Java code below simply adds the two BoxBorder components you see.
These components are nested borders which each draw a thin black line around their contents.
The rest of the magic is in the NavomaticBorder markup.


それでは、NavomaticBorderはどのように動くのでしょうか?よくぞ聞いてくれました。
下のJavaコードは、ただ単に2つのBoxBorderコンポーネントを追加してるように見えますね。
これらのコンポーネントは、それぞれ周りが黒い細い線で囲まれた、ネストされたボーダーです。
残りの仕掛けは、NavomaticBorderマークアップにあります。


NavomaticBorder.java


package wicket.examples.navomatic;

import wicket.markup.html.border.Border;
import wicket.markup.html.border.BoxBorder;

public class NavomaticBorder extends Border
{
    public NavomaticBorder(final String componentName)
    {
        super(componentName);
        add(new BoxBorder("navigationBorder"));
        add(new BoxBorder("bodyBorder"));
    }
}


NavomaticBorder.html


<html>
<body>
    <wicket:border>
        <p>
        <table>
            <tr>
                <td>
                    <span wicket:id = "navigationBorder">
                      <b>Navigation Links</b>
                      <p>
                        <wicket:link>
                          <a href = "Page1.html">Page1</a><br/>
                          <a href = "Page2.html">Page2</a><br/>
                          <a href = "Page3.html">Page3</a>
                        </wicket:link>
                      </p>
                    </span>
                </td>
                <td>
                    <span wicket:id = "bodyBorder">
                        <wicket:body/>
                    </span>
                </td>
            </tr>
        </table>
        </p>
    </wicket:border>
</body>
</html>
Notice that the markup above encloses the entire contents of the markup file's <body> with a <wicket:border> tag, as we described earlier.
This lets the NavomaticBorder know how much of its markup to use when it wraps itself around the markup it finds in the context where it is used.
Notice also the <wicket:body/> marker which designates where to put whatever is found inside the tag at the use context.


上記のマークアップが、マークアップファイルの<body>の全体のコンテンツと、先ほど説明した<wicket:border>タグとを一緒に囲んでいることに注目してください。
これ(<wicket:border>タグ)は、使っているマークアップの数をNavomaticBorderに知らせます。
その数とは、現在のコンテキストで見つける<wicket:border>マークアップに囲まれているマークアップの数です。
wicket:body/>マーカーにも注目してください。<wicket:body/>マーカーは、コンテキストで使われているタグの中でどんなものが見つかろうとも、それをどこに置くかを指定します。

Next, notice that the navigation links and the border's <wicket:body/> are both enclosed in <span> tags
which have wicket:id attributes that associate those tags with the BoxBorder components added in the NavomaticBorder contstructor.
These nested border components will each draw a thin black line around their contents.


次に注目するのは、ナビゲーションリンクとボーダーの<wicket:body/>の両方が<span>タグに囲まれているところです。
これらの<span>タグは、そのタグをNavomaticBorderのコンストラクターで追加されたBoxBorderコンポーネントに関連づけるwicket:id属性をもっています。
これらのネストされたボーダーコンポーネントは、それぞれ細くて黒い線が周りに引かれるでしょう。

Finally, the <wicket:link> tag is used to mark the links in the navigation as automatic links.
Ordinarily, you would need to create link components and attach them to your page manually,
but anchor links that are marked as automatic are parsed and hooked up to link components for you, as appropriate.
The italicizing behavior is also automatic.
Since Wicket knows which page is current, it removes the anchor link tag for any link that points to the current page (since the link would be useless) and italicizes the link text.


最後に、<wicket:link>タグは、ナビゲーションの中の自動的なリンクとして、リンクを記述するために使われている。
通常、リンクコンポーネントを作って、それらを手動でページに結びつける必要がある。
しかし、自動的に記述されたアンカーリンクは、解析されるときに妥当なコンポーネントにリンクを接続してくれる。
イタリック体にする動作も自動です。
現在ページをWikcetが判断したとき、現在のページを指すすべてのリンクのアンカーリンクタグが除去され(リンクは使用できないようになり)、リンクテキストがイタリック体になります。

web.xml
In order to get this application up and running, we need to register the application with the Wicket servlet in the web.xml file.
The following sections need to be added to the web.xml in the WEB-INF folder.


Wicketサーブレットを含んだアプリケーションを実行するために、web.xml
を知らせるという意味でweb.xmlファイルを作る必要があります。


    <servlet>
        <servlet-name>NavomaticApplication</servlet-name>
        <servlet-class>wicket.protocol.http.WicketServlet</servlet-class>
        <init-param>
          <param-name>applicationClassName</param-name>
          <param-value>wicket.examples.navomatic.NavomaticApplication</param-value>
        </init-param>
        <load-on-startup>1</load-on-startup>
    </servlet>
    <servlet-mapping>
        <servlet-name>NavomaticApplication</servlet-name>
        <url-pattern>/app/*</url-pattern>
    </servlet-mapping>