docs(nav): fix sidebar nesting, dynamic language switcher, and delete translations page (#5535)

This commit is contained in:
James Rich
2026-05-20 08:42:34 -07:00
committed by GitHub
parent 19d10a18cd
commit 89fe2b58d7
31 changed files with 223 additions and 204 deletions
+1 -2
View File
@@ -17,8 +17,7 @@ docs/
│ ├── developer/ ← Developer Guide pages
│ ├── index.md ← Site home page
│ ├── user.md ← User Guide nav parent
── developer.md ← Developer Guide nav parent
│ └── translations.md ← Translations landing page
── developer.md ← Developer Guide nav parent
├── fr-rFR/ ← French (Crowdin-generated)
│ └── user/ ← Translated user guide
├── de-rDE/ ← German (Crowdin-generated)
+76 -72
View File
@@ -30,171 +30,169 @@ defaults:
- scope:
path: "en/user/"
values:
parent: User Guide
layout: default
- scope:
path: "en/developer/"
values:
parent: Developer Guide
layout: default
# Locale-translated pages are excluded from main nav but still rendered.
# They use a dedicated locale layout with a back-link to the English version.
# Auto-generated from Android app locales (values-* resource dirs).
- scope:
path: "ar"
path: "ar-rSA"
values:
layout: locale_page
locale: ar
locale: ar-rSA
nav_exclude: true
- scope:
path: "be"
path: "be-rBY"
values:
layout: locale_page
locale: be
locale: be-rBY
nav_exclude: true
- scope:
path: "bg"
path: "bg-rBG"
values:
layout: locale_page
locale: bg
locale: bg-rBG
nav_exclude: true
- scope:
path: "ca"
path: "ca-rES"
values:
layout: locale_page
locale: ca
locale: ca-rES
nav_exclude: true
- scope:
path: "cs"
path: "cs-rCZ"
values:
layout: locale_page
locale: cs
locale: cs-rCZ
nav_exclude: true
- scope:
path: "de"
path: "de-rDE"
values:
layout: locale_page
locale: de
locale: de-rDE
nav_exclude: true
- scope:
path: "el"
path: "el-rGR"
values:
layout: locale_page
locale: el
locale: el-rGR
nav_exclude: true
- scope:
path: "es"
path: "es-rES"
values:
layout: locale_page
locale: es
locale: es-rES
nav_exclude: true
- scope:
path: "et"
path: "et-rEE"
values:
layout: locale_page
locale: et
locale: et-rEE
nav_exclude: true
- scope:
path: "fi"
path: "fi-rFI"
values:
layout: locale_page
locale: fi
locale: fi-rFI
nav_exclude: true
- scope:
path: "fr"
path: "fr-rFR"
values:
layout: locale_page
locale: fr
locale: fr-rFR
nav_exclude: true
- scope:
path: "ga"
path: "ga-rIE"
values:
layout: locale_page
locale: ga
locale: ga-rIE
nav_exclude: true
- scope:
path: "gl"
path: "gl-rES"
values:
layout: locale_page
locale: gl
locale: gl-rES
nav_exclude: true
- scope:
path: "he"
path: "iw-rIL"
values:
layout: locale_page
locale: he
locale: iw-rIL
nav_exclude: true
- scope:
path: "hr"
path: "hr-rHR"
values:
layout: locale_page
locale: hr
locale: hr-rHR
nav_exclude: true
- scope:
path: "ht"
path: "ht-rHT"
values:
layout: locale_page
locale: ht
locale: ht-rHT
nav_exclude: true
- scope:
path: "hu"
path: "hu-rHU"
values:
layout: locale_page
locale: hu
locale: hu-rHU
nav_exclude: true
- scope:
path: "is"
path: "is-rIS"
values:
layout: locale_page
locale: is
locale: is-rIS
nav_exclude: true
- scope:
path: "it"
path: "it-rIT"
values:
layout: locale_page
locale: it
locale: it-rIT
nav_exclude: true
- scope:
path: "ja"
path: "ja-rJP"
values:
layout: locale_page
locale: ja
locale: ja-rJP
nav_exclude: true
- scope:
path: "ko"
path: "ko-rKR"
values:
layout: locale_page
locale: ko
locale: ko-rKR
nav_exclude: true
- scope:
path: "lt"
path: "lt-rLT"
values:
layout: locale_page
locale: lt
locale: lt-rLT
nav_exclude: true
- scope:
path: "nl"
path: "nl-rNL"
values:
layout: locale_page
locale: nl
locale: nl-rNL
nav_exclude: true
- scope:
path: "no"
path: "no-rNO"
values:
layout: locale_page
locale: no
locale: no-rNO
nav_exclude: true
- scope:
path: "pl"
path: "pl-rPL"
values:
layout: locale_page
locale: pl
locale: pl-rPL
nav_exclude: true
- scope:
path: "pt"
path: "pt-rPT"
values:
layout: locale_page
locale: pt
locale: pt-rPT
nav_exclude: true
- scope:
path: "pt-rBR"
@@ -203,58 +201,64 @@ defaults:
locale: pt-rBR
nav_exclude: true
- scope:
path: "ro"
path: "ro-rRO"
values:
layout: locale_page
locale: ro
locale: ro-rRO
nav_exclude: true
- scope:
path: "ru"
path: "ru-rRU"
values:
layout: locale_page
locale: ru
locale: ru-rRU
nav_exclude: true
- scope:
path: "sk"
path: "sk-rSK"
values:
layout: locale_page
locale: sk
locale: sk-rSK
nav_exclude: true
- scope:
path: "sl"
path: "sl-rSI"
values:
layout: locale_page
locale: sl
locale: sl-rSI
nav_exclude: true
- scope:
path: "sq"
path: "sq-rAL"
values:
layout: locale_page
locale: sq
locale: sq-rAL
nav_exclude: true
- scope:
path: "sr"
path: "sr-rLatn"
values:
layout: locale_page
locale: sr
locale: sr-rLatn
nav_exclude: true
- scope:
path: "sv"
path: "srp"
values:
layout: locale_page
locale: sv
locale: srp
nav_exclude: true
- scope:
path: "tr"
path: "sv-rSE"
values:
layout: locale_page
locale: tr
locale: sv-rSE
nav_exclude: true
- scope:
path: "uk"
path: "tr-rTR"
values:
layout: locale_page
locale: uk
locale: tr-rTR
nav_exclude: true
- scope:
path: "uk-rUA"
values:
layout: locale_page
locale: uk-rUA
nav_exclude: true
- scope:
path: "zh-rCN"
+42 -39
View File
@@ -1,114 +1,117 @@
# Supported documentation locales.
# Each entry maps a Crowdin 2-letter code to its native name.
# Each entry maps a regional qualifier code to its native name.
# Pages land at docs/{code}/user/*.md via Crowdin sync.
# Synced with Android app locales (values-* resource dirs).
ar:
ar-rSA:
name: "العربية"
dir: rtl
be:
be-rBY:
name: "Беларуская"
dir: ltr
bg:
bg-rBG:
name: "Български"
dir: ltr
ca:
ca-rES:
name: "Català"
dir: ltr
cs:
cs-rCZ:
name: "Čeština"
dir: ltr
de:
de-rDE:
name: "Deutsch"
dir: ltr
el:
el-rGR:
name: "Ελληνικά"
dir: ltr
es:
es-rES:
name: "Español"
dir: ltr
et:
et-rEE:
name: "Eesti"
dir: ltr
fi:
fi-rFI:
name: "Suomi"
dir: ltr
fr:
fr-rFR:
name: "Français"
dir: ltr
ga:
ga-rIE:
name: "Gaeilge"
dir: ltr
gl:
gl-rES:
name: "Galego"
dir: ltr
he:
iw-rIL:
name: "עברית"
dir: rtl
hr:
hr-rHR:
name: "Hrvatski"
dir: ltr
ht:
ht-rHT:
name: "Kreyòl Ayisyen"
dir: ltr
hu:
hu-rHU:
name: "Magyar"
dir: ltr
is:
is-rIS:
name: "Íslenska"
dir: ltr
it:
it-rIT:
name: "Italiano"
dir: ltr
ja:
ja-rJP:
name: "日本語"
dir: ltr
ko:
ko-rKR:
name: "한국어"
dir: ltr
lt:
lt-rLT:
name: "Lietuvių"
dir: ltr
nl:
nl-rNL:
name: "Nederlands"
dir: ltr
"no":
no-rNO:
name: "Norsk"
dir: ltr
pl:
pl-rPL:
name: "Polski"
dir: ltr
pt:
name: "Português"
dir: ltr
pt-rBR:
name: "Português (Brasil)"
dir: ltr
ro:
pt-rPT:
name: "Português"
dir: ltr
ro-rRO:
name: "Română"
dir: ltr
ru:
ru-rRU:
name: "Русский"
dir: ltr
sk:
sk-rSK:
name: "Slovenčina"
dir: ltr
sl:
sl-rSI:
name: "Slovenščina"
dir: ltr
sq:
sq-rAL:
name: "Shqip"
dir: ltr
sr:
name: "Српски"
sr-rLatn:
name: "Српски (Latinica)"
dir: ltr
sv:
srp:
name: "Српски (Ћирилица)"
dir: ltr
sv-rSE:
name: "Svenska"
dir: ltr
tr:
tr-rTR:
name: "Türkçe"
dir: ltr
uk:
uk-rUA:
name: "Українська"
dir: ltr
zh-rCN:
+2 -1
View File
@@ -125,7 +125,8 @@
.language-switcher-list {
position: absolute;
top: 100%;
left: 0;
right: 0;
left: auto;
z-index: 100;
list-style: none;
padding: 8px 0;
+59 -44
View File
@@ -6,49 +6,49 @@
Usage: {% include language_switcher.html %}
Logic:
- Derives the current page's relative path within its section
- Checks if translated versions exist in locale subdirectories
- Shows a globe icon with available locale links
- Dynamically detects the current language and page name.
- Dynamically updates the switcher button's native language name.
- Correctly matches English pages to translated equivalents and vice versa.
- Pre-verifies existing files to only render valid, non-404 options.
{% endcomment %}
{% assign current_path = page.path %}
{% assign locales = site.data.locales %}
{% if locales and current_path %}
{% assign path_parts = current_path | split: "/" %}
{% assign first_segment = path_parts[0] %}
{% assign path_parts = current_path | split: "/" %}
{% assign first_segment = path_parts[0] %}
{% comment %} Build the list of available translations first {% endcomment %}
{% assign has_translations = false %}
{% comment %}
Identify the current page's language code and native language name.
If the first segment is defined in locales.yml, we are on a translation.
Otherwise, we are in default English.
{% endcomment %}
{% if locales[first_segment] %}
{% assign current_lang_code = first_segment %}
{% assign current_lang_name = locales[first_segment].name %}
{% else %}
{% assign current_lang_code = "en" %}
{% assign current_lang_name = "English" %}
{% endif %}
{% if locales[first_segment] %}
{% comment %} We're on a translated page — English link is always available {% endcomment %}
{% assign has_translations = true %}
{% comment %}
Extract the relative base path (independent of locale prefix and file extension).
E.g., "en/user/connections.md" and "be-rBY/user/connections.md" both resolve to "user/connections".
{% endcomment %}
{% assign remaining_parts = path_parts | slice: 1, path_parts.size %}
{% assign en_path = remaining_parts | join: "/" | replace: ".md", "" %}
{% else %}
{% comment %} Check if any translated version exists {% endcomment %}
{% assign en_relative = current_path | replace: ".md", "" %}
{% for locale in locales %}
{% assign locale_code = locale[0] %}
{% assign locale_file = locale_code | append: "/" | append: en_relative | append: ".md" %}
{% for p in site.pages %}
{% if p.path == locale_file %}
{% assign has_translations = true %}
{% break %}
{% endif %}
{% endfor %}
{% if has_translations %}{% break %}{% endif %}
{% endfor %}
{% endif %}
{% assign base_path = remaining_parts | join: "/" | replace: ".md", "" %}
{% if has_translations %}
<details class="language-switcher" aria-label="Language options">
<summary class="language-switcher-btn" title="View in another language">
🌐 <span class="lang-current">English</span>
</summary>
<ul class="language-switcher-list">
{% if locales[first_segment] %}
{% comment %}
Pre-render the dropdown list items.
{% endcomment %}
{% capture dropdown_items %}
{% if current_lang_code != "en" %}
{% if base_path == "index" %}
{% assign en_path = "en/" %}
{% else %}
{% assign en_path = "en/" | append: base_path %}
{% endif %}
<li><a href="{{ en_path | relative_url }}" lang="en">English</a></li>
{% endif %}
@@ -56,16 +56,12 @@
{% assign locale_code = locale[0] %}
{% assign locale_info = locale[1] %}
{% if locales[first_segment] %}
{% if locale_code == first_segment %}
{% continue %}
{% endif %}
{% assign locale_path = locale_code | append: "/" | append: en_path %}
{% else %}
{% assign locale_path = locale_code | append: "/" | append: en_relative %}
{% if locale_code == current_lang_code %}
{% continue %}
{% endif %}
{% assign locale_file = locale_path | append: ".md" %}
{% assign locale_file = locale_code | append: "/" | append: base_path | append: ".md" %}
{% assign page_exists = false %}
{% for p in site.pages %}
{% if p.path == locale_file %}
@@ -75,10 +71,29 @@
{% endfor %}
{% if page_exists %}
{% if base_path == "index" %}
{% assign locale_path = locale_code | append: "/" %}
{% else %}
{% assign locale_path = locale_code | append: "/" | append: base_path %}
{% endif %}
<li><a href="{{ locale_path | relative_url }}" lang="{{ locale_code }}" {% if locale_info.dir == "rtl" %}dir="rtl"{% endif %}>{{ locale_info.name }}</a></li>
{% endif %}
{% endfor %}
</ul>
</details>
{% endif %}
{% endcapture %}
{% assign dropdown_items_stripped = dropdown_items | strip %}
{% comment %}
Only render the switcher if there is at least one other language option available.
{% endcomment %}
{% if dropdown_items_stripped != "" %}
<details class="language-switcher" aria-label="Language options">
<summary class="language-switcher-btn" title="View in another language">
🌐 <span class="lang-current">{{ current_lang_name }}</span>
</summary>
<ul class="language-switcher-list">
{{ dropdown_items }}
</ul>
</details>
{% endif %}
{% endif %}
@@ -1,5 +1,6 @@
---
title: Adding a Feature Module
parent: Developer Guide
nav_order: 3
last_updated: 2026-05-13
aliases:
+1
View File
@@ -1,5 +1,6 @@
---
title: Architecture
parent: Developer Guide
nav_order: 1
last_updated: 2026-05-13
aliases:
+1
View File
@@ -1,5 +1,6 @@
---
title: Codebase
parent: Developer Guide
nav_order: 2
last_updated: 2026-05-13
aliases:
+1
View File
@@ -1,5 +1,6 @@
---
title: Contributing
parent: Developer Guide
nav_order: 8
last_updated: 2026-05-13
aliases:
+1
View File
@@ -1,5 +1,6 @@
---
title: Measurement & Formatting
parent: Developer Guide
nav_order: 9
last_updated: 2026-05-13
aliases:
@@ -1,5 +1,6 @@
---
title: Navigation & Deep Links
parent: Developer Guide
nav_order: 4
last_updated: 2026-05-13
aliases:
+1
View File
@@ -1,5 +1,6 @@
---
title: Persistence
parent: Developer Guide
nav_order: 6
last_updated: 2026-05-13
aliases:
+1
View File
@@ -1,5 +1,6 @@
---
title: Testing
parent: Developer Guide
nav_order: 7
last_updated: 2026-05-13
aliases:
+1
View File
@@ -1,5 +1,6 @@
---
title: Transport
parent: Developer Guide
nav_order: 5
last_updated: 2026-05-13
aliases:
-46
View File
@@ -1,46 +0,0 @@
---
title: Translations
layout: default
nav_order: 99
---
# Translations
This documentation is translated by the community via [Crowdin](https://crowdin.com/project/meshtastic-android). Translations appear here automatically as volunteers contribute them.
## Available Languages
{% assign any_locale_exists = false %}
{% for locale in site.data.locales %}
{% assign locale_code = locale[0] %}
{% assign locale_info = locale[1] %}
{% assign locale_prefix = locale_code | append: "/" %}
{% assign has_content = false %}
{% for p in site.pages %}
{% assign page_path_check = p.path | slice: 0, locale_prefix.size %}
{% if page_path_check == locale_prefix %}
{% assign has_content = true %}
{% assign any_locale_exists = true %}
{% break %}
{% endif %}
{% endfor %}
{% if has_content %}
- [{{ locale_info.name }}]({{ locale_code }}/) ({{ locale_code }})
{% endif %}
{% endfor %}
{% unless any_locale_exists %}
> No translations available yet. Want to help? [Join our Crowdin project →](https://crowdin.com/project/meshtastic-android)
{% endunless %}
---
## Contributing Translations
1. Visit [Crowdin](https://crowdin.com/project/meshtastic-android)
2. Select a language
3. Translate the User Guide documentation files
4. Translations are automatically synced to this site via PR
Translation coverage and quality are tracked per-language. Pages without full translation show the English original for untranslated sections.
+1
View File
@@ -1,5 +1,6 @@
---
title: Connections
parent: User Guide
nav_order: 2
last_updated: 2026-05-13
description: Connect your phone or desktop to a Meshtastic radio via Bluetooth, USB, or TCP/IP.
+1
View File
@@ -1,5 +1,6 @@
---
title: Desktop App
parent: User Guide
nav_order: 14
last_updated: 2026-05-13
description: Install and use the Meshtastic Desktop app on Linux, macOS, and Windows — connections, feature parity, and keyboard shortcuts.
+1
View File
@@ -1,5 +1,6 @@
---
title: Discovery
parent: User Guide
nav_order: 12
last_updated: 2026-05-13
description: Explore your mesh network — traceroute paths, neighbor maps, and node discovery tools.
+1
View File
@@ -1,5 +1,6 @@
---
title: Firmware Updates
parent: User Guide
nav_order: 13
last_updated: 2026-05-13
description: Update your radio firmware over Bluetooth — OTA process, version channels, pre-flight checks, and recovery.
+1
View File
@@ -1,5 +1,6 @@
---
title: Map & Waypoints
parent: User Guide
nav_order: 6
last_updated: 2026-05-13
description: View node positions on the map, create and share waypoints, and manage position sharing and privacy.
+1
View File
@@ -1,5 +1,6 @@
---
title: Messages & Channels
parent: User Guide
nav_order: 3
last_updated: 2026-05-13
description: Send and receive messages, manage channels, configure encryption, and use quick chat, reactions, and message actions.
+1
View File
@@ -1,5 +1,6 @@
---
title: MQTT
parent: User Guide
nav_order: 11
last_updated: 2026-05-13
description: Bridge your mesh to the internet — MQTT broker setup, encryption layers, and map reporting.
+1
View File
@@ -1,5 +1,6 @@
---
title: Node Metrics
parent: User Guide
nav_order: 5
last_updated: 2026-05-13
description: Telemetry dashboards for each mesh node — device health, environment sensors, signal quality, power, traceroute, and position history.
+1
View File
@@ -1,5 +1,6 @@
---
title: Nodes
parent: User Guide
nav_order: 4
last_updated: 2026-05-13
description: Browse, filter, and sort mesh nodes — view details, signal quality, roles, and quick actions.
+1
View File
@@ -1,5 +1,6 @@
---
title: Getting Started
parent: User Guide
nav_order: 1
last_updated: 2026-05-13
description: First-launch setup — permissions, onboarding flow, and next steps after connecting your radio.
+1
View File
@@ -1,5 +1,6 @@
---
title: Settings — Modules & Admin
parent: User Guide
nav_order: 8
last_updated: 2026-05-13
description: Configure optional feature modules (MQTT, telemetry, canned messages, TAK, and more) and perform device administration.
+1
View File
@@ -1,5 +1,6 @@
---
title: Settings — Radio & User
parent: User Guide
nav_order: 7
last_updated: 2026-05-13
description: Configure your radio hardware, LoRa presets, user profile, position sharing, power management, and security.
+1
View File
@@ -1,5 +1,6 @@
---
title: How the Meshtastic Signal Meter Works
parent: User Guide
nav_order: 15
last_updated: 2026-05-13
description: How the signal meter calculates quality from RSSI and SNR — LoRa spread spectrum, presets, and what the bars really mean.
+1
View File
@@ -1,5 +1,6 @@
---
title: TAK Integration
parent: User Guide
nav_order: 10
last_updated: 2026-05-13
description: Interoperate with ATAK and WinTAK — CoT position sharing, TAK roles, and plugin setup.
+1
View File
@@ -1,5 +1,6 @@
---
title: Telemetry & Sensors
parent: User Guide
nav_order: 9
last_updated: 2026-05-13
description: Sensor data on the mesh — supported environment, air quality, and power sensors, plus configuration and viewing guides.