On this page ⌄
Configure a screen from FHIR data
Change which FHIR fields a Player client screen renders, without modifying application code.
What you can change
Which FHIR fields a screen reads, how they are composed into view state, and which renderer options apply. None of it requires changing application code.
What you cannot change this way is how the view state is drawn. That needs a renderer, which is code. See decide when code is necessary.
Read the configuration model first if the pieces below are unfamiliar.
Where the configuration lives
Configuration ships with the reference application as FHIR Binary resources, under this path.
ohs-player-reference-app/src/commonMain/composeResources/files/
Three directories divide it by role.
| Directory | Holds |
|---|---|
states/ | ViewDefinition and ViewJoinMap resources |
configs/ | ViewConfig resources |
viewtypes/ | The CodeSystem of view types renderers register against |
Change what a screen shows
1. Project the fields. Add or update a ViewDefinition in states/, for example Binary-PatientSummary.json.
Each field is a column with a name, a FHIRPath expression that fills it, and a type. Here is one column, excerpted.
{
"name": "familyName",
"path": "name.family.first()",
"type": "http://hl7.org/fhir/StructureDefinition/string"
}
2. Name the view state. Add or update its ViewJoinMap in states/, which binds the named state to its pivot view. These are short enough to read whole. This is Binary-PatientSummaryState.json in full.
{
"resourceType": "http://ohs.dev/StructureDefinition/ViewJoinMap",
"name": "patientSummary",
"from": "root",
"resource": "Patient",
"view": "PatientSummary"
}
3. Set renderer options. Add or update a ViewConfig in configs/, such as Binary-PatientCardConfig.json.
4. Build. The ig-codegen Gradle plugin runs as part of compilation and generates the matching Kotlin state and configuration types. There is no separate generation step to remember.
./gradlew :ohs-player-reference-app:run
How the application picks it up
The reference application loads configuration through LocalConfigSource and ConfigStore, then calls GenericStateExtractor.extract<T>() to turn a FHIR SearchResult into the generated state type.
You do not wire any of that per screen. Adding a field means updating the ViewDefinition, building, and using the regenerated field in the renderer that already draws that state.
When a change needs a new view type
Introducing a genuinely new kind of presentation (not new fields, but a new way of drawing them) crosses into code.
- Add a view type to
viewtypes/CodeSystem-ViewTypes.json. - Build, so
ig-codegengenerates the matchingViewTypeCSentry. - Implement a
ComponentRenderer, register it in theViewRegistryunder that view type, and render the state withListScaffoldorDetailScaffold.
Steps 1 and 2 are configuration, and step 3 is application code. Decide when code is necessary covers how to tell in advance which side of that line a change falls on.
Expected result
Rebuild and the screen renders the fields you projected. If a field is missing, the usual cause is the FHIRPath expression rather than the wiring. A path that matches nothing yields an empty column rather than an error.
Where to go next
Decide when code is necessary for changes that may need a renderer.
For renderer API detail use the Player Client repository, and for the complete configuration definitions and examples use the Player Configuration IG.