field customization

This section describes what Conzept fields are and how they are structured.

introduction

Each section of a topic-card can be populated by links. These links are constructed from declarative field definitions. When a user clicks on such a link, it can trigger some kind of action.

There are several types of actions a field can trigger:

  • Open a link in the content area. 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 browser 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 a list of items from the Wikidata entity. (The field needs to have the multi-value key set to “true” in Conzept and also contain multiple values in Wikidata. If there is only one item in Wikidata the field will be rendered as a normal link to the Wikipedia/Wikidata page.)
    • Show a list of items fetched from an API. These type of actions also require some code support to fetch the API data.
    • 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. Once you have added one or more field definitions to this file, you only need to run “npm run build” in the “app/explore2/” directory to start using these new fields.
To make sure all users use the most recent version, it is recommended to also update the version setting.

[ Note: that the topic-headline buttons are not yet defined in the “field.js” file, but instead in the createItemHtml.js file. ]

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.

For each topic listed in the search results, 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 used to render a link in the user interface.

When a field has a non-false / not-empty value (meaning: “item.<name>” is set to some non-false value), the field is active and will be used for further processing. In all other cases, the field will not be processed further.

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.

field schema

Fields are defined as a list of JavaScript objects with a certain structure.

Each field-object must have a unique name (the object key) and a set of properties (shown in the table below).
All properties are optional, but some types of fields will require certain properties.

Here is a list of the properties that can be used to define fields:

name data type description used in stage
default_value <string> if set: set the “item.<name>” field to this value pre-create
value_condition <eval-string-to-boolean> if set: and evaluates to “true” ⇒ set “item.<name>” to “true” create
value <eval-string> ⇒ evaluate this string create
create_condition <eval-string-to-boolean> if set: and evaluates to “true” ⇒ set “item.<name>” to “true”

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
pre-create
create_trigger <eval-string> if the “create_condition” is set to “true” ⇒ evaluate this code-string to achieve extra side-effects during the input-stage post-create
render_condition <eval-string-to-boolean> if set: and evaluates to “true” ⇒ render this field pre-render
render_trigger <eval-string> if set AND the “render_condition” is “true” ⇒ evaluate this code-string to achieve extra side-effects during the render-stage render
string_format <eval-string> string-format used to transform the Wikidata property string or number into custom HTML create and pre-render
url_format <eval-string-to-url> URL-address-format from Wikidata (or another source), to use when a link is clicked create and pre-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> icon class from FontAwesome or OpenMoji pre-render
text <plain-string> text under the icon (note: don't use long words here) 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

These types are currently available in field-definitions:

type required field description
no type If the field-type is left empty, the data is treated as (one or more) strings by default (but not treated as an “info”-section field, as is done for “symbol-string” and “symbol-number” fields.).
wikipedia-qid prop Fetch the Wikidata for this property. This will return 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. Showing the Wikipedia article takes precedence, if it is available in the users' language.
symbol-number prop Number coming from a Wikidata item statement (eg. “3051”).
symbol-string prop String coming from a Wikidata item statement (eg. “+45-111-222-333”).
symbol-html prop This type should only be used when you want create raw HTML-string output, based on some Wikidata item statement string.

For example when creating an audio-element HTML string from the audio-file data.
link url Open the URL in a single content-pane
url url Open the URL in a new browser-tab
link-split url Open the URL in two content panes. Load the supplied URL into the first content pane, in the second-content pane we try to load the Wikipedia / Wikidata page for this search-string / qid
rest-json “prop: 0”, and “value: '${api-function-name}:${argument-string}':true” Fetch API data from the supplied API-function and the argument-string (eg. a title-string or qid). The third boolean-argument can enable/disable the API data fetching. The results are rendered in the topic-card.

Note: The required field structure is likely to change in the future. Likely becoming a JS-object instead of a colon-delimited string.

special values

Conzept has some special title-values which can be used anywhere in the field definition values:

name description
title title as-is
title_ title without any Wikipedia namespace-prefix and braces
title_enc title URL-encoded
title_quoted title “in quotes”
title_plus title with a plus for spaces
title_dashed title with dash for spaces
title_lowercase title in lowercase
title_no_spaces title without spaces
title_no_braces title without braces
title_no_braces_lowercase title without braces in lowercase


There is currently one 'magic'-variable usable in field-definition values:

name description
Xvalue Used to automatically iterate over a list of values (or just one value) coming from Wikidata. This makes it easy to use multi-values to create multiple new strings. See examples of its use here.

types of fields

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

Wikidata-based fields

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

examples

An example which renders a link to all the “members of” (Wikidata property) values of a topic:

'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
},


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,
},


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 ) }',
  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,
},


An example where the magic variable “${Xvalue}” is used to automatically iterate over a list of values (or just one value) coming from Wikidata. This makes it easy to use multi-values to create multiple new strings.

The example below illustrates the rendering of multiple website URL(s), if there are multiple websites listed on Wikidata for that entity.

'website' : {
  title: 'official website',
  prop: '856',
  type: 'url',
  url: '${Xvalue}', // each website URL will be rendered as a link
  mv: true,
  icon: 'fas fa-home',
  text: 'site',
  section: 'main',
  rank: 40,
},


Another example using “${Xvalue}” for a part of the URL:

'twitter_topic' : {
  title: 'Twitter topic',
  prop: '8672',
  type: 'url',
  url: 'https://twitter.com/i/topics/${Xvalue}',
  mv: true,
  icon: 'fab fa-twitter',
  text: 'Twitter topic',
  section: ['news-social','main'],
  rank: [34,9070],
},

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 all sorts of 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.

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' : { // normal 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}',
       // The "explore.base" directory comes from the Conzept setting "CONZEPT_WEB_BASE",
       // to make the URL root location more flexible, but is not required.
  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.

[ Note: In the future this API-interface will likely be further specified and passed on to the API-function as a normal JS object. ]

'wikicommons_inline' : {
  value: 'wikicommons:${item.title}:true', // name of the API to call in the code, and the arguments which are passed to it.
  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],
},