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

我的问题

现在,如果我更改 URL 中的语言环境,它会起作用:
/my-account :我的页面内容是英文的(默认 _locale)
/fr/my-account :我的页面内容是法语
/en/my-account : 我的页面内容是英文的

如何通过单击 html 元素来执行相同的操作?

我正在寻找一些想法来解决我的问题,并在可能的情况下寻找一些好的做法来“以正确的方式”做到这一点。

我的代码

这是我用来管理多语言的 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 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');

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

关于如何做的一些想法/问题
  • 用 Ajax 调用来做这件事是个好主意吗?
  • 如果我在我的 url 中通过 fr 更改 en 它可以工作,例如尝试使用 window.location.href 在 javascript 中执行它是个好主意吗? (我认为不是,但仍在问)
  • 我看到 this solution 有其他问题,并在我的 Controller 中尝试,但出现此错误:500 (Internal Server Error)(我做了同样的事情,使用 $new_langue 而不是 $app['defaultLanguage'] 并为我的主页使用正确的名称)。

  • 这是我第一次用 Silex 创建一个完整的网站,我是 php 框架的初学者,所以如果有人可以帮助实现我想要的......提前感谢!

    编辑:

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

    例如,这给了我当前的路线:global.request.get('_route'),这个 global.request.get('_locale') 给了我语言环境。

    如果我以我的主页为例,这就是我的 Controller 现在的样子(我只显示模板):
    $app->match('/', function (Request $request) use ($app) {
        return $app['twig']->render('home.html.twig');
    })->bind('home');
    

    如您所见,我的 URL 中没有 {_locale} 参数。 那么我可以在没有 {_locale} 的情况下保留这个“干净的 URL”并点击停留在同一页面上 + 更改当前语言吗?

    我想做这样的事情:<a href="{{ path(global.request.get('_route')), global.request.set('_locale', 'FR') }}">FR</a>
    但这肯定行不通……我可以这样做吗?

    最佳答案

    因此,从您的消息中,我可以提取出您的目标是允许在您单击 HTML 元素时更改语言。

    a标签的用法定义了一个超链接,用于从一个页面链接到另一个页面,可以用来实现你想要的。

    我以前做过多语言网站,您可以通过多种方式实现这一点。

    ///////////////////////////// 方法一:在HTML属性href中定义位置

    在您的 HTML 代码中,您在超链接中使用了 hash - # 。

    超链接需要 href 属性,因为它指定了一个位置。

    查看您的代码,您有标签,但缺少指向您要将用户重定向到的特定位置的链接。

    假设您希望它转到法语的 my-account 页面。

    所以,你的 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="http://yourwebsite.com/fr/my-account" data-lg="fr"><span>FR</span></a>
            </div>
        </div>
    </li>
    

    注意: 将 yourwebsite.com 替换为您网站的域。

    ///////////////////////////// 方法一结束

    在您的 HTML 代码中,您提到了 // Could be nice to change the langue staying on the same page

    这可以使用 AJAX 来完成,是的。

    但我不建议您这样做,因为从拥有多种语言(例如 SAPApple)网站的大公司来看,它们都重定向到不同的页面。

    ///////////////////////////// 更新: 直到现在的答案才被创建,因为我认为您的需要只是允许单击 HTML 元素时要更改的语言。

    显然,您的目标比这稍微复杂一些。

    根据 Silex 文档, _locale 的用法是 the way to go

    this question you can see working code 中:
    <?php
    
    require_once __DIR__.'/../vendor/autoload.php';
    
    $app = new Silex\Application();
    $app['debug'] = true;
    
    $app->register(new Silex\Provider\UrlGeneratorServiceProvider());
    $app->register(new Silex\Provider\TwigServiceProvider(), array(
        'twig.path' => __DIR__.'/../views',
    ));
    
    $app->register(new Silex\Provider\TranslationServiceProvider(array(
        'locale_fallbacks' => array('hr'),
    )));
    
    
    $app['translator'] = $app->share($app->extend('translator', function($translator) {
    
        $translator->addLoader('xlf', new \Symfony\Component\Translation\Loader\XliffFileLoader());
    
        $translator->addResource('xlf', __DIR__.'/../locales/hr.xlf', 'hr');
        $translator->addResource('xlf', __DIR__.'/../locales/en.xlf', 'en');
        $translator->addResource('xlf', __DIR__.'/../locales/sl.xlf', 'sl');
    
        return $translator;
    }));
    
    
    $app->get('/', function () use ($app) {
    
        $app['translator']->setLocale('hr');
    
        return $app['twig']->render('home.twig', array('d' => $app['translator']->getLocale()));
    
    });
    
    
    $app->get('/{_locale}/', function() use ($app) {
        $app['translator']->setLocale($app['request']->get('locale'));
    
        return $app['twig']->render('home.twig', array('d' => $app['translator']->getLocale()));
    });
    
    
    
    $app->run();
    

    关于php - 西莱克斯 : allow user to change langage by clicking on html element and keeping clean URL,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/49055253/

    10-11 22:13
    查看更多