field customization

introduction

Each section of a topic can be populated by links. These links are defined in fields. When a user clicks on such a link, it can trigger some kind of action.

There are five types of actions a field can trigger:

  • Open a link in the content pane. This can be an self-hosted app URL or a remote website which allows being embedded (without CORS issues).
  • Open a link in a new tab. This is sometimes required because the website does not allow being embedded in a 3rd-party iframe or user authentication is needed.
  • Inline view in the sidebar: Show an inline iframe from an URL
  • Trigger some code to run when the link is clicked. Examples: create a new bookmark or start/stop playing an audio file.

You can see all the fields used for the Conzept website in the “src/data/field.js” file.

[ Note: that the topic-headline buttons are not yet defined in the “field.js” file, but instead in the createItemHtml.js file. That functionality will be included at a later stage. ]

field processing

The field list is processed in two phases. Normally, you wont need to understand the details of these stages, but sometimes understanding them can help how to create more complicated field definitions.

The first phase is the input phase, where all the field data is collected from external sources such as Wikidata and other API's. This phase has three stages: pre-create, create and post-create. See: setWikidata.js and the API fetch functions.

The second phase is the render phase where fields are processed for display to the user (since all the data is now available), and has two stages: pre-render and render. See: createItemHtml.js.

field schema

Fields are defined as a list of JavaScript objects with a certain structure. (shown in the table below below)

For each topic listed in the sidebar, Conzept will check all the defined fields, to find the usable ones. When a field is used, it will set a value (on an internal Conzept data-structure), which will eventually be rendered as a link in the user interface.

The fields are read in order, without any dependency resolving. This also implies, that if you want to use an existing field-value in another field, you need to place that field after it.

