This repository contains a proof of concept tool that allows users to render a frontend for SNOMED Expression Template Language (ETL) templates. More information on the ETL spec can be found at https://confluence.ihtsdotools.org/display/DOCSTS/6.1.%2BExpression%2BTemplate%2BLanguage. The aim of this tool is to simplify working with SNOMED postcoordination. The means by which we aimed to simplify this process is through using ETL, and automated rendering of a GUI.
After filling the required slots in the ETL, the GUI generates both a string that can be used as a readable string for the postcoordination string, and the postcoordination string.
Each template is stored as a separate xml-file in /SnomedTemplateService.Web/SnomedTemplates/{organisation name}/. An example and xsd are provided in /model/. The filename should contain a descripion of the template's purpose followed by a timestamp. Replace {organisation name} with the name of your organisation in the file path in order to clearly state the owner of the template.
Each template should contain the following metadata:
- One or more authors, with name and contact email
- Title
- Description
- Snomed version
- Snomed branch
- One or more tags, to improve the templates findability
The etl element should contain the template, composed in Expression Template Language (ETL). The specification of this syntax can be read at https://confluence.ihtsdotools.org/display/DOCSTS/6.1.+Expression+Template+Language. It is a member of a syntax family that was developed by Snomed International to support postcoordination and analysis using SNOMED.
An ETL expression is basically a postcoordination, where some of the focus concepts, attributes or target values have been replaced by an expression constraint. This is especially useful if you need to create multiple complex but similar postcoordinations, for instance 30 separate postcoordinations for the OREF (open reducation and external fixation) of a fracture of 30 different bones in the body. The template for that comes down to the postcoordination for OREF of fracture, with as procedure site an expression constraint encompassing all bones:
‹etl›
‹![CDATA[
=== 86480004 |open reductie van fractuur (verrichting)| :
{
[[ @Locatie ]] 405813007 |directe locatie van verrichting (attribuut)| = [[+id(<< 272673000 |botstructuur (lichaamsstructuur)|),
424226004 |met gebruik van hulpmiddel (attribuut)| = 261200006 |extern fixatiesysteem (fysiek object)|,
260686004 |methode (attribuut)| = 129371009 |fixatie (kwalificatiewaarde)|,
363700003 |directe morfologie (attribuut)| = 72704001 |fractuur (afwijkende morfologie)|
}
{
[[ @Locatie ]] 405813007 |directe locatie van verrichting (attribuut)| = [[+id(<< 272673000 |botstructuur (lichaamsstructuur)|),
363700003 |directe morfologie (attribuut)| = 72704001 |fractuur (afwijkende morfologie)|,
260686004 |methode (attribuut)| = 426530000 |open reduceren (kwalificatiewaarde)|
}
]]›
‹/etl›
Square brackets mark the places where expression constraints and interface annotations are inserted.
Always check your ETL syntax against https://apg.ihtsdotools.org/SCT-etl.html before deploying, in order to ensure that your syntax is valid.
You can use @ to mark where annotations are applicable, which will be shown in the interface. For instance, the template in the example contains a single annotation which should be shown in two places, i.e. each of the location slots. The annotation's identifier is Locatie. You can specify the text to show in the user interface in an item element:
‹items›
‹item›
‹title›Locatie‹/title›
‹description›Welk bot?‹/description›
‹/item›
‹/items›
The stringFormat element allows you to specify the natural language representation of the template: how the postcoordinations that are created with the template should be presented as human-readable text. For instance, the template above might have the format:
‹stringFormat›Open reductie van [1/0] en externe fixatie van [0/0]‹/stringFormat›
The first number refers to the attribute group, the second to the slot within the attribute group. In this template there are two groups with one slot each, hence the identifiers [0/0] and [1/0]. Please note that in this example, the second slot is actually presented first in the human-readable text!
If you are unsure of the identifiers for each slot, the frontend page for each template contains a debug output for this purpose. You can find this expandable expansion panel on the bottom of the template page, titled: '[DEBUG] Identifiers voor gebruik in leesbare titel'.
This tool is designed to be deployed as a docker-compose stack.
If you want to further develop the tooling, or locally add and test templates, you can "run docker-compose up" in the root of the repository. This will build the node and templateparser containers and run them on ports 9124 and 9125.
After making changes to templates, be sure to rebuild the templateparser container with --no-cache "docker-compose build --no-cache templateparser".
The production docker-compose can be run using "docker-compose -f docker-compose_prod.yml up". In this stack, an nginx container has been added. This particular compose file has been written to notify a reverse proxy service that it wants to receive all requests sent to a particular URI, including requesting a letsencrypt certificate. For your own server, this will probably not work. You should redirect all traffic for this service to the nginx container. The nginx configuration in this repository will redirect all traffic / to the node container, and templates/ to the templateparser.
In this proof of concept, many URI's have been hardcoded. In the future this will change.
Change the URI (https://snowstorm.test-nictiz.nl/) to your own preferred Snowstorm server (https://github.com/IHTSDO/snowstorm/) in all files in the folder vue/src/components/templateFrontend/. Using the default snowstorm server for anything other than very infrequent testing is not allowed.
This service has been created as a proof of concept by people with an interest in postcoordination. Not all of us are trained software developers, and will definitely have made some mistakes. We strive for valid output based on valid input.
First things first: we welcome all contributions to the project. Be it philosophical in nature or by improving the codebase.
If you would like to contribute to this project in order to improve this fully functional open source stack, please do so! You can contribute by opening issues for bugs or improvement requests, forking the repository and creating a pull request, or any other way you see fit. Pointing potential users of the tool to our repository is also a great way to contribute.
If you have the expertise to create templates and would like to add these to this stack; please feel free to fork the repository, add your templates in a new folder following the above instructions, and create a pull request. We will ensure the templates are valid before merging the pull request, but making sure the templates adhere to the SNOMED concept model is your responsibility. After merging, the added templates will be made available on our public server.
This tool will remain open source. The biggest future planned projects include adding a GUI template editor and FHIR questionnaire API for the templates. All templates created by the contributors will be made publicly available.