Skip to content

Commit

Permalink
[#2217] Translation of content on tag list page
Browse files Browse the repository at this point in the history
ckan/plugins/interfaces.py
Add new ITagController plugin interface.

ckanext/multilingual/plugin.py
Add MultilingualTag plugin using the new ITagController interface.

Add tests for the new plugin.

ckan/controllers/tag.py
Put for_view: True in context and all_fields: True in data_dict when
calling tag_list()

ckan/lib/alphabet_paginate.py
Handle paginating lists of dicts.

ckan/lib/dictization/model_dictize.py:tag_dictize()
1. Add 'display_name' field to tag dicts. This is a hack, display_name
or title should be added to tag objects at model level.
2. If for_view in context call before_view() method of each
ITagController extension.

Some tweaks to the tag index template, and update some tests.
  • Loading branch information
Sean Hammond committed Mar 13, 2012
1 parent 64cb200 commit 73a2b88
Show file tree
Hide file tree
Showing 10 changed files with 80 additions and 19 deletions.
4 changes: 2 additions & 2 deletions ckan/controllers/tag.py
Original file line number Diff line number Diff line change
Expand Up @@ -25,9 +25,9 @@ def index(self):
c.q = request.params.get('q', '')

context = {'model': model, 'session': model.Session,
'user': c.user or c.author}
'user': c.user or c.author, 'for_view': True}

data_dict = {}
data_dict = {'all_fields': True}

