1

重複の可能性:
doctrine に基づくカスタム symfony ルーティング

私のプロジェクトには、各オブジェクト タイプに関連する URL がいくつかあります。元。

製品の場合:

/product/product-1
/product/product-2

しかし今、一般的な情報管理用のコントローラーを作成しました。元。利用規約、私たちについて..etc.

ページスラッグのみを含む URL が必要です。

/terms-use
/about-us

いいえ:

/page/terms-use
/page/about-us

これをrouting.ymlで定義するには?

4

1 に答える 1

1

Venu は正しいです。doctrine に基づくカスタム symfony ルーティングはこれを行う方法を提供します。唯一の複雑さは、親ページのスラッグを追加してスラッグ パラメータを構築し、孫ページにgrandparent-slug/parent-slug/child-slug例外がスローされるようなスラッグがある場合にのみ発生します。 .

私が与えた例のようにルーティングを使用してスラッグを照合しましたが、注釈に正規表現が必要でした:

/**
 * @Route("{slug}", name="page_index", defaults={"slug" = false}, requirements={"slug" = "[0-9a-zA-Z\/\-]*"})
 * @Template()
 */
public function indexAction($slug)
{
    if ($slug !== false) {
        $page = $this->findPage($slug);

上記の要件の注釈は、スラッグがスラッシュとハイフンを含む英数字であってもよいことを意味します。findPage($slug)次に、スラッグをスラッシュで分解し、正しい子ページを見つけるメソッドを実装する必要があります。

ルートは他の多くのルートと一致するため、このコントローラーを routing.yml ファイルの最後に含め、このアクションをコントローラーのパブリック アクションの最後に含めて、他のすべてのルートが最初に一致するようにすることが重要です。

編集

これは、上記のスラッグからページを見つけるために作成した findPage メソッドです。

protected function findPage($slug_string, $first_page = false)
{
    $slug_array = explode("/", $slug_string);
    $slug = array_shift($slug_array);
    $page = $this->em->getRepository("PagesBundle:Page")->getPageBySlug($slug, $this->site_id);
    if (!$page) {
        return false;
    }
    // if only the first matched page is required return it
    if ($first_page) {
        return $page;
    }
    // Otherwise loop through the slug array and match recursive 
    //children until slug array is empty or no match found
    while (!empty($slug_array)) {
        if ($page->getChildren()) {
            $slug = array_shift($slug_array);
            foreach ($page->getChildren() as $child_page) {
                if ($child_page->getSlug() == $slug) {
                    $page = $child_page;
                    break;
                }
            }
        } else {
            return false;
        }
    }

    return $page;
}
于 2013-01-18T06:17:10.253 に答える