Skip to content

Commit e60d154

Browse files
feat: add language switcher for multilingual site support (#374)
* feat: add language switcher for multilingual site support Add a hosting-agnostic language switcher to the theme toolbar that allows users to switch between translated versions of lecture sites. Theme changes: - New theme options: languages (list) and current_language (string) - Globe icon dropdown at far right of toolbar (after GitHub icon) - hreflang link tags in head for SEO - Dark theme and RTL-aware styling - Keyboard accessible (Escape to close, click-outside-to-close) - Only renders when 2+ languages configured (backwards compatible) Documentation: - Updated docs/developer/multilingual.md with implementation docs - New docs/developer/infrastructure.md for hosting guidance - Updated PLAN_MULTILINGUAL_SUPPORT.md (theme-focused) - New PLAN-INFRASTRUCTURE.md (hosting/DNS concerns) Files added: - src/quantecon_book_theme/assets/scripts/language-switcher.js - src/quantecon_book_theme/assets/styles/_language-switcher.scss - docs/developer/infrastructure.md - PLAN-INFRASTRUCTURE.md * chore: remove completed PLAN documents All content has been implemented in code and documented in docs/developer/multilingual.md and docs/developer/infrastructure.md. * fix: address Copilot review feedback and add test coverage - Validate language entries (require code, name, url fields) - Normalize URLs by stripping trailing slashes - Extract _process_languages() for testability - Fix ARIA roles: role=menuitem on <a>, role=none on <li> - Fix theme.conf defaults: languages = [] for type consistency - Fix broken reference to deleted PLAN-INFRASTRUCTURE.md - Add 10 unit tests for language processing (test_language_switcher.py) * fix: remove unused pytest import (flake8 F401) * Rename lecture-python-programming.myst to lecture-python-programming Update all references to the renamed repository across CI workflows, tox configuration, Playwright config, documentation, and .gitignore. * UPDATE: Regenerate all visual snapshots (1 files) * Increase toolbar visual test tolerance to 0.03 The toolbar screenshot on mobile has minor pixel-level rendering variability with the language switcher, causing flaky failures at the default 0.01 threshold. * Fix language switcher dropdown opening off-screen The dropdown was positioned above the toolbar (bottom: 100%) which caused it to open off-screen since the toolbar is at the top of the page. Changed to open below (top: 100%) with arrow pointing up and right-aligned to stay within the viewport. * Remove dir=rtl from language switcher menu items Language names in the dropdown should be consistently left-aligned regardless of the target language's text direction. The dir attribute is for content blocks, not navigation labels. * Add language switcher and repo rename to CHANGELOG --------- Co-authored-by: github-actions[bot] <github-actions[bot]@users.noreply.github.com>
1 parent 6ae9b3b commit e60d154

23 files changed

Lines changed: 880 additions & 794 deletions

File tree

.github/workflows/ci.yml

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -10,18 +10,18 @@ jobs:
1010
steps:
1111
- name: Checkout
1212
uses: actions/checkout@v6
13-
- name: Fetch lecture-python-programming.myst
13+
- name: Fetch lecture-python-programming
1414
shell: bash -l {0}
1515
run: |
16-
git clone --branch quantecon-book-theme https://github.com/QuantEcon/lecture-python-programming.myst
16+
git clone --branch quantecon-book-theme https://github.com/QuantEcon/lecture-python-programming
1717
- name: Setup Anaconda
1818
uses: conda-incubator/setup-miniconda@v3
1919
with:
2020
auto-update-conda: true
2121
auto-activate-base: true
2222
miniconda-version: 'latest'
2323
python-version: "3.13"
24-
environment-file: lecture-python-programming.myst/environment.yml
24+
environment-file: lecture-python-programming/environment.yml
2525
activate-environment: lecture-python-programming
2626
- name: Install quantecon-book-theme
2727
shell: bash -l {0}
@@ -36,7 +36,7 @@ jobs:
3636
- name: Build HTML
3737
shell: bash -l {0}
3838
run: |
39-
cd lecture-python-programming.myst
39+
cd lecture-python-programming
4040
jb build lectures --path-output ./
4141
4242
# Visual Regression Testing
@@ -54,7 +54,7 @@ jobs:
5454
run: npm run test:visual
5555
continue-on-error: true
5656
env:
57-
SITE_PATH: lecture-python-programming.myst/_build/html
57+
SITE_PATH: lecture-python-programming/_build/html
5858
- name: Upload Playwright Report
5959
uses: actions/upload-artifact@v7
6060
if: always()
@@ -83,7 +83,7 @@ jobs:
8383
- name: Preview Deploy to Netlify
8484
uses: nwtgck/actions-netlify@v3.0
8585
with:
86-
publish-dir: 'lecture-python-programming.myst/_build/html/'
86+
publish-dir: 'lecture-python-programming/_build/html/'
8787
production-branch: main
8888
github-token: ${{ secrets.GITHUB_TOKEN }}
8989
deploy-message: "Preview Deploy from GitHub Actions"

.github/workflows/update-snapshots.yml

Lines changed: 10 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -33,10 +33,10 @@ jobs:
3333
ref: ${{ steps.pr.outputs.ref }}
3434
token: ${{ secrets.GITHUB_TOKEN }}
3535

36-
- name: Fetch lecture-python-programming.myst
36+
- name: Fetch lecture-python-programming
3737
shell: bash -l {0}
3838
run: |
39-
git clone --branch quantecon-book-theme https://github.com/QuantEcon/lecture-python-programming.myst
39+
git clone --branch quantecon-book-theme https://github.com/QuantEcon/lecture-python-programming
4040
4141
- name: Setup Anaconda
4242
uses: conda-incubator/setup-miniconda@v3
@@ -45,7 +45,7 @@ jobs:
4545
auto-activate-base: true
4646
miniconda-version: 'latest'
4747
python-version: "3.13"
48-
environment-file: lecture-python-programming.myst/environment.yml
48+
environment-file: lecture-python-programming/environment.yml
4949
activate-environment: lecture-python-programming
5050

5151
- name: Install quantecon-book-theme
@@ -56,7 +56,7 @@ jobs:
5656
- name: Build HTML
5757
shell: bash -l {0}
5858
run: |
59-
cd lecture-python-programming.myst
59+
cd lecture-python-programming
6060
jb build lectures --path-output ./
6161
6262
- name: Setup Node.js
@@ -74,7 +74,7 @@ jobs:
7474
continue-on-error: true
7575
run: npx playwright test --update-snapshots=missing
7676
env:
77-
SITE_PATH: lecture-python-programming.myst/_build/html
77+
SITE_PATH: lecture-python-programming/_build/html
7878

7979
- name: Commit and Push Updated Snapshots
8080
run: |
@@ -140,10 +140,10 @@ jobs:
140140
ref: ${{ steps.pr.outputs.ref }}
141141
token: ${{ secrets.GITHUB_TOKEN }}
142142

143-
- name: Fetch lecture-python-programming.myst
143+
- name: Fetch lecture-python-programming
144144
shell: bash -l {0}
145145
run: |
146-
git clone --branch quantecon-book-theme https://github.com/QuantEcon/lecture-python-programming.myst
146+
git clone --branch quantecon-book-theme https://github.com/QuantEcon/lecture-python-programming
147147
148148
- name: Setup Anaconda
149149
uses: conda-incubator/setup-miniconda@v3
@@ -152,7 +152,7 @@ jobs:
152152
auto-activate-base: true
153153
miniconda-version: 'latest'
154154
python-version: "3.13"
155-
environment-file: lecture-python-programming.myst/environment.yml
155+
environment-file: lecture-python-programming/environment.yml
156156
activate-environment: lecture-python-programming
157157

158158
- name: Install quantecon-book-theme
@@ -163,7 +163,7 @@ jobs:
163163
- name: Build HTML
164164
shell: bash -l {0}
165165
run: |
166-
cd lecture-python-programming.myst
166+
cd lecture-python-programming
167167
jb build lectures --path-output ./
168168
169169
- name: Setup Node.js
@@ -181,7 +181,7 @@ jobs:
181181
continue-on-error: true
182182
run: npx playwright test --update-snapshots
183183
env:
184-
SITE_PATH: lecture-python-programming.myst/_build/html
184+
SITE_PATH: lecture-python-programming/_build/html
185185

186186
- name: Upload Old vs New Diff
187187
uses: actions/upload-artifact@v7

.gitignore

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -145,7 +145,7 @@ playwright-report/
145145
test-results/
146146

147147
# Visual test lecture site (cloned by tox -e visual)
148-
lecture-python-programming.myst/
148+
lecture-python-programming/
149149

150150
# macOS visual test snapshots (tox uses macos/ dir, CI uses __snapshots__/)
151151
tests/visual/macos/

CHANGELOG.md

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,14 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
77

88
## [Unreleased]
99

10+
### Added
11+
- **Language switcher for multilingual site support** (#374) — a globe icon dropdown in the bottom toolbar that enables users to switch between translated versions of a lecture site. Only renders when 2+ languages are configured via `html_theme_options`. Includes keyboard navigation, click-outside-to-close, and dark mode support.
12+
- **SEO hreflang tags** (#374) — automatically injects `<link rel="alternate" hreflang="...">` meta tags in `<head>` for all configured languages, improving search engine discovery of translated content.
13+
- **Multilingual infrastructure documentation** (#374) — new developer guide at `docs/developer/infrastructure.md` covering three hosting options (GitHub Pages, subdomains, reverse proxy) for deploying translated lecture sites.
14+
15+
### Changed
16+
- **Renamed `lecture-python-programming.myst` to `lecture-python-programming`** (#374) — updated all CI workflows, tox config, Playwright config, and documentation to reflect the renamed test repository.
17+
1018
## [0.19.0] - 2026-03-08
1119

1220
### Changed

0 commit comments

Comments
 (0)