dongzhong7443 2018-03-01 17:15
浏览 65
已采纳

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

I am using Silex and Twig for a website and I want to allow the user to change the langage of the site.

My problem

Right now, it works if I change the locale in the URL :

/my-account: my page content is in English (default _locale)

/fr/my-account: my page content is in French

/en/my-account: my page content is in English

How can I do the do the same by clicking on an html element?

I am looking for some idea to solve my problem and some good practice to do this "the right way" if possible.

My code

Here is the Silex component I use to manage the multilangue :

// 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;
});

Here is my html for the user to change the langage:

<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>

Now my jQuery to get the value :

$(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);
            }
        });
    });
});

My Ajax controller :

$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');

If I do this, my Ajax success console.log(resp); give me en as I want.

Some ideas / questions about how to do it

  1. Is it a good idea to do it with an Ajax call?
  2. If I change fr by en in my url it works, is it a good idea to try to do it in javascript using window.location.href for example? (I think not but still asking)
  3. I saw this solution for an other problem and try it in my controller but I get this error : 500 (Internal Server Error) (I did the same, with $new_langue instead of $app['defaultLanguage'] and with the right name for my homepage).

It's the first time I create a full website with Silex and I'm beginner with php framework so if someone can help to achieve what I want...thanks by advance !

EDIT :

According to the anwser I get and what I want to achieve, is it possible to change the locale and staying in the same page with Silex / Twig?

For example, this give me the current route : global.request.get('_route') and this global.request.get('_locale') give me the locale.

If I take the example of my Home Page, this is how my controller look right now (I just show the template) :

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

As you can see, I have no {_locale} param in my URL. So can I keep this "clean URL" without the {_locale} and make a click that stay in the same page + change the current langage?

I'd like to make somehting like this : <a href="{{ path(global.request.get('_route')), global.request.set('_locale', 'FR') }}">FR</a>

But it won't work for sure...can I do this?

  • 写回答

4条回答 默认 最新

  • dsgrgaz321973284 2018-03-12 10:09
    关注

    I finally find a solution to do what I want, using pmaxs/silex-locale (https://github.com/pmaxs/silex-locale).

    As I said in my question, I already used it for my translation but I didn't used the "Url generation" as I should...So here is a recap of how to use it (read the documentation if you use Silex v1.x):

    1/ Loading Provider

    $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/ Usage

    Here is my home route controller :

    // 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');
    

    As you can see, I have no {_locale} variable in my routing, but still can use it to change the langage of my page.

    3/ Url generator

    Now, here is how I change my langage :

    {% 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>
    

    I'm using the "Url Generator", it works like this : locale_generate('es', $name, $parameters = array(), $referenceType = UrlGeneratorInterface::ABSOLUTE_PATH) (more details in the documentation).

    This way, when I come in my website I'm in english (my default locale) with my "clean Url" /. Then by clicking on FR my url become /fr/ and my content is translate in French with a new selection menu (current-langue = FR and I can select "EN").

    本回答被题主选为最佳回答 , 对您是否有帮助呢?
    评论
查看更多回答(3条)

报告相同问题?

悬赏问题

  • ¥15 做个有关计算的小程序
  • ¥15 MPI读取tif文件无法正常给各进程分配路径
  • ¥15 如何用MATLAB实现以下三个公式(有相互嵌套)
  • ¥30 关于#算法#的问题:运用EViews第九版本进行一系列计量经济学的时间数列数据回归分析预测问题 求各位帮我解答一下
  • ¥15 setInterval 页面闪烁,怎么解决
  • ¥15 如何让企业微信机器人实现消息汇总整合
  • ¥50 关于#ui#的问题:做yolov8的ui界面出现的问题
  • ¥15 如何用Python爬取各高校教师公开的教育和工作经历
  • ¥15 TLE9879QXA40 电机驱动
  • ¥20 对于工程问题的非线性数学模型进行线性化