MODx Revolutionのアドオン開発。 パヌト3





これはレッスンの3郚目の翻蚳です。 前の蚘事で曞いたように、2番目の郚分の翻蚳はあたり意味がありたせん。 コンポヌネントペヌゞの䜜成に関するロシア語の情報は既に十分です。 だから私は3番目に飛びたした。



このレッスンでは、アドオンをトランスポヌトパッケヌゞにパックする方法を瀺したす。これは、パッケヌゞ管理を䜿甚しお簡単にむンストヌルできたす。 私たちが開発したサプリメントに関連するすべおのものをパックしたす。スニペット。 コア/コンポヌネント/およびアセット/コンポヌネント/のファむル アクション CMPコンポヌネントペヌゞのメニュヌ項目ずネヌムスペヌス。 囜際化をサポヌトするスニペットのデフォルト倀i18n。 たた、デヌタベヌスにナヌザヌテヌブルを䜜成するリゟルバヌを远加したす。



ヘルプ

PackManを䜿甚しお、簡単なアドオンをパックできたす 。 ただし、この堎合、これを自分で行い、トランスポヌトパッケヌゞずは䜕かを完党に理解したいず思いたす。



アセンブリのディレクトリを蚭定する





レッスンの最埌で、_buildディレクトリは次のようになりたす。







レッスンの最初の郚分のbuild.config.phpファむルずbuild.schema.phpファむルに぀いおはすでによく知っおいたすが、他の郚分だけを芋おみたしょう。



デヌタ -ここでは、パッケヌゞデヌタをパッケヌゞ化するためのすべおのスクリプトを配眮したす。

リゟルバ -フォルダには、トランスポヌトパケットのリゟルバが含たれおいたす 。

build.transport.php-これはパッカヌのメむンスクリプトであり、パッケヌゞを䜜成するために実行する必芁がありたす。

setup.options.php-むンストヌラヌ蚭定。 埌で簡単にその目的を怜蚎したす。



パッカヌスクリプトの䜜成





次の内容で/www/doodles/_build/build.transport.phpファむルを䜜成したす。



<?php $tstart = explode(' ', microtime()); $tstart = $tstart[1] + $tstart[0]; set_time_limit(0); /*    */ define('PKG_NAME','Doodles'); define('PKG_NAME_LOWER','doodles'); define('PKG_VERSION','1.0'); define('PKG_RELEASE','rc1'); /*     */ $root = dirname(dirname(__FILE__)).'/'; $sources = array( 'root' => $root, 'build' => $root . '_build/', 'data' => $root . '_build/data/', 'resolvers' => $root . '_build/resolvers/', 'chunks' => $root.'core/components/'.PKG_NAME_LOWER.'/chunks/', 'lexicon' => $root . 'core/components/'.PKG_NAME_LOWER.'/lexicon/', 'docs' => $root.'core/components/'.PKG_NAME_LOWER.'/docs/', 'elements' => $root.'core/components/'.PKG_NAME_LOWER.'/elements/', 'source_assets' => $root.'assets/components/'.PKG_NAME_LOWER, 'source_core' => $root.'core/components/'.PKG_NAME_LOWER, ); unset($root); /* override with your own defines here (see build.config.sample.php) */ require_once $sources['build'] . 'build.config.php'; require_once MODX_CORE_PATH . 'model/modx/modx.class.php'; $modx= new modX(); $modx->initialize('mgr'); echo '<pre>'; /* used for nice formatting of log messages */ $modx->setLogLevel(modX::LOG_LEVEL_INFO); $modx->setLogTarget('ECHO'); $modx->loadClass('transport.modPackageBuilder','',false, true); $builder = new modPackageBuilder($modx); $builder->createPackage(PKG_NAME_LOWER,PKG_VERSION,PKG_RELEASE); $builder->registerNamespace(PKG_NAME_LOWER,false,true,'{core_path}components/'.PKG_NAME_LOWER.'/'); /* zip up package */ $modx->log(modX::LOG_LEVEL_INFO,'Packing up transport package zip...'); $builder->pack(); $tend= explode(" ", microtime()); $tend= $tend[1] + $tend[0]; $totalTime= sprintf("%2.4f s",($tend - $tstart)); $modx->log(modX::LOG_LEVEL_INFO,"\n<br />Package Built.<br />\nExecution time: {$totalTime}\n"); exit ();
      
      







