Versions Compared

Key

  • This line was added.
  • This line was removed.
  • Formatting was changed.

VEF-based viewers enable the user allow users to style the popup and sidebar metadata that gets displayed appears when clicking users click on features on the map for better , improving readability and visualization. Templates are based on the Markdown language and allow for flexible customization of metadata rendering. Predefined function calls enable allow the use of advanced visualizations, such as displaying diagrams charts or a video player. Without the use of templates, the original metadata gets is displayed in a simple table while , using the technical names of each property.

...

Unstyled MetadataStyled Metadata
Unstyled Metadata


Styled Metadata

Format Specifications

The basis for the metadata templates is are based on the lightweight markup language Markdown. Markdown has a lot of flexiblility flexibility for formatting text and is human-readable in its unparsed form.
To display the metadata properties, they need to must be enclosed in curly bracketsbraces. The metadata is inside an object and can be accessed using dot - notation or like dictionary entries from a dictionary.

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 need to be enclosed in curly brackets and use rounded 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 need to must be passed as strings enclosed in quotes.

NotationExplanation
{properties.expediton}Accessed Accessing the property Property "expedition" from the clicked feature
{properties["general.name"]}Accesses the property "event.name from " 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 property " 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.

Available Functions

NameDescription
formatLatLng(latitude, longitude)

Format lat/lng

to

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.

Only works

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

Timestring

timestamps more readable

Example: {formatDate(properties.date_time_start)}

isDefined(valueToCheck, then, else)

Only returns 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, ...)

Concats Concatenate values if every 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

given decimals

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 whole entire popup feature. The PopupRenderer will extract the title from that this property to display it in the header. This is set directly set in the container.

Example: {setTitle("Event: ", properties.event)}

parseJSON(jsonstring, key1, key2, ...)

Parses a json string and outputs 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 to be from being displayed in a table row

hideOnSiteStart(site)
hideOnSiteEnd(site)

Prevents content from being rendered by inserting a comment if when the site page matches. These functions need to must be used together to mark an area to be removedremove

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 the an image opens it in a fullscreen lightbox that can be zoomedfull-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 content should be structured vertically, because the popups and sidebars have a limited width
  • Ideally the metadata is structured in a two-column table like the example below

HTML Post-Processing

The resulting HTML markup gets altered is modified by the viewer for optimized after the templates have been evaluated for optimal visualization of the metadata after the templates got evaluated.

  • Headlines will be are grouped in into collapsible sections. H3 using with ### is recommended
  • Empty collapsible groups are not rendered
  • A copy Copy button will be automatically added automatically to table rows to copy a property
  • Table Removes table rows with empty content in the second cell will be removed

Recommendations

  • The content should be organized vertically because the pop-ups and sidebars have a limited width.
  • Ideally, the metadata is structured in a two-column table, as in the following example

Example Template

Code Block
languagetext
titleTemplate for Expedition Tracklines
{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} |

...