mirror of
https://github.com/wekan/wekan.git
synced 2026-11-05 21:44:59 -05:00
On the server only the default (English) translation bundle is loaded at startup. Translating a notification to a user's language called TAPi18n.__(key, params, lang) with lng=lang, but that resource bundle was never added on the server, so i18next fell back to English — every notification email went out in English regardless of the user's profile language. (The client works because switching language calls setLanguage, which loads the bundle.) Add TAPi18n.ensureLanguageLoaded(language), which loads the bundle on demand if i18next does not already have it, and await it before translating in the email notification, EmailLocalization.sendEmail and outgoing webhook paths. Closes #5875 Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
63 lines
2.2 KiB
JavaScript
63 lines
2.2 KiB
JavaScript
// emailLocalization.js
|
|
// Utility functions to handle email localization in Wekan
|
|
|
|
import { TAPi18n } from '/imports/i18n';
|
|
import { ReactiveCache } from '/imports/reactiveCache';
|
|
|
|
// Main object for email localization utilities
|
|
const EmailLocalization = {
|
|
/**
|
|
* Send an email using the recipient's preferred language
|
|
* @param {Object} options - Standard email sending options plus language options
|
|
* @param {String} options.to - Recipient email address
|
|
* @param {String} options.from - Sender email address
|
|
* @param {String} options.subject - Email subject i18n key
|
|
* @param {String} options.text - Email text i18n key
|
|
* @param {Object} options.params - Parameters for i18n translation
|
|
* @param {String} options.language - Language code to use (if not provided, will try to detect)
|
|
* @param {String} options.userId - User ID to determine language (if not provided with language)
|
|
*/
|
|
async sendEmail(options) {
|
|
// Determine the language to use
|
|
let lang = options.language;
|
|
|
|
// If no language is specified but we have a userId, try to get the user's language
|
|
if (!lang && options.userId) {
|
|
const user = await ReactiveCache.getUser(options.userId);
|
|
if (user) {
|
|
lang = user.getLanguage();
|
|
}
|
|
}
|
|
|
|
// If no language could be determined, use the site default
|
|
if (!lang) {
|
|
lang = TAPi18n.getLanguage() || 'en';
|
|
}
|
|
|
|
// #5875: ensure the chosen language's bundle is loaded on the server before
|
|
// translating, otherwise __() falls back to English.
|
|
await TAPi18n.ensureLanguageLoaded(lang);
|
|
|
|
// Translate subject and text using the determined language
|
|
const subject = TAPi18n.__(options.subject, options.params || {}, lang);
|
|
let text = options.text;
|
|
|
|
// If text is an i18n key, translate it
|
|
if (typeof text === 'string' && text.startsWith('email-')) {
|
|
text = TAPi18n.__(text, options.params || {}, lang);
|
|
}
|
|
|
|
// Send the email with translated content
|
|
return await Email.sendAsync({
|
|
to: options.to,
|
|
from: options.from || Accounts.emailTemplates.from,
|
|
subject: subject,
|
|
text: text,
|
|
html: options.html
|
|
});
|
|
}
|
|
};
|
|
|
|
// Add module.exports to make it accessible from other files
|
|
export default EmailLocalization;
|