VEF-based viewers allow users to style the popup and sidebar metadata that appears when users click on features on the map, improving readability and visualization. Templates are based on the Markdown language and allow for flexible customization of metadata rendering. Predefined function calls allow the use of advanced visualizations, such as displaying charts or a video player. Without the use of templates, the original metadata is displayed in a simple table, using the technical names of each property.
The folliowing screenshots are taken from a VEF-based viewer using the same clicked feature
Unstyled Metadata | Styled Metadata |
---|---|
The metadata templates are based on the lightweight markup language Markdown. Markdown has a lot of flexibility for formatting text and is human-readable in its unparsed form.
To display the metadata properties, they must be enclosed in curly braces. The metadata is inside an object and can be accessed using dot notation or like dictionary entries.
The root for the displayed metadata is structured like a GeoJSON feature and contains a geometry, properties, and layer object.
A predefined list of function calls can be used to perform additional metadata transformations. Function calls must also be enclosed in curly brackets and use round brackets to enclose parameters.
Function parameters can be a string or a reference to a property from the properties, layer, or geometry object. When passing numbers, they must be passed as strings enclosed in quotes.
Notation | Explanation |
---|---|
{properties.expediton} | Accessing the Property "expedition" from the clicked feature |
{properties["general.name"]} | Accesses the "event.name" property of the clicked feature. Dot notation cannot be used here because the property name itself contains a dot. |
{layer.name} | Acccesses the name of the layer itself |
{formatDate(properties.date_time_end)} | Calls a custom function to format a date string using the" date_time_end" property as a parameter. |
{addFilterButton("device", properties.device)} | Calls a custom function with two parameters to display a filter button in the table column that filters by device. |
Name | Description |
---|---|
formatLatLng(latitude, longitude) | Format lat/lng into a readable string with decimal degrees Example: {formatLatLng(properties.begin_latitude, properties.begin_longitude)} |
formatGeometry(geometry) | Format the geojson geometry and display it as human-readable coordinates. Works only for type=point Example: {formatGeometry(geometry)} |
addFilterButton(name, value) | Add a button to request filtering by an attribute Example: {addFilterButton("platform", properties.platform)} |
formatDate(isoDateString) | Make ISO timestamps more readable Example: {formatDate(properties.date_time_start)} |
isDefined(valueToCheck, then, else) | Returns the given string only if the first value is not null or undefined. Used as a way to implement conditions. Uses the optional else-value if not defined. Example: {isDefined(properties.date_time_end, "Date Time Start", "Date Time")} |
concatIfDefined(concat1, concat2, ...) | Concatenate values if each value is defined (not null or undefined) Example: {concatIfDefined(properties.elevation, " m")} |
encodeURLComponent(urlComponent) | Encode String to URL Compatible characters Example: {encodeURLComponent("PS133/2_0_Underway-6")} |
round(number, decimals) | Round a number to the specified decimal places Example: {round("1.12345", "3")} |
splitString(string, substring, index) | Split a string at a substring and return the given index Example: {splitString("Hello World", " ", "1")} |
substring(string, startIndex, endIndex) | Split a string at an index and get the substring Example: {substring("Hello World", "0", "5")} |
setTitle(str1, str2, ...) | Defines the title in data-title for the entire popup feature. The PopupRenderer will extract the title from this property to display it in the header. This is set directly in the container. Example: {setTitle("Event: ", properties.event)} |
parseJSON(jsonstring, key1, key2, ...) | Parses a json string and returns the value of the given property identified by the list of keys. Example: {parseJSON('{"outer": {"inner": "Hello World"}}', "outer", "inner")} |
noCopy() | Prevents the copy button from being displayed in a table row |
hideOnSiteStart(site) hideOnSiteEnd(site) | Prevents content from being rendered by inserting a comment when the page matches. These functions must be used together to mark an area to remove Example: {hideOnSiteStart("gallery")} ...... {hideOnSiteEnd("gallery")} |
parseMarkdown(text) | Parse markdown text to html. Useful when text from a variable/property is formatted as markdown e.g. layer.abstract Example: {parseMarkdown(layer.abstract)} |
joinArray(array, seperator) | Join Array values as a string. Default seperator is ", " Example: {joinArray(array, " - ")} |
displayLayerLegend() | Display the active layers legend graphic |
displayImage(src, width (optional), height (optional), srcset (optional)) | Display an image. Clicking on an image opens it in a full-screen, zoomable lightbox. Example: {displayImage(propertie.picture, properties.width, properties.height, properties.srcset)} |
displayVideo(media, width, height, thumbnail (optional), cover (optional), poster (optional)) | The following keys are supported: "media" (url to media file), thumbnail (url to webvtt file for seekbar thumbnails), cover (url to video cover) and poster (url to background poster on video player loading). They contain the respective urls. Example: {displayVideo(properties.video, properties.width, properties.height, properties.thumbnail, propertie.cover)} |
displayVideoPlayerKeys() | Displays a link to open a documentation of video player hotkeys. |
The resulting HTML markup is modified by the viewer after the templates have been evaluated for optimal visualization of the metadata.
{isDefined(properties.attachment_url, "<h3>Cruise Overview</h3>")} {displayImage(properties.attachment_url)} {isDefined(properties.attachment_url, "<h3 class='collapsed'>Measurement Plot</h3>")} {marehubOverviewPlot()} ### Space & Time | | | |--|--| | {isDefined(properties.date_time_end, "Date Time Start", "Date Time")} | {formatDate(properties.date_time_start)} | | Date Time End | {formatDate(properties.date_time_end)} | | Coordinates | {formatGeometry(geometry)} | | Elevation | {concatIfDefined(properties.elevation, " m")} | ### Event | | | |--|--| | Expedition | [{properties.expedition}](https://marine-data.de/?site=expedition&expedition={encodeURLComponent(properties.expedition)}") {addFilterButton("expedition", properties.expedition)} | | Expedition Alias | {properties.expedition_alias} | | Event | [{properties.event}](https://marine-data.de/?site=data&qf=events.name/{encodeURLComponent(properties.event)}") {addFilterButton("event", properties.event)} | | Event Alias | {properties.event_alias} | | Platform | {properties.platform} {addFilterButton("platform", properties.platform)} | | Device | {properties.device} {addFilterButton("device", properties.device)} | | Sensor URI | [{properties.sensor_uri}]({properties.sensor_uri}) | ### Data | | | |--|--| | Aggregation Type | {properties.ov_type} {addFilterButton("ov_type", properties.ov_type)} | | Current Velocity | {getMarehubOverviewValue("values_mag")} | | Current Direction | {getMarehubOverviewValue("values_dir", "°")} | | {isDefined(properties.parameter_name, properties.parameter_name, "Value")} | {getMarehubOverviewValue()} | | Method | {properties.method} {addFilterButton("method", properties.method)}| | {isDefined(properties.depth_type, properties.depth_type, "Depth")} | {getMarehubOverviewValue("depths", "m")} | #### View Original Data | | | |--|--| | Original Parameter Name | {properties.parameter_origin_name} | | Original UC Name | {properties.uc_origin_name} | | Original VC Name | {properties.vc_origin_name} | | Original Unit | {properties.parameter_origin_unit} | | Original Method | {properties.origin_method} | ### References {properties.citation} | | | |--|--| | License | {properties.license} | | DOI | [{properties.doi}]({properties.doi}) | | Data URL | [{properties.data_url}]({properties.data_url}) | | Metadata URL |[{properties.metadata_url}]({properties.metadata_url}) | | SOP |[{properties.sop_url}]({properties.sop_url}) | | Provider | {properties.provider} {addFilterButton("provider", properties.provider)} | | Dataset | {properties.dataset} | | Curator | {properties.curator} |