Home

おしえてSideB

追加課題1:解答編(oscar varsion)

それでは、追加課題1の解答です。
もちろん私のバージョンです。そしてあくまでも、解答の一例でしかありません。

テーブル部分のみのコードになります。

<$MTSetVar name="thumb_count" value="0"$>
<MTEntries days="70">
  <MTEntryAssets type="image">
    <$MTSetVar name="thumb_count" op="++"$>
    <MTIf name="thumb_count" eq="1"><table class="thumbnail" summary="最近(さいきん)の写真"></MTIf>
    <MTIf name="thumb_count" value="3" op="%" eq="1"><tr></MTIf>
    <td><p><a href="<$MTEntryPermalink$>" title="<$MTEntryTitle encode_html="1"$>">
      <img src="<$MTAssetThumbnailURL height="208"$>" alt="<$MTEntryTitle encode_html="1"$>" title="<$MTEntryTitle encode_html="1"$>" />
      </a></p>
      <h3><span class="<$MTEntryAuthorUsername$>"><a href="<$MTEntryPermalink$>"><$MTEntryTitle encode_html="1"$></a></span></h3></td>
    <MTIf name="thumb_count" value="3" op="%" eq="0"></tr></MTIf>
  </MTEntryAssets>
  <MTIf name="__Last__">
    <MTIf name="thumb_count" value="3" op="%" ne="0">
      <$MTGetVar name="thumb_count" value="3" op="%" setvar="amari"$>
      <$MTSetVar name="amari" value="3"op="-"$>
      <td colspan="<$MTGetVar name="amari" value="-1"op="*"$>">&nbsp;</td>
      </tr>
    </MTIf>
    <MTIf name="thumb_count" ne="0"></table></MTIf>
  </MTIf>
</MTEntries>

改行をわざと入れないで、コンパクトに(出力の改行を少なく)書こうとするので、見ずらいですね。でもホントは、さらに見づらく書いたりするんですよ。

<$MTSetVar name="thumb_count" value="0"$><MTEntries days="120"><MTEntryAssets type="image"><$MTSetVar name="thumb_count" op="++"$>
<MTIf name="thumb_count" eq="1"><table class="thumbnail" summary="最近(さいきん)の写真">
</MTIf><MTIf name="thumb_count" value="3" op="%" eq="1"><tr>
</MTIf><td><p><a href="<$MTEntryPermalink$>" title="<$MTEntryTitle encode_html="1"$>">
<img src="<$MTAssetThumbnailURL height="208"$>" alt="<$MTEntryTitle encode_html="1"$>" title="<$MTEntryTitle encode_html="1"$>" />
</a></p>
<h3><span class="<$MTEntryAuthorUsername$>"><a href="<$MTEntryPermalink$>"><$MTEntryTitle encode_html="1"$></a></span></h3></td>
<MTIf name="thumb_count" value="3" op="%" eq="0"></tr>
</MTIf></MTEntryAssets><MTIf name="__Last__"><MTIf name="thumb_count" value="3" op="%" ne="0"><$MTGetVar name="thumb_count" value="3" op="%" setvar="amari"$><$MTSetVar name="amari" value="3"op="-"$>
<td colspan="<$MTGetVar name="amari" value="-1"op="*"$>" class="amari">&nbsp;</td>
</tr></MTIf>
<MTIf name="thumb_count" ne="0"></table></MTIf></MTIf></MTEntries>

通常は見やすいコードで書いて、デバッグ済んだ後で、改行調整して本コードにするようにしています。

あと、すでにことわった通り、<td colspan="1">というコードになる時があります。さらに条件分岐をはさんで、これを回避する事も可能です。

今回__last__を使っている部分は、MTEntriesFooterでも可能です。慣れている方を使いましょう。(ただし__last__とMTEntriesFooterを同一のものと思ってはいけません)
なおこの様なコードを書く場合に、すべてのエントリーに画像アイテムが含まれなかった場合に、空のセルをテーブル内に出力するのか、テーブルタグ自身(<table>)も出力させないのかを考えることが重要です。私のコードではテーブル自身が出力されません。
テーブルの開始タグの位置が変だったので、修正しました。

ちなみに出力結果がこれです。

追加課題1:余り部分の処理・捻った回答

別解も表示しときます。
ほんの少しだけ、捻りいれてます。
最初に0の場合を除外します。
変数amariに、3で割った余りをセットします。
amariから3を引くと、負の符号が付いていますが、足りないセル数になります。
amariに-1をかけて、符号を反転させたものを、colspanにセットします。
colspan="1"というのが、絶対許せない方には、お勧めできません。

