MODX Revolution Meets Fenom

最近、英語圏のMODXコミュニティでは、「どうすればさらに先に進むことができるか」というトピックについて多くの議論があります。 誰もが間もなく(数年後には)メジャーバージョン3について議論しますが、現時点では、追加により現在のバージョンを改善しています。



幅広い読者と共有したい最近のイベントは、Fenom テンプレートエンジンを備えたpdoToolsの新しいバージョンのリリースです。



この手順では、サイトを変更する必要はありません。pdoToolsをバージョン2.0にアップグレードするだけで、 新しい構文を使用できます 。 最良の部分は、MODXタグがFenomに完全に隣接し、問題なく連携することです。 シードの簡単な例:

{if $parent == 3} [[!pdoMenu?parents=`0`]] {else} [[!pdoResources?parents=`1,2,3`]] {/if}
      
      



カットの下では、pdoToolsパーサーに関する膨大な量の情報が、私が一度も収集したことがありません。



そのため、pdoToolsパーサーは、MODXシステム設定に登録され、ページ上のタグ処理をインターセプトする別個のクラスです。

コンポーネントの古いバージョンでは、インストール時にパーサーを含めることを確認する必要がありましたが、バージョン2.1.1-plからはデフォルトで有効になっています。 何らかの理由でこれがあなたに合わない場合は、システム設定を削除します



デフォルトでは、MODXにはこれらの設定はありません。これらの設定は、この場合のように、外部パーサーを接続するためにのみ必要です。



動作原理



pdoParserは、次の2つの場合に使用できます。





チャンク処理



pdoToolsクラスには、このための2つのメソッドがあり、modXクラスのメソッドに非常に似ています。





これらのメソッドの主な機能は、 _loadChunkプロテクトメソッドを使用してチャンクをダウンロードすることです。これにより、データベースからチャンクをロードできるだけでなく、任意の文字列を変換できます。



チャンクオプション



したがって、両方のpdoToolsメソッドは、次のタイプのチャンク名をサポートします。



@INLINEまたは@CODE



最も一般的なオプションの1つは、ページ上でチャンクの本文を直接示すことです。 例:

 [[!pdoResources? &parents=`0` &tpl=`@INLINE <p>{{+id}} - {{+pagetitle}}</p>` ]]
      
      





このような表示には、多くの人が気にしないという機能があります。スニペットが呼び出される前に 、チャンク内のすべてのプレースホルダーがパーサーによって処理されます。



つまり、次のようにページ上でスニペットを呼び出すと:

 [[!pdoResources? &parents=`0` &tpl=`@INLINE <p>[[+id]] - [[+pagetitle]]</p>` ]]
      
      





プレースホルダー[[+id]]



または[[+pagetitle]]



がシステムのメモリに設定されると、既に処理されたチャンクがスニペットに送られ、次のような同じ行がページに表示されます。

 15 -  15 -  15 - 
      
      





他のスニペットが以前に設定したものと同じ値。 そのため、例ではこのような異常なプレースホルダーがあります- [[+]]



代わりに{{+}}



。 システムパーサーはそれらに触れず、操作中にpdoToolsがそれらを通常のものに置き換えます。



すべてのpdoToolsチャンクのプレースホルダーのフレームとして中括弧を使用できます-ロード時にそれらを[[+]]



に変換します。



同じ理由で、INLINEチャンクのスニペットとフィルターの呼び出しは機能しません。 これは動作しません

 [[!pdoResources? &parents=`0` &tpl=`@INLINE <p>[[+id]] - [[+pagetitle:default=` `]]</p>` ]]
      
      





そして-問題ない

 [[!pdoResources? &parents=`0` &tpl=`@INLINE <p>{{+id}} - {{+pagetitle:default=` `}}</p>` ]]
      
      





インラインチャンクを使用するときは、このニュアンスを覚えておいてください。



@FILE



多くの人々は、MODXをチャンクをファイルに保存できず、データベースで再び動作するように強制したことを非難します。 これは、バージョン管理システムにとっては不便であり、低速です。



