WinterCMS research
This commit is contained in:
@@ -0,0 +1,146 @@
|
||||
---
|
||||
phase: 15-locale-detection-routing
|
||||
verified: 2026-02-02T01:12:14Z
|
||||
status: passed
|
||||
score: 11/11 must-haves verified
|
||||
---
|
||||
|
||||
# Phase 15: Locale Detection & Routing Verification Report
|
||||
|
||||
**Phase Goal:** URL-based locale switching (/pl/, /de/), browser detection for first visit, persistent user preference, language switcher UI
|
||||
**Verified:** 2026-02-02T01:12:14Z
|
||||
**Status:** passed
|
||||
**Re-verification:** No - initial verification
|
||||
|
||||
## Goal Achievement
|
||||
|
||||
### Observable Truths
|
||||
|
||||
| # | Truth | Status | Evidence |
|
||||
|---|-------|--------|----------|
|
||||
| 1 | Manual locale selection via LocalePicker sets 1-year cookie | VERIFIED | `plugins/golem15/quotify/Plugin.php:503-507` - Cookie::queue with manualSelectionCookie config key, 525600 min expiry |
|
||||
| 2 | URL prefix visit (/pl/, /de/) sets manual selection cookie | VERIFIED | `plugins/golem15/translate/routes.php:31-35` - Cookie::queue after loadLocaleFromRequest() succeeds |
|
||||
| 3 | Logged-in user's locale switch updates their DB preference | VERIFIED | `plugins/golem15/quotify/Plugin.php:510-513` - Auth::getUser()->preferred_locale = $locale; $user->save() |
|
||||
| 4 | Browser detection skipped when manual selection cookie exists | VERIFIED | `plugins/golem15/translate/classes/LocaleMiddleware.php:214-228` - hasManualLocaleSelection() checks cookie |
|
||||
| 5 | Language switcher dropdown visible in header | VERIFIED | `themes/quotify/partials/header.htm:15-17` - includes language-switcher partial in header-actions |
|
||||
| 6 | Clicking language option switches locale and reloads page | VERIFIED | `themes/quotify/partials/language-switcher.htm:17` - data-request="localePicker::onSwitchLocale" |
|
||||
| 7 | Current language name shown in native form (Polski, Deutsch, English) | VERIFIED | `themes/quotify/partials/language-switcher.htm:7` - displays activeLocaleName from LocalePicker |
|
||||
| 8 | All pages have hreflang tags for SEO | VERIFIED | All 3 layouts (default, dashboard, empty) have alternateHrefLangElements component and {% component 'alternateHrefLangElements' %} |
|
||||
| 9 | Account settings has language preference section | VERIFIED | `themes/quotify/partials/account/update.htm:97-118` - Language Preference section with dropdown |
|
||||
| 10 | Logged-in users can select preferred language in profile | VERIFIED | `themes/quotify/partials/account/update.htm:107` - name="preferred_locale" select element in form_ajax onUpdate |
|
||||
| 11 | Language suggestion banner appears when browser language differs | VERIFIED | `plugins/golem15/translate/components/LocaleSuggestionBanner.php` - shouldShowBanner() logic with Accept-Language detection |
|
||||
| 12 | Dismissing banner sets cookie to prevent showing again | VERIFIED | `plugins/golem15/translate/components/LocaleSuggestionBanner.php:96` - locale_banner_dismissed cookie, 1 week expiry |
|
||||
|
||||
**Score:** 11/11 truths verified (12 listed but 11-12 are sub-items of the same truth)
|
||||
|
||||
### Required Artifacts
|
||||
|
||||
| Artifact | Expected | Status | Details |
|
||||
|----------|----------|--------|---------|
|
||||
| `plugins/golem15/quotify/Plugin.php` | LocalePicker extension with cookie and DB sync | VERIFIED | extendLocalePicker() method at lines 482-517 |
|
||||
| `plugins/golem15/translate/routes.php` | Cookie setting on URL prefix detection | VERIFIED | Cookie::queue at lines 31-35 after locale loaded |
|
||||
| `themes/quotify/partials/language-switcher.htm` | Dropdown language switcher UI | VERIFIED | 58 lines, accessible dropdown with ARIA, JS toggle |
|
||||
| `themes/quotify/partials/header.htm` | Header with language switcher | VERIFIED | Lines 14-17 include language-switcher partial |
|
||||
| `themes/quotify/layouts/default.htm` | Layout with hreflang and LocalePicker | VERIFIED | Components registered, hreflang output at line 23 |
|
||||
| `themes/quotify/layouts/dashboard.htm` | Layout with hreflang and LocalePicker | VERIFIED | Components registered lines 7-9, hreflang output at line 22 |
|
||||
| `themes/quotify/layouts/empty.htm` | Layout with hreflang and LocalePicker | VERIFIED | Components registered lines 4-5, hreflang output at line 15 |
|
||||
| `themes/quotify/partials/account/update.htm` | Language preference section in account settings | VERIFIED | Language Preference section lines 97-118 with preferred_locale field |
|
||||
| `plugins/golem15/translate/components/LocaleSuggestionBanner.php` | Component for language mismatch detection | VERIFIED | 120 lines, shouldShowBanner(), getSuggestedLocale(), onDismissBanner() |
|
||||
| `plugins/golem15/translate/components/localesuggestionbanner/default.htm` | Banner template | VERIFIED | 35 lines, conditional banner with localized text |
|
||||
| `themes/quotify/assets/css/components/language-switcher.css` | Language switcher styles | VERIFIED | 115 lines, responsive design |
|
||||
| `themes/quotify/assets/css/components/locale-banner.css` | Banner styles | VERIFIED | 85 lines, sticky positioning, gradient background |
|
||||
| `themes/quotify/assets/css/app.css` | Imports for both CSS files | VERIFIED | Lines 14-15 import language-switcher.css and locale-banner.css |
|
||||
|
||||
### Key Link Verification
|
||||
|
||||
| From | To | Via | Status | Details |
|
||||
|------|-----|-----|--------|---------|
|
||||
| LocalePicker::onSwitchLocale | Cookie::queue | Component extension in Plugin.php boot() | WIRED | `Plugin.php:503` - Cookie::queue call inside bindEvent handler |
|
||||
| LocalePicker::onSwitchLocale | User::preferred_locale | Auth::getUser()->save() | WIRED | `Plugin.php:510-513` - Auth check + save |
|
||||
| language-switcher.htm | localePicker::onSwitchLocale | data-request attribute | WIRED | `language-switcher.htm:17` - data-request present |
|
||||
| routes.php | Cookie::queue | After loadLocaleFromRequest() | WIRED | `routes.php:31-35` - Cookie set after locale loaded |
|
||||
| LocaleMiddleware | hasManualLocaleSelection | Cookie read in detection cascade | WIRED | `LocaleMiddleware.php:34` - calls hasManualLocaleSelection |
|
||||
| default.htm | alternateHrefLangElements | Component registration | WIRED | Component registered line 8, output line 23 |
|
||||
| account/update.htm | Account::onUpdate | Form submission with preferred_locale | WIRED | form_ajax('onUpdate') at line 95, preferred_locale field at line 107 |
|
||||
| LocaleSuggestionBanner | Accept-Language detection | detectBrowserLocale() | WIRED | `LocaleSuggestionBanner.php:63-79` - Request::header parsing |
|
||||
| onDismissBanner | Cookie::queue | locale_banner_dismissed cookie | WIRED | `LocaleSuggestionBanner.php:96` - 1-week cookie set |
|
||||
|
||||
### Requirements Coverage
|
||||
|
||||
Phase 15 requirements from ROADMAP.md:
|
||||
- URL-based locale switching (/pl/, /de/) - SATISFIED
|
||||
- Browser detection for first visit - SATISFIED
|
||||
- Persistent user preference - SATISFIED
|
||||
- Language switcher UI - SATISFIED
|
||||
|
||||
### Anti-Patterns Found
|
||||
|
||||
| File | Line | Pattern | Severity | Impact |
|
||||
|------|------|---------|----------|--------|
|
||||
| - | - | None found | - | - |
|
||||
|
||||
No stub patterns, placeholder content, or empty implementations detected in any verified artifacts.
|
||||
|
||||
### Human Verification Required
|
||||
|
||||
### 1. Visual Language Switcher Appearance
|
||||
**Test:** Navigate to homepage, check header area
|
||||
**Expected:** Language switcher dropdown visible near right side of header, styled consistently with site design
|
||||
**Why human:** Visual appearance and styling cannot be verified programmatically
|
||||
|
||||
### 2. Language Switch Flow
|
||||
**Test:** Click language switcher, select "Polski" or "Deutsch"
|
||||
**Expected:** Page reloads in selected language, switcher shows new language name
|
||||
**Why human:** Page reload and full interaction flow requires browser testing
|
||||
|
||||
### 3. Mobile Language Switcher
|
||||
**Test:** View site on mobile viewport (< 768px)
|
||||
**Expected:** Language label hidden, globe icon visible, touch targets adequate
|
||||
**Why human:** Responsive behavior requires actual device/viewport testing
|
||||
|
||||
### 4. hreflang Tags in Source
|
||||
**Test:** View page source, search for "hreflang"
|
||||
**Expected:** `<link rel="alternate" hreflang="en/pl/de" href="...">` tags present for all locales
|
||||
**Why human:** Need to verify rendered HTML output
|
||||
|
||||
### 5. Account Settings Language Preference
|
||||
**Test:** Log in, go to account settings, select "Account Info" tab
|
||||
**Expected:** Language Preference section visible with dropdown showing en/pl/de options
|
||||
**Why human:** Requires authenticated session and UI interaction
|
||||
|
||||
### 6. Language Suggestion Banner
|
||||
**Test:** Clear cookies, set browser language to German, visit English page
|
||||
**Expected:** Banner appears at top: "Diese Seite ist auf Deutsch verfugbar" with switch button
|
||||
**Why human:** Requires browser language configuration and cookie clearing
|
||||
|
||||
### 7. Banner Dismissal Persistence
|
||||
**Test:** Dismiss the suggestion banner, refresh page
|
||||
**Expected:** Banner does not reappear (cookie prevents)
|
||||
**Why human:** Requires cookie behavior verification
|
||||
|
||||
### Gaps Summary
|
||||
|
||||
No gaps found. All must-haves verified as implemented:
|
||||
|
||||
**Plan 15-01 (Core Locale Infrastructure):**
|
||||
- LocalePicker extension in Quotify Plugin.php sets 1-year cookie on manual locale switch
|
||||
- routes.php sets cookie when URL prefix detected
|
||||
- LocaleMiddleware correctly skips browser detection when cookie present
|
||||
- Logged-in users' preferences saved to database
|
||||
|
||||
**Plan 15-02 (Language Switcher UI):**
|
||||
- Language switcher partial created with accessible dropdown
|
||||
- Integrated into header across all pages
|
||||
- All three layouts register localePicker and alternateHrefLangElements components
|
||||
- hreflang tags output in head section of all layouts
|
||||
|
||||
**Plan 15-03 (Account Settings & Suggestion Banner):**
|
||||
- Language Preference section added to account settings
|
||||
- LocaleSuggestionBanner component created with browser detection
|
||||
- Banner template with localized text in target language
|
||||
- Dismissal cookie (1 week) prevents repeated banner display
|
||||
|
||||
---
|
||||
|
||||
*Verified: 2026-02-02T01:12:14Z*
|
||||
*Verifier: Claude (gsd-verifier)*
|
||||
Reference in New Issue
Block a user