「Help:テンプレートの制限」の版間の差分

削除された内容 追加された内容
組み換え。加筆修正。
新プリプロセッサ導入にともない更新
8行目: 8行目:
構文解析の過程では、生成されるページの複雑性を把握するためにいくつかのカウンターが使用されます。カウンターは解析開始時点でゼロに設定され、解析中に該当するプロセスがあると数値が計上されていきます。カウンターには上限値が設定されており、上限値を越えると展開ができなくなります。
構文解析の過程では、生成されるページの複雑性を把握するためにいくつかのカウンターが使用されます。カウンターは解析開始時点でゼロに設定され、解析中に該当するプロセスがあると数値が計上されていきます。カウンターには上限値が設定されており、上限値を越えると展開ができなくなります。


極端に長いページや[[Help:テンプレート|テンプレート]]をたくさん呼び出しているような複雑なページは解析に時間がかかります。このことは利用者にとって不便なだけでなく、処理不可能なほど巨大なデータを MediaWiki に解析させることで[[DoS攻撃]]の手段として悪用される可能性もあります。このような攻撃を予防し、ページの読み込みが常識的なスピードで行われることを保証するために、このような制限が設定されています。読み込みデータの制限は、2006年8月より導入されました。なお、2008年1月から英語版などで新しいプリプロセッサが導入され、制限の方法が変更されました。今後他のプロジェクトにも漸次拡大が予定されています([[meta:Migration to the new preprocessor]]参照)。日本語版ではURLで指定することでこのプリプロセッサを一時的に使うことができます([[#読み込み量]]参照)。
極端に長いページや[[Help:テンプレート|テンプレート]]をたくさん呼び出しているような複雑なページは解析に時間がかかります。このことは利用者にとって不便なだけでなく、処理不可能なほど巨大なデータを MediaWiki に解析させることで[[DoS攻撃]]の手段として悪用される可能性もあります。このような攻撃を予防し、ページの読み込みが常識的なスピードで行われることを保証するために、このような制限が設定されています。読み込みデータの制限は、2006年8月より導入されました。2008年2月から新しいプリプロセッサが導入され、制限の方法が変更されました([[meta:Migration to the new preprocessor]]参照)。


== 制限がおこりやすい事例 ==
== 制限がおこりやすい事例 ==
16行目: 16行目:
生成されたページ本体のHTMLソース中には、ソースの比較的末尾にHTMLコメントによってカウンターの数値が描き込まれています。そこで、ブラウザのHTMLソースを表示する機能を利用してHTMLソースを確認することで、そのページのカウンターの数値を知る事ができます。
生成されたページ本体のHTMLソース中には、ソースの比較的末尾にHTMLコメントによってカウンターの数値が描き込まれています。そこで、ブラウザのHTMLソースを表示する機能を利用してHTMLソースを確認することで、そのページのカウンターの数値を知る事ができます。


例えば、[[沖縄県]](<small>[http://ja.wikipedia.org/w/index.php?title=沖縄県&oldid=18080226 2008年2月18日 () 14:36 (UTC) の版]</small>)のページの生成されたHTMLソースにはつぎのコメントが含まれています。
例えば、[[沖縄県]](<small>[http://ja.wikipedia.org/w/index.php?title=沖縄県&oldid=18235452 2008年2月26日 () 14:15 (UTC) の版]</small>)のページの生成されたHTMLソースにはつぎのコメントが含まれています。


<pre>
<pre>
<!--
<!--
NewPP limit report
Pre-expand include size: 68326/2048000 bytes
Preprocessor node count: 1477/1000000
Post-expand include size: 43390/2048000 bytes
Template argument size: 13601/2048000 bytes
Post-expand include size: 45830/2048000 bytes
Template argument size: 10079/2048000 bytes
#ifexist count: 1/500
#ifexist count: 1/500
-->
--></pre>
</pre>


/の前の数値が計上された数値、/の後の数値が制限値です。カウンターの仕様により、表示される数値は常に制限値よりも小さくなります。もし/の前の数値が制限値(/の後の数値)に近ければ、読み込まれなかったテンプレートがある可能性があります。呼び込まれなかったテンプレートがある場合、この旨を伝えるエラーメッセージがHTMLソース中に表示されます。例えば、[http://ja.wikipedia.org/w/index.php?title=皇室の系図一覧&oldid=15529665 皇室の系図一覧 2008年1月16日 (水) 07:10 (UTC) の版] を見てみましょう。カウンターの数値は
/の前の数値が計上された数値、/の後の数値が制限値です。カウンターの仕様により、表示される数値は常に制限値よりも小さくなります。もし/の前の数値が制限値(/の後の数値)に近ければ、読み込まれなかったテンプレートがある可能性があります。呼び込まれなかったテンプレートがある場合、この旨を伝えるエラーメッセージがHTMLソース中に表示されます。
<pre>
<!--
Pre-expand include size: 2047788/2048000 bytes
Post-expand include size: 395045/2048000 bytes
Template argument size: 717271/2048000 bytes
#ifexist count: 1/500
-->
</pre>
となっており、読み込みに失敗してテンプレートへのリンクだけが示されている部分のHTMLソースにはそれぞれ “<tt>&lt;!-- WARNING: template omitted, pre-expand include size too large--&gt;</tt>” のコメントが書き込まれていますね。


== 読み込み制限の仕組み ==
== 読み込み制限の仕組み ==
解析の過程で使われる制限には、「展開前読み込み量「展開後読み込み量」、「テンプレート引数量」、「#ifexixt 使用回数」の4種があります(新プリプロセッサでは「展開前読み込み量」の代わりに「プリプロセッサ・ノード数」を使用)
解析の過程で使われる制限には、「プリプロセッサ・ノード数「展開後読み込み量」、「テンプレート引数量」、「#ifexixt 使用回数」の4種があります。


=== プリプロセッサ・ノード数 ===
=== 読み込み量 ===
「プリプロセッサ・ノード数」(Preprocessor node count)のカウンターは新プリプロセッサから採用されました。これは、データの量ではなく、ページの複雑性を計測しています。解析によってページが展開される時には、HTMLの構造に対応する「ツリー」と呼ばれるデータ構造を生成しますが、このツリーのノードの数を計るものです。このカウンターが制限値を越えると、解析が中止され、生成HTMLページ中に "Node-count limit exceeded" のエラーメッセージを生成します。ノード数にはテンプレートだけでなく、リンク、セクション見出し、HTML要素などがすべて計上されています。
ページ内のソースコードに従って、テンプレートの展開行うための構文解析がはじまると、ソフトウェアはまず、展開のテンプレートソースコードの長さ(展開読み込み量(pre-expand include size))読み込み先のページの「展開カウンター」に計上ます。このとき、もし計上後の数値が「展開読み込み制限値」を越えていれば、テンプレートは展開されず、生成されたHTMLソース中にコメントとしてエラーメッセージが出力されます。


=== 読み込み量 ===
計上後の数値が「展開前読み込み制限値」内であれば、「展開前カウンター」の数値が新しい値に設定され、テンプレートが展開されます。テンプレート展開後には、テンプレートによって生成されるHTMLソースコードの長さ(展開後読み込み両(post-expand include size))が、「展開後カウンター」に計上されます。もし計上後の数値が「展開後読み込み制限値」を越えていれば、テンプレートはページ内に読み込まれず、生成されたHTMLソース中に別のエラーメッセージが出力されます。数値が「展開後読み込み制限値」内であれば、テンプレートによって生成されたHTMLコードがページ本体のHTMLの中に組み込まれ、「展開後カウンター」の数値が新しい値に設定されます。
ソフトウェアはページ内のソースコードに従って構文解析を行い、テンプレートを展開します。こ時、テンプレートによって生成されるHTMLソースコードの長さ(展開読み込み量(post-expand include size))、「展開カウンター」に計上されます。もし計上後の数値が「展開読み込み制限値」を越えていれば、テンプレートはページ内に読み込まれず、生成されたHTMLソース中にエラーメッセージが出力されます。数値が「展開後読み込み制限値」内であれば、テンプレートによって生成されたHTMLコードがページ本体のHTMLの中に組み込まれ、「展開後カウンター」の数値が新しい値に設定されます。


テンプレートは再帰的に展開されるため、もし読み込まれているテンプレート自体に他のテンプレートが呼び出されている場合、呼び出されている下位のテンプレートの値も、最終的に呼び出されているページのカウンターの数値に影響します。そのため、下位のテンプレートを呼び出している途中に制限値を超過した場合、テンプレートの展開が途中でとまってしまうこともありえます。
テンプレートは再帰的に展開されるため、もし読み込まれているテンプレート自体に他のテンプレートが呼び出されている場合、呼び出されている下位のテンプレートの値も、最終的に呼び出されているページのカウンターの数値に影響します。そのため、下位のテンプレートを呼び出している途中に制限値を超過した場合、テンプレートの展開が途中でとまってしまうこともありえます。

例えば、テンプレート <code><nowiki>{{A}}</nowiki></code> に <code><nowiki>{{B}}{{B}}{{B}}{{B}}{{B}}</nowiki></code> が含まれておりプレト <code><nowiki>{{B}}</nowiki></code> ソースは、100バイトのプレインテキストが含まれているとし。テンプレート <code><nowiki>{{A}}</nowiki></code> を呼び出す前の段階で、展開後カウンターに余裕が150バイトしかなかったと仮定します。この時、テンプレート <code><nowiki>{{B}}</nowiki></code> の展開が2回行われた後のテンプレート <code><nowiki>{{A}}</nowiki></code> が生成するHTMLソースは200バイトを越えますので、結果としてテンプレート <code><nowiki>{{A}}</nowiki></code> は呼び出し先のページに表示されません。


また、カウンターはテンプレートがページに読み込まれるたびに増加しますので、1ページ内に何度も使用されているテンプレートがあった場合、読み込まれている回数分、カウンターの数値が増加することになります。
また、カウンターはテンプレートがページに読み込まれるたびに増加しますので、1ページ内に何度も使用されているテンプレートがあった場合、読み込まれている回数分、カウンターの数値が増加することになります。


新プリプロセッサの導入前は、テンプレートの展開前のデータ量も計測しており、これがテンプレートの制限でもっとも問題になっていました。[[特別:ParserDiffTest]]は古いプリプロセッサと新しいプリプロセッサの出力結果の違いを差分表示する特別ページです。/を使って直接解析ページを指定したリンクも作れます(例:[[特別:ParserDiffTest/皇室の系図一覧]]。リンク先は非常に重いページとなっていますので、クリックする際にはご注意下さい)。
例えば、テンプレート <code><nowiki>{{A}}</nowiki></code> に <code><nowiki>{{B}}{{B}}{{B}}{{B}}{{B}}</nowiki></code> が含まれており、テンプレート <code><nowiki>{{B}}</nowiki></code> のソースには、100バイトのプレインテキストが含まれているとします。この時、
# テンプレート <code><nowiki>{{A}}</nowiki></code> の呼び出しは、呼び出し先のページの「展開前カウンター」に25バイトを計上します。25を計上すると展開前カウンターが制限値を越えてしまう場合、テンプレート <code><nowiki>{{A}}</nowiki></code> は展開されません。
# テンプレート <code><nowiki>{{A}}</nowiki></code> を呼び出す前の段階で、展開前カウンターに余裕が250バイトあったと仮定します。この時、テンプレート <code><nowiki>{{A}}</nowiki></code> が展開されると、カウンターの残りは225バイトですから、最初の2回のテンプレート <code><nowiki>{{B}}</nowiki></code> は展開されますが、残りの3回は制限値を越えるため、展開されません。
# 上記の仮定は「展開後カウことを考慮れていませんここで、テンプレート <code><nowiki>{{A}}</nowiki></code> を呼び出す前の段階で、展開後カウンターに余裕が150バイトしかなかったと仮定します。この時、テンプレート <code><nowiki>{{B}}</nowiki></code> の展開が2回行われた後のテンプレート <code><nowiki>{{A}}</nowiki></code> が生成するHTMLソースは200バイトを越えますので、結果としてテンプレート <code><nowiki>{{A}}</nowiki></code> は呼び出し先のページに表示されません。

テンプレートの制限でもっとも問題になりやすいのが、「展開前読み込み量」の制限です。英語版で導入されている新プリプロセッサでは「展開前読み込み量」の制限はなく、「展開後読み込み量」のプロセスだけが行われます。このため、現在日本語版でテンプレートの読み込みに失敗している場合、 新しいプリプロセッサを使えば読み込める場合があります。これは <code>&timtest=newpp</code> の引数をURLに追加するか、[[特別:ParserDiffTest]]を使って確認できます(&#123;&#123;[[Template:Npp|Npp]]&#125;&#125;のテンプレートを使用すると、<code>&timtest=newpp</code> の引数を追加したURLへのリンクを簡便に表示させることができます)。

例えば上の読み込みに失敗している例で取り上げた皇室の系図一覧のページを <code>http://ja.wikipedia.org/w/index.php?title=皇室の系図一覧&oldid=17394772&timtest=newpp </code>というURLを使って表示させると、新しいプリプロセッサが一時的に使われ、テンプレートはすべて読み込みに成功しています。ちなみにカウンターの数値は
<pre>
<!--
NewPP limit report
Preprocessor node count: 134618/1000000
Post-expand include size: 711668/2048000 bytes
Template argument size: 325381/2048000 bytes
#ifexist count: 1/500
-->
</pre>
となっています。

[[特別:ParserDiffTest]]は古いプリプロセッサと新しいプリプロセッサの出力結果の違いを差分表示する特別ページです。/を使って直接解析ページを指定したリンクも作れます(例:[[特別:ParserDiffTest/皇室の系図一覧]]。リンク先は非常に重いページとなっていますので、クリックする際にはご注意下さい)。


また、新プリプロセッサでは、条件文を用いたテンプレートの実行されない部分を展開しません。例えば、<code><nowiki>{{#if:yes|{{bar}}|{{foo}} }}</nowiki></code>というコードがあったとすると、テンプレート <nowiki>{{bar}}</nowiki> は展開され、テンプレート <nowiki>{{foo}}</nowiki> は展開されません。ただし、最終的な出力結果には表れないテンプレートの引数が展開後読み込み量に計上されることがあります。例えば <code><nowiki>{{#if:{{foo}}|yes|no}}</nowiki></code> というコードがあったとすると、解析の際に条件文の決定のためにテンプレート <nowiki>{{foo}}</nowiki> の展開が必要なため、 <nowiki>{{foo}}</nowiki> の展開量が展開後カウンターに計上されます。
また、新プリプロセッサでは、条件文を用いたテンプレートの実行されない部分を展開しません。例えば、<code><nowiki>{{#if:yes|{{bar}}|{{foo}} }}</nowiki></code>というコードがあったとすると、テンプレート <nowiki>{{bar}}</nowiki> は展開され、テンプレート <nowiki>{{foo}}</nowiki> は展開されません。ただし、最終的な出力結果には表れないテンプレートの引数が展開後読み込み量に計上されることがあります。例えば <code><nowiki>{{#if:{{foo}}|yes|no}}</nowiki></code> というコードがあったとすると、解析の際に条件文の決定のためにテンプレート <nowiki>{{foo}}</nowiki> の展開が必要なため、 <nowiki>{{foo}}</nowiki> の展開量が展開後カウンターに計上されます。
78行目: 53行目:
=== #ifexist 使用回数 ===
=== #ifexist 使用回数 ===
<nowiki>#</nowiki>ifexist 使用回数の制限は、[[Help:条件文|条件文]]中の #ifexist の使用回数を制限するものです。この機能は、指定されたページが存在するかどうかで出力を切り替えるのに使用されます。使用回数が制限値を超えると、それより後の #ifexist では、ページの存在はすべてないものとして返されます。
<nowiki>#</nowiki>ifexist 使用回数の制限は、[[Help:条件文|条件文]]中の #ifexist の使用回数を制限するものです。この機能は、指定されたページが存在するかどうかで出力を切り替えるのに使用されます。使用回数が制限値を超えると、それより後の #ifexist では、ページの存在はすべてないものとして返されます。

=== プリプロセッサ・ノード数 ===
新プリプロセッサで採用されている「プリプロセッサ・ノード数」(Preprocessor node count)は、データの量ではなく、ページの複雑性を計測しています。解析によってページが展開される時には、HTMLの構造に対応する「ツリー」と呼ばれるデータ構造を生成しますが、このツリーのノードの数を計るものです。このカウンターが制限値を越えると、解析が中止され、生成HTMLページ中に "Node-count limit exceeded" のエラーメッセージを生成します。ノード数にはテンプレートだけでなく、リンク、セクション見出し、HTML要素などがすべて計上されています。


== 制限内でやりくりするには ==
== 制限内でやりくりするには ==
86行目: 58行目:


=== noinclude と onlyinclude タグおよびコメントの使用 ===
=== noinclude と onlyinclude タグおよびコメントの使用 ===
テンプレートの展開時には、テンプレートのウィキソースの全体量が展開前カウンターに計上され、この時、データが&lt;noinclude&gt; や &lt;includeonly&gt; 、 &lt;onlyinclude&gt; タグに囲まれているかどうかは無関係です。しかし、&lt;noinclude&gt; タグに囲まれている部分、もしくは &lt;onlyinclude&gt; タグの外にある部分は呼び出し先に展開されませんから、これらの部分が「展開前カウンター」に計上される時展開ータ量分だけが計上された「展開カウンター数値には一切影響を与えせん
テンプレートの展開時には &lt;noinclude&gt; タグに囲まれている部分、もしくは &lt;onlyinclude&gt; タグの外にある部分は呼び出し先に展開されません。またHTMLコメントも展開されません。したがって、これらの部分は「展開後カウンター」の数値には一切影響を与えません、新プリプロセッサ導入前に用いられていた、「展開前カウンター」に計上されていました。このカウンターの制限よりテンプレートが展開されない場合が少なくなかったため、[[Help:テンプレート説明文|テンプレトの説明文]]を /doc というサブページに切り離し、&lt;noinclude&gt; グで囲んでテンプレート本体に読み込むようにすることで、テンプレートの読み込みサイズを小くすることが行わていす。新プリプロセッサでは展開カウンターを使用しないで、説明文がり離されているかどうかは読み込み制限にほとんど影響がなくなりす。詳しくは[[Help:テンプレートの説明文]]を参照してください

例えば、<code><nowiki>{{C}}</nowiki></code> には <code><nowiki><noinclude>{{D}}</noinclude></nowiki></code> が含まれ、 <code><nowiki>{{D}}</nowiki></code> には500バイトのデータが含まれており、呼び出し先のページの「展開前カウンター」に250バイトの余裕がある時、テンプレート <code><nowiki>{{C}}</nowiki></code> は問題なく読み込まれ、ページの「展開前カウンター」には28バイトしか計上されません。

[[Help:テンプレートの説明文|テンプレートの説明文]]は、多くの場合、&lt;noinclude&gt; タグで囲んで提供されます。テンプレート呼び出しの際には、これらの部分の展開前のウィキテキストのデータ量しか展開前カウンターには計上されませんから、テンプレートの説明文を /doc というサブページに切り離し、テンプレート本体に読み込むようにすることで、テンプレートの読み込みサイズを小さくすることができます。詳しくは[[Help:テンプレートの説明文]]を参照してください。ただし新プリプロセッサでは展開前カウンターを使用しないので、説明文が切り離されているかどうかは読み込み制限にほとんど影響がなくなります。

HTMLコメントも展開前カウンターには計上されますが、展開後カウンターには計上されません。

=== 条件文の使用 ===
<nowiki>{{#ifexpr}}</nowiki> などの[[Help:条件文]]を用いて、テンプレートの読み込みを制限することが可能です。この時、条件文の書き方によっては、条件文の結果によってテンプレートが読み込まれなくても、テンプレートのソースのデータ量は呼び出し先のページのカウンターに計上されます。これは、条件文を展開する前に、条件文の内容が読み込まれるためです。例えば、
<nowiki>{{#ifexpr:0|{{:123}}}}</nowiki>
では、結果は自明に偽なので、ページ [[123]]は読み込まれませんが、ページ[[123]]のデータ量は、「展開前カウンター」に計上されます。

この問題を解決するためには、呼び出しタグを条件文の外に出します。
<nowiki>{{ {{#ifexpr:0|:123|x0}} }}</nowiki>
この場合も、ページ[[123]]は読み込まれませんが、条件文中に呼び出しタグがないため、条件文の計算前に[[123]]が読み込まれることはなく、中身が空のテンプレート<nowiki>{{</nowiki>[[:en:Template:x0|x0]]}}が呼び出されるだけのため、結果としてカウンターにはなにも計上されません。

=== 配列の各要素にテンプレートを使う ===
巨大な[[配列]](例えば要素が100以上のもの)を用いる時には、各要素に別のテンプレートを用意した方がよいでしょう(例:[[:meta:Template:Eln de]])。このようにしておけば、配列に含まれている要素を1回ずつ呼び出しても、その展開前読み込みサイズは配列全体のサイズの一次に留まります。しかし、もし全ての要素を #switch を用いて1つのテンプレートに収めると(例えば[[:meta:Template:N en]])、各要素を呼び出した時の展開前読み込みサイズは配列全体のサイズの倍数になってしまい、あっというまに制限値に達してしまうでしょう。

ただし、100の要素を含む1つのテンプレートのかわりに、1つの要素を持つ100のテンプレートを作るのも大変ですので、例えば10の要素を持つテンプレートを10作る、というような方策もあるでしょう。


=== 同じテンプレートの呼び出しを避ける ===
=== 同じテンプレートの呼び出しを避ける ===

2008年3月1日 (土) 02:54時点における版


ウィキペディア日本語版ヘルプページです。


ウィキペディアの使用しているソフトウェアMediaWikiには、テンプレート呼び出しやテンプレートの代入展開によってページに読み込まれるデータ量を制限するためのパラメータがいくつかあります。このページでは、なぜ、そしてどのようにこの制限が用いられているかについて解説しています。

概要

MediaWikiソフトウェアでは、ウィキテキスト(ウィキソース)をもとにHTMLページが生成されますが、読み込みデータについては構文解析の一種(再帰下降構文解析)を使用しています。ウィキテキストは「プリプロセッサ」を用いて「ツリー」と呼ばれるデータ構造に変換され、このツリーを用いてHTMLソースが生成されます。

構文解析の過程では、生成されるページの複雑性を把握するためにいくつかのカウンターが使用されます。カウンターは解析開始時点でゼロに設定され、解析中に該当するプロセスがあると数値が計上されていきます。カウンターには上限値が設定されており、上限値を越えると展開ができなくなります。

極端に長いページやテンプレートをたくさん呼び出しているような複雑なページは解析に時間がかかります。このことは利用者にとって不便なだけでなく、処理不可能なほど巨大なデータを MediaWiki に解析させることでDoS攻撃の手段として悪用される可能性もあります。このような攻撃を予防し、ページの読み込みが常識的なスピードで行われることを保証するために、このような制限が設定されています。読み込みデータの制限は、2006年8月より導入されました。2008年2月から新しいプリプロセッサが導入され、制限の方法が変更されました(meta:Migration to the new preprocessor参照)。

制限がおこりやすい事例

読み込み制限は、同じテンプレートを何度も使用している場合によく起こります。例えば、長い表の各行に同じテンプレートを呼び出しているような場合です。テンプレート自体のデータが小さくても、テンプレート呼び出しの際ごとにテンプレートページのソース全体量が計上されますので、思っているよりも簡単に制限値に達することになります。また、当然ながら、呼び出しているテンプレートのサイズが大きければ大きいほど、制限に達するのも早くなります。サイズが大きい理由としては、テンプレート本体が複雑であったり、テンプレートの説明文が付随していたり、呼び出し先で必要なデータ以外の多くのデータを含んでいたりすることが考えられます。

制限値に達しているか判別するには

生成されたページ本体のHTMLソース中には、ソースの比較的末尾にHTMLコメントによってカウンターの数値が描き込まれています。そこで、ブラウザのHTMLソースを表示する機能を利用してHTMLソースを確認することで、そのページのカウンターの数値を知る事ができます。

例えば、沖縄県2008年2月26日 (火) 14:15 (UTC) の版)のページの生成されたHTMLソースにはつぎのコメントが含まれています。

<!-- 
NewPP limit report
Preprocessor node count: 1477/1000000
Post-expand include size: 45830/2048000 bytes
Template argument size: 10079/2048000 bytes
#ifexist count: 1/500
-->

/の前の数値が計上された数値、/の後の数値が制限値です。カウンターの仕様により、表示される数値は常に制限値よりも小さくなります。もし/の前の数値が制限値(/の後の数値)に近ければ、読み込まれなかったテンプレートがある可能性があります。呼び込まれなかったテンプレートがある場合、この旨を伝えるエラーメッセージがHTMLソース中に表示されます。

読み込み制限の仕組み

解析の過程で使われる制限には、「プリプロセッサ・ノード数」、「展開後読み込み量」、「テンプレート引数量」、「#ifexixt 使用回数」の4種があります。

プリプロセッサ・ノード数

「プリプロセッサ・ノード数」(Preprocessor node count)のカウンターは新プリプロセッサから採用されました。これは、データの量ではなく、ページの複雑性を計測しています。解析によってページが展開される時には、HTMLの構造に対応する「ツリー」と呼ばれるデータ構造を生成しますが、このツリーのノードの数を計るものです。このカウンターが制限値を越えると、解析が中止され、生成HTMLページ中に "Node-count limit exceeded" のエラーメッセージを生成します。ノード数にはテンプレートだけでなく、リンク、セクション見出し、HTML要素などがすべて計上されています。

読み込み量

ソフトウェアはページ内のソースコードに従って構文解析を行い、テンプレートを展開します。この時、テンプレートによって生成されるHTMLソースコードの長さ(展開後読み込み量(post-expand include size))が、「展開後カウンター」に計上されます。もし計上後の数値が「展開後読み込み制限値」を越えていれば、テンプレートはページ内に読み込まれず、生成されたHTMLソース中にエラーメッセージが出力されます。数値が「展開後読み込み制限値」内であれば、テンプレートによって生成されたHTMLコードがページ本体のHTMLの中に組み込まれ、「展開後カウンター」の数値が新しい値に設定されます。

テンプレートは再帰的に展開されるため、もし読み込まれているテンプレート自体に他のテンプレートが呼び出されている場合、呼び出されている下位のテンプレートの値も、最終的に呼び出されているページのカウンターの数値に影響します。そのため、下位のテンプレートを呼び出している途中に制限値を超過した場合、テンプレートの展開が途中でとまってしまうこともありえます。

例えば、テンプレート {{A}}{{B}}{{B}}{{B}}{{B}}{{B}} が含まれており、テンプレート {{B}} のソースには、100バイトのプレインテキストが含まれているとします。テンプレート {{A}} を呼び出す前の段階で、展開後カウンターに余裕が150バイトしかなかったと仮定します。この時、テンプレート {{B}} の展開が2回行われた後のテンプレート {{A}} が生成するHTMLソースは200バイトを越えますので、結果としてテンプレート {{A}} は呼び出し先のページに表示されません。

また、カウンターはテンプレートがページに読み込まれるたびに増加しますので、1ページ内に何度も使用されているテンプレートがあった場合、読み込まれている回数分、カウンターの数値が増加することになります。

新プリプロセッサの導入前は、テンプレートの展開前のデータ量も計測しており、これがテンプレートの制限でもっとも問題になっていました。特別:ParserDiffTestは古いプリプロセッサと新しいプリプロセッサの出力結果の違いを差分表示する特別ページです。/を使って直接解析ページを指定したリンクも作れます(例:特別:ParserDiffTest/皇室の系図一覧。リンク先は非常に重いページとなっていますので、クリックする際にはご注意下さい)。

また、新プリプロセッサでは、条件文を用いたテンプレートの実行されない部分を展開しません。例えば、{{#if:yes|{{bar}}|{{foo}} }}というコードがあったとすると、テンプレート {{bar}} は展開され、テンプレート {{foo}} は展開されません。ただし、最終的な出力結果には表れないテンプレートの引数が展開後読み込み量に計上されることがあります。例えば {{#if:{{foo}}|yes|no}} というコードがあったとすると、解析の際に条件文の決定のためにテンプレート {{foo}} の展開が必要なため、 {{foo}} の展開量が展開後カウンターに計上されます。

テンプレート引数量

「テンプレート引数量」カウンターは、代入されるテンプレート変数の引数を計上します。

#ifexist 使用回数

#ifexist 使用回数の制限は、条件文中の #ifexist の使用回数を制限するものです。この機能は、指定されたページが存在するかどうかで出力を切り替えるのに使用されます。使用回数が制限値を超えると、それより後の #ifexist では、ページの存在はすべてないものとして返されます。

制限内でやりくりするには

ページがテンプレートの制限に達した場合、もっとも一般的な解決法は、下記の方法を用いてテンプレートを短くすることです。これでも解決しない場合、テンプレート呼び出しではなく、ページ本体に直接記述するデータを増やすことを考えてみてください。その際には特別ページのテンプレートを展開が利用できます。

noinclude と onlyinclude タグおよびコメントの使用

テンプレートの展開時には <noinclude> タグに囲まれている部分、もしくは <onlyinclude> タグの外にある部分は呼び出し先に展開されません。またHTMLコメントも展開されません。したがって、これらの部分は「展開後カウンター」の数値には一切影響を与えませんが、新プリプロセッサ導入前に用いられていた、「展開前カウンター」には計上されていました。このカウンターの制限によりテンプレートが展開されない場合が少なくなかったため、テンプレートの説明文を /doc というサブページに切り離し、<noinclude> タグで囲んでテンプレート本体に読み込むようにすることで、テンプレートの読み込みサイズを小さくすることが行われています。新プリプロセッサでは展開前カウンターを使用しないので、説明文が切り離されているかどうかは読み込み制限にほとんど影響がなくなります。詳しくはHelp:テンプレートの説明文を参照してください。

同じテンプレートの呼び出しを避ける

テンプレートAを何度も呼び出す代りに、Aを引数にとるテンプレートBを呼び出すということが可能な場合があります。

参考文献