Quelle est la meilleure logique pour changer de langue dans Laravel?
J'utilise la localisation Laravel pour fournir deux langues différentes. J'ai tous les trucs de chemin mis en place, et mydomain.com/en/bla fournit l'anglais et stocke la variable de session 'en', et mydomain.com/he/bla Livre l'hébreu et stocke la variable de session 'il'. Cependant, je ne peux pas trouver un moyen décent de fournir un lien de commutation de langue. Comment serait-il?
8 réponses
J'ai résolu mon problème en ajoutant ceci au filtre before dans les routes.php:
// Default language ($lang) & current uri language ($lang_uri)
$lang = 'he';
$lang_uri = URI::segment(1);
// Set default session language if none is set
if(!Session::has('language'))
{
Session::put('language', $lang);
}
// Route language path if needed
if($lang_uri !== 'en' && $lang_uri !== 'he')
{
return Redirect::to($lang.'/'.($lang_uri ? URI::current() : ''));
}
// Set session language to uri
elseif($lang_uri !== Session::get('language'))
{
Session::put('language', $lang_uri);
}
// Store the language switch links to the session
$he2en = preg_replace('/he\//', 'en/', URI::full(), 1);
$en2he = preg_replace('/en\//', 'he/', URI::full(), 1);
Session::put('he2en', $he2en);
Session::put('en2he', $en2he);
Ceci est un post que j'ai posté à l'origine sur les forums laravel, mais peut-être que cela aidera quelqu'un d'autre, alors je le poste ici aussi.
J'ai eu quelques problèmes avec la construction d'un sélecteur de langue facile pour mon application, et les informations sur les forums où un peu vieux (certains messages), donc j'ai fait ce simple morceau de code qui le rend super facile de changer de langue sur votre application à la volée.
J'ai les chaînes de langue dans mes vues comme suit:
{{ __('languagefile.the_language_string'); }}
Et je reçois les langues avec une URL, Je pensez que c'est la meilleure façon, aussi son bon pour le référencement et pour les liens que les gens partagent. Exemple:
www.myapp.com/fi/support (Finnish)
www.myapp.com/en/support (English)
www.myapp.com/sv/support (Swedish)
Ok, donc le problème était que je voulais un moyen facile de changer la langue à la volée, sans avoir à jouer avec les sessions et les cookies. Voici comment je l'ai fait:
Créez une bibliothèque dans votre dossier Bibliothèques appelée chooselang.php
Insérer ce code à l'intérieur:
class Chooselang extends HTML {
/**
* Generate a Language changer link.
*
* <code>
* // Generate a link to the current location,
* // but still change the site langauge on the fly
* // Change $langcode to desired language, also change the Config::set('application.language', 'YOUR-LANG-HERE')); to desired language
* // Example
* echo Chooselang::langslug(URI::current() , $langcode = 'Finnish' . Config::set('application.language', 'fi'));
* </code>
*
* @param string $url
* @param string $langcode
* @param array $attributes
* @param bool $https
* @return string
*/
public static function langslug($url, $langcode = null, $attributes = array(), $https = null)
{
$url = URL::to($url, $https);
if (is_null($langcode)) $langcode = $url;
return '<a href="'.$url.'"'.static::attributes($attributes).'>'.static::entities($langcode).'</a>';
}
}
Après cela, vous êtes prêt à obtenir votre URL switcher URL:s généré. Ajoutez simplement eux comme vous whould tous les autres liens de lame.
Exemple comment générer des liens pour le finnois, le suédois et l'anglais (avec Blade)
{{ Chooselang::langslug(URI::current() , $langcode = 'Fin' . Config::set('application.language', 'fi')); }}
{{ Chooselang::langslug(URI::current() , $langcode = 'Swe' . Config::set('application.language', 'sv')); }}
{{ Chooselang::langslug(URI::current() , $langcode = 'Eng' . Config::set('application.language', 'en')); }}
Ce qui précède va générer des URL: s qui sont toujours sur la page en cours, et changer le slug lang à celui que vous voulez. De cette façon, la langue change à celle que vous voulez, et l'utilisateur reste naturellement sur la même page. Le slug de langue par défaut n'est jamais ajouté à l'url.
Les URL générées ressemblent à:
<a href="http://localhost/laravel/public/support">Fin</a>
<a href="http://localhost/laravel/public/sv/support">Swe</a>
<a href="http://localhost/laravel/public/en/support">Eng</a>
PS. Les liens sont particulièrement utile si vous les ajoutez à votre fichier de modèle maître.
Vous pourriez avoir un itinéraire pour changer de langue, par exemple:
Route::get('translate/(:any)', 'translator@set');
Puis dans l'action set
dans le contrôleur translator
pourrait modifier la session, en fonction du code de langue passé via L'URL.
Vous pouvez également modifier le paramètre de configuration en utilisant
Config::set('application.language', $url_variable');
Exemple de contrôleur-traduire.php
public function action_set($url_variable)
{
/* Your code Here */
}
Juste au cas où pour les futurs utilisateurs si vous voulez utiliser package pour la localisation, il y a un excellent paquet à https://github.com/mcamara/laravel-localization . qui est facile à installer et a de nombreuses aides.
Essayez d'utiliser la Session. quelque chose comme ceci:
Contrôleur:
class Language_Controller extends Base_Controller {
function __construct(){
$this->action_set();
parent::__construct();
}
private function checkLang($lang = null){
if(isset($lang)){
foreach($this->_Langs as $k => $v){
if(strcmp($lang, $k) == 0) $Check = true;
}
}
return isset($Check) ? $Check : false;
}
public function action_set($lang = null){
if(isset($lang) && $this->checkLang($lang)){
Session::put('lang', $lang);
$this->_Langs['current'] = $lang;
Config::set('application.language', $lang);
} else {
if(Session::has('lang')){
Config::set('application.language', Session::get('lang'));
$this->_Langs['current'] = Session::get('lang');
} else {
$this->_Langs['current'] = $this->_Default;
}
}
return Redirect::to('/');
}
}
En Route.php:
Route::get('lang/(:any)', 'language@set');
Je l'ai fait comme ceci:
$languages = Config::get('lang.languages'); //returns array('hrv', 'eng')
$locale = Request::segment(1); //fetches first URI segment
//for default language ('hrv') set $locale prefix to "", otherwise set it to lang prefix
if (in_array($locale, $languages) && $locale != 'hrv') {
App::setLocale($locale);
} else {
App::setLocale('hrv');
$locale = null;
}
// "/" routes will be default language routes, and "/$prefix" routes will be routes for all other languages
Route::group(array('prefix' => $locale), function() {
//my routes here
});
Source: http://forumsarchive.laravel.io/viewtopic.php?pid=35185#p35185
Cette question vient toujours dans la recherche Google, alors voici la réponse si vous utilisez Laravel 4 ou 5, et mcamara / laravellocalization.
<ul>
<li class="h5"><strong><span class="ee-text-dark">{{ trans('common.chooselanguage') }}:</span></strong> </li>
@foreach(LaravelLocalization::getSupportedLocales() as $localeCode => $properties)
<li>
<a rel="alternate" hreflang="{{$localeCode}}" href="{{LaravelLocalization::getLocalizedURL($localeCode) }}">
<img src="/img/flags/{{$localeCode}}.gif" /> {{{ $properties['native'] }}}
</a>
</li>
@endforeach
</ul>
Notez que cet exemple montre des drapeaux (dans public / img / flags / {{locale}}.gif), et pour l'utiliser, vous aurez besoin d'un peu de .css, mais vous pouvez la modifier pour afficher le texte si vous le souhaitez...
POUR INFO. La documentation mcamara/laravellocalization a des exemples et beaucoup d'aides, alors regardez à travers la documentation sur github. (https://github.com/mcamara/laravel-localization)
Ce que je fais se compose de deux étapes: Je crée une table de langages qui se compose de ces champs:
Id | nom | slug
Qui contiennent les données dont je vais avoir besoin pour les langues par exemple
1 | grec | gr
2 / Français / fr
3 | néerlandais | de
le modèle de langue que j'utilise dans le code ci-dessous fait référence à cette table.
Donc, dans mes routes.php j'ai quelque chose comme:
//get the first segment of the url
$slug = Request::segment(1);
$requested_slug = "";
//I retrieve the recordset from the languages table that has as a slug the first url segment of request
$lang = Language::where('slug', '=', $slug)->first();
//if it's null, the language I will retrieve a new recordset with my default language
$lang ? $requested_slug = $slug : $lang = Language::where('slug', '=', **mydefaultlanguage**')->first();
//I'm preparing the $routePrefix variable, which will help me with my forms
$requested_slug == ""? $routePrefix = "" : $routePrefix = $requested_slug.".";
//and I'm putting the data in the in the session
Session::put('lang_id', $lang->id);
Session::put('slug', $requested_slug);
Session::put('routePrefix', $routePrefix );
Session::put('lang', $lang->name);
Et puis je peux m'écrire des routes en utilisant le slug demandé comme préfixe...
Route::group(array('prefix' => $requested_slug), function()
{
Route::get('/', function () {
return "the language here is gonna be: ".Session::get('lang');
});
Route::resource('posts', 'PostsController');
Route::resource('albums', 'AlbumsController');
});
Cela fonctionne mais ce code demandera à la base de données pour les langues chaque fois que l'itinéraire change dans mon application. Je ne sais pas comment je pourrais, et si je devrais, trouver un mécanisme qui détecte si la route change dans une autre langue.
J'espère que cela a aidé.