Multilanguage Database
Eerder heb ik hier een topic geplaatst met een vrij ingewikkeld database ontwerp. Hierin zei ik dat het ook meertalig is en zei heel stoer dat dat geen probleem zou opleveren.
Helaas, doet dit het dus wel.
Ik heb 2 tabellen (even kort)
table content heeft de volgende velden
id
lang_id
content
table languages heeft de volgende velden
id
name
abbr (afkorting van afkorting)
Waarbij lang_id natuurlijk refereerd aan languages.id
Nu wil het zo backend users kunnen content toevoegen. Dit zullen ze in eerste instantie doen in default taal (laten we dat record 1 - english - en, noemen) daarna kunnen ze als ze willen een vertaling toevoegen (bijv. nederlands), nu kan ik natuurlijk een query schrijven a la:
Code (php)
1
2
3
4
2
3
4
SELECT content.content
FROM content
WHERE lang_id IN
(SELECT id FROM languages WHERE languages.abbr = $GLOBALS['lang_abbr'])
FROM content
WHERE lang_id IN
(SELECT id FROM languages WHERE languages.abbr = $GLOBALS['lang_abbr'])
Er van uitgaande dat $GLOBALS['lang_abbr'] de juiste taalafkorting bevat.
Maar nu komt mijn probleem, ik wil dat als de bezoeker bijvoorbeeld in het Nederlands mijn site bezoekt en een content item aanroept die er alleen in het Engels is moet deze toch worden getoont...
Hoe los ik dat op in 1 query?
Ik draai MySQL 5.0 met InnoDB
Alvast bedankt!
Een vriendelijke groet,
Jason
Gewijzigd op 01/01/1970 01:00:00 door Jacco Engel
Jacco, daar gaat het niet om.. Die default language. Het gaat erom hoe ik als een content element van een tweede (of derder of vierde etc.) niet bestaat hij deze moet overriden met de default taal. En die default taal heb ik wel. Maar daar moet dus een query voor geschreven worden...
Dit zou zoiets worden:
Waarom de gekke naam 'abbr' voor een kolomnaam? Gebruik bijvoorbeeld 'iso' of 'iso_code', dat is met een taal een heel stuk duidelijker. Vervolgens zet je hier geldige ISO-codes in en klaar ben je.
abbr zegt helemaal niks, behalve dat het een afkorting zou kunnen zijn. En afkortingen zijn er in 1000 en 1 soorten en maten en ook nog in verschillende talen. 'sp' staat voor spaans? Of pak je de ISO-code 'es' ?
Helaas de query werkt niet. Volgens mij is dit op set-niveau, en ik wil het eigenlijk op veld niveau (wordt dit gesnapt???) Of moet ik dan een dubbele query uitvoeren? of met PHP oplossen?
Gewijzigd op 01/01/1970 01:00:00 door Jason de Ridder
BUMPPPPPPPP (A)
je zou ook bij het aanmaken van een nieuwe taal je default taal kunnen kopieren... zo is alles iig gevuld in de default taal en kan de gebruiker het op zijn gemak vertalen.
Michel, dan kan hij beter een verwijzing maken naar het default, want dit kan je database (als je website groot is) langzamer krijgen :).
Meertaligheid zou generiek moeten zijn, en als je gaat kopiëren ben je naar mijn idee wel erg pragmatisch bezig.
Dat betekend dat als je een nieuw bericht toevoegd, dat die (als je 4 talen hebt) 4 keer in je tabel zou komen, elk met een ander taal id?
Lijkt me niet. In een goede database komen geen redundante gegevens voor. Op jou manier werk je juist redundantie in de hand. Dat kan niet de bedoeling zijn.
Je database hoeft er niet trager door te worden CB2thephp, er staat alleen meer data in, maar dit hoeft voor de prestaties niet/nauwelijks merkbaar te zijn.
@Jason
Query van Blanché zit wel erg logisch in elkaar, ik weet niet zeker of het zou moeten werken, maar er zat iig nog iets niet goed met de quotes:
Code (php)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
2
3
4
5
6
7
8
9
10
11
12
13
14
15
<?php
$query = "SELECT c.content
FROM content AS c, languages AS l
WHERE c.lang_id = l.id
AND l.abbr =
CASE WHEN
( SELECT COUNT(c.id)
FROM content AS c, languages AS l
WHERE c.lang_id = l.id
AND l.abbr = '".$GLOBALS['lang_abbr']."'
) = 0
THEN 'en'
ELSE '".$GLOBALS['lang_abbr']."'
END";
?>
$query = "SELECT c.content
FROM content AS c, languages AS l
WHERE c.lang_id = l.id
AND l.abbr =
CASE WHEN
( SELECT COUNT(c.id)
FROM content AS c, languages AS l
WHERE c.lang_id = l.id
AND l.abbr = '".$GLOBALS['lang_abbr']."'
) = 0
THEN 'en'
ELSE '".$GLOBALS['lang_abbr']."'
END";
?>
idd ik stond ook zelf niet achter mijn idee, ik was alleen even aan het mee brainstormen
Tnx, maar m'n database zit net iets lastiger in elkaar dan ik heb gezegd. In de basis klopt het wel. Dus ik heb hem als 'inspiratie' bron gebruikt. En dat werkte niet.
Ik denk dat ik het met PHP op moet gaan lossen... Helaas.
Maar eventueel andere SQL oplossingen graaaag!
Ik denk dat ik ook heb ontdekt waarom dit niet werkt. Je zou het "per bericht" moeten controleren of daar de standaard taal beschikbaar voor is. Maar je hebt niets om te vergelijken of het om hetzelfde bericht gaat:
id, lang_id, bericht
-> Zou iets moeten worden als:
id, bericht_id, lang_id, bericht.
Voor dezelfde berichten in een andere taal, zou je de bericht_id allemaal hetzelfde moeten houden. Dan zou het idee van Blanche volgens mij wel werken.
Met poEdit gebruik maak je .mo en .po textfiles die dan je gehele output vertalen.
Edit: Ahh, I see. Ja, dan is het niet zo'n goede oplossing nee.
Gewijzigd op 01/01/1970 01:00:00 door Gerben Jacobs
gettext is voor de teksten die niet veranderen, zoals meldingen en knoppen. Voor database-tekst zoals nieuwsberichten is het geen oplossing.
Je zou het zowizow niet met een database moeten doen. Als je even snel wat wilt veranderen, moet je zoveel zoeken enzo... Je kan beter gewoon een gettext doen dus, of zelf een class of dergelijke maken die het uit een text file haalt en ordend als voorbeeld
Beetje ouwe koeien uit de sloot halen...
Maar een database is veel sneller, beter en makkelijker.... Leer je dat nu van Jelle? Van wie krijg je les?