Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
[#2750] Add ckanext/example_idatasetform
- Loading branch information
Sean Hammond
committed
Mar 11, 2013
1 parent
c8d788f
commit 9a56e8e
Showing
8 changed files
with
254 additions
and
0 deletions.
There are no files selected for viewing
Empty file.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,163 @@ | ||
import logging | ||
|
||
import ckan.plugins as plugins | ||
import ckan.plugins.toolkit as tk | ||
import ckan.lib.plugins as lib_plugins | ||
|
||
|
||
class ExampleIDatasetFormPlugin(plugins.SingletonPlugin, | ||
lib_plugins.DefaultDatasetForm): | ||
'''An example IDatasetForm CKAN plugin. | ||
Uses a tag vocabulary to add a custom metadata field to datasets. | ||
''' | ||
plugins.implements(plugins.IConfigurer, inherit=False) | ||
plugins.implements(plugins.IDatasetForm, inherit=False) | ||
|
||
# These record how many times methods that this plugin's methods are | ||
# called, for testing purposes. | ||
num_times_new_template_called = 0 | ||
num_times_read_template_called = 0 | ||
num_times_edit_template_called = 0 | ||
num_times_comments_template_called = 0 | ||
num_times_search_template_called = 0 | ||
num_times_history_template_called = 0 | ||
num_times_package_form_called = 0 | ||
num_times_check_data_dict_called = 0 | ||
|
||
def create_country_codes(self): | ||
'''Create country_codes vocab and tags, if they don't exist already. | ||
Note that you could also create the vocab and tags using CKAN's API, | ||
and once they are created you can edit them (e.g. to add and remove | ||
possible dataset country code values) using the API. | ||
''' | ||
user = tk.get_action('get_site_user')({'ignore_auth': True}, {}) | ||
context = {'user': user['name']} | ||
try: | ||
data = {'id': 'country_codes'} | ||
tk.get_action('vocabulary_show')(context, data) | ||
logging.info("Example genre vocabulary already exists, skipping.") | ||
except tk.ObjectNotFound: | ||
logging.info("Creating vocab 'country_codes'") | ||
data = {'name': 'country_codes'} | ||
vocab = tk.get_action('vocabulary_create')(context, data) | ||
for tag in (u'uk', u'ie', u'de', u'fr', u'es'): | ||
logging.info( | ||
"Adding tag {0} to vocab 'country_codes'".format(tag)) | ||
data = {'name': tag, 'vocabulary_id': vocab['id']} | ||
tk.get_action('tag_create')(context, data) | ||
|
||
def update_config(self, config): | ||
# Add this plugin's templates dir to CKAN's extra_template_paths, so | ||
# that CKAN will use this plugin's custom templates. | ||
tk.add_template_directory(config, 'templates') | ||
|
||
def is_fallback(self): | ||
# Return True to register this plugin as the default handler for | ||
# package types not handled by any other IDatasetForm plugin. | ||
return True | ||
|
||
def package_types(self): | ||
# This plugin doesn't handle any special package types, it just | ||
# registers itself as the default (above). | ||
return [] | ||
|
||
def form_to_db_schema(self): | ||
schema = super(ExampleIDatasetFormPlugin, self).form_to_db_schema() | ||
|
||
# Add our custom country_code metadata field to the schema. | ||
schema.update({ | ||
'country_code': [tk.get_validator('ignore_missing'), | ||
tk.get_converter('convert_to_tags')('country_codes')] | ||
}) | ||
|
||
# Add our custom_test metadata field to the schema, this one will use | ||
# convert_to_extras instead of convert_to_tags. | ||
schema.update({ | ||
'custom_text': [tk.get_validator('ignore_missing'), | ||
tk.get_converter('convert_to_extras')] | ||
}) | ||
|
||
return schema | ||
|
||
def db_to_form_schema(self): | ||
schema = super(ExampleIDatasetFormPlugin, self).db_to_form_schema() | ||
|
||
# Don't show vocab tags mixed in with normal 'free' tags | ||
# (e.g. on dataset pages, or on the search page) | ||
schema['tags']['__extras'].append(tk.get_converter('free_tags_only')) | ||
|
||
# Add our custom country_code metadata field to the schema. | ||
schema.update({ | ||
'country_code': [ | ||
tk.get_converter('convert_from_tags')('country_codes'), | ||
tk.get_validator('ignore_missing')] | ||
}) | ||
|
||
# Add our custom_text field to the dataset schema. | ||
schema.update({ | ||
'custom_text': [tk.get_converter('convert_from_extras'), | ||
tk.get_validator('ignore_missing')] | ||
}) | ||
|
||
return schema | ||
|
||
def setup_template_variables(self, context, data_dict=None): | ||
super(ExampleIDatasetFormPlugin, self).setup_template_variables( | ||
context, data_dict) | ||
|
||
# Create the country_codes vocab and tags, if they don't already exist. | ||
self.create_country_codes() | ||
|
||
# Add the list of available country codes, from the country_codes | ||
# vocab, to the template context. | ||
try: | ||
tk.c.country_codes = tk.get_action('tag_list')( | ||
context, {'vocabulary_id': 'country_codes'}) | ||
except tk.ObjectNotFound: | ||
tk.c.country_codes = None | ||
|
||
# These methods just record how many times they're called, for testing | ||
# purposes. | ||
# TODO: It might be better to test that custom templates returned by | ||
# these methods are actually used, not just that the methods get | ||
# called. | ||
|
||
def new_template(self): | ||
ExampleIDatasetFormPlugin.num_times_new_template_called += 1 | ||
return lib_plugins.DefaultDatasetForm.new_template(self) | ||
|
||
def read_template(self): | ||
ExampleIDatasetFormPlugin.num_times_read_template_called += 1 | ||
return lib_plugins.DefaultDatasetForm.read_template(self) | ||
|
||
def edit_template(self): | ||
ExampleIDatasetFormPlugin.num_times_edit_template_called += 1 | ||
return lib_plugins.DefaultDatasetForm.edit_template(self) | ||
|
||
def comments_template(self): | ||
ExampleIDatasetFormPlugin.num_times_comments_template_called += 1 | ||
return lib_plugins.DefaultDatasetForm.comments_template(self) | ||
|
||
def search_template(self): | ||
ExampleIDatasetFormPlugin.num_times_search_template_called += 1 | ||
return lib_plugins.DefaultDatasetForm.search_template(self) | ||
|
||
def history_template(self): | ||
ExampleIDatasetFormPlugin.num_times_history_template_called += 1 | ||
return lib_plugins.DefaultDatasetForm.history_template(self) | ||
|
||
def package_form(self): | ||
ExampleIDatasetFormPlugin.num_times_package_form_called += 1 | ||
return lib_plugins.DefaultDatasetForm.package_form(self) | ||
|
||
def check_data_dict(self, data_dict, schema=None): | ||
ExampleIDatasetFormPlugin.num_times_check_data_dict_called += 1 | ||
# Disable DefaultDatasetForm's check_data_dict(), because it breaks | ||
# with the new three-stage dataset creation when using | ||
# convert_to_extras. | ||
#return lib_plugins.DefaultDatasetForm.check_data_dict(self, data_dict, | ||
# schema) |
6 changes: 6 additions & 0 deletions
6
ckanext/example_idatasetform/templates/package/new_package_metadata.html
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,6 @@ | ||
{% ckan_extends %} | ||
|
||
<!-- Pass c.country_codes to package_metadata_form.html. | ||
FIXME: If ckan passed c to package_metadata_form.html anyway, we wouldn't need | ||
to override this block here. --> | ||
{% block form %}{{ h.snippet('package/snippets/package_metadata_form.html', data=data, errors=errors, include_metadata=false, pkg_name=pkg_name, country_codes=c.country_codes) }}{% endblock %} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,13 @@ | ||
{% ckan_extends %} | ||
|
||
{% block package_description %} | ||
{{ super() }} | ||
|
||
<!-- Add our custom country_code field to the dataset read page. --> | ||
{% if pkg.get('country_code') %} | ||
<section id="dataset-country_code" class="resources module-content"> | ||
<p><strong>Country Code</strong>: {{ pkg.country_code[0] }}</p> | ||
</section> | ||
{% endif %} | ||
|
||
{% endblock %} |
8 changes: 8 additions & 0 deletions
8
ckanext/example_idatasetform/templates/package/snippets/package_form.html
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,8 @@ | ||
{% ckan_extends %} | ||
|
||
<!-- Pass c.country_codes to package_metadata_fields.html. | ||
FIXME: If ckan passed c to package_metadata_fields.html anyway, we wouldn't | ||
need to override this block here. --> | ||
{% block metadata_fields %} | ||
{% snippet 'package/snippets/package_metadata_fields.html', data=data, errors=errors, country_codes=c.country_codes %} | ||
{% endblock %} |
42 changes: 42 additions & 0 deletions
42
ckanext/example_idatasetform/templates/package/snippets/package_metadata_fields.html
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,42 @@ | ||
{% import 'macros/form.html' as form %} | ||
|
||
{% set groups_available = h.groups_available() %} | ||
{% if groups_available %} | ||
<div class="control-group"> | ||
{% set groups = h.dict_list_reduce(data.groups, 'id') %} | ||
<label for="field-groups" class="control-label">{{ _('Add to Groups') }}</label> | ||
<div class="controls"> | ||
<select id="field-groups" name="groups__{{ groups | count }}__id" data-module="autocomplete"> | ||
<option value="">{{ _('Select a group...') }}</option> | ||
{% for group in groups_available %} | ||
<option value="{{ group.id }}" {% if group.id in groups %}selected="selected"{% endif %}>{{ group.name }}</option> | ||
{% endfor %} | ||
</select> | ||
</div> | ||
</div> | ||
{% endif %} | ||
|
||
{{ form.input('author', label=_('Author'), id='field-author', placeholder=_('Joe Bloggs'), value=data.author, error=errors.author, classes=['control-medium']) }} | ||
|
||
{{ form.input('author_email', label=_('Author Email'), id='field-author-email', placeholder=_('joe@example.com'), value=data.author_email, error=errors.author_email, classes=['control-medium']) }} | ||
|
||
{{ form.input('maintainer', label=_('Maintainer'), id='field-maintainer', placeholder=_('Joe Bloggs'), value=data.maintainer, error=errors.maintainer, classes=['control-medium']) }} | ||
|
||
{{ form.input('maintainer_email', label=_('Maintainer Email'), id='field-maintainer-email', placeholder=_('joe@example.com'), value=data.maintainer_email, error=errors.maintainer_email, classes=['control-medium']) }} | ||
|
||
<label class="control-label" for="field-country_code">{{ _("Country Code") }}</label> | ||
<div class="controls"> | ||
<select id="field-country_code" name="country_code" data-module="autocomplete"> | ||
{% for country_code in country_codes %} | ||
<option value="{{ country_code }}" {% if country_code in data.get('country_code', []) %}selected="selected"{% endif %}>{{ country_code }}</option> | ||
{% endfor %} | ||
</select> | ||
</div> | ||
|
||
{{ form.input('custom_text', label=_('Custom Text'), id='field-custom_text', placeholder=_('custom text'), value=data.custom_text, error=errors.custom_text, classes=['control-medium']) }} | ||
|
||
{# | ||
{% block custom_fields %} | ||
{% snippet 'snippets/custom_form_fields.html', extras=data.extras, errors=errors, limit=3 %} | ||
{% endblock %} | ||
#} |
21 changes: 21 additions & 0 deletions
21
ckanext/example_idatasetform/templates/package/snippets/package_metadata_form.html
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,21 @@ | ||
{% import "macros/form.html" as form %} | ||
|
||
{% set data = data or {} %} | ||
{% set errors = errors or {} %} | ||
|
||
<form class="dataset-form dataset-resource-form form-horizontal" method="post" data-module="basic-form"> | ||
{{ h.snippet('package/snippets/stages.html', stages=['complete', 'complete', 'active'], pkg_name=pkg_name) }} | ||
{{ form.errors(error_summary) }} | ||
|
||
<!-- Pass country_codes to package_metadata_fields.html. | ||
FIXME: If CKAN would pass c to package_metadata_fields.html anyway, we | ||
wouldn't need to override this template here. --> | ||
{% snippet 'package/snippets/package_metadata_fields.html', data=data, errors=errors, groups_available=groups_available, country_codes=country_codes %} | ||
|
||
<div class="form-actions"> | ||
{# TODO: Go back to previous resource form #} | ||
<button class="btn" name="save" value="go-resources" type="submit">{{ _('Previous') }}</button> | ||
<button class="btn btn-primary" name="save" value="finish" type="submit">{{ _('Finish') }}</button> | ||
</div> | ||
|
||
</form> |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters