Files
carei.pagedev.pl/.paul/phases/18-en-translation/18-01-PLAN.md
2026-04-22 22:00:50 +02:00

16 KiB
Raw Blame History

phase, plan, type, wave, depends_on, files_modified, autonomous, delegation
phase plan type wave depends_on files_modified autonomous delegation
18-en-translation 01 execute 1
16-01
17-01
wp-content/plugins/carei-reservation/languages/carei-reservation-en_US.po (nowy)
wp-content/plugins/carei-reservation/languages/carei-reservation-en_GB.po (nowy, symlink/kopia en_US)
wp-content/plugins/carei-reservation/languages/carei-reservation-en_US.mo (nowy, binarny)
wp-content/plugins/carei-reservation/languages/carei-reservation-en_GB.mo (nowy, binarny)
false off
## Goal Dostarczyć kompletne tłumaczenie EN dla pluginu carei-reservation: przetłumaczyć wszystkie 157 msgid z `carei-reservation.pot` na `msgstr` angielskie w pliku `carei-reservation-en_US.po`, skompilować do `.mo`, zduplikować jako `en_GB` (Polylang w WordPress może używać różnych locale EN — pokrywamy oba najczęstsze warianty). Po uploadzie plików UI pluginu na wersji angielskiej przełącza się całkowicie.

Purpose

Phase 16 dostarczyła infrastrukturę (__(), textdomain, .pot), Phase 17 dodała bilingual pakiety + mapowanie błędów Softra. Phase 18 to jedyna faza, która wizualnie przełączy cały plugin na EN. Do tej pory użytkownik EN widzi oryginalne polskie stringi — brak .mo = brak tłumaczeń, __('Wybierz segment pojazdu', ...) zwraca polski msgid.

Output

  • carei-reservation-en_US.po — 157 msgstr wypełnionych profesjonalnym angielskim tłumaczeniem branży wynajmu samochodów
  • carei-reservation-en_US.mo — binarny plik zgodny z formatem gettext (magic bytes 0x950412de, big-endian byte order)
  • carei-reservation-en_GB.po + .mo — identyczna kopia (lub drobne różnice rental vs hire, license vs licence — opcjonalne)
  • Po załadowaniu przez load_plugin_textdomain (już wpięte w Phase 16) — wszystkie __()/esc_html__() i wp_localize_script('careiI18n') zwracają EN w locale en_*
@.paul/PROJECT.md @.paul/ROADMAP.md @.paul/STATE.md @.paul/phases/16-i18n-plugin-refactor/16-01-SUMMARY.md @.paul/phases/17-bilingual-packages-and-softra-errors/17-01-SUMMARY.md @wp-content/plugins/carei-reservation/languages/carei-reservation.pot

<acceptance_criteria>

AC-1: Plik .po kompletnie przetłumaczony

Given istnieje plik `languages/carei-reservation-en_US.po`
When policzymy niepuste msgstr (`grep -c '^msgstr "[^"]' plik.po`)
Then wszystkie 157 wpisów ma wypełnione msgstr (nie-puste)
  And nagłówek zawiera Language: en_US, poprawne Plural-Forms (nplurals=2; plural=(n != 1))
  And msgid zawierające placeholdery `%count%`, `%name%`, `%price%`, `%status%` itp. mają je **zachowane w msgstr** (nietknięte — te same tokeny)
  And msgid zawierające tagi HTML (`<strong>...</strong>`) mają je zachowane
  And tłumaczenie zachowuje branżowy ton: `doba` → `day`, `oddział` → `location`, `pakiet ochronny` → `protection package`, `rezerwacja` → `reservation`, `zł` → `PLN`, itp.

AC-2: Plik .mo poprawny binarnie

Given istnieje plik `languages/carei-reservation-en_US.mo`
When otworzymy go jako binary
Then pierwsze 4 bajty to magic number `0xde120495` (little-endian) LUB `0x950412de` (big-endian)
  And zawiera wszystkie tłumaczenia z .po
  And daje się poprawnie sparsować przez `gettext` (WordPress i18n czyta go bez błędu)
  And jest < 50 KB (typowy rozmiar dla 157 wpisów)

AC-3: EN UI działa po uploadzie

Given administrator ustawił Polylang locale na en_US albo en_GB
When użytkownik otwiera stronę w EN
Then modal rezerwacji ma WSZYSTKIE etykiety po angielsku (segment, dates, location, protection packages, booking summary, success)
  And hero search form po angielsku
  And widgety (mapa, grid miast, grid oddziałów) po angielsku gdzie są stringi UI
  And wp-admin → Rezerwacje (dla administratora z EN locale) po angielsku
  And błędy z Softra API (dla znanych komunikatów) po angielsku
  And pakiety ochronne pokazują wartości z pól `_en` (lub PL fallback gdy puste — z Phase 17)

