Skip to content
Snippets Groups Projects
Commit 5694b42b authored by Martin Weise's avatar Martin Weise
Browse files

Resolve "Provide schema.org metadata for google SEO"

parent e2eb7dc6
Branches
Tags
4 merge requests!231CI: Remove build for log-service,!228Better error message handling in the frontend,!225Resolve "Provide schema.org metadata for google SEO",!223Release of version 1.4.0
......@@ -33,7 +33,7 @@ public class MariaDbContainerConfig {
public static synchronized CustomMariaDBContainer getInstance() {
if (instance == null) {
instance = new CustomMariaDBContainer("mariadb:11.2.2-debian-11-r0");
instance = new CustomMariaDBContainer("mariadb:11.2.2");
instance.withImagePullPolicy(PullPolicy.alwaysPull());
instance.addFixedExposedPort(BaseTest.CONTAINER_1_PORT, BaseTest.IMAGE_1_PORT);
instance.withUsername(BaseTest.CONTAINER_1_PRIVILEGED_USERNAME);
......
......@@ -34,7 +34,7 @@ public class MariaDbContainerConfig {
public static synchronized CustomMariaDBContainer getInstance() {
if (instance == null) {
instance = new CustomMariaDBContainer("mariadb:11.2.2-debian-11-r0");
instance = new CustomMariaDBContainer("mariadb:11.2.2");
instance.withImagePullPolicy(PullPolicy.alwaysPull());
instance.addFixedExposedPort(BaseTest.CONTAINER_1_PORT, BaseTest.IMAGE_1_PORT);
instance.withUsername(BaseTest.CONTAINER_1_PRIVILEGED_USERNAME);
......
import UserMapper from '@/api/user.mapper'
const baseUrl = `${location.protocol}//${location.host}`
class DatabaseMapper {
databaseToOwner (database) {
......@@ -14,6 +15,31 @@ class DatabaseMapper {
}
return UserMapper.userToFullName(database.contact)
}
databaseToJsonLd (database) {
const jsonLd = {
'@context': 'https://schema.org/',
'@type': 'Dataset',
name: database.name,
description: 'Relational database hosted by the database repository.',
url: `${baseUrl}/database/${database.id}/info`,
isAccessibleForFree: database.is_public,
creator: {
'@type': 'Person'
}
}
jsonLd.creator.name = database.owner.name ? database.owner.name : database.owner.username
if (database.owner.given_name) {
jsonLd.creator.givenName = database.owner.given_name
}
if (database.owner.family_name) {
jsonLd.creator.familyName = database.owner.family_name
}
if (database.owner.attributes.orcid) {
jsonLd.creator.sameAs = database.owner.attributes.orcid
}
return jsonLd
}
}
export default new DatabaseMapper()
import store from '@/store'
const baseUrl = `${location.protocol}//${location.host}`
class IdentifierMapper {
identifierToCreators (identifier) {
......@@ -102,6 +103,13 @@ class IdentifierMapper {
return null
}
identifierToPreferFirstLicenseUri (identifier) {
if (!identifier || !identifier.licenses || identifier.licenses.length === 0) {
return null
}
return identifier.licenses[0].uri
}
identifierPreferEnglishDescription (identifier) {
if (!identifier || !identifier.descriptions || identifier.descriptions.length === 0) {
return null
......@@ -148,7 +156,7 @@ class IdentifierMapper {
}
return `${store().state.doiUrl}/${identifier.doi}`
}
return `/pid/${identifier.id}`
return `${baseUrl}/pid/${identifier.id}`
}
identifierToDisplayName (identifier) {
......@@ -161,7 +169,7 @@ class IdentifierMapper {
}
return identifier.doi
}
return `/pid/${identifier.id}`
return `${baseUrl}/pid/${identifier.id}`
}
identifierToDisplayAcronym (identifier) {
......@@ -170,6 +178,71 @@ class IdentifierMapper {
}
return identifier.doi !== null ? 'DOI' : 'URI'
}
creatorToCreatorJsonLd (creator) {
const jsonLd = {
name: creator.creator_name
}
if (creator.name_type === 'Personal') {
jsonLd['@type'] = 'Person'
if (creator.name_identifier) {
jsonLd.sameAs = creator.name_identifier
}
if (creator.firstname) {
jsonLd.givenName = creator.firstname
}
if (creator.lastname) {
jsonLd.familyName = creator.lastname
}
} else {
jsonLd['@type'] = 'Organization'
if (creator.affiliation_identifier) {
jsonLd.sameAs = creator.affiliation_identifier
}
}
return jsonLd
}
identifierToHasPartJsonLd (identifier) {
return {
'@type': 'Dataset',
name: this.identifierPreferEnglishTitle(identifier),
description: this.identifierPreferEnglishDescription(identifier),
identifier: this.identifierToUrl(identifier),
citation: this.identifierToUrl(identifier),
temporalCoverage: identifier.publication_year,
version: identifier.created
}
}
identifiersToJsonLd (database) {
const identifier = database.identifiers[0]
const partIdentifiers = []
if (database.subsets.length > 0) {
database.subsets.forEach((s) => { if (s.identifiers.length > 0) { s.identifiers.forEach(i => partIdentifiers.push(i)) } })
}
if (database.tables.length > 0) {
database.tables.forEach((t) => { if (t.identifiers.length > 0) { t.identifiers.forEach(i => partIdentifiers.push(i)) } })
}
if (database.views.length > 0) {
database.views.forEach((v) => { if (v.identifiers.length > 0) { v.identifiers.forEach(i => partIdentifiers.push(i)) } })
}
return {
'@context': 'https://schema.org/',
'@type': 'Dataset',
name: this.identifierPreferEnglishTitle(identifier),
description: this.identifierPreferEnglishDescription(identifier),
url: `${baseUrl}/database/${identifier.database_id}/info`,
identifier: database.identifiers.map(i => this.identifierToUrl(i)),
license: this.identifierToPreferFirstLicenseUri(identifier),
isAccessibleForFree: database.is_public,
creator: identifier.creators.map(c => this.creatorToCreatorJsonLd(c)),
citation: this.identifierToUrl(identifier),
hasPart: partIdentifiers.map(i => this.identifierToHasPartJsonLd(i)),
temporalCoverage: identifier.publication_year,
version: identifier.created
}
}
}
export default new IdentifierMapper()
......@@ -125,6 +125,7 @@
<nuxt />
</v-container>
</v-main>
<script v-if="hasDataset" type="application/ld+json" v-text="datasetJsonLd" />
</v-app>
</template>
......@@ -133,6 +134,8 @@ import DatabaseService from '@/api/database.service'
import TableService from '@/api/table.service'
import AuthenticationService from '@/api/authentication.service'
import AuthenticationMapper from '@/api/authentication.mapper'
import DatabaseMapper from '@/api/database.mapper'
import IdentifierMapper from '@/api/identifier.mapper'
export default {
data () {
......@@ -182,6 +185,18 @@ export default {
},
logo () {
return this.$config.logo
},
hasDataset () {
return this.$route.path.startsWith('/database')
},
datasetJsonLd () {
if (!this.hasDataset || !this.database) {
return {}
}
if (!('identifiers' in this.database) || this.database.identifiers.length === 0) {
return DatabaseMapper.databaseToJsonLd(this.database)
}
return IdentifierMapper.identifiersToJsonLd(this.database)
}
},
watch: {
......
......@@ -25,9 +25,14 @@
</v-list-item-title>
<v-list-item-content v-if="!loading" v-text="internal_name" />
<v-list-item-title class="mt-2">
Database Creator
Database Owner
</v-list-item-title>
<v-list-item-content v-if="!loading" v-text="creator" />
<v-list-item-content v-if="!loading">
<p class="mb-0">
<OrcidIcon v-if="database.owner.attributes.orcid" :orcid="database.owner.attributes.orcid" />
<span v-text="owner" />
</p>
</v-list-item-content>
<v-list-item-title class="mt-2">
Database Creation
</v-list-item-title>
......@@ -53,7 +58,10 @@
Database Contact
</v-list-item-title>
<v-list-item-content v-if="contact">
<span v-if="!loading" v-text="contact" />
<p class="mb-0">
<OrcidIcon v-if="database.contact.attributes.orcid" :orcid="database.contact.attributes.orcid" />
<span v-text="contact" />
</p>
</v-list-item-content>
</v-list-item-content>
</v-list-item>
......@@ -100,9 +108,11 @@ import { formatTimestampUTCLabel } from '@/utils'
import DatabaseMapper from '@/api/database.mapper'
import Summary from '@/components/identifier/Summary'
import Select from '@/components/identifier/Select'
import OrcidIcon from '@/components/icons/OrcidIcon.vue'
export default {
components: {
OrcidIcon,
DatabaseToolbar,
Summary,
Select
......@@ -190,12 +200,9 @@ export default {
contact () {
return DatabaseMapper.databaseToContact(this.database)
},
creator () {
owner () {
return DatabaseMapper.databaseToOwner(this.database)
},
creatorVerified () {
return this.database.creator.email_verified
},
hasIdentifier () {
return this.identifiers.length > 0
},
......
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Please register or to comment