[php] Strings buiten code (voor vertalingen). Hoe optimaal?

Pagina: 1
Acties:

Onderwerpen


Acties:
  • 0 Henk 'm!

  • mahi
  • Registratie: Juni 2001
  • Laatst online: 22-09-2020

mahi

God bless GoT

Topicstarter
Hoi mensen,

Weer een onduidelijke topictitel, maar ik ben slecht in het samenvatten van een probleem op zo'n klein stukje :)

Ik ben al twee dagen aan het ploeteren door de Got search en andere sites, maar ik kom niet tot een duidelijk antwoord. Wat is m'n probleem?

Ik heb een PHP-site. Wat ie doet is niet van belang want alles werkt perfect. Nu heb ik de site zo opgezet dat vertalingen eenvoudig zijn door alle strings die tekstuitvoer op het scherm geven in een apart bestand op te slaan - buiten de code dus. Wil je een andere taal, dan moet dus gewoon dat bestand vertaald worden.

Voorlopig werk ik als volgt. In de configuratie van m'n scripts staat:
PHP:
1
define("LANGUAGE_FILE", "nederlands.lang");
De constante LANGUAGE_FILE bevat dit aparte bestand met alle taalafhankelijke strings. Het bestand nederlands.lang heeft een opbouw als volgt (vereenvoudigd voorbeeld omdat het om vele honderden strings gaat):
PHP:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
$language_string = array(
    "main_page" => array(
        "title" => "Mijn Site",
        "intro" => "Welkom op mij site blah blah",
        "member" => "U bent ingelogd"
    ),
    
    "user_page" => array(
        0 => "Overzicht van de gebruikers op deze site.",
        1 => "Administrator",
        2 => "Nieuwsposter",
        3 => "Gast"
    )
);
Het bestand nederlands.lang wordt met een require opgenomen in de PHP code zodat de variabele $language_string eigenlijk een globale variabele is. Met de functie GetLanguageText kan ik dan van eender waar in m'n code teksten ophalen:
PHP:
1
2
3
4
GetLanguageText($pagina, $string) {
    global $language_string;
    return $language_string[$pagina][$string];
}
Dus als ik ergens in m'n code bijvoorbeeld GetLanguageText("user_page", 1) oproep, dan krijg ik de string "Administrator" terug.

Dat werkt allemaal fijn, maar is niet het probleem... Het probleem is dat $language_string een globale variabele is. Ik zit nu al 2 dagen te zoeken naar een definitief antwoord op de vraag: is de methode die ik gebruik goed? Sommigen vinden het gebruik van globale variabelen geen enkel probleem terwijl anderen al beginnen te schuimbekken bij het horen ervan. Of is m'n methode al fundamenteel verkeerd? Voor de rest gebruik ik geen globale variabelen. Ik begrijp wat sommigen ertegen hebben en probeer ze zoveel mogelijk te vermijden (voor de configuratievariabelen gebruik ik constanten), maar ik weet niet goed hoe ik het hier moet aanpakken. Alles in een functie? Maar dan moeten al die honderden strings telkens weer opnieuw worden ingelezen als die functie aangeroepen wordt terwijl ze nu in het begin éénmaal in de globale variabele worden opgeslagen.

Hoe zouden jullie dit aanpakken?

A bus station is where a bus stops. A train station is where a train stops... On my desk I have a workstation.


Acties:
  • 0 Henk 'm!

  • .oisyn
  • Registratie: September 2000
  • Laatst online: 03:42

.oisyn

Moderator Devschuur®

Demotivational Speaker

niets mis met globale variabelen hoor, je moet ze alleen niet overal her en der neerpleuren :)
Beetje een ordening erin, bijvoorbeeld door ze te prefixen met "global_", of ze in een structure (class) te plaatsen die bijvoorbeeld $globals heet oid (hoewel dat weer verwarrend is met $_GLOBALS)

Give a man a game and he'll have fun for a day. Teach a man to make games and he'll never have fun again.


Acties:
  • 0 Henk 'm!

  • Rataplan
  • Registratie: Oktober 2001
  • Niet online

Rataplan

per aspera ad astra

Ik zou idd geen globale variabelen gebruiken.

Twee alternatieven:
(1) locale variabelen "static" binnen GetLanguageText definieren (ik weet niet zeker of dit je performanceprobleem oplost) of
(2) je data in een database gooien, en alleen die waarden ophalen die je nodig hebt. Da's iig de optie die ik zou gebruiken.

Eventueel zou je ook met templates kunnen gaan werken, maar dat zal wel een complete rewrite van je site vereisen, dus dat zal wel geen oplossing zijn...

[ Voor 9% gewijzigd door Rataplan op 05-09-2003 17:01 ]


