Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 2 additions & 0 deletions examples/affiliation.md
Original file line number Diff line number Diff line change
@@ -1,3 +1,5 @@
Note: This example (.json and .js files) currently rely on the ROR v1 API which won't be supported as of ~12/2025. They could be updated to use v2 of the API as the main authorIdandAffiliationUsingORCIDandROR example and ror.js script have.)

The affiliation example illustrates a lookup in ROR.org for the author affiliation field. As with the authors example, it is a simple lookup and fill-in solution. Do not expect changes in the ROR database to be propagated in the Dataset metadata.

Two files comprise this example:
Expand Down
11 changes: 11 additions & 0 deletions examples/authorIDandAffilationUsingORCIDandROR.md
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,17 @@ This example requires several files:

(These scripts also use jquery and select2 which are already included in Dataverse).

## Dataverse Compatibility note:

The ROR configuration/script now use ROR's v2 API and require Dataverse 6.9+ for full functionality.
For installations on earlier versions, the ROR organization name will not be added to the DataCite XML metadata.
Installations on <= Dataverse v6.8 should not upgrade their CVocConf configuration (keeping the retrieval-url pointed to ROR's v1 API or should delete the contents of the "retrieval-filtering" object (e.g. set "retrieval-filtering": {} ).

## ROR Compatibility note:
As of Dec. 2025, ROR will no longer support it's v1 API. To retain ROR functionality, Dataverse sites should update to use the current ror.js script (which uses ROR's v2 API).
Dataverse instances on v6.9+ should also update to use the current :CVocConf configuration.
Dataverse instances using <=v6.8 also need to update the ror.js script but should not update their configuration (or should delete the contents of the retrieval-filtering object as discussed above).

### How to install:

