Pomoc - Szukaj - Użytkownicy - Kalendarz
Pełna wersja: Proste tłumaczenie strony w locie - prośba o pomoc
Forum PHP.pl > Forum > Gotowe rozwiązania > Szukam
Dopler
Znalazłem tutaj dwa tematy o tłumaczeniu ale jakoś nie rozwiązują one mojego problemu.

Mam strony html (tekstowe drzewka genealogiczne) które są zbudowane z powtarzających się słów oraz z nazwisk. "Słowa" takie jak:
ur. zm. ojciec matka .....

chciałbym móc w prosty sposób stronę wyświetlić w innym języku korzystając z bazy MSQL. Trzymał bym tam wszystkie z możliwych słów które wymagają tłumaczenia
b. d. father mother ....

wynik wyświetlany byłby w formie strony php - która korzystając z owej html i bazy wyświetlała gotowe drzewko genealogiczne np. w angielskim.
kromieszewski.html --> kromieszewski_ang.php --> kromieszewski_fr.php -->

wydaje mi się że to bardzo prosta sprawa ale nie jestem biegły. mogę liczyć na pomoc ?

Tłumacz Google się nie bardzo nadaje - po pierwsze nie potrzebuje tłumaczyć całych tekstów, po drugie nazwiska często mają formę rzeczowników np. Katarzyna Ogień to Katarzyna Ogień a nie "Katherine Flame", po trzecie google nie tłumaczy prawidłowo skrótów genealogicznych.
mikiroro
Zrób zmienną $jezyk albo $lang która będzie miała wartość 'pol', 'eng', 'ger', 'fra' itd.
Potem tablice ze słowami:
  1. $words['pol'] = array('ur.'=>'ur.', 'zm.'=>'zm.', 'ojciec'=>'ojciec', 'syn'=>'syn', 'matka'=>'matka');
  2. $words['eng'] = array('ur.'=>'b.', 'zm.'=>'d.', 'ojciec'=>'father', 'syn'=>'son', 'matka'=>'mother');
  3. $words['ger'] = array('ur.'=>'Geb.', 'zm.'=>'Gestorben.', 'ojciec'=>'Vater', 'syn'=>'Sohn', 'matka'=>'Mutter');
  4. $words['fra'] = array('ur.'=>'né.', 'zm.'=>'Mourut.', 'ojciec'=>'p?re', 'syn'=>'fils', 'matka'=>'m?re'); // na forum jest złe kodowanie, więc literki z akcentami się źle pokazują
  5. // i tak dalej


potem jak będzie do wyświetlenia jakiś napis, to:
  1. echo $words[$lang]['ur'].' 12.03.1960';

zamiast:
  1. ur. 12.03.1960


tylko na początku daj:
  1. $lang = $_GET['lang'];
  2. if(!isset($words[$lang]))
  3. $lang='pol';


