Vocabularies

Vocabularies provide lists of {token, title} pairs served via GET /@vocabularies/:name. They are used for field choices (e.g. content types, roles, languages, workflow states).

Types

interface VocabularyTerm {
  title: string;
  token: string;
}

type Vocabulary = VocabularyTerm[];

type VocabularyHandler = (
  req: Request,
  trx: Knex.Transaction,
) => Promise<Vocabulary>;

Two approaches

Code-based vocabulary

Create an async handler function that returns an array of {title, token} terms, then register it with the in-memory registry.

Model-driven — fetch records from a model and delegate to getVocabulary():

// src/vocabularies/my-vocab/my-vocab.ts
import models from '../../models';

export async function myVocab(
  req: Request,
  trx: Knex.Transaction,
): Promise<Vocabulary> {
  const MyModel = models.get('MyModel');
  const items = await MyModel.fetchAll({}, { order: 'title' }, trx);
  return items.getVocabulary(req);
}

Static/config-driven — return terms from config or constants:

import config from '../../helpers/config/config';
import { arrayToVocabulary } from '../../helpers/utils/utils';

export async function myVocab(
  _req: Request,
  _trx: Knex.Transaction,
): Promise<VocabularyTerm[]> {
  return arrayToVocabulary(config.settings.myList);
}

Computed — transform DB data before returning:

import { uniq } from 'es-toolkit/array';
import { arrayToVocabulary } from '../../helpers/utils/utils';
import models from '../../models';

export async function myVocab(
  req: Request,
  trx: Knex.Transaction,
): Promise<VocabularyTerm[]> {
  const Catalog = models.get('Catalog');
  const items = await Catalog.fetchAll({ field: ['is not', null] }, {}, trx);
  return arrayToVocabulary(uniq(items.map((item) => item.field)));
}

Profile-based vocabulary (JSON)

For static vocabulary data, place a JSON file in the profile’s vocabularies/ directory. It is automatically loaded into the database when the profile is installed:

{
  "id": "my_vocab",
  "title:i18n": "My Vocabulary",
  "items": [
    { "title:i18n": "Option One", "token": "option_one" },
    { "title:i18n": "Option Two", "token": "option_two" }
  ]
}

The :i18n suffix enables translation of the title at runtime.

Registration

In a profile’s init() function, register the vocabulary handler:

import vocabularies from '../../vocabularies';
import { myVocab } from '../../vocabularies/my-vocab/my-vocab';

// In init():
vocabularies.register('myVocab', myVocab);

The vocabulary is then available at GET /@vocabularies/myVocab.

Helper functions

// Each array item becomes { title: item, token: item }
arrayToVocabulary(['a', 'b']);
// → [{ title: 'a', token: 'a' }, { title: 'b', token: 'b' }]

// Each object entry becomes { title: value, token: key }
objectToVocabulary({ key1: 'Value 1', key2: 'Value 2' });
// → [{ title: 'Value 1', token: 'key1' }, { title: 'Value 2', token: 'key2' }]

This site uses Just the Docs, a documentation theme for Jekyll.