{% endblock %} @@ -8,6 +12,17 @@
{% block form %} + {# (canada fork only): handle validation errors #} + {# TODO: upstream contrib?? #} + {# (canada fork only): handle all errors in resource actions #} + {# TODO: upstream contrib?? #} + {% block errors %} + {% if resource_validation_errors %} + {{ form.resource_validation_errors(errors=resource_validation_errors, pkg_name=pkg_id, dataset_type=dataset_type, h=h) }} + {% else %} + {{ form.errors(errors=errors) }} + {% endif %} + {% endblock %}

{{ _('Are you sure you want to delete resource - {name}?').format(name=h.resource_display_name(resource_dict)) }}

diff --git a/ckan/templates/package/new_resource.html b/ckan/templates/package/new_resource.html index 370df275a36..ed57a7aafd5 100644 --- a/ckan/templates/package/new_resource.html +++ b/ckan/templates/package/new_resource.html @@ -12,7 +12,9 @@ {% endif %} {% endblock %} -{% block form %}{% snippet resource_form_snippet, data=data, errors=errors, error_summary=error_summary, include_metadata=false, pkg_name=pkg_name, stage=stage, dataset_type=dataset_type %}{% endblock %} +{# (canada fork only): handle all errors in resource actions #} +{# TODO: upstream contrib?? #} +{% block form %}{% snippet resource_form_snippet, data=data, errors=errors, error_summary=error_summary, resource_validation_errors=resource_validation_errors, include_metadata=false, pkg_name=pkg_name, stage=stage, dataset_type=dataset_type %}{% endblock %} {% block secondary_content %} {% snippet 'package/snippets/resource_help.html' %} diff --git a/ckan/templates/package/new_resource_not_draft.html b/ckan/templates/package/new_resource_not_draft.html index 4ab9f93e476..34ac9d7b5cd 100644 --- a/ckan/templates/package/new_resource_not_draft.html +++ b/ckan/templates/package/new_resource_not_draft.html @@ -9,7 +9,9 @@ {% endblock %} {% block form %} - {% snippet resource_form_snippet, data=data, errors=errors, error_summary=error_summary, include_metadata=false, pkg_name=pkg_name, stage=stage, dataset_type=dataset_type %} + {# (canada fork only): handle all errors in resource actions #} + {# TODO: upstream contrib?? #} + {% snippet resource_form_snippet, data=data, errors=errors, error_summary=error_summary, resource_validation_errors=resource_validation_errors, include_metadata=false, pkg_name=pkg_name, stage=stage, dataset_type=dataset_type %} {% endblock %} {% block content_primary_nav %} diff --git a/ckan/templates/package/resource_edit.html b/ckan/templates/package/resource_edit.html index cb482bdb19d..e5950914893 100644 --- a/ckan/templates/package/resource_edit.html +++ b/ckan/templates/package/resource_edit.html @@ -3,10 +3,14 @@ {% block subtitle %}{{ _('Edit') }} {{ g.template_title_delimiter }} {{ h.resource_display_name(res) }} {{ g.template_title_delimiter }} {{ h.dataset_display_name(pkg) }}{% endblock %} {% block form %} + {# (canada fork only): handle all errors in resource actions #} + {# TODO: upstream contrib?? #} {% snippet 'package/snippets/resource_edit_form.html', data=data, errors=errors, error_summary=error_summary, + resource_validation_errors=resource_validation_errors, + pkg_dict=pkg_dict, pkg_name=pkg.name, form_action=form_action, resource_form_snippet=resource_form_snippet, diff --git a/ckan/templates/package/snippets/resource_form.html b/ckan/templates/package/snippets/resource_form.html index 7b63eaa1563..9fd82f86f36 100644 --- a/ckan/templates/package/snippets/resource_form.html +++ b/ckan/templates/package/snippets/resource_form.html @@ -6,7 +6,7 @@ - {{ h.csrf_input() }} + {{ h.csrf_input() }} {% block stages %} {# An empty stages variable will not show the stages #} {% if stage %} @@ -14,7 +14,15 @@ {% endif %} {% endblock %} - {% block errors %}{{ form.errors(error_summary) }}{% endblock %} + {# (canada fork only): handle all errors in resource actions #} + {# TODO: upstream contrib?? #} + {% block errors %} + {% if resource_validation_errors %} + {{ form.resource_validation_errors(errors=resource_validation_errors, pkg_name=pkg_name, dataset_type=dataset_type, h=h) }} + {% else %} + {{ form.errors(errors=errors) }} + {% endif %} + {% endblock %} diff --git a/ckan/views/resource.py b/ckan/views/resource.py index 14bd44ccab0..a6779359333 100644 --- a/ckan/views/resource.py +++ b/ckan/views/resource.py @@ -316,12 +316,23 @@ def get(self, package_type = pkg_dict[u'type'] or package_type + # (canada fork only): handle all errors in resource actions + # TODO: upstream contrib?? + # we do this here to avoid issues with ckanext-scheming support + resource_validation_errors = {} + if errors and 'resources' in errors and isinstance(errors['resources'], dict): + resource_validation_errors = dict(errors) + errors = None + errors = errors or {} error_summary = error_summary or {} extra_vars: dict[str, Any] = { u'data': data, u'errors': errors, u'error_summary': error_summary, + # (canada fork only): handle all errors in resource actions + # TODO: upstream contrib?? + 'resource_validation_errors': resource_validation_errors, u'action': u'new', u'resource_form_snippet': _get_pkg_template( u'resource_form', package_type @@ -424,12 +435,23 @@ def get(self, package_type = pkg_dict[u'type'] or package_type + # (canada fork only): handle all errors in resource actions + # TODO: upstream contrib?? + # we do this here to avoid issues with ckanext-scheming support + resource_validation_errors = {} + if errors and 'resources' in errors and isinstance(errors['resources'], dict): + resource_validation_errors = dict(errors) + errors = None + errors = errors or {} error_summary = error_summary or {} extra_vars: dict[str, Any] = { u'data': data, u'errors': errors, u'error_summary': error_summary, + # (canada fork only): handle all errors in resource actions + # TODO: upstream contrib?? + 'resource_validation_errors': resource_validation_errors, u'action': u'edit', u'resource_form_snippet': _get_pkg_template( u'resource_form', package_type @@ -478,6 +500,14 @@ def post(self, package_type: str, id: str, resource_id: str) -> Response: ) else: return h.redirect_to(u'{}.read'.format(package_type), id=id) + # (canada fork only): handle validation errors + # TODO: upstream contrib?? + except ValidationError as e: + errors = e.error_dict + error_summary = e.error_summary + return self.get( + package_type, id, resource_id, errors, error_summary + ) except NotAuthorized: return base.abort( 403, @@ -486,7 +516,11 @@ def post(self, package_type: str, id: str, resource_id: str) -> Response: except NotFound: return base.abort(404, _(u'Resource not found')) - def get(self, package_type: str, id: str, resource_id: str) -> str: + # (canada fork only): handle validation errors + # TODO: upstream contrib?? + def get(self, package_type: str, id: str, resource_id: str, + errors: Optional[dict[str, Any]] = None, + error_summary: Optional[dict[str, Any]] = None) -> str: context = self._prepare(id) try: resource_dict = get_action(u'resource_show')( @@ -494,6 +528,10 @@ def get(self, package_type: str, id: str, resource_id: str) -> str: u'id': resource_id } ) + # (canada fork only): handle all errors in resource actions + # TODO: upstream contrib?? + pkg_dict = get_action('package_show')( + context, {'id': id}) pkg_id = id except NotAuthorized: return base.abort( @@ -507,8 +545,24 @@ def get(self, package_type: str, id: str, resource_id: str) -> str: g.resource_dict = resource_dict g.pkg_id = pkg_id + # (canada fork only): handle all errors in resource actions + # TODO: upstream contrib?? + # we do this here to avoid issues with ckanext-scheming support + resource_validation_errors = {} + if errors and 'resources' in errors and isinstance(errors['resources'], dict): + resource_validation_errors = dict(errors) + errors = None + return base.render( u'package/confirm_delete_resource.html', { + # (canada fork only): handle validation errors + # TODO: upstream contrib?? + 'errors': errors, + 'error_summary': error_summary, + # (canada fork only): handle all errors in resource actions + # TODO: upstream contrib?? + 'resource_validation_errors': resource_validation_errors, + 'pkg_dict': pkg_dict, u'dataset_type': _get_package_type(id), u'resource_dict': resource_dict, u'pkg_id': pkg_id