8

独自の xml サイトマップを作成しようとしています。最も簡単だと思った部分を除いて、すべてが完了しました。サイトのすべてのページのリストを取得するにはどうすればよいですか? /site フォルダーと他のいくつかのビューにたくさんのビューがあります。URL を明示的に要求する方法、またはコントローラーを介して要求する方法はありますか?

エクステンションは使いたくない

4

5 に答える 5

9

リフレクションを使用して、すべてのコントローラーのすべてのメソッドを反復処理できます。

Yii::import('application.controllers.*');
$urls = array();

$directory = Yii::getPathOfAlias('application.controllers');
$iterator = new DirectoryIterator($directory);
foreach ($iterator as $fileinfo)
{
    if ($fileinfo->isFile() and $fileinfo->getExtension() == 'php')
    {
        $className = substr($fileinfo->getFilename(), 0, -4); //strip extension
        $class = new ReflectionClass($className);

        foreach ($class->getMethods(ReflectionMethod::IS_PUBLIC) as $method)
        {
            $methodName = $method->getName();
            //only take methods that begin with 'action', but skip actions() method
            if (strpos($methodName, 'action') === 0 and $methodName != 'actions')
            {   
                $controller = lcfirst(substr($className, 0, strrpos($className, 'Controller')));
                $action = lcfirst(substr($methodName, 6));
                $urls[] = Yii::app()->createAbsoluteUrl("$controller/$action");
            }
        }
    }
}
于 2013-03-04T13:32:29.320 に答える
1

あなたの質問に基づいて:1。サイト上のすべてのページのリストをどのように取得しますか?

Yiiのmodule/controller / action / action_paramsの方法と、SEOのサイトマップを作成する必要性に基づいています。

  1. アクションパラメータは無期限に変化するため、自動的に解析してすべてのURLを取得することは困難です。Pavle Predicによって構築されたように、コントローラー/アクションを簡単に取得できますが。SEO向けにカスタマイズされた(SERF)URLルールを使用すると、複雑さが増します。

次善の解決策は、コンテンツのデータベースを用意し、URLルールを介して各コンテンツを取得する方法を知っていることです。次に、cronコンソールジョブを使用して、sitemap.xmlとして保存するすべてのURLを作成します。

お役に立てれば!

于 2013-03-08T07:44:22.860 に答える
1

sitemap.xml に含めたいコンテンツを知る必要があります。sitemap.xml にすべてのページを含めたいとは思わないか、site.com/article/edit のようなものを本当に含めたいと思いますか? /1 ?

とは言ってもview、コントローラーのアクションからの結果のみが必要な場合があります。真実は、インデックスを作成したいものを知る必要があるということです。

コントローラー/アクション/ビューの観点から考えるのではなく、記事であれページであれ、インデックスを作成したいシステム内のリソースについて考えてください。それらはすべてデータベースにあるか、何らかの方法で保存されているため、リストできます。それらはそれらを識別する URI を持っています。URI を取得するには、いくつかの関数を呼び出すだけです。

于 2013-01-14T15:06:02.097 に答える
1

2つの可能性があります -

ケース 1:

静的な Web サイトを実行している場合、すべての HTML を 1 つのフォルダー内に見つけることができます 。 yii/

ケース 2:

ウェブサイトは動的です。サイトマップの生成や再生成などのタスクは、バックグラウンド タスクに分類できます。

バックグラウンド タスクの実行は、Linux でWGETGETまたはlynxコマンドを使用してブラウザをエミュレートすることで実現できます。

または、 CronController を CConsoleCommand として作成できます。YII でコマンドを使用する方法は、以下のリンクに示されています - http://tariffstreet.com/yii/2012/04/implementing-cron-jobs-with-yii-and-cconsolecommand/

サイトマップは、サイトの URL をリストする XML です。しかし、それだけではありません。ウェブサイトの構造を視覚化するのに役立ちます。

  • カテゴリー
  • サブカテゴリ。

便利な拡張を行いながら、設計前に上記の点を考慮することができます。

Wordpressのようなフレームワークは、カテゴリ サイトマップを生成する方法を提供します。そのため、各ページのメタデータは以前から保存されており、そのメタデータを使用して検出し、ページをグループ化します。

@Pavleによって提案されたリフレクションによる解決策は優れており、進むべき道です。部分的なビューが存在する可能性があり、それらを個別のリンクとしてリストしたい場合としない場合があることを考慮してください。

そのため、拡張機能の作成にどれだけの労力を費やすかは、これらのいくつかにも影響されます。

ユーザーに構成ファイルのすべての変数をリストしてそこから移動するように依頼するか、ページをグループ化し、リフレクションページの解析、正規表現の検索などの手法を使用してリストする必要があります。

例-モジュール名に基づいて、最初にそれらをグループ化し、モジュール内のコントローラーでサブグループを形成できます。

于 2013-03-04T14:49:55.250 に答える
1

CController::renderPartial()最初のアプローチの 1 つは、ビュー ファイルを反復処理することですが、場合によっては、ビューがページの宛先ではなく、メソッドを使用して別のページに含まれるページ セクションであることを考慮する必要があります。CController のクラス リファレンスを調べると、このCController::actions()メソッドにたどり着きました。

したがって、CController のすべてのアクションを反復処理するYii の方法は見つかりませんでしたが、php を使用してプロジェクトの 1 つで SiteController のすべてのメソッドを反復処理し、接頭辞「action」を使用してそれらをフィルタリングしました。は私のアクションプレフィックスです。これがサンプルです

class SiteController extends Controller{
    public function actionTest(){
        echo '<h1>Test Page!</h1></p>';
        $methods = get_class_methods(get_class($this));
        // The action prefix is strlen('action') = 6
        $actionPrefix = 'action';
        $reversedActionPrefix = strrev($actionPrefix);
        $actionPrefixLength = strlen($actionPrefix);
        foreach ($methods as $index=>$methodName){
            //Always unset actions(), since it is not a controller action itself and it has the prefix 'action'
            if ($methodName==='actions') {
                unset($methods[$index]);
                continue;
            }
            $reversedMethod = strrev($methodName);
            /* if the last 6 characters of the reversed substring === 'noitca', 
             * it means that $method Name corresponds to a Controller Action,
             * otherwise it is an inherited method and must be unset.
             */
            if (substr($reversedMethod, -$actionPrefixLength)!==$reversedActionPrefix){
                unset($methods[$index]);
            } else $methods[$index] = strrev(str_replace($reversedActionPrefix, '', $reversedMethod,$replace=1));
        }
        echo 'Actions '.CHtml::listBox('methods', NULL, $methods);
    }
    ...
}

そして、私が得た出力は..

ListBox 内のすべてのアクション!

さらに洗練できると確信していますが、この方法は、お持ちのどのコントローラーでも機能するはずです...

したがって、あなたがしなければならないことは次のとおりです。

コントローラごとに: 上記のメソッドを使用して、クラスのすべての非アクション メソッドを除外します。次のような連想配列を作成できます

array(
    'controllerName1'=>array(
        'action1_1',
        'action1_2'),
    'controllerName2'=>array(
        'action2_1',
        'action2_2'),
);

このために、静的メソッド getAllActions() を SiteController に追加します。

get_class_methodsget_classstrrevstrlenはすべて PHP 関数です。

于 2013-03-04T16:14:27.667 に答える