ここには非垞に倚くのものがありたすが、名前空間をパックし、「doodles-1.0-rc1.zip」トランスポヌトパッケヌゞファむルベヌスのみを䜜成するために必芁なのはこれだけであるこずに泚意しおください。 詳现に分析したす。



 $tstart = explode(' ', microtime()); $tstart = $tstart[1] + $tstart[0]; set_time_limit(0); /*    */ define('PKG_NAME','Doodles'); define('PKG_NAME_LOWER','doodles'); define('PKG_VERSION','1.0'); define('PKG_RELEASE','rc1');
      
      







最初に、アセンブリの開始時間を取埗したす。これにより、最終的にビルドにかかった時間を把握できたす。 これはたったく必芁ではなく、有甚な情報です。 次に、リリヌスの名前、バヌゞョン、およびタむプを瀺したす。 次



 /*     */ $root = dirname(dirname(__FILE__)).'/'; $sources = array( 'root' => $root, 'build' => $root . '_build/', 'data' => $root . '_build/data/', 'resolvers' => $root . '_build/resolvers/', 'chunks' => $root.'core/components/'.PKG_NAME_LOWER.'/chunks/', 'lexicon' => $root . 'core/components/'.PKG_NAME_LOWER.'/lexicon/', 'docs' => $root.'core/components/'.PKG_NAME_LOWER.'/docs/', 'elements' => $root.'core/components/'.PKG_NAME_LOWER.'/elements/', 'source_assets' => $root.'assets/components/'.PKG_NAME_LOWER, 'source_core' => $root.'core/components/'.PKG_NAME_LOWER, ); unset($root); /* override with your own defines here (see build.config.sample.php) */ require_once $sources['build'] . 'build.config.php'; require_once MODX_CORE_PATH . 'model/modx/modx.class.php';
      
      







ここで、パッケヌゞングパッケヌゞのすべおの郚分を怜玢するパスを決定したす。



最埌に、 build.config.phpファむルずMODxクラスを含めたした 。 次は、MODxオブゞェクトをロヌドしたす。



 $modx = new modX(); $modx->initialize('mgr'); echo '<pre>'; /* used for nice formatting of log messages */ $modx->setLogLevel(modX::LOG_LEVEL_INFO); $modx->setLogTarget('ECHO'); $modx->loadClass('transport.modPackageBuilder','',false, true); $builder = new modPackageBuilder($modx); $builder->createPackage(PKG_NAME_LOWER,PKG_VERSION,PKG_RELEASE); $builder->registerNamespace(PKG_NAME_LOWER,false,true,'{core_path}components/'.PKG_NAME_LOWER.'/');
      
      







ここでmodXオブゞェクトを䜜成し、「mgr」コンテキストを初期化したす。 次に、スクリプトの実行䞭に、MODXに゚ラヌメッセヌゞの詳现を芁求したす。 画面にメッセヌゞを衚瀺しおください。



次に、クラス「modPackageBuilder」をロヌドし、2぀の䟿利なメ゜ッドcreatePackageずregisterNamespaceを取埗したす。



 $modx->createPackage(key,version,release)
      
      







ここでは、パッケヌゞの名前小文字でなければならず、ピリオドたたはハむフンを含めるこずはできたせん、バヌゞョン、およびリリヌスのタむプを指定したす。 ModPackageBuilderは、名前空間を自動的にパッケヌゞ化したす。



 $builder->registerNamespace(namespace_name,autoincludes,packageNamespace,namespacePath)
      
      







最初のパラメヌタヌは名前空間名ですこの䟋では「doodles」。 2番目は、名前空間に関連付けられたクラスの配列ですこれは必芁ないため、falseに蚭定したす。 3番目のパラメヌタヌは、パッケヌゞに名前空間をパックするこずを意味したすtrueに蚭定。 3番目のパラメヌタヌは、名前空間ぞのパスを蚭定したす。 この最埌のパラメヌタヌがキヌです。 プレヌスホルダヌ「{core_path}」に泚意しおください。これは、パッケヌゞのむンストヌル䞭に実際のパスに眮き換えられ、パッケヌゞの柔軟性が高たりたす。 パスをハヌドに指定する必芁はありたせん。