name data type description used in stage
default_value <string> (if set:) set the “item.<name>” field to this default value pre-create
value_condition <eval-string-to-boolean> (if set:) and is true create
value <eval-string> –> evaluate this string create
create_condition <eval-string-to-boolean> note: only needed to activate derived-item-fields (as these item-fields don't exist yet)

note: a missing or empty “create_condition” defaults to relying on the items current-value

(if set:) and evaluates to “true”

–> set item value to “true”
pre-create
create_trigger <eval-string> note: if ( the internal “create_trigger_enabled” was set to true by a wikidata-field update OR the field is not a wikidata field ) AND there is “create_trigger” value defined: –> evaluate this code-string to achieve extra 'side effects' during the input-stage post-create
render_condition <eval-string-to-boolean> note: a missing or empty “render_condition” defaults to “true” TODO: should we change this to “false”? (so an explicite 'false' is needed to prevent the rendering of a field) (if set:) and evaluates to “true” –> render item-field pre-render
render_trigger <eval-string> note: if the internal “render_trigger_enabled” is true

–> evaluate this code-string to achieve extra 'side effects' during the render-stage
render
url <eval-string-to-url> URL-address to use when a link is clicked create and pre-render
title <eval-string> link hover-title pre-render
prop <integer> wikidata-property-number create
type <link | link-split | url | wikipedia-qid | symbol-number | symbol-string> indicate the type of field create and pre-render
mv <true | false> indicate if multiple values are allowed create and pre-render
icon <css-class-string> link icon pre-render
text <plain-string> link text pre-render
section <plain-string | array-of-strings> section(s) in which to place the link render
rank <number | array-of-numbers> position of the link (set for each section) render

field types

There are two main classes of fields: Wikibased-fields and derived fields.

Wikidata-based fields

These fields have a Wikidata property number listed for the “prop:” key. If a topic has such a Wikidata property value, Conzept will get that data from Wikidata.

Wikidata-based fields can generate three types of data (based on Wikidata item statement values):

name description
wikipedia-qid One or more Wikidata Q-IDs coming from a Wikidata item statement (eg. “Q42”).

Note: the “wikipedia-qid” name is used to automatically render either a Wikipedia page or a Wikidata page. The Wikipedia page takes precedence, if it is available in the users' language.
no type If the field-type is left empty, the data is treated as (one or more) strings by default.
symbol-number Number coming from a Wikidata item statement (eg. “3051”).
symbol-html This type should only be used when want create raw HTML-string output (based on some Wikidata item statement string). For example when creating an audio-element html string.

examples

Here is an example which renders a link to “members of” values of a topic, using the Qid data:

'member_of' : {             // ID of the field (must be unique)
  title: 'member of',       // title of the field (shown when a user hovers over the link)
  prop: '463',              // Wikidata property
  type: 'wikipedia-qid',    // expected data type are Wikidata Qid's
  mv: true,                 // multiple values are allowed
  icon: 'far fa-handshake', // icon shown for the link
  text: 'member of',        // text shown for the link
  section: ['main'],        // which section(s) to show the link in
  rank: [5160],             // position of each link within each section
},

Here is an example of a field without a type (which means the data will be treated as a string):

'atomic_symbol' : {
  render_condition: false, // this means we wont show this field in the UI, but just store the value.
  title: 'atomic symbol',
  prop: '246',
  type: '',
  mv: false,
  icon: '',
  text: '',
  section: '',
  rank: 1,
},

Here is an example for the “number of employees” of a topic:

'employees' : {
  title: 'employees',
  prop: '1128',
  type: 'symbol-number',
  mv: false,
  icon: 'fas fa-male',
  text: '',
  section: ['main'],
  rank: [3180],
},

Here's an example where the “symbol-string” HTML-creation is used to present an audio element (in the topic card):

'audio_widget' : {
  create_condition: '${ valid( item.audio ) }', // FIXME the audio_widget is sometimes showing up for non-audio topics, why?
  title: 'audio play',
  prop: '',
  type: 'symbol-html',
  mv: false,
  string_format: '<div id="${item.qid}" class="audio-widget" title="audio" aria-label="audio"><audio class="inline-audio" controls> <source src="${item.audio}"> </audio></div>',
  icon: '',
  text: '',
  section: '',
  rank: 1,
},

Derived fields

Derived fields have a dependency on another field or value. These fields may or may not use some Wikidata data.

Dependent values can be many different things:

  • The existance of a Wikidata-Qid for the topic.
  • A topic title string like “Classical music”
  • an active user language like “es” (Spanish)
  • a remote JSON API call definition (eg. for the Rijksmuseum API)
  • etc.

Derived fields come in various forms:

name description
link open URL in the local content pane
link-split open URL as two content panes
url open as external URL
rest-json API fetch

examples

example: wikidata-derived field

The derived-field example below will show a link to the “GBIF organism occurrence map”, but only if the “item.gbif_id” was set (from an earlier Wikidata field definition).

'gbif_id' : { // Wikidata field
  render_condition: false,
  title: 'gbif_id',
  prop: '846',
  type: '',
  mv: false,
  icon: '',
  text: '',
  section: '',
  rank: 1,
},

'gbif_occurence_map' : { // Derived field, which depends on the field above being set
  create_condition: '${ valid( item.gbif_id ) }',
  title: 'GBIF occurence map',
  prop: '',
  type: 'link',
  url: '${explore.base}/app/response/gbif-map?l=${explore.language}&t=${title_enc}&id=${item.gbif_id}',
  mv: false,
  icon: 'fas fa-binoculars',
  text: 'occurence map',
  section: ['science-biology','main'],
  rank: [400,7900],
},

This will show a tab-opening link to Google Scholar.

'google_scholar' : {
  create_condition: true,
  title: 'Google Scholar',
  prop: '',
  type: 'url', // "url" always opens links in a new tab
  mv: false,
  url: 'https://scholar.google.com/scholar?q=${title_quoted}',
  icon: 'fab fa-google',
  text: 'Google Scholar',
  section: 'science-search-tools',
  rank: 60,
},

This will show the Russian Yandex search-engine link, but only if the users' language is set to Russian:

'yandex_ru' : {
  create_condition: '"${explore.language}" === "ru"',
  title: 'Yandex search',
  prop: '',
  type: 'url',
  mv: false,
  url: 'https://yandex.ru/search/?text=${title_quoted}',
  icon: 'fab fa-yandex',
  text: 'Yandex',
  section: 'web',
  rank: 4,
},

This is an example of a field which fetches data from the Wikicommons API, using special code located in the fetch directory.

The specific code for this API can be found here.

'wikicommons_inline' : {
  value: 'wikicommons:${item.title}:true',
  title: 'view wikiCommons media',
  render_condition: 'valid( item.qid )', // only render this link if there is a Wikidata Qid
  prop: '0', // Note: currently all API derived-fields must set their property-key to "0".
             // Doing this triggers the data to be processed similar to Wikidata data.
  type: 'rest-json', // this indicates the field is an API-derived field
  mv: true,
  icon: 'far fa-images',
  text: 'Commons',
  section: ['media-image'],
  rank: [61],
},