Files
stack/zotero/data/translators/CMS 4innovation.js
kert 7a15981184 fix 4innovation translator lastUpdated to ISO 8601 format
The translator metadata had '2026-02-08 23:00:00' (space-separated)
instead of '2026-02-08T23:00:00Z'. Zotero validates this field and
throws 'accessDate must be in ISO 8601' when loading translators
with non-conformant dates.
2026-03-21 23:53:28 -04:00

118 lines
3.5 KiB
JavaScript

{
"translatorID": "68c61549-9e8c-4645-8061-64281058c2f9",
"label": "CMS 4innovation",
"creator": "ACO Data Platform",
"target": "^https?://4innovation\\.cms\\.gov/secure/knowledge-management/view/",
"minVersion": "3.0",
"maxVersion": "",
"priority": 100,
"inRepository": false,
"translatorType": 4,
"browserSupport": "gcsibv",
"lastUpdated": "2026-02-08T23:00:00Z"
}
/*
CMS 4innovation Knowledge Management Translator
Captures structured metadata from 4innovation.cms.gov knowledge
base articles.
Captured fields: title, subcategory, description, date, author,
views, KM article ID, attachment filenames.
TODO: File download via API. The 4i API proxy at
https://4innovation.cms.gov/api/knowledge-management/{kmId}
returns article JSON including files[].fileMetaId. Download URL:
https://4innovation.cms.gov/api/knowledge-management/download/{fileMetaId}
The callback-based ZU.doGet approach with same-origin URLs is the
correct path forward. async/await crashes the Connector sandbox.
The cross-origin API (4innovation-api.cms.gov) returns 403.
Need to debug why ZU.doGet callback doesn't trigger file saves.
License: AGPL-3.0
*/
function detectWeb(doc, url) {
if (/\/secure\/knowledge-management\/view\/\d+/.test(url)) {
return 'webpage';
}
return false;
}
function doWeb(doc, url) {
var item = new Zotero.Item('webpage');
item.url = url;
item.websiteTitle = '4Innovation';
var kmId = '';
var idMatch = url.match(/\/view\/(\d+)/);
if (idMatch) kmId = idMatch[1];
// Title
var el = doc.querySelector('[id="title-1"]');
item.title = (el && el.textContent) ? el.textContent.replace(/\s+/g, ' ').trim() : ('4i Article ' + kmId);
// Date
var el2 = doc.querySelector('[id="state-last-updated-date"]');
if (el2 && el2.textContent) {
var dateRaw = el2.textContent.replace(/\s+/g, ' ').trim();
var dm = dateRaw.match(/(\d{2})\/(\d{2})\/(\d{4})/);
if (dm) item.date = dm[3] + '-' + dm[1] + '-' + dm[2];
}
// Author
var el3 = doc.querySelector('[id="state-creatdBy"]');
if (el3 && el3.textContent) {
var author = el3.textContent.replace(/\s+/g, ' ').trim();
if (author) {
item.creators.push({ lastName: author, creatorType: 'author', fieldMode: 1 });
}
}
// Description
var el4 = doc.querySelector('[id="description-1"]');
if (el4 && el4.textContent) {
var desc = el4.textContent.replace(/\s+/g, ' ').trim();
if (desc) item.abstractNote = desc;
}
// Subcategory
var subcategory = '';
var el5 = doc.querySelector('[id="subcategory-1"]');
if (el5 && el5.textContent) subcategory = el5.textContent.replace(/\s+/g, ' ').trim();
// Views
var views = '';
var el6 = doc.querySelector('[id="view-count-1"]');
if (el6 && el6.textContent) views = el6.textContent.replace(/\s+/g, ' ').trim();
// Extra
var extraParts = [];
if (kmId) extraParts.push('KM-ID: ' + kmId);
if (subcategory) extraParts.push('Subcategory: ' + subcategory);
if (views) extraParts.push('Views: ' + views);
// Filenames from DOM (recorded but not downloaded)
var fileEls = doc.querySelectorAll('[id^="file-"]');
var filenames = [];
for (var i = 0; i < fileEls.length; i++) {
var fn = fileEls[i].textContent.replace(/\s+/g, ' ').trim();
if (fn && fn.indexOf('.') !== -1) filenames.push(fn);
}
if (filenames.length) extraParts.push('Attachments: ' + filenames.join('; '));
item.extra = extraParts.join('\n');
// Tags
item.tags.push({ tag: 'source:4i' });
if (subcategory) {
item.tags.push({ tag: 'category:' + subcategory.toLowerCase().replace(/\s+/g, '-') });
}
// Snapshot
item.attachments.push({ document: doc, title: 'Snapshot' });
item.complete();
}