️ fix: improve accessibility and i18n (#183)

main
Óscar Fernández 1 year ago committed by GitHub
parent 28fb52581f
commit 2c6ac293ad
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23

@ -19,6 +19,10 @@ next = "Següent" # As in "Next" page.
of = "de" # E.g. Page 1 "of" 3
all_posts = "Totes les entrades"
all_tags = "Totes les etiquetes"
language_selection = "Selecció d'idioma"
toggle_mode = "Canvia el mode $MODE" # $MODE will be replaced by a value (or both) below.
dark = "obscur"
light = "clar"
# Post metadata.
draft = "ESBORRANY"
@ -31,6 +35,10 @@ see_changes = "Veure canvis"
table_of_contents = "Taula de contingut"
load_comments = "Carregar comentaris"
# Copy code block button.
copied = "Copiat!"
copy_code_to_clipboard = "Copia el codi al porta-retalls"
# Footer: Powered by Zola and tabi.
powered_by = "Propulsat per"
and = "i"

@ -23,6 +23,10 @@ next = "Nächst" # As in "Next" page.
of = "von" # E.g. Page 1 "of" 3
all_posts = "Alle Beiträge"
all_tags = "Alle Tags"
language_selection = "Sprachauswahl"
toggle_mode = "Wechsle in den $MODE Modus" # $MODE will be replaced by a value (or both) below.
dark = "dunkel"
light = "hell"
# Post metadata.
draft = "ENTWURF"
@ -35,6 +39,10 @@ see_changes = "Änderungen anzeigen"
table_of_contents = "Inhaltsverzeichnis"
load_comments = "Kommentare laden"
# Copy code block button.
copied = "Kopiert!"
copy_code_to_clipboard = "Code in die Zwischenablage kopieren"
# Footer.
powered_by = "Angetrieben von"
and = "und"

@ -19,6 +19,10 @@ next = "Next" # As in "Next" page.
of = "of" # E.g. Page 1 "of" 3
all_posts = "All posts"
all_tags = "All tags"
language_selection = "Language selection"
toggle_mode = "Toggle $MODE mode" # $MODE will be replaced by a value (or both) below.
dark = "dark"
light = "light"
# Post metadata.
draft = "DRAFT"
@ -31,6 +35,10 @@ see_changes = "See changes"
table_of_contents = "Table of Contents"
load_comments = "Load comments"
# Copy code block button.
copied = "Copied!"
copy_code_to_clipboard = "Copy code to clipboard"
# Footer: Powered by Zola and tabi.
powered_by = "Powered by"
and = "&"

@ -19,6 +19,10 @@ next = "Siguiente" # As in "Next" page.
of = "sur" # E.g. Page 1 "of" 3
all_posts = "Todas las entradas"
all_tags = "Todas las etiquetas"
language_selection = "Selección de idioma"
toggle_mode = "Cambiar a modo $MODE" # $MODE will be replaced by a value (or both) below.
dark = "oscuro"
light = "claro"
# Post metadata.
draft = "BORRADOR"
@ -31,6 +35,10 @@ see_changes = "Ver cambios"
table_of_contents = "Tabla de contenido"
load_comments = "Cargar comentarios"
# Copy code block button.
copied = "Copiado!"
copy_code_to_clipboard = "Copiar código al portapapeles"
# Footer: Powered by Zola and tabi.
powered_by = "Impulsado por"
and = "y"

@ -23,6 +23,10 @@ next = "Suivant" # As in "Next" page.
of = "de" # E.g. Page 1 "of" 3
all_posts = "Tous les articles"
all_tags = "Toutes les étiquettes"
language_selection = "Sélection de la langue"
toggle_mode = "Basculer en mode $MODE" # $MODE will be replaced by a value (or both) below.
dark = "sombre"
light = "clair"
# Post metadata.
draft = "BROUILLON"
@ -35,6 +39,10 @@ see_changes = "Voir les modifications"
table_of_contents = "Table des matières"
load_comments = "Afficher les commentaires"
# Copy code block button.
copied = "Copié!"
copy_code_to_clipboard = "Copier le code dans le presse-papiers"
# Footer: Powered by Zola and tabi.
powered_by = "Propulsé par"
and = "et"

@ -21,6 +21,10 @@ next = "अगला" # As in "Next" page.
of = "का" # E.g. Page 1 "of" 3
all_posts = "सभी पोस्ट्स"
all_tags = "सभी टैग्स"
language_selection = "भाषा चयन"
toggle_mode = "$MODE मोड में टॉगल करें" # $MODE will be replaced by a value (or both) below.
dark = "अंधेरा"
light = "रोशनी"
# Post metadata.
draft = "मसौदा"
@ -33,6 +37,10 @@ see_changes = "बदलाव देखें"
table_of_contents = "विषय सूची"
load_comments = "कमेंट्स लोड करें"
# Copy code block button.
copied = "कॉपी किया गया!"
copy_code_to_clipboard = "कोड क्लिपबोर्ड में कॉपी करें"
# Footer: Powered by Zola and tabi.
powered_by = "चालित द्वारा"
and = "और"

@ -19,6 +19,10 @@ next = "Successivo" # As in "Next" page.
of = "di" # E.g. Page 1 "of" 3
all_posts = "Tutti i post"
all_tags = "Tutti i tag"
language_selection = "Selezione della lingua"
toggle_mode = "Passa alla modalità $MODE" # $MODE will be replaced by a value (or both) below.
dark = "scuro"
light = "chiaro"
# Post metadata.
draft = "BOZZA"
@ -31,6 +35,10 @@ see_changes = "Vedi modifiche"
table_of_contents = "Indice"
load_comments = "Carica commenti"
# Copy code block button.
copied = "Copiato!"
copy_code_to_clipboard = "Copia codice negli appunti"
# Footer: Powered by Zola and tabi.
powered_by = "Alimentato da"
and = "e"

@ -23,6 +23,10 @@ next = "次" # As in "Next" page.
of = "中" # E.g. Page 1 "of" 3
all_posts = "すべての投稿"
all_tags = "すべてのタグ"
language_selection = "言語選択"
toggle_mode = "$MODE モードに切り替え" # $MODE will be replaced by a value (or both) below.
dark = "暗い"
light = "明るい"
# Post metadata.
draft = "ドラフト"
@ -35,6 +39,10 @@ see_changes = "変更を見る"
table_of_contents = "目次"
load_comments = "コメントを読む"
# Copy code block button.
copied = "コピーしました!"
copy_code_to_clipboard = "コードをクリップボードにコピー"
# Footer: Powered by Zola and tabi.
powered_by = "Powered by"
and = "と"

@ -23,6 +23,10 @@ next = "다음" # As in "Next" page.
of = "중" # E.g. Page 1 "of" 3
all_posts = "모든 게시물"
all_tags = "모든 태그"
language_selection = "언어 선택"
toggle_mode = "$MODE 모드로 전환" # $MODE will be replaced by a value (or both) below.
dark = "어두운"
light = "밝은"
# Post metadata.
draft = "임시 저장"
@ -35,6 +39,10 @@ see_changes = "변경사항 보기"
table_of_contents = "목차"
load_comments = "댓글 불러오기"
# Copy code block button.
copied = "복사됨!"
copy_code_to_clipboard = "코드를 클립보드에 복사"
# Footer: Powered by Zola and tabi.
powered_by = "제공됨"
and = "&"

@ -19,6 +19,10 @@ next = "Seguinte" # As in "Next" page.
of = "de" # E.g. Page 1 "of" 3
all_posts = "Todas as publicações"
all_tags = "Todas as etiquetas"
language_selection = "Seleção de idioma"
toggle_mode = "Alternar para o modo $MODE" # $MODE will be replaced by a value (or both) below.
dark = "escuro"
light = "claro"
# Post metadata.
draft = "RASCUNHO"
@ -31,6 +35,10 @@ see_changes = "Ver alterações"
table_of_contents = "Índice de conteúdo"
load_comments = "Carregar comentários"
# Copy code block button.
copied = "Copiado!"
copy_code_to_clipboard = "Copiar código para a área de transferência"
# Footer: Powered by Zola and tabi.
powered_by = "Impulsionado por"
and = "e"

@ -19,6 +19,10 @@ next = "След." # As in "Next" page.
of = "из" # E.g. Page 1 "of" 3
all_posts = "Все посты"
all_tags = "Все теги"
language_selection = "Выбор языка"
toggle_mode = "Переключить на режим $MODE" # $MODE will be replaced by a value (or both) below.
dark = "тёмный"
light = "светлый"
# Post metadata.
draft = "ЧЕРНОВИК"
@ -31,6 +35,10 @@ see_changes = "Смотреть изменения"
table_of_contents = "Содержание"
load_comments = "Загрузить комментарии"
# Copy code block button.
copied = "Скопировано!"
copy_code_to_clipboard = "Скопировать код в буфер обмена"
# Footer: Powered by Zola and tabi.
powered_by = "Под управлением"
and = "&"

@ -23,6 +23,10 @@ next = "Наст." # As in "Next" page.
of = "з" # E.g. Page 1 "of" 3
all_posts = "Всі пости"
all_tags = "Всі теги"
language_selection = "Вибір мови"
toggle_mode = "Перемкнути в режим $MODE" # $MODE will be replaced by a value (or both) below.
dark = "темний"
light = "світлий"
# Post metadata.
draft = "ЧЕРНЕТКА"
@ -35,6 +39,10 @@ see_changes = "Переглянути зміни"
table_of_contents = "Зміст"
load_comments = "Завантажити коментарі"
# Copy code block button.
copied = "Скопійовано!"
copy_code_to_clipboard = "Копіювати код у буфер обміну"
# Footer: Powered by Zola and tabi.
powered_by = "Під управлінням"
and = "та"

@ -19,6 +19,10 @@ next = "下一页" # As in "Next" page.
of = "/" # E.g. Page 1 "of" 3
all_posts = "所有文章"
all_tags = "所有标签"
language_selection = "语言选择" # Machine translated.
toggle_mode = "切换到$MODE模式" # $MODE will be replaced by a value (or both) below. Machine translated.
dark = "暗" # Machine translated.
light = "亮" # Machine translated.
# Post metadata.
draft = "草稿"
@ -31,6 +35,10 @@ see_changes = "修改纪录"
table_of_contents = "目录"
load_comments = "载入留言"
# Copy code block button.
copied = "已复制!" # Machine translated.
copy_code_to_clipboard = "复制代码到剪贴板" # Machine translated.
# Footer: Powered by Zola and tabi.
powered_by = "网站基于"
and = "和"

@ -19,6 +19,10 @@ next = "下一頁" # As in "Next" page.
of = "/" # E.g. Page 1 "of" 3
all_posts = "所有文章"
all_tags = "所有標籤"
language_selection = "語言選擇" # Machine translated.
toggle_mode = "切換到$MODE模式" # $MODE will be replaced by a value (or both) below. Machine translated.
dark = "暗" # Machine translated.
light = "亮" # Machine translated.
# Post metadata.
draft = "草稿"
@ -31,6 +35,10 @@ see_changes = "修改紀錄"
table_of_contents = "目錄"
load_comments = "載入留言"
# Copy code block button.
copied = "已复制!" # Machine translated.
copy_code_to_clipboard = "复制代码到剪贴板" # Machine translated.
# Footer: Powered by Zola and tabi.
powered_by = "網站基於"
and = "和"

@ -81,14 +81,12 @@ header {
list-style-type: none;
}
}
.language-switcher {
display: flex;
justify-content: center;
align-items: center;
margin-right: 0.5rem;
margin-left: 0.5rem;
}
.language-switcher-icon {
-webkit-mask: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24'%3E%3Cpath fill='none' stroke='%23000' stroke-width='1.8' d='M1 12a11 11 90 0 0 22 0 11 11 90 0 0-22 0m1-4h20M2 16h20M11 1a21 21 90 0 0 0 22m2-22a21 21 90 0 1 0 22'/%3E%3C/svg%3E%0A");
@ -98,6 +96,11 @@ header {
background: var(--text-color);
width: 1rem;
height: 1rem;
&:hover {
background: var(--meta-color);
}
}
}
.dropdown {
@ -105,6 +108,18 @@ header {
position: relative;
z-index: 1;
font-size: 0.8rem;
&:hover .dropdown-content,
&:focus-within .dropdown-content {
display: block;
}
summary {
list-style: none;
&::-webkit-details-marker {
display: none;
}
}
.dropdown-content {
@ -123,9 +138,6 @@ header {
display: block;
}
}
.dropdown:hover .dropdown-content {
display: block;
}
@media only screen and (max-width: 1000px) {

@ -150,3 +150,7 @@ hr {
#page-content {
margin-top: 4vmin;
}
.hidden {
display: none;
}

@ -7,4 +7,7 @@
background: var(--text-color);
width: 1rem;
height: 1rem;
&:hover {
background: var(--meta-color);
}
}

@ -1,6 +1,13 @@
const copiedText = document.getElementById('copy-success').textContent;
const initCopyText = document.getElementById('copy-init').textContent;
const changeIcon = (copyDiv, className) => {
copyDiv.classList.add(className);
setTimeout(() => copyDiv.classList.remove(className), 2500);
copyDiv.setAttribute("aria-label", copiedText);
setTimeout(() => {
copyDiv.classList.remove(className);
copyDiv.setAttribute("aria-label", initCopyText);
}, 2500);
};
const addCopyEventListenerToDiv = (copyDiv, block) => {
@ -31,6 +38,9 @@ const getTableCode = (block) => {
document.querySelectorAll("pre").forEach((block) => {
const copyDiv = document.createElement("div");
copyDiv.setAttribute("role", "button");
copyDiv.setAttribute("aria-label", initCopyText);
copyDiv.setAttribute("title", initCopyText);
copyDiv.className = "copy-code";
block.prepend(copyDiv);
addCopyEventListenerToDiv(copyDiv, block);

@ -1 +1 @@
const changeIcon=(e,t)=>{e.classList.add(t),setTimeout(()=>e.classList.remove(t),2500)},addCopyEventListenerToDiv=(e,t)=>{e.addEventListener("click",()=>copyCodeAndChangeIcon(e,t))},copyCodeAndChangeIcon=async(e,t)=>{let o=t.querySelector("table")?getTableCode(t):getNonTableCode(t);try{await navigator.clipboard.writeText(o),changeIcon(e,"checked")}catch(c){changeIcon(e,"error")}},getNonTableCode=e=>[...e.querySelectorAll("code")].map(e=>e.textContent).join(""),getTableCode=e=>[...e.querySelectorAll("tr")].map(e=>e.querySelector("td:last-child")?.innerText??"").join("");document.querySelectorAll("pre").forEach(e=>{let t=document.createElement("div");t.className="copy-code",e.prepend(t),addCopyEventListenerToDiv(t,e)});
const copiedText=document.getElementById("copy-success").textContent,initCopyText=document.getElementById("copy-init").textContent,changeIcon=(e,t)=>{e.classList.add(t),e.setAttribute("aria-label",copiedText),setTimeout(()=>{e.classList.remove(t),e.setAttribute("aria-label",initCopyText)},2500)},addCopyEventListenerToDiv=(e,t)=>{e.addEventListener("click",()=>copyCodeAndChangeIcon(e,t))},copyCodeAndChangeIcon=async(t,e)=>{e=(e.querySelector("table")?getTableCode:getNonTableCode)(e);try{await navigator.clipboard.writeText(e),changeIcon(t,"checked")}catch(e){changeIcon(t,"error")}},getNonTableCode=e=>[...e.querySelectorAll("code")].map(e=>e.textContent).join(""),getTableCode=e=>[...e.querySelectorAll("tr")].map(e=>e.querySelector("td:last-child")?.innerText??"").join("");document.querySelectorAll("pre").forEach(e=>{var t=document.createElement("div");t.setAttribute("role","button"),t.setAttribute("aria-label",initCopyText),t.setAttribute("title",initCopyText),t.className="copy-code",e.prepend(t),addCopyEventListenerToDiv(t,e)});

@ -8,6 +8,8 @@ let currentTheme = localStorage.getItem("theme") || document.documentElement.get
function setTheme(theme, saveToLocalStorage = false) {
document.documentElement.setAttribute("data-theme", theme);
currentTheme = theme;
let togglePressed = theme === "dark" ? "true" : "false";
themeSwitcher.setAttribute("aria-pressed", togglePressed);
if (saveToLocalStorage) {
localStorage.setItem("theme", theme);
@ -29,6 +31,10 @@ function switchTheme() {
// Initialize the theme switcher button.
themeSwitcher.addEventListener("click", switchTheme, false);
themeSwitcher.setAttribute("role", "button");
themeSwitcher.setAttribute("aria-label", "Toggle dark mode");
let togglePressed = currentTheme === "dark" ? "true" : "false";
themeSwitcher.setAttribute("aria-pressed", togglePressed);
// Update the theme based on system preference if the user hasn't manually changed the theme.
window.matchMedia("(prefers-color-scheme: dark)").addEventListener("change", e => {

@ -1 +1 @@
const themeSwitcher=document.querySelector(".theme-switcher");let currentTheme=localStorage.getItem("theme")||document.documentElement.getAttribute("data-theme");function setTheme(e,t=!1){document.documentElement.setAttribute("data-theme",e),currentTheme=e,t&&localStorage.setItem("theme",e);t=new CustomEvent("themeChanged",{detail:{theme:e}});window.dispatchEvent(t)}function switchTheme(){setTheme("dark"===currentTheme?"light":"dark",!0)}themeSwitcher.addEventListener("click",switchTheme,!1),window.matchMedia("(prefers-color-scheme: dark)").addEventListener("change",e=>{setTheme(e.matches?"dark":"light")});
const themeSwitcher=document.querySelector(".theme-switcher");let currentTheme=localStorage.getItem("theme")||document.documentElement.getAttribute("data-theme");function setTheme(e,t=!1){document.documentElement.setAttribute("data-theme",e);var r="dark"===(currentTheme=e)?"true":"false",r=(themeSwitcher.setAttribute("aria-pressed",r),t&&localStorage.setItem("theme",e),new CustomEvent("themeChanged",{detail:{theme:e}}));window.dispatchEvent(r)}function switchTheme(){setTheme("dark"===currentTheme?"light":"dark",!0)}themeSwitcher.addEventListener("click",switchTheme,!1),themeSwitcher.setAttribute("role","button"),themeSwitcher.setAttribute("aria-label","Toggle dark mode");let togglePressed="dark"===currentTheme?"true":"false";themeSwitcher.setAttribute("aria-pressed",togglePressed),window.matchMedia("(prefers-color-scheme: dark)").addEventListener("change",e=>{setTheme(e.matches?"dark":"light")});

@ -37,6 +37,13 @@
{# Add copy button to code blocks #}
{%- if macros_settings::evaluate_setting_priority(setting="copy_button", page=page, default_global_value=true) == "true" -%}
{#- Add hidden HTML elements with the translated strings for the button's interactions -#}
<span id="copy-success" class="hidden">
{{ macros_translate::translate(key="copied", default="Copied!", language_strings=language_strings) }}
</span>
<span id="copy-init" class="hidden">
{{ macros_translate::translate(key="copy_code_to_clipboard", default="Copy code to clipboard", language_strings=language_strings) }}
</span>
<script defer src="{{ get_url(path='js/copyCodeToClipboard.min.js', trailing_slash=false) | safe }}"></script>
{%- endif -%}

@ -1,43 +1,38 @@
<li class="language-switcher">
<div class="dropdown" type="Button">
<details class="dropdown">
<summary role="button" aria-haspopup="true" title="{{ macros_translate::translate(key="language_selection", default="Language selection", language_strings=language_strings) }}" aria-label="{{ macros_translate::translate(key="language_selection", default="Language selection", language_strings=language_strings) }}">
<div class="language-switcher-icon"></div>
<div class="dropdown-content">
</summary>
<div class="dropdown-content" role="menu">
{#- Display the current language first in the dropdown -#}
{{ macros_translate::translate(key="language_name", default=lang, language_strings=language_strings) }}
{#- Loop through all the available languages in the config -#}
{%- for lcode, ldetails in config.languages -%}
{#- Skip the current language to avoid linking to the current page -#}
{%- if lang == lcode -%}
{%- continue -%}
{%- endif -%}
{#- Dynamically load the language strings for each language -#}
{%- set other_language_strings = load_data(path="i18n/" ~ lcode ~ ".toml", required=false) -%}
{%- if not other_language_strings -%}
{%- set other_language_strings = load_data(path="themes/tabi/i18n/" ~ lcode ~ ".toml", required=false) -%}
{%- endif -%}
{#- Use the loaded language strings to get the language name -#}
{% set language_name = macros_translate::translate(key="language_name", default=lcode,
language_strings=other_language_strings) %}
{#- Check if the language code matches the default language -#}
{%- if lcode == config.default_language -%}
{#- If it does, link to the root path (no language code in URL) -#}
<a type="Button" href="{{ current_url | replace(from='/' ~ lang ~ '/', to = '/') }}">{{ language_name }}</a>
{%- elif lang == config.default_language -%}
<a role="menuitem" lang="{{ lcode }}" aria-label="{{ language_name }}" href="{{ current_url | replace(from='/' ~ lang ~ '/', to = '/') }}">{{ language_name }}</a>
{#- Check if the current language is the default language -#}
{#- If it is, append the language code to the base URL -#}
<a type="Button" href="{{ config.base_url }}/{{ lcode }}{{ current_path | default(value=" /") | safe }}">{{
language_name }}</a>
{%- elif lang == config.default_language -%}
<a role="menuitem" lang="{{ lcode }}" aria-label="{{ language_name }}" href="{{ config.base_url }}/{{ lcode }}{{ current_path | default(value=" /") | safe }}">{{ language_name }}</a>
{%- else -%}
{#- If it's not, replace the current language code in the URL with the new one -#}
<a type="Button" href="{{ current_url | replace(from='/' ~ lang ~ '/', to='/' ~ lcode ~ '/') }}">{{
language_name }}</a>
<a role="menuitem" lang="{{ lcode }}" aria-label="{{ language_name }}" href="{{ current_url | replace(from='/' ~ lang ~ '/', to='/' ~ lcode ~ '/') }}">{{ language_name }}</a>
{%- endif -%}
{%- endfor -%}
</div>
</div>
</details>
</li>

@ -26,9 +26,7 @@
{# Theme switcher #}
{%- if config.extra.theme_switcher and config.extra.theme_switcher == true -%}
<li class="theme-switcher-wrapper js">
<div class="theme-switcher" title="Toggle dark/light theme"></div>
</li>
{%- include "partials/theme_switcher.html" -%}
{%- endif -%}
</ul>
</div>

@ -0,0 +1,18 @@
<li class="theme-switcher-wrapper js">
{#- Create the localised strings for the title and aria-label attributes -#}
{%- set toggle_str = macros_translate::translate(key='toggle_mode', default='Toggle $MODE mode', language_strings=language_strings) -%}
{%- set dark_str = macros_translate::translate(key='dark', default='dark', language_strings=language_strings) -%}
{%- set light_str = macros_translate::translate(key='light', default='light', language_strings=language_strings) -%}
{%- set combined_mode_str = dark_str ~ "/" ~ light_str -%}
{%- set title_label = toggle_str | replace(from="$MODE", to=combined_mode_str) -%}
{%- set aria_label = 'Toggle ' ~ dark_str ~ ' mode' -%}
<div
title="{{ title_label }}"
class="theme-switcher"
role="button"
aria-label="{{ aria_label }}"
aria-pressed="false">
</div>
</li>
Loading…
Cancel
Save