Skip to content

Commit 95f3666

Browse files
committed
Merge remote-tracking branch 'origin/completeness' into iformredirect-compat
2 parents b486b30 + cc70d43 commit 95f3666

File tree

16 files changed

+374
-82
lines changed

16 files changed

+374
-82
lines changed

.github/workflows/test.yml

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -24,6 +24,7 @@ jobs:
2424
runs-on: ubuntu-latest
2525
container:
2626
image: ckan/ckan-dev:${{ matrix.ckan-version }}
27+
options: --user root
2728
services:
2829
solr:
2930
image: ckan/ckan-solr:${{ matrix.ckan-version }}-solr9

CHANGELOG.md

Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -103,3 +103,26 @@
103103
* fix for applying default org/group types
104104
* sync example dataset schemas, presets and templates with upstream ckan
105105
changes
106+
107+
## 3.1.0
108+
109+
2024-03-27
110+
111+
* This version drops support for CKAN 2.8, 2.9 and adds support for 2.11
112+
* Pass dataset name to resource fields snippets [#437](https://github.com/ckan/ckanext-scheming/pull/354)
113+
* Allow literal parameters in validator string [#372](https://github.com/ckan/ckanext-scheming/pull/372)
114+
* Fix delete URL for custom organizations [#374](https://github.com/ckan/ckanext-scheming/pull/374)
115+
* Group Form Required Message Position [#376](https://github.com/ckan/ckanext-scheming/pull/376)
116+
* Resource Form Errors Super Fallback [#380](https://github.com/ckan/ckanext-scheming/pull/380)
117+
* Use form_snippets/help_text.html in repeating_subfields.html [#387](https://github.com/ckan/ckanext-scheming/pull/397)
118+
* Add form-select CSS class to select elements [#399](https://github.com/ckan/ckanext-scheming/pull/399)
119+
* Fix ckan version comparison [#406](https://github.com/ckan/ckanext-scheming/pull/406)
120+
* Add number and file_size snippets [#412](https://github.com/ckan/ckanext-scheming/pull/412)
121+
* Before and After Validators for Groups [#428](https://github.com/ckan/ckanext-scheming/pull/428)
122+
* Drop ckantoolkit requirement [#432](https://github.com/ckan/ckanext-scheming/pull/432)
123+
* Fix `is_organization` for custom `organization_type` [#437](https://github.com/ckan/ckanext-scheming/pull/437), [#431](https://github.com/ckan/ckanext-scheming/pull/431)
124+
* fix: Move toggle-more rows to bottom of resource table [#420](https://github.com/ckan/ckanext-scheming/pull/420)
125+
* fix: Add default text to update/edit buttons in group_form [#421](https://github.com/ckan/ckanext-scheming/pull/421)
126+
* fix: False is also a value for radio and select snippets [#417](https://github.com/ckan/ckanext-scheming/pull/417)
127+
* Remove presets parsing cache check [#425](https://github.com/ckan/ckanext-scheming/pull/425)
128+
* fix: optional multiple_text saved as empty string if missing on create

README.md

Lines changed: 64 additions & 48 deletions
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,8 @@ This CKAN extension provides a way to configure and share metadata schemas using
55
YAML or JSON schema description. Custom validation and template snippets for editing
66
and display are supported.
77

8-
[![Tests](https://github.com/ckan/ckanext-scheming/workflows/Tests/badge.svg?branch=master)](https://github.com/ckan/ckanext-scheming/actions)
8+
[![Tests](https://github.com/ckan/ckanext-scheming/actions/workflows/test.yml/badge.svg)](https://github.com/ckan/ckanext-scheming/actions)
9+
910

1011
Table of contents:
1112

@@ -14,19 +15,18 @@ Table of contents:
1415
3. [Configuration](#configuration)
1516
- [Schema Types](#schema-types)
1617
- [Example Schemas](#example-schemas)
17-
- [Storing non-string data](#storing-non-string-data)
1818
- [Common Schema Keys](#common-schema-keys)
1919
- [`scheming_version`](#scheming_version)
2020
- [`about_url`](#about_url)
21+
- [`before_validators`, `after_validators`](#before_validators-after_validators)
2122
- [Dataset Schema Keys](#dataset-schema-keys)
2223
- [`dataset_type`](#dataset_type)
2324
- [`dataset_fields`, `resource_fields`](#dataset_fields-resource_fields)
24-
- [`before_validators`, `after_validators`](#before_validators-after_validators)
25+
- [`draft_fields_required`](#draft_fields_required)
2526
- [Group / Organization Schema Keys](#group--organization-schema-keys)
2627
- [`group_type`](#group_type)
2728
- [`organization_type`](#organization_type)
2829
- [`fields`](#fields)
29-
- [`before_validators`, `after_validators`](#before_validators-after_validators-1)
3030
- [Field Keys](#field-keys)
3131
- [`field_name`](#field_name)
3232
- [`label`](#label)
@@ -113,6 +113,7 @@ Dataset schemas:
113113
* [camel photos schema](ckanext/scheming/camel_photos.yaml)
114114
* [subfields schema](ckanext/scheming/subfields.yaml)
115115
* [form pages schema](ckanext/scheming/ckan_formpages.yaml)
116+
* [form pages schema with `draft_fields_required: false`](ckanext/scheming/ckan_formpages_draft.yaml)
116117

117118
These schemas are included in ckanext-scheming and may be enabled
118119
with e.g: `scheming.dataset_schemas = ckanext.scheming:camel_photos.yaml`
@@ -196,7 +197,25 @@ before_validators: validator_name
196197
after_validators: validator_name
197198
```
198199

199-
Runs validator functions before and after the `dataset_type` package is created/updated.
200+
Runs validator functions before and after the `dataset_type` package or `organization_type`/`group_type` group is created/updated.
201+
202+
See [`validators`](#validators) for a description of the values accepted.
203+
204+
### `draft_fields_required`
205+
206+
Enforce required fields even if a dataset is still in draft state.
207+
Default: `true`
208+
209+
```yaml
210+
draft_fields_required: false
211+
```
212+
213+
> [!NOTE]
214+
> Setting `draft_fields_required: false` is only supported by **_CKAN 2.12+_** or with https://github.com/ckan/ckan/pull/8309 .
215+
216+
Set to `false` to allow saving dataset and resource metadata even
217+
if some *required fields* have not been provided as long as the dataset
218+
is still in *draft* state (has not been published).
200219

201220

202221
## Group / Organization Schema Keys
@@ -241,21 +260,9 @@ fields:
241260
242261
...
243262
```
244-
A single `fields` list replaces the `dataset_fields` and `resource_fields` schema properties doin dataset schemas.
263+
A single `fields` list replaces the `dataset_fields` and `resource_fields` schema properties in dataset schemas.
245264

246265

247-
### `before_validators`, `after_validators`
248-
249-
```yaml
250-
before_validators: validator_name
251-
252-
after_validators: validator_name
253-
```
254-
255-
Runs validator functions before and after the `organization_type`/`group_type` group is created/updated.
256-
257-
258-
----------------
259266

260267
## Field Keys
261268
### `field_name`
@@ -304,7 +311,8 @@ When using a plain string translations will be provided with gettext:
304311
This field is the parent of group of repeating subfields. The value is
305312
a list of fields entered the same way as normal fields.
306313

307-
> **_NOTE:_** CKAN needs an IPackageController plugin with `before_index` to
314+
> [!NOTE]
315+
> CKAN needs an IPackageController plugin with `before_index` to
308316
> convert repeating subfields to formats that can be indexed by solr. For
309317
> testing you may use the included `scheming_nerf_index` plugin to encode
310318
> all repeating fields as JSON strings to prevent solr errors.
@@ -333,9 +341,12 @@ for each group.
333341
### `start_form_page`
334342

335343
Dataset fields may be divided into separate form pages for creation
336-
and editing. **_CKAN 2.9+ only_**. Form pages for `dataset` type
337-
only supported by **_CKAN 2.10+_** or with https://github.com/ckan/ckan/pull/7032
338-
. Adding `start_form_page` to a field marks this field as the start of a
344+
and editing.
345+
346+
> [!NOTE]
347+
> Form pages for `dataset` type is only supported by **_CKAN 2.10+_** or with https://github.com/ckan/ckan/pull/7032 .
348+
349+
Adding `start_form_page` to a field marks this field as the start of a
339350
new page of fields.
340351

341352

@@ -364,13 +375,7 @@ Use for fields that must be included. Set to `false` or
364375
don't include this key for fields that are optional.
365376

366377
Setting to `true` will mark the field as required in the editing form
367-
and include `not_empty` in the default validators that will be applied
368-
when `validators` is not specified.
369-
370-
> **_NOTE:_** To honor this settings with custom validators include `scheming_required`
371-
> as the first validator. `scheming_required` will check the required
372-
> setting for this field and apply either the `not_empty` or `ignore_missing`
373-
> validator.
378+
and affects the behavior of the `scheming_required` field validator.
374379

375380

376381
### `choices`
@@ -587,40 +592,50 @@ Set a `property` attribute on dataset fields displayed as "Additional Info", use
587592
### `validators`
588593

589594
The `validators` value is a space-separated string of validator and converter
590-
functions to use for this field when creating or updating data. When a
591-
validator name is followed by parenthesis the function is called passing the
592-
comma-separated values within and the result is used as the
595+
functions to use for this field when creating or updating data. For core fields
596+
the validators default to the ones defined in the CKAN core schemas.
597+
598+
> [!WARNING]
599+
> Use `scheming_required` as the first validator
600+
> or the [`required`](#required) field setting will be ignored.
601+
> `scheming_required` applies either the `not_empty` or `ignore_missing`
602+
> validator based on the `required` field setting.
603+
604+
When a validator name is followed by parenthesis the function is called
605+
passing the comma-separated values within and the result is used as the
593606
validator/converter.
594607

595608
```yaml
596-
validators: if_empty_same_as(name) unicode_safe
609+
validators: scheming_required if_empty_same_as(name) unicode_safe
597610
```
598611

599-
is the same as a plugin using the validators:
612+
is the same as a form plugin using the validators:
600613

601614
```python
602-
[get_validator('if_empty_same_as')("name"), unicode_safe]
615+
[
616+
get_validator('scheming_required'),
617+
get_validator('if_empty_same_as')("name"),
618+
get_validator('unicode_safe')
619+
]
603620
```
604621

605-
If parameters can be parsed as a valid python literals, they are passed with
606-
original type. If not, all parameters passed as strings. In addition, space
607-
character is not allowed in argument position. Use its HEX code instead `\\x20`.
622+
If validator parameters can be parsed as a valid python literals,
623+
they are passed with the original type. If not, all parameters passed
624+
as strings. In addition, space character is not allowed in argument
625+
position. Use its HEX code instead `\\x20`.
608626

609627
```yaml
610-
validators: xxx(hello,world) # xxx("hello", "world")
611-
validators: xxx(hello,1) # xxx("hello", "1")
612-
validators: xxx("hello",1,None) # xxx("hello", 1, None)
628+
validators: xxx(hello,world) # xxx("hello", "world")
629+
validators: xxx(hello,1) # xxx("hello", "1")
630+
validators: xxx("hello",1,None) # xxx("hello", 1, None)
613631
validators: xxx("hello\\x20world") # xxx("hello world")
614632
```
615633

616-
This string does not contain arbitrary python code to be executed,
617-
you may only use registered validator functions, optionally calling
618-
them with static string values provided.
619-
620-
> **_NOTE:_** ckanext-scheming automatically adds calls to `convert_to_extras`
634+
> [!NOTE]
635+
> ckanext-scheming automatically adds a call to `convert_to_extras`
621636
> for extra fields when required.
622637

623-
New validators and converters may be added using the
638+
New validators and converters may be registered using the
624639
[IValidators plugin interface](http://docs.ckan.org/en/latest/extensions/plugin-interfaces.html?highlight=ivalidator#ckan.plugins.interfaces.IValidators).
625640

626641
Validators that need access to other values in this schema (e.g.
@@ -657,7 +672,8 @@ retrieving values from the database instead of when saving them.
657672
These validators may be used to transform the data before it is
658673
sent to the user.
659674
660-
> **_NOTE:_** ckanext-scheming automatically adds calls to `convert_from_extras`
675+
> [!NOTE]
676+
> ckanext-scheming automatically adds calls to `convert_from_extras`
661677
> for extra fields when required.
662678
663679
### `create_validators`
Lines changed: 115 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,115 @@
1+
scheming_version: 2
2+
dataset_type: formpages
3+
about: The default CKAN dataset schema with form split across multiple pages
4+
about_url: http://github.com/ckan/ckanext-scheming
5+
6+
draft_fields_required: false
7+
8+
dataset_fields:
9+
10+
- start_form_page:
11+
title: Basic Info
12+
description: Required and core dataset fields
13+
14+
field_name: title
15+
label: Title
16+
preset: title
17+
form_placeholder: eg. A descriptive title
18+
19+
- field_name: name
20+
label: URL
21+
preset: dataset_slug
22+
form_placeholder: eg. my-dataset
23+
24+
- field_name: notes
25+
label: Description
26+
form_snippet: markdown.html
27+
form_placeholder: eg. Some useful notes about the data
28+
required: true
29+
validators: scheming_required unicode_safe
30+
31+
- field_name: owner_org
32+
label: Organization
33+
preset: dataset_organization
34+
35+
- start_form_page:
36+
title: Detailed Info
37+
description:
38+
These fields improve search and give users important links
39+
40+
field_name: tag_string
41+
label: Tags
42+
preset: tag_string_autocomplete
43+
form_placeholder: eg. economy, mental health, government
44+
45+
- field_name: license_id
46+
label: License
47+
form_snippet: license.html
48+
help_text: License definitions and additional information can be found at http://opendefinition.org/
49+
50+
- field_name: url
51+
label: Source
52+
form_placeholder: http://example.com/dataset.json
53+
display_property: foaf:homepage
54+
display_snippet: link.html
55+
56+
- field_name: version
57+
label: Version
58+
validators: ignore_missing unicode_safe package_version_validator
59+
form_placeholder: '1.0'
60+
required: true
61+
validators: scheming_required unicode_safe package_version_validator
62+
63+
- start_form_page:
64+
title: Contact Info
65+
description: Names and email addresses for this dataset
66+
67+
field_name: author
68+
label: Author
69+
form_placeholder: Joe Bloggs
70+
display_property: dc:creator
71+
required: true
72+
validators: scheming_required unicode_safe
73+
74+
- field_name: author_email
75+
label: Author Email
76+
form_placeholder: [email protected]
77+
display_property: dc:creator
78+
display_snippet: email.html
79+
display_email_name_field: author
80+
validators: ignore_missing unicode_safe strip_value email_validator
81+
82+
- field_name: maintainer
83+
label: Maintainer
84+
form_placeholder: Joe Bloggs
85+
display_property: dc:contributor
86+
87+
- field_name: maintainer_email
88+
label: Maintainer Email
89+
form_placeholder: [email protected]
90+
display_property: dc:contributor
91+
display_snippet: email.html
92+
display_email_name_field: maintainer
93+
validators: ignore_missing unicode_safe strip_value email_validator
94+
95+
96+
resource_fields:
97+
98+
- field_name: url
99+
label: URL
100+
preset: resource_url_upload
101+
102+
- field_name: name
103+
label: Name
104+
form_placeholder: eg. January 2011 Gold Prices
105+
required: true
106+
validators: scheming_required unicode_safe
107+
108+
- field_name: description
109+
label: Description
110+
form_snippet: markdown.html
111+
form_placeholder: Some useful notes about the data
112+
113+
- field_name: format
114+
label: Format
115+
preset: resource_format_autocomplete

ckanext/scheming/helpers.py

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -441,3 +441,21 @@ def scheming_flatten_subfield(subfield, data):
441441
for k in record:
442442
flat[prefix + k] = record[k]
443443
return flat
444+
445+
446+
@helper
447+
def scheming_missing_required_fields(pages, data=None, package_id=None):
448+
if package_id:
449+
try:
450+
data = LocalCKAN().action.package_show(id=package_id)
451+
except (NotFound, NotAuthorized):
452+
pass
453+
if data is None:
454+
data = {}
455+
missing = []
456+
for p in pages:
457+
missing.append([
458+
f['field_name'] for f in p['fields']
459+
if f.get('required') and not data.get(f['field_name'])
460+
])
461+
return missing

0 commit comments

Comments
 (0)