diff --git a/CHANGELOG.md b/CHANGELOG.md index ca4774aa..9f59ce60 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -7,6 +7,138 @@ und dieses Projekt folgt [Semantic Versioning](https://semver.org/spec/v2.0.0.ht --- +## [2.41.0] — 2026-08-27 + +Fünf Punkte aus dem Usability-Test. Hilfetexte haben jetzt je einen Ort, die Definition zeigt +ihre Struktur und verweist auf den Standard — und wo ein Feld eine feste Auswahl hat, ist es +auch eine Auswahl und kein Textfeld, das seine Optionen erst nach dem Tippen preisgibt. + +### ✨ Added +- **Merkmalsliste über jeder Definition.** Das „Mehr erfahren"-Panel nennt oben in zwei Zeilen + die DCAT-AP-Eigenschaft und die Multiplizität, darunter folgen wie bisher Alltagssprache und + Definition. Der Tester hatte bemerkt, dass die Definitionstexte einer festen Struktur folgen, + diese aber nur im Fließtext steht. +- **`cardinality` als eigenes Feld im Katalog** — für alle 53 Einträge. Zwei neue Tests halten + den strukturierten Wert und die Angabe im Definitionstext zusammen; ohne sie laufen beide + auseinander, sobald jemand nur eine Seite anfasst. +- **Link auf die Spezifikation je Profil-Klasse.** Am Fuß jedes Panels steht „Im Standard + nachlesen: Datensatz" bzw. „: Distribution" mit Verweis auf den passenden Abschnitt von + DCAT-AP.de 3.0. Bewusst je Klasse und nicht je Feld: Die feldgenauen Anker ließen sich von + hier aus nicht überprüfen — bei den drei Klassen-Ankern führt ein Irrtum schlimmstenfalls an + den Anfang des richtigen Dokuments. Die Zuordnung der 12 Distributions-Felder stammt aus + `odw_build_distribution_node()` und wird von einem Test dagegen gehalten. +- **`entity` als eigenes Feld im Katalog** — 41 Datensatz-, 12 Distributions-Felder, + gegengeprüft gegen die Registry. + +### ✨ Added (Fortsetzung) +- **Thema ist eine Mehrfachauswahl.** `dcat:theme` erlaubt laut Profil 0..n Themen; das Formular + bot ein Auswahlfeld in Tab 1 und ein Tipp-Feld unter „Erweiterte Angaben" — zusammen höchstens + zwei, auf zwei verschiedene Arten. Beide sind durch ein Mehrfachfeld mit den EU-Themen ersetzt. + Der Batch-Import nimmt jetzt ebenfalls mehrere Themen an (Komma- oder Zeilentrennung). +- **Engagementfeld ist eine Mehrfachauswahl, Contributor-ID ein Auswahlfeld.** Beide waren + Textfelder mit einer `` dahinter — man musste erst tippen, um überhaupt zu sehen, + dass es eine Auswahl gibt, und wer daneben tippte, bekam einen Wert ohne URI. 16 bzw. 69 + Einträge passen in eine Liste. `dct:subject` erlaubt 0..n, deshalb ist das Engagementfeld + mehrfach wählbar; die Contributor-ID bleibt einfach. +- **Die CESSDA-Vorschläge öffnen sich beim Anklicken.** Mit mehreren hundert Konzepten bleibt + hier eine Vorschlagsliste richtig — aber eine, die zeigt, was zur Auswahl steht. Sie ersetzt + das native `` durch eine eigene Liste mit Tastaturbedienung (Pfeiltasten, Enter, + Escape). Nebeneffekt: Das Verhalten ist in allen Browsern dasselbe und im E2E-Test überhaupt + prüfbar — ein datalist-Popup ist Browser-Chrome und für Playwright unsichtbar. + +### 🎨 Changed +- **Tooltip und „Mehr erfahren" haben getrennte Rollen.** Das ⓘ trägt nur noch den DCAT-AP-Begriff, + alles Erklärende steht im Panel. Vorher stand beides an beiden Orten — beim Herausgeber sogar + mit unterschiedlichen Beispielen. Betrifft 42 Felder. +- **Fünf Felder hatten gar keinen Fachbegriff im Tooltip**, sondern schon dort Prosa: die drei + Kontaktfelder, die eigene Lizenz-URI und die HVD-Kennzeichnung. Sie tragen jetzt ihren + tatsächlich ausgegebenen Begriff (`vcard:fn`, `vcard:hasEmail`, `vcard:hasURL`, `dct:license`, + `dcatap:applicableLegislation`). +- **Das Schlagwort-Beispiel widersprach seiner eigenen Regel.** Der Text verlangte ein Wort je + Zeile und nannte dann ein Beispiel mit Kommas — wer nur den Katalog las, tippte genau die + falsche Form. + +### 🐛 Fixed +- **Migration der Themen, damit nichts verlorengeht.** Carbon Fields legt Mehrfachwerte unter + eigenen Meta-Keys ab (`_odw_theme|||0|value`), die alten flachen Zeilen wären unsichtbar + geworden. Eine einmalige Umschreibung überführt beim ersten Aufruf des Backends alle + Datensätze — über `carbon_set_post_meta()`, nicht über selbstgebaute Schlüssel, weil deren + Format ein Interna der Bibliothek ist. +- **Themenfilter und Sortierung wären still kaputtgegangen.** Beide fragten die Datenbank auf + `_odw_theme` ab und hätten Mehrfachwerte nicht mehr gefunden. Das Plugin schreibt die Auswahl + deshalb zusätzlich flach: `_odw_theme_index` (eine Zeile je Thema) für den Katalogfilter, + `_odw_theme_sort` für die Spaltensortierung. Der bestehende E2E-Test auf `?theme=Bildung` + prüft das mit — und fand dabei gleich noch, dass der Katalogfilter den Parameter anders + auflöste als der Index geschrieben wird: `resolve_theme_uri()` kennt nur die EU-Bezeichnungen, + und „Bildung" heißt dort „Bildung, Kultur und Sport". Der Filter nimmt jetzt dieselbe + Auflösung wie das Speichern, damit Harvester mit dem alten deutschen Kurznamen weiter + Treffer bekommen. +- **Das Engagementfeld hätte seinen Wert verloren.** Wie beim Thema ändert die Mehrfachauswahl + das Speicherformat; dieselbe einmalige Umschreibung überführt jetzt beide Felder und löst + dabei einen von Hand eingetippten Namen zur Vokabular-URI auf. +- **`bin/check-i18n.py` übersah `config/`.** `mqa-metrics.php` und `dcat-ap-fields.php` führen + ihre Beschriftungen über `__()`, standen aber nicht in der Dateiliste der Prüfung — für 31 + Zeichenketten hätte eine fehlende Übersetzung also nie jemand gemeldet. Aufgefallen ist es, + weil ich beim Aufräumen der Kataloge beinahe genau diese Einträge gelöscht hätte. + +### 🧹 Removed +- **Das generische Vokabular-Autosuggest (`data-odw-vocab`) ist entfallen** — mit Thema, + Engagementfeld und Contributor-ID hatte es keine Nutzer mehr. Damit entfällt auch die + Auslieferung der drei Vokabulare an jede Admin-Seite; die Optionen stehen jetzt im Formular + selbst. Die Vokabulardateien unter `config/vocabularies/` bleiben unverändert. + +### ℹ️ Eine Ausnahme mit Begründung +Das Wiederholfeld für weitere Distributionen behält seinen Hilfetext: Für dieses Feld gibt es +keinen Katalogeintrag, das Panel erscheint dort also gar nicht — der Tooltip ist die einzige +Erklärung, die es hat. + +--- + +## [2.40.3] — 2026-08-27 + +Vier Punkte aus einem Usability-Test — und was beim Nachprüfen sonst noch auffiel. + +### 🐛 Fixed +- **`dct:subject` war fälschlich als DCAT-AP-Definition ausgewiesen.** Die Eigenschaft (CESSDA- + Themenklassifikation, ZiviZ-Engagementfeld) gehört nicht zum Profil — in den mitgelieferten + offiziellen SHACL-Shapes taucht sie für Datensätze nirgends auf. Zulässig ist sie trotzdem, + RDF erlaubt zusätzliche Aussagen, und sie bleibt bewusst erhalten; die Feld-Referenz sagt jetzt + aber dazu, dass streng profilkonforme Portale sie ignorieren dürfen. Beim systematischen + Abgleich aller 43 Katalog-Eigenschaften gegen die Shapes fiel ein zweiter Fall auf: + `dcatap:hvdCategory` stammt aus der HVD-Erweiterung (EU-Verordnung 2023/138), nicht aus dem + Kernprofil DCAT-AP 3.0. Auch vermerkt. +- **Die Verwaltungsebene nannte Optionen, die es nicht gibt.** Die Beschreibung sprach von + „Kreis" und „Kommune", die Auswahlliste bietet „Landkreis" und „Gemeinde". Betraf beide + Beschreibungstexte, den allgemeinverständlichen und den fachlichen. + +### 🎨 Changed +- **Pflichtfeld-Hinweis umformuliert:** „* Pflichtfeld für die Veröffentlichung. Als Entwurf + können Sie den Datensatz jederzeit speichern." Der bisherige Satz stolperte über sich selbst. +- **Beispiele aus den Tooltips fester Auswahllisten entfernt.** Ein Beispiel, das nur die + Optionen des Dropdowns wiederholt, hilft niemandem. Der Tester fand einen Fall — es waren + acht: Thema, Sprache, Format, Lizenz, Verfügbarkeit, Aktualisierungsfrequenz, Verwaltungsebene + und HVD-Kategorie. Erklärende Sätze sind geblieben, gestrichen wurde nur der Beispielteil. +- **„Kardinalität" heißt jetzt durchgängig „Multiplizität"** — den Begriff verwendet die + deutsche Spezifikation DCAT-AP.de. Betrifft 52 Stellen im Feld-Katalog, die daraus generierte + Feld-Referenz und `TECHNICAL-SPEC.md`. Dort auch die Spaltenabkürzung „Norm-Kard." → + „Norm-Mult.": Eine reine Wortersetzung hätte sie nicht erfasst, und eine Legende, die eine + Abkürzung auf ein anderes Wort auflöst, ist schlimmer als der alte Begriff. +- **Der neue Pflichtfeld-Wortlaut gilt jetzt überall.** Beim ersten Anlauf hatte ich nur die + Legende unter dem Formular geändert; „Als Entwurf können Sie jederzeit unvollständig + speichern" stand weiter in der Meldung nach blockierter Veröffentlichung, auf der + Einstiegsseite und im README. +- **Die Einstiegsseite versprach Beispiele, die es nicht mehr gibt.** „Jedes Feld hat hilfreiche + Beispiele, die Sie über das ⓘ-Symbol einblenden" stimmte nach dem Entfernen der acht Beispiele + nicht mehr. Der Satz benennt jetzt die tatsächliche Aufteilung: ⓘ zeigt den DCAT-AP-Begriff, + „Mehr erfahren" die ausführliche Erklärung. + +### 🧹 Aufgeräumt +- Zehn verwaiste Übersetzungseinträge entfernt, die durch die Textänderungen ohne Fundstelle + im Code zurückgeblieben waren. `bin/check-i18n.py` prüft nur auf fehlende, nicht auf + überzählige Einträge — die CI hätte das nicht gemeldet. + +--- + ## [2.40.2] — 2026-08-23 Zwei Rückmeldungen aus dem Backend. diff --git a/README.md b/README.md index 1da7bc91..d537bbaa 100644 --- a/README.md +++ b/README.md @@ -6,7 +6,7 @@

Lizenz - Version + Version DCAT-AP 3.0 PHP >= 8.1 WordPress 6.4+ @@ -85,12 +85,12 @@ Eigener Bereich im WordPress-Backend mit Übersicht, Filterung und Statusverwalt ### 😊 Benutzerfreundliche Formularsprache Das Wizard-Formular wurde vollständig überarbeitet, um es auch ohne DCAT-AP-Kenntnisse intuitiv zu machen: - **Klare Fragen statt technischer Begriffe:** Statt „Herausgebende Organisation (dct:publisher)" fragt das Plugin: „Wer gibt diese Daten heraus?" -- **Hilfreiche Beispiele:** Jedes Feld hat konkrete, praxisnahe Beispiele -- **Ursprüngliche Labels in Hilfetexten:** DCAT-AP Bezeichnungen und technische Details bleiben in den Hilfetexten sichtbar +- **Zwei Hilfen mit klaren Rollen:** Das ⓘ-Symbol zeigt den DCAT-AP-Begriff des Feldes — der schnelle Blick für alle, die wissen wollen, was das im Standard ist. „Mehr erfahren" klappt die ausführliche Erklärung auf: die DCAT-AP-Eigenschaft und ihre Multiplizität als Kurzangabe, darunter eine Erklärung in Alltagssprache mit Beispiel und die normkonforme Definition +- **Jede Information an genau einem Ort:** Dadurch können Kurzhilfe und Langtext sich nicht mehr widersprechen - **Validierungsmeldungen in Klartext, mit Ort:** Wird die Veröffentlichung blockiert, nennt die Meldung den Tab und den verständlichen Feldnamen (der technische DCAT-AP-Begriff steht nur klein daneben) — ein Klick auf „Zum Feld springen" öffnet den passenden Tab und hebt das Feld hervor ### 🧭 Geführter Wizard -Fünf-Tab-Assistent mit praktischen Beispielen. Pflichtfelder sind mit einem roten Sternchen (`*`) gekennzeichnet; als **Entwurf** lässt sich jederzeit unvollständig speichern — erst zum **Veröffentlichen** müssen alle Pflichtangaben ausgefüllt sein. +Fünf-Tab-Assistent mit praktischen Beispielen. Pflichtfelder sind mit einem roten Sternchen (`*`) gekennzeichnet; als **Entwurf** lässt sich der Datensatz jederzeit speichern — erst zum **Veröffentlichen** müssen alle Pflichtangaben ausgefüllt sein. 1. **Grundlegende Informationen** — „Wer gibt diese Daten heraus?", „Worum geht es in diesem Datensatz?", „Welchem Thema ist dieser Datensatz zugeordnet?", „Mit welchen Schlagworten finde ich diese Daten?". Weniger häufige Einordnungen (CESSDA-Themenklassifikation, ZiviZ-Engagementfeld) liegen in einer aufklappbaren Untergruppe am Tab-Ende. 2. **Sprache & Übersetzungen** — die Sprache der Daten sowie Titel, Beschreibung und Schlagworte in weiteren Sprachen diff --git a/TECHNICAL-SPEC.md b/TECHNICAL-SPEC.md index d4c9c38b..11ca66c2 100644 --- a/TECHNICAL-SPEC.md +++ b/TECHNICAL-SPEC.md @@ -40,7 +40,7 @@ Bausatz: | Baustein (piveau) | Inhalt | ODW-Pendant | |---|---|---| -| `input-definition.ts` | Alle Felder: Typ, DCAT-Prädikat, Kardinalität, Validierung, Vokabular | `config/dcat-ap-fields.php` (erweiterbar) | +| `input-definition.ts` | Alle Felder: Typ, DCAT-Prädikat, Multiplizität, Validierung, Vokabular | `config/dcat-ap-fields.php` (erweiterbar) | | `page-content-config.js` | Zuordnung Feld → Wizard-Schritt (Essentials/Additionals) | Tab-Zuordnung in `class-fields.php` | | `prefixes.js` | Namespace-Präfixe für JSON-LD | `odw_build_dataset_jsonld()` (`@context`) | | `vocab-prefixes.js` | Basis-URIs der kontrollierten Vokabulare | `dct-format-list.php`, `licenses.txt`, CESSDA-RDF | @@ -99,19 +99,22 @@ DCAT-AP verlangt für viele Felder URIs aus EU-Authority-Tables statt Freitext. | `corporate-body` | `http://publications.europa.eu/resource/authority/corporate-body/` | `dct:publisher` | ⚠️ Freitext | | `iana-media-types` | `https://www.iana.org/assignments/media-types/` | `dcat:mediaType` | ❌ | -> **Wiederverwendbares Muster:** Der bestehende CESSDA-Auto-Suggest (`odw-admin-fields.js` + SKOS/RDF) ist die -> Blaupause für ein generisches „Vokabular-Autosuggest"-Widget, das künftig `data-theme`, `access-right`, -> `planned-availability` etc. aus lokal gebündelten Vokabulardateien bedient (keine externe Abhängigkeit). +> **Muster nach Vokabulargröße (Stand v2.41.0):** Ein Vokabular mit überschaubar vielen Konzepten wird ein +> Auswahlfeld (`select`/`multiselect`, Optionen aus der gebündelten JSON-Datei) — `data-theme` (13), +> `engagementfeld` (16), `contributors` (69), `access-right` (3), `language` (24). Nur wo die Liste zu lang +> für ein Auswahlfeld ist, bleibt eine Vorschlagsliste: CESSDA mit mehreren hundert Konzepten. Diese Liste +> klappt seit v2.41.0 beim Anklicken auf (`odw-suggest` in `odw-admin-fields.js`) statt erst beim Tippen — +> ein `` verrät sonst nicht, dass es überhaupt eine Auswahl gibt. ### 4. Vollständiger DCAT-AP-Feldkatalog & Gap-Analyse **Legende** — Profil: `AP` = DCAT-AP 3.0 · `DE` = DCAT-AP.de 2.0 · `HVD` = High-Value-Dataset-Pflicht · -Norm-Kard.: Kardinalität laut Standard (`M`andatory/`R`ecommended/`O`ptional) · +Norm-Mult.: Multiplizität laut Standard (`M`andatory/`R`ecommended/`O`ptional) · ODW: ✅ vorhanden · ⚠️ teilweise/Freitext · ❌ fehlt. #### 4.1 Dataset (`dcat:Dataset`) -| DCAT-Prädikat | Range | Profil | Norm-Kard. | ODW | +| DCAT-Prädikat | Range | Profil | Norm-Mult. | ODW | |---|---|---|---|---| | `dct:title` | lang-Literal | AP | M (1..n) | ✅ | | `dct:description` | lang-Literal | AP | M (1..n) | ✅ | @@ -139,7 +142,7 @@ ODW: ✅ vorhanden · ⚠️ teilweise/Freitext · ❌ fehlt. | `dcatde:politicalGeocodingLevelURI` | URI | DE | R (DE) | ✅ | | `dcatde:politicalGeocodingURI` | URI | DE | O (0..n) | ✅ | | `dcatde:geocodingDescription` | lang-Literal | DE | O | ❌ | -| `dcatde:contributorID` | URI (`contributors`) | DE | R (DE) | ✅ (Autosuggest) | +| `dcatde:contributorID` | URI (`contributors`) | DE | R (DE) | ✅ (Auswahlfeld) | | `dcatde:legalBasis` | lang-Literal | DE | O | ✅ | | `dcatde:qualityProcessURI` | URI | DE | O | ✅ | | `dcatde:originator` / `dcatde:maintainer` | `foaf:Agent` | DE | O | ✅ | @@ -149,7 +152,7 @@ ODW: ✅ vorhanden · ⚠️ teilweise/Freitext · ❌ fehlt. #### 4.2 Distribution (`dcat:Distribution`) -| DCAT-Prädikat | Range | Profil | Norm-Kard. | ODW | +| DCAT-Prädikat | Range | Profil | Norm-Mult. | ODW | |---|---|---|---|---| | `dcat:accessURL` | URI | AP | M (1..n) | ✅ | | `dcat:downloadURL` | URI | AP | O (0..n) | ✅ | @@ -184,7 +187,7 @@ unterstützt; `dct:license`, `dct:language`, `dcat:themeTaxonomy` und `dct:spati Jeder Registry-Eintrag trägt die Basis-Schlüssel `key`, `meta_key`, `dcat_prop`, `label`, `points`, `required` sowie seit v2.5.1 die **deklarativen Schema-Metadaten** `profile`, `tier`, `range`, `cardinality`, `entity`, `vocab`. -Damit ist die Registry die dokumentierte Single Source of Truth für Pflichtigkeit, Kardinalität und Wertform +Damit ist die Registry die dokumentierte Single Source of Truth für Pflichtigkeit, Multiplizität und Wertform (wie piveaus `input-definition.ts`). Die Metadaten sind **abwärtskompatibel** — bestehende Konsumenten (Qualität, Validierung) lesen weiterhin nur die Basis-Schlüssel; das 0–100-Punkteschema bleibt unverändert. Eine Schema-Validierung sichert die Invarianten (`tests/test-registry-schema.php`): @@ -211,7 +214,7 @@ array( - `profile`/`tier`/`cardinality` steuern Validierung und Qualitäts-Scoring deklarativ. - `range` steuert die JSON-LD-Serialisierung (`uri` → `{"@id": …}`, `literal-lang` → `{"@value":…,"@language":…}`). -- `vocab` aktiviert das Vokabular-Autosuggest-Widget. +- `vocab` benennt das gebündelte Vokabular, aus dem die Optionen des Feldes stammen. - `tab`/`entity` steuern die automatische Einsortierung im Carbon-Fields-Formular. ### 6. Mapping piveau-FormKit → Carbon Fields @@ -223,7 +226,7 @@ array( | `text` / `simpleInput` | `Field::make( 'text', … )` | mit Sanitization | | `textarea` | `Field::make( 'textarea', … )` | | | `select` / `simpleSelect` | `Field::make( 'select', … )` | Optionen aus Vokabular | -| `auto` (Vokabular-Autocomplete) | `text` + Autosuggest-JS | CESSDA-Muster generalisieren | +| `auto` (Vokabular-Autocomplete) | `select`/`multiselect` aus dem Vokabular | Vorschlagsliste nur bei sehr großen Vokabularen (CESSDA) | | `repeatable` (group) | `Field::make( 'complex', … )` | wiederholbare Gruppen | | `group` / `formkitGroup` | `complex` (max. 1) | strukturierter Knoten | | `simpleConditional` | `text/select` + `->set_conditional_logic()` | Vokabular ODER manuell | @@ -248,7 +251,7 @@ Priorisiert nach Nutzen/Aufwand; jede Phase ist eigenständig auslieferbar. #### Phase B — DCAT-AP.de & Vokabulare (v2.5) — ✅ weitgehend umgesetzt - ✅ DCAT-AP.de-Felder: `dcatde:contributorID`, `dcatde:originator`, `dcatde:maintainer`, `dcatap:availability` (zzgl. `dcatde:politicalGeocodingLevelURI` aus v2.3). -- ✅ Generisches Vokabular-Autosuggest (`data-odw-vocab=""`) + lokal gebündelte Vokabulardateien unter `config/vocabularies/` (Start: `contributors`, 69 Einträge). +- ✅ Generisches Vokabular-Autosuggest (`data-odw-vocab=""`) + lokal gebündelte Vokabulardateien unter `config/vocabularies/` (Start: `contributors`, 69 Einträge). Das Autosuggest ist in v2.41.0 durch Auswahlfelder ersetzt worden (siehe Abschnitt 3); die Vokabulardateien sind geblieben. - ✅ DCAT-AP.de-Felder `politicalGeocodingURI`, `legalBasis`, `qualityProcessURI` (v2.6.0). - ✅ Gebündelte Vokabulare `access-right` (Feld `dct:accessRights`) und `data-theme` (Zusatz-Theme) (v2.7.0). - ☐ Offen (optional): vollständige EU-Sprachliste als Autosuggest (bewusst zurückgestellt). diff --git a/assets/css/admin.css b/assets/css/admin.css index 411d5c78..28840642 100644 --- a/assets/css/admin.css +++ b/assets/css/admin.css @@ -688,6 +688,48 @@ input.odw-cessda-input, word-break: break-all; } +/* ========================================================================= + Vorschlagsliste (odw-suggest) — klappt beim Anklicken auf + ========================================================================= */ + +/* Der Container umschliesst nur das Eingabefeld, damit die absolut + positionierte Liste genau darunter sitzt und nicht unter der Hinweiszeile. */ +.odw-suggest { + position: relative; +} + +.odw-suggest__list { + position: absolute; + z-index: 100; + top: 100%; + left: 0; + right: 0; + margin: 2px 0 0; + padding: 0; + max-height: 260px; + overflow-y: auto; + list-style: none; + background: var(--odw-color-primary-bg); + border: 1px solid var(--odw-color-border); + border-radius: 3px; + box-shadow: 0 2px 8px rgba(0, 0, 0, 0.12); +} + +.odw-suggest__option { + margin: 0; + padding: 6px 10px; + font-size: 13px; + line-height: 1.4; + color: var(--odw-color-text); + cursor: pointer; +} + +.odw-suggest__option:hover, +.odw-suggest__option.is-active { + background: var(--odw-color-primary); + color: #fff; +} + /* ========================================================================= License description (shown under the license select on selection) ========================================================================= */ @@ -1043,6 +1085,41 @@ input.odw-cessda-input, border-radius: 0 var(--odw-radius, 4px) var(--odw-radius, 4px) 0; } +/* Merkmalsliste über der Definition: zwei Spalten, damit Beschriftung und + Wert untereinander fluchten. Der Wert steht in Monospace — es sind + technische Bezeichner, keine Prosa. */ +.odw-field-more__facts { + display: grid; + grid-template-columns: max-content 1fr; + gap: 2px 10px; + margin: 0 0 10px; + padding: 0 0 8px; + border-bottom: 1px solid var(--odw-color-border, #c3c4c7); +} + +.odw-field-more__facts dt { + margin: 0; + color: var(--odw-color-text-muted, #50575e); +} + +.odw-field-more__facts dd { + margin: 0; + font-family: ui-monospace, SFMono-Regular, Menlo, Consolas, monospace; + color: var(--odw-color-text, #1d2327); +} + +.odw-field-more__spec { + display: inline-block; + margin-top: 2px; + color: var( --odw-color-primary, #2271b1 ); + text-decoration: none; +} + +.odw-field-more__spec:hover, +.odw-field-more__spec:focus-visible { + text-decoration: underline; +} + .odw-field-more__block { margin: 0 0 8px; line-height: 1.5; diff --git a/assets/js/odw-admin-fields.js b/assets/js/odw-admin-fields.js index 78f60e59..01589b58 100644 --- a/assets/js/odw-admin-fields.js +++ b/assets/js/odw-admin-fields.js @@ -4,7 +4,7 @@ * * Handles: * 1. Auto-suggest datalist for license_custom (inside distributions) - * 2. Auto-suggest datalist for CESSDA topic classification + * 2. Vorschlagsliste für die CESSDA-Themenklassifikation (öffnet beim Klick) * 3. Composite file-size widget (Zahl + Einheit → Bytes in backing field) * Widget HTML is built via JS so no CF html-field is needed inside * the complex field (CF5 React renderer crashes on html fields there). @@ -54,6 +54,144 @@ input.setAttribute( 'list', listId ); } + // ------------------------------------------------------------------------- + // Eigene Vorschlagsliste statt + // + // Ein natives datalist öffnet erst beim Tippen — bei mehreren hundert + // Konzepten (CESSDA) sieht man ohne Anfangsbuchstaben also gar nichts und + // muss raten, was überhaupt zur Auswahl steht. Diese Liste klappt beim + // Anklicken auf und grenzt beim Tippen ein. Nebeneffekt: Das Verhalten ist + // in allen Browsern dasselbe und im E2E-Test überhaupt prüfbar — ein + // datalist-Popup ist Browser-Chrome und für Playwright unsichtbar. + // + // @param {HTMLInputElement} input Sichtbares Eingabefeld. + // @param {Array} options Einträge mit label (und optional value). + // @param {Function} onPick Wird nach der Auswahl gerufen. + // ------------------------------------------------------------------------- + function attachSuggestList( input, options, onPick ) { + var list = document.createElement( 'ul' ); + list.className = 'odw-suggest__list'; + list.hidden = true; + list.setAttribute( 'role', 'listbox' ); + + // Eigener Container um genau das Eingabefeld: Die Liste wird absolut + // darunter positioniert, und im umgebenden Feld stehen noch Beschriftung + // und Hinweiszeile — an denen würde sie sonst hängen. + var host = document.createElement( 'div' ); + host.className = 'odw-suggest'; + input.parentNode.insertBefore( host, input ); + host.appendChild( input ); + host.appendChild( list ); + + var aktiv = -1; + + function sichtbare() { + return Array.prototype.slice.call( list.querySelectorAll( 'li:not([hidden])' ) ); + } + + function markiere( index ) { + var eintraege = sichtbare(); + eintraege.forEach( function ( li ) { + li.classList.remove( 'is-active' ); + } ); + aktiv = index; + if ( index >= 0 && eintraege[ index ] ) { + eintraege[ index ].classList.add( 'is-active' ); + eintraege[ index ].scrollIntoView( { block: 'nearest' } ); + } + } + + function schliesse() { + list.hidden = true; + input.setAttribute( 'aria-expanded', 'false' ); + markiere( -1 ); + } + + function oeffne() { + filtere(); + list.hidden = false; + input.setAttribute( 'aria-expanded', 'true' ); + } + + // Leeres Feld zeigt alles — genau der Fall, in dem die Liste gebraucht wird. + function filtere() { + var suche = input.value.trim().toLowerCase(); + var treffer = 0; + Array.prototype.forEach.call( list.children, function ( li ) { + var passt = '' === suche || li.textContent.toLowerCase().indexOf( suche ) !== -1; + li.hidden = ! passt; + if ( passt ) { + treffer++; + } + } ); + return treffer; + } + + options.forEach( function ( opt ) { + var li = document.createElement( 'li' ); + li.className = 'odw-suggest__option'; + li.textContent = opt.label; + li.setAttribute( 'role', 'option' ); + // mousedown statt click: Ein click käme erst nach dem blur des + // Eingabefelds — und das schließt die Liste, bevor der Treffer steht. + li.addEventListener( 'mousedown', function ( ev ) { + ev.preventDefault(); + setInputValue( input, opt.label ); + schliesse(); + if ( onPick ) { + onPick( opt ); + } + } ); + list.appendChild( li ); + } ); + + input.setAttribute( 'role', 'combobox' ); + input.setAttribute( 'aria-expanded', 'false' ); + input.setAttribute( 'autocomplete', 'off' ); + + input.addEventListener( 'focus', oeffne ); + input.addEventListener( 'click', oeffne ); + input.addEventListener( 'input', oeffne ); + input.addEventListener( 'blur', schliesse ); + + input.addEventListener( 'keydown', function ( ev ) { + if ( 'Escape' === ev.key ) { + schliesse(); + return; + } + if ( 'ArrowDown' !== ev.key && 'ArrowUp' !== ev.key && 'Enter' !== ev.key ) { + return; + } + if ( list.hidden ) { + if ( 'Enter' === ev.key ) { + return; + } + oeffne(); + } + var eintraege = sichtbare(); + if ( ! eintraege.length ) { + return; + } + if ( 'Enter' === ev.key ) { + if ( aktiv >= 0 && eintraege[ aktiv ] ) { + ev.preventDefault(); + // Der Klick-Handler trägt den Wert ein; hier reicht es, ihn auszulösen. + eintraege[ aktiv ].dispatchEvent( new MouseEvent( 'mousedown' ) ); + } + return; + } + ev.preventDefault(); + var naechster = 'ArrowDown' === ev.key ? aktiv + 1 : aktiv - 1; + if ( naechster < 0 ) { + naechster = eintraege.length - 1; + } + if ( naechster >= eintraege.length ) { + naechster = 0; + } + markiere( naechster ); + } ); + } + // ------------------------------------------------------------------------- // 1. License auto-suggest (inside distribution complex groups) // ------------------------------------------------------------------------- @@ -84,19 +222,6 @@ uriToLabel[ o.value ] = o.label; } ); - // Shared datalist of human-readable labels. - var listId = 'odw-cessda-label-datalist'; - if ( ! document.getElementById( listId ) ) { - var dl = document.createElement( 'datalist' ); - dl.id = listId; - opts.forEach( function ( o ) { - var el = document.createElement( 'option' ); - el.value = o.label; - dl.appendChild( el ); - } ); - document.body.appendChild( dl ); - } - document.querySelectorAll( 'input[data-odw-backing="cessda"]' ).forEach( function ( backing ) { if ( backing.dataset.odwCessdaInit ) { return; @@ -126,7 +251,6 @@ input.type = 'text'; input.className = 'odw-cessda-input'; input.placeholder = w.placeholder || ''; - input.setAttribute( 'list', listId ); var hint = document.createElement( 'span' ); hint.className = 'odw-cessda-hint description'; @@ -158,6 +282,10 @@ input.addEventListener( 'input', sync ); input.addEventListener( 'change', sync ); + + // Die Liste hängt am Eingabefeld — deshalb erst jetzt, wenn es im + // Dokument steht und einen Elternknoten zum Positionieren hat. + attachSuggestList( input, opts, sync ); } ); } @@ -218,32 +346,6 @@ } ); } - // ------------------------------------------------------------------------- - // 2d. Generic vocabulary auto-suggest — any input[data-odw-vocab=""] - // pulls its options from data.vocabularies[] (bundled JSON vocab). - // ------------------------------------------------------------------------- - function attachVocab( input ) { - var id = input.getAttribute( 'data-odw-vocab' ); - if ( ! id ) { - return; - } - var vocab = ( data.vocabularies || {} )[ id ]; - if ( ! vocab || ! vocab.length ) { - return; - } - // Suggest the human-readable label as the field value (so the user can - // type a name to filter in every browser and never sees a raw URI). The - // label→URI resolution happens server-side in odw_resolve_vocab_uri(). - var opts = vocab.map( function ( o ) { - return { value: o.label, label: '' }; - } ); - attachDatalist( input, 'odw-vocab-datalist-' + id, opts ); - } - - function initVocabAutosuggest() { - document.querySelectorAll( 'input[data-odw-vocab]' ).forEach( attachVocab ); - } - // ------------------------------------------------------------------------- // 2e. "Erweiterte Angaben für Profis" — collapse all Tab-4 fields after the // toggle into an opt-in section. Progressive enhancement: if JS is absent, @@ -574,6 +676,34 @@ return p; } + // Zwei Merkmale über der Definition: die DCAT-AP-Eigenschaft und die + // Multiplizität. Beide stehen bisher nur mitten im Fließtext — als eigene + // Zeilen sind sie auf einen Blick erfassbar. + function moreFacts( cfg, field ) { + var rows = [ + [ cfg.prop || 'Eigenschaft', field.dcat_prop ], + [ cfg.mult || 'Multiplizität', field.cardinality ] + ].filter( function ( row ) { + return row[ 1 ]; + } ); + + if ( ! rows.length ) { + return null; + } + + var dl = document.createElement( 'dl' ); + dl.className = 'odw-field-more__facts'; + rows.forEach( function ( row ) { + var dt = document.createElement( 'dt' ); + dt.textContent = row[ 0 ]; + var dd = document.createElement( 'dd' ); + dd.textContent = row[ 1 ]; + dl.appendChild( dt ); + dl.appendChild( dd ); + } ); + return dl; + } + function initFieldMore() { var cfg = data.fieldMore || {}; var catalog = data.fieldCatalog || []; @@ -605,12 +735,30 @@ // formale Definition allein keine Hilfe ist. var body = document.createElement( 'div' ); body.className = 'odw-field-more__body'; + var facts = moreFacts( cfg, f ); + if ( facts ) { + body.appendChild( facts ); + } if ( f.desc_human ) { body.appendChild( moreBlock( cfg.plain, f.desc_human ) ); } if ( f.desc_dcat ) { body.appendChild( moreBlock( cfg.dcat, f.desc_dcat ) ); } + if ( f.spec_url ) { + // Ein Link je Profil-Klasse, nicht je Feld: Die feldgenauen Anker + // der Spezifikation ließen sich nicht überprüfen — hier landet man + // im schlimmsten Fall am Anfang des richtigen Dokuments. + var names = cfg.ent || {}; + var link = document.createElement( 'a' ); + link.className = 'odw-field-more__spec'; + link.href = f.spec_url; + link.target = '_blank'; + link.rel = 'noopener noreferrer'; + link.textContent = ( cfg.spec || 'Im Standard nachlesen' ) + + ( names[ f.entity ] ? ': ' + names[ f.entity ] : '' ) + ' ↗'; + body.appendChild( link ); + } details.appendChild( body ); field.appendChild( details ); } ); @@ -902,7 +1050,6 @@ node.querySelectorAll( 'input[data-odw-backing="byte_size"]' ).forEach( function ( backing ) { initFileSizeWidget( backing ); } ); - node.querySelectorAll( 'input[data-odw-vocab]' ).forEach( attachVocab ); initHelpTooltips(); initFieldMore(); } ); @@ -920,7 +1067,6 @@ initLicenseInfo(); initCessdaWidget(); initSpatialAutosuggest(); - initVocabAutosuggest(); initProSection(); initFileSizeWidgets(); initHelpTooltips(); @@ -939,7 +1085,6 @@ initLicenseInfo(); initCessdaWidget(); initSpatialAutosuggest(); - initVocabAutosuggest(); initProSection(); initFileSizeWidgets(); initHelpTooltips(); diff --git a/bin/check-i18n.py b/bin/check-i18n.py index c419d02c..2533dc1d 100755 --- a/bin/check-i18n.py +++ b/bin/check-i18n.py @@ -37,6 +37,10 @@ def source_strings(): found = set() files = [os.path.join(ROOT, 'open-data-wizard.php')] files += sorted(glob.glob(os.path.join(ROOT, 'includes', '*.php'))) + # config/ ebenfalls: mqa-metrics.php und dcat-ap-fields.php führen ihre + # Labels über __(). Sie standen bis v2.41.0 nicht in dieser Liste — die + # Prüfung meldete für sie also nie eine fehlende Übersetzung. + files += sorted(glob.glob(os.path.join(ROOT, 'config', '*.php'))) for path in files: src = io.open(path, encoding='utf-8').read() diff --git a/config/dcat-ap-fields.php b/config/dcat-ap-fields.php index 5d2d3cfb..828a3cdd 100644 --- a/config/dcat-ap-fields.php +++ b/config/dcat-ap-fields.php @@ -17,7 +17,7 @@ * profile — 'ap' (DCAT-AP 3.0) | 'ap.de' (DCAT-AP.de) | 'hvd' (High-Value-Dataset) * tier — 'mandatory' | 'recommended' | 'optional' (vom Plugin erzwungene Stufe) * range — 'literal' | 'literal-lang' | 'uri' | 'node' (JSON-LD-Wertform) - * cardinality — '0..1' | '0..n' | '1..1' | '1..n' (Kardinalität laut Profil) + * cardinality — '0..1' | '0..n' | '1..1' | '1..n' (Multiplizität laut Profil) * entity — 'dataset' | 'distribution' | 'catalog' (Ziel-Entität) * vocab — ID eines kontrollierten Vokabulars (falls zutreffend), sonst '' * diff --git a/config/field-catalog.php b/config/field-catalog.php index 2539b224..93b75190 100644 --- a/config/field-catalog.php +++ b/config/field-catalog.php @@ -38,76 +38,88 @@ // ========================================================================= array( - 'key' => 'publisher', - 'meta_key' => '_odw_publisher', - 'dcat_prop' => 'dct:publisher', - 'tab' => '1 — Grundlegende Informationen', - 'tier' => 'mandatory', - 'vocab' => '', - 'q_dcat' => 'Welche Stelle ist `dct:publisher` (verantwortliche Herausgeberin) des Datensatzes?', - 'q_human' => 'Wer gibt diese Daten heraus?', - 'desc_dcat' => '`dct:publisher` benennt die für die Bereitstellung des Datensatzes verantwortliche Stelle (eine `foaf:Agent`-Entität). In DCAT-AP 3.0 ist die Angabe verpflichtend (Kardinalität 1..1). Idealerweise wird die Organisation über eine URI referenziert; als Minimalform genügt der Name (`foaf:name`).', - 'desc_human' => 'Tragen Sie hier die Organisation ein, die die Daten offiziell veröffentlicht — also wer dafür verantwortlich ist, dass die Daten bereitstehen. Das ist oft eine Behörde, ein Amt oder ein Verein. Beispiel: „Statistisches Landesamt Musterstadt" oder „Umweltbundesamt".', - ), - array( - 'key' => 'theme', - 'meta_key' => '_odw_theme', - 'dcat_prop' => 'dcat:theme', - 'tab' => '1 — Grundlegende Informationen', - 'tier' => 'recommended', - 'vocab' => 'data-theme', - 'q_dcat' => 'Welchem `dcat:theme` (Datenthema) ist der Datensatz zugeordnet?', - 'q_human' => 'Welchem Thema ist dieser Datensatz zugeordnet?', - 'desc_dcat' => '`dcat:theme` ordnet den Datensatz einer oder mehreren Kategorien zu. In DCAT-AP wird das kontrollierte EU-Vokabular „Data Theme" (`http://publications.europa.eu/resource/authority/data-theme/`) verwendet, z. B. `ENVI` (Umwelt) oder `EDUC` (Bildung). Kardinalität 0..n.', - 'desc_human' => 'Wählen Sie das Themengebiet, zu dem die Daten am besten passen — ähnlich einer Schublade, in die der Datensatz einsortiert wird. Das hilft anderen, Ihre Daten über Themenfilter zu finden. Beispiel: Umwelt, Bildung, Gesundheit, Wirtschaft, Kultur.', - ), - array( - 'key' => 'keywords', - 'meta_key' => '_odw_keywords', - 'dcat_prop' => 'dcat:keyword', - 'tab' => '1 — Grundlegende Informationen', - 'tier' => 'recommended', - 'vocab' => '', - 'q_dcat' => 'Welche `dcat:keyword` (Schlagwörter) beschreiben den Datensatz?', - 'q_human' => 'Mit welchen Schlagworten finde ich diese Daten?', - 'desc_dcat' => '`dcat:keyword` sind freie, sprachlich getaggte Schlagwörter zur Verbesserung der Auffindbarkeit (`literal-lang`, Kardinalität 0..n). Anders als `dcat:theme` sind sie nicht an ein kontrolliertes Vokabular gebunden. Je Schlagwort ein Wert.', - 'desc_human' => 'Tragen Sie einzelne Schlagwörter ein, unter denen man Ihre Daten suchen würde — jedes Wort in eine eigene Zeile. Sie ergänzen das Thema und machen die Daten leichter auffindbar. Beispiel: Umwelt, Wasser, Luftverschmutzung.', - ), - array( - 'key' => 'cessda_topic', - 'meta_key' => '_odw_cessda_topic', - 'dcat_prop' => 'dct:subject', - 'tab' => '1 — Grundlegende Informationen', - 'tier' => 'optional', - 'vocab' => 'cessda', - 'q_dcat' => 'Welches `dct:subject` (Fachthema) nach CESSDA-Vokabular beschreibt den Datensatz?', - 'q_human' => 'Welchem Themenfeld nach CESSDA ordnen Sie den Datensatz zu?', - 'desc_dcat' => '`dct:subject` verweist auf ein fachliches Thema aus einem kontrollierten Vokabular — hier die CESSDA Topic Classification (Version 4.2.3). Der Wert ist die Konzept-URI aus dem CESSDA-Vokabular. Mehrfachangabe möglich (Kardinalität 0..n); erscheint zusammen mit anderen Themenzuordnungen als Liste.', - 'desc_human' => 'Optional für sozial- und wirtschaftswissenschaftliche Daten: Ordnen Sie den Datensatz einem Fachthema aus dem CESSDA-Katalog zu (ein europäischer Standard für Forschungsdaten). Tippen Sie das Thema ein und wählen Sie aus der Vorschlagsliste. Beispiel: Volkszählungen, Migration, Wirtschaftspolitik.', - ), - array( - 'key' => 'engagementfeld', - 'meta_key' => '_odw_engagementfeld', - 'dcat_prop' => 'dct:subject', - 'tab' => '1 — Grundlegende Informationen', - 'tier' => 'optional', - 'vocab' => 'engagementfeld', - 'q_dcat' => 'Welches `dct:subject` (Engagementfeld) nach ZiviZ-Vokabular beschreibt den Datensatz?', - 'q_human' => 'Welchem Engagementfeld ist dieser Datensatz zuzuordnen?', - 'desc_dcat' => '`dct:subject` mit einem Konzept aus dem ZiviZ-Vokabular „Engagementfeld" (`https://ziviz.de/def/engagementfeld/`), das zivilgesellschaftliche Tätigkeitsfelder klassifiziert. Der Wert ist die Konzept-URI; die Label→URI-Auflösung erfolgt beim Speichern. Mehrfachangabe möglich (Kardinalität 0..n).', - 'desc_human' => 'Optional für Organisationen der Zivilgesellschaft: Ordnen Sie den Datensatz einem Engagementfeld zu — also dem gesellschaftlichen Bereich, in dem Sie aktiv sind. Wählen Sie einen Eintrag aus der Liste; die passende Kennung wird automatisch gesetzt. Beispiel: Kultur, Sport, Umwelt- und Naturschutz.', - ), - array( - 'key' => 'description', - 'meta_key' => '_odw_description', - 'dcat_prop' => 'dct:description', - 'tab' => '1 — Grundlegende Informationen', - 'tier' => 'mandatory', - 'vocab' => '', - 'q_dcat' => 'Wie lautet die `dct:description` (Freitextbeschreibung) des Datensatzes?', - 'q_human' => 'Worum geht es in diesem Datensatz?', - 'desc_dcat' => '`dct:description` ist eine frei formulierte, sprachlich getaggte Beschreibung des Datensatzes (`literal-lang`). In DCAT-AP 3.0 verpflichtend (Kardinalität 1..n je Sprache). Sie ergänzt den Titel um Inhalt, Kontext, Erhebungsmethode und Abgrenzung des Datensatzes.', - 'desc_human' => 'Beschreiben Sie in eigenen Worten, was in den Daten steckt: Worum geht es, was kann man damit machen, was ist enthalten? Ein bis zwei Absätze reichen. Beispiel: „Überblick über die bevölkerungsreichsten Städte Deutschlands mit Einwohnerzahlen und Entwicklung seit 2010."', + 'key' => 'publisher', + 'meta_key' => '_odw_publisher', + 'dcat_prop' => 'dct:publisher', + 'cardinality' => '1..1', + 'entity' => 'dataset', + 'tab' => '1 — Grundlegende Informationen', + 'tier' => 'mandatory', + 'vocab' => '', + 'q_dcat' => 'Welche Stelle ist `dct:publisher` (verantwortliche Herausgeberin) des Datensatzes?', + 'q_human' => 'Wer gibt diese Daten heraus?', + 'desc_dcat' => '`dct:publisher` benennt die für die Bereitstellung des Datensatzes verantwortliche Stelle (eine `foaf:Agent`-Entität). In DCAT-AP 3.0 ist die Angabe verpflichtend (Multiplizität 1..1). Idealerweise wird die Organisation über eine URI referenziert; als Minimalform genügt der Name (`foaf:name`).', + 'desc_human' => 'Tragen Sie hier die Organisation ein, die die Daten offiziell veröffentlicht — also wer dafür verantwortlich ist, dass die Daten bereitstehen. Das ist oft eine Behörde, ein Amt oder ein Verein. Beispiel: „Statistisches Landesamt Musterstadt" oder „Umweltbundesamt".', + ), + array( + 'key' => 'theme', + 'meta_key' => '_odw_theme', + 'dcat_prop' => 'dcat:theme', + 'cardinality' => '0..n', + 'entity' => 'dataset', + 'tab' => '1 — Grundlegende Informationen', + 'tier' => 'recommended', + 'vocab' => 'data-theme', + 'q_dcat' => 'Welchem `dcat:theme` (Datenthema) ist der Datensatz zugeordnet?', + 'q_human' => 'Welchen Themen ist dieser Datensatz zugeordnet?', + 'desc_dcat' => '`dcat:theme` ordnet den Datensatz einer oder mehreren Kategorien zu. In DCAT-AP wird das kontrollierte EU-Vokabular „Data Theme" (`http://publications.europa.eu/resource/authority/data-theme/`) verwendet, z. B. `ENVI` (Umwelt) oder `EDUC` (Bildung). Multiplizität 0..n.', + 'desc_human' => 'Wählen Sie ein oder mehrere Themengebiete, zu denen die Daten passen — ähnlich einer Schublade, in die der Datensatz einsortiert wird. Das hilft anderen, Ihre Daten über Themenfilter zu finden. Beispiel: Umwelt, Bildung, Gesundheit, Wirtschaft, Kultur.', + ), + array( + 'key' => 'keywords', + 'meta_key' => '_odw_keywords', + 'dcat_prop' => 'dcat:keyword', + 'cardinality' => '0..n', + 'entity' => 'dataset', + 'tab' => '1 — Grundlegende Informationen', + 'tier' => 'recommended', + 'vocab' => '', + 'q_dcat' => 'Welche `dcat:keyword` (Schlagwörter) beschreiben den Datensatz?', + 'q_human' => 'Mit welchen Schlagworten finde ich diese Daten?', + 'desc_dcat' => '`dcat:keyword` sind freie, sprachlich getaggte Schlagwörter zur Verbesserung der Auffindbarkeit (`literal-lang`, Multiplizität 0..n). Anders als `dcat:theme` sind sie nicht an ein kontrolliertes Vokabular gebunden. Je Schlagwort ein Wert.', + 'desc_human' => 'Tragen Sie einzelne Schlagwörter ein, unter denen man Ihre Daten suchen würde — jedes Wort in eine eigene Zeile. Sie ergänzen das Thema und machen die Daten leichter auffindbar. Beispiel: erst „Umwelt", darunter „Wasser", darunter „Luftverschmutzung". Trennen Sie die Schlagwörter nicht mit Komma.', + ), + array( + 'key' => 'cessda_topic', + 'meta_key' => '_odw_cessda_topic', + 'dcat_prop' => 'dct:subject', + 'cardinality' => '0..n', + 'entity' => 'dataset', + 'tab' => '1 — Grundlegende Informationen', + 'tier' => 'optional', + 'vocab' => 'cessda', + 'q_dcat' => 'Welches `dct:subject` (Fachthema) nach CESSDA-Vokabular beschreibt den Datensatz?', + 'q_human' => 'Welchem Themenfeld nach CESSDA ordnen Sie den Datensatz zu?', + 'desc_dcat' => '`dct:subject` verweist auf ein fachliches Thema aus einem kontrollierten Vokabular — hier die CESSDA Topic Classification (Version 4.2.3). Der Wert ist die Konzept-URI aus dem CESSDA-Vokabular. Mehrfachangabe möglich (Multiplizität 0..n); erscheint zusammen mit anderen Themenzuordnungen als Liste. Hinweis: `dct:subject` gehört nicht zum DCAT-AP.de-Profil — die offiziellen SHACL-Shapes kennen die Eigenschaft für Datensätze nicht. Als Dublin-Core-Angabe ist sie zulässig (RDF erlaubt zusätzliche Aussagen) und wird hier bewusst ausgegeben; streng profilkonforme Portale können sie ignorieren.', + 'desc_human' => 'Optional für sozial- und wirtschaftswissenschaftliche Daten: Ordnen Sie den Datensatz einem Fachthema aus dem CESSDA-Katalog zu (ein europäischer Standard für Forschungsdaten). Klicken Sie ins Feld, um die Vorschläge zu sehen, oder tippen Sie, um die Liste einzugrenzen. Beispiel: Volkszählungen, Migration, Wirtschaftspolitik.', + ), + array( + 'key' => 'engagementfeld', + 'meta_key' => '_odw_engagementfeld', + 'dcat_prop' => 'dct:subject', + 'cardinality' => '0..n', + 'entity' => 'dataset', + 'tab' => '1 — Grundlegende Informationen', + 'tier' => 'optional', + 'vocab' => 'engagementfeld', + 'q_dcat' => 'Welches `dct:subject` (Engagementfeld) nach ZiviZ-Vokabular beschreibt den Datensatz?', + 'q_human' => 'Welchen Engagementfeldern ist dieser Datensatz zuzuordnen?', + 'desc_dcat' => '`dct:subject` mit einem Konzept aus dem ZiviZ-Vokabular „Engagementfeld" (`https://ziviz.de/def/engagementfeld/`), das zivilgesellschaftliche Tätigkeitsfelder klassifiziert. Der Wert ist die Konzept-URI; die Label→URI-Auflösung erfolgt beim Speichern. Mehrfachangabe möglich (Multiplizität 0..n). Hinweis: `dct:subject` gehört nicht zum DCAT-AP.de-Profil — die offiziellen SHACL-Shapes kennen die Eigenschaft für Datensätze nicht. Als Dublin-Core-Angabe ist sie zulässig (RDF erlaubt zusätzliche Aussagen) und wird hier bewusst ausgegeben; streng profilkonforme Portale können sie ignorieren.', + 'desc_human' => 'Optional für Organisationen der Zivilgesellschaft: Ordnen Sie den Datensatz einem oder mehreren Engagementfeldern zu — also den gesellschaftlichen Bereichen, in denen Sie aktiv sind. Wählen Sie die Einträge in der Liste aus; die passenden Kennungen werden automatisch gesetzt. Beispiel: Kultur, Sport, Umwelt- und Naturschutz.', + ), + array( + 'key' => 'description', + 'meta_key' => '_odw_description', + 'dcat_prop' => 'dct:description', + 'cardinality' => '1..n', + 'entity' => 'dataset', + 'tab' => '1 — Grundlegende Informationen', + 'tier' => 'mandatory', + 'vocab' => '', + 'q_dcat' => 'Wie lautet die `dct:description` (Freitextbeschreibung) des Datensatzes?', + 'q_human' => 'Worum geht es in diesem Datensatz?', + 'desc_dcat' => '`dct:description` ist eine frei formulierte, sprachlich getaggte Beschreibung des Datensatzes (`literal-lang`). In DCAT-AP 3.0 verpflichtend (Multiplizität 1..n je Sprache). Sie ergänzt den Titel um Inhalt, Kontext, Erhebungsmethode und Abgrenzung des Datensatzes.', + 'desc_human' => 'Beschreiben Sie in eigenen Worten, was in den Daten steckt: Worum geht es, was kann man damit machen, was ist enthalten? Ein bis zwei Absätze reichen. Beispiel: „Überblick über die bevölkerungsreichsten Städte Deutschlands mit Einwohnerzahlen und Entwicklung seit 2010."', ), // ========================================================================= @@ -115,16 +127,18 @@ // ========================================================================= array( - 'key' => 'language', - 'meta_key' => '_odw_language', - 'dcat_prop' => 'dct:language', - 'tab' => '2 — Sprache & Übersetzungen', - 'tier' => 'recommended', - 'vocab' => 'language', - 'q_dcat' => 'In welcher `dct:language` (Sprache) liegen die Daten vor?', - 'q_human' => 'In welcher Sprache sind die Daten?', - 'desc_dcat' => '`dct:language` gibt die Sprache des Datensatzes an, referenziert über das EU-Authority-Vokabular „Language" (`http://publications.europa.eu/resource/authority/language/`, z. B. `DEU`, `ENG`). Kardinalität 0..n — mehrsprachige Datensätze können mehrere Sprachen angeben.', - 'desc_human' => 'Geben Sie an, in welcher Sprache die Inhalte der Daten verfasst sind (z. B. die Spaltenüberschriften und Texte). Das hilft Nutzenden einzuschätzen, ob sie die Daten verstehen. Beispiel: Deutsch, Englisch.', + 'key' => 'language', + 'meta_key' => '_odw_language', + 'dcat_prop' => 'dct:language', + 'cardinality' => '0..n', + 'entity' => 'dataset', + 'tab' => '2 — Sprache & Übersetzungen', + 'tier' => 'recommended', + 'vocab' => 'language', + 'q_dcat' => 'In welcher `dct:language` (Sprache) liegen die Daten vor?', + 'q_human' => 'In welcher Sprache sind die Daten?', + 'desc_dcat' => '`dct:language` gibt die Sprache des Datensatzes an, referenziert über das EU-Authority-Vokabular „Language" (`http://publications.europa.eu/resource/authority/language/`, z. B. `DEU`, `ENG`). Multiplizität 0..n — mehrsprachige Datensätze können mehrere Sprachen angeben.', + 'desc_human' => 'Geben Sie an, in welcher Sprache die Inhalte der Daten verfasst sind (z. B. die Spaltenüberschriften und Texte). Das hilft Nutzenden einzuschätzen, ob sie die Daten verstehen. Beispiel: Deutsch, Englisch.', ), // ========================================================================= @@ -132,88 +146,102 @@ // ========================================================================= array( - 'key' => 'access_url', - 'meta_key' => '_odw_access_url', - 'dcat_prop' => 'dcat:accessURL', - 'tab' => '3 — Datenbereitstellung', - 'tier' => 'mandatory', - 'vocab' => '', - 'q_dcat' => 'Unter welcher `dcat:accessURL` ist die Distribution erreichbar?', - 'q_human' => 'Wo kann man die Datei herunterladen oder ansehen?', - 'desc_dcat' => '`dcat:accessURL` verweist auf eine Ressource, über die auf die Distribution zugegriffen werden kann (Range `rdfs:Resource`, Kardinalität 1..n je Distribution). Sie kann auf eine Landing-Page, einen Feed, einen Endpunkt oder — bei direktem Download — dieselbe Ressource wie `dcat:downloadURL` zeigen. Pflichtangabe je Distribution.', - 'desc_human' => 'Tragen Sie den Link ein, unter dem Ihre Daten zu finden sind — die Adresse einer Datei zum Herunterladen oder einer Seite, auf der die Daten liegen. Alternativ laden Sie die Datei über die Mediathek-Box hoch; dann wird dieser Link automatisch gesetzt und Sie müssen ihn nicht selbst eintippen. Beispiel: https://beispiel.de/daten/statistik.csv.', - ), - array( - 'key' => 'format', - 'meta_key' => '_odw_format', - 'dcat_prop' => 'dct:format', - 'tab' => '3 — Datenbereitstellung', - 'tier' => 'recommended', - 'vocab' => 'file-type', - 'q_dcat' => 'Welches `dct:format` (Dateiformat) hat die Distribution?', - 'q_human' => 'In welchem Format ist die Datei?', - 'desc_dcat' => '`dct:format` gibt das Format der Distribution an, referenziert über das EU-Authority-Vokabular „File Type" (`http://publications.europa.eu/resource/authority/file-type/`, z. B. `CSV`, `JSON`, `PDF`). Kardinalität 0..1. Ergänzt `dcat:mediaType` (MIME-Typ) um das anwendungsnahe Format.', - 'desc_human' => 'Wählen Sie das Format der bereitgestellten Datei. Daran erkennen Nutzende, mit welchem Programm sie die Daten öffnen können. Maschinenlesbare, offene Formate wie CSV oder JSON sind besonders empfehlenswert. Beispiel: CSV, JSON, PDF.', - ), - array( - 'key' => 'byte_size', - 'meta_key' => '_odw_byte_size', - 'dcat_prop' => 'dcat:byteSize', - 'tab' => '3 — Datenbereitstellung', - 'tier' => 'optional', - 'vocab' => '', - 'q_dcat' => 'Wie groß ist die Distribution laut `dcat:byteSize` (in Bytes)?', - 'q_human' => 'Wie groß ist die Datei?', - 'desc_dcat' => '`dcat:byteSize` gibt die Größe der Distribution in Bytes als nicht-negative Ganzzahl an (`xsd:nonNegativeInteger`, Kardinalität 0..1). Bei einem Mediathek-Upload wird der Wert automatisch aus der Datei ermittelt.', - 'desc_human' => 'Die Dateigröße in Bytes — nur die reine Zahl. Nutzende sehen so vorab, wie viel sie herunterladen. Bei hochgeladenen Dateien wird die Größe automatisch berechnet. Beispiel: 2048576 (das sind rund 2 MB).', - ), - array( - 'key' => 'license', - 'meta_key' => '_odw_license', - 'dcat_prop' => 'dct:license', - 'tab' => '3 — Datenbereitstellung', - 'tier' => 'mandatory', - 'vocab' => 'licenses', - 'q_dcat' => 'Unter welcher `dct:license` (Lizenz) steht die Distribution?', - 'q_human' => 'Unter welcher Lizenz sind diese Daten verfügbar?', - 'desc_dcat' => '`dct:license` benennt das rechtliche Dokument, unter dem die Distribution bereitgestellt wird (Range `dct:LicenseDocument`, referenziert per URI). Verpflichtend für die Wiederverwendbarkeit. Empfohlen werden URIs offener Lizenzen (Creative Commons, Datenlizenz Deutschland, DCAT-AP.de-Lizenzregister).', - 'desc_human' => 'Legen Sie fest, was andere mit Ihren Daten tun dürfen — das regelt die Lizenz. Wählen Sie eine der vorgeschlagenen Standardlizenzen; „offene" Lizenzen erlauben die freie Weiternutzung. Ohne Lizenz sind Daten rechtlich unklar und kaum nachnutzbar. Beispiel: CC-BY 4.0 (Namensnennung).', - ), - array( - 'key' => 'license_custom', - 'meta_key' => '_odw_license_custom', - 'dcat_prop' => 'dct:license', - 'tab' => '3 — Datenbereitstellung', - 'tier' => 'conditional', - 'vocab' => 'licenses', - 'q_dcat' => 'Welche `dct:license`-URI gilt, wenn keine Standardlizenz zutrifft?', - 'q_human' => 'Welche eigene Lizenz-URI möchten Sie angeben?', - 'desc_dcat' => 'Nur relevant, wenn im Lizenzfeld „Sonstige" gewählt wurde: Hier wird die `dct:license`-URI einer nicht in der Standardliste enthaltenen Lizenz eingetragen. Das Auto-Suggest bietet zusätzlich die URIs des DCAT-AP.de-Lizenzregisters (`http://dcat-ap.de/def/licenses/…`) an.', - 'desc_human' => 'Dieses Feld erscheint nur, wenn Sie oben „Sonstige" Lizenz gewählt haben. Tragen Sie dann die Web-Adresse (URI) Ihrer Lizenz ein oder wählen Sie eine aus der Vorschlagsliste. Beispiel: http://dcat-ap.de/def/licenses/dl-by-de/2.0.', - ), - array( - 'key' => 'attribution_text', - 'meta_key' => '_odw_attribution_text', - 'dcat_prop' => 'dcatde:licenseAttributionByText', - 'tab' => '3 — Datenbereitstellung', - 'tier' => 'optional', - 'vocab' => '', - 'q_dcat' => 'Welcher `dcatde:licenseAttributionByText` (Namensnennungstext) ist bei Nachnutzung anzugeben?', - 'q_human' => 'Welcher Namensnennungstext soll bei Weiternutzung angegeben werden?', - 'desc_dcat' => '`dcatde:licenseAttributionByText` (DCAT-AP.de) enthält den exakten Namensnennungstext, den Nachnutzende bei Lizenzen mit Namensnennungspflicht (z. B. CC-BY, DL-DE-BY) zitieren müssen. Freitext (`literal`), Kardinalität 0..1.', - 'desc_human' => 'Bei Lizenzen mit Namensnennung („BY") geben Sie hier vor, wie andere Sie nennen sollen, wenn sie Ihre Daten verwenden. So bekommen Sie korrekt Credit. Beispiel: „Datenquelle: Stadt Musterstadt, 2026".', - ), - array( - 'key' => 'availability', - 'meta_key' => '_odw_availability', - 'dcat_prop' => 'dcatap:availability', - 'tab' => '3 — Datenbereitstellung', - 'tier' => 'optional', - 'vocab' => 'planned-availability', - 'q_dcat' => 'Welche `dcatap:availability` (Verfügbarkeitsgarantie) hat die Distribution?', - 'q_human' => 'Wie dauerhaft ist diese Datei verfügbar?', - 'desc_dcat' => '`dcatap:availability` beschreibt die geplante Verfügbarkeit einer Distribution über das EU-Vokabular „Planned Availability" (z. B. `AVAILABLE`, `TEMPORARY`, `EXPERIMENTAL`, `STABLE`). Kardinalität 0..1. Gibt Nachnutzenden Planungssicherheit.', - 'desc_human' => 'Geben Sie an, wie verlässlich die Datei langfristig erreichbar bleibt — dauerhaft, nur vorübergehend oder experimentell. Das hilft anderen einzuschätzen, ob sie sich auf den Link verlassen können. Beispiel: Dauerhaft verfügbar.', + 'key' => 'access_url', + 'meta_key' => '_odw_access_url', + 'dcat_prop' => 'dcat:accessURL', + 'cardinality' => '1..n', + 'entity' => 'distribution', + 'tab' => '3 — Datenbereitstellung', + 'tier' => 'mandatory', + 'vocab' => '', + 'q_dcat' => 'Unter welcher `dcat:accessURL` ist die Distribution erreichbar?', + 'q_human' => 'Wo kann man die Datei herunterladen oder ansehen?', + 'desc_dcat' => '`dcat:accessURL` verweist auf eine Ressource, über die auf die Distribution zugegriffen werden kann (Range `rdfs:Resource`, Multiplizität 1..n je Distribution). Sie kann auf eine Landing-Page, einen Feed, einen Endpunkt oder — bei direktem Download — dieselbe Ressource wie `dcat:downloadURL` zeigen. Pflichtangabe je Distribution.', + 'desc_human' => 'Tragen Sie den Link ein, unter dem Ihre Daten zu finden sind — die Adresse einer Datei zum Herunterladen oder einer Seite, auf der die Daten liegen. Alternativ laden Sie die Datei über die Mediathek-Box hoch; dann wird dieser Link automatisch gesetzt und Sie müssen ihn nicht selbst eintippen. Beispiel: https://beispiel.de/daten/statistik.csv.', + ), + array( + 'key' => 'format', + 'meta_key' => '_odw_format', + 'dcat_prop' => 'dct:format', + 'cardinality' => '0..1', + 'entity' => 'distribution', + 'tab' => '3 — Datenbereitstellung', + 'tier' => 'recommended', + 'vocab' => 'file-type', + 'q_dcat' => 'Welches `dct:format` (Dateiformat) hat die Distribution?', + 'q_human' => 'In welchem Format ist die Datei?', + 'desc_dcat' => '`dct:format` gibt das Format der Distribution an, referenziert über das EU-Authority-Vokabular „File Type" (`http://publications.europa.eu/resource/authority/file-type/`, z. B. `CSV`, `JSON`, `PDF`). Multiplizität 0..1. Ergänzt `dcat:mediaType` (MIME-Typ) um das anwendungsnahe Format.', + 'desc_human' => 'Wählen Sie das Format der bereitgestellten Datei. Daran erkennen Nutzende, mit welchem Programm sie die Daten öffnen können. Maschinenlesbare, offene Formate wie CSV oder JSON sind besonders empfehlenswert. Beispiel: CSV, JSON, PDF.', + ), + array( + 'key' => 'byte_size', + 'meta_key' => '_odw_byte_size', + 'dcat_prop' => 'dcat:byteSize', + 'cardinality' => '0..1', + 'entity' => 'distribution', + 'tab' => '3 — Datenbereitstellung', + 'tier' => 'optional', + 'vocab' => '', + 'q_dcat' => 'Wie groß ist die Distribution laut `dcat:byteSize` (in Bytes)?', + 'q_human' => 'Wie groß ist die Datei?', + 'desc_dcat' => '`dcat:byteSize` gibt die Größe der Distribution in Bytes als nicht-negative Ganzzahl an (`xsd:nonNegativeInteger`, Multiplizität 0..1). Bei einem Mediathek-Upload wird der Wert automatisch aus der Datei ermittelt.', + 'desc_human' => 'Die Dateigröße in Bytes — nur die reine Zahl. Nutzende sehen so vorab, wie viel sie herunterladen. Bei hochgeladenen Dateien wird die Größe automatisch berechnet. Beispiel: 2048576 (das sind rund 2 MB).', + ), + array( + 'key' => 'license', + 'meta_key' => '_odw_license', + 'dcat_prop' => 'dct:license', + 'cardinality' => '0..1', + 'entity' => 'distribution', + 'tab' => '3 — Datenbereitstellung', + 'tier' => 'mandatory', + 'vocab' => 'licenses', + 'q_dcat' => 'Unter welcher `dct:license` (Lizenz) steht die Distribution?', + 'q_human' => 'Unter welcher Lizenz sind diese Daten verfügbar?', + 'desc_dcat' => '`dct:license` benennt das rechtliche Dokument, unter dem die Distribution bereitgestellt wird (Range `dct:LicenseDocument`, referenziert per URI). Multiplizität 0..1 je Distribution; das Plugin erzwingt die Angabe, weil ohne Lizenz keine Nachnutzung möglich ist. Empfohlen werden URIs offener Lizenzen (Creative Commons, Datenlizenz Deutschland, DCAT-AP.de-Lizenzregister).', + 'desc_human' => 'Legen Sie fest, was andere mit Ihren Daten tun dürfen — das regelt die Lizenz. Wählen Sie eine der vorgeschlagenen Standardlizenzen; „offene" Lizenzen erlauben die freie Weiternutzung. Ohne Lizenz sind Daten rechtlich unklar und kaum nachnutzbar. Beispiel: CC-BY 4.0 (Namensnennung).', + ), + array( + 'key' => 'license_custom', + 'meta_key' => '_odw_license_custom', + 'dcat_prop' => 'dct:license', + 'cardinality' => '0..1', + 'entity' => 'distribution', + 'tab' => '3 — Datenbereitstellung', + 'tier' => 'conditional', + 'vocab' => 'licenses', + 'q_dcat' => 'Welche `dct:license`-URI gilt, wenn keine Standardlizenz zutrifft?', + 'q_human' => 'Welche eigene Lizenz-URI möchten Sie angeben?', + 'desc_dcat' => 'Nur relevant, wenn im Lizenzfeld „Sonstige" gewählt wurde: Hier wird die `dct:license`-URI einer nicht in der Standardliste enthaltenen Lizenz eingetragen. Das Auto-Suggest bietet zusätzlich die URIs des DCAT-AP.de-Lizenzregisters (`http://dcat-ap.de/def/licenses/…`) an. Multiplizität 0..1 je Distribution — es ist dieselbe Eigenschaft wie oben.', + 'desc_human' => 'Dieses Feld erscheint nur, wenn Sie oben „Sonstige" Lizenz gewählt haben. Tragen Sie dann die Web-Adresse (URI) Ihrer Lizenz ein oder wählen Sie eine aus der Vorschlagsliste. Beispiel: http://dcat-ap.de/def/licenses/dl-by-de/2.0.', + ), + array( + 'key' => 'attribution_text', + 'meta_key' => '_odw_attribution_text', + 'dcat_prop' => 'dcatde:licenseAttributionByText', + 'cardinality' => '0..1', + 'entity' => 'distribution', + 'tab' => '3 — Datenbereitstellung', + 'tier' => 'optional', + 'vocab' => '', + 'q_dcat' => 'Welcher `dcatde:licenseAttributionByText` (Namensnennungstext) ist bei Nachnutzung anzugeben?', + 'q_human' => 'Welcher Namensnennungstext soll bei Weiternutzung angegeben werden?', + 'desc_dcat' => '`dcatde:licenseAttributionByText` (DCAT-AP.de) enthält den exakten Namensnennungstext, den Nachnutzende bei Lizenzen mit Namensnennungspflicht (z. B. CC-BY, DL-DE-BY) zitieren müssen. Freitext (`literal`), Multiplizität 0..1.', + 'desc_human' => 'Bei Lizenzen mit Namensnennung („BY") geben Sie hier vor, wie andere Sie nennen sollen, wenn sie Ihre Daten verwenden. So bekommen Sie korrekt Credit. Beispiel: „Datenquelle: Stadt Musterstadt, 2026".', + ), + array( + 'key' => 'availability', + 'meta_key' => '_odw_availability', + 'dcat_prop' => 'dcatap:availability', + 'cardinality' => '0..1', + 'entity' => 'distribution', + 'tab' => '3 — Datenbereitstellung', + 'tier' => 'optional', + 'vocab' => 'planned-availability', + 'q_dcat' => 'Welche `dcatap:availability` (Verfügbarkeitsgarantie) hat die Distribution?', + 'q_human' => 'Wie dauerhaft ist diese Datei verfügbar?', + 'desc_dcat' => '`dcatap:availability` beschreibt die geplante Verfügbarkeit einer Distribution über das EU-Vokabular „Planned Availability" (z. B. `AVAILABLE`, `TEMPORARY`, `EXPERIMENTAL`, `STABLE`). Multiplizität 0..1. Gibt Nachnutzenden Planungssicherheit.', + 'desc_human' => 'Geben Sie an, wie verlässlich die Datei langfristig erreichbar bleibt — dauerhaft, nur vorübergehend oder experimentell. Das hilft anderen einzuschätzen, ob sie sich auf den Link verlassen können. Beispiel: Dauerhaft verfügbar.', ), // ========================================================================= @@ -221,476 +249,540 @@ // ========================================================================= array( - 'key' => 'landing_page', - 'meta_key' => '_odw_landing_page', - 'dcat_prop' => 'dcat:landingPage', - 'tab' => '4 — Erweiterte Angaben', - 'tier' => 'optional', - 'vocab' => '', - 'q_dcat' => 'Welche `dcat:landingPage` (Projekt-/Infoseite) gehört zum Datensatz?', - 'q_human' => 'Wo finde ich mehr Informationen zu diesem Projekt?', - 'desc_dcat' => '`dcat:landingPage` verweist auf eine menschenlesbare Webseite mit weiteren Informationen zum Datensatz (Range `foaf:Document`, Kardinalität 0..n). Anders als `dcat:accessURL` führt sie nicht direkt zu den Daten, sondern zu Kontext, Dokumentation oder Projektbeschreibung.', - 'desc_human' => 'Verlinken Sie eine Webseite, auf der man mehr über die Daten oder das Projekt erfährt — etwa eine Projekt- oder Dokumentationsseite. Das ist nicht der direkte Download, sondern die „Über uns"-Seite zu den Daten. Beispiel: https://beispiel.de/projekt.', - ), - array( - 'key' => 'issued', - 'meta_key' => '_odw_issued', - 'dcat_prop' => 'dct:issued', - 'tab' => '4 — Erweiterte Angaben', - 'tier' => 'recommended', - 'vocab' => '', - 'q_dcat' => 'Wann wurde der Datensatz `dct:issued` (erstveröffentlicht)?', - 'q_human' => 'Wann wurden diese Daten zum ersten Mal veröffentlicht?', - 'desc_dcat' => '`dct:issued` ist das Datum der formalen Erstveröffentlichung des Datensatzes, typisiert als `xsd:date` bzw. `xsd:dateTime`. Kardinalität 0..1. Nicht zu verwechseln mit `dct:modified` (letzte Änderung) oder dem Erhebungszeitraum (`dct:temporal`).', - 'desc_human' => 'Geben Sie das Datum an, an dem die Daten erstmals veröffentlicht wurden. Das ist der „Geburtstag" des Datensatzes, nicht der Zeitraum, den die Daten abdecken. Beispiel: 2024-01-15.', - ), - array( - 'key' => 'modified', - 'meta_key' => '_odw_modified', - 'dcat_prop' => 'dct:modified', - 'tab' => '4 — Erweiterte Angaben', - 'tier' => 'recommended', - 'vocab' => '', + 'key' => 'landing_page', + 'meta_key' => '_odw_landing_page', + 'dcat_prop' => 'dcat:landingPage', + 'cardinality' => '0..n', + 'entity' => 'dataset', + 'tab' => '4 — Erweiterte Angaben', + 'tier' => 'optional', + 'vocab' => '', + 'q_dcat' => 'Welche `dcat:landingPage` (Projekt-/Infoseite) gehört zum Datensatz?', + 'q_human' => 'Wo finde ich mehr Informationen zu diesem Projekt?', + 'desc_dcat' => '`dcat:landingPage` verweist auf eine menschenlesbare Webseite mit weiteren Informationen zum Datensatz (Range `foaf:Document`, Multiplizität 0..n). Anders als `dcat:accessURL` führt sie nicht direkt zu den Daten, sondern zu Kontext, Dokumentation oder Projektbeschreibung.', + 'desc_human' => 'Verlinken Sie eine Webseite, auf der man mehr über die Daten oder das Projekt erfährt — etwa eine Projekt- oder Dokumentationsseite. Das ist nicht der direkte Download, sondern die „Über uns"-Seite zu den Daten. Beispiel: https://beispiel.de/projekt.', + ), + array( + 'key' => 'issued', + 'meta_key' => '_odw_issued', + 'dcat_prop' => 'dct:issued', + 'cardinality' => '0..1', + 'entity' => 'dataset', + 'tab' => '4 — Erweiterte Angaben', + 'tier' => 'recommended', + 'vocab' => '', + 'q_dcat' => 'Wann wurde der Datensatz `dct:issued` (erstveröffentlicht)?', + 'q_human' => 'Wann wurden diese Daten zum ersten Mal veröffentlicht?', + 'desc_dcat' => '`dct:issued` ist das Datum der formalen Erstveröffentlichung des Datensatzes, typisiert als `xsd:date` bzw. `xsd:dateTime`. Multiplizität 0..1. Nicht zu verwechseln mit `dct:modified` (letzte Änderung) oder dem Erhebungszeitraum (`dct:temporal`).', + 'desc_human' => 'Geben Sie das Datum an, an dem die Daten erstmals veröffentlicht wurden. Das ist der „Geburtstag" des Datensatzes, nicht der Zeitraum, den die Daten abdecken. Beispiel: 2024-01-15.', + ), + array( + 'key' => 'modified', + 'meta_key' => '_odw_modified', + 'dcat_prop' => 'dct:modified', + 'cardinality' => '0..1', + 'entity' => 'dataset', + 'tab' => '4 — Erweiterte Angaben', + 'tier' => 'recommended', + 'vocab' => '', // Kein Formularfeld: Der Wert wird beim Speichern automatisch gesetzt. // Das Flag nimmt den Eintrag von der Formular-Abdeckungsprüfung aus, // ohne die Eigenschaft aus der Feld-Referenz zu entfernen — sie steht // weiterhin im veröffentlichten JSON-LD. - 'auto' => true, - 'q_dcat' => 'Wann wurde der Datensatz zuletzt `dct:modified` (geändert)?', - 'q_human' => 'Wann wurden diese Daten zuletzt aktualisiert?', - 'desc_dcat' => '`dct:modified` gibt das Datum der letzten inhaltlichen Änderung des Datensatzes an (`xsd:date`/`xsd:dateTime`, Kardinalität 0..1). Das Plugin setzt diesen Wert bei jeder Speicherung automatisch; ein Eingabefeld gibt es bewusst nicht, da eine manuelle Angabe beim nächsten Speichern überschrieben würde.', - 'desc_human' => 'Das Datum der letzten Aktualisierung. Es wird beim Speichern automatisch gesetzt, sodass Nutzende immer sehen, wie aktuell die Daten sind — Sie müssen dafür nichts eintragen. Beispiel: 2026-04-22.', - ), - array( - 'key' => 'accrual_periodicity', - 'meta_key' => '_odw_accrual_periodicity', - 'dcat_prop' => 'dct:accrualPeriodicity', - 'tab' => '4 — Erweiterte Angaben', - 'tier' => 'optional', - 'vocab' => 'frequency', - 'q_dcat' => 'Welche `dct:accrualPeriodicity` (Aktualisierungsfrequenz) hat der Datensatz?', - 'q_human' => 'Wie oft werden diese Daten aktualisiert?', - 'desc_dcat' => '`dct:accrualPeriodicity` gibt an, in welchem Rhythmus der Datensatz aktualisiert wird, referenziert über das EU-Vokabular „Frequency" (`http://publications.europa.eu/resource/authority/frequency/`, z. B. `DAILY`, `MONTHLY`, `ANNUAL`). Kardinalität 0..1.', - 'desc_human' => 'Geben Sie an, wie regelmäßig neue Daten hinzukommen — täglich, monatlich, jährlich oder unregelmäßig. Nutzende wissen dann, wie oft sich ein erneuter Blick lohnt. Beispiel: Jährlich.', - ), - array( - 'key' => 'political_geocoding_level', - 'meta_key' => '_odw_political_geocoding_level', - 'dcat_prop' => 'dcatde:politicalGeocodingLevelURI', - 'tab' => '4 — Erweiterte Angaben', - 'tier' => 'optional', - 'vocab' => 'politicalGeocodingLevel', - 'q_dcat' => 'Welche `dcatde:politicalGeocodingLevelURI` (Verwaltungsebene) betrifft der Datensatz?', - 'q_human' => 'Auf welcher Verwaltungsebene wurden diese Daten erhoben?', - 'desc_dcat' => '`dcatde:politicalGeocodingLevelURI` (DCAT-AP.de) klassifiziert die administrative Ebene des räumlichen Bezugs über das GovData-Vokabular (Bund, Land, Kreis, Kommune). Kardinalität 0..1. Ergänzt die konkrete Gebietsangabe.', - 'desc_human' => 'Wählen Sie, auf welcher staatlichen Ebene die Daten angesiedelt sind — Bund, Land, Kreis oder Kommune. Das ordnet die Daten geografisch-administrativ ein. Beispiel: Kommune.', - ), - array( - 'key' => 'political_geocoding_uri', - 'meta_key' => '_odw_political_geocoding_uri', - 'dcat_prop' => 'dcatde:politicalGeocodingURI', - 'tab' => '4 — Erweiterte Angaben', - 'tier' => 'optional', - 'vocab' => '', - 'q_dcat' => 'Welches `dcatde:politicalGeocodingURI` (amtliches Gebiet) beschreibt den räumlichen Bezug?', - 'q_human' => 'Auf welches amtliche Gebiet beziehen sich die Daten?', - 'desc_dcat' => '`dcatde:politicalGeocodingURI` (DCAT-AP.de) referenziert ein konkretes amtliches Gebiet über eine URI (z. B. amtlicher Regionalschlüssel/AGS als URI). Kardinalität 0..n. Ermöglicht die eindeutige, maschinenlesbare Verortung.', - 'desc_human' => 'Verlinken Sie das genaue amtliche Gebiet, auf das sich die Daten beziehen — als offizielle Kennung (z. B. Gemeindeschlüssel). Damit ist eindeutig, welche Region gemeint ist. Beispiel: die URI zum amtlichen Gemeindeschlüssel Ihrer Stadt.', - ), - array( - 'key' => 'geocoding_description', - 'meta_key' => '_odw_geocoding_description', - 'dcat_prop' => 'dcatde:geocodingDescription', - 'tab' => '4 — Erweiterte Angaben', - 'tier' => 'optional', - 'vocab' => '', - 'q_dcat' => 'Wie lautet die `dcatde:geocodingDescription` (textuelle Beschreibung des räumlichen Bezugs)?', - 'q_human' => 'Wie lässt sich der räumliche Bezug in Worten beschreiben?', - 'desc_dcat' => '`dcatde:geocodingDescription` (DCAT-AP.de) ist eine frei formulierte textuelle Beschreibung der räumlichen Abdeckung (`literal`/`literal-lang`). Kardinalität 0..n. Ergänzt die maschinenlesbaren Angaben `dct:spatial` und `dcatde:politicalGeocodingURI` um eine menschenlesbare Erläuterung.', - 'desc_human' => 'Beschreiben Sie den räumlichen Bezug zusätzlich in Worten — etwa wenn ein Gebietsschlüssel allein nicht genau genug ist. Das hilft Nutzenden, die Abdeckung einzuordnen. Beispiel: „Stadtgebiet Musterstadt ohne den Ortsteil X".', - ), - array( - 'key' => 'spatial', - 'meta_key' => '_odw_spatial', - 'dcat_prop' => 'dct:spatial', - 'tab' => '4 — Erweiterte Angaben', - 'tier' => 'optional', - 'vocab' => '', - 'q_dcat' => 'Welche `dct:spatial` (geografische Abdeckung) hat der Datensatz?', - 'q_human' => 'Welche geografische Region betreffen diese Daten?', - 'desc_dcat' => '`dct:spatial` beschreibt die räumliche Abdeckung des Datensatzes (Range `dct:Location`). Als Wert dient eine Gebiets-URI (z. B. GeoNames, EU-Continents) oder eine Freitext-Ortsangabe. Kardinalität 0..n.', - 'desc_human' => 'Geben Sie an, welches geografische Gebiet die Daten abdecken — eine Stadt, ein Bundesland, ein Land oder eine Region. So finden Nutzende Daten zu ihrer Gegend. Beispiel: Musterstadt oder Bayern.', - ), - array( - 'key' => 'temporal_start', - 'meta_key' => '_odw_temporal_start', - 'dcat_prop' => 'dct:temporal', - 'tab' => '4 — Erweiterte Angaben', - 'tier' => 'optional', - 'vocab' => '', - 'q_dcat' => 'Ab welchem `dct:temporal`-Startdatum gilt der Abdeckungszeitraum?', - 'q_human' => 'Ab wann sind diese Daten gültig?', - 'desc_dcat' => '`dct:temporal` beschreibt den Zeitraum, den die Daten inhaltlich abdecken (Range `dct:PeriodOfTime`). Dieses Feld liefert die Startangabe (`dcat:startDate`) des Intervalls. Kardinalität 0..1. Nicht zu verwechseln mit `dct:issued` (Veröffentlichung).', - 'desc_human' => 'Der Beginn des Zeitraums, den die Daten inhaltlich beschreiben — also ab wann die erfassten Werte gelten. Das ist der abgedeckte Zeitraum, nicht das Veröffentlichungsdatum. Beispiel: 2020-01-01.', - ), - array( - 'key' => 'temporal_end', - 'meta_key' => '_odw_temporal_end', - 'dcat_prop' => 'dct:temporal', - 'tab' => '4 — Erweiterte Angaben', - 'tier' => 'optional', - 'vocab' => '', - 'q_dcat' => 'Bis zu welchem `dct:temporal`-Enddatum gilt der Abdeckungszeitraum?', - 'q_human' => 'Bis wann sind diese Daten gültig?', - 'desc_dcat' => '`dct:temporal` liefert hier die Endangabe (`dcat:endDate`) des abgedeckten Zeitintervalls (Range `dct:PeriodOfTime`). Kardinalität 0..1. Zusammen mit dem Startdatum ergibt sich der vollständige Abdeckungszeitraum.', - 'desc_human' => 'Das Ende des Zeitraums, den die Daten abdecken — bis wann die erfassten Werte reichen. Bleibt das Feld leer, gilt der Zeitraum als offen (bis heute fortlaufend). Beispiel: 2025-12-31.', - ), - array( - 'key' => 'contact_name', - 'meta_key' => '_odw_contact_name', - 'dcat_prop' => 'dcat:contactPoint', - 'tab' => '4 — Erweiterte Angaben', - 'tier' => 'optional', - 'vocab' => '', - 'q_dcat' => 'Wie lautet der `vcard:fn` (Name) des `dcat:contactPoint`?', - 'q_human' => 'Wer ist Ansprechperson für Fragen zu diesen Daten?', - 'desc_dcat' => 'Teil des `dcat:contactPoint` (Range `vcard:Kind`): `vcard:fn` benennt die Kontaktstelle oder -person für Rückfragen zum Datensatz. Kardinalität des Kontaktpunkts 0..n. Name, E-Mail und URL bilden zusammen einen Kontaktpunkt.', - 'desc_human' => 'Nennen Sie, an wen sich Nutzende bei Fragen wenden können — eine Person oder eine Abteilung. So ist klar, wer für die Daten zuständig ist. Beispiel: Open-Data-Team der Stadt Musterstadt.', - ), - array( - 'key' => 'contact_email', - 'meta_key' => '_odw_contact_email', - 'dcat_prop' => 'dcat:contactPoint', - 'tab' => '4 — Erweiterte Angaben', - 'tier' => 'optional', - 'vocab' => '', - 'q_dcat' => 'Welche `vcard:hasEmail` gehört zum `dcat:contactPoint`?', - 'q_human' => 'Unter welcher E-Mail-Adresse kann ich Fragen stellen?', - 'desc_dcat' => 'Teil des `dcat:contactPoint`: `vcard:hasEmail` liefert die E-Mail-Adresse der Kontaktstelle (als `mailto:`-URI serialisiert). Kardinalität 0..1 je Kontaktpunkt.', - 'desc_human' => 'Die E-Mail-Adresse, unter der man Fragen zu den Daten stellen kann. Das ist der einfachste Weg für Nachnutzende, Sie zu erreichen. Beispiel: opendata@musterstadt.de.', - ), - array( - 'key' => 'contact_url', - 'meta_key' => '_odw_contact_url', - 'dcat_prop' => 'dcat:contactPoint', - 'tab' => '4 — Erweiterte Angaben', - 'tier' => 'optional', - 'vocab' => '', - 'q_dcat' => 'Welche `vcard:hasURL` gehört zum `dcat:contactPoint`?', - 'q_human' => 'Auf welcher Website finde ich weitere Kontaktinformationen?', - 'desc_dcat' => 'Teil des `dcat:contactPoint`: `vcard:hasURL` verweist auf eine Webseite mit weiteren Kontaktinformationen der zuständigen Stelle. Kardinalität 0..1 je Kontaktpunkt.', - 'desc_human' => 'Verlinken Sie optional eine Kontakt- oder Impressumsseite mit weiteren Wegen, Sie zu erreichen. Ergänzt E-Mail und Name um eine Anlaufstelle im Web. Beispiel: https://musterstadt.de/kontakt.', - ), - array( - 'key' => 'contributor_id', - 'meta_key' => '_odw_contributor_id', - 'dcat_prop' => 'dcatde:contributorID', - 'tab' => '4 — Erweiterte Angaben', - 'tier' => 'optional', - 'vocab' => 'contributors', - 'q_dcat' => 'Welche `dcatde:contributorID` (bereitstellende Stelle) gilt im GovData-Verbund?', - 'q_human' => 'Welche Stelle stellt diese Daten im GovData-Verbund bereit?', - 'desc_dcat' => '`dcatde:contributorID` (DCAT-AP.de) ist die offizielle Kennung der im GovData-Verbund bereitstellenden Stelle, referenziert über das gebündelte Contributors-Vokabular. Kardinalität 0..n. Dient der Zuordnung im nationalen Metadatenverbund.', - 'desc_human' => 'Nur für Stellen, die im deutschen GovData-Verbund veröffentlichen: Wählen Sie Ihre Stelle aus der Liste; die zugehörige offizielle Kennung wird automatisch verwendet. Für die meisten Nutzenden ist dieses Feld nicht relevant. Beispiel: Bundesministerium des Innern.', - ), - array( - 'key' => 'originator_name', - 'meta_key' => '_odw_originator_name', - 'dcat_prop' => 'dcatde:originator', - 'tab' => '4 — Erweiterte Angaben', - 'tier' => 'optional', - 'vocab' => '', - 'q_dcat' => 'Wer ist `dcatde:originator` (ursprünglicher Urheber) der Daten?', - 'q_human' => 'Wer hat diese Daten ursprünglich erstellt?', - 'desc_dcat' => '`dcatde:originator` (DCAT-AP.de) benennt die Stelle, von der die Daten ursprünglich stammen (Range `foaf:Agent`). Kann von Herausgeber (`dct:publisher`) und Ersteller (`dct:creator`) abweichen. Kardinalität 0..n.', - 'desc_human' => 'Nennen Sie die Stelle, von der die Daten ursprünglich stammen — das kann eine andere sein als die, die sie jetzt veröffentlicht. So bleibt die Herkunft nachvollziehbar. Beispiel: Statistisches Landesamt.', - ), - array( - 'key' => 'originator_email', - 'meta_key' => '_odw_originator_email', - 'dcat_prop' => 'dcatde:originator', - 'tab' => '4 — Erweiterte Angaben', - 'tier' => 'optional', - 'vocab' => '', - 'q_dcat' => 'Welche E-Mail-Adresse gehört zum `dcatde:originator`?', - 'q_human' => 'Wie lautet die E-Mail-Adresse des Urhebers?', - 'desc_dcat' => 'Ergänzt `dcatde:originator` um eine E-Mail-Adresse des ursprünglichen Urhebers (als `mailto:`-URI). Optional, Kardinalität 0..1.', - 'desc_human' => 'Optional die E-Mail-Adresse der ursprünglichen Urheber-Stelle, falls abweichend erreichbar. Beispiel: statistik@landesamt.de.', - ), - array( - 'key' => 'maintainer_name', - 'meta_key' => '_odw_maintainer_name', - 'dcat_prop' => 'dcatde:maintainer', - 'tab' => '4 — Erweiterte Angaben', - 'tier' => 'optional', - 'vocab' => '', - 'q_dcat' => 'Wer ist `dcatde:maintainer` (pflegende Stelle) der Daten?', - 'q_human' => 'Wer pflegt diese Daten laufend?', - 'desc_dcat' => '`dcatde:maintainer` (DCAT-AP.de) benennt die für die laufende Pflege und Aktualisierung zuständige Stelle (Range `foaf:Agent`). Kardinalität 0..n. Kann von Herausgeber und Urheber abweichen.', - 'desc_human' => 'Nennen Sie, wer die Daten laufend betreut und aktuell hält. Das ist die Stelle, die sich um Updates kümmert — nicht unbedingt die, die sie erstellt hat. Beispiel: Open-Data-Team.', - ), - array( - 'key' => 'maintainer_email', - 'meta_key' => '_odw_maintainer_email', - 'dcat_prop' => 'dcatde:maintainer', - 'tab' => '4 — Erweiterte Angaben', - 'tier' => 'optional', - 'vocab' => '', - 'q_dcat' => 'Welche E-Mail-Adresse gehört zum `dcatde:maintainer`?', - 'q_human' => 'Wie lautet die E-Mail-Adresse der pflegenden Stelle?', - 'desc_dcat' => 'Ergänzt `dcatde:maintainer` um eine E-Mail-Adresse der pflegenden Stelle (als `mailto:`-URI). Optional, Kardinalität 0..1.', - 'desc_human' => 'Optional die E-Mail-Adresse der Stelle, die die Daten pflegt. Beispiel: opendata@beispiel.de.', - ), - array( - 'key' => 'legal_basis', - 'meta_key' => '_odw_legal_basis', - 'dcat_prop' => 'dcatde:legalBasis', - 'tab' => '4 — Erweiterte Angaben', - 'tier' => 'optional', - 'vocab' => '', - 'q_dcat' => 'Auf welcher `dcatde:legalBasis` (Rechtsgrundlage) beruht die Bereitstellung?', - 'q_human' => 'Auf welcher rechtlichen Grundlage werden die Daten bereitgestellt?', - 'desc_dcat' => '`dcatde:legalBasis` (DCAT-AP.de) nennt das Gesetz oder die Verordnung, die die Bereitstellung der Daten regelt (Freitext, `literal`). Kardinalität 0..n.', - 'desc_human' => 'Falls es eine gesetzliche Grundlage für die Veröffentlichung gibt, nennen Sie sie hier. Das schafft Transparenz über die rechtliche Verpflichtung oder Erlaubnis. Beispiel: § 12a EGovG (E-Government-Gesetz).', - ), - array( - 'key' => 'quality_process_uri', - 'meta_key' => '_odw_quality_process_uri', - 'dcat_prop' => 'dcatde:qualityProcessURI', - 'tab' => '4 — Erweiterte Angaben', - 'tier' => 'optional', - 'vocab' => '', - 'q_dcat' => 'Welche `dcatde:qualityProcessURI` dokumentiert das Qualitätssicherungs-Verfahren?', - 'q_human' => 'Wo ist das Qualitätssicherungs-Verfahren dokumentiert?', - 'desc_dcat' => '`dcatde:qualityProcessURI` (DCAT-AP.de) verweist per URI auf eine Beschreibung des Qualitätssicherungs-Prozesses des Datensatzes. Kardinalität 0..1.', - 'desc_human' => 'Verlinken Sie optional eine Seite, die beschreibt, wie Sie die Qualität der Daten sichern (z. B. Prüfschritte). Das stärkt das Vertrauen in Ihre Daten. Beispiel: https://beispiel.de/qualitaetssicherung.', - ), - array( - 'key' => 'access_rights', - 'meta_key' => '_odw_access_rights', - 'dcat_prop' => 'dct:accessRights', - 'tab' => '4 — Erweiterte Angaben', - 'tier' => 'optional', - 'vocab' => 'access-right', - 'q_dcat' => 'Welche `dct:accessRights` (Zugriffsklassifikation) gelten für den Datensatz?', - 'q_human' => 'Wer darf auf diese Daten zugreifen?', - 'desc_dcat' => '`dct:accessRights` klassifiziert den Zugriffsstatus über das EU-Vokabular „Access Right" (`PUBLIC`, `RESTRICTED`, `NON_PUBLIC`). Kardinalität 0..1. Relevant für die MQA-Dimension Wiederverwendbarkeit.', - 'desc_human' => 'Geben Sie an, ob die Daten für alle offen (öffentlich), nur eingeschränkt oder gar nicht öffentlich zugänglich sind. Für offene Daten ist das in der Regel „öffentlich". Beispiel: Öffentlich.', - ), - array( - 'key' => 'theme_uri', - 'meta_key' => '_odw_theme_uri', - 'dcat_prop' => 'dcat:theme', - 'tab' => '4 — Erweiterte Angaben', - 'tier' => 'optional', - 'vocab' => 'data-theme', - 'q_dcat' => 'Welches zusätzliche `dcat:theme` (EU-Themen-URI) gilt für den Datensatz?', - 'q_human' => 'Welches weitere EU-Thema möchten Sie ergänzen?', - 'desc_dcat' => 'Zusätzliches `dcat:theme` als direkte EU-Themen-URI (`http://publications.europa.eu/resource/authority/data-theme/…`). Ergänzt die Themen-Auswahl aus Tab 1 um weitere Themen. Kardinalität 0..n.', - 'desc_human' => 'Falls Ihr Datensatz zu mehr als einem Thema passt, ergänzen Sie hier ein weiteres EU-Thema aus der Vorschlagsliste. Das erhöht die Auffindbarkeit über mehrere Themenfilter. Beispiel: Umwelt zusätzlich zu Gesundheit.', - ), - array( - 'key' => 'is_hvd', - 'meta_key' => '_odw_is_hvd', - 'dcat_prop' => 'dcatap:applicableLegislation', - 'tab' => '4 — Erweiterte Angaben', - 'tier' => 'optional', - 'vocab' => '', - 'q_dcat' => 'Ist der Datensatz ein High-Value-Dataset nach `dcatap:applicableLegislation` (EU-VO 2023/138)?', - 'q_human' => 'Ist dies ein hochwertiger Datensatz (HVD)?', - 'desc_dcat' => 'Kennzeichen, ob der Datensatz ein High-Value-Dataset im Sinne der EU-Durchführungsverordnung 2023/138 ist. Ist es gesetzt, wird `dcatap:applicableLegislation` (Verweis auf die Verordnung) ausgegeben und das Feld HVD-Kategorie relevant.', - 'desc_human' => '„High-Value-Datasets" sind von der EU als besonders wertvoll eingestufte Datensätze (z. B. Geo-, Umwelt- oder Mobilitätsdaten). Setzen Sie dies nur, wenn Ihr Datensatz in eine der offiziellen HVD-Kategorien fällt — im Zweifel „Nein". Beispiel: Ja, bei amtlichen Geodaten.', - ), - array( - 'key' => 'hvd_category', - 'meta_key' => '_odw_hvd_category', - 'dcat_prop' => 'dcatap:hvdCategory', - 'tab' => '4 — Erweiterte Angaben', - 'tier' => 'optional', - 'vocab' => 'hvd-category', - 'q_dcat' => 'Welcher `dcatap:hvdCategory` (HVD-Kategorie) gehört der Datensatz an?', - 'q_human' => 'Welcher HVD-Kategorie gehört dieser Datensatz an?', - 'desc_dcat' => '`dcatap:hvdCategory` ordnet ein High-Value-Dataset einer der sechs HVD-Kategorien der EU zu (Geospatial, Erdbeobachtung/Umwelt, Meteorologie, Statistik, Unternehmen, Mobilität), referenziert per EU-URI. Nur relevant, wenn HVD gesetzt ist. Kardinalität 0..n.', - 'desc_human' => 'Wenn es ein hochwertiger Datensatz ist, wählen Sie hier die passende der sechs EU-HVD-Kategorien. Damit ordnen Sie den Datensatz korrekt in das EU-Schema ein. Beispiel: Georaum, Mobilität, Statistik.', - ), - array( - 'key' => 'identifier', - 'meta_key' => '_odw_identifier', - 'dcat_prop' => 'dct:identifier', - 'tab' => '4 — Erweiterte Angaben', - 'tier' => 'optional', - 'vocab' => '', - 'q_dcat' => 'Welcher `dct:identifier` (eindeutige Kennung) identifiziert den Datensatz?', - 'q_human' => 'Welche eindeutige Kennung hat dieser Datensatz?', - 'desc_dcat' => '`dct:identifier` ist eine eindeutige, im System der Herausgeberin vergebene Kennung des Datensatzes (Freitext/`literal`). Kardinalität 0..n. Ermöglicht die stabile Referenzierung über Systemgrenzen hinweg.', - 'desc_human' => 'Falls Ihr Datensatz eine feste Kennnummer aus Ihrem eigenen System hat, tragen Sie sie hier ein. So bleibt der Datensatz eindeutig identifizierbar. Beispiel: DS-2026-00042.', - ), - array( - 'key' => 'type', - 'meta_key' => '_odw_type', - 'dcat_prop' => 'dct:type', - 'tab' => '4 — Erweiterte Angaben', - 'tier' => 'optional', - 'vocab' => 'dataset-type', - 'q_dcat' => 'Welchen `dct:type` (Datensatz-Typ) hat der Datensatz?', - 'q_human' => 'Um welchen Typ von Datensatz handelt es sich?', - 'desc_dcat' => '`dct:type` klassifiziert die Art des Datensatzes, idealerweise über das EU-Vokabular „Dataset Type". Kardinalität 0..1. Unterscheidet z. B. Erhebungsdaten, Registerdaten oder Geodaten.', - 'desc_human' => 'Geben Sie an, um welche Art von Datensatz es sich grundsätzlich handelt. Das hilft bei der groben Einordnung. Beispiel: Statistische Erhebung, Geodaten.', - ), - array( - 'key' => 'creator_name', - 'meta_key' => '_odw_creator_name', - 'dcat_prop' => 'dct:creator', - 'tab' => '4 — Erweiterte Angaben', - 'tier' => 'optional', - 'vocab' => '', - 'q_dcat' => 'Wer ist `dct:creator` (Ersteller) des Datensatzes?', - 'q_human' => 'Wer hat diese Daten erstellt?', - 'desc_dcat' => '`dct:creator` benennt die primär für die Erstellung des Datensatzes verantwortliche Stelle oder Person (Range `foaf:Agent`). Kardinalität 0..n. Unterscheidet sich vom Herausgeber (`dct:publisher`), der für die Bereitstellung verantwortlich ist.', - 'desc_human' => 'Nennen Sie, wer die Daten inhaltlich erstellt hat — die Person oder Stelle, die die eigentliche Arbeit gemacht hat. Das kann von der herausgebenden Organisation abweichen. Beispiel: Forschungsgruppe Stadtklima.', - ), - array( - 'key' => 'creator_email', - 'meta_key' => '_odw_creator_email', - 'dcat_prop' => 'dct:creator', - 'tab' => '4 — Erweiterte Angaben', - 'tier' => 'optional', - 'vocab' => '', - 'q_dcat' => 'Welche E-Mail-Adresse gehört zum `dct:creator`?', - 'q_human' => 'Wie lautet die E-Mail-Adresse des Erstellers?', - 'desc_dcat' => 'Ergänzt `dct:creator` um eine E-Mail-Adresse der erstellenden Stelle (als `mailto:`-URI). Optional, Kardinalität 0..1.', - 'desc_human' => 'Optional die E-Mail-Adresse der erstellenden Person oder Stelle. Beispiel: forschung@beispiel.de.', - ), - array( - 'key' => 'version', - 'meta_key' => '_odw_version', - 'dcat_prop' => 'owl:versionInfo', - 'tab' => '4 — Erweiterte Angaben', - 'tier' => 'optional', - 'vocab' => '', - 'q_dcat' => 'Welche `owl:versionInfo` (Versionsbezeichnung) hat der Datensatz?', - 'q_human' => 'Welche Version hat dieser Datensatz?', - 'desc_dcat' => '`owl:versionInfo` gibt die Versionsbezeichnung des Datensatzes als Freitext an (`literal`). Kardinalität 0..1. Erlaubt die Unterscheidung aufeinanderfolgender Ausgaben desselben Datensatzes.', - 'desc_human' => 'Falls es mehrere Ausgaben Ihrer Daten gibt, tragen Sie die Versionsnummer ein. So wissen Nutzende, welche Fassung sie vor sich haben. Beispiel: 2.0.', - ), - array( - 'key' => 'version_notes', - 'meta_key' => '_odw_version_notes', - 'dcat_prop' => 'adms:versionNotes', - 'tab' => '4 — Erweiterte Angaben', - 'tier' => 'optional', - 'vocab' => '', - 'q_dcat' => 'Welche `adms:versionNotes` (Änderungshinweise) beschreiben diese Version?', - 'q_human' => 'Was hat sich in dieser Version geändert?', - 'desc_dcat' => '`adms:versionNotes` beschreibt die Änderungen gegenüber der Vorversion als sprachlich getaggten Freitext (`literal-lang`). Kardinalität 0..n. Ergänzt `owl:versionInfo` um den inhaltlichen Änderungsverlauf.', - 'desc_human' => 'Beschreiben Sie kurz, was sich gegenüber der letzten Version geändert hat — wie ein Änderungsprotokoll. Nutzende sehen so, ob sich ein erneuter Download lohnt. Beispiel: „Daten für 2025 ergänzt, Tippfehler korrigiert."', - ), - array( - 'key' => 'spatial_resolution', - 'meta_key' => '_odw_spatial_resolution', - 'dcat_prop' => 'dcat:spatialResolutionInMeters', - 'tab' => '4 — Erweiterte Angaben', - 'tier' => 'optional', - 'vocab' => '', - 'q_dcat' => 'Welche `dcat:spatialResolutionInMeters` (räumliche Auflösung) haben die Daten?', - 'q_human' => 'Welche räumliche Auflösung haben die Daten (in Metern)?', - 'desc_dcat' => '`dcat:spatialResolutionInMeters` gibt die kleinste räumlich unterscheidbare Einheit in Metern an (`xsd:decimal`). Kardinalität 0..n. Relevant vor allem für Geodaten und Rasterdaten.', - 'desc_human' => 'Bei Geodaten: Geben Sie an, wie fein die Daten räumlich aufgelöst sind — der kleinste unterscheidbare Abstand in Metern. Ein kleiner Wert bedeutet detailliertere Daten. Beispiel: 10 (Raster von 10 Metern).', - ), - array( - 'key' => 'temporal_resolution', - 'meta_key' => '_odw_temporal_resolution', - 'dcat_prop' => 'dcat:temporalResolution', - 'tab' => '4 — Erweiterte Angaben', - 'tier' => 'optional', - 'vocab' => '', - 'q_dcat' => 'Welche `dcat:temporalResolution` (zeitliche Auflösung) haben die Daten?', - 'q_human' => 'Welche zeitliche Auflösung haben die Daten?', - 'desc_dcat' => '`dcat:temporalResolution` gibt die kleinste zeitlich unterscheidbare Einheit als ISO-8601-Dauer an (`xsd:duration`). Kardinalität 0..1. Beschreibt z. B. den Messabstand einer Zeitreihe.', - 'desc_human' => 'Bei Zeitreihen: Geben Sie an, in welchem zeitlichen Abstand die Werte erfasst sind — z. B. stündlich, täglich, monatlich. Format ist die ISO-8601-Dauer. Beispiel: P1D (ein Tag) oder PT1H (eine Stunde).', - ), - array( - 'key' => 'conforms_to', - 'meta_key' => '_odw_conforms_to', - 'dcat_prop' => 'dct:conformsTo', - 'tab' => '4 — Erweiterte Angaben', - 'tier' => 'optional', - 'vocab' => '', - 'q_dcat' => 'Welchem `dct:conformsTo` (Standard/Schema) entsprechen die Daten?', - 'q_human' => 'Welchem Standard oder Schema entsprechen die Daten?', - 'desc_dcat' => '`dct:conformsTo` verweist auf einen implementierten Standard, ein Anwendungsprofil oder ein Schema, dem die Daten entsprechen (Range `dct:Standard`, per URI oder Bezeichnung). Kardinalität 0..n.', - 'desc_human' => 'Falls Ihre Daten einem bestimmten Standard oder Schema folgen, nennen Sie ihn hier. So können Systeme die Daten korrekt interpretieren. Beispiel: INSPIRE, XÖV oder ein fachliches Datenschema.', - ), - array( - 'key' => 'provenance', - 'meta_key' => '_odw_provenance', - 'dcat_prop' => 'dct:provenance', - 'tab' => '4 — Erweiterte Angaben', - 'tier' => 'optional', - 'vocab' => '', - 'q_dcat' => 'Welche `dct:provenance` (Herkunft/Entstehung) hat der Datensatz?', - 'q_human' => 'Woher stammen die Daten und wie sind sie entstanden?', - 'desc_dcat' => '`dct:provenance` beschreibt die Herkunft und Entstehungsgeschichte des Datensatzes (Range `dct:ProvenanceStatement`, Freitext). Kardinalität 0..n. Dokumentiert Erhebungs- und Verarbeitungsschritte.', - 'desc_human' => 'Beschreiben Sie, woher die Daten kommen und wie sie entstanden sind — z. B. aus welcher Erhebung oder welchem Verfahren. Das macht die Daten nachvollziehbar und vertrauenswürdig. Beispiel: „Erhoben im Rahmen der Bürgerbefragung 2025, anonymisiert aufbereitet."', - ), - array( - 'key' => 'dist_title', - 'meta_key' => '_odw_dist_title', - 'dcat_prop' => 'dct:title', - 'tab' => '4 — Erweiterte Angaben', - 'tier' => 'optional', - 'vocab' => '', - 'q_dcat' => 'Wie lautet der `dct:title` der Distribution?', - 'q_human' => 'Wie heißt die bereitgestellte Datei/Distribution?', - 'desc_dcat' => '`dct:title` auf Ebene der Distribution benennt die konkrete bereitgestellte Ressource (`literal-lang`). Kardinalität 0..n. Nützlich, wenn der Distributionsname vom Datensatztitel abweicht.', - 'desc_human' => 'Geben Sie der bereitgestellten Datei einen eigenen Namen, falls er sich vom Titel des Datensatzes unterscheidet. Beispiel: „Rohdaten CSV 2025".', - ), - array( - 'key' => 'dist_description', - 'meta_key' => '_odw_dist_description', - 'dcat_prop' => 'dct:description', - 'tab' => '4 — Erweiterte Angaben', - 'tier' => 'optional', - 'vocab' => '', - 'q_dcat' => 'Wie lautet die `dct:description` der Distribution?', - 'q_human' => 'Wie lässt sich die Distribution beschreiben?', - 'desc_dcat' => '`dct:description` auf Distributionsebene beschreibt die konkrete Datei/Ressource (`literal-lang`). Kardinalität 0..n. Ergänzt die Datensatzbeschreibung um distributionsspezifische Hinweise (z. B. Spaltenaufbau).', - 'desc_human' => 'Beschreiben Sie die konkrete Datei näher — etwa welche Spalten sie enthält oder wie sie aufgebaut ist. Das hilft beim direkten Umgang mit der Datei. Beispiel: „Spalten: Jahr, Stadt, Einwohner; Trennzeichen Semikolon."', - ), - array( - 'key' => 'download_url', - 'meta_key' => '_odw_download_url', - 'dcat_prop' => 'dcat:downloadURL', - 'tab' => '4 — Erweiterte Angaben', - 'tier' => 'optional', - 'vocab' => '', - 'q_dcat' => 'Unter welcher `dcat:downloadURL` ist die Datei direkt herunterladbar?', - 'q_human' => 'Wie lautet der direkte Download-Link zur Datei?', - 'desc_dcat' => '`dcat:downloadURL` verweist auf eine direkt herunterladbare Datei (Range `rdfs:Resource`). Anders als `dcat:accessURL` garantiert sie einen unmittelbaren Download derselben Ressource. Kardinalität 0..n. Relevant für die MQA-Dimension Zugänglichkeit.', - 'desc_human' => 'Falls es einen direkten Link gibt, der die Datei sofort herunterlädt (ohne Umweg über eine Seite), tragen Sie ihn hier ein. Das ist der bequemste Weg für Nachnutzende. Beispiel: https://beispiel.de/daten/statistik.csv.', - ), - array( - 'key' => 'media_type', - 'meta_key' => '_odw_media_type', - 'dcat_prop' => 'dcat:mediaType', - 'tab' => '4 — Erweiterte Angaben', - 'tier' => 'optional', - 'vocab' => 'iana-media-type', - 'q_dcat' => 'Welchen `dcat:mediaType` (IANA-MIME-Typ) hat die Distribution?', - 'q_human' => 'Welchen Medientyp (MIME) hat die Datei?', - 'desc_dcat' => '`dcat:mediaType` gibt den Medientyp der Distribution als IANA-Media-Type an (z. B. `text/csv`, `application/json`), referenziert über das IANA-Media-Types-Register. Kardinalität 0..1. Ergänzt `dct:format` um den technischen MIME-Typ.', - 'desc_human' => 'Der technische Medientyp der Datei (MIME-Typ) — die maschinenlesbare Entsprechung zum Format. Systeme erkennen daran, wie sie die Datei behandeln müssen. Beispiel: text/csv, application/json.', - ), - array( - 'key' => 'dist_rights', - 'meta_key' => '_odw_dist_rights', - 'dcat_prop' => 'dct:rights', - 'tab' => '4 — Erweiterte Angaben', - 'tier' => 'optional', - 'vocab' => '', - 'q_dcat' => 'Welche `dct:rights` (Nutzungsrechte) gelten für die Distribution?', - 'q_human' => 'Welche Nutzungsrechte gelten für die Datei?', - 'desc_dcat' => '`dct:rights` beschreibt rechtliche Hinweise zur Distribution jenseits der Lizenz — etwa Urheberrechts- oder Zugriffsvermerke (Range `dct:RightsStatement`, Freitext oder URI). Kardinalität 0..1.', - 'desc_human' => 'Ergänzende rechtliche Hinweise zur Datei, die über die Lizenz hinausgehen — z. B. Urheberrechtsvermerke. Für viele offene Datensätze bleibt das leer. Beispiel: „© Stadt Musterstadt 2026".', + 'auto' => true, + 'q_dcat' => 'Wann wurde der Datensatz zuletzt `dct:modified` (geändert)?', + 'q_human' => 'Wann wurden diese Daten zuletzt aktualisiert?', + 'desc_dcat' => '`dct:modified` gibt das Datum der letzten inhaltlichen Änderung des Datensatzes an (`xsd:date`/`xsd:dateTime`, Multiplizität 0..1). Das Plugin setzt diesen Wert bei jeder Speicherung automatisch; ein Eingabefeld gibt es bewusst nicht, da eine manuelle Angabe beim nächsten Speichern überschrieben würde.', + 'desc_human' => 'Das Datum der letzten Aktualisierung. Es wird beim Speichern automatisch gesetzt, sodass Nutzende immer sehen, wie aktuell die Daten sind — Sie müssen dafür nichts eintragen. Beispiel: 2026-04-22.', + ), + array( + 'key' => 'accrual_periodicity', + 'meta_key' => '_odw_accrual_periodicity', + 'dcat_prop' => 'dct:accrualPeriodicity', + 'cardinality' => '0..1', + 'entity' => 'dataset', + 'tab' => '4 — Erweiterte Angaben', + 'tier' => 'optional', + 'vocab' => 'frequency', + 'q_dcat' => 'Welche `dct:accrualPeriodicity` (Aktualisierungsfrequenz) hat der Datensatz?', + 'q_human' => 'Wie oft werden diese Daten aktualisiert?', + 'desc_dcat' => '`dct:accrualPeriodicity` gibt an, in welchem Rhythmus der Datensatz aktualisiert wird, referenziert über das EU-Vokabular „Frequency" (`http://publications.europa.eu/resource/authority/frequency/`, z. B. `DAILY`, `MONTHLY`, `ANNUAL`). Multiplizität 0..1.', + 'desc_human' => 'Geben Sie an, wie regelmäßig neue Daten hinzukommen — täglich, monatlich, jährlich oder unregelmäßig. Nutzende wissen dann, wie oft sich ein erneuter Blick lohnt. Beispiel: Jährlich.', + ), + array( + 'key' => 'political_geocoding_level', + 'meta_key' => '_odw_political_geocoding_level', + 'dcat_prop' => 'dcatde:politicalGeocodingLevelURI', + 'cardinality' => '0..1', + 'entity' => 'dataset', + 'tab' => '4 — Erweiterte Angaben', + 'tier' => 'optional', + 'vocab' => 'politicalGeocodingLevel', + 'q_dcat' => 'Welche `dcatde:politicalGeocodingLevelURI` (Verwaltungsebene) betrifft der Datensatz?', + 'q_human' => 'Auf welcher Verwaltungsebene wurden diese Daten erhoben?', + 'desc_dcat' => '`dcatde:politicalGeocodingLevelURI` (DCAT-AP.de) klassifiziert die administrative Ebene des räumlichen Bezugs über das GovData-Vokabular; im Formular wählbar als Bund, Land, Landkreis und Gemeinde. Multiplizität 0..1. Ergänzt die konkrete Gebietsangabe.', + 'desc_human' => 'Wählen Sie, auf welcher staatlichen Ebene die Daten angesiedelt sind — Bund, Land, Landkreis oder Gemeinde. Das ordnet die Daten geografisch-administrativ ein. Beispiel: Gemeinde.', + ), + array( + 'key' => 'political_geocoding_uri', + 'meta_key' => '_odw_political_geocoding_uri', + 'dcat_prop' => 'dcatde:politicalGeocodingURI', + 'cardinality' => '0..n', + 'entity' => 'dataset', + 'tab' => '4 — Erweiterte Angaben', + 'tier' => 'optional', + 'vocab' => '', + 'q_dcat' => 'Welches `dcatde:politicalGeocodingURI` (amtliches Gebiet) beschreibt den räumlichen Bezug?', + 'q_human' => 'Auf welches amtliche Gebiet beziehen sich die Daten?', + 'desc_dcat' => '`dcatde:politicalGeocodingURI` (DCAT-AP.de) referenziert ein konkretes amtliches Gebiet über eine URI (z. B. amtlicher Regionalschlüssel/AGS als URI). Multiplizität 0..n. Ermöglicht die eindeutige, maschinenlesbare Verortung.', + 'desc_human' => 'Verlinken Sie das genaue amtliche Gebiet, auf das sich die Daten beziehen — als offizielle Kennung (z. B. Gemeindeschlüssel). Damit ist eindeutig, welche Region gemeint ist. Beispiel: die URI zum amtlichen Gemeindeschlüssel Ihrer Stadt.', + ), + array( + 'key' => 'geocoding_description', + 'meta_key' => '_odw_geocoding_description', + 'dcat_prop' => 'dcatde:geocodingDescription', + 'cardinality' => '0..n', + 'entity' => 'dataset', + 'tab' => '4 — Erweiterte Angaben', + 'tier' => 'optional', + 'vocab' => '', + 'q_dcat' => 'Wie lautet die `dcatde:geocodingDescription` (textuelle Beschreibung des räumlichen Bezugs)?', + 'q_human' => 'Wie lässt sich der räumliche Bezug in Worten beschreiben?', + 'desc_dcat' => '`dcatde:geocodingDescription` (DCAT-AP.de) ist eine frei formulierte textuelle Beschreibung der räumlichen Abdeckung (`literal`/`literal-lang`). Multiplizität 0..n. Ergänzt die maschinenlesbaren Angaben `dct:spatial` und `dcatde:politicalGeocodingURI` um eine menschenlesbare Erläuterung.', + 'desc_human' => 'Beschreiben Sie den räumlichen Bezug zusätzlich in Worten — etwa wenn ein Gebietsschlüssel allein nicht genau genug ist. Das hilft Nutzenden, die Abdeckung einzuordnen. Beispiel: „Stadtgebiet Musterstadt ohne den Ortsteil X".', + ), + array( + 'key' => 'spatial', + 'meta_key' => '_odw_spatial', + 'dcat_prop' => 'dct:spatial', + 'cardinality' => '0..n', + 'entity' => 'dataset', + 'tab' => '4 — Erweiterte Angaben', + 'tier' => 'optional', + 'vocab' => '', + 'q_dcat' => 'Welche `dct:spatial` (geografische Abdeckung) hat der Datensatz?', + 'q_human' => 'Welche geografische Region betreffen diese Daten?', + 'desc_dcat' => '`dct:spatial` beschreibt die räumliche Abdeckung des Datensatzes (Range `dct:Location`). Als Wert dient eine Gebiets-URI (z. B. GeoNames, EU-Continents) oder eine Freitext-Ortsangabe. Multiplizität 0..n.', + 'desc_human' => 'Geben Sie an, welches geografische Gebiet die Daten abdecken — eine Stadt, ein Bundesland, ein Land oder eine Region. So finden Nutzende Daten zu ihrer Gegend. Beispiel: Musterstadt oder Bayern. Wählen Sie die Region aus der Vorschlagsliste — dann wird die passende Kennung automatisch gesetzt — oder tippen Sie das Gebiet einfach selbst ein.', + ), + array( + 'key' => 'temporal_start', + 'meta_key' => '_odw_temporal_start', + 'dcat_prop' => 'dct:temporal', + 'cardinality' => '0..1', + 'entity' => 'dataset', + 'tab' => '4 — Erweiterte Angaben', + 'tier' => 'optional', + 'vocab' => '', + 'q_dcat' => 'Ab welchem `dct:temporal`-Startdatum gilt der Abdeckungszeitraum?', + 'q_human' => 'Ab wann sind diese Daten gültig?', + 'desc_dcat' => '`dct:temporal` beschreibt den Zeitraum, den die Daten inhaltlich abdecken (Range `dct:PeriodOfTime`). Dieses Feld liefert die Startangabe (`dcat:startDate`) des Intervalls. Multiplizität 0..1. Nicht zu verwechseln mit `dct:issued` (Veröffentlichung).', + 'desc_human' => 'Der Beginn des Zeitraums, den die Daten inhaltlich beschreiben — also ab wann die erfassten Werte gelten. Das ist der abgedeckte Zeitraum, nicht das Veröffentlichungsdatum. Beispiel: 2020-01-01.', + ), + array( + 'key' => 'temporal_end', + 'meta_key' => '_odw_temporal_end', + 'dcat_prop' => 'dct:temporal', + 'cardinality' => '0..1', + 'entity' => 'dataset', + 'tab' => '4 — Erweiterte Angaben', + 'tier' => 'optional', + 'vocab' => '', + 'q_dcat' => 'Bis zu welchem `dct:temporal`-Enddatum gilt der Abdeckungszeitraum?', + 'q_human' => 'Bis wann sind diese Daten gültig?', + 'desc_dcat' => '`dct:temporal` liefert hier die Endangabe (`dcat:endDate`) des abgedeckten Zeitintervalls (Range `dct:PeriodOfTime`). Multiplizität 0..1. Zusammen mit dem Startdatum ergibt sich der vollständige Abdeckungszeitraum.', + 'desc_human' => 'Das Ende des Zeitraums, den die Daten abdecken — bis wann die erfassten Werte reichen. Bleibt das Feld leer, gilt der Zeitraum als offen (bis heute fortlaufend). Beispiel: 2025-12-31.', + ), + array( + 'key' => 'contact_name', + 'meta_key' => '_odw_contact_name', + 'dcat_prop' => 'dcat:contactPoint', + 'cardinality' => '0..1', + 'entity' => 'dataset', + 'tab' => '4 — Erweiterte Angaben', + 'tier' => 'optional', + 'vocab' => '', + 'q_dcat' => 'Wie lautet der `vcard:fn` (Name) des `dcat:contactPoint`?', + 'q_human' => 'Wer ist Ansprechperson für Fragen zu diesen Daten?', + 'desc_dcat' => 'Teil des `dcat:contactPoint` (Range `vcard:Kind`): `vcard:fn` benennt die Kontaktstelle oder -person für Rückfragen zum Datensatz. Multiplizität 0..1 je Kontaktpunkt; ein Datensatz kann mehrere Kontaktpunkte tragen (0..n). Name, E-Mail und URL bilden zusammen einen Kontaktpunkt.', + 'desc_human' => 'Nennen Sie, an wen sich Nutzende bei Fragen wenden können — eine Person oder eine Abteilung. So ist klar, wer für die Daten zuständig ist. Beispiel: Open-Data-Team der Stadt Musterstadt.', + ), + array( + 'key' => 'contact_email', + 'meta_key' => '_odw_contact_email', + 'dcat_prop' => 'dcat:contactPoint', + 'cardinality' => '0..1', + 'entity' => 'dataset', + 'tab' => '4 — Erweiterte Angaben', + 'tier' => 'optional', + 'vocab' => '', + 'q_dcat' => 'Welche `vcard:hasEmail` gehört zum `dcat:contactPoint`?', + 'q_human' => 'Unter welcher E-Mail-Adresse kann ich Fragen stellen?', + 'desc_dcat' => 'Teil des `dcat:contactPoint`: `vcard:hasEmail` liefert die E-Mail-Adresse der Kontaktstelle (als `mailto:`-URI serialisiert). Multiplizität 0..1 je Kontaktpunkt.', + 'desc_human' => 'Die E-Mail-Adresse, unter der man Fragen zu den Daten stellen kann. Das ist der einfachste Weg für Nachnutzende, Sie zu erreichen. Beispiel: opendata@musterstadt.de.', + ), + array( + 'key' => 'contact_url', + 'meta_key' => '_odw_contact_url', + 'dcat_prop' => 'dcat:contactPoint', + 'cardinality' => '0..1', + 'entity' => 'dataset', + 'tab' => '4 — Erweiterte Angaben', + 'tier' => 'optional', + 'vocab' => '', + 'q_dcat' => 'Welche `vcard:hasURL` gehört zum `dcat:contactPoint`?', + 'q_human' => 'Auf welcher Website finde ich weitere Kontaktinformationen?', + 'desc_dcat' => 'Teil des `dcat:contactPoint`: `vcard:hasURL` verweist auf eine Webseite mit weiteren Kontaktinformationen der zuständigen Stelle. Multiplizität 0..1 je Kontaktpunkt.', + 'desc_human' => 'Verlinken Sie optional eine Kontakt- oder Impressumsseite mit weiteren Wegen, Sie zu erreichen. Ergänzt E-Mail und Name um eine Anlaufstelle im Web. Beispiel: https://musterstadt.de/kontakt.', + ), + array( + 'key' => 'contributor_id', + 'meta_key' => '_odw_contributor_id', + 'dcat_prop' => 'dcatde:contributorID', + 'cardinality' => '0..n', + 'entity' => 'dataset', + 'tab' => '4 — Erweiterte Angaben', + 'tier' => 'optional', + 'vocab' => 'contributors', + 'q_dcat' => 'Welche `dcatde:contributorID` (bereitstellende Stelle) gilt im GovData-Verbund?', + 'q_human' => 'Welche Stelle stellt diese Daten im GovData-Verbund bereit?', + 'desc_dcat' => '`dcatde:contributorID` (DCAT-AP.de) ist die offizielle Kennung der im GovData-Verbund bereitstellenden Stelle, referenziert über das gebündelte Contributors-Vokabular. Multiplizität 0..n. Dient der Zuordnung im nationalen Metadatenverbund.', + 'desc_human' => 'Nur für Stellen, die im deutschen GovData-Verbund veröffentlichen: Wählen Sie Ihre Stelle aus der Liste; die zugehörige offizielle Kennung wird automatisch verwendet. Für die meisten Nutzenden ist dieses Feld nicht relevant. Beispiel: Bundesministerium des Innern.', + ), + array( + 'key' => 'originator_name', + 'meta_key' => '_odw_originator_name', + 'dcat_prop' => 'dcatde:originator', + 'cardinality' => '0..n', + 'entity' => 'dataset', + 'tab' => '4 — Erweiterte Angaben', + 'tier' => 'optional', + 'vocab' => '', + 'q_dcat' => 'Wer ist `dcatde:originator` (ursprünglicher Urheber) der Daten?', + 'q_human' => 'Wer hat diese Daten ursprünglich erstellt?', + 'desc_dcat' => '`dcatde:originator` (DCAT-AP.de) benennt die Stelle, von der die Daten ursprünglich stammen (Range `foaf:Agent`). Kann von Herausgeber (`dct:publisher`) und Ersteller (`dct:creator`) abweichen. Multiplizität 0..n.', + 'desc_human' => 'Nennen Sie die Stelle, von der die Daten ursprünglich stammen — das kann eine andere sein als die, die sie jetzt veröffentlicht. So bleibt die Herkunft nachvollziehbar. Beispiel: Statistisches Landesamt.', + ), + array( + 'key' => 'originator_email', + 'meta_key' => '_odw_originator_email', + 'dcat_prop' => 'dcatde:originator', + 'cardinality' => '0..1', + 'entity' => 'dataset', + 'tab' => '4 — Erweiterte Angaben', + 'tier' => 'optional', + 'vocab' => '', + 'q_dcat' => 'Welche E-Mail-Adresse gehört zum `dcatde:originator`?', + 'q_human' => 'Wie lautet die E-Mail-Adresse des Urhebers?', + 'desc_dcat' => 'Ergänzt `dcatde:originator` um eine E-Mail-Adresse des ursprünglichen Urhebers (als `mailto:`-URI). Optional, Multiplizität 0..1.', + 'desc_human' => 'Optional die E-Mail-Adresse der ursprünglichen Urheber-Stelle, falls abweichend erreichbar. Beispiel: statistik@landesamt.de.', + ), + array( + 'key' => 'maintainer_name', + 'meta_key' => '_odw_maintainer_name', + 'dcat_prop' => 'dcatde:maintainer', + 'cardinality' => '0..n', + 'entity' => 'dataset', + 'tab' => '4 — Erweiterte Angaben', + 'tier' => 'optional', + 'vocab' => '', + 'q_dcat' => 'Wer ist `dcatde:maintainer` (pflegende Stelle) der Daten?', + 'q_human' => 'Wer pflegt diese Daten laufend?', + 'desc_dcat' => '`dcatde:maintainer` (DCAT-AP.de) benennt die für die laufende Pflege und Aktualisierung zuständige Stelle (Range `foaf:Agent`). Multiplizität 0..n. Kann von Herausgeber und Urheber abweichen.', + 'desc_human' => 'Nennen Sie, wer die Daten laufend betreut und aktuell hält. Das ist die Stelle, die sich um Updates kümmert — nicht unbedingt die, die sie erstellt hat. Beispiel: Open-Data-Team.', + ), + array( + 'key' => 'maintainer_email', + 'meta_key' => '_odw_maintainer_email', + 'dcat_prop' => 'dcatde:maintainer', + 'cardinality' => '0..1', + 'entity' => 'dataset', + 'tab' => '4 — Erweiterte Angaben', + 'tier' => 'optional', + 'vocab' => '', + 'q_dcat' => 'Welche E-Mail-Adresse gehört zum `dcatde:maintainer`?', + 'q_human' => 'Wie lautet die E-Mail-Adresse der pflegenden Stelle?', + 'desc_dcat' => 'Ergänzt `dcatde:maintainer` um eine E-Mail-Adresse der pflegenden Stelle (als `mailto:`-URI). Optional, Multiplizität 0..1.', + 'desc_human' => 'Optional die E-Mail-Adresse der Stelle, die die Daten pflegt. Beispiel: opendata@beispiel.de.', + ), + array( + 'key' => 'legal_basis', + 'meta_key' => '_odw_legal_basis', + 'dcat_prop' => 'dcatde:legalBasis', + 'cardinality' => '0..n', + 'entity' => 'dataset', + 'tab' => '4 — Erweiterte Angaben', + 'tier' => 'optional', + 'vocab' => '', + 'q_dcat' => 'Auf welcher `dcatde:legalBasis` (Rechtsgrundlage) beruht die Bereitstellung?', + 'q_human' => 'Auf welcher rechtlichen Grundlage werden die Daten bereitgestellt?', + 'desc_dcat' => '`dcatde:legalBasis` (DCAT-AP.de) nennt das Gesetz oder die Verordnung, die die Bereitstellung der Daten regelt (Freitext, `literal`). Multiplizität 0..n.', + 'desc_human' => 'Falls es eine gesetzliche Grundlage für die Veröffentlichung gibt, nennen Sie sie hier. Das schafft Transparenz über die rechtliche Verpflichtung oder Erlaubnis. Beispiel: § 12a EGovG (E-Government-Gesetz).', + ), + array( + 'key' => 'quality_process_uri', + 'meta_key' => '_odw_quality_process_uri', + 'dcat_prop' => 'dcatde:qualityProcessURI', + 'cardinality' => '0..1', + 'entity' => 'dataset', + 'tab' => '4 — Erweiterte Angaben', + 'tier' => 'optional', + 'vocab' => '', + 'q_dcat' => 'Welche `dcatde:qualityProcessURI` dokumentiert das Qualitätssicherungs-Verfahren?', + 'q_human' => 'Wo ist das Qualitätssicherungs-Verfahren dokumentiert?', + 'desc_dcat' => '`dcatde:qualityProcessURI` (DCAT-AP.de) verweist per URI auf eine Beschreibung des Qualitätssicherungs-Prozesses des Datensatzes. Multiplizität 0..1.', + 'desc_human' => 'Verlinken Sie optional eine Seite, die beschreibt, wie Sie die Qualität der Daten sichern (z. B. Prüfschritte). Das stärkt das Vertrauen in Ihre Daten. Beispiel: https://beispiel.de/qualitaetssicherung.', + ), + array( + 'key' => 'access_rights', + 'meta_key' => '_odw_access_rights', + 'dcat_prop' => 'dct:accessRights', + 'cardinality' => '0..1', + 'entity' => 'dataset', + 'tab' => '4 — Erweiterte Angaben', + 'tier' => 'optional', + 'vocab' => 'access-right', + 'q_dcat' => 'Welche `dct:accessRights` (Zugriffsklassifikation) gelten für den Datensatz?', + 'q_human' => 'Wer darf auf diese Daten zugreifen?', + 'desc_dcat' => '`dct:accessRights` klassifiziert den Zugriffsstatus über das EU-Vokabular „Access Right" (`PUBLIC`, `RESTRICTED`, `NON_PUBLIC`). Multiplizität 0..1. Relevant für die MQA-Dimension Wiederverwendbarkeit.', + 'desc_human' => 'Geben Sie an, ob die Daten für alle offen (öffentlich), nur eingeschränkt oder gar nicht öffentlich zugänglich sind. Für offene Daten ist das in der Regel „öffentlich". Beispiel: Öffentlich. „Öffentlich" ist bereits vorausgewählt — ändern Sie die Angabe nur, wenn der Zugriff eingeschränkt oder gar nicht öffentlich ist.', + ), + array( + 'key' => 'is_hvd', + 'meta_key' => '_odw_is_hvd', + 'dcat_prop' => 'dcatap:applicableLegislation', + 'cardinality' => '0..1', + 'entity' => 'dataset', + 'tab' => '4 — Erweiterte Angaben', + 'tier' => 'optional', + 'vocab' => '', + 'q_dcat' => 'Ist der Datensatz ein High-Value-Dataset nach `dcatap:applicableLegislation` (EU-VO 2023/138)?', + 'q_human' => 'Ist dies ein hochwertiger Datensatz (HVD)?', + 'desc_dcat' => 'Kennzeichen, ob der Datensatz ein High-Value-Dataset im Sinne der EU-Durchführungsverordnung 2023/138 ist. Ist es gesetzt, wird `dcatap:applicableLegislation` (Verweis auf die Verordnung) ausgegeben und das Feld HVD-Kategorie relevant. Multiplizität 0..1.', + 'desc_human' => '„High-Value-Datasets" sind von der EU als besonders wertvoll eingestufte Datensätze (z. B. Geo-, Umwelt- oder Mobilitätsdaten). Setzen Sie dies nur, wenn Ihr Datensatz in eine der offiziellen HVD-Kategorien fällt — im Zweifel „Nein". Beispiel: Ja, bei amtlichen Geodaten. Das betrifft ausschließlich öffentliche Stellen — Vereine, Verbände und andere zivilgesellschaftliche Organisationen können das Feld leer lassen.', + ), + array( + 'key' => 'hvd_category', + 'meta_key' => '_odw_hvd_category', + 'dcat_prop' => 'dcatap:hvdCategory', + 'cardinality' => '0..n', + 'entity' => 'dataset', + 'tab' => '4 — Erweiterte Angaben', + 'tier' => 'optional', + 'vocab' => 'hvd-category', + 'q_dcat' => 'Welcher `dcatap:hvdCategory` (HVD-Kategorie) gehört der Datensatz an?', + 'q_human' => 'Welcher HVD-Kategorie gehört dieser Datensatz an?', + 'desc_dcat' => '`dcatap:hvdCategory` ordnet ein High-Value-Dataset einer der sechs HVD-Kategorien der EU zu (Geospatial, Erdbeobachtung/Umwelt, Meteorologie, Statistik, Unternehmen, Mobilität), referenziert per EU-URI. Nur relevant, wenn HVD gesetzt ist. Multiplizität 0..n. Hinweis: Die Eigenschaft stammt aus der HVD-Erweiterung zu DCAT-AP (EU-Durchführungsverordnung 2023/138), nicht aus dem Kernprofil DCAT-AP 3.0; keine der mitgelieferten SHACL-Shapes prüft sie deshalb.', + 'desc_human' => 'Wenn es ein hochwertiger Datensatz ist, wählen Sie hier die passende der sechs EU-HVD-Kategorien. Damit ordnen Sie den Datensatz korrekt in das EU-Schema ein. Beispiel: Georaum, Mobilität, Statistik.', + ), + array( + 'key' => 'identifier', + 'meta_key' => '_odw_identifier', + 'dcat_prop' => 'dct:identifier', + 'cardinality' => '0..n', + 'entity' => 'dataset', + 'tab' => '4 — Erweiterte Angaben', + 'tier' => 'optional', + 'vocab' => '', + 'q_dcat' => 'Welcher `dct:identifier` (eindeutige Kennung) identifiziert den Datensatz?', + 'q_human' => 'Welche eindeutige Kennung hat dieser Datensatz?', + 'desc_dcat' => '`dct:identifier` ist eine eindeutige, im System der Herausgeberin vergebene Kennung des Datensatzes (Freitext/`literal`). Multiplizität 0..n. Ermöglicht die stabile Referenzierung über Systemgrenzen hinweg.', + 'desc_human' => 'Falls Ihr Datensatz eine feste Kennnummer aus Ihrem eigenen System hat, tragen Sie sie hier ein. So bleibt der Datensatz eindeutig identifizierbar. Beispiel: DS-2026-00042. Neben einer internen Nummer können Sie hier auch eine dauerhafte, extern vergebene Kennung wie einen DOI eintragen.', + ), + array( + 'key' => 'type', + 'meta_key' => '_odw_type', + 'dcat_prop' => 'dct:type', + 'cardinality' => '0..1', + 'entity' => 'dataset', + 'tab' => '4 — Erweiterte Angaben', + 'tier' => 'optional', + 'vocab' => 'dataset-type', + 'q_dcat' => 'Welchen `dct:type` (Datensatz-Typ) hat der Datensatz?', + 'q_human' => 'Um welchen Typ von Datensatz handelt es sich?', + 'desc_dcat' => '`dct:type` klassifiziert die Art des Datensatzes, idealerweise über das EU-Vokabular „Dataset Type". Multiplizität 0..1. Unterscheidet z. B. Erhebungsdaten, Registerdaten oder Geodaten.', + 'desc_human' => 'Geben Sie an, um welche Art von Datensatz es sich grundsätzlich handelt. Das hilft bei der groben Einordnung. Beispiel: Statistische Erhebung, Geodaten. Einzutragen ist die vollständige Web-Adresse des passenden Eintrags aus der EU-Liste der Datensatz-Typen, nicht die Bezeichnung als Text.', + ), + array( + 'key' => 'creator_name', + 'meta_key' => '_odw_creator_name', + 'dcat_prop' => 'dct:creator', + 'cardinality' => '0..n', + 'entity' => 'dataset', + 'tab' => '4 — Erweiterte Angaben', + 'tier' => 'optional', + 'vocab' => '', + 'q_dcat' => 'Wer ist `dct:creator` (Ersteller) des Datensatzes?', + 'q_human' => 'Wer hat diese Daten erstellt?', + 'desc_dcat' => '`dct:creator` benennt die primär für die Erstellung des Datensatzes verantwortliche Stelle oder Person (Range `foaf:Agent`). Multiplizität 0..n. Unterscheidet sich vom Herausgeber (`dct:publisher`), der für die Bereitstellung verantwortlich ist.', + 'desc_human' => 'Nennen Sie, wer die Daten inhaltlich erstellt hat — die Person oder Stelle, die die eigentliche Arbeit gemacht hat. Das kann von der herausgebenden Organisation abweichen. Beispiel: Forschungsgruppe Stadtklima.', + ), + array( + 'key' => 'creator_email', + 'meta_key' => '_odw_creator_email', + 'dcat_prop' => 'dct:creator', + 'cardinality' => '0..1', + 'entity' => 'dataset', + 'tab' => '4 — Erweiterte Angaben', + 'tier' => 'optional', + 'vocab' => '', + 'q_dcat' => 'Welche E-Mail-Adresse gehört zum `dct:creator`?', + 'q_human' => 'Wie lautet die E-Mail-Adresse des Erstellers?', + 'desc_dcat' => 'Ergänzt `dct:creator` um eine E-Mail-Adresse der erstellenden Stelle (als `mailto:`-URI). Optional, Multiplizität 0..1.', + 'desc_human' => 'Optional die E-Mail-Adresse der erstellenden Person oder Stelle. Beispiel: forschung@beispiel.de.', + ), + array( + 'key' => 'version', + 'meta_key' => '_odw_version', + 'dcat_prop' => 'owl:versionInfo', + 'cardinality' => '0..1', + 'entity' => 'dataset', + 'tab' => '4 — Erweiterte Angaben', + 'tier' => 'optional', + 'vocab' => '', + 'q_dcat' => 'Welche `owl:versionInfo` (Versionsbezeichnung) hat der Datensatz?', + 'q_human' => 'Welche Version hat dieser Datensatz?', + 'desc_dcat' => '`owl:versionInfo` gibt die Versionsbezeichnung des Datensatzes als Freitext an (`literal`). Multiplizität 0..1. Erlaubt die Unterscheidung aufeinanderfolgender Ausgaben desselben Datensatzes.', + 'desc_human' => 'Falls es mehrere Ausgaben Ihrer Daten gibt, tragen Sie die Versionsnummer ein. So wissen Nutzende, welche Fassung sie vor sich haben. Beispiel: 2.0.', + ), + array( + 'key' => 'version_notes', + 'meta_key' => '_odw_version_notes', + 'dcat_prop' => 'adms:versionNotes', + 'cardinality' => '0..n', + 'entity' => 'dataset', + 'tab' => '4 — Erweiterte Angaben', + 'tier' => 'optional', + 'vocab' => '', + 'q_dcat' => 'Welche `adms:versionNotes` (Änderungshinweise) beschreiben diese Version?', + 'q_human' => 'Was hat sich in dieser Version geändert?', + 'desc_dcat' => '`adms:versionNotes` beschreibt die Änderungen gegenüber der Vorversion als sprachlich getaggten Freitext (`literal-lang`). Multiplizität 0..n. Ergänzt `owl:versionInfo` um den inhaltlichen Änderungsverlauf.', + 'desc_human' => 'Beschreiben Sie kurz, was sich gegenüber der letzten Version geändert hat — wie ein Änderungsprotokoll. Nutzende sehen so, ob sich ein erneuter Download lohnt. Beispiel: „Daten für 2025 ergänzt, Tippfehler korrigiert."', + ), + array( + 'key' => 'spatial_resolution', + 'meta_key' => '_odw_spatial_resolution', + 'dcat_prop' => 'dcat:spatialResolutionInMeters', + 'cardinality' => '0..n', + 'entity' => 'dataset', + 'tab' => '4 — Erweiterte Angaben', + 'tier' => 'optional', + 'vocab' => '', + 'q_dcat' => 'Welche `dcat:spatialResolutionInMeters` (räumliche Auflösung) haben die Daten?', + 'q_human' => 'Welche räumliche Auflösung haben die Daten (in Metern)?', + 'desc_dcat' => '`dcat:spatialResolutionInMeters` gibt die kleinste räumlich unterscheidbare Einheit in Metern an (`xsd:decimal`). Multiplizität 0..n. Relevant vor allem für Geodaten und Rasterdaten.', + 'desc_human' => 'Bei Geodaten: Geben Sie an, wie fein die Daten räumlich aufgelöst sind — der kleinste unterscheidbare Abstand in Metern. Ein kleiner Wert bedeutet detailliertere Daten. Beispiel: 10 (Raster von 10 Metern). Tragen Sie dabei nur die Zahl ein, ohne die Einheit dahinterzuschreiben.', + ), + array( + 'key' => 'temporal_resolution', + 'meta_key' => '_odw_temporal_resolution', + 'dcat_prop' => 'dcat:temporalResolution', + 'cardinality' => '0..1', + 'entity' => 'dataset', + 'tab' => '4 — Erweiterte Angaben', + 'tier' => 'optional', + 'vocab' => '', + 'q_dcat' => 'Welche `dcat:temporalResolution` (zeitliche Auflösung) haben die Daten?', + 'q_human' => 'Welche zeitliche Auflösung haben die Daten?', + 'desc_dcat' => '`dcat:temporalResolution` gibt die kleinste zeitlich unterscheidbare Einheit als ISO-8601-Dauer an (`xsd:duration`). Multiplizität 0..1. Beschreibt z. B. den Messabstand einer Zeitreihe.', + 'desc_human' => 'Bei Zeitreihen: Geben Sie an, in welchem zeitlichen Abstand die Werte erfasst sind — z. B. stündlich, täglich, monatlich. Format ist die ISO-8601-Dauer. Beispiel: P1D (ein Tag) oder PT1H (eine Stunde).', + ), + array( + 'key' => 'conforms_to', + 'meta_key' => '_odw_conforms_to', + 'dcat_prop' => 'dct:conformsTo', + 'cardinality' => '0..n', + 'entity' => 'dataset', + 'tab' => '4 — Erweiterte Angaben', + 'tier' => 'optional', + 'vocab' => '', + 'q_dcat' => 'Welchem `dct:conformsTo` (Standard/Schema) entsprechen die Daten?', + 'q_human' => 'Welchem Standard oder Schema entsprechen die Daten?', + 'desc_dcat' => '`dct:conformsTo` verweist auf einen implementierten Standard, ein Anwendungsprofil oder ein Schema, dem die Daten entsprechen (Range `dct:Standard`, per URI oder Bezeichnung). Multiplizität 0..n.', + 'desc_human' => 'Falls Ihre Daten einem bestimmten Standard oder Schema folgen, nennen Sie ihn hier. So können Systeme die Daten korrekt interpretieren. Beispiel: INSPIRE, XÖV oder ein fachliches Datenschema. Einzutragen ist die Web-Adresse, unter der der Standard beschrieben ist.', + ), + array( + 'key' => 'provenance', + 'meta_key' => '_odw_provenance', + 'dcat_prop' => 'dct:provenance', + 'cardinality' => '0..n', + 'entity' => 'dataset', + 'tab' => '4 — Erweiterte Angaben', + 'tier' => 'optional', + 'vocab' => '', + 'q_dcat' => 'Welche `dct:provenance` (Herkunft/Entstehung) hat der Datensatz?', + 'q_human' => 'Woher stammen die Daten und wie sind sie entstanden?', + 'desc_dcat' => '`dct:provenance` beschreibt die Herkunft und Entstehungsgeschichte des Datensatzes (Range `dct:ProvenanceStatement`, Freitext). Multiplizität 0..n. Dokumentiert Erhebungs- und Verarbeitungsschritte.', + 'desc_human' => 'Beschreiben Sie, woher die Daten kommen und wie sie entstanden sind — z. B. aus welcher Erhebung oder welchem Verfahren. Das macht die Daten nachvollziehbar und vertrauenswürdig. Beispiel: „Erhoben im Rahmen der Bürgerbefragung 2025, anonymisiert aufbereitet."', + ), + array( + 'key' => 'dist_title', + 'meta_key' => '_odw_dist_title', + 'dcat_prop' => 'dct:title', + 'cardinality' => '0..n', + 'entity' => 'distribution', + 'tab' => '4 — Erweiterte Angaben', + 'tier' => 'optional', + 'vocab' => '', + 'q_dcat' => 'Wie lautet der `dct:title` der Distribution?', + 'q_human' => 'Wie heißt die bereitgestellte Datei/Distribution?', + 'desc_dcat' => '`dct:title` auf Ebene der Distribution benennt die konkrete bereitgestellte Ressource (`literal-lang`). Multiplizität 0..n. Nützlich, wenn der Distributionsname vom Datensatztitel abweicht.', + 'desc_human' => 'Geben Sie der bereitgestellten Datei einen eigenen Namen, falls er sich vom Titel des Datensatzes unterscheidet. Beispiel: „Rohdaten CSV 2025".', + ), + array( + 'key' => 'dist_description', + 'meta_key' => '_odw_dist_description', + 'dcat_prop' => 'dct:description', + 'cardinality' => '0..n', + 'entity' => 'distribution', + 'tab' => '4 — Erweiterte Angaben', + 'tier' => 'optional', + 'vocab' => '', + 'q_dcat' => 'Wie lautet die `dct:description` der Distribution?', + 'q_human' => 'Wie lässt sich die Distribution beschreiben?', + 'desc_dcat' => '`dct:description` auf Distributionsebene beschreibt die konkrete Datei/Ressource (`literal-lang`). Multiplizität 0..n. Ergänzt die Datensatzbeschreibung um distributionsspezifische Hinweise (z. B. Spaltenaufbau).', + 'desc_human' => 'Beschreiben Sie die konkrete Datei näher — etwa welche Spalten sie enthält oder wie sie aufgebaut ist. Das hilft beim direkten Umgang mit der Datei. Beispiel: „Spalten: Jahr, Stadt, Einwohner; Trennzeichen Semikolon."', + ), + array( + 'key' => 'download_url', + 'meta_key' => '_odw_download_url', + 'dcat_prop' => 'dcat:downloadURL', + 'cardinality' => '0..n', + 'entity' => 'distribution', + 'tab' => '4 — Erweiterte Angaben', + 'tier' => 'optional', + 'vocab' => '', + 'q_dcat' => 'Unter welcher `dcat:downloadURL` ist die Datei direkt herunterladbar?', + 'q_human' => 'Wie lautet der direkte Download-Link zur Datei?', + 'desc_dcat' => '`dcat:downloadURL` verweist auf eine direkt herunterladbare Datei (Range `rdfs:Resource`). Anders als `dcat:accessURL` garantiert sie einen unmittelbaren Download derselben Ressource. Multiplizität 0..n. Relevant für die MQA-Dimension Zugänglichkeit.', + 'desc_human' => 'Falls es einen direkten Link gibt, der die Datei sofort herunterlädt (ohne Umweg über eine Seite), tragen Sie ihn hier ein. Das ist der bequemste Weg für Nachnutzende. Beispiel: https://beispiel.de/daten/statistik.csv.', + ), + array( + 'key' => 'media_type', + 'meta_key' => '_odw_media_type', + 'dcat_prop' => 'dcat:mediaType', + 'cardinality' => '0..1', + 'entity' => 'distribution', + 'tab' => '4 — Erweiterte Angaben', + 'tier' => 'optional', + 'vocab' => 'iana-media-type', + 'q_dcat' => 'Welchen `dcat:mediaType` (IANA-MIME-Typ) hat die Distribution?', + 'q_human' => 'Welchen Medientyp (MIME) hat die Datei?', + 'desc_dcat' => '`dcat:mediaType` gibt den Medientyp der Distribution als IANA-Media-Type an (z. B. `text/csv`, `application/json`), referenziert über das IANA-Media-Types-Register. Multiplizität 0..1. Ergänzt `dct:format` um den technischen MIME-Typ.', + 'desc_human' => 'Der technische Medientyp der Datei (MIME-Typ) — die maschinenlesbare Entsprechung zum Format. Systeme erkennen daran, wie sie die Datei behandeln müssen. Beispiel: text/csv, application/json. Einzutragen ist die vollständige Web-Adresse aus dem IANA-Verzeichnis, zum Beispiel https://www.iana.org/assignments/media-types/text/csv.', + ), + array( + 'key' => 'dist_rights', + 'meta_key' => '_odw_dist_rights', + 'dcat_prop' => 'dct:rights', + 'cardinality' => '0..1', + 'entity' => 'distribution', + 'tab' => '4 — Erweiterte Angaben', + 'tier' => 'optional', + 'vocab' => '', + 'q_dcat' => 'Welche `dct:rights` (Nutzungsrechte) gelten für die Distribution?', + 'q_human' => 'Welche Nutzungsrechte gelten für die Datei?', + 'desc_dcat' => '`dct:rights` beschreibt rechtliche Hinweise zur Distribution jenseits der Lizenz — etwa Urheberrechts- oder Zugriffsvermerke (Range `dct:RightsStatement`, Freitext oder URI). Multiplizität 0..1.', + 'desc_human' => 'Ergänzende rechtliche Hinweise zur Datei, die über die Lizenz hinausgehen — z. B. Urheberrechtsvermerke. Für viele offene Datensätze bleibt das leer. Beispiel: „© Stadt Musterstadt 2026".', ), ); diff --git a/config/phpstan.neon b/config/phpstan.neon index 5d15608f..69a3d453 100644 --- a/config/phpstan.neon +++ b/config/phpstan.neon @@ -35,7 +35,7 @@ parameters: # WP_CLI and progress bar not in stubs - identifier: function.notFound - message: '/Function WP_CLI.*not found|Function carbon_get_post_meta not found/' + message: '/Function WP_CLI.*not found|Function carbon_(get|set)_post_meta not found/' # Plugin constants are defined at runtime, not recognized by static analysis - identifier: constant.notFound diff --git a/config/shacl/README.md b/config/shacl/README.md index b22ce907..055f64af 100644 --- a/config/shacl/README.md +++ b/config/shacl/README.md @@ -22,7 +22,7 @@ Grundlage, gegen die diese Ausgabe geprüft wird (u. a. für die MQA-Metrik „D ### Datei-Beschreibungen -- **`dcat-ap-SHACL.ttl`** — Die generischen DCAT-AP-3.0-Constraints der EU (SEMIC). Enthält alle Pflichtfelder und Kardinalitäten für DCAT-AP-konforme Metadaten. +- **`dcat-ap-SHACL.ttl`** — Die generischen DCAT-AP-3.0-Constraints der EU (SEMIC). Enthält alle Pflichtfelder und Multiplizitäten für DCAT-AP-konforme Metadaten. - **`dcat-ap-SHACL-DE.ttl`** — Die DCAT-AP.de-Ergänzungen/-Anpassungen. Enthält deutschsprachige Fehlermeldungen, deaktivierte Shapes und Severity-Overrides. Für dieses Plugin besonders relevant, da `dcatde:`-Felder ausgegeben werden. - **`dcat-ap-spec-german-additions.ttl`** — Zusätzliche deutsche Shapes (u.a. `foaf:Agent`-Constraints für `dcatde:originator`/`maintainer`). - **`dcat-ap-de-deprecated.ttl`** — Deprecation-Hinweise für veraltete Felder. diff --git a/docs/FELD-REFERENZ.md b/docs/FELD-REFERENZ.md index a73ae47a..d28004a8 100644 --- a/docs/FELD-REFERENZ.md +++ b/docs/FELD-REFERENZ.md @@ -18,10 +18,10 @@ Legende der Stufen-Spalte: **Pflicht** (Veröffentlichung wird ohne dieses Feld - **1 — Grundlegende Informationen** - [Wer gibt diese Daten heraus?](#wer-gibt-diese-daten-heraus) - - [Welchem Thema ist dieser Datensatz zugeordnet?](#welchem-thema-ist-dieser-datensatz-zugeordnet) + - [Welchen Themen ist dieser Datensatz zugeordnet?](#welchen-themen-ist-dieser-datensatz-zugeordnet) - [Mit welchen Schlagworten finde ich diese Daten?](#mit-welchen-schlagworten-finde-ich-diese-daten) - [Welchem Themenfeld nach CESSDA ordnen Sie den Datensatz zu?](#welchem-themenfeld-nach-cessda-ordnen-sie-den-datensatz-zu) - - [Welchem Engagementfeld ist dieser Datensatz zuzuordnen?](#welchem-engagementfeld-ist-dieser-datensatz-zuzuordnen) + - [Welchen Engagementfeldern ist dieser Datensatz zuzuordnen?](#welchen-engagementfeldern-ist-dieser-datensatz-zuzuordnen) - [Worum geht es in diesem Datensatz?](#worum-geht-es-in-diesem-datensatz) - **2 — Sprache & Übersetzungen** - [In welcher Sprache sind die Daten?](#in-welcher-sprache-sind-die-daten) @@ -55,7 +55,6 @@ Legende der Stufen-Spalte: **Pflicht** (Veröffentlichung wird ohne dieses Feld - [Auf welcher rechtlichen Grundlage werden die Daten bereitgestellt?](#auf-welcher-rechtlichen-grundlage-werden-die-daten-bereitgestellt) - [Wo ist das Qualitätssicherungs-Verfahren dokumentiert?](#wo-ist-das-qualitätssicherungs-verfahren-dokumentiert) - [Wer darf auf diese Daten zugreifen?](#wer-darf-auf-diese-daten-zugreifen) - - [Welches weitere EU-Thema möchten Sie ergänzen?](#welches-weitere-eu-thema-möchten-sie-ergänzen) - [Ist dies ein hochwertiger Datensatz (HVD)?](#ist-dies-ein-hochwertiger-datensatz-hvd) - [Welcher HVD-Kategorie gehört dieser Datensatz an?](#welcher-hvd-kategorie-gehört-dieser-datensatz-an) - [Welche eindeutige Kennung hat dieser Datensatz?](#welche-eindeutige-kennung-hat-dieser-datensatz) @@ -84,6 +83,8 @@ Legende der Stufen-Spalte: **Pflicht** (Veröffentlichung wird ohne dieses Feld |---|---| | DCAT-Property | `dct:publisher` | | Meta-Key | `_odw_publisher` | +| Multiplizität | `1..1` | +| Profil-Klasse | [Datensatz](https://www.dcat-ap.de/def/dcatde/3.0/spec/#datensatz) | | Stufe | Pflicht | | Vokabular | — | @@ -91,26 +92,28 @@ Legende der Stufen-Spalte: **Pflicht** (Veröffentlichung wird ohne dieses Feld **2 · Verständliche Frage:** Wer gibt diese Daten heraus? -**3 · DCAT-AP-Langbeschreibung:** `dct:publisher` benennt die für die Bereitstellung des Datensatzes verantwortliche Stelle (eine `foaf:Agent`-Entität). In DCAT-AP 3.0 ist die Angabe verpflichtend (Kardinalität 1..1). Idealerweise wird die Organisation über eine URI referenziert; als Minimalform genügt der Name (`foaf:name`). +**3 · DCAT-AP-Langbeschreibung:** `dct:publisher` benennt die für die Bereitstellung des Datensatzes verantwortliche Stelle (eine `foaf:Agent`-Entität). In DCAT-AP 3.0 ist die Angabe verpflichtend (Multiplizität 1..1). Idealerweise wird die Organisation über eine URI referenziert; als Minimalform genügt der Name (`foaf:name`). **4 · Verständliche Langbeschreibung:** Tragen Sie hier die Organisation ein, die die Daten offiziell veröffentlicht — also wer dafür verantwortlich ist, dass die Daten bereitstehen. Das ist oft eine Behörde, ein Amt oder ein Verein. Beispiel: „Statistisches Landesamt Musterstadt" oder „Umweltbundesamt". -### Welchem Thema ist dieser Datensatz zugeordnet? +### Welchen Themen ist dieser Datensatz zugeordnet? | Eigenschaft | Wert | |---|---| | DCAT-Property | `dcat:theme` | | Meta-Key | `_odw_theme` | +| Multiplizität | `0..n` | +| Profil-Klasse | [Datensatz](https://www.dcat-ap.de/def/dcatde/3.0/spec/#datensatz) | | Stufe | Empfohlen | | Vokabular | `data-theme` | **1 · DCAT-AP-Frage:** Welchem `dcat:theme` (Datenthema) ist der Datensatz zugeordnet? -**2 · Verständliche Frage:** Welchem Thema ist dieser Datensatz zugeordnet? +**2 · Verständliche Frage:** Welchen Themen ist dieser Datensatz zugeordnet? -**3 · DCAT-AP-Langbeschreibung:** `dcat:theme` ordnet den Datensatz einer oder mehreren Kategorien zu. In DCAT-AP wird das kontrollierte EU-Vokabular „Data Theme" (`http://publications.europa.eu/resource/authority/data-theme/`) verwendet, z. B. `ENVI` (Umwelt) oder `EDUC` (Bildung). Kardinalität 0..n. +**3 · DCAT-AP-Langbeschreibung:** `dcat:theme` ordnet den Datensatz einer oder mehreren Kategorien zu. In DCAT-AP wird das kontrollierte EU-Vokabular „Data Theme" (`http://publications.europa.eu/resource/authority/data-theme/`) verwendet, z. B. `ENVI` (Umwelt) oder `EDUC` (Bildung). Multiplizität 0..n. -**4 · Verständliche Langbeschreibung:** Wählen Sie das Themengebiet, zu dem die Daten am besten passen — ähnlich einer Schublade, in die der Datensatz einsortiert wird. Das hilft anderen, Ihre Daten über Themenfilter zu finden. Beispiel: Umwelt, Bildung, Gesundheit, Wirtschaft, Kultur. +**4 · Verständliche Langbeschreibung:** Wählen Sie ein oder mehrere Themengebiete, zu denen die Daten passen — ähnlich einer Schublade, in die der Datensatz einsortiert wird. Das hilft anderen, Ihre Daten über Themenfilter zu finden. Beispiel: Umwelt, Bildung, Gesundheit, Wirtschaft, Kultur. ### Mit welchen Schlagworten finde ich diese Daten? @@ -118,6 +121,8 @@ Legende der Stufen-Spalte: **Pflicht** (Veröffentlichung wird ohne dieses Feld |---|---| | DCAT-Property | `dcat:keyword` | | Meta-Key | `_odw_keywords` | +| Multiplizität | `0..n` | +| Profil-Klasse | [Datensatz](https://www.dcat-ap.de/def/dcatde/3.0/spec/#datensatz) | | Stufe | Empfohlen | | Vokabular | — | @@ -125,9 +130,9 @@ Legende der Stufen-Spalte: **Pflicht** (Veröffentlichung wird ohne dieses Feld **2 · Verständliche Frage:** Mit welchen Schlagworten finde ich diese Daten? -**3 · DCAT-AP-Langbeschreibung:** `dcat:keyword` sind freie, sprachlich getaggte Schlagwörter zur Verbesserung der Auffindbarkeit (`literal-lang`, Kardinalität 0..n). Anders als `dcat:theme` sind sie nicht an ein kontrolliertes Vokabular gebunden. Je Schlagwort ein Wert. +**3 · DCAT-AP-Langbeschreibung:** `dcat:keyword` sind freie, sprachlich getaggte Schlagwörter zur Verbesserung der Auffindbarkeit (`literal-lang`, Multiplizität 0..n). Anders als `dcat:theme` sind sie nicht an ein kontrolliertes Vokabular gebunden. Je Schlagwort ein Wert. -**4 · Verständliche Langbeschreibung:** Tragen Sie einzelne Schlagwörter ein, unter denen man Ihre Daten suchen würde — jedes Wort in eine eigene Zeile. Sie ergänzen das Thema und machen die Daten leichter auffindbar. Beispiel: Umwelt, Wasser, Luftverschmutzung. +**4 · Verständliche Langbeschreibung:** Tragen Sie einzelne Schlagwörter ein, unter denen man Ihre Daten suchen würde — jedes Wort in eine eigene Zeile. Sie ergänzen das Thema und machen die Daten leichter auffindbar. Beispiel: erst „Umwelt", darunter „Wasser", darunter „Luftverschmutzung". Trennen Sie die Schlagwörter nicht mit Komma. ### Welchem Themenfeld nach CESSDA ordnen Sie den Datensatz zu? @@ -135,6 +140,8 @@ Legende der Stufen-Spalte: **Pflicht** (Veröffentlichung wird ohne dieses Feld |---|---| | DCAT-Property | `dct:subject` | | Meta-Key | `_odw_cessda_topic` | +| Multiplizität | `0..n` | +| Profil-Klasse | [Datensatz](https://www.dcat-ap.de/def/dcatde/3.0/spec/#datensatz) | | Stufe | Optional | | Vokabular | `cessda` | @@ -142,26 +149,28 @@ Legende der Stufen-Spalte: **Pflicht** (Veröffentlichung wird ohne dieses Feld **2 · Verständliche Frage:** Welchem Themenfeld nach CESSDA ordnen Sie den Datensatz zu? -**3 · DCAT-AP-Langbeschreibung:** `dct:subject` verweist auf ein fachliches Thema aus einem kontrollierten Vokabular — hier die CESSDA Topic Classification (Version 4.2.3). Der Wert ist die Konzept-URI aus dem CESSDA-Vokabular. Mehrfachangabe möglich (Kardinalität 0..n); erscheint zusammen mit anderen Themenzuordnungen als Liste. +**3 · DCAT-AP-Langbeschreibung:** `dct:subject` verweist auf ein fachliches Thema aus einem kontrollierten Vokabular — hier die CESSDA Topic Classification (Version 4.2.3). Der Wert ist die Konzept-URI aus dem CESSDA-Vokabular. Mehrfachangabe möglich (Multiplizität 0..n); erscheint zusammen mit anderen Themenzuordnungen als Liste. Hinweis: `dct:subject` gehört nicht zum DCAT-AP.de-Profil — die offiziellen SHACL-Shapes kennen die Eigenschaft für Datensätze nicht. Als Dublin-Core-Angabe ist sie zulässig (RDF erlaubt zusätzliche Aussagen) und wird hier bewusst ausgegeben; streng profilkonforme Portale können sie ignorieren. -**4 · Verständliche Langbeschreibung:** Optional für sozial- und wirtschaftswissenschaftliche Daten: Ordnen Sie den Datensatz einem Fachthema aus dem CESSDA-Katalog zu (ein europäischer Standard für Forschungsdaten). Tippen Sie das Thema ein und wählen Sie aus der Vorschlagsliste. Beispiel: Volkszählungen, Migration, Wirtschaftspolitik. +**4 · Verständliche Langbeschreibung:** Optional für sozial- und wirtschaftswissenschaftliche Daten: Ordnen Sie den Datensatz einem Fachthema aus dem CESSDA-Katalog zu (ein europäischer Standard für Forschungsdaten). Klicken Sie ins Feld, um die Vorschläge zu sehen, oder tippen Sie, um die Liste einzugrenzen. Beispiel: Volkszählungen, Migration, Wirtschaftspolitik. -### Welchem Engagementfeld ist dieser Datensatz zuzuordnen? +### Welchen Engagementfeldern ist dieser Datensatz zuzuordnen? | Eigenschaft | Wert | |---|---| | DCAT-Property | `dct:subject` | | Meta-Key | `_odw_engagementfeld` | +| Multiplizität | `0..n` | +| Profil-Klasse | [Datensatz](https://www.dcat-ap.de/def/dcatde/3.0/spec/#datensatz) | | Stufe | Optional | | Vokabular | `engagementfeld` | **1 · DCAT-AP-Frage:** Welches `dct:subject` (Engagementfeld) nach ZiviZ-Vokabular beschreibt den Datensatz? -**2 · Verständliche Frage:** Welchem Engagementfeld ist dieser Datensatz zuzuordnen? +**2 · Verständliche Frage:** Welchen Engagementfeldern ist dieser Datensatz zuzuordnen? -**3 · DCAT-AP-Langbeschreibung:** `dct:subject` mit einem Konzept aus dem ZiviZ-Vokabular „Engagementfeld" (`https://ziviz.de/def/engagementfeld/`), das zivilgesellschaftliche Tätigkeitsfelder klassifiziert. Der Wert ist die Konzept-URI; die Label→URI-Auflösung erfolgt beim Speichern. Mehrfachangabe möglich (Kardinalität 0..n). +**3 · DCAT-AP-Langbeschreibung:** `dct:subject` mit einem Konzept aus dem ZiviZ-Vokabular „Engagementfeld" (`https://ziviz.de/def/engagementfeld/`), das zivilgesellschaftliche Tätigkeitsfelder klassifiziert. Der Wert ist die Konzept-URI; die Label→URI-Auflösung erfolgt beim Speichern. Mehrfachangabe möglich (Multiplizität 0..n). Hinweis: `dct:subject` gehört nicht zum DCAT-AP.de-Profil — die offiziellen SHACL-Shapes kennen die Eigenschaft für Datensätze nicht. Als Dublin-Core-Angabe ist sie zulässig (RDF erlaubt zusätzliche Aussagen) und wird hier bewusst ausgegeben; streng profilkonforme Portale können sie ignorieren. -**4 · Verständliche Langbeschreibung:** Optional für Organisationen der Zivilgesellschaft: Ordnen Sie den Datensatz einem Engagementfeld zu — also dem gesellschaftlichen Bereich, in dem Sie aktiv sind. Wählen Sie einen Eintrag aus der Liste; die passende Kennung wird automatisch gesetzt. Beispiel: Kultur, Sport, Umwelt- und Naturschutz. +**4 · Verständliche Langbeschreibung:** Optional für Organisationen der Zivilgesellschaft: Ordnen Sie den Datensatz einem oder mehreren Engagementfeldern zu — also den gesellschaftlichen Bereichen, in denen Sie aktiv sind. Wählen Sie die Einträge in der Liste aus; die passenden Kennungen werden automatisch gesetzt. Beispiel: Kultur, Sport, Umwelt- und Naturschutz. ### Worum geht es in diesem Datensatz? @@ -169,6 +178,8 @@ Legende der Stufen-Spalte: **Pflicht** (Veröffentlichung wird ohne dieses Feld |---|---| | DCAT-Property | `dct:description` | | Meta-Key | `_odw_description` | +| Multiplizität | `1..n` | +| Profil-Klasse | [Datensatz](https://www.dcat-ap.de/def/dcatde/3.0/spec/#datensatz) | | Stufe | Pflicht | | Vokabular | — | @@ -176,7 +187,7 @@ Legende der Stufen-Spalte: **Pflicht** (Veröffentlichung wird ohne dieses Feld **2 · Verständliche Frage:** Worum geht es in diesem Datensatz? -**3 · DCAT-AP-Langbeschreibung:** `dct:description` ist eine frei formulierte, sprachlich getaggte Beschreibung des Datensatzes (`literal-lang`). In DCAT-AP 3.0 verpflichtend (Kardinalität 1..n je Sprache). Sie ergänzt den Titel um Inhalt, Kontext, Erhebungsmethode und Abgrenzung des Datensatzes. +**3 · DCAT-AP-Langbeschreibung:** `dct:description` ist eine frei formulierte, sprachlich getaggte Beschreibung des Datensatzes (`literal-lang`). In DCAT-AP 3.0 verpflichtend (Multiplizität 1..n je Sprache). Sie ergänzt den Titel um Inhalt, Kontext, Erhebungsmethode und Abgrenzung des Datensatzes. **4 · Verständliche Langbeschreibung:** Beschreiben Sie in eigenen Worten, was in den Daten steckt: Worum geht es, was kann man damit machen, was ist enthalten? Ein bis zwei Absätze reichen. Beispiel: „Überblick über die bevölkerungsreichsten Städte Deutschlands mit Einwohnerzahlen und Entwicklung seit 2010." @@ -190,6 +201,8 @@ Legende der Stufen-Spalte: **Pflicht** (Veröffentlichung wird ohne dieses Feld |---|---| | DCAT-Property | `dct:language` | | Meta-Key | `_odw_language` | +| Multiplizität | `0..n` | +| Profil-Klasse | [Datensatz](https://www.dcat-ap.de/def/dcatde/3.0/spec/#datensatz) | | Stufe | Empfohlen | | Vokabular | `language` | @@ -197,7 +210,7 @@ Legende der Stufen-Spalte: **Pflicht** (Veröffentlichung wird ohne dieses Feld **2 · Verständliche Frage:** In welcher Sprache sind die Daten? -**3 · DCAT-AP-Langbeschreibung:** `dct:language` gibt die Sprache des Datensatzes an, referenziert über das EU-Authority-Vokabular „Language" (`http://publications.europa.eu/resource/authority/language/`, z. B. `DEU`, `ENG`). Kardinalität 0..n — mehrsprachige Datensätze können mehrere Sprachen angeben. +**3 · DCAT-AP-Langbeschreibung:** `dct:language` gibt die Sprache des Datensatzes an, referenziert über das EU-Authority-Vokabular „Language" (`http://publications.europa.eu/resource/authority/language/`, z. B. `DEU`, `ENG`). Multiplizität 0..n — mehrsprachige Datensätze können mehrere Sprachen angeben. **4 · Verständliche Langbeschreibung:** Geben Sie an, in welcher Sprache die Inhalte der Daten verfasst sind (z. B. die Spaltenüberschriften und Texte). Das hilft Nutzenden einzuschätzen, ob sie die Daten verstehen. Beispiel: Deutsch, Englisch. @@ -211,6 +224,8 @@ Legende der Stufen-Spalte: **Pflicht** (Veröffentlichung wird ohne dieses Feld |---|---| | DCAT-Property | `dcat:accessURL` | | Meta-Key | `_odw_access_url` | +| Multiplizität | `1..n` | +| Profil-Klasse | [Distribution](https://www.dcat-ap.de/def/dcatde/3.0/spec/#distribution) | | Stufe | Pflicht | | Vokabular | — | @@ -218,7 +233,7 @@ Legende der Stufen-Spalte: **Pflicht** (Veröffentlichung wird ohne dieses Feld **2 · Verständliche Frage:** Wo kann man die Datei herunterladen oder ansehen? -**3 · DCAT-AP-Langbeschreibung:** `dcat:accessURL` verweist auf eine Ressource, über die auf die Distribution zugegriffen werden kann (Range `rdfs:Resource`, Kardinalität 1..n je Distribution). Sie kann auf eine Landing-Page, einen Feed, einen Endpunkt oder — bei direktem Download — dieselbe Ressource wie `dcat:downloadURL` zeigen. Pflichtangabe je Distribution. +**3 · DCAT-AP-Langbeschreibung:** `dcat:accessURL` verweist auf eine Ressource, über die auf die Distribution zugegriffen werden kann (Range `rdfs:Resource`, Multiplizität 1..n je Distribution). Sie kann auf eine Landing-Page, einen Feed, einen Endpunkt oder — bei direktem Download — dieselbe Ressource wie `dcat:downloadURL` zeigen. Pflichtangabe je Distribution. **4 · Verständliche Langbeschreibung:** Tragen Sie den Link ein, unter dem Ihre Daten zu finden sind — die Adresse einer Datei zum Herunterladen oder einer Seite, auf der die Daten liegen. Alternativ laden Sie die Datei über die Mediathek-Box hoch; dann wird dieser Link automatisch gesetzt und Sie müssen ihn nicht selbst eintippen. Beispiel: https://beispiel.de/daten/statistik.csv. @@ -228,6 +243,8 @@ Legende der Stufen-Spalte: **Pflicht** (Veröffentlichung wird ohne dieses Feld |---|---| | DCAT-Property | `dct:format` | | Meta-Key | `_odw_format` | +| Multiplizität | `0..1` | +| Profil-Klasse | [Distribution](https://www.dcat-ap.de/def/dcatde/3.0/spec/#distribution) | | Stufe | Empfohlen | | Vokabular | `file-type` | @@ -235,7 +252,7 @@ Legende der Stufen-Spalte: **Pflicht** (Veröffentlichung wird ohne dieses Feld **2 · Verständliche Frage:** In welchem Format ist die Datei? -**3 · DCAT-AP-Langbeschreibung:** `dct:format` gibt das Format der Distribution an, referenziert über das EU-Authority-Vokabular „File Type" (`http://publications.europa.eu/resource/authority/file-type/`, z. B. `CSV`, `JSON`, `PDF`). Kardinalität 0..1. Ergänzt `dcat:mediaType` (MIME-Typ) um das anwendungsnahe Format. +**3 · DCAT-AP-Langbeschreibung:** `dct:format` gibt das Format der Distribution an, referenziert über das EU-Authority-Vokabular „File Type" (`http://publications.europa.eu/resource/authority/file-type/`, z. B. `CSV`, `JSON`, `PDF`). Multiplizität 0..1. Ergänzt `dcat:mediaType` (MIME-Typ) um das anwendungsnahe Format. **4 · Verständliche Langbeschreibung:** Wählen Sie das Format der bereitgestellten Datei. Daran erkennen Nutzende, mit welchem Programm sie die Daten öffnen können. Maschinenlesbare, offene Formate wie CSV oder JSON sind besonders empfehlenswert. Beispiel: CSV, JSON, PDF. @@ -245,6 +262,8 @@ Legende der Stufen-Spalte: **Pflicht** (Veröffentlichung wird ohne dieses Feld |---|---| | DCAT-Property | `dcat:byteSize` | | Meta-Key | `_odw_byte_size` | +| Multiplizität | `0..1` | +| Profil-Klasse | [Distribution](https://www.dcat-ap.de/def/dcatde/3.0/spec/#distribution) | | Stufe | Optional | | Vokabular | — | @@ -252,7 +271,7 @@ Legende der Stufen-Spalte: **Pflicht** (Veröffentlichung wird ohne dieses Feld **2 · Verständliche Frage:** Wie groß ist die Datei? -**3 · DCAT-AP-Langbeschreibung:** `dcat:byteSize` gibt die Größe der Distribution in Bytes als nicht-negative Ganzzahl an (`xsd:nonNegativeInteger`, Kardinalität 0..1). Bei einem Mediathek-Upload wird der Wert automatisch aus der Datei ermittelt. +**3 · DCAT-AP-Langbeschreibung:** `dcat:byteSize` gibt die Größe der Distribution in Bytes als nicht-negative Ganzzahl an (`xsd:nonNegativeInteger`, Multiplizität 0..1). Bei einem Mediathek-Upload wird der Wert automatisch aus der Datei ermittelt. **4 · Verständliche Langbeschreibung:** Die Dateigröße in Bytes — nur die reine Zahl. Nutzende sehen so vorab, wie viel sie herunterladen. Bei hochgeladenen Dateien wird die Größe automatisch berechnet. Beispiel: 2048576 (das sind rund 2 MB). @@ -262,6 +281,8 @@ Legende der Stufen-Spalte: **Pflicht** (Veröffentlichung wird ohne dieses Feld |---|---| | DCAT-Property | `dct:license` | | Meta-Key | `_odw_license` | +| Multiplizität | `0..1` | +| Profil-Klasse | [Distribution](https://www.dcat-ap.de/def/dcatde/3.0/spec/#distribution) | | Stufe | Pflicht | | Vokabular | `licenses` | @@ -269,7 +290,7 @@ Legende der Stufen-Spalte: **Pflicht** (Veröffentlichung wird ohne dieses Feld **2 · Verständliche Frage:** Unter welcher Lizenz sind diese Daten verfügbar? -**3 · DCAT-AP-Langbeschreibung:** `dct:license` benennt das rechtliche Dokument, unter dem die Distribution bereitgestellt wird (Range `dct:LicenseDocument`, referenziert per URI). Verpflichtend für die Wiederverwendbarkeit. Empfohlen werden URIs offener Lizenzen (Creative Commons, Datenlizenz Deutschland, DCAT-AP.de-Lizenzregister). +**3 · DCAT-AP-Langbeschreibung:** `dct:license` benennt das rechtliche Dokument, unter dem die Distribution bereitgestellt wird (Range `dct:LicenseDocument`, referenziert per URI). Multiplizität 0..1 je Distribution; das Plugin erzwingt die Angabe, weil ohne Lizenz keine Nachnutzung möglich ist. Empfohlen werden URIs offener Lizenzen (Creative Commons, Datenlizenz Deutschland, DCAT-AP.de-Lizenzregister). **4 · Verständliche Langbeschreibung:** Legen Sie fest, was andere mit Ihren Daten tun dürfen — das regelt die Lizenz. Wählen Sie eine der vorgeschlagenen Standardlizenzen; „offene" Lizenzen erlauben die freie Weiternutzung. Ohne Lizenz sind Daten rechtlich unklar und kaum nachnutzbar. Beispiel: CC-BY 4.0 (Namensnennung). @@ -279,6 +300,8 @@ Legende der Stufen-Spalte: **Pflicht** (Veröffentlichung wird ohne dieses Feld |---|---| | DCAT-Property | `dct:license` | | Meta-Key | `_odw_license_custom` | +| Multiplizität | `0..1` | +| Profil-Klasse | [Distribution](https://www.dcat-ap.de/def/dcatde/3.0/spec/#distribution) | | Stufe | Bedingt | | Vokabular | `licenses` | @@ -286,7 +309,7 @@ Legende der Stufen-Spalte: **Pflicht** (Veröffentlichung wird ohne dieses Feld **2 · Verständliche Frage:** Welche eigene Lizenz-URI möchten Sie angeben? -**3 · DCAT-AP-Langbeschreibung:** Nur relevant, wenn im Lizenzfeld „Sonstige" gewählt wurde: Hier wird die `dct:license`-URI einer nicht in der Standardliste enthaltenen Lizenz eingetragen. Das Auto-Suggest bietet zusätzlich die URIs des DCAT-AP.de-Lizenzregisters (`http://dcat-ap.de/def/licenses/…`) an. +**3 · DCAT-AP-Langbeschreibung:** Nur relevant, wenn im Lizenzfeld „Sonstige" gewählt wurde: Hier wird die `dct:license`-URI einer nicht in der Standardliste enthaltenen Lizenz eingetragen. Das Auto-Suggest bietet zusätzlich die URIs des DCAT-AP.de-Lizenzregisters (`http://dcat-ap.de/def/licenses/…`) an. Multiplizität 0..1 je Distribution — es ist dieselbe Eigenschaft wie oben. **4 · Verständliche Langbeschreibung:** Dieses Feld erscheint nur, wenn Sie oben „Sonstige" Lizenz gewählt haben. Tragen Sie dann die Web-Adresse (URI) Ihrer Lizenz ein oder wählen Sie eine aus der Vorschlagsliste. Beispiel: http://dcat-ap.de/def/licenses/dl-by-de/2.0. @@ -296,6 +319,8 @@ Legende der Stufen-Spalte: **Pflicht** (Veröffentlichung wird ohne dieses Feld |---|---| | DCAT-Property | `dcatde:licenseAttributionByText` | | Meta-Key | `_odw_attribution_text` | +| Multiplizität | `0..1` | +| Profil-Klasse | [Distribution](https://www.dcat-ap.de/def/dcatde/3.0/spec/#distribution) | | Stufe | Optional | | Vokabular | — | @@ -303,7 +328,7 @@ Legende der Stufen-Spalte: **Pflicht** (Veröffentlichung wird ohne dieses Feld **2 · Verständliche Frage:** Welcher Namensnennungstext soll bei Weiternutzung angegeben werden? -**3 · DCAT-AP-Langbeschreibung:** `dcatde:licenseAttributionByText` (DCAT-AP.de) enthält den exakten Namensnennungstext, den Nachnutzende bei Lizenzen mit Namensnennungspflicht (z. B. CC-BY, DL-DE-BY) zitieren müssen. Freitext (`literal`), Kardinalität 0..1. +**3 · DCAT-AP-Langbeschreibung:** `dcatde:licenseAttributionByText` (DCAT-AP.de) enthält den exakten Namensnennungstext, den Nachnutzende bei Lizenzen mit Namensnennungspflicht (z. B. CC-BY, DL-DE-BY) zitieren müssen. Freitext (`literal`), Multiplizität 0..1. **4 · Verständliche Langbeschreibung:** Bei Lizenzen mit Namensnennung („BY") geben Sie hier vor, wie andere Sie nennen sollen, wenn sie Ihre Daten verwenden. So bekommen Sie korrekt Credit. Beispiel: „Datenquelle: Stadt Musterstadt, 2026". @@ -313,6 +338,8 @@ Legende der Stufen-Spalte: **Pflicht** (Veröffentlichung wird ohne dieses Feld |---|---| | DCAT-Property | `dcatap:availability` | | Meta-Key | `_odw_availability` | +| Multiplizität | `0..1` | +| Profil-Klasse | [Distribution](https://www.dcat-ap.de/def/dcatde/3.0/spec/#distribution) | | Stufe | Optional | | Vokabular | `planned-availability` | @@ -320,7 +347,7 @@ Legende der Stufen-Spalte: **Pflicht** (Veröffentlichung wird ohne dieses Feld **2 · Verständliche Frage:** Wie dauerhaft ist diese Datei verfügbar? -**3 · DCAT-AP-Langbeschreibung:** `dcatap:availability` beschreibt die geplante Verfügbarkeit einer Distribution über das EU-Vokabular „Planned Availability" (z. B. `AVAILABLE`, `TEMPORARY`, `EXPERIMENTAL`, `STABLE`). Kardinalität 0..1. Gibt Nachnutzenden Planungssicherheit. +**3 · DCAT-AP-Langbeschreibung:** `dcatap:availability` beschreibt die geplante Verfügbarkeit einer Distribution über das EU-Vokabular „Planned Availability" (z. B. `AVAILABLE`, `TEMPORARY`, `EXPERIMENTAL`, `STABLE`). Multiplizität 0..1. Gibt Nachnutzenden Planungssicherheit. **4 · Verständliche Langbeschreibung:** Geben Sie an, wie verlässlich die Datei langfristig erreichbar bleibt — dauerhaft, nur vorübergehend oder experimentell. Das hilft anderen einzuschätzen, ob sie sich auf den Link verlassen können. Beispiel: Dauerhaft verfügbar. @@ -334,6 +361,8 @@ Legende der Stufen-Spalte: **Pflicht** (Veröffentlichung wird ohne dieses Feld |---|---| | DCAT-Property | `dcat:landingPage` | | Meta-Key | `_odw_landing_page` | +| Multiplizität | `0..n` | +| Profil-Klasse | [Datensatz](https://www.dcat-ap.de/def/dcatde/3.0/spec/#datensatz) | | Stufe | Optional | | Vokabular | — | @@ -341,7 +370,7 @@ Legende der Stufen-Spalte: **Pflicht** (Veröffentlichung wird ohne dieses Feld **2 · Verständliche Frage:** Wo finde ich mehr Informationen zu diesem Projekt? -**3 · DCAT-AP-Langbeschreibung:** `dcat:landingPage` verweist auf eine menschenlesbare Webseite mit weiteren Informationen zum Datensatz (Range `foaf:Document`, Kardinalität 0..n). Anders als `dcat:accessURL` führt sie nicht direkt zu den Daten, sondern zu Kontext, Dokumentation oder Projektbeschreibung. +**3 · DCAT-AP-Langbeschreibung:** `dcat:landingPage` verweist auf eine menschenlesbare Webseite mit weiteren Informationen zum Datensatz (Range `foaf:Document`, Multiplizität 0..n). Anders als `dcat:accessURL` führt sie nicht direkt zu den Daten, sondern zu Kontext, Dokumentation oder Projektbeschreibung. **4 · Verständliche Langbeschreibung:** Verlinken Sie eine Webseite, auf der man mehr über die Daten oder das Projekt erfährt — etwa eine Projekt- oder Dokumentationsseite. Das ist nicht der direkte Download, sondern die „Über uns"-Seite zu den Daten. Beispiel: https://beispiel.de/projekt. @@ -351,6 +380,8 @@ Legende der Stufen-Spalte: **Pflicht** (Veröffentlichung wird ohne dieses Feld |---|---| | DCAT-Property | `dct:issued` | | Meta-Key | `_odw_issued` | +| Multiplizität | `0..1` | +| Profil-Klasse | [Datensatz](https://www.dcat-ap.de/def/dcatde/3.0/spec/#datensatz) | | Stufe | Empfohlen | | Vokabular | — | @@ -358,7 +389,7 @@ Legende der Stufen-Spalte: **Pflicht** (Veröffentlichung wird ohne dieses Feld **2 · Verständliche Frage:** Wann wurden diese Daten zum ersten Mal veröffentlicht? -**3 · DCAT-AP-Langbeschreibung:** `dct:issued` ist das Datum der formalen Erstveröffentlichung des Datensatzes, typisiert als `xsd:date` bzw. `xsd:dateTime`. Kardinalität 0..1. Nicht zu verwechseln mit `dct:modified` (letzte Änderung) oder dem Erhebungszeitraum (`dct:temporal`). +**3 · DCAT-AP-Langbeschreibung:** `dct:issued` ist das Datum der formalen Erstveröffentlichung des Datensatzes, typisiert als `xsd:date` bzw. `xsd:dateTime`. Multiplizität 0..1. Nicht zu verwechseln mit `dct:modified` (letzte Änderung) oder dem Erhebungszeitraum (`dct:temporal`). **4 · Verständliche Langbeschreibung:** Geben Sie das Datum an, an dem die Daten erstmals veröffentlicht wurden. Das ist der „Geburtstag" des Datensatzes, nicht der Zeitraum, den die Daten abdecken. Beispiel: 2024-01-15. @@ -368,6 +399,8 @@ Legende der Stufen-Spalte: **Pflicht** (Veröffentlichung wird ohne dieses Feld |---|---| | DCAT-Property | `dct:modified` | | Meta-Key | `_odw_modified` | +| Multiplizität | `0..1` | +| Profil-Klasse | [Datensatz](https://www.dcat-ap.de/def/dcatde/3.0/spec/#datensatz) | | Stufe | Empfohlen | | Vokabular | — | @@ -375,7 +408,7 @@ Legende der Stufen-Spalte: **Pflicht** (Veröffentlichung wird ohne dieses Feld **2 · Verständliche Frage:** Wann wurden diese Daten zuletzt aktualisiert? -**3 · DCAT-AP-Langbeschreibung:** `dct:modified` gibt das Datum der letzten inhaltlichen Änderung des Datensatzes an (`xsd:date`/`xsd:dateTime`, Kardinalität 0..1). Das Plugin setzt diesen Wert bei jeder Speicherung automatisch; ein Eingabefeld gibt es bewusst nicht, da eine manuelle Angabe beim nächsten Speichern überschrieben würde. +**3 · DCAT-AP-Langbeschreibung:** `dct:modified` gibt das Datum der letzten inhaltlichen Änderung des Datensatzes an (`xsd:date`/`xsd:dateTime`, Multiplizität 0..1). Das Plugin setzt diesen Wert bei jeder Speicherung automatisch; ein Eingabefeld gibt es bewusst nicht, da eine manuelle Angabe beim nächsten Speichern überschrieben würde. **4 · Verständliche Langbeschreibung:** Das Datum der letzten Aktualisierung. Es wird beim Speichern automatisch gesetzt, sodass Nutzende immer sehen, wie aktuell die Daten sind — Sie müssen dafür nichts eintragen. Beispiel: 2026-04-22. @@ -385,6 +418,8 @@ Legende der Stufen-Spalte: **Pflicht** (Veröffentlichung wird ohne dieses Feld |---|---| | DCAT-Property | `dct:accrualPeriodicity` | | Meta-Key | `_odw_accrual_periodicity` | +| Multiplizität | `0..1` | +| Profil-Klasse | [Datensatz](https://www.dcat-ap.de/def/dcatde/3.0/spec/#datensatz) | | Stufe | Optional | | Vokabular | `frequency` | @@ -392,7 +427,7 @@ Legende der Stufen-Spalte: **Pflicht** (Veröffentlichung wird ohne dieses Feld **2 · Verständliche Frage:** Wie oft werden diese Daten aktualisiert? -**3 · DCAT-AP-Langbeschreibung:** `dct:accrualPeriodicity` gibt an, in welchem Rhythmus der Datensatz aktualisiert wird, referenziert über das EU-Vokabular „Frequency" (`http://publications.europa.eu/resource/authority/frequency/`, z. B. `DAILY`, `MONTHLY`, `ANNUAL`). Kardinalität 0..1. +**3 · DCAT-AP-Langbeschreibung:** `dct:accrualPeriodicity` gibt an, in welchem Rhythmus der Datensatz aktualisiert wird, referenziert über das EU-Vokabular „Frequency" (`http://publications.europa.eu/resource/authority/frequency/`, z. B. `DAILY`, `MONTHLY`, `ANNUAL`). Multiplizität 0..1. **4 · Verständliche Langbeschreibung:** Geben Sie an, wie regelmäßig neue Daten hinzukommen — täglich, monatlich, jährlich oder unregelmäßig. Nutzende wissen dann, wie oft sich ein erneuter Blick lohnt. Beispiel: Jährlich. @@ -402,6 +437,8 @@ Legende der Stufen-Spalte: **Pflicht** (Veröffentlichung wird ohne dieses Feld |---|---| | DCAT-Property | `dcatde:politicalGeocodingLevelURI` | | Meta-Key | `_odw_political_geocoding_level` | +| Multiplizität | `0..1` | +| Profil-Klasse | [Datensatz](https://www.dcat-ap.de/def/dcatde/3.0/spec/#datensatz) | | Stufe | Optional | | Vokabular | `politicalGeocodingLevel` | @@ -409,9 +446,9 @@ Legende der Stufen-Spalte: **Pflicht** (Veröffentlichung wird ohne dieses Feld **2 · Verständliche Frage:** Auf welcher Verwaltungsebene wurden diese Daten erhoben? -**3 · DCAT-AP-Langbeschreibung:** `dcatde:politicalGeocodingLevelURI` (DCAT-AP.de) klassifiziert die administrative Ebene des räumlichen Bezugs über das GovData-Vokabular (Bund, Land, Kreis, Kommune). Kardinalität 0..1. Ergänzt die konkrete Gebietsangabe. +**3 · DCAT-AP-Langbeschreibung:** `dcatde:politicalGeocodingLevelURI` (DCAT-AP.de) klassifiziert die administrative Ebene des räumlichen Bezugs über das GovData-Vokabular; im Formular wählbar als Bund, Land, Landkreis und Gemeinde. Multiplizität 0..1. Ergänzt die konkrete Gebietsangabe. -**4 · Verständliche Langbeschreibung:** Wählen Sie, auf welcher staatlichen Ebene die Daten angesiedelt sind — Bund, Land, Kreis oder Kommune. Das ordnet die Daten geografisch-administrativ ein. Beispiel: Kommune. +**4 · Verständliche Langbeschreibung:** Wählen Sie, auf welcher staatlichen Ebene die Daten angesiedelt sind — Bund, Land, Landkreis oder Gemeinde. Das ordnet die Daten geografisch-administrativ ein. Beispiel: Gemeinde. ### Auf welches amtliche Gebiet beziehen sich die Daten? @@ -419,6 +456,8 @@ Legende der Stufen-Spalte: **Pflicht** (Veröffentlichung wird ohne dieses Feld |---|---| | DCAT-Property | `dcatde:politicalGeocodingURI` | | Meta-Key | `_odw_political_geocoding_uri` | +| Multiplizität | `0..n` | +| Profil-Klasse | [Datensatz](https://www.dcat-ap.de/def/dcatde/3.0/spec/#datensatz) | | Stufe | Optional | | Vokabular | — | @@ -426,7 +465,7 @@ Legende der Stufen-Spalte: **Pflicht** (Veröffentlichung wird ohne dieses Feld **2 · Verständliche Frage:** Auf welches amtliche Gebiet beziehen sich die Daten? -**3 · DCAT-AP-Langbeschreibung:** `dcatde:politicalGeocodingURI` (DCAT-AP.de) referenziert ein konkretes amtliches Gebiet über eine URI (z. B. amtlicher Regionalschlüssel/AGS als URI). Kardinalität 0..n. Ermöglicht die eindeutige, maschinenlesbare Verortung. +**3 · DCAT-AP-Langbeschreibung:** `dcatde:politicalGeocodingURI` (DCAT-AP.de) referenziert ein konkretes amtliches Gebiet über eine URI (z. B. amtlicher Regionalschlüssel/AGS als URI). Multiplizität 0..n. Ermöglicht die eindeutige, maschinenlesbare Verortung. **4 · Verständliche Langbeschreibung:** Verlinken Sie das genaue amtliche Gebiet, auf das sich die Daten beziehen — als offizielle Kennung (z. B. Gemeindeschlüssel). Damit ist eindeutig, welche Region gemeint ist. Beispiel: die URI zum amtlichen Gemeindeschlüssel Ihrer Stadt. @@ -436,6 +475,8 @@ Legende der Stufen-Spalte: **Pflicht** (Veröffentlichung wird ohne dieses Feld |---|---| | DCAT-Property | `dcatde:geocodingDescription` | | Meta-Key | `_odw_geocoding_description` | +| Multiplizität | `0..n` | +| Profil-Klasse | [Datensatz](https://www.dcat-ap.de/def/dcatde/3.0/spec/#datensatz) | | Stufe | Optional | | Vokabular | — | @@ -443,7 +484,7 @@ Legende der Stufen-Spalte: **Pflicht** (Veröffentlichung wird ohne dieses Feld **2 · Verständliche Frage:** Wie lässt sich der räumliche Bezug in Worten beschreiben? -**3 · DCAT-AP-Langbeschreibung:** `dcatde:geocodingDescription` (DCAT-AP.de) ist eine frei formulierte textuelle Beschreibung der räumlichen Abdeckung (`literal`/`literal-lang`). Kardinalität 0..n. Ergänzt die maschinenlesbaren Angaben `dct:spatial` und `dcatde:politicalGeocodingURI` um eine menschenlesbare Erläuterung. +**3 · DCAT-AP-Langbeschreibung:** `dcatde:geocodingDescription` (DCAT-AP.de) ist eine frei formulierte textuelle Beschreibung der räumlichen Abdeckung (`literal`/`literal-lang`). Multiplizität 0..n. Ergänzt die maschinenlesbaren Angaben `dct:spatial` und `dcatde:politicalGeocodingURI` um eine menschenlesbare Erläuterung. **4 · Verständliche Langbeschreibung:** Beschreiben Sie den räumlichen Bezug zusätzlich in Worten — etwa wenn ein Gebietsschlüssel allein nicht genau genug ist. Das hilft Nutzenden, die Abdeckung einzuordnen. Beispiel: „Stadtgebiet Musterstadt ohne den Ortsteil X". @@ -453,6 +494,8 @@ Legende der Stufen-Spalte: **Pflicht** (Veröffentlichung wird ohne dieses Feld |---|---| | DCAT-Property | `dct:spatial` | | Meta-Key | `_odw_spatial` | +| Multiplizität | `0..n` | +| Profil-Klasse | [Datensatz](https://www.dcat-ap.de/def/dcatde/3.0/spec/#datensatz) | | Stufe | Optional | | Vokabular | — | @@ -460,9 +503,9 @@ Legende der Stufen-Spalte: **Pflicht** (Veröffentlichung wird ohne dieses Feld **2 · Verständliche Frage:** Welche geografische Region betreffen diese Daten? -**3 · DCAT-AP-Langbeschreibung:** `dct:spatial` beschreibt die räumliche Abdeckung des Datensatzes (Range `dct:Location`). Als Wert dient eine Gebiets-URI (z. B. GeoNames, EU-Continents) oder eine Freitext-Ortsangabe. Kardinalität 0..n. +**3 · DCAT-AP-Langbeschreibung:** `dct:spatial` beschreibt die räumliche Abdeckung des Datensatzes (Range `dct:Location`). Als Wert dient eine Gebiets-URI (z. B. GeoNames, EU-Continents) oder eine Freitext-Ortsangabe. Multiplizität 0..n. -**4 · Verständliche Langbeschreibung:** Geben Sie an, welches geografische Gebiet die Daten abdecken — eine Stadt, ein Bundesland, ein Land oder eine Region. So finden Nutzende Daten zu ihrer Gegend. Beispiel: Musterstadt oder Bayern. +**4 · Verständliche Langbeschreibung:** Geben Sie an, welches geografische Gebiet die Daten abdecken — eine Stadt, ein Bundesland, ein Land oder eine Region. So finden Nutzende Daten zu ihrer Gegend. Beispiel: Musterstadt oder Bayern. Wählen Sie die Region aus der Vorschlagsliste — dann wird die passende Kennung automatisch gesetzt — oder tippen Sie das Gebiet einfach selbst ein. ### Ab wann sind diese Daten gültig? @@ -470,6 +513,8 @@ Legende der Stufen-Spalte: **Pflicht** (Veröffentlichung wird ohne dieses Feld |---|---| | DCAT-Property | `dct:temporal` | | Meta-Key | `_odw_temporal_start` | +| Multiplizität | `0..1` | +| Profil-Klasse | [Datensatz](https://www.dcat-ap.de/def/dcatde/3.0/spec/#datensatz) | | Stufe | Optional | | Vokabular | — | @@ -477,7 +522,7 @@ Legende der Stufen-Spalte: **Pflicht** (Veröffentlichung wird ohne dieses Feld **2 · Verständliche Frage:** Ab wann sind diese Daten gültig? -**3 · DCAT-AP-Langbeschreibung:** `dct:temporal` beschreibt den Zeitraum, den die Daten inhaltlich abdecken (Range `dct:PeriodOfTime`). Dieses Feld liefert die Startangabe (`dcat:startDate`) des Intervalls. Kardinalität 0..1. Nicht zu verwechseln mit `dct:issued` (Veröffentlichung). +**3 · DCAT-AP-Langbeschreibung:** `dct:temporal` beschreibt den Zeitraum, den die Daten inhaltlich abdecken (Range `dct:PeriodOfTime`). Dieses Feld liefert die Startangabe (`dcat:startDate`) des Intervalls. Multiplizität 0..1. Nicht zu verwechseln mit `dct:issued` (Veröffentlichung). **4 · Verständliche Langbeschreibung:** Der Beginn des Zeitraums, den die Daten inhaltlich beschreiben — also ab wann die erfassten Werte gelten. Das ist der abgedeckte Zeitraum, nicht das Veröffentlichungsdatum. Beispiel: 2020-01-01. @@ -487,6 +532,8 @@ Legende der Stufen-Spalte: **Pflicht** (Veröffentlichung wird ohne dieses Feld |---|---| | DCAT-Property | `dct:temporal` | | Meta-Key | `_odw_temporal_end` | +| Multiplizität | `0..1` | +| Profil-Klasse | [Datensatz](https://www.dcat-ap.de/def/dcatde/3.0/spec/#datensatz) | | Stufe | Optional | | Vokabular | — | @@ -494,7 +541,7 @@ Legende der Stufen-Spalte: **Pflicht** (Veröffentlichung wird ohne dieses Feld **2 · Verständliche Frage:** Bis wann sind diese Daten gültig? -**3 · DCAT-AP-Langbeschreibung:** `dct:temporal` liefert hier die Endangabe (`dcat:endDate`) des abgedeckten Zeitintervalls (Range `dct:PeriodOfTime`). Kardinalität 0..1. Zusammen mit dem Startdatum ergibt sich der vollständige Abdeckungszeitraum. +**3 · DCAT-AP-Langbeschreibung:** `dct:temporal` liefert hier die Endangabe (`dcat:endDate`) des abgedeckten Zeitintervalls (Range `dct:PeriodOfTime`). Multiplizität 0..1. Zusammen mit dem Startdatum ergibt sich der vollständige Abdeckungszeitraum. **4 · Verständliche Langbeschreibung:** Das Ende des Zeitraums, den die Daten abdecken — bis wann die erfassten Werte reichen. Bleibt das Feld leer, gilt der Zeitraum als offen (bis heute fortlaufend). Beispiel: 2025-12-31. @@ -504,6 +551,8 @@ Legende der Stufen-Spalte: **Pflicht** (Veröffentlichung wird ohne dieses Feld |---|---| | DCAT-Property | `dcat:contactPoint` | | Meta-Key | `_odw_contact_name` | +| Multiplizität | `0..1` | +| Profil-Klasse | [Datensatz](https://www.dcat-ap.de/def/dcatde/3.0/spec/#datensatz) | | Stufe | Optional | | Vokabular | — | @@ -511,7 +560,7 @@ Legende der Stufen-Spalte: **Pflicht** (Veröffentlichung wird ohne dieses Feld **2 · Verständliche Frage:** Wer ist Ansprechperson für Fragen zu diesen Daten? -**3 · DCAT-AP-Langbeschreibung:** Teil des `dcat:contactPoint` (Range `vcard:Kind`): `vcard:fn` benennt die Kontaktstelle oder -person für Rückfragen zum Datensatz. Kardinalität des Kontaktpunkts 0..n. Name, E-Mail und URL bilden zusammen einen Kontaktpunkt. +**3 · DCAT-AP-Langbeschreibung:** Teil des `dcat:contactPoint` (Range `vcard:Kind`): `vcard:fn` benennt die Kontaktstelle oder -person für Rückfragen zum Datensatz. Multiplizität 0..1 je Kontaktpunkt; ein Datensatz kann mehrere Kontaktpunkte tragen (0..n). Name, E-Mail und URL bilden zusammen einen Kontaktpunkt. **4 · Verständliche Langbeschreibung:** Nennen Sie, an wen sich Nutzende bei Fragen wenden können — eine Person oder eine Abteilung. So ist klar, wer für die Daten zuständig ist. Beispiel: Open-Data-Team der Stadt Musterstadt. @@ -521,6 +570,8 @@ Legende der Stufen-Spalte: **Pflicht** (Veröffentlichung wird ohne dieses Feld |---|---| | DCAT-Property | `dcat:contactPoint` | | Meta-Key | `_odw_contact_email` | +| Multiplizität | `0..1` | +| Profil-Klasse | [Datensatz](https://www.dcat-ap.de/def/dcatde/3.0/spec/#datensatz) | | Stufe | Optional | | Vokabular | — | @@ -528,7 +579,7 @@ Legende der Stufen-Spalte: **Pflicht** (Veröffentlichung wird ohne dieses Feld **2 · Verständliche Frage:** Unter welcher E-Mail-Adresse kann ich Fragen stellen? -**3 · DCAT-AP-Langbeschreibung:** Teil des `dcat:contactPoint`: `vcard:hasEmail` liefert die E-Mail-Adresse der Kontaktstelle (als `mailto:`-URI serialisiert). Kardinalität 0..1 je Kontaktpunkt. +**3 · DCAT-AP-Langbeschreibung:** Teil des `dcat:contactPoint`: `vcard:hasEmail` liefert die E-Mail-Adresse der Kontaktstelle (als `mailto:`-URI serialisiert). Multiplizität 0..1 je Kontaktpunkt. **4 · Verständliche Langbeschreibung:** Die E-Mail-Adresse, unter der man Fragen zu den Daten stellen kann. Das ist der einfachste Weg für Nachnutzende, Sie zu erreichen. Beispiel: opendata@musterstadt.de. @@ -538,6 +589,8 @@ Legende der Stufen-Spalte: **Pflicht** (Veröffentlichung wird ohne dieses Feld |---|---| | DCAT-Property | `dcat:contactPoint` | | Meta-Key | `_odw_contact_url` | +| Multiplizität | `0..1` | +| Profil-Klasse | [Datensatz](https://www.dcat-ap.de/def/dcatde/3.0/spec/#datensatz) | | Stufe | Optional | | Vokabular | — | @@ -545,7 +598,7 @@ Legende der Stufen-Spalte: **Pflicht** (Veröffentlichung wird ohne dieses Feld **2 · Verständliche Frage:** Auf welcher Website finde ich weitere Kontaktinformationen? -**3 · DCAT-AP-Langbeschreibung:** Teil des `dcat:contactPoint`: `vcard:hasURL` verweist auf eine Webseite mit weiteren Kontaktinformationen der zuständigen Stelle. Kardinalität 0..1 je Kontaktpunkt. +**3 · DCAT-AP-Langbeschreibung:** Teil des `dcat:contactPoint`: `vcard:hasURL` verweist auf eine Webseite mit weiteren Kontaktinformationen der zuständigen Stelle. Multiplizität 0..1 je Kontaktpunkt. **4 · Verständliche Langbeschreibung:** Verlinken Sie optional eine Kontakt- oder Impressumsseite mit weiteren Wegen, Sie zu erreichen. Ergänzt E-Mail und Name um eine Anlaufstelle im Web. Beispiel: https://musterstadt.de/kontakt. @@ -555,6 +608,8 @@ Legende der Stufen-Spalte: **Pflicht** (Veröffentlichung wird ohne dieses Feld |---|---| | DCAT-Property | `dcatde:contributorID` | | Meta-Key | `_odw_contributor_id` | +| Multiplizität | `0..n` | +| Profil-Klasse | [Datensatz](https://www.dcat-ap.de/def/dcatde/3.0/spec/#datensatz) | | Stufe | Optional | | Vokabular | `contributors` | @@ -562,7 +617,7 @@ Legende der Stufen-Spalte: **Pflicht** (Veröffentlichung wird ohne dieses Feld **2 · Verständliche Frage:** Welche Stelle stellt diese Daten im GovData-Verbund bereit? -**3 · DCAT-AP-Langbeschreibung:** `dcatde:contributorID` (DCAT-AP.de) ist die offizielle Kennung der im GovData-Verbund bereitstellenden Stelle, referenziert über das gebündelte Contributors-Vokabular. Kardinalität 0..n. Dient der Zuordnung im nationalen Metadatenverbund. +**3 · DCAT-AP-Langbeschreibung:** `dcatde:contributorID` (DCAT-AP.de) ist die offizielle Kennung der im GovData-Verbund bereitstellenden Stelle, referenziert über das gebündelte Contributors-Vokabular. Multiplizität 0..n. Dient der Zuordnung im nationalen Metadatenverbund. **4 · Verständliche Langbeschreibung:** Nur für Stellen, die im deutschen GovData-Verbund veröffentlichen: Wählen Sie Ihre Stelle aus der Liste; die zugehörige offizielle Kennung wird automatisch verwendet. Für die meisten Nutzenden ist dieses Feld nicht relevant. Beispiel: Bundesministerium des Innern. @@ -572,6 +627,8 @@ Legende der Stufen-Spalte: **Pflicht** (Veröffentlichung wird ohne dieses Feld |---|---| | DCAT-Property | `dcatde:originator` | | Meta-Key | `_odw_originator_name` | +| Multiplizität | `0..n` | +| Profil-Klasse | [Datensatz](https://www.dcat-ap.de/def/dcatde/3.0/spec/#datensatz) | | Stufe | Optional | | Vokabular | — | @@ -579,7 +636,7 @@ Legende der Stufen-Spalte: **Pflicht** (Veröffentlichung wird ohne dieses Feld **2 · Verständliche Frage:** Wer hat diese Daten ursprünglich erstellt? -**3 · DCAT-AP-Langbeschreibung:** `dcatde:originator` (DCAT-AP.de) benennt die Stelle, von der die Daten ursprünglich stammen (Range `foaf:Agent`). Kann von Herausgeber (`dct:publisher`) und Ersteller (`dct:creator`) abweichen. Kardinalität 0..n. +**3 · DCAT-AP-Langbeschreibung:** `dcatde:originator` (DCAT-AP.de) benennt die Stelle, von der die Daten ursprünglich stammen (Range `foaf:Agent`). Kann von Herausgeber (`dct:publisher`) und Ersteller (`dct:creator`) abweichen. Multiplizität 0..n. **4 · Verständliche Langbeschreibung:** Nennen Sie die Stelle, von der die Daten ursprünglich stammen — das kann eine andere sein als die, die sie jetzt veröffentlicht. So bleibt die Herkunft nachvollziehbar. Beispiel: Statistisches Landesamt. @@ -589,6 +646,8 @@ Legende der Stufen-Spalte: **Pflicht** (Veröffentlichung wird ohne dieses Feld |---|---| | DCAT-Property | `dcatde:originator` | | Meta-Key | `_odw_originator_email` | +| Multiplizität | `0..1` | +| Profil-Klasse | [Datensatz](https://www.dcat-ap.de/def/dcatde/3.0/spec/#datensatz) | | Stufe | Optional | | Vokabular | — | @@ -596,7 +655,7 @@ Legende der Stufen-Spalte: **Pflicht** (Veröffentlichung wird ohne dieses Feld **2 · Verständliche Frage:** Wie lautet die E-Mail-Adresse des Urhebers? -**3 · DCAT-AP-Langbeschreibung:** Ergänzt `dcatde:originator` um eine E-Mail-Adresse des ursprünglichen Urhebers (als `mailto:`-URI). Optional, Kardinalität 0..1. +**3 · DCAT-AP-Langbeschreibung:** Ergänzt `dcatde:originator` um eine E-Mail-Adresse des ursprünglichen Urhebers (als `mailto:`-URI). Optional, Multiplizität 0..1. **4 · Verständliche Langbeschreibung:** Optional die E-Mail-Adresse der ursprünglichen Urheber-Stelle, falls abweichend erreichbar. Beispiel: statistik@landesamt.de. @@ -606,6 +665,8 @@ Legende der Stufen-Spalte: **Pflicht** (Veröffentlichung wird ohne dieses Feld |---|---| | DCAT-Property | `dcatde:maintainer` | | Meta-Key | `_odw_maintainer_name` | +| Multiplizität | `0..n` | +| Profil-Klasse | [Datensatz](https://www.dcat-ap.de/def/dcatde/3.0/spec/#datensatz) | | Stufe | Optional | | Vokabular | — | @@ -613,7 +674,7 @@ Legende der Stufen-Spalte: **Pflicht** (Veröffentlichung wird ohne dieses Feld **2 · Verständliche Frage:** Wer pflegt diese Daten laufend? -**3 · DCAT-AP-Langbeschreibung:** `dcatde:maintainer` (DCAT-AP.de) benennt die für die laufende Pflege und Aktualisierung zuständige Stelle (Range `foaf:Agent`). Kardinalität 0..n. Kann von Herausgeber und Urheber abweichen. +**3 · DCAT-AP-Langbeschreibung:** `dcatde:maintainer` (DCAT-AP.de) benennt die für die laufende Pflege und Aktualisierung zuständige Stelle (Range `foaf:Agent`). Multiplizität 0..n. Kann von Herausgeber und Urheber abweichen. **4 · Verständliche Langbeschreibung:** Nennen Sie, wer die Daten laufend betreut und aktuell hält. Das ist die Stelle, die sich um Updates kümmert — nicht unbedingt die, die sie erstellt hat. Beispiel: Open-Data-Team. @@ -623,6 +684,8 @@ Legende der Stufen-Spalte: **Pflicht** (Veröffentlichung wird ohne dieses Feld |---|---| | DCAT-Property | `dcatde:maintainer` | | Meta-Key | `_odw_maintainer_email` | +| Multiplizität | `0..1` | +| Profil-Klasse | [Datensatz](https://www.dcat-ap.de/def/dcatde/3.0/spec/#datensatz) | | Stufe | Optional | | Vokabular | — | @@ -630,7 +693,7 @@ Legende der Stufen-Spalte: **Pflicht** (Veröffentlichung wird ohne dieses Feld **2 · Verständliche Frage:** Wie lautet die E-Mail-Adresse der pflegenden Stelle? -**3 · DCAT-AP-Langbeschreibung:** Ergänzt `dcatde:maintainer` um eine E-Mail-Adresse der pflegenden Stelle (als `mailto:`-URI). Optional, Kardinalität 0..1. +**3 · DCAT-AP-Langbeschreibung:** Ergänzt `dcatde:maintainer` um eine E-Mail-Adresse der pflegenden Stelle (als `mailto:`-URI). Optional, Multiplizität 0..1. **4 · Verständliche Langbeschreibung:** Optional die E-Mail-Adresse der Stelle, die die Daten pflegt. Beispiel: opendata@beispiel.de. @@ -640,6 +703,8 @@ Legende der Stufen-Spalte: **Pflicht** (Veröffentlichung wird ohne dieses Feld |---|---| | DCAT-Property | `dcatde:legalBasis` | | Meta-Key | `_odw_legal_basis` | +| Multiplizität | `0..n` | +| Profil-Klasse | [Datensatz](https://www.dcat-ap.de/def/dcatde/3.0/spec/#datensatz) | | Stufe | Optional | | Vokabular | — | @@ -647,7 +712,7 @@ Legende der Stufen-Spalte: **Pflicht** (Veröffentlichung wird ohne dieses Feld **2 · Verständliche Frage:** Auf welcher rechtlichen Grundlage werden die Daten bereitgestellt? -**3 · DCAT-AP-Langbeschreibung:** `dcatde:legalBasis` (DCAT-AP.de) nennt das Gesetz oder die Verordnung, die die Bereitstellung der Daten regelt (Freitext, `literal`). Kardinalität 0..n. +**3 · DCAT-AP-Langbeschreibung:** `dcatde:legalBasis` (DCAT-AP.de) nennt das Gesetz oder die Verordnung, die die Bereitstellung der Daten regelt (Freitext, `literal`). Multiplizität 0..n. **4 · Verständliche Langbeschreibung:** Falls es eine gesetzliche Grundlage für die Veröffentlichung gibt, nennen Sie sie hier. Das schafft Transparenz über die rechtliche Verpflichtung oder Erlaubnis. Beispiel: § 12a EGovG (E-Government-Gesetz). @@ -657,6 +722,8 @@ Legende der Stufen-Spalte: **Pflicht** (Veröffentlichung wird ohne dieses Feld |---|---| | DCAT-Property | `dcatde:qualityProcessURI` | | Meta-Key | `_odw_quality_process_uri` | +| Multiplizität | `0..1` | +| Profil-Klasse | [Datensatz](https://www.dcat-ap.de/def/dcatde/3.0/spec/#datensatz) | | Stufe | Optional | | Vokabular | — | @@ -664,7 +731,7 @@ Legende der Stufen-Spalte: **Pflicht** (Veröffentlichung wird ohne dieses Feld **2 · Verständliche Frage:** Wo ist das Qualitätssicherungs-Verfahren dokumentiert? -**3 · DCAT-AP-Langbeschreibung:** `dcatde:qualityProcessURI` (DCAT-AP.de) verweist per URI auf eine Beschreibung des Qualitätssicherungs-Prozesses des Datensatzes. Kardinalität 0..1. +**3 · DCAT-AP-Langbeschreibung:** `dcatde:qualityProcessURI` (DCAT-AP.de) verweist per URI auf eine Beschreibung des Qualitätssicherungs-Prozesses des Datensatzes. Multiplizität 0..1. **4 · Verständliche Langbeschreibung:** Verlinken Sie optional eine Seite, die beschreibt, wie Sie die Qualität der Daten sichern (z. B. Prüfschritte). Das stärkt das Vertrauen in Ihre Daten. Beispiel: https://beispiel.de/qualitaetssicherung. @@ -674,6 +741,8 @@ Legende der Stufen-Spalte: **Pflicht** (Veröffentlichung wird ohne dieses Feld |---|---| | DCAT-Property | `dct:accessRights` | | Meta-Key | `_odw_access_rights` | +| Multiplizität | `0..1` | +| Profil-Klasse | [Datensatz](https://www.dcat-ap.de/def/dcatde/3.0/spec/#datensatz) | | Stufe | Optional | | Vokabular | `access-right` | @@ -681,26 +750,9 @@ Legende der Stufen-Spalte: **Pflicht** (Veröffentlichung wird ohne dieses Feld **2 · Verständliche Frage:** Wer darf auf diese Daten zugreifen? -**3 · DCAT-AP-Langbeschreibung:** `dct:accessRights` klassifiziert den Zugriffsstatus über das EU-Vokabular „Access Right" (`PUBLIC`, `RESTRICTED`, `NON_PUBLIC`). Kardinalität 0..1. Relevant für die MQA-Dimension Wiederverwendbarkeit. +**3 · DCAT-AP-Langbeschreibung:** `dct:accessRights` klassifiziert den Zugriffsstatus über das EU-Vokabular „Access Right" (`PUBLIC`, `RESTRICTED`, `NON_PUBLIC`). Multiplizität 0..1. Relevant für die MQA-Dimension Wiederverwendbarkeit. -**4 · Verständliche Langbeschreibung:** Geben Sie an, ob die Daten für alle offen (öffentlich), nur eingeschränkt oder gar nicht öffentlich zugänglich sind. Für offene Daten ist das in der Regel „öffentlich". Beispiel: Öffentlich. - -### Welches weitere EU-Thema möchten Sie ergänzen? - -| Eigenschaft | Wert | -|---|---| -| DCAT-Property | `dcat:theme` | -| Meta-Key | `_odw_theme_uri` | -| Stufe | Optional | -| Vokabular | `data-theme` | - -**1 · DCAT-AP-Frage:** Welches zusätzliche `dcat:theme` (EU-Themen-URI) gilt für den Datensatz? - -**2 · Verständliche Frage:** Welches weitere EU-Thema möchten Sie ergänzen? - -**3 · DCAT-AP-Langbeschreibung:** Zusätzliches `dcat:theme` als direkte EU-Themen-URI (`http://publications.europa.eu/resource/authority/data-theme/…`). Ergänzt die Themen-Auswahl aus Tab 1 um weitere Themen. Kardinalität 0..n. - -**4 · Verständliche Langbeschreibung:** Falls Ihr Datensatz zu mehr als einem Thema passt, ergänzen Sie hier ein weiteres EU-Thema aus der Vorschlagsliste. Das erhöht die Auffindbarkeit über mehrere Themenfilter. Beispiel: Umwelt zusätzlich zu Gesundheit. +**4 · Verständliche Langbeschreibung:** Geben Sie an, ob die Daten für alle offen (öffentlich), nur eingeschränkt oder gar nicht öffentlich zugänglich sind. Für offene Daten ist das in der Regel „öffentlich". Beispiel: Öffentlich. „Öffentlich" ist bereits vorausgewählt — ändern Sie die Angabe nur, wenn der Zugriff eingeschränkt oder gar nicht öffentlich ist. ### Ist dies ein hochwertiger Datensatz (HVD)? @@ -708,6 +760,8 @@ Legende der Stufen-Spalte: **Pflicht** (Veröffentlichung wird ohne dieses Feld |---|---| | DCAT-Property | `dcatap:applicableLegislation` | | Meta-Key | `_odw_is_hvd` | +| Multiplizität | `0..1` | +| Profil-Klasse | [Datensatz](https://www.dcat-ap.de/def/dcatde/3.0/spec/#datensatz) | | Stufe | Optional | | Vokabular | — | @@ -715,9 +769,9 @@ Legende der Stufen-Spalte: **Pflicht** (Veröffentlichung wird ohne dieses Feld **2 · Verständliche Frage:** Ist dies ein hochwertiger Datensatz (HVD)? -**3 · DCAT-AP-Langbeschreibung:** Kennzeichen, ob der Datensatz ein High-Value-Dataset im Sinne der EU-Durchführungsverordnung 2023/138 ist. Ist es gesetzt, wird `dcatap:applicableLegislation` (Verweis auf die Verordnung) ausgegeben und das Feld HVD-Kategorie relevant. +**3 · DCAT-AP-Langbeschreibung:** Kennzeichen, ob der Datensatz ein High-Value-Dataset im Sinne der EU-Durchführungsverordnung 2023/138 ist. Ist es gesetzt, wird `dcatap:applicableLegislation` (Verweis auf die Verordnung) ausgegeben und das Feld HVD-Kategorie relevant. Multiplizität 0..1. -**4 · Verständliche Langbeschreibung:** „High-Value-Datasets" sind von der EU als besonders wertvoll eingestufte Datensätze (z. B. Geo-, Umwelt- oder Mobilitätsdaten). Setzen Sie dies nur, wenn Ihr Datensatz in eine der offiziellen HVD-Kategorien fällt — im Zweifel „Nein". Beispiel: Ja, bei amtlichen Geodaten. +**4 · Verständliche Langbeschreibung:** „High-Value-Datasets" sind von der EU als besonders wertvoll eingestufte Datensätze (z. B. Geo-, Umwelt- oder Mobilitätsdaten). Setzen Sie dies nur, wenn Ihr Datensatz in eine der offiziellen HVD-Kategorien fällt — im Zweifel „Nein". Beispiel: Ja, bei amtlichen Geodaten. Das betrifft ausschließlich öffentliche Stellen — Vereine, Verbände und andere zivilgesellschaftliche Organisationen können das Feld leer lassen. ### Welcher HVD-Kategorie gehört dieser Datensatz an? @@ -725,6 +779,8 @@ Legende der Stufen-Spalte: **Pflicht** (Veröffentlichung wird ohne dieses Feld |---|---| | DCAT-Property | `dcatap:hvdCategory` | | Meta-Key | `_odw_hvd_category` | +| Multiplizität | `0..n` | +| Profil-Klasse | [Datensatz](https://www.dcat-ap.de/def/dcatde/3.0/spec/#datensatz) | | Stufe | Optional | | Vokabular | `hvd-category` | @@ -732,7 +788,7 @@ Legende der Stufen-Spalte: **Pflicht** (Veröffentlichung wird ohne dieses Feld **2 · Verständliche Frage:** Welcher HVD-Kategorie gehört dieser Datensatz an? -**3 · DCAT-AP-Langbeschreibung:** `dcatap:hvdCategory` ordnet ein High-Value-Dataset einer der sechs HVD-Kategorien der EU zu (Geospatial, Erdbeobachtung/Umwelt, Meteorologie, Statistik, Unternehmen, Mobilität), referenziert per EU-URI. Nur relevant, wenn HVD gesetzt ist. Kardinalität 0..n. +**3 · DCAT-AP-Langbeschreibung:** `dcatap:hvdCategory` ordnet ein High-Value-Dataset einer der sechs HVD-Kategorien der EU zu (Geospatial, Erdbeobachtung/Umwelt, Meteorologie, Statistik, Unternehmen, Mobilität), referenziert per EU-URI. Nur relevant, wenn HVD gesetzt ist. Multiplizität 0..n. Hinweis: Die Eigenschaft stammt aus der HVD-Erweiterung zu DCAT-AP (EU-Durchführungsverordnung 2023/138), nicht aus dem Kernprofil DCAT-AP 3.0; keine der mitgelieferten SHACL-Shapes prüft sie deshalb. **4 · Verständliche Langbeschreibung:** Wenn es ein hochwertiger Datensatz ist, wählen Sie hier die passende der sechs EU-HVD-Kategorien. Damit ordnen Sie den Datensatz korrekt in das EU-Schema ein. Beispiel: Georaum, Mobilität, Statistik. @@ -742,6 +798,8 @@ Legende der Stufen-Spalte: **Pflicht** (Veröffentlichung wird ohne dieses Feld |---|---| | DCAT-Property | `dct:identifier` | | Meta-Key | `_odw_identifier` | +| Multiplizität | `0..n` | +| Profil-Klasse | [Datensatz](https://www.dcat-ap.de/def/dcatde/3.0/spec/#datensatz) | | Stufe | Optional | | Vokabular | — | @@ -749,9 +807,9 @@ Legende der Stufen-Spalte: **Pflicht** (Veröffentlichung wird ohne dieses Feld **2 · Verständliche Frage:** Welche eindeutige Kennung hat dieser Datensatz? -**3 · DCAT-AP-Langbeschreibung:** `dct:identifier` ist eine eindeutige, im System der Herausgeberin vergebene Kennung des Datensatzes (Freitext/`literal`). Kardinalität 0..n. Ermöglicht die stabile Referenzierung über Systemgrenzen hinweg. +**3 · DCAT-AP-Langbeschreibung:** `dct:identifier` ist eine eindeutige, im System der Herausgeberin vergebene Kennung des Datensatzes (Freitext/`literal`). Multiplizität 0..n. Ermöglicht die stabile Referenzierung über Systemgrenzen hinweg. -**4 · Verständliche Langbeschreibung:** Falls Ihr Datensatz eine feste Kennnummer aus Ihrem eigenen System hat, tragen Sie sie hier ein. So bleibt der Datensatz eindeutig identifizierbar. Beispiel: DS-2026-00042. +**4 · Verständliche Langbeschreibung:** Falls Ihr Datensatz eine feste Kennnummer aus Ihrem eigenen System hat, tragen Sie sie hier ein. So bleibt der Datensatz eindeutig identifizierbar. Beispiel: DS-2026-00042. Neben einer internen Nummer können Sie hier auch eine dauerhafte, extern vergebene Kennung wie einen DOI eintragen. ### Um welchen Typ von Datensatz handelt es sich? @@ -759,6 +817,8 @@ Legende der Stufen-Spalte: **Pflicht** (Veröffentlichung wird ohne dieses Feld |---|---| | DCAT-Property | `dct:type` | | Meta-Key | `_odw_type` | +| Multiplizität | `0..1` | +| Profil-Klasse | [Datensatz](https://www.dcat-ap.de/def/dcatde/3.0/spec/#datensatz) | | Stufe | Optional | | Vokabular | `dataset-type` | @@ -766,9 +826,9 @@ Legende der Stufen-Spalte: **Pflicht** (Veröffentlichung wird ohne dieses Feld **2 · Verständliche Frage:** Um welchen Typ von Datensatz handelt es sich? -**3 · DCAT-AP-Langbeschreibung:** `dct:type` klassifiziert die Art des Datensatzes, idealerweise über das EU-Vokabular „Dataset Type". Kardinalität 0..1. Unterscheidet z. B. Erhebungsdaten, Registerdaten oder Geodaten. +**3 · DCAT-AP-Langbeschreibung:** `dct:type` klassifiziert die Art des Datensatzes, idealerweise über das EU-Vokabular „Dataset Type". Multiplizität 0..1. Unterscheidet z. B. Erhebungsdaten, Registerdaten oder Geodaten. -**4 · Verständliche Langbeschreibung:** Geben Sie an, um welche Art von Datensatz es sich grundsätzlich handelt. Das hilft bei der groben Einordnung. Beispiel: Statistische Erhebung, Geodaten. +**4 · Verständliche Langbeschreibung:** Geben Sie an, um welche Art von Datensatz es sich grundsätzlich handelt. Das hilft bei der groben Einordnung. Beispiel: Statistische Erhebung, Geodaten. Einzutragen ist die vollständige Web-Adresse des passenden Eintrags aus der EU-Liste der Datensatz-Typen, nicht die Bezeichnung als Text. ### Wer hat diese Daten erstellt? @@ -776,6 +836,8 @@ Legende der Stufen-Spalte: **Pflicht** (Veröffentlichung wird ohne dieses Feld |---|---| | DCAT-Property | `dct:creator` | | Meta-Key | `_odw_creator_name` | +| Multiplizität | `0..n` | +| Profil-Klasse | [Datensatz](https://www.dcat-ap.de/def/dcatde/3.0/spec/#datensatz) | | Stufe | Optional | | Vokabular | — | @@ -783,7 +845,7 @@ Legende der Stufen-Spalte: **Pflicht** (Veröffentlichung wird ohne dieses Feld **2 · Verständliche Frage:** Wer hat diese Daten erstellt? -**3 · DCAT-AP-Langbeschreibung:** `dct:creator` benennt die primär für die Erstellung des Datensatzes verantwortliche Stelle oder Person (Range `foaf:Agent`). Kardinalität 0..n. Unterscheidet sich vom Herausgeber (`dct:publisher`), der für die Bereitstellung verantwortlich ist. +**3 · DCAT-AP-Langbeschreibung:** `dct:creator` benennt die primär für die Erstellung des Datensatzes verantwortliche Stelle oder Person (Range `foaf:Agent`). Multiplizität 0..n. Unterscheidet sich vom Herausgeber (`dct:publisher`), der für die Bereitstellung verantwortlich ist. **4 · Verständliche Langbeschreibung:** Nennen Sie, wer die Daten inhaltlich erstellt hat — die Person oder Stelle, die die eigentliche Arbeit gemacht hat. Das kann von der herausgebenden Organisation abweichen. Beispiel: Forschungsgruppe Stadtklima. @@ -793,6 +855,8 @@ Legende der Stufen-Spalte: **Pflicht** (Veröffentlichung wird ohne dieses Feld |---|---| | DCAT-Property | `dct:creator` | | Meta-Key | `_odw_creator_email` | +| Multiplizität | `0..1` | +| Profil-Klasse | [Datensatz](https://www.dcat-ap.de/def/dcatde/3.0/spec/#datensatz) | | Stufe | Optional | | Vokabular | — | @@ -800,7 +864,7 @@ Legende der Stufen-Spalte: **Pflicht** (Veröffentlichung wird ohne dieses Feld **2 · Verständliche Frage:** Wie lautet die E-Mail-Adresse des Erstellers? -**3 · DCAT-AP-Langbeschreibung:** Ergänzt `dct:creator` um eine E-Mail-Adresse der erstellenden Stelle (als `mailto:`-URI). Optional, Kardinalität 0..1. +**3 · DCAT-AP-Langbeschreibung:** Ergänzt `dct:creator` um eine E-Mail-Adresse der erstellenden Stelle (als `mailto:`-URI). Optional, Multiplizität 0..1. **4 · Verständliche Langbeschreibung:** Optional die E-Mail-Adresse der erstellenden Person oder Stelle. Beispiel: forschung@beispiel.de. @@ -810,6 +874,8 @@ Legende der Stufen-Spalte: **Pflicht** (Veröffentlichung wird ohne dieses Feld |---|---| | DCAT-Property | `owl:versionInfo` | | Meta-Key | `_odw_version` | +| Multiplizität | `0..1` | +| Profil-Klasse | [Datensatz](https://www.dcat-ap.de/def/dcatde/3.0/spec/#datensatz) | | Stufe | Optional | | Vokabular | — | @@ -817,7 +883,7 @@ Legende der Stufen-Spalte: **Pflicht** (Veröffentlichung wird ohne dieses Feld **2 · Verständliche Frage:** Welche Version hat dieser Datensatz? -**3 · DCAT-AP-Langbeschreibung:** `owl:versionInfo` gibt die Versionsbezeichnung des Datensatzes als Freitext an (`literal`). Kardinalität 0..1. Erlaubt die Unterscheidung aufeinanderfolgender Ausgaben desselben Datensatzes. +**3 · DCAT-AP-Langbeschreibung:** `owl:versionInfo` gibt die Versionsbezeichnung des Datensatzes als Freitext an (`literal`). Multiplizität 0..1. Erlaubt die Unterscheidung aufeinanderfolgender Ausgaben desselben Datensatzes. **4 · Verständliche Langbeschreibung:** Falls es mehrere Ausgaben Ihrer Daten gibt, tragen Sie die Versionsnummer ein. So wissen Nutzende, welche Fassung sie vor sich haben. Beispiel: 2.0. @@ -827,6 +893,8 @@ Legende der Stufen-Spalte: **Pflicht** (Veröffentlichung wird ohne dieses Feld |---|---| | DCAT-Property | `adms:versionNotes` | | Meta-Key | `_odw_version_notes` | +| Multiplizität | `0..n` | +| Profil-Klasse | [Datensatz](https://www.dcat-ap.de/def/dcatde/3.0/spec/#datensatz) | | Stufe | Optional | | Vokabular | — | @@ -834,7 +902,7 @@ Legende der Stufen-Spalte: **Pflicht** (Veröffentlichung wird ohne dieses Feld **2 · Verständliche Frage:** Was hat sich in dieser Version geändert? -**3 · DCAT-AP-Langbeschreibung:** `adms:versionNotes` beschreibt die Änderungen gegenüber der Vorversion als sprachlich getaggten Freitext (`literal-lang`). Kardinalität 0..n. Ergänzt `owl:versionInfo` um den inhaltlichen Änderungsverlauf. +**3 · DCAT-AP-Langbeschreibung:** `adms:versionNotes` beschreibt die Änderungen gegenüber der Vorversion als sprachlich getaggten Freitext (`literal-lang`). Multiplizität 0..n. Ergänzt `owl:versionInfo` um den inhaltlichen Änderungsverlauf. **4 · Verständliche Langbeschreibung:** Beschreiben Sie kurz, was sich gegenüber der letzten Version geändert hat — wie ein Änderungsprotokoll. Nutzende sehen so, ob sich ein erneuter Download lohnt. Beispiel: „Daten für 2025 ergänzt, Tippfehler korrigiert." @@ -844,6 +912,8 @@ Legende der Stufen-Spalte: **Pflicht** (Veröffentlichung wird ohne dieses Feld |---|---| | DCAT-Property | `dcat:spatialResolutionInMeters` | | Meta-Key | `_odw_spatial_resolution` | +| Multiplizität | `0..n` | +| Profil-Klasse | [Datensatz](https://www.dcat-ap.de/def/dcatde/3.0/spec/#datensatz) | | Stufe | Optional | | Vokabular | — | @@ -851,9 +921,9 @@ Legende der Stufen-Spalte: **Pflicht** (Veröffentlichung wird ohne dieses Feld **2 · Verständliche Frage:** Welche räumliche Auflösung haben die Daten (in Metern)? -**3 · DCAT-AP-Langbeschreibung:** `dcat:spatialResolutionInMeters` gibt die kleinste räumlich unterscheidbare Einheit in Metern an (`xsd:decimal`). Kardinalität 0..n. Relevant vor allem für Geodaten und Rasterdaten. +**3 · DCAT-AP-Langbeschreibung:** `dcat:spatialResolutionInMeters` gibt die kleinste räumlich unterscheidbare Einheit in Metern an (`xsd:decimal`). Multiplizität 0..n. Relevant vor allem für Geodaten und Rasterdaten. -**4 · Verständliche Langbeschreibung:** Bei Geodaten: Geben Sie an, wie fein die Daten räumlich aufgelöst sind — der kleinste unterscheidbare Abstand in Metern. Ein kleiner Wert bedeutet detailliertere Daten. Beispiel: 10 (Raster von 10 Metern). +**4 · Verständliche Langbeschreibung:** Bei Geodaten: Geben Sie an, wie fein die Daten räumlich aufgelöst sind — der kleinste unterscheidbare Abstand in Metern. Ein kleiner Wert bedeutet detailliertere Daten. Beispiel: 10 (Raster von 10 Metern). Tragen Sie dabei nur die Zahl ein, ohne die Einheit dahinterzuschreiben. ### Welche zeitliche Auflösung haben die Daten? @@ -861,6 +931,8 @@ Legende der Stufen-Spalte: **Pflicht** (Veröffentlichung wird ohne dieses Feld |---|---| | DCAT-Property | `dcat:temporalResolution` | | Meta-Key | `_odw_temporal_resolution` | +| Multiplizität | `0..1` | +| Profil-Klasse | [Datensatz](https://www.dcat-ap.de/def/dcatde/3.0/spec/#datensatz) | | Stufe | Optional | | Vokabular | — | @@ -868,7 +940,7 @@ Legende der Stufen-Spalte: **Pflicht** (Veröffentlichung wird ohne dieses Feld **2 · Verständliche Frage:** Welche zeitliche Auflösung haben die Daten? -**3 · DCAT-AP-Langbeschreibung:** `dcat:temporalResolution` gibt die kleinste zeitlich unterscheidbare Einheit als ISO-8601-Dauer an (`xsd:duration`). Kardinalität 0..1. Beschreibt z. B. den Messabstand einer Zeitreihe. +**3 · DCAT-AP-Langbeschreibung:** `dcat:temporalResolution` gibt die kleinste zeitlich unterscheidbare Einheit als ISO-8601-Dauer an (`xsd:duration`). Multiplizität 0..1. Beschreibt z. B. den Messabstand einer Zeitreihe. **4 · Verständliche Langbeschreibung:** Bei Zeitreihen: Geben Sie an, in welchem zeitlichen Abstand die Werte erfasst sind — z. B. stündlich, täglich, monatlich. Format ist die ISO-8601-Dauer. Beispiel: P1D (ein Tag) oder PT1H (eine Stunde). @@ -878,6 +950,8 @@ Legende der Stufen-Spalte: **Pflicht** (Veröffentlichung wird ohne dieses Feld |---|---| | DCAT-Property | `dct:conformsTo` | | Meta-Key | `_odw_conforms_to` | +| Multiplizität | `0..n` | +| Profil-Klasse | [Datensatz](https://www.dcat-ap.de/def/dcatde/3.0/spec/#datensatz) | | Stufe | Optional | | Vokabular | — | @@ -885,9 +959,9 @@ Legende der Stufen-Spalte: **Pflicht** (Veröffentlichung wird ohne dieses Feld **2 · Verständliche Frage:** Welchem Standard oder Schema entsprechen die Daten? -**3 · DCAT-AP-Langbeschreibung:** `dct:conformsTo` verweist auf einen implementierten Standard, ein Anwendungsprofil oder ein Schema, dem die Daten entsprechen (Range `dct:Standard`, per URI oder Bezeichnung). Kardinalität 0..n. +**3 · DCAT-AP-Langbeschreibung:** `dct:conformsTo` verweist auf einen implementierten Standard, ein Anwendungsprofil oder ein Schema, dem die Daten entsprechen (Range `dct:Standard`, per URI oder Bezeichnung). Multiplizität 0..n. -**4 · Verständliche Langbeschreibung:** Falls Ihre Daten einem bestimmten Standard oder Schema folgen, nennen Sie ihn hier. So können Systeme die Daten korrekt interpretieren. Beispiel: INSPIRE, XÖV oder ein fachliches Datenschema. +**4 · Verständliche Langbeschreibung:** Falls Ihre Daten einem bestimmten Standard oder Schema folgen, nennen Sie ihn hier. So können Systeme die Daten korrekt interpretieren. Beispiel: INSPIRE, XÖV oder ein fachliches Datenschema. Einzutragen ist die Web-Adresse, unter der der Standard beschrieben ist. ### Woher stammen die Daten und wie sind sie entstanden? @@ -895,6 +969,8 @@ Legende der Stufen-Spalte: **Pflicht** (Veröffentlichung wird ohne dieses Feld |---|---| | DCAT-Property | `dct:provenance` | | Meta-Key | `_odw_provenance` | +| Multiplizität | `0..n` | +| Profil-Klasse | [Datensatz](https://www.dcat-ap.de/def/dcatde/3.0/spec/#datensatz) | | Stufe | Optional | | Vokabular | — | @@ -902,7 +978,7 @@ Legende der Stufen-Spalte: **Pflicht** (Veröffentlichung wird ohne dieses Feld **2 · Verständliche Frage:** Woher stammen die Daten und wie sind sie entstanden? -**3 · DCAT-AP-Langbeschreibung:** `dct:provenance` beschreibt die Herkunft und Entstehungsgeschichte des Datensatzes (Range `dct:ProvenanceStatement`, Freitext). Kardinalität 0..n. Dokumentiert Erhebungs- und Verarbeitungsschritte. +**3 · DCAT-AP-Langbeschreibung:** `dct:provenance` beschreibt die Herkunft und Entstehungsgeschichte des Datensatzes (Range `dct:ProvenanceStatement`, Freitext). Multiplizität 0..n. Dokumentiert Erhebungs- und Verarbeitungsschritte. **4 · Verständliche Langbeschreibung:** Beschreiben Sie, woher die Daten kommen und wie sie entstanden sind — z. B. aus welcher Erhebung oder welchem Verfahren. Das macht die Daten nachvollziehbar und vertrauenswürdig. Beispiel: „Erhoben im Rahmen der Bürgerbefragung 2025, anonymisiert aufbereitet." @@ -912,6 +988,8 @@ Legende der Stufen-Spalte: **Pflicht** (Veröffentlichung wird ohne dieses Feld |---|---| | DCAT-Property | `dct:title` | | Meta-Key | `_odw_dist_title` | +| Multiplizität | `0..n` | +| Profil-Klasse | [Distribution](https://www.dcat-ap.de/def/dcatde/3.0/spec/#distribution) | | Stufe | Optional | | Vokabular | — | @@ -919,7 +997,7 @@ Legende der Stufen-Spalte: **Pflicht** (Veröffentlichung wird ohne dieses Feld **2 · Verständliche Frage:** Wie heißt die bereitgestellte Datei/Distribution? -**3 · DCAT-AP-Langbeschreibung:** `dct:title` auf Ebene der Distribution benennt die konkrete bereitgestellte Ressource (`literal-lang`). Kardinalität 0..n. Nützlich, wenn der Distributionsname vom Datensatztitel abweicht. +**3 · DCAT-AP-Langbeschreibung:** `dct:title` auf Ebene der Distribution benennt die konkrete bereitgestellte Ressource (`literal-lang`). Multiplizität 0..n. Nützlich, wenn der Distributionsname vom Datensatztitel abweicht. **4 · Verständliche Langbeschreibung:** Geben Sie der bereitgestellten Datei einen eigenen Namen, falls er sich vom Titel des Datensatzes unterscheidet. Beispiel: „Rohdaten CSV 2025". @@ -929,6 +1007,8 @@ Legende der Stufen-Spalte: **Pflicht** (Veröffentlichung wird ohne dieses Feld |---|---| | DCAT-Property | `dct:description` | | Meta-Key | `_odw_dist_description` | +| Multiplizität | `0..n` | +| Profil-Klasse | [Distribution](https://www.dcat-ap.de/def/dcatde/3.0/spec/#distribution) | | Stufe | Optional | | Vokabular | — | @@ -936,7 +1016,7 @@ Legende der Stufen-Spalte: **Pflicht** (Veröffentlichung wird ohne dieses Feld **2 · Verständliche Frage:** Wie lässt sich die Distribution beschreiben? -**3 · DCAT-AP-Langbeschreibung:** `dct:description` auf Distributionsebene beschreibt die konkrete Datei/Ressource (`literal-lang`). Kardinalität 0..n. Ergänzt die Datensatzbeschreibung um distributionsspezifische Hinweise (z. B. Spaltenaufbau). +**3 · DCAT-AP-Langbeschreibung:** `dct:description` auf Distributionsebene beschreibt die konkrete Datei/Ressource (`literal-lang`). Multiplizität 0..n. Ergänzt die Datensatzbeschreibung um distributionsspezifische Hinweise (z. B. Spaltenaufbau). **4 · Verständliche Langbeschreibung:** Beschreiben Sie die konkrete Datei näher — etwa welche Spalten sie enthält oder wie sie aufgebaut ist. Das hilft beim direkten Umgang mit der Datei. Beispiel: „Spalten: Jahr, Stadt, Einwohner; Trennzeichen Semikolon." @@ -946,6 +1026,8 @@ Legende der Stufen-Spalte: **Pflicht** (Veröffentlichung wird ohne dieses Feld |---|---| | DCAT-Property | `dcat:downloadURL` | | Meta-Key | `_odw_download_url` | +| Multiplizität | `0..n` | +| Profil-Klasse | [Distribution](https://www.dcat-ap.de/def/dcatde/3.0/spec/#distribution) | | Stufe | Optional | | Vokabular | — | @@ -953,7 +1035,7 @@ Legende der Stufen-Spalte: **Pflicht** (Veröffentlichung wird ohne dieses Feld **2 · Verständliche Frage:** Wie lautet der direkte Download-Link zur Datei? -**3 · DCAT-AP-Langbeschreibung:** `dcat:downloadURL` verweist auf eine direkt herunterladbare Datei (Range `rdfs:Resource`). Anders als `dcat:accessURL` garantiert sie einen unmittelbaren Download derselben Ressource. Kardinalität 0..n. Relevant für die MQA-Dimension Zugänglichkeit. +**3 · DCAT-AP-Langbeschreibung:** `dcat:downloadURL` verweist auf eine direkt herunterladbare Datei (Range `rdfs:Resource`). Anders als `dcat:accessURL` garantiert sie einen unmittelbaren Download derselben Ressource. Multiplizität 0..n. Relevant für die MQA-Dimension Zugänglichkeit. **4 · Verständliche Langbeschreibung:** Falls es einen direkten Link gibt, der die Datei sofort herunterlädt (ohne Umweg über eine Seite), tragen Sie ihn hier ein. Das ist der bequemste Weg für Nachnutzende. Beispiel: https://beispiel.de/daten/statistik.csv. @@ -963,6 +1045,8 @@ Legende der Stufen-Spalte: **Pflicht** (Veröffentlichung wird ohne dieses Feld |---|---| | DCAT-Property | `dcat:mediaType` | | Meta-Key | `_odw_media_type` | +| Multiplizität | `0..1` | +| Profil-Klasse | [Distribution](https://www.dcat-ap.de/def/dcatde/3.0/spec/#distribution) | | Stufe | Optional | | Vokabular | `iana-media-type` | @@ -970,9 +1054,9 @@ Legende der Stufen-Spalte: **Pflicht** (Veröffentlichung wird ohne dieses Feld **2 · Verständliche Frage:** Welchen Medientyp (MIME) hat die Datei? -**3 · DCAT-AP-Langbeschreibung:** `dcat:mediaType` gibt den Medientyp der Distribution als IANA-Media-Type an (z. B. `text/csv`, `application/json`), referenziert über das IANA-Media-Types-Register. Kardinalität 0..1. Ergänzt `dct:format` um den technischen MIME-Typ. +**3 · DCAT-AP-Langbeschreibung:** `dcat:mediaType` gibt den Medientyp der Distribution als IANA-Media-Type an (z. B. `text/csv`, `application/json`), referenziert über das IANA-Media-Types-Register. Multiplizität 0..1. Ergänzt `dct:format` um den technischen MIME-Typ. -**4 · Verständliche Langbeschreibung:** Der technische Medientyp der Datei (MIME-Typ) — die maschinenlesbare Entsprechung zum Format. Systeme erkennen daran, wie sie die Datei behandeln müssen. Beispiel: text/csv, application/json. +**4 · Verständliche Langbeschreibung:** Der technische Medientyp der Datei (MIME-Typ) — die maschinenlesbare Entsprechung zum Format. Systeme erkennen daran, wie sie die Datei behandeln müssen. Beispiel: text/csv, application/json. Einzutragen ist die vollständige Web-Adresse aus dem IANA-Verzeichnis, zum Beispiel https://www.iana.org/assignments/media-types/text/csv. ### Welche Nutzungsrechte gelten für die Datei? @@ -980,6 +1064,8 @@ Legende der Stufen-Spalte: **Pflicht** (Veröffentlichung wird ohne dieses Feld |---|---| | DCAT-Property | `dct:rights` | | Meta-Key | `_odw_dist_rights` | +| Multiplizität | `0..1` | +| Profil-Klasse | [Distribution](https://www.dcat-ap.de/def/dcatde/3.0/spec/#distribution) | | Stufe | Optional | | Vokabular | — | @@ -987,7 +1073,7 @@ Legende der Stufen-Spalte: **Pflicht** (Veröffentlichung wird ohne dieses Feld **2 · Verständliche Frage:** Welche Nutzungsrechte gelten für die Datei? -**3 · DCAT-AP-Langbeschreibung:** `dct:rights` beschreibt rechtliche Hinweise zur Distribution jenseits der Lizenz — etwa Urheberrechts- oder Zugriffsvermerke (Range `dct:RightsStatement`, Freitext oder URI). Kardinalität 0..1. +**3 · DCAT-AP-Langbeschreibung:** `dct:rights` beschreibt rechtliche Hinweise zur Distribution jenseits der Lizenz — etwa Urheberrechts- oder Zugriffsvermerke (Range `dct:RightsStatement`, Freitext oder URI). Multiplizität 0..1. **4 · Verständliche Langbeschreibung:** Ergänzende rechtliche Hinweise zur Datei, die über die Lizenz hinausgehen — z. B. Urheberrechtsvermerke. Für viele offene Datensätze bleibt das leer. Beispiel: „© Stadt Musterstadt 2026". diff --git a/includes/class-admin.php b/includes/class-admin.php index 354629bc..89dbed6b 100644 --- a/includes/class-admin.php +++ b/includes/class-admin.php @@ -137,8 +137,8 @@ public static function render_column( string $column, int $post_id ): void { break; case 'odw_theme': - $theme = (string) carbon_get_post_meta( $post_id, 'odw_theme' ); - echo esc_html( '' !== $theme ? ODW_Fields::resolve_label( 'theme', $theme ) : '—' ); + $themes = ODW_Fields::theme_labels( $post_id ); + echo esc_html( array() !== $themes ? implode( ', ', $themes ) : '—' ); break; case 'odw_status': @@ -236,7 +236,7 @@ public static function handle_meta_orderby( WP_Query $query ): void { } if ( 'odw_theme' === $query->get( 'orderby' ) ) { - $query->set( 'meta_key', '_odw_theme' ); + $query->set( 'meta_key', '_odw_theme_sort' ); $query->set( 'orderby', 'meta_value' ); } @@ -403,11 +403,6 @@ public static function enqueue_assets( string $hook ): void { 'licenseDescriptions' => (object) ODW_Fields::get_license_descriptions(), 'cessdaOptions' => $cessda_options, 'spatialOptions' => $spatial_options, - 'vocabularies' => array( - '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' ), 'placeholder' => __( 'Thema eintippen oder auswählen…', 'open-data-wizard' ), @@ -419,8 +414,8 @@ public static function enqueue_assets( string $hook ): void { ), 'required' => array( 'star' => '*', - 'starTitle' => __( 'Pflichtfeld zum Veröffentlichen', 'open-data-wizard' ), - 'legend' => __( '* Pflichtfeld zum Veröffentlichen. Als Entwurf können Sie jederzeit unvollständig speichern.', 'open-data-wizard' ), + 'starTitle' => __( 'Pflichtfeld für die Veröffentlichung', 'open-data-wizard' ), + 'legend' => __( '* Pflichtfeld für die Veröffentlichung. Als Entwurf können Sie den Datensatz jederzeit speichern.', 'open-data-wizard' ), 'keys' => array( '_odw_publisher', '_odw_description', '_odw_license' ), ), 'livePreview' => array( @@ -446,6 +441,14 @@ public static function enqueue_assets( string $hook ): void { 'toggle' => __( 'Mehr erfahren', 'open-data-wizard' ), 'dcat' => __( 'DCAT-AP-Definition', 'open-data-wizard' ), 'plain' => __( 'Einfach erklärt', 'open-data-wizard' ), + 'prop' => __( 'Eigenschaft', 'open-data-wizard' ), + 'mult' => __( 'Multiplizität', 'open-data-wizard' ), + 'spec' => __( 'Im Standard nachlesen', 'open-data-wizard' ), + 'ent' => array( + 'dataset' => __( 'Datensatz', 'open-data-wizard' ), + 'distribution' => __( 'Distribution', 'open-data-wizard' ), + 'catalog' => __( 'Katalog', 'open-data-wizard' ), + ), ), ) ); @@ -790,7 +793,7 @@ class="odw-introduction-figure"

- +

diff --git a/includes/class-batch-import.php b/includes/class-batch-import.php index 482969f9..f4302da4 100644 --- a/includes/class-batch-import.php +++ b/includes/class-batch-import.php @@ -479,13 +479,15 @@ private static function create_dataset_from_record( array $record, int $row_inde if ( isset( $record[ $field ] ) && ! empty( $record[ $field ] ) ) { $value = (string) $record[ $field ]; + if ( 'theme' === $field ) { + // Themen werden weiter unten gesetzt: Seit v2.41.0 ist das Feld + // eine Mehrfachauswahl und muss über die Carbon-Fields-API + // geschrieben werden, nicht über den flachen Meta-Key. + continue; + } + if ( 'byte_size' === $field ) { $value = (string) absint( $value ); - } elseif ( 'theme' === $field ) { - // Code (SOCI) oder Label → gespeicherte EU-URI. - $value = class_exists( 'ODW_Fields' ) - ? ODW_Fields::resolve_theme_uri( sanitize_text_field( $value ) ) - : sanitize_text_field( $value ); } elseif ( 'keywords' === $field ) { // Schlagworte werden intern zeilengetrennt gespeichert. Import // erlaubt Komma- ODER Zeilentrennung — beides zu Zeilen normalisieren. @@ -509,6 +511,20 @@ static function ( string $keyword ): bool { } } + // Themen: Mehrfachauswahl seit v2.41.0. Der Import erlaubt Komma- oder + // Zeilentrennung, jeder Eintrag wird zur EU-URI aufgelöst. Geschrieben + // wird über carbon_set_post_meta(), weil Carbon Fields Mehrfachwerte + // unter eigenen Meta-Keys ablegt; die flache Spiegelung zieht danach nach. + if ( isset( $record['theme'] ) && '' !== trim( (string) $record['theme'] ) && class_exists( 'ODW_Fields' ) ) { + $split = preg_split( '/[\r\n,]+/', self::neutralize_formula( (string) $record['theme'] ) ); + $themes = ODW_Fields::normalize_themes( is_array( $split ) ? $split : array() ); + + if ( array() !== $themes ) { + carbon_set_post_meta( $post_id, 'odw_theme', $themes ); + ODW_Fields::sync_theme_index( $post_id ); + } + } + // Set import tracking. update_post_meta( $post_id, '_odw_imported', current_time( 'mysql' ) ); diff --git a/includes/class-field-reference.php b/includes/class-field-reference.php index 2f7418dc..c9b89a97 100644 --- a/includes/class-field-reference.php +++ b/includes/class-field-reference.php @@ -43,6 +43,38 @@ class ODW_Field_Reference { 'conditional' => 'Bedingt', ); + /** + * Abschnitt der DCAT-AP.de-Spezifikation je Profil-Klasse. + * + * Bewusst grobkörnig — ein Link je Klasse statt je Feld. Die feldgenauen + * Anker (etwa `#datensatz-herausgeber`) ließen sich hier nicht überprüfen, + * weil dcat-ap.de aus der Entwicklungsumgebung nicht erreichbar ist; ein + * falscher Anker führte zu 53 Links, von denen einige ins Leere zeigen. + * Bei den drei Klassen-Ankern ist der Schaden im Fehlerfall null: Der + * Browser landet dann am Seitenanfang, also weiterhin im richtigen Dokument. + * + * @var array + */ + private const SPEC_ANCHORS = array( + 'dataset' => 'datensatz', + 'distribution' => 'distribution', + 'catalog' => 'katalog', + ); + + /** Basis-URL der Spezifikation. */ + private const SPEC_BASE = 'https://www.dcat-ap.de/def/dcatde/3.0/spec/'; + + /** + * Returns the spec section URL for a profile class, or '' when unknown. + * + * @param string $entity Profile class ('dataset', 'distribution', 'catalog'). + * @return string + */ + public static function spec_url( string $entity ): string { + $anchor = self::SPEC_ANCHORS[ $entity ] ?? ''; + return '' !== $anchor ? self::SPEC_BASE . '#' . $anchor : ''; + } + /** * Loads the field catalog array. * @@ -62,17 +94,22 @@ public static function load_catalog(): array { * Returns a compact catalog map for the admin JS ("Mehr erfahren" panels). * * Only the fields needed on the client are exposed: the distribution meta key - * (to locate the DOM field) and the two long descriptions. + * (to locate the DOM field), the two long descriptions und die beiden + * Merkmale, die das Panel als Kurzangabe über der Definition zeigt. * - * @return array + * @return array */ public static function js_map(): array { $map = array(); foreach ( self::load_catalog() as $field ) { $map[] = array( - 'meta_key' => (string) $field['meta_key'], - 'desc_dcat' => (string) $field['desc_dcat'], - 'desc_human' => (string) $field['desc_human'], + 'meta_key' => (string) $field['meta_key'], + 'dcat_prop' => (string) ( $field['dcat_prop'] ?? '' ), + 'cardinality' => (string) ( $field['cardinality'] ?? '' ), + 'entity' => (string) ( $field['entity'] ?? '' ), + 'spec_url' => self::spec_url( (string) ( $field['entity'] ?? '' ) ), + 'desc_dcat' => (string) $field['desc_dcat'], + 'desc_human' => (string) $field['desc_human'], ); } return $map; @@ -137,6 +174,11 @@ public static function build(): string { $out[] = '|---|---|'; $out[] = '| DCAT-Property | `' . $field['dcat_prop'] . '` |'; $out[] = '| Meta-Key | `' . ( '' !== $field['meta_key'] ? $field['meta_key'] : '—' ) . '` |'; + $out[] = '| Multiplizität | `' . ( '' !== ( $field['cardinality'] ?? '' ) ? $field['cardinality'] : '—' ) . '` |'; + $spec = self::spec_url( (string) ( $field['entity'] ?? '' ) ); + $out[] = '| Profil-Klasse | ' . ( '' !== $spec + ? '[' . ( 'distribution' === $field['entity'] ? 'Distribution' : 'Datensatz' ) . '](' . $spec . ') |' + : '— |' ); $out[] = '| Stufe | ' . $tier . ' |'; $out[] = '| Vokabular | ' . $vocab . ' |'; $out[] = ''; diff --git a/includes/class-fields.php b/includes/class-fields.php index adc96e3c..5fcd4e2f 100644 --- a/includes/class-fields.php +++ b/includes/class-fields.php @@ -32,6 +32,11 @@ public static function init(): void { // save_post_{post_type} grundsätzlich DAVOR — nur mit 'save_post'@20 läuft // das Auto-Update nach CF und wird nicht vom Formularwert überschrieben. add_action( 'save_post', array( self::class, 'set_modified_date' ), 20, 2 ); + // Auf 'save_post'@30, NICHT auf save_post_odw_dataset: WordPress feuert + // save_post_{post_type} vor save_post, die Spiegelung liefe dann vor + // Carbon Fields und läse den alten Wert. Die Typprüfung steht in der + // Methode. + add_action( 'save_post', array( self::class, 'sync_theme_index' ), 30 ); } /** @@ -72,7 +77,7 @@ private static function register_required_fields(): void { ->set_attribute( 'data-odw-required', '1' ) ->set_default_value( class_exists( 'ODW_Settings' ) ? (string) ODW_Settings::get( 'default_publisher' ) : '' ) ->set_attribute( 'placeholder', __( 'z.B. Musterorganisation e.V.', 'open-data-wizard' ) ) - ->set_help_text( __( 'HERAUSGEBENDE ORGANISATION (dct:publisher)', 'open-data-wizard' ) . "\n\n" . __( 'Beispiel: Musterstadt Statistikamt, Umweltbundesamt, Verbraucherzentrale e.V.', 'open-data-wizard' ) ), + ->set_help_text( __( 'HERAUSGEBENDE ORGANISATION (dct:publisher)', 'open-data-wizard' ) ), // Beschreibung direkt nach dem Herausgeber (beide Pflicht), damit die // zwei wichtigsten Angaben oben stehen (B3). @@ -81,11 +86,15 @@ private static function register_required_fields(): void { ->set_attribute( 'data-odw-required', '1' ) ->set_rows( 5 ) ->set_attribute( 'placeholder', __( 'Kurze Beschreibung des Datensatzes…', 'open-data-wizard' ) ) - ->set_help_text( __( 'BESCHREIBUNG (dct:description)', 'open-data-wizard' ) . "\n\n" . __( 'Beispiel: Ein Überblick über die bevölkerungsreichsten Städte in Deutschland mit statistischen Daten zu Einwohnerzahl und Entwicklung.', 'open-data-wizard' ) ), + ->set_help_text( __( 'BESCHREIBUNG (dct:description)', 'open-data-wizard' ) ), - Field::make( 'select', 'odw_theme', __( 'Welchem Thema ist dieser Datensatz zugeordnet?', 'open-data-wizard' ) ) - ->add_options( self::get_theme_options() ) - ->set_help_text( __( 'THEMA (dcat:theme)', 'open-data-wizard' ) . "\n\n" . __( 'Beispiel: Umwelt, Bildung, Gesundheit, Wirtschaft, Kultur', 'open-data-wizard' ) ), + // Mehrfachauswahl statt Einzelauswahl: dcat:theme erlaubt laut Profil + // 0..n Themen. Vorher gab es ein Auswahlfeld hier und ein + // Vorschlagsfeld unter „Erweiterte Angaben" — zwei Bedienarten + // für dieselbe Sache, zusammen höchstens zwei Themen. + Field::make( 'multiselect', 'odw_theme', __( 'Welchen Themen ist dieser Datensatz zugeordnet?', 'open-data-wizard' ) ) + ->add_options( self::get_theme_options_multi() ) + ->set_help_text( __( 'THEMA (dcat:theme)', 'open-data-wizard' ) ), // Schlagworte gehören zur inhaltlichen Erschließung und stehen // deshalb bei Thema, CESSDA und Engagementfeld statt bei Sprache @@ -94,7 +103,7 @@ private static function register_required_fields(): void { Field::make( 'textarea', 'odw_keywords', __( 'Mit welchen Schlagworten finde ich diese Daten?', 'open-data-wizard' ) ) ->set_rows( 3 ) ->set_attribute( 'placeholder', __( "Umwelt\nWasser\nLuftverschmutzung", 'open-data-wizard' ) ) - ->set_help_text( __( 'SCHLAGWORTE (dcat:keyword)', 'open-data-wizard' ) . "\n\n" . __( "Jedes Schlagwort in eine eigene Zeile (nicht mit Komma trennen). Beispiel:\nUmwelt\nWasser\nLuftverschmutzung", 'open-data-wizard' ) ), + ->set_help_text( __( 'SCHLAGWORTE (dcat:keyword)', 'open-data-wizard' ) ), // Weniger häufige Einordnungen (CESSDA, ZiviZ) als aufklappbare // Untergruppe ans Tab-Ende — entschlackt den Einstieg für die @@ -109,16 +118,20 @@ private static function register_required_fields(): void { Field::make( 'text', 'odw_cessda_topic', __( 'Ordnen Sie den Datensatz einem oder mehreren Themenfeld nach CESSDA-Vokabular zu', 'open-data-wizard' ) ) ->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' ) ), + ->set_help_text( __( 'CESSDA THEMENKLASSIFIKATION (dct:subject)', 'open-data-wizard' ) ), // Der Wert landet als dct:subject am Datensatz, nicht am Herausgeber. // Die Frage muss das abbilden — sonst tragen Redakteur:innen das // Tätigkeitsfeld ihrer Organisation ein und der Datensatz erhält // eine inhaltlich falsche Sacherschließung. - Field::make( 'text', 'odw_engagementfeld', __( 'Welchem Engagementfeld ist dieser Datensatz zuzuordnen?', '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' ) ), + // Mehrfachauswahl statt Tipp-Feld: 16 Einträge passen in eine + // Liste, und dct:subject erlaubt 0..n. Der Tester fragte + // ausdrücklich nach einem Dropdown, das aussieht wie die + // übrigen — statt einer Vorschlagsliste, die erst nach dem + // Tippen zeigt, dass es überhaupt eine Auswahl gibt. + Field::make( 'multiselect', 'odw_engagementfeld', __( 'Welchen Engagementfeldern ist dieser Datensatz zuzuordnen?', 'open-data-wizard' ) ) + ->add_options( self::vocabulary_options( 'engagementfeld' ) ) + ->set_help_text( __( 'ENGAGEMENTFELD (ZiviZ, dct:subject)', 'open-data-wizard' ) ), ) ) @@ -137,7 +150,7 @@ private static function register_required_fields(): void { Field::make( 'select', 'odw_language', __( 'In welcher Sprache sind die Daten?', 'open-data-wizard' ) ) ->set_default_value( class_exists( 'ODW_Settings' ) ? (string) ODW_Settings::get( 'default_language' ) : '' ) ->add_options( self::get_language_options() ) - ->set_help_text( __( 'SPRACHE (dct:language)', 'open-data-wizard' ) . "\n\n" . __( 'Beispiel: Deutsch, Englisch', 'open-data-wizard' ) ), + ->set_help_text( __( 'SPRACHE (dct:language)', 'open-data-wizard' ) ), Field::make( 'html', 'odw_hint_translations' ) ->set_html( '

' . esc_html__( 'Übersetzungen (optional)', 'open-data-wizard' ) . '

' . esc_html__( 'Titel, Beschreibung und Schlagworte zusätzlich in weiteren Sprachen — für mehrsprachige, DCAT-AP-konforme Metadaten. Die Angaben in Tab 1 bleiben die Hauptsprache.', 'open-data-wizard' ) . '

' ), @@ -216,7 +229,7 @@ private static function register_required_fields(): void { Field::make( 'text', 'odw_access_url', __( 'Ergänzen Sie den Link zu Ihrem Datensatz oder laden Sie die Datei in die Mediathek hoch', 'open-data-wizard' ) ) ->set_attribute( 'placeholder', 'https://beispiel.de/daten/datei.csv' ) ->set_attribute( 'type', 'url' ) - ->set_help_text( __( 'ZUGRIFFS-URL (dcat:accessURL)', 'open-data-wizard' ) . "\n\n" . __( 'Zwei Wege — einer genügt: Tragen Sie hier den Link zu Ihrer Datei ein ODER laden Sie die Datei direkt darunter aus der Mediathek hoch. Bei einem Upload wird die URL beim Speichern automatisch übernommen; dieses Feld können Sie dann leer lassen.', 'open-data-wizard' ) ), + ->set_help_text( __( 'ZUGRIFFS-URL (dcat:accessURL)', 'open-data-wizard' ) ), // Der Datei-Upload stand früher als eigene Meta-Box in der // Seitenleiste — zwei Orte für denselben Sachverhalt, die zu @@ -235,7 +248,7 @@ static function (): string { Field::make( 'select', 'odw_format', __( 'In welchem Format ist die Datei?', 'open-data-wizard' ) ) ->add_options( self::get_format_options() ) - ->set_help_text( __( 'FORMAT (dct:format)', 'open-data-wizard' ) . "\n\n" . __( 'Beispiel: CSV, JSON, PDF', 'open-data-wizard' ) ), + ->set_help_text( __( 'FORMAT (dct:format)', 'open-data-wizard' ) ), Field::make( 'text', 'odw_byte_size', __( 'Dateigröße (Bytes)', 'open-data-wizard' ) ) ->set_attribute( 'type', 'number' ) @@ -247,7 +260,7 @@ static function (): string { ->set_attribute( 'data-odw-required', '1' ) ->set_default_value( class_exists( 'ODW_Settings' ) ? (string) ODW_Settings::get( 'default_license' ) : '' ) ->add_options( self::get_license_options() ) - ->set_help_text( __( 'LIZENZ (dct:license)', 'open-data-wizard' ) . "\n\n" . __( 'Beispiel: CC0 1.0, CC-BY 4.0 – Diese bestimmt, wie andere die Daten nutzen dürfen.', 'open-data-wizard' ) ), + ->set_help_text( __( 'LIZENZ (dct:license)', 'open-data-wizard' ) ), Field::make( 'html', 'odw_license_info' ) ->set_html( '' ), @@ -255,7 +268,7 @@ static function (): string { Field::make( 'text', 'odw_license_custom', __( 'Lizenz-URI eingeben oder auswählen', 'open-data-wizard' ) ) ->set_attribute( 'placeholder', __( 'https://example.org/meine-lizenz', 'open-data-wizard' ) ) ->set_attribute( 'data-odw-autosuggest', 'license_custom' ) - ->set_help_text( __( 'EIGENE LIZENZ-URI', 'open-data-wizard' ) . "\n\n" . __( 'Vollständige URI der Lizenz eingeben oder aus der Liste auswählen. Beispiel: https://creativecommons.org/licenses/by/4.0/', 'open-data-wizard' ) ) + ->set_help_text( __( 'EIGENE LIZENZ-URI (dct:license)', 'open-data-wizard' ) ) ->set_conditional_logic( array( array( @@ -268,7 +281,7 @@ static function (): string { Field::make( 'text', 'odw_attribution_text', __( 'Welcher Namensnennungstext soll bei Weiternutzung angegeben werden?', 'open-data-wizard' ) ) ->set_attribute( 'placeholder', __( 'optional – nur bei CC BY oder CC BY-SA', 'open-data-wizard' ) ) - ->set_help_text( __( 'NAMENSNENNUNGSTEXT (dcatde:licenseAttributionByText)', 'open-data-wizard' ) . "\n\n" . __( 'Empfohlen bei CC BY und CC BY-SA Lizenzen. Beispiel: Datensatz von Musterorganisation e.V., bereitgestellt unter CC BY 4.0', 'open-data-wizard' ) ) + ->set_help_text( __( 'NAMENSNENNUNGSTEXT (dcatde:licenseAttributionByText)', 'open-data-wizard' ) ) ->set_conditional_logic( array( 'relation' => 'OR', @@ -287,7 +300,7 @@ static function (): string { Field::make( 'select', 'odw_availability', __( 'Wie verlässlich bleibt diese Datei abrufbar?', 'open-data-wizard' ) ) ->add_options( self::get_availability_options() ) - ->set_help_text( __( 'PLANBARE VERFÜGBARKEIT (dcatap:availability)', 'open-data-wizard' ) . "\n\n" . __( 'Wie verlässlich/dauerhaft ist der Zugriff auf diese Datei geplant? Beispiel: Stabil, Verfügbar, Temporär', 'open-data-wizard' ) ), + ->set_help_text( __( 'PLANBARE VERFÜGBARKEIT (dcatap:availability)', 'open-data-wizard' ) ), Field::make( 'complex', 'odw_extra_distributions', __( 'Weitere Distributionen', 'open-data-wizard' ) ) ->set_help_text( __( 'MEHRERE DISTRIBUTIONEN (dcat:distribution)', 'open-data-wizard' ) . "\n\n" . __( 'Optional: zusätzliche Zugänge zu diesem Datensatz — z. B. dieselben Daten in einem weiteren Format oder unter einer anderen URL. Die oben angegebene Datei bleibt die primäre Distribution.', 'open-data-wizard' ) ) @@ -356,7 +369,7 @@ static function (): string { Field::make( 'text', 'odw_landing_page', __( 'Wo finde ich die Projektseite zu diesen Daten?', 'open-data-wizard' ) ) ->set_attribute( 'type', 'url' ) ->set_attribute( 'placeholder', 'https://beispiel.de/projekt' ) - ->set_help_text( __( 'PROJEKTSEITE (dcat:landingPage)', 'open-data-wizard' ) . "\n\n" . __( 'URL der Projektwebsite oder des Datenportals mit weiteren Informationen zum Datensatz. Beispiel: https://beispiel.de/projekt', 'open-data-wizard' ) ), + ->set_help_text( __( 'PROJEKTSEITE (dcat:landingPage)', 'open-data-wizard' ) ), // Erstveröffentlichung und Aktualisierungsfrequenz beschreiben // beide die Aktualität des Datensatzes und stehen deshalb hier @@ -369,7 +382,7 @@ static function (): string { 'locale' => 'de', ) ) - ->set_help_text( __( 'VERÖFFENTLICHUNGSDATUM (dct:issued)', 'open-data-wizard' ) . "\n\n" . __( 'Beispiel: 2024-01-15', 'open-data-wizard' ) ), + ->set_help_text( __( 'VERÖFFENTLICHUNGSDATUM (dct:issued)', 'open-data-wizard' ) ), // Das Änderungsdatum (dct:modified) hat kein Eingabefeld mehr: // ODW_Fields::set_modified_date() überschreibt _odw_modified bei @@ -387,28 +400,28 @@ static function (): string { Field::make( 'select', 'odw_accrual_periodicity', __( 'Wie oft werden diese Daten aktualisiert?', 'open-data-wizard' ) ) ->add_options( self::get_periodicity_options() ) - ->set_help_text( __( 'AKTUALISIERUNGSFREQUENZ (dct:accrualPeriodicity)', 'open-data-wizard' ) . "\n\n" . __( 'Beispiel: Täglich, Monatlich, Jährlich, Unregelmäßig', 'open-data-wizard' ) ), + ->set_help_text( __( 'AKTUALISIERUNGSFREQUENZ (dct:accrualPeriodicity)', 'open-data-wizard' ) ), Field::make( 'html', 'odw_ext_hint_coverage' ) ->set_html( '

' . esc_html__( 'Abdeckung', 'open-data-wizard' ) . '

' ), Field::make( 'select', 'odw_political_geocoding_level', __( 'Auf welcher Verwaltungsebene wurden diese Daten erhoben?', 'open-data-wizard' ) ) ->add_options( self::get_political_geocoding_level_options() ) - ->set_help_text( __( 'VERWALTUNGSEBENE (dcatde:politicalGeocodingLevelURI)', 'open-data-wizard' ) . "\n\n" . __( 'Beispiel: Gemeinde, Landkreis, Land, Bund', 'open-data-wizard' ) ), + ->set_help_text( __( 'VERWALTUNGSEBENE (dcatde:politicalGeocodingLevelURI)', 'open-data-wizard' ) ), Field::make( 'text', 'odw_political_geocoding_uri', __( 'Auf welches amtliche Gebiet beziehen sich die Daten?', 'open-data-wizard' ) ) ->set_attribute( 'type', 'url' ) ->set_attribute( 'placeholder', 'http://dcat-ap.de/def/politicalGeocoding/regionalKey/09' ) - ->set_help_text( __( 'AMTLICHER GEBIETSSCHLÜSSEL (dcatde:politicalGeocodingURI)', 'open-data-wizard' ) . "\n\n" . __( 'URI des amtlichen Regional-/Gemeindeschlüssels (AGS/ARS). Beispiel: http://dcat-ap.de/def/politicalGeocoding/regionalKey/09', 'open-data-wizard' ) ), + ->set_help_text( __( 'AMTLICHER GEBIETSSCHLÜSSEL (dcatde:politicalGeocodingURI)', 'open-data-wizard' ) ), Field::make( 'text', 'odw_geocoding_description', __( 'Wie lässt sich der räumliche Bezug in Worten beschreiben?', 'open-data-wizard' ) ) ->set_attribute( 'placeholder', __( 'z.B. Stadtgebiet Musterstadt ohne Ortsteil X', 'open-data-wizard' ) ) - ->set_help_text( __( 'RÄUMLICHE BESCHREIBUNG (dcatde:geocodingDescription)', 'open-data-wizard' ) . "\n\n" . __( 'Freitextbeschreibung des räumlichen Bezugs, ergänzend zum amtlichen Gebietsschlüssel. Beispiel: Stadtgebiet Musterstadt', 'open-data-wizard' ) ), + ->set_help_text( __( 'RÄUMLICHE BESCHREIBUNG (dcatde:geocodingDescription)', 'open-data-wizard' ) ), Field::make( 'text', 'odw_spatial', __( 'Welche geografische Region betreffen diese Daten?', 'open-data-wizard' ) ) ->set_attribute( 'placeholder', __( 'Region aus der Liste wählen oder eintippen…', 'open-data-wizard' ) ) ->set_attribute( 'data-odw-autosuggest', 'spatial' ) - ->set_help_text( __( 'GEOGRAPHISCHE ABDECKUNG (dct:spatial)', 'open-data-wizard' ) . "\n\n" . __( 'Region aus der Liste wählen (mit GeoNames verknüpft) oder Freitext/URI eingeben. Beispiel: Deutschland, Bayern, Berlin', 'open-data-wizard' ) ), + ->set_help_text( __( 'GEOGRAPHISCHE ABDECKUNG (dct:spatial)', 'open-data-wizard' ) ), Field::make( 'date', 'odw_temporal_start', __( 'Ab wann reicht der Zeitraum, den die Daten abdecken?', 'open-data-wizard' ) ) ->set_storage_format( 'Y-m-d' ) @@ -418,7 +431,7 @@ static function (): string { 'locale' => 'de', ) ) - ->set_help_text( __( 'ZEITLICHER BEZUG — START (dct:temporal)', 'open-data-wizard' ) . "\n\n" . __( 'Beispiel: 2024-01-01', 'open-data-wizard' ) ), + ->set_help_text( __( 'ZEITLICHER BEZUG — START (dct:temporal)', 'open-data-wizard' ) ), Field::make( 'date', 'odw_temporal_end', __( 'Bis wann reicht der Zeitraum, den die Daten abdecken?', 'open-data-wizard' ) ) ->set_storage_format( 'Y-m-d' ) @@ -428,7 +441,7 @@ static function (): string { 'locale' => 'de', ) ) - ->set_help_text( __( 'ZEITLICHER BEZUG — ENDE (dct:temporal)', 'open-data-wizard' ) . "\n\n" . __( 'Beispiel: 2024-12-31', 'open-data-wizard' ) ), + ->set_help_text( __( 'ZEITLICHER BEZUG — ENDE (dct:temporal)', 'open-data-wizard' ) ), Field::make( 'html', 'odw_ext_hint_contact' ) ->set_html( '

' . esc_html__( 'Kontakt', 'open-data-wizard' ) . '

' ), @@ -438,17 +451,17 @@ static function (): string { // Organisation, und genau das zeigt das Beispiel im Hilfetext. Field::make( 'text', 'odw_contact_name', __( 'An wen kann ich mich bei Fragen zu diesen Daten wenden?', 'open-data-wizard' ) ) ->set_attribute( 'placeholder', __( 'z.B. Open Data Team', 'open-data-wizard' ) ) - ->set_help_text( __( 'Name einer Person, eines Teams oder einer Organisation.', 'open-data-wizard' ) . "\n\n" . __( 'Beispiel: Open Data Team, Statistisches Landesamt', 'open-data-wizard' ) ), + ->set_help_text( __( 'KONTAKTPUNKT · NAME (dcat:contactPoint / vcard:fn)', 'open-data-wizard' ) ), Field::make( 'text', 'odw_contact_email', __( 'Unter welcher E-Mail-Adresse kann ich Fragen stellen?', 'open-data-wizard' ) ) ->set_attribute( 'type', 'email' ) ->set_attribute( 'placeholder', 'opendata@beispiel.de' ) - ->set_help_text( __( 'E-Mail-Adresse für Rückfragen.', 'open-data-wizard' ) . "\n\n" . __( 'Beispiel: opendata@beispiel.de', 'open-data-wizard' ) ), + ->set_help_text( __( 'KONTAKTPUNKT · E-MAIL (dcat:contactPoint / vcard:hasEmail)', 'open-data-wizard' ) ), Field::make( 'text', 'odw_contact_url', __( 'Auf welcher Website finde ich weitere Kontaktinformationen?', 'open-data-wizard' ) ) ->set_attribute( 'type', 'url' ) ->set_attribute( 'placeholder', 'https://beispiel.de/kontakt' ) - ->set_help_text( __( 'Website mit weiteren Kontaktinformationen.', 'open-data-wizard' ) . "\n\n" . __( 'Beispiel: https://beispiel.de/kontakt', 'open-data-wizard' ) ), + ->set_help_text( __( 'KONTAKTPUNKT · WEBSITE (dcat:contactPoint / vcard:hasURL)', 'open-data-wizard' ) ), // "Erweiterte Angaben" — the groups below are individually // collapsible (progressive enhancement via odw-admin-fields.js: @@ -467,14 +480,15 @@ static function (): string { . '' ), - Field::make( 'text', 'odw_contributor_id', __( 'Welche Stelle stellt diese Daten im GovData-Verbund bereit?', 'open-data-wizard' ) ) - ->set_attribute( 'data-odw-vocab', 'contributors' ) - ->set_attribute( 'placeholder', __( 'Stelle eintippen oder auswählen…', 'open-data-wizard' ) ) - ->set_help_text( __( 'CONTRIBUTOR-ID (dcatde:contributorID)', 'open-data-wizard' ) . "\n\n" . __( 'Offizielle Kennung der bereitstellenden Stelle aus dem DCAT-AP.de-Verzeichnis. Stelle aus der Liste wählen; die zugehörige offizielle URI wird automatisch verwendet.', 'open-data-wizard' ) ), + // Auswahlfeld statt Tipp-Feld: 69 Einträge sind für eine Liste + // noch handhabbar, und die Stelle wird genau einmal gewählt. + Field::make( 'select', 'odw_contributor_id', __( 'Welche Stelle stellt diese Daten im GovData-Verbund bereit?', 'open-data-wizard' ) ) + ->add_options( self::vocabulary_options( 'contributors', __( '— Keine Angabe —', 'open-data-wizard' ) ) ) + ->set_help_text( __( 'CONTRIBUTOR-ID (dcatde:contributorID)', 'open-data-wizard' ) ), Field::make( 'text', 'odw_originator_name', __( 'Wer hat diese Daten ursprünglich erstellt?', 'open-data-wizard' ) ) ->set_attribute( 'placeholder', __( 'z.B. Statistisches Landesamt', 'open-data-wizard' ) ) - ->set_help_text( __( 'URHEBER (dcatde:originator)', 'open-data-wizard' ) . "\n\n" . __( 'Stelle, von der die Daten ursprünglich stammen (kann von Herausgeber abweichen).', 'open-data-wizard' ) ), + ->set_help_text( __( 'URHEBER (dcatde:originator)', 'open-data-wizard' ) ), Field::make( 'text', 'odw_originator_email', __( 'E-Mail des Urhebers', 'open-data-wizard' ) ) ->set_attribute( 'type', 'email' ) @@ -483,7 +497,7 @@ static function (): string { Field::make( 'text', 'odw_maintainer_name', __( 'Wer pflegt diese Daten laufend?', 'open-data-wizard' ) ) ->set_attribute( 'placeholder', __( 'z.B. Open Data Team', 'open-data-wizard' ) ) - ->set_help_text( __( 'PFLEGENDE STELLE (dcatde:maintainer)', 'open-data-wizard' ) . "\n\n" . __( 'Stelle, die für die laufende Pflege/Aktualisierung der Daten zuständig ist.', 'open-data-wizard' ) ), + ->set_help_text( __( 'PFLEGENDE STELLE (dcatde:maintainer)', 'open-data-wizard' ) ), Field::make( 'text', 'odw_maintainer_email', __( 'E-Mail der pflegenden Stelle', 'open-data-wizard' ) ) ->set_attribute( 'type', 'email' ) @@ -493,12 +507,12 @@ static function (): string { Field::make( 'textarea', 'odw_legal_basis', __( 'Auf welcher rechtlichen Grundlage werden die Daten bereitgestellt?', 'open-data-wizard' ) ) ->set_rows( 2 ) ->set_attribute( 'placeholder', __( 'z.B. § 12a EGovG, Informationsweiterverwendungsgesetz (IWG)', 'open-data-wizard' ) ) - ->set_help_text( __( 'RECHTSGRUNDLAGE (dcatde:legalBasis)', 'open-data-wizard' ) . "\n\n" . __( 'Gesetz/Verordnung, das die Bereitstellung regelt. Beispiel: § 12a EGovG', 'open-data-wizard' ) ), + ->set_help_text( __( 'RECHTSGRUNDLAGE (dcatde:legalBasis)', 'open-data-wizard' ) ), Field::make( 'text', 'odw_quality_process_uri', __( 'Wo ist das Qualitätssicherungs-Verfahren dokumentiert?', 'open-data-wizard' ) ) ->set_attribute( 'type', 'url' ) ->set_attribute( 'placeholder', 'https://beispiel.de/qualitaetssicherung' ) - ->set_help_text( __( 'QUALITÄTSPROZESS (dcatde:qualityProcessURI)', 'open-data-wizard' ) . "\n\n" . __( 'URL zur Beschreibung des Qualitätssicherungs-Prozesses (optional).', 'open-data-wizard' ) ), + ->set_help_text( __( 'QUALITÄTSPROZESS (dcatde:qualityProcessURI)', 'open-data-wizard' ) ), Field::make( 'html', 'odw_ext_hint_access' ) ->set_html( @@ -516,12 +530,7 @@ static function (): string { Field::make( 'select', 'odw_access_rights', __( 'Wer darf auf diese Daten zugreifen?', 'open-data-wizard' ) ) ->add_options( self::get_access_rights_options() ) ->set_default_value( 'http://publications.europa.eu/resource/authority/access-right/PUBLIC' ) - ->set_help_text( __( 'ZUGRIFFSRECHTE (dct:accessRights)', 'open-data-wizard' ) . "\n\n" . __( 'Zugriffs-Klassifikation des Datensatzes. Vorbelegt mit „Öffentlich“ — bitte ändern, wenn die Daten nur eingeschränkt oder gar nicht öffentlich zugänglich sind.', 'open-data-wizard' ) ), - - Field::make( 'text', 'odw_theme_uri', __( 'Weiteres EU-Thema (Themen-URI)?', 'open-data-wizard' ) ) - ->set_attribute( 'data-odw-vocab', 'data-theme' ) - ->set_attribute( 'placeholder', __( 'EU-Datenthema eintippen oder auswählen…', 'open-data-wizard' ) ) - ->set_help_text( __( 'ZUSÄTZLICHES THEMA (dcat:theme)', 'open-data-wizard' ) . "\n\n" . __( 'Optional ein weiteres Thema aus der offiziellen EU-Themenliste (ergänzt das Thema aus Tab 1).', 'open-data-wizard' ) ), + ->set_help_text( __( 'ZUGRIFFSRECHTE (dct:accessRights)', 'open-data-wizard' ) ), Field::make( 'html', 'odw_ext_hint_hvd' ) ->set_html( @@ -538,11 +547,11 @@ static function (): string { // für wen sie gedacht sind. Field::make( 'select', 'odw_is_hvd', __( 'Nur für öffentliche Stellen: Ist dies ein hochwertiger Datensatz (HVD)?', 'open-data-wizard' ) ) ->add_options( self::get_hvd_flag_options() ) - ->set_help_text( __( 'HIGH-VALUE-DATENSATZ (EU-Durchführungsverordnung 2023/138)', 'open-data-wizard' ) . "\n\n" . __( 'Betrifft ausschließlich öffentliche Stellen — Vereine, Verbände und andere zivilgesellschaftliche Organisationen können dieses Feld leer lassen. Hochwertige Datensätze (HVD) sind von der EU festgelegte Datensätze mit besonderem Nutzen für Wirtschaft und Gesellschaft. Falls zutreffend, wählen Sie unten die passende Kategorie.', 'open-data-wizard' ) ), + ->set_help_text( __( 'HOCHWERTIGER DATENSATZ (dcatap:applicableLegislation)', 'open-data-wizard' ) ), Field::make( 'select', 'odw_hvd_category', __( 'Welcher HVD-Kategorie gehört dieser Datensatz an?', 'open-data-wizard' ) ) ->add_options( self::get_hvd_category_options() ) - ->set_help_text( __( 'HVD-KATEGORIE (dcatap:hvdCategory)', 'open-data-wizard' ) . "\n\n" . __( 'Eine der sechs EU-Themenkategorien. Beispiel: Georaum, Meteorologie, Mobilität', 'open-data-wizard' ) ) + ->set_help_text( __( 'HVD-KATEGORIE (dcatap:hvdCategory)', 'open-data-wizard' ) ) ->set_conditional_logic( array( array( @@ -563,16 +572,16 @@ static function (): string { Field::make( 'text', 'odw_identifier', __( 'Welche eindeutige Kennung hat dieser Datensatz?', 'open-data-wizard' ) ) ->set_attribute( 'placeholder', __( 'z. B. DOI oder interne ID', 'open-data-wizard' ) ) - ->set_help_text( __( 'IDENTIFIER (dct:identifier)', 'open-data-wizard' ) . "\n\n" . __( 'Eine eindeutige Kennung des Datensatzes (z. B. DOI oder interne ID). Beispiel: 10.1234/abcd', 'open-data-wizard' ) ), + ->set_help_text( __( 'IDENTIFIER (dct:identifier)', 'open-data-wizard' ) ), Field::make( 'text', 'odw_type', __( 'Um welchen Typ von Datensatz handelt es sich?', 'open-data-wizard' ) ) ->set_attribute( 'type', 'url' ) ->set_attribute( 'placeholder', 'http://publications.europa.eu/resource/authority/dataset-type/...' ) - ->set_help_text( __( 'DATENSATZ-TYP (dct:type)', 'open-data-wizard' ) . "\n\n" . __( 'URI aus der EU-Liste „dataset-type". Beispiel: http://publications.europa.eu/resource/authority/dataset-type/STATISTICAL', 'open-data-wizard' ) ), + ->set_help_text( __( 'DATENSATZ-TYP (dct:type)', 'open-data-wizard' ) ), Field::make( 'text', 'odw_creator_name', __( 'Wer hat diese Daten erstellt?', 'open-data-wizard' ) ) ->set_attribute( 'placeholder', __( 'z. B. Statistisches Amt', 'open-data-wizard' ) ) - ->set_help_text( __( 'ERSTELLER (dct:creator)', 'open-data-wizard' ) . "\n\n" . __( 'Stelle oder Person, die die Daten erstellt hat (kann vom Herausgeber abweichen).', 'open-data-wizard' ) ), + ->set_help_text( __( 'ERSTELLER (dct:creator)', 'open-data-wizard' ) ), Field::make( 'text', 'odw_creator_email', __( 'E-Mail-Adresse des Erstellers (optional).', 'open-data-wizard' ) ) ->set_attribute( 'type', 'email' ) @@ -580,28 +589,28 @@ static function (): string { Field::make( 'text', 'odw_version', __( 'Welche Version hat dieser Datensatz?', 'open-data-wizard' ) ) ->set_attribute( 'placeholder', __( 'z. B. 1.0', 'open-data-wizard' ) ) - ->set_help_text( __( 'VERSION (owl:versionInfo)', 'open-data-wizard' ) . "\n\n" . __( 'Versionsbezeichnung des Datensatzes. Beispiel: 1.0, 2024-Q1', 'open-data-wizard' ) ), + ->set_help_text( __( 'VERSION (owl:versionInfo)', 'open-data-wizard' ) ), Field::make( 'textarea', 'odw_version_notes', __( 'Was hat sich in dieser Version geändert?', 'open-data-wizard' ) ) ->set_rows( 2 ) - ->set_help_text( __( 'VERSIONSHINWEISE (adms:versionNotes)', 'open-data-wizard' ) . "\n\n" . __( 'Kurze Beschreibung der Änderungen gegenüber der Vorversion.', 'open-data-wizard' ) ), + ->set_help_text( __( 'VERSIONSHINWEISE (adms:versionNotes)', 'open-data-wizard' ) ), Field::make( 'text', 'odw_spatial_resolution', __( 'Welche räumliche Auflösung haben die Daten (in Metern)?', 'open-data-wizard' ) ) ->set_attribute( 'placeholder', __( 'z. B. 30', 'open-data-wizard' ) ) - ->set_help_text( __( 'RÄUMLICHE AUFLÖSUNG IN METERN (dcat:spatialResolutionInMeters)', 'open-data-wizard' ) . "\n\n" . __( 'Kleinste räumlich auflösbare Distanz in Metern (nur Zahl). Beispiel: 30', 'open-data-wizard' ) ), + ->set_help_text( __( 'RÄUMLICHE AUFLÖSUNG IN METERN (dcat:spatialResolutionInMeters)', 'open-data-wizard' ) ), Field::make( 'text', 'odw_temporal_resolution', __( 'Welche zeitliche Auflösung haben die Daten?', 'open-data-wizard' ) ) ->set_attribute( 'placeholder', 'P1D' ) - ->set_help_text( __( 'ZEITLICHE AUFLÖSUNG (dcat:temporalResolution)', 'open-data-wizard' ) . "\n\n" . __( 'Als ISO-8601-Dauer. Beispiel: P1D (täglich), PT1H (stündlich)', 'open-data-wizard' ) ), + ->set_help_text( __( 'ZEITLICHE AUFLÖSUNG (dcat:temporalResolution)', 'open-data-wizard' ) ), Field::make( 'text', 'odw_conforms_to', __( 'Welchem Standard oder Schema entsprechen die Daten?', 'open-data-wizard' ) ) ->set_attribute( 'type', 'url' ) ->set_attribute( 'placeholder', 'https://…' ) - ->set_help_text( __( 'KONFORM ZU (dct:conformsTo)', 'open-data-wizard' ) . "\n\n" . __( 'URI des Standards/Anwendungsprofils, dem die Daten folgen.', 'open-data-wizard' ) ), + ->set_help_text( __( 'KONFORM ZU (dct:conformsTo)', 'open-data-wizard' ) ), Field::make( 'textarea', 'odw_provenance', __( 'Woher stammen die Daten und wie sind sie entstanden?', 'open-data-wizard' ) ) ->set_rows( 2 ) - ->set_help_text( __( 'HERKUNFT (dct:provenance)', 'open-data-wizard' ) . "\n\n" . __( 'Freitext zur Entstehung und Herkunft der Daten.', 'open-data-wizard' ) ), + ->set_help_text( __( 'HERKUNFT (dct:provenance)', 'open-data-wizard' ) ), // Die Überschrift benennt ausdrücklich die primäre Distribution: // Die Felder dieser Sektion sind Singular-Felder und gelten nicht @@ -615,7 +624,7 @@ static function (): string { ), Field::make( 'text', 'odw_dist_title', __( 'Wie heißt die bereitgestellte Datei/Distribution?', 'open-data-wizard' ) ) - ->set_help_text( __( 'TITEL DER DISTRIBUTION (dct:title)', 'open-data-wizard' ) . "\n\n" . __( 'Kurzer Titel der Distribution. Beispiel: Gesamtdaten als CSV', 'open-data-wizard' ) ), + ->set_help_text( __( 'TITEL DER DISTRIBUTION (dct:title)', 'open-data-wizard' ) ), Field::make( 'textarea', 'odw_dist_description', __( 'Wie lässt sich die Distribution beschreiben?', 'open-data-wizard' ) ) ->set_rows( 2 ) @@ -624,14 +633,14 @@ static function (): string { Field::make( 'text', 'odw_download_url', __( 'Direkter Download-Link zur Datei?', 'open-data-wizard' ) ) ->set_attribute( 'type', 'url' ) ->set_attribute( 'placeholder', 'https://beispiel.de/daten/datei.csv' ) - ->set_help_text( __( 'DOWNLOAD-URL (dcat:downloadURL)', 'open-data-wizard' ) . "\n\n" . __( 'Direkte URL zum Herunterladen der Datei (im Gegensatz zur Zugriffs-URL).', 'open-data-wizard' ) ), + ->set_help_text( __( 'DOWNLOAD-URL (dcat:downloadURL)', 'open-data-wizard' ) ), Field::make( 'text', 'odw_media_type', __( 'Welchen Medientyp (MIME) hat die Datei?', 'open-data-wizard' ) ) ->set_attribute( 'placeholder', 'https://www.iana.org/assignments/media-types/text/csv' ) - ->set_help_text( __( 'MEDIENTYP (dcat:mediaType)', 'open-data-wizard' ) . "\n\n" . __( 'IANA-Media-Type als URI. Beispiel: https://www.iana.org/assignments/media-types/text/csv', 'open-data-wizard' ) ), + ->set_help_text( __( 'MEDIENTYP (dcat:mediaType)', 'open-data-wizard' ) ), Field::make( 'text', 'odw_dist_rights', __( 'Welche Nutzungsrechte gelten für die Datei?', 'open-data-wizard' ) ) - ->set_help_text( __( 'RECHTE (dct:rights)', 'open-data-wizard' ) . "\n\n" . __( 'URI oder Freitext zu den Nutzungsrechten der Distribution.', 'open-data-wizard' ) ), + ->set_help_text( __( 'RECHTE (dct:rights)', 'open-data-wizard' ) ), ) ) @@ -1036,6 +1045,12 @@ public static function resolve_label( string $vocab, string $value ): string { case 'cessda': $map = self::load_cessda_options(); break; + case 'engagementfeld': + case 'contributors': + // Gebündelte Vokabulare: seit v2.41.0 Auswahlfelder, deren + // gespeicherte URI im Frontend als Label erscheinen soll. + $map = self::vocabulary_options( $vocab ); + break; default: $map = array(); } @@ -1043,6 +1058,185 @@ public static function resolve_label( string $vocab, string $value ): string { return isset( $map[ $value ] ) && '' !== (string) $map[ $value ] ? (string) $map[ $value ] : $value; } + /** + * Ein gebündeltes Vokabular als URI → Label Map für Auswahlfelder. + * + * @param string $id Vokabular-ID (Dateiname ohne .json). + * @param string $placeholder Optionaler Platzhalter-Eintrag mit leerem Wert. + * @return array + */ + public static function vocabulary_options( string $id, string $placeholder = '' ): array { + $options = array(); + if ( '' !== $placeholder ) { + $options[''] = $placeholder; + } + foreach ( self::load_vocabulary( $id ) as $entry ) { + $options[ $entry['value'] ] = $entry['label']; + } + return $options; + } + + /** + * Bringt einen gespeicherten Vokabularwert auf eine Liste von URIs. + * + * Wie normalize_themes(), aber für die gebündelten Vokabulare: Array + * (Mehrfachauswahl), einzelner String oder ein Label, das vor der Umstellung + * im Textfeld stand und erst aufgelöst werden muss. + * + * @param mixed $value Gespeicherter Wert. + * @param string $vocab Vokabular-ID. + * @return array + */ + public static function normalize_vocabulary( $value, string $vocab ): array { + $werte = is_array( $value ) ? $value : array( $value ); + $out = array(); + + foreach ( $werte as $einzeln ) { + $einzeln = trim( (string) $einzeln ); + if ( '' === $einzeln ) { + continue; + } + $uri = odw_resolve_vocab_uri( $einzeln, $vocab ); + if ( '' !== $uri && ! in_array( $uri, $out, true ) ) { + $out[] = $uri; + } + } + + return $out; + } + + /** + * Flache Spiegelung der gewählten Themen für Abfragen. + * + * Carbon Fields legt Mehrfachwerte unter `_odw_theme|||N|value` ab. Eine + * meta_query auf `_odw_theme` findet sie deshalb nicht — und genau darauf + * beruhten der Themenfilter des Katalogs und die Sortierung der Listenspalte. + * Diese Methode schreibt die Auswahl zusätzlich flach: + * `_odw_theme_index` — eine Zeile je Thema, für den Filter, + * `_odw_theme_sort` — Label des ersten Themas, für die Sortierung. + * + * @param int $post_id Dataset post ID. + */ + public static function sync_theme_index( int $post_id ): void { + if ( 'odw_dataset' !== get_post_type( $post_id ) ) { + return; + } + if ( defined( 'DOING_AUTOSAVE' ) && DOING_AUTOSAVE ) { + return; + } + + $themes = self::normalize_themes( carbon_get_post_meta( $post_id, 'odw_theme' ) ); + + delete_post_meta( $post_id, '_odw_theme_index' ); + foreach ( $themes as $uri ) { + add_post_meta( $post_id, '_odw_theme_index', $uri ); + } + + $sort = ''; + if ( isset( $themes[0] ) ) { + $sort = self::resolve_label( 'theme', $themes[0] ); + } + update_post_meta( $post_id, '_odw_theme_sort', $sort ); + } + + /** + * Labels aller gewählten Themen, in Auswahlreihenfolge. + * + * @param int $post_id Dataset post ID. + * @return array + */ + public static function theme_labels( int $post_id ): array { + $out = array(); + foreach ( self::normalize_themes( carbon_get_post_meta( $post_id, 'odw_theme' ) ) as $uri ) { + $label = self::resolve_label( 'theme', $uri ); + $out[] = '' !== $label ? $label : $uri; + } + return $out; + } + + /** + * Labels aller gewählten Konzepte eines gebündelten Vokabulars. + * + * Gegenstück zu theme_labels() für die übrigen Mehrfachauswahlen; kann eine + * URI nicht aufgelöst werden, steht sie selbst da statt einer Lücke. + * + * @param int $post_id Dataset post ID. + * @param string $field Carbon-Feld-Schlüssel, z. B. "odw_engagementfeld". + * @param string $vocab Vokabular-ID. + * @return array + */ + public static function vocabulary_labels( int $post_id, string $field, string $vocab ): array { + $out = array(); + foreach ( self::normalize_vocabulary( carbon_get_post_meta( $post_id, $field ), $vocab ) as $uri ) { + $label = self::resolve_label( $vocab, $uri ); + $out[] = '' !== $label ? $label : $uri; + } + return $out; + } + + /** + * Bringt den gespeicherten Themenwert auf eine Liste von EU-URIs. + * + * Drei Formen können auftreten: + * - Array von URIs — die Mehrfachauswahl seit v2.41.0. + * - Einzelner String — Datensätze vor der Migration und Tests mit altem Mock. + * - Deutsches Kurzlabel („Bildung", „Soziales") — die Auswahlliste vor + * v2.5.0 speicherte Labels statt URIs; der Demo-Datensatz tut es bis heute. + * + * @param mixed $value Gespeicherter Wert. + * @return array Liste eindeutiger URIs, leere Werte entfallen. + */ + public static function normalize_themes( $value ): array { + $base = 'http://publications.europa.eu/resource/authority/data-theme/'; + $legacy = array( + 'Bildung' => $base . 'EDUC', + 'Gesundheit' => $base . 'HEAL', + 'Soziales' => $base . 'SOCI', + 'Umwelt' => $base . 'ENVI', + 'Wirtschaft' => $base . 'ECON', + 'Kultur' => $base . 'EDUC', + 'Sport' => $base . 'EDUC', + 'Sonstiges' => $base . 'GOVE', + ); + + $werte = is_array( $value ) ? $value : array( $value ); + $out = array(); + + foreach ( $werte as $einzeln ) { + $einzeln = trim( (string) $einzeln ); + if ( '' === $einzeln ) { + continue; + } + if ( isset( $legacy[ $einzeln ] ) ) { + $einzeln = $legacy[ $einzeln ]; + } else { + // Labels aus dem Vokabular ebenfalls auflösen; eine bereits + // eingetragene URI reicht resolve_theme_uri() unverändert durch. + $einzeln = self::resolve_theme_uri( $einzeln ); + } + if ( '' !== $einzeln && ! in_array( $einzeln, $out, true ) ) { + $out[] = $einzeln; + } + } + + return $out; + } + + /** + * Themen-Vokabular ohne den Platzhalter-Eintrag. + * + * Die Mehrfachauswahl braucht kein „— Bitte wählen —": Nichts auszuwählen + * ist dort bereits der leere Zustand, und ein Eintrag mit leerem Wert würde + * als auswählbares Thema erscheinen. + * + * @return array + */ + public static function get_theme_options_multi(): array { + $options = self::get_theme_options(); + unset( $options[''] ); + return $options; + } + /** * Themen-Vokabular als EU-Vocabulary-URI → Label Map. * @@ -1766,7 +1960,6 @@ function odw_build_dataset_jsonld( int $post_id ): ?array { $language = carbon_get_post_meta( $post_id, 'odw_language' ); $keywords = carbon_get_post_meta( $post_id, 'odw_keywords' ); $theme = carbon_get_post_meta( $post_id, 'odw_theme' ); - $theme_uri = (string) carbon_get_post_meta( $post_id, 'odw_theme_uri' ); $issued = carbon_get_post_meta( $post_id, 'odw_issued' ); $modified = get_post_meta( $post_id, '_odw_modified', true ); $dist_access_url = (string) carbon_get_post_meta( $post_id, 'odw_access_url' ); @@ -1777,7 +1970,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' ); + $engagementfeld = 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' ); @@ -1882,27 +2075,12 @@ function odw_build_dataset_jsonld( int $post_id ): ?array { $dataset['dcat:keyword'] = $keyword_literals; } + // Seit v2.41.0 ist odw_theme eine Mehrfachauswahl und liefert ein Array. + // Ein einzelner String kann trotzdem auftreten: bei Datensätzen, die vor der + // Migration angelegt wurden, und in Tests, die den alten Wert mocken. $themes = array(); - if ( ! empty( $theme ) ) { - $theme_base = 'http://publications.europa.eu/resource/authority/data-theme/'; - $theme_legacy = array( - 'Bildung' => $theme_base . 'EDUC', - 'Gesundheit' => $theme_base . 'HEAL', - 'Soziales' => $theme_base . 'SOCI', - 'Umwelt' => $theme_base . 'ENVI', - 'Wirtschaft' => $theme_base . 'ECON', - 'Kultur' => $theme_base . 'EDUC', - 'Sport' => $theme_base . 'EDUC', - 'Sonstiges' => $theme_base . 'GOVE', - ); - $themes[] = array( '@id' => odw_sanitize_jsonld_id( $theme_legacy[ (string) $theme ] ?? (string) $theme ) ); - } - // Optional additional EU data-theme (advanced field, bundled vocabulary). - // The field stores the human-readable label; resolve it to the official URI - // (a directly entered URI passes through unchanged). - $theme_uri_resolved = odw_resolve_vocab_uri( $theme_uri, 'data-theme' ); - if ( '' !== $theme_uri_resolved ) { - $themes[] = array( '@id' => odw_sanitize_jsonld_id( $theme_uri_resolved ) ); + foreach ( ODW_Fields::normalize_themes( $theme ) as $theme_uri_value ) { + $themes[] = array( '@id' => odw_sanitize_jsonld_id( $theme_uri_value ) ); } if ( 1 === count( $themes ) ) { $dataset['dcat:theme'] = $themes[0]; @@ -1917,11 +2095,11 @@ function odw_build_dataset_jsonld( int $post_id ): ?array { if ( ! empty( $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 ) ); - } + // Seit v2.41.0 ist das Engagementfeld eine Mehrfachauswahl. normalize_vocabulary() + // nimmt daneben weiterhin den einzelnen String entgegen, den Datensätze vor der + // Migration tragen, und löst ein Label zur URI auf. + foreach ( ODW_Fields::normalize_vocabulary( $engagementfeld, 'engagementfeld' ) as $engagement_uri ) { + $subjects[] = array( '@id' => odw_sanitize_jsonld_id( $engagement_uri ) ); } if ( ! empty( $subjects ) ) { $dataset['dct:subject'] = 1 === count( $subjects ) ? $subjects[0] : $subjects; diff --git a/includes/class-quality.php b/includes/class-quality.php index 021e9b65..01f04a1a 100644 --- a/includes/class-quality.php +++ b/includes/class-quality.php @@ -245,7 +245,7 @@ private static function check_metric( string $check, \WP_Post $post ): bool { return ! empty( $keywords ); case 'theme': - return '' !== trim( (string) carbon_get_post_meta( $id, 'odw_theme' ) ); + return array() !== ODW_Fields::normalize_themes( carbon_get_post_meta( $id, 'odw_theme' ) ); case 'spatial': return '' !== trim( (string) carbon_get_post_meta( $id, 'odw_spatial' ) ); diff --git a/includes/class-rest-api.php b/includes/class-rest-api.php index b136d723..b39cb191 100644 --- a/includes/class-rest-api.php +++ b/includes/class-rest-api.php @@ -210,9 +210,20 @@ public static function get_catalog( WP_REST_Request $request ): WP_REST_Response $meta_query = array(); if ( ! empty( $theme ) ) { + // Dieselbe Auflösung wie beim Schreiben des Index (normalize_themes), + // nicht bloß resolve_theme_uri: Sonst findet `?theme=Bildung` nichts, + // weil das EU-Vokabular diesen Namen gar nicht kennt — es heißt dort + // „Bildung, Kultur und Sport". Harvester, die den alten deutschen + // Kurznamen verwenden, sollen weiter Treffer bekommen. + $theme_uri = $theme; + if ( class_exists( 'ODW_Fields' ) ) { + $aufgeloest = ODW_Fields::normalize_themes( $theme ); + $theme_uri = $aufgeloest[0] ?? $theme; + } + $meta_query[] = array( - 'key' => '_odw_theme', - 'value' => class_exists( 'ODW_Fields' ) ? ODW_Fields::resolve_theme_uri( $theme ) : $theme, + 'key' => '_odw_theme_index', + 'value' => $theme_uri, ); } diff --git a/includes/class-setup.php b/includes/class-setup.php index 3a670e5f..0a3ccab3 100644 --- a/includes/class-setup.php +++ b/includes/class-setup.php @@ -25,6 +25,7 @@ class ODW_Setup { private const DEMO_OPTION = 'odw_demo_post_id'; private const WELCOME_OPTION = 'odw_show_welcome'; private const REDIRECT_OPTION = 'odw_activation_redirect'; + private const MULTI_MIGRATED = 'odw_multi_value_migrated'; /** * Custom capability, die Batch-Import & Co. schützt. @@ -49,10 +50,76 @@ public static function init(): void { add_action( 'admin_init', array( self::class, 'maybe_grant_capability' ) ); add_action( 'admin_init', array( self::class, 'maybe_redirect_to_intro' ) ); add_action( 'admin_init', array( self::class, 'maybe_create_demo' ) ); + add_action( 'admin_init', array( self::class, 'maybe_migrate_multi_values' ) ); add_action( 'admin_init', array( self::class, 'handle_dismiss' ) ); add_action( 'admin_notices', array( self::class, 'render_welcome_notice' ) ); } + /** + * Überführt Einzelwerte in die Mehrfachauswahlen (einmalig, ab v2.41.0). + * + * Betroffen sind `odw_theme` und `odw_engagementfeld`. Bis v2.40.x waren + * beide Auswahl- bzw. Textfelder und lagen flach unter `_odw_theme` bzw. + * `_odw_engagementfeld`; ein zweites Thema konnte unter `_odw_theme_uri` + * stehen. Carbon Fields legt Mehrfachwerte unter eigenen Meta-Keys ab, die + * alten Zeilen wären also unsichtbar geworden — deshalb diese Umschreibung. + * + * Geschrieben wird über carbon_set_post_meta(), nicht über selbstgebaute + * Meta-Keys: Das Schlüsselformat ist ein Interna von Carbon Fields und + * darf sich ändern. + */ + public static function maybe_migrate_multi_values(): void { + if ( get_option( self::MULTI_MIGRATED ) ) { + return; + } + if ( ! function_exists( 'carbon_set_post_meta' ) || ! class_exists( 'ODW_Fields' ) ) { + return; + } + + $posts = get_posts( + array( + 'post_type' => 'odw_dataset', + 'post_status' => 'any', + 'numberposts' => -1, + 'fields' => 'ids', + 'suppress_filters' => true, + ) + ); + + foreach ( $posts as $post_id ) { + $post_id = (int) $post_id; + $alt = get_post_meta( $post_id, '_odw_theme', true ); + $alt_uri = get_post_meta( $post_id, '_odw_theme_uri', true ); + + $themes = ODW_Fields::normalize_themes( array( $alt, $alt_uri ) ); + + if ( array() !== $themes ) { + carbon_set_post_meta( $post_id, 'odw_theme', $themes ); + ODW_Fields::sync_theme_index( $post_id ); + } + + // Die alten flachen Zeilen entfernen: Sie würden sonst neben den + // neuen stehen bleiben und bei einer erneuten Migration wieder + // eingelesen — mit dann womöglich überholten Werten. + delete_post_meta( $post_id, '_odw_theme' ); + delete_post_meta( $post_id, '_odw_theme_uri' ); + + // Engagementfeld: bis v2.40.x ein Textfeld mit Autosuggest, das + // entweder die URI oder — bei von Hand eingetragenen Werten — das + // Label enthielt. normalize_vocabulary() löst beides auf. + $alt_engagement = get_post_meta( $post_id, '_odw_engagementfeld', true ); + $engagement = ODW_Fields::normalize_vocabulary( $alt_engagement, 'engagementfeld' ); + + if ( array() !== $engagement ) { + carbon_set_post_meta( $post_id, 'odw_engagementfeld', $engagement ); + } + + delete_post_meta( $post_id, '_odw_engagementfeld' ); + } + + update_option( self::MULTI_MIGRATED, '1', false ); + } + /** * Vergibt manage_open_data an Administratoren und Redakteure. */ @@ -152,7 +219,10 @@ private static function create_demo_dataset(): int { update_post_meta( $post_id, '_odw_license', 'https://creativecommons.org/publicdomain/zero/1.0/' ); update_post_meta( $post_id, '_odw_language', 'de' ); update_post_meta( $post_id, '_odw_keywords', "Zivilgesellschaft\nEngagement\nOrganisationen\nDemo" ); - update_post_meta( $post_id, '_odw_theme', 'Soziales' ); + if ( function_exists( 'carbon_set_post_meta' ) && class_exists( 'ODW_Fields' ) ) { + carbon_set_post_meta( $post_id, 'odw_theme', ODW_Fields::normalize_themes( 'Soziales' ) ); + ODW_Fields::sync_theme_index( $post_id ); + } update_post_meta( $post_id, '_odw_issued', current_time( 'Y-m-d' ) ); update_post_meta( $post_id, '_odw_modified', current_time( 'Y-m-d' ) ); diff --git a/includes/class-shortcode.php b/includes/class-shortcode.php index 52825c9c..b369f272 100644 --- a/includes/class-shortcode.php +++ b/includes/class-shortcode.php @@ -284,9 +284,17 @@ private static function collect_metadata_rows( int $post_id, string $license_lab $add( __( 'Herausgeber', 'open-data-wizard' ), self::meta( $post_id, 'odw_publisher' ) ); $add( __( 'Beschreibung', 'open-data-wizard' ), self::meta( $post_id, 'odw_description' ) ); - $add( __( 'Thema', 'open-data-wizard' ), self::label( 'theme', 'odw_theme', $post_id ) ); + // Themen sind seit v2.41.0 eine Mehrfachauswahl — alle gewählten anzeigen. + $add( + __( 'Thema', 'open-data-wizard' ), + class_exists( 'ODW_Fields' ) ? implode( ', ', ODW_Fields::theme_labels( $post_id ) ) : '' + ); $add( __( 'CESSDA-Themenfeld', 'open-data-wizard' ), self::label( 'cessda', 'odw_cessda_topic', $post_id ) ); - $add( __( 'Engagementfeld', 'open-data-wizard' ), self::meta( $post_id, 'odw_engagementfeld' ) ); + // Engagementfelder sind seit v2.41.0 eine Mehrfachauswahl — alle anzeigen. + $add( + __( 'Engagementfeld', 'open-data-wizard' ), + class_exists( 'ODW_Fields' ) ? implode( ', ', ODW_Fields::vocabulary_labels( $post_id, 'odw_engagementfeld', 'engagementfeld' ) ) : '' + ); $add( __( 'Sprache', 'open-data-wizard' ), self::label( 'language', 'odw_language', $post_id ) ); $keywords = array_filter( array_map( 'trim', explode( "\n", self::meta( $post_id, 'odw_keywords' ) ) ) ); diff --git a/includes/class-validation.php b/includes/class-validation.php index e7727dd8..492edb35 100644 --- a/includes/class-validation.php +++ b/includes/class-validation.php @@ -484,7 +484,7 @@ public static function show_validation_notice(): void { } echo ''; - echo '

' . esc_html__( 'Der Datensatz wurde als Entwurf gespeichert. Bitte alle Pflichtangaben befüllen und erneut veröffentlichen. Als Entwurf können Sie jederzeit unvollständig speichern.', 'open-data-wizard' ) . '

'; + echo '

' . esc_html__( 'Der Datensatz wurde als Entwurf gespeichert. Bitte alle Pflichtangaben befüllen und erneut veröffentlichen. Als Entwurf können Sie den Datensatz jederzeit speichern.', 'open-data-wizard' ) . '

'; echo ''; } } diff --git a/languages/open-data-wizard-en_US.mo b/languages/open-data-wizard-en_US.mo index ab7ea123..8a33c668 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 00cdd115..60d437bf 100644 --- a/languages/open-data-wizard-en_US.po +++ b/languages/open-data-wizard-en_US.po @@ -33,6 +33,9 @@ msgstr "(optional)" msgid "(von max. %d)" msgstr "(of max. %d)" +msgid "* Pflichtfeld für die Veröffentlichung. Als Entwurf können Sie den Datensatz jederzeit speichern." +msgstr "* Required for publishing. You can save the dataset as a draft at any time." + msgid "1 — Grundlegende Informationen" msgstr "1 — Basic Information" @@ -156,33 +159,15 @@ msgstr "Example: 2024-01-15" msgid "Beispiel: 2024-12-31" msgstr "Example: 2024-12-31" -msgid "Beispiel: CC0 1.0, CC-BY 4.0 – Diese bestimmt, wie andere die Daten nutzen dürfen." -msgstr "Example: CC0 1.0, CC-BY 4.0 – this determines how others may use the data." - -msgid "Beispiel: CSV, JSON, PDF" -msgstr "Example: CSV, JSON, PDF" - -msgid "Beispiel: Deutsch, Englisch" -msgstr "Example: German, English" - msgid "Beispiel: Ein Überblick über die bevölkerungsreichsten Städte in Deutschland mit statistischen Daten zu Einwohnerzahl und Entwicklung." msgstr "Example: An overview of the most populous cities in Germany with statistical data on population and development." -msgid "Beispiel: Gemeinde, Landkreis, Land, Bund" -msgstr "Example: municipality, district, state, federal" - msgid "Beispiel: Musterstadt Statistikamt, Umweltbundesamt, Verbraucherzentrale e.V." msgstr "Example: Sampletown Statistics Office, Federal Environment Agency, Consumer Advice Center" msgid "Beispiel: Open Data Team, Statistisches Landesamt" msgstr "Example: Open Data Team, State Statistical Office" -msgid "Beispiel: Täglich, Monatlich, Jährlich, Unregelmäßig" -msgstr "Example: daily, monthly, yearly, irregular" - -msgid "Beispiel: Umwelt, Bildung, Gesundheit, Wirtschaft, Kultur" -msgstr "Example: environment, education, health, economy, culture" - msgid "Beispiel: Zivilgesellschaftliche Organisationen" msgstr "Example: Civil society organizations" @@ -414,6 +399,9 @@ msgstr "Uninstallation" msgid "Demo-Datensatz bearbeiten" msgstr "Edit demo dataset" +msgid "Der Datensatz wurde als Entwurf gespeichert. Bitte alle Pflichtangaben befüllen und erneut veröffentlichen. Als Entwurf können Sie den Datensatz jederzeit speichern." +msgstr "The dataset was saved as a draft. Please fill in all required fields and publish again. You can save the dataset as a draft at any time." + msgid "Der Datensatz wurde als Entwurf gespeichert. Bitte alle Pflichtfelder befüllen und erneut veröffentlichen." msgstr "The dataset was saved as a draft. Please fill in all required fields and publish again." @@ -435,6 +423,9 @@ msgstr "The Idea" msgid "Die JSON-LD-Ansicht unten zeigt das zuletzt gespeicherte Ergebnis." msgstr "The JSON-LD view below shows the last saved result." +msgid "Die Pflichtfelder sind mit einem roten Sternchen (*) gekennzeichnet. Als Entwurf können Sie den Datensatz jederzeit speichern – erst zum Veröffentlichen müssen alle Pflichtfelder ausgefüllt sein. Zu jedem Feld gibt es Erläuterungen: Das ⓘ-Symbol zeigt den DCAT-AP-Begriff, „Mehr erfahren\" die ausführliche Erklärung mit Beispielen." +msgstr "Required fields are marked with a red asterisk (*). You can save the dataset as a draft at any time — only publishing requires every mandatory field. Each field comes with guidance: the ⓘ icon shows the DCAT-AP term, \"Learn more\" the full explanation with examples." + msgid "Die Qualitätsprüfung bewertet die Vollständigkeit der Metadaten. Die Werte werden bei jedem Speichern neu berechnet – Änderungen im Formular wirken sich erst nach dem Speichern auf das Ergebnis aus." msgstr "The quality check evaluates the completeness of the metadata. The values are recalculated each time you save – changes in the form only affect the result after saving." @@ -444,6 +435,9 @@ msgstr "The preview shows the generated JSON-LD based on the most recently saved msgid "Diese Werte werden beim Anlegen eines neuen Datensatzes automatisch vorausgefüllt." msgstr "These values are pre-filled automatically when creating a new dataset." +msgid "Diese bestimmt, wie andere die Daten nutzen dürfen." +msgstr "This determines how others may use the data." + msgid "Dieser Datensatz ist nicht veröffentlicht." msgstr "This dataset is not published." @@ -474,6 +468,36 @@ msgstr "Distribution with URL (dcat:accessURL)" msgid "Distribution mit Zugriffs-URL (dcat:accessURL)" msgstr "Distribution with access URL (dcat:accessURL)" +msgid "EIGENE LIZENZ-URI (dct:license)" +msgstr "CUSTOM LICENCE URI (dct:license)" + +msgid "Eigenschaft" +msgstr "Property" + +msgid "Eine der sechs EU-Themenkategorien." +msgstr "One of the six EU thematic categories." + +msgid "HOCHWERTIGER DATENSATZ (dcatap:applicableLegislation)" +msgstr "HIGH-VALUE DATASET (dcatap:applicableLegislation)" + +msgid "Im Standard nachlesen" +msgstr "Read it in the standard" + +msgid "KONTAKTPUNKT · E-MAIL (dcat:contactPoint / vcard:hasEmail)" +msgstr "CONTACT POINT · EMAIL (dcat:contactPoint / vcard:hasEmail)" + +msgid "KONTAKTPUNKT · NAME (dcat:contactPoint / vcard:fn)" +msgstr "CONTACT POINT · NAME (dcat:contactPoint / vcard:fn)" + +msgid "KONTAKTPUNKT · WEBSITE (dcat:contactPoint / vcard:hasURL)" +msgstr "CONTACT POINT · WEBSITE (dcat:contactPoint / vcard:hasURL)" + +msgid "Multiplizität" +msgstr "Multiplicity" + +msgid "Pflichtfeld für die Veröffentlichung" +msgstr "Required for publishing" + msgid "Primäre Distribution — weitere Angaben" msgstr "Primary distribution — further details" @@ -534,9 +558,6 @@ msgstr "A demo dataset with a sample CSV was created automatically. Insert this msgid "Ein Fehler ist aufgetreten." msgstr "An error occurred." -msgid "Eine der sechs EU-Themenkategorien. Beispiel: Georaum, Meteorologie, Mobilität" -msgstr "One of the six EU thematic categories. Example: Geospatial, Meteorological, Mobility" - msgid "Eine eindeutige Kennung des Datensatzes (z. B. DOI oder interne ID). Beispiel: 10.1234/abcd" msgstr "A unique identifier of the dataset (e.g. DOI or internal ID). Example: 10.1234/abcd" @@ -759,8 +780,11 @@ msgstr "In three steps: fill in the form, generate DCAT-AP.de metadata, portals msgid "In welche Kategorie gehört dieser Datensatz?" msgstr "Which category does this dataset belong to?" -msgid "Welchem Engagementfeld ist dieser Datensatz zuzuordnen?" -msgstr "Which field of civic engagement does this dataset belong to?" +msgid "Welchen Engagementfeldern ist dieser Datensatz zuzuordnen?" +msgstr "Which fields of civic engagement does this dataset belong to?" + +msgid "— Keine Angabe —" +msgstr "— Not specified —" msgid "In welchem Format ist die Datei?" msgstr "What format is the file in?" @@ -1507,6 +1531,9 @@ msgstr "Which standard or schema does the data conform to?" msgid "Welchen Medientyp (MIME) hat die Datei?" msgstr "What media type (MIME) does the file have?" +msgid "Welchen Themen ist dieser Datensatz zugeordnet?" +msgstr "Which themes is this dataset assigned to?" + msgid "Welcher HVD-Kategorie gehört dieser Datensatz an?" msgstr "Which HVD category does this dataset belong to?" @@ -1558,8 +1585,8 @@ msgstr "How can the distribution be described?" msgid "Wie oft werden diese Daten aktualisiert?" msgstr "How often are these data updated?" -msgid "Wie verlässlich/dauerhaft ist der Zugriff auf diese Datei geplant? Beispiel: Stabil, Verfügbar, Temporär" -msgstr "How reliable/durable is access to this file planned to be? Example: Stable, Available, Temporary" +msgid "Wie verlässlich/dauerhaft ist der Zugriff auf diese Datei geplant?" +msgstr "How reliable/permanent is access to this file intended to be?" msgid "Wiederverwendbarkeit" msgstr "Reusability" @@ -1766,12 +1793,6 @@ msgstr "Tab %s" msgid "Zum Feld springen" msgstr "Go to field" -msgid "Pflichtfeld zum Veröffentlichen" -msgstr "Required for publishing" - -msgid "* Pflichtfeld zum Veröffentlichen. Als Entwurf können Sie jederzeit unvollständig speichern." -msgstr "* Required for publishing. You can always save an incomplete draft." - msgid "Link zur Datei oder Datei-Upload" msgstr "Link to the file or file upload" @@ -1790,9 +1811,6 @@ msgstr "Data provision" msgid "Folgende Pflichtangaben fehlen oder sind leer:" msgstr "The following required fields are missing or empty:" -msgid "Der Datensatz wurde als Entwurf gespeichert. Bitte alle Pflichtangaben befüllen und erneut veröffentlichen. Als Entwurf können Sie jederzeit unvollständig speichern." -msgstr "The dataset was saved as a draft. Please complete all required fields and publish again. You can always save an incomplete draft." - msgid "Welchem Thema ist dieser Datensatz zugeordnet?" msgstr "Which theme is this dataset assigned to?" @@ -1838,9 +1856,6 @@ msgstr "The language of the data and — if desired — title, description and k msgid "Wer gibt diese Daten heraus? Worum geht es? Welchem Thema ist der Datensatz zugeordnet? Und mit welchen Schlagworten findet man ihn? Optional lassen sich unter „Weitere Einordnung\" eine Themenklassifikation und ein Engagementfeld ergänzen." msgstr "Who publishes these data? What are they about? Which theme is the dataset assigned to? And which keywords lead people to it? Optionally, a topic classification and a field of civic engagement can be added under \"Further classification\"." -msgid "Die Pflichtfelder sind mit einem roten Sternchen (*) gekennzeichnet. Als Entwurf können Sie jederzeit unvollständig speichern – erst zum Veröffentlichen müssen alle Pflichtfelder ausgefüllt sein. Jedes Feld hat hilfreiche Beispiele, die Sie über das ⓘ-Symbol einblenden." -msgstr "Required fields are marked with a red asterisk (*). You can always save an incomplete draft — only publishing requires all mandatory fields to be filled in. Every field has helpful examples that you can reveal via the ⓘ icon." - msgid "DCAT-AP.de · Turtle (empfohlen)" diff --git a/languages/open-data-wizard.pot b/languages/open-data-wizard.pot index 93531a0d..97b1b563 100644 --- a/languages/open-data-wizard.pot +++ b/languages/open-data-wizard.pot @@ -15,6 +15,9 @@ msgstr "" msgid "(optional)" msgstr "" +msgid "* Pflichtfeld für die Veröffentlichung. Als Entwurf können Sie den Datensatz jederzeit speichern." +msgstr "" + msgid "1 — Grundlegende Informationen" msgstr "" @@ -87,33 +90,15 @@ msgstr "" msgid "Beispiel: 2024-12-31" msgstr "" -msgid "Beispiel: CC0 1.0, CC-BY 4.0 – Diese bestimmt, wie andere die Daten nutzen dürfen." -msgstr "" - -msgid "Beispiel: CSV, JSON, PDF" -msgstr "" - -msgid "Beispiel: Deutsch, Englisch" -msgstr "" - msgid "Beispiel: Ein Überblick über die bevölkerungsreichsten Städte in Deutschland mit statistischen Daten zu Einwohnerzahl und Entwicklung." msgstr "" -msgid "Beispiel: Gemeinde, Landkreis, Land, Bund" -msgstr "" - msgid "Beispiel: Musterstadt Statistikamt, Umweltbundesamt, Verbraucherzentrale e.V." msgstr "" msgid "Beispiel: Open Data Team, Statistisches Landesamt" msgstr "" -msgid "Beispiel: Täglich, Monatlich, Jährlich, Unregelmäßig" -msgstr "" - -msgid "Beispiel: Umwelt, Bildung, Gesundheit, Wirtschaft, Kultur" -msgstr "" - msgid "Beispiel: Zivilgesellschaftliche Organisationen" msgstr "" @@ -291,6 +276,9 @@ msgstr "" msgid "Demo-Datensatz bearbeiten" msgstr "" +msgid "Der Datensatz wurde als Entwurf gespeichert. Bitte alle Pflichtangaben befüllen und erneut veröffentlichen. Als Entwurf können Sie den Datensatz jederzeit speichern." +msgstr "" + msgid "Der Datensatz wurde als Entwurf gespeichert. Bitte alle Pflichtfelder befüllen und erneut veröffentlichen." msgstr "" @@ -309,6 +297,9 @@ msgstr "" msgid "Die Idee" msgstr "" +msgid "Die Pflichtfelder sind mit einem roten Sternchen (*) gekennzeichnet. Als Entwurf können Sie den Datensatz jederzeit speichern – erst zum Veröffentlichen müssen alle Pflichtfelder ausgefüllt sein. Zu jedem Feld gibt es Erläuterungen: Das ⓘ-Symbol zeigt den DCAT-AP-Begriff, „Mehr erfahren\" die ausführliche Erklärung mit Beispielen." +msgstr "" + msgid "Die Qualitätsprüfung bewertet die Vollständigkeit der Metadaten. Die Werte werden bei jedem Speichern neu berechnet – Änderungen im Formular wirken sich erst nach dem Speichern auf das Ergebnis aus." msgstr "" @@ -318,6 +309,9 @@ msgstr "" msgid "Diese Werte werden beim Anlegen eines neuen Datensatzes automatisch vorausgefüllt." msgstr "" +msgid "Diese bestimmt, wie andere die Daten nutzen dürfen." +msgstr "" + msgid "Dieser Datensatz ist nicht veröffentlicht." msgstr "" @@ -342,12 +336,21 @@ msgstr "" msgid "EIGENE LIZENZ-URI" msgstr "" +msgid "EIGENE LIZENZ-URI (dct:license)" +msgstr "" + +msgid "Eigenschaft" +msgstr "" + msgid "Ein Demo-Datensatz mit Beispiel-CSV wurde automatisch erstellt. Fügen Sie diesen Shortcode in einen Beitrag oder eine Seite ein, um die Download-Card anzuzeigen:" msgstr "" msgid "Ein Fehler ist aufgetreten." msgstr "" +msgid "Eine der sechs EU-Themenkategorien." +msgstr "" + msgid "Einheit" msgstr "" @@ -447,6 +450,9 @@ msgstr "" msgid "HERAUSGEBENDE ORGANISATION (dct:publisher)" msgstr "" +msgid "HOCHWERTIGER DATENSATZ (dcatap:applicableLegislation)" +msgstr "" + msgid "Harvest-Endpoint" msgstr "" @@ -465,6 +471,9 @@ msgstr "" msgid "Hinweis ausblenden" msgstr "" +msgid "Im Standard nachlesen" +msgstr "" + msgid "Import abgeschlossen!" msgstr "" @@ -519,6 +528,15 @@ msgstr "" msgid "Jährlich" msgstr "" +msgid "KONTAKTPUNKT · E-MAIL (dcat:contactPoint / vcard:hasEmail)" +msgstr "" + +msgid "KONTAKTPUNKT · NAME (dcat:contactPoint / vcard:fn)" +msgstr "" + +msgid "KONTAKTPUNKT · WEBSITE (dcat:contactPoint / vcard:hasURL)" +msgstr "" + msgid "Katalog" msgstr "" @@ -627,6 +645,9 @@ msgstr "" msgid "Monatlich" msgstr "" +msgid "Multiplizität" +msgstr "" + msgid "Musterorganisation e.V." msgstr "" @@ -700,6 +721,9 @@ msgstr "" msgid "Pflichtangaben" msgstr "" +msgid "Pflichtfeld für die Veröffentlichung" +msgstr "" + msgid "Pflichtfelder" msgstr "" @@ -898,6 +922,9 @@ msgstr "" msgid "Welche geografische Region betreffen diese Daten?" msgstr "" +msgid "Welchen Themen ist dieser Datensatz zugeordnet?" +msgstr "" + msgid "Welcher Namensnennungstext soll bei Weiternutzung angegeben werden?" msgstr "" @@ -922,6 +949,9 @@ msgstr "" msgid "Wie oft werden diese Daten aktualisiert?" msgstr "" +msgid "Wie verlässlich/dauerhaft ist der Zugriff auf diese Datei geplant?" +msgstr "" + msgid "Willkommen im Open Data Wizard" msgstr "" @@ -1042,9 +1072,6 @@ msgstr "" msgid "HVD-KATEGORIE (dcatap:hvdCategory)" msgstr "" -msgid "Eine der sechs EU-Themenkategorien. Beispiel: Georaum, Meteorologie, Mobilität" -msgstr "" - msgid "Georaum (Geospatial)" msgstr "" @@ -1072,9 +1099,6 @@ msgstr "" msgid "PLANBARE VERFÜGBARKEIT (dcatap:availability)" msgstr "" -msgid "Wie verlässlich/dauerhaft ist der Zugriff auf diese Datei geplant? Beispiel: Stabil, Verfügbar, Temporär" -msgstr "" - msgid "Verfügbar (mittelfristige Planung)" msgstr "" @@ -1390,12 +1414,6 @@ msgstr "" msgid "Zum Feld springen" msgstr "" -msgid "Pflichtfeld zum Veröffentlichen" -msgstr "" - -msgid "* Pflichtfeld zum Veröffentlichen. Als Entwurf können Sie jederzeit unvollständig speichern." -msgstr "" - msgid "Link zur Datei oder Datei-Upload" msgstr "" @@ -1414,9 +1432,6 @@ msgstr "" msgid "Folgende Pflichtangaben fehlen oder sind leer:" msgstr "" -msgid "Der Datensatz wurde als Entwurf gespeichert. Bitte alle Pflichtangaben befüllen und erneut veröffentlichen. Als Entwurf können Sie jederzeit unvollständig speichern." -msgstr "" - msgid "Welchem Thema ist dieser Datensatz zugeordnet?" msgstr "" @@ -1462,9 +1477,6 @@ msgstr "" msgid "Wer gibt diese Daten heraus? Worum geht es? Welchem Thema ist der Datensatz zugeordnet? Und mit welchen Schlagworten findet man ihn? Optional lassen sich unter „Weitere Einordnung\" eine Themenklassifikation und ein Engagementfeld ergänzen." msgstr "" -msgid "Die Pflichtfelder sind mit einem roten Sternchen (*) gekennzeichnet. Als Entwurf können Sie jederzeit unvollständig speichern – erst zum Veröffentlichen müssen alle Pflichtfelder ausgefüllt sein. Jedes Feld hat hilfreiche Beispiele, die Sie über das ⓘ-Symbol einblenden." -msgstr "" - msgid "DCAT-AP.de · Turtle (empfohlen)" @@ -1522,7 +1534,10 @@ msgstr "" msgid "Davon steuert der Wizard %d Punkte selbst bei: Das Änderungsdatum wird bei jedem Speichern automatisch gesetzt. Deshalb steht auch ein noch leerer Datensatz nicht bei 0 %%." msgstr "" -msgid "Welchem Engagementfeld ist dieser Datensatz zuzuordnen?" +msgid "Welchen Engagementfeldern ist dieser Datensatz zuzuordnen?" +msgstr "" + +msgid "— Keine Angabe —" msgstr "" msgid "(ohne Titel, ID %d)" diff --git a/open-data-wizard.php b/open-data-wizard.php index 2553581e..d375be37 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.40.2 + * Version: 2.41.0 * Requires at least: 6.4 * Requires PHP: 8.1 * Author: nozilla @@ -26,7 +26,7 @@ exit; } -define( 'ODW_VERSION', '2.40.2' ); +define( 'ODW_VERSION', '2.41.0' ); define( 'ODW_PLUGIN_DIR', plugin_dir_path( __FILE__ ) ); define( 'ODW_PLUGIN_URL', plugin_dir_url( __FILE__ ) ); define( 'ODW_PLUGIN_FILE', __FILE__ ); diff --git a/package.json b/package.json index 6c54f69b..53ff439d 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "open-data-wizard", - "version": "2.40.2", + "version": "2.41.0", "description": "WordPress plugin for publishing open data as DCAT-AP 3.0 compliant metadata", "author": "Open Data Wizard Team", "license": "GPL-2.0-or-later", diff --git a/tests/e2e/admin-workflow.spec.js b/tests/e2e/admin-workflow.spec.js index b6136b00..2d2d3a2a 100644 --- a/tests/e2e/admin-workflow.spec.js +++ b/tests/e2e/admin-workflow.spec.js @@ -103,6 +103,110 @@ test.describe('Formular', () => { await expect(page.locator(cfField('odw_publisher'))).toHaveValue('Stadt Musterstadt'); }); + test('„Mehr erfahren" zeigt Merkmale, Erklärung und Definition', async ({ page }) => { + await page.goto('/wp-admin/post-new.php?post_type=odw_dataset'); + + // Das Panel hängt am Feld, nicht am Reiter — der Herausgeber steht in Tab 1. + const panel = page.locator('.cf-field', { has: page.locator(cfField('odw_publisher')) }) + .locator('details.odw-field-more'); + await expect(panel).toBeVisible(); + await panel.locator('summary').click(); + + // Zwei Merkmalszeilen über der Definition: Eigenschaft und Multiplizität. + // Beide standen vorher nur mitten im Fließtext. + const facts = panel.locator('.odw-field-more__facts'); + await expect(facts.locator('dt')).toHaveText(['Eigenschaft', 'Multiplizität']); + await expect(facts.locator('dd')).toHaveText(['dct:publisher', '1..1']); + + // Darunter unverändert beide Langtexte. + await expect(panel).toContainText('Einfach erklärt'); + await expect(panel).toContainText('DCAT-AP-Definition'); + + // Und ein Link auf den Abschnitt der Spezifikation, der zu dieser + // Profil-Klasse gehört — der Herausgeber steht am Datensatz. + const spec = panel.locator('a.odw-field-more__spec'); + await expect(spec).toHaveAttribute( + 'href', + 'https://www.dcat-ap.de/def/dcatde/3.0/spec/#datensatz' + ); + await expect(spec).toContainText('Datensatz'); + }); + + test('das Tooltip trägt nur noch den Fachbegriff', async ({ page }) => { + await page.goto('/wp-admin/post-new.php?post_type=odw_dataset'); + + // Rollentrennung: Im ⓘ steht der DCAT-AP-Begriff, alles Erklärende liegt + // im Panel. Das Beispiel, das früher hier stand, darf nicht zurückkehren. + const tip = page.locator('.cf-field', { has: page.locator(cfField('odw_publisher')) }) + .locator('.odw-help-pop'); + await expect(tip).toContainText('dct:publisher'); + await expect(tip).not.toContainText('Beispiel'); + }); + + test('Thema ist eine Mehrfachauswahl mit den EU-Themen', async ({ page }) => { + await page.goto('/wp-admin/post-new.php?post_type=odw_dataset'); + + // Seit v2.41.0 ein Mehrfachfeld: dcat:theme erlaubt 0..n Themen. Vorher + // gab es ein Auswahlfeld hier und ein Tipp-Feld unter „Erweiterte Angaben". + const themeField = page.locator('.cf-field', { has: page.locator(cfField('odw_theme')) }); + await expect(themeField).toBeVisible(); + // Carbon Fields 3.6 rendert multiselect über react-select: ein
mit der + // Klasse cf-multiselect__select, kein