Stronę otwierasz:
kromieszewski.php?lang=eng
(na przykład, a jak nie podasz parametru, to będzie po polsku)
Dopler
Dzięki za pomoc, jednak potrzebne by było nieco inne rozwiązanie.
Ta metoda ma jedną wadę - mianowicie teskt trzeba napisać z dużą ilością kodowania php.
Niestety struktura serwisu wymaga aby tekst był niemal jak w Worszie (jest on nawet w znacznikach "pre" aby nie trzeba było dawać znaku końca linijki oraz żeby linijki się nie zawijały na stronie

Przykład strony w skrócie (strona HTML-owa ! abecadlo.htm)
Cytat
-html-
-head-
-/head-
-body-
nagłówek strony
-pre-

1. Jacek Abecadło ur. 1658 Warszawa, zm. 25.11.1672 Piotrków, leśnik
1.1. Rozalia Abecadło, chrz. 1692 + Julian Bęc, hetman wielki koronny
1.2. Hermenegilda Abecadło + Pomponiusz Cudak "Platfus", ur. Zgierz, własność ziemska: Kormorany, Zgierz
...


-/pre-
stopka
-/body-
-/html-


Tekst w dziale -pre- jest więc niemal taki jakby był w pliku "txt"

Silnik tłumaczenia powinien być następujący:

Strona abecadlo.php (inna niż abecadlo.htm)
-korzysta z dwóch plików
-- abecadlo.htm - jako tekstu
-- slownik.txt (np.), lub z bazy SQL, lub tabeli - cokolwiek - jako zestawu słów do tłumaczenia
-wynik wyświetla słowo po słowie dokonując jego tłumaczenia jeśli słowo jest w słowniku.

a więc np:
Cytat
1. Jacek Abecadło b. 1658 Warsaw, d. 25.11.1672 Piotrków, forester
1.1. Rozalia Abecadło, bapt. 1692 + Julian Bęc, Hetman of the Crown
1.2. Hermenegilda Abecadło + Pomponiusz Cudak "Platfus", b. Zgierz, landed property: Kormorany, Zgierz



Chodzi o to że strona abecadlo.htm zmienia się często (zawartość działu -pre-) użytkownicy nie mają wiedzy na temat html-a, przysyłają więc dane w formie worda, przetwarzanie tego za każdym razem na ciąg php typu "echo ..." spowodowałoby kolosalne obciążenie i uniemożliwiło by działanie strony i redakcji.
Na stronie może być więc link do strony "php" - automatyczne tłumaczenie
Ponieważ stron typu abecadlo.htm jest mnóstwo, potrzebne jest aby wszystko się działo poza tą stroną i korzystało z jednego silnika.
skowron-line
Może google translate api
z tym że ma on ograniczoną ilość słów do przesłania i zamianę. Ale można w JS zrobić aby akapit po akapicie wysyłał i tłumaczył.
Dopler
google translacja w tym wypadku kompletnie nie ma zastosowania
jak pisałem z dwóch przyczyn

1. są tam charakterystyczne skróty które google źle interpretuje
2. Są nazwiska w formie rzeczownika np. "Grzegorz Koń" i nie potrzebuję mieć "Grzegorz Horse"

Zresztą jakość tłumaczenia jest wciąż strasznie mizerna.

Wydaje mi się że taki silnik php o jakim pisałem powinien być prosty do zrobienia.

1. pobierz słowo
2. sprawdź czy istnieje tłumaczenie
3a. jeśli tak- pisz tłumaczenie
3b. jeśli nie - pisz słowo
4. przejdź do kolejnego słowa
mikiroro
W takim razie umieść raczej to, co w <pre> w pliku txt i abecadlo.html niech będzie php, a tam plik załączysz przez file_get_contents().
Więc najpierw umieść zawartość bloku <pre> w pliku family.txt, a następnie stwórz plik z tłumaczeniami w postaci:
Kod
ojciec>father
matka>mother

i zapisz jako eng.txt
zamiast > może być byle co, np tab.

  1. $family = file_get_contents('family.txt');
  2. if(!file_exists("{$lang}.txt")) $lang='pol'; // jeśli nie można znaleźć "słownika", to ustaw polski
  3.  
  4. if($lang!='pol') // tłumaczymy tylko, jeśli nie ma być po polsku
  5. {
  6. foreach(file($lang.'.txt') as $word)
  7. {
  8. list($find,$replace)=explode('>', trim($word)); // jak mówiłem, zamiast > dowolny separator
  9. $family = str_replace($find, $replace, $family);
  10. }
  11. }


i potem:
<pre>
<?php
echo $family;
?>
</pre>

No i nie próbuj używać pliku HTML jako bazy danych. Do tego są pliki xml i tekstowe.
A poza tym żeby były html-owe przejścia do nowej linii, a nie zależy Ci na zachowaniu spacji i czcionki o stałej szerokości, to możesz użyć funkcji PHP nl2br().
Dopler
dzięki wielkie - to już bliżej ale...
nie rozumiem - czyli nie można do jednego pliku php pobrać tekstu z pliku o dowolnym rozszerzeniu ? np. family.htm ? tak to utrudnia sprawę ?

upieram się - że plik *.htm jako wersja wyjściowa polska MUSI pozostać, cały system ma zbyt dużo spraw z tym związanych - np. automatyczne bbcody w innych bazach, tysiące linków rozrzuconych po różnych stronach.

chodzi o to aby wersje językowe były DRUGIM plikiem - i on może być php. Pobierać tekst z htm a tłumaczenie z txt czy whatever czyli

family.htm - źródło polskie, strona podstawowa
family.php (z silnikiem) wyświetlająca tłumaczone wersje
ang.txt
fr.txt
...
mikiroro
Ostatecznie można tak zrobić. Tylko wtedy musisz wyraźnie zaznaczyć, gdzie zaczyna się i kończy część, która ma być przetłumaczona.
Na przykład zrób:
  1. <!--start-->
  2. <pre>
  3. ...
  4. </pre>
  5. <!--koniec-->


i wtedy:
  1. $family = file_get_contents('abecadlo.html');
  2. $start_pos = strpos($family, '<!--start-->');
  3. $end_pos = strpos($family, '<!--koniec-->');
  4. $length = $start_pos-$end_pos;
  5. $to_translate = substr($family, $start_pos, $length);
  6. // i teraz na ciągu $to_translate wykonujesz operację tłumaczenia, którą opisałem w moim poprzednim poście
Dopler
"tak czułem, cholera tak czułem" (j.Stuhr, Seksmisja)
Dzięki na prawdę wielkie!, to świetnie rozwiązuje sprawę.
Zaraz postaram się zrobić i zdam sprawę z rezultatu.

Faktycznie działa fajnie, tzn ... yyy.... działało, ale coś chyba spiep... i nie widzę gdzie twki błąd.
Troszkę przerobiłem bo translacja robiła:

nagłówek
nagłówek przetłumaczony
tekst przetłumaczony
koniec przetłumaczony
koniec

dodałem jeszcze tymczasowo tekst ostrzegający, ponadto też tymczasowo każde słowo przetłumaczone w słowniku ma dodane styl na czerwono.

wygląda to tak:
Kod
<?php

$lang = $_GET['lang'];

$family = file_get_contents('zboinski.htm');

$poczatek_strony = strpos($family, '<html>');
$poczatek_tlum = strpos($family, '<pre '); //taki zapis - gdyż znacznik <pre> ma parametry
$koniec_tlum = strpos($family, '</pre>');
$koniec_strony = strpos($family, '</html>');

$od_poczatku = substr($family, $poczatek_strony, $poczatek_tlum);
$do_konca = substr($family, $koniec_tlum, $koniec_strony);

$tlum_length = $koniec_tlum-$poczatek_tlum;
$to_translate = substr($family, $poczatek_tlum, $tlum_length);


if(!file_exists("{$lang}.txt")) $lang='pol'; // jeśli nie można znaleźć "słownika", to ustaw polski
  
if($lang!='pol') // tłumaczymy tylko, jeśli nie ma być po polsku
{
   foreach(file($lang.'.txt') as $word)
   {
     list($find,$replace)=explode('¤',trim($word)); // separator (może być dowolny)
     $translated = str_replace($find, $replace, $to_translate);
   }
}

else // jeśli po polsku - tylko przenosi tekst
{
$translated = $to_translate;
}


echo $od_poczatku;
echo '<span style="color: red">English automatical translation of some particular words. Page may by corrupted</span>
';
echo $translated;
echo $do_konca;
?>


Efekt jest do zobaczenia w pliku
http://genealogia.okiem.pl/zboinski.php?lang=ang

I tu jest problem - bo w sumie wszystko działa ale..

tłumaczone jest tylko jedno słowo - dokładnie to które jest w najniższej linijce pliku ang.txt, wcześniejsze są pomijane.

* miałbym jeszcze prośbę żeby przy tłumaczeniu słowa tłumaczone były na kolorowo, (może się odnosić do stylu który zadam w css - n. "ang", "fr") - próbowałem i nie umiem tego dodać. Ale to już kosmetyka. Zastanawiam się też nad tym aby silnik był w jakimś jednym pliku i żeby bie trzeba było tworzyć dla wszystkich nazwisko.htm plików nazwisko.php - ale to potem.
mikiroro
Cytat(Dopler @ 30.01.2010, 15:13:30 ) *
  1.  
  2. <?php
  3. // [...]
  4. list($find,$replace)=explode('¤',trim($word)); // separator (może być dowolny)
  5. $translated = str_replace($find, $replace, $to_translate); // <- tutaj bug
  6. // [...]
  7. ?>

Musi być:
  1. $translated = str_replace($find, $replace, $translated);
  2. // ten sam ciąg, jasne?


Masz jeszcze błąd HTML:
  1. <p<span style="color: red">English automatical translation of some particular words. Page may by corrupted</span><br>
Dopler
Trochę nie rozumiem więc jak to działa - ale nie szkodzi - ważne że działa

teraz prośba kosmetyczna - jak zrobić żeby tłumaczone słowo miało styl (taki jak lang)
Czyli zamiana postępuje tak:

blablabla => style=$lang blablabla /style

(w uproszczeniu)
mikiroro
No, tak jak zrobiłeś kolorowanie. A jeżeli ten $lang ma być wartością zmienną, trzeba użyć wyrażeń regularnych, co jest już wyższą szkołą jazdy.
pyro
Przyznam szczerze, że nie chciało mi się czytać całego tematu. Spojrzałem tylko na kody, czy ktoś nie podał takiego rozwiązania:

Pliki językowe:

pl.lang
  1. <?php
  2. // Polski
  3. define('MOTHER', 'Matka');
  4. define('FATHER', 'Ojciec');
  5. ?>


en.lang
  1. // English
  2. define('MOTHER', 'Mother');
  3. define('FATHER', 'Father');


I teraz generowanie strony:

  1. $languages = array('pl', 'en');
  2. if(in_array($_GET['lang'], $languages))
  3. {
  4. require_once('lang/'.$_GET['lang'].'.lang');
  5. }
  6. else
  7. {
  8. require_once('lang/pl.lang');
  9. }
  10.  
  11. // Wyświetlanie
  12. echo MOHTER.': 1732-1990<br />';
  13. echo FATHER.': 1420-1710';
Dopler
Cytat
No, tak jak zrobiłeś kolorowanie. A jeżeli ten $lang ma być wartością zmienną, trzeba użyć wyrażeń regularnych, co jest już wyższą szkołą jazdy.


no nie - bo w css zrobie po prostu style "ang" "fr" "niem" "rus" itp .... po jednym do każdego pliku słownika. Załączenie css jest w nagłówku html-a więc to nie problem

Chodzi tylko żeby

$find - - zmieniał na - - - coś1 $lang $replace coś2

gdzie coś1 i coś2 będą stałe.


ps. Stronka już bardzo ładnie chodzi - wszystkie pliki nazwiskowe się same tłumaczą, Kod umieściłem w pliku tlumacz.php i dałem żeby nazwę pliku pobierał z referera. Link na każdej ze stron wygląda tlumacz.php?lang=ang
Na tlumaczu dodałem jeszcze powrót do pliku referer

ps2. pyro - dzięki, tylko że jak pisałem chodzi nie o wersje jednej strony, tylko o tłumaczenie odcinków istniejących stron htm

ps3. UDAŁO SIE - Zrobiłem tak:

Kod
    list($find,$replace)=explode('¤',trim($word)); // separator (może być dowolny)
     $pieces = array('<span class="',$lang,'">',$replace,'</span>');
     $polacz = implode($pieces);
     $to_translate = str_replace($find, $polacz, $to_translate);

mikiroro
Zgłaszam buga:
pokazuje "sbef.ał" zamiast "sprzedał"
(tłumaczy przed na bef.)
Niestety, nie wiem, jak tłumaczyć tylko całe wyrazy.
Fifi209
Zrobiłem dla Ciebie coś takiego:
  1. <?php
  2.  
  3. $dict = file('dict.txt');
  4.  
  5. $dict_ap = array();
  6. $dict_pa = array();
  7.  
  8. foreach ($dict as $value) {
  9. list($pl_w, $ang_w) = explode(':', $value);
  10. $dict_ap[trim($ang_w)] = trim($pl_w);
  11. $dict_pa[trim($pl_w)] = trim($ang_w);
  12. }
  13.  
  14. function translate($dict, $string) {
  15. $reg = '#<translate>(.*)</translate>#is';
  16. preg_match($reg, $string, $matches);
  17. $words = preg_split('#([\s]{1,1})#', $matches[1]);
  18. $str = '';
  19. foreach ($words as $value) {
  20. if (array_key_exists($value, $dict)) {
  21. $str = $str.' '.$dict[$value];
  22. }else{
  23. $str = $str.' '.$value;
  24. }
  25. }
  26. return $str;
  27. }
  28.  
  29. $txt = translate($dict_pa, file_get_contents('text.txt'));
  30.  
  31. echo $txt;
  32.  
  33. $txt = translate($dict_ap, file_get_contents('text.txt'));
  34.  
  35. echo '<br/>'.$txt;
  36.  
  37. ?>


Plik dict.txt:
Kod
tekst:text
zostanie:will
przetłumaczony:translated


Plik text.txt:
Kod
to jest jakiś tekst

<translate>
tekst zostanie
przetłumaczony
a to nie
</translate>

to inny tekst


Tłumaczy w obie strony.
Dopler
mikiroro:

Cytat
Zgłaszam buga:
pokazuje "sbef.ał" zamiast "sprzedał"
(tłumaczy przed na bef.)
Niestety, nie wiem, jak tłumaczyć tylko całe wyrazy.


a ja wiem jak
wystarczy w słowniku dać
zamiast linijki

Kod
przed¤bef.


linijkę ze spacjami przed i po słowach (tu się to nie wyświetla dobrze)

Kod
przed ¤ bef.


tylko na końcu trzeba dać znak twardej spacji - czyli

Kod
przed ¤ bef. 



fifi209

Dzięki za pracę. Ja już system mikiroro zainstalowałem, teraz go tylko dopracowuje - działa (choć ma drobne wady)

Z tego co widzę w Twoim jest tylko angielskie, a w tym co już jest jest możliwość dodania kolejnych języków bardzo prosto. Ale za pewne i ten się da dostosować.



w każdym razie system działa na
www.genealogia.okiem.pl (strony nazwisk - z listy po lewej stronie)
Fifi209
Cytat(Dopler @ 1.02.2010, 21:56:50 ) *
Z tego co widzę w Twoim jest tylko angielskie, a w tym co już jest jest możliwość dodania kolejnych języków bardzo prosto. Ale za pewne i ten się da dostosować.

Przecież możesz wczytać dowolny słownik, w dodatku przystosowałem tak aby działał w obie strony - a z angielskim to był tylko przykład.
Dopler
sorry - ja się aż tak nie znam

dlatego też trudno mi ocenić czy ten system jest lepszy czy gorszy - a tamten już działa

jakie są zalety oprócz działania w obie strony ? - mi potrzeba tylko
pol=>tlumaczenia
Fifi209
Cytat(Dopler @ 2.02.2010, 00:12:22 ) *
jakie są zalety oprócz działania w obie strony ? - mi potrzeba tylko
pol=>tlumaczenia

Właśnie możliwość łatwej wymiany słownika, tylko zmieniasz plik z którego ma czytać słownik. Ja to zrobiłem bardziej do przykładu - z myślą, że może się komuś przyda. haha.gif
To jest wersja lo-fi głównej zawartości. Aby zobaczyć pełną wersję z większą zawartością, obrazkami i formatowaniem proszę kliknij tutaj.
Invision Power Board © 2001-2024 Invision Power Services, Inc.