Як визначити мову сторінки в Publii без плагінів
Частина 2. Як визначити мову сторінки в Publii
Продовження Частина 1. Чому мені знадобився власний i18n у Publii
У першій частині я зупинився на простій, але показовій проблемі: англомовний пост — і український інтерфейс навколо нього.
Перш ніж перекладати тексти, дати чи plural, потрібно відповісти на базове питання:
Якою мовою зараз відкрито цю сторінку?
У Publii немає вбудованої відповіді на це питання для окремо взятої теми. Тому її доводиться знаходити самостійно — але, на щастя, це можна зробити досить просто.
Основна ідея полягала в тому, що не потрібно намагатися вигадувати складну систему. Я виходив з простого припущення: Якщо сторінка має мовну версію, яка позначена в її URL або slug то post-title-en, about-de, homepage-uk більш ніж достатньо для статичного сайту.
Витягуємо мову зі slug або URL
Почнемо з маленької функції, яка шукає код мови в рядку:
function detectLang(ctx) {
const slug = ctx?.slug || '';
if (/(^|[-_])en([-_]|$)/i.test(slug)) return 'en';
if (/(^|[-_])de([-_]|$)/i.test(slug)) return 'de';
if (/(^|[-_])uk([-_]|$)/i.test(slug)) return 'uk';
return null;
}
Що тут відбувається:
- ми не прив’язані до конкретного формату, підтримуються
- і _ - код мови може бути: на початку, в середині, в кінці
slug, а якщо мови немає — повертаєтьсяnull.
Ця функція нічого не вирішує сама. Вона лише відповідає на запитання: «Я бачу тут код мови чи ні?»
Але однієї функції detectLang недостатньо. У Publii helper може викликатися в різному контексті: постс, торінка, головна, partial, index. І в кожному з них: this, post, page, root можуть виглядати по-різному. Тому мені потрібна була функція, яка перевіряє кілька джерел і робить це в правильному порядку, завжди повертаючи мову.
Функція resolveLang
function resolveLang(ctx, root) {
const url =
root?.post?.url ||
root?.page?.url ||
root?.url ||
'';
const fromUrl = detectLang({ slug: url });
if (fromUrl) return fromUrl;
const fromPost = detectLang(root?.post);
if (fromPost) return fromPost;
const fromCtx = detectLang(ctx);
if (fromCtx) return fromCtx;
return root?.website?.language?.substring(0, 2) || 'uk';
}
Давайте розберемо логіку по кроках.
URL сторінки — найнадійніше джерело
root?.post?.url ||
root?.page?.url ||
root?.url
URL — це фінальний результат генерації сторінки. Якщо мова є там — це найточніший варіант. Тому він іде першим.
slug поста
Іноді helper викликається ще до того, як URL доступний повністю. У такому випадку slug поста — хороший fallback.
локальний контекст helper
Це страховка для edge cases: partial, нестандартний виклик, кастомна логіка в шаблоні.
Fallback на мову сайту
root?.website?.language?.substring(0, 2) || 'uk'
Це важливо з двох причин:
- helper завжди повертає мову
- тема ніколи не ламається
Навіть якщо сторінка без мовного коду — інтерфейс залишиться консистентним.
Чому я не використовую cookies або JS
Тому що:
- це статичний сайт
- Publii генерує HTML
- усе має працювати без клієнтської логіки
Мова сторінки має бути визначена на етапі генерації, а не в браузері.
На цьому етапі у нас є проста функція визначення мови, передбачуваний результат, відсутність залежностей, однакова поведінка для всіх helpers. І тепер можна зробити головне — передати цю мову в будь-який helper теми.
Що далі?
Тепер, коли ми знаємо мову сторінки, логічно перейти до перекладу текстів. У наступній частині я покажу: як я зберігаю словники, як працює helper {{t}}, чому post.readMore — зручніший за плоскі ключі і як fallback рятує шаблони.
Коментарі:
Завантаження коментарів…