<MTIf name="__last__">
<MTIf name="thumb_count" value="3" op="%" ne="0">
<$MTGetVar name="thumb_count" value="3" op="%" setvar="amari"$>
<$MTSetVar name="amari" value="3"op="-"$>
<td colspan="<$MTGetVar name="amari" value="-1"op="*"$>">&nbsp;</td>
</tr>
</MTIf>
</MTIf>

追加課題1:余り部分の処理をするには2

カウンターは引き継がれていますので、3で割った余りが1の場合は、残りは2つになります。その場合、colspanは2です。行は閉じていませんので閉じタグを追加します。
余りが1の場合はcolspan指定無しで空セルを追加、この時も閉じタグを追加します。
なお、割り切れる場合には、セルの追加の必要はありませんし、行の閉じタグもすでに追加されています。

以上の内容だと下の様なテンプレートになります。

<MTIf name="__last__">
<MTIf name="thumb_count" value="3" op="%" eq="1">
<td colspan="2">&nbsp;</td>
</tr>
<MTElseIf name="thumb_count" value="3" op="%" eq="2">
<td>&nbsp;</td>
</tr>
</MTIf>
</MTIf>

割り切れる場合には、条件に合致しませんから、何も出力されません。

追加課題1:余り部分の処理をするには1

さぁ、大分形になってきました。
後足りないのは、「最後に3つ並べるのに足りなくなった場所」の処理です。

ここで登場するのが、出題のヒントにある<MTIf name="__last__">です。__last__はブロックタグ内の繰り返しの中で、一番最後であることを表す変数です。

MTIfと組み合わせて、最後のみ処理されるブロックを指定できます。
<MTEntries>
<MTEntryAssets>
・内部処理
</MTEntryAssets>
<MTIf name="__last__">
・最後の処理
</MTIf>
</MTEntries>
とする事で、今回のケースの様な処理を行わせる事が可能です。

つまり一番最後のエントリーで、アイテム処理が終了した後で、足りない部分を埋める処理をさせる訳です。
セットしたカウンター変数には、画像アイテムの個数がセットされています。後は余りがいくつになるかで、colspan処理を変えます。

追加課題1:表示列で処理を分岐する

次は内部での分岐です。
最初に説明した、繰り返し毎の出力を使います。

画像アイテムが3つずつ繰り返し配置になります。
最初の列ではアイテムを囲む<td>のほかに、行を開始する<tr>が必要になります。
2列目はそのままアイテムを囲む<td>を出力します。
3列目では、行を終了する</tr>がアイテムを囲む<td>の後に必要です。
出力はこの繰り返しになります。

実際には1列目の最初に<tr>を出力し、3列目の最後に</tr>を出力するよう、処理を追加すればよいことになります。

1列目はかうんたーの数字を3で割って、余りが1になるケースです。
2列目は余りが2で、3列目は割り切れるケースになります。これ以外の状態はありません。

<カウンターを3で割った余りが1の場合>
・<tr>を出力
</1の場合の追加処理終了>
・すべてに共通な、<td>で囲んだ画像アイテムの出力
<カウンターを3で割りきれる(余りが0)場合>
・</tr>を出力
</3の場合の処理終了>

これをテンプレートにすると以下のようになります。

<table class="thumbnail" summary="最近(さいきん)の写真">
<$MTSetVar name="thumb_count" value="0"$>
<MTEntries days="70">
<MTEntryAssets type="image">
<$MTSetVar name="thumb_count" op="++"$>
<MTIf name="thumb_count" value="3" op="%" eq="1"><tr></MTIf>
<td><a href="<$MTEntryPermalink$>" title="<$MTEntryTitle$>">
<img src="<$MTAssetThumbnailURL width="208"$>" alt="<$MTEntryTitle$>" title="<$MTEntryTitle$>" />
</a></td>
<MTIf name="thumb_count" value="3" op="%" eq="0"></tr></MTIf>
</MTEntryAssets>
</MTEntries>
</table>

ここまででは、余り分の処理は行っていません。

追加課題1:ブロックタグが入れ子になった時のカウント2

カウンター変数は、ブロックタグの外側で初期化(ゼロにセット)します。
カウントしたいものの前後どちらかで、カウンターを一つ増やします(インクリメント)。

初期化する位置、初期化する値(0か1か)、カウントする位置は、常に決まっている訳ではありません。何をカウントするかを考えて、挿入位置を決定します。

