Witaj Gościu! ( Zaloguj | Rejestruj )

Forum PHP.pl

> Zasady pisania na forum Pro

Tematy na forum Pro mogą zakładać jedynie moderatorzy. W otwartych tematach może pisać każdy, kto ma coś fachowego do powiedzenia. Wszystkie posty nie wnoszące nic do tematu będą natychmiast usuwane, a ich autorzy dostaną ostrzeżenie.
Jeśli uważasz, że jakiś temat jest warty dyskusji na tym forum, zgłoś go w temacie Propozycje.

9 Stron V   1 2 3 > »   
Reply to this topicStart new topic
> Wielojęzykowość, Czekam na Wasze propozycje
Ociu
post
Post #1





Grupa: Moderatorzy
Postów: 1 566
Pomógł: 37
Dołączył: 14.05.2003
Skąd: Kraków




Witam,
Od jakiegoś czasu piszę duży projekt i doszedłem do wybierania języku. Chciałbym poznać Wasze zdanie jak ma działać taki system wielojęzykowości strony. Pobuszowałem po internecie i oto, co wymyśliłem.
  • Pliki.
    Trzymamy pliki językowe w plikach. Każdy język ma osobny katalog, każdy ma pliki o takiej samej nazwie jak reszta języków, w plikach tablice o takich samych kluczach. Wybieramy odpowiedni język, include odpowiedniego pliku i print.
  • Teksty w bazie danych.
    Tworzymy dwa obiekty. Jeden (może być traktowany jako filter) pobiera dane z bazy danych i przerzuca je do klasy o nazwie np. LangWrapper. Używając magicznych metod __get() pobieramy tekst z klasy i __set() gdy nie ma potrzebnego tekstu należy do stworzyć
  • Open Power Template

Byłbym wdzięczny za propozycje rozwiązań.
Wojtek.
Go to the top of the page
+Quote Post
pEbE
post
Post #2





Grupa: Zarejestrowani
Postów: 106
Pomógł: 3
Dołączył: 21.03.2006
Skąd: Sosnowiec

Ostrzeżenie: (0%)
-----


Myślę ze dobrym rozwiązaniem są pliki. Stosuje sie je w wielu cmsach i projektach.
Tłumaczenia w bazie danych to według mnie zaśmiecanie db i w dodatku majac wiele jezykow robi sie syf i przedluza sie czas wyszukiwania.
Tutaj nalezy zadac pytanie jak stworzyc taki plik. Czy ma byc to plik php w ktorym definiuje się zmienne/stałe czy zwykły plik tekstowy typu

Kod
ERROR_CONNECTION=bład przy polaczeniu z baza;
ERROR_SELECT_DB=bład przy wybieraniu bazy;
itp...


Nie wiem co jest bardziej wydajne, jednak jesli chcemy zeby naszych jezykow nikt nie "podgladal" no to php
Go to the top of the page
+Quote Post
Strzałek
post
Post #3





Grupa: Przyjaciele php.pl
Postów: 384
Pomógł: 6
Dołączył: 11.09.2004
Skąd: Grodzisk Mazowiecki

Ostrzeżenie: (0%)
-----


jeżeli w projekcie masz zamiar używać OPT, to ja na twoim miejscu użył bym opt'owego i18n ;]
Go to the top of the page
+Quote Post
sf
post
Post #4





Grupa: Zarejestrowani
Postów: 1 597
Pomógł: 30
Dołączył: 19.02.2003
Skąd: Tychy

Ostrzeżenie: (0%)
-----


Smarty: {config_load file="text.conf" section=$language} no i posprzątane
Go to the top of the page
+Quote Post
NuLL
post
Post #5





Grupa: Zarejestrowani
Postów: 2 262
Pomógł: 21
Dołączył: 3.05.2004
Skąd: Sopot, Krakow, W-wa

Ostrzeżenie: (0%)
-----


Ja korzystam z modifiera SMARTY
  1. {"Jakis_tam_komunikat"|lang:"admin"}

Przepuszczam to przez modifier lang z paramtrem admin.
Go to the top of the page
+Quote Post
TomASS
post
Post #6





Grupa: Zarejestrowani
Postów: 1 660
Pomógł: 13
Dołączył: 9.06.2004
Skąd: Wrocław i okolice

Ostrzeżenie: (0%)
-----


A ja się bawię "słownikiem" - mam plik lang_pl.php, lang_en.php itp..... w bazie trzymam dla jakiego użytkownika jaki plik załadować (oczywiście to może później sobie zrobić). W plikach tych mam tablicę $Lang:

  1. <?php
  2. $Lang['Enter'] = 'Wejście';
  3. $Lang['Exit'] = 'Wyjście';
  4. .
  5. .
  6. .
  7. ?>

i tak plik normalnie includuje....
Go to the top of the page
+Quote Post
eMartio
post
Post #7





Grupa: Zablokowani
Postów: 46
Pomógł: 0
Dołączył: 12.01.2006

Ostrzeżenie: (10%)
X----


Ja z kolei napisałem sobie plugin do Smartego. Templejty tworzę normalnie, używając naszego narodowego języka. Mam również plik XML, który nazywa się identycznie jak nazwa szablonu czy też modułu szablonu i zawiera tłumaczenia tekstów z templejta w wielu językach.

Np.:

Moduł szablonu: menu.mod.tpl
Kod
<div>
<a href="home.php" title="Moja strona domowa">strona domowa</a>
</div>


Plik XML zawierający tłumaczenie:
Kod
<translations>
  <translation>
    <source>Moja</source>
    <en>My</en>
  </translation>
  <translation>
    <source>strona domowa</source>
    <en>home site</en>
  </translation>
</translations>


Plugin Smartego po skomiliowaniu szablonu zamienia wszystkie teksty, które są uwzględnione w pliku XML (sekcja source) na żądany język.

Ma to dwie ogrome zalety:
- w połączniu z keszowaniem parsowanie xml-u nie jest aż tak uciążliwe dla systemu
- mój tłumacz nie musi znać się na php (aplikacja), HTML (templejty); ba! nawet nie zagląda do tych plików - ma swój katalog, do którego wrzuca pliki XML

Ten post edytował eMartio 7.04.2006, 10:17:59
Go to the top of the page
+Quote Post
Vengeance
post
Post #8





Grupa: Zarejestrowani
Postów: 657
Pomógł: 2
Dołączył: 15.08.2003
Skąd: Łódź

Ostrzeżenie: (0%)
-----


I ma taką wadę, że języki są różne i różną mają gramatyke... twoim sposobem czesto zdażyć się może, że nie da się w prosty sposób przetłumaczyć danego zdania.
Go to the top of the page
+Quote Post
Fipaj
post
Post #9





Grupa: Zarejestrowani
Postów: 691
Pomógł: 0
Dołączył: 19.01.2005
Skąd: Warszawa

Ostrzeżenie: (0%)
-----


http://developer.gnome.org/projects/gtp/tr...-gnome/x22.html - pliki .po i ich dekoder napisany przez Bastiona to całkiem dobre rozwiązanie.

Fajnie też rozwiązał to NuLL, ale pliki .PO są bardzo popularne, istnieje też wiele programów służących do ich edycji, co upraszcza tworzenie nowych wersji językowych. gTranslator i KBabel, for example.
Go to the top of the page
+Quote Post
3rdeye
post
Post #10





Grupa: Zarejestrowani
Postów: 25
Pomógł: 0
Dołączył: 6.04.2006

Ostrzeżenie: (0%)
-----


Cytat(TomASS @ 2006-04-07 06:27:19)
A ja się bawię "słownikiem" - mam plik lang_pl.php, lang_en.php itp..... w bazie trzymam dla jakiego użytkownika jaki plik załadować (oczywiście to może później sobie zrobić). W plikach tych mam tablicę $Lang:

  1. <?php
  2. $Lang['Enter'] = 'Wejście';
  3. $Lang['Exit'] = 'Wyjście';
  4. .
  5. .
  6. .
  7. ?>

i tak plik normalnie includuje....

wydaje mi się, że to jest dobry pomysł. ja tak robię.

choć lepszym sposobem jest napisanie

$lang = array(
'czesc' => 'eloza',
'czlowiek' => 'ziom'
);

może się czepiam, ale sposób pisania TomASS'a jest jednak bardzo nieefetywny. php to nie C w php'ie najlepiej robić wszystko w jednej komendzie. choć szacun dla Niego, Jego squadu i Jego samicy za sposób robienia słownika (IMG:http://forum.php.pl/style_emoticons/default/biggrin.gif) podoba mi się (IMG:http://forum.php.pl/style_emoticons/default/biggrin.gif)

z resztą ten sposób jest użyty także w sugarCRM.

Ten post edytował 3rdeye 12.04.2006, 15:11:27
Go to the top of the page
+Quote Post
splatch
post
Post #11





Grupa: Zarejestrowani
Postów: 487
Pomógł: 7
Dołączył: 7.01.2004
Skąd: Warszawa

Ostrzeżenie: (0%)
-----


Ja ze swojej strony mogę polecić draft i18n z Mojavi 4, całość prezentuje się iście interesująco.. niestety w chwili obecnej serwer Mojavi leży..
Go to the top of the page
+Quote Post
yavaho
post
Post #12





Grupa: Zarejestrowani
Postów: 449
Pomógł: 0
Dołączył: 26.05.2004
Skąd: Nowy Sącz

Ostrzeżenie: (0%)
-----


Ja mam strony wielojezykowe zrobione na podstawie bazy danych i dosłownie zero tekstu w kodzie html. Struktura plikow php wyglada podobnie jak bym smarty zastosowal.
Jeden minus to ze jest duzo zapytan do bazy i moze stanowic obciazenie przy wiekszym serwisie. Ale wtedy juz prosto mozna zastosowac cachowanie stron.
Go to the top of the page
+Quote Post
Ace
post
Post #13





Grupa: Zarejestrowani
Postów: 216
Pomógł: 0
Dołączył: 9.08.2003
Skąd: Warszawa

Ostrzeżenie: (0%)
-----


Ja osobiscie korzystam z plikow ini. Plik jezykowy globalny, + pomniejsze pliki jezykowe np: do konkretnego modulu. W Smarty korzystam z postfilter ktory podmienia odpowiednie ciagi znakow na wartosci np: [lang:mod_news,dodaj] na "Dodaj newsa"
Go to the top of the page
+Quote Post
dtb
post
Post #14





Grupa: Zarejestrowani
Postów: 476
Pomógł: 1
Dołączył: 5.11.2005
Skąd: Bieruń city

Ostrzeżenie: (0%)
-----


ja wczytuje zawartosc pliku ini dla wybranego jezyka do tablicy (parse_ini_file) a potem po prostu:
{$lang[costam][costam]}
Go to the top of the page
+Quote Post
krzemian
post
Post #15





Grupa: Zarejestrowani
Postów: 47
Pomógł: 0
Dołączył: 25.01.2004
Skąd: Świętochłowice

Ostrzeżenie: (0%)
-----


Moim zdaniem prawda znowu leży po środku - wydaje mi się, że pliki są bardzo dobrym rozwiązaniem, jeśli chodzi o teksty formularzy itp. Jednak co, jeśli ktoś będzie chciał tłumaczyć całe artykuły, znajdujące się w bazie? Wtedy najlepszym rozwiązaniem byłoby połączenie systemu pliki+baza.
Wydaje mi się, że można by stworzyć tabele osobno dla każdego języka, np. en_articles, pl_articles itp., bo trzymanie tych danych w jednej tabeli nie miałoby raczej najmniejszego sensu, skoro i tak są one wykorzystywane naprzemiennie, a nie razem.

PS. Nie jedźcie po mnie za bardzo, bo ostatnio w php coś pisałem chyba z pół roku temu:) I wesołych świąt wam życzę.
Go to the top of the page
+Quote Post
NoiseMc
post
Post #16





Grupa: Zarejestrowani
Postów: 398
Pomógł: 10
Dołączył: 24.11.2004
Skąd: Łódź