</acceptance_criteria>

Task 1: Translate .pot → carei-reservation-en_US.po wp-content/plugins/carei-reservation/languages/carei-reservation-en_US.po 1. Przeczytaj `languages/carei-reservation.pot` (157 msgid, ~13.7 KB) 2. Dla każdego wpisu msgid wygeneruj angielskie tłumaczenie w msgstr: - **Ton:** profesjonalny, branża wynajmu samochodów (car rental) - **Kluczowe terminy:** - „doba" / „dób" / „doby" → `day` / `days` (bez skomplikowanej pluralizacji — EN ma tylko one/other) - „oddział" → `location` (nie `branch` — bardziej rental-naturalne) - „pakiet ochronny" → `protection package` - „rezerwacja" → `reservation` (nie `booking` — spójne z nazwą pluginu) - „Złóż zapytanie o rezerwację" → `Request a reservation` (skrócone, CTA-friendly) - „klient" → `customer` - „zł" → `PLN` - „Wyjazd zagraniczny" → `International travel` - „Zniesienie udziału" → `Deductible waiver` (jeśli gdzieś zostało) - „najemca" → `renter` - „segment pojazdu" → `vehicle segment` - „miejsce odbioru" / „miejsce zwrotu" → `pickup location` / `return location` - „politykę prywatności" → `privacy policy` - „Pakiet SOFT" → `SOFT Package` (nazwy własne bez zmian) - **Placeholdery:** tokeny typu `%name%`, `%count%`, `%price%`, `%status%`, `%days%`, `%total%`, `%unit%`, `%no%`, `%msg%`, `%perDay%`, `%min%`, `%max%`, `%label%` → **ZACHOWAJ DOKŁADNIE** jak w oryginale (nie tłumacz, nie zmieniaj kolejności placeholderów jeśli to zmieniałoby znaczenie; ale możesz zmienić kolejność słów wokół nich) - **HTML tagi:** `...` → ZACHOWAJ - **%s** (sprintf) → ZACHOWAJ 3. Zapisz jako `wp-content/plugins/carei-reservation/languages/carei-reservation-en_US.po` z nagłówkiem: ``` # English (US) translation for Carei Reservation # This file is distributed under the same license as the Carei Reservation plugin. msgid "" msgstr "" "Project-Id-Version: Carei Reservation 1.0.0\n" "Report-Msgid-Bugs-To: \n" "POT-Creation-Date: 2026-04-22 12:00+0000\n" "PO-Revision-Date: 2026-04-22 12:00+0000\n" "Last-Translator: Carei\n" "Language-Team: English\n" "Language: en_US\n" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=UTF-8\n" "Content-Transfer-Encoding: 8bit\n" "Plural-Forms: nplurals=2; plural=(n != 1);\n" "X-Domain: carei-reservation\n" ``` 4. Zachowaj komentarze `#:` z referencjami plik:linia (dla kontekstu tłumacza przy przyszłych zmianach) 5. Sanity check per wpis: - msgid niepuste → msgstr niepuste - `%TOKEN%` w msgid → `%TOKEN%` w msgstr (ten sam token) - `` w msgid → `` w msgstr (dokładnie ten sam tag)
Unikaj:
- Dosłownego tłumaczenia słowo-w-słowo (kluczowe są frazy rental, nie słownikowe mapowania)
- Zachowywania polskich diakrytyków w EN (ąćęłńóśźż nie powinny być w msgstr)
- Tłumaczenia nazw własnych (`SOFT`, `PREMIUM`, `Carei`, `Softra`)
- Zmiany placeholderów (`%count%` → `%iloscDni%` = katastrofa w runtime)
1. Plik `carei-reservation-en_US.po` istnieje 2. `grep -c '^msgid "[^"]' plik.po` ≈ 158 (157 + header) 3. `grep -c '^msgstr "[^"]' plik.po` ≈ 158 (wszystkie wypełnione) 4. `grep -cP "[ąćęłńóśźż]" plik.po` → tylko w msgid (oryginalne PL), zero w msgstr 5. Spot-check 10 wpisów: ton angielski branżowy, placeholdery zachowane, HTML zachowany AC-1 satysfakcjonowane. Task 2: Kompilacja .po → .mo (+ kopia en_GB) wp-content/plugins/carei-reservation/languages/carei-reservation-en_US.mo, wp-content/plugins/carei-reservation/languages/carei-reservation-en_GB.po, wp-content/plugins/carei-reservation/languages/carei-reservation-en_GB.mo **Problem:** `msgfmt` (standardowy kompilator gettext) nie jest dostępny w systemie developera. Python `msgfmt.py` również nie dostępny.
**Rozwiązanie:** Wygeneruj plik `.mo` binarnie programistycznie. Możliwe ścieżki (wybierz dostępną):

