diff --git a/CHANGELOG.md b/CHANGELOG.md index b21fcc5..525bc1c 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -7,6 +7,19 @@ und dieses Projekt folgt [Semantic Versioning](https://semver.org/spec/v2.0.0.ht --- +## [2.19.0] — 2026-07-09 + +### ✨ Added — ZiviZ-Engagementfelder +- Neues **optionales** Auswahlfeld **„In welchem Engagementfeld ist die Organisation aktiv?"** im + Schritt „Grundlegende Informationen". Auto-Suggest aus dem gebündelten **ZiviZ-Engagementfeld- + Vokabular** (`config/vocabularies/engagementfeld.json`, 16 Felder — Soziale Dienste, Kultur, Sport, + Umwelt- und Naturschutz u. a.); die zugehörige `ziviz.de`-URI wird automatisch verwendet. +- Im JSON-LD als `dct:subject` ausgegeben — zusammen mit einer CESSDA-Klassifikation wird + `dct:subject` zu einem Array. +- Erscheint auch im Frontend-Widget-Accordion „Alle Metadaten anzeigen". + +--- + ## [2.18.0] — 2026-07-09 ### 💅 Changed — Download-Card (`[odw_dataset]`) neu gestaltet diff --git a/README.md b/README.md index 3483be4..fa42be1 100644 --- a/README.md +++ b/README.md @@ -7,7 +7,7 @@ ![PHP Version](https://img.shields.io/badge/PHP-%3E%3D%208.1-8892BF?style=flat-square&logo=php&logoColor=white) ![WordPress](https://img.shields.io/badge/WordPress-compatible-21759B?style=flat-square&logo=wordpress&logoColor=white) ![DCAT-AP](https://img.shields.io/badge/DCAT--AP-3.0-brightgreen?style=flat-square) -![Version](https://img.shields.io/badge/Version-2.18.0-brightgreen?style=flat-square) +![Version](https://img.shields.io/badge/Version-2.19.0-brightgreen?style=flat-square) ![PRs Welcome](https://img.shields.io/badge/PRs-willkommen-brightgreen?style=flat-square) 📖 [Dokumentation](DOCUMENTATION.md) · 📐 [Technische Spezifikation](TECHNICAL-SPEC.md) · 📝 [Changelog](CHANGELOG.md) · 🛡️ [Security](SECURITY.md) · ⚖️ [Lizenz](LICENSE) diff --git a/config/vocabularies/engagementfeld.json b/config/vocabularies/engagementfeld.json new file mode 100644 index 0000000..1356bf4 --- /dev/null +++ b/config/vocabularies/engagementfeld.json @@ -0,0 +1,66 @@ +[ + { + "value": "https://ziviz.de/def/engagementfeld/bevoelkerungsUNDkatastrophenschutz", + "label": "Bevölkerungs- und Katastrophenschutz" + }, + { + "value": "https://ziviz.de/def/engagementfeld/bildungUNDerziehung", + "label": "Bildung und Erziehung" + }, + { + "value": "https://ziviz.de/def/engagementfeld/buergerUNDverbraucherinteressen", + "label": "Bürger- und Verbraucherinteressen" + }, + { + "value": "https://ziviz.de/def/engagementfeld/freizeitUNDgeselligkeit", + "label": "Freizeit und Geselligkeit" + }, + { + "value": "https://ziviz.de/def/engagementfeld/gemeinschaftlicheversorgungsaufgaben", + "label": "Gemeinschaftliche Versorgungsaufgaben" + }, + { + "value": "https://ziviz.de/def/engagementfeld/gesundheitswesen", + "label": "Gesundheitswesen" + }, + { + "value": "https://ziviz.de/def/engagementfeld/internationalesolidaritaet", + "label": "Internationale Solidarität" + }, + { + "value": "https://ziviz.de/def/engagementfeld/kirchenUNDreligioesevereinigungen", + "label": "Kirchen und religiöse Vereinigungen" + }, + { + "value": "https://ziviz.de/def/engagementfeld/kultur", + "label": "Kultur" + }, + { + "value": "https://ziviz.de/def/engagementfeld/medien", + "label": "Medien" + }, + { + "value": "https://ziviz.de/def/engagementfeld/sozialedienste", + "label": "Soziale Dienste" + }, + { + "value": "https://ziviz.de/def/engagementfeld/sport", + "label": "Sport" + }, + { + "value": "https://ziviz.de/def/engagementfeld/umweltUNDnaturschutz", + "label": "Umwelt- und Naturschutz" + }, + { + "value": "https://ziviz.de/def/engagementfeld/wirtschaftsverbaendeUNDberufsorganisationen", + "label": "Wirtschaftsverbände und Berufsorganisationen" + }, + { + "value": "https://ziviz.de/def/engagementfeld/wissenschaftUNDforschung", + "label": "Wissenschaft und Forschung" + }, + { + "value": "https://ziviz.de/def/engagementfeld/sonstiges", + "label": "Sonstiges" + } +] diff --git a/includes/class-admin.php b/includes/class-admin.php index d82387a..9b5d4ef 100644 --- a/includes/class-admin.php +++ b/includes/class-admin.php @@ -372,8 +372,9 @@ public static function enqueue_assets( string $hook ): void { 'cessdaOptions' => $cessda_options, 'spatialOptions' => $spatial_options, 'vocabularies' => array( - 'contributors' => ODW_Fields::load_vocabulary( 'contributors' ), - 'data-theme' => ODW_Fields::load_vocabulary( 'data-theme' ), + 'contributors' => ODW_Fields::load_vocabulary( 'contributors' ), + 'data-theme' => ODW_Fields::load_vocabulary( 'data-theme' ), + 'engagementfeld' => ODW_Fields::load_vocabulary( 'engagementfeld' ), ), 'cessdaWidget' => array( 'label' => __( 'CESSDA Themenklassifikation', 'open-data-wizard' ), diff --git a/includes/class-fields.php b/includes/class-fields.php index 9d7776d..9e27cce 100644 --- a/includes/class-fields.php +++ b/includes/class-fields.php @@ -74,6 +74,11 @@ private static function register_required_fields(): void { ->set_attribute( 'data-odw-backing', 'cessda' ) ->set_help_text( __( 'CESSDA THEMENKLASSIFIKATION (dct:subject)', 'open-data-wizard' ) . "\n\n" . __( 'Aus dem CESSDA Controlled Vocabulary (Version 4.2.3, Deutsch). Beispiel: Volkszählungen, Migration, Wirtschaftspolitik', 'open-data-wizard' ) ), + Field::make( 'text', 'odw_engagementfeld', __( 'In welchem Engagementfeld ist die Organisation aktiv?', 'open-data-wizard' ) ) + ->set_attribute( 'data-odw-vocab', 'engagementfeld' ) + ->set_attribute( 'placeholder', __( 'Engagementfeld eintippen oder auswählen…', 'open-data-wizard' ) ) + ->set_help_text( __( 'ENGAGEMENTFELD (ZiviZ, dct:subject)', 'open-data-wizard' ) . "\n\n" . __( 'Optional: Ordnen Sie den Datensatz einem Engagementfeld der Zivilgesellschaft nach dem ZiviZ-Vokabular zu. Feld aus der Liste wählen — die zugehörige URI wird automatisch verwendet. Beispiel: Kultur, Sport, Umwelt- und Naturschutz.', 'open-data-wizard' ) ), + Field::make( 'textarea', 'odw_description', __( 'Worum geht es in diesem Datensatz?', 'open-data-wizard' ) ) ->set_required( true ) ->set_rows( 5 ) @@ -1299,6 +1304,7 @@ function odw_build_dataset_jsonld( int $post_id ): ?array { $dist_attribution = (string) carbon_get_post_meta( $post_id, 'odw_attribution_text' ); $dist_availability = (string) carbon_get_post_meta( $post_id, 'odw_availability' ); $cessda_topic = (string) carbon_get_post_meta( $post_id, 'odw_cessda_topic' ); + $engagementfeld = (string) carbon_get_post_meta( $post_id, 'odw_engagementfeld' ); // Extended DCAT-AP fields (Tab 4). $landing_page = (string) carbon_get_post_meta( $post_id, 'odw_landing_page' ); @@ -1410,12 +1416,21 @@ static function ( $kw ) use ( $lang_tag ) { $dataset['dcat:theme'] = $themes; } + // Thematic classifications are attached via the standard DCAT-AP subject + // property. CESSDA topic and ZiviZ engagement field both map to dct:subject; + // when both are present, dct:subject becomes an array. + $subjects = array(); if ( ! empty( $cessda_topic ) ) { - // CESSDA Topic Classification concept attached via the standard DCAT-AP - // subject property. Emitting an undeclared `cessda:` prefix would produce - // invalid JSON-LD; `dct:subject` is the conformant predicate and is - // already part of the @context. - $dataset['dct:subject'] = array( '@id' => odw_sanitize_jsonld_id( (string) $cessda_topic ) ); + $subjects[] = array( '@id' => odw_sanitize_jsonld_id( (string) $cessda_topic ) ); + } + if ( ! empty( $engagementfeld ) ) { + $engagement_uri = odw_resolve_vocab_uri( $engagementfeld, 'engagementfeld' ); + if ( '' !== $engagement_uri ) { + $subjects[] = array( '@id' => odw_sanitize_jsonld_id( $engagement_uri ) ); + } + } + if ( ! empty( $subjects ) ) { + $dataset['dct:subject'] = 1 === count( $subjects ) ? $subjects[0] : $subjects; } if ( ! empty( $issued ) ) { diff --git a/includes/class-shortcode.php b/includes/class-shortcode.php index 5fb30cc..2f078c9 100644 --- a/includes/class-shortcode.php +++ b/includes/class-shortcode.php @@ -248,6 +248,7 @@ private static function collect_metadata_rows( int $post_id, string $license_lab $add( __( 'Beschreibung', 'open-data-wizard' ), self::meta( $post_id, 'odw_description' ) ); $add( __( 'Thema', 'open-data-wizard' ), self::meta( $post_id, 'odw_theme' ) ); $add( __( 'CESSDA-Themenfeld', 'open-data-wizard' ), self::meta( $post_id, 'odw_cessda_topic' ), true ); + $add( __( 'Engagementfeld', 'open-data-wizard' ), self::meta( $post_id, 'odw_engagementfeld' ) ); $add( __( 'Sprache', 'open-data-wizard' ), self::meta( $post_id, 'odw_language' ), true ); $keywords = array_filter( array_map( 'trim', explode( "\n", self::meta( $post_id, 'odw_keywords' ) ) ) ); diff --git a/languages/open-data-wizard-en_US.mo b/languages/open-data-wizard-en_US.mo index 8bc337a..2ff09a8 100644 Binary files a/languages/open-data-wizard-en_US.mo and b/languages/open-data-wizard-en_US.mo differ diff --git a/languages/open-data-wizard-en_US.po b/languages/open-data-wizard-en_US.po index 796b80e..e56678e 100644 --- a/languages/open-data-wizard-en_US.po +++ b/languages/open-data-wizard-en_US.po @@ -474,6 +474,9 @@ msgstr "Email address for inquiries." msgid "EIGENE LIZENZ-URI" msgstr "CUSTOM LICENSE URI" +msgid "ENGAGEMENTFELD (ZiviZ, dct:subject)" +msgstr "FIELD OF ENGAGEMENT (ZiviZ, dct:subject)" + msgid "ERSTELLER (dct:creator)" msgstr "CREATOR (dct:creator)" @@ -519,6 +522,12 @@ msgstr "Recommended fields" msgid "Energie" msgstr "Energy" +msgid "Engagementfeld" +msgstr "Field of engagement" + +msgid "Engagementfeld eintippen oder auswählen…" +msgstr "Type or select a field of engagement…" + msgid "Englisch (EN)" msgstr "English (EN)" @@ -681,6 +690,9 @@ msgstr "Insert into dataset" msgid "In welche Kategorie gehört dieser Datensatz?" msgstr "Which category does this dataset belong to?" +msgid "In welchem Engagementfeld ist die Organisation aktiv?" +msgstr "In which field of engagement is the organization active?" + msgid "In welchem Format ist die Datei?" msgstr "What format is the file in?" @@ -969,6 +981,9 @@ msgstr "Open data platforms can add this URL as a harvest source and collect the msgid "Optional ein weiteres Thema aus der offiziellen EU-Themenliste (ergänzt die Kategorie aus Tab 1)." msgstr "Optionally an additional theme from the official EU theme list (supplements the category from tab 1)." +msgid "Optional: Ordnen Sie den Datensatz einem Engagementfeld der Zivilgesellschaft nach dem ZiviZ-Vokabular zu. Feld aus der Liste wählen — die zugehörige URI wird automatisch verwendet. Beispiel: Kultur, Sport, Umwelt- und Naturschutz." +msgstr "Optional: assign the dataset to a civil-society field of engagement from the ZiviZ vocabulary. Pick one from the list — the matching URI is used automatically. Example: Culture, Sports, Environmental and nature protection." + msgid "Optionale Angaben" msgstr "Optional details" diff --git a/open-data-wizard.php b/open-data-wizard.php index d8332ae..9a44bbb 100644 --- a/open-data-wizard.php +++ b/open-data-wizard.php @@ -3,7 +3,7 @@ * Plugin Name: Open Data Wizard * Plugin URI: https://github.com/daimpad/OpenDataWizard * Description: DCAT-AP 3.0 konforme Open Data Metadatenverwaltung für WordPress. Bereitstellung als maschinenlesbarer JSON-LD-Endpoint für offene Daten. - * Version: 2.18.0 + * Version: 2.19.0 * Requires at least: 6.4 * Requires PHP: 8.1 * Author: nozilla @@ -26,7 +26,7 @@ exit; } -define( 'ODW_VERSION', '2.18.0' ); +define( 'ODW_VERSION', '2.19.0' ); define( 'ODW_PLUGIN_DIR', plugin_dir_path( __FILE__ ) ); define( 'ODW_PLUGIN_URL', plugin_dir_url( __FILE__ ) ); define( 'ODW_PLUGIN_FILE', __FILE__ );