diff --git a/ckanext/metadata/controllers/metadata_record.py b/ckanext/metadata/controllers/metadata_record.py new file mode 100644 index 0000000..72a16a5 --- /dev/null +++ b/ckanext/metadata/controllers/metadata_record.py @@ -0,0 +1,262 @@ +# encoding: utf-8 + +import ckan.plugins.toolkit as tk +import ckan.model as model +import ckan.lib.helpers as helpers +import ckan.authz as authz +from ckan.logic import clean_dict, tuplize_dict, parse_params +import ckan.lib.navl.dictization_functions as dict_fns + + +class MetadataRecordController(tk.BaseController): + + # Note: URLs must be constructed using metadata_record.id rather than metadata_record.name, + # because name can be mapped from a metadata JSON element which we cannot rely on to be + # URL safe; e.g. if name gets the DOI it will contain a '/'. + + @staticmethod + def _set_containers_on_context(organization_id, metadata_collection_id): + context = {'model': model, 'session': model.Session, 'user': tk.c.user} + + if organization_id and not tk.c.organization: + data_dict = {'id': organization_id} + try: + tk.c.organization = tk.get_action('organization_show')(context, data_dict) + except tk.ObjectNotFound: + tk.abort(404, tk._('Organization not found')) + except tk.NotAuthorized: + tk.abort(403, tk._('Not authorized to see this page')) + + if metadata_collection_id and not tk.c.metadata_collection: + data_dict = {'id': metadata_collection_id} + try: + tk.c.metadata_collection = tk.get_action('metadata_collection_show')(context, data_dict) + except tk.ObjectNotFound: + tk.abort(404, tk._('Metadata collection not found')) + except tk.NotAuthorized: + tk.abort(403, tk._('Not authorized to see this page')) + + if not organization_id: + tk.abort(400, tk._('Organization not specified')) + org = tk.c.organization + if tk.c.metadata_collection['organization_id'] not in (org['id'], org['name']): + tk.abort(400, tk._('Metadata collection does not belong to the specified organization')) + + def index(self, organization_id=None, metadata_collection_id=None): + self._set_containers_on_context(organization_id, metadata_collection_id) + + page = tk.h.get_page_number(tk.request.params) or 1 + items_per_page = 21 + + context = {'model': model, 'session': model.Session, + 'user': tk.c.user, 'for_view': True} + + q = tk.c.q = tk.request.params.get('q', '') + sort_by = tk.c.sort_by_selected = tk.request.params.get('sort') + try: + tk.check_access('site_read', context) + tk.check_access('metadata_record_list', context) + except tk.NotAuthorized: + tk.abort(403, tk._('Not authorized to see this page')) + + if tk.c.userobj: + context['user_id'] = tk.c.userobj.id + context['user_is_admin'] = tk.c.userobj.sysadmin + + try: + data_dict_global_results = { + 'owner_org': organization_id, + 'metadata_collection_id': metadata_collection_id, + 'all_fields': False, + 'q': q, + 'sort': sort_by, + 'type': 'metadata_record', + } + global_results = tk.get_action('metadata_record_list')(context, data_dict_global_results) + except tk.ValidationError as e: + if e.error_dict and e.error_dict.get('message'): + msg = e.error_dict['message'] + else: + msg = str(e) + tk.h.flash_error(msg) + tk.c.page = helpers.Page([], 0) + return tk.render('metadata_record/index.html') + + data_dict_page_results = { + 'owner_org': organization_id, + 'metadata_collection_id': metadata_collection_id, + 'all_fields': True, + 'q': q, + 'sort': sort_by, + 'limit': items_per_page, + 'offset': items_per_page * (page - 1), + } + page_results = tk.get_action('metadata_record_list')(context, data_dict_page_results) + + tk.c.page = helpers.Page( + collection=global_results, + page=page, + url=tk.h.pager_url, + items_per_page=items_per_page, + ) + + tk.c.page.items = page_results + return tk.render('metadata_record/index.html') + + def new(self, data=None, errors=None, error_summary=None, organization_id=None, metadata_collection_id=None): + self._set_containers_on_context(organization_id, metadata_collection_id) + + context = {'model': model, 'session': model.Session, 'user': tk.c.user, + 'save': 'save' in tk.request.params} + try: + tk.check_access('metadata_record_create', context) + except tk.NotAuthorized: + tk.abort(403, tk._('Unauthorized to create a metadata record')) + + if context['save'] and not data and tk.request.method == 'POST': + return self._save_new(context) + + data = data or {} + errors = errors or {} + error_summary = error_summary or {} + vars = {'data': data, 'errors': errors, 'error_summary': error_summary, 'action': 'new', + 'metadata_standard_lookup_list': self._metadata_standard_lookup_list(), + 'infrastructure_lookup_list': self._infrastructure_lookup_list()} + + tk.c.is_sysadmin = authz.is_sysadmin(tk.c.user) + tk.c.form = tk.render('metadata_record/edit_form.html', extra_vars=vars) + return tk.render('metadata_record/new.html') + + def edit(self, id, data=None, errors=None, error_summary=None, organization_id=None, metadata_collection_id=None): + self._set_containers_on_context(organization_id, metadata_collection_id) + + context = {'model': model, 'session': model.Session, 'user': tk.c.user, + 'save': 'save' in tk.request.params, 'for_edit': True} + data_dict = {'id': id} + + if context['save'] and not data and tk.request.method == 'POST': + return self._save_edit(id, context) + + try: + old_data = tk.get_action('metadata_record_show')(context, data_dict) + data = data or old_data + except (tk.ObjectNotFound, tk.NotAuthorized): + tk.abort(404, tk._('Metadata record not found')) + + tk.c.metadata_record = old_data + try: + tk.check_access('metadata_record_update', context) + except tk.NotAuthorized: + tk.abort(403, tk._('User %r not authorized to edit %s') % (tk.c.user, id)) + + errors = errors or {} + vars = {'data': data, 'errors': errors, 'error_summary': error_summary, 'action': 'edit', + 'metadata_standard_lookup_list': self._metadata_standard_lookup_list(), + 'infrastructure_lookup_list': self._infrastructure_lookup_list(), + 'selected_infrastructure_ids': [i['id'] for i in data['infrastructures']]} + + tk.c.form = tk.render('metadata_record/edit_form.html', extra_vars=vars) + return tk.render('metadata_record/edit.html') + + def delete(self, id, organization_id=None, metadata_collection_id=None): + if 'cancel' in tk.request.params: + tk.h.redirect_to('metadata_record_edit', id=id, organization_id=organization_id, metadata_collection_id=metadata_collection_id) + + context = {'model': model, 'session': model.Session, 'user': tk.c.user} + try: + tk.check_access('metadata_record_delete', context, {'id': id}) + except tk.NotAuthorized: + tk.abort(403, tk._('Unauthorized to delete metadata record')) + + try: + if tk.request.method == 'POST': + tk.get_action('metadata_record_delete')(context, {'id': id}) + tk.h.flash_notice(tk._('Metadata Record has been deleted.')) + tk.h.redirect_to('metadata_record_index', organization_id=organization_id, metadata_collection_id=metadata_collection_id) + tk.c.metadata_record = tk.get_action('metadata_record_show')(context, {'id': id}) + except tk.NotAuthorized: + tk.abort(403, tk._('Unauthorized to delete metadata record')) + except tk.ObjectNotFound: + tk.abort(404, tk._('Metadata_record not found')) + return tk.render('metadata_record/confirm_delete.html') + + def read(self, id, organization_id=None, metadata_collection_id=None): + self._set_containers_on_context(organization_id, metadata_collection_id) + context = {'model': model, 'session': model.Session, 'user': tk.c.user, 'for_view': True} + tk.c.metadata_record = tk.get_action('metadata_record_show')(context, {'id': id}) + return tk.render('metadata_record/read.html') + + def activity(self, id, organization_id=None, metadata_collection_id=None): + self._set_containers_on_context(organization_id, metadata_collection_id) + context = {'model': model, 'session': model.Session, 'user': tk.c.user, 'for_view': True} + tk.c.metadata_record = tk.get_action('metadata_record_show')(context, {'id': id}) + return tk.render('metadata_record/activity_stream.html') + + @staticmethod + def _metadata_standard_lookup_list(): + """ + Return a list of {'value': name, 'text': display_name} dicts for populating the + metadata standard select control. + """ + context = {'model': model, 'session': model.Session, 'user': tk.c.user} + metadata_standards = tk.get_action('metadata_standard_list')(context, {'all_fields': True}) + return [{'value': '', 'text': tk._('(None)')}] + \ + [{'value': metadata_standard['name'], 'text': metadata_standard['display_name']} + for metadata_standard in metadata_standards] + + @staticmethod + def _infrastructure_lookup_list(): + """ + Return a list of {'value': name, 'text': display_name} dicts for populating the + infrastructure select control. + """ + context = {'model': model, 'session': model.Session, 'user': tk.c.user} + infrastructures = tk.get_action('infrastructure_list')(context, {'all_fields': True}) + return [{'value': infrastructure['name'], 'text': infrastructure['display_name']} + for infrastructure in infrastructures] + + def _save_new(self, context): + try: + data_dict = clean_dict(dict_fns.unflatten(tuplize_dict(parse_params(tk.request.params)))) + data_dict['infrastructures'] = self._parse_infrastructure_ids(data_dict.get('infrastructure_ids')) + context['message'] = data_dict.get('log_message', '') + metadata_record = tk.get_action('metadata_record_create')(context, data_dict) + tk.h.redirect_to('metadata_record_read', id=metadata_record['id'], + organization_id=tk.c.organization['name'], + metadata_collection_id=tk.c.metadata_collection['name']) + except (tk.ObjectNotFound, tk.NotAuthorized): + tk.abort(404, tk._('Metadata record not found')) + except dict_fns.DataError: + tk.abort(400, tk._(u'Integrity Error')) + except tk.ValidationError, e: + errors = e.error_dict + error_summary = e.error_summary + return self.new(data_dict, errors, error_summary) + + def _save_edit(self, id, context): + try: + data_dict = clean_dict(dict_fns.unflatten(tuplize_dict(parse_params(tk.request.params)))) + data_dict['id'] = id + data_dict['infrastructures'] = self._parse_infrastructure_ids(data_dict.get('infrastructure_ids')) + context['message'] = data_dict.get('log_message', '') + context['allow_partial_update'] = True + metadata_record = tk.get_action('metadata_record_update')(context, data_dict) + tk.h.redirect_to('metadata_record_read', id=metadata_record['id'], + organization_id=tk.c.organization['name'], + metadata_collection_id=tk.c.metadata_collection['name']) + except (tk.ObjectNotFound, tk.NotAuthorized), e: + tk.abort(404, tk._('Metadata record not found')) + except dict_fns.DataError: + tk.abort(400, tk._(u'Integrity Error')) + except tk.ValidationError, e: + errors = e.error_dict + error_summary = e.error_summary + return self.edit(id, data_dict, errors, error_summary) + + @staticmethod + def _parse_infrastructure_ids(infrastructure_ids): + if not infrastructure_ids: + return [] + if isinstance(infrastructure_ids, basestring): + return [{'id': infrastructure_ids}] + return [{'id': infrastructure_id} for infrastructure_id in infrastructure_ids] diff --git a/ckanext/metadata/lib/dictization/model_dictize.py b/ckanext/metadata/lib/dictization/model_dictize.py index c3d41ca..2e6c12b 100644 --- a/ckanext/metadata/lib/dictization/model_dictize.py +++ b/ckanext/metadata/lib/dictization/model_dictize.py @@ -29,10 +29,11 @@ def metadata_record_dictize(pkg, context): result = execute(q, package_rev, context).first() if not result: raise tk.ObjectNotFound + result_dict = d.table_dictize(result, context) - # strip whitespace from title if result_dict.get('title'): result_dict['title'] = result_dict['title'].strip() + result_dict['display_name'] = result_dict['title'] or result_dict['name'] or result_dict['id'] # extras if is_latest_revision: diff --git a/ckanext/metadata/logic/schema.py b/ckanext/metadata/logic/schema.py index 8a93c73..c4964b1 100644 --- a/ckanext/metadata/logic/schema.py +++ b/ckanext/metadata/logic/schema.py @@ -158,6 +158,7 @@ def metadata_record_show_schema(deserialize_json=False): 'workflow_state_id': [convert_from_extras, default(None), v.convert_id_to_name('workflow_state')], 'private': [], 'extras': _extras_schema(), + 'display_name': [], }) return schema diff --git a/ckanext/metadata/plugin.py b/ckanext/metadata/plugin.py index 1ed6591..e54dacd 100644 --- a/ckanext/metadata/plugin.py +++ b/ckanext/metadata/plugin.py @@ -76,6 +76,14 @@ def before_map(self, map): controller = 'ckanext.metadata.controllers.organization:OrganizationController' map.connect('organization_datasets', '/organization/datasets/{id}', controller=controller, action='datasets', ckan_icon='site-map') + controller = 'ckanext.metadata.controllers.metadata_record:MetadataRecordController' + map.connect('metadata_record_index', '/organization/{organization_id}/metadata_collection/{metadata_collection_id}/metadata_record', controller=controller, action='index') + map.connect('metadata_record_new', '/organization/{organization_id}/metadata_collection/{metadata_collection_id}/metadata_record/new', controller=controller, action='new') + map.connect('metadata_record_edit', '/organization/{organization_id}/metadata_collection/{metadata_collection_id}/metadata_record/edit/{id}', controller=controller, action='edit', ckan_icon='pencil-square-o') + map.connect('metadata_record_delete', '/organization/{organization_id}/metadata_collection/{metadata_collection_id}/metadata_record/delete/{id}', controller=controller, action='delete') + map.connect('metadata_record_read', '/organization/{organization_id}/metadata_collection/{metadata_collection_id}/metadata_record/{id}', controller=controller, action='read', ckan_icon='file-text-o') + map.connect('metadata_record_activity', '/organization/{organization_id}/metadata_collection/{metadata_collection_id}/metadata_record/activity/{id}', controller=controller, action='activity', ckan_icon='clock-o') + controller = 'ckanext.metadata.controllers.metadata_standard:MetadataStandardController' map.connect('metadata_standard_index', '/metadata_standard', controller=controller, action='index') map.connect('metadata_standard_new', '/metadata_standard/new', controller=controller, action='new') diff --git a/ckanext/metadata/public/images/credits.txt b/ckanext/metadata/public/images/credits.txt index 708a027..8857bf4 100644 --- a/ckanext/metadata/public/images/credits.txt +++ b/ckanext/metadata/public/images/credits.txt @@ -1,3 +1,4 @@ metadata_schema: https://json-schema.org/assets/logo.svg metadata_standard: Icon made by Smashicons from www.flaticon.com (search term: standard) +metadata_record: adapted from https://json-schema.org/assets/logo.svg workflow_state: Icon made by Freepik from www.flaticon.com (search term: to do list) diff --git a/ckanext/metadata/public/images/metadata_record.png b/ckanext/metadata/public/images/metadata_record.png new file mode 100644 index 0000000..02c9798 Binary files /dev/null and b/ckanext/metadata/public/images/metadata_record.png differ diff --git a/ckanext/metadata/templates/metadata_record/activity_stream.html b/ckanext/metadata/templates/metadata_record/activity_stream.html new file mode 100644 index 0000000..45097a6 --- /dev/null +++ b/ckanext/metadata/templates/metadata_record/activity_stream.html @@ -0,0 +1,10 @@ +{% extends "metadata_record/read_base.html" %} + +{% block subtitle %}{{ _('Activity Stream') }} - {{ super() }}{% endblock %} + +{% block primary_content_inner %} +

