Skip to main content
Version: 3.19

Databox Indexer: Phraseanet Configuration

Example Configuration​

Below is an example configuration for a Phraseanet location. Explanations for each field are provided after the code block.

...
"locations": [
{
"name": "phraseanet-full-example",
"type": "phraseanet",
"options": {
"url": "https://phraseanet.phrasea.local/",
"token": "-------mytoken-------",
"verifySSL": false,
"importFiles": false,
"searchOrder": "%env(PHRASEANET_SEARCH_ORDER)%",
"idempotencePrefixes": {
"asset": "idmp_asset",
"collection": "idmp_collection",
"attributeDefinition": "idmp_attributeDefinition",
"renditionDefinition": "idmp_renditionDefinition"
},
"databoxMapping": [
{
"databox": "db_databox1",
"collections": "",
"workspaceSlug": "phnet",
"searchQuery": "",
"importStories": true,
"recordsCollectionPath": "/Records/{{ collection.name | escapePath }}/{{ record.getMetadata('Country', '_').value | escapePath }}/{{ record.getMetadata('City', '_').value | escapePath }}",
"storiesCollectionPath": "/Stories/{{ collection.name | escapePath }}/{{ record.getMetadata('Country', '_').value | escapePath }}/{{ record.getMetadata('City', '_').value | escapePath }}",
"copyTo": [
"{% for s in record.getMetadata('Subject', 'no_subject').values %}/classification/{{ record.getMetadata('Creator', 'no_creator').value | escapePath }}/{{ s | escapePath }}\n{% endfor %}"
],
"fieldMap": {
"Title": {
"values": [
{
"locale": "fr",
"type": "metadata",
"value": "Titre"
},
{
"locale": "en",
"type": "metadata",
"value": "Title"
}
]
},
"Subject": {
"type": "string",
"values": [
{
"type": "template",
"value": "{% for v in record.getMetadata('Subject').values %}{{v}}\n{% endfor %}"
}
]
},
"Copyright": {
"type": "string",
"values": [
{
"type": "template",
"value": "(c){{record.getMetadata('ArchiveDate', '').value | date('Y')}} {{record.getMetadata('Creator', '').value}}"
}
]
},
"Filename": {
"values": [
{
"type": "metadata",
"value": "Filename"
}
]
}
}
}
]
}
}
...

databox​

The name or id of the Phraseanet databox to import.

collections​

A list/filter of Phraseanet collections (id or name, delimited by ,) to import/search on. If unset or empty, will query all collections.

searchQuery​

The Phraseanet query to search for records to import. If empty: import all.

workspaceSlug​

The Databox workspace where to import (created if not exists).

recordsCollectionPath​

Collection-path where to import records as "main" assets. The asset name will always be the same ase the "original_name" of the record.

  • The recordsCollectionPath can be a Twig expression (see About Twig), allowing to dispatch the assets into a tree of collections.

    e.g.: Dispatch by phraseanet collection name, then country and city:

    "recordsCollectionPath": "/Collections/{{ collection.name | escapePath }}/{{ record.getMetadata('Country', '_').value | escapePath }}/{{ record.getMetadata('City', '_').value | escapePath }}",

    --> /Collections/MyPhraseanetCollection/France/Paris/IMG_1234.jpg

  • /!\ For backward compatibility: If the recordsCollectionPath is a simple string (no twig tags), it will be used as a root path and completd with phraseanet collection name

    "recordsCollectionPath": "/Collections",

    --> /Collections/MyPhraseanetCollection/IMG_1234.jpg

  • recordsCollectionPath can be empty string (or not set): Since this is a simple (empty) string, the backward compatibility applies, so the phraseanet collection name will be used as first-level collection.

    --> /MyPhraseanetCollection/IMG_1234.jpg

importStories & storiesCollectionPath​

storiesCollectionPath and storiesCollectionPath define how to import Phraseanet stories, with 3 combinations:

- Do not import stories.​

importStories: false

- Import stories as Phrasea stories​

importStories: true

A "storyAsset" is created at root of the workspace, and "points" to a collection invisible / noname / not-indexed "storyCollection".

Each contained record (imported elsewhere as an asset) is copied / aliased to this (invisible) collection.

The title of the storyAsset will be the same as the title of the story.

- import stories as Phrasea collections​

importStories: true                 # or unset, for bc
storiesCollectionPath: "/Stories" # where to import stories

Each story becomes a collection, and each contained record (imported elsewhere as an asset) is copied / aliased to this collection.

The name of the collection will be the same as the title of the story.

/!\ There is no "storyAsset" created, the Phraseanet "story-record" is not imported.

The storiesCollectionPath can be a Twig expression, allowing to dispatch the stories into a tree of collections.

e.g. 1: Import all stories, as Phrasea stories:

"recordsCollectionPath": "/Collections", # where to import records AND stories
"importStories": true,

--> /Stories/JO-2024 where "JO-2024" is the name of a phraseanet story.

e.g. 2: Import all stories in the same collection, as Phrasea collections:

"importStories": true,
"storiesCollectionPath": "/Stories",

--> /Stories/JO-2024 where "JO-2024" is the name of a phraseanet story.

e.g. 3: Dispatch by phraseanet collection name, then country and city:

"importStories": true,
"storiesCollectionPath": "/Stories/{{ collection.name | escapePath }}/{{ record.getMetadata('Country', '_').value | escapePath }}/{{ record.getMetadata('City', '_').value | escapePath }}",

--> /Stories/MyPhraseanetCollection/France/Paris/JO-2024 where "JO-2024" is the name of a phraseanet story.

copyTo​

list (array) of paths where to copy / alias "main" assets.

Each path is a Twig expressions that must generate databox path(s), depending on run-time values like record metadata.

If the asset is to be copied in many places (paths), the twig must generate one line per path.

  • e.g. 1: Two levels dispatch with unique destination (mono-value fields):

    "copyTo": [
    "/classification/{{record.getMetadata('Category', 'unknown_category').value | escapePath}}/{{record.getMetadata('SubCategory', 'unknown_subcategory').value | escapePath}}"
    ]
  • e.g. 2: Multiples destinations (multi-values field):

    "copyTo": [
    "{% for s in record.getMetadata('Keywords', 'no_keyword').values %}/classification/{{ s | escapePath }}\n{% endfor %}"
    ]

    note: The \n is used to output one line (= one path) per keyword.

    note: The default value "no_keyword" is a must-have, because if the record had no keyword, it would not be copied anywhere.

  • e.g. 3: multiples destinations :

    To dispatch the records in many "classification" places, one can set multiple copyTo settings.

    "copyTo": [
    "/classification/author/{{record.getMetadata('Author', 'unknown_author').value | escapePath}},
    "/classification/category/{{record.getMetadata('Category', 'unknown_category').value | escapePath}},
    "/classification/year/{{record.getMetadata('Date', '').value is empty ? 'unknown_date' : {{record.getMetadata('Date').value | date('Y')}}
    ]

fieldMap​

Map (key=AttributeDefinition name) of attributes to create / import.

AttributeDefinition settings:​

  • type: "text", "number" or "json" (more todo) ; Default: "text"

  • multivalue: boolean

  • readonly: boolean

  • labels: map, e.g. {"fr": "Titre", "en": "Title"}

  • values: Array of objects to declare initial metadata value(s).

    values:​

    • locale: e.g. "fr"
    • type: how to evaluate the value ("metadata", "template", "text" ; default: "text")
    • value: value expression, as metadata (=phraseanet field name), template (twig) code or simple text

    text type: The value is the immediate value for the attribute.

    metadata type: The value is the name of a Phraseanet field, like "Title".

    template type: The value is a Twig code, to compose complex value(s)

For the template type, the Attribute value(s) is the result of the Twig expression, which must generate one item per line for multi-values. The Twig context is the same as copyTo

note 1:

If the attribute-definition name matches exactly a Phraseanet field name, some AttributeDefinition settings will be copied from the Phraseanet metadata-structure (type, multivalue, readonly, labels).

If the name does not match a Phraseanet field, those settings can be set in conf block.

note 2:

If FieldMap is not set: Phraseanet full equivalent configuration is dumped.

note 3:

If an AttributeDefinition setting is declared with a locale, it will be created with translatable=true.

All the different AttributeDefinition locales are copied to the "Enabled locales" of the workspace.

sourceFile​

Declare le phraseanet subdef to be used as source file for the asset.

Mostly "sourceFile": "document" for the original file.

If not set, assets will be created without source file.

renditions​

Allows to map Phraseanet subdef / (structures) to Phrasea renditions / (definitions).

A Phraseanet subdef is identified by it type (image, video, audio, document, unknown) and its name. e.g. image:thumbnail.

A Phrasea rendition-definition is declared by its name and build settings (sections image, video, ...).

note:

  • If renditions is not set, Phraseanet full equivalent configuration is dumped.

  • To not import / create any rendition / rendition-definition: set both "sourceFile":false and "renditions": false

  • It is possible to declare a rendition with no from: not imported from Phraseanet, but created in Phrasea.

parent​

One can declare a parent relation between renditions, the parent rendition must be declared before the child.

If not set, the rendition will be built from the asset file.

useAsMain, useAsPreview, useAsThumbnail, useAsAnimatedThumbnail​

Declare the rendition to be used as main, preview, thumbnail or animated thumbnail.

buildMode​

Tells the builder how to "build" the rendition.

  • 0: Do not build the rendition
  • 1: Copy the parent file (if no parent: copy the asset file); Mostly used to copy the asset file to the "main" rendition.
  • 2: Build the rendition using build rules defined in builders blocks.

class​

Phrasea rendition class, mostly "public" or "private". If not set, the value will be "guessed" from the subdef class (document, preview, ...).

builders​

A builder can be defined for each family of renditions (image, video, audio, ...).

from​

Inside the builder, the from maps the phrasea rendition-definition - for the family -, to the phraseanet subdef.

The from value (phraseanet subdef) is a string like \<document_type>:\<subdef_name>, e.g. video:preview.

The build settings will be generated from the phraseanet to match the subdef.

e.g.​

...
"sourceFile": "document",
"renditions": {
"main": {
"useAsMain": true,
"buildMode": 1,
"class": "public"
},
"preview": {
"useAsPreview": true,
"class": "public",
"builders": {
"image": {
"from": "image:preview"
},
"video": {
"from": "video:preview"
}
}
},
"thumbnail": {
"useAsThumbnail": true,
"class": "public",
"parent": "preview",
"builders": {
"image": {
"from": "image:thumbnail"
},
"video": {
"from": "video:thumbnail"
}
}
}
}
...

About Twig

When using twig expressions in the configuration, the context is the following:

  • record: record object
    • record.record_id : string
    • record.resource_id : string
    • record.databox_id : string
    • record.base_id : string
    • record.uuid : string
    • record.title : string
    • record.original_name : string
    • record.mime_type : string
    • record.created_on : string
    • record.updated_on : string
    • record.status : status[] use getStatus() method
    • record.getStatus(\<bit> [, \<valueIfTrue> [, \<valueIfFalse>]]) : boolean ; Value of sb <bit> (4...63). Boolean value can be replaced by string value(s) valueIf...
    • record.subdef : subdef[] use getSubdef() method
    • record.getSubdef(\<name>) : subdef object
      • record.getSubdef(...).height : number
      • record.getSubdef(...).width : number
      • record.getSubdef(...).filesize : number
      • record.getSubdef(...).player_type : string
      • record.getSubdef(...).mime_type : number
      • record.getSubdef(...).created_on : string
      • record.getSubdef(...).updated_on : string
      • record.getSubdef(...).url : string
      • record.getSubdef(...).permalink : permalink object
        • record.getSubdef(...).permalink.url : string
    • record.metadata : metata[] use getMetadata() method
    • record.getMetadata(\<fieldName> [,\<default>]) : metadata object, with default value(s) if the field is not set for this record.
      • record.getMetadata(...).value : The mono-value (if the field is multi-value : concat values with " ; ").
      • record.getMetadata(...).values : The multi-values as array (if the field is mono-value : array with a single value).
  • collection: collection object (of the record)
    • collection.databox_id: string (same as record.databox_id)
    • collection.base_id: string (same as record.base_id)
    • collection.collection_id: number
    • collection.name: string

Twig context technical note:​

To prevent twig to crash if a field doest not exists in a record (when trying to access a property like .value), getMetadata(...) will return a "fake" empty metadata object.

Same method applies for subdefs: record.getSubdef('missingSubdef').permalink.url will return null.