バージョン2.2のMODXでは、 これらの目的静的要素を使用することを推奨していますが、いくつかの理由から、この方法はファイルを直接操作するよりも便利ではありません。



pdoToolsは、@ FILEを指定するときにこの可能性を開きます。

 [[!pdoResources? &parents=`0` &tpl=`@FILE resources/mychank.tpl` ]]
      
      





セキュリティ上の理由から、拡張子がhtmlおよびtplのファイルは、事前定義された特定のディレクトリからのみ使用できます。 デフォルトでは、次のとおりです/assets/elements/chunks/







&tplPath



パラメーターを使用して、ファイル用の独自のディレクトリーを指定できます。

 [[!pdoResources? &parents=`0` &tpl=`@FILE resources/mychunk.tpl` &tplPath=`/core/elements` ]]
      
      





このファイルは、サイトのルートから/core/elements/resources/mychunk.tpl



ファイルからダウンロードされます。



@TEMPLATE



このタイプのチャンクにより、システムテンプレート(つまりmodTemplateオブジェクト)を使用して出力をスタイル設定できます。

 [[!pdoResources? &parents=`0` &tpl=`@TEMPLATE Base Template` ]]
      
      





空のテンプレートが指定され、選択されたレコードにidまたはテンプレート名のtemplate



フィールドがある場合、レコードはこのテンプレートにラップされます。

 [[!pdoResources? &parents=`0` &tpl=`@TEMPLATE` ]]
      
      





これは、 renderResourcesスニペットに類似しています。



テンプレートを表示するときに、一連のパラメーター(スニペットなど)を指定することもできます。

 [[!pdoResources? &parents=`0` &tpl=`@TEMPLATE Base Template@MyPropertySet` ]]
      
      





次に、このセットの値がテンプレートに挿入されます。



通常のチャンク



これは、データベースからチャンクをロードするデフォルトモードです。

 [[!pdoResources? &parents=`0` &tpl=`MyChunk` ]]
      
      





パラメーターセットも同じ方法でサポートされます。

 [[!pdoResources? &parents=`0` &tpl=`MyChunk@MyPropertySet` ]]
      
      





チャンクをロードするこれらのメソッドは、すべてのネイティブpdoToolsスニペットと、pdoToolsのgetChunk



およびparseChunk



を使用する他のすべてのスニペットparseChunk







GetChunkメソッド



このメソッドの宣言は次のようになります。

 getChunk(string $chunkName, array $properties, bool $fastMode = false)
      
      





メソッドは、指定されたチャンクをロードし(存在する場合は@BINDINGの指示に従って)、それを完全に反転し、すべてのプレースホルダーを渡された値(パラメーター$プロパティ)に置き換えます。



3番目のパラメーター、 fastMode



、ページに余分なタグがないように、残りのすべての未加工のプレースホルダーを切り取ります。 これが行われない場合、パーサーはこれらのタグを再帰的に解析しようとします(デフォルトでは最大10回の反復)。これにより、速度が低下する可能性があります。



再帰的パーサーは、MODXの利点の1つであり、特別に残されたタグは、システムスニペットのロジックに非常によく見られます。 そのため、 fastMode



デフォルトで無効になっています。使用していることが確実な場合にのみ使用する必要があります。



pdoToolsパーサーは、すべてのプレースホルダーを独自に解析できた場合、システムパーサーを呼び出しません。 フィルターまたはスニペットへの呼び出しがチャンクに残っている場合、作業はmodParserに転送され、追加の処理時間が必要になります。



ParseChunkメソッド



そして、このメソッドは次のように宣言されます:

 parseChunk(string $name, array $properties, string $prefix = '[[+', string $suffix = ']]')
      
      





また、指定された名前からチャンクを作成し、@ BINDINGがある場合は解析し、特別な処理を行わずにプレースホルダーを値に置き換えます。



これは、データをチャンクでフォーマットする最も簡単で最速の方法です。



ページ処理