{% block page_heading %}{{ _('Activity Stream') }}{% endblock %}

+ {% block activity_stream %} + {{ c.metadata_record_activity_stream | safe }} + {% endblock %} +{% endblock %} diff --git a/ckanext/metadata/templates/metadata_record/edit.html b/ckanext/metadata/templates/metadata_record/edit.html new file mode 100644 index 0000000..f71e157 --- /dev/null +++ b/ckanext/metadata/templates/metadata_record/edit.html @@ -0,0 +1,7 @@ +{% extends "metadata_record/edit_base.html" %} + +{% block page_heading_class %}hide-heading{% endblock %} +{% block page_heading %}{{ _('Edit Metadata Record') }}{% endblock %} +{% block subtitle %} + {{ _('Manage') }} - {{ c.metadata_record.display_name }} - {{ _('Metadata Records') }} +{% endblock %} diff --git a/ckanext/metadata/templates/metadata_record/edit_base.html b/ckanext/metadata/templates/metadata_record/edit_base.html new file mode 100644 index 0000000..323303e --- /dev/null +++ b/ckanext/metadata/templates/metadata_record/edit_base.html @@ -0,0 +1,29 @@ +{% extends "page.html" %} + +{% block breadcrumb_content %} + {% snippet "metadata_record/snippets/breadcrumb_content_outer.html" %} + {% snippet "metadata_record/snippets/breadcrumb_content_item.html" %} + {% snippet "metadata_record/snippets/breadcrumb_content_manage.html" %} +{% endblock %} + +{% block page_primary_action %}{% endblock %} + +{% block primary_content_inner %} +

