Skip to content

Commit d2a8b44

Browse files
authored
✨ NEW: Add translations for all buttons and tooltips (#214)
1 parent fdd3519 commit d2a8b44

File tree

80 files changed

+138
-18
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

80 files changed

+138
-18
lines changed

MANIFEST.in

+4
Original file line numberDiff line numberDiff line change
@@ -22,3 +22,7 @@ include web-compile-config.yml
2222
include sphinx_book_theme/theme.conf
2323
recursive-include sphinx_book_theme *.html
2424
recursive-include sphinx_book_theme/static *.js *.png *.css *.svg
25+
include sphinx_book_theme/translations/README.md
26+
recursive-include sphinx_book_theme/translations *.mo
27+
exclude jsons
28+
recursive-exclude sphinx_book_theme/translations *.json

sphinx_book_theme/__init__.py

+14-2
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,7 @@
1111
from bs4 import BeautifulSoup as bs
1212
from docutils.parsers.rst import directives
1313
from docutils import nodes
14+
from sphinx.application import Sphinx
1415
from sphinx.locale import get_translation
1516
from sphinx.util import logging
1617

@@ -21,6 +22,7 @@
2122
"""sphinx-book-theme version"""
2223

2324
SPHINX_LOGGER = logging.getLogger(__name__)
25+
MESSAGE_CATALOG_NAME = "booktheme"
2426

2527

2628
def get_html_theme_path():
@@ -272,7 +274,12 @@ def add_header_level_recursive(ul, level):
272274
if key in context:
273275
context[key] = _string_or_bool(context[key])
274276

275-
context["translate"] = get_translation("sphinx")
277+
translation = get_translation(MESSAGE_CATALOG_NAME)
278+
context["translate"] = translation
279+
# this is set in the html_theme
280+
context["theme_search_bar_text"] = translation(
281+
context.get("theme_search_bar_text", "Search the docs ...")
282+
)
276283

277284

278285
def update_thebe_config(app, env, docnames):
@@ -349,7 +356,7 @@ def run(self):
349356
return nodes
350357

351358

352-
def setup(app):
359+
def setup(app: Sphinx):
353360
app.connect("env-before-read-docs", update_thebe_config)
354361

355362
# Configuration for Juypter Book
@@ -358,6 +365,11 @@ def setup(app):
358365
app.connect("builder-inited", add_static_paths)
359366
app.connect("env-updated", update_all)
360367

368+
# add translations
369+
package_dir = os.path.abspath(os.path.dirname(__file__))
370+
locale_dir = os.path.join(package_dir, "translations", "locales")
371+
app.add_message_catalog(MESSAGE_CATALOG_NAME, locale_dir)
372+
361373
app.add_html_theme("sphinx_book_theme", get_html_theme_path())
362374
app.connect("html-page-context", add_to_context)
363375

sphinx_book_theme/topbar.html

+4-4
Original file line numberDiff line numberDiff line change
@@ -5,8 +5,8 @@
55
{% if theme_single_page != True %}
66
<button id="navbar-toggler" class="navbar-toggler ml-0" type="button" data-toggle="collapse"
77
data-toggle="tooltip" data-placement="bottom" data-target=".site-navigation" aria-controls="navbar-menu"
8-
aria-expanded="true" aria-label="Toggle navigation" aria-controls="site-navigation"
9-
title="Toggle navigation" data-toggle="tooltip" data-placement="left">
8+
aria-expanded="true" aria-label="{{ translate('Toggle navigation') }}" aria-controls="site-navigation"
9+
title="{{ translate('Toggle navigation') }}" data-toggle="tooltip" data-placement="left">
1010
<i class="fas fa-bars"></i>
1111
<i class="fas fa-arrow-left"></i>
1212
<i class="fas fa-arrow-up"></i>
@@ -17,7 +17,7 @@
1717

1818
<!-- Full screen (wrap in <a> to have style consistency -->
1919
<a class="full-screen-button"><button type="button" class="btn btn-secondary topbarbtn" data-toggle="tooltip"
20-
data-placement="bottom" onclick="toggleFullScreen()" title="Fullscreen mode"><i
20+
data-placement="bottom" onclick="toggleFullScreen()" title="{{ translate('Fullscreen mode') }}"><i
2121
class="fas fa-expand"></i></button></a>
2222

2323
{% include "topbar/launchbuttons.html" %}
@@ -27,7 +27,7 @@
2727
<div class="d-none d-md-block col-md-2 bd-toc show">
2828
{%- if toc %}
2929
<div class="tocsection onthispage pt-5 pb-3">
30-
<i class="fas fa-list"></i> {{ translate("Contents") }}
30+
<i class="fas fa-list"></i> {{ translate('Contents') }}
3131
</div>
3232
{%- endif %}
3333
<nav id="bd-toc-nav">

sphinx_book_theme/topbar/download.html

+4-4
Original file line numberDiff line numberDiff line change
@@ -1,20 +1,20 @@
11
<div class="dropdown-buttons-trigger">
2-
<button id="dropdown-buttons-trigger" class="btn btn-secondary topbarbtn" aria-label="Download this page"><i
2+
<button id="dropdown-buttons-trigger" class="btn btn-secondary topbarbtn" aria-label="{{ translate('Download this page') }}"><i
33
class="fas fa-download"></i></button>
44

55
{% if page_source_suffix %}
66
<div class="dropdown-buttons">
77
<!-- ipynb file if we had a myst markdown file -->
88
{% if ipynb_source %}<a class="dropdown-buttons"
99
href="{{ pathto('_sources', 1) }}/{{ ipynb_source }}"><button type="button"
10-
class="btn btn-secondary topbarbtn" title="Download notebook file" data-toggle="tooltip"
10+
class="btn btn-secondary topbarbtn" title="{{ translate('Download notebook file') }}" data-toggle="tooltip"
1111
data-placement="left">.ipynb</button></a>{% endif %}
1212
<!-- Download raw file -->
1313
<a class="dropdown-buttons" href="{{ pathto('_sources', 1) }}/{{ sourcename }}"><button type="button"
14-
class="btn btn-secondary topbarbtn" title="Download source file" data-toggle="tooltip"
14+
class="btn btn-secondary topbarbtn" title="{{ translate('Download source file') }}" data-toggle="tooltip"
1515
data-placement="left">{{ page_source_suffix }}</button></a>
1616
<!-- Download PDF via print -->
17-
<button type="button" id="download-print" class="btn btn-secondary topbarbtn" title="Print to PDF"
17+
<button type="button" id="download-print" class="btn btn-secondary topbarbtn" title="{{ translate('Print to PDF') }}"
1818
onClick="window.print()" data-toggle="tooltip" data-placement="left">.pdf</button>
1919
</div>
2020
{% endif %}

sphinx_book_theme/topbar/launchbuttons.html

+4-4
Original file line numberDiff line numberDiff line change
@@ -6,27 +6,27 @@
66
<div class="dropdown-buttons">
77
{% if binder_url %}
88
<a class="binder-button" href="{{ binder_url }}"><button type="button"
9-
class="btn btn-secondary topbarbtn" title="Launch Binder" data-toggle="tooltip"
9+
class="btn btn-secondary topbarbtn" title="{{ translate('Launch') }} Binder" data-toggle="tooltip"
1010
data-placement="left"><img class="binder-button-logo"
1111
src="{{ pathto('_static/images/logo_binder.svg', 1) }}"
1212
alt="Interact on binder">Binder</button></a>
1313
{% endif %}
1414
{% if jupyterhub_url %}
1515
<a class="jupyterhub-button" href="{{ jupyterhub_url }}"><button type="button"
16-
class="btn btn-secondary topbarbtn" title="Launch JupyterHub" data-toggle="tooltip"
16+
class="btn btn-secondary topbarbtn" title="{{ translate('Launch') }} JupyterHub" data-toggle="tooltip"
1717
data-placement="left"><img class="jupyterhub-button-logo"
1818
src="{{ pathto('_static/images/logo_jupyterhub.svg', 1) }}"
1919
alt="Interact on JupyterHub">JupyterHub</button></a>
2020
{% endif %}
2121
{% if colab_url and page_source_suffix==".ipynb" %}
2222
<a class="colab-button" href="{{ colab_url }}"><button type="button" class="btn btn-secondary topbarbtn"
23-
title="Launch Colab" data-toggle="tooltip" data-placement="left"><img class="colab-button-logo"
23+
title="{{ translate('Launch') }} Colab" data-toggle="tooltip" data-placement="left"><img class="colab-button-logo"
2424
src="{{ pathto('_static/images/logo_colab.png', 1) }}"
2525
alt="Interact on Colab">Colab</button></a>
2626
{% endif %}
2727
{% if use_thebe -%}
2828
<button type="button" class="btn btn-secondary topbarbtn"
29-
onclick="initThebeSBT()" title="Launch Thebe" data-toggle="tooltip" data-placement="left"><i
29+
onclick="initThebeSBT()" title="{{ translate('Launch') }} Thebe" data-toggle="tooltip" data-placement="left"><i
3030
class="fas fa-play"></i><span style="margin-left: .4em;">Live Code</span></button>
3131
{% endif %}
3232
</div>

sphinx_book_theme/topbar/repobuttons.html

+4-4
Original file line numberDiff line numberDiff line change
@@ -6,15 +6,15 @@
66
<div class="dropdown-buttons sourcebuttons">
77
{% if theme_use_repository_button %}<a class="repository-button"
88
href="{{ theme_repository_url }}"><button type="button" class="btn btn-secondary topbarbtn"
9-
data-toggle="tooltip" data-placement="left" title="Source repository"><i
10-
class="fab fa-github"></i>repository</button></a>{% endif %}
9+
data-toggle="tooltip" data-placement="left" title="{{ translate('Source repository') }}"><i
10+
class="fab fa-github"></i>{{ translate('repository') }}</button></a>{% endif %}
1111
{% if theme_use_issues_button %}<a class="issues-button"
1212
href="{{ theme_repository_url }}/issues/new?title=Issue%20on%20page%20%2F{{ pagename }}.html&body=Your%20issue%20content%20here."><button
1313
type="button" class="btn btn-secondary topbarbtn" data-toggle="tooltip" data-placement="left"
14-
title="Open an issue"><i class="fas fa-lightbulb"></i>open issue</button></a>{% endif %}
14+
title="{{ translate('Open an issue') }}"><i class="fas fa-lightbulb"></i>{{ translate('open issue') }}</button></a>{% endif %}
1515
{% if theme_use_edit_page_button %}<a class="edit-button" href="{{ get_edit_url() }}"><button
1616
type="button" class="btn btn-secondary topbarbtn" data-toggle="tooltip" data-placement="left"
17-
title="Edit this page"><i class="fas fa-pencil-alt"></i>suggest edit</button></a>{% endif %}
17+
title="{{ translate('Edit this page') }}"><i class="fas fa-pencil-alt"></i>{{ translate('suggest edit') }}</button></a>{% endif %}
1818
</div>
1919
</div>
2020
{% endif %}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,2 @@
1+
*.po
2+
!*.mo
+3
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
JSONs created using https://smodin.me/translate-one-text-into-multiple-languages
2+
3+
To convert to locale files run `python sphinx_book_theme/translations/_convert.py`

sphinx_book_theme/translations/__init__.py

Whitespace-only changes.
+57
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,57 @@
1+
import json
2+
import os
3+
from pathlib import Path
4+
import subprocess
5+
6+
7+
def convert_json(folder=None):
8+
folder = folder or Path(__file__).parent
9+
10+
# remove exising
11+
for path in (folder / "locales").glob("**/booktheme.po"):
12+
path.unlink()
13+
14+
# compile po
15+
for path in (folder / "jsons").glob("*.json"):
16+
data = json.loads(path.read_text("utf8"))
17+
assert data[0]["symbol"] == "en"
18+
english = data[0]["text"]
19+
for item in data[1:]:
20+
language = item["symbol"]
21+
out_path = folder / "locales" / language / "LC_MESSAGES" / "booktheme.po"
22+
if not out_path.parent.exists():
23+
out_path.parent.mkdir(parents=True)
24+
if not out_path.exists():
25+
header = f"""
26+
msgid ""
27+
msgstr ""
28+
"Project-Id-Version: Sphinx-Book-Theme\\n"
29+
"MIME-Version: 1.0\\n"
30+
"Content-Type: text/plain; charset=UTF-8\\n"
31+
"Content-Transfer-Encoding: 8bit\\n"
32+
"Language: {language}\\n"
33+
"Plural-Forms: nplurals=2; plural=(n != 1);\\n"
34+
"""
35+
out_path.write_text(header)
36+
37+
with out_path.open("a") as f:
38+
f.write("\n")
39+
f.write(f'msgid "{english}"\n')
40+
text = item["text"].replace('"', '\\"')
41+
f.write(f'msgstr "{text}"\n')
42+
43+
# compile mo
44+
for path in (folder / "locales").glob("**/booktheme.po"):
45+
print(path)
46+
subprocess.check_call(
47+
[
48+
"msgfmt",
49+
os.path.abspath(path),
50+
"-o",
51+
os.path.abspath(path.parent / "booktheme.mo"),
52+
]
53+
)
54+
55+
56+
if __name__ == "__main__":
57+
convert_json()
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
[{"language":"English","symbol":"en","text":"By the"}, {"language":"Arabic","symbol":"ar","text":"بواسطة"},{"language":"Bulgarian","symbol":"bg","text":"По"},{"language":"Chinese Simplified","symbol":"zh-cn","text":"由"},{"language":"Chinese Traditional","symbol":"zh-tw","text":"由"},{"language":"Croatian","symbol":"hr","text":"Od strane"},{"language":"Czech","symbol":"cs","text":"Podle"},{"language":"Danish","symbol":"da","text":"Ved"},{"language":"Dutch","symbol":"nl","text":"Door de"},{"language":"Esperanto","symbol":"eo","text":"Per la"},{"language":"Estonian","symbol":"et","text":"Autor"},{"language":"Finnish","symbol":"fi","text":"Mukaan"},{"language":"French","symbol":"fr","text":"Par le"},{"language":"German","symbol":"de","text":"Bis zum"},{"language":"Greek","symbol":"el","text":"Από το"},{"language":"Hebrew","symbol":"iw","text":"דרך"},{"language":"Indonesian","symbol":"id","text":"Oleh"},{"language":"Italian","symbol":"it","text":"Dal"},{"language":"Japanese","symbol":"ja","text":"によって"},{"language":"Korean","symbol":"ko","text":"에 의해"},{"language":"Latvian","symbol":"lv","text":"Ar"},{"language":"Lithuanian","symbol":"lt","text":"Prie"},{"language":"Norwegian","symbol":"no","text":"Ved"},{"language":"Polish","symbol":"pl","text":"Przez"},{"language":"Portuguese","symbol":"pt","text":"Pelo"},{"language":"Romanian","symbol":"ro","text":"Langa"},{"language":"Russian","symbol":"ru","text":"Посредством"},{"language":"Serbian","symbol":"sr","text":"Од"},{"language":"Slovak","symbol":"sk","text":"Podľa"},{"language":"Slovenian","symbol":"sl","text":"Avtor"},{"language":"Spanish","symbol":"es","text":"Por el"},{"language":"Swedish","symbol":"sv","text":"Vid"},{"language":"Tajik","symbol":"tg","text":"Бо"},{"language":"Thai","symbol":"th","text":"โดย"},{"language":"Turkish","symbol":"tr","text":"Tarafından"},{"language":"Ukrainian","symbol":"uk","text":"По"},{"language":"Vietnamese","symbol":"vi","text":"Bằng"},{"language":"Bengali","symbol":"bn","text":"দ্বারা"},{"language":"Filipino","symbol":"tl","text":"Sa pamamagitan ng"},{"language":"Marathi","symbol":"mr","text":"द्वारा"},{"language":"Malay","symbol":"ms","text":"Oleh"},{"language":"Malayalam","symbol":"ml","text":"എഴുതിയത്"},{"language":"Urdu","symbol":"ur","text":"کی طرف"},{"language":"Telugu","symbol":"te","text":"ద్వారా"},{"language":"Tamil","symbol":"ta","text":"மூலம்"},{"language":"Catalan","symbol":"ca","text":"Per la"}]
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
[{"language":"English","symbol":"en","text":"Contents"}, {"language":"Arabic","symbol":"ar","text":"محتويات"},{"language":"Bulgarian","symbol":"bg","text":"Съдържание"},{"language":"Chinese Simplified","symbol":"zh-cn","text":"内容"},{"language":"Chinese Traditional","symbol":"zh-tw","text":"內容"},{"language":"Croatian","symbol":"hr","text":"Sadržaj"},{"language":"Czech","symbol":"cs","text":"Obsah"},{"language":"Danish","symbol":"da","text":"Indhold"},{"language":"Dutch","symbol":"nl","text":"Inhoud"},{"language":"Esperanto","symbol":"eo","text":"Enhavo"},{"language":"Estonian","symbol":"et","text":"Sisu"},{"language":"Finnish","symbol":"fi","text":"Sisällys"},{"language":"French","symbol":"fr","text":"Contenu"},{"language":"German","symbol":"de","text":"Inhalt"},{"language":"Greek","symbol":"el","text":"Περιεχόμενα"},{"language":"Hebrew","symbol":"iw","text":"תוכן"},{"language":"Indonesian","symbol":"id","text":"Isi"},{"language":"Italian","symbol":"it","text":"Contenuti"},{"language":"Japanese","symbol":"ja","text":"目次"},{"language":"Korean","symbol":"ko","text":"내용"},{"language":"Latvian","symbol":"lv","text":"Saturs"},{"language":"Lithuanian","symbol":"lt","text":"Turinys"},{"language":"Norwegian","symbol":"no","text":"Innhold"},{"language":"Polish","symbol":"pl","text":"Zawartość"},{"language":"Portuguese","symbol":"pt","text":"Conteúdo"},{"language":"Romanian","symbol":"ro","text":"Cuprins"},{"language":"Russian","symbol":"ru","text":"Содержание"},{"language":"Serbian","symbol":"sr","text":"Садржај"},{"language":"Slovak","symbol":"sk","text":"Obsah"},{"language":"Slovenian","symbol":"sl","text":"Vsebina"},{"language":"Spanish","symbol":"es","text":"Contenido"},{"language":"Swedish","symbol":"sv","text":"Innehåll"},{"language":"Tajik","symbol":"tg","text":"Мундариҷа"},{"language":"Thai","symbol":"th","text":"สารบัญ"},{"language":"Turkish","symbol":"tr","text":"İçindekiler"},{"language":"Ukrainian","symbol":"uk","text":"Зміст"},{"language":"Vietnamese","symbol":"vi","text":"Nội dung"}]
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
[{"language":"English","symbol":"en","text":"Copyright"}, {"language":"Arabic","symbol":"ar","text":"حقوق النشر"},{"language":"Bulgarian","symbol":"bg","text":"Авторско право"},{"language":"Chinese Simplified","symbol":"zh-cn","text":"版权"},{"language":"Chinese Traditional","symbol":"zh-tw","text":"版權"},{"language":"Croatian","symbol":"hr","text":"Autorska prava"},{"language":"Czech","symbol":"cs","text":"autorská práva"},{"language":"Danish","symbol":"da","text":"ophavsret"},{"language":"Dutch","symbol":"nl","text":"auteursrechten"},{"language":"Esperanto","symbol":"eo","text":"Kopirajto"},{"language":"Estonian","symbol":"et","text":"Autoriõigus"},{"language":"Finnish","symbol":"fi","text":"Tekijänoikeus"},{"language":"French","symbol":"fr","text":"droits d'auteur"},{"language":"German","symbol":"de","text":"Urheberrechte ©"},{"language":"Greek","symbol":"el","text":"Πνευματική ιδιοκτησία"},{"language":"Hebrew","symbol":"iw","text":"זכויות יוצרים"},{"language":"Indonesian","symbol":"id","text":"hak cipta"},{"language":"Italian","symbol":"it","text":"Diritto d'autore"},{"language":"Japanese","symbol":"ja","text":"著作権"},{"language":"Korean","symbol":"ko","text":"저작권"},{"language":"Latvian","symbol":"lv","text":"Autortiesības"},{"language":"Lithuanian","symbol":"lt","text":"Autorių teisės"},{"language":"Norwegian","symbol":"no","text":"opphavsrett"},{"language":"Polish","symbol":"pl","text":"prawa autorskie"},{"language":"Portuguese","symbol":"pt","text":"direito autoral"},{"language":"Romanian","symbol":"ro","text":"Drepturi de autor"},{"language":"Russian","symbol":"ru","text":"авторское право"},{"language":"Serbian","symbol":"sr","text":"Ауторско право"},{"language":"Slovak","symbol":"sk","text":"Autorské práva"},{"language":"Slovenian","symbol":"sl","text":"avtorske pravice"},{"language":"Spanish","symbol":"es","text":"Derechos de autor"},{"language":"Swedish","symbol":"sv","text":"upphovsrätt"},{"language":"Tajik","symbol":"tg","text":"Ҳуқуқи муаллиф"},{"language":"Thai","symbol":"th","text":"ลิขสิทธิ์"},{"language":"Turkish","symbol":"tr","text":"Telif hakkı"},{"language":"Ukrainian","symbol":"uk","text":"Авторське право"},{"language":"Vietnamese","symbol":"vi","text":"Bản quyền"},{"language":"Bengali","symbol":"bn","text":"কপিরাইট"},{"language":"Catalan","symbol":"ca","text":"Copyright"},{"language":"Filipino","symbol":"tl","text":"Copyright"},{"language":"Malayalam","symbol":"ml","text":"പകർപ്പവകാശം"},{"language":"Malay","symbol":"ms","text":"hak cipta"},{"language":"Marathi","symbol":"mr","text":"कॉपीराइट"},{"language":"Tamil","symbol":"ta","text":"பதிப்புரிமை"},{"language":"Telugu","symbol":"te","text":"కాపీరైట్"},{"language":"Urdu","symbol":"ur","text":"کاپی رائٹ"}]

0 commit comments

Comments
 (0)