Skip to content

Commit

Permalink
[#2214] Translation of content on group view pages#2214] Translation of
Browse files Browse the repository at this point in the history
content on group view pages#2214] Translation of content on group view
pages
  • Loading branch information
Sean Hammond committed Mar 7, 2012
1 parent 1148b78 commit 9af55f1
Show file tree
Hide file tree
Showing 4 changed files with 137 additions and 79 deletions.
6 changes: 4 additions & 2 deletions ckan/lib/create_test_data.py
Original file line number Diff line number Diff line change
Expand Up @@ -785,7 +785,8 @@ def get_all_data(cls):
'123',
'456',
'789',
'plain text'
'plain text',
'Roger likes these books.',
)
english_translations = {
'123': 'jealousy',
Expand All @@ -804,7 +805,8 @@ def get_all_data(cls):
'book': 'Buch',
'456': 'Realismus',
'789': 'Heuchelei',
'plain text': 'Klartext'
'plain text': 'Klartext',
'Roger likes these books.': 'Roger mag diese Bucher.'
}
french_translations = {
'A Novel By Tolstoy': 'A Novel par Tolstoi',
Expand Down
4 changes: 2 additions & 2 deletions ckan/templates/group/read.html
Original file line number Diff line number Diff line change
Expand Up @@ -4,8 +4,8 @@
py:strip="">

<xi:include href="../facets.html" />
<py:def function="page_title">${c.group.display_name}</py:def>
<py:def function="page_heading">${c.group.display_name}</py:def>
<py:def function="page_title">${c.group_dict.display_name}</py:def>
<py:def function="page_heading">${c.group_dict.display_name}</py:def>

<py:match path="primarysidebar">

Expand Down
153 changes: 79 additions & 74 deletions ckanext/multilingual/plugin.py
Original file line number Diff line number Diff line change
@@ -1,11 +1,87 @@
import sets
import ckan
from ckan.plugins import SingletonPlugin, implements, IPackageController
from ckan.plugins import IGroupController
import pylons
from pylons import config

LANGS = ['en', 'fr', 'de', 'es', 'it', 'nl', 'ro', 'pt', 'pl']

def translate_data_dict(data_dict):
desired_lang_code = pylons.request.environ['CKAN_LANG']
fallback_lang_code = pylons.config.get('ckan.locale_default', 'en')

# Get a flattened copy of data_dict to do the translation on.
flattened = ckan.lib.navl.dictization_functions.flatten_dict(
data_dict)

# Get a simple flat list of all the terms to be translated, from the
# flattened data dict.
terms = sets.Set()
for (key, value) in flattened.items():
if value in (None, True, False):
continue
elif isinstance(value, basestring):
terms.add(value)
else:
for item in value:
terms.add(item)

# Get the translations of all the terms (as a list of dictionaries).
translations = ckan.logic.action.get.term_translation_show(
{'model': ckan.model},
{'terms': terms,
'lang_codes': (desired_lang_code, fallback_lang_code)})

# Transform the translations into a more convenient structure.
desired_translations = {}
fallback_translations = {}
for translation in translations:
if translation['lang_code'] == desired_lang_code:
desired_translations[translation['term']] = (
translation['term_translation'])
else:
assert translation['lang_code'] == fallback_lang_code
fallback_translations[translation['term']] = (
translation['term_translation'])

# Make a copy of the flattened data dict with all the terms replaced by
# their translations, where available.
translated_flattened = {}
for (key, value) in flattened.items():

# Don't translate names that are used for form URLs.
if key == ('name',):
translated_flattened[key] = value
elif (key[0] in ('tags', 'groups') and len(key) == 3
and key[2] == 'name'):
translated_flattened[key] = value

elif value in (None, True, False):
# Don't try to translate values that aren't strings.
translated_flattened[key] = value

elif isinstance(value, basestring):
if desired_translations.has_key(value):
translated_flattened[key] = desired_translations[value]
else:
translated_flattened[key] = fallback_translations.get(
value, value)
else:
translated_value = []
for item in value:
if desired_translations.has_key(value):
translated_flattened[key] = desired_translations[value]
else:
translated_flattened[key] = fallback_translations.get(
value, value)
translated_flattened[key] = translated_value

# Finally unflatten and return the translated data dict.
translated_data_dict = (ckan.lib.navl.dictization_functions
.unflatten(translated_flattened))
return translated_data_dict

class MultilingualDataset(SingletonPlugin):
implements(IPackageController, inherit=True)

Expand Down Expand Up @@ -73,81 +149,10 @@ def after_search(self, search_results, search_params):
return search_results

def before_view(self, data_dict):
desired_lang_code = pylons.request.environ['CKAN_LANG']
fallback_lang_code = pylons.config.get('ckan.locale_default', 'en')

# Get a flattened copy of data_dict to do the translation on.
flattened = ckan.lib.navl.dictization_functions.flatten_dict(
data_dict)

# Get a simple flat list of all the terms to be translated, from the
# flattened data dict.
terms = sets.Set()
for (key, value) in flattened.items():
if value in (None, True, False):
continue
elif isinstance(value, basestring):
terms.add(value)
else:
for item in value:
terms.add(item)

# Get the translations of all the terms (as a list of dictionaries).
translations = ckan.logic.action.get.term_translation_show(
{'model': ckan.model},
{'terms': terms,
'lang_codes': (desired_lang_code, fallback_lang_code)})

# Transform the translations into a more convenient structure.
desired_translations = {}
fallback_translations = {}
for translation in translations:
if translation['lang_code'] == desired_lang_code:
desired_translations[translation['term']] = (
translation['term_translation'])
else:
assert translation['lang_code'] == fallback_lang_code
fallback_translations[translation['term']] = (
translation['term_translation'])

# Make a copy of the flattened data dict with all the terms replaced by
# their translations, where available.
translated_flattened = {}
for (key, value) in flattened.items():

# Don't translate names that are used for form URLs.
if key == ('name',):
translated_flattened[key] = value
elif key[0] in ('tags', 'groups') and key[2] == 'name':
translated_flattened[key] = value

elif value in (None, True, False):
# Don't try to translate values that aren't strings.
translated_flattened[key] = value

elif isinstance(value, basestring):
if desired_translations.has_key(value):
translated_flattened[key] = desired_translations[value]
else:
translated_flattened[key] = fallback_translations.get(
value, value)
else:
translated_value = []
for item in value:
if desired_translations.has_key(value):
translated_flattened[key] = desired_translations[value]
else:
translated_flattened[key] = fallback_translations.get(
value, value)
translated_flattened[key] = translated_value

# Finally unflatten and return the translated data dict.
translated_data_dict = (ckan.lib.navl.dictization_functions
.unflatten(translated_flattened))
return translated_data_dict
return translate_data_dict(data_dict)

class MultilingualGroup(SingletonPlugin):
implements(IPackageController, inherit=True)
implements(IGroupController, inherit=True)

def before_view(self, data_dict):
return data_dict
return translate_data_dict(data_dict)
53 changes: 52 additions & 1 deletion ckanext/multilingual/tests/test_multilingual_plugin.py
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@ class TestDatasetTermTranslation(ckan.tests.html_check.HtmlCheckMethods):
def setup(cls):
cls.app = paste.fixture.TestApp(pylons.test.pylonsapp)
ckan.plugins.load('multilingual_dataset')
ckan.plugins.load('multilingual_group')
ckan.tests.setup_test_search_index()
ckan.lib.create_test_data.CreateTestData.create_translations_test_data()
# Add translation terms that match a couple of group names and package
Expand Down Expand Up @@ -59,7 +60,21 @@ def test_dataset_view_translation(self):
response = self.app.get(offset, status=200,
extra_environ={'CKAN_LANG': lang_code,
'CKAN_CURRENT_URL': offset})
for term in ckan.lib.create_test_data.terms:
terms = ('A Novel By Tolstoy',
'Index of the novel',
'russian',
'tolstoy',
"Dave's books",
"Roger's books",
'Other (Open)',
'romantic novel',
'book',
'123',
'456',
'789',
'plain text',
)
for term in terms:
if term in translations:
response.mustcontain(translations[term])
elif term in ckan.lib.create_test_data.english_translations:
Expand Down Expand Up @@ -97,3 +112,39 @@ def test_dataset_search_results_translation(self):
response.mustcontain('/%s/dataset?groups=%s' % (lang_code, group_name))
nose.tools.assert_raises(IndexError, response.mustcontain,
'this should not be rendered')

def test_group_search_results_translation(self):
for (lang_code, translations) in (
('de', ckan.lib.create_test_data.german_translations),
('fr', ckan.lib.create_test_data.french_translations),
('en', ckan.lib.create_test_data.english_translations),
('pl', {})):
offset = '/%s/group/roger' % lang_code
response = self.app.get(offset, status=200)
terms = ('A Novel By Tolstoy',
'Index of the novel',
'russian',
'tolstoy',
#"Dave's books",
"Roger's books",
#'Other (Open)',
#'romantic novel',
#'book',
'123',
'456',
'789',
'plain text',
'Roger likes these books.',
)
for term in terms:
if term in translations:
response.mustcontain(translations[term])
elif term in ckan.lib.create_test_data.english_translations:
response.mustcontain(
ckan.lib.create_test_data.english_translations[term])
else:
response.mustcontain(term)
for tag_name in ('123', '456', '789', 'russian', 'tolstoy'):
response.mustcontain('%s?tags=%s' % (offset, tag_name))
nose.tools.assert_raises(IndexError, response.mustcontain,
'this should not be rendered')

0 comments on commit 9af55f1

Please sign in to comment.