1. **Preferowana:** Napisz tymczasowy skrypt Node.js w sandbox używający pakietu `gettext-parser` (dostępny przez npm):
   ```js
   // Wymaga: npm i gettext-parser
   const fs = require('fs');
   const gp = require('gettext-parser');
   const po = fs.readFileSync('carei-reservation-en_US.po');
   const parsed = gp.po.parse(po);
   const mo = gp.mo.compile(parsed);
   fs.writeFileSync('carei-reservation-en_US.mo', mo);
   ```
2. **Alternatywa PHP:** Napisz własny skrypt PHP implementujący format `.mo` (magic 0x950412de, header 7×uint32, offset tables, string data). Format jest w dokumentacji gettext: https://www.gnu.org/software/gettext/manual/html_node/MO-Files.html
   - Parsuj `.po` ręcznie (rozpoznaj msgid/msgstr, unescape)
   - Zbuduj binarny layout: header → offset/length tables for originals → offset/length tables for translations → string blobs (null-terminated)
   - Zapisz jako binary file
3. **Loco Translate (wp-admin):** gdyby powyższe zawiodły — upload `.po` do wp-content/languages/plugins/ i niech Loco Translate w `wp-admin → Loco Translate → Plugins → Carei Reservation → en_US → Sync → Save` wygeneruje `.mo` w server-side.

**Preferuj opcję 1** (Node.js + gettext-parser) — działa deterministycznie w dev environment, bez potrzeby wp-admin.

**Po skompilowaniu en_US:**
- Skopiuj `.po` jako `carei-reservation-en_GB.po` (zmień `Language: en_US\n` → `Language: en_GB\n` w nagłówku)
- Opcjonalnie: drobne poprawki UK-english (license→licence, color→colour, itp.) — na tym etapie zostaw identyczne
- Skompiluj `.po` → `.mo` tym samym skryptem

**Weryfikacja binarnej poprawności `.mo`:**
```bash
# Pierwsze 4 bajty = magic number (little-endian 0x950412de)
xxd -l 4 carei-reservation-en_US.mo
# Powinno pokazać: 0000000: de12 0495  (le) lub 9504 12de (be)
```
1. Pliki istnieją: `en_US.po`, `en_US.mo`, `en_GB.po`, `en_GB.mo` w `languages/` 2. Rozmiar `.mo` między 550 KB 3. Magic number poprawny (xxd/hexdump pierwsze 4 bajty) 4. PHP sanity check (opcjonalny): `php -r "$mo=file_get_contents('path.mo'); echo bin2hex(substr($mo,0,4));"` → `de120495` lub `950412de` AC-2 satysfakcjonowane. - `carei-reservation-en_US.po` + `.mo` z 157 przetłumaczonymi wpisami - `carei-reservation-en_GB.po` + `.mo` jako kopia en_US - Po uploadzie wszystkie `__()`/`esc_html__()` + `careiI18n` w pluginie zwracają EN przy locale en_* 1. **Deploy:** wypchnij 4 nowe pliki (`carei-reservation-en_US.po`, `.mo`, `en_GB.po`, `.mo`) do `wp-content/plugins/carei-reservation/languages/` na serwer 2. **Cache:** wyczyść cache pluginu (jeśli masz WP Rocket / Autoptimize) + opcache PHP (zwykle wystarczy reboot fpm, albo `wp cache flush`) 3. **Admin panel pakietów:** - Zaloguj się do wp-admin (jeśli twoja konto admina jest PL → zostawcie PL dla admina, albo zmień WP user locale na EN w Users → Profile → Language: English (United States)) - `Rezerwacje → Pakiety ochronne` — labele powinny być po EN (jeśli admin locale = EN) - Uzupełnij pola EN dla SOFT i PREMIUM (np. `SOFT Protection` + `Basic damage coverage with 2000 PLN deductible`; `PREMIUM Protection` + `Full damage waiver, zero deductible`) - Zapisz 4. **Frontend EN — modal rezerwacji:** - Przełącz Polylang switcher na EN - Otwórz stronę z przyciskiem → przycisk pokazuje `Request a reservation` (lub podobne) - Modal otwiera się, WSZYSTKIE labele po angielsku: `Vehicle segment`, `From`, `To`, `Pickup location`, `Return location`, `Protection packages`, `Additional options`, `International travel`, `First name`, `Last name`, `Email`, `Phone`, `I agree to the privacy policy`, `Send request` - Pakiety ochronne: `SOFT Protection` / `PREMIUM Protection` z angielskim opisem (z Phase 17) - Komunikaty walidacji (spróbuj wysłać pusty form) po EN: `Enter first name`, `Enter a valid email`, itp. - Podsumowanie → `Reservation summary`, `Subtotal`, `VAT`, `Total`, `Confirm reservation` - Success: `Reservation confirmed`, `Order number: X` 5. **Hero search form:** `Vehicle segment`, `From`, `To`, `Pickup location`, `Check availability` 6. **Widgety:** - Mapa Polski: tooltipy `Location: {city}`, `ul. {street}` → po EN - Grid miast, grid oddziałów → po EN 7. **Błędy Softra:** - Spróbuj zarezerwować niedostępny pojazd / nieprawidłową datę — komunikat po EN (z słownika Phase 17 via `__()`) 8. **DevTools sanity:** - `window.careiI18n.selectSegment` → `"Select vehicle segment"` (lub podobne) - `window.careiI18n.dayOne` → `"day"`, `dayOther` → `"days"` (jeśli dodałeś `dayOther` jako en-plural) - Network: `/wp-json/carei/v1/protection-packages?lang=en` → response z EN treścią 9. **Powrót do PL:** - Przełącz Polylang na PL - Wszystko wraca do polskiego bez regresji (oryginał zachowany)
**Kryterium przejścia:** cała UI pluginu w EN (modal + hero + widgety + admin + error messages). Zero polskich literałów przy locale EN (poza treściami z DB które admin zostawił puste → fallback PL z Phase 17).

