Content Package Specification
Unlike modules, content packages are not natively supported by OpenMRS. One cannot simply drop a content package zip file into one’s OpenMRS Application Data Directory and expect OpenMRS to be able to install it. Instead, content packages work as components of a distribution, and are build components that the OpenMRS SDK is able to process when building a distribution or installing or deploying a distribution to an SDK server.
Content package structure and identification
All content packages should adhere to the following conventions:
A content package should be identified via a set of Maven coordinates that allow publishing and retrieval in a Maven repository as a
zip
artifactA content package zip file should have the following structure. Each of the following are optional:
A file named
content.properties
at the root. See content.properties section below for more details on the make-up of this file.A directory named
configuration
at the root, with sub-directories namedbackend_configuration
andfrontend_configuration
Files within the
configuration/backend_configuration
directory should match the expected format of the OpenMRS Initializer moduleFiles within the
configuration/frontend_configuration
directory should match the expected format of O3 configuration JSON files
The content.properties file
The content.properties
file is the primary mechanism that can be used to communicate the requirements and dependencies of the overall package. This includes the supported OpenMRS environment (specific core version or module version, for example), as well as any particular configuration values that are needed. If no content.properties
file is present, the SDK will still process the content package, and will simply assume there are no dependencies or requirements. It is considered best practice to include a content.properties
file, even if there is nothing yet to communicate in this file.
As a general rule, the supported properties in a content.properties
file mirror the support properties in an openmrs-distro.properties
file, with one main difference. The content.properties
exist to provide information as to the range of properties that are required or supported, whereas an openmrs-distro.properties
file provides the actual, resolved properties.
Informational properties:
All content properties should contain the name
and version
of the package:
name=My First Content Package
version=1.0.0
Required component versions:
Any components that the content package needs to be present in order for the content package to function properly can be expressed in the same way in which components are added to an openmrs-distro.properties
file. However, the biggest difference is that - instead of requiring a specific version, content properties support version ranges. For full documentation on how version ranges can be expressed, please consult the semver4j documentation. However, the most common example will be requiring an artifact that is >=x.y.z
. Below are some example properties showing how to indicate that components of each supported type might be required:
# Platform minimum version
war.openmrs=>=2.4.0
# Backend modules
omod.fhir2=>=1.8.0
omod.webservices.rest=>=2.42.0
omod.initializer=>=2.5.2
# Owas
owa.orderentry=>=1.2.4
# Frontend modules
spa.frontendModules.@openmrs/esm-patient-chart-app=>=8.1.0
Variable properties:
It is quite common for a content package to define new metadata that it requires, along with configurations that use that metadata. Variables provide a means to support 3 primary use cases around this:
If the same value (e.g. a particular concept uuid) is used across one’s content package in several files, one can extract that out to a variable, and then reference that variable in each file where it is needed. This eliminates copying the same hard-coded value throughout one’s configuration.
If the author of a content package wants to support both new implementations with suitable default values, and also wants to support existing implementations that may already have some of the needed metadata in place with different identifiers (e.g. existing encounter types with different uuids than the defaults provided by the package author), then the author can extract such values out into variables with defaults. This will allow consumers to use or override these defaults via properties added to their
openmrs-distro.properties
file if needed.If the author of a content package wants to require that a consumer explicitly provides a value into their content package, for which there is no appropriate default, then the author can declare this variable without a default value in their
content.properties
. Including such a content package in a distribution will cause that distribution to fail to build until the distribution author provides a suitable value in theiropenmrs-distro.properties
file.
Variables are defined as used as follows:
Within the content.properties
file, add a new property with the var.
prefix:
var.concept.height.uuid=5090AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
var.concept.weight.uuid=5089AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
And then within any of the configuration
files, you would add a variable reference like follows (here you do not include the var.
prefix:
A consuming distribution could then include this content package and override these variables as follows: