I have a multilanguage website in Laravel 4.2, and would like to send an email notification to the admins in a specified language using the lang files.
How can I call Lang::get('group.key') specifying the needed language ?
Thank you for your help !
Edit: existing code: (the lang items are option1, option2, .., option6)
class EmailController extends BaseController {
public static function contact(){
$rules = [
'name' => 'required',
'email' => 'required|email',
'subject' => 'required|digits_between:1,6',
'message' => 'required'
];
$validator = Validator::make(Input::all(), $rules);
if (!$validator->fails()){
$data = ['subject' => Input::get('subject'),
'email' => Input::get('email'),
'content' => Input::get('message')];
Mail::send('emails.contact', $data, function($message){
$message->from(Input::get('email'), Input::get('name'));
$message->to('admin#email.com', 'Admin');
$message->subject(Lang::get('contact.option'.Input::get('subject')));
});
}
return Redirect::to('/');
}
}
There are 3 ways to achieve this:
You can change default language at runtime by doing this:
App::setLocale('fr');
NB: This is not suitable for your current need as it will only take effect on next page load.
You can set default language here app/config/app.php
'fallback_locale' => 'fr'
I took a deeper look at Illuminate\Translation\Translator:
get($key, array $replace = array(), $locale = null)
This means you can do this using Translator Facade:
Lang::get($key, array $replace = array(), $locale = null);
Example:
Lang::get('group.key',[],'fr');
NB: You folder structure should look like this
/app
/lang
/en
messages.php
/fr
messages.php
To get a language specific translation - different from the current locales without setting and unsetting the locales, just do
__('description_1', [], 'en')
Just set needed locale before calling Lang::get():
App::setLocale('es');
<?php
return [
'welcome' => 'welcome :name',
];
trans('welcome', [ 'name' => 'xyz' ], 'fr');
I would recommend something like this:
$savedLocale = App::getLocale();
App::setLocale($this->getUserMailingLanguage());
Mail::to($this->e_mail)->send($mailable);
App::setLocale($savedLocale);
I had exactly the same issue and found the desired answer.
This will provide you the desired result:
trans('welcome',array(),null,'fr');
This is working since Laravel vers. 5.2.
Related
I am trying to configure Yii2 url manager in a manner that if a controller name is skipped in url it should call the default controller for action. I have managed to achieve this without action parameter. But got stuck when using parameters in action name.
Here is my route config:
return [
'catalog/category/<alias:[\w-]+>' => 'catalog/default/category',
'catalog/<action:\w+>' => 'catalog/default/<action>',
];
Controller File:
namespace app\modules\catalog\controllers;
use yii\base\Controller;
use app\modules\catalog\models\Categories;
class DefaultController extends Controller
{
public function actionShopbydepartment()
{
$data['categories'] = Categories::findParentSubHierarchy();
return $this->renderPartial('shopbydepartment', $data);
}
public function actionCategory($alias = null)
{
die(var_dump($alias));
$data['category'] = Categories::findCategoryBySlug($alias);
return $this->render('category', $data);
}
}
when I access the following url it loads perfectly.
http://domain.com/index.php/catalog/shopbydepartment
But when i access the below url it called the right function but did not pass the $alias value:
http://domain.com/index.php/catalog/category/appliances
UPDATE:
I have used the following approach for module wise url rules declaration:
https://stackoverflow.com/a/27959286/1232366
Here is what i have in the main config file:
'rules' => [
[
'pattern' => 'admin/<controller:\w+>/<action:[\w-]+>/<id:\d+>',
'route' => 'admin/<controller>/<action>'
],
[
'pattern' => 'admin/<module:\w+>/<controller:\w+>/<action:[\w-]+>/<id:\d+>',
'route' => 'admin/<module>/<controller>/<action>'
],
],
the admin is working fine and this is my first module so rest of the rules are mentioned already
Well just to help other fellows I have retrieve the value of $alias using the following approach:
$alias = \Yii::$app->request->get('alias');
But definitely this is not an accurate answer of the question. I still didn't know what i am doing wrong that i didn't get the value using the approach mentioned in question.
It wirk!
[
'name' => 'lang_country_seller_catalog',
'pattern' => '<lang:\w+>-<country:\w+>/seller/catalog/<module>/<controller>/<action>',
'route' => 'seller/catalog/<module>/<controller>/<action>',
],
[
'name' => 'lang_country_seller_catalog_attributes',
'pattern' => '<lang:\w+>-<country:\w+>/seller/catalog/attributes/<module>',
'route' => 'seller/catalog/attributes/<module>',
],
I'm using the dwightwatson/validating package to create validation rules in the model.
I particularly like the custom rulesets you can create for different routes.
Model
protected $rulesets = [
'set_up_all' => [
'headline' => 'required|max:100',
'description' => 'required'
],
'set_up_property' => [
'pets' => 'required'
],
'set_up_room' => [
'residents_gender' => 'required',
'residents_smoker' => 'required'
],
'set_up_roommate' => [
'personal_gender' => 'required',
'personal_smoker' => 'required'
]
];
Controller
$post = new Post(Input::all());
if($post->isValid('set_up_all', false)) {
return 'It passed validation';
} else {
return 'It failed validation';
}
In the above example, it works well in validating against the set_up_all ruleset. Now I would like to combine several rulesets and validate against all of them together.
According to the documentation, the package offers a way to merge rulesets. I just can't figure out how to integrate the example provided into my current flow.
According to the docs, I need to implement this line:
$mergedRules = $post->mergeRulesets('set_up_all', 'set_up_property_room', 'set_up_property');
This was my attempt, but it didn't work:
if($mergedRules->isValid()) { ...
I get the following error:
Call to a member function isValid() on array
I also tried this, but that didn't work either:
if($post->isValid($mergedRules)) { ...
I get the following error:
array_key_exists(): The first argument should be either a string or an integer
Any suggestions on how I would implement the merging rulesets?
From what I can see - mergeRulesets() returns an array of rules.
So if you do this - it might work:
$post = new Post(Input::all());
$post->setRules($post->mergeRulesets('set_up_all', 'set_up_property_room', 'set_up_property'));
if($post->isValid()) {
///
}
I've released an update version of the package for Laravel 4.2 (0.10.7) which now allows you to pass your rules to the isValid() method to validate against them.
$post->isValid($mergedRules);
The other answers will work, but this syntax is nicer (and won't override the existing rules on the model).
Can we rename routing resource path names in Laravel like in Ruby on Rails?
Current
/users/create -> UsersController#create
/users/3/edit -> UsersController#edit
..
I want like this;
/users/yeni -> UsersController#create
/users/3/duzenle -> UsersController#edit
I want to do this for localization.
Example from Ruby on Rails;
scope(path_names: { new: "ekle" }) do
resources :users
end
I know this is an old question. I'm just posting this answer for historical purposes:
Laravel now has the possibility to localize the resources. https://laravel.com/docs/5.5/controllers#restful-localizing-resource-uris
Localizing Resource URIs By default, Route::resource will create
resource URIs using English verbs. If you need to localize the create
and edit action verbs, you may use the Route::resourceVerbs method.
This may be done in the boot method of your AppServiceProvider:
use Illuminate\Support\Facades\Route;
/**
* Bootstrap any application services.
*
* #return void
*/
public function boot() {
Route::resourceVerbs([
'create' => 'crear',
'edit' => 'editar',
]); }
Once the verbs have been customized, a resource route registration such as Route::resource('fotos', 'PhotoController') will
produce the following URIs:
/fotos/crear
/fotos/{foto}/editar
It ain't pretty, but you could define multiple routes that use the same controller function. For example:
Route::get("user/create", "UsersController#create");
Route::get("user/yeni", "UsersController#create");
The only (glaringly obvious downside) being that you're routes will get quite cluttered quite quickly. There is a setting in app/config/app.php where you can set/change your locale, and it could be possible to use that in conjunction with a filter to use the routes and then group those routes based on the current local/language, but that would require more research.
As far as I know, there isn't a way to rename resource routes on the fly, but if you get creative you can figure something out. Best of luck!
You can't change the resource url's.
For this you will need to define/create each route according your needs
Route::get("user/yeni", "UsersController#create");
and if you need more than one languages you can use the trans helper function, which is an alias for the Lang::get method
Route::get('user/'.trans('routes.create'), 'UsersController#create');
I just had the same issue. And managed to recreate some sort of custom resource route method. It probably could be a lot better, but for now it works like a charm.
namespace App\Helpers;
use Illuminate\Support\Facades\App;
class RouteHelper
{
public static function NamedResourceRoute($route, $controller, $named, $except = array())
{
$routes = RouteHelper::GetDefaultResourceRoutes($route);
foreach($routes as $method => $options) {
RouteHelper::GetRoute($route, $controller, $method, $options['type'], $options['name'], $named);
}
}
public static function GetRoute($route, $controller, $method, $type, $name, $named) {
App::make('router')->$type($named.'/'.$name, ['as' => $route.'.'.$method, 'uses' => $controller.'#'.$method]);
}
public static function GetDefaultResourceRoutes($route) {
return [
'store' => [
'type' => 'post',
'name' => ''
],
'index' => [
'type' => 'get',
'name' => ''
],
'create' => [
'type' => 'get',
'name' => trans('routes.create')
],
'update' => [
'type' => 'put',
'name' => '{'.$route.'}'
],
'show' => [
'type' => 'get',
'name' => '{'.$route.'}'
],
'destroy' => [
'type' => 'delete',
'name' => '{'.$route.'}'
],
'edit' => [
'type' => 'get',
'name' => '{'.$route.'}/'.trans('routes.edit')
]
];
}
}
Use it like this in the routes.php:
\App\Helpers\RouteHelper::NamedResourceRoute('recipes', 'RecipeController', 'recepten');
Where the first parameter is for the named route, second the controller and third the route itself.
And something like this to the view/lang/{language}/route.php file:
'edit' => 'wijzig',
'create' => 'nieuw'
This results in something like this:
This is not possible in Laravel as they use code by convention over configuration. A resources uses the RESTfull implementation
Therefore you have to stick to the convention of
GET /news/create
POST /news
GET /news/1
GET /news/1/edit
...
I don't know if this is a bug or a mistake on my end but basically I followed the Yii2 documentation to setup i18n translations for modules. The following snippet is directly copy pasted from the Yii2 guide.
public function init()
{
parent::init();
$this->registerTranslations();
}
public function registerTranslations()
{
Yii::$app->i18n->translations['modules/users/*'] = [
'class' => 'yii\i18n\PhpMessageSource',
'sourceLanguage' => 'en',
'basePath' => '#app/modules/users/messages',
];
}
public static function t($category, $message, $params = [], $language = null)
{
return Yii::t('modules/users/' . $category, $message, $params, $language);
}
According to the guide I should call it like this:
Module::t('validation', 'your custom validation message')
However, Yii2 tries to load the the 'validation.php' from the wrong location. This is the output of the debugger:
The message file for category 'modules/users/validation' does not exist: /Applications/MAMP/htdocs/.../domains/localhost/public_html/.../backend/modules/users/messages/en/modules/users/validation.php
From what I understand, it should be looking for modules/users/message/<lang>/validation.php instead, which makes a lot more sense than what it is looking for right now.
What am I doing wrong?
Thank you in advance.
You should simply add a filemap param, e.g. :
public function registerTranslations()
{
Yii::$app->i18n->translations['modules/users/*'] = [
'class' => 'yii\i18n\PhpMessageSource',
'sourceLanguage' => 'en',
'basePath' => '#app/modules/users/messages',
'fileMap' => [
'modules/users/validation' => 'validation.php',
],
];
}
Read more : http://www.yiiframework.com/doc-2.0/guide-tutorial-i18n.html#translating-module-messages
EDIT : As stated in Yii2 guide, if you want to remove filemap, your validation.php file should be in modules/users/messages/[lang]/modules/users/validation.php.
Instead of configuring fileMap you can rely on convention which is to use the category name as the file name (e.g. category app/error will result in the file name app/error.php under the basePath.
I am wondering if the Yii framework uses the defined Labels atttributes in a multilanguage process.
So if I have
public function attributeLabels() {
return array(
'email' => 'Email address',
'rememberMe' => 'Remember me next time',
'password' => 'Password'
);
}
Will this be translated to some other language? Or do I have to do something manually to work?
Yii doesn't translate it automatically. You need to use the i18n built-in in Yii and manually add the translations and modify the labels as follow:
public function attributeLabels() {
return array(
'email' => Yii::t('account','Email address'),
'rememberMe' => Yii::t('account','Remember me next time'),
'password' => Yii::t('account','Password')
);
}
You can get more info about internationalize you app at Quick Start to Internationalize your application in Yii Framework
Well, you can use the built-in translation system to translate your attribute labels, for example:
public function attributeLabels() {
return array(
'email' => Yii::t('myapp','Email address'),
);
}
and then in messages folder create a directory for your language, for example:
messages\dk\myapp.php
myapp.php should return the translation, for example:
return array('Email address' => 'TRANSLATION...');
Next you need to set the language of your application in the config file for instance.
'language' => 'dk',
I had assumed that Yii AR would run getAttributeLabel through Yii::t. Not wanting to do all that copy and pasting on dozens of models, I added this function to my intermediate AR class:
public function getAttributeLabel($attribute)
{
$baseLabel = parent::getAttributeLabel($attribute);
return Yii::t(get_called_class(), $baseLabel);
}
Now to write a shell command that loops through the models and adds their labels to the message file.