Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Make sure the default_language, if any, is first #1975

Merged
merged 2 commits into from
Sep 5, 2018
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
53 changes: 28 additions & 25 deletions kpi/models/asset.py
Original file line number Diff line number Diff line change
Expand Up @@ -218,14 +218,18 @@ def _unlink_list_items(self, content):
def _remove_empty_expressions(self, content):
remove_empty_expressions_in_place(content)

def _adjust_active_translation(self, content):
# to get around the form builder's way of handling translations where
# the interface focuses on the "null translation" and shows other ones
# in advanced settings, we allow the builder to attach a parameter
# which says what to name the null translation.
_null_translation_as = content.pop('#active_translation_name', None)
if _null_translation_as:
self._rename_translation(content, None, _null_translation_as)
def _make_default_translation_first(self, content):
# The form builder only shows the first language, so make sure the
# default language is always at the top of the translations list. The
# new translations UI, on the other hand, shows all languages:
# https://github.com/kobotoolbox/kpi/issues/1273
try:
default_translation_name = content['settings']['default_language']
except KeyError:
# No `default_language`; don't do anything
return
else:
self._prioritize_translation(content, default_translation_name)

def _strip_empty_rows(self, content, vals=None):
if vals is None:
Expand Down Expand Up @@ -291,28 +295,27 @@ def update_translation_list(self, translation_list):
)

def _prioritize_translation(self, content, translation_name, is_new=False):
_translations = content.get('translations')
# the translations/languages present this particular content
_translations = content['translations']
# the columns that have translations
_translated = content.get('translated', [])
if is_new and (translation_name in _translations):
raise ValueError('cannot add existing translation')
elif (not is_new) and (translation_name not in _translations):
raise ValueError('translation cannot be found')
_tindex = -1 if is_new else _translations.index(translation_name)
if is_new or (_tindex > 0):
for row in content.get('survey', []):
for col in _translated:
if is_new:
val = '{}'.format(row[col][0])
else:
val = row[col].pop(_tindex)
row[col].insert(0, val)
for row in content.get('choices', []):
for col in _translated:
if is_new:
val = '{}'.format(row[col][0])
else:
val = row[col].pop(_tindex)
row[col].insert(0, val)
for sheet_name in 'survey', 'choices':
for row in content.get(sheet_name, []):
for col in _translated:
if is_new:
val = '{}'.format(row[col][0])
else:
try:
val = row[col].pop(_tindex)
except KeyError:
continue
row[col].insert(0, val)
if is_new:
_translations.insert(0, translation_name)
else:
Expand Down Expand Up @@ -544,7 +547,7 @@ def adjust_content_on_save(self):
'''
self._standardize(self.content)

self._adjust_active_translation(self.content)
self._make_default_translation_first(self.content)
self._strip_empty_rows(self.content)
self._assign_kuids(self.content)
self._autoname(self.content)
Expand Down Expand Up @@ -818,7 +821,7 @@ def save(self, *args, **kwargs):
if _source is None:
_source = {}
self._standardize(_source)
self._adjust_active_translation(_source)
self._make_default_translation_first(_source)
self._strip_empty_rows(_source)
self._autoname(_source)
self._remove_empty_expressions(_source)
Expand Down
62 changes: 53 additions & 9 deletions kpi/tests/test_assets.py
Original file line number Diff line number Diff line change
Expand Up @@ -146,20 +146,64 @@ def _wrap_type(self, type_val, select_from=None):
{'list_name': 'yn', 'name': 'n', 'label': 'No'},
]}

def test_rename_null_translation(self):
def test_default_translation_first(self):
'''
This allows a workaround to enable multi-translation editing in the
form builder which focuses on the "null" language.
'''
self.asset = Asset.objects.create(content={'survey': [
{'label': ['lang1', 'lang2'], 'type': 'text', 'name': 'q1'},
],
'translations': ['lang1', None],
'#active_translation_name': 'lang2',
def _check_content(content, expected_translations):
self.assertListEqual(
content['translations'], expected_translations
)
for sheet_name in 'survey', 'choices':
for row in content[sheet_name]:
for col in 'label', 'hint':
for index, cell in enumerate(row.get(col, [])):
self.assertTrue(
str(cell).endswith(
str(expected_translations[index])
)
)

self.asset = Asset.objects.create(content={
'survey': [
{
'name': 'q1',
'type': 'select_one',
'label': ['q label lang1', None, 'q label lang3'],
'hint': ['q hint lang1', 'q hint None', 'q hint lang3'],
'select_from_list_name': 'choice_list',
},
],
'choices': [
{'list_name': 'choice_list', 'name': 'c1',
'label': ['c1 lang1', None, 'c1 lang3']},
{'list_name': 'choice_list', 'name': 'c2',
'label': ['c2 lang1', 'c2 None', 'c2 lang3']},
{'list_name': 'choice_list', 'name': 'c3',
'label': ['c3 lang1', 'c3 None', 'c3 lang3']},
],
'settings': [{'default_language': 'lang3'}],
'translations': ['lang1', None, 'lang3'],
})
self.assertEqual(self.asset.content['translations'], ['lang1', 'lang2'])
self.assertTrue('#active_translation_name' not in self.asset.content)
self.assertTrue('#null_translation' not in self.asset.content)
_check_content(
self.asset.content,
expected_translations=['lang3', 'lang1', None]
)

self.asset.content['settings']['default_language'] = None
self.asset.save()
_check_content(
self.asset.content,
expected_translations=[None, 'lang3', 'lang1']
)

del self.asset.content['settings']['default_language']
self.asset.save()
_check_content(
self.asset.content,
expected_translations=[None, 'lang3', 'lang1']
)

def test_rename_translation(self):
'''
Expand Down