i18n Class
Ik weet niet of er iemand bekend is met i18n Class? Dit is een class bedoeld voor meertalige websites. Hiermee kun je op een relatief makkelijke manier bepaalde secties (b.v. contact pagina) in de website in diversen talen weergeven d.m.v. van vertaalbestanden(lang_en.ini, lang_nl.ini). Op zich werkt dit prima ik zit alleen met het format van de output:
Waar L de prefix is gevolgd door twee maal dubbele punt, waardoor ik dit onbruikbaar is als PHP variabele als ik dit in een database zou opslaan. Mijn vraag is derhalve: Is iemand bekend met deze Class en zo ja hoe kan ik di dubbele punten omzeilen. Als ik het nu in de database zet wordt gewoon de daadwerkelijke tekst L::contact_naam"in plaats van de waarde die ik er aan heb toegekend in de ini files
Waar L de prefix is gevolgd door twee maal dubbele punt, waardoor ik dit onbruikbaar is als PHP variabele als ik dit in een database zou opslaan. Mijn vraag is derhalve: Is iemand bekend met deze Class en zo ja hoe kan ik di dubbele punten omzeilen. Als ik het nu in de database zet wordt gewoon de daadwerkelijke tekst L::contact_naam"in plaats van de waarde die ik er aan heb toegekend in de ini files
Maar met welke reden zet je dat in de database? En waar vind ik die class?
Gewijzigd op 07/10/2018 16:37:04 door - Ariën -
- Ariën - op 07/10/2018 16:24:19:
Maar met welke reden zet je dat in de database? En waar vind ik die class?
`@- Ariën -
Ik heb b.v.een sectie met verschillende categorieen. In plaats van alles inline te zetten leek het mij handig om doormiddel van een foreach loop over deze categorieen te gaan:
De betreffende class vindt je hier
Als ik de voorbeelden zie, staat de vertaling van L::contact_naam in een ini of json bestand voor die taal.
https://github.com/Philipp15b/php-i18n/blob/master/example.php
https://github.com/Philipp15b/php-i18n/blob/master/lang/lang_de.ini
https://github.com/Philipp15b/php-i18n/blob/master/example.php
https://github.com/Philipp15b/php-i18n/blob/master/lang/lang_de.ini
Dan zou ik denken aan eval() maar het blijft iets wat je eigenlijk niet moet gebruiken uit veiligheidsoverwegingen.
De class heeft er voor zover ik zie geen ondersteuning voor.
Misschien dat het met GetText beter zal gaan dan met een uitgeklede class die haast hetzelfde bereikt.
De class heeft er voor zover ik zie geen ondersteuning voor.
Misschien dat het met GetText beter zal gaan dan met een uitgeklede class die haast hetzelfde bereikt.
Zo te zien compileert die class vanuit je .ini bestand een PHP bestand met een class "L" (dat is de default "prefix"). Vanuit die class L kun je "static" (met dubbele-dubbele-punt) de teksten aanroepen. Je kunt (als ik het zo 123 even goed lees) echter ook met een functie de vertaling ophalen (er even vanuit gaande dat je de prefix op "L" heft gelaten):
(zie regel 160 van de i18n class)
En dan kun je dus gewoon met "gewone" variabelen werken.
Code (php)
1
2
3
2
3
$strs = new L(); //eenmalig
$id = 'contact_naam'; //id van vertaling die je op wilt halen
print($strs->L($id));
$id = 'contact_naam'; //id van vertaling die je op wilt halen
print($strs->L($id));
(zie regel 160 van de i18n class)
En dan kun je dus gewoon met "gewone" variabelen werken.
** quoteknip **
@Rob Doemaarwat
En als ik gewoonweg de dubbele-dubbelepunt uit deze lijn weghaal:
of kan dat niet. Overigens dit is een voorbeeld van een .ini bestand(nl):
Hetgeen momenteel de volgende, eerder genoemde ouput vereist
Toevoeging op 07/10/2018 18:35:08:
@Rob Doemaarwat
Wat ik je vroeg:
En als ik gewoonweg de dubbele-dubbelepunt uit deze lijn weghaal
Werkt dus niet. Kun je wat duidelijker uitleggen wat je bedoeld met het door jou voorgestelde?
Alvast bedankt
@Rob Doemaarwat
En als ik gewoonweg de dubbele-dubbelepunt uit deze lijn weghaal:
of kan dat niet. Overigens dit is een voorbeeld van een .ini bestand(nl):
Code (php)
1
2
3
4
5
6
7
8
9
2
3
4
5
6
7
8
9
[categorie]
label1 = "Antiek"
label2 = "Oudheden"
label3 = "Kunst"
label4 = "Curiosa"
label5 = "Instrumenten"
label6 = "Boeken"
label7 = "Platen"
label8 = "Meubelen"
label1 = "Antiek"
label2 = "Oudheden"
label3 = "Kunst"
label4 = "Curiosa"
label5 = "Instrumenten"
label6 = "Boeken"
label7 = "Platen"
label8 = "Meubelen"
Hetgeen momenteel de volgende, eerder genoemde ouput vereist
Toevoeging op 07/10/2018 18:35:08:
@Rob Doemaarwat
Wat ik je vroeg:
En als ik gewoonweg de dubbele-dubbelepunt uit deze lijn weghaal
Werkt dus niet. Kun je wat duidelijker uitleggen wat je bedoeld met het door jou voorgestelde?
Alvast bedankt
Gewijzigd op 08/10/2018 23:09:38 door - Ariën -
In het README.md bestand staat hoe je variable kunt gebruiken.
Dus zoiets, waarbij ik de categorie (en taal) uit de URL haal :
met dit :
Dus zoiets, waarbij ik de categorie (en taal) uit de URL haal :
met dit :
Code (php)
1
2
3
4
2
3
4
<?php
$categorie = 'categorie_label' . $_GET['cat'];
?>
<p>Categorie : <?php echo L($categorie); ?></p>
$categorie = 'categorie_label' . $_GET['cat'];
?>
<p>Categorie : <?php echo L($categorie); ?></p>
**quoteknip**
@Adoptive Solution. Bedankt voor de reactie. Of ik heb het verkeerd uitgelegd, of ik begrijp je verkeerd. Ik probeer met gebruik van een foreach loop een 8-tal categorieën te tonen (met bijbehorende foto's etc):
In de database had ik derhalve in het veld label, waardes als:
welke overeenkomen met de waardes in de .ini files:
Maar zoals ik al eerder aangaf werkte dat niet door de dubbele-dubbele punt. Het heeft dus niets met een url variabele ($_GET) te maken. Ik zoek naar een manier waarbij de waardes in het veld label in de database de waardes weergeven uit de .ini files
@Adoptive Solution. Bedankt voor de reactie. Of ik heb het verkeerd uitgelegd, of ik begrijp je verkeerd. Ik probeer met gebruik van een foreach loop een 8-tal categorieën te tonen (met bijbehorende foto's etc):
In de database had ik derhalve in het veld label, waardes als:
welke overeenkomen met de waardes in de .ini files:
Code (php)
1
2
3
4
5
6
7
8
9
2
3
4
5
6
7
8
9
[categorie]
label1 = "Antiek"
label2 = "Oudheden"
label3 = "Kunst"
label4 = "Curiosa"
label5 = "Instrumenten"
label6 = "Boeken"
label7 = "Platen"
label8 = "Meubelen"
label1 = "Antiek"
label2 = "Oudheden"
label3 = "Kunst"
label4 = "Curiosa"
label5 = "Instrumenten"
label6 = "Boeken"
label7 = "Platen"
label8 = "Meubelen"
Maar zoals ik al eerder aangaf werkte dat niet door de dubbele-dubbele punt. Het heeft dus niets met een url variabele ($_GET) te maken. Ik zoek naar een manier waarbij de waardes in het veld label in de database de waardes weergeven uit de .ini files
Gewijzigd op 08/10/2018 23:09:15 door - Ariën -
Of je het categorienummer uit een url haal of uit een database, het resultaat is hetzelfde.
Sla in de database de nummers (1...n) van de categorie op, vraag ze op en toon ze in de loop.
Aangenomen dat $category o.a. het categorienummer bevat :
Sla in de database de nummers (1...n) van de categorie op, vraag ze op en toon ze in de loop.
Aangenomen dat $category o.a. het categorienummer bevat :
Code (php)
Gewijzigd op 07/10/2018 21:47:49 door Adoptive Solution
Als je hier wat abstracter naar kijkt dan heb je hier gewoon een lijst van woorden (categorieën) die je achter elkaar wilt uitdraaien. Het is niet erg elegant en waarschijnlijk ook niet altijd voor de hand liggend dat zo'n lijst in alle talen dezelfde volgorde heeft, laat staan dat alle categorieën in alle talen beschikbaar zijn / op alle talen van toepassing zouden zijn.
Het is mogelijk handiger om de beschikbare categorieën en de volgorde per taal vast te leggen in de database, dan kun je vervolgens 1:1 een vertaling van een specifieke (in die taal van toepassing zijnde) categorie opsnorren?
Ik denk dat je jezelf in de problemen werkt door het op de bovenstaande manier in wezen te hardcoden en tegelijkertijd de volgorde te verankeren door het (mogelijk?) taalonafhankelijke "$categories".
Alle "administratie" voor het uitdraaien van $categories zou voor dat moment eigenlijk al gedaan moeten zijn, en niet van een taalbestand af moeten hangen door een nummering (in zekere zin hard coding?). Dit is voor de vertaling/vertaalfunctionaliteit niet relevant en zou dus daar niet bepaald moeten worden.
tl;dr trek even wat zaken uit elkaar: bepaal eerst wat er weergegeven moet worden (selectie van relevante categorieën in huidige taal) en vervolgens hoe dit zou moeten gebeuren (simpelweg een 1:1 vertaling in specifieke taal).
En zorg ervoor dat je vertaalfunctionaliteit ook uitsluitend doet waar het voor bedoeld is: enkel vertalen, zonder enige extra logica.
NB: op de bovenstaande manier creëer je daadwerkelijk een dynamische meertalige pagina.
De waarden van de labels zelf volgen toch ook vaak de vertaling van de standaardtaal en zijn niet generiek zoals "categorie_1" of wat dan ook? Bijvoorbeeld: standaard taal EN, het label voor de vertaling "meubels" in het NL is dan bijvoorbeeld "furniture", en om aan te geven dat dit een categorienaam betreft zou je bijvoorbeeld "category_furniture" o.i.d. kunnen gebruiken, of dit op een andere manier kunnen categoriseren? dit is enkel naamgeving-logica, zonder hard coding van magische nummers. Het lijkt mij dat je geen (in ieder geval geen programmeer)logica in je taalbestanden wilt stoppen :/.
Het is mogelijk handiger om de beschikbare categorieën en de volgorde per taal vast te leggen in de database, dan kun je vervolgens 1:1 een vertaling van een specifieke (in die taal van toepassing zijnde) categorie opsnorren?
Ik denk dat je jezelf in de problemen werkt door het op de bovenstaande manier in wezen te hardcoden en tegelijkertijd de volgorde te verankeren door het (mogelijk?) taalonafhankelijke "$categories".
Alle "administratie" voor het uitdraaien van $categories zou voor dat moment eigenlijk al gedaan moeten zijn, en niet van een taalbestand af moeten hangen door een nummering (in zekere zin hard coding?). Dit is voor de vertaling/vertaalfunctionaliteit niet relevant en zou dus daar niet bepaald moeten worden.
tl;dr trek even wat zaken uit elkaar: bepaal eerst wat er weergegeven moet worden (selectie van relevante categorieën in huidige taal) en vervolgens hoe dit zou moeten gebeuren (simpelweg een 1:1 vertaling in specifieke taal).
En zorg ervoor dat je vertaalfunctionaliteit ook uitsluitend doet waar het voor bedoeld is: enkel vertalen, zonder enige extra logica.
NB: op de bovenstaande manier creëer je daadwerkelijk een dynamische meertalige pagina.
De waarden van de labels zelf volgen toch ook vaak de vertaling van de standaardtaal en zijn niet generiek zoals "categorie_1" of wat dan ook? Bijvoorbeeld: standaard taal EN, het label voor de vertaling "meubels" in het NL is dan bijvoorbeeld "furniture", en om aan te geven dat dit een categorienaam betreft zou je bijvoorbeeld "category_furniture" o.i.d. kunnen gebruiken, of dit op een andere manier kunnen categoriseren? dit is enkel naamgeving-logica, zonder hard coding van magische nummers. Het lijkt mij dat je geen (in ieder geval geen programmeer)logica in je taalbestanden wilt stoppen :/.
Gewijzigd op 08/10/2018 00:25:07 door Thomas van den Heuvel
@Adoptive Solution. Dat werkt perfect. Hartelijk bedankt
Als je dan toch al in de database bezig bent, waarom houd je daar dan niet direct een vertaling bij? :/
Dit klinkt allemaal vreselijk inefficiënt, bedenk eens wat je allemaal aan het verzetten bent om enkel een categorienaam in taal X weer te kunnen geven...
Maar goed, je hebt je gram, dus je kunt verder naar je volgende klus?
Dit klinkt allemaal vreselijk inefficiënt, bedenk eens wat je allemaal aan het verzetten bent om enkel een categorienaam in taal X weer te kunnen geven...
Maar goed, je hebt je gram, dus je kunt verder naar je volgende klus?
@Thomas van den Heuvel. Ik ben niet zo enorm veel aan het verzetten hoor Thomas. Valt echt reuze mee!
Gewijzigd op 08/10/2018 22:25:32 door Donald Boers
Op zich hoeft het niet meteen in een DB, maar ik vraag me wel een beetje af waarom je je vertalingen eerst in een .ini bestand in zou voeren, en de boel dan weer door een wrapper class naar PHP files zou compileren (incl. constante check of de .ini toevallig nieuwer is dan de .php).
Zet het dan meteen in een PHP bestand en include gewoon direct het juiste bestand. Bijvoorbeeld:
nl.php
pseudo code voor ophalen vertaling (je mag er ook een mooie class van maken):
Zet het dan meteen in een PHP bestand en include gewoon direct het juiste bestand. Bijvoorbeeld:
nl.php
Code (php)
1
2
3
4
5
6
7
8
9
10
2
3
4
5
6
7
8
9
10
<?php return [
'label1' => "Antiek",
'label2' => "Oudheden",
'label3' => "Kunst",
'label4' => "Curiosa",
'label5' => "Instrumenten",
'label6' => "Boeken",
'label7' => "Platen",
'label8' => "Meubelen"
]; ?>
'label1' => "Antiek",
'label2' => "Oudheden",
'label3' => "Kunst",
'label4' => "Curiosa",
'label5' => "Instrumenten",
'label6' => "Boeken",
'label7' => "Platen",
'label8' => "Meubelen"
]; ?>
pseudo code voor ophalen vertaling (je mag er ook een mooie class van maken):
Code (php)
1
2
3
4
5
6
7
8
9
2
3
4
5
6
7
8
9
$lang = $_GET['lang'] ?? 'nl'; //of net zoiets als die getUserLangs()
$langs = ['nl','en','fr']; //ondersteunde talen, waar dus een xx.php bestand voor bestaat
if(!in_array($lang,$langs)) $lang = 'nl'; //default lang
$strs = require($lang . '.php');
function str($key){ //string ophalen (met default indien niet bestaand)
global $strs;
return $strs[$key] ?? null;
}
$langs = ['nl','en','fr']; //ondersteunde talen, waar dus een xx.php bestand voor bestaat
if(!in_array($lang,$langs)) $lang = 'nl'; //default lang
$strs = require($lang . '.php');
function str($key){ //string ophalen (met default indien niet bestaand)
global $strs;
return $strs[$key] ?? null;
}
Gewijzigd op 08/10/2018 23:54:24 door Rob Doemaarwat
Donald Boers op 08/10/2018 22:21:49:
@Thomas van den Heuvel. Ik ben niet zo enorm veel aan het verzetten hoor Thomas. Valt echt reuze mee!
Twee abstractielagen (database + (gecachede?) ini bestanden) voor iets simpels, dan is wat @Rob hierboven doet vele malen eenvoudiger en zeker meer lichtgewicht.
Ook is het stuk minder complex, wat het ook veel makkelijker maakt om te debuggen wanneer er onverhoopt iets fout zou gaan.
In plaats van een class constant L::contact_name zou je globale constanten zoals I18N_CONTACT_NAME of constanten zoals I18N\CONTACT_NAME in een eigen namespace kunnen gebruiken.
Ik gebruik zelf ook een database voor het complete translation memory (TM) plus aparte cachebestanden per taal.
Ik gebruik zelf ook een database voor het complete translation memory (TM) plus aparte cachebestanden per taal.
@Rob Doemaarwat. Als dit principe ook zonder deze Class uitgevoerd kan worden ben ik een en al oor. Ik begrijp echter niet zo goed hoe ik dit dan implementeer. Gebruikmakend van de Class wordt deze op de volgende manier aangeroepen:
$i18n = new i18n(APP_PATH.'/lang/lang_{LANGUAGE}.ini', APP_PATH.'/langcache/', 'nl');
$i18n->init();
Met de manier zoals geformuleerd door @Adoptive Solution kan ik de Class zowel met als zonder database. Hoe zou het werken met database in jou voorbeeld opgaan?
@Ward van der Put. Een heleboel informatie, die ik vandaag eens rustig ga verwerken en doornemen. Hartelijk bedankt voor de input
@Thomas van den Heuvel. Het is niet zo zeer dat ik niet begrijp dat het een en ander beter in de database gedefinieerd kan worden want voor de rest van de site in kwestie gebeurt dat al door middel van een veld(`lang` char(2) NOT NULL) in de verschillende tafels. Het is meer dat ik wilde weten of ik deze class op een efficiënte manier zou kunnen gebruiken waarbij mij is opgevallen dat het voor losse fragmenten een handige class zou kunnen zijn zijn. Echter de methode van @Rob Doemaarwat spreekt me ook zeer aan
Code (php)
1
2
3
2
3
$i18n = new i18n(APP_PATH.'/lang/lang_{LANGUAGE}.ini', APP_PATH.'/langcache/', 'nl');
$i18n->init();
Met de manier zoals geformuleerd door @Adoptive Solution kan ik de Class zowel met als zonder database. Hoe zou het werken met database in jou voorbeeld opgaan?
@Ward van der Put. Een heleboel informatie, die ik vandaag eens rustig ga verwerken en doornemen. Hartelijk bedankt voor de input
@Thomas van den Heuvel. Het is niet zo zeer dat ik niet begrijp dat het een en ander beter in de database gedefinieerd kan worden want voor de rest van de site in kwestie gebeurt dat al door middel van een veld(`lang` char(2) NOT NULL) in de verschillende tafels. Het is meer dat ik wilde weten of ik deze class op een efficiënte manier zou kunnen gebruiken waarbij mij is opgevallen dat het voor losse fragmenten een handige class zou kunnen zijn zijn. Echter de methode van @Rob Doemaarwat spreekt me ook zeer aan
Als die i18n class alleen maar wordt gebruikt om de naam van een categorie uit een ini bestand te halen, lijkt het me dat je dat ini bestand ook kan omzetten naar een array om vanuit daar verder te gaan.
Code (php)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
<?php
// voorbeeld url : categories.php?lang=nl&cat=label4
// kan ook uit DB worden gehaald
$lang = $_GET['lang'];
$cat = $_GET['cat'];
// parse_ini_file = FALSE
$categories = parse_ini_file( "lang/lang_". $lang . ".ini" , FALSE );
echo '<pre>';
print_r($categories);
echo '</pre>';
echo '<p>Categorie is : ' . $categories[$cat] . '</p>';
// parse_ini_file = TRUE
$categories = parse_ini_file( "lang/lang_". $lang . ".ini" , TRUE );
echo '<pre>';
print_r($categories);
echo '</pre>';
echo '<p>Categorie is : ' . $categories['categorie'][$cat] . '</p>';
?>
// voorbeeld url : categories.php?lang=nl&cat=label4
// kan ook uit DB worden gehaald
$lang = $_GET['lang'];
$cat = $_GET['cat'];
// parse_ini_file = FALSE
$categories = parse_ini_file( "lang/lang_". $lang . ".ini" , FALSE );
echo '<pre>';
print_r($categories);
echo '</pre>';
echo '<p>Categorie is : ' . $categories[$cat] . '</p>';
// parse_ini_file = TRUE
$categories = parse_ini_file( "lang/lang_". $lang . ".ini" , TRUE );
echo '<pre>';
print_r($categories);
echo '</pre>';
echo '<p>Categorie is : ' . $categories['categorie'][$cat] . '</p>';
?>
Gewijzigd op 10/10/2018 13:45:20 door Adoptive Solution
Volgens mij staat alles hierboven. Ipv uit de $_GET haal je je actieve taal gewoon uit je cookie van je vorige vraag, dus dan wordt het (en ik zou je vertaal bestanden in een aparte map zetten, dus translations/nl.php, enz):
Met bovenstaande ergens in je algemene initialisatie code kun je dan je vertalingen ophalen via:
Code (php)
1
2
3
4
5
6
7
8
9
2
3
4
5
6
7
8
9
$lang = $_COOKIE["language"] ?? 'nl';
$langs = ['nl','en','fr']; //ondersteunde talen, waar dus een xx.php bestand voor bestaat
if(!in_array($lang,$langs)) $lang = 'nl'; //default lang
$strs = require("translations/$lang.php");
function str($key){ //string ophalen (met default indien niet bestaand)
global $strs;
return $strs[$key] ?? null;
}
$langs = ['nl','en','fr']; //ondersteunde talen, waar dus een xx.php bestand voor bestaat
if(!in_array($lang,$langs)) $lang = 'nl'; //default lang
$strs = require("translations/$lang.php");
function str($key){ //string ophalen (met default indien niet bestaand)
global $strs;
return $strs[$key] ?? null;
}
Met bovenstaande ergens in je algemene initialisatie code kun je dan je vertalingen ophalen via:
Gewijzigd op 10/10/2018 15:20:29 door Rob Doemaarwat
@Rob Doemaarwat. Ik begrijp het. Hartelijk bedankt voor alle input. Andere leden trouwens ook bedankt