{% block page_heading %}{{ _('Metadata Record Form') }}{% endblock %}

+ {% block form %} + {{ c.form | safe }} + {% endblock %} +{% endblock %} + +{% block content_action %} + {% link_for _('View'), controller='ckanext.metadata.controllers.metadata_record:MetadataRecordController', + action='read', id=c.metadata_record.id, organization_id=c.organization.name, metadata_collection_id=c.metadata_collection.name, class_='btn', icon='eye' %} +{% endblock %} + +{% block content_primary_nav %} + {{ h.build_nav_icon('metadata_record_edit', _('Edit'), id=c.metadata_record.id, organization_id=c.organization.name, metadata_collection_id=c.metadata_collection.name) }} +{% endblock %} + +{% block secondary_content %} + {% snippet "metadata_record/snippets/info.html", metadata_record=c.metadata_record %} +{% endblock %} diff --git a/ckanext/metadata/templates/metadata_record/edit_form.html b/ckanext/metadata/templates/metadata_record/edit_form.html new file mode 100644 index 0000000..5dcd378 --- /dev/null +++ b/ckanext/metadata/templates/metadata_record/edit_form.html @@ -0,0 +1,42 @@ +{% import "macros/form.html" as form %} + +
+ {{ form.errors(error_summary) }} + + {{ form.hidden('owner_org', c.organization.name) }} + {{ form.hidden('metadata_collection_id', c.metadata_collection.name) }} + + {{ form.select('metadata_standard_id', label=_('Metadata Standard'), id='field-metadata-standard', + options=metadata_standard_lookup_list, selected=data.metadata_standard_id, error=errors.metadata_standard_id, + classes=['control-medium'], is_required=true) }} + + {{ form.textarea('metadata_json', label=_('Metadata JSON'), id='field-metadata-json', + placeholder=_('The JSON metadata dictionary.'), + value=data.metadata_json, error=errors.metadata_json, is_required=true, + attrs={'style': 'font-family: monospace'}, rows=12) }} + + {% call form.multiselect('infrastructure_ids', label=_('Infrastructures'), id='field-infrastructures', + options=infrastructure_lookup_list, selected=selected_infrastructure_ids, error=errors.infrastructures, + classes=['control-medium']) %} + {{ form.info(_('Select the infrastructure(s) with which to associate the metadata record. Use Ctrl+Click to select / deselect individual items.')) }} + {% endcall %} + + {{ form.required_message() }} + +
+ {% if action == "edit" %} + {% if h.check_access('metadata_record_delete', {'id': data.id}) %} + + {% block delete_button_text %}{{ _('Delete') }}{% endblock %} + {% endif %} + {% endif %} + +
+
diff --git a/ckanext/metadata/templates/metadata_record/index.html b/ckanext/metadata/templates/metadata_record/index.html new file mode 100644 index 0000000..925c014 --- /dev/null +++ b/ckanext/metadata/templates/metadata_record/index.html @@ -0,0 +1,49 @@ +{% extends "page.html" %} + +{% block subtitle %}{{ _('Metadata Records') }}{% endblock %} + +{% block breadcrumb_content %} + {% snippet "metadata_record/snippets/breadcrumb_content_outer.html" %} +{% endblock %} + +{% block page_header %}{% endblock %} + +{% block page_primary_action %} + {% if h.check_access('metadata_record_create') %} + {% link_for _('Add Metadata Record'), action='new', class_='btn btn-primary', icon='plus-square', + organization_id=c.organization.name, metadata_collection_id=c.metadata_collection.name, + controller='ckanext.metadata.controllers.metadata_record:MetadataRecordController' %} + {% endif %} +{% endblock %} + +{% block primary_content_inner %} +