Ostrzeżenie: (0%)
-----


Cytat(krzemian @ 2006-04-16 12:53:05)
Wydaje mi się, że można by stworzyć tabele osobno dla każdego języka, np. en_articles, pl_articles itp., bo trzymanie tych danych w jednej tabeli nie miałoby raczej najmniejszego sensu, skoro i tak są one wykorzystywane naprzemiennie, a nie razem.

Ja osobiście trzymam wszystko w jednej tabeli, w której mam kolumnę "Lang" określającą w jakim języku jest dany wiersz czyli np:
  1. ID | Tytul | Tresc | Lang

Potem w zalezności od wybranego języka wybieram potrzebne dane np.:
  1. SELECT *
  2. FROM tabela
  3. WHERE Lang=$_GET['lang']


Jeżeli natomiast chodzi o stałe teksty typu: "Więcej", "Strona głowna" to trzymam je w XML - ach gdzie struktura plików jest następująca:
Kod
languages
  en
      Translation.xml
  pl
      Translation.xml

parsuję XML z wykorzystaniem PEAR::XML_Unserializer i podrzucam do smartów gdzie wyświetlam to:
  1. <?php
  2. {$Translation.StronaGlowna}
  3. ?>

Obecnie pracuję nad manadżerem do tłumaczeń - coś na zasadzie kompilacji XML - a do pliku w którym byłaby zserializowana tablica z tłumaczeniami. I jeżeli XML jest nowszy niż skompilowane dane to wtedy kompiluję jeszcze raz. Jeżeli nie to odczytuję i podstawiam zserializowaną tablicę
Go to the top of the page
+Quote Post
krzemian
post
Post #17





Grupa: Zarejestrowani
Postów: 47
Pomógł: 0
Dołączył: 25.01.2004
Skąd: Świętochłowice

Ostrzeżenie: (0%)
-----


Teraz tak myślę i doszedłem do wniosku, że twoj podejście jest chyba lepsze od mojego (jeśli chodzi o trzymanie w bazie, bo xml i pliki to dla mnie to samo - wszystko zależy od możliwości serwera itp) - zakładając, że chcę dodać kolejny język, przy twoim podejściu mogę (przynajmniej teoretycznie) dodać go z poziomu panelu, nie grzebiąc w strukturze baz.
Go to the top of the page
+Quote Post
Jabol
post
Post #18





Grupa: Przyjaciele php.pl
Postów: 1 467
Pomógł: 13
Dołączył: 22.02.2003

Ostrzeżenie: (0%)
-----


A co wy na to (suma kilku pomysłów):
  1. <?php
  2.  function array_path_insert(&$array, $sep, $path, $value)
  3.  {
  4.  $path_el = split($sep, $path);
  5.  
  6.  $arr_ref =& $array;
  7.  
  8.  for($i = 0; $i < sizeof($path_el); $i++)
  9.  {
  10.  $arr_ref =& $arr_ref[$path_el[$i]];
  11.  }
  12.  
  13.  $arr_ref = $value;
  14.  }
  15.  
  16. $trans=array();
  17.  
  18. foreach(file("translations/{$lang}.txt") as $line)
  19. {
  20. $chunks=explode("=", $line);
  21. define("TXT_".array_shift($chunks), implode("=", $chunks));
  22. /* define("TXT_".array_shift($chunks), eval(implode("=", $chunks))); // tak jakby chciać tutaj włożyć jakąś logikę */
  23. /* define("TXT_".array_shift($chunks), str_replace('\n', "\n", implode("=", $chunks))); // tutaj jakby nie chcieć interpretować wszystkiego */
  24. /* można też zrobić preg_replace z tablicami */
  25. /* XXX: Ależ mi nachodzi pomysłów. Dla tablicowców-smartowców następna wersja. (funkcje znalazłem w komentarzach do manuala) */
  26. array_path_insert($trans, '.', array_shift($chunks), implode("=", $chunks));
  27. }
  28. $smarty->cośtam('lang', $trans);
  29. ?>
A plik translacji wyglądałby oczywiście
Kod
TEXT1=BlaBlaBla
TEXT2=Myślę więc jestem
TEXT3=W matematycie wiem, że 2*2=4!
Taka synteza paru pomysłów - prosta i szybka implementacja.
Do drugiej metody (tej z tablicami), wyglądałobyto oczywiście analogicznie
Kod
MAIN.TEXT1=BlaBlaBla
MAIN.TEXT2=Myślę więc jestem
MAIN.TEXT3=W matematycie wiem, że 2*2=4!


To oczywiście tylko dla małych tekstów dla tworzenia innojęzycznych wersji serwisów. Dla mniejszycg napisów, dla których nie chcemy marnować cennych id w bazie danych. Bo co do większych napisów zgadzam się z przedmówcami.

Ten post edytował Jabol 16.04.2006, 21:40:21
Go to the top of the page
+Quote Post
Bora
post
Post #19





Grupa: Zarejestrowani
Postów: 270
Pomógł: 0
Dołączył: 15.06.2003

Ostrzeżenie: (0%)
-----


Cytat(Jabol @ 2006-04-16 21:23:09)
A plik translacji wyglądałby oczywiście
Kod
TEXT1=BlaBlaBla
TEXT2=Myślę więc jestem
TEXT3=W matematycie wiem, że 2*2=4!
Taka synteza paru pomysłów - prosta i szybka implementacja.
Do drugiej metody (tej z tablicami), wyglądałobyto oczywiście analogicznie
Kod
MAIN.TEXT1=BlaBlaBla
MAIN.TEXT2=Myślę więc jestem
MAIN.TEXT3=W matematycie wiem, że 2*2=4!

To nie lepiej użyć poprostu plików ini ?
Podczas moich praktyk w firmie gdzie brałem udział w tworzeniu aplikacji w springu (java) był stworzony plik (nie pamiętam jakie miał rozrzeszenie może .properties czy cuś) ale wyglądał on niej więcej :

main.welcome = Witam
main.menu = Menu
itp.
Go to the top of the page
+Quote Post
Fipaj
post
Post #20





Grupa: Zarejestrowani
Postów: 691
Pomógł: 0
Dołączył: 19.01.2005
Skąd: Warszawa

Ostrzeżenie: (0%)
-----


A co, jeśli w tłumaczonym tekście wystąpi znak "=" bądź przełamanie linii?
Go to the top of the page
+Quote Post
Ociu
post
Post #21





Grupa: Moderatorzy
Postów: 1 566
Pomógł: 37
Dołączył: 14.05.2003
Skąd: Kraków




Jabol: Muszę się zgodzić z Borą, wygląd pliku jest podobny do plików INI,a wprowadzenie tego w życie jest bardzije zamotane niż INI. Mój skrypt jest tylko silnikiem (albo słowo ostatnio bardzo popularne - frameworkiem) i nie ja go będe dalej rozwijał. Parse_ini_file jest w php4, pod które skrypt (niestety)...

Pewnie zaraz padnie pytanie: "Po co ten temat ?". Szukam jakieś alternatywy dla plików ini i wielkich tablic.

pozdrawiam
Go to the top of the page
+Quote Post
sf
post
Post #22





Grupa: Zarejestrowani
Postów: 1 597
Pomógł: 30
Dołączył: 19.02.2003
Skąd: Tychy

Ostrzeżenie: (0%)
-----


Cytat(Fipaj @ 2006-04-17 14:24:45)
A co, jeśli w tłumaczonym tekście wystąpi znak "=" bądź przełamanie linii?

Użyć encji. Przełamanie lini jest rozwiązane w plikach konfiguracyjnych smarty. Jeszcze jakieś trudne pytania?
Go to the top of the page
+Quote Post
Jabol
post
Post #23





Grupa: Przyjaciele php.pl
Postów: 1 467
Pomógł: 13
Dołączył: 22.02.2003

Ostrzeżenie: (0%)
-----


Cytat(Fipaj @ 2006-04-17 14:24:45)
A co, jeśli w tłumaczonym tekście wystąpi znak "=" bądź przełamanie linii?
Przeczytaj dokładnie to zauważysz, że oba problemy już są rozwiązane.

Osobiście w pewnym projekcie używałem też takiej opcji:

tabela: txts
pola:
id int
name varchar
pl text
de text

Tyle, że wiedziałem ile będzie języków... Teksty ogólne miały w name jakąś nazwę i je ładowałem do smarta i potem tylko
Kod
{$txts.PageName}
Teksty, które miały tam NULL były modułami innych modułów i z nich też były podlinkowane, także nie trzeba było się o nie martwić.

Ten post edytował Jabol 18.04.2006, 18:05:24
Go to the top of the page
+Quote Post
Prph
post
Post #24





Grupa: Zarejestrowani
Postów: 338
Pomógł: 2
Dołączył: 4.03.2006
Skąd: Łódź

Ostrzeżenie: (0%)
-----


Witam,

Kilka dni temu pisalem klase opbsugujaca jezyk w moim frameworku. Wyglada to tak:

Klasa Language :

