Jak sprawić, by ciągi szablonów były tłumaczone na wszystkich wyświetlanych stronach?

14

Mam kilka wywołań t()w plikach * .tpl.php. Na przykład, powiedzmy, że mówię o produktach i pliku product.tpl.php.

Ciągi w szablonach nie są rozpoznawane do momentu ich pierwszego użycia. Na Drupal.org był wątek i stwierdziłem, że jest dokładny. Niestety, jeśli przejdę do, powiedzmy, http://example.com/pl/product/200 , ten ciąg zostanie zapisany w {locales_source}tabeli z locationpolem ustawionym na /pl/product/200.

Potrzebuję moich użytkowników, aby móc tłumaczyć za pomocą narzędzia do tłumaczenia na miejscu modułu klienta Lokalizacji , aby mogli zobaczyć to, co tłumaczą, mając odpowiedni kontekst. Przy lokalizacji źródła ustawionej na /pl/product/200, produkt o identyfikatorze 200 jest jedynym, na którym pokazany jest ciąg do przetłumaczenia. Co gorsza, jeśli będę w stanie zmusić użytkowników do przetłumaczenia tego konkretnego produktu, potrzebuję ich również do tłumaczenia na rosyjski, a nie ma produktu z ustawioną lokalizacją /ru/product/PID.

Czy istnieje sposób na ponowne sformatowanie ciągu lokalizacji w bazie danych, aby wszystkie ciągi były widoczne we wszystkich produktach i we wszystkich językach w narzędziu l10n_client?

Próbowałem ustawić to na:

  • ; sites/default/themes/mytheme/product.tpl.php,
  • sites/default/themes/mytheme/product.tpl.php,
  • sites/default/modules/mymodule/mymodule.module (moduł generujący dane tematyczne)

Ale to tylko uczyniło ich niewidocznymi dla narzędzia do tłumaczenia.

Jestem prawie pewien, że nie jest to błąd w kliencie Lokalizacji , pokazuje ciąg, w którym powiedziano, że wystąpił. I wydaje się, że jest to „tak, jak to działa” również dla systemu tłumaczeń Drupal 7 - zostało to już omówione i zgłoszone i nic się nie zmieniło. Więc to nie jest raport o błędzie, po prostu pytam, jak pracować z tym, z czym musimy pracować.


Mówię o tekstach, które nie mają nic wspólnego z działającym modułem danych . Nie chcę tłumaczyć produktów, tylko ciągi szablonów, które nie mają nic wspólnego z samym produktem, takie jak Poprzedni - Następny na szablonie galerii zdjęć produktu.

Na przykład moduł zwraca 15 miniatur, a zadaniem motywu jest wyświetlanie 5 za jednym razem. I potrzeby alti titleatrybuty poprzednich / następnych linków . Przetłumaczony. Ale mój moduł tego nie wie. I nigdy nie powinien.

