Fonto Why and How: How do I use document metadata!?

Fonto Why and How: How do I use document metadata!?

In this weekly series Martin describes a question that was raised by a Fonto developer, how it was resolved and why Fonto behaved like that in the first place. This week, a partner wondered how to insert a caption to a number of different elements. They already had an operation, but it did not always work!

In Fonto there’s a type called DocumentMetadata. It is typed as an object with a string as a key, and anything as the value. The documentation states it is “Additional metadata about the document. This object can be used to store application specific metadata“. Related links to that type are setDocumentMetadata and a way to read the documentmetadata: documentsManager.getDocumentMetadata.

Searching through the documentation shows another reference, in the API documentation of the document-related endpoints: Document saving, loading, locking, and state management.

metadataoptionalMetadataAdditional metadata, that is not included inside the XML document itself.

These two properties are actually the same! In Fonto, a document consists of its XML and this metadata field. This tuple is identified with a RemoteDocumentId. Locally we use the local DocumentId, but for clarity in this post, let’s talk about remote document ids here.

Document metadata can be used to store just about anything. We have seen it being used to store the workflow state of a document in an editor that manages workflow in a custom sidebar. We have seen it store the version label of a document (whether it is a major or minor version bump), the logical title of the document that is not stored in the XML, the file path in a filesystem-based CMS and more.

Whenever either the document metadata or the XML of a document changes in the editor, the document will be marked as dirty and we will start autosaving the document. This means you can not set the document metadata just for a single save request. If you for example set a flag in the metadata of the document to indicate the upcoming ‘save’ is a major one, it should be unset before the following save request. This will cause another save request immediately after: the metadata changes twice in this process.

Using document metadata for a workflow state

This partner loads DITA maps and uses a custom sidebar where they manage the workflow state of the map. It goes from ‘in progess’ to ‘under review’ to ‘done’. A whole DITA map (and all the documents under it) are always in the same workflow state, saved on the ‘map’ document.

They use the setDocumentMetadata method on documentsManager to change the metadata of the map document whenever a document moves through the workflow:

import documentsManager from 'fontoxml-documents/src/documentsManager';

export default function setWorkflowStep (documentId: DocumentId, workflowStep: string) {
	const currentMetadata = documentsManager.getDocumentMetadata(documentId);
	documentsManager.setDocumentMetadata(documentId, {...currentMetadata, workflowStep: workflowStep});
};

This is then used in the React component in the editor with a custom hook that is built using useManagerState, like this:

import documentsManager from 'fontoxml-documents/src/documentsManager';
import useManagerState from 'fontoxml-fx/src/useManagerState';
import Notifier from 'fontoxml-utils/src/Notifier';


export default useWorkflowState (mapDocumentId: DocumentId) {
	return useManagerState(
		// This argument should have been a notifier, but the document metadata API does not accept one.
		{
			addCallback: (callback) => {
				documentsManager.addDocumentMetadataChangeCallback(mapDocumentId, callback);
			}
		},
		() => documentsManager.getDocumentMetadata(mapDocumentId)?.workflowStep
	);
};

Using document metadata for versioning

This partner uses document metadata to set a version of the document: should the next save be ‘major’, or ‘minor’. They do this with a custom save button. Because of how metadata triggers a save call, they can not set the metadata for just the upcoming save. Therefore they use Fonto to set the upcoming version of the document, not the version bump. They added a new save button that sets the version of the upcoming save.

import documentsManager from 'fontoxml-documents/src/documentsManager';

export default function incrementVersion (documentId: DocumentId, howMuch: 'minor'|'major') {
	const currentMetadata = documentsManager.getDocumentMetadata(documentId);
	const currentVersion: [number,number] = currentMetadata?.version; // for example [1,0] for version 1.0
	switch (howMuch) {
		case 'major':
			currentVersion[0]++;
			currentVersion[1] = 0;
			break;
		case 'minor':
			currentVersion[1]++;
			break;
	}
	
	documentsManager.setDocumentMetadata(documentId, {...currentMetadata, version: currentVersion});
};

I hope this explained how Fonto works and why it works like that. During the years we built quite the product, and we are aware some parts work in unexpected ways for those who have not been with it from the start. If you have any points of Fonto you would like some focus on, we are always ready and willing to share! Reach out on Twitter to Martin Middel or file a support issue!

Stay up-to-dateFonto Why & How posts direct in your inbox

Receive updates on new Fonto Why & How blog posts by email

Leave a Comment

Your email address will not be published. Required fields are marked *

Scroll to Top