2012-04-04 13 views
2

テンプレートの現在のリンクを作成するにはどうすればよいですか?Symfony 2の現在のページへのリンク

私はVARIOS言語で現在のページにリンクする必要があり、言語スイッチャーを作成したいので、すべてのパラメータは、ロケールのためのexept同じである必要があります。

答えて

7

私はこのために私自身の機能を転がり終わります。私は最初にFrameworkBundleのどこかに含まれていましたが、それについて何も見つかりませんでした。ここで私が取った手順。まず

は、私は、出力ユーザが現在訪問しているものと同じルート(パラメータとクエリ文字列を含む)であろう小枝拡張機能を作成しました。私はこのステップをあなたに任せました。あなたは、Twig拡張モジュールを作成する方法については、Symfony2の良いチュートリアルのthis linkをご覧ください。あなたがそれを必要とするなら、私はあなたにそれを手伝うことができました。

次のステップは、現在のルートのロケールを切り替えます機能自体を作成することです。この機能には、RequestRouterオブジェクトが依存する必要があります。私の個人的なケースでは、私はこのサービスをRoutingHelperサービスと呼ばれる専用サービスに入れました。このサービスは、私のTwig拡張機能で使用されます。ここで私は、依存関係のコンテナに追加されたサービスの定義:

acme.helper.routing: 
    class: Application\AcmeBundle\Helper\RoutingHelper 
    scope: "request" 
    arguments: 
     request: "@request" 
     router: "@router" 

そして、私のサービスのコンストラクタ:

protected $request; 
protected $router; 

public function __construct($request, $router) 
{ 
    $this->request = $request; 
    $this->router = $router; 
} 

$ロケールパラメータは、新しいロケールに切り替えるしたいです。ここでは、関数:

public function localizeCurrentRoute($locale) 
{ 
    $attributes = $this->request->attributes->all(); 
    $query = $this->request->query->all(); 
    $route = $attributes['_route']; 

    # This will add query parameters to attributes and filter out attributes starting with _ 
    $attributes = array_merge($query, $this->filterPrivateKeys($attributes)); 

    $attributes['_locale'] = $locale; 

    return $this->router->generate($route, $attributes); 
} 

これは他の人がこれまで行ってきたことを本質的には行いますが、パラメータとクエリ文字列も処理します。メソッドfilterPrivateKeysは、ルート属性からプライベート属性を削除します。これらの属性は、アンダースコアで始まり、ルートジェネレータに戻されるべきではありません。ここではそのdefintion:最後に

private function filterPrivateKeys($attributes) 
{ 
    $filteredAttributes = array(); 
    foreach ($attributes as $key => $value) { 
     if (!empty($key) && $key[0] != '_') { 
      $filteredAttributes[$key] = $value; 
     } 
    } 

    return $filteredAttributes; 
} 

、私はロケールを切り替えるには、リンクを作成するために、私の小枝ビューで、このことができるよ:

{% block language_bar %} 
     <a href="{{ localize_route('en') }}"> English </a> 
     <a href="{{ localize_route('fr') }}"> Français </a> 
{% endblock %} 

編集

ここに私の小枝拡張サービス定義:

acme.twig.extension: 
    class: Application\AcmeBundle\Twig\Extension\AcmeExtension 
    arguments: 
     container: "@service_container" 
    tags: 
     - { name: twig.extension } 

そして、小枝$routingHelper = $this->container->get('acme.helper.routing');

小枝拡張がリクエストスコープにないので、これが起こって例外を広げる範囲を解決する必要があります:拡張機能は、私はこのコールを持っています。

更新:

それは以前よりも簡単な方法でロケールスイッチャーを持っているのSymfony 2.1で可能になりました。確かに、2。symfonyの1バージョンでは、それをとする経路に新しいパラメータが導入されました。は簡単にロケール切り替えを行うことができます。ここでのコードは、すべての小枝

{% set route_params = app.request.attributes.get('_route_params') %} 

{# merge the query string params if you want to keep them when switching the locale #} 
{% set route_params = route_params|merge(app.request.query.all) %} 

{# merge the additional params you want to change #} 
{% set route_params = route_params|merge({'_locale': 'fr'}) %} 

{{ path(app.request.attributes.get('_route'), route_params) }} 

にそれはまだ小枝の数行のコードですが、簡単に再利用のための小枝ブロックに含めることができます。上記のコードのために、symfonyコミュニティからstofへのクレジット

これがあなたが探しているものです。

よろしく、
マット

+0

だから、私はそれを自分で書く必要があります。それは本質的な機能なので、フレームワークにはそういうものがなければならないと思った。私はプラグインとヘルパークラスを書くことができましたが、私は今スコープに問題があります。ヘルパーと小枝の拡張子は "scope:"要求 ""であり、小枝自体はありません(Scope Widening Injection detected:定義 "twig"は狭い範囲に属するサービス "s2_tools.twig.routing_helper"を参照します。 )。どのようにこれを管理しましたか? – Johni

+0

ええ、これもやったけど、まだ何も見つかりませんでした。私は何かを組み込むのが大好きです。私はフルサービスコンテナを注入することでこの問題を管理しました。私はこれを反映するために私の答えを編集しました。 – Matt

+0

これで、フルサービスコンテナが注入されました。今すぐ動作します。ありがとう。 – Johni

1
<a href="{{ path(app.request.get('_route'), {'_locale': 'en'}) }}">English</a> 
+1

はい、私がすでに見つけたことです、私はまた、パラメータを持つページのルートを構築するために現在のパラメータが必要です。 – Johni

関連する問題