Commit 8b42f3ed authored by Jérome Perrin's avatar Jérome Perrin

web_renderjs_ui: rework "Update Translation Data" action

- user no longer have to choose the translation data script, it's
  selected automatically from the translation gadget configured on the
  web site
- add some notes in workflow history for traceability
- rename from "Create Translation Data" to *Update* Translation Data, as
  this script can be called multiple times to update
- rename the dialog and script to comply with naming conventions
- add a header to generated translation data script to explain that this
  is generated and that it should not be edited manually
- generate code passing jslint and typescript
parent 6e3370ce
...@@ -60,7 +60,7 @@ ...@@ -60,7 +60,7 @@
</item> </item>
<item> <item>
<key> <string>title</string> </key> <key> <string>title</string> </key>
<value> <string>Create Translation Data</string> </value> <value> <string>Update Translation Data</string> </value>
</item> </item>
<item> <item>
<key> <string>visible</string> </key> <key> <string>visible</string> </key>
...@@ -77,7 +77,7 @@ ...@@ -77,7 +77,7 @@
<dictionary> <dictionary>
<item> <item>
<key> <string>text</string> </key> <key> <string>text</string> </key>
<value> <string>string:${object_url}/WebSite_createTranslationData</string> </value> <value> <string>string:${object_url}/WebSite_viewUpdateTranslationDataDialog</string> </value>
</item> </item>
</dictionary> </dictionary>
</pickle> </pickle>
......
/**
* This translation data is generated automatically and updated with upgrader in post-upgarde.
* Do not edit manually, but use "Update Translation Data" action on web site to update from
* Localizer and from data-i18n tags on web pages.
*/
/*globals window*/ /*globals window*/
/*jslint indent: 2, nomen: true, maxlen: 80*/ /*jslint indent: 2, nomen: true */
(function (window) { (function (window) {
"use strict"; "use strict";
// @ts-ignore
window.translation_data = { window.translation_data = {
en: { "en": {
} }
}; };
}(window)); }(window));
<?xml version="1.0"?>
<ZopeData>
<record id="1" aka="AAAAAAAAAAE=">
<pickle>
<global name="ProxyField" module="Products.ERP5Form.ProxyField"/>
</pickle>
<pickle>
<dictionary>
<item>
<key> <string>delegated_list</string> </key>
<value>
<list>
<string>first_item</string>
<string>items</string>
<string>title</string>
</list>
</value>
</item>
<item>
<key> <string>id</string> </key>
<value> <string>your_translation_data_file</string> </value>
</item>
<item>
<key> <string>message_values</string> </key>
<value>
<dictionary>
<item>
<key> <string>external_validator_failed</string> </key>
<value> <string>The input failed the external validator.</string> </value>
</item>
</dictionary>
</value>
</item>
<item>
<key> <string>overrides</string> </key>
<value>
<dictionary>
<item>
<key> <string>field_id</string> </key>
<value> <string></string> </value>
</item>
<item>
<key> <string>form_id</string> </key>
<value> <string></string> </value>
</item>
</dictionary>
</value>
</item>
<item>
<key> <string>tales</string> </key>
<value>
<dictionary>
<item>
<key> <string>field_id</string> </key>
<value> <string></string> </value>
</item>
<item>
<key> <string>first_item</string> </key>
<value> <string></string> </value>
</item>
<item>
<key> <string>form_id</string> </key>
<value> <string></string> </value>
</item>
<item>
<key> <string>items</string> </key>
<value>
<persistent> <string encoding="base64">AAAAAAAAAAI=</string> </persistent>
</value>
</item>
<item>
<key> <string>title</string> </key>
<value> <string></string> </value>
</item>
</dictionary>
</value>
</item>
<item>
<key> <string>values</string> </key>
<value>
<dictionary>
<item>
<key> <string>field_id</string> </key>
<value> <string>my_list_field</string> </value>
</item>
<item>
<key> <string>first_item</string> </key>
<value> <int>1</int> </value>
</item>
<item>
<key> <string>form_id</string> </key>
<value> <string>Base_viewFieldLibrary</string> </value>
</item>
<item>
<key> <string>items</string> </key>
<value>
<list/>
</value>
</item>
<item>
<key> <string>title</string> </key>
<value> <string>Translation Data File</string> </value>
</item>
</dictionary>
</value>
</item>
</dictionary>
</pickle>
</record>
<record id="2" aka="AAAAAAAAAAI=">
<pickle>
<global name="TALESMethod" module="Products.Formulator.TALESField"/>
</pickle>
<pickle>
<dictionary>
<item>
<key> <string>_text</string> </key>
<value> <string>python: [ (x,x) for x in here.Base_getTranslationSourceFileList()]</string> </value>
</item>
</dictionary>
</pickle>
</record>
</ZopeData>
"""Returns the `text_content` that should be set on the translation data script for this RJS website.
"""
import re import re
import json import json
portal = context.getPortalObject() portal = context.getPortalObject()
Base_translateString = context.Base_translateString Base_translateString = context.Base_translateString
#(data-i18n)=["']{{((?:.(?!["']?(?:\S+)=|[>"']))+.)}}["']
attribute_filter_re = re.compile(r"""(data-i18n)=["']?((?:.(?!["']?\s+(?:\S+)=|[>"']))+.)["']?""")
translate_word = []
# Collect all translatable messages from web pages referenced by this web sites.
# The convention is to use data-i18n tags in HTML, like:
# <span data-18n="The message">The message</span>
# or in comments, like this:
# <!-- data-i18n="The message" -->
attribute_filter_re = re.compile(r"""(data-i18n)=["']?((?:.(?!["']?\s+(?:\S+)=|[>"']))+.)["']?""")
translatable_message_set = set([])
for web_page in portal.web_page_module.searchFolder(portal_type='Web Page', for web_page in portal.web_page_module.searchFolder(portal_type='Web Page',
reference=context.Base_getTranslationSourceFileList(only_html=1)): reference=context.Base_getTranslationSourceFileList(only_html=1)):
data = attribute_filter_re.findall(web_page.getTextContent()) data = attribute_filter_re.findall(web_page.getTextContent())
...@@ -16,38 +20,31 @@ for web_page in portal.web_page_module.searchFolder(portal_type='Web Page', ...@@ -16,38 +20,31 @@ for web_page in portal.web_page_module.searchFolder(portal_type='Web Page',
a = re.sub(r'[{|}]', "", attribute[1]) a = re.sub(r'[{|}]', "", attribute[1])
a = re.sub(r'\[.*?\]', "", a) a = re.sub(r'\[.*?\]', "", a)
if a: if a:
translate_word.append(a) translatable_message_set.add(a)
translate_word = list(set(translate_word))
language_list = context.getAvailableLanguageSet()
content = """
/*globals window*/\n
/*jslint indent: 2, nomen: true, maxlen: 80*/\n
(function (window) {\n
"use strict";\n
"""
tmp = {} tmp = {}
for language in context.getAvailableLanguageSet():
for language in language_list:
tmp[language] = {} tmp[language] = {}
for word in translate_word: for word in translatable_message_set:
tmp[language][word] = Base_translateString(word, lang = language) tmp[language][word] = Base_translateString(word, lang = language)
return """/**
* This translation data is generated automatically and updated with upgrader in post-upgarde.
content += " window.translation_data = " + json.dumps(tmp, indent=3, ensure_ascii=False, separators=(',', ': ')) * Do not edit manually, but use "Update Translation Data" action on web site to update from
content += ";\n}(window));" * Localizer and from data-i18n tags on web pages.
#return json.dumps(tmp, indent=3, ensure_ascii=False, separators=(',', ': ')) */
translation_data_file=context.web_page_module.searchFolder(portal_type='Web Script',reference=translation_data_file)[0] /*globals window*/
translation_data_file.edit(text_content = content) /*jslint indent: 2, nomen: true */
# Edit web section modification date (function (window) {
context.edit() "use strict";
// @ts-ignore
if batch_mode: window.translation_data = %s;
return 'done' }(window));
return context.Base_redirect('view', keep_items=dict(portal_status_message=Base_translateString("Translation Data Create"))) """ % ("\n ".join(
json.dumps(
tmp,
sort_keys=True,
indent=2,
ensure_ascii=False,
separators=(',', ': ')).splitlines()))
...@@ -50,11 +50,11 @@ ...@@ -50,11 +50,11 @@
</item> </item>
<item> <item>
<key> <string>_params</string> </key> <key> <string>_params</string> </key>
<value> <string> translation_data_file, batch_mode=0</string> </value> <value> <string></string> </value>
</item> </item>
<item> <item>
<key> <string>id</string> </key> <key> <string>id</string> </key>
<value> <string>Base_createTranslateData</string> </value> <value> <string>WebSite_getTranslationDataTextContent</string> </value>
</item> </item>
</dictionary> </dictionary>
</pickle> </pickle>
......
# type: () -> Optional[erp5.portal_type.WebScript]
"""Returns the web script used to contain the translation data for this RJS web site.
"""
translation_gadget_url = context.getLayoutProperty(
"configuration_translation_gadget_url")
if not translation_gadget_url:
return None
translation_gadget = context.getDocumentValue(translation_gadget_url)
if not translation_gadget:
return None
# find the .js containing translation data
for successor in translation_gadget.getImplicitSuccessorValueList():
successor = successor.getObject()
if successor.getReference() and successor.getReference().endswith(
'translation_data.js'):
return successor
return None
<?xml version="1.0"?>
<ZopeData>
<record id="1" aka="AAAAAAAAAAE=">
<pickle>
<global name="PythonScript" module="Products.PythonScripts.PythonScript"/>
</pickle>
<pickle>
<dictionary>
<item>
<key> <string>Script_magic</string> </key>
<value> <int>3</int> </value>
</item>
<item>
<key> <string>_bind_names</string> </key>
<value>
<object>
<klass>
<global name="NameAssignments" module="Shared.DC.Scripts.Bindings"/>
</klass>
<tuple/>
<state>
<dictionary>
<item>
<key> <string>_asgns</string> </key>
<value>
<dictionary>
<item>
<key> <string>name_container</string> </key>
<value> <string>container</string> </value>
</item>
<item>
<key> <string>name_context</string> </key>
<value> <string>context</string> </value>
</item>
<item>
<key> <string>name_m_self</string> </key>
<value> <string>script</string> </value>
</item>
<item>
<key> <string>name_subpath</string> </key>
<value> <string>traverse_subpath</string> </value>
</item>
</dictionary>
</value>
</item>
</dictionary>
</state>
</object>
</value>
</item>
<item>
<key> <string>_params</string> </key>
<value> <string></string> </value>
</item>
<item>
<key> <string>id</string> </key>
<value> <string>WebSite_getTranslationDataWebScriptValue</string> </value>
</item>
</dictionary>
</pickle>
</record>
</ZopeData>
from Products.ERP5Type.Message import translateString
portal = context.getPortalObject()
gadget_translation_data_js = context.WebSite_getTranslationDataWebScriptValue()
if gadget_translation_data_js is None:
return context.Base_redirect(
form_id,
keep_items=dict(
portal_status_message=translateString("No translation data script.")))
gadget_translation_data_js.setTextContent(
context.WebSite_getTranslationDataTextContent())
portal.portal_workflow.doActionFor(
gadget_translation_data_js,
'edit_action',
comment=translateString(
"Translation data updated from web site ${web_site_id}.",
mapping={'web_site_id': context.getId()}))
# Edit web section modification date
portal.portal_workflow.doActionFor(
context,
'edit_action',
comment=translateString("Translation data updated.",))
if REQUEST is not None:
return context.Base_redirect(
form_id,
keep_items=dict(
portal_status_message=translateString("Translation data updated.")))
<?xml version="1.0"?>
<ZopeData>
<record id="1" aka="AAAAAAAAAAE=">
<pickle>
<global name="PythonScript" module="Products.PythonScripts.PythonScript"/>
</pickle>
<pickle>
<dictionary>
<item>
<key> <string>Script_magic</string> </key>
<value> <int>3</int> </value>
</item>
<item>
<key> <string>_bind_names</string> </key>
<value>
<object>
<klass>
<global name="NameAssignments" module="Shared.DC.Scripts.Bindings"/>
</klass>
<tuple/>
<state>
<dictionary>
<item>
<key> <string>_asgns</string> </key>
<value>
<dictionary>
<item>
<key> <string>name_container</string> </key>
<value> <string>container</string> </value>
</item>
<item>
<key> <string>name_context</string> </key>
<value> <string>context</string> </value>
</item>
<item>
<key> <string>name_m_self</string> </key>
<value> <string>script</string> </value>
</item>
<item>
<key> <string>name_subpath</string> </key>
<value> <string>traverse_subpath</string> </value>
</item>
</dictionary>
</value>
</item>
</dictionary>
</state>
</object>
</value>
</item>
<item>
<key> <string>_params</string> </key>
<value> <string>form_id=\'\', REQUEST=None</string> </value>
</item>
<item>
<key> <string>id</string> </key>
<value> <string>WebSite_updateTranslationData</string> </value>
</item>
</dictionary>
</pickle>
</record>
</ZopeData>
...@@ -14,7 +14,11 @@ ...@@ -14,7 +14,11 @@
</item> </item>
<item> <item>
<key> <string>action</string> </key> <key> <string>action</string> </key>
<value> <string>Base_createTranslateData</string> </value> <value> <string>WebSite_updateTranslationData</string> </value>
</item>
<item>
<key> <string>action_title</string> </key>
<value> <string></string> </value>
</item> </item>
<item> <item>
<key> <string>description</string> </key> <key> <string>description</string> </key>
...@@ -72,7 +76,7 @@ ...@@ -72,7 +76,7 @@
<key> <string>left</string> </key> <key> <string>left</string> </key>
<value> <value>
<list> <list>
<string>your_translation_data_file</string> <string>your_translation_data_reference</string>
</list> </list>
</value> </value>
</item> </item>
...@@ -87,7 +91,7 @@ ...@@ -87,7 +91,7 @@
</item> </item>
<item> <item>
<key> <string>id</string> </key> <key> <string>id</string> </key>
<value> <string>WebSite_createTranslationData</string> </value> <value> <string>WebSite_viewUpdateTranslationDataDialog</string> </value>
</item> </item>
<item> <item>
<key> <string>method</string> </key> <key> <string>method</string> </key>
...@@ -95,7 +99,7 @@ ...@@ -95,7 +99,7 @@
</item> </item>
<item> <item>
<key> <string>name</string> </key> <key> <string>name</string> </key>
<value> <string>WebSite_createTranslationData</string> </value> <value> <string>WebSite_viewUpdateTranslationDataDialog</string> </value>
</item> </item>
<item> <item>
<key> <string>pt</string> </key> <key> <string>pt</string> </key>
...@@ -111,7 +115,7 @@ ...@@ -111,7 +115,7 @@
</item> </item>
<item> <item>
<key> <string>title</string> </key> <key> <string>title</string> </key>
<value> <string>Create Translation Data</string> </value> <value> <string>Update Translation Data</string> </value>
</item> </item>
<item> <item>
<key> <string>unicode_mode</string> </key> <key> <string>unicode_mode</string> </key>
......
<?xml version="1.0"?>
<ZopeData>
<record id="1" aka="AAAAAAAAAAE=">
<pickle>
<global name="StringField" module="Products.Formulator.StandardFields"/>
</pickle>
<pickle>
<dictionary>
<item>
<key> <string>id</string> </key>
<value> <string>your_translation_data_reference</string> </value>
</item>
<item>
<key> <string>message_values</string> </key>
<value>
<dictionary>
<item>
<key> <string>external_validator_failed</string> </key>
<value> <string>The input failed the external validator.</string> </value>
</item>
<item>
<key> <string>required_not_found</string> </key>
<value> <string>Input is required but no input given.</string> </value>
</item>
<item>
<key> <string>too_long</string> </key>
<value> <string>Too much input was given.</string> </value>
</item>
</dictionary>
</value>
</item>
<item>
<key> <string>overrides</string> </key>
<value>
<dictionary>
<item>
<key> <string>alternate_name</string> </key>
<value> <string></string> </value>
</item>
<item>
<key> <string>css_class</string> </key>
<value> <string></string> </value>
</item>
<item>
<key> <string>default</string> </key>
<value> <string></string> </value>
</item>
<item>
<key> <string>description</string> </key>
<value> <string></string> </value>
</item>
<item>
<key> <string>display_maxwidth</string> </key>
<value> <string></string> </value>
</item>
<item>
<key> <string>display_width</string> </key>
<value> <string></string> </value>
</item>
<item>
<key> <string>editable</string> </key>
<value> <string></string> </value>
</item>
<item>
<key> <string>enabled</string> </key>
<value> <string></string> </value>
</item>
<item>
<key> <string>external_validator</string> </key>
<value> <string></string> </value>
</item>
<item>
<key> <string>extra</string> </key>
<value> <string></string> </value>
</item>
<item>
<key> <string>hidden</string> </key>
<value> <string></string> </value>
</item>
<item>
<key> <string>input_type</string> </key>
<value> <string></string> </value>
</item>
<item>
<key> <string>max_length</string> </key>
<value> <string></string> </value>
</item>
<item>
<key> <string>required</string> </key>
<value> <string></string> </value>
</item>
<item>
<key> <string>title</string> </key>
<value> <string></string> </value>
</item>
<item>
<key> <string>truncate</string> </key>
<value> <string></string> </value>
</item>
<item>
<key> <string>unicode</string> </key>
<value> <string></string> </value>
</item>
<item>
<key> <string>whitespace_preserve</string> </key>
<value> <string></string> </value>
</item>
</dictionary>
</value>
</item>
<item>
<key> <string>tales</string> </key>
<value>
<dictionary>
<item>
<key> <string>alternate_name</string> </key>
<value> <string></string> </value>
</item>
<item>
<key> <string>css_class</string> </key>
<value> <string></string> </value>
</item>
<item>
<key> <string>default</string> </key>
<value>
<persistent> <string encoding="base64">AAAAAAAAAAI=</string> </persistent>
</value>
</item>
<item>
<key> <string>description</string> </key>
<value> <string></string> </value>
</item>
<item>
<key> <string>display_maxwidth</string> </key>
<value> <string></string> </value>
</item>
<item>
<key> <string>display_width</string> </key>
<value> <string></string> </value>
</item>
<item>
<key> <string>editable</string> </key>
<value> <string></string> </value>
</item>
<item>
<key> <string>enabled</string> </key>
<value> <string></string> </value>
</item>
<item>
<key> <string>external_validator</string> </key>
<value> <string></string> </value>
</item>
<item>
<key> <string>extra</string> </key>
<value> <string></string> </value>
</item>
<item>
<key> <string>hidden</string> </key>
<value> <string></string> </value>
</item>
<item>
<key> <string>input_type</string> </key>
<value> <string></string> </value>
</item>
<item>
<key> <string>max_length</string> </key>
<value> <string></string> </value>
</item>
<item>
<key> <string>required</string> </key>
<value> <string></string> </value>
</item>
<item>
<key> <string>title</string> </key>
<value> <string></string> </value>
</item>
<item>
<key> <string>truncate</string> </key>
<value> <string></string> </value>
</item>
<item>
<key> <string>unicode</string> </key>
<value> <string></string> </value>
</item>
<item>
<key> <string>whitespace_preserve</string> </key>
<value> <string></string> </value>
</item>
</dictionary>
</value>
</item>
<item>
<key> <string>values</string> </key>
<value>
<dictionary>
<item>
<key> <string>alternate_name</string> </key>
<value> <string></string> </value>
</item>
<item>
<key> <string>css_class</string> </key>
<value> <string></string> </value>
</item>
<item>
<key> <string>default</string> </key>
<value> <string></string> </value>
</item>
<item>
<key> <string>description</string> </key>
<value> <string></string> </value>
</item>
<item>
<key> <string>display_maxwidth</string> </key>
<value> <string></string> </value>
</item>
<item>
<key> <string>display_width</string> </key>
<value> <int>20</int> </value>
</item>
<item>
<key> <string>editable</string> </key>
<value> <int>0</int> </value>
</item>
<item>
<key> <string>enabled</string> </key>
<value> <int>1</int> </value>
</item>
<item>
<key> <string>external_validator</string> </key>
<value> <string></string> </value>
</item>
<item>
<key> <string>extra</string> </key>
<value> <string></string> </value>
</item>
<item>
<key> <string>hidden</string> </key>
<value> <int>0</int> </value>
</item>
<item>
<key> <string>input_type</string> </key>
<value> <string>text</string> </value>
</item>
<item>
<key> <string>max_length</string> </key>
<value> <string></string> </value>
</item>
<item>
<key> <string>required</string> </key>
<value> <int>0</int> </value>
</item>
<item>
<key> <string>title</string> </key>
<value> <string>Translation Data Script</string> </value>
</item>
<item>
<key> <string>truncate</string> </key>
<value> <int>0</int> </value>
</item>
<item>
<key> <string>unicode</string> </key>
<value> <int>0</int> </value>
</item>
<item>
<key> <string>whitespace_preserve</string> </key>
<value> <int>0</int> </value>
</item>
</dictionary>
</value>
</item>
</dictionary>
</pickle>
</record>
<record id="2" aka="AAAAAAAAAAI=">
<pickle>
<global name="TALESMethod" module="Products.Formulator.TALESField"/>
</pickle>
<pickle>
<dictionary>
<item>
<key> <string>_text</string> </key>
<value> <string>python: context.WebSite_getTranslationDataWebScriptValue().getReference() if context.WebSite_getTranslationDataWebScriptValue() else context.Base_translateString("No translation data script.")</string> </value>
</item>
</dictionary>
</pickle>
</record>
</ZopeData>
...@@ -85,6 +85,6 @@ for tmp in param_dict: ...@@ -85,6 +85,6 @@ for tmp in param_dict:
context.Base_addUITestTranslation(message = tmp['message'], translation = tmp['translation'], language = tmp['language']) context.Base_addUITestTranslation(message = tmp['message'], translation = tmp['translation'], language = tmp['language'])
context.web_site_module.renderjs_runner.setAvailableLanguageSet(['en', 'fr', 'wo']) context.web_site_module.renderjs_runner.setAvailableLanguageSet(['en', 'fr', 'wo'])
context.web_site_module.renderjs_runner.Base_createTranslateData(translation_data_file='gadget_translation_data.js',batch_mode=1) context.web_site_module.renderjs_runner.WebSite_updateTranslationData()
context.ERP5Site_updateTranslationTable() context.ERP5Site_updateTranslationTable()
return 'done' return 'done'
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment