規定PageクラスのHTMLのbodyタグのcssを、
条件により切り替えたくなり、試した結果を備忘として、残します。


参考にしたサイト



プログラム


1. BasePage.html

<!DOCTYPE html>
<html xmlns:wicket="http://wicket.apache.org" lang="ja">
    <head wicket:id="headPanel"></head>
    <body wicket:id="body">
        <header wicket:id="headerPanel"></header>
        <wicket:child/>
        <footer wicket:id="footerPanel"></footer>
    </body>
</html>

2. BasePage.java

public abstract class BasePage extends WebPage {

    private static final long serialVersionUID = -8517634810326079326L;

    public BasePage() {
        super();
    }

    public BasePage(final PageParameters parameters) {
        super(parameters);
    }

    @Override
    protected void onInitialize() {
        super.onInitialize();
        // Add Panel
        add(new HeadPanel("headPanel"));
        // Add BodyContainer
        TransparentWebMarkupContainer bodyContainer = new TransparentWebMarkupContainer("body");
        BodyCssClass css = getBodyCssClass();
        bodyContainer.add(AttributeModifier.replace("class", css.getCssClass()));
        add(bodyContainer);
        add(new HeadPanel("headerPanel"));
        add(new FooterPanel("footerPanel"));

        // initPage()
        initPage(getPageParameters());
    }

    protected BodyCssClass getBodyCssClass() {
        return BodyCssClass.NORMAL;
    }
}


2.1 プログラムの補足説明


  1. wicket:id=”body”に設定するContainerとして、
    TransparentWebMarkupContainerをを使用しています。

  2. protected メソッド getBodyCssClass() でCss定義を表すenumクラスを取得。
    cssの変更が必要な場合は、継承クラス側で、オーバーライドします。

  3. bodyContainer.add(AttributeModifier.replace(“class”, css.getCssClass()));
    bodyタグのcssをenumクラスのcss定義で上書きします。


2.2 TransparentWebMarkupContainerについて


Wicket - Add body tag attribute記載のあるWebMarkupContainerのメソッド

       bodyContainer.setTransparentResolver(true);
は、wicket1.5以降は削除されてしまったようです。

Migration to Wicket 1.5 には


MarkupContainer.isTransparentResolver() removed
We removed MarkupContainer.isTransparentResolver() in favor of the more general IComponentResolver. To mitigate the transition, we >provide a TransparentWebMarkupContainer. But please note it does not solve all use cases isTransparentResolver() did.
There are several solutions for you. Your component may implement IComponentResolver itself and resolve the child component. The TransparentWebMarkupContainer implementation may serve as an example.
The main reason why we removed MarkupContainer.isTransparentResolver() has been the magic necessary in Wicket’s core and the number of issues/questions, where we identified isTransparentResolver() as the root cause. It all boils down to that with isTransparentResolver() the markup and component hierarchies get out of sync.
Noteable difference: different than MarkupContainer.isTransparentResolver() where the component id wasn’t needed in the path (transparent), with IComponentResolver it must be included. Imagine you used to have a transparent container such as , where you were able to access a label from the Page just by “myLabel”. In 1.5. you must use “myBody:myLabel”.



  • 上記の日本語訳(適当)
    MarkupContainer.isTransparentResolver() は削除されました。
    私たちは、より汎用的なIComponentResolverを選び、MarkupContainer.isTransparentResolver()を削除しました。移行負荷の軽減のため、私たちは、TransparentWebMarkupContainerを提供します。
    しかし、TransparentWebMarkupContainerが、isTransparentResolver()の全てのユースケースをカバーするわけではないことに注意してください。
    ユースケースに応じたIComponentResolverを実装することが、解決策となります。TransparentWebMarkupContainerはその一例です。
    私たちがMarkupContainer.isTransparentResolverを削除した主な理由は、isTransparentResolver()を根本的な原因とする、かなりの数の課題が存在したためです。
    isTransparentResolver()を使用すると、マークアップとコンポーネントの階層が同期し、値を取得するため、パフォーマンスに悪影響を与えます。
    重要な違い:
    MarkupContainer.isTransparentResolver()はcomponent idに対する明確なpathを必要としませんが、 IComponentResolverはcomponent idに対する明確なpathを必要とします。のようなtagがあるとすると、
    Pageクラスから、“myBody”の子コンポーネントには、“myLabel”でアクセスできましたが、1.5からは、“myBody:myLabel”でアクセスしなければいけません。

と記載があり、(置き換え可能な場合は)TransparentWebMarkupContainerを使用してくださいと、読み取れました。

ちなみにTransparentWebMarkupContainerを使用しないで、WebMarkupContainerを使用すると、以下の内容のエラーが出力されました。

ERROR [2015-11-29 10:51:14,506] org.apache.wicket.MarkupContainer: Unable to find component with id 'headerPanel' in [WebMarkupContainer [Component id = body]]
    Expected: 'body:headerPanel'.
    Found with similar names: 'headPanel', headerPanel'

※bodyタグのWebMarkupContainerに対して、headerPanel、footerPanelをaddすると、
上記エラーも解決したのですが、今後は子クラス側で、エラーとなってしまったので、
TransparentWebMarkupContainerを使用することにしました。
ちなみに、子クラス側のaddメソッドをqueueに変更することでも上手く動作しました。

コメント