<$MTSetVar name="thumb_count" value="0"$>
<MTEntries days="70">
<MTEntryAssets type="image">
<$MTSetVar name="thumb_count" op="++"$>
<a href="<$MTEntryPermalink$>" title="<$MTEntryTitle encode_html="1"$>">
<img src="<$MTAssetThumbnailURL width="208"$>" alt="<$MTEntryTitle encode_html="1"$>" title="<$MTEntryTitle encode_html="1"$>" />
</a>
</MTEntryAssets>
</MTEntries>

__counter__ではなく、独自の変数(上のケースでは「thumb_count」)をカウンターに使っているので、ブロックタグの繰り返し内のどの部分でも、アイテム数を取り出せます。またブロックタグを抜けても、変数は保持されていますので、後から参照できます。

追加課題1:ブロックタグが入れ子になった時のカウント1

追加課題の場合を数えてみましょう。

70日以内に書かれたエントリーを抜き出す。
エントリー内の画像アイテムをすべて並べる。

これは

<MTEntries days="70">
<MTEntryAssets type="image">
<a href="<$MTEntryPermalink$>" title="<$MTEntryTitle encode_html="1"$>">
<img src="<$MTAssetThumbnailURL width="208"$>" alt="<$MTEntryTitle encode_html="1"$>" title="<$MTEntryTitle encode_html="1"$>" />
</a>
</MTEntryAssets>
</MTEntries>

というタグになります。
(このタグを使用するには、使用画像をアセットとして登録していることが必要になります)

実はこの場合には、__counter__は使えなくなります。というのも、カウンターはブロックタグ内の繰り返し回数を表示するもので、MTEntriesとMTEntryAssetsという2つのブロックタグが入れ子になっているからです。
1つのエントリー内で、アセット数をカウントしても、次のエントリーに移った時に、カウントのリセットが行われます。

こういう場合には、自分でカウント用変数を作成し、カウントを行わせることで、対応します。

変数の書き方2(MTSetVarBlockの注意点)

MTSetVarBlockを使う上で、注意点があります。

<MTSetVarBlock name="numbers">
<MTEntryKeywords>
</MTSetVarBlock>

これは、前のコードと同じように見えますが、実は変数 numbers の中身は、前回と異なります。
前回の説明で、<MTSetVarBlock>で挟まれた内容が、変数にセットされると書きました。前回とはの違いは改行コードが含まれている点です。

この場合変数 numbers の中身には、<MTEntryKeywords>の出力の前後に改行が含まれます。そのため、後で変数を使い比較して条件分岐させるような場合に、予想外の動きをされる場合があります。

この様なケースを避けるために、比較する変数をセットする場合には、<MTSetVarBlock>の中で改行を使わないようにすべきです。

<MTSetVarBlock name="numbers"><MTEntryKeywords></MTSetVarBlock>

変数の書き方2(MTSetVarBlock)

MTタグのモディファイアに、MTタグの値を使いたい場合には、<MTSetVarBlock>タグを使います。

このタグで挟まれた内容が、変数に格納されます。

<MTSetVarBlock name="numbers"><MTEntryKeywords></MTSetVarBlock>
<MTComments lastn="$numbers">
    <p><$MTCommentAuthor$> said:<br />
    <$MTCommentBody$></p>
</MTComments>

最初の行で、変数 numbers に、エントリーのキーワードの値が設定されます。
次の行の $numbers というのは、変数を参照しています。モディファイアとして指定する場合には、<MTGetVar name="numbers">ではなく、こちらを使います。

変数の書き方2

MovableTypeの制限事項として、MTタグ内のモディファイア指定にMTタグは使えないというのがあります。

<MTSetVar name="mycategory" value="<$MTEntryCategory$>">

この様なMTタグの使い方は認められておりません。

MT3.3までは、この様なケースを処理するために、MTTagInvokeというプラグインを、使いました。

<MTTagInvoke tag_name="MTComments"> 
<MTTagInvokeAttribute name="lastn"><MTEntryKeywords></MTTagInvokeAttribute>
<MTTagInvokeContent>
    <p><$MTCommentAuthor$> said:<br />
    <$MTCommentBody$></p>
</MTTagInvokeContent>
</MTTagInvoke>

これは、実際には

<MTComments lastn="<MTEntryKeywords>">
    <p><$MTCommentAuthor$> said:<br />
    <$MTCommentBody$></p>
</MTComments>

という内容を、処理しようとしている事になります。

MT4以降では、変数を使って同様の処理が可能になっています。

Index of all entries

Home

Search
Feeds

Return to page top