Mołot
źródło
Nie jestem pewien, czy w pełni zrozumiałem, czego chcesz, ale czy wystarczy zaindeksowanie witryny we wszystkich językach? Możesz użyć np. xmlsitemap, aby wygenerować linki w wielu językach, a następnie użyć wgetlub cokolwiek. Hackish, ale powiedziałeś, że to dozwolone (:
Andy,
@Andy Localization Client pozwala użytkownikom otworzyć pasek na dole strony i tłumaczyć teksty, które pojawiają się bezpośrednio na tej stronie, gdy je zobaczą. Mogę wyeksportować wszystkie teksty w porządku, ale nie o to chodzi.
Mołot
1
Pamiętam z drupal_set_message () i dpm (), że te wiadomości będą w kolejce do następnego żądania, jeśli zostaną wywołane np. Ze strony.tpl.php. Jest tak, ponieważ szablony są zwykle przetwarzane dość późno w żądaniu, po przetworzeniu wiadomości. Podobnie może być w przypadku t () i klienta lokalizacji.
donquixote
Fajne pytanie. Niezły problem.
amator barista
Po prostu sugestia ... jeśli chcesz, aby użytkownicy mogli tłumaczyć ciąg tpl t () w dowolnym momencie na dowolny język, możesz wyodrębnić te ciągi za pomocą narzędzia do ekstrakcji szablonów tłumaczeń ( drupal.org/project/potx ) i dać im original .po, które mogliby przetłumaczyć za pomocą narzędzia takiego jak Poedit? ( poedit.net ). Gdy przedstawisz te ciągi jako kilka statycznych, zadanie zostanie wykonane za każdym razem przez każdego tłumacza ...
Kojo

Odpowiedzi:

5

Twoje wymagania:
aby moja witryna działała w wielu językach
jako uwierzytelniony użytkownik
, muszę mieć możliwość tłumaczenia na raz wszystkich wywołań tłumaczeń znalezionych w bazie kodu mojej witryny wykonanych za pomocą funkcji t ().

Czy ten opis wymagań jest nawet bliski temu, o co prosisz?


Roboty

Jak ktoś powiedział - robot może teoretycznie przejść przez całą witrynę, aby wymusić rejestrację wszystkich wywołań t (). Ale 1) robot indeksujący nie wie, które strony należy indeksować; 2) dlatego nie chcemy utrzymywać listy stron do indeksowania; 3) nie chcemy używać robota, kropka. Eww. Po prostu eww. Dobrze?


Problem

  1. Nie mamy listy wszystkich ciągów tłumaczeń.
  2. Drupal / PHP to dynamiczny język w przeciwieństwie do kompilowanego języka C. Nie możemy więc iść i powiedzieć na przykład: skompiluj całą t()bazę kodu, a następnie znajdź wszystkie instancje tej funkcji , a następnie zarejestruj te instancje w bazie danych, a następnie przetłumacz wszystkie zarejestrowane instancje za t()jednym razem. Nie sądzę, że jest to opcja, którą mamy na stole.
  3. Narzędzie do analizy kodu statycznego byłoby bezradne z tego samego powodu, dla którego przeszukiwacz byłby bezradny. Znalazłem to t()w tym pliku. Świetny! W jakim adresie URL jest używany? Jaki jest kontekst?

Zaatakowanie problemu za pomocą bieżących narzędzi (Drupal i niektórych modułów contrib) oraz obecnych ograniczeń (polegających na wywołaniach motywów w czasie rzeczywistym -> plikach szablonów -> t()wywołaniach) wygląda tutaj jak ścieżka wyjścia bez wyjścia. Być może będziemy musieli pomyśleć trochę po wyjęciu z pudełka.


Czego potrzebujemy

  1. Potrzebujemy źródła danych, modelu, który mówi mi, jakie mamy obecne ciągi tłumaczeń i jaki jest ich kontekst -
  2. Proaktywny model danych. Bieżący model danych jest reaktywny (model jest aktualizowany za każdym razem, gdy t()nastąpi wywołanie ). Potrzebujemy proaktywnego modelu danych - takiego, w którym aplikacja zajmuje się wyszukiwaniem t()instancji, zanim zostaną faktycznie wykonane przez klienta.
  3. Potrzebujemy kontekstu. t()sam tego nie wycina - ponieważ - nie wiemy, że tłumaczymy „foo”, ale język docelowy, na który tłumaczymy, zależy od adresu URL miejsca, w którym t()występuje. Nawet gdybyśmy mogli na stałe zakodować język docelowy w t()połączeniu, powiedzmy, używając połączenia otokowego, nie działałoby to dla twoich celów.

Zidentyfikowałem niektóre narzędzia, które - gdybyśmy je mieli - pomogłyby naszemu problemowi. Za pomocą tych narzędzi możemy przejść do modelu danych i powiedzieć: daj mi wszystkie zawinięte ciągi t(), które nie zostały jeszcze wypełnione. Teraz wstaw te tłumaczenia. Dziękuję Ci.

