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 { ...@@ -33,7 +33,7 @@ public class MariaDbContainerConfig {
public static synchronized CustomMariaDBContainer getInstance() { public static synchronized CustomMariaDBContainer getInstance() {
if (instance == null) { 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.withImagePullPolicy(PullPolicy.alwaysPull());
instance.addFixedExposedPort(BaseTest.CONTAINER_1_PORT, BaseTest.IMAGE_1_PORT); instance.addFixedExposedPort(BaseTest.CONTAINER_1_PORT, BaseTest.IMAGE_1_PORT);
instance.withUsername(BaseTest.CONTAINER_1_PRIVILEGED_USERNAME); instance.withUsername(BaseTest.CONTAINER_1_PRIVILEGED_USERNAME);
......
...@@ -34,7 +34,7 @@ public class MariaDbContainerConfig { ...@@ -34,7 +34,7 @@ public class MariaDbContainerConfig {
public static synchronized CustomMariaDBContainer getInstance() { public static synchronized CustomMariaDBContainer getInstance() {
if (instance == null) { 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.withImagePullPolicy(PullPolicy.alwaysPull());
instance.addFixedExposedPort(BaseTest.CONTAINER_1_PORT, BaseTest.IMAGE_1_PORT); instance.addFixedExposedPort(BaseTest.CONTAINER_1_PORT, BaseTest.IMAGE_1_PORT);
instance.withUsername(BaseTest.CONTAINER_1_PRIVILEGED_USERNAME); instance.withUsername(BaseTest.CONTAINER_1_PRIVILEGED_USERNAME);
......
import UserMapper from '@/api/user.mapper' import UserMapper from '@/api/user.mapper'
const baseUrl = `${location.protocol}//${location.host}`
class DatabaseMapper { class DatabaseMapper {
databaseToOwner (database) { databaseToOwner (database) {
...@@ -14,6 +15,31 @@ class DatabaseMapper { ...@@ -14,6 +15,31 @@ class DatabaseMapper {
} }
return UserMapper.userToFullName(database.contact) 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() export default new DatabaseMapper()
import store from '@/store' import store from '@/store'
const baseUrl = `${location.protocol}//${location.host}`
class IdentifierMapper { class IdentifierMapper {
identifierToCreators (identifier) { identifierToCreators (identifier) {
...@@ -102,6 +103,13 @@ class IdentifierMapper { ...@@ -102,6 +103,13 @@ class IdentifierMapper {
return null return null
} }
identifierToPreferFirstLicenseUri (identifier) {
if (!identifier || !identifier.licenses || identifier.licenses.length === 0) {
return null
}
return identifier.licenses[0].uri
}
identifierPreferEnglishDescription (identifier) { identifierPreferEnglishDescription (identifier) {
if (!identifier || !identifier.descriptions || identifier.descriptions.length === 0) { if (!identifier || !identifier.descriptions || identifier.descriptions.length === 0) {
return null return null
...@@ -148,7 +156,7 @@ class IdentifierMapper { ...@@ -148,7 +156,7 @@ class IdentifierMapper {
} }
return `${store().state.doiUrl}/${identifier.doi}` return `${store().state.doiUrl}/${identifier.doi}`
} }
return `/pid/${identifier.id}` return `${baseUrl}/pid/${identifier.id}`
} }
identifierToDisplayName (identifier) { identifierToDisplayName (identifier) {
...@@ -161,7 +169,7 @@ class IdentifierMapper { ...@@ -161,7 +169,7 @@ class IdentifierMapper {
} }
return identifier.doi return identifier.doi
} }
return `/pid/${identifier.id}` return `${baseUrl}/pid/${identifier.id}`
} }
identifierToDisplayAcronym (identifier) { identifierToDisplayAcronym (identifier) {
...@@ -170,6 +178,71 @@ class IdentifierMapper { ...@@ -170,6 +178,71 @@ class IdentifierMapper {
} }
return identifier.doi !== null ? 'DOI' : 'URI' 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() export default new IdentifierMapper()
...@@ -125,6 +125,7 @@ ...@@ -125,6 +125,7 @@
<nuxt /> <nuxt />
</v-container> </v-container>
</v-main> </v-main>
<script v-if="hasDataset" type="application/ld+json" v-text="datasetJsonLd" />
</v-app> </v-app>
</template> </template>
...@@ -133,6 +134,8 @@ import DatabaseService from '@/api/database.service' ...@@ -133,6 +134,8 @@ import DatabaseService from '@/api/database.service'
import TableService from '@/api/table.service' import TableService from '@/api/table.service'
import AuthenticationService from '@/api/authentication.service' import AuthenticationService from '@/api/authentication.service'
import AuthenticationMapper from '@/api/authentication.mapper' import AuthenticationMapper from '@/api/authentication.mapper'
import DatabaseMapper from '@/api/database.mapper'
import IdentifierMapper from '@/api/identifier.mapper'
export default { export default {
data () { data () {
...@@ -182,6 +185,18 @@ export default { ...@@ -182,6 +185,18 @@ export default {
}, },
logo () { logo () {
return this.$config.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: { watch: {
......
...@@ -25,9 +25,14 @@ ...@@ -25,9 +25,14 @@
</v-list-item-title> </v-list-item-title>
<v-list-item-content v-if="!loading" v-text="internal_name" /> <v-list-item-content v-if="!loading" v-text="internal_name" />
<v-list-item-title class="mt-2"> <v-list-item-title class="mt-2">
Database Creator Database Owner
</v-list-item-title> </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"> <v-list-item-title class="mt-2">
Database Creation Database Creation
</v-list-item-title> </v-list-item-title>
...@@ -53,7 +58,10 @@ ...@@ -53,7 +58,10 @@
Database Contact Database Contact
</v-list-item-title> </v-list-item-title>
<v-list-item-content v-if="contact"> <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-content> </v-list-item-content>
</v-list-item> </v-list-item>
...@@ -100,9 +108,11 @@ import { formatTimestampUTCLabel } from '@/utils' ...@@ -100,9 +108,11 @@ import { formatTimestampUTCLabel } from '@/utils'
import DatabaseMapper from '@/api/database.mapper' import DatabaseMapper from '@/api/database.mapper'
import Summary from '@/components/identifier/Summary' import Summary from '@/components/identifier/Summary'
import Select from '@/components/identifier/Select' import Select from '@/components/identifier/Select'
import OrcidIcon from '@/components/icons/OrcidIcon.vue'
export default { export default {
components: { components: {
OrcidIcon,
DatabaseToolbar, DatabaseToolbar,
Summary, Summary,
Select Select
...@@ -190,12 +200,9 @@ export default { ...@@ -190,12 +200,9 @@ export default {
contact () { contact () {
return DatabaseMapper.databaseToContact(this.database) return DatabaseMapper.databaseToContact(this.database)
}, },
creator () { owner () {
return DatabaseMapper.databaseToOwner(this.database) return DatabaseMapper.databaseToOwner(this.database)
}, },
creatorVerified () {
return this.database.creator.email_verified
},
hasIdentifier () { hasIdentifier () {
return this.identifiers.length > 0 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