Open tomcrane opened 2 years ago
Example flow
Viewing the catalogue record for a digitised item in the Canadiana system Catalogue record has a link to the Manifest (hosted on Canadiana) Catalogue record also has link to EDIT the manifest (opens up a project for that Manifest in ME) User works on Manifest in ME User hits Save - Save is configured to POST the manifest back to appropriate Canadiana endpoint
This implies #184
Loading fixed by #185
Examples:
manifest-editor.com?manifest=https://example.org/records/12345/manifest.json
ME loads from that URL. What if it's a 404? Either: create a blank manifest OR warn user that no manifest exists at that URL
either way, Save => HTTP PUT back to that URL?
Need to discuss.
Currently loading works by using
#?manifest=[...]
But for publishing, a project could be created with a publishing configuration:
#?manifest=[...]&publish_type=custom-type&publish_options={...}
Canadiana comments:
If we implement a IIIF Presentation API with POST and PUT requests, the manifest editor will automatically know where to send the save request. (See issue #184)
Digirati comments
The Manifest Editor needs to recognise that the passed Manifest URI "belongs" to the custom storage adaptor. Or even, if the ME has multiple storage adaptors (it can load and save to local file system and GitHub and IIIF REST A and IIIF REST B) that it matches the URI with one of these, so it knows that a Save is a PUT back to that location. This can be quite simple - just the string start of a URL.
Everything looks good! :smile:
Especially the multiple storage adaptors~
Implementation details:
This has been expanded slightly, in a preview PR at #267 It allows you to create an embedded Manifest Editor - passing it a Manifest and then Requesting the JSON after it's saved.
So you create an iFrame:
const $frame = document.createElement("iframe");
$frame.setAttribute("src", `https://deploy-preview-267--manifest-editor-testing.netlify.app/?embed=true&local=true&manifest=${id}`);
$frame.setAttribute("width", "100%");
$frame.setAttribute("height", "900");
And then there are two helpers (as examples) to show the process of sending and reading data through the iFrame.
const getManifestData = (iframe) => new Promise(resolve => {
// Post messaging telling the Manifest Editor (in the iframe) to
// Save the IIIF Manifest.
iframe.contentWindow.postMessage({
type: "manifest-editor:save",
}, "*");
const listener = e => {
const { type, data } = e.data || {};
// After the save is sent, a save-response will be
// sent by the Manifest Editor. This contains the
// new JSON for the Manifest.
if (type === "manifest-editor:save-response") {
resolve(data);
window.removeEventListener("message", listener);
}
};
window.addEventListener("message", listener);
});
const sendManifestData = (iframe, data) => {
const listener = e => new Promise(resolve => {
const { type } = e.data || {};
// The Manifest Editor will raise a manifest-request
// when it's ready to load a manifest. It will wait
// for a response after loaded.
if (type === "manifest-editor:manifest-request") {
resolve();
// Here we can respond when it's ready, with the JSON
// for our manifest. This will only happen if `local=true`
// is set in the URL of the iFrame, otherwise it will fetch
// the Manifest from the ID.
iframe.contentWindow.postMessage({
type: "manifest-editor:manifest-response",
data,
}, "*");
window.removeEventListener("message", listener);
}
});
window.addEventListener("message", listener);
};
There is also: manifest-editor:close
when the editor is closed.
Additionally, if you pass mini=true
then you can limit the editor to just the sidebar.
Specify a Manifest to load and edit via a query string parameter, for systems integration scenarios.
Should we redirect once loaded, to take the manifest param off of the query string?