field customization

fields

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 when the website does not allow being embedded in a 3rd-party iframe or user-authentication is required.
  • Show an inline view in the sidebar. There are some variations of this:
    • 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 single 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 new field definitions to this file:

  • Update the version setting in “/etc/conzept/settings.conf”
  • Run “npm run build” in the “app/explore2/” directory.

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
headline_create <eval-string> condition to check whether to display the headline-field render
headline_type <link | link-split | url | wikipedia-qid | symbol-number | symbol-string> render
headline_url <eval-string-to-url> (when omitted, defaults to “url”) render
headline_icon <css-class-string> icon class from FontAwesome or OpenMoji (when omitted, defaults to “icon”) render
headline_rank <number> position of the field in the topic-headline-row 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 custom 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 various title-forms which can be used anywhere in the field definition values:

name description example
title_no_braces title without braces A Night at the Opera (Queen album)
title_no_braces_lowercase title without braces in lowercase a night at the opera
title_ title without any Wikipedia namespace-prefix and braces (note: also the basis for all the titles below) A Night at the Opera
title_enc title URL-encoded A%20Night%20at%20the%20Opera%20(Queen%20album)
title_quoted title “in quotes” (note: this is the most used title-form, for 3rd-party site searches) “A Night at the Opera”
title_plus title with a plus for spaces A+Night+at+the+Opera
title_dashed title with dash for spaces A-Night-at-the-Opera
title_lowercase title in lowercase a night at the opera
title_no_spaces title without spaces A_Night_at_the_Opera


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.

utility functions

Here is a list of often used utility functions, to make the field definitions easier to write and maintain.

name arguments output description examples
valid() string, variable, array or expression boolean check if ALL provided inputs resolves to TRUE or FALSE valid( item.qid ) → true, if this condition is true

valid( [ item.qid, item.category ] ) → true, if all these conditions are true
validAny() string, variable, array or expression boolean check if ANY of the provided inputs resolves to TRUE or FALSE validAny( [ item.qid, item.category ] ) → true, if any these conditions are true
checkLC() language (string or array-of-strings of language-iso2-codes),

country (string or list-of-strings of country-iso-codes)
boolean Language and/or country check.

This function is used for matching against a websites supported languages and/or countries. The country-argument can be omitted.
checkLC( [“fr”,“es”,“zh”,“hi”] ) → true, if any one of these languages is the active user language

checkLC(“”,“US”) → true, if the user-country is “US”
checkTag() item-object (required),

[tag-field-index] (required),

tag string or list-of-strings
boolean Check if a topic has either a certain main-tag (0) or a certain sub-tag (1) tag. checkTag(item, 0, “person”) → true, if the topic's main-tag is “person”

checkTag( item, 1, [“writer”, “written-work” ] ) → true, if topic's sub-class is either “writer” or “work”
setTags() item,

[ main-tag-string, sub-tag-string ]
(none) Set main and/or sub-tag of a topic. If either of the tags is left as an empty string, this part will be skipped. setTags( item, [ “work”, “painting” ] ) → set the main-tag (“work”) and the sub-tag “painting “
listed() list-of-reference-qids,

list-of-provided-qids
boolean check if the provided Qid of the topic listed( item.instances, [ 3305213 ] ) → check if the topic instance-Qids contains a Qid for painting

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


The “symbol-html”-type can be used to create customized HTML strings. This example presents 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 one or more website URLs.

'website' : {
  title: 'official website',
  prop: '856',
  type: 'url', // open links in a new tab
  url: '${Xvalue}', // each website URL-value 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],
},

An example of a headline field:

'gbif_id' : {
  title: 'gbif_id',
  prop: '846',
  type: '',
  mv: false,
  icon: '',
  text: '',
  section: '',
  rank: 1,
  headline_create: 'valid( item.gbif_id )', // create the headline if this value exists
  headline_type: 'link',
  headline_url: '${explore.base}/app/response/gbif-map?l=${explore.language}&t=${title_enc}&id=${item.gbif_id}',
  headline_icon: 'fa-solid fa-binoculars',
  headline_rank: 275,
},

When the field values are mostly the same for the headline, you can omit these:

'chemical_formula' : {
  title: 'chemical formula',
  prop: '274',
  type: 'symbol-html',
  mv: false,
  string_format: '<span title="chemical formula">${item.chemical_formula}</span>', // this string will be re-used for the headline
  icon: '',
  text: '',
  section: '',
  rank: 1,
  headline_create: true,
  headline_rank: 350,
},

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: 'checkLC( "ru" )', // check if the user-language is set to the Russian-language
  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],
},