IG Publisher Documentation

From HL7Wiki
Jump to navigation Jump to search

Control file

When the IG publisher is executed, it is pointed at a control file. This is a json file that contains all the information that the publisher needs to publish the implementation guide. It has this structure:

 {
   "source": "[ig]", // the name of the ImplementationGuide resource file to load
   "version" : "[optional - see below]",
   "fixed-business-version" : "[optional - see below]",
   "logging" : "[optional - see below]",
   "html-template" : "[optional - see below]",
   "paths" : { // see paths below
     "resources" : [
       "[resourcesFolder]"
      ],
     "pages" : [
       "[pagesFolder]"
     ],
     "temp" : "[temp]",
     "output" : "[output]",
     "txCache" : "[txCache]",
     "qa" : "[qa]",
     "history" : "[history page]",
     "specification" : "[specification]"
   },
   "language" : "[language]", // see 'Language support' below
   "languages" : [
     "[language]"
   ]
   "pre-process" : [{ // optional section see below
      "folder" : "[folder]",
      "transform" : "[xslt file (conditional)]",
      "relativePath" : "[relative path (conditional)]"
   }],
   "sct-edition" : "[uri - see below]",
   "no-inactive-codes" : "true | false",
   "gen-examples" : "true", // optional, see below (processing options)
   "do-transforms" : "true", // optional, see below (processing options)
   "canonicalBase": "[where this will be published - see above]",
   "dependencyList": [
     // a list of other implementation guides that this guide depends on
     // e.g. uses profiles, value sets, code systems etc
     // zero or more of this object:
     {
        "name" : "[name of the IG, for logging, and Jekyll variable name for location]",
        "location" : "[http address where the IG lives]",
        "source" : "[folder to get the definitions from if running ahead of publication at location (relative)]"
     }
   ],
   "extension-domains" : [ 
     "[url]" // list of domains from which undeclared extensions are allowed to come from
   ]
   // Templates lists any additional templates beyond "base" and "format" that can be generated for one or more artifact types
   // The list of template names below are examples
   "extraTemplates": ["mapping", "foo", "bar"],
   "defaults": {
     // this object contains the default publishing policy for different types. 
     // Anything not mentioned defaults to true
     "Any": {
       // fragment and template options - see below. example:
       "xml" : false // don't produce xml example
       "template-base" : "sometemplatefile.html"  // use this as the default template for all base pages if not overridden
     },
     "[Type]": {
       // fragment and template options - see below
     }
   },
   "spreadsheets" : [
     "[filename]" // see using spreadsheets
   ], 
   "bundles" : [
     "[id]" // see using bundles below
   ],
   "resources": {
     "[Type]/[id]": {
       "source" : "[optional source file]", 
       "version" : "[optional version]",
       // template and fragment options - see below.  E.g.
       "base": "[overridden name for destination page for things referring to this resource]",
       "template-defns": "[template to use for resource definitions]",
     }
   },
   "special-urls" : [
     // list of special URLs - see below
   ],
   "tool" : "jekyll" // the tool used for the 3rd step of the build. See tooling below
 }

The control file must be maintained by the editor of the implementation guide.

Version

