Version: 1.0
This repository contains community extensions to the OCFL Specification and Implementation Notes. Extensions are a means of adding new functionality and documenting standards outside of the main OCFL specification process. For example, storage layout extensions define how OCFL object IDs are mapped to OCFL object root directories within an OCFL storage root. This mapping is outside of the scope of the OCFL specification, but is valuable information to capture so that repositories are self-describing and easily accessible using generic OCFL tooling.
This is a community driven repository. Community members are encouraged to contribute by submitting new extensions and reviewing others' submissions. For more details, see the review/merge policy below.
See the current set of adopted extensions and extensions open for review and discussion.
To use OCFL extensions you first need an OCFL client that supports the desired extensions. OCFL clients are not required to support extensions to be compliant with the OCFL specification, and the extensions that any given client supports will vary. The idea behind this repository is to encourage the development and implementation of common extensions so that there can be interoperability between OCFL clients.
Reference the OCFL specification's description of object extensions and storage root extensions.
The OCFL storage root MAY contain a copy of an extension's specification.
Each extension specification details how it should be implemented, but there are a few rules that apply to every extension.
A root extension directory refers to the directory named extensions
that is located in either the storage root or an object root. An extension directory is an extension specific directory that is the child of a root extension directory and MUST be named using the extension's Registered Name, or initial
(see Optional Initial Extension). For example, extensions/0000-example-extension
is the extension directory for the extension 0000-example-extension.
An extension's parameters are serialized as a JSON object and written to a configuration file named config.json
within the extension's extension directory.
If an extension includes a configuration file, one of the properties in that file MUST be extensionName
, where the value is the Registered Name of the extension.
For example, the extension 0000-example-extension could be parameterized as follows:
{
"extensionName": "0000-example-extension",
"firstExampleParameter": 12,
"secondExampleParameter": "Hello",
"thirdExampleParameter": "Green"
}
Based on how the extension is used, its configuration file is written to one of the following locations, relative the storage root:
extensions/0000-example-extension/config.json
, if it is a storage root extensionOBJECT_ROOT/extensions/0000-example-extension/config.json
, if it is an object extension
It is conceivable that some extensions may not be compatible with other extensions, or may be rendered incompatible based on how they're implemented in a client. For example, suppose that there are multiple extensions that define how logs should be written to an object's log directory. You could declare that your objects are using multiple log extensions, but the result is undefined and up to the implementing client. It may only write one log format or the other, it may write all of them, or it may reject the configuration entirely.
Because OCFL clients are not required to implement any or all extensions, it is also possible that a client may encounter an extension that it does not implement. In these cases, it is up to the client to decide how to proceed. A client may fail on unsupported extensions, or it may choose to ignore the extensions and carry on.
A root extension directory MAY optionally contain an initial extension that, if it exists, SHOULD be applied before all other extensions in the directory. An initial extension is identified by the extension directory name "initial".
An initial extension could be used to address some of the undefined behaviors, define how extensions are applied, and answer questions such as:
- Is an extension deactivated, only applying to earlier versions of the object?
- Should extensions be applied in a specific order?
- Does one extension depend on another?
Community extensions MUST be written as GitHub flavored markdown files in the docs
directory of this repository. The
filename of an extension is based on its Registered Name with a .md
extension.
Extensions are numbered sequentially, and the Registered Name of an extension is prefixed with this 4-digit, zero-padded decimal number. The Registered Name should be descriptive, use hyphens to separate words, and have a maximum of 250 characters in total.
New extensions should use NNNN
as a place-holder for the next available prefix number at the time of merging. New extension pull-requests should not update the index document (docs/index.md
), this will be done post-approval.
Extensions are intended to be mostly static once published. Substantial revisions of content beyond simple fixes warrants publishing a new extension, and marking the old extension obsolete by updating the Obsoletes/Obsoleted by sections in each extension respectively.
An example/template is available in this repository as "OCFL Community Extension 0000: Example Extension" and is rendered via GitHub pages as https://ocfl.github.io/extensions/0000-example-extension
Extension definitions MUST contain a header section that defines the following fields:
- Extension Name: The extension's unique Registered Name
- Authors: The names of the individuals who authored the extension
- Minimum OCFL Version: The minimum OCFL version that the extension requires, eg. 1.0
- OCFL Community Extensions Version: The version of the OCFL Extensions Specification that the extension conforms to, eg. 1.0
- Obsoletes: The Registered Name of the extension that this extension obsoletes, or n/a
- Obsoleted by: The Registered Name of the extension that obsoletes this extension, or n/a
Extension definitions MAY define parameters to enable configuration as needed. Extension parameters are serialized as JSON values, and therefore must conform to the JSON specification. Parameters MUST be defined in the following structure:
- Name: A short, descriptive name for the parameter. The name is used as the parameter's key within its JSON representation.
- Description: A brief description of the function of the parameter. This should be expanded on in the main description of the extension which MUST reference all the parameters.
- Type: The JSON data type of the parameter value. One of
string
,number
,boolean
,array
, orobject
. The structure of complex types MUST be further described. - Constraints: A description of any constraints to apply to parameter values. Constraints may be plain text, regular expressions, JSON Schema, or whatever makes the most sense for the extension.
- Default: The default value of parameter. If no default is specified, then the parameter is mandatory.
Each specification MUST thoroughly document how it is intended to be implemented and used, including detailed examples is helpful. If the extension uses parameters, the parameters MUST be described in detail in the body of the specification.
- A pull-request is submitted per the guidelines described in the "Organization of this repository" section of this document
- Authors of (legitimate) pull-requests will be added by an owner of the OCFL GitHub organization to the extension-authors team
- The purpose of being added to this team is to enable adding
labels
to their pull-request(s)
- The purpose of being added to this team is to enable adding
- If a pull-request is submitted in order to facilitate discussion, the
draft
label should be applied by the author - If a pull-request is ready for review, it should have a title that is suitable for merge (i.e. not have a title indicating "draft"), and optionally have the
in-review
label applied by the author - A pull-request must be merged by an OCFL Editor if the following criteria are met. Pull-requests may remain in an
in-review
state for an extended period as it waits for these requirements to be met. - After the pull-request has been merged with
NNNN
as a placeholder for the extension number in the Registered Name, an OCFL Editor will determine the extension number based on the next sequentially available number. They will create an additional administrative pull-request to changeNNNN
to the appropriate number in the extension file name and the extension document itself, as well as adding an entry to the index page entry (docs/index.md
).