diff --git a/java/src/main/java/uk/ac/ceh/gateway/catalogue/gemini/GeminiDocument.java b/java/src/main/java/uk/ac/ceh/gateway/catalogue/gemini/GeminiDocument.java index e90cc063f..9e38d6180 100644 --- a/java/src/main/java/uk/ac/ceh/gateway/catalogue/gemini/GeminiDocument.java +++ b/java/src/main/java/uk/ac/ceh/gateway/catalogue/gemini/GeminiDocument.java @@ -38,7 +38,7 @@ @Template(called = "html/gemini.ftlh", whenRequestedAs = MediaType.TEXT_HTML_VALUE), @Template(called = "xml/gemini.ftlx", whenRequestedAs = GEMINI_XML_VALUE), @Template(called = "rdf/ttl.ftl", whenRequestedAs = RDF_TTL_VALUE), - @Template(called = "schema.org/schema.org.ftlh", whenRequestedAs = RDF_SCHEMAORG_VALUE), + @Template(called = "schema.org/schema.org.ftl", whenRequestedAs = RDF_SCHEMAORG_VALUE), @Template(called = "rocrate/rocrate.ftl", whenRequestedAs = ROCRATE_VALUE), @Template(called = "rocrate/rocrate_attached.ftl", whenRequestedAs = ROCRATE_ATTACHED_VALUE), @Template(called = "ceda/ceda.ftlh", whenRequestedAs = CEDA_YAML_VALUE) @@ -323,6 +323,21 @@ public long getIncomingCitationCount() { .orElse(0); } + public List getLicences() { + return Optional.ofNullable(useConstraints) + .orElseGet(Collections::emptyList) + .stream().filter(resourceConstraint -> resourceConstraint.getCode().equalsIgnoreCase("license")) + .collect(Collectors.toCollection(ArrayList::new)); + } + + public List getInfoLinks() { + return Optional.ofNullable(onlineResources) + .orElseGet(Collections::emptyList) + .stream() + .filter(onlineResource -> onlineResource.getFunction().equalsIgnoreCase("information")) + .collect(Collectors.toCollection(ArrayList::new)); + } + private static @NonNull String convertEmail(@NonNull String email) { return email.endsWith("@ceh.ac.uk") ? "enquiries@ceh.ac.uk" : email; } diff --git a/java/src/main/java/uk/ac/ceh/gateway/catalogue/templateHelpers/FileDetailsService.java b/java/src/main/java/uk/ac/ceh/gateway/catalogue/templateHelpers/FileDetailsService.java index ccdaad8ce..90f946b6b 100644 --- a/java/src/main/java/uk/ac/ceh/gateway/catalogue/templateHelpers/FileDetailsService.java +++ b/java/src/main/java/uk/ac/ceh/gateway/catalogue/templateHelpers/FileDetailsService.java @@ -92,7 +92,7 @@ private String path(boolean isAttached, String fileId, String path){ } @lombok.Value - public class Part { + public static class Part { String id, type, name, encodingFormat, contentUrl; Long bytes; LocalDateTime lastModified; diff --git a/java/src/test/java/templates/DataciteTemplateTest.java b/java/src/test/java/templates/DataciteTemplateTest.java index ed6ebfcef..45b92cd05 100644 --- a/java/src/test/java/templates/DataciteTemplateTest.java +++ b/java/src/test/java/templates/DataciteTemplateTest.java @@ -87,7 +87,7 @@ void related() { gemini.setUri(uri); val jena = mock(JenaLookupService.class); configuration.setSharedVariable("jena", jena); - val expected = expected("related-full.xml"); + val expected = expected("datacite/related-full.xml"); given(jena.relationships(uri, "https://vocabs.ceh.ac.uk/eidc#supersedes")).willReturn(List.of( Link.builder().href("https://catalogue.ceh.ac.uk/id/847463839").build() @@ -140,7 +140,7 @@ void full() { .build() )); - val expected = expected("subjects-full.xml"); + val expected = expected("datacite/subjects-full.xml"); //when val actual = template("_subjects.ftlx"); @@ -195,7 +195,7 @@ void full() { custodian )); - val expected = expected("contributors-full.xml"); + val expected = expected("datacite/contributors-full.xml"); //when val actual = template("_contributors.ftlx"); diff --git a/java/src/test/java/templates/RoCrateTest.java b/java/src/test/java/templates/RoCrateTest.java new file mode 100644 index 000000000..95037ef57 --- /dev/null +++ b/java/src/test/java/templates/RoCrateTest.java @@ -0,0 +1,243 @@ +package templates; + +import freemarker.template.Configuration; +import lombok.SneakyThrows; +import lombok.extern.slf4j.Slf4j; +import lombok.val; +import org.apache.commons.io.IOUtils; +import org.junit.jupiter.api.BeforeEach; +import org.junit.jupiter.api.DisplayName; +import org.junit.jupiter.api.Nested; +import org.junit.jupiter.api.Test; +import org.junit.jupiter.api.extension.ExtendWith; +import org.mockito.Mock; +import org.mockito.junit.jupiter.MockitoExtension; +import org.skyscreamer.jsonassert.JSONAssert; +import org.springframework.ui.freemarker.FreeMarkerTemplateUtils; +import uk.ac.ceh.gateway.catalogue.citation.Citation; +import uk.ac.ceh.gateway.catalogue.gemini.*; +import uk.ac.ceh.gateway.catalogue.geometry.BoundingBox; +import uk.ac.ceh.gateway.catalogue.model.ObservedProperty; +import uk.ac.ceh.gateway.catalogue.model.ResponsibleParty; +import uk.ac.ceh.gateway.catalogue.model.Supplemental; +import uk.ac.ceh.gateway.catalogue.templateHelpers.CodeLookupService; +import uk.ac.ceh.gateway.catalogue.templateHelpers.FileDetailsService; + +import java.io.File; +import java.nio.charset.StandardCharsets; +import java.time.LocalDate; +import java.time.LocalDateTime; +import java.util.List; +import java.util.Objects; + +import static org.mockito.BDDMockito.given; +import static org.mockito.Mockito.verify; + +@Slf4j +@DisplayName("RO-Crate") +@ExtendWith(MockitoExtension.class) +public class RoCrateTest { + + Configuration configuration; + GeminiDocument gemini; + @Mock + CodeLookupService codeLookupService; + @Mock + FileDetailsService fileDetailsService; + + private void givenCodeLookupService() { + given(codeLookupService.lookup("datacite.resourceTypeGeneral", "resourceType")) + .willReturn("Resource Type"); + } + + private void givenFileDetailsServiceDetached(String fileId) { + given(fileDetailsService.getDetailsFor(fileId, false)) + .willReturn(List.of( + new FileDetailsService.Part(fileId, "File", "name1", "text/csv", "https://example.com/name1", 12L, LocalDateTime.of(2024,12,9,15, 34)), + new FileDetailsService.Part(fileId, "File", "name2", "text/csv", "https://example.com/name2", 9832L, LocalDateTime.of(2020,5,6,23, 59)) + )); + } + + private void givenFileDetailsServiceAttached(String fileId) { + given(fileDetailsService.getDetailsFor(fileId, true)) + .willReturn(List.of( + new FileDetailsService.Part(fileId, "File", "name1", "text/csv", "data/name4", 542L, LocalDateTime.of(2024,12,9,15, 34)), + new FileDetailsService.Part(fileId, "File", "name2", "text/csv", "data/name5", 32L, LocalDateTime.of(2020,5,6,23, 59)) + )); + } + + private GeminiDocument createGeminiDocument(String fileId) { + val gemini = new GeminiDocument(); + gemini.setUri("https://example.org/id/" + fileId); + gemini.setId(fileId); + gemini.setTitle("Title"); + gemini.setType("dataset"); + return gemini; + } + + @SneakyThrows + private String expected(String filename) { + val expected = Objects.requireNonNull(getClass().getResourceAsStream(filename)); + return IOUtils.toString(expected, StandardCharsets.UTF_8); + } + + @SneakyThrows + private String template(String templateFilename) { + return FreeMarkerTemplateUtils.processTemplateIntoString( + configuration.getTemplate(templateFilename), + gemini + ); + } + + @SneakyThrows + @BeforeEach + void init() { + configuration = new Configuration(Configuration.VERSION_2_3_33); + configuration.setDirectoryForTemplateLoading(new File("../templates")); + configuration.setSharedVariable("codes", codeLookupService); + configuration.setSharedVariable("fileDetails", fileDetailsService); + } + + @Nested + @DisplayName("Attached") + class Attached { + + @SneakyThrows + @Test + void rocrateAttachedMinimal() { + //given + val expected = expected("rocrate/attached-minimal.json"); + val fileId = "123456789"; + gemini = createGeminiDocument(fileId); + givenFileDetailsServiceAttached(fileId); + + //when + val actual = template("rocrate/rocrate_attached.ftl"); + + //then + JSONAssert.assertEquals(expected, actual, true); + verify(fileDetailsService).getDetailsFor(fileId, true); + } + } + + @Nested + @DisplayName("Detached") + class Detached { + + @SneakyThrows + @Test + void rocrateMinimal() { + //given + val expected = expected("rocrate/minimal.json"); + val fileId = "09837382"; + gemini = createGeminiDocument(fileId); + givenFileDetailsServiceDetached(fileId); + + //when + val actual = template("rocrate/rocrate.ftl"); + + //then + JSONAssert.assertEquals(expected, actual, true); + verify(fileDetailsService).getDetailsFor(fileId, false); + } + + @SneakyThrows + @Test + void rocrateFull() { + //given + val expected = expected("rocrate/full.json"); + + val fileId = "882739943"; + gemini = createGeminiDocument(fileId); + + // partsList & partDetails + givenFileDetailsServiceDetached(fileId); + + // datacite + givenCodeLookupService(); + gemini.setDatacitable(true); + gemini.setCitation(Citation.builder() + .doi("10.5285/" + fileId) + .authors(List.of("Able", "Bracken", "Charles")) + .year(2020) + .title("Title") + .publisher("Publisher") + .resourceTypeGeneral("resourceType") + .build()); + + // resourceStatus not Deleted + gemini.setAccessLimitation(AccessLimitation.builder() + .code("Available") + .build()); + gemini.setDescription("Description"); + gemini.setAlternateTitles(List.of("Alternate Title 1", "Alternate Title 2")); + + // creation & publication dates + gemini.setDatasetReferenceDate(DatasetReferenceDate.builder() + .creationDate(LocalDate.of(2024, 1, 28)) + .publicationDate(LocalDate.of(2024, 9, 7)) + .build()); + + // observed properties + gemini.setObservedProperty(List.of( + ObservedProperty.builder().title("observed property 1").uri("https://example.com/op/1").unitsUri("https://example.com/units/m").units("metre").build(), + ObservedProperty.builder().value("observed property 2 value").build() + )); + + // keywords + gemini.setKeywordsPlace(List.of( + Keyword.builder().value("Lancaster").URI("https://example.com/lacaster").build(), + Keyword.builder().value("Bangor").URI("https://example.com/bangor").build() + )); + + // authors and points of contact + gemini.setResponsibleParties(List.of( + ResponsibleParty.builder().role("author").individualName("Donald").email("donald@example.com").nameIdentifier("https://orcid.org/0000-1234-5678-9101").build(), + ResponsibleParty.builder().role("pointOfContact").organisationName("TMSP").email("pocs@example.com").organisationIdentifier("https://example.com/TMSP").build() + )); + + // incoming citations + gemini.setIncomingCitations(List.of( + Supplemental.builder().url("https://example.com/citations/0").description("description").build(), + Supplemental.builder().url("https://example.com/citations/1").build(), + Supplemental.builder().name("something else").build() + )); + + // temporal extents + gemini.setTemporalExtents(List.of( + TimePeriod.builder().begin("2024-02-01").end("2024-10-28").build(), + TimePeriod.builder().begin("2019-08-22").build(), + TimePeriod.builder().end("2018-11-30").build() + )); + + // bounding boxes + gemini.setBoundingBoxes(List.of( + BoundingBox.builder().northBoundLatitude("46.2").eastBoundLongitude("2.3").southBoundLatitude("45.7").westBoundLongitude("0.4").build(), + BoundingBox.builder().northBoundLatitude("36.8").eastBoundLongitude("48.7").southBoundLatitude("-11.6").westBoundLongitude("-120.5").build() + )); + + gemini.setFunding(List.of( + Funding.builder().funderName("UKRI").build(), + Funding.builder().funderName("University of Oxford").build() + )); + + // OGL licences + gemini.setUseConstraints(List.of( + ResourceConstraint.builder().code("license").uri("https://eidc.ceh.ac.uk/licences/OGL/plain").build() + )); + + // downloads + gemini.setOnlineResources(List.of( + OnlineResource.builder().function("download").url("https://example.com/download/0").build(), + OnlineResource.builder().function("order").url("https://example.com/order/1").build() + )); + + //when + val actual = template("rocrate/rocrate.ftl"); + + //then + JSONAssert.assertEquals(expected, actual, true); + verify(fileDetailsService).getDetailsFor(fileId, false); + } + } +} diff --git a/java/src/test/java/templates/SchemaDotOrgTest.java b/java/src/test/java/templates/SchemaDotOrgTest.java new file mode 100644 index 000000000..332afb4f9 --- /dev/null +++ b/java/src/test/java/templates/SchemaDotOrgTest.java @@ -0,0 +1,69 @@ +package templates; + +import freemarker.template.Configuration; +import lombok.SneakyThrows; +import lombok.extern.slf4j.Slf4j; +import lombok.val; +import org.apache.commons.io.IOUtils; +import org.junit.jupiter.api.BeforeEach; +import org.junit.jupiter.api.Test; +import org.skyscreamer.jsonassert.JSONAssert; +import org.springframework.ui.freemarker.FreeMarkerTemplateUtils; +import uk.ac.ceh.gateway.catalogue.gemini.GeminiDocument; + +import java.io.File; +import java.nio.charset.StandardCharsets; +import java.util.Objects; + +@Slf4j +public class SchemaDotOrgTest { + + Configuration configuration; + GeminiDocument gemini; + + @SneakyThrows + private String expected(String filename) { + val expected = Objects.requireNonNull(getClass().getResourceAsStream(filename)); + return IOUtils.toString(expected, StandardCharsets.UTF_8); + } + + @SneakyThrows + private String template(String templateFilename) { + return FreeMarkerTemplateUtils.processTemplateIntoString( + configuration.getTemplate(templateFilename), + gemini + ); + } + + private GeminiDocument createGeminiDocument(String fileId) { + val gemini = new GeminiDocument(); + gemini.setUri("https://example.org/id/" + fileId); + gemini.setId(fileId); + gemini.setTitle("Title"); + gemini.setType("dataset"); + return gemini; + } + + @SneakyThrows + @BeforeEach + void init() { + configuration = new Configuration(Configuration.VERSION_2_3_33); + configuration.setDirectoryForTemplateLoading(new File("../templates")); + } + + @SneakyThrows + @Test + void schemaDotOrgMinimal() { + //given + val expected = expected("schemaDotOrg/minimal.json"); + val fileId = "123456789"; + gemini = createGeminiDocument(fileId); + + //when + val actual = template("schema.org/schema.org.ftl"); + log.info(actual); + + //then + JSONAssert.assertEquals(expected, actual, true); + } +} diff --git a/java/src/test/resources/templates/contributors-full.xml b/java/src/test/resources/templates/datacite/contributors-full.xml similarity index 100% rename from java/src/test/resources/templates/contributors-full.xml rename to java/src/test/resources/templates/datacite/contributors-full.xml diff --git a/java/src/test/resources/templates/related-full.xml b/java/src/test/resources/templates/datacite/related-full.xml similarity index 100% rename from java/src/test/resources/templates/related-full.xml rename to java/src/test/resources/templates/datacite/related-full.xml diff --git a/java/src/test/resources/templates/subjects-full.xml b/java/src/test/resources/templates/datacite/subjects-full.xml similarity index 100% rename from java/src/test/resources/templates/subjects-full.xml rename to java/src/test/resources/templates/datacite/subjects-full.xml diff --git a/java/src/test/resources/templates/rocrate/attached-minimal.json b/java/src/test/resources/templates/rocrate/attached-minimal.json new file mode 100644 index 000000000..d237397fe --- /dev/null +++ b/java/src/test/resources/templates/rocrate/attached-minimal.json @@ -0,0 +1,66 @@ +{ + "@context": "https://w3id.org/ro/crate/1.1/context", + "@graph": [ + { + "@type": "CreativeWork", + "@id": "ro-crate-metadata.json", + "conformsTo": { + "@id": "https://w3id.org/ro/crate/1.1" + }, + "about": { + "@id": "https://example.org/id/123456789" + } + }, + { + "@type": "Dataset", + "name": "Title", + "@id": "https://example.org/id/123456789", + "hasPart": [ + { + "@id": "#part123456789" + }, + { + "@id": "#part123456789" + } + ], + "url": "https://example.org/id/123456789", + "provider": { + "@id": "https://ror.org/04xw4m193" + }, + "includedInDataCatalog": { + "@id": "#eidc-dataCatalogue" + } + }, + { + "@id": "#eidc-dataCatalogue", + "@type": "DataCatalog", + "name": "Environmental Information Data Centre", + "alternateName": "EIDC", + "url": "https://catalogue.ceh.ac.uk/eidc/documents" + }, + { + "@id": "https://ror.org/04xw4m193", + "@type": "Organization", + "name": "NERC EDS Environmental Information Data Centre", + "email": "info@eidc.ac.uk" + }, + { + "@id": "#part123456789", + "name": "123456789", + "@type": "File", + "encodingFormat": "text/csv", + "lastModified": "2024-12-09T15:34", + "bytes": 542, + "contentUrl": "data/name4" + }, + { + "@id": "#part123456789", + "name": "123456789", + "@type": "File", + "encodingFormat": "text/csv", + "lastModified": "2020-05-06T23:59", + "bytes": 32, + "contentUrl": "data/name5" + } + ] +} diff --git a/java/src/test/resources/templates/rocrate/full.json b/java/src/test/resources/templates/rocrate/full.json new file mode 100644 index 000000000..db79ce43e --- /dev/null +++ b/java/src/test/resources/templates/rocrate/full.json @@ -0,0 +1,234 @@ +{ + "@context": "https://w3id.org/ro/crate/1.1/context", + "@graph": [ + { + "@type": "CreativeWork", + "@id": "ro-crate-metadata.json", + "conformsTo": { + "@id": "https://w3id.org/ro/crate/1.1" + }, + "about": { + "@id": "https://example.org/id/882739943" + } + }, + { + "@type": "Dataset", + "name": "Title", + "@id": "https://example.org/id/882739943", + "hasPart": [ + { + "@id": "#part882739943" + }, + { + "@id": "#part882739943" + } + ], + "identifier": { + "@type": "PropertyValue", + "propertyID": "https://registry.identifiers.org/registry/doi", + "value": "doi:10.5285/882739943", + "url": "https://doi.org/10.5285/882739943" + }, + "url": "https://doi.org/10.5285/882739943", + "creditText": "Able, Bracken, Charles (2020). Title. Publisher. (Resource Type). https://doi.org/10.5285/882739943", + "description": "Description", + "alternateName": [ + "Alternate Title 1", + "Alternate Title 2" + ], + "isAccessibleForFree": true, + "dateCreated": "2024-01-28", + "datePublished": "2024-09-07", + "variableMeasured": [ + { + "@type": "StatisticalVariable", + "@id": "https://example.com/op/1", + "name": "observed property 1", + "unitCode": "https://example.com/units/m", + "unitText": "metre" + }, + "observed property 2 value" + ], + "keywords": [ + { + "@type": "DefinedTerm", + "@id": "https://example.com/bangor", + "name": "Bangor" + }, + { + "@type": "DefinedTerm", + "@id": "https://example.com/lacaster", + "name": "Lancaster" + } + ], + "author": [ + { + "@id": "https://orcid.org/0000-1234-5678-9101" + } + ], + "contactPoint": [ + { + "@id": "https://example.com/TMSP" + } + ], + "@reverse": { + "citation": [ + { + "@id": "https://example.com/citations/0" + }, + { + "@id": "https://example.com/citations/1" + }, + { + "@id": "#citation2" + } + ] + }, + "temporalCoverage": [ + "2024-02-01/2024-10-28", + "2019-08-22/", + "/2018-11-30" + ], + "spatialCoverage": [ + { + "@id": "#bbox0" + }, + { + "@id": "#bbox1" + } + ], + "funder": [ + { + "@id": "#fund0" + }, + { + "@id": "#fund1" + } + ], + "license": { + "@id": "#oglLicence" + }, + "distribution": [ + { + "@id": "#distribution0" + }, + { + "@id": "#distribution1" + } + ], + "provider": { + "@id": "https://ror.org/04xw4m193" + }, + "includedInDataCatalog": { + "@id": "#eidc-dataCatalogue" + } + }, + { + "@id": "#eidc-dataCatalogue", + "@type": "DataCatalog", + "name": "Environmental Information Data Centre", + "alternateName": "EIDC", + "url": "https://catalogue.ceh.ac.uk/eidc/documents" + }, + { + "@id": "https://ror.org/04xw4m193", + "@type": "Organization", + "name": "NERC EDS Environmental Information Data Centre", + "email": "info@eidc.ac.uk" + }, + { + "@id": "#oglLicence", + "@type": "CreativeWork", + "name": "Open Government Licence v3", + "alternateName": "OGL-UK-3.0", + "license": "https://spdx.org/licenses/OGL-UK-3.0.html" + }, + { + "@id": "#bbox0", + "@type": "Place", + "geo": { + "@type": "GeoShape", + "box": "0.4 45.7, 2.3 46.2" + } + }, + { + "@id": "#bbox1", + "@type": "Place", + "geo": { + "@type": "GeoShape", + "box": "-120.5 -11.6, 48.7 36.8" + } + }, + { + "@id": "https://orcid.org/0000-1234-5678-9101", + "@type": "Person", + "name": "Donald", + "email": "donald@example.com", + "identifier": { + "@type": "PropertyValue", + "propertyID": "orcid", + "value": "https://orcid.org/0000-1234-5678-9101" + } + }, + { + "@id": "https://example.com/TMSP", + "@type": "Organization", + "name": "TMSP", + "email": "pocs@example.com", + "identifier": "https://example.com/TMSP" + }, + { + "@id": "https://example.com/citations/0", + "@type": "CreativeWork", + "creditText": "description", + "url": "https://example.com/citations/0" + }, + { + "@id": "https://example.com/citations/1", + "@type": "CreativeWork", + "url": "https://example.com/citations/1" + }, + { + "@id": "#citation2", + "@type": "CreativeWork" + }, + { + "@id": "#fund0", + "@type": "Organization", + "name": "UKRI" + }, + { + "@id": "#fund1", + "@type": "Organization", + "name": "University of Oxford" + }, + { + "@id": "#part882739943", + "name": "882739943", + "@type": "File", + "encodingFormat": "text/csv", + "lastModified": "2024-12-09T15:34", + "bytes": 12, + "contentUrl": "https://example.com/name1" + }, + { + "@id": "#part882739943", + "name": "882739943", + "@type": "File", + "encodingFormat": "text/csv", + "lastModified": "2020-05-06T23:59", + "bytes": 9832, + "contentUrl": "https://example.com/name2" + }, + { + "@id": "#distribution0", + "@type": "DataDownload", + "contentUrl": "https://example.com/download/0" + }, + { + "@id": "#distribution1", + "@type": "DataDownload", + "contentUrl": "https://example.com/order/1" + } + ] +} diff --git a/java/src/test/resources/templates/rocrate/minimal.json b/java/src/test/resources/templates/rocrate/minimal.json new file mode 100644 index 000000000..db5e0de9c --- /dev/null +++ b/java/src/test/resources/templates/rocrate/minimal.json @@ -0,0 +1,66 @@ +{ + "@context": "https://w3id.org/ro/crate/1.1/context", + "@graph": [ + { + "@type": "CreativeWork", + "@id": "ro-crate-metadata.json", + "conformsTo": { + "@id": "https://w3id.org/ro/crate/1.1" + }, + "about": { + "@id": "https://example.org/id/09837382" + } + }, + { + "@type": "Dataset", + "name": "Title", + "@id": "https://example.org/id/09837382", + "hasPart": [ + { + "@id": "#part09837382" + }, + { + "@id": "#part09837382" + } + ], + "url": "https://example.org/id/09837382", + "provider": { + "@id": "https://ror.org/04xw4m193" + }, + "includedInDataCatalog": { + "@id": "#eidc-dataCatalogue" + } + }, + { + "@id": "#eidc-dataCatalogue", + "@type": "DataCatalog", + "name": "Environmental Information Data Centre", + "alternateName": "EIDC", + "url": "https://catalogue.ceh.ac.uk/eidc/documents" + }, + { + "@id": "https://ror.org/04xw4m193", + "@type": "Organization", + "name": "NERC EDS Environmental Information Data Centre", + "email": "info@eidc.ac.uk" + }, + { + "@id": "#part09837382", + "name": "09837382", + "@type": "File", + "encodingFormat": "text/csv", + "lastModified": "2024-12-09T15:34", + "bytes": 12, + "contentUrl": "https://example.com/name1" + }, + { + "@id": "#part09837382", + "name": "09837382", + "@type": "File", + "encodingFormat": "text/csv", + "lastModified": "2020-05-06T23:59", + "bytes": 9832, + "contentUrl": "https://example.com/name2" + } + ] +} diff --git a/java/src/test/resources/templates/schemaDotOrg/minimal.json b/java/src/test/resources/templates/schemaDotOrg/minimal.json new file mode 100644 index 000000000..cbbf8094a --- /dev/null +++ b/java/src/test/resources/templates/schemaDotOrg/minimal.json @@ -0,0 +1,30 @@ +{ + "@context": "http://schema.org/", + "@graph": [ + { + "@type": "Dataset", + "name": "Title", + "@id": "https://example.org/id/123456789", + "url": "https://example.org/id/123456789", + "provider": { + "@id": "https://ror.org/04xw4m193" + }, + "includedInDataCatalog": { + "@id": "#eidc-dataCatalogue" + } + }, + { + "@id": "#eidc-dataCatalogue", + "@type": "DataCatalog", + "name": "Environmental Information Data Centre", + "alternateName": "EIDC", + "url": "https://catalogue.ceh.ac.uk/eidc/documents" + }, + { + "@id": "https://ror.org/04xw4m193", + "@type": "Organization", + "name": "NERC EDS Environmental Information Data Centre", + "email": "info@eidc.ac.uk" + } + ] +} diff --git a/templates/datacite/datacite.ftlx b/templates/datacite/datacite.ftlx index a06e2071f..ff92c4a9b 100644 --- a/templates/datacite/datacite.ftlx +++ b/templates/datacite/datacite.ftlx @@ -1,4 +1,4 @@ -<#compress><#import "../functions.ftlh" as func> +<#compress> ${doi} diff --git a/templates/html/elter.ftlh b/templates/html/elter.ftlh index 4ea6303b4..441407694 100644 --- a/templates/html/elter.ftlh +++ b/templates/html/elter.ftlh @@ -159,7 +159,7 @@ diff --git a/templates/html/gemini.ftlh b/templates/html/gemini.ftlh index ebda854f6..186f06ec0 100644 --- a/templates/html/gemini.ftlh +++ b/templates/html/gemini.ftlh @@ -222,7 +222,7 @@ diff --git a/templates/html/search/_page.ftlh b/templates/html/search/_page.ftlh index 6ec1b0fa6..347830d9c 100644 --- a/templates/html/search/_page.ftlh +++ b/templates/html/search/_page.ftlh @@ -37,7 +37,7 @@ + <#if (result.resourceStatus??)>result--${result.resourceStatus}" data-location="${(result.locations?join('|'))!}" id="${result.identifier}">
${(codes.lookup("publication.state", result.state)!)!?upper_case!''}
diff --git a/templates/rdf/_macros.ftl b/templates/rdf/_macros.ftl index 666a73fb0..dc05bf06c 100644 --- a/templates/rdf/_macros.ftl +++ b/templates/rdf/_macros.ftl @@ -1,8 +1,4 @@ -<#import "../functions.ftlh" as func> <#setting date_format = 'yyyy-MM-dd'> -<#if useConstraints?has_content> - <#assign licences = func.filter(useConstraints, "code", "license")> - <#macro displayLiteral string> <#--Ensure literals do not contain " characters or line breaks--> diff --git a/templates/rocrate/rocrate.ftl b/templates/rocrate/rocrate.ftl index b420c9aa7..3b96a9746 100644 --- a/templates/rocrate/rocrate.ftl +++ b/templates/rocrate/rocrate.ftl @@ -1,27 +1,11 @@ <#compress> - -<#if type=='dataset' || type=='nonGeographicDataset' || type=='signpost'> - <#assign docType = "Dataset"> -<#elseif type=='aggregate' || type=='series'> - <#assign docType = "Series"> -<#elseif type=='application'> - <#assign docType = "SoftwareSourceCode"> - - -<#if docType?has_content> - { - "@context": "https://w3id.org/ro/crate/1.1/context", - "@graph": [ - { - "@type": "CreativeWork", - "@id": "ro-crate-metadata.json", - "conformsTo": { "@id": "https://w3id.org/ro/crate/1.1" }, - "about": { - "@id": "${uri?trim}" - } - }, - <#include "../schema.org/schema.org.ftlh"> - ] - } - + <#import "../schema.org/macros.ftl" as m> + <#if type=='dataset' || type=='nonGeographicDataset' || type=='signpost'> + <#assign docType = "Dataset"> + <#elseif type=='aggregate' || type=='series'> + <#assign docType = "Series"> + <#elseif type=='application'> + <#assign docType = "SoftwareSourceCode"> + + <@m.rocrate docType fileDetails.getDetailsFor(id, false)/> diff --git a/templates/rocrate/rocrate_attached.ftl b/templates/rocrate/rocrate_attached.ftl index cd3abef46..c18e39491 100644 --- a/templates/rocrate/rocrate_attached.ftl +++ b/templates/rocrate/rocrate_attached.ftl @@ -1,2 +1,11 @@ -<#assign isAttached=true> -<#include "rocrate.ftl"> +<#compress> + <#import "../schema.org/macros.ftl" as m> + <#if type=='dataset' || type=='nonGeographicDataset' || type=='signpost'> + <#assign docType = "Dataset"> + <#elseif type=='aggregate' || type=='series'> + <#assign docType = "Series"> + <#elseif type=='application'> + <#assign docType = "SoftwareSourceCode"> + + <@m.rocrate docType fileDetails.getDetailsFor(id, true)/> + diff --git a/templates/schema.org/macros.ftl b/templates/schema.org/macros.ftl new file mode 100644 index 000000000..0b98cb8a9 --- /dev/null +++ b/templates/schema.org/macros.ftl @@ -0,0 +1,407 @@ +<#-- Top-level entry macros either 'rocrate' or 'schemaDotOrg' --> + +<#macro rocrate docType="" parts=[]> + <#if docType?has_content> + { + "@context": "https://w3id.org/ro/crate/1.1/context", + "@graph": [ + { + "@type": "CreativeWork", + "@id": "ro-crate-metadata.json", + "conformsTo": { "@id": "https://w3id.org/ro/crate/1.1" }, + "about": { "@id": "${uri?trim}" } + }, + <@schemaDocument docType parts/> + ] + } + + + +<#macro schemaDotOrg docType="", parts=[]> + <#if docType?has_content> + { + "@context":"http://schema.org/", + "@graph": [ + <@m.schemaDocument docType parts/> + ] + } + + + +<#macro schemaDocument docType parts> + { + "@type":<@displayLiteral docType/>, + "name":<@displayLiteral title/>, + "@id": "${uri?trim}", + <@partsList parts/> + <@datacite/> + <#if resourceStatus?lower_case != "deleted"> + <#if description?has_content>"description":<@displayLiteral description/>, + <@alternateTitlesList/> + <#if resourceStatus == "Available">"isAccessibleForFree": true, + <@creationDate/> + <@publicationDate/> + <@observedPropertiesList/> + <@keywordsList/> + <#if authors?has_content>"author": [<@contactList authors "author"/>], + <#if pointsOfContact?has_content>"contactPoint": [<@contactList pointsOfContact/>], + <@citationList/> + <@temporalExtentsList/> + <#if boundingBoxes?has_content>"spatialCoverage": [<@itemList boundingBoxes "bbox"/>], + <#if funding?has_content>"funder": [<@itemList funding "fund"/>], + <#if docType == "Dataset" || docType == "SoftwareSourceCode"> + <@licencesLink/> + <#if downloads?has_content>"distribution": [<@itemList downloads "distribution" />], + <@publisherLink/> + + "provider" : {"@id":"https://ror.org/04xw4m193"}, + "includedInDataCatalog":{ "@id": "#eidc-dataCatalogue"} + <#else> + <#-- information to include if the dataset has been permanently deleted --> + "description": "This resource is no longer available please contact the Environmental Information Data Centre for more details", + "creativeWorkStatus": "Deleted" + + }, + { + "@id": "#eidc-dataCatalogue", + "@type":"DataCatalog", + "name":"Environmental Information Data Centre", + "alternateName":"EIDC", + "url":"https://catalogue.ceh.ac.uk/eidc/documents" + }, + { + "@id": "https://ror.org/04xw4m193", + "@type":"Organization", + "name":"NERC EDS Environmental Information Data Centre", + "email": "info@eidc.ac.uk" + } + <@licencesDetail/> + <#if boundingBoxes?has_content>,<@bboxDetails/> + <#if authors?has_content>,<@contactDetails authors "author"/> + <#if pointsOfContact?has_content>,<@contactDetails pointsOfContact/> + <#if incomingCitations?has_content>,<@citationDetails/> + <#if funding?has_content>,<@fundDetails/> + <#if parts?has_content>,<@partDetails parts/> + <#if downloads?has_content>,<@distributionDetails/> + + +<#macro alternateTitlesList> + <#if alternateTitles??> + <#list alternateTitles> + "alternateName":[ + <#items as altTitle> + <@displayLiteral altTitle/><#sep>, + + ], + + + + +<#macro bboxDetails> + <#list boundingBoxes as bbox> + { + "@id": "#bbox${bbox?index}", + "@type":"Place", + "geo":{ + "@type":"GeoShape", + "box":"${bbox.westBoundLongitude} ${bbox.southBoundLatitude}, ${bbox.eastBoundLongitude} ${bbox.northBoundLatitude}" + } + }<#sep>, + + + +<#macro creationDate> + <#if datasetReferenceDate?? && datasetReferenceDate.creationDate?has_content> + "dateCreated":"${datasetReferenceDate.creationDate}", + + + +<#macro publicationDate> + <#if datasetReferenceDate?? && datasetReferenceDate.publicationDate?has_content> + "datePublished":"${datasetReferenceDate.publicationDate}", + + + +<#macro datacite> + <#if datacitable && citation?has_content> + "identifier": { + "@type":"PropertyValue", + "propertyID": "https://registry.identifiers.org/registry/doi", + "value": "doi:${citation.doi}", + "url": "${citation.url}" + }, + "url": "${citation.url}", + "creditText":"${citation.authors?join(', ')} (${citation.year?string["0000"]}). ${citation.title}. ${citation.publisher}. (${codes.lookup('datacite.resourceTypeGeneral',citation.resourceTypeGeneral)}). ${citation.url}", + <#else> + "url":"${uri?trim}", + + + +<#macro keywordsList> + <#if allKeywords??> + <#list allKeywords?sort_by("value")?sort_by("uri")> + "keywords": [ + <#items as keyword> + <#if keyword.uri?has_content> + <#assign subjectScheme="" schemeURI=""> + <#if keyword.uri?matches("^http[s]?://inspire.ec.europa.eu/\\S+$")> + <#assign subjectScheme="European Union INSPIRE registry" schemeURI="http://inspire.ec.europa.eu/registry/"> + <#elseif keyword.uri?matches("^http[s]?://www.wikidata.org/entity/\\S+$")> + <#assign subjectScheme="Wikidata" schemeURI="https://www.wikidata.org/"> + <#elseif keyword.uri?matches("^http[s]?://sws.geonames.org/\\S+$")> + <#assign subjectScheme="Geonames" schemeURI="https://www.geonames.org/"> + <#elseif keyword.uri?matches("^http[s]?://www.eionet.europa.eu/gemet/concept/\\S+$")> + <#assign subjectScheme="GEMET concepts" schemeURI="https://www.eionet.europa.eu/gemet/"> + + <#t>{ + <#t>"@type": "DefinedTerm", + <#t>"@id": "${keyword.uri?trim}", + <#t>"name": <@displayLiteral keyword.value/> + <#t><#if subjectScheme?has_content>,"inDefinedTermSet": "${schemeURI}" + } + <#else> + "${keyword.value?trim}" + + <#sep>, + ], + + + + +<#macro licencesLink> + <#if licences?? && licences?has_content> + <#if licences?first.uri?? && licences?first.uri?has_content> + <#if licences?first.uri?matches("^http[s]?://eidc.ceh.ac.uk/licences/OGL/plain")> + "license": {"@id": "#oglLicence"}, + <#else> + "license": "${licences?first.uri?trim}", + + + + + +<#macro licencesDetail> + <#if licences?? && licences?has_content> + <#if licences?first.uri?? && licences?first.uri?has_content> + <#if licences?first.uri?matches("^http[s]?://eidc.ceh.ac.uk/licences/OGL.+$")> + ,{ + "@id": "#oglLicence", + "@type": "CreativeWork", + "name": "Open Government Licence v3", + "alternateName":"OGL-UK-3.0", + "license": "https://spdx.org/licenses/OGL-UK-3.0.html" + } + + + + + +<#macro observedPropertiesList> +<#if observedProperty?? && observedProperty?has_content> +"variableMeasured": [ + <#list observedProperty as op> + <#assign opLabel ="unknown"> + <#if op.title?has_content> + <#assign opLabel = op.title?trim> + <#elseif op.value?has_content> + <#assign opLabel = op.value?trim> + + + <#if op.uri?has_content> + { + "@type": "StatisticalVariable", + "@id": "${op.uri?trim}", + "name": "${opLabel}" + <#if op.unitsUri?has_content>,"unitCode": "${op.unitsUri?trim}" + <#if op.units?has_content>,"unitText": "${op.units?trim}" + } + <#else> + <@displayLiteral opLabel/> + + <#sep>, + + ], + + + +<#macro partsList parts> + <#if parts?size lt 60000> + <#list parts> + "hasPart": [ + <#items as part> + <#if part.id?has_content>{"@id": "#part${part.id}"}<#sep>, + + ], + + <#else> + {"@id": "${id}-files"}, + + + +<#macro partDetails parts> + <#if parts?size lt 60000> + <#list parts as part> + <#if part.id?has_content> + { + <#t>"@id": "#part${part.id}", + <#t>"name": "${part.id}" + <#if part.type?? && part.type?has_content><#t>,"@type": "${part.type}" + <#if part.encodingFormat?? && part.encodingFormat?has_content>,<#t>"encodingFormat": "${part.encodingFormat}" + <#if part.lastModified?? && part.lastModified?has_content>,<#t>"lastModified": "${part.lastModified}" + <#if part.bytes?? && part.bytes?has_content>,<#t>"bytes": ${part.bytes?long?c} + <#if part.contentUrl?? && part.contentUrl?has_content>,<#t>"contentUrl": "${part.contentUrl}" + } + + <#sep>,<#t> + + <#else> + { + "@id": "${id}-files", + "@type": "Dataset", + "name": "Files", + "description": "This dataset contains ${parts?size} files" + } + + + +<#macro publisherLink> + <#if publishers?has_content> + <#assign publisher = publishers?first> + <#if publisher.organisationIdentifier?has_content> + "publisher":{"@id":"${publisher.organisationIdentifier}"}, + + + + +<#macro itemList list idlabel="item"> + <#list list as item> + {"@id": "#${idlabel}${item?index}"}<#sep>, + + + +<#macro contactList contacts idlabel="contact"> + <#list contacts as contact> + <#assign contactid = "#" + idlabel + contact?index> + <#if contact.individualName?has_content> + <#if contact.nameIdentifier?has_content && contact.nameIdentifier?matches("^http(|s)://orcid.org/\\d{4}-\\d{4}-\\d{4}-\\d{3}(X|\\d)$")> + <#assign contactid = contact.nameIdentifier> + + <#elseif contact.organisationName?has_content> + <#if contact.organisationIdentifier?has_content> + <#assign contactid = contact.organisationIdentifier > + + + {"@id": "${contactid}"}<#sep>, + + + +<#macro contactDetails contacts idlabel="contact"> + <#list contacts as contact> + <#assign contactid = "#" + idlabel + contact?index> + <#if contact.individualName?has_content> + <#if contact.nameIdentifier?has_content && contact.nameIdentifier?matches("^http(|s)://orcid.org/\\d{4}-\\d{4}-\\d{4}-\\d{3}(X|\\d)$")> + <#assign contactid = contact.nameIdentifier> + + <#elseif contact.organisationName?has_content> + <#if contact.organisationIdentifier?has_content> + <#assign contactid = contact.organisationIdentifier> + + + { + "@id": "${contactid}", + <#if contact.individualName?has_content> + "@type": "Person", + "name": "${contact.individualName}" + <#if contact.email?has_content>,"email": "${contact.email}" + <#if contact.nameIdentifier?has_content && contact.nameIdentifier?matches("^http(|s)://orcid.org/\\d{4}-\\d{4}-\\d{4}-\\d{3}(X|\\d)$")> + ,"identifier": { + "@type":"PropertyValue", + "propertyID": "orcid", + "value": "${contact.nameIdentifier}" + } + + <#if contact.organisationName?has_content> + ,"affiliation":{ + "@type":"Organization", + "name":"${contact.organisationName}" + <#if contact.organisationIdentifier?has_content> + ,"identifier":"${contact.organisationIdentifier}" + + } + + <#else> + "@type":"Organization" + <#if contact.organisationName?has_content>,"name": "${contact.organisationName}" + <#if contact.email?has_content>,"email": "${contact.email}" + <#if contact.organisationIdentifier?has_content>,"identifier":"${contact.organisationIdentifier}" + + }<#sep>, + + + +<#macro citationList> + <#if incomingCitations?has_content> + "@reverse": { + "citation":[ + <#list incomingCitations as citation> + <#assign citationid = "#citation" + citation?index> + <#if citation.url?has_content><#assign citationid = citation.url> + {"@id": "${citationid}"}<#sep>, + + ] + }, + + + +<#macro citationDetails> + <#list incomingCitations as citation> + <#assign citationid = "#citation" + citation?index> + <#if citation.url?has_content><#assign citationid = citation.url> + { + "@id": "${citationid}", + "@type": "CreativeWork" + <#if citation.description?has_content>,"creditText": <@displayLiteral citation.description/> + <#if citation.url?has_content>,"url": "${citation.url?trim}" + }<#sep>, + + + +<#macro distributionDetails> + <#list downloads as distribution> + { + "@id": "#distribution${distribution?index}", + "@type":"DataDownload", + "contentUrl":"${distribution.url}" + <#if distribution.url?ends_with(".zip")>,"encodingFormat":"application/zip" + <#elseif distribution.url?ends_with(".csv")>,"encodingFormat":"text/csv" + <#elseif distribution.url?starts_with("https://data-package.ceh.ac.uk/data/")>,"encodingFormat":"application/zip" + <#elseif distribution.url?starts_with("https://catalogue.ceh.ac.uk/datastore")>,"encodingFormat":"text/directory" + + }<#sep>, + + + +<#macro fundDetails> + <#list funding as fund> + { + "@id": "#fund${fund?index}", + "@type":"Organization" + <#if fund.funderName?? && fund.funderName?has_content>,<#t>"name":"${fund.funderName}" + }<#sep>, + + + +<#macro displayLiteral string> + <#--Ensure literals do not contain " characters or line breaks--> + <#t>"${string?trim?replace("\"","'")?replace("\n"," ")}" + + +<#macro temporalExtentsList> + <#if temporalExtents?has_content> + "temporalCoverage":[ + <#list temporalExtents as temporal> + "${temporal.begin!""}/${temporal.end!""}"<#sep>, + + ], + + diff --git a/templates/schema.org/schema.org.ftl b/templates/schema.org/schema.org.ftl new file mode 100644 index 000000000..744e04285 --- /dev/null +++ b/templates/schema.org/schema.org.ftl @@ -0,0 +1,11 @@ +<#compress> + <#import "macros.ftl" as m> + <#if type=='dataset' || type=='nonGeographicDataset' || type=='signpost'> + <#assign docType = "Dataset"> + <#elseif type=='aggregate' || type=='series'> + <#assign docType = "Series"> + <#elseif type=='application'> + <#assign docType = "SoftwareSourceCode"> + + <@m.schemaDotOrg docType/> + diff --git a/templates/schema.org/schema.org.ftlh b/templates/schema.org/schema.org.ftlh deleted file mode 100644 index b40948075..000000000 --- a/templates/schema.org/schema.org.ftlh +++ /dev/null @@ -1,348 +0,0 @@ -<#import "../functions.ftlh" as func> -<#compress> - -<#if useConstraints?has_content> - <#assign licences = func.filter(useConstraints, "code", "license")> - -<#if responsibleParties?has_content> - <#assign authors = func.filter(responsibleParties, "role", "author") - publishers = func.filter(responsibleParties, "role", "publisher") > - -<#if onlineResources?has_content> - <#assign - infoLinks = func.filter(onlineResources, "function", "information") - > - - -<#-- COMPILE KEYWORD LIST---> - <#assign keywordList = [] > - - <#if descriptiveKeywords?has_content> - <#list descriptiveKeywords as descriptiveKeyword> - <#list descriptiveKeyword.keywords as keyword> - <#assign keywordList = keywordList + [keyword] > - - - - - <#if allKeywords?has_content> - <#list allKeywords as keyword> - <#assign keywordList = keywordList + [keyword]> - - - - <#--DE-DUPLICATE KEYWORD LIST --> - <#assign deDup = [] /> - <#list keywordList as originalList> - <#if ! deDup?seq_contains(originalList)> - <#assign deDup = deDup + [originalList] /> - - - <#assign keywordList = deDup?sort_by("value")?sort_by("uri") /> -<#-- END KEYWORD LIST---> - -<#if type=='dataset' || type=='nonGeographicDataset' || type=='signpost'> - <#assign docType = "Dataset"> -<#elseif type=='aggregate' || type=='series'> - <#assign docType = "Series"> -<#elseif type=='application'> - <#assign docType = "SoftwareSourceCode"> - - -<#if docType?has_content> - { - "@type":<@displayLiteral docType/>, - "name":<@displayLiteral title/>, - - <#if docType == "Dataset"> - <#if isAttached!false> - <@displayParts fileDetails.getDetailsFor(id, true)/> - <#else> - <@displayParts fileDetails.getDetailsFor(id, false)/> - - - - <#if datacitable?string == "true" && citation?has_content> - "@id": "${citation.url}", - "identifier": { - "@type":"PropertyValue", - "propertyID": "doi", - "value": "${citation.url}" - }, - "url": "${citation.url}", - "creditText":"${citation.authors?join(', ')} (${citation.year?string["0000"]}). ${citation.title}. ${citation.publisher}. (${codes.lookup('datacite.resourceTypeGeneral',citation.resourceTypeGeneral)}). ${citation.url}", - <#else> - "@id": "${uri?trim}", - "url":"${uri?trim}", - - - <#if resourceStatus != "Deleted"> - <#if description?has_content>"description":<@displayLiteral description/>, - - <#if alternateTitles?has_content> - "alternateName":[ - <#list alternateTitles as altTitle> - <@displayLiteral altTitle/><#sep>, - - ], - - - <#if resourceStatus == "Available"> - "isAccessibleForFree": true, - - - <#if datasetReferenceDate?? && datasetReferenceDate.creationDate?has_content> - "dateCreated":"${datasetReferenceDate.creationDate}", - - - <#if datasetReferenceDate?? && datasetReferenceDate.publicationDate?has_content> - "datePublished":"${datasetReferenceDate.publicationDate}", - - - <#if observedProperty?? && observedProperty?has_content> - "variableMeasured": [ <@displayObservedProperties observedProperty/>], - - - <#if keywordList?has_content> - "keywords": [<@displayKeywords keywordList/>], - - - <#--Authors--> - <#if authors?has_content> - "creator":[ - <#list authors as author> - <#if author.individualName?has_content> - { - "@type":"Person", - "name": "${author.individualName}" - <#if author.organisationName?has_content> - ,"email": "${author.email}" - - <#if author.nameIdentifier?has_content && author.nameIdentifier?matches("^http(|s)://orcid.org/\\d{4}-\\d{4}-\\d{4}-\\d{3}(X|\\d)$")> - ,"identifier": { - "@type":"PropertyValue", - "propertyID": "orcid", - "value": "${author.nameIdentifier}" - } - - <#if author.organisationName?has_content> - ,"affiliation":{ - "@type":"Organization", - "name":"${author.organisationName}" - <#if author.organisationIdentifier?has_content> - ,"identifier":"${author.organisationIdentifier}" - - } - - } - <#else> - { - "@type":"Organization", - "name": "${author.organisationName}" - <#if author.organisationName?has_content> - ,"email": "${author.email}" - - <#if author.organisationIdentifier?has_content> - ,"identifier":"${author.organisationIdentifier}" - - } - - <#sep>, - - ] - , - - - <#--Citations--> - <#if incomingCitations?has_content> - "@reverse": { - "citation":[ - <#list incomingCitations as citation> - { - "@type": "CreativeWork" - <#if citation.description?has_content>,"creditText": <@displayLiteral citation.description/> - <#if citation.url?has_content>,"url": "${citation.url?trim}" - }<#sep>, - - ] - }, - - - <#if temporalExtents?has_content> - "temporalCoverage":[ - <#list temporalExtents as temporal> - <#if temporal.begin?has_content> - <#assign begin = temporal.begin> - <#else> - <#assign begin = ""> - - <#if temporal.end?has_content> - <#assign end = temporal.end> - <#else> - <#assign end = ""> - - "${begin}/${end}"<#sep>, - - ], - - - <#if boundingBoxes?has_content> - "spatialCoverage": [ - <#list boundingBoxes as extent> - { - "@type":"Place", - "geo":{ - "@type":"GeoShape", - "box":"${extent.westBoundLongitude} ${extent.southBoundLatitude}, ${extent.eastBoundLongitude} ${extent.northBoundLatitude}" - } - }<#sep>, - - ], - - - <#if docType == "Dataset" || docType == "SoftwareSourceCode"> - - <#if licences?? && licences?has_content> - <#if licences?first.uri?? && licences?first.uri?has_content> - <#if licences?first.uri?matches("^http[s]?://eidc.ceh.ac.uk/licences/OGL.+$")> - "license": { - "@type": "CreativeWork", - "name": "Open Government Licence v3", - "alternateName":"OGL-UK-3.0", - "license": "https://spdx.org/licenses/OGL-UK-3.0.html" - }, - <#else> - "license": "${licences?first.uri?trim}", - - - - - <#--Distributions--> - <#list downloads> - "distribution":[ - <#items as download> - { - "@type":"DataDownload", - "contentUrl":"${download.url}" - <#if download.url?ends_with(".zip")>,"encodingFormat":"application/zip" - <#elseif download.url?ends_with(".csv")>,"encodingFormat":"text/csv" - <#elseif download.url?starts_with("https://data-package.ceh.ac.uk/data/")>,"encodingFormat":"application/zip" - <#elseif download.url?starts_with("https://catalogue.ceh.ac.uk/datastore")>,"encodingFormat":"text/directory" - }<#sep>, - - ], - - - <#if publishers?has_content> - <#assign publisher = publishers?first> - "publisher": - { - "@type":"Organization","name":"${publisher.organisationName}" - <#if publisher.organisationIdentifier?has_content> - ,"identifier":"${publisher.organisationIdentifier}" - - <#if publisher.organisationName?has_content> - ,"email": "${publisher.email}" - - }, - - - - "provider" : {"@type":"Organization","name":"Environmental Information Data Centre"}, - "includedInDataCatalog":{"@type":"DataCatalog", "name":"Environmental Information Data Centre", "alternatename":"EIDC", "url":"https://catalogue.ceh.ac.uk/eidc/documents"}, - - <#else> - <#-- information to include if the dataset has been permanently deleted --> - "description": "This resource is no longer available please contact the Environmental Information Data Centre for more details", - "creativeWorkStatus": "Deleted", - - - "@context":"http://schema.org/" - } - - - -<#macro displayKeywords keywords> - <#list keywords as keyword> - <#if keyword.uri?has_content> - <#assign subjectScheme="" schemeURI=""> - <#if keyword.uri?matches("^http[s]?://inspire.ec.europa.eu/\\S+$")> - <#assign subjectScheme="European Union INSPIRE registry" schemeURI="http://inspire.ec.europa.eu/registry/"> - <#elseif keyword.uri?matches("^http[s]?://www.wikidata.org/entity/\\S+$")> - <#assign subjectScheme="Wikidata" schemeURI="https://www.wikidata.org/"> - <#elseif keyword.uri?matches("^http[s]?://sws.geonames.org/\\S+$")> - <#assign subjectScheme="Geonames" schemeURI="https://www.geonames.org/"> - <#elseif keyword.uri?matches("^http[s]?://www.eionet.europa.eu/gemet/concept/\\S+$")> - <#assign subjectScheme="GEMET concepts" schemeURI="https://www.eionet.europa.eu/gemet/"> - - <#t>{ - <#t>"@type": "DefinedTerm", - <#t>"@id": "${keyword.uri?trim}", - <#t>"name": <@displayLiteral keyword.value/> - <#t><#if subjectScheme?has_content>,"inDefinedTermSet": "${schemeURI}" - } - <#else> - "${keyword.value?trim}" - - <#sep>,<#t> - - - -<#macro displayObservedProperties props> - <#list props as op> - <#assign opLabel ="unknown"> - <#if op.title?has_content> - <#assign opLabel = op.title?trim> - <#elseif op.value?has_content> - <#assign opLabel = op.value?trim> - - - <#if op.uri?has_content> - { - "@type": "StatisticalVariable", - "@id": "${op.uri?trim}", - "name": "${opLabel}" - <#if op.unitsUri?has_content>,"unitCode": "${op.unitsUri?trim}" - <#if op.units?has_content>,"unitText": "${op.units?trim}" - } - <#else> - <@displayLiteral opLabel/> - - <#sep>, - - - -<#macro displayParts parts> - <#if parts?size gt 0> - "hasPart": [ - <#if parts?size lt 60000> - <#list parts as part> - <#if part.id?has_content> - { - <#t>"@id": "${part.id}", - <#t>"@type": "${part.type}", - <#t>"name": "${part.id}", - <#if part.encodingFormat?? && part.encodingFormat?has_content><#t>"encodingFormat": "${part.encodingFormat}", - <#t>"lastModified": "${part.lastModified}", - <#t>"bytes": ${part.bytes?long?c}, - <#t>"contentUrl": "${part.contentUrl}" - } - - <#sep>,<#t> - - <#else> - { - "@id": "${id}-files", - "@type": "Dataset", - "name": "Files", - "description": "This dataset contains ${parts?size} files" - } - - ], - - - -<#macro displayLiteral string> - <#--Ensure literals do not contain " characters or line breaks--> - <#t>"${string?trim?replace("\"","'")?replace("\n"," ")}" - diff --git a/web/scss/search.scss b/web/scss/search.scss index dae98fd6b..588d2becb 100644 --- a/web/scss/search.scss +++ b/web/scss/search.scss @@ -164,7 +164,7 @@ main { .leaflet-control-layers-list { overflow: hidden; - padding:0.5em; + padding: 0.5em; font-size: 1em; } @@ -225,6 +225,16 @@ main { font-size: 0.9rem; padding-block-start: 3px; } + + .opstatus { + display: none; + } + } + + &.opstatus-Inactive { + .opstatus { + display: inline-block; + } } &__title {