Did you have some discomfort, creating multilingual sites and Models? I didn't find any elegant interface for solving this problem. So, what i need? I'd like to create automatically CRUD for any model with multilingual support. Create model of any structure and create automatically CRUD for managing this model with any list of languages. I don't need any additional tables for translations, but out-of-the-box generator for any model structure. Certainly, there will be some constraints to make it workable:
<li>you need to make an additional field - varchar(10) 'language' to keep language in</li>
<li>change primary_key(id) to composite primary_key(id, language)</li>
<li>connect special multilingual behavior for more efficiency usage</li>
And that's all. After this you can:
<li>automatically generate CRUD for any multilingual CRUD</li>
<li>easily manipulate your model's data in your routines</li>
Installation routines
Unpack module files to your application.module path. Configurate config/main.php:
<li> add <a href="http://www.yiiframework.com/doc/guide/1.1/en/topics.gii" target="_blank">gii generator</a> additional templates path</li>
'modules' => array(
...
'gii' => array(
...
'generatorPaths' => array(
'application.modules.MultilingualCrud.extensions.gii-templates'
),
...
),
...
'MultilingualCrud' => array(
'defaultLayout' => 'application.custom.layout', /// you can set default layout for your controller here, or //layouts/column2 will be used
'fieldsPk' => array('id', 'language'), /// you can set composite key fields names (not tested yet). It is better to keep default. Chabge before generating
),
...
configure your current language in config
...
'language' => 'en_us',
...
- configure your exist model:
- add composite key ('id', 'language')
- add custom multilingual behavior to your model
....
public function behaviors()
{
return array(
...
'ml' => array( /// ml is neccessary name
'class' => 'application.modules.MultilingualCrud.components.MultilingualActiveRecordBehavior'
)
);
}
....
- manage your languages using predefined module controller
go 'MultilingualCrud/' and admin your languages list. You can easily disable/enable exist languages to provide access for translations in your models.
<li>go to the GII and create CRUD, using MultilingualCrud generator</li>
That's all.
Now you can access your CRUD like always:
<controller>/admin
<controller>/create
<controller>/index
view, delete, update, etc.
Additional documentation and links:
<li><a href="https://github.com/deeptowncitizen/MultilingualCrud" target="_blank">module repository</a>;</li>
<li><a href="http://www.yiiframework.com/doc/guide/1.1/en/topics.gii" target="_blank">Yii Automatic code generation</a>.</li>
<li><a href="http://all-of.me/yii-multilingual-crud/" target="_blank">Official website and free support</a>.</li>
I only get duplicate entry for....xxx
Thanks for sharing, but this doesn't work for me, i always get error when trying to create a new record.
CDbException
CDbCommand falhou ao executar o comando SQL: SQLSTATE[23000]: Integrity constraint violation: 1062 Duplicate entry '2-' for key 'PRIMARY'. The SQL statement executed was: INSERT INTO
df_prodcategory
(status
,order
,name
,id
) VALUES (:yp0, :yp1, :yp2, :yp3). Bound with :yp0=1, :yp1=1, :yp2='Blade Sharpeners', :yp3=2Also documentation lacks telling that you need to create the language table
Some hacks were needed to get it running, but inserting records doesn't work properly
regards
edit:
I've put a rule aray('id, language', 'safe') in the model and now it is working...is it necessary?
tks
Reproducing steps
Hello. Excuse me for this inconvtnience.
Please, could you share with me a model and sql for this model to reproduce the issue you are experiencing (mail me on reshetnikd at gmail.com)?
And thank you for pointing on documentation lacks, i'll fix it in a few days.
Using elrtef WYSIWYG extension together with multilingual-crud
@deeptowncitizen:
I don't really know what happened, I regenerated models and now it is working like a charm, thank you very much for sharing this ext!
My two cents of contribution:
For those who wants to use the elrtef wysiwyg editor, some tips:
First, comment out the following code in form view:
//else if(stripos($columnType,'text')!==false){ //return CHtml::textArea(generateName($language, $columnName), $value, array('rows'=>6, 'cols'=>50));
This will disable field generation for TEXTAREA items
After that, make a simple change in ext.elrtef.elRTE.php:
Include a public property called "value", this will be used in the form view to pass attribute value to the widget
public $value = null;
In the same file, change the code that generates the TEXTAREA field (in the very bottom of the code):
echo '<textarea id="'.$id.'" name="'.$name.'" rows="10" cols="40">'; echo $this->model['attributes'][$this->attribute]; if(isset($this->value)) echo $this->value; echo '</textarea>';
Back to our form view file, insert a beginclip that captures the elrtef content for our field, inside the "foreach($langs as $language)" code. I've inserted after the line "$page = 0;".
$this->beginClip($language->language.'ELRTE'); $this->widget('ext.elrtef.elRTE', array( 'model' => $model, 'attribute' => generateName($language->language, 'body'), 'name' => generateName($language->language, 'body'), 'value'=>$model->body, 'options' => array( 'doctype'=>'js:\'<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">\'', 'cssClass' => 'el-rte', 'cssfiles' => array('css/elrte-inner.css'), 'absoluteURLs'=>true, 'allowSource' => true, 'lang' => Yii::app()->getLanguage(), 'height' => 600, 'fmAllow'=>true, //if you want to use Media-manager 'fmOpen'=>'js:function(callback) {$("<div id=\"elfinder\" />").elfinder(%elfopts%);}',//here used placeholder for settings 'toolbar' => 'df9', ), 'elfoptions' => array( //elfinder options 'url'=>'auto', //if set auto - script tries to connect with native connector 'passkey'=>'df9password', //here passkey from first connector`s line 'dialog'=>array('width'=>'600','modal'=>true,'title'=>'Select file'), 'lang' => Yii::app()->getLanguage(), 'closeOnEditorCallback'=>true, 'editorCallback'=>'js:callback', 'baseUrl'=>'http://local.df9cms.com/legal/' ), ) ); $this->endClip();
Obviously, adjust the widget rendering according to your needs, please, don't simply "copy and paste" the above code without paying attention to properties or else it may break your code
Well, finally, in the same form view file, we need to skip the "auto-generation" of the field we want to be wysiwyg. Just change
$content .= "<div class=\"row\">" . CHtml::activeLabelEx($model,'body') . $this->clips[$language->language.'ELRTE'] . //generateField('body', 'text', 0, $language->language, ($model->language === $language->language) ? $model->body : '' ) . "</div>";
This will place the visual editor with the content captured by the clip in the exact place you want
Hope this can be useful for someone
Regards!
:)
Little improvement
Hi there!
I've tried to get related models with the "with" chained method and got an error that the "language" field was ambiguous.
Changing the line 'condition' of the Ml Behavior file solved the problem. Just added $owner->getTableAlias() and a dot before the {$languageField}
... public function locale($language = null) { $owner->getDbCriteria()->mergeWith( array( 'condition' => $owner->getTableAlias() . ".{$languageField}='{$language}'" ) ); return $owner; }
Hope this helps
Regards
If you have any questions, please ask in the forum instead.
Signup or Login in order to comment.