Skip to content

Commit

Permalink
Changes to vue router history mode in order to improve SEO
Browse files Browse the repository at this point in the history
This includes several diffs, including some patches dealing with the fallout:
- Changes the vue-router configuration from hash mode to history mode in order
  to remove the # in the URL which makes google crawling difficult.
- As a necessary consequence, updates all html and js pages with changes relating
  to the relative location of files; now everything is relative to root, i.e. starts with '/'.
- Fixes the backbutton display which started being buggy after the change to history mode.
- Adds an href property to all subdataset links on all dataset pages,
  so that they can be more easily crawlable by google.
- Add structured and linked data in json-ld format to the html document head for each dataset,
  which makes a dataset page show rich metadata in google's dataset search.
- Update local server functionality to redirect urls starting with '/dataset'
  to '/index.html' in order to be compatible with the new router history mode.

See sfb1451/metadata-catalog#83 for more context.
  • Loading branch information
jsheunis committed Feb 8, 2024
1 parent 15be13d commit 32f1f4c
Show file tree
Hide file tree
Showing 7 changed files with 82 additions and 56 deletions.
33 changes: 24 additions & 9 deletions datalad_catalog/catalog/assets/app_component_dataset.js
Original file line number Diff line number Diff line change
Expand Up @@ -38,7 +38,6 @@ const datasetView = () =>
citation_busy: false,
citation_text: "",
invalid_doi: false,
show_backbutton: false,
};
},
watch: {
Expand Down Expand Up @@ -204,6 +203,22 @@ const datasetView = () =>
// Write main derived variable and set to ready
this.displayData = disp_dataset;
this.display_ready = true;

// Add json-ld data to head
var scripttag = document.getElementById("structured-data")
if (!scripttag) {
scripttag = document.createElement("script");
scripttag.setAttribute("type", "application/ld+json");
scripttag.setAttribute("id", "structured-data");
document.head.appendChild(scripttag);
}
obj = {
"@context": "https://schema.org/",
"@type": "Dataset",
"name": this.displayData.display_name ? this.displayData.display_name : "",
"description": this.selectedDataset.description ? this.selectedDataset.description : ""
}
scripttag.textContent = JSON.stringify(obj);
}
},
},
Expand Down Expand Up @@ -271,6 +286,13 @@ const datasetView = () =>
}
return sorted;
},
showBackButtonComp() {
if (this.currentIsHome()) {
return false
} else {
return true
}
},
},
methods: {
newTabActivated(newTabIndex, prevTabIndex, bvEvent) {
Expand All @@ -284,9 +306,7 @@ const datasetView = () =>
// https://www.sitepoint.com/clipboard-api/
selectText = document.getElementById("clone_code").textContent;
selectText = '\n ' + selectText + ' \n\n '
console.log(selectText)
selectText = selectText.replace(/^\s+|\s+$/g, '');
console.log(selectText)
navigator.clipboard
.writeText(selectText)
.then(() => {})
Expand Down Expand Up @@ -318,6 +338,7 @@ const datasetView = () =>
}, 1000);
},
async selectDataset(event, obj, objId, objVersion, objPath) {
event.preventDefault()
var newBrowserTab = event.ctrlKey || event.metaKey || (event.button == 1)
if (obj != null) {
objId = obj.dataset_id;
Expand Down Expand Up @@ -720,12 +741,6 @@ const datasetView = () =>
available_tabs_lower,
this.$root.selectedDataset.config?.dataset_options?.default_tab
)
// if navigated to using vue router (i.e. internal to the app), show the back button
if (this.currentIsHome()) {
this.$root.selectedDataset.show_backbutton = false
} else {
this.$root.selectedDataset.show_backbutton = true
}
next();
},
async created() {
Expand Down
12 changes: 5 additions & 7 deletions datalad_catalog/catalog/assets/app_globals.js
Original file line number Diff line number Diff line change
Expand Up @@ -2,17 +2,17 @@
// Data //
/********/

const config_file = "./config.json";
const metadata_dir = "./metadata";
const superdatasets_file = metadata_dir + "./super.json";
const json_file = metadata_dir + "./datasets.json";
const template_dir = "/templates";
const config_file = "/config.json";
const metadata_dir = "/metadata";
const superdatasets_file = metadata_dir + "/super.json";
const SPLIT_INDEX = 3;
const SHORT_NAME_LENGTH = 0; // number of characters in name to display, zero if all
const default_config = {
catalog_name: "DataCat",
link_color: "#fba304",
link_hover_color: "#af7714",
logo_path: "artwork/catalog_logo.svg",
logo_path: "/artwork/catalog_logo.svg",
social_links: {
about: null,
documentation: "https://docs.datalad.org/projects/catalog/en/latest/",
Expand All @@ -24,7 +24,6 @@ const default_config = {
include_metadata_export: true,
}
};
const template_dir = "./templates";

/*************/
// Functions //
Expand All @@ -48,7 +47,6 @@ async function grabSubDatasets(app) {
console.error(er);
subds_json[index] = "unavailable";
}
console.log(subds_json[index]);
}
})
);
Expand Down
8 changes: 7 additions & 1 deletion datalad_catalog/catalog/assets/app_router.js
Original file line number Diff line number Diff line change
Expand Up @@ -41,11 +41,17 @@ const routes = [
name: "dataset",
},
{ path: "/about", component: aboutPage, name: "about" },
{ path: "*", component: notFound, name: "404" },
{
path: '/:catchAll(.*)',
component: notFound,
name: '404'
},
];