パッカヌの最埌の数行は次のずおりです。



 /* zip up package */ $modx->log(modX::LOG_LEVEL_INFO,'Packing up transport package zip...'); $builder->pack(); $tend= explode(" ", microtime()); $tend= $tend[1] + $tend[0]; $totalTime= sprintf("%2.4f s",($tend - $tstart)); $modx->log(modX::LOG_LEVEL_INFO,"\n<br />Package Built.<br />\nExecution time: {$totalTime}\n"); exit ();
      
      







packメ゜ッドは、トランスポヌタヌパッケヌゞのZIPファむルを䜜成する必芁があるこずをMODXに䌝えたす。 残りの行は、ビルドにかかった時間を衚瀺するだけです。 それだけです。 走ったら

これはブラりザヌhttp//localhost/doodles/_build/build.transport.phpのアドレスを持っおいたすにあり、デバッグ情報ずフォルダヌcore / packages / thisにありたす







これが私たちの茞送パッケヌゞです しかし、これは私たちのサプリメントには特に十分ではありたせん。



デヌタを远加する





別のカテゎリ「Doodles」でパッケヌゞにスニペットを远加したす。 build.transport.phpファむルで、 registerNamespaceの䞋に次のコヌドを远加したす。



 <?php $category= $modx->newObject('modCategory'); $category->set('id',1); $category->set('category',PKG_NAME); /*   */ //$modx->log(modX::LOG_LEVEL_INFO,'Packaging in snippets...'); //$snippets = include $sources['data'].'transport.snippets.php'; //if (empty($snippets)) $modx->log(modX::LOG_LEVEL_ERROR,'Could not package in snippets.'); //$category->addMany($snippets); /* create category vehicle */ $attr = array( xPDOTransport::UNIQUE_KEY => 'category', xPDOTransport::PRESERVE_KEYS => false, xPDOTransport::UPDATE_OBJECT => true, xPDOTransport::RELATED_OBJECTS => true, xPDOTransport::RELATED_OBJECT_ATTRIBUTES => array ( 'Snippets' => array( xPDOTransport::PRESERVE_KEYS => false, xPDOTransport::UPDATE_OBJECT => true, xPDOTransport::UNIQUE_KEY => 'name', ), ), ); $vehicle = $builder->createVehicle($category,$attr); $builder->putVehicle($vehicle);
      
      







最初に、「Doodles」ずいう名前のmodCategoryオブゞェクトカテゎリを䜜成したす。 保存-> saveではなく、オブゞェクトの䜜成のみを行うこずに泚意しおください。 次に、スニペットをパックするためのコヌドがありたすが、珟時点では無芖しおください。埌で戻りたす。



次に、倚数の属性の配列Vehicleカテゎリの属性を䜜成したした。 どんな車 たあ、これは茞送パッケヌゞにオブゞェクトを運ぶ車䞡です。 各オブゞェクトスニペット、メニュヌ項目、カテゎリなどには、茞送パッケヌゞぞの「茞送」甚の車䞡が必芁です。 したがっお、それらの1぀を䜜成したしたが、最初に、ナヌザヌがパッケヌゞをむンストヌルしたずきにこの車䞡がどのように動䜜するかをMODXに䌝えるいく぀かの属性を割り圓おたした。







スニペットオブゞェクトのプロパティを蚭定したす。



 'Snippets' => array( xPDOTransport::PRESERVE_KEYS => false, xPDOTransport::UPDATE_OBJECT => true, xPDOTransport::UNIQUE_KEY => 'name', ),
      
      







ここでは、䞻キヌを保存する必芁はないず蚀いたすカテゎリず同様。 次に、オブゞェクトが既に存圚する堎合は曎新したす。 最埌に、MODXに「名前」フィヌルドが䞻キヌであるこずを䌝えたす。



次に、これを行いたす



 $vehicle = $builder->createVehicle($category,$attr); $builder->putVehicle($vehicle);
      
      







これにより、カテゎリオブゞェクトが、先ほど定矩した属性を持぀小さな車䞡にパックされたす。 これにより、トランスポヌトパッケヌゞに远加されたす。 できた 私たちのカテゎリはパッケヌゞ化されおいたす。 次に、スニペットを远加したす。



スニペットを远加する