{{ _('Metadata Record') }}

+ {% block metadata_records_search_form %} + {% snippet 'snippets/search_form.html', form_id='metadata-record-search-form', type='metadata_record', + query=c.q, sorting_selected=c.sort_by_selected, count=c.page.item_count, + placeholder=_('Search metadata records...'), show_empty=request.params, no_bottom_border=true if c.page.items, + sorting = [(_('Name Ascending'), 'display_name asc'), (_('Name Descending'), 'display_name desc')] %} + {% endblock %} + {% block metadata_records_list %} + {% if c.page.items or request.params %} + {% if c.page.items %} + {% snippet "metadata_record/snippets/metadata_record_list.html", metadata_records=c.page.items %} + {% endif %} + {% else %} +

+ {{ _('There are currently no metadata records for this site') }}. + {% if h.check_access('metadata_record_create') %} + {% link_for _('How about creating one?'), action='new', organization_id=c.organization.name, metadata_collection_id=c.metadata_collection.name, + controller='ckanext.metadata.controllers.metadata_record:MetadataRecordController' %}. + {% endif %} +

+ {% endif %} + {% endblock %} + {% block page_pagination %} + {{ c.page.pager(q=c.q or '', sort=c.sort_by_selected or '') }} + {% endblock %} +{% endblock %} + +{% block secondary_content %} + {% snippet "metadata_record/snippets/helper.html" %} +{% endblock %} diff --git a/ckanext/metadata/templates/metadata_record/new.html b/ckanext/metadata/templates/metadata_record/new.html new file mode 100644 index 0000000..384ed08 --- /dev/null +++ b/ckanext/metadata/templates/metadata_record/new.html @@ -0,0 +1,19 @@ +{% extends "metadata_record/edit_base.html" %} + +{% block page_heading %}{{ _('Create a Metadata Record') }}{% endblock %} +{% block page_header %}{% endblock %} +{% block subtitle %}{{ _('Create a Metadata Record') }}{% endblock %} + +{% block breadcrumb_content %} + {% snippet "metadata_record/snippets/breadcrumb_content_outer.html" %} +
  • + {% block breadcrumb_link %} + {{ h.nav_link(_('Create a Metadata Record'), action='new', organization_id=c.organization.name, metadata_collection_id=c.metadata_collection.name, + controller='ckanext.metadata.controllers.metadata_record:MetadataRecordController') }} + {% endblock %} +
  • +{% endblock %} + +{% block secondary_content %} + {% snippet "metadata_record/snippets/helper.html" %} +{% endblock %} diff --git a/ckanext/metadata/templates/metadata_record/read.html b/ckanext/metadata/templates/metadata_record/read.html new file mode 100644 index 0000000..3db0552 --- /dev/null +++ b/ckanext/metadata/templates/metadata_record/read.html @@ -0,0 +1,7 @@ +{% extends "metadata_record/read_base.html" %} + +{% block primary_content_inner %} + +{% endblock %} diff --git a/ckanext/metadata/templates/metadata_record/read_base.html b/ckanext/metadata/templates/metadata_record/read_base.html new file mode 100644 index 0000000..087d476 --- /dev/null +++ b/ckanext/metadata/templates/metadata_record/read_base.html @@ -0,0 +1,24 @@ +{% extends "page.html" %} + +{% block subtitle %}{{ c.metadata_record.display_name }} - {{ _('Metadata Records') }}{% endblock %} + +{% block breadcrumb_content %} + {% snippet "metadata_record/snippets/breadcrumb_content_outer.html" %} + {% snippet "metadata_record/snippets/breadcrumb_content_item.html" %} +{% endblock %} + +{% block content_action %} + {% if h.check_access('metadata_record_update', {'id': c.metadata_record.id}) %} + {% link_for _('Manage'), controller='ckanext.metadata.controllers.metadata_record:MetadataRecordController', + action='edit', id=c.metadata_record.id, organization_id=c.organization.name, metadata_collection_id=c.metadata_collection.name, class_='btn', icon='wrench' %} + {% endif %} +{% endblock %} + +{% block content_primary_nav %} + {{ h.build_nav_icon('metadata_record_read', _('Metadata Dictionary'), id=c.metadata_record.id, organization_id=c.organization.name, metadata_collection_id=c.metadata_collection.name) }} + {{ h.build_nav_icon('metadata_record_activity', _('Activity Stream'), id=c.metadata_record.id, organization_id=c.organization.name, metadata_collection_id=c.metadata_collection.name, offset=0) }} +{% endblock %} + +{% block secondary_content %} + {% snippet "metadata_record/snippets/info.html", metadata_record=c.metadata_record %} +{% endblock %} diff --git a/ckanext/metadata/templates/metadata_record/snippets/breadcrumb_content_item.html b/ckanext/metadata/templates/metadata_record/snippets/breadcrumb_content_item.html new file mode 100644 index 0000000..596d7aa --- /dev/null +++ b/ckanext/metadata/templates/metadata_record/snippets/breadcrumb_content_item.html @@ -0,0 +1,5 @@ +
  • + {% link_for c.metadata_record.display_name |truncate(35), action='read', + id=c.metadata_record.id, organization_id=c.organization.name, metadata_collection_id=c.metadata_collection.name, + controller='ckanext.metadata.controllers.metadata_record:MetadataRecordController' %} +
  • diff --git a/ckanext/metadata/templates/metadata_record/snippets/breadcrumb_content_manage.html b/ckanext/metadata/templates/metadata_record/snippets/breadcrumb_content_manage.html new file mode 100644 index 0000000..11bb939 --- /dev/null +++ b/ckanext/metadata/templates/metadata_record/snippets/breadcrumb_content_manage.html @@ -0,0 +1,4 @@ +
  • + {% link_for _('Manage'), controller='ckanext.metadata.controllers.metadata_record:MetadataRecordController', + action='edit', id=c.metadata_record.id, organization_id=c.organization.name, metadata_collection_id=c.metadata_collection.name %} +
  • diff --git a/ckanext/metadata/templates/metadata_record/snippets/breadcrumb_content_outer.html b/ckanext/metadata/templates/metadata_record/snippets/breadcrumb_content_outer.html new file mode 100644 index 0000000..e75617c --- /dev/null +++ b/ckanext/metadata/templates/metadata_record/snippets/breadcrumb_content_outer.html @@ -0,0 +1,20 @@ +
  • + {% link_for _('Organizations'), controller='organization', action='index' %} +
  • +
  • + {% link_for c.organization.display_name|truncate(35), controller='ckanext.metadata.controllers.organization:OrganizationController', + action='read', id=c.organization.name %} +
  • +
  • + {% link_for _('Metadata Collections'), controller='ckanext.metadata.controllers.metadata_collection:MetadataCollectionController', + action='index', organization_id=c.organization.name %} +
  • +
  • + {% link_for c.metadata_collection.display_name |truncate(35), action='read', + id=c.metadata_collection.name, organization_id=c.organization.name, + controller='ckanext.metadata.controllers.metadata_collection:MetadataCollectionController' %} +
  • +
  • + {% link_for _('Metadata Records'), controller='ckanext.metadata.controllers.metadata_record:MetadataRecordController', + action='index', organization_id=c.organization.name, metadata_collection_id=c.metadata_collection.name %} +
  • diff --git a/ckanext/metadata/templates/metadata_record/snippets/helper.html b/ckanext/metadata/templates/metadata_record/snippets/helper.html new file mode 100644 index 0000000..95a65e7 --- /dev/null +++ b/ckanext/metadata/templates/metadata_record/snippets/helper.html @@ -0,0 +1,15 @@ +
    +

    + + {{ _('What are Metadata Records?') }} +

    +
    +

    + {% trans %} + A metadata record is a specialized type of CKAN dataset encapsulating a + JSON metadata dictionary that describes a digital object. The metadata + dictionary may be validated against one or more metadata schemas. + {% endtrans %} +

    +
    +
    \ No newline at end of file diff --git a/ckanext/metadata/templates/metadata_record/snippets/info.html b/ckanext/metadata/templates/metadata_record/snippets/info.html new file mode 100644 index 0000000..cfa67a7 --- /dev/null +++ b/ckanext/metadata/templates/metadata_record/snippets/info.html @@ -0,0 +1,30 @@ +{% block info %} +
    +
    + {% block inner %} + {% block image %} +
    + + {{ metadata_record.name }} + +
    + {% endblock %} + {% block heading %} +

    + {{ metadata_record.display_name }} + {% if metadata_record.state == 'deleted' %} + [{{ _('Deleted') }}] + {% endif %} +

    + {% endblock %} + {% block description %} + {% if h.get_translated(metadata_record, 'description') %} +

    + {{ h.markdown_extract(h.get_translated(metadata_record, 'description'), 180) }} +

    + {% endif %} + {% endblock %} + {% endblock %} +
    +
    +{% endblock %} diff --git a/ckanext/metadata/templates/metadata_record/snippets/metadata_record_item.html b/ckanext/metadata/templates/metadata_record/snippets/metadata_record_item.html new file mode 100644 index 0000000..00ff588 --- /dev/null +++ b/ckanext/metadata/templates/metadata_record/snippets/metadata_record_item.html @@ -0,0 +1,40 @@ +{# +Renders a media item for a metadata_record. This should be used in a list. + +metadata_record - A metadata_record dict. + +Example: + + +#} +{% set url = h.url_for('metadata_record_read', action='read', id=metadata_record.id, + organization_id=c.organization.name, metadata_collection_id=c.metadata_collection.name) %} +{% block item %} +
  • + {% block item_inner %} + {% block image %} + {{ metadata_record.name }} + {% endblock %} + {% block title %} +

    {{ metadata_record.display_name }}

    + {% endblock %} + {% block description %} + {% if h.get_translated(metadata_record, 'description') %} +

    {{ h.markdown_extract(h.get_translated(metadata_record, 'description'), extract_length=80) }}

    + {% endif %} + {% endblock %} + {% block link %} + + {{ _('View {name}').format(name=metadata_record.display_name) }} + + {% endblock %} + {% endblock %} +
  • +{% endblock %} +{% if position is divisibleby 3 %} +
  • +{% endif %} diff --git a/ckanext/metadata/templates/metadata_record/snippets/metadata_record_list.html b/ckanext/metadata/templates/metadata_record/snippets/metadata_record_list.html new file mode 100644 index 0000000..07a9064 --- /dev/null +++ b/ckanext/metadata/templates/metadata_record/snippets/metadata_record_list.html @@ -0,0 +1,19 @@ +{# +Display a grid of metadata_record items. + +metadata_records - A list of metadata_records. + +Example: + + {% snippet "metadata_record/snippets/metadata_record_list.html" %} + +#} +{% block metadata_record_list %} + +{% endblock %} diff --git a/ckanext/metadata/templates/snippets/search_result_text.html b/ckanext/metadata/templates/snippets/search_result_text.html index ae2fb72..d275098 100644 --- a/ckanext/metadata/templates/snippets/search_result_text.html +++ b/ckanext/metadata/templates/snippets/search_result_text.html @@ -5,7 +5,7 @@ query - The text that was searched for count - The number of results for the search type - Search result type (dataset, group, organization, infrastructure, metadata_collection, - metadata_standard, metadata_schema, workflow_state) + metadata_record, metadata_standard, metadata_schema, workflow_state) Example: @@ -42,6 +42,12 @@ {% set text_no_query = ungettext('{number} metadata collection found', '{number} metadata collections found', count) %} {% set text_no_query_none = _('No metadata collections found') %} +{% elif type == 'metadata_record' %} + {% set text_query = ungettext('{number} metadata record found for "{query}"', '{number} metadata records found for "{query}"', count) %} + {% set text_query_none = _('No metadata records found for "{query}"') %} + {% set text_no_query = ungettext('{number} metadata record found', '{number} metadata records found', count) %} + {% set text_no_query_none = _('No metadata records found') %} + {% elif type == 'metadata_standard' %} {% set text_query = ungettext('{number} metadata standard found for "{query}"', '{number} metadata standards found for "{query}"', count) %} {% set text_query_none = _('No metadata standards found for "{query}"') %}