From f7cbcf871db45d5d24559290f5e13b2800d41322 Mon Sep 17 00:00:00 2001 From: Tomas Bures Date: Sun, 18 Nov 2018 22:53:34 +0100 Subject: [PATCH] Work in progress on supporting languages in custom forms --- client/src/lib/i18n.js | 3 ++- client/src/lists/forms/CUD.js | 15 +++++++++++++-- locales/extract.js | 2 +- server/models/forms.js | 18 ++++++++++++------ 4 files changed, 28 insertions(+), 10 deletions(-) diff --git a/client/src/lib/i18n.js b/client/src/lib/i18n.js index 7b9440b4..224d1d16 100644 --- a/client/src/lib/i18n.js +++ b/client/src/lib/i18n.js @@ -45,7 +45,8 @@ i18n }, react: { - wait: true + wait: true, + defaultTransParent: 'span' // This is because we use React < v16 }, detection: { diff --git a/client/src/lists/forms/CUD.js b/client/src/lists/forms/CUD.js index 45d719fe..9fbd5b8a 100644 --- a/client/src/lists/forms/CUD.js +++ b/client/src/lists/forms/CUD.js @@ -16,6 +16,7 @@ import { AlignedRow, Button, ButtonRow, + CheckBox, Dropdown, Fieldset, Form, @@ -33,6 +34,7 @@ import { import {DeleteModalDialog} from "../../lib/modals"; import mailtrainConfig from 'mailtrainConfig'; +import {langCodes} from "../../../../shared/langs"; @withTranslation() @withForm @@ -82,7 +84,7 @@ export default class CUD extends Component { const t = props.t; const helpEmailText = t('thePlaintextVersionForThisEmail'); - const helpMjmlGeneral = Custom forms use MJML for formatting. See the MJML documentation here; + const helpMjmlGeneral = Custom forms use MJML for formatting. See the MJML documentation here; this.templateSettings = { layout: { @@ -283,6 +285,7 @@ export default class CUD extends Component { name: '', description: '', selectedTemplate: 'layout', + selectedLanguage: '', namespace: mailtrainConfig.user.namespace }; supplyDefaults(data); @@ -378,6 +381,11 @@ export default class CUD extends Component { }); } + const langOptions = [{key: '', label: t('Default')}]; + for (const lng of mailtrainConfig.enabledLanguages) { + langOptions.push({key: lng, label: langCodes[lng].getLabel(t)}); + } + const listsColumns = [ { data: 0, title: "#" }, @@ -388,6 +396,7 @@ export default class CUD extends Component { const previewListId = this.getFormValue('previewList'); const selectedTemplate = this.getFormValue('selectedTemplate'); + const selectedLanguage = this.getFormValue('selectedLanguage'); return (
@@ -448,8 +457,10 @@ export default class CUD extends Component { { selectedTemplate &&
+ + - +
} diff --git a/locales/extract.js b/locales/extract.js index 3a5479bf..3f25e442 100644 --- a/locales/extract.js +++ b/locales/extract.js @@ -145,7 +145,7 @@ function parseSpec(specStr) { } // see http://blog.stevenlevithan.com/archives/match-quoted-string -const tMatcher = /(^|[ {+(=])((?:tUI|tLog|t|tMark)\s*\(\s*(?:\/\*(.*?)\*\/)?\s*)(["'])((?:(?!\4)[^\\]|\\.)*)(\4)/; +const tMatcher = /(^|[ {+(=.])((?:tUI|tLog|t|tMark)\s*\(\s*(?:\/\*(.*?)\*\/)?\s*)(["'])((?:(?!\4)[^\\]|\\.)*)(\4)/; const transMatcher = /(\/\*(.*?)\*\/\s*)?(\][\s\S]*?\<\/Trans\>)/; const jsxParser = acorn.Parser.extend(acornJsx()); diff --git a/server/models/forms.js b/server/models/forms.js index 15425794..c788f8ea 100644 --- a/server/models/forms.js +++ b/server/models/forms.js @@ -7,7 +7,6 @@ const dtHelpers = require('../lib/dt-helpers'); const interoperableErrors = require('../../shared/interoperable-errors'); const shares = require('./shares'); const namespaceHelpers = require('../lib/namespace-helpers'); -const bluebird = require('bluebird'); const fs = require('fs-extra'); const path = require('path'); const mjml = require('mjml'); @@ -189,7 +188,7 @@ async function getDefaultCustomFormValues() { async function getContents(fileName) { try { - const template = await fs.readFile(path.join(basePath, fileName), 'utf8'); + return await fs.readFile(path.join(basePath, fileName), 'utf8'); } catch (err) { return false; } @@ -205,12 +204,13 @@ async function getDefaultCustomFormValues() { } form.layout = await getContents('views/subscription/layout.mjml.hbs') || ''; - form.form_input_style = await getContents('static/subscription/form-input-style.css') || '@import url(/subscription/form-input-style.css);'; + form.form_input_style = await getContents('../client/static/subscription/form-input-style.css') || '@import url(/subscription/form-input-style.css);'; return form; } +// TODO - this could run in the browser too - move to shared function checkForMjmlErrors(form) { let testLayout = '{{{body}}}'; @@ -234,9 +234,15 @@ function checkForMjmlErrors(form) { const template = form[key]; const errs = hasMjmlError(template); - const msgs = errs.map(x => x.formattedMessage); + let msgs; + if (Array.isArray(errs)) { + msgs = errs.map(x => x.formattedMessage) + } else { + msgs = [ errs.message ]; + } + if (key === 'mail_confirm_html' && !template.includes('{{confirmUrl}}')) { - msgs.push('Missing {{confirmUrl}}'); + msgs.push('Missing {{confirmUrl}}'); // TODO - add localization support } if (msgs.length) { @@ -255,7 +261,7 @@ function checkForMjmlErrors(form) { } if (!layout.includes('{{{body}}}')) { - msgs.push(`{{{body}}} not found`); + msgs.push(`{{{body}}} not found`); // TODO - add localization support } if (msgs.length) {