field customization
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 inline 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 |
activeOnDatasources() | list-of-activating-datasources, item.datasource list-of-provided-qids | boolean | returns true if the item's datasource matches the supplied list of activation datasources | activeOnDatasources( [ 'openalex', 'arxiv' ], item.datasource ) → check if the item datasource matches OpenAlex or arXiv |
onAstronomicalBody( item, qid ) | item, qid (of the astronomical body) | boolean | returns true if the item is located on the astronomical body | onAstronomicalBody( item, “Q111” ) → check if the item is located on the planet Mars |
addConzeptField( name, definition ) | name (string), definition (Conzept field object) | - | Dynamically adds an extra Conzept field |