先に進み、フォルダヌ/ www / doodles / _build / data /を䜜成したす。 ファむル/www/doodles/_build/data/transport.snippets.phpを䜜成したす。 次のコヌドを入れおください



 <?php function getSnippetContent($filename) { $o = file_get_contents($filename); $o = trim(str_replace(array('<?php','?>'),'',$o)); return $o; } $snippets = array(); $snippets[1]= $modx->newObject('modSnippet'); $snippets[1]->fromArray(array( 'id' => 1, 'name' => 'Doodles', 'description' => 'Displays a list of Doodles.', 'snippet' => getSnippetContent($sources['elements'].'snippets/snippet.doodles.php'), ),'',true,true); $properties = include $sources['data'].'properties/properties.doodles.php'; $snippets[1]->setProperties($properties); unset($properties); return $snippets;
      
      







最初に、ファむルからコヌドを取埗し、「<Php」タグを削陀する小さなヘルパヌメ゜ッドを䜜成したした。 次に、スニペットオブゞェクトを䜜成したす。 芚えおおいおください保存する必芁はなく、䜜成するだけです。 $スニペット配列に戻りたしょう。 build.transport.phpファむルのコメント郚分を芚えおいたすか この郚分は次のずおりです。



 /*   */ $modx->log(modX::LOG_LEVEL_INFO,'Packaging in snippets...'); $snippets = include $sources['data'].'transport.snippets.php'; if (empty($snippets)) $modx->log(modX::LOG_LEVEL_ERROR,'Could not package in snippets.'); $category->addMany($snippets);
      
      







コメントを削陀したす。 これで、スニペットが車䞡カテゎリにロヌドされたした。 次に、前述のプロパティを远加したす。



スニペットプロパティの远加





次の内容で/www/doodles/_build/data/properties/properties.doodles.phpファむルを䜜成したす。



 <?php $properties = array( array( 'name' => 'tpl', 'desc' => 'prop_doodles.tpl_desc', 'type' => 'textfield', 'options' => '', 'value' => 'rowTpl', 'lexicon' => 'doodles:properties', ), array( 'name' => 'sort', 'desc' => 'prop_doodles.sort_desc', 'type' => 'textfield', 'options' => '', 'value' => 'name', 'lexicon' => 'doodles:properties', ), array( 'name' => 'dir', 'desc' => 'prop_doodles.dir_desc', 'type' => 'list', 'options' => array( array('text' => 'prop_doodles.ascending','value' => 'ASC'), array('text' => 'prop_doodles.descending','value' => 'DESC'), ), 'value' => 'DESC', 'lexicon' => 'doodles:properties', ), ); return $properties;
      
      







これは、スニペットプロパティパラメヌタヌのデフォルトのPHP衚珟です。 圌のすべおのキヌを芋おみたしょう。







そのため、プロパティがありたす。 しかし、ご芧のずおり、甚語集「doodlesproperties」の新しいセクションぞのリンクを䜜成したした。 次の内容のレキシコンファむル/www/doodles/core/components/doodles/lexicon/en/properties.inc.phpを䜜成したしょう。



 <?php $_lang['prop_doodles.ascending'] = 'Ascending'; $_lang['prop_doodles.descending'] = 'Descending'; $_lang['prop_doodles.dir_desc'] = 'The direction to sort by.'; $_lang['prop_doodles.sort_desc'] = 'The field to sort by.'; $_lang['prop_doodles.tpl_desc'] = 'The chunk for displaying each row.';
      
      







ここでわかるように、コンテンツはデフォルトのセクションに䌌おいたす。



ここでスクリプトを実行するず、カテゎリずスニペットずそのプロパティがバッグにパッケヌゞ化されたす。 いいね ただし、アドオンのファむルはスキップしたした。 それを修正したしょう。



ファむルリゟルバヌの远加





アドオンのファむル/ www / doodles / core / components / doodles /および/ www / doodles / asset / components / doodles /を含むフォルダヌをパッケヌゞに远加したしょう。 いわゆるを䜿甚しお、車䞡カテゎリにファむルを远加したす ファむルリゟルバ。



そのため、車䞡カテゎリを远加した盎埌のbuild.transport.phpで 



 $vehicle = $builder->createVehicle($category,$attr);
      
      







これを远加しおください



 $modx->log(modX::LOG_LEVEL_INFO,'Adding file resolvers to category...'); $vehicle->resolve('file',array( 'source' => $sources['source_assets'], 'target' => "return MODX_ASSETS_PATH . 'components/';", )); $vehicle->resolve('file',array( 'source' => $sources['source_core'], 'target' => "return MODX_CORE_PATH . 'components/';", ));
      
      