I kiedy następnym razem pojawi się klient, tłumaczenia są na miejscu.

Jak moglibyśmy ... zbudować te narzędzia?


Ograniczenia

  1. Językiem docelowym nie może być szablon, który określa adres URL. Zakładając, że ciąg musi obsługiwać dowolny język.
  2. Przetłumaczony ciąg nie może znajdować się w szablonie. Tłumaczenie będzie znajdować się w bazie danych.

Teraz, gdy bardziej zastanowiłem się nad problemem i zidentyfikowałem pewne wyzwania i ograniczenia, mogę pomyśleć o znalezieniu dostępnych rozwiązań lub stworzeniu niestandardowych rozwiązań.

Rozwiązanie burzy mózgów

Potrzebuję czegoś, co łączy ze sobą „wszystko”. Co z ... bytem?

  • Jednostka może przechowywać produkt, który musi zostać przetłumaczony.
  • Podmioty mogą zapewnić relację - klej - między produktem, który należy przetłumaczyć, a jego kontekstem.
  • Jednostka może określić powiedzmy w polu domyślną lokalizację adresu URL produktu.
  • Tokeny mogą służyć do określania alternatywnych lokalizacji (języków?), W których pojawi się produkt.
  • Podmioty zapewniają nam proaktywny model danych, którego potrzebujemy i jego kontekst. Co z kolei pozwala nam na takie rzeczy, jak: przejście do bazy danych, pobranie wszystkich jednostek produktu, a jeśli nie mają łańcucha tłumaczenia dla pól X, Y i Z, utwórz te łańcuchy tłumaczenia.

Kiedy następnie klient chwyta /pl/product/200, udajesz się do bazy danych, wyszukujesz produkt 200 i chwytasz już istniejące pltłumaczenie. Masz także pole tytułu i podpisu dla tego produktu? Tłumaczenia też powinny tam być.

Pamiętaj, że jestem bardzo niejasny i ogólny, jeśli chodzi o używany moduł tłumaczący. Możesz równie dobrze skorzystać z własnego modułu tłumaczącego - najprawdopodobniej tak jest. Wszystkie modele tłumaczeń, które do tej pory widziałem w Drupal (od D7, jeszcze nie oglądałem D8) są reaktywne, a nie proaktywne.

W skrócie

Teoretycznie istnieją narzędzia do budowania tego, czego potrzebujesz, a podmioty są kluczowym składnikiem, który łączy wszystko razem: - dane (ciąg tłumaczący), - języki docelowe. Nie musisz być w samym Podmiocie, najlepiej w języku taksonomii, na przykład w językach produktów. a może ogólną taksonomię również dla innych podmiotów. - Kontekst. Adres URL, pod którym pojawia się jednostka. Adres URL zawierałby token, który z kolei odwoływałby się do systematyki języka docelowego.

Dzięki tym trzem składnikom możesz powiedzieć: Złap wszystkie productbyty, idź na URL aliaspole, zdobądź token taksonomii , przejdź przez wszystkie możliwe kombinacje terminów, przedstaw wszystkie kombinacje obecnemu użytkownikowi używając bardzo dużej brzydkiej formy - lub AJAX - i formularze wieloetapowe (coś takiego), a ponieważ aktualnie zalogowany użytkownik tłumaczy różne języki dla produktu 200, zapisz je gdzieś w bazie danych

Gdzieś w bazie danych może być pole Field API w encji, pole ustawień należące do każdej encji (niezupełnie Field API, ale nadal może przechowywać dane) lub osobna tabela, której używasz do tego. Myślę, że zapisanie danych w Entity pozwoliłoby uporządkować kod i dane i ułatwić.


Budowanie: Możliwe rozwiązania

  • D8MI (Inicjatywa wielojęzyczna Drupal 8)
  • Kod niestandardowy: tłumaczenia „indeksowe” udostępniane w szablonach przez t () poprzez programowe zapytania i renderowanie dostępnych pakietów oraz powiązanych z nimi implementacji haków motywu.