Journalism is printing what someone else does not want printed; everything else is public relations.


Acties:
  • 0 Henk 'm!

  • Prozaq
  • Registratie: Juni 2000
  • Laatst online: 12-08 09:47
Kijk hier eens naar:

http://php.net/gettext

Acties:
  • 0 Henk 'm!

  • sjroorda
  • Registratie: December 2001
  • Laatst online: 19-09 11:05
Zelf zou ik het idd ook global doen, scheelt zoals je zelf al zegt een hoop definities inlezen elke keer dat je iets aanroept
Daarnaast zou ik de verschillende pagina's in aparte textfiles zetten; zo is het aantal in te lezen variabelen klein, en gebruik je (dus) minder geheugen, en gaat het daarbij sneller. Wat wil je nog meer ;).

Acties:
  • 0 Henk 'm!

  • djluc
  • Registratie: Oktober 2002
  • Laatst online: 13:12
Rataplan schreef op 05 September 2003 @ 16:59:
je data in een database gooien, en alleen die waarden ophalen die je nodig hebt. Da's iig de optie die ik zou gebruiken.

Eventueel zou je ook met templates kunnen gaan werken, maar dat zal wel een complete rewrite van je site vereisen, dus dat zal wel geen oplossing zijn...
Het mooie aan templates is net dat je een scheiding kunt maken tussen code en opmaak. Het voordeel is echter ook dat je de data weer kunt scheiden door die in een database te plaatsen.

Als je meerdere templates maakt omdat je verschillende talen hebt ben je volgens mij verkeerd bezig.

Ik zou alle tekst in een db zetten, die je dan naar een template parsed. Dan maak je een functie waarmee je 1x alle data uit uit de db haalt en in een lokale variable zet. Dit kun je natuurlijk op basis van taal doen.

De functie kun je aanroepen met bijvoorbeeld
PHP:
1
$tpl->assign('naamintpl', textfunction('KEYWORD vh tekstelement.'));


De data in de database kun je natuurlijk erg goed beheersen met een CMS, wat wel handig is als je zoveel teksten in verschillende talen hebt.

[ Voor 13% gewijzigd door djluc op 05-09-2003 17:19 ]


Acties:
  • 0 Henk 'm!

  • JaQ
  • Registratie: Juni 2001
  • Laatst online: 20-09 16:59

JaQ

ik ben nu zelf bezig met een applicatie waarin ik de labels van velden, error messages, form validaties en form layout in tabellen heb gezet. Vervolgens gebruik ik een class die messages ophaald (en de language_id zet ik dus weg in de sessie variabelen, samen met user_id die ik weer gebruik voor autorisatie truckjes).

Een array met messages raad ik je ten zeerste af, eigenlijk voornamelijk omdat het zo ontzettend onoverzichtelijk wordt. (kijk voor de grap eens naar phpaga bijvoorbeeld. het "locale' filetje is 30k)

Egoist: A person of low taste, more interested in themselves than in me


Acties:
  • 0 Henk 'm!

  • wustenveld
  • Registratie: Februari 2002
  • Laatst online: 07-07 13:36
Ik gebruik ook van die taalbestanden, maar ik gooi geen teksten in variabelen maar in constanten.

Bijvoorbeeld
PHP:
1
2
3
4
define('title',"Mijn Site");
define('intro',"Welkom op mijn site blaat");
define('member',"Lid");
define('guest',"Gast");


Op deze manier kan ik mijn tekstuitvoer vanuit elke plek in m'n applicatie benaderen.

Acties:
  • 0 Henk 'm!

  • djluc
  • Registratie: Oktober 2002
  • Laatst online: 13:12
Maar hoe wil je dat een beetje praktisch gaan beheren? Dan zul je steeds gebruik moeten maken van een tekste3ditior. Dan zou ik echt eerder voor een db gaan. Die kun je vanuit een functie zoals eerder beschreven eenvoudig gebruiken.

Acties:
  • 0 Henk 'm!

  • stekkel
  • Registratie: Augustus 2001
  • Laatst online: 17-09 08:05
IMHO ook de beste oplossing. Voor SquirrelMail gebruiken we het ook en daar ondersteunen we 39 talen en dat allemaal met behulp van gettext.

Wanneer je een internationale string opneemt dan is het een kwestie van de strings zo te programmeren:

$blah = _("This is an international string");

De string definities stop je in een .po file waar je een .mo db van maakt wordt en klaar is kees.

gettext doet de rest en je hebt ook geen gezeik met templates aangezien je gewoon $blah als template var kan gebruiken.

Acties:
  • 0 Henk 'm!

Verwijderd

Ik gebruik de parse_ini_file functie om een "ini" achtige language file in te lezen

Acties:
  • 0 Henk 'm!

  • mahi
  • Registratie: Juni 2001
  • Laatst online: 22-09-2020

mahi

God bless GoT

Topicstarter
Bedankt voor jullie antwoorden!

Die gettext ziet er iets interessants uit. Ik ben nu een tutorial erover aan het lezen. Moet ik straks eens uitvissen hoe ik m'n eigen taalbestanden kan omzetten naar de .po en .mo bestanden.

A bus station is where a bus stops. A train station is where a train stops... On my desk I have a workstation.


Acties:
  • 0 Henk 'm!

Verwijderd

Ik doe het met een include file
PHP:
1
<?php include("language.txt"); ?>

file:
PHP:
1
2
3
<?php
$L_english_name_var = "Nederlands Woord" ;
?>

Hierdoor hoeft er alleen een ander txt file gemaakt te worden.
Ik ben een Newby, maar dit leek mij handig?

[ Voor 24% gewijzigd door Verwijderd op 06-09-2003 16:10 ]


Acties:
  • 0 Henk 'm!

Verwijderd

Je kan ook voor de OO versie van globale variabelen kiezen: singleton classes (i.e. classes die maar 1 instantie hebben).

code:
1
2
3
4
5
6
7
8
9
10
11
12
class MyClass {
    /* get the one instance of MyClass */
    function &getInstance() {
      static $instance = NULL;

      if( !$instance ) {
        $instance = new MyClass();
      }

      return $instance;
    }
}


en waar nodig deze oproepen:

code:
1
2
  $myclass =& MyClass::getInstance();
  $myclass->functie();


voordeel: afscherming door OO.
nadeel: de instance moet steeds opgezocht worden (MyClass::getInstance() moet eerst steeds aangeroepen worden). Dit komt overigens mede door een defect in het ontwerp van PHP4: MyClass::getInstance()->functie() kan niet geparsed worden. Misschien ooit in PHP5 wel :)

