diff --git a/config/context_processors.py b/config/context_processors.py
index da5e98a752..8f4ae91dbb 100644
--- a/config/context_processors.py
+++ b/config/context_processors.py
@@ -1,17 +1,54 @@
from django.conf import settings
+from django.templatetags.static import static
+
from mathesar.utils.frontend import get_manifest_data
def frontend_settings(request):
+ manifest_data = get_manifest_data()
+ development_mode = settings.MATHESAR_MODE == 'DEVELOPMENT'
+
+ i18n_settings = get_i18n_settings(manifest_data, development_mode)
frontend_settings = {
- 'development_mode': settings.MATHESAR_MODE == 'DEVELOPMENT',
- 'manifest_data': get_manifest_data(),
+ 'development_mode': development_mode,
+ 'manifest_data': manifest_data,
'live_demo_mode': getattr(settings, 'MATHESAR_LIVE_DEMO', False),
'live_demo_username': getattr(settings, 'MATHESAR_LIVE_DEMO_USERNAME', None),
'live_demo_password': getattr(settings, 'MATHESAR_LIVE_DEMO_PASSWORD', None),
+ **i18n_settings
}
# Only include development URL if we're in development mode.
if frontend_settings['development_mode'] is True:
frontend_settings['client_dev_url'] = settings.MATHESAR_CLIENT_DEV_URL
+
return frontend_settings
+
+
+def get_i18n_settings(manifest_data, development_mode):
+ """
+ Hard coding this for now
+ but will be taken from users model
+ and cookies later on
+ """
+ display_language = 'en'
+ fallback_language = 'en'
+
+ client_dev_url = settings.MATHESAR_CLIENT_DEV_URL
+
+ if development_mode is True:
+ module_translations_file_path = f'{client_dev_url}/src/i18n/{display_language}/index.ts'
+ legacy_translations_file_path = f'{client_dev_url}/src/i18n/{display_language}/index.ts'
+ else:
+ try:
+ module_translations_file_path = static(manifest_data[display_language]["file"])
+ legacy_translations_file_path = static(manifest_data[f"{display_language}-legacy"]["file"])
+ except KeyError:
+ module_translations_file_path = static(manifest_data[fallback_language]["file"])
+ legacy_translations_file_path = static(manifest_data[f"{fallback_language}-legacy"]["file"])
+
+ return {
+ 'module_translations_file_path': module_translations_file_path,
+ 'legacy_translations_file_path': legacy_translations_file_path,
+ 'display_language': display_language
+ }
diff --git a/config/settings/common_settings.py b/config/settings/common_settings.py
index 3889a27cc2..af4a9297de 100644
--- a/config/settings/common_settings.py
+++ b/config/settings/common_settings.py
@@ -15,6 +15,7 @@
from decouple import Csv, config as decouple_config
from dj_database_url import parse as db_url
+from django.utils.translation import gettext_lazy
# We use a 'tuple' with pipes as delimiters as decople naively splits the global
@@ -254,4 +255,9 @@ def pipe_delim(pipe_string):
# List of Template names that contains additional script tags to be added to the base template
BASE_TEMPLATE_ADDITIONAL_SCRIPT_TEMPLATES = []
+# i18n
+LANGUAGES = [
+ ('en', gettext_lazy('English')),
+ ('ja', gettext_lazy('Japanese')),
+]
SALT_KEY = SECRET_KEY
diff --git a/mathesar/templates/mathesar/index.html b/mathesar/templates/mathesar/index.html
index e26130095d..30e8593603 100644
--- a/mathesar/templates/mathesar/index.html
+++ b/mathesar/templates/mathesar/index.html
@@ -4,9 +4,11 @@
{% block title %}Home{% endblock %}
{% block styles %}
- {% if not development_mode %} {% for css_file in manifest_data.module_css %}
-
- {% endfor %} {% endif %}
+ {% if not development_mode %}
+ {% for css_file in manifest_data.module_css %}
+
+ {% endfor %}
+ {% endif %}
{% endblock %}
{% block scripts %}
@@ -17,6 +19,8 @@
{% endfor %}
{% endif %}
+
+
{% if development_mode %}
@@ -52,12 +56,22 @@
>
+
+
{% endif %}
{% endblock %}
diff --git a/mathesar/utils/frontend.py b/mathesar/utils/frontend.py
index 428017f7f0..8c0ad8fff4 100644
--- a/mathesar/utils/frontend.py
+++ b/mathesar/utils/frontend.py
@@ -21,11 +21,14 @@ def get_manifest_data():
module_data = raw_data['src/main.ts']
manifest_data['module_css'] = [filename for filename in module_data['css']]
manifest_data['module_js'] = module_data['file']
-
legacy_data = raw_data['src/main-legacy.ts']
manifest_data['legacy_polyfill_js'] = raw_data['vite/legacy-polyfills-legacy']['file']
manifest_data['legacy_js'] = legacy_data['file']
+ for locale, _ in settings.LANGUAGES or []:
+ manifest_data[locale] = raw_data[f'src/i18n/{locale}/index.ts']
+ manifest_data[f"{locale}-legacy"] = raw_data[f'src/i18n/{locale}/index-legacy.ts']
+
# Cache data for 1 hour
cache.set('manifest_data', manifest_data, 60 * 60)
return manifest_data
diff --git a/mathesar_ui/src/App.svelte b/mathesar_ui/src/App.svelte
index 4fe08c214e..f512425f81 100644
--- a/mathesar_ui/src/App.svelte
+++ b/mathesar_ui/src/App.svelte
@@ -3,38 +3,42 @@
import { preloadCommonData } from '@mathesar/utils/preloadData';
import AppContext from './AppContext.svelte';
import RootRoute from './routes/RootRoute.svelte';
- import { loadLocaleAsync } from './i18n/i18n-load';
import { setLocale } from './i18n/i18n-svelte';
- import type { RequestStatus } from './api/utils/requestUtils';
- import { getErrorMessage } from './utils/errors';
import ErrorBox from './components/message-boxes/ErrorBox.svelte';
+ import { loadLocaleAsync, loadTranslations } from './i18n/i18n-load';
+ let isTranslationsLoaded = false;
/**
- * Later the translations file will be loaded
- * in parallel to the FE's first chunk
+ * Why translations are being read from window object?
+ * In order to -
+ * 1. Load the translations file in parallel to the first FE chunk.
+ * 2. And then make it available for the entry(App.svelte)
+ * file to load them into memory.
+ *
+ * The index.html loads it as using a script tag
+ * Each translations file on load, attaches the translations
+ * to the window object
*/
- let translationLoadStatus: RequestStatus = { state: 'processing' };
void (async () => {
- try {
+ const { translations, displayLanguage } = window.Mathesar || {};
+ if (translations && displayLanguage) {
+ loadTranslations(displayLanguage, translations[displayLanguage]);
+ setLocale(displayLanguage);
+ isTranslationsLoaded = true;
+ } else {
await loadLocaleAsync('en');
- setLocale('en');
- translationLoadStatus = { state: 'success' };
- } catch (exp) {
- translationLoadStatus = {
- state: 'failure',
- errors: [getErrorMessage(exp)],
- };
+ isTranslationsLoaded = true;
}
})();
const commonData = preloadCommonData();
-{#if translationLoadStatus.state === 'success' && commonData}
+{#if isTranslationsLoaded && commonData}