feat(i18n): Implement server-side internationalization support

- Added ServerI18nManager to handle translations and locale settings on the server.
- Integrated server-side translations into templates, reducing language flashing on initial load.
- Created API endpoints for setting and getting user language preferences.
- Enhanced client-side i18n handling to work seamlessly with server-rendered content.
- Updated various templates to utilize the new translation system.
- Added mixed i18n handler to coordinate server and client translations, improving user experience.
- Expanded translation files to include initialization messages for various components.
This commit is contained in:
Will Miao
2025-08-30 16:56:56 +08:00
parent 3c9e402bc0
commit 29160bd6e5
14 changed files with 775 additions and 42 deletions

View File

@@ -17,6 +17,7 @@ from ..recipes import RecipeParserFactory
from ..utils.constants import CARD_PREVIEW_WIDTH
from ..services.settings_manager import settings
from ..services.server_i18n import server_i18n
from ..config import config
# Check if running in standalone mode
@@ -127,6 +128,17 @@ class RecipeRoutes:
# Ensure services are initialized
await self.init_services()
# 获取用户语言设置
user_language = settings.get('language', 'en')
# 设置服务端i18n语言
server_i18n.set_locale(user_language)
# 为模板环境添加i18n过滤器
if not hasattr(self.template_env, '_i18n_filter_added'):
self.template_env.filters['t'] = server_i18n.create_template_filter()
self.template_env._i18n_filter_added = True
# Skip initialization check and directly try to get cached data
try:
# Recipe scanner will initialize cache if needed
@@ -136,7 +148,18 @@ class RecipeRoutes:
recipes=[], # Frontend will load recipes via API
is_initializing=False,
settings=settings,
request=request
request=request,
user_language=user_language,
# 添加服务端翻译函数
t=server_i18n.get_translation,
server_i18n=server_i18n,
# 添加一些常用的翻译到上下文
common_translations={
'loading': server_i18n.get_translation('common.status.loading'),
'error': server_i18n.get_translation('common.status.error'),
'refresh': server_i18n.get_translation('common.actions.refresh'),
'search': server_i18n.get_translation('common.actions.search'),
}
)
except Exception as cache_error:
logger.error(f"Error loading recipe cache data: {cache_error}")
@@ -145,7 +168,16 @@ class RecipeRoutes:
rendered = template.render(
is_initializing=True,
settings=settings,
request=request
request=request,
user_language=user_language,
# 添加服务端翻译函数
t=server_i18n.get_translation,
server_i18n=server_i18n,
# 添加一些常用的翻译到上下文
common_translations={
'loading': server_i18n.get_translation('common.status.loading'),
'error': server_i18n.get_translation('common.status.error'),
}
)
logger.info("Recipe cache error, returning initialization page")