Compare commits

...
Author SHA1 Message Date
ArcandGitHub 5a6ff7ed02 Merge branch 'dev' into trans_exts 2026-05-22 14:15:17 +01:00
Arc 335c056a4b feat: translation support for extensions 2026-05-01 13:05:47 +01:00
3 changed files with 57 additions and 5 deletions
+7 -3
View File
@@ -20,7 +20,7 @@ from lnbits.decorators import (
check_first_install,
check_user_exists,
)
from lnbits.helpers import check_callback_url, template_renderer
from lnbits.helpers import check_callback_url, extension_id_from_path, template_renderer
from lnbits.settings import settings
from ..crud import get_user
@@ -198,7 +198,9 @@ admin_ui_checks = [Depends(check_admin), Depends(check_admin_ui)]
async def index(
request: Request, user: User = Depends(check_user_exists)
) -> HTMLResponse:
return template_renderer().TemplateResponse(
return template_renderer(
extension_id=extension_id_from_path(request.url.path)
).TemplateResponse(
request,
"base.html",
{
@@ -211,7 +213,9 @@ async def index(
@generic_router.get("/node/public")
@generic_router.get("/first_install", dependencies=[Depends(check_first_install)])
async def index_public(request: Request) -> HTMLResponse:
return template_renderer().TemplateResponse(request, "base.html", {"public": True})
return template_renderer(
extension_id=extension_id_from_path(request.url.path)
).TemplateResponse(request, "base.html", {"public": True})
@generic_router.get("/uuidv4/{hex_value}")
+47 -1
View File
@@ -52,7 +52,45 @@ def static_url_for(static: str, path: str) -> str:
return f"/{static}/{path}?v={settings.server_startup_time}"
def template_renderer(additional_folders: list | None = None) -> Jinja2Templates:
def extension_id_from_path(path: str) -> str | None:
parts = [part for part in path.split("/") if part]
if not parts:
return None
if len(parts) >= 3 and parts[0] == "upgrades":
return parts[2]
ext_id = parts[0]
ext_i18n_dir = Path(
settings.lnbits_extensions_path, "extensions", ext_id, "static", "i18n"
)
if ext_i18n_dir.is_dir():
return ext_id
return None
def extension_i18n_urls(extension_id: str | None) -> list[str]:
if not extension_id:
return []
i18n_dir = Path(
settings.lnbits_extensions_path, "extensions", extension_id, "static", "i18n"
)
if not i18n_dir.is_dir():
return []
files = [file.name for file in i18n_dir.glob("*.js") if file.is_file()]
return [
static_url_for(f"{extension_id}/static", f"i18n/{filename}")
for filename in sorted(files, key=lambda name: (name != "en.js", name))
]
def template_renderer(
additional_folders: list | None = None,
extension_id: str | None = None,
) -> Jinja2Templates:
folders = [
"lnbits/templates",
settings.extension_builder_working_dir_path.as_posix(),
@@ -86,6 +124,14 @@ def template_renderer(additional_folders: list | None = None) -> Jinja2Templates
t.env.globals["INCLUDED_CSS"] = vendor_files["css"]
t.env.globals["INCLUDED_COMPONENTS"] = vendor_files["components"]
if not extension_id and additional_folders:
for folder in additional_folders:
parts = Path(folder).parts
if parts and parts[-1] == "templates" and len(parts) >= 2:
extension_id = parts[-2]
break
t.env.globals["INCLUDED_EXTENSION_I18N"] = extension_i18n_urls(extension_id)
# backwards compatibility for extensions (tpos)
t.env.globals["LNBITS_DENOMINATION"] = settings.lnbits_denomination
+3 -1
View File
@@ -90,7 +90,9 @@
window.g.isPublicPage = false
{% endif %}
</script>
{% endif %}
{% endif %} {% for url in INCLUDED_EXTENSION_I18N %}
<script src="{{ url }}"></script>
{% endfor %}
<!-- app init -->
<script>
window.app = Vue.createApp({