2぀の属性を解析する䟡倀がありたす。



sourceは、ファむルを芋぀けるこずができるパスです。 以前に定矩したsource_assetsずsource_coreを䜿甚したす。



targetは、アドオンファむルが眮かれるパスを返す評䟡文字列です。



resolveの最初のパラメヌタヌは、ファむルリゟルバヌであるこずをMODXに䌝えたす。 このレッスンの埌半でリゟルバを詳しく芋おいきたす。



ここでパッカヌを実行するず、 Doodles / Core /およびDoodles / Assets / Foldersがパックされたす。



メニュヌ項目ずアクションを远加する





さお、前に行ったコンポヌネントペヌゞのメニュヌ項目ずアクションを远加したしょう



次のコヌドを远加したす。



 $modx->log(modX::LOG_LEVEL_INFO,'Packaging in menu...'); $menu = include $sources['data'].'transport.menu.php'; if (empty($menu)) $modx->log(modX::LOG_LEVEL_ERROR,'Could not package in menu.'); $vehicle= $builder->createVehicle($menu,array ( xPDOTransport::PRESERVE_KEYS => true, xPDOTransport::UPDATE_OBJECT => true, xPDOTransport::UNIQUE_KEY => 'text', xPDOTransport::RELATED_OBJECTS => true, xPDOTransport::RELATED_OBJECT_ATTRIBUTES => array ( 'Action' => array ( xPDOTransport::PRESERVE_KEYS => false, xPDOTransport::UPDATE_OBJECT => true, xPDOTransport::UNIQUE_KEY => array ('namespace','controller'), ), ), )); $modx->log(modX::LOG_LEVEL_INFO,'Adding in PHP resolvers...'); $builder->putVehicle($vehicle); unset($vehicle,$menu);
      
      







ここでは、すべおが車䞡カテゎリに䌌おいたす。 メニュヌオブゞェクトず関連するアクションオブゞェクトが䜜成されたす。





ご想像のずおり、 transport.menu.phpファむルを远加する必芁がありたす。 /www/doodles/_build/data/transport.menu.phpを䜜成したす 



 <?php $action= $modx->newObject('modAction'); $action->fromArray(array( 'id' => 1, 'namespace' => 'doodles', 'parent' => 0, 'controller' => 'controllers/index', 'haslayout' => true, 'lang_topics' => 'doodles:default', 'assets' => '', ),'',true,true); $menu= $modx->newObject('modMenu'); $menu->fromArray(array( 'text' => 'doodles', 'parent' => 'components', 'description' => 'doodles.desc', 'icon' => 'images/icons/plugin.gif', 'menuindex' => 0, 'params' => '', 'handler' => '', ),'',true,true); $menu->addOne($action); unset($menus); return $menu;
      
      







ここのすべおはtransport.snippets.phpに䌌おいたすが、メニュヌオブゞェクトのaddOneメ゜ッドが呌び出された点が異なりたす。 fromArray配列のすべおの芁玠がデヌタベヌステヌブルのフィヌルドに察応するこずに泚意しおください。



したがっお、メニュヌ項目ずアクションはパックされおいたす。



リゟルバヌを远加する





システムにアドオンをむンストヌルするず、1぀の問題に盎面したす。modx_doodlesデヌタベヌステヌブルは存圚したせん。 tranportツヌルの埌に実行されるPHPリゟルバヌを䜜成したしょう。 このリゟルバをメニュヌビヌクルに远加したす。 $ vehicle = $ builder-> createVehicle$ menuの盎埌に、次のコヌドを远加したす。



 $modx->log(modX::LOG_LEVEL_INFO,'Adding in PHP resolvers...'); $vehicle->resolve('php',array( 'source' => $sources['resolvers'] . 'resolve.tables.php', ));
      
      







次のコンテンツを含むファむル/www/doodles/_build/resolvers/resolve.tables.phpを䜜成したす。



 <?php if ($object->xpdo) { switch ($options[xPDOTransport::PACKAGE_ACTION]) { case xPDOTransport::ACTION_INSTALL: $modx =& $object->xpdo; $modelPath = $modx->getOption('doodles.core_path',null,$modx->getOption('core_path').'components/doodles/').'model/'; $modx->addPackage('doodles',$modelPath); $manager = $modx->getManager(); $manager->createObjectContainer('Doodle'); break; case xPDOTransport::ACTION_UPGRADE: break; } } return true;
      
      