**Znane limitacje (NIE blokują approve):**
- Treści stron Elementora (nagłówki hero, sekcje marketingowe) — tłumaczone osobno przez Polylang addon (poza scope tej fazy)
- Menu, footer, inne treści WP — Polylang / Polylang Strings Translation (poza scope)
Napisz "approved" aby zamknąć Milestone v0.7, albo wskaż stringi które pozostały po polsku pomimo EN locale.

DO NOT CHANGE

  • Żaden plik PHP/JS pluginu (Phase 1617 już to załatwiły)
  • Plik .pot (baseline — nie nadpisujemy bazowego template)
  • Textdomain, mechanizm load_plugin_textdomain (Phase 16)
  • Panel admina pakietów — tylko DANE w bazie mogą być wypełnione przez admina (to nie zmiana kodu)
  • carei-reservation.css — styling niezależny od języka
  • mu-plugins/fix-sprintf-global.php — dalej potrzebny dla Polylang addon

SCOPE LIMITS

  • Nie tłumaczymy innych pluginów (tylko carei-reservation)
  • Nie tłumaczymy Elementora ani treści stron (Polylang addon)
  • Nie tłumaczymy nazw krajów w sekcji wyjazdu zagranicznego (dane biznesowe COUNTRY_FLAGS — pozostają po polsku bo backend tak zwraca)
  • Nie tłumaczymy slugów URL, permalink structures
  • Nie generujemy dodatkowych locale (fr, de, itp.) — tylko en_US + en_GB
  • Nie zmieniamy generatora .pot ani pipeline-u i18n
Przed zamknięciem planu: - [ ] `carei-reservation-en_US.po` istnieje, 157 wpisów, msgstr wszystkie wypełnione - [ ] `carei-reservation-en_US.mo` istnieje, magic number poprawny - [ ] `carei-reservation-en_GB.po` + `.mo` — kopia en_US - [ ] Brak polskich diakrytyków w msgstr - [ ] Placeholdery `%TOKEN%` zachowane 1:1 między msgid i msgstr - [ ] HTML tagi zachowane w msgstr - [ ] Human-verify — pełen flow EN bez regresji PL - [ ] AC-1, AC-2, AC-3 pass

<success_criteria>

  • Task 12 ukończone
  • Checkpoint zatwierdzony
  • Milestone v0.7 — 100% complete
  • Plugin carei-reservation pełnoprawnie dwujęzyczny (PL + EN) </success_criteria>
Po zakończeniu: `.paul/phases/18-en-translation/18-01-SUMMARY.md` Następnie: `/paul:complete-milestone v0.7`