Text vIewer for Digital Objects. With this project we provide a highly configurable viewer for projects that implement the TextAPI.
Please visit our demo page where you can run TIDO with your own TextAPI endpoint and also view our production examples.
- Getting Started
- Configuration
- Methods
- Bookmarking
- Getting Started (Developers)
- TextAPI Support
- Contributing
- Versioning
- Authors
TIDO is provided as npm package. Please follow the steps below to include it for production:
npm i tido
- Add these two files to your application:
tido.js
andtido.css
.
HTML:
<link href="/node_modules/tido/dist/tido.css" rel="stylesheet">
<script src="/node_modules/tido/dist/tido.js"></script>
JS:
import 'tido/dist/tido.js'
import 'tido/dist/tido.css'
- Add a container element to your application where TIDO can hook into. Please make sure that this element has your desired dimensions and position.
<style>
#app {
height: 100vh;
width: 100%;
}
</style>
<div id="app"></div>
- Create a new TIDO instance and provide optionally your TIDO configuration:
<script>
const tido = new Tido({
manifest: 'https://example.com/textapi/manifest.json'
});
</script>
Below you can find a detailed explanation of the configuration object.
You can fully customize the viewer's behaviour by providing a configuration object to the TIDO instance.
First of all, there should be set either a collection
or a manifest
value.
By default, TIDO will render 5 panels displaying sequence tree, metadata, image, text content and annotation views.
There are options to
- add/remove multiple panels
- freely combine view components in panels
- show/hide header features
- change the color scheme
- and more ...
Example configuration:
Click to open
<script id="tido-config" type="application/json">
{
"collection": "http://localhost:8181/ahiqar/arabic-karshuni/collection.json",
"panels": [
{
"label": "contents_and_metadata",
"views": [
{
"id": "tree",
"label": "contents",
"connector": {
"id": 1,
"options": {
"labels": {
"item": "Sheet",
"manifest": "Manuscript"
}
}
}
},
{
"id": "metadata",
"label": "metadata",
"connector": {
"id": 2,
"options": {
"collection": {
"all": true
},
"manifest": {
"all": true
},
"item": {
"all": true
}
}
}
}
]
},
{
"label": "image",
"views": [
{
"id": "image",
"label": "Image",
"connector": {
"id": 3
}
}]
},
{
"label": "text",
"views": [
{
"id": "text1",
"label": "Transcription",
"default": true,
"connector": {
"id": 4,
"options": {
"type": "transcription"
}
}
},
{
"id": "text2",
"label": "Transliteration",
"connector": {
"id": 4,
"options": {
"type": "transliteration"
}
}
}
]
},
{
"label": "annotations",
"views": [
{
"id": "annotations1",
"label": "Editorial",
"default": true,
"connector": {
"id": 5,
"options": {
"types": [
{
"name": "Person",
"index": "person",
},
{
"name": "Place",
"index": "marker",
},
{
"name": "Editorial Comment",
"index": "chat",
},
{
"name": "Reference",
"index": "externalLink",
}
]
}
}
},
{
"id": "annotations2",
"label": "Motif",
"connector": {
"id": 5,
"options": {
"types": [
{
"name": "Motif",
"index": "pen",
}
]
}
}
}
]
}
],
"translations": {
"en": {
"contents_and_metadata": "Contents & Metadata",
"next_item": "Next Sheet",
"previous_item": "Previous Sheet",
"next_manifest": "Next Manuscript",
"previous_manifest": "Previous Manuscript",
"item": "Sheet"
}
}
}
</script>
Name | Type | Default | Description |
---|---|---|---|
collection | String | null | Specifies a collection endpoint URL. Will be prioritized over manifest key. |
colors | Object | ↓ | Sets custom theme colors. If any value is left blank (e.g. "primary": "", ), a default color scheme will be used. |
colors.forceMode | String | light |
Enforces the initial color mod despite the browser settings. Supported values: light , dark , none . |
colors.primary | String | #477fbf |
Used as main color in buttons, active states, highlights |
colors.secondary | String | #eeeeee |
Can be used as contrast or background color |
container | String | #app |
Specifies the CSS selector where we should append the TIDO app to. |
header | Object | ↓ | Controls the elements in the section above the content |
header.show | Boolean | true |
Toggle visibility of the whole header |
header.navigation | Boolean | true |
Toggle visibility of prev/next buttons |
header.panelsToggle | Boolean | true |
Toggle visibility of panel toggle buttons |
header.languageSwitch | Boolean | false |
Toggle visibility of language switch for supported languages |
lang | String | en |
Sets the default language. Possible supported values: en , de |
manifest | String | null | Specifies a manifest endpoint URL. Will be ignored when there is a collection key specified. |
panels | PanelConfig[] | ↓ | Defines an array of panel objects. The panels will appear in the same order. |
panels[i].label | String | Panel i |
Sets the label which appears in the panel header. If there is only one view in the panel then the view label will be displayed instead. Translatable. |
panels[i].views | ViewConfig[] | ↓ | Defines an array of views inside of a panel. If there are multiple views, we display them in tabs. If there is only one view we omit the tabs and display the view directly inside the panel. |
panels[i].views[j].id | String | view-j |
Unique identifier for the view across the app. |
panels[i].views[j].label | String | View j |
Sets the label which appears in the tab header. If there is only one view then this label will be displayed as panel header label. Translatable. |
panels[i].views[j].default | Boolean | false |
Specifies whether this view should be visible at the initial start of the app. If no default keys provided on views or all default keys are set to false , then the first view will be considered as default. |
panels[i].views[j].connector | Object | ↓ | Defines which view component and its options. Each view can have its own arbitrary config options. |
panels[i].views[j].connector.id | Number | null | Defines the component id which will be rendered dynamically for this view. See view connectors. |
panels[i].views[j].connector.options | Object | null | Defines options for individual view components. Each view component has different options. See view connector options. |
translations | Object | null | Specifies a custom translations object. |
translations.[langKey] | Object | null | Defines a translation object for supported languages with the respective langKey which can have following values: en , de . |
translations.[langKey].[translationKey] | String | null | Defines a translation key/value pair for a supported language. You can override existing key/value pairs or define custom key/value pairs. There is a list that we expose for overriding in the configuration. |
TIDO can be configured to display dynamic panel with dynamic views inside. In order to tell TIDO how the panels and views should be rendered, you need to assign the right connectors in the config. This is done via component IDs which currently are plain integers. Below you can find a list of available components.
ID | Name | Description |
---|---|---|
1 | Tree | Displays an expandable/collapsible tree view that renders TextAPi sequences. |
2 | Metadata | Displays dynamic metadata from collection, manifest and item levels. |
3 | Image | Displays the image resource from the item in an OpenSeadragon instance. |
4 | Text | Displays one text type from the item. Loads a support CSS file it provided. Handles text highlighting and selecting |
5 | Annotations | Displays a list of annotations. Handles selecting. |
6 | Variants | Displays a list variants with their corresponding witnesses. Enables to filter variants by witness. Provides a "single select mode" to pick variants from the text panel. |
Each view component can be configured via an options
object that can be passed at the connector.
Here is an overview of available options:
Name | Type | Default | Description |
---|---|---|---|
labels | Object | null | You can overwrite default labels of tree nodes. |
labels["item"] | String | "page" |
Label prefix for an item tree node. The item number in the sequence will be appended. It will be displayed when no other label is given by the item itself. The output could look like this: "Page 3" |
labels["manifest"] | String | "manifest" |
Label prefix for an manifest tree node. The manifest number in the sequence will be appended. It will be displayed when no other label is given by the item itself. The output could look like this: "Manifest 3" |
Name | Type | Default | Description |
---|---|---|---|
collection | Boolean | true |
Toggle on/off the collection section. |
manifest | Boolean | true |
Toggle on/off the manifest section. |
item | Boolean | true |
Toggle on/off the item section. |
no options
Name | Type | Default | Description |
---|---|---|---|
type | String | null | Specify the content type slug that is served from item.content response. |
Name | Type | Default | Description |
---|---|---|---|
types | AnnotationTypeConfig[] | [] |
Defines annotation types that should be displayed in this view. The Annotation API response will then be filtered according to this config. |
types[i].name | String | null |
Specifies the name which corresponds to the x-content-type property from annotations response. |
types[i].icon | String | null |
Specifies an icon that is displayed on the left of the annotation item. Currently we provide only a fixed list of possible icons. here |
types[i].index | String | null |
Specifies the index name that should be used in the annotation item. TIDO uses Bootstrap Icons, please lookup the allowed values here |
types[i].displayWhen | String | null |
Text content type that was specified under Text options. Annotation will only be shown if that content type is currently active. |
types[i].annotationType | String | annotation |
Controls the look of the annotation item. Allowed values: annotation or text . Currently the only difference is that there is no index at type text . |
Below you can find a list of icons that can be used for annotation items. Please use these as values for the icon
configuration option at annotations.
archive
arrowLeft
arrowRight
bank
book
chat
check
code
dropdown
externalLink
fullscreen
info
journals
marker
minus
moon
pen
pencil
person
reset
sun
translate
warning
zoomIn
zoomOut
In the configuration object you are able to set certain translation keys to display your desired texts in the application. Here is a list of keys that you can override:
item
manifest
previous_manifest
next_manifest
next_item
previous_item
The instantiated TIDO Object exposes methods to control TIDO's behaviour programmatically. Just call them in your outer JavaScript application like this:
const tido = new Tido()
tido.someMethod()
Available Methods:
Name | Arguments | Type | Description |
---|---|---|---|
setTheme | name | dark , light |
Sets color theme. The attribute color-scheme at the container element will be overridden. |
TIDO will reflect certain state changes to the URL so you can save and share your current view.
It appends only one GET parameter. The key
is tido
and the value
are the settings of the current app state.
Full example of the bookmarking concept: http://localhost:5173/?tido=m0_i1_s0-2-3_p0.0-1.0-2.0-3.1
.
The 'value' consists of 4 parts:
- Manifest part: m0
- Item part: i1
- Visible panels: s0-2-3
- Active tab for each panel: p0.0-1.0-2.0-3.1
Currently we provide the following bookmarking keys:
Key | Value | Description |
---|---|---|
collection |
URL | Specifies a collection entrypoint. Will be preferred before manifest . |
manifest |
URL | Specifies a manifest entrypoint. |
item |
URL | Specifies an item entrypoint. If not set the first possible item will be appended and displayed. |
m |
Int: i.e 0 | Specifies the manifest index inside a certain collection. Syntax: m[manifest index], example: m0 |
i |
Int: i.e 1 | Specifies the item index of a certain manifest. Syntax: i[item index], example: i1 |
s |
0-1-2 |
Controls the visibility of panels. It's a list of dash-separated panel indexes. All other panels will be hidden. Not set = all visible. Syntax: s[index1]-[index2]..., example: s0-1-2 |
p |
0.1-1.1-2.1-3.1 |
Specifies the active view (tab) in a respective panel. Syntax: p[panel index1].[view_index1]-[panel index2].[view_index2].. , example p0.1-1.1-2.1-3.1 . Each user interaction will change this parameter. |
Hint: With this setup you are able to load your entrypoint dynamically by appending it at the URL instead of rendering it via the configuration object inside your wrapper application.
To get TIDO up and running you should have the following software installed:
- npm
- nvm
Note:
We recommend to make use of nvm
, since there might be issues with npm regarding permissions.
The main purpose of nvm
is to have multiple node versions installed in regards to different projects which might demand some sort of backwards compatibility.
It enables you to just switch to the appropriate node version.
Besides it also keeps track of resolving permission issues, since all your global installations go to your home directory (~/.nvm/) instead of being applied systemwide.
curl -o- https://raw.githubusercontent.com/nvm-sh/nvm/v0.35.3/install.sh | bash
nvm install stable
Note:
After the nvm installation is done, please restart
your shell session once. That's due to changes to your profile environment.
git clone [email protected]:subugoe/tido.git
Head over to your project directory, where you just cloned the repository to as described above and get all the dependencies needed by typing:
cd /path/to/projectdir
npm install
That's it. You should now be able to run the Viewer.
Please run this command to create a production build.
npm run build
The output files are located at /dist
.
Builds the app in development mode
(hot reloading, error reporting, etc.).
npm run dev
You can modify /index.html
to load your required TIDO configuration. It will be available under localhost:5173
.
You can start up a production build with
You can modify /index.html
to load your required TIDO configuration. It will be available under localhost:4173
.
You can also inspect some example TIDO configurations that we provide under /examples
.
Run this command which will create a TIDO production build, copy the result files into /examples
and start up a local web server:
npm run preview:examples
This examples are available under localhost:2222
. Each example has its own HTML file:
http://localhost:2222/[example-name].html
We provide several mock JSON files in order to create API endpoints for testing purposes. You can start your own local API server with this command:
npm run start:mock-api
The server will be available at localhost:8181
. Check out /tests/mocks
inspect the files.
We run tests only on production code. So you need to make sure to create a TIDO build before starting to run tests. TIDO follows the "Zero Config" policy but projects can provide a very detailed config that can drastically change the behaviour of the app. Therefore, we provide some example configurations from previous implementation projects that cover the most important features.
Following examples are available under (/examples
):
ahiqar-arabic-karshuni.html
ahiqar-arabic-karshuni-local.html
ahiqar-syriac.html
gfl.html
gfl-local.html
zero-config.html
This is a minimal command to run tests once on your local machine.
npm run start:mock-api & npm run test
If you want to gain more control during development you can do the following. Prepare the environment before running the tests:
npm run start:mock-api
npm run preview:examples
Now you can run the tests on your local machine with a proper Cypress UI and selective steps or run the tests only in headless mode which will prompt the results on the console.
npm run cypress
ornpm run cypress:headless
npm run lint # to lint all the files at once
npm run lint:js # to lint js files only
npm run lint:markdown # to lint the markdown
npm run lint:scss # to lint the styles
npm run lint:vue # to lint vue files only
We maintain a JSON file (/.validation/support-matrix.json
) that keeps track of supported TextAPI features.
If you need to recreate that file and rerender /SUPPORT.md
, here is an explanation:
- Make sure you run NodeJS version >= 20
- Set
GITLAB_ACCESS_TOKEN
in/.env
file - Run
node ./.validation/create-support-matrix.js
- Inspect
/.validation/support-matrix.json
, all status values are set to 0 (= not supported) by default - Edit the statuses manually: 0 = not supported, 1 = supported, 2 = partially supported, 3 = unused
- Run
node ./.validation/create-support-matrix.js
again to generate new/SUPPORT.md
Please view this document to see an overview of supported TextAPI features: State of TextAPI support
Please read CONTRIBUTING.md for details on our code of conduct, and the process for submitting pull requests to us.
We use SemVer for versioning. For the versions available, see the tags on this repository.
See the list of contributors who participated in this project. First line added!