diff --git a/frontend/public/ontology/edm.owl b/frontend/public/ontology/edm.owl new file mode 100644 index 0000000000..f92eb32d8d --- /dev/null +++ b/frontend/public/ontology/edm.owl @@ -0,0 +1,902 @@ + + + + + + + + + + + + + + + + + + +]> + + + + + + edm + http://www.europeana.eu/schemas/edm/ + Europeana Data Model (EDM) vocabulary + The Europeana Data Model (EDM) is aimed at being an integration medium for collecting, connecting and enriching the descriptions provided by Europeana data providers. The RDF vocabulary for http://www.europeana.eu/schemas/edm/ defines the elements introduced by EDM (as opposed to the ones EDM re-uses from other namespaces). + 2010-03-25 + 2013-05-20 + 5.2.4 + The present specification is based on the document "Definition of the Europeana Data Model elements", originally edited by Carlo Meghini. It is aligned with the version 5.2.4 of these EDM Definitions. + + + + + + + + + + + + + +======= +Changes between ontology file EDM version 5.2.4 (edm, was once EDM-v524-120820) +and ontology file EDM version 5.2.3 (EDM-v523-120123) +======= +1. edm:isShownAt made a sub-property of edm:hasView +2. added edm:begin and edm:end and their mappings to CRM +3. added owl:Class declarations added for compatibility with some OWL-DL reasoners (feedback from Pedro Szekely, ISI) +4. added "of" at the end of the label for edm:isNextInSequence +5. added vocabulary metadata to follow Linked Open Vocabularies (http://lov.okfn.org/) and ADMS (https://joinup.ec.europa.eu/asset/adms/release/100) guidelines +6. removed a domain axiom on edm:hasMet +7. added edm:collectionName and edm:europeanaProxy +8. removed version number from file name +9. generalisation of Country, DataProvider and Provider +10. updated CRM namespace and CRM class and property identifiers +11. added FRBRoo mappings + + +======= +Remaining TODOs for ontology file EDM version 5.2.4 +======= +- finish and check FRBRoo mappings according to the recommendations of the EDM-FRBRoo task force. Also include implicit mappings and mappings for elements outside the EDM namespace? +- try to capture formal cardinality constraints resulting from "Obligation and Occurrence" documentation, which should be attached to non-EDM constructs (esp. ore:Aggregation) +- continue adding documentation values (skos:scopeNote, skos:example, etc, according to 1.), starting from edm:InformationResource. Add all Europeana examples and rationale notes for non-EDM constructs +- use specific EDM-doc properties for "rationale" and "obligation and occurrence". Use skos:definition for "Europeana definition", skos:example for "Example", skos:note for "Europeana note" + + + + + + + + + Agent + This class comprises people, either individually or in groups, who have the +potential to perform intentional actions for which they can be held responsible. + Leonardo da Vinci, the British Museum, W3C + + + Rationale: This class is a domain of edm:wasPresentAt + + + + + + + Europeana Aggregation + The set of resources related to a single Cultural Heritage Object that +collectively represent that object in Europeana. Such set consists of: all +descriptions about the object that Europeana collects from (possibly different) content providers, including thumbnails and other forms of abstractions, as well as of the description of the object Europeana builds. + + + + + 1 + + + + An instance of EuropeanaAggregation is created at ingestion time for each different Cultural Heritage Object recognized by Europeana. Such instance is associated to the Cultural Heritage Object that it is about, by the property edm:aggregatedCHO + Obligation and Occurence: The relation between the Cultural Heritage Objects represented in Europeana and the instances of the class EuropeanaAggregation is one-to-one, in the data maintained by Europeana: every Cultural Heritage Object is represented by an instance of EuropeanaAggregation, and every instance of EuropeanaAggregation represent a Cultural Heritage Object. + The painting Mona Lisa is a Cultural Heritage Object represented in Europeana by one EuropeanaAggregation instance + The journal "Le Temps" is a Cultural Heritage Object represented in Europeana by one EuropeanaAggregation instance + The 56th issue of "Le Temps" is a (different) Cultural Heritage Object represented in Europeana by another EuropeanaAggregation instance + Rationale: This class is used in Europeana to gather in a single conceptual unit all the information about a Cultural Heritage Object, necessary for all operations on these objects. + + + + + + Europeana Object + Any object that is the result of Europeana’s activities + + Any instance of the class EuropeanaAggregation + An annotation created by a user through the Europeana portal + Any content created by the users through the service made available by Europeana for that purpose + Rationale: This class is used to tag objects that are the result of activity of Europeana, and, as such, objects on which Europeana holds rights + + + + + + Event + An event is a change "of states in cultural, social or physical systems, + regardless of scale, brought about by a series or group of coherent physical, +cultural, technological or legal phenomena" (E5 Event in CIDOC CRM) or a "set of coherent phenomena or cultural manifestations bounded in time and space" (E4 Period in CIDOC CRM) + + + + + + + + + 1 + + + + Events are identified either by the content provider or by Europeana enrichment at ingestion time + the act of painting Mona Lisa + the 2nd World War + the change of custody of Mona Lisa + Rationale:This class is a domain of edm:happenedAt and the domain of edm:occurredAt + + + + + + Information Resource + An information resource is a resource whose essential characteristics can be conveyed in a single message. It can be associated with a URI, it can have a representation, for example: a text is an InformationResource. + + + + + + + + + + + + + + + + + + + + + + + + + + Non-Information Resource + All resources that are not information resources. + + + + + + + Physical Thing + A persistent physical item such as a painting, a building, a book or a stone. +Persons are not items. This class represents Cultural Heritage Objects known to Europeana to be physical things (such as Mona Lisa) as well as all physical things Europeana refers to in the descriptions of Cultural Heritage Objects (such as the Rosetta Stone). + + + + + + + + Place + An "extent in space, in particular on the surface of the earth, in the pure sense of physics: independent from temporal phenomena and matter" (CIDOC CRM) + + + + + + + + + + + + Provided CHO + This class comprises the Cultural Heritage objects that Europeana collects descriptions about. + + + 1 + + + + + + + + This class has been mostly motivated by the need to assign a type to the “central node” in the EDM pattern, during the ingestion process, related to the XML expression of EDM at that stage. It was especially intended to fit the cases where edm:PhysicalThing cannot be used as the type of the resource standing for the real-world object (independently of any specific data contributor perspective). + Mona Lisa, Winged Victory of Samothrace + Rationale: This class is the range of edm:aggregatedCHO. A resource of type ProvidedCHO can be the subject of statements using edm:isRelatedTo or any more specific property. + + + + + + Time Span + The class of "abstract temporal extents, in the sense of Galilean physics, + having a beginning, an end and a duration" (CIDOC CRM) + + + + + + + + + + + Web Resource + Information Resources that have at least one Web Representation and at least +a URI. + + + + + + + + + + Aggregated Cultural Heritage Object + This property associates an ORE aggregation with the cultural heritage object(s) (CHO for short) it is about. + + + + + + + + + + + Begin + This property denotes the start date of a period of time. + + + + + + + + + + + + + + + Collection Name + This property holds the collection identifier given to the dataset in Europeana. + The value of this property is provided by Europeana as part of the ingestion process. + + + + + + Current Location + The geographic location and/or name of the repository, building, site, or other entity whose boundaries presently include the resource. + + + + + + + + + + + + + + + + + + + + + + + + + + End + This property denotes the end date of a period of time. + + + + + + + + + + + + + + + Europeana Proxy + This property serves only as a flag to indicate that a proxy is a Europeana proxy (as opposed to a provider proxy). It is for internal use only. + By default, any proxy without this flag can be interpreted as having the value false and is a provider proxy. + + + + + + Happened At + This property associates an event with the place at which the event +happened. + + + + + + + + + + Has Met + edm:hasMet relates a resource with the objects or phenomena that have happened to or have happened together with the resource under consideration. We can abstractly think of history and the present as a series of “meetings” between people and other things in space-time. Therefore we name this relationship as the things the object “has met” in the course of its existence. These meetings are events in the proper sense, in which other people and things participate in any role. + + + + + + + Has Type + This property relates a resource with the concepts it belongs to in a suitable +type system such as MIME or any thesaurus that captures categories of objects in a given field (e.g., the “Objects” facet in Getty’s Art and Architecture Thesaurus). It does not capture aboutness. + + + + + + + + + + + + + + + + + + + + + + + + + Has View + This property relates a ORE aggregation about a CHO with a web resource +providing a view of that CHO. Examples of view are: a thumbnail, a textual +abstract and a table of contents. The ORE aggregation may be a Europeana +Aggregation, in which case the view is an object owned by Europeana (i.e., an instance of edm:EuropeanaObject) or an aggregation contributed by a content provider. In order to capture both these cases, the domain of edm:hasView is ore:Aggregation and its range is edm:WebResource + + + + + + + + + Incorporates + This property captures the use of some resource to add value to another +resource. Such resources may be nested, such as performing a theater play text, and then recording the performance, or creating an artful edition of a collection of poems or just aggregating various poems in an anthology. There may be no single part that contains ultimately the incorporated object, which may be dispersed in the presentation. Therefore, incorporated resources do in general not form proper parts. Incorporated resources are not part of the same resource, but are taken from other resources, and have an independent history. Therefore edm:incorporates is not a sub-property of dcterm:hasPart. + + + + + + + + Is Annotation Of + This property relates an annotation (a Europeana object) with the resource +that it annotates. + + + + + + + + + + + + + + + + + + + + + + + + + Is Derivative Of + This property captures a narrower notion of derivation than edm:isSimilarTo, in the sense that it relates a resource to another one, obtained by reworking, reducing, expanding, parts or the whole contents of the former, and possibly adding some minor parts. Versions have an even narrower meaning, in that it requires common identity between the related resources. Translations, summaries, abstractions etc. do not qualify as versions, but do qualify as derivatives. + + + + + + + + Is Next In Sequence Of + edm:isNextInSequence relates two resources S and R that are ordered parts of the same resource A, and such that S comes immediately after R in the order created by their being parts of A. + + + + + + + + Is Related To + edm:isRelatedTo is the most general contextual property in EDM. Contextual +properties have typically to do either with the things that have happened to or together with the object under consideration, or what the object refers to by its shape, form or features in a figural or encoded form. For sake of simplicity, we include in the contextual relationships also the scholarly classification, which may have either to do with the role and cultural connections of the object in the past, or its kind of structure, substance or contents as it can be verified at present. + + + + + + + + + + + + + + + + + + + + + + Is Representation Of + This property associates an information resource to the resource (if any) that it represents + + + + + + + + + Is Similar To + The most generic derivation property, covering also the case of questionable derivation. Is Similar To asserts that parts of the contents of one resource exhibit common features with respect to ideas, shapes, structures, colors, words, plots, topics with the contents of the related resource. Those common features may be attributed to a common origin or influence (in particular for derivation), but also to more generic cultural or psychological factors. + + + + + + + + Is Successor Of + This property captures the relation between the continuation of a resource and that resource. This applies to a story, a serial, a journal etc. No content of the successor resource is identical or has a similar form with that of the precursor. The similarity is only in the context, subjects and figures of a plot. Successors typically form part of a common whole – such as a trilogy, a journal, etc. + + + + + + + Landing Page + This property captures the relation between a Europeana aggregation representing a cultural heritage object and a (reference) Web resource giving access to that object. Europeana provides the value for this property. + + + + + + + + Occured At + This property associates an event to the smallest known time span that +overlaps with the occurrence of that event + + + + + + + + + + Preview + The URL of a thumbnail representing the digital object, generated by Europeana. + + + + + + + + Realizes + This property describes a relation between a physical thing and the information resource that is contained in it, visible at it or otherwise carried by it, if applicable. + + + + + + + + + + + Was Present At + This property associates the people, things or information resources with an event at which they were present + + + + + + + + + + + + + + + + + + + + + + + Country + + + + + + + Data Provider + The name or identifier of the organisation who contributes data indirectly to an aggregation service (e.g. Europeana). + + + + + + + + + Is Shown At + An unambiguous URL reference to the digital object on the provider’s web site in its full information context. + + + + + + + + Is Shown By + An unambiguous URL reference to the digital object on the provider’s web site in the best available resolution/quality. + + + + + + + + Europeana Language + The value for this element is added by the Data Ingestion Team as part of the ingestion process, based on the language of the data provider. + + + + + + Object + The URL of a thumbnail representing the digital object or, if there is no such +thumbnail, the URL of the digital object in the best resolution available on the +web site of the data provider from which a thumbnail could be generated. This will often be the same URL as given in edm:isShownBy. + + + + + + + + Provider + The name or identifier of the organization who delivers data directly to an aggregation service (e.g. Europeana) + + + + + + + + Europeana Rights + Information about copyright of the digital object as specified by isShownBy +and isShownAt + + + + + + Europeana Type + The Europeana material type of the resource + + + + + TEXT + + IMAGE + + SOUND + + VIDEO + + 3D + + + + + + + + + + + + + + UGC + This element is used to identify user generated content (also called user created content). It should be applied to all digitised or born digital content contributed by the general public and collected by Europeana through a crowdsourcing initiative or project. + + + + TRUE + + + + + + + + + + Unstored + This is a container element which includes all relevant information that +otherwise cannot be mapped to another element in the ESE. + + + + + + Europeana URI + This is a tag created by a user through the Europeana interface. + + + + + + User Tag + This is a tag created by a user through the Europeana interface. + + + + + + + Europeana Year + A point of time associated with an event in the life of the original analog or +born digital object. + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/frontend/src/components/ontology/OntologyTermPopup.tsx b/frontend/src/components/ontology/OntologyTermPopup.tsx index 7767ead8f3..505e5f5063 100644 --- a/frontend/src/components/ontology/OntologyTermPopup.tsx +++ b/frontend/src/components/ontology/OntologyTermPopup.tsx @@ -13,6 +13,7 @@ */ import React, { useEffect, useState, useRef, useCallback } from 'react'; +import DOMPurify from 'dompurify'; import { loadOntology, getOntologyFileByUri, @@ -51,6 +52,7 @@ const STANDARD_PREFIXES: Record = { 'premis': 'http://www.loc.gov/premis/rdf/v3/', 'pico': 'https://pico.hypotheses.org/the-pico-ontology#', 'tooi': 'https://identifier.overheid.nl/tooi/def/ont/', + 'edm': 'http://www.europeana.eu/schemas/edm/', // Application ontologies 'cpov': 'http://data.europa.eu/m8g/', @@ -330,6 +332,35 @@ async function loadTermInfo(curie: string): Promise { } } +/** + * Sanitize HTML content for safe rendering. + * Allows safe tags like ,
, , while stripping dangerous ones. + * Also fixes Schema.org relative links (href="/something" -> href="https://schema.org/something") + */ +function sanitizeHtml(html: string): string { + // Configure DOMPurify to allow only safe tags + const clean = DOMPurify.sanitize(html, { + ALLOWED_TAGS: ['a', 'br', 'em', 'strong', 'b', 'i', 'code', 'span', 'p'], + ALLOWED_ATTR: ['href', 'class', 'title', 'target', 'rel'], + ADD_ATTR: ['target'], // Will add target="_blank" to links + }); + + // Fix relative links from Schema.org (href="/businessFunction" -> "https://schema.org/businessFunction") + // and add target="_blank" for external links + const withFixedLinks = clean.replace( + /href="\/([^"]+)"/g, + 'href="https://schema.org/$1" target="_blank" rel="noopener noreferrer"' + ); + + // Also add target="_blank" to any remaining links that don't have it + const withTargetBlank = withFixedLinks.replace( + /href="(https?:\/\/[^"]+)"(?![^>]*target=)/g, + 'href="$1" target="_blank" rel="noopener noreferrer"' + ); + + return withTargetBlank; +} + /** * Compact a full URI back to CURIE form if possible */ @@ -358,6 +389,7 @@ const ONTOLOGY_COLORS: Record = { 'DCAT 3': '#3B82F6', // Blue 'CPOV (Core Public Org)': '#3B82F6', 'BIBFRAME': '#14B8A6', // Teal + 'EDM': '#0369A1', // Sky dark - Europeana blue 'TOOI': '#14B8A6', 'PiCo': '#0EA5E9', // Sky 'Wikidata': '#339966', // Wikidata green @@ -720,9 +752,12 @@ export const OntologyTermPopup: React.FC = ({ {(termInfo.description || termInfo.comment) && (
Description: -

- {termInfo.description || termInfo.comment} -

+
)} diff --git a/frontend/src/lib/ontology/ontology-loader.ts b/frontend/src/lib/ontology/ontology-loader.ts index b09b236076..1eb81bae96 100644 --- a/frontend/src/lib/ontology/ontology-loader.ts +++ b/frontend/src/lib/ontology/ontology-loader.ts @@ -300,6 +300,14 @@ export const ONTOLOGY_FILES: OntologyFile[] = [ description: 'Library of Congress bibliographic description', namespaces: ['http://id.loc.gov/ontologies/bibframe/'] }, + { + name: 'EDM', + path: 'edm.owl', + format: 'owl', + category: 'domain', + description: 'Europeana Data Model - cultural heritage aggregation', + namespaces: ['http://www.europeana.eu/schemas/edm/'] + }, { name: 'PREMIS 3', path: 'premis3.owl', @@ -1105,6 +1113,7 @@ function processSubject( /** * Resolve a relative URI against a base URI * Handles relative URIs like "#Concept" with xml:base="http://example.org/ontology" + * Also handles bare local names like "E27_Site" used by CIDOC-CRM */ function resolveUri(uri: string, base: string | null): string { if (!uri) return uri; @@ -1114,11 +1123,21 @@ function resolveUri(uri: string, base: string | null): string { return uri; } - // Relative URI starting with # - resolve against base + // Relative URI starting with # - resolve against base (e.g., "#Concept" -> "http://base/#Concept") if (uri.startsWith('#') && base) { return base + uri; } + // Bare local name without # (e.g., "E27_Site" with base "http://www.cidoc-crm.org/cidoc-crm/") + // This pattern is used by CIDOC-CRM and EDM ontologies + if (base && !uri.includes(':') && !uri.includes('/')) { + // Ensure base ends with / or # for proper concatenation + if (base.endsWith('/') || base.endsWith('#')) { + return base + uri; + } + return base + '/' + uri; + } + return uri; }