設定でpdoParserが有効になっている場合、ユーザーに表示されるときにページ全体を処理するために呼び出されます。



このパーサーを使用すると、すべてのMODXチャンクとアドオンが少し速く処理されます。 条件とフィルターを使用せず、 [[+id]]



[[~15]]



などの単純なタグのみを処理するため、「少し」だけです。 ただし、彼は不要なオブジェクトを作成しないため、modParserよりも高速です。



速度の向上に加えて、さまざまなリソースからデータを便利に出力するための新しい機会も得られます。



タグfastField



2012年の終わりに、MODXパーサーに新しいタグが追加され、fastFieldコンポーネントに成長し小さなプラグイン公開されまし



彼は[[#15.pagetitle]]



などの追加のプレースホルダーの処理をシステムに追加します。 著者の許可を得て 、この機能はすでにpdoParserに含まれており、わずかに拡張されています。



すべてのfastFieldタグは#



で始まり、目的のリソースのIDまたはグローバル配列の名前のいずれかを含みます。



通常のリソースフィールドの出力:

 [[#15.pagetitle]] [[#20.content]]
      
      





TVリソースパラメーター:

 [[#15.date]] [[#20.some_tv]]
      
      





MiniShop2製品フィールド:

 [[#21.price]] [[#22.article]]
      
      





リソースと商品の配列:

 [[#12.properties.somefield]] [[#15.size.1]]
      
      





スーパーグローバル配列:

 [[#POST.key]] [[#SESSION.another_key]] [[#GET.key3]] [[#REQUEST.key]] [[#SERVER.key]] [[#FILES.key]] [[#COOKIE.some_key]]
      
      





配列内の任意のフィールドを指定できます。

 [[#15.properties.key1.key2]]
      
      





配列内の値がわからない場合は、指定するだけで完全に出力されます。

 [[#GET]] [[#15.colors]] [[#12.properties]]
      
      





FastFieldタグは、MODXタグと組み合わせることができます。

 [[#[[++site_start]].pagetitle]] [[#[[++site_start]]]]
      
      





フェノムテンプレートエンジン



Fenomテンプレートエンジンのサポートは、 バージョン2.0からpdoToolsに登場し 、その後PHP 5.3+を必要とし始めました。



ネイティブmodParserよりもはるかに高速に動作し、単一のMODXタグを持たないようにチャンクを書き換えると、modParserはまったく起動しません。 同時に、もちろん、1つのチャンクで古いタグと新しいタグの両方を同時に操作することもできます。



次のシステム設定は、テンプレートエンジンによる処理に影響します。



そのため、デフォルトでは、FenomはpdoToolsを通過するチャンクでのみ動作するように有効になっています。 それは完全に安全であり、システム管理者は、より便利な構文と高速を除いて、追加機能を受け取りません。



pdotools_fenom_parserを有効にすると、ドキュメントおよびページテンプレートのコンテンツで直接Fenom構文を使用できますが、1つの注意点があります。テンプレートエンジンは、中括弧に誤って応答する可能性があります。



そのような場合、著者は{ ignore }タグの使用を推奨します。



Fenomをサイト全体でグローバルに有効にする予定がある場合、すべてのページで正常に機能するかどうかを確認する必要があります。



構文



開始するには、 公式ドキュメントを読むことをお勧めします。その後、MODXの構文を検討します。



スニペットのすべての変数はそのままチャンクに転送されるため、古いチャンクを新しい構文で書き換えることは本当に楽しいです。

MODX フェノム
[[+ id]] {$ id}
[[+ id:default = `test`]] {$ id ?: 'test'}
[[+ id:is = ``:then = `test`:else =` [[+ pagetitle]] `]]] {$ id == ''? 'テスト':$ pagetitle}


より複雑なエンティティを使用するために、pdoParserはサービス変数{$ _modx}を提供します。これにより、システムのいくつかの変数とメソッドに安全にアクセスできます。

MODX フェノム
[[* id]] {$ _modx-> resource.id}
[[* tv_param]] {$ _modx-> resource.tv_param}
[[%lexicon]] {$ _modx-> lexicon( 'lexicon')}
[[〜15]] {$ _modx-> makeUrl(15)}
[[〜[[* id]]]] {$ _modx-> makeUrl($ _ modx-> resource.id)}
[[++ system_setting]] {$ _modx-> config.system_setting}


これに加えて、変数を使用できます。

{$ _modx-> config} -システム設定

 {$_modx->config.site_name} {$_modx->config.emailsender} {$_modx->config['site_url']} {$_modx->config['any_system_setting']}
      
      





{$ _modx-> user} -現在のユーザーの配列。 許可されている場合、プロファイルのデータが追加されます。

 {if $_modx->user.id > 0} , {$_modx->user.fullname}! {else}   . {/if}
      
      





{$ _modx-> context} -現在のコンテキストを持つ配列

     {$_modx->context.key}
      
      





{$ _modx-> resource} -既に上記の例で見たように、現在のリソースの配列

 {$_modx->resource.id} {$_modx->resource.pagetitle} {$_modx->makeUrl($_modx->resource.id)}
      
      





{$ _modx-> lexicon} -任意の辞書をロードするために使用できるオブジェクト(配列ではありません!) modLexicon

 {$_modx->lexicon->load('ms2gallery:default')}   ms2Gallery: {$_modx->lexicon('ms2gallery_err_gallery_exists')}
      
      





別の関数{$_modx->lexicon()}



がレコードの出力を担当します。



ポイントを持つプレースホルダー



Fenomは配列の値にアクセスするためにポイントを使用し、MODXは通常このような配列からプレースホルダーを置きます。 したがって、[[+ tag.sub_tag]]タグの場合、Fenomには類似物はありません。



したがって、そのようなプレースホルダーには、2番目のユーティリティ変数- {$ _pls}を使用する必要があります。

 {$_pls['tag.subtag']}
      
      





出力スニペットとチャンク



{$_modx}



変数は、実際にはシンプルで安全なmicroMODXクラスです



したがって、スニペットとチャンクは次のように呼び出されます。

 {$_modx->runSnippet('!pdoPage@PropertySet', [ 'parents' => 0, 'showLog' => 1, 'element' => 'psoResources', 'where' => ['isfolder' => 1], 'showLog' => 1, ])} {$_modx->getPlaceholder('page.total')} {$_modx->getPlaceholder('page.nav')}
      
      





ご覧のとおり、構文はPHPとほぼ同じであり、新しい可能性が開かれています。 たとえば、JSON文字列の代わりに配列を指定できます。



デフォルトでは、すべてのスニペットはキャッシュと呼ばれますが、追加でき!



名前の前-MODXタグのように。



ネイティブMODXメソッドを使用してスニペットを呼び出すと、pdoToolsが起動してチャンクが表示され、そのすべての機能を使用できます。

 {$_modx->getChunk('MyChunk@PropertySet')} {$_modx->parseChunk('MyChunk', [ 'pl1' => 'placeholder1', 'pl2' => 'placeholder2', ])} {$_modx->getChunk('@TEMPLATE Base Template')} {$_modx->getChunk('@INLINE  : {$_modx->config.site_name} ')} {$_modx->getChunk( '@INLINE    : {$var}', ['var' => ''] )} {$_modx->getChunk(' @INLINE     : {$_modx->runSnippet("pdoResources", [ "parents" => $parents ])}  : {$_modx->getPlaceholder("total")} ', ['parents' => 0] )}
      
      





上記の例は少しおかしいですが、それらは自分で動作します。



キャッシュ管理



modX :: cacheManagerサービスは{$ _modx}オブジェクトで利用できます。これにより、呼び出されたスニペットに任意のキャッシュ時間を設定できます。

 {if !$snippet = $_modx->cacheManager->get('cache_key')} {set $snippet = $_modx->runSnippet('!pdoResources', [ 'parents' => 0, 'tpl' => '@INLINE {$id} - {$pagetitle}', 'showLog' => 1, ])} {set $null = $_modx->cacheManager->set('cache_key', $snippet, 1800)} {/if} {$snippet}
      
      





このキャッシュは、 /core/cache/default/



で表示できます。この例では、30分間保存されます。



cacheManager->set



がページに1(つまりtrue)をcacheManager->set



しないように、 set $null = ...



必要です。



また、システムプロセッサを起動できます(十分な権限がある場合)。

 {$_modx->runProcessor('resource/update', [ 'id' => 10, 'alias' => 'test', 'context_key' => 'web', ])}
      
      





認可チェック



{$_modx}



にはユーザーを持つオブジェクトがないため、承認とアクセス権をチェックするメソッドはクラスに直接使用されます。

 {$_modx->isAuthenticated()} {$_modx->hasSessionContext('web')} {$_modx->hasPermission('load')}
      
      





その他の方法



これらのメソッドはすべてのMODX開発者に馴染みがあるはずなので、例を挙げて説明します。

 {$_modx->regClientCss('/assets/css/style.css')} {$_modx->regClientScript('/assets/css/script.js')} {$_modx->sendForward(10)} {$_modx->sendRedirect('http://yandex.ru')} {$_modx->setPlaceholder('key', 'value')} {$_modx->getPlaceholder('key')} {if $res = $_modx->findResource('url-to/doc/')} {$_modx->sendRedirect( $_modx->makeUrl($res) )} {/if}
      
      





テンプレート拡張



Fenomテンプレートエンジンを使用すると、1つのチャンク(他のテンプレート)を含めたり、拡張したりすることができます。



たとえば、チャンクのコンテンツを単にロードできます。

   {include ' '}  modTemplate {include 'template: '}     {include 'chunk@propertySet'} {include 'template:Name@propertySet'}
      
      





公式ドキュメントの{ include }の詳細をご覧ください。



さらに興味深い機能は、テンプレートの{ extends }です。含まれるシステム設定pdotools_fenom_parserが必要です



基本テンプレート「Fenom Base」を作成します。

 <!DOCTYPE html> <html lang="en"> <head> {include 'head'} </head> <body> {block 'navbar'} {include 'navbar'} {/block} <div class="container"> <div class="row"> <div class="col-md-10"> {block 'content'} {$_modx->resource.content} {/block} </div> <div class="col-md-2"> {block 'sidebar'} Sidebar {/block} </div> </div> {block 'footer'} {include 'footer'} {/block} </div> </body> </html>
      
      





通常のチャンク(ちなみに、 Theme.Bootstrapコンポーネントの通常のMODXプレースホルダー)が含まれ、別のテンプレートで展開できるいくつかのブロックを定義します。



次に、「Fenom Extended」を作成します。

 {extends 'template:Fenom Base'} {block 'content'} <h3>{$_modx->resource.pagetitle}</h3> <div class="jumbotron"> {parent} </div> {/block}
      
      





したがって、1つの基本的なテンプレートを記述し、それを子で展開できます。



同様に、チャンクを作成および展開できます。modTemplateで作業するには、 template:プレフィックスを指定する必要がありますが、チャンクではなく、すべての{include}



および{extends}



デフォルトで機能することに注意してください。



性能試験



このコンソールスクリプトを使用して、新しいサイトを作成し、1000個のリソースを追加します。

 <?php define('MODX_API_MODE', true); require 'index.php'; $modx->getService('error','error.modError'); $modx->setLogLevel(modX::LOG_LEVEL_FATAL); $modx->setLogTarget(XPDO_CLI_MODE ? 'ECHO' : 'HTML'); for ($i = 1; $i <= 1000; $i++) { $modx->runProcessor('resource/create', array( 'parent' => 1, 'pagetitle' => 'page_' . rand(), 'template' => 1, 'published' => 1, )); }
      
      





次に、2つのチャンクを作成します。それぞれ、次の内容のmodx



modx



です。

 <p>[[+id]] - [[+pagetitle]]</p>
      
      





そして

 <p>{$id} - {$pagetitle}</p>
      
      





そして、2つのコンソールテストスクリプトを追加します。 ネイティブパーサーMODXの場合

 <?php define('MODX_API_MODE', true); require 'index.php'; $modx->getService('error','error.modError'); $modx->setLogLevel(modX::LOG_LEVEL_FATAL); $modx->setLogTarget(XPDO_CLI_MODE ? 'ECHO' : 'HTML'); $res = array(); $c = $modx->newQuery('modResource'); $c->select($modx->getSelectColumns('modResource')); $c->limit(10); if ($c->prepare() && $c->stmt->execute()) { while ($row = $c->stmt->fetch(PDO::FETCH_ASSOC)) { $res .= $modx->getChunk('modx', $row); } } echo number_format(microtime(true) - $modx->startTime, 4), 's<br>'; echo number_format(memory_get_usage() / 1048576, 4), 'mb<br>'; echo $res;
      
      





そして、pdoToolsの場合:

 <?php define('MODX_API_MODE', true); require 'index.php'; $modx->getService('error','error.modError'); $modx->setLogLevel(modX::LOG_LEVEL_FATAL); $modx->setLogTarget(XPDO_CLI_MODE ? 'ECHO' : 'HTML'); $pdoTools = $modx->getService('pdoTools'); $res = array(); $c = $modx->newQuery('modResource'); $c->select($modx->getSelectColumns('modResource')); $c->limit(10); if ($c->prepare() && $c->stmt->execute()) { while ($row = $c->stmt->fetch(PDO::FETCH_ASSOC)) { $res .= $pdoTools->getChunk('fenom', $row); //$res .= $pdoTools->getChunk('modx', $row); } } echo number_format(microtime(true) - $modx->startTime, 4), 's<br>'; echo number_format(memory_get_usage() / 1048576, 4), 'mb<br>'; echo $res;
      
      





pdoToolsは両方の構文を理解するため、MODXタグモードとFenomモードの2つのテストがあります。

スクリプトには、制限= 10の指示があります。その後、表に、増加した数値を示します。

制限 MODX pdoTools(MODX) pdoTools(フェノム)
10 0.0369秒8.1973mb 0.0136秒7.6760mb 0.0343秒8.6503mb
100 0.0805秒8.1996mb 0.0501秒7.6783mb 0.0489秒8.6525mb
500 0.2498秒8.2101mb 0.0852秒7.6888mb 0.0573秒8.6630mb
1000 0.4961s 8.2232mb 0.1583秒7.7019mb 0.0953秒8.6761mb


そして、チャンクを少し複雑にします-リソースのリンク生成とmenutitle



出力を追加しmenutitle





 <p><a href="[[~[[+id]]]]">[[+id]] - [[+menutitle:default=`[[+pagetitle]]`]]</a></p>
      
      





そして

 <p><a href="{$_modx->makeUrl($id)}">{$id} - {$menutitle ?: $pagetitle}</a></p>
      
      





制限 MODX pdoTools(MODX) pdoTools(フェノム)
10 0.0592秒8.2010mb 0.0165秒7.8505mb 0.0346秒8.6539mb
100 0.1936s 8.2058mb 0.0793秒7.8553mb 0.0483秒8.6588mb
500 0.3313秒8.2281mb 0.2465s 7.8776mb 0.0686秒8.6811mb
1000 0.6073秒8.2560mb 0.4733s 7.9055mb 0.1047秒8.7090mb


ご覧のとおり、pdoToolsを介したチャンクの処理は、すべての場合において高速です。

同時に、Fenomチャンクの開始には一定の最小値がありますが、これはテンプレートをコンパイルする必要があるためです。



おわりに



pdoToolsパーサーの機能を要約しましょう。



現時点では、pdoToolsは公式リポジトリから40,000回以上、modstore.proリポジトリから10,000回以上ダウンロードされており、MODXでの新しいテンプレートテクノロジーの広範な普及を期待できます。



素晴らしいテンプレートエンジンを提供してくれたaco habrayuzerに感謝します!



All Articles