Symfony2 で管理するのが非常に簡単な、特定のエンティティを含む定義済みのページと、異なるレイアウトのコンテンツ ページの両方を表示する必要がある現在のプロジェクトがあります。
ルーティング システムを構築しようとすると問題が発生します。
たとえば、ニュースのあるページを表示する必要がある場合、次のような新しいルートでバンドルのルーターを更新したいと思います。
my_bundle_news_page:
pattern: /news
defaults:
_controller: MyBundle:NewsController:indexAction
しかし、多くのレベルで完全にカスタムの URL を持つ動的ルーターを管理するにはどうすればよいでしょうか?
オプションの「親子」関係の自己参照である「ページ」エンティティがあるとします。この特定のルーティングに任意の構成 YAML ファイルを使用できるとは思いませんか?!
my_bundle_custom_page:
pattern: /{slug}
defaults:
_controller: MyBundle:PageController:showAction
これにより、すべての第 1 レベルのページがバインドされます。
/プロジェクト
/約
/コンタクト
/私たちのプロジェクト
たとえば、次のようなスラッグで表示されるページはどうでしょうか。
/私たちのプロジェクト/健康
実際、どの URL...
/{slug-level1}/{slug-level2}/{slug-level3} など
ページが変更され、ウェブマスタリングから更新されることが想定されているためです。
{slug} をデータベース フィールド (エンティティ プロパティ) と比較するルーターを用意するのが最善の方法だと思います。
Symfony-CMF docで、ルートプロバイダーに基づいたサービスを作成できることを読みました。
namespace MyBundle\Routing;
use Symfony\Component\Routing\RouteCollection;
use Symfony\Component\Routing\Route as SymfonyRoute;
use MyBundle\Entity\PageRepository;
class RouteProvider extends PageRepository {
public function findPageBySlug($slug)
{
// Find a page by slug property
$page = $this->findOneBySlug($slug);
if (!$page) {
// Maybe any custom Exception
throw $this->createNotFoundException('The page you are looking for does not exists.');
}
$pattern = $page->getUrl(); // e.g. "/first-level/second-level/third-level"
$collection = new RouteCollection();
// create a new Route and set our page as a default
// (so that we can retrieve it from the request)
$route = new SymfonyRoute($pattern, array(
'page' => $page,
));
// add the route to the RouteCollection using a unique ID as the key.
$collection->add('page_'.uniqid(), $route);
return $collection;
}
}
しかし、それをサービスとして設定する方法は? いくつかの要件はありますか? リクエストが呼び出されたときに RouteCollection にルートを追加しますか?
そして、この方法で任意のルートをバインドできますか?
編集: 私のバンドルの services.yml
parameters:
cmf_routing.matcher.dummy_collection.class: Symfony\Component\Routing\RouteCollection
cmf_routing.matcher.dummy_context.class: Symfony\Component\Routing\RequestContext
cmf_routing.generator.class: Symfony\Cmf\Bundle\RoutingBundle\Routing\ContentAwareGenerator
cmf_routing.nested_matcher.class: Symfony\Cmf\Component\Routing\NestedMatcher\NestedMatcher
cmf_routing.url_matcher.class: Symfony\Cmf\Component\Routing\NestedMatcher\NestedMatcher
fsbcms.chain_router.class: Symfony\Cmf\Component\Routing\ChainRouter
fsbcms.route_provider.class: FSB\CMSBundle\Routing\RouteProvider
fsbcms.dynamic_router.class: Symfony\Cmf\Component\Routing\DynamicRouter
fsbcms.route_entity.class: null
services:
fsbcms.router:
class: %fsbcms.chain_router.class%
arguments:
- "@logger"
calls:
- [setContext, ["router.request_context"]]
fsbcms.route_provider:
class: "%fsbcms.route_provider.class%"
arguments:
- "@doctrine"
cmf_routing.matcher.dummy_collection:
class: "%cmf_routing.matcher.dummy_collection.class%"
public: "false"
cmf_routing.matcher.dummy_context:
class: "%cmf_routing.matcher.dummy_context.class%"
public: false
cmf_routing.generator:
class: "%cmf_routing.generator.class%"
arguments:
- "@fsbcms.route_provider"
- "@logger"
calls:
- [setContainer, ["service_container"]]
- [setContentRepository, ["cmf_routing.content_repository"]]
cmf_routing.url_matcher:
class: "%cmf_routing.url_matcher.class%"
arguments: ["@cmf_routing.matcher.dummy_collection", "@cmf_routing.matcher.dummy_context"]
cmf_routing.nested_matcher:
class: "%cmf_routing.nested_matcher.class%"
arguments: ["@fsbcms.route_provider"]
calls:
- [setFinalMatcher, ["cmf_routing.url_matcher"]]
fsbcms.dynamic_router:
class: "%fsbcms.dynamic_router.class%"
arguments:
- "@router.request_context"
- "@cmf_routing.nested_matcher"
- "@cmf_routing.generator"
tags:
- { name: router, priority: 300 }