__construct($sLanguage = null)
1. jezeli podano w parametrze jezyk, ustaw go.
2. jezeli nie podano go, a ustnieje ciastko z nazwa jezyka (tlumaczenie strony w czasie trwania sesji), to zastosuja taki jezyk
3. w innym przypadku stosuj dod`myslny.

__get() dzieki ktorej w prtosty sposob korzysta,my z jezyka.

W pliku english.php mam tablice:

$aLanguage['main_menu_custam'] = 'SuperTurboMegaGigaUltraString ';

W aplikacji odwoluje sie do tego tak:

$oLanguage->main_menu_custam;

W szablonach wpisuje: {$LANGUAGE.MAIN_MENU_CUSTAM}.

Dziala :]
Go to the top of the page
+Quote Post
Neotion
post
Post #25





Grupa: Zarejestrowani
Postów: 67
Pomógł: 0
Dołączył: 13.09.2004

Ostrzeżenie: (0%)
-----


Przepraszam będe pisał bez shifta bo siedze w szkole (IMG:http://forum.php.pl/style_emoticons/default/smile.gif)

w każdym razie:
wg. mnie najlepszym rozwiązaniem jest to które już oferuje pewien mod do php (nie pamiętam niestsety nazwy ale jest nawet jego opis gdzieś w manualu):
polega on na korzystaniu z tablic zawierających całe tłumaczenia stringów i wywoływanie tłumaczeń np poprzez funkcję
  1. <?php
  2. _("Tłumacz mnie");
  3. ?>
a przedtem na załądowaniu tej tablicy do pamięci. Potem wystarczy napisać sobie edytor w c++ (czy co tam chcecie) który wyciąga wszystkie stringi zawarte w tych funkcjach np. w podanym katalogu i przedstawia wygodny formularz do tłumaczenia. Za to w plikach .php pisazemy sobie jakimś językiem referencyjnym np. angielskim.

Pomysł programu pomocniczego to już idea barzeij wniesiona przeze mnie (albo plagiat czyjejś - nie pamiętam) ale takie rozwiązanie wydaje się wygodne i szybkie.
Go to the top of the page
+Quote Post
Bastion
post
Post #26





Grupa: Zarejestrowani
Postów: 505
Pomógł: 0
Dołączył: 8.01.2005

Ostrzeżenie: (0%)
-----


takie wlasnie (podobne) rozwiaznie jest w klasie Babel, ktory korzysta z plikow .po / .mo z gettexta. nie trzeba pisac zadnego programu w c++, wystarczy skorzytac z progmau gettext

xgettext example01.php -L php -o pl_PL.po --keyword=_r --keyword=_p

i wycina do pliku po wszystkie ciagi tekstowe poprzedzone funkcja _r i _p
Go to the top of the page
+Quote Post
sadu
post
Post #27





Grupa: Zarejestrowani
Postów: 30
Pomógł: 0
Dołączył: 25.04.2006

Ostrzeżenie: (0%)
-----


moze pomoze:

http://www.tutorialized.com/tutorial/Multi...ge-System/12488

pozdro
Go to the top of the page
+Quote Post
Seth
post
Post #28





Grupa: Przyjaciele php.pl
Postów: 2 335
Pomógł: 6
Dołączył: 7.03.2002

Ostrzeżenie: (0%)
-----


Odkopuje temat bo zastanawiam sie nad tym w jaki spsob, zgrabnie pobierac dane z tablicy z jezykami wewnatrz obiektu.

Moja tablica wyglada mnie wiecej tak:
  1. <?php
  2. $lang['pl_PL'] = array(
  3. 'app' => array(
  4.  'title' => 'Test'
  5. )
  6.  );
  7. ?>


Trzymam ja w pliku pl_PL.lang.php i includuje w zaleznosci od ustawien lokalizacji.

Teraz aby moc uzywac tej tablicy w klasie, przekazuj ja do konstruktora:

  1. <?php
  2. $landSetting = 'pl_PL';
  3.  
  4. require_once($landSetting . '.lang.php');
  5.  
  6. $foo = new Foo($lang[$landSetting]);
  7.  
  8. class Foo {
  9.  var $_lang = null;
  10.  
  11.  
  12.  function Foo(&$lang) {
  13. $this->_lang = &$lang;
  14.  }
  15. }
  16. ?>


Robie tak bo nie chce uzywac globali.

Zastanawiam sie teraz, czy dalo by sie to jednak inaczej zapisac.

Moze zamiast przekazywania tablicy uzyc singletonu zawierajacego ta tablice i odwolywac sie do niej np tak:

  1. <?php
  2. Lang::getMsg('app.title', 'pl_PL')
  3. ?>

?


Ogolnie chodzi mi o to zeby wewnatrz obiektu moc sie dostac do pliku jezykowego bez uzywania global.

Ma ktos jakies pomysly? (IMG:http://forum.php.pl/style_emoticons/default/smile.gif)
Go to the top of the page
+Quote Post
splatch
post
Post #29





Grupa: Zarejestrowani
Postów: 487
Pomógł: 7
Dołączył: 7.01.2004
Skąd: Warszawa

Ostrzeżenie: (0%)
-----


Bardzo przydatny temat dla wszystkich którzy odwiedziają ten wątek: http://forum.mojavi.org/index.php?showtopic=1502&st=0

Są tam diagramy które ilustrują istotę działania. Polecam uwadze wszystkich.
Go to the top of the page
+Quote Post
AveNET
post
Post #30





Grupa: Zarejestrowani
Postów: 3
Pomógł: 0
Dołączył: 7.03.2006

Ostrzeżenie: (0%)
-----


Mam taką tablicę
  1. <?php
  2.  
  3. $lang=array (
  4.  
  5. 'Ave' => 'Łukasz Peroń',
  6. 'JK' => 'Jan Kowalski',
  7.  
  8. );
  9.  
  10. ?>


Chciałbym żeby zamiast za każdym razem pisać (aby się wyświetliło Łukasz Peroń)
  1. <?php
  2. echo $lang['Ave'];
  3. ?>


żeby stosować krótką forme (taką jak niżej) ale o tym samym działaniu co powyższy kod

  1. <?php
  2. {%Ave%}
  3. ?>


Może ktoś ma pomysł jak to zrobić, wielkie THX

Ten post edytował AveNET 20.05.2006, 09:56:12
Go to the top of the page
+Quote Post
DeyV
post
Post #31





Grupa: Zarząd
Postów: 2 277
Pomógł: 6
Dołączył: 27.12.2002
Skąd: Wołów/Wrocław




Cytat(Seth @ 2006-05-05 13:20:27)
Ogolnie chodzi mi o to zeby wewnatrz obiektu moc sie dostac do pliku jezykowego bez uzywania global.

A może po prostu nie używać tablicy?

W końcu jest tyle "ładniejszych" rozwiązań?

Można np. przechowywać te dane w pliku pl_PL.ini (.php) który nie tylko jest szybciej parsowany, niż php, to na dodatek - łatwiejszy do generowania z utomatu.

Równie dobrze - można te dane przechowywać przecież w mini klasach, a wtedy korzystanie z sigletona staje się już banalne.

Choć osobiście najbardziej żałuję, że prace z plikami .po / .mo z gettexta jest w tej chwili tak skomplikowana, ponieważ najchętniej na nie przerzuciłbym cały ten problem - choćby z uwagi na wydajność i wszechstonność (obsluga liczb pojedynczych i mnogich, odmiany itp.)
Go to the top of the page
+Quote Post
g00fy
post
Post #32





Grupa: Zarejestrowani
Postów: 22
Pomógł: 0
Dołączył: 23.11.2004

Ostrzeżenie: (0%)
-----


a co powiedzie o languagefactory::GetLang()
a pozniej w miejscach w tpl <? $lang->get('id_slowa');?>
?
Go to the top of the page
+Quote Post
nasty
post
Post #33





Grupa: Zarejestrowani
Postów: 634
Pomógł: 14
Dołączył: 27.05.2006
Skąd: Berlin

Ostrzeżenie: (0%)
-----


Moim zdaniem, (ja tak zrobilem w moim programie ktory teraz pisze), w pliku php, zrobic array :
Angielskie:
  1. <?php
  2. $cp_Lang = array(
  3. "ok" => "OK",
  4. "yes" => "Yes",
  5. "no" => "No",
  6. "user not found" => "User not found");
  7. ?>

Polskie:
  1. <?php
  2. $cp_Lang = array(
  3. "ok" => "OK",
  4. "yes" => "Tak",
  5. "no" => "Nie",
  6. "user not found" => "U?ytkownik nie istnieje");
  7. ?>

Wyjasniam, texty w plikach sa zachowane w tej postaci, znaczy sie "key" od przeumaczonego slowa albo zdanie to jest to samo zdanie tylko ze po angielsku, wtedy bedziesz wyswietlal error np. user not found, to poszuka w array czy jest index z takim kluczem, jak tak to go wyswietli a jak nie to wyswietli to zdanie ktore pisales, ktore tez jest poprawne.

a oto funkcja to tumaczy:
  1. <?php
  2. function _($string) {
  3.  
  4. $string = trim(strtolower($string));
  5. $language = $_CFG['system_language'];
  6. require_once("i18n/lang.$language.php");
  7.  
  8. if(!empty($cp_Lang[$string])) {
  9. return $cp_Lang[$string];
  10. } else {
  11. return $string;
  12. }
  13.  
  14. }
  15. ?>

t tak mozesz byc pewien ze nigdy nikt nie zobaczy bledu zwiazanego z nie znalezieniem polskiego (czy innego) odpowiednika.
Go to the top of the page
+Quote Post
DooBLER
post
Post #34





Grupa: Zarejestrowani
Postów: 16
Pomógł: 0
Dołączył: 7.08.2006

Ostrzeżenie: (0%)
-----


Witam
Odgrzeję kotleta...

Piszę średniej wielkości aplikację i także stanąłem przed problemem wielojęzyczności.

Miałem zamiar rozwiązać to przy pomocy plików językowych zawierających tablice z całymi "zdaniami"

Jednak po przeczytaniu tego tematu zainteresowałem się plikami .po/.mo (zwłaszcza, że miałem z nimi już do czynienia przy okazji tłumaczenia jakiejś gry...)

I teraz mam prośbę do kogoś kto kożysta z tego sposobu tłumaczenia w php.
Proszę o jakieś fragmęty kodu jak się używa tych plików.

I jescze nasówa mi się pytanie czy na serwerze nie musi być coś doinstalowywane żeby obsługa tych plików była możliwa, bo jeśli tak to niestety ten sposób lokalizacji odpada

Pozdrawiam
Go to the top of the page
+Quote Post
NuLL
post
Post #35





Grupa: Zarejestrowani
Postów: 2 262
Pomógł: 21
Dołączył: 3.05.2004
Skąd: Sopot, Krakow, W-wa

Ostrzeżenie: (0%)
-----


http://forum.php.pl/index.php?showtopic=42371&hl=babel
Go to the top of the page
+Quote Post
cicik
post
Post #36





Grupa: Zarejestrowani
Postów: 219
Pomógł: 5
Dołączył: 18.07.2006
Skąd: Piekary Śląskie

Ostrzeżenie: (0%)
-----


Można też skorzystać z TMX, zunifikowany opis XMLowy.
Go to the top of the page
+Quote Post
Sh4dow
post
Post #37





Grupa: Zarejestrowani
Postów: 569
Pomógł: 0
Dołączył: 17.08.2003
Skąd: Dąbrowa Górnicza

Ostrzeżenie: (0%)
-----


Nie wiem czy ktoś wogóle o tym słyszał czy używał, ale ja osobiscie pracuje z gettextem. Bardzo szybki, duzo narzedzi okienkowych, z webowymi jest gorzej, chociaz sam juz napisałem cos takiego ale jest jeszcze w wersji wczesnych beta, jesli nie masz tlumaczenia dla klucza, to pokazuje ci sie klucz, niby wymaga od uzytkownika zeby klucze byly pelnymi zdaniami, ale chociaz szablony dla widoku sa czytelniejsze. Problemy: trzeba przygotowywac pliki poprzez kompliacje.
Jeszcze jeden blad to to ze serverrobi cache plikow skompilowanych i przy czestej edycji nie widac poprawek. Ale sa sposoby na obejscie tego problemu

Ten post edytował Sh4dow 4.12.2006, 10:57:13
Go to the top of the page
+Quote Post
DeyV
post
Post #38





Grupa: Zarząd
Postów: 2 277
Pomógł: 6
Dołączył: 27.12.2002
Skąd: Wołów/Wrocław




Właśnie o gettext była mowa, gdy wspominaliśmy o Babel oraz plikach .mo i .po (IMG:http://forum.php.pl/style_emoticons/default/smile.gif)
Go to the top of the page
+Quote Post
pawkow
post
Post #39





Grupa: Zarejestrowani
Postów: 76
Pomógł: 7
Dołączył: 30.09.2006

Ostrzeżenie: (0%)
-----


Problem multijęzykowości rozwiązałem w prosty sposób. Mam taką strukturę katalogów:

Kod
| Languages
| -- Polish
| -- | -- global.php
| -- | -- header.php
| -- | -- footer.php
| -- | -- cośtam.php
| -- English
| -- | -- global.php
| -- | -- header.php
| -- | -- footer.php
| -- | -- cośtam.php


I w bazie mam np. artykuły: id, pl_title, eng_title, pl_body, eng_body

W cookies trzymam pl lub eng, i sprawdzam w aplikacji, czy jest pl, czy eng. Jeżeli nie ma lub jest inne, to korzystam z default (pl) i ładuję odpowiednie pliki językowe w odpowiednich częściach aplikacji, oraz pobieram odpowiednie treści z bazy danych. Proste, i wydajne
Go to the top of the page
+Quote Post
mike
post
Post #40





Grupa: Przyjaciele php.pl
Postów: 7 494
Pomógł: 302
Dołączył: 31.03.2004

Ostrzeżenie: (0%)
-----


Cytat(pawkow @ 21.03.2007, 20:27:11 ) *
Proste, i wydajne
Sposób najgorszy z możliwych.
Jakbym miał 5 wersji językowych i znalazł błąd w jednym z plików to by mnie coś trafiło przy poprawianiu.

Odradzam stanowczo takich rozwiązań.
Go to the top of the page
+Quote Post
pawkow
post
Post #41





Grupa: Zarejestrowani
Postów: 76
Pomógł: 7
Dołączył: 30.09.2006

Ostrzeżenie: (0%)
-----


musiałbyś poprawić tylko jeden plik, czy się mylę ?
Go to the top of the page
+Quote Post
Zeman
post
Post #42





Grupa: Zarejestrowani
Postów: 70
Pomógł: 0
Dołączył: 29.03.2007

Ostrzeżenie: (0%)
-----


Korzystam z autorskiego edytora i 2 pluginów multijezykowych:

1. pierwszy pozwala mi pisać w kodzie php coś takiego
  1. <?php
  2. echo('{*pl:To jest komputer**eng:This is computer*}');
  3. ?>

i wypluwa kod php z zamienionym powyższym na mniej więcej
  1. <?php
  2. echo(''.lang_const_1.'');
  3. ?>
oraz dodatkowy plik ze stałymi


2. drugi wyciąga wszystkie zastosowania powyższej postaci z wszystkich plików projektu i zestawia je w siatce


Suma sumarum w efekcie końcowym można powiedzieć że stosuję metodę podstawiania stałych i tworzenia plików postaci .../pl/index.php gdzie są stałe z tekstami.

Pozwiodronka,
Zeman.
Go to the top of the page
+Quote Post
Diabl0
post
Post #43





Grupa: Zarejestrowani
Postów: 24
Pomógł: 1
Dołączył: 25.03.2006

Ostrzeżenie: (0%)
-----


Widzę że prawie każdy skupił się tylko na jednej (IMHO prostszej) stronie medalu jakim są teksty stałe. Tutaj w zasadzie pomysły są 2/3 (tablice, pliki ini i pokrewne własne formaty i ewentualnie i18n) różniące się tylko sposobem implementacji. Mnie natomiast interesuje ta ciekawsza strona medalu jaką jest:

Jak rozwiązujecie kwestie wielu języków w bazach danych.

Jak do tego podchodzicie robiąc projekt z założenia 2-językowy (np. pl i en) oraz jak to rozwiązujecie mając w planie pełną wielojęzykowość bez z góry określonej liczby języków. Interesuje mnie nie tylko jak kształtujecie samą bazę ale także typowe odwołania do niej.


W przypadku projektów 2-językowych korzystam głównie z typowej konstrukcji wielokolumnowej:

id | date | title_pl | title_en | content_pl | content_en

dorzucając do niej ewentualnie pole boolean valid_{$lang} określające czy dany język występuje w danym rekordzie.
Użycie w kodzie dość banalne:
$SQL = 'SELECT title_' . $_USER['lang'] . ', content_'' . $_USER['lang'] itd

Natomiast w przypadku projektów wielojęzykowych mam zawsze dylemat jak konstruować bazę danych.
Go to the top of the page
+Quote Post
Sedziwoj
post
Post #44





Grupa: Zarejestrowani
Postów: 793
Pomógł: 32
Dołączył: 23.11.2006
Skąd: Warszawa

Ostrzeżenie: (0%)
-----


Czy mi się wydaje czy to jest jeden 'artykuł' -> wiele wersji? Bo takie określenie podsuwa od razu sposób rozwiązania.
czyli tabele wiążącą 'artykuł' z treścią, coś w stylu:
artykul_id|tresc_id|jezyk_id
(czy coś podobnego, bo język można przecież określić na zbiorze, ale z drugiej strony może być w tabeli języków nazwa skrótowa jak i cała, też ułatwi sprawdzenie jakie języki obsługuje)

Ale to tak na z marszu piszę, do tego mam nikłe doświadczenie, więc lepiej niech ktoś lepszy w tych sprawach skomentuje...
Go to the top of the page
+Quote Post
Athlan
post
Post #45





Grupa: Developerzy
Postów: 823
Pomógł: 12
Dołączył: 18.12.2005

Ostrzeżenie: (0%)
-----


Moim zdaniem baza danych w zupełności odpada, bez sensu, przy dużych iloścach informacji czas działania aplikacji zwrasta, a nie o to chodzi. U mnie wszystkie pliki językowe siedzą w plikach:

/Application/Languages/Polish/Polish.Language.php - domyślny plik języka polskiego
/Application/Languages/Polish/Subgrupa_Polish.Language.php - inny plik języka polskiego, przykład:
/Application/Languages/Polish/Register_Polish.Language.php

Budowa takiego pliku jest następująca:

  1. <?php
  2.  
  3. final class fr_Vlang extends VlangPattern
  4. {
  5. public $foo = 'C’est le foo.';
  6.  
  7. public $change_id = 'Polski';
  8. public $change_sr = 'FR';
  9.  
  10. public $entry_add_true = 'L’entrée a été ajoutée avec succes! Afficher?';
  11. public $entry_add_false = 'Erreur de base de données, entrée non ajoutée!';
  12. public $entry_add_false_text = 'Copiez ici le code a ajouter!';
  13. public $entry_add_false_token = 'L’identifiant d’autorisation est erroné!';
  14. public $entry_link = 'Voici le lien vers votre entrée:';
  15. public $entry_connection_lost = 'Impossible d’accéder au serveur, réessayez.';
  16.  
  17. // itd itd itd...
  18.  
  19. }
  20. ?>


Dodatkowo automatycznie wybierany jest domyślny język użytkownika. Aby wymusić priorytet języka, w jego folderze tworzymy plik Język.tmp z wartością w środku od 0.1 - 1, przykład:
/Application/Languages/Polish/Polish.tmp

Klasy:
http://framework.vgroup.pl/expose-409ea1a4...af9923731ec.htm
http://framework.vgroup.pl/expose-d41766b6...fb6deba59c0.htm

Przykład działania wielojęzykowości możecie zobaczeć na www.cpaste.com... działa pięknie (IMG:http://forum.php.pl/style_emoticons/default/smile.gif)

Pozdrawiam, Athlan
Go to the top of the page
+Quote Post
Sedziwoj
post
Post #46





Grupa: Zarejestrowani
Postów: 793
Pomógł: 32
Dołączył: 23.11.2006
Skąd: Warszawa

Ostrzeżenie: (0%)
-----


Cytat(Athlan @ 4.04.2007, 08:05:59 ) *
Moim zdaniem baza danych w zupełności odpada, bez sensu, przy dużych iloścach informacji czas działania aplikacji zwrasta

Czyli Twoim zdaniem przy dużych ilościach informacji trzeba używać plików nie baz danych (IMG:http://forum.php.pl/style_emoticons/default/blinksmiley.gif)
Go to the top of the page
+Quote Post
Zeman
post
Post #47





Grupa: Zarejestrowani
Postów: 70
Pomógł: 0
Dołączył: 29.03.2007

Ostrzeżenie: (0%)
-----


Cytat(Diabl0 @ 4.04.2007, 02:17:23 ) *
...
id | date | title_pl | title_en | content_pl | content_en
...
Użycie w kodzie dość banalne:
$SQL = 'SELECT title_' . $_USER['lang'] . ', content_'' . $_USER['lang'] itd
...
Natomiast w przypadku projektów wielojęzykowych mam zawsze dylemat jak konstruować bazę danych.


Takie podejście może być trochę męczące przy pisaniu zapytań. Ponadto nie bardzo daje możliwość utworzenia różnych danych dla różnych języków, mam na myśli przykładowo, że sklep oferuje w wersji polskiej pewną ilość produktów, w wersji angielskiej może niektórych produktów nie chcieć proponować. Jeszcze bardziej gdy wyobrazimy sobie produkty w sklepie i komentarze klientów, jakby nie patrzeć, nie możemy kazać komentować we wszystkich językach naraz (IMG:http://forum.php.pl/style_emoticons/default/winksmiley.jpg)

Osobiście preferuję nazwy tabel products_pl, products_eng, products_de, ....
i oczywiście 'SELECT id, title, .. FROM products_'.$lang.' ...'


Jeśli klient jednak przewiduje że każdy rekord będzie miał odzwierciedlenia we wszystkich językach, to niby można się pokusić o sposób id | date | title_pl | title_en | content_pl | content_en, choć osobiście pewnie bym zastosował coś innego, co to jeszcze nie wiem, bo nie miałem przypadku żeby każdy rekord miał być we wszystkich językach. Można niby tabelę "mapującą" products: products_pl_id, products_en_id, ...
Go to the top of the page
+Quote Post
Kayne
post
Post #48





Grupa: Zarejestrowani
Postów: 82
Pomógł: 0
Dołączył: 30.04.2006
Skąd: Kalisz

Ostrzeżenie: (0%)
-----


Hm... Jest trochę prostsze rozwiązanie, z którego ja korzystam. Może i jest przez to więcej rekordów w bazie danych... no ale cóż (IMG:http://forum.php.pl/style_emoticons/default/winksmiley.jpg)

Ogólnie koncepcja jest prosta. Mamy tabelę articles:

id | date | title | body | author |lang

Pole lang jest polem CHAR (2) w którym mamy podane np.: pl, en, fr...

Czyli pobranie artykułu po angielsku to po prostu:

  1. <?php
  2. $test = mysql_query('SELECT * FROM articles WHERE lang='en');
  3. ?>


Ten post edytował Kayne 4.04.2007, 14:34:34
Go to the top of the page
+Quote Post
bela
post
Post #49


Administrator PHPedia.pl


Grupa: Developerzy
Postów: 1 102
Pomógł: 2
Dołączył: 14.09.2003

Ostrzeżenie: (0%)
-----


rozwiazanie powyzej jest fajne, ale ma jedna wade: dane w bazie sie powtarzaja

ja uzywam symfony i rozwiazania z tamtego frameworka, czyli mamy dwie tabele w jednej sa dane, ktore sie nie zmieniaja np id uzytkownika, data utworzenia a w drugiej teksty powiazane za pomoca klucza obcego i dodatkowo pole z jezykiem
Go to the top of the page
+Quote Post
Kayne
post
Post #50





Grupa: Zarejestrowani
Postów: 82
Pomógł: 0
Dołączył: 30.04.2006
Skąd: Kalisz

Ostrzeżenie: (0%)
-----


No, powtarzają się, ale jest to bardzo łatwe do zaimplementowania. Odpowiednia budowa tabel w bazie danych a będzie śmigać aż miło (IMG:http://forum.php.pl/style_emoticons/default/smile.gif)
Go to the top of the page
+Quote Post
empathon
post
Post #51





Grupa: Zarejestrowani
Postów: 246
Pomógł: 31
Dołączył: 13.11.2006
Skąd: się znamy?

Ostrzeżenie: (0%)
-----


Ja podobnie jak ~bela używam symfony i uważam tamto rozwiązanie za optymalne. Zarówno pod względem przechowywania elementów interface i treści w bazie danych. Polecam zapoznanie się z tym jak jest to tam rozwiązane (IMG:http://forum.php.pl/style_emoticons/default/wub.gif)
Go to the top of the page
+Quote Post
bela
post
Post #52


Administrator PHPedia.pl


Grupa: Developerzy
Postów: 1 102
Pomógł: 2
Dołączył: 14.09.2003

Ostrzeżenie: (0%)
-----


jezeli ktos sie zdecyduje na symfony, to radze pobierac przez metode doSelectWithI18n, bo samo doSelect nie pobiera danych z jezykow i za kazdym razem wali selecta.
Go to the top of the page
+Quote Post
cicik
post
Post #53





Grupa: Zarejestrowani
Postów: 219
Pomógł: 5
Dołączył: 18.07.2006
Skąd: Piekary Śląskie

Ostrzeżenie: (0%)
-----


Od jakiegoś czasu zastanawiam się na wielojęzykowością w moich projektach i patrząc na potrzeby moich klientów widzę cztery mechanizmy opisujące ich oczekiwania:

1. Klient chce mieć TYLKO z góry określoną liczbę języków.
W takich wypadkach robię po prostu jak kolega wyżej zaproponował, czyli kolumny w tabeli: tytul_pl, tytul_en etc.

2. Klient chce mieć stronę w kilku językach ale one generalnie są niezależne (różne działy etc.).
Wtedy po prostu robię kilka stron, którymi da się administrować z jednego panelu.

3. Klient chce mieć jedną stronę w kilku językach, każdy artykuł w różnych wersjach językowych.
Internauta przełącza się pomiędzy wersjami za pomocą linków (np. chorągiewek z flagami).
W bazie jest to zapisywane jako relacja n do n pomiędzy artykułami i językami gdzie w relacji łączącej jest zapisany tytuł i treść artykułu w odpowiednim języku.

4. Klient chce mieć stronę generalnie w jednym języku (menu etc.) ale poszczególne artykuły w kilku wersjach wyświetlanych na jednej stronie.
Baza jest podobna do tej z pkt. 3.

Przypadek 1. jest szczególną formą jednego z pozostałych.
Go to the top of the page
+Quote Post
faster
post
Post #54





Grupa: Zarejestrowani
Postów: 49
Pomógł: 0
Dołączył: 9.09.2002
Skąd: Pszczyna

Ostrzeżenie: (0%)
-----


Cytat(bela @ 4.04.2007, 17:52:29 ) *
rozwiazanie powyzej jest fajne, ale ma jedna wade: dane w bazie sie powtarzaja

ja uzywam symfony i rozwiazania z tamtego frameworka, czyli mamy dwie tabele w jednej sa dane, ktore sie nie zmieniaja np id uzytkownika, data utworzenia a w drugiej teksty powiazane za pomoca klucza obcego i dodatkowo pole z jezykiem


Moim zdaniem, rozwiązanie zaproponowane prze Kayne jest bardziej wydajne. Wzrost ilości rekordów nie jest raczej problemem podczas, gdy odwoływanie się do dwóch tabel w celu uzyskania danych jest bardziej obciążające.
Rozważając ten problem myślałem początkowo o zastosowaniu właśnie tablic z tłumaczeniami (trochę podobne rozwiązanie jakie opisał bela) czyli mamy tablicę z danymi np. produkty czy też osoby a mamy również w systemie tablicę tlumaczenia (id,tabela,pole,jezyk,dane) i tam zapisujemy "tłumaczenia" wartości domyślnych. Jak słusznie można zauważyć rozwiązanie pozostawia wiele do życzenia (IMG:http://forum.php.pl/style_emoticons/default/smile.gif) . Kayne natomiast otworzył mi oczy na proste i moim zdaniem bardzo wydajne i uniwersalne rozwiązanie (zmieniasz strukturę danych dodając kolejne pola nie martwisz się o języki - w bazie dodają się same).
Zastanawiałem się jeszcze nad problemem podczas obsługi na formularz i wieloma językami. Co sądzicie o takim mechanizmie: normalnie funkcjonuje domyślny formularz tylko w jednym języku, gdy chcemy dodać tłumaczenie klikamy na przycisk z wyborem języka i pojawia nam się okienko z formularzem z polami w danym języku (IMG:http://forum.php.pl/style_emoticons/default/smile.gif) and so on ...

pozdro

... tak zrobię a potem podzielę się uwagami z pola boju

Ten post edytował faster 30.04.2007, 00:20:26
Go to the top of the page
+Quote Post
Siner
post
Post #55





Grupa: Zarejestrowani
Postów: 159
Pomógł: 6
Dołączył: 2.01.2004

Ostrzeżenie: (0%)
-----


Ostatnio zastanawiam się nad wyglądem linków wielojęzykowej strony.
Z jednej strony ciekawym rozwiązaniem było by budowanie strony na zasadzie: "example.com/kontakt/" - dla polskiej wersji językowej, a "example.com/contact/" - w przypadku anglojezycznej wersji. Ale co w przypadku gdy np po niemiecku kontakt pisze się tak samo jak po polsku, można zawsze wczytywać język przeglądarki w takim wypadku i zapisywać go do sesji, ale czy to nie będzie "przyrost formy nad treścią"?

Dodatkowa sprawa to zapisywanie jak mają wyglądać linki w danym języku, pobieranie z bazy danych bądź pliku zawsze trochę zmniejszy trochę szybkość
No i jak na takie rzeczy reagują wyszukiwarki, bo zmniejsza to chyba to skuteczność trafności wyników.
Macie jakieś inne ciekawe sposoby na budowanie odnośników na stronach wielojęzykowych?
Go to the top of the page
+Quote Post
Nitryt14
post
Post #56





Grupa: Zarejestrowani
Postów: 76
Pomógł: 0
Dołączył: 17.02.2004
Skąd: Gdańsk

Ostrzeżenie: (0%)
-----


Mam podobny problem jezykowy przy tworzeniu strony moich rodzicow.
Maja biuro projektowe, a na stronce chcą miec dane kontaktowe oraz opisy wraz ze zdjąciami budynków przez nich zaprojektowanych.

Wymyśliłem nastepujace rozwiazanie:
- dane stale takie jak dane kontaktowe, wszystkie podpisy (menu, strona główna etc.) przechowywał bym w plikach lang_xx.php
- a dane zmienne (opisy budynków, zdjęć etc.) dodawał bym do bazy danych przy czym każdy język... i tu sie pojawia problem czy lepiej żeby miał osobną baze (np. sim_pl etc.) czy wystarczy osobna tabela (np. opisy_pl etc.)

chyba ze by było jakieś jeszcze lepsze rozwiązanie.
Go to the top of the page
+Quote Post
kubarek
post
Post #57





Grupa: Zarejestrowani
Postów: 43
Pomógł: 0
Dołączył: 19.02.2007

Ostrzeżenie: (0%)
-----


moja idea:
  1. <?php
  2. class language
  3. {
  4.  
  5.  function __construct($language='pl'){
  6. $this->language=$language;
  7. $this->get_data();
  8.  }
  9.  
  10.  function __get($id){
  11. return $this->data[$id];
  12.  }
  13.  
  14.  function get_data(){
  15. /* funkcja jakoś pobierze dane językowe, np z bazy danych mysql */
  16. /* mogą być to dane zapisane już jako tablica w pliku php */
  17. include 'plik_z_jezykiem_'.$this->language.'.php';
  18. /* etc. */
  19. $this->data=...
  20.  }
  21.  
  22. }
  23.  
  24. $l='pl';
  25.  
  26. $lang=new language($l);
  27.  
  28. echo $lang->10;
  29. echo $lang->1337;
  30. ?>


i w tym przypadku ( gdy zmienna $l zawiera 'pl' ), instrukcja $lang->10 może wyświetlić np. 'Witaj świecie', a po zmianie $l na en może pokazać 'Hello world', podobnie jak z np. $lang->1337

chodzi, o to, że każdy tekst ma przypisany swój unikalny id, ergo dodanie/usuwanie/modyfikowanie danych językowych nie będzie skomplikowane

to jest w przypadku jakichś stałych danych, np. komunikatów z błędami czy czegoś podobnego; nie myślałem na razie o tym, jak zrobić żeby działało dla artykułów w wielu językach
Go to the top of the page
+Quote Post
eai
post
Post #58





Grupa: Zarejestrowani
Postów: 367
Pomógł: 10
Dołączył: 20.05.2005

Ostrzeżenie: (0%)
-----


Mój sposób wygląda tak:
Plik Global_Lang.php:
  1. <?php
  2.  
  3. $glang[] = 'polish';
  4. $glang[] = 'english';
  5. $glang[] = 'spanish';
  6.  
  7. ?>


Folder __language: Zawiera pod foldery z plikami językowymi oraz z interfejsem

interface.php:
  1. <?php
  2.  
  3. $interface['val1'] = null;
  4. $interface['val2'] = null;
  5. $interface['val3'] = null;
  6. //... itd są to indexy które muszą występować w każdym pliku językowym w tym folde
    rze
  7. ?>

lang.polish.php:
  1. <?php
  2.  
  3. $lang['val1'] = 'czesc';
  4. $lang['val2'] = 'czas';
  5. $lang['val3'] = 'zegnaj';
  6. ?>


lang.english.php:
  1. <?php
  2.  
  3. $lang['val1'] = 'hello';
  4. $lang['val2'] = 'time';
  5. $lang['val3'] = 'goodbye';
  6. ?>


Klasa Language zawiera funkcje laczaca wszystkie pliki w jedna statyczna tablice (tylko aktualnie wybranego jezyka),
podczas mapowania folderow i laczenia plikow sprawdza czy sie zgadzaja indexy z plikiem interface.php jesli cos jest nie tak
wywala ostrzeżenie lub error (Klasa Exceptions). Po zmapowaniu wszystkich plikow zapisujemy sobie zserializowana tablice do pliku compiled.lang.polish.php (aktualnie wybrany język). Dzieki temu nie musimy ponownie skanować folderów, poprostu dołączamy plik z tablicą. Sprawdza rowniez czy sa wszystkie pliki z jezykami (Global_lang.php)

Umożliwia również tworzenie nowych języków z poziomu www, pobiera podfoldery z folderu __language wraz z plikiem interface.php,
wyswietla wszystko w formularzu form w krokach jeden formularz to jeden podfolder. Do póki administrator nie uzupełni wszystkich kroków nowy język nie zostanie dodany do aplikacji, jeśli wszystko uzupełnił zapisujemy nowy język w pliku.php do każdego podfolderu.

W ten sposób wykorzystuje to do stałych wartości które chce mieć w różnych językach, np wyświetlanie komunikatów o błędach, czy jakieś stałe nazwy w linkach typu Rejestracja,Register itd.. Inaczej trzeba podejść gdy chcemy mieć wielojęzyczne artykuły tutaj po stronie artykułów trzeba mieć odpowiednie funkcje które do tabeli dodadzą nam nowy język nie trzeba będzie tłumaczyć każdego artykułu podczas dodawania języka tak jak do tej pory, tylko wyświetlenie komórki z domyślnym językiem. Chociaż może to odbywać się też w klasie Language który wygeneruje nam polecenie SQL.

Według mnie takie rozwiązanie daje możliwość swobodnego zarządzania językami.
Jestem w trakcie pisania, jak dokończe pokaże jak to wyszło.
Go to the top of the page
+Quote Post
Sedziwoj
post
Post #59





Grupa: Zarejestrowani
Postów: 793
Pomógł: 32
Dołączył: 23.11.2006
Skąd: Warszawa

Ostrzeżenie: (0%)
-----


A mnie tak ciągle zastanawia, dlaczego artykuły/newsy itp. idą z id języka do bazy danych, a już np. nazwy działów lecą do plików?
Przecież to są informacje które można modyfikować, jak jeszcze założymy że tych elementów nie można przez panel admina ruszać to można by było podciągnąć pod statyczne elementy, ale przy możliwości dodania języka?

Ale może niech ktoś, kto ma jakieś pojęcie o tym wypowie, bo ja sobie tak gdybam i tylko jedna rzecz przychodzi mi do głowy, która może determinować wybór, aby za każdym razem nie pobierało danych z bazy.
Tylko że baza ma służyć do przechowywania i sprawnej dystrybucji danych...
Go to the top of the page
+Quote Post
siemakuba
post
Post #60





Grupa: Przyjaciele php.pl
Postów: 1 112
Pomógł: 20
Dołączył: 10.04.2005

Ostrzeżenie: (0%)
-----


Pojawił się w tym wątku pomysł, aby trzymać dane zależnie od języków w odpowiednich tabelach, przykładowo:
Kod
articles_pl
articles_en
articles_de


Początkowo wydało mi się to niezbyt dobre rozwiązanie, ale po zastanowieniu, może to być całkiem słuszne. Dlaczego?
  • Łatwiej dodać język, zakładając, że system wie, które z tabel są "wrażliwe na język" - wystarczy zrobić skrypt kopiujący strukturę tych tabel i zmieniający ich nazwę
  • Do obsługi danych używam klas modeli opartych na wzorcu ActiveRecord. Aby pobrać dane z tabeli articles o id=10 robię tak:
    1. <?php
    2. $this->ArticlesModel->FinById(10);
    3. ?>
    Przy nazwach tabel z dodanym oznaczeniem języka, konieczne by było posiadanie modelu dla każdej tabeli, lub co wydaje mi się prostsze i oczywiste, zbudowanie jakiegoś Factory dla tych modeli - w momencie, kiedy tworzę model, sprawdzam czy jest to tabela wrażliwa językowo i wtedy uruchamiam fabrykę. Dzięki temu, zawsze do danych o artykułach dostanę się przez $this->ArticlesModel (nie potrzebuję mieć, ArticlesPl_Model czy ArticlesDe_Model). Również przy dodaniu języka nie interesuje mnie budowa nowego modelu - factory zrobi to za mnie.
  • Może być to również słuszne z punktu widzenia danych na stronie. Przy rozwiązaniu takim: tabela articles (title_pl, title_en, title_de,...) przy wyświetlaniu danych pobierałbym przy wybranym angielskim title_en. A co jeżeli te informacje nie zostały uzupełnione? Mam puste dane? Czy może pokazuję po polsku? Przy wielu tabelach dane te są niezależne od siebie, i taki problem się nie rodzi, a przynajmniej można sobie darować dodatkowe warunki sprawdzające czy mam odpowiednie dane w takim języku (bo rekord dla tych danych zostanie utworzony jeżeli zostaną one dodane w jakimkolwiek języku)

Co o tym myślicie? Mi wydaje się całkiem słuszne, choć na chwilę obecną to tylko teoria ;)

pozdr.
Go to the top of the page
+Quote Post
Sedziwoj
post
Post #61





Grupa: Zarejestrowani
Postów: 793
Pomógł: 32
Dołączył: 23.11.2006
Skąd: Warszawa

Ostrzeżenie: (0%)
-----


Ja bym szybciej jedną tabele `article` i w niej kolumny:
id|lang_id|... PRIMARY KEY (id,lang_id)
bo obie są unikalnym identyfikatorem, zakładając że mam powiązania miedzy artykułami w różnych językach.
A wybieranie to z automatu dodawany jeden warunek, jak nie ma rekordu z takimi warunkami to nie ma, a nie tworzy bóg wie ile tabel.
Go to the top of the page
+Quote Post
siemakuba
post
Post #62





Grupa: Przyjaciele php.pl
Postów: 1 112
Pomógł: 20
Dołączył: 10.04.2005

Ostrzeżenie: (0%)
-----


@Sedziwoj - masz oczywiście rację, zdaje się, że trochę się zapędziłem :)
Jedna tabela z oznaczeniem języka dla każdego rekordu to faktycznie bardziej elegenackie rozwiązanie.

pozdr.
Go to the top of the page
+Quote Post
Black-Berry
post
Post #63





Grupa: Zarejestrowani
Postów: 663
Pomógł: 6
Dołączył: 3.06.2007
Skąd: Kraków

Ostrzeżenie: (0%)
-----


Dawno nie pisałem na forum dlatego pozdrawiam i witam wszystkich. Sporo siedziałem nad tym tematem i chciałbym pokazać swój sposób i prośić o ewentualny komentarz:

1. Tabela bazy sql "languages" zawiera pola: ID | name | short . Można ona pomiescić dowolną liczbę języków.

2. Przy starcie strony wybierany jest język o ID=1 który jest językiem głównym. Jego parametry zapisane są w sesji: $_SESSION["language"]="polish" $_SESSION["language_id"] = 1 $_SESSION["language_short"] = "pl". Teraz możemy dla całego serwisu wykożystywać te zmienne. Czasem przydają się wszystkie 3.

3. Kliknięcie na flagę języka zmajdującej się gdzieś na witrynie powodujemy zmianę tych 3 zmiennych.

4. Ładowane są odpowiednie pliki które zawierają definicje sztywne np: define( "_COM_NEWSLETTER_TITLE", "Newsletter" ); Zeby wszystko działało gładko każdy komponent ma swój plik z tłumaczeniem np "russian_newsletter.php". Każdy plik zawiera w nazwie język tak żeby przypadkiem sobie nie nadpisać przy wysyłaniu na serwer róznych plików językowych.

5. Każda tabela z tekstami wprowadzanymi do bazy zawiera pole "language" identyfikujący język. Nie tworzę osobnych tabel dla innych języków, dzięki temu przy dodaniu nowego języka nie muszę tworzyc nowych tabel dla każdego komponentu.

==================
6. Zauważyłem, że taki system pozwala na dużo ciekawych rozwiązań np:
--- Można używać języka o ID=1 jako języka głównego a resztę jako reference. Wtedy przy odpowiedniej konfiguracji serwisu jeśli jakieś tłumaczenie nie istnieje łąduje się język główny i informacja, że wyświetlony został język natywny.
--- Można wysłać do tłumacza cały folder lub plik z tłumaczeniami sztywnymi.
--- Zmienną $_SESSION["language_short"] dobrze wykożystuje się do obrazków. Serwis może dla róznych języków załadować np "logo_pl.jpg" lub "logo_en.jpg"
Go to the top of the page
+Quote Post
Nattfarinn
post
Post #64





Grupa: Zarejestrowani
Postów: 136
Pomógł: 22
Dołączył: 19.09.2007
Skąd: Sosnowiec

Ostrzeżenie: (0%)
-----


A ja się zastanawiam nad sensownością innego rozwiązania wielojęzykowości. Generalnie jeśli chodzi o treści statyczne (czy to formularze, czy proste zwroty na stronach wbudowane w szablon), to rozwiązanie na poziomie plików (sposób dowolny) wydaje się najsensowniejsze. Jeśli jednak chodzi o wielojęzykowość treści podlegających ciągłym zmianom takich jak na przykład artykuły, wiadomości i tym podobne sprawy, rozwiązanie praktycznie musi leżeć po stronie bazy danych.

Myślałem jednak nad rozwiązaniem tego w następujący sposób (to tylko czyste spekulacje, bo nie próbowałem tego wprowadzać w życie).

Tabela odpowiadająca za artykuły (w sensie produkty, bo przykładem będzie wielojęzykowość na potrzeby e-commerce) przechowywane w bazie wg. pewnego bliżej nieokreślonego, przykładowego schematu (typy pól nieistotne):

Tabela: products
Kod
Id produktu
Cena produktu
Kategoria produktu
Data dodania
Data wygaśnięcia
Id promocji
Stan magazynowy


Tabela: products_lang
Kod
Id produktu
Id/Skrót języka
Nazwa produktu
Szczegóły produktu


Czyli rozbicie samych produktów na dwie osobne tabele bazy, a samo pobieranie danych za pomocą funkcji/procedur czy widoków. Z jednej strony to trochę "brudzenie" rozbiciem na tabele, z drugiej strony nie powielamy danych. Jak wszystko: posiada zalety jak i wady.

To czy obecny język przechowujemy w zmiennej sesyjnej, czy też jako wartość bazy danych dla poszczególnych użytkowników zostawia się woli piszącego system i nie jest to rzecz istotna, dlatego nie roztrząsam tego problemu.

Ten post edytował Nattfarinn 27.12.2007, 11:19:30
Go to the top of the page
+Quote Post
acztery
post
Post #65





Grupa: Zarejestrowani
Postów: 945
Pomógł: 7
Dołączył: 15.03.2005
Skąd: katowice

Ostrzeżenie: (0%)
-----


ja stosuję metodę zapisu do bazy każdy element ma swój prefix językowy na tej podstawię identyfikuję wszystko.
Go to the top of the page
+Quote Post
Strzałek
post
Post #66





Grupa: Przyjaciele php.pl
Postów: 384
Pomógł: 6
Dołączył: 11.09.2004
Skąd: Grodzisk Mazowiecki

Ostrzeżenie: (0%)
-----


W Doctrine jest plugin do i18n. Wielojęzykowość staje się wtedy bardzo przyjemna.

http://www.phpdoctrine.org/documentation/m...ation-with-i18n
Go to the top of the page
+Quote Post
Sh4dow
post
Post #67





Grupa: Zarejestrowani
Postów: 569
Pomógł: 0
Dołączył: 17.08.2003
Skąd: Dąbrowa Górnicza

Ostrzeżenie: (0%)
-----


a jak w tym doctrine wyglada to tłumacznie ? Osobne tabele ? Bo przy jednej jezykowosci jakos to widze przy powiedzmy 6-10 prawdopodobnie zaczely by sie schody z iloscia rekordow, a nie mowiac juz o wiecej ilosci rekordow powiedzmy z wiadomosciami, opisami, cechami przedmiotow/produktow.
No i czy to by uwzglednialo powtarzajace sie frazy.

Pytam tak bo szukam jakiegos dobrego rozwiazania wielojezykowego i jedynie na chwile obecna gettext jakos dziala, ale to tez ma swoje ograniczenia.
Go to the top of the page
+Quote Post
Strzałek
post
Post #68





Grupa: Przyjaciele php.pl
Postów: 384
Pomógł: 6
Dołączył: 11.09.2004
Skąd: Grodzisk Mazowiecki

Ostrzeżenie: (0%)
-----


Przykład z dokumentacji doctrine:

news:
id | content

news_translation:
id | title | lang

W tym przypadku dla newsów będą tytuły w różnych językach. A używając doctrine wyciąga sie je tak:

  1. <?php
  2. //po wykonaniu wcześniejszego Doctrine_Query
  3.  
  4. echo $items[0]->Translation['PL']->title; // 'Witaj Świecie'
  5. ?>


Możesz jednak zmodyfikować ten plugin aby działał on inaczej. Sam plugin nie jest jakoś specjalnie skomplikowany, jak i również pisanie pluginów dla Doctrine jest proste.

Tak w ogóle to polecam Doctrine. To naprawdę bardzo dobry ORM.
Go to the top of the page
+Quote Post
lusiek
post
Post #69





Grupa: Zarejestrowani
Postów: 4
Pomógł: 0
Dołączył: 11.05.2007

Ostrzeżenie: (0%)
-----


(sorry za odkop)

Nie można po prostu użyć prefixów w bazie danych? np.
tabela

pl.news
en.news

w PHP:
  1. <?php
  2. //[...]
  3.  
  4. $lang_prefix = ('pl');
  5.  
  6.  
  7. $sql="SELECT * FROM ".$lang_prefix."news ORDER BY dodano DESC";
  8. //[...]
  9. ?>


Ten post edytował lusiek 22.05.2008, 09:12:52
Go to the top of the page
+Quote Post
empathon
post
Post #70





Grupa: Zarejestrowani
Postów: 246
Pomógł: 31
Dołączył: 13.11.2006
Skąd: się znamy?

Ostrzeżenie: (0%)
-----


Cytat(lusiek @ 22.05.2008, 10:10:58 ) *
(sorry za odkop)

Nie można po prostu użyć prefixów w bazie danych? np.
tabela

pl.news
en.news

w PHP:
  1. <?php
  2. //[...]
  3.  
  4. $lang_prefix = ('pl');
  5. $sql="SELECT * FROM ".$lang_prefix."news ORDER BY dodano DESC";
  6. //[...]
  7. ?>

Oczywiście, że możesz ale to mało elastyczne. Było to już wałkowane we wcześniejszych postach (nie przeczytałeś?).
Wiele danych będzie się powtarzać a dodanie kolejnej wersji językowej wymaga dodania tabeli.
Cytat
news
id | author_id | created_at | ...

news.translation
... | news_id | lang | title | content ...

Nie sensowniej?
Go to the top of the page
+Quote Post
.radex
post
Post #71





Grupa: Zarejestrowani
Postów: 1 657
Pomógł: 125
Dołączył: 29.04.2006

Ostrzeżenie: (0%)
-----


Mam jeden prosty i sprawdzony sposób.

  1. <?php
  2. echo __('Witaj Świecie!');
  3. ?>


I tyle. Funkcja __ wyszukuje w specjalnej tablicy dany string i do niego przyporządkowuje odpowiednie tłumaczenie.

Tablice wyglądają np. tak:

plik langs/en/cnt_test.php :

$langArray['modules/controllers/test.php']['Witaj Świecie!'] = 'Hello World';

Zamiast ['modules/controllers/test.php'] może być [''] - wtedy dane tłumaczenie będzie obejmowało wszystkie pliki.
Go to the top of the page
+Quote Post
Sedziwoj
post
Post #72





Grupa: Zarejestrowani
Postów: 793
Pomógł: 32
Dołączył: 23.11.2006
Skąd: Warszawa

Ostrzeżenie: (0%)
-----


@radex_p
Co innego tłumaczenie statycznych rzeczy, co innego dynamicznie dodawanych.
Go to the top of the page
+Quote Post
.radex
post
Post #73





Grupa: Zarejestrowani
Postów: 1 657
Pomógł: 125
Dołączył: 29.04.2006

Ostrzeżenie: (0%)
-----


Co masz na myśli? Te tablice z tłumaczeniami są (o ile dobrze zrozumiałem) statyczne.

EDIT:

Chyba już wiem, co miałeś na myśli. Napisałem "przyporządkowuje". __() nie dodaje tłumaczenia, tylko zwraca tłumaczenie stringa zawartego w argumencie.

Ten post edytował radex_p 23.05.2008, 19:57:25
Go to the top of the page
+Quote Post
Crozin
post
Post #74





Grupa: Zarejestrowani
Postów: 6 476
Pomógł: 1306
Dołączył: 6.08.2006
Skąd: Kraków

Ostrzeżenie: (0%)
-----


@radex_p - myślę, że chodziło o np. artykuł dodawany do serwisu. Który tłumaczysz na polski, angielski czy niderlandzki. (IMG:http://forum.php.pl/style_emoticons/default/winksmiley.jpg)
Go to the top of the page
+Quote Post
.radex
post
Post #75





Grupa: Zarejestrowani
Postów: 1 657
Pomógł: 125
Dołączył: 29.04.2006

Ostrzeżenie: (0%)
-----


aaaaa..... Teraz już rozumiem (IMG:http://forum.php.pl/style_emoticons/default/tongue.gif)
Go to the top of the page
+Quote Post
Sedziwoj
post
Post #76





Grupa: Zarejestrowani
Postów: 793
Pomógł: 32
Dołączył: 23.11.2006
Skąd: Warszawa

Ostrzeżenie: (0%)
-----


Dokładnie, bo można rozgraniczyć na dwa rodzaje, jeden to to co jest właściwie raz tworzone, czyli komunikaty, teksty np. "Dodaj komentarz" itp. co jest przez nas robione, drugie to są rzeczy dodawane dynamicznie, czyli artykuły, wiadomości czy co tam w aplikacji zaoferujemy. Te drugie są w bazie danych więc, oczywiste jest że wszystkie wersje językowe tam muszą być.
Co do pierwszych, no to już jak widać różne opinie, ja do opisu statusów wykorzystuję bazę danych, bo i tak muszą być w bazie przez FK. Co do tekstów, to można zrobić tak jak już było nieraz podane, przez funkcję, ale tak na prawdę skąd ona bierze te dane, to już inna sprawa, ważne jest że w kodzie widzimy tekst jaki ma się pojawić a nie jakiś jego znacznik.
Można by dyskutować, a co jak nie będzie działać baza danych? Ale tak na prawdę to jak nie działa, to już cała strona też, więc tylko komunikat o niemożliwości połączenia z bazą musi być w pliku zapisany.
Go to the top of the page
+Quote Post
joohn
post
Post #77





Grupa: Zarejestrowani
Postów: 9
Pomógł: 0
Dołączył: 10.12.2007

Ostrzeżenie: (0%)
-----


Obecnie korzystam z Symfony i podoba mi sie jak to tam jest rozwiązane.
Przypomne:
Teksty statyczne - XML i funkcja __('tekst')
Teksty dynamiczne - dwie tabele, np. products (id, symbol, item_number) i products_i18n(id,lang,name,description)

Jedyny minus Symfony to jeżeli brak tłumaczenia dla danego obiektu (np. nazwy produktu), wyświetlany jest pusty string, a w mojej aplikacji chciałbym żeby jeśli np. brak tłumaczenia polskiego, było wyświetlane tłumaczenie angielskie domyślnie. Oczywiście da się tak zrobić modyfikując propelowy generator, no ale znów generuje to dodatkowe zapytania do bazy.

Swojego czasu napisałem własny ORM który wykorzystał rozwiązanie jakiego tu jeszcze nikt nie zaproponował (IMG:http://forum.php.pl/style_emoticons/default/smile.gif)
Miałem tabele w bazie danych:
strings
id (int)
lang
content (varchar255)
texts
id (int)
lang
content(text)

gdzie id i lang były kluczem głównym. Jeżeli w którejkolwiek innej tabeli miał być content zależny od języka, oznaczałem to tak:

products
id
symbol
string_name (int)
text_description (int)

ORM w momencie pobierania obiektu z bazy danych, przed przygotowanie query, jeżeli napotkał pola z prefixem "string_" bądź "text_" robił joina z odpowiednia tabela strings bądż texts. Podobnie przy zapisie i uaktualnieniu danych.

Co sądzicie o takim rozwiązaniu? Jego zaleta to taka, że nie muszę projektować dodatkowych tabel _i18n, wystarczy że wszystkie pola zależne od języka będę oznaczał jako string_ bądż text_. Wada to oczywiście dodatkowy join w każdym zapytaniu (ale w symfony jest to samo), koniecznosc napisania wlasnego orm badz zmodyfikowania istniejacego, no i tak jak wcześniej napisałem, problem gdy chcemy korzystać z degradacji języka (czyli nie ma polskiego to angielski, nie ma angielskiego to niemiecki itp)
Go to the top of the page
+Quote Post
Sedziwoj
post
Post #78





Grupa: Zarejestrowani
Postów: 793
Pomógł: 32
Dołączył: 23.11.2006
Skąd: Warszawa

Ostrzeżenie: (0%)
-----


@joohn
Wada, to że wszystkie teksty są wrzucone do jednego worka, czyli tak na prawdę nie wiemy co to jest, tylko tyle że jakieś teksty.
Go to the top of the page
+Quote Post
rzymek01
post
Post #79





Grupa: Zarejestrowani
Postów: 592
Pomógł: 62
Dołączył: 3.08.2006

Ostrzeżenie: (0%)
-----


Witam!

Podsumowując, moim zdaniem optymalnym rozwiązaniem:
dla elementów stałych jest utworzenie przykładowej klasy Language:
  • każdy język podzielony na części (moduły, sekcje odpowiadające skryptowi)
  • format zapisu: php bądź ini
  • wynikowo klasa wczytuje odpowiedni język z odpowiednią częścią/częściami, tzn. np. dla części newsów nie wczytuje langów dla części download
lub: wykorzystanie "modyfiera" Smarty, innego gotowego rozwiązania


dla elementów dynamicznych (każdy język -> inna treść):
  • możemy ograniczyć się do jednej tabeli (plus tabela lang, czytaj dalej)
  • tabela, która w swoich kolumnach posiada wszystkie niezbędne info
    1. [b]artykuly[/b]
    2. id | autor_id | lang_id | tytul | zawartosc | ogladany | komentarzy | ocena | ...
    3. -------------------------------------------------------------------------------------
    4. 1 | 476 | 1 | PHP 6 | content.. | 23 | 9 | 5 | ...

  • w takim układzie do wyświetlenia przykładowo listy artykułów pl wystarczy dodać do where,np. lang=1 (gdzie 1 to np. pl):
    1. SELECT tytul, ogladany, ocena FROM artykuly WHERE lang = 1

  • przy tym rozwiązaniu każdy artykuł ma swoje komentarze (artykuł pl -> komentarze pl)
dla elementów dynamicznych (każdy język -> taka sama treść):
  • potrzebujemy dwóch tabeli (plus tabela lang, czytaj dalej)
  • tabela główna, która nie zawiera treści artykułu, lecz inne info na jego temat
    1. [b]artykuly[/b]
    2. id | ogladany | komentarzy | ocena | ...
    3. -----------------------------------------------------------------------------------------------
    4. 1 | 23 | 9 | 5 | ...

  • tabela zawierająca treść artykułów w różnych wersjach językowych
    1. [b]artykuly_lang[/b]
    2. ... | art_id | lang_id | tytul | zawartosc | ...
    3. -----------------------------------------------------------------------------------------------
    4. ... | 1 | 1 | PHP 6 | content.. | ...

  • przy tym rozwiązaniu komentarze dla każdego artykułu są zbiorcze (czyli mogą występować komenty w różnych językach)
EDIT:
by Sedziwoj: tabela z językami
  1. [b]lang[/b]
  2. id | short_name | name
  3. --------------------------
  4. 1 | pl | Polski


Oczywiście, że istnieją inne rozwiązania jak np. tabele pl_news, en_news, lecz te sposoby, które przedstawiłem wydają mi się najbardziej elastyczne i uniwersalne.

Pozdrawiam!

Ten post edytował rzymek01 30.05.2008, 13:45:44
Go to the top of the page
+Quote Post
Sedziwoj
post
Post #80





Grupa: Zarejestrowani
Postów: 793
Pomógł: 32
Dołączył: 23.11.2006
Skąd: Warszawa

Ostrzeżenie: (0%)
-----


@rzymek01
Jak masz kolumnę lang, to niech to będzie integer, po co męczyć bazę stringiem, do tego najlepiej lang_id, i tabela gdzie jest id|short_name|name czyli skrócona nazwa języka np. PL i pełna Polski.
Go to the top of the page
+Quote Post
rzymek01
post
Post #81





Grupa: Zarejestrowani
Postów: 592
Pomógł: 62
Dołączył: 3.08.2006

Ostrzeżenie: (0%)
-----


racja, mój błąd (IMG:http://forum.php.pl/style_emoticons/default/smile.gif)

nie chciałem już mieszać, bo na początku chciałem zrobić lang_id
Go to the top of the page
+Quote Post
Blodo
post
Post #82





Grupa: Zarejestrowani
Postów: 51
Pomógł: 1
Dołączył: 1.02.2005

Ostrzeżenie: (0%)
-----


Kolejny odkop no ale..

Ja uzywam dwoch tabel: jedna dla tzw. metadata czyli ID, kategoria; druga dla samych tlumaczen. Przypisuje im jezyk za pomoca lang_id w drugiej tabeli, I wyciagam z bazy za pomoca JOINa. Ogolnie ten skrypt co mam automatycznie wybiera jezyk przegladarki dla uzytkownika, lub - jezeli nie ma takiego jezyka w systemie - wybiera jezyk domyslny (angielski).

Zakladajac ze w bazie danych nie zawsze bedzie tlumaczenie dla kazdego artykulu w jezyku uzywanym w tym momencie przez uzytkownika, jak moznaby sformulowac zapytanie do SQLa tak aby przy wyciaganiu artykulow dla danej kategorii wyciagalo wszystkie artykuly w wersji jezykowej uzytkownika lub w wersji jezyka domyslnego jezeli poprzednie sie nie powiodlo? Poki co moim rozwiazaniem jest SELECT na wszystkie lang_id, i potem sprawdzanie co wyswietlic a co nie za pomoca PHP, ale to troche badziewne rozwiazanie IMO. Ktos sie natknal na taki problem?
Go to the top of the page
+Quote Post
Sedziwoj
post
Post #83





Grupa: Zarejestrowani
Postów: 793
Pomógł: 32
Dołączył: 23.11.2006
Skąd: Warszawa

Ostrzeżenie: (0%)
-----


@Blodo
Może coś w tym stylu:
  1. SELECT * FROM base_data AS b LEFT JOIN lang_data AS l ON ( l.base_data_id = b.id AND l.lang_id = x) LEFT JOIN lang_data AS l2 ON (l2.lang_id = y AND l.id IS NULL);

x - id wybranego języka
y - id domyślnego języka
To jest na JOIN, ale mam parę pomysłów na inne rozwiązania, tylko raczej nie wydajniejsze.
Go to the top of the page
+Quote Post
Blodo
post
Post #84





Grupa: Zarejestrowani
Postów: 51
Pomógł: 1
Dołączył: 1.02.2005

Ostrzeżenie: (0%)
-----


Hmm, dobry pomysl. Co prawda trzeba w php potem sprawdzic ktore pole z tabeli nie jest "NULL", no ale i tak lepiej niz bylo. Dzieki ci za to.
Go to the top of the page
+Quote Post
Sedziwoj
post
Post #85





Grupa: Zarejestrowani
Postów: 793
Pomógł: 32
Dołączył: 23.11.2006
Skąd: Warszawa

Ostrzeżenie: (0%)
-----


Cytat(Blodo @ 8.07.2008, 00:24:09 ) *
Hmm, dobry pomysl. Co prawda trzeba w php potem sprawdzic ktore pole z tabeli nie jest "NULL", no ale i tak lepiej niz bylo. Dzieki ci za to.


No to zrób jeszcze jedno użyj CASE... i wtedy w php nic nie robisz, tylko wyświetlasz.
Go to the top of the page
+Quote Post
Albitos
post
Post #86





Grupa: Zarejestrowani
Postów: 37
Pomógł: 4
Dołączył: 6.08.2006
Skąd: Lublin

Ostrzeżenie: (0%)
-----


Wybaczcie, że odgrzewam temat. Baardzo długo zastanawiałem się nad rozwiązaniem wielojęzykowości w moich skryptach. Końcowo doszedłem do wniosku, że idealnym rozwiązaniem będzie wykorzystanie systemu wbudowanego w OPT oraz kilku ciekawych ulepszeń. Po pierwsze, wszystkie stałe językowe przechowywane są w kategoriach niezależnych od czegokolwiek. Grupujesz jak chcesz, potem wczytujesz te grupy. Wczytanie jednej stałej z grupy powoduje wczytanie wszystkich z danej grupy.

Załóżmy, że mamy takie grupy:
  • navigation
  • contact
  • home
  • global
Teraz struktura plików:
languages/pl/
navigation.php
contact.php
home.php
global.php
languages/en/
navigation.php
contact.php
home.php
global.php

Każdy plik PHP składa się z tablicy $lang, która zawiera stałe. Dlaczego akurat tablica, a nie jakiś XML/YAML? Otóż z bardzo banalnego powodu. W pewnym momencie, kiedy pracowałem nad grą internetową (http://orodlin.pl) okazało się, że stałych odpowiedzialnych za niektóre akcje jest bardzo dużo (w jednym pliku ponad 500), natomiast wykorzystywana jest tylko jedna. Ładowanie wszytkich takich danych przy pomocy parsera byłoby całkowicie bezcelowe - marnotrawstwo pamięci.
Dlatego zamiast tablicy stworzyłem obiekt implementujący interfejs ArrayAccess, który pobiera potrzebne stałe prosto z bazy danych. Muszę przyznać, że jestem z takiego rozwiązania bardzo zadowolony. Wszystkie stałe są pogrupowane w logiczne kategorie, w razie konieczności przechowania większych ilości danych, używam odpowiedniego obiektu bez modyfikowania samego systemu językowego.
Pozostał tylko jeden zasadniczy problem - rozbicie wszystkich stałych na kilka plików wymusza wczytanie za każdym razem kilku plików. Ten problem rozwiązałem, używając cache. Wszystkie stałe, o ile nie pochodzą z dynamicznych tablic (tych obiektów implementujących ArrayAccess) zapisuję przy pomocy jednej wielkiej zserializowanej tablicy i zapisuję w pliku. Każda akcja w kontrolerze ma taki swój własny plik. W ten sposób kilka plików ładowanych jest tylko za pierwszym razem.

Jestem w trakcie pisania pluginu do OPT który będzie realizował taki system. Mam nadzieję, że wszystkim się spodoba. Tymczasem chciałbym poznać wszystkich opinie, co sądzą o takim rozwiązaniu.

EDIT: Co do danych dynamicznych, w Orodlinie istnieje założenie, że gra = jeden język. W innych projektach, gdy muszę mieć różne wersje językowe dynamicznych danych (np. artykułów), po prostu w tabeli dodaję pole określające język.

Ten post edytował Albitos 19.08.2008, 15:19:07
Go to the top of the page
+Quote Post
tomek_swat
post
Post #87





Grupa: Zarejestrowani
Postów: 72
Pomógł: 0
Dołączył: 3.04.2008

Ostrzeżenie: (0%)
-----


mam pytanie jak sobie radzicie z wersją językową przechwyconych wyjątków, w każdej klasie jest:
  1. <?php
  2. throw new exception (..)
  3. ?>

i jak to uzależnić od wyboru języka, ja trzymam wszystkie klasy w folderze /classes i właśnie rozwiązanie tego problemu sprawia mi kłopoty?
pzdr
Go to the top of the page
+Quote Post
Crozin
post
Post #88





Grupa: Zarejestrowani
Postów: 6 476
Pomógł: 1306
Dołączył: 6.08.2006
Skąd: Kraków

Ostrzeżenie: (0%)
-----


Ale w jakim celu tłumaczyć wyjątki? One są raczej informacją dla programu/skryptu, a nie użytkownika.

Możesz:
1) Przeklazać już odpowiednio przetłumaczony wyjątek:
  1. <?
  2. throw new Exception(myTransolator('invalidABCDE'));
  3. ?>

2) Napisać właśną klasę wyjątków, która robi to co kod powyżej, ale już wewnątrz siebie:
  1. <?
  2. class MyException extends Exception{
  3.  public function __construct($msg = '', $code = 0){
  4.    $this->msg = myTranslate($msg);
  5.    $this->code = $code;
  6.  }
  7. }
  8. ?>
Ale jeszcze raz zapytam: po co?
Go to the top of the page
+Quote Post
tomek_swat
post
Post #89





Grupa: Zarejestrowani
Postów: 72
Pomógł: 0
Dołączył: 3.04.2008

Ostrzeżenie: (0%)
-----


załóżmy, że mam klasę Config, która jest Singletonem i pobiera z pliku .ini wersję jęzkową systemu
jezyk = "pl" i w zależności od tego klasa Lang, parsuję odpowieni plik .ini z folderu gdzie znajdują się odpowiednie wersję językowe
co jeśli w pliku settings.php parsowanym przez klasę Config, użytkownik wpiszę język, który nie jest uwzględniony w folderze w którym znajdują się wersję językowe? pozostaję wypluć wyjątek, tu właśnie pojawia się w problem w jakim on ma być języku i jak ten język zaimplementować w klasie Lang i Config?
pzdr
Go to the top of the page
+Quote Post
Sedziwoj
post
Post #90





Grupa: Zarejestrowani
Postów: 793
Pomógł: 32
Dołączył: 23.11.2006
Skąd: Warszawa

Ostrzeżenie: (0%)
-----


Nie zawsze wyjątki są najlepsze, powinieneś sprawdzić czy dany język istnieje jeśli nie to ustawiany jest domyślny. Jeśli gdzieś w serwisie jest użyte coś, czego nie ma w pliku językowym to jest błąd, i taka informacja też nie musi być rozpowszechniana po prostu wymuszenie przez moduł językowy załadowania informacji o błędzie/braku informacji, to już jest statyczna informacja niezależna od błędu, no i log dla nas aby dojść co się sypnęło.
Go to the top of the page
+Quote Post
test_next
post
Post #91





Grupa: Zarejestrowani
Postów: 9
Pomógł: 0
Dołączył: 23.11.2007

Ostrzeżenie: (0%)
-----


Witam,
tak pobieżnie przeglądając odpowiedzi nie widziałem sposobu z definiowaniem zmiennych językowych jako stałe np. define('HELLO_WORLD","Hello world"); echo HELLO_WORLD. Co o tym sądzicie?
Pozdrawiam
Go to the top of the page
+Quote Post
erix
post
Post #92





Grupa: Moderatorzy
Postów: 15 467
Pomógł: 1451
Dołączył: 25.04.2005
Skąd: Szczebrzeszyn/Rzeszów




Mało przenośne. Co w sytuacji, gdy np. stała konfiguracyjna będzie nosiła tę samą nazwę jak językowa?

Poza tym, wg Twojego schematu idealny byłby gettext" title="Zobacz w manualu PHP" target="_manual.
Go to the top of the page
+Quote Post
test_next
post
Post #93





Grupa: Zarejestrowani
Postów: 9
Pomógł: 0
Dołączył: 23.11.2007

Ostrzeżenie: (0%)
-----


tak tylko aplikacja ma być przenośna, a gettext nie wszędzie jest zainstalowany.
No i jeszcze wchodzi w grę licencja tego typu rozwiązań - odpada GPL.
Go to the top of the page
+Quote Post
viking
post
Post #94





Grupa: Zarejestrowani
Postów: 6 381
Pomógł: 1116
Dołączył: 30.08.2006

Ostrzeżenie: (0%)
-----


To zainteresuj się Zend Framework (i zanim napiszesz coś o gettext przeczytaj dokładnie dokumentację).
Go to the top of the page
+Quote Post
test_next
post
Post #95





Grupa: Zarejestrowani
Postów: 9
Pomógł: 0
Dołączył: 23.11.2007

Ostrzeżenie: (0%)
-----


To include GNU gettext support in your PHP build you must add the option --with-gettext[=DIR]
przeczytałem i ?
Go to the top of the page
+Quote Post
bim2
post
Post #96





Grupa: Zarejestrowani
Postów: 1 873
Pomógł: 152
Dołączył: 9.04.2006
Skąd: Berlin

Ostrzeżenie: (0%)
-----


Nie miałem siły przeglądać całego watku, ale moim zdaniem najlepszym wyjściem jest podany 3 posty wyżej przez erixa sposób. gettext" title="Zobacz w manualu PHP" target="_manual Oczywiście jakaś nakładka na to co by zapamiętała jakie frazy używam w systemie i generacja pliku .po A później już z górki :]

Przez 2 lata używałem zwykłych zmiennych includowanych do klasy języków i metodą get() pobierania ich. Ale to nie jest wyjście. Ciężko się połapać w tym wszystkim.
Go to the top of the page
+Quote Post
viking
post
Post #97





Grupa: Zarejestrowani
Postów: 6 381
Pomógł: 1116
Dołączył: 30.08.2006

Ostrzeżenie: (0%)
-----


Cytat(test_next @ 2.07.2009, 12:51:36 ) *
To include GNU gettext support in your PHP build you must add the option --with-gettext[=DIR]
przeczytałem i ?

Mówiłem o ZF.

Cytat
The Zend_Translate Gettext Adapter is not implemented using PHP's gettext extension. You can use the Gettext Adapter even if you do not have the PHP gettext extension installed. Also the Adapter is thread-safe and the PHP gettext extension is currently not thread-safe.
Go to the top of the page
+Quote Post
test_next
post
Post #98





Grupa: Zarejestrowani
Postów: 9
Pomógł: 0
Dołączył: 23.11.2007

Ostrzeżenie: (0%)
-----


viking: ok, ale aplikacja jest dosyć rozbudowana i nie ma już sensu przenosić jej na zend'a...
Go to the top of the page
+Quote Post
Crozin
post
Post #99





Grupa: Zarejestrowani
Postów: 6 476
Pomógł: 1306
Dołączył: 6.08.2006
Skąd: Kraków

Ostrzeżenie: (0%)
-----


Zapewne da się ten komponent "wyciąć" z niego i stosować osobno.
Go to the top of the page
+Quote Post
erix
post
Post #100





Grupa: Moderatorzy
Postów: 15 467
Pomógł: 1451
Dołączył: 25.04.2005
Skąd: Szczebrzeszyn/Rzeszów




Cytat
tak tylko aplikacja ma być przenośna, a gettext nie wszędzie jest zainstalowany.

Zobacz sobie, jak jest emulowane to rozszerzenie w Wordpressie.
Go to the top of the page
+Quote Post

9 Stron V   1 2 3 > » 
Reply to this topicStart new topic
2 Użytkowników czyta ten temat (2 Gości i 0 Anonimowych użytkowników)
0 Zarejestrowanych:

 



RSS Aktualny czas: 4.02.2026 - 11:16