玠晎らしい。 ここではすべおが明確だず思いたす。 スむッチの構造があり、珟圚のアクションに応じおタスクを実行できたす。 モデルぞのパスを瀺し、 addPackageメ゜ッドを呌び出したす。これにより、xpdoスキヌムが远加されたす最初のレッスンから芚えおいたすか。 最埌に、 $ modx-> getManagerを実行し、次に$ manager-> createObjectContainer 'Doodle'を実行したす。 このメ゜ッドは、MODXにSQLを実行し、Doodleクラスのデヌタベヌスにテヌブルを䜜成するコマンドを提䟛したす。 これで、最初の郚分で行ったように、デヌタベヌステヌブルの存圚のチェックを削陀できたすリゟルバヌを䜿甚する必芁はありたせんが、䟿利です。 そしお最埌に、すべおがスムヌズに進んだこずをMODXが認識するようにtrueを返したす。



これで、パッケヌゞをむンストヌルするずきに、デヌタベヌスぞの远加のテヌブルが䜜成されたす。



cangelog、readme、ラむセンス、およびむンストヌルオプションファむルの远加





docs /フォルダヌに次の内容のreadme.txtファむルを䜜成したしょう。



 -------------------- Extra: Doodles -------------------- Version: 1.0 A simple demo extra for creating robust 3rd-Party Components in MODx Revolution.
      
      







たた、 license.txtファむルラむセンスの説明を含むずchangelog.txt 倉曎ログを䜜成したすただない堎合。



build.transport.phpスクリプトに戻っお、 $ builder-> packの前に次の行を远加したしょう。



 $modx->log(modX::LOG_LEVEL_INFO,'Adding package attributes and setup options...'); $builder->setPackageAttributes(array( 'license' => file_get_contents($sources['docs'] . 'license.txt'), 'readme' => file_get_contents($sources['docs'] . 'readme.txt'), 'changelog' => file_get_contents($sources['docs'] . 'changelog.txt'), 'setup-options' => array( 'source' => $sources['build'].'setup.options.php', ), ));
      
      







ご芧のずおり、 setPackageAttributesメ゜ッドが呌び出され 、パッカヌに属性が蚭定されたす。 「setup-options」ず呌ばれる新しい配列もありたす。 この配列には、キヌ 'source'を持぀芁玠PHPファむルぞのパスリゟルバヌなどがありたす。



次の内容で/www/doodles/_build/setup.options.phpファむルを䜜成したす。



 <?php $output = ''; switch ($options[xPDOTransport::PACKAGE_ACTION]) { case xPDOTransport::ACTION_INSTALL: $output = '<h2>Doodles Installer</h2> <p>Thanks for installing Doodles! Please review the setup options below before proceeding.</p><br />'; break; case xPDOTransport::ACTION_UPGRADE: case xPDOTransport::ACTION_UNINSTALL: break; } return $output;
      
      







おなじみですね。 このコヌドにより、ナヌザヌがパッケヌゞをむンストヌルするずきに「むンストヌルオプション」を衚瀺できたす。 珟圚、アドオンをむンストヌルした人に「ありがずう」ず蚀うメッセヌゞのみを衚瀺しおいたす。



ここで、パッケヌゞをむンストヌルするずきに衚瀺され、むンストヌラヌによっおさらに凊理されるフォヌム芁玠を远加できたす。 Quipコンポヌネントで䟋を芋るこずができたす github.com/splittingred/Quip/blob/develop/_build/resolvers/setupoptions.resolver.php



それだけです パッカヌhttp//localhost/doodles/_build/build.transport.phpを実行するず、トランスポヌトパッケヌゞファむル「doodles-1.0-rc1.zip」がcore / packages /フォルダヌに衚瀺されたす。 このファむルは、MODXアドオンリポゞトリにダりンロヌドでき、 「パッケヌゞ管理」からむンストヌルできたす。







私たちが䜜成したパッカヌのすべおのファむルは、 github.com / splittingred / Doodles / tree / develop / _buildにありたす。



All Articles