Hårdkodede tekster blokerer for danske versioner
Der er flere måder at sprog-versionere software på. Programmørerne kan enten vælge at hardcode tekststrenge direkte ind i kildekoden eller lave en eller flere eksterne filer, som indeholder teksterne. Den sidste metode gør det væsentligt nemmere at oversætte en engelsksproget applikation til eksempelvis dansk.
Alligevel er flere, typisk kommercielle applikationer, opbygget efter det første princip - altså med hardcodede tekststrenge i selve kildekoden, fortæller administrerende direktør i IT-Quality Mads N. Madsen til Version2.dk.
»Vi møder det rigtigt meget i Danmark, at produkterne ikke har dansk. Og hvis nogen af de store kunder så gerne vil have dansk-understøttelse, så skal producenten til at lave det om, og det koster dem flere hundrede tusinde. Og når du så laver en opdatering, så virker det ikke igen,« siger han.
Ifølge Mads N. Madsen er det ofte visse kommercielle produkter, der halter bagefter, når det kommer til fleksibilitet i forhold til sprogudvidelse, mens open source-produkterne typisk er lettere at oversætte, fordi de kommer med seperate tekststrenge.
»Jeg tror, det er et udbredt problem i de europæiske lande, hvor man ikke taler engelsk. Men jo større landene er, jo mere har man taget højde for det fra starten af. Frankrig er nok ikke så hårdt ramt,« siger han og tilføjer:
»Vi ser det i hvert fald med nogle af de kommercielle produkter, som vi har med at gøre. Der er produktet simpelthen hardcoded til fransk, spansk, engelsk og tysk. Men så kommer alle de andre lande, som eksempelvis de skandinaviske.«
Hovedproblemet ved hardcodede strenge er ifølge Mads N. Madsen, at det er nødvendigt at rekompilere kildekoden med de nye strenge, det vil sige, at man skal til at være programmør. Hvorimod når det gælder produkter med eksterne strenge, så kan alle og enhver i princippet give sig i kast med at oversætte produktet.
»OpenOffice findes jo i gode danske versioner, det fungerer rigtigt godt,« siger han.
Mads N. Madsen undrer sig desuden over, hvorfor der overhovedet er nogen, som vælger at hardcode tekststrengene ind i kildekoden.
»Lige præcis her er der simpelthen ikke nogen omkostning forbundet med det, hvis de (udviklingshusene, red.) gør det rigtigt fra starten af. De kan stadig godt begrænse sig til rent engelsk, men de har lavet et framework, der supporterer sprog,« siger han.
Hvad mener du? Er du enig med Mads N. Madsen, eller er det lettere sagt end gjort at kode software, som er let at udbygge med sprogunderstøttelse? Giv din mening til kende i debatten herunder.
Kommentarer (35)
Det er et hestearbejde, uanset hvilken metode det er man har valgt. Du kan ikke bare tage en/flere fil(er) med alle tekst værdier og så oversætte fra en ende til en anden, du vil løbe ind i en række problemer.
1. Med din tunge kan man ikke formulere sig så kort som det originalle sprog. Det er gangske simpelt ikke sikkert at der er plads til din lange tekst.
2. Det modsatte, dine forms kan komme til at se åndsvage ud.
3. Kontexten er vigtig, ord oversættes ikke altid 1 til 1, og ude af kontekst kan du vælge det forkerte ord.
4. Nogle projekter bruger maskineoversættelser - resultatet er forståeligt, men ser ikke prof ud.
Jeg er dog enig i at have det som en eksern fil er lang nemmere.
Det ville være lettere hvis programmeringssproget havde support for oversættelse indbygget, fx skulle en streng i et program som hovedregel føre til at der oprettedes en fil med oversættelige strenge. Hvis tekststrengen var uoversættelig skulle man gøre noget specielt.
I open source verdenen findes der standardrutiner til at markere strenge til oversættelse i programmer, (gettext) og standardværktøjer til administration af oversættelse med diverse hjælp til oversætterne med programmerne kbabel og gtranslator. På dansk har vi en ordliste med anbefalede oversættelser af engelske ord til dansk på http://www.klid.dk/dansk/ordlister/ordliste.html
1. Med din tunge kan man ikke formulere sig så kort som det originalle sprog. Det er gangske simpelt ikke sikkert at der er plads til din lange tekst. 2. Det modsatte, dine forms kan komme til at se åndsvage ud. 3. Kontexten er vigtig, ord oversættes ikke altid 1 til 1, og ude af kontekst kan du vælge det forkerte ord.
Er punkt 1 og 2 ikke passé for mange år siden? Det har det da været i mindst 8 år i open source verdenen, men jeg kan da godt huske at det var et problem med MFC da jeg programmerede sådan noget for 3-4 år siden.
Punkterne er ikke nødvendigvis problemer. Der findes minimum et framework der tager hensyn til alle disse problemer - og det er Qt. For lange strenge opstår ikke - det sørger layout manageren for og konteksten for stregen er simpelthen en del af oversættelsesnøglen i .ts filerne. Qt ligger til grund for KDE som groft taget står for halvdelen af de kendte "store" open source applikationer, derfor er jeg nok nød til at give Mads N. Madsen ret i at problemet ikke er lige så stort i open source verdenen og en hver som har haft Linux installeret på sin PC ved da også at stort set alle programmer er oversat til dansk og de fleste er endda godt oversat.
Jeg kan ikke huske hvordan det forholder sig med GTK baserede programmer (Gnome) men der er måske en anden der vil støde til?
/ Jakob
Er punkt 1 og 2 ikke passé for mange år siden?
For lange strenge opstår ikke
- OK. Tell me more :)
Fra ordlisten
ambiguous *flertydig, tvetydig
:) (Ja, * har en betydning, men jeg syntes stadig den er lidt sjov)
Dine problemer med 1&2 opstår kun, hvis du har lavet den anden del af fejlen: Dit UI har hardcodede størrelser til knapper, tekst-feedback o.s.v.
Der er adskillige best-practice dokumenter med hensyn til at holde en GUI applikation klar til oversættelser.
Mit største problem (både som udvikler og bruger), er at alt, ALT for mange applikationer stadig ikke kan finde ud af Unicode. Internationale karakterer burde være et løst problem for 15 år siden, også på tværs af systemer...
Dine problemer med 1&2 opstår kun, hvis du har lavet den anden del af fejlen: Dit UI har hardcodede størrelser til knapper, tekst-feedback o.s.v.
Klart, fik nok ikke understreget at jeg mener at ens UI kan komme til at se latterlig ud, specielt et problem for folk som jeg der i forvejen ikke har nogen æstetisk sans.
- OK. Tell me more :)
Jamen der er faktisk ikke så meget mere at fortælle. Som Dennis Krøger skitserer så bestemmer layout manageren størrelsen på knapper lables osv. vha. size-hints, man kan også resize sine forms under programafviklingen.
Konteksten er virkelig ikke noget problem for som regel er man grundig med at sende forståelsen af strengen med over til oversætteren via kontekst strengen.
- se doc.trolltech.com under linguist, hvis du vil vide mere.
/ Jakob
...specielt et problem for folk som jeg der i forvejen ikke har nogen æstetisk sans.
Se DET kender jeg udemærket, hvorfor jeg generelt også klamrer mig til best-practice og HIG dokumenter når jeg bliver tvunget til at rode mig ud i GUI apps. ;)
- Forøvrigt bliver dit punkt 3 også oftest formindsket af best-practice, ved at man, så vidt som muligt, undgår at stykke sætninger sammen, men istedet lader oversættelsen bestemme hvor de enkelte ord skal placeres. F.eks. (med Java .properties):
en_US
server_error = Received error code {0} from the server {1}
da_DK:
server_error = Serveren {1} har meldt fejlkode {0}
(Nope, der er ikke rigtig nogen grund til at det skal være omvendt på dansk, det var mest for eksemplet)
Jeg ved ikke med andre sprog/teknologier, men i .NET-verdenen er det temmelig nemt at skifte sprog. Hvis man anvender CultureInfo og ResourceManager sammen med satellite assemblies, kan man nemt styre sproget i en applikation.
Jeg ser selvfølgelig lige kort bort fra arbejdet med at vedligeholde forskellige assemblies med oversættelserne, og med lange tekster, som specielt er et problem med f.eks. finske tekster på en PDA-applikation.
On topic:
Jeg har flere gange set projekter, hvor man af "tidshensyn" har udskudt f.eks. localization og sikkerhed (logon, rettigheder etc.) til senere, bland andet med begrundelsen "vi skal hurtigt i gang, og have noget at fremvise". Det er en uskik - der er altså ting man ikke kan komme uden om. Har vi udviklere virkelig så dårlig kollektiv hukommelse at vi ikke kan huske de problemer det skaber, at noget så grundlæggende ikke er på plads fra starten? Ja, for det kan vel ikke være dovenskab - arbejdsmængden stiger jo længere vi venter med at få sådanne fundamenter på plads...
(Billedet er paa forsiden af version2.dk lige nu - her paa selve artiklen kan man ikke se det).
Hvis jeg ikke tager meget fejl, er billedet til denne artikel fra forsiden af Paul Grahams bog "Hackers & Painters".
Det er ioevrigt en bog, jeg varmt kan anbefale, men hvad i alverden har den med denne artikel at goere??
Det er et meget berømt billede af Bruegel. Som bekendt blev det sprogforvirring, der fældede det berømte tårn på billedet. Jeg gætter på, at det er sammenhængen.
Mvh Tania Andersen
Babeltårnet :) Herren blev sur over at de kunne alt fordi de havde et tungemål, derfor forvirrede han dem lidt.
Hårdkodede???
Jeg har igennem et par år stået for alt hvad der havde med oversættelser at gøre, på Syllable, og jeg har faktisk selv klargjort over 90% af softwaren til oversættelse.
Hvis systemet er opbygget bare nogenlunde fornuftigt, så er det intet problem overhovedet, at understøtte flere sprog fra starten af. Er det ordentligt opbygget, ja så er det faktisk ikke engang noget problem at opdatere gammelt enkelt-sproget software...
At der er folk der i ramme alvor kan mene at gettext er godt, går ud over min forstand... Eller er det fordi man har løst problemet, med at man antager at alle forekomster af en tekst-streng, altid skal oversættes til det samme?
At der er folk der i ramme alvor kan mene at gettext er godt, går ud over min forstand... Eller er det fordi man har løst problemet, med at man antager at alle forekomster af en tekst-streng, altid skal oversættes til det samme?
Gettext bruger markers, der samtidig kan bruges som almindelige strenge, indtil man har fået lavet sine oversættelsesfiler. Man bruger så et værktøj til at skanne sourcekoden og lave en skabelon til oversættelserne.
Temmeligt praktisk, efter min mening.
Hvorfor ialverden skulle man indsætte samme streng flere steder, hvis det ikke er planen at alle forekomster skal oversættes til det samme? Eller misforstår jeg dig?
Jeg kan naturligvis tage fejl, men...
Hvis du har to forekomster af strengen "Save", så vil gettext gå ud fra at de begge to skal oversættes til det samme. Altså på dansk skal de begge oversættes til "Gem". Det er ikke nødvendigvis tilfældet, hvis det er Russisk, Hindi, eller Japansk. Problemet er så, at den ene forekomst af "Save" handler om at gemme et billede, mens den anden måske gemmer indstillinger.
...eller tager jeg helt fejl?
Hvis du stykker oversættelser af enkeltord sammen til sætninger, gør du noget helt grundlæggende forkert.
Du kan ikke regne med at rækkefølgen er den samme på forskellige sprog.
I de tilfælde hvor du skal lave lister, o.lign., hvor et enkelt eller få ord skal være headers, gør du en anden fejl, hvis du bruger samme ord som "marker" til forskellige ting.
- Du SKAL ikke bruge almindelige sætninger for at bruge gettext, at man kan bruge sætninger som markers, er kun en hjælp til at komme hurtigt igang.
Jeg ved ikke hvor meget du kender gettext, men gettext skanner ikke bare en almindelig applikation, og laver templates ud fra dem, almindeligvis markerer man selv "oversætbare" strenge ved at bruge kommandoen _().
C eksempel tyvstjålet fra Wikipedia:
Et eller andet sted i .c-fil:
printf(_("My name is %s.\n"), my_name);
.pot-fil (Automatisk generet af gettext fra c-source).
#: src/name.c:36
msgid "My name is %s.\n"
msgstr ""
Denne laves om til en .po-fil: (Helst af en der kan sproget ;)
#: src/name.c:36
msgid "My name is %s.\n"
msgstr "Je m'appelle %s.\n"
Det kunne aldrig falde mig ing at gøre noget så perverst, men faktum er at mange tekst strenge består af 1-3 ord, og hvis de ikke håndteres korrekt, kan kan du lige så godt smide det hele i den binære affaldskværn.
Samme eksempel, men på Syllable:
Et eller andet sted i source-fil:
printf(MSG_EXAMPLE_MYNAME.c_str(), my_name);
Indsæt i .cat-fil (kræver lidt mere arbejde, da den laves manuelt):
MSG_EXAMPLE_MYNAME My name is %s.\n"
Denne oversættes så:
MSG_EXAMPLE_MYNAME Mit navn er %s.\n"
Herefter laves den om til en .catalog-fil, med catcomp eller CatFish, og kan tilføjes som en resource.
Ha ha, tak for forklaringen Tania og Martin! Min bibelkundskab er væsentligt ringere end de flestes ;-)
Det er jo nøjagtigt det samme, forskellen er bare at man med gettext kan (ikke SKAL) bruge almindelige ord og sætninger som placeholders, indtil man har fået lavet .po filerne.
Hvis man bruger samme ord som placeholder for to forskellige ting, er man selv ude om det. (Jeg mener også at gettext advarer en, men jeg er ikke sikker).
Hvis de samme ord skal oversættes forskelligt med gettext, ja så må man markere det med nogen ekstra information. Standard er at hvis der er flere tekster som er ens, så administrerer gettext det i .po-flierne som én tekst, hvilket jo også er hensigtsmæssigt.
Gettext kan godt finde ud af at lave om på argumenternes rækkefølge, man angiver bare hvilket argiment der skal bruges i oversættelsen med $<argumentnummer>
Er det ikke kun farven der har en anden lyd i alle de eksempler der er nævnt her?
Hvorfor er det ikke første gang jeg ser finsk nævnt som warstory i debatter om dette emne?
Er det ikke kun farven der har en anden lyd i alle de eksempler der er nævnt her?
Du har helt ret i at, der ikke er den store forskel på de forskellige i18n frameworks. Nogen har så åbenbart alligevel en eller anden idé om at farven på deres lyd er meget bedre end de andres.
Det vigtige er hvordan man anvender det, ikke så meget hvad man anvender. Det dikteres alligevel ofte af sprog, system eller framework.
Jeg ved ikke hvad der er med finsk. Det skrives åbenbart meget langt :)
Til gengæld; Hvad er det med folk der altid skal opfinde deres eget, obskure sprog system? Jeg har efterhånden set MANGE applikationer, der absolut skal opfinde den dybe tallerken igen.
Interessant debat. Jeg har arbejdet i et par forskellige it-firmaer og det har altid undret mig hvorfor man ikke har focus på dette. Og undskyldninger er der: Det behøver vi ikke, det skal kun være det her sprog, det er besværligt osv. Samme som fremgår af tidligere tråde. Men hov om man skal have understørrelse af 1 eller 2 sprog, det er da lige meget hvad nu hvis man laver en skvrie fjel som her :) "skrive fejl". Skal man virkelig rekompilere hele sin applikation for at rette så sølle en fejl, som smutter med ud ind imellem? nej vel!. Derfor indfør nu den ressource styring og som en gylden regl når man skal forklare noget undlad nu "but.....", just do IT :)
Hvis man bruger samme ord som placeholder for to forskellige ting, er man selv ude om det. (Jeg mener også at gettext advarer en, men jeg er ikke sikker).
Et eksempel, jeg plejer at hive frem i sådan en debat som denne er det engelske "Submit".
En englænder/amerikaner vil formentlig bruge "Submit" som tekst til en knap på en formular. Han/hun vil ikke vide, at vi på dansk formentlig vil foretrække "Send" i visse tilfælde, "Gem" i andre og "Fortsæt" i endnu andre tilfælde - på engelsk kan "Submit" bruges i rigtig mange sammenhænge.
Så jeg mener ikke, man "selv er ude om det" for den originale programmør VED ikke, at det er to forskellige betydninger.
Hvis det er to forskellige ting, er det to forskellige ting, uanset om man ville bruge samme ord for det, eller ej.
Det lyder så også lidt forkert at bruge submit til så mange forskellige ting på engelsk.
- Det ændrer selvfølgelig ikke noget, der er mange tilfælde hvor det er almindeligt at bruge samme ord, men man bliver altså nødt til at holde sig for øje at det er brugt til forskellige ting/situationer. Hvis det endeligt er, er det ikke så slemt at ændre, hvis en oversætter brokker sig.
Hvis det er to forskellige ting, er det to forskellige ting, uanset om man ville bruge samme ord for det, eller ej.
På alle sprog?
Min pointe er, at der kan opstå situationer, hvor man ville se det som en ting på et sprog og som to forskellige ting på et andet.
Hvis gettext har en løsning på dette problem er jeg nysgerrig efter at lære den at kende.
Og så skal jeg måske understrege, at jeg er helt enig i, at det er nemmere at lave understøttelse for flere sprog fra starten end at lægge det ovenpå bagefter - det er kun en diskussion om hvilken teknologi, man vil benytte.
Mit største problem (både som udvikler og bruger), er at alt, ALT for mange applikationer stadig ikke kan finde ud af Unicode. Internationale karakterer burde være et løst problem for 15 år siden, også på tværs af systemer...
Se jeg synes at Dennis har fat i noget endnu mere vigtigt her, nemlig hele forbistringen omkring tegnsæt.
For hvor er det dog hamrende irriterende at skulle ty til fiksfakserier for at være sikker på at en applikation virker på tværs af systemer.
En anden ting der er drønende irriterende er at de tåbelige amerikanere ikke kan finde ud af at bruge komma, så man er tvungen til at lave inputvalidering - giver en frygtelig masse bøvl.
For ikke at tale om datoformater, samt den tåbelige ide at bruge komma som separator i en SQL sætning, i stedet for at bruge en specialkarakter der ikke var risiko for blev benyttet af vanvare.
Og hvorfor er telefontastaturer omvendt fra regnemaskinetastaturer osv. osv.
Lad os starte med at få sådan nogle ting på plads, det er langt mere alvorligt IMO.
/Christian
En englænder/amerikaner vil formentlig bruge "Submit" som tekst til en knap på en formular. Han/hun vil ikke vide, at vi på dansk formentlig vil foretrække "Send" i visse tilfælde, "Gem" i andre og "Fortsæt" i endnu andre tilfælde - på engelsk kan "Submit" bruges i rigtig mange sammenhænge.
Godt eksempel, og de fleste systemer skal oversætteren så kigge i en fil hvor man se en tekst i dur med
TEXTVAL_SUBMIT=submit
hvad dælen skal man skrive som dansker på den plads, en ting er hvis man kunne se formen, men tekst filerne er ikke til stor hjælp altid.
I .NET som er mit domæne er der råd for dette. På ressource styring har man mulighed for at knytte en kommentar. Dvs. hvis man kan trække den med ud så er det vel én løsning på problemet.
På alle sprog? Min pointe er, at der kan opstå situationer, hvor man ville se det som en ting på et sprog og som to forskellige ting på et andet.
Hov undskyld, så ikke dit andet indlæg før nu.
Det der er vigtigt her, er om man bruger det på to forskellige måder. Hvis det ikke er helt standard knapper (f.eks. Ok/Cancel) der bruges flere forskellige steder, eller meget ens ting (og det er her man skal være forsigtig), bør man nok generelt bruge forskellige markers.
Men igen, det er ikke nogen katastrofe hvis en oversætter kommer og siger "øhhhh, det er ikke det samme", man kan hurtigt lave det om, og så sørge for at kopiere det oprindelige resultat på de andre oversættelser der ikke har haft det problem.
Og ja, man bliver nødt til at vise noget kontekst i kommentarer, før at oversættere har en jordisk chance for at opdage det.
- Det skal man så have under alle omstændigheder, for at oversættelser i det hele taget kan være af en acceptabel kvalitet.
gettext og flere betydninger:
I gettext kan programmørerne af programmet give en kommentar til en tekst der skal oversættes. Hvis der så er to strenge der er ens, men skal oversættes forskelligt, så skriver programmøren to forskellige kommentarer, en til hver tekst, som så kommer med i oversættelsesfilen.
Hvordan véd programmøren så at der er forskelle på de to ens tekster? Det gør han muligvis ikke, men han kan få input fra de forskellige oversættere at her er der et problem.
Og så bruger man selve strengen som identifikator i gettext, det lyder som om man skal sætte en text-id som man selv skal finde på i nogen andre systemer. Det må da være besværligt, og være en hindring for at programmøren har internationaliseret programmet. Og iøvrigt gøre programmet mindre læseligt. Hvilke systemer benytter sådanne metodikker?
En anden fordel med gettext er at alle tekster samles i en .po fil, med den tekst der skal oversættes og så den oversatte tekst. Jeg har set at i Java er det hele samlet i et ressourcebundle, hvor teksterne ligger sammen med en række andre data som programmet skal bruge. Det gør det en del sværere at administrere. gettext har mulighed for at tage korrekte tekster fra tidligere udgaver af et program, og så blande det med nye tekster, så kun de nye tekster skal oversættes, det véd jeg heller ikke om det kan lade sig gøre i Java mm.
I min ungdom fik jeg et feriejob med at at "oversætte" programmer til Atari 800 til dansk. Det foregik ved at erstatte tekster i den binære kode -- så man skulle sikre, at den nye tekst fyldte præcis det samme som den gamle. Hvis den danske tekst var kortere, kunne man fylde ud med blanktegn, men hvis den var længere, måtte man omformulere eller bruge forkrtlsr.
Hvis man har kildeteksten er det sjældent et problem -- dog kan man risikere at linjer bliver ombrudt uheldigt, hvis der er fast bredde på vinduer og lignende.
Et større problem er dog programmerede ændringer af tekst, f.eks. ord, der kan stå i både ental og flertal og bliver valgt ud fra værdien af en variabel, f.eks. noget i stil med
[code=c]printf ("%d %s",number,item);
if (number!=1) printf("s\n");
else printf("\n");[/code]
Det kræver, at man forstår koden, før man kan oversætte dette korrekt. Det betyder, at man ikke kan sætte ikke-programmører til at lave oversættelsen. Endnu værre er det, hvis ovenstående kode oversættes til et sprog, hvor flertalsformen ikke dannes ved at sætte et eller flere bogstaver efter entalsformen. Det er iøvrigt ikke altid, det vil virke på engelsk (f.eks. woman/women), men programmøren kan have sikret sig, at disse ord ikke kan forekomme.
En anden måde er at lave to markers, en til ental, en til flertal. Så behøver oversætteren heller ikke at kunne programmere.
[code=c]
if(number == 1){
/// woman, singular.
printf(("1 woman attended"));
}else
/// women, plural.
printf(("%s women attended"), number);
[/code]
Med en .pot:
#. woman, singular
#: src/count.c:14
msgid "1 woman attended"
msgstr "1 kvinde deltog"
#. women, plural
#: src/count.c:17
msgid "%s women attended"
msgstr "%s kvinder deltog"