Pseudo kod

Foreach encja (typu x),
Znajdź wszystkie języki (taksonomia lub język podstawowy związany z produktem),
Renderuj encję,
- aby wykryć jej ciągi t ()
- renderuj wywołania theme (), który obsługuje wielojęzyczną warstwę prezentacji produkt, a nie sam model danych produktu.

Wynik:
- Pierwsze wywołanie w celu wyświetlenia szablonu encji w każdym języku zwraca domyślną implementację języka dla każdego wywołania.
- Parametry t () w szablonie są teraz buforowane w Drupal i gotowe do tłumaczenia (dla każdej instancji języka, nie każdej instancji produktu).
- Użytkownik z rolą „tłumacz” może teraz przejść do interfejsu tłumaczenia i przetłumaczyć wszystkie dostępne parametry t () dla każdego języka.
- Właściciel witryny nie musi czekać, aż klienci odwiedzą każdą stronę produktu lub ręcznie odwiedzą każdą stronę produktu, ponieważ zrobiono to dla niego programowo.

Otwarte pytania:
- Jaki jest kontekst? Jeśli wykonam programowe wywołanie funkcji theme () dla każdego pakietu encji „produktu”, czy rejestruje lokalizację, z której wykonano połączenie? Czy rejestruje adres URL węzła? Czy można zmienić „kontekst”? Gdzie zapisywany jest kontekst? Co dzieje się, gdy masz „dynamiczne” szablony - tj. Kiedy masz więcej niż jeden szablon na produkt i jak zaczynasz wykrywać te odmiany?

Jak zawsze, teoretyzowanie i pseudokod nadaje się tylko do burzy mózgów. Ale w fazie rozwoju nie będziemy wiedzieć, z czym tak naprawdę mamy do czynienia, dopóki nie zaczniemy prototypowania. Tak więc, po opracowaniu kilku ograniczeń, możliwych rozwiązań oraz możliwych problemów lub pytań - mogę teraz wdrożyć dowód koncepcji lub działającego prototypu. Na niektóre powyższe otwarte pytania można odpowiedzieć tylko w ten sposób, a najwcześniej prototypujemy (niezależnie od sukcesu lub porażki), możemy zacząć odpowiadać na niektóre z tych pytań - lub całkowicie zmienić podejście. Bądź na bieżąco ~

amator barista
źródło
1
Nawet bez przeczytania całego wpisu taka odpowiedź zasługuje na entuzjazm
Oleg Videnov
Chodzi o to, że narzędzie, które twierdzi, że robi dokładnie to, czego potrzebuję dla Drupala 7, już istnieje. Problem polega na tym, że Drupal zapisuje te ciągi ze złymi metadanymi. Ale mogę zmienić te metadane w db po zebraniu ciągów, nie ma problemu. Muszę tylko wiedzieć, na co je ustawić, aby narzędzie mogło to zobaczyć. A przynajmniej wierzyłem, że tego właśnie potrzebuję. I najważniejsze: nie chcę tłumaczyć produktów, tylko ciągi szablonów, które nie mają nic wspólnego z samym produktem, jak poprzedni - następny szablon galerii zdjęć produktu.
Mołot
2

