Dans la première partie de cet article je vous avais proposé une solution simple pour faire un site multi-langues en PHP. Dans la seconde partie je vous avais montré la class IziTranslate pour faciliter l'utilisation d'un site multi-langues.
Dans cette avant dernière partie je vais vous présenter une class que j'utilise pour gérer les traductions de mes textes. C'est une extension de la classe IziTranslate : IziTranslateEdit.
IziTranslateEdit vous aide à gérer vos traductions
Cette extension de la class IziTranslate a deux fonctions principales.
D'une part elle crée un tableau HTML avec dans la première colonne l'identifiant du texte, puis dans les colonnes suivantes, le texte qui correspond à chaque langue. La dernière colonne contient un bouton pour supprimer une ligne.
La class renvoie également le code javascript nécessaire, il n'y a aucun fichier supplémentaire à intégrer à votre page. Vous n'avez qu'à l'intégrer dans un formulaire de type POST.
D'autre part elle enregistre les modifications apportées à un fichier.
Le fonctionnement est le même que la class IziTranslate :
- Créez une instance de la class.
- Ajoutez les différents langages.
- Éditer les fichiers.
- Enregistrer vos modifications.
Pour afficher les champs de texte on utilise la fonction GetHtml() qui renvoie un tableau HTML avec des champs éditables pour chaque langue, ainsi que le code javascript pour supprimer et ajouter une ligne au tableau.
// importe les classes
require 'IziTranslate.class.php';
require 'IziTranslateEdit.class.php';
// crée l'objet
$ITE = new IziTranslateEdit('lang');
// ajoute les langues
// le premier paramètres est le nom du dossier
// le second est le texte qui est affiché dans le tableau
$ITE->AddLanguage('fr', 'Français');
$ITE->AddLanguage('en', 'Anglais');
// charge un fichier à éditer dans chaque langue
$ITE->EditTxt('common.json');
// affiche le tableau HTML dans un formulaire
echo '<form action="" method="post">'.$ITE->GetHtml().'
<input type="submit" value="Enregistrer">
</form>';
Pour enregistrer les modifications apportées on utilise la fonction SaveFromPostValue() qui va chercher les textes modifiés dans les données $_POST et les enregistrer dans le fichier ouvert pour chaque langue.
// importe les classes
require 'IziTranslate.class.php';
require 'IziTranslateEdit.class.php';
// crée l'objet
$ITE = new IziTranslateEdit('lang');
// ajoute les langues
$ITE->AddLanguage('fr', 'Français');
$ITE->AddLanguage('en', 'Anglais');
// charge le fichier dans lequel on va enregistrer les textes
$ITE->EditTxt('common.json');
// enregistre les modifications
if($ITE->SaveFromPostValue()){
// les modifications sont enregistrées
}else{
// une erreur est survenue
}
La class peut également vous renvoyer la liste des fichiers présents dans le dossier de la langue de référence avec la fonction GetFileList().
// importe les classes
require 'IziTranslate.class.php';
require 'IziTranslateEdit.class.php';
// crée l'objet
$ITE = new IziTranslateEdit('lang');
// ajoute les langues
$ITE->AddLanguage('fr', 'Français');
$ITE->AddLanguage('en', 'Anglais');
// récupère la liste des fichiers dans le dossier de référence
$fileLst = $ITE->GetFileList();
// affiche la liste des fichiers
$html = '<ul>';
foreach($fileLst as $k=>$v){
$html .= '<li>'.$v.'</li>';
}
$html .= '</ul>';
echo $html;
Le code
Voici le code de la class IziTranslateEdit, vous n'avez qu'à le copier coller dans un fichier que vous nommerez 'IziTranslateEdit.class.php'
// class IziTranslateEdit
// http://blog.niap3d.com/fr/1,10,news-46-Internationaliser-un-site-partie-3-.html
class IziTranslateEdit extends IziTranslate{
protected $filePath = '';
//
// Charge un fichier pour le modifier
//
// argument :
// $aFile = nom du fichier à éditer
//
public function EditTxt($aFile){
if($this->LoadTxt($aFile)) $this->filePath = $aFile;
}
//
// renvoi un tableau html les textes
//
public function GetHtml(){
if(!$this->langRef) return '';
$h = '<table id="IziTranslateEditTable">';
$h .= '<tr><th>Identifiant</th>';
// affiche le nom de la langue en entete
foreach($this->langLst as $k1=>$v1){
$h .= '<th>'.($v1=='' ? $k1:$v1).'</th>';
}
$h .= '<th></th></tr>';
// boucle a travers toutes les clé de la langue de référence
$l = 0;
foreach($this->txt[$this->langRef] as $k1=>$v1){
$l++;
// ajoute le champ de l'identifiant
$h .= '<tr><td><input type="text" size="35" name="title_'.$l.'" id="champ_title_'.$l.'" value="'.$k1.'" /></td>';
// cherche dans chaque langue la clé trouvé dans la langue de référence et ajoute une zone de texte
foreach($this->langLst as $k2=>$v2){
$h .= '<td><textarea rows="4" cols="40" name="'.$k2.'_'.$l.'" id="champ_'.$k2.'_'.$l.'">'.$this->txt[$k2][$k1].'</textarea></td>';
}
// bouton pour supprimer la ligne
$h .= '<td><input type="button" name="lineDel" value="-" onclick="IziTranslateEditDelLine(this)"></td></tr>';
}
$h .= '</table>';
// bouton pour ajouter une nouvelle ligne
$h .= '<p><input type="button" name="lineAdd" value="+" onclick="IziTranslateEditAddLine()"></p>';
// code javascript qui contient les fonctions pour ajouter et supprimer des lignes
$h .= '<script type="text/javascript">
//<![CDATA[
var IziTranslateEditTxtNb = '.$l.';
function IziTranslateEditAddLine(){
var el = document.getElementById("IziTranslateEditTable");
if(el==undefined) return 0;
var lang= new Array("'.implode('","', array_keys($this->langLst)).'");
var row = el.insertRow(-1);
IziTranslateEditTxtNb++;
var html = \'<td><input type="text" size="35" name="title_\'+IziTranslateEditTxtNb+\'" id="champ_title_\'+IziTranslateEditTxtNb+\'"></td>\'
for(var i=0; i<lang.length; i++){
html += \'<td><textarea rows="4" cols="40" name="\'+lang[i]+\'_\'+IziTranslateEditTxtNb+\'" id="champ_\'+lang[i]+\'_\'+IziTranslateEditTxtNb+\'"></textarea></td>\';
}
html += \'<td><input type="button" name="lineDel" value="-" onclick="IziTranslateEditDelLine(this)"></td>\'
row.innerHTML = html;
return 1;
}
function IziTranslateEditDelLine(aCell){
var el = document.getElementById("IziTranslateEditTable");
if(el==undefined) return 0;
var row = aCell.parentNode.parentNode;
el.deleteRow(row.rowIndex);
return 1;
}
//]]>
</script>';
return $h;
}
//
// renvoi la liste des fichiers enregistrés dans le dossier lang de référence
//
public function GetFileList(){
$l = @scandir($this->pathLang.'/'.$this->langRef.'/', 1);
$l2 = array();
if(!empty($l)){
foreach($l as $f){
if($f!='.' && $f!='..') $l2[] = $f;
}
}
return $l2;
}
//
// enregistre les textes de chaque langues
//
public function SaveFromPostValue(){
// initialise le tableau des textes
$this->txt = array();
foreach($this->langLst as $k2=>$v2){
$this->txt[$k2] = array();
}
// boucle à travers les données $_POST
foreach($_POST as $k=>$v){
// cherche les champs dont le nom commencent par title
if(substr($k, 0, 5)=='title'){
// vérifie si la valeur du titre n'est pas vide
if(empty($v)) continue;
// cherche l'identifiant lié
$id = substr($k, 6, strlen($k)-6);
// pour chaque langue cherche le texte qui correspond [identifiant de la langue]_[identifiant champ]
foreach($this->langLst as $k2=>$v2){
if(!empty($_POST[$k2.'_'.$id])) $this->txt[$k2][$v] = $_POST[$k2.'_'.$id];
}
}
}
// enregistre les fichiers
foreach($this->langLst as $k1=>$v1){
$p = $this->pathLang.'/'.$k1.'/'.$this->filePath;
if(!$f = fopen($p, 'w')){
return 0;
}else{
fwrite($f, json_encode($this->txt[$k1]));
fclose($f);
}
}
return 1;
}
}