.. _narrativegeneration:
Narrative Generation
====================
Narrative generation is a programmed mapping that automatically produces an HTML narrative for a FHIR resource during openEHR → FHIR mapping. It is powered by `Thymeleaf `_ templates and HAPI NarrativeGeneration logic and runs as part of the normal mapping pipeline.
.. note::
Narrative generation only applies in the openEHR → FHIR direction.
How it works
____________
When ``generateNarrative`` is declared as a ``mappingCode`` on a mapping, openFHIR assembles the mapped FHIR resource (or the section entries referenced by it), selects the appropriate Thymeleaf template, renders the HTML, and sets the result to the fhirPath indicated in `with.fhir`.
``generateNarrative`` accepts two arguments, first one is a fhirPath to a Resource (or resources) for which narrative will try to be generated. Second argument is optional and it's a profile that will be used for narrowing down available HTML templates to pick.
Template selection is determined in the following order:
1. If a profile URL is passed as the second argument, openFHIR looks for a template registered for that profile.
2. Otherwise it falls back to a template registered for the resource type.
Defining it in a mapping
________________________
Add a ``mappingCode`` entry to any mapping in a model mapper. The ``with`` block is omitted — ``mappingCode`` replaces it.
**Basic usage** (template selected by resource type):
.. code-block:: yaml
- name: "narrativeText"
with:
fhir: "text"
openehr: "$composition"
mappingCode: "generateNarrative(entry)"
unidirectional: "openehr->fhir"
**Profile-scoped usage** (template selected by profile URL):
.. code-block:: yaml
- name: "narrativeText"
with:
fhir: "text"
openehr: "$composition"
mappingCode: "generateNarrative(entry, http://hl7.org/fhir/uv/ips/StructureDefinition/Composition-uv-ips)"
unidirectional: "openehr->fhir"
The ``entry`` argument refers to the section entries of the resource being mapped. The ``unidirectional: "openehr->fhir"`` field should always be set so the mapping is skipped in the FHIR → openEHR direction.
Configuring templates
_____________________
openFHIR ships with built-in narrative templates for common IPS resource types. You can override these or register additional templates by pointing openFHIR at a properties file.
**Step 1 — configure the properties file location:**
.. code-block:: yaml
openfhir:
narrative:
properties-file: file:/config/openfhir-narratives.properties
The value accepts both ``classpath:`` and ``file:`` prefixes. When using Docker, mount your properties file and templates into the container and use ``file:`` paths.
**Step 2 — define templates in the properties file:**
Each template entry consists of three keys sharing a common prefix:
.. code-block:: properties
bundle_conditions.resourceType=Bundle
bundle_conditions.narrative=file:/config/condition-narrative-template.html
bundle_conditions.profile=http://hl7.org/fhir/uv/ips/StructureDefinition/Composition-uv-ips
* ``resourceType`` — the FHIR resource type this template applies to
* ``narrative`` — path to the Thymeleaf HTML template (``classpath:`` or ``file:``)
* ``profile`` — *(optional)* profile URL; when set, this template is only selected when the profile matches the argument passed to ``generateNarrative``
Multiple templates can be registered in the same file using different prefixes.
Writing a template
__________________
Templates are standard Thymeleaf HTML fragments. The root variable exposed to the template is ``${resource}``, which is the HAPI FHIR resource object being rendered. For ``Bundle`` resources, iterate over ``${resource.entry}`` to access individual entries.
Example template for a Condition section:
.. code-block:: html
.. note::
Always guard rows with a resource type check (``entry.getResource().fhirType() == 'Condition'``) when iterating over a Bundle that may contain mixed resource types. Without this guard, calling a type-specific method on the wrong resource type will throw a runtime error.
.. note::
Narrative generation leverages HAPI's implementation. See https://hapifhir.io/hapi-fhir/docs/model/narrative_generation.html for more information.