【Thymeleaf】Thymeleaf の Dialect でのタグ編集まとめ
Thymeleaf の Dialect を実装、オリジナルのタグや属性値を使ってよく使う DOM 要素を短く書きたいといったことはよくあるケースだと思います。
IElementTagProcessor を使い実装するときは doProcess メソッドを実装することで処理を書いていきますが、そこでタグを編集する方法をまとめます。
doProcess メソッドの処理の流れ
IElementTagProcessor の doProcess メソッドの大まかな実装の流れを書きます。
protected void doProcess(ITemplateContext context, IProcessableElementTag tag, IElementTagStructureHandler structureHandler) { // ①タグ作成の準備 IModelFactory modelFactory = context.getModelFactory(); IModel model = modelFactory.createModel(); // ②ここからごにょごにょ新しいタグを作る model.add(modelFactory.createStandaloneElementTag("input", "type", "text")); // テキストボックスを作るコード例 // ③作った新しいタグを追加・古いタグに対して置換など structureHandler.replaceWith(model, false); // 置換するコード例 }
本記事では主に②〜③でどんなことができるのかをまとめます。
タグ編集 tips 目次
新しいタグ作成してみる
新しいタグを作るには IModelFactory クラスの以下メソッドを使用する。
メソッド | 生成するもの |
---|---|
createOpenElementTag | 開始タグを作成 |
createCloseElementTag | 終了タグを作成 |
createStandaloneElementTag | タグを作成 |
createText | テキストを挿入 |
基本的にはレンダリングされる View の各行ごとに必要なメソッドでタグやテキストを追加してあげるイメージ。
上で紹介したメソッドを使った例として次のようなログインフォームを作ることを考える。
<form> <p>username</p> <input name="username"> <p>password</p> <input name="password"> <input type="submit"> </form>
これを生成するためのコード例は次。
// form の開始タグの作成 model.add(modelFactory.createOpenElementTag("form")); // username の p タグと input タグの作成 model.add(modelFactory.createOpenElementTag("p")); model.add(modelFactory.createText("username")); model.add(modelFactory.createCloseElementTag("p")); model.add(modelFactory.createStandaloneElementTag("input", "name", "username")); // password の p タグと input タグの作成 model.add(modelFactory.createOpenElementTag("p")); model.add(modelFactory.createText("password")); model.add(modelFactory.createCloseElementTag("p")); model.add(modelFactory.createStandaloneElementTag("input", "name", "password")); // submit の input タグの作成 model.add(modelFactory.createStandaloneElementTag("input", "type", "submit")); // form の終了タグの作成 model.add(modelFactory.createCloseElementTag("form"));
新しいタグ生成してみる(その他)
上で紹介していない IModelFactory のタグ生成メソッド。
あまり使う機会はないかも。。
メソッド | 生成するもの |
---|---|
createComment | コメントを生成 |
createCDATASection | CDATASectionを作成 |
createHTML5DocType | HTML5 の DocType を作成 |
とりあえずサンプルとして書き出してみるとこんな感じ。
model.add(modelFactory.createHTML5DocType()); model.add(modelFactory.createCDATASection("しーでーたー")); model.add(modelFactory.createComment("コメントはさんどく?"));
レンダリング結果は次。
<!doctype html> <!--[CDATA[しーでーたー]]--> <!--コメントはさんどく?-->
新しいタグの属性値を編集してみる
上のログインフォームの生成例だと、いくつかのタグで属性値が付属しているので実際にログインフォームとして機能はできないはず(サンプルなのでご勘弁を。。)。
しっかりしたフォームを作ろうと思うとよりたくさんの属性値を追加する必要があり、そのためのメソッドも IModelFactory に用意されている。
メソッド | 生成するもの |
---|---|
setAttribute | 属性値を追加 |
removeAttribute | 属性値を削除 |
例として、
<input type="text" name="username">
をそれぞれのメソッドを使いながら遠回しに作ってみると
IStandaloneElementTag inputTag = modelFactory.createStandaloneElementTag("input"); inputTag = modelFactory.setAttribute(inputTag, "type", "text"); inputTag = modelFactory.setAttribute(inputTag, "name", "username"); iinputTag = modelFactory.setAttribute(inputTag, "dummy", "dummyValue"); // お試しで追加してみたが、、 inputTag = modelFactory.removeAttribute(inputTag, "dummy"); // ダミー属性なんてやっぱりいらない。。 model.add(inputTag);
正直、この属性値の追加の仕方は個人的には好きではない。。
上のログインフォーム生成例のコードだと、生成 html と java コードの各行がちょうど対応関係があってみやすかったのに、属性値編集のメソッドで丸つぶれになってしまうため。
これを避けるために、createOpenElementTag または createStandaloneElementTag メソッドに属性値の組み合わせを Map で渡す方法もある。
こちらの方がまだマシかも。
// 属性値を Map で準備 HashMap<String, String> attributeMap = new HashMap<>(); attributeMap.put("type", "text"); attributeMap.put("name", "username"); // input タグの生成 model.add(modelFactory.createStandaloneElementTag("input", attributeMap, AttributeValueQuotes.DOUBLE, false, false));
新しく作ったタグを追加または置換してみる
作ったタグを実際に置換するための処理は IElementTagStructureHandler を使う。
主なメソッドは以下。
メソッド | 実行内容 |
---|---|
setBody | 元タグの子要素にテキストを追加 |
insertBefore | 元タグの直前に新しいタグを追加 |
insertImmediatelyAfter | 元タグの直後に新しいタグを追加 |
replaceWith | 元タグを新しいタグに置換 |
それぞれの使用例を書いてみる。
元のオリジナルタグを、
<ex:test> <p>hello</p> </ex:test>
として、それぞれのメソッドの実行例を見てみる。
setBody
指定できるのは model か文字列。
元々のタグの中身を指定したものに変更してくれる。
model.add(modelFactory.createStandaloneElementTag("input", "type", "text")); structureHandler.setBody(model, false);
レンダリング結果。
<ex:test> <input type="text"> </ex:test>
insertBefore
元々のタグの直前に新しいタグを追加してくれる。
model.add(modelFactory.createStandaloneElementTag("input", "type", "text")); structureHandler.insertBefore(model);
レンダリング結果。
<input type="text"> <ex:test> <p>hello</p> </ex:test>
insertImmediatelyAfter
元々のタグの直後に新しいタグを追加してくれる。
注意なのがあくまで指定したタグの直後ということなので、開始タグの直後に割り込む形になる。
model.add(modelFactory.createStandaloneElementTag("input", "type", "text")); structureHandler.insertImmediatelyAfter(model, false);
レンダリング結果。
<ex:test> <input type="text"> <p>hello</p> </ex:test>
replaceWith
元々のタグを新しいタグに置換する。
model.add(modelFactory.createStandaloneElementTag("input", "type", "text")); structureHandler.replaceWith(model, false);
レンダリング結果。
<input type="text">
元タグの属性値編集してみる
新しいタグを追加することなく、元タグの属性値のみを変更する時は IElementTagStructureHandler を使用する。
メソッド | 実行内容 |
---|---|
setAttribute | 元タグに新しい属性値を追加 |
removeAttribute | 元タグの属性値を削除 |
以下にサンプルコードを示す。
次のようなオリジナルタグを用意し、
<ex:test name="おなまえ"></ex:test>
それぞれのメソッドを使ってみると、
structureHandler.setAttribute("test", "testValue"); structureHandler.removeAttribute("name");
test 属性を追加し name 属性を追加したので、レンダリング結果は次。
<ex:test test="testValue"></ex:test>