diff --git a/packages/cms/lib/modules/openstad-global/lib/api.js b/packages/cms/lib/modules/openstad-global/lib/api.js index 9f6a42a8a..f64ec22a2 100644 --- a/packages/cms/lib/modules/openstad-global/lib/api.js +++ b/packages/cms/lib/modules/openstad-global/lib/api.js @@ -13,47 +13,64 @@ const translatorConfig = { maxRetries: 5, minTimeout: 10000 }; module.exports = (self, options) => { self.translate = (req, res) => { - let deeplAuthKey = options.deeplKey; - let content = req.body.contents; - let origin = req.body.origin; + const deeplAuthKey = options.deeplKey; + const content = req.body.contents; + const origin = req.body.origin; + const sourceLanguageCode = req.body.sourceLanguageCode; + const destinationLanguage = req.body.targetLanguageCode; + + const cacheKey = crypto.createHash('sha256').update(`${destinationLanguage}${origin}${JSON.stringify(content)}`).digest('hex'); if (!origin) { - res.status(400).send('Could not determine the page to translate'); + return res.status(400).json({ error: 'Could not determine the page to translate' }); } - const destinationLanguage = req.body.targetLanguageCode; - const cacheKey = crypto.createHash('sha256').update(`${destinationLanguage}${origin}${JSON.stringify(content)}`).digest('hex'); - let result = cache.get(cacheKey); + const result = cache.get(cacheKey); if (result) { console.log("Receiving translations from cache"); return res.json(result); } + // content should always be a collection of dutch terms, translations to other languages are translated from dutch to (for example) english + if (destinationLanguage === 'nl') { + console.log("Target language is dutch, not translating and responding with the dutch sentences received"); + return res.json(content); + } + + if (deeplAuthKey) { + let translator = null; + try { - const translator = new deepl.Translator(deeplAuthKey, translatorConfig); + translator = new deepl.Translator(deeplAuthKey, translatorConfig); + } catch (error) { + console.log({ error }); + return res.status(500).json({ error: 'Could not translate the page at this time' }); + } + + if (translator) { translator.translateText( content, - req.body.sourceLanguageCode, - req.body.targetLanguageCode, - ) - .then(response => { - cache.set(`${cacheKey}`, response, { - life: cacheLifespan - }) - return res.json(response); - }) - .catch(error => console.log({ error })); - } catch (error) { - console.log({ translationError: error }); + sourceLanguageCode, + destinationLanguage, + ).then(response => { + cache.set(`${cacheKey}`, response, { + life: cacheLifespan + }); + return res.json(response); + }) + .catch(error => { + console.error({ error }); + return res.status(500).json({ error: 'Error while translating the page' }); + }); } } else { - res.status(400).send('No valid key provided'); + return res.status(400).json({ error: 'No valid key provided' }); } } - self.apos.app.post('/modules/openstad-global/translate', function(req, res){ + self.apos.app.post('/modules/openstad-global/translate', function (req, res) { self.translate(req, res); }); diff --git a/packages/cms/lib/modules/openstad-global/public/js/always.js b/packages/cms/lib/modules/openstad-global/public/js/always.js index 2bb535ee3..5c75d6c75 100644 --- a/packages/cms/lib/modules/openstad-global/public/js/always.js +++ b/packages/cms/lib/modules/openstad-global/public/js/always.js @@ -1,11 +1,17 @@ -apos.on('ready', function() { +apos.on('ready', function () { var nodes = []; - const selectedLanguage = sessionStorage.getItem("targetLanguageCode"); + var selectedLanguage = sessionStorage.getItem("targetLanguageCode"); - if(selectedLanguage && selectedLanguage !== 'nl') { - nodes = handleNode(document.body, nodes); - const nlContents = nodes.map(function(itemToTranslate) { return itemToTranslate.orgText }); + /** + * The translate widget if set on the page will trigger an onchange event when it has been loaded + * thus triggering the fetching of translations. Then this one should do nothing and let the dedicated + * widget make the call. + */ + var translationWidgetOnSamePage = $('.translation-widget-select').length > 0; + if (!translationWidgetOnSamePage && selectedLanguage && selectedLanguage !== 'nl') { + nodes = handleNode(document.body, nodes); + var nlContents = nodes.map(function (itemToTranslate) { return itemToTranslate.orgText }); $.ajax({ url: '/modules/openstad-global/translate', method: 'post', @@ -17,21 +23,21 @@ apos.on('ready', function() { origin: window.location.href }), success: function (sentences) { - sentences = sentences.map(function(sentence) { return sentence.text }); + sentences = sentences.map(function (sentence) { return sentence.text }); changeTextInNodes(sentences, nodes); - }, + }, }); } }); changeTextInNodes = function (sentences, nodes) { - sentences.forEach(function(sentence, index) { + sentences.forEach(function (sentence, index) { nodes[index].node.textContent = sentence; }); } handleNode = function (node, toBeTranslated) { - const childNodes = node.childNodes; + var childNodes = node.childNodes; for (var i = 0; i < childNodes.length; i++) { if (childNodes[i].nodeType == Node.ELEMENT_NODE) { var nodeName = childNodes[i].nodeName.toLowerCase(); @@ -39,8 +45,8 @@ handleNode = function (node, toBeTranslated) { handleNode(childNodes[i], toBeTranslated); } } else if (childNodes[i].nodeType == Node.TEXT_NODE) { - const parentElement = childNodes[i].parentElement; - const shouldTranslate = parentElement && parentElement.getAttribute('translate') !== 'no'; + var parentElement = childNodes[i].parentElement; + var shouldTranslate = parentElement && parentElement.getAttribute('translate') !== 'no'; if (shouldTranslate) { var textContent = childNodes[i].textContent; diff --git a/packages/cms/lib/modules/translation-widgets/index.js b/packages/cms/lib/modules/translation-widgets/index.js index b56b617b6..4979c5f60 100644 --- a/packages/cms/lib/modules/translation-widgets/index.js +++ b/packages/cms/lib/modules/translation-widgets/index.js @@ -1,8 +1,6 @@ const styleSchema = require('../../../config/styleSchema.js').default; -const crypto = require('crypto'); const deepl = require('deepl-node'); const cache = require('../../../services/cache').cache; -const cacheLifespan = 8 * 60 * 60; // set lifespan of 8 hours; const cacheLanguagesLifespan = (24 * 60 * 60) * 7; // set lifespan of language cache to a week; const translatorConfig = { maxRetries: 5, minTimeout: 10000 }; @@ -63,13 +61,17 @@ module.exports = { supportedLanguages = languages.map((language, index) => { language['code'] = supportedLanguages[index].code; return language; - }) + }); cache.set(`${cacheKeyForLanguages}`, supportedLanguages, { life: cacheLanguagesLifespan }); }); } catch(error) { + supportedLanguages = supportedLanguages.map((language, index) => { + language['text'] = supportedLanguages[index].name; + return language; + }) console.error({translationError: error}); } } else { diff --git a/packages/cms/lib/modules/translation-widgets/public/js/always.js b/packages/cms/lib/modules/translation-widgets/public/js/always.js index f3639510f..b802ba744 100644 --- a/packages/cms/lib/modules/translation-widgets/public/js/always.js +++ b/packages/cms/lib/modules/translation-widgets/public/js/always.js @@ -10,7 +10,7 @@ apos.define('translation-widgets', { var nodes = []; var nlContents = []; - const languageSelectContainer = $('.language-select-container'); + var languageSelectContainer = $('.language-select-container'); $('.translation-widget-select') .on('change', function (e) { return changeLanguage(e) }); @@ -28,18 +28,16 @@ apos.define('translation-widgets', { function saveLanguagePreference(targetLanguageCode) { try{ sessionStorage.setItem("targetLanguageCode", targetLanguageCode); - console.log("Saved language preference"); } catch(quotaExceededError) { console.log("Could not save the language preference"); } } changeLanguage = function (e) { - const select = e.target; - const targetLanguageCode = select.value; + var select = e.target; + var targetLanguageCode = select.value; setSelectDisabled(select); - console.log('translate to', targetLanguageCode); var node = document.body; @@ -50,10 +48,12 @@ apos.define('translation-widgets', { } if (targetLanguageCode === 'nl') { + console.log("Language is set to the default: " + targetLanguageCode +". No need to translate"); changeTextInNodes(nlContents, nodes); setSelectEnabled(select); saveLanguagePreference(targetLanguageCode); } else { + console.log('translating to', targetLanguageCode); $.ajax({ url: '/modules/translation-widgets/submit', method: 'POST', @@ -72,6 +72,7 @@ apos.define('translation-widgets', { }, error: function() { setSelectEnabled(select); + setSelectedLanguage('nl'); } }) } @@ -79,7 +80,14 @@ apos.define('translation-widgets', { } }); +function setSelectedLanguage(language) { + $('.translation-widget-select').val(language ? language : 'nl').trigger('change'); +} + +/** + * Makes a call to the backend to translate. This needs to happen to set the initial selection after rendering the page, + * collecting the initial values and if the language is not the default 'nl', fetching the translations + */ apos.on('ready', function() { - const selectedLanguage = sessionStorage.getItem('targetLanguageCode'); - $('.translation-widget-select').val(selectedLanguage ? selectedLanguage : 'nl').trigger('change'); + setSelectedLanguage(sessionStorage.getItem('targetLanguageCode')); });