Acties:
  • 0 Henk 'm!

  • chem
  • Registratie: Oktober 2000
  • Laatst online: 19-09 22:18

chem

Reist de wereld rond

gettext is toch echt de standaard hiervoor. React maakt er ook gebruik van voor de error-meldingen, en icm sprintf() kan de vertaler zelfs variabelen plaatsen (en op de juiste plek).

Klaar voor een nieuwe uitdaging.


Acties:
  • 0 Henk 'm!

Verwijderd

mmM dat wou ik ook al eens eerder op mijn site hebben, zijn er goede info sites over?
want misschien dat ik het dan kan proberen.

Ik snap ongeveer hoe dat met vertalen werkt maar nog niet hoe je het op je site moet krijgen

Acties:
  • 0 Henk 'm!

  • Apache
  • Registratie: Juli 2000
  • Laatst online: 16-09 10:29

Apache

amateur software devver

If it ain't broken it doesn't have enough features


Acties:
  • 0 Henk 'm!

  • mahi
  • Registratie: Juni 2001
  • Laatst online: 22-09-2020

mahi

God bless GoT

Topicstarter
Toch nog een vraagje over gettext... Wanneer ik de text strings uit m'n php bestanden wil halen dan krijg ik een waarschuwing dat xgettext geen PHP ondersteunt. Bijvoorbeeld:

xgettext: warning: file `public_html/index.php' extension `php' is unknown; will try C

Voorlopig lijkt het te werken, zelfs met die foutmelding, maar in de tutorials die ik tot nu toe heb gelezen werd er nooit iets gezegd van eventuele foutmeldingen. Ik denk dan ook dat het niet normaal is dat ik die fout krijg. Waarschijnlijk moet ik nog ergens iets instellen, maar wat en waar?

A bus station is where a bus stops. A train station is where a train stops... On my desk I have a workstation.


Acties:
  • 0 Henk 'm!

  • djluc
  • Registratie: Oktober 2002
  • Laatst online: 13:12
Waarom zet je ze dan niet in een bestand met een andere extentie?

Acties:
  • 0 Henk 'm!

Verwijderd

Ik heb het gedaan dmv een xml file. Je geeft per node een module aan, of het labels zijn, tooltips, acties, meldingen etc.

Deze xml bestanden worden eenmaal ingelezen, in server memory geplaatst, en zodoende direct uit memory gelezen ipv telkens i/o verkeer te veroorzaken.

Tevens wordt er bij deze actie een datemodified opgeslagen, van de hoogst aanwezige file.datemodified bij de bestanden, en wordt er opnieuw geparsed naar memory als er een hogere datemodified wordt aangetroffen dan is opgeslagen.

Een retesnelle methode iig.
Pagina: 1