Install via pip:
pip install ckanext-duo
Enable the plugins (select based on what you need to translate):
ckan.plugins = duo duo_dataset duo_organization duo_group
Plugins:
- duo: Base plugin (required)
- duo_dataset: Dataset translation
- duo_organization: Organization translation
- duo_group: Group translation
Required CKAN configuration:
ckan.locale_default = en
ckan.locales_offered = en ar fr de es
Field naming pattern:
Datasets:
- title_ (e.g., title_ar, title_fr)
- notes_ (e.g., notes_ar, notes_fr)
Organizations/Groups:
- title_ (e.g., title_ar, title_fr)
- description_ (e.g., description_ar, description_fr)
Integration with ckanext-scheming:
Add locale-specific fields to your schema:
dataset_fields:
- field_name: title_ar
label: Arabic Name
validators: if_empty_same_as(title)
- field_name: notes_ar
label: Arabic Description
validators: if_empty_same_as(notes)
- field_name: title_fr
label: French Name
validators: if_empty_same_as(title)
The if_empty_same_as validator ensures fallback to default language field when translation is empty.
Custom fields via IDatasetForm/IGroupForm/IOrganizationForm:
If not using scheming, define custom fields programmatically:
from ckan.plugins import IDatasetForm
class MyPlugin(p.SingletonPlugin, DefaultDatasetForm):
p.implements(IDatasetForm)
def _modify_package_schema(self, schema):
schema.update({
'title_ar': [validators],
'notes_ar': [validators],
})
return schema
Fallback to extras:
If schema modification not possible, add fields via CKAN extras (key/value pairs at bottom of forms).
Workflow:
1. Configure locales in CKAN config
2. Add locale-specific fields to schemas
3. Users fill translations in dataset/org/group forms
4. Extension displays appropriate translation based on user’s locale
5. Falls back to default language if translation missing
Dependencies:
- blinker (for signal handling)
Requirements:
- CKAN >= 2.9
- Python >= 3.7
- ckan.locale_default configured (non-empty)
- ckan.locales_offered configured (non-empty)