Silex:允许用户通过单击html元素并保持干净的URL来更改语言

时间:2018-03-01 17:15:48

标签: php ajax symfony silex

我正在使用Silex和Twig作为网站,我希望允许用户更改网站的语言。

我的问题

现在,如果我更改了网址中的区域设置,它就可以了:

/my-account:我的网页内容为英文(默认_locale)

/fr/my-account:我的网页内容为法语

/en/my-account:我的网页内容为英文

如何通过点击html元素来做同样的事情?

我正在寻找一些想法来解决我的问题和一些好的做法来做到这一点"正确的方式"如果可能的话。

我的代码

这是我用来管理multilangue的Silex组件:

// TRANSLATION
$app->register(new Silex\Provider\LocaleServiceProvider());
$app->register(new Silex\Provider\TranslationServiceProvider());
$app->register(new \Pmaxs\Silex\Locale\Provider\LocaleServiceProvider(), [
    'locale.locales' => ['en', 'fr'],
    'locale.default_locale' => 'en',
    'locale.resolve_by_host' => false,
    'locale.exclude_routes' => ['^_']
]);
$app->extend('translator', function($translator, $app) {
    $translator->addLoader('yaml', new YamlFileLoader());

    $translator->addResource('yaml', __DIR__.'/../src/locales/en.yml', 'en');
    $translator->addResource('yaml', __DIR__.'/../src/locales/fr.yml', 'fr');

    return $translator;
});

这是我的html,供用户更改语言:

<li id="drop-langue" data-lg="en">
    <span id="current-lg">EN</span> // My current langue
    <div class="drop-langue">
        // The list of langage the user can choose : here ONE -> FR
        <div id="list_langue">
          <a class="change_langue" href="#" data-lg="fr"> <span>FR</span></a> // Could be nice to change the langue staying on the same page
        </div>
    </div>
</li>

现在我的jQuery获取值:

$(document).ready(function() {
    $(".change_langue").on("click", function() {
        var new_langue = $(this).data("lg");

        $.ajax({
            url: "{{ path('new-langue') }}",
            type: 'POST',
            data: {'langue': new_langue},
            success: function (resp) {
                console.log(resp);
            },
            error: function (resp) {
                console.log(resp);
            }
        });
    });
});

我的Ajax控制器:

$app->match('/new-langue', function (Request $request) use ($app) {
    $new_langue = $request->get('langue');

    // some code to change the langage

    return New Response($new_langue);
})->bind('new-langue');

如果我这样做,我的Ajax成功console.log(resp);会根据我的意愿给我en

关于如何做的一些想法/问题

  1. 使用Ajax调用做一个好主意吗?
  2. 如果我在我的网址中按fr更改了en它是否有效,那么尝试使用window.location.href在javascript中进行此操作是个好主意吗? (我想不是但仍在问)
  3. 我看到了this solution其他问题并在我的控制器中尝试了但是我收到了这个错误:500 (Internal Server Error)(我做了同样的事情,$new_langue而不是$app['defaultLanguage']并且我的主页有正确的名称。)
  4. 这是我第一次使用Silex创建一个完整的网站,而我是初学者使用php框架,所以如果有人可以帮助实现我想要的东西......感谢提前!

    编辑:

    根据我得到的anwser以及我想要实现的目标,是否可以更改语言环境并与Silex / Twig保持同一页面?

    例如,这会为我提供当前路线:global.request.get('_route'),此global.request.get('_locale')会为我提供区域设置。

    如果我以我的主页为例,这就是我的控制器现在的样子(我只是展示模板):

    $app->match('/', function (Request $request) use ($app) {
        return $app['twig']->render('home.html.twig');
    })->bind('home');
    

    如您所见,我的网址中没有{_locale}参数。 我可以保留这个&#34;干净的网址&#34;没有{_locale}并点击停留在同一页面+更改当前的语言?

    我想像这样做:<a href="{{ path(global.request.get('_route')), global.request.set('_locale', 'FR') }}">FR</a>

    但它确实无法工作......我可以这样做吗?