// Create router
const router = new VueRouter({
mode: 'history',
base: '/',
routes: routes,
scrollBehavior(to, from, savedPosition) {
return { x: 0, y: 0, behavior: "auto" };
Expand Down
18 changes: 9 additions & 9 deletions datalad_catalog/catalog/display_schema.html
Original file line number Diff line number Diff line change
Expand Up @@ -7,16 +7,16 @@
<meta http-equiv="content-type" content="text/html; charset=UTF-8" />

<!-- Required Stylesheets -->
<link rel="stylesheet" type="text/css" href="assets/style.css"/>
<link rel="stylesheet" type="text/css" href="assets/fontawesome.min.css"/>
<link rel="stylesheet" type="text/css" href="assets/brands.min.css"/>
<link type="text/css" rel="stylesheet" href="assets/bootstrap.5.1.3.min.css"/>
<link type="text/css" rel="stylesheet" href="assets/bootstrap-vue.2.21.2.min.css"/>
<link rel="stylesheet" type="text/css" href="/assets/style.css"/>
<link rel="stylesheet" type="text/css" href="/assets/fontawesome.min.css"/>
<link rel="stylesheet" type="text/css" href="/assets/brands.min.css"/>
<link type="text/css" rel="stylesheet" href="/assets/bootstrap.5.1.3.min.css"/>
<link type="text/css" rel="stylesheet" href="/assets/bootstrap-vue.2.21.2.min.css"/>

<!-- Required scripts -->
<script src="https://unpkg.com/[email protected]/dist/vue.js"></script>
<!-- <script src="assets/vue.2.6.14.min.js"></script> -->
<script src="assets/bootstrap-vue.2.21.2.min.js"></script>
<!-- <script src="https://unpkg.com/[email protected]/dist/vue.js"></script> -->
<script src="/assets/vue.2.6.14.min.js"></script>
<script src="/assets/bootstrap-vue.2.21.2.min.js"></script>

<!-- Vue component templates -->

Expand Down Expand Up @@ -327,6 +327,6 @@
</b-container>
<br><br><br><br>
<!-- Start running your app -->
<script src="assets/display_schema.js"></script>
<script src="/assets/display_schema.js"></script>
</body>
</html>
44 changes: 22 additions & 22 deletions datalad_catalog/catalog/index.html
Original file line number Diff line number Diff line change
Expand Up @@ -6,26 +6,26 @@
<meta name="viewport" content="width=device-width, initial-scale=1, shrink-to-fit=no" />
<meta http-equiv="content-type" content="text/html; charset=UTF-8" />

<link rel="icon" href="assets/favicon/favicon.ico" type="image/x-icon">
<link rel="icon" type="image/png" sizes="32x32" href="assets/favicon/favicon-32x32.png">
<link rel="icon" type="image/png" sizes="16x16" href="assets/favicon/favicon-16x16.png">
<link rel="icon" href="/assets/favicon/favicon.ico" type="image/x-icon">
<link rel="icon" type="image/png" sizes="32x32" href="/assets/favicon/favicon-32x32.png">
<link rel="icon" type="image/png" sizes="16x16" href="/assets/favicon/favicon-16x16.png">

<title>DataLad Catalog</title>

<!-- Required Stylesheets -->
<link rel="stylesheet" type="text/css" href="assets/style.css"/>
<link rel="stylesheet" type="text/css" href="assets/fontawesome.min.css"/>
<link rel="stylesheet" type="text/css" href="assets/brands.min.css"/>
<link type="text/css" rel="stylesheet" href="assets/bootstrap.5.1.3.min.css"/>
<link type="text/css" rel="stylesheet" href="assets/bootstrap-vue.2.21.2.min.css"/>
<link rel="stylesheet" type="text/css" href="/assets/style.css"/>
<link rel="stylesheet" type="text/css" href="/assets/fontawesome.min.css"/>
<link rel="stylesheet" type="text/css" href="/assets/brands.min.css"/>
<link type="text/css" rel="stylesheet" href="/assets/bootstrap.5.1.3.min.css"/>
<link type="text/css" rel="stylesheet" href="/assets/bootstrap-vue.2.21.2.min.css"/>

<!-- Required scripts -->
<script src="https://unpkg.com/[email protected]/dist/vue.js"></script>
<!-- <script src="assets/vue.2.6.14.min.js"></script> -->
<script src="assets/bootstrap-vue.2.21.2.min.js"></script>
<script src="assets/vue-router.3.5.3.min.js"></script>
<script src="assets/md5-2.3.0.js"></script>
<script src="assets/marked.4.0.17.min.js"></script>
<!-- <script src="https://unpkg.com/[email protected]/dist/vue.js"></script> -->
<script src="/assets/vue.2.6.14.min.js"></script>
<script src="/assets/bootstrap-vue.2.21.2.min.js"></script>
<script src="/assets/vue-router.3.5.3.min.js"></script>
<script src="/assets/md5-2.3.0.js"></script>
<script src="/assets/marked.4.0.17.min.js"></script>

</head>

Expand Down Expand Up @@ -70,13 +70,13 @@
<br>
</b-container>
<!-- Run the Vue app scripts - DO NOT CHANGE ORDER -->
<script src="assets/app_globals.js"></script>
<script src="assets/app_component_item.js"></script>
<script src="assets/app_component_contexttab.js"></script>
<script src="assets/app_component_dataset.js"></script>
<script src="assets/app_component_about.js"></script>
<script src="assets/app_component_notfound.js"></script>
<script src="assets/app_router.js"></script>
<script src="assets/app.js"></script>
<script src="/assets/app_globals.js"></script>
<script src="/assets/app_component_item.js"></script>
<script src="/assets/app_component_contexttab.js"></script>
<script src="/assets/app_component_dataset.js"></script>
<script src="/assets/app_component_about.js"></script>
<script src="/assets/app_component_notfound.js"></script>
<script src="/assets/app_router.js"></script>
<script src="/assets/app.js"></script>
</body>
</html>
8 changes: 4 additions & 4 deletions datalad_catalog/catalog/templates/dataset-template.html
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@
<span>
<a @click="gotoHome" class="newlink"><small><i class="fas fa-home"></i></small></a>
</span>
<span class="dataset-nav-item" v-if="selectedDataset.show_backbutton">
<span class="dataset-nav-item" v-if="showBackButtonComp">
<a @click="history.back()" class="newlink"><small><i class="fas fa-backward"></i></small></a>
</span>
</span>
Expand Down Expand Up @@ -38,7 +38,7 @@
alt="datalad_d" height="14em" class="mb-1"/>
Download with DataLad</b-button>&nbsp;</span>
<span v-show="displayData.is_github"><b-button variant="outline-dark" size="sm" @click="gotoURL(displayData.url)"><i class="fab fa-github"></i> View on GitHub</b-button>&nbsp;</span>
<span v-show="displayData.is_gin"><b-button variant="outline-dark" size="sm" @click="gotoURL(displayData.url)"><img src="artwork/ginfavicon.png" style="height: 1em;"></img> View on GIN</b-button>&nbsp;</span>
<span v-show="displayData.is_gin"><b-button variant="outline-dark" size="sm" @click="gotoURL(displayData.url)"><img src="/artwork/ginfavicon.png" style="height: 1em;"></img> View on GIN</b-button>&nbsp;</span>
<span v-show="selectedDataset.doi"><b-button variant="outline-dark" size="sm" v-b-modal.modal-2 @click="getCitationText(selectedDataset.doi)"><i class="fas fa-quote-right"></i> Cite</b-button>&nbsp;</span>
<span v-if="displayData.show_export"><b-button variant="outline-dark" size="sm" :href="displayData.file_path" :download="displayData.download_filename"><i class="fas fa-share"></i> Export metadata</b-button>&nbsp;</span>
<span><b-button variant="outline-dark" size="sm" @click="openWithBinder(displayData.url)"><img src="data:image/png;base64,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"
Expand All @@ -57,7 +57,7 @@
ok-only>
<template #modal-header="{ close }">
<div class="d-block text-center">
<h3>Download with <img src="artwork/datalad_logo_wide.svg" width="100em"></h3>
<h3>Download with <img src="/artwork/datalad_logo_wide.svg" width="100em"></h3>
</div>
</template>
<h5>Step 1: Install DataLad</h5>
Expand Down Expand Up @@ -265,7 +265,7 @@ <h3>Dataset not found</h3>
<span class="xxlfont"><i class="fas fa-database"></i></span>
</b-col>
<b-col class="text-muted" md="7">
<h5><a @click="selectDataset($event, ds)" class="newlink">{{ds.dirs_from_path.at(-1)}}</a></h5>
<h5><a :href="'/dataset/'+ds.dataset_id+'/'+ds.dataset_version" @click.prevent="selectDataset($event, ds)" class="newlink">{{ds.dirs_from_path.at(-1)}}</a></h5>
<span v-for="(author, index) in ds.authors">
<small>
<span v-if="author.givenName">{{author.givenName}} {{author.familyName}}</span><span v-else>{{author.name}}</span><span v-if="index != ds.authors.length - 1">, </span>
Expand Down
15 changes: 11 additions & 4 deletions datalad_catalog/webcatalog.py
Original file line number Diff line number Diff line change
Expand Up @@ -287,14 +287,21 @@ def serve(
"""Serve a catalog via a local http server"""
os.chdir(self.location)

import http.server
from http.server import SimpleHTTPRequestHandler
import socketserver
from datalad.ui import ui
import datalad.support.ansi_colors as ac

Handler = http.server.SimpleHTTPRequestHandler
class CustomHandler(SimpleHTTPRequestHandler):
# Redirect all '/dataset' URLs to '/index.html'
def do_GET(self):
if self.path.startswith('/dataset'):
self.path = '/index.html'
# Continue with the default behavior
return SimpleHTTPRequestHandler.do_GET(self)

try:
with socketserver.TCPServer((host, port), Handler) as httpd:
with socketserver.TCPServer((host, port), CustomHandler) as httpd:
ui.message(
"\nServing catalog at: http://{h}:{p}/ - navigate to this "
"address in your browser to test the catalog locally - press "
Expand All @@ -308,4 +315,4 @@ def serve(
lgr.error(
msg="Unable to serve at the desired host and port", exc_info=e
)
raise (e)
raise (e)

0 comments on commit 32f1f4c

Please sign in to comment.