Minimal:
Expand Down
4 changes: 2 additions & 2 deletions examples/config/authorsOrcidAndRor.json
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@
"term-uri-field": "authorAffiliation",
"js-url": ["https://gdcc.github.io/dataverse-external-vocab-support/scripts/ror.js","https://gdcc.github.io/dataverse-external-vocab-support/scripts/cvocutils.js"],
"protocol": "ror",
"retrieval-uri": "https://api.ror.org/v1/organizations/{0}",
"retrieval-uri": "https://api.ror.org/v2/organizations/{0}",
"allow-free-text": true,
"prefix": "https://ror.org/",
"managed-fields": {},
Expand All @@ -26,7 +26,7 @@
},
"termName": {
"pattern": "{0}",
"params": ["/name"]
"params": ["/names/types=ror_display/value"]
},
"@type": {
"pattern": "https://schema.org/Organization"
Expand Down
4 changes: 2 additions & 2 deletions examples/config/demos/rorAuthAffiliation.json
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@
"term-uri-field": "authorAffiliation",
"js-url": ["/cvoc/js/ror.js","/cvoc/js/cvocutils.js"],
"protocol": "ror",
"retrieval-uri": "https://api.ror.org/organizations/{0}",
"retrieval-uri": "https://api.ror.org/v2/organizations/{0}",
"allow-free-text": true,
"prefix": "https://ror.org/",
"managed-fields": {},
Expand All @@ -26,7 +26,7 @@
},
"termName": {
"pattern": "{0}",
"params": ["/name"]
"params": ["/names/types=ror_display/value"]
},
"@type": {
"pattern": "https://schema.org/Organization"
Expand Down
4 changes: 2 additions & 2 deletions examples/config/grantNumberAgencyRor.json
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@
"term-uri-field": "grantNumberAgency",
"js-url": ["https://qualitativedatarepository.github.io/dataverse-external-vocab-support/scripts/ror.js","https://qualitativedatarepository.github.io/dataverse-external-vocab-support/scripts/cvocutils.js"],
"protocol": "ror",
"retrieval-uri": "https://api.ror.org/organizations/{0}",
"retrieval-uri": "https://api.ror.org/v2/organizations/{0}",
"allow-free-text": true,
"prefix": "https://ror.org/",
"managed-fields": {},
Expand All @@ -26,7 +26,7 @@
},
"termName": {
"pattern": "{0}",
"params": ["/name"]
"params": ["/names/types=ror_display/value"]
},
"@type": {
"pattern": "https://schema.org/Organization"
Expand Down
2 changes: 1 addition & 1 deletion scripts/affiliation.js
Original file line number Diff line number Diff line change
Expand Up @@ -106,7 +106,7 @@ function createAffiliationModal() {

function affiliationsQuery(str) {
// Vocabulary search REST call
fetch("https://api.ror.org/organizations?query=" + str)
fetch("https://api.ror.org/v1/organizations?query=" + str)
.then(response => response.json())
.then(data => {
let table = document.querySelector('#' + affiliationSearchResultsID + ' tbody');
Expand Down
56 changes: 46 additions & 10 deletions scripts/ror.js
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
console.log("ror.js..");
var rorSelector = "span[data-cvoc-protocol='ror']";
var rorInputSelector = "input[data-cvoc-protocol='ror']";
var rorRetrievalUrl = "https://api.ror.org/v1/organizations";
var rorRetrievalUrl = "https://api.ror.org/v2/organizations";
var rorIdStem = "https://ror.org/";
var rorPrefix = "ror";
//Max chars that displays well for a child field
Expand Down Expand Up @@ -62,12 +62,19 @@ function expandRors() {
},
success: function(ror, status) {
// If found, construct the HTML for display
var name = ror.name;
var altNames = ror.acronyms;
// Find the display name (type: "ror_display" or "label")
const displayName = ror.names.find(n =>
n.types && (n.types.includes("ror_display") || n.types.includes("label"))
)?.value || ror.id;

// Find all acronyms
const acronyms = ror.names
.filter(n => n.types && n.types.includes("acronym"))
.map(n => n.value);

$(rorElement).html(getRorDisplayHtml(name, rorIdStem + id, altNames, false, true));
$(rorElement).html(getRorDisplayHtml(displayName, rorIdStem + id, acronyms, false, true));
//Store values in localStorage to avoid repeating calls to CrossRef
storeValue(rorPrefix, id, name + "#" + altNames);
storeValue(rorPrefix, id, displayName + "#" + acronyms.join(','));
},
failure: function(jqXHR, textStatus, errorThrown) {
// Generic logging - don't need to do anything if 404 (leave
Expand Down Expand Up @@ -190,14 +197,34 @@ function updateRorInputs() {
// Sort the list
// Prioritize active orgs
.sort((a, b) => Number(b.status === 'active') - Number(a.status === 'active'))
// Extract display name and acronyms from the names array
.map(org => {
// Find the display name (type: "ror_display" or "label")
const displayName = org.names.find(n =>
n.types && (n.types.includes("ror_display") || n.types.includes("label"))
)?.value || org.id;

// Find all acronyms
const acronyms = org.names
.filter(n => n.types && n.types.includes("acronym"))
.map(n => n.value);

return {
...org,
name: displayName,
acronyms: acronyms
};
})
// Prioritize those with this acronym
.sort((a, b) => Number(b.acronyms.includes(params.term)) - Number(a.acronyms.includes(params.term)))
.sort((a, b) => Number(b.acronyms.some(acr => acr === params.term)) -
Number(a.acronyms.some(acr => acr === params.term)))
// Prioritize previously used entries
.sort((a, b) => Number(getValue(rorPrefix, b['id'].replace(rorIdStem, '')).name != null) - Number(getValue(rorPrefix, a['id'].replace(rorIdStem, '')).name != null))
.sort((a, b) => Number(getValue(rorPrefix, b['id'].replace(rorIdStem, '')).name != null) -
Number(getValue(rorPrefix, a['id'].replace(rorIdStem, '')).name != null))
.map(
function(x) {
return {
text: x.name + ", " + x.id.replace(rorIdStem, '') + ', ' + x.acronyms,
text: x.name + ", " + x.id.replace(rorIdStem, '') + ', ' + x.acronyms.join(','),
id: x.id
}
})
Expand Down Expand Up @@ -236,9 +263,18 @@ function updateRorInputs() {
'Accept': 'application/json'
},
success: function(ror, status) {
var name = ror.name;
// Find the display name (type: "ror_display" or "label")
const displayName = ror.names.find(n =>
n.types && (n.types.includes("ror_display") || n.types.includes("label"))
)?.value || ror.id;

// Find all acronyms
const acronyms = ror.names
.filter(n => n.types && n.types.includes("acronym"))
.map(n => n.value);

//Display the name and id number in the selection menu
var text = name + ", " + ror.id.replace(rorIdStem, '') + ', ' + ror.acronyms;
var text = displayName + ", " + ror.id.replace(rorIdStem, '') + ', ' + acronyms.join(',');
var newOption = new Option(text, id, true, true);
$('#' + selectId).append(newOption).trigger('change');
},
Expand Down