3 个答案:

答案 0 :(得分:1)

在你的情况下,只需添加适当的链接以允许用户,以便他们可以切换语言。其余的工作已由你完成。语言切换器下拉列表必须包含所有支持的语言,包括英语。请参见下面的示例图片。

enter image description here

您必须重定向到http://yourwebsite.com/[fr]/my-account之类的特殊方法,而不是将用户重定向到http://www.yourwebsite.com/language_change?lang=fr。您将在HTTP_REFERRER变量中获得$_SERVER,以便您可以将用户重定向回原来的页面。这样您就可以保留用户当前访问的页面/网址。

其次,Ajax vs Redirect:最好使用重定向而不是AJAX。如果您使用AJAX,您将增加与自己的共谋。

使用多语言网站时,我们必须遵循这些最佳做法。

  • 每种语言的具体路线

  • 菜单,标签和表格

  • 网站内容

  • 额外:翻译FOSUserBundle

答案 1 :(得分:0)

这里的简单想法是:您的应用程序如何确定用于呈现页面的语言。

解决方案#1 (您当前的解决方案)基于网址参数(&#39; s _locale),并回退到某个默认值case没有给出URL参数。
因此在这个解决方案中,翻译组件总是在路由器组件准备的参数包中查找所选语言。

解决方案#2 将您的语言标识符放在会话变量中。  您的/new-langue页面必须使用它接收的值设置此会话变量。并且您的路由器将填充该会话变量的_locale参数。

稍后我可能会提供一些代码段。

答案 2 :(得分:0)

我终于找到了一个使用pmaxs/silex-localehttps://github.com/pmaxs/silex-locale)来做我想做的事情的解决方案。

正如我在我的问题中所说,我已经将它用于我的翻译,但我没有使用“Url代”,因为我应该...所以这里是如何使用它的概述(如果你阅读文档使用Silex v1.x):

1 /正在加载提供商

$app->register(new \Pmaxs\Silex\Locale\Provider\LocaleServiceProvider(), [
    'locale.locales' => ['en', 'fr'],  //I want to translate my site in English and French
    'locale.default_locale' => 'en',   // By default, the locale is "en"
    'locale.resolve_by_host' => false,
    'locale.exclude_routes' => ['^_']
]);
$app->register(new Silex\Provider\LocaleServiceProvider());

2 /用法

这是我的家庭路线控制器:

// this page is accessible by urls '/', '/fr/' or '/en/'
$app->match('/', function (Request $request) use ($app) {

    // my code

     return $app['twig']->render('home.html.twig');
})->bind('home');

正如您所看到的,我的路由中没有{_locale}变量,但仍可以使用它来更改页面的语言。

3 / Url生成器

现在,这是我改变语言的方法:

{% set locale_list = ["en", "fr"] %} // the list of all langage in my website
{% set current_locale = global.request.getLocale() %} // the current langage of my page

<li id="drop-langue">
    // I display the current langage
    <span id="current-lg">{{ current_locale|upper }}</span> 
    <div class="drop-langue">
        <div id="list_langue">
            {% for locale in locale_list %}
                {% if locale != current_locale %}
                    // I create one link to change the langage according to all the langage I want, minus the current langage
                    <a class="change_langue" href="{{ locale_generate(locale , global.request.get('_route')) }}" >
                        <span>{{ locale|upper }}</span>
                    </a>
                 {% endif %}
             {% endfor %}
         </div>
     </div>
 </li>

我正在使用“Url Generator”,它的工作方式如下:locale_generate('es', $name, $parameters = array(), $referenceType = UrlGeneratorInterface::ABSOLUTE_PATH)(文档中的更多详细信息)。

这样,当我进入我的网站时,我的英文(我的默认语言环境)和我的“干净网址”/。然后点击FR我的网址变为/fr/,我的内容将使用新的选择菜单翻译成法语(current-langue = FR,我可以选择“EN”)。