--=REKLAMA=--
Joomla! jest w pełni wielojęzyczną aplikacją obsługująca tłumaczenie wszystkich etykiet i komunikatów ekranowych. Szablony nie stanowią pod tym względem żadnego wyjątku. Chwilę czasu poświęconego na tłumaczenie napisów zastosowanych w szablonie wynagrodzą korzyści z jego dostępności.
System lokalizacji Joomla! został zaprojektowany tak, aby był tak prosty i bezbłędny, jak to tylko możliwe. Na przykład jeśli brakuje jakiegoś pliku językowego albo brakuje jakiegoś tłumaczenia w pliku językowym, Joomla! wyświetla oryginalny, nieprzetłumaczony napis, a nie komunikat błędu. W samym Joomla! znajdują się również narzędzia pomagające tłumaczom w tworzeniu nowych plików językowych.
W tym rozdziale nauczysz się tworzenia plików definicji językowych dla szablonu oraz dołączania tłumaczeń do pakietu instalacyjnego szablonu. Nauczysz się również, jak zbadać, czy wszystkie zastosowane w szablonie napisy zostały przetłumaczone oraz jak zbadać kompletność nowego tłumaczenia.
Pliki definicji językowych zawierające tłumaczenia napisów widocznych w witrynie przechowywane są w:
[sciezka-do-Joomla]/language/[ln-LN]
gdzie [ln-LN] jest kodem języka i kraju. Kody językowe zostaly zdefiniowane w RFC3066[1] Pliok musi być nazwany
[ln-LN].tpl_[nazwa-szablonu].ini
gdzie [nazwa-szablonu] jest nazwą szablonu zapisaną małymi literami. Na przykład, brytyjski plik językowy dla szablonu Beez nazywa się:
[path-to-Joomla]/language/en-GB/en-GB.tpl_beez.ini
Odrębny plik językowy tworzymy z tłumaczeniami napisów widocznych na zapleczu na stronie edytora szablonu. Ten plik przechowywany będzie w
[path-to-Joomla]/administrator/language/[ln-LN]
ale konwencja nazewnicza jest taka sama.
W przypadku szablonów zaplecza, inaczej niż w przypadku szablonów witryny, wymagany jest tylko drugi z tych plików. Na przykład brytyjski plik językowy dla szablonu zaplecza Khepri jest umieszczony pod adresem:
[sciezka-do-Joomla]/administrator/language/en-GB/en-GB.tpl_khepri.ini
Tłumaczenia wszystkich stałych językowych użytych w szablonie zamieszczamy w specjalnym pliku językowym. Jego konstrukcja jest bardzo prosta. Może się składać z:
Czyste linie oraz linie rozpoczynające się od znaku "#" są ignorowane, dlatego znak "#" stosowany jest do oznaczania komentarzy. Komentarze moga się rozpoczynać nie tylko znakiem "#", ale także podwójnym prawym ukośnikiem "//". Komentarz może posłużyć m.in. do zapisania informacji o pliku (nazwa, data utworzenia, autor, licencja), nazywania grup stałych językowych czy innych uwag, np.
# $Id: pl-PL.tpl_wzorzec.ini 1.5.0 2007-08-01 zwiastun $ # author Imię i Nazwisko # copyright (C) 2007 Nazwa projektanta. Wszystkie prawa zastrzeżone. # UWAGA: Wszystkie pliki ini muszą być kodowane w UTF-8 // Pasek narzędzi
Definicja stałej językowej jest równaniem, które po lewej stronie musi zawierać nazwę stałej językowej, a po znaku równania tłumaczenie. Nazwa stałej językowej to albo po prostu tekst napisu do przetlumaczenia, albo jakaś nazwa umowna, zapisana wielkimi literami. Nazwę definiowanej stałej językowej nazywamy także kluczem.
Każda linia definicji zawiera więc parę napisów, jak poniżej:
KLUCZ=Wartość
gdzie KLUCZ to napis do przetłumaczenia, a Wartość to przetłumaczony napis. Na przykład:
ADDITIONAL INFORMATION=Dodatkowe informacje
KLUCZ, a więc część definiowana, musi być zapisana wielkimi literami, w przeciwnym przypadku definicja napisu nie zostanie rozpoznana. Nie ma natomiast znaczenia, w jaki sposób część definiowana jest zapisana w kodzie źródłowym. Wielkość liter w kodzie nie ma praktycznego znaczenia dla funkcjonowania mechanizmu tłumaczenia napisów. Podczas sprawdzania, czy tekst napisu jest przetłumaczony, Joomla ignoruje wielkość znaków. Inaczej mówiąc: bez względu na wielkość znaków napisu w kodzie źródłowym w plikach językowych poszukiwany będzie odpowiednik zapisany wielkimi literami. Tak więc zostanie przetłumaczony zarówno napis „additional information”, „Additional Information” a nawet „AdDiTiOnAl InFoRmAtIoN”.
W tekście klucza mogą znajdować się odstępy (spacje) oraz znaki interpunkcyjne, ale ilość spacji nie może być większa niż w oryginalnych napisach do przetłumaczenia - dodatkowe spacje mają znaczenie odróżniające napisy: klucz zawierający dwa takie same wyrazy oddzielone jedną spacją wskazuje na inny ciąg niż klucz z wyrazami oddzielonymi dwoma spacjami.
Ostrzeżenie! Jeśli w pliku językowym znajdzie się więcej niż jedna taka sama deklaracja, stosowane jest pierwsze znalezione tłumaczenie sprawdzić, czy przypadkiem nie ostatnie. |
A oto przykładowe pliki
# $Id: pl-PL.tpl_wzorzec.ini 1.5.0 2007-08-01 zwiastun $ # author Imię i Nazwisko # copyright (C) 2007 Nazwa projektanta. Wszystkie prawa zastrzeżone. # UWAGA: Wszystkie pliki ini muszą być kodowane w UTF-8 SITE NAME=Nazwa witryny SITE LOGO=Logo witryny // Pasek narzędzi FONTSIZE=Rozmiar czcionki: DECREASE SIZE=Zmniejsz rozmiar czcionki INCREASE SIZE=Zwiększ rozmiar czcionki PARAMNAMEFONTSIZE=Jeśli Tak, zostanie umieszczony
A oto plik języka angielskiego:
# $Id: gb-GB.tpl_wzorzec.ini 1.5.0 2007-08-01 zwiastun $ # author First & Last Name # copyright (C) 2007 Developer Name. All rights reserved. # Note : All ini files need to be saved as UTF-8 SITE NAME=Site Name SITE LOGO=Site Logo // Toolbar FONTSIZE=Font-size: DECREASE SIZE=Decrease size INCREASE SIZE=Increase size
Pliki językowe Joomla! INI muszą być zapisane w kodowaniu UTF-8 bez znacznika kolejności bajtów (BOM)[2] [3]
.
Nazwa pliku językowego musi składać się z następujących elementów oddzielonych kropkami:
Przykładowo plik języka polskiego dla naszego szablonu musi się nazywać pl-PL.tpl_wzorzec.ini, a dla języka angielskiego gb-GB.tpl_wzorzec.ini
Przypisy
Joomla 1.5 został wyposażony w narzędzia umożliwiające pełną lokalizację witryny i zaplecza, w tym także szablonów. Dzięki temu można tłumaczyć na język użytkowników napisy umieszczone na stałe w szablonach (np. nazwa witryny, nazwy przycisków) oraz opisy i etykiety umieszczone w pliku templateDetails.xml, a widoczne w edytorze szablonu na zapleczu administracyjnym.
Do umieszczania stałych tekstów w kodzie szablonu służy specjalna klasa statyczna JText, definiująca stałą językową i zwracająca tłumaczenie w bieżącym języku, jeśli jest dostępne, albo angielski oryginał, jeśli tłumaczenie jest niedostępne. Przed zastosowaniem metod tej klasy nie jest wymagane tworzenie egzemplarza obiektu, stąd jej statyczny charakter.
Napisy mogą być tłumaczone za pomocą metody "_()". Załóżmy na przykład, że w szablonie znajduje się angielski napis „Welcome”:
<?php echo 'Welcome'; ?>
Jeśli chcemy, aby ten napis „Welcome” był tłumaczony, zapiszemy w szablonie następującą instrukcję:
<?php echo JText::_( 'Welcome' ); ?>
Taka instrukcja spowoduje, że system przeszuka odpowiedni plik języka, np. języka polskiego, poszukując wśród deklaracji napisów takiej, której lewa strona brzmi „WELCOME”. Wielkość znaków w napisie nie ma znaczenia. Przykładowo, jeśli w plikach języka polskiego znajdzie się deklaracja:
WELCOME=Witaj!
do przeglądarki użytkownika zostanie wysłany tekst „Witaj!”. Jeśli użytkownik będzie wyświetlać witrynę w języku niemieckim, przeszukany zostanie plik języka niemieckiego, w którym może się znajdować linia:
WELCOME=Wilkommen
W takim przypadku do przeglądarki zostanie wysłany tekst „Wilkommen”.
Jeśli odpowiedni plik języka nie zostanie znaleziony albo nie będzie w nim deklaracji „WELCOME = Przetłumaczony napis”, do przeglądarki zostanie wysłany tekst angielski, umieszczony w instrukcji w nawiasie, a więc „Welcome”.
A zatem z klasy JText korzystamy zawsze, gdy chcemy umieścić w kodzie szablonu jakikolwiek tekst, który będzie widoczny dla odwiedzających witrynę. Takie napisy umieszczamy w szablonie za pomocą instrukcji PHP echo, np.:
<?php echo JText::_('Site name'); ?>
Niekiedy konieczne jest umieszczenie wewnątrz tłumaczonego napisu specjalnie sformatowanego pola (elementu). Zdarza się to zwykle wówczas, gdy dodawane są (włączane są) jakieś liczby, ale także oznaczenia czasu, daty, a także specjalne instrukcje formatujące. Gdyby napisy nie miały być tłumaczone, wystarczyłoby zastosowanie standardowej funkcji PHP printf lub sprintf. Funkcja printf zwraca napis sformatowany zgodnie z podanym zbiorem reguł określonych argumentem w postaci napisu formatującego. Podobnie funkcja sprintf zwraca napis powstały w wyniku sformatowania łańcucha znaków zgodnie z regułami formatującymi.
Klasa JText umożliwia zastosowanie funkcji dla printf i sprintf pozwalających formatować tłumaczone teksty za pomocą tej samej składni, co funkcje PHP
Na przykład, przyjmijmy że masz napis “Donations of 12.45 GBP have been received” („Nadeszła darowizna wysokości 12.45 GBP”), w którym wysokość darowizny pochodzi ze zmiennej $donations. Można by podzielić napis na dwie części, jak poniżej:
JText::_( 'DONATIONS_OF' ) . “ $donations GBP “ . JText::_( 'HAVE_BEEN_RECEIVED' )
a w plikach językowych umieścić definicje napisów:
DONATIONS_OF="Donations of" HAVE_BEEN_RECEIVED="have been received" # w polskim pliku językowym np. DONATIONS_OF="Darowiznę w wysokości" HAVE_BEEN_RECEIVED="otrzymano."
Ale nie jest to dobre rozwiązanie w przypadku języków, których składnia wymaga określonego szyku wyrazów, jak na przykład w języku polskim. Zamiast powyższego rozwiązania można skorzystać z funkcji sprintf, jak poniżej:
JText::sprintf( 'DONATIONS_HAVE_BEEN_RECEIVED', $donations )
a w plikach językowych umieścić definicje:
DONATIONS_HAVE_BEEN_RECEIVED="Donations of %.2f GBP have been received" # w polskim pliku językowym DONATIONS_HAVE_BEEN_RECEIVED="Nadeszła darowizna wysokości %.2f GBP"
W napisie do przetłumaczenia można umieścić więcej niż jedną dyrektywę formatującą. Podstawienie następuje zgodnie z podaną kolejnością
JText::sprintf( 'STRING_WITH_NUMBERS_IN_IT', $num1, $num2, $num3 )
z definicją napisu w plikach językowych:
STRING_WITH_NUMBERS_IN_IT="First %d, second %d, third %d" # w polskim pliku językowym STRING_WITH_NUMBERS_IN_IT="Pierwszy %d, drugi %d, trzeci %d"
Każdy wyznacznik formatowania rozpoczyna się od znaku procenta (%) i może zawierać jedną lub więcej z pięciu poniższych dyrektyw z zachowaniem - gdy elementów jest więcej - podanej kolejności:
|
Typ | Wartość | |
|
Znak | + lub - | Wymusza znak (+ lub -) zastosowany z liczbą. Domyślnie tylko znak minus jest stosowany na oznaczenie liczb ujemnych. Aby wymusić umieszczenie oznaczenie liczby dodatniej można umieścić znak +. |
|
Dopełnienie | <spacje>
lub 0 albo '<znak> |
Opcjonalny określnik dopełnienia - znak dopełniający wynik do odpowiedniej długości. Można podać znaki spacji albo 0 albo jakikolwiek inny znak poprzedzony pojedynczym cudzysłowem ('). Domyślnie jako dopełnienie stosowane są spacje. |
|
Wyrównanie | <nic> albo - |
Opcjonalny znak wyrównania. Domyślnie dane są wyrównywane do prawej. Znak minusa (-) wymusza wyrównanie do lewej. |
|
Szerokość | Liczba | Opcjonalna minimalna ilość znaków, jaką powinien zawierać element - rezultat tego przekształcenia. |
|
Precyzja | .Liczba | Opcjonalne określenie precyzji - ilości cyfr dziesiętnych w liczbach zmiennoprzecinkowych. Dla innych liczb niż zmiennoprzecinkowe - ignorowany. |
|
Typ | Wymagane. Informuje funkcje printf i sprintf o typie przekazywanych do nich danych. Możliwe są następujące typy: | |
|
Znak procenta. Oznacza, że nie jest konieczne podawanie żadnego argumentu. | ||
|
Argument będzie traktowany jako liczba całkowita, a jego wartość zostanie wyświetlona w postaci binarnej. | ||
|
Argument będzie traktowany jako liczba całkowita, a jego wartość zostanie przedstawiona w postaci znaku o takim kodzie ASCII. | ||
|
Argument będzie traktowany jako liczba całkowita, a jego wartość zostanie przedstawiona jako liczba dziesiętna. | ||
|
Argument będzie traktowany jako liczba zmiennoprzecinkowa, a jego wartość zostanie przedstawiona w zapisie naukowym (np. 1.2e+2). The precision specifier stands for the number of digits after the decimal point since PHP 5.2.1. In earlier versions, it was taken as the number of significant digits (one less). | ||
|
Argument będzie traktowany jako liczba całkowita, a jego wartość zostanie przedstawiona bez znaku w formacie dziesiętnym. | ||
|
Argument będzie traktowany jako liczba zmiennoprzecinkowa o podwójnej precyzji (typ double), a jego wartość zostanie przedstawiona jako liczba zmiennoprzecinkowa (z automatyczną konwersją - przecinek lub kropka). | ||
|
Argument będzie traktowany jako liczba zmiennoprzecinkowa o podwójnej precyzji (typ double), a jego wartość zostanie przedstawiona jako liczba zmiennoprzecinkowa (bez automatycznej konwersji). | ||
|
Argument będzie traktowany jako liczba ), a jego wartość zostanie przedstawiona jako liczba ósemkowa. | ||
|
Argument będzie traktowany jako napis (łańcuch znaków) i zostanie przedstawiony jako napis. | ||
|
Argument będzie traktowany jako liczba całkowita, a jego wartość zostanie przedstawiona jako liczba szesnastkowa (małymi literami). | ||
|
Argument będzie traktowany jako liczba całkowita, a jego wartość zostanie przedstawiona jako liczba szesnastkowa (wielkimi literami). |
Format napisów obsługuje argumenty liczbowe oraz even swapping. To jest przydatne, gdy dwa lub więcej elementów danych musi być wstawione w napisie, ale różna składnia języków powoduje, że nie można zastosować takiej samej kolejności argumentów.
Przykładowo, weźmy następujący kod:
echo JText::sprintf( 'BALLS_IN_THE_BUCKET', $number, $location );
z definicjami napisów w plikach językowych:
BALLS_IN_THE_BUCKET="There are %d balls in the %s" # w polskim pliku językowym np. BALLS_IN_THE_BUCKET="Mamy %d piłki w %s"
Wtedy, jeżeli
$number = 3 $location = 'hat' // hat=kapelusz
to otrzymamy na wyjściu napis brzmiący tak: “Mamy 3 piłki w kapelusz”. Ale zobaczmy, co się stanie, gdy zmienimy tłumaczenie na:
BALLS_IN_THE_BUCKET="The %s contains %d balls" # w polskim pliku językowym np. BALLS_IN_THE_BUCKET="%s zawiera %d piłki"
Teraz w efekcie otrzymalibyśmy napis "3 zawiera kapelusz piłki", co jest oczywistym nonsensem. Raczej gdy zmienisz kod, możesz wskazywać w tłumaczeniu napisu, który argument do którego wypełniacza się odnosi. Zmień tłumaczenie na
BALLS_IN_THE_BUCKET="The %2$s contains %1$d balls"
i otrzymujemy wyjście "Kapelusz zawiera 3 piłki" zgodnie z oczekiwaniem.
Dodatkową korzyścią możliwości numerowania argumentów jest możliwość powtórzenia znaków wypełniacza, dodając więcej argumentów w kodzie. Na przykład zmieńmy tłumaczenie na
BALLS_IN_THE_BUCKET="The %2$s contains %1$d balls, so there are %1$d balls in the %2$s" # w polskim pliku językowym np. BALLS_IN_THE_BUCKET="%2$s zawiera %1$d piłki, tak jak %1$d piłki są w %2$s"
co da poprawne zdanie "Kapelusz zawiera 3 piłki, tak jak 3 piłki są w kapeluszu"
Podobnie jak w przypadku innych plików, w pliku templateDetails.xml umieszczamy informację o plikach językowych dołączonych do szablonu witryny:
<languages> <language tag="en-GB">en-GB.tpl_wzorzec.ini</language> <language tag="pl_PL">pl-PL.tpl_wzorzec.ini</language> </languages>
Albo o dołączonych do szablonu zaplecza:
<administration> <languages folder="admin"> <language tag="en-GB">en-GB.tpl_wzorzec.ini</language> <language tag="pl_PL">pl-PL.tpl_wzorzec.ini</language> </languages> </administration>
Aby zapewnić, że Twój szablon jest w pełni międzynarodowy, wielojęzyczny, musisz przetłumaczyć kilka elementów pliku XML, dołączyć pliki definicji językowych oraz ich listę w pliku templateDetails.plik xml.
Kilka elementów skryptu templateDetails.xml wyświetlanych w edytorze szablonu na zapleczu wymaga przetłumaczenia. Są to co najmniej:
name | Nazwa szablonu. Na przykład, Beez |
description | Opis szablonu. |
Pola te wyświetlane są również podczas instalacji szablonu.
Wszystkie pliki językowe muszą być zadeklarowane w skrypcie templateDetails.plik xml. Oddzielnie umieszczamy informacje o plikach tłumaczących napisy widoczne w witrynie i napisy widoczne w edytorze szablonu na zapleczu. Informacja o plikach językowych objęte są znacznikami <languages>. Przykładowo dwa angielskie (brytyjskie) pliki językowe i dwa niemieckie pliki językowe dla szablonu Beez zadeklarowane są następująco:
<?xml version=”1.0” encoding=”utf-8” ?> <install version=”1.5” type=”template”> ......... <languages> <language tag=”en-GB”>en-GB.tpl_beez.ini</language> <language tag=”de-DE”>de-DE.tpl_beez.ini</language> </languages> ......... <administration> <languages folder=”admin”> <language tag=”en-GB”>en-GB.tpl_beez.ini</language> <language tag=”de-DE”>de-DE.tpl_beez.ini</language> </languages> </administration> </install>
Zwróć uwagę: w znaczniku <languages> dla zaplecza użyty jest atrybut folder. Jest to konieczne, ponieważ pliki językowe witryny i zaplecza są nazwane tak samo i nie mogą znajdować się w jednym katalogu pakietu instalacyjnego szablonu. W tym przykładzie pliki językowe zaplecza zostały umieszczone w katalogu nazwanym admin, aby odróżnić je od plików tłumaczących napisy witryny.
Podobnie jak w przypadku innych plików, w pliku templateDetails.xml umieszczamy informację o plikach językowych dołączonych do szablonu witryny:
<languages> <language tag="en-GB">en-GB.tpl_wzorzec.ini</language> <language tag="pl_PL">pl-PL.tpl_wzorzec.ini</language> </languages>
Albo o dołączonych do szablonu zaplecza:
<administration> <languages folder="admin"> <language tag="en-GB">en-GB.tpl_wzorzec.ini</language> <language tag="pl_PL">pl-PL.tpl_wzorzec.ini</language> </languages> </administration>
Joomla! obsługuje przydatne narzędzia diagnostyki debagowania (diagnostyczne), które ułatwiają zlokalizowanie nieprzetłumaczonych napisów oraz wykrywanie i korygowanie błędów i usterek w tłumaczeniu etykiet i komunikatów ekranowych w zainstalowanych rozszerzeniach.
W polskim tłumaczeniu Joomla! zamiast informatycznego terminu debugowanie, stosujemy ogólniejszy i powszechniej zrozumiały, choć nie tak precyzyjny termin diagnostyka.
Aby uaktywnić debugger języka, wybierz z menu zaplecza opcję Konfiguracja globalna, a następnie kartę System. Po prawej stronie znajduje się sekcja Diagnostyka, a w niej możliwość włączenia analizy języka. Zaznacz opcję Tak i zachowaj nowe ustawienia.
Gdy uaktywnimy analizę języka, wszystkie frazy językowe, zdefiniowane w plikach językowych, a pojawiające się w treści strony są oznaczane z lewej i prawej strony punktorami w postaci kropek, np. ●Fraza językowa●, a poniżej treści strony mogą być wyświetlone:
|
(tekst otoczony punktorami) oznacza napis znaleziony w pliku definicji językowych i przetłumaczony na bieżący język. |
|
(tekst otoczył parami znaków zapytania) oznacza napis przeznaczony do tłumaczenia, nieprzetłumaczony w pliku definicji językowych. |
|
(tekst bez otoczek) oznacza napisy nieprzeznaczone do tłumaczenia (treści witryny i inne!). |
Dodatkowe informacje diagnostyczne otrzymamy, jeśli zostanie uaktywniona opcja Analiza systemu. Wybierz z menu zaplecza opcję Konfiguracja globalna, a następnie kartę System. Po prawej stronie znajduje się sekcja Diagnostyka. Przy parametrze Analiza systemu zaznacz opcję Tak i zachowaj nowe ustawienia.
Gdy ta opcja zostanie uaktywniona, na wszystkich ekranach pojawią się dodatkowe informacje diagnostyczne na dole każdej strony. Aktualnie znajdziemy tam:
Dodatek systemowy Diagnostyka kontroluje zakres i sposób przedstawiania informacji diagnostycznych, gdy uaktywnione zostaną parametry debuggera w Konfiguracji globalnej. Aby uzyskać dostęp do własności dodatku, wybierz z menu zaplecza opcję Rozszerzenia -> Dodatki, a następnie znajdź na liście dodatek System – Diagnostyka [System – Debug] i naciśnij jego nazwę. Przejdziesz na stronę edytora własności dodatku.
Po prawej stronie w sekcji parametrów trzy opcje dotyczą diagnostyki tłumaczenia etykiet i komunikatów ekranowych:
Uwaga: Na liście nieprzetłumaczonych fraz wyświetlane są jedynie napisy umieszczone w kodzie za pomocą metody JText, na przykład kodem:
echo JText::_( 'Reports Import Configuration' );
Jeśli fraza nie będzie przetłumaczona, to w trybie projektanta zostanie ona wyświetlona następująco:
# /administrator/components/com_reports/views/reports/tmpl/default.php REPORTS IMPORT CONFIGURATION=Reports Import Configuration
Jeśli w parametrze Usuń przedrostek kluczy zostanie podany przedrostek "Reports", napis ten w trybie projektanta będzie wyświetlony następująco::
# /administrator/components/com_reports/views/reports/tmpl/default.php REPORTS IMPORT CONFIGURATION=Import Configuration
Zwróć uwagę, że ścieżka do pliku, w którym napis został umieszczony, oparta jest na funkcji PHP debug_backtrace. Czasami to jest dokładna, innym razem nie, a zdarza się także, iż żaden plik nie zostanie wskazany. W takim przypadku musisz skorzystać z lepszych narzędzi.