Naše portály bežia na Slovensku, v Česku a vo Švajčiarsku: štyri portály na troch trhoch, tri jazyky, tri meny, dva databázové systémy a jedna spoločná architektúra. Článok sa venuje trom repozitárom, jednému pre každý trh, a je určený tímom, ktoré prevádzkujú produkt vo viacerých krajinách alebo sa naň chystajú a riešia otázku, či stavať jeden kód s prepínačom krajiny, alebo samostatné nasadenia. Opisujeme, ako sme sa rozhodli, čo nás to stojí a kde sme robili chyby.
Prečo tri repozitáre, a nie jeden kód
Jeden kód s nastavením krajiny je lacnejší, pokiaľ sa trhy líšia len jazykom a obsahom. Naše sa líšia viac a tieto štyri dôvody rozhodli:
- Regulácia a právne texty. Každá krajina má vlastné pravidlá pre obsah, povinné upozornenia a ochranu osobných údajov. Tie sa nepíšu prekladom, ale pre konkrétnu krajinu.
- Hosting. Dva trhy bežia na PostgreSQL u jedného poskytovateľa, tretí na MySQL u iného, s inými limitmi. Jeden kód by musel nosiť výnimky pre obe prostredia.
- Tempo. Nové funkcie vznikajú spravidla najprv na jednom trhu a na ďalšie idú vtedy, keď tam dávajú zmysel. Niektoré dátové funkcie a celé moduly redakčnej správy dnes existujú len na jednom trhu.
- Riziko regresie. Zmena nasadená na jednom trhu sa ostatných nedotkne, kým ju niekto vedome neprenesie. Chyba v kóde jedného trhu nezhodí tri weby naraz.
Nevýhodou je, že repozitáre sa časom rozchádzajú a každá spoločná zmena sa musí preniesť vedome. Švajčiarsky repozitár má napríklad články v samostatnom priečinku a hodnotiace stránky skladá z dátových súborov, kým ostatné dva ich majú ako samostatné stránky. Ak by vaše trhy mali rovnaký hosting, rovnaký rytmus vydávania a rovnaké právne rámce, zvoľte jeden kód.
Čo je spoločné a čo lokálne
Spoločné sú princípy, nie súbory: čisté PHP bez frameworku, rovnaká databázová knižnica v rovnakej verzii vo všetkých troch repozitároch, rovnaký dátový model katalógu, prístupové údaje a nastavenia mimo repozitára, rovnaký vzor smerovania adries a rovnako postavený kontrolný zoznam pre hotovú stránku. Lokálne je všetko, čo vidí čitateľ alebo regulátor: obsah, adresy stránok, zoznam partnerov a ich presmerovacie odkazy, mena, formát čísel, právne texty, nastavenie súhlasu s cookies a redakčné pravidlá pre daný jazyk.
Hranica je zapísaná v dokumentácii každého repozitára. Má jednu výslovnú výnimku: prevádzkové návody, ktoré pokrývajú všetky tri projekty naraz (napríklad prístup k databázam alebo vizuálne kontroly), existujú v troch identických kópiách a menia sa jedna k jednej. Je to jediný druh obsahu, ktorý sa medzi repozitármi kopíruje.
Prenos zmeny: zámer, nie súbor
Keď na jednom trhu pribudne funkcia alebo oprava, na ostatné sa prenáša jej účel. Postup je zapísaný a rovnaký pri každej zmene:
- V cieľovom projekte nájsť najbližší funkčný ekvivalent: súbor, šablónu alebo funkciu, ktorá robí to isté.
- Zachovať účel zmeny a prispôsobiť texty, adresy, interné odkazy, názvy partnerov, menu a obrázky.
- Nekopírovať slepo tam, kde má cieľový projekt inú štruktúru.
- Ak priamy ekvivalent neexistuje, zvoliť najbližšie miesto a tento predpoklad výslovne uviesť pri odovzdaní zmeny.
- Čo sa na daný trh neprenesie, pomenovať, aby to nevyzeralo ako zabudnutá práca.
Typická chyba vzniká, keď sa predpokladá rovnaká adresa. U nás odkazovali jazykové alternatívy trinástich stránok na české adresy, ktoré neexistovali, lebo české adresy majú iné tvary. Pomohla až explicitná mapa ekvivalentov. Kde ekvivalent v mape nie je, odkaz sa nevypíše. Pravidlá prenosu sú zapísané tak, aby ich rovnako použil človek aj asistent na programovanie s umelou inteligenciou. Až zápis z nich robí proces.
Dve databázy: čo abstrakcia vyrieši a čo nie
Slovenský a český trh zdieľajú jednu databázu PostgreSQL a líšia sa schémou. Švajčiarsky beží na MySQL u iného poskytovateľa. Názov schémy je v kóde vždy premenná načítaná z konfigurácie, nikdy nie text v dotaze, takže ten istý dotaz slúži obom trhom v spoločnej databáze. Databázová knižnica s pomenovanými zástupnými znakmi pre identifikátory a hodnoty prispôsobí úvodzovky a escapovanie danému systému.
Abstrakcia však z dvoch databáz nerobí jednu. Spoločné dotazy nad katalógom sú písané tak, aby fungovali na oboch systémoch. Funkcie, ktoré využívajú špecifické vlastnosti PostgreSQL, napríklad dátové typy pre JSON, existujú len na trhoch s PostgreSQL a ich prenos na MySQL by znamenal prepísať dotazy, nie skopírovať ich. Rozdiel sa teda rieši rozsahom funkcií, nie vrstvou, ktorá by ho skryla.
Rovnako dôležité sú limity hostingu. Na testovacej databáze jedného poskytovateľa sme narazili na limit nových spojení za hodinu. Každé zobrazenie stránky pritom otvára spojenie. Hromadná kontrola nastavená podľa iného trhu tam po čase hlási už len chyby databázy, nie chyby kódu, preto beží v dávkach. Limity treba preveriť osobitne pre testovacie aj produkčné prostredie.
Jedna administrácia pre všetky trhy
Interná administrácia existuje v jedinej inštancii v jednom repozitári a obsluhuje všetky portály aj firemný web. Jedna verzia na údržbu a jeden bezpečnostný perimeter sú dôležitejšie než pohodlie mať nástroj v každom repozitári. Pre všetky weby z nej beží generovanie máp stránok, kontrola nefunkčných a partnerských odkazov a hromadná validácia HTML. Položky katalógu sa zo slovenských dát exportujú do českých s prepočtom meny, ktorý je len návrh: hodnoty sa zaokrúhlia nahor na celé koruny, popis sa preloží a človek oboje skontroluje pred zápisom.
Redakčné moduly zatiaľ pokrývajú len jeden trh. Dáta ostatných sa menia skriptmi SQL. Pre budúcnosť platí pravidlo, že keď niektorému trhu chýba proces, vznikne ako nový modul v spoločnej administrácii, nie ako nástroj v repozitári trhu. Zmeny administrácie sa preto medzi trhmi nesynchronizujú, lebo nie je čo synchronizovať.
Lokalizácia nie je preklad
Preklad rieši jazyk. Lokalizácia rieši všetko ostatné, čo musí na trhu sedieť:
- Mena. Hodnoty, ktoré sa často menia, idú z konfigurácie alebo databázy, nikdy nie natvrdo do textu článku. Inak zastarajú skôr, než ich niekto nájde.
- Formát čísel. Na Slovensku a v Česku medzera medzi tisícmi a desatinná čiarka, vo Švajčiarsku apostrof a desatinná bodka. Štandard CLDR používa typografický apostrof, mnohé texty rovný. Treba zvoliť jeden a držať sa ho.
- Pravopis. Švajčiarska spisovná nemčina nepoužíva ß, píše sa dvojité s. Redakčné pravidlá sú preto pre každý jazyk samostatné, nie preložené.
- Právne texty a súhlas s cookies. Píšu sa pre krajinu a jej predpisy, nie prekladom z iného trhu.
- Partneri. Každý trh má vlastný zoznam partnerov a vlastné presmerovacie odkazy. Prenos funkcie ich nikdy nepreberá automaticky.
- Adresy. Rovnaká funkcia má na každom trhu inú adresu v miestnom jazyku, preto potrebuje mapu ekvivalentov.
Hreflang medzi doménami: len pri skutočnom ekvivalente
Naše portály sú na rôznych doménach. Google pripúšťa jazykové alternatívy aj naprieč doménami, ale každá verzia musí uvádzať seba aj všetky ostatné a odkazy musia byť obojstranné, inak sa anotácie ignorujú. Hreflang je určený pre jazykové alebo regionálne verzie tej istej stránky. Jazyk stránky z neho Google podľa vlastnej dokumentácie neurčuje.
Preto ho medzi trhmi používame len na stránkach, ktoré sú lokalizovanou verziou toho istého obsahu, napríklad úvodné a prehľadové stránky, metodika alebo vybrané návody. Väčšina stránok uvádza len seba a predvolenú verziu, lebo český alebo švajčiarsky článok na podobnú tému je iný článok, nie preklad. Kanonická adresa ukazuje vždy na stránku v jej vlastnom jazyku, nikdy na iný trh. Pri vlastných auditoch sme našli nejednotný zápis kódov jazyka medzi portálmi, alternatívy smerujúce na neexistujúce alebo presmerované adresy a blok značiek písaný ručne v hlavičke každej stránky, ktorý sa zle mení hromadne.
- Hreflang len pri skutočnom ekvivalente, podobná téma nestačí.
- Jednotný zápis kódov jazyka a regiónu na všetkých portáloch skupiny.
- Mapa ekvivalentov na jednom mieste namiesto ručne písaných značiek v každej hlavičke.
- Pri zmene alebo zrušení adresy na jednom trhu skontrolovať odkazy z ostatných trhov.
- Kanonická adresa v rovnakom jazyku ako stránka.
Odporúčanie
Najprv si zapíšte, čo je spoločné a čo lokálne, a až potom rozhodnite o počte repozitárov. Ak sa trhy líšia reguláciou, hostingom alebo tempom, samostatné nasadenia so spoločnou architektúrou a písaným postupom prenosu sú bezpečnejšie než jeden kód s výnimkami. Neplánujte rovnaký rozsah funkcií na všetkých trhoch. Každý prenos je rozhodnutie pre konkrétny trh. V malom tíme sa to dá udržať práve preto, že väčšina práce pri prenose je rozhodovanie, nie prepisovanie.