Ok, spędziłem trochę więcej czasu z modułem tłumaczenia klienta i jednostki tłumaczenia lokalizacji, aby odtworzyć ten sam scenariusz. Ponieważ ta odpowiedź różni się całkowicie od mojej poprzedniej, dodając jako osobny komentarz:

  1. Tłumaczenie dodane dla języka w jednym / pierwszym węźle jest dostępne dla wszystkich węzłów.

    Oto przykład:

    • Jeśli dodam nowy produkt tego samego typu co nid 200 i odwiedzę tłumaczenie pl nowego węzła (powiedzmy pl / product / 204), zobaczyłbym ten sam ciąg tłumaczenia w pl / product / 200.

    • Jedyną różnicą jest to, że nie pojawia się w kliencie Lokalizacji. Możemy poprosić o tę funkcję w kolejce problemów modułu, jednak wprowadziłoby to więcej zamieszania, ponieważ tłumaczenie nie jest specyficzne dla bieżącej strony i wpłynęłoby na wszystkie strony (tj. Zarówno pl / product / 200 & pl / product / 204).

    • Jeśli dwa węzły utworzone przez dwie różne osoby, a później jeden chce zmienić tłumaczenie, muszą użyć tłumaczenia interfejsu.

  2. Ciąg jest dostępny w kliencie Lokalizacji dla pierwszego języka odwiedzanego dla tego samego węzła

    Oto przykład:

    • Jeśli dodam nowy produkt nid 199 i utworzę tłumaczenie dla języka „pl” (nid 200) i tłumaczenie dla języka „rs” (nid 201), ciąg znaków będzie widoczny tylko na stronie „pl”, a nie na stronie „rs”. Ponownie wygląda to na ograniczenie w module klienta Lokalizacji.
vijaycs85
źródło
1

Twoje podejście do dodawania ciągu tłumaczenia na poziomie pliku szablonu lub modułu może działać w interfejsie użytkownika tłumaczenia interfejsu, ale nie w przypadku klienta lokalizacji.

Oczywiście, jeśli masz rosyjską wersję produktu 200, będzie to nowy węzeł, na przykład / ru / product / 201, w którym możesz tłumaczyć za pomocą klienta Lokalizacji.

Tylko myśl: poszukaj ciągu, który można przetłumaczyć na wszystkie języki w interfejsie tłumaczenia interfejsu i poproś klienta o przetłumaczenie poziomu produktu, gdy jest to naprawdę konieczne. Oto przykład:

„To jest foo produktu paska kategorii”

a jeśli jesteśmy pewni, że inne niż „foo” i „bar” mogą być powszechne, możemy dodać

$vars['product_title'] = t('This is product @product of category @category')

w procesie wstępnym.

i plik .tpl.php będzie

<?php t($product_title, array('@product' => t('foo'),  '@category' => t('bar')); ?>
vijaycs85
źródło
To więcej o titletekstach strzałek w rotatorze obrazów. Mój moduł nie dba o to, jak motyw wyświetli 15 obrazów. A motyw wyświetla 5 naraz, ze strzałkami „poprzedni” i „następny”, które wymagają alti title, i wymagają ich przetłumaczenia. Zmiana modułu za każdym razem, gdy mój front-end będzie się zmieniać, jest możliwa, ale na pewno nie powinna być potrzebna. Te ciągi nie mają nic wspólnego z samym modułem. Last but not least, mogę być po prostu nieświadomy zmienionych ciągów w temacie. Lub niedostępne, aby przenieść je do modułu.
Mołot
IMHO, ten przypadek powinien być obsługiwany w interfejsie użytkownika tłumaczenia interfejsu zamiast klienta lokalizacji.
vijaycs85,
Klient lokalizacji ma na celu umożliwienie „naprawy tłumaczeń w witrynie w miarę zauważania problemów”. - dlaczego nie powinien mieć zastosowania do plików szablonów? Ciągi w tpl są jeszcze bardziej wrażliwe na kontekst, w jakim się pojawiają.
Mołot
1

AFAIK z ekstraktorem szablonów tłumaczenia można wyodrębnić ciąg znaków we wszystkich wywołaniach t()funkcji.

Ekstraktor szablonów tłumaczeń udostępnia interfejs narzędzia do ekstrakcji szablonów tłumaczenia Gettext oparty na sieci Web i wierszu poleceń dla Drupala, a także interfejs API wielokrotnego użytku do wyszukiwania ciągów znaków i błędów tłumaczenia. To narzędzie jest używane pod maską na stronie http://localize.drupal.org/, a także służy jako maszyna analizująca wydania projektu Drupal.org.

Przeczytaj to Jak przetłumaczyć moduł?

Adrian Cid Almaguer
źródło