if c.q:
page = int(request.params.get('page', 1))
Expand Down
7 changes: 6 additions & 1 deletion ckan/lib/alphabet_paginate.py
Original file line number Diff line number Diff line change
Expand Up @@ -45,7 +45,12 @@ def __init__(self, collection, alpha_attribute, page, other_text, paging_thresho
self.controller_name = controller_name
self.available = dict( (c,0,) for c in "ABCDEFGHIJKLMNOPQRSTUVWXYZ" )
for c in self.collection:
x = c[0] if isinstance( c, unicode ) else getattr(c, self.alpha_attribute)[0]
if isinstance(c, unicode):
x = c[0]
elif isinstance(c, dict):
x = c[self.alpha_attribute][0]
else:
x = getattr(c, self.alpha_attribute)[0]
self.available[x] = self.available.get(x, 0) + 1


Expand Down
21 changes: 17 additions & 4 deletions ckan/lib/dictization/model_dictize.py
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
from pylons import config
from sqlalchemy.sql import select
from ckan.plugins import PluginImplementations, IPackageController, IGroupController
import ckan.plugins
import datetime

from ckan.model import PackageRevision
Expand Down Expand Up @@ -34,7 +34,8 @@ def group_list_dictize(obj_list, context,
group_dict['packages'] = len(obj.active_packages().all())

if context.get('for_view'):
for item in PluginImplementations(IGroupController):
for item in ckan.plugins.PluginImplementations(
ckan.plugins.IGroupController):
group_dict = item.before_view(group_dict)

result_list.append(group_dict)
Expand Down Expand Up @@ -218,7 +219,8 @@ def package_dictize(pkg, context):
tag['display_name'] = tag['name']

if context.get('for_view'):
for item in PluginImplementations(IPackageController):
for item in ckan.plugins.PluginImplementations(
ckan.plugins.IPackageController):
result_dict = item.before_view(result_dict)


Expand Down Expand Up @@ -265,7 +267,8 @@ def group_dictize(group, context):
context['with_capacity'] = False

if context.get('for_view'):
for item in PluginImplementations(IGroupController):
for item in ckan.plugins.PluginImplementations(
ckan.plugins.IGroupController):
result_dict = item.before_view(result_dict)

return result_dict
Expand All @@ -279,6 +282,7 @@ def tag_list_dictize(tag_list, context):
dictized = table_dictize(tag, context, capacity=capacity)
else:
dictized = table_dictize(tag, context)

result_list.append(dictized)

return result_list
Expand All @@ -287,6 +291,15 @@ def tag_dictize(tag, context):

result_dict = table_dictize(tag, context)
result_dict["packages"] = obj_list_dictize(tag.packages, context)

assert not result_dict.has_key('display_name')
result_dict['display_name'] = result_dict['name']

if context.get('for_view'):
for item in ckan.plugins.PluginImplementations(
ckan.plugins.ITagController):
result_dict = item.before_view(result_dict)

return result_dict

def user_list_dictize(obj_list, context,
Expand Down
16 changes: 16 additions & 0 deletions ckan/plugins/interfaces.py
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@
'IConfigurable', 'IConfigurer', 'IAuthorizer',
'IActions', 'IResourceUrlChange', 'IDatasetForm',
'IGroupForm',
'ITagController',
]

from inspect import isclass
Expand Down Expand Up @@ -181,6 +182,21 @@ class IResourceUrlChange(Interface):
def notify(self, resource):
pass

class ITagController(Interface):
'''
Hook into the Tag controller. These will usually be called just before
committing or returning the respective object, i.e. all validation,
synchronization and authorization setup are complete.
'''
def before_view(self, tag_dict):
'''
Extensions will recieve this before the tag gets displayed. The
dictionary passed will be the one that gets sent to the template.
'''
return tag_dict

class IGroupController(Interface):
"""
Hook into the Group controller. These will
Expand Down
8 changes: 0 additions & 8 deletions ckan/templates/_util.html
Original file line number Diff line number Diff line change
Expand Up @@ -33,14 +33,6 @@
</py:for>
</ul>

<!--! List of tags: pass in a list of tag name and this renders the standard
tag listing -->
<ul py:def="tag_list_from_name(tags)" class="tags clearfix">
<li py:for="tag in tags">
${h.link_to(tag, h.url_for(controller='tag', action='read', id=tag))}
</li>
</ul>

<!--! List of users: pass in a collection of users and this renders the standard
user listing -->
<ul py:def="user_list(users)" class="users">
Expand Down
2 changes: 1 addition & 1 deletion ckan/templates/tag/index.html
Original file line number Diff line number Diff line change
Expand Up @@ -27,7 +27,7 @@ <h2>Tags</h2>
</p>

${c.page.pager(q=c.q)}
${tag_list_from_name(c.page.items)}
${tag_list(c.page.items)}
${c.page.pager(q=c.q)}

<p py:if="c.q">
Expand Down
5 changes: 3 additions & 2 deletions ckan/tests/lib/test_dictization.py
Original file line number Diff line number Diff line change
Expand Up @@ -926,8 +926,9 @@ def test_16_group_dictized(self):
result = self.remove_changable_columns(group_dictized)
result['packages'] = sorted(result['packages'], key=lambda x: x['name'])

assert result == expected, pformat(result)

assert_equal(sorted(result.keys()), sorted(expected.keys()))
for key in result:
assert_equal(sorted(result[key]), sorted(expected[key]))

def test_17_group_apis_to_dict(self):

Expand Down
9 changes: 8 additions & 1 deletion ckanext/multilingual/plugin.py
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
import sets
import ckan
from ckan.plugins import SingletonPlugin, implements, IPackageController
from ckan.plugins import IGroupController
from ckan.plugins import IGroupController, ITagController
import pylons
from pylons import config

Expand Down Expand Up @@ -162,3 +162,10 @@ class MultilingualGroup(SingletonPlugin):

def before_view(self, data_dict):
return translate_data_dict(data_dict)

class MultilingualTag(SingletonPlugin):
implements(ITagController, inherit=True)

def before_view(self, data_dict):
translated_data_dict = translate_data_dict(data_dict)
return translated_data_dict
26 changes: 26 additions & 0 deletions ckanext/multilingual/tests/test_multilingual_plugin.py
Original file line number Diff line number Diff line change
Expand Up @@ -173,3 +173,29 @@ def test_group_list_translation(self):
response.mustcontain(term)
nose.tools.assert_raises(IndexError, response.mustcontain,
'this should not be rendered')

def test_tag_list_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/tag' % lang_code
response = self.app.get(offset, status=200)
terms = (
"123",
"456",
'789',
"russian",
"tolstoy",
)
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)
nose.tools.assert_raises(IndexError, response.mustcontain,
'this should not be rendered')
1 change: 1 addition & 0 deletions setup.py
Original file line number Diff line number Diff line change
Expand Up @@ -94,6 +94,7 @@
publisher_dataset_form=ckanext.publisher_form.forms:PublisherDatasetForm
multilingual_dataset=ckanext.multilingual.plugin:MultilingualDataset
multilingual_group=ckanext.multilingual.plugin:MultilingualGroup
multilingual_tag=ckanext.multilingual.plugin:MultilingualTag
test_tag_vocab_plugin=ckanext.test_tag_vocab_plugin:MockVocabTagsPlugin
[ckan.system_plugins]
Expand Down

0 comments on commit 73a2b88

Please sign in to comment.