Skip to content

[WIP] internalization support #4752

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Draft
wants to merge 1 commit into
base: main
Choose a base branch
from
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
15 changes: 15 additions & 0 deletions main.py
Original file line number Diff line number Diff line change
Expand Up @@ -52,6 +52,21 @@ def _documentation_detail_page(name: str) -> Optional[RedirectResponse]:
return RedirectResponse(documentation.redirects[name])
raise HTTPException(404, f'documentation for "{name}" could not be found')

# Debug page for setting the language


@ui.page('/set_language')
def _set_language() -> None:
my_input = ui.input('Language', placeholder='en')

def set_language():
app.storage.user['language'] = my_input.value
ui.navigate.reload()

ui.button('Set Language', on_click=set_language)

ui.label(f"Current Language: {app.storage.user.get('language', 'en')}")


@app.get('/status')
def _status():
Expand Down
2 changes: 2 additions & 0 deletions website/documentation/content/doc/api.py
Original file line number Diff line number Diff line change
Expand Up @@ -104,6 +104,8 @@ def decorator(function: Callable) -> Callable:
page.title = f'ui.*{ui_name}*'
elif app_name:
page.title = f'app.*{app_name}*'
print('Title:', title_)
print('Description:', description)
page.parts.append(DocumentationPart(
title=title_,
description=description,
Expand Down
4 changes: 2 additions & 2 deletions website/documentation/content/overview.py
Original file line number Diff line number Diff line change
Expand Up @@ -18,14 +18,14 @@

doc.title('*NiceGUI* Documentation', 'Reference, Demos and more')

doc.text('Overview', '''
doc.text('Overview<!--TRANSLATEID-id1-->', '''
NiceGUI is an open-source Python library to write graphical user interfaces which run in the browser.
It has a very gentle learning curve while still offering the option for advanced customizations.
NiceGUI follows a backend-first philosophy:
It handles all the web development details.
You can focus on writing Python code.
This makes it ideal for a wide range of projects including short
scripts, dashboards, robotics projects, IoT solutions, smart home automation, and machine learning.
scripts, dashboards, robotics projects, IoT solutions, smart home automation, and machine learning.<!--TRANSLATEID-id2-->
''')

doc.text('How to use this guide', '''
Expand Down
75 changes: 75 additions & 0 deletions website/documentation/i18n.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,75 @@
# ruff: noqa: RUF001

import re

from nicegui import app

mydict = {
'id1': {
'en': 'Overview',
'cn': '概述',
'jp': '概要',
'de': 'Überblick',
},

'id2': {
'en': '''NiceGUI is an open-source Python library to write graphical user interfaces which run in the browser.
It has a very gentle learning curve while still offering the option for advanced customizations.
NiceGUI follows a backend-first philosophy:
It handles all the web development details.
You can focus on writing Python code.
This makes it ideal for a wide range of projects including short
scripts, dashboards, robotics projects, IoT solutions, smart home automation, and machine learning.''',
'cn': '''NiceGUI 是一个开源的 Python 库,用于编写在浏览器中运行的图形用户界面。
它具有非常温和的学习曲线,同时仍然提供高级自定义的选项。
NiceGUI 遵循后端优先的理念:
它处理所有 Web 开发的细节。
您可以专注于编写 Python 代码。
这使它非常适合广泛的项目,包括短脚本、仪表板、机器人项目、物联网解决方案、智能家居自动化和机器学习。''',
'jp': '''NiceGUIは、ブラウザで実行されるグラフィカルユーザーインターフェイスを作成するためのオープンソースのPythonライブラリです。
非常に緩やかな学習曲線を持ちながら、高度なカスタマイズのオプションも提供しています。
NiceGUIはバックエンドファーストの哲学に従っています。
すべてのWeb開発の詳細を処理します。
Pythonコードの記述に集中できます。
これにより、短いスクリプト、ダッシュボード、ロボティクスプロジェクト、IoTソリューション、スマートホームオートメーション、機械学習など、幅広いプロジェクトに最適です。''',
'de': '''NiceGUI ist eine Open-Source-Python-Bibliothek zur Erstellung grafischer Benutzeroberflächen, die im Browser ausgeführt werden.
Sie hat eine sehr sanfte Lernkurve und bietet dennoch die Möglichkeit zu erweiterten Anpassungen.
NiceGUI folgt einer Backend-First-Philosophie:
Es kümmert sich um alle Details der Webentwicklung.
Sie können sich auf das Schreiben von Python-Code konzentrieren.
Dies macht es ideal für eine Vielzahl von Projekten, darunter kurze
Skripte, Dashboards, Robotikprojekte, IoT-Lösungen, Smart-Home-Automatisierung und maschinelles Lernen.''',
},
}


def i18nify(text: str):
try:
language = app.storage.user['language']
except Exception as e:
print('Error getting language:', e)
language = 'en'
return i18nify_language(text, language=language)


def i18nify_language(text: str, *, language: str = 'en') -> str:
"""Translate the given text to the specified language."""

# Look for the HTML tag <!--TRANSLATEID-{uuid}--> in the text using regex
print('i18nify_language', text, language)
match = re.search(r'<!--TRANSLATEID-([a-zA-Z0-9-]+)-->', text)
if not match:
return drop_the_tag(text)

translation_id = match.group(1)
if not translation_id or translation_id not in mydict or language not in mydict[translation_id]:
return drop_the_tag(text)

text = mydict[translation_id].get(language, mydict[translation_id][language])
return text


def drop_the_tag(text: str) -> str:
"""Remove the HTML tag from the text."""
# Remove the HTML tag <!--TRANSLATEID-{uuid}--> from the text
return re.sub(r'<!--TRANSLATEID-[a-zA-Z0-9-]+-->', '', text)
7 changes: 4 additions & 3 deletions website/documentation/rendering.py
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
from nicegui import ui
from website.documentation.i18n import i18nify

from ..header import add_head_html, add_header
from ..style import section_heading, subheading
Expand Down Expand Up @@ -38,12 +39,12 @@ def render_content():
if part.title:
if part.link_target:
ui.link_target(part.link_target)
subheading(part.title, link=part.link, major=part.reference is not None)
subheading(i18nify(part.title), link=part.link, major=part.reference is not None)
if part.description:
if part.description_format == 'rst':
element = custom_restructured_text(part.description.replace(':param ', ':'))
element = custom_restructured_text(i18nify(part.description).replace(':param ', ':'))
else:
element = ui.markdown(part.description)
element = ui.markdown(i18nify(part.description))
element.classes('bold-links arrow-links')
if ':param' in part.description:
element.classes('rst-param-tables')
Expand Down