The IG publisher lives in the current build (http://build.fhir.org), where it is maintained in an ongoing fashion. The IG publisher knows how to publish IGs for the following versions:

  • 1.0.2: DSTU2
  • 1.4.0: May 2016 draft release (supported for some stakeholders who use it, and make that possible)
  • 3.0.0: DSTU3
  • [current] - the current build.

The IG publisher may work with other versions (e.g. forks of R4 candidate versions) but this is not guaranteed.

If you are using a version other than the current build, you need to specify the version in the control file:

 "version" : "1.0.2"

Business Version

You can impose a fixed business version on all the conformance resources using

 "fixed-business-version" : "1.2"

If you use this, then the version element in the source for all the conformance resources in the IG must be either the same as the nominated business version, or empty.

This approach to profile versioning means that profiles do not need to have their cannonical URLs changed when substantive changes are made (nor do references to those profiles need to be updated). Instead, all profile references within an IG simply use a consistent canonical URL. When instances declare the profile in an instance, they combine the canonical URL with the profile/IG version as follows:

[someurl]|[someVersion]

E.g. <profile value="http://example.org/fhir/StructureDefinition/someProfileId%7C1.2"/>

This tells the validator which version of the profile must be used when validating the instance.

Paths

The IG publisher defines the following paths that can be configured in the control file:

  • [resources]: the directory or set of directories where all the input FHIR resources are found (usually conformance resources and examples). Multiple directories can be used to allow source files to be grouped - e.g. separate folders for examples, vocabulary-related files and 'other' files.
  • [pages]: the directory or set of directories that contain the jekyll source (not process, just passed to Jekyll for processing). Multiple directories can be used if it makes implementation guide maintenance easier to separate certain files. (Also see pre-process.)
  • [temp]: a scratch directory that is used for the temporary source for jekyll processing (do not use this directory for anything else)
  • [output]: where the final output from the tool (the complete IG) will be placed
  • [qa]: a folder where the validation output (validation.html) will be produced, along with a page for each fragment (for css style checking)
  • [txCache]: where the terminology service cache goes. see below.
  • [history page]: the page that lists the history of the implementation guide. This page is manually managed when the IG is published formally, so it is not produced (and cannot be produced) but is not listed as a broken link

All these folders are file paths that are relative to the control file. They are usually sub-folders, for version control/build convenience, but do not need to be. There is one more path:

  • [specification]

This is an HTTP page (http:// or file:// that points to the version of the specification on which this IG is based (use a version specific reference, not http://hl7.org/fhir itself, unless the IG is synced to the current build). It should also be the version on which the IG itself is based.

DependencyList

As stated above this is a list of other implementation guides that this guide depends on. For example building a profile upon a another profile or referencing another profile's structuredefinitions, value sets, code systems etc.

an example of this would be:

  "dependencyList": [
   
    {
       "name" : "uscore",
       "location" : "http://hl7.org/fhir/us/core",
       "source" : "definitions.json.zip"
    }

Note that a source file is generated by the IG publisher. This definitions folder 'lives' in the resources folder specified in the "[resources]" path defined above.

In theory, all extensions that are referred to should be from Implementation Guides explicitly listed in the dependencyList. However, for a variety of reasons, that's not always possible. So particular domains that are explicitly allowed as unregistered extensions can be added using the allowed-domains list - an array of strings:

 "allowed-domains" : [
   "http://my.server.url"
 ]

Terminology Service Cache

The IG Publisher uses a terminology server to support it's operations (presently, this is fhir3.healthintersections.com/au, but is planned to move to tx.fhir.org soon). In order to improve operational performance, the IG publisher caches the outcome of all interactions with the terminology server. This makes a substantial difference to the performance of the publication, but also means that there's a risk of the terminology content becoming stale.

IG authors can choose to put the terminology cache into version control. This means that all builds (either by authors or by CI builds) get the same content, and reduces the load on the terminology server. Also, all authors get fully efficient publication. This also means that flushing the terminology cache is under the control of the editors process. It also means that editors have to commit the contents of the txCache when committing. Note that there is never any reason not to simply commit whatever changes have happened, and no user review is needed on this.

Note that the CI build does not maintain it's own persistent cache; if the terminology cache is not in version control, it will not have a terminology cache.

There are several ways to delete the terminology service cache:

  • find the directory and manually delete content from it (e.g. all files). This is can be done safely at any time
  • run the IG Publisher with the parameter -resetTx - this clears the folder
  • run the IG Publisher with the parameter -resetTxErrors - this clears the folder of any errors from the terminology server but keeps successful operations
  • the terminology cache will be flushed completely when the terminology server is upgraded

Terminology Options

If you use SNOMED CT, you must specify a SNOMED CT Edition to use:

 "sct-edition" : "http://snomed.info/sct/[module]",

where [module] comes from this list:

  • International: 900000000000207008
  • us: 731000124108
  • AU: 32506021000036107
  • Spanish: 449081005
  • Danish: 554471000005108
  • Dutch: 11000146104
  • Swedish: 45991000052106
  • UK: 999000041000000102
  • CA: 20611000087101

Note that you can only specify a version supported by the infrastructure (currently: International, US, AU, CA). You can specify a version if you want (but it will fail if this is a different version to the infrastructure). You will have to delete the terminology cache if you change this value.

In addition to this, you can specify whether to include inactive codes or not:

   "activeOnly" : "true",

By default, inactive codes are included

Pre-processing Pages

The IG publisher can pre-process pages. If you specify a pre-process option, then the IG publisher will copy the content from the pre-process directory and will then do one or more of two things:

  • rather than putting it directly in the "pages" folder, will place it in the designated subfolder of pages. This allows pointing to a folder that contains content intended to map to _data, _includes or some other sub-folder without needing to create a directory hierarcy in the implementation guide's source files
  • executing the specified transform on it as it copies the content. Directory structure will be preserved. Note: changes to the transform are not picked up when running in -watch mode.

The transform engine uses XSLT1 not XSLT2 (e.g. the standard java transform engine).

Processing Options

These are global flags that control FHIR specific pre-processing associated of profiles. All the flags default to false.

Fragment & Template Options

When deciding whether to produce a particular kind of fragment, the IG Publisher will look for a property of type boolean with the name given below. Similarly, when deciding to produce a particular type of web page, it will look for a template file (also described below).

In either case, it will look in the following places, in order:

  • on the resource entry for the resource in question
  • on the defaults entry for the resource type in question
  • on the defaults entry for "ANY"

For fragment codes, if the IG tool doesn't find anything, it will produce the fragment. For templates, if no template is found, it will NOT produce an output page.

Fragment Codes

There will be one each of these fragments for each resource type that is found:

  • xml: XML version of the resource (all resource types)
  • json: JSON version of the resource (all resource types)
  • ttl: Turtle version of the resource (all resource types)
  • xml-html: html representation of XML version of the resource (all resource types)
  • json-html: html representation of JSON version of the resource (all resource types)
  • ttl-html: html representation of Turtle version of the resource (all resource types)
  • html: narrative of resource as html
  • summary: An html summary for the resource (all conformance resources)
  • content: An HTML representation of the content in resource (code system, concept map, structure map)
  • xref: A list of all the places where the resource is used (all conformance resources)
  • cld: An HTML representation of the content in resource (value set)
  • expansion: The expansion of the value set (Value set)
  • shex: ShEx statement for the structure (Structure Definition)
  • sch: schematron statement for the structure (Structure Definition)
  • json-schema: JSON Schema statement for the structure (Structure Definition)
  • header: Description of the identification of the structure (Structure Definition)
  • diff: Logical Table of the diff (Structure Definition)
  • snapshot: Logical Table of the snapshot (Structure Definition)
  • pseudo-xml: XML template for the snapshot (Structure Definition);
  • pseudo-json: JSON template for the snapshot (Structure Definition)
  • pseudo-ttl: Turtle template for the snapshot (Structure Definition)
  • uml: UML diagram for the structure (Structure Definition)
  • tx: Terminology Notes for the structure (Structure Definition)
  • inv: invariant summary for the structure (Structure Definition)
  • dict: Detailed Element Definitions (Structure Definition)
  • maps: Presentation of the mappings (Structure Definition)
  • span: Presentation of all profiles a profile refers to (StructureDefinition where derivation = constraint)
  • spanall: Presentation of all profiles & base resources a profile refers to (StructureDefinition where derivation = constraint)
  • script: Script language rendition of a StructureMap (StructureMap)
  • profiles: List of Profiles generated from a StructureMap (StructureMap)

In addition, the publisher produces the following set of fragments for listing all the content:

  • list-[type].xhtml
  • table-[type].xhtml

If there are any structure definitions of the right type, the publisher will also produce the following:

  • table-profiles.xhtml & list-profiles.xhtml
  • table-extensions.xhtml & list-extensions.xhtml
  • table-logicals.xhtml & list-logicals.xhtml

Page templates

The IG tooling can automatically generate 0 or more HTML pages for each type of resource included in the IG. To generate files for resources, a template file must be declared that provides the base structure for what the resource file should look like. The template file will be a jekyll source file (e.g. html or markdown etc.) containing imports, variable references and other embedded control tags used by the static generation tool to produce the fully populated resource-specific pages.

The template can be declared in the default section for ANY or a specific type or for a specific artifact id. There are three standard templates available:

  • template-base defines the base page that acts as the home page when references are encountered to that resource. Each resource should have one of these
  • template-defns defines the base that provides the data dictionary with anchors for each data element in a structure definition. (In the future, this may be applicable to other resources too - let us know)
  • template-fmt defines the page format for pretty-printed views of the JSON, XML and TTL representations of the resource.

The file names of these generated pages will default to the following:

  • base: [ResourceType]-[id].html
  • defns: [ResourceType]-[id]-definitions.html
  • fmt: [ResourceType]-[id].[fmt].html where [fmt] is xml, json and ttl

In addition to these, additional template types can be declared (e.g. for mappings, lists of referenced elements, etc.) To provide support for additional template types, the name of each template type must be included in the extraTemplates list. This name is appended to "template-" to create the name of the template tag. (For example, "template-mapping", "template-foo" and "template-bar" in the example above.) The default file name is [ResourceType]-[id]-[templateName].html, for example [ResourceType]-[id]-mapping.html.

These file names can be overridden on a per-resource instance basis by declaring an alternate name in the resource declaration. For example,

 "StructureDefinition/123": {
   "base": "my123.html",
   "defns": "my123-defs.html"
 }

When the template files are used, they are pre-processed and then copied to the correct place for the xml/json/ttl wrapper for each resource. When copied, the following strings will be replaced:

  • {{[title]}} - a description of the content of the resource (typical use: <h2>{{[title]}}</h2>)
  • {{[name]}} - the path for the source fragment to include (proper use: {% include {{[name]}}.xhtml %})
  • {{[id]}} - the id of the resource
  • [[[type]}} - the type of the resource
  • [[[uid]}} - type-id (combination)

HTML Template

In addition to the pages generated from artifacts, implementation guides will typically have non-generated HTML pages that provide navigation, background and other supporting information. In most IGs, these pages will follow a typical pattern in terms of header and footer, with only the "body" of the page changing. To allow this content to be edited in pure XHTML (with schema validation support), the IG publisher allows identifying a Jekyll template file that is to be used for some or all such files. The tool will look for HTML pages that are referenced in the implementation guide file but are not present in the pages folder. For each one found, it will look for a corresponding XML file and apply the templates specified with the html-template property.

Loading Resources

Resources are loaded as follows:

  • The IG resource is loaded (by literal filename)
  • any spreadsheets are loaded (by literal filename) and converted to resources (for editor support, all the identities of the generated resources are noted in the validation output)
  • any bundles are loaded (by Type/id)
  • any resources referenced in the IG resource are loaded (by Type/Id)

Note: The IG resource must use sourceReference references by id. e.g.

 <sourceReference>
   <reference value="ValueSet/my-value-set"/>
 </sourceReference>

A Type/Id reference is resolved to a to a local file by the control file, using the object /resources/"[Type]/[id]". If this object does not exist, the IG publication will fail. If this object exists, and has no "source" property, then the source property specifies the location of the file source relative to the IG file. If there is no "source" property, the IG publisher will look for [resources]/[Type]-[id].xml/json or [Type]-[id].xml/json (it's at editor discretion whether to store files using the simpler form, since this can cause conflicts between different resources with the same id (e.g. both Patient and Practitioner with the id of 'example')

By default, the version of the input resource is assumed to be the same version is the IG Publisher itself. However the IG publisher can also load resources from Forge. in order to load resources from forge, specify the version "1.0.1" for each forge resource. Note: this is only known to work reliably for StructureDefinition resources

Using Bundles

There's 2 different ways to use Bundles. The first way is examples of type Bundle. These are treated like any other resource. The second is where the bundle is a collection that contains a set of resources that need to be processed individually by the IG Publisher. To specify one of these bundles, use the "bundles" property:

   "bundles" : [
     "[id]"
   ]

The bundles property is an array of strings, where each entry is the id of a bundle. The bundle will be located using the standard resource location process, but once loaded, the bundle itself will be ignored, and the individual resources processed directly. Each resource in the bundle must have an entry in the resources section, and should be entered in the implementation guide.

Using Spreadsheets

For legacy reasons, it's possible to author profiles using spreadsheets. This approach is deprecated. To get the IG publisher to process a spreadsheet:

   "spreadsheets" : [
     "[filename]"
   ]

This is an array of strings, which each entry is the filename of the spreadsheet, relative to the control file. Each resource represented in the spreadsheet (profiles, value sets, search parameters) must have an entry in the resources section, and should be entered in the implementation guide. Note that the loading is order dependent - the author must ensure dependent profiles are listed and loaded after the ones they depend on.

There's some differences between the spreadsheets used in the build directly, and the spreadsheets used by the IG Publisher, and these are changes that must be made manually:

  • Value Set references - use either
    • ValueSet/xxx a reference to a value set defined in the IG, and registered directly in the implemnentation guide resource
    • http(s)://... a reference to a value set from outside the IG, or in the IG
    • valueset-xxx where:
      • valueset-xxx is the name of a file found in the same directory as the spreadsheet
      • The filename must not have .xml or .json on it, but a file with either .xml or .json appended to it must exist
      • The file must be a ValueSet resource, with an id of xxx and the appropriate canonical URL
  • Search Parameters
    • You have to provide a fluent path expression directly ("Expression")
    • you have to provide a description directly
    • you have to specify the target types directly
  • Types
    • the build tool allows for the use of "SimpleQuantity" and other data type profiles (not that the build tool uses any other) as types, but they have to be invoked as profiles in the IG spreadsheets
    • You can specify ElementDefinition.type.versioning by appending a ~ then the versioning code to the type
  • Note that IG publisher enforces the use of correct ids and canonical URLs against the base stated in the control file

Special URLs

For MetadataResources - CodeSystem, ValueSet, etc (anything with a canonical URL) - the IG publisher expects that their Canonical URL is equal to [canonical]/[type]/[id] where [canonical is the IG canonical URL. The IG publisher will ensure that the IG itself is an valid FHIR implementation guide and responds correctly to requests for the resources by their canonical URL.

However in some cases, it's not possible or appropriate for a metadata resource to use the same canonical URL as where the IG is publishing it. In these cases, the URLs that are exempt from this rules need to listed explicitly in the special-urls property, which is array of strings that are the exempt URLs.

Notes:

  • URLs have to be explicitly listed because it's too easy for an author to make a mistake and get the canonical URL wrong
  • one case for using this facility is where the IG includes a resource that is also published elsewhere. Author's should think hard before doing this - referring to a resource by it's canonical URL rather than copying into the IG is generally a much better in terms of ongoing maintenance.