Mixin
Mixin、説明として適切な例がなかなか浮かばないのですが、とりあえず私が最近書いたMixinを晒してみます。
import org.apache.tapestry.MarkupWriter; import org.apache.tapestry.annotations.MixinAfter; import org.apache.tapestry.annotations.Parameter; @MixinAfter public class TableRow { @Parameter(required = true) private int _columns; private int _index; void setupRender() { _index = -1; } void beginRender(MarkupWriter writer) { ++_index; if ((_index % _columns) == 0) { writer.element("tr"); } } void afterRender(MarkupWriter writer) { if ((_index % _columns) == _columns - 1) { writer.end(); // tr } } void cleanupRender(MarkupWriter writer) { int n = _columns - 1 - (_index % _columns); if (n > 0) { writer.element("td", "colspan", n); writer.end(); writer.end(); // tr } } }
使用例:
<table> <t:loop source="dataList" value="data" t:mixins="tablerow" tablerow.columns="5"> <td>${data.name}</td> </t:loop> </table>
Loopコンポーネントに対して使用することを想定しています。
tablerow.columnsパラメータで指定した回数分ループが回る毎に <tr>...</tr> で囲むという単純なものです。
最後の行で不足分がある時は <td colspan="不足分"></td> で埋めます。
@MixinAfter public class TableRow {
と、@MixinAfterアノテーションしているのは、Loopコンポーネントの各処理フェーズの「後」にMixinするためです(この場合、afterRender, cleanupRenderフェーズでは、Loopコンポーネントの「前」に処理されるので、MixinAfterという名前よりもMixinInnerとかの方が良い気がしますが)。このアノテーションが無い場合は各フェーズの前(というか外側)にMixinされます。