Collections

The Duda platform provides a data structure as part of a site's content library called collections. Collections are similar to databases in that they are made up of fields (similar to columns) that are assigned a data type. Collections are populated with rows of data.

Purpose

Collections are useful in two main use cases.

Widgets

A widget can connect to a collection and display all the rows that live in that collection. Examples of widgets with this capability are Duda's native Image Gallery and List Widget. When the collection, say adding a new row, this is automatically reflected in the content of the widget.

Additionally a Custom Widget can connect to a collection as well.

Dynamic Pages

Another useful application of collections are powering Dynamic Pages. Using Dynamic Pages each row in a collection automatically becomes its own page on a site. Learn more in the Dynamic Pages guide.

Types

Duda currently offers the following types of collections:

πŸ“˜

Follow the links above to learn more about using Airtable and Google Sheets. This guide focuses on Internal and External collections

There are a few fundamental differences between an internal and external collection.

  • An external collection is populated from an external URL that you provide. This is a useful option when the source of record for the collection is hosted externally (ex. in your database). Any updates from your database will automatically reflect on the website.

🚧

External collection endpoint considerations

Duda will create a collection based on the data returned from an external endpoint URL you provide. This URL must return data with a Content-Type header value of application/json, other content types will result in an error when creating the collection.

  • An internal collection has a "spreadsheet" like view in the Duda editor. This view allows users to add, update and delete data that is part of that collection. This is a perfect option when you want to provide users the ability to manage their data within the Duda editor.

Create a Collection

The first action we need to do is define the structure of the collection we would like to create. This can be thought of similar to the columns and data types of a database table. This is normally done when the collection is created, but can also be updated after the collection is created. Collections can be created in two different ways.

Editor

When creating a new collection, select the type of collection you want to create. See screenshot below. The steps within the editor are documented on our help center.

API

A collection is created by calling the create collection API and defining the fields for that collection. There is an example call below:

curl -X POST \
  https://api.duda.co/api/sites/multiscreen/{{site_name}}/collection \
  -u 'APIUser:APIPassword' \
  -H 'Content-Type: application/json' \
  -d '{ "name": "Tour", "fields": [ { "name": "details", "type": "text" }, { "name": "formatted-address", "type": "text" }, { "name": "is-sold-out", "type": "text" }, { "name": "link-text-1", "type": "text" }, { "name": "link-url-1", "type": "link" }, { "name": "starts-at-short", "type": "text" }, { "name": "venue-name", "type": "text" }, { "name": "event-image", "type": "image" } ] }'

Here's a more detailed look at the fields we sent in our create collection call. We will review all those data types below.

{
  "name": "tour",
  "fields": [
    {
      "name": "details",
      "type": "text"
    },
    {
      "name": "formatted-address",
      "type": "text"
    },
    {
      "name": "is-sold-out",
      "type": "text"
    },
    {
      "name": "link-text-1",
      "type": "text"
    },
    {
      "name": "link-url-1",
      "type": "link"
    },
    {
      "name": "starts-at-short",
      "type": "text"
    },
    {
      "name": "venue-name",
      "type": "text"
    },
    {
      "name": "event-image",
      "type": "image"
    }
  ]
}

When creating an external collection the following fields are used to define where to pull the data from. You can see a sample API call using these fields below the table.

πŸ“˜

These fields can be defined in the Duda editor as well. If no fields are specified, Duda will attempt to create the collection schema based on the values returned in the collection_data_json_path of your endpoint.

Property Name

Type

Description

enabled

boolean

If enabled, Duda will attempt to fetch data from the external endpoint specified. If not enabled the collection will be treated as an internal collection.

external_endpoint

URL

An absolute URI from which Duda will fetch the data for the collection. The endpoint protocol must be https.

external_id

String

Optional parameter which can be used to revalidate the collection cache on demand via the clear collection cache endpoint without using a site alias.

authorization_header_value

String

Optional value to be sent in the Authorization header. This value should include the authorization scheme e.g., Basic or Bearer.

page_item_url_field

String

The value of the name property of an item within the fields array. The value of this field will be used to generate the URL slug for dynamic pages generated by this collection.

collection_data_json_path

String

Path to the root of the collection data within the collection endpoint response. If no path is provided the entire response will be used as collection data. The value can use dot or bracket notation e.g., object.property or ['object'].['property']

curl -X PUT \
https://api.duda.co/api/sites/multiscreen/{{site_name}}/collection/Tour \
  -u 'APIUsername:APIPassword' \
  -H 'Content-Type: application/json' \
  -d '{ "name":"Tour", "external_details":{"enabled":true, "external_endpoint":"https://example.org/tours/performer", "external_id":"abcd", "authorization_header_value":"Bearer xyZaBc", "page_item_url_field":"slug", "collection_data_json_path":"tour.performances" } }'
{
  "name": "Tour",
  "external_details": {
    "enabled": true,
    "external_endpoint": "https://example.org/tours/performer",
    "external_id": "abcd",
    "authorization_header_value": "Bearer xyZaBc",
    "page_item_url_field": "slug",
    "collection_data_json_path": "tour.performances"
  }
}

πŸ“˜

The collection_data_json_path is case sensitive. If special characters are included in the path's property names, bracket notation should be used. Any values returned by the collection endpoint outside of this path will be ignored during data extraction.

Example response from a collection endpoint

{
  "id": "0001",
  "performer": "Rex Manning",
  "tour": {
    "id": "0002"
    "name": "The Say No More Tour",
    "performances": [{
      "id": "0003",
      "slug": "empire",
      "venue": "Empire Records",
      "date": "April 8th"
      }, {
      "id": "004",
      "slug": "duda",
      "venue": "Duda HQ",
      "date": "April 10th"
    }]
  }
}

🚧

Limitations on the property specified in the page_item_url_field

  • Only text fields may be used as the page item URL.
  • The value must be URL compatible and encode any unsafe or reserved characters.
  • Page item multi slash URL is not supported, the value should not contain any slashes.
  • Every row in the data feed has to contain content for the selected field, missing values will cause the data extraction to fail.

🚧

Limitations on the property specified in the collection_data_json_path

  • The property value must be an array of objects.

Fields

Fields are similar to database columns. They are defined with a name and data type. Fields can be added to a collection when it is first created. Additionally they can be added, updated and removed after a collection is created. Whether working with an internal or external collection you must define the schema of that collection. This can be done via the API or through the editor.

Below you will see an example of adding a new field to an existing collection.

curl -X POST \
https://api.duda.co/api/sites/multiscreen/{{site_name}}/collection/{{collection_name}}/field \
  -u 'APIUser:APIPassword' \
  -H 'Content-Type: application/json' \
  -d '[
  {
    "name": "myNewField",
    "type": "text"
  }
]'

There are additional API calls for updating a field and deleting a field.

Supported Field Types

Below is a list of all types of data that are supported for collections.

Text

type: "text" This is the default type for a collection field. Any string is valid.

Image

type: "image" This is a URL for an image. This can be hosted on Duda's CDN or elsewhere (ex. https://www.domain.com/img/name.jpg).

Link

type: "link" This is a URL which is can be used as a link for native Duda widgets like a button. (ex. https://www.domain.com/link.html).

Business Hours

type: "business_hours" This is data structure that represents business hours. This field type connects to the Duda business hours widget. See the structure below.

"my_business_hours": [
    {
      "days": [
        "FRI"
      ],
      "open": "09:00",
      "close": "20:00"
    },
    {
      "days": [
        "MON",
        "TUE",
        "WED",
        "THU"
      ],
      "open": "09:00",
      "close": "18:00"
    }
]

πŸ“˜

In the Business Hours example above both SAT and SUN will display as Closed since they are not included in the JSON

Video

type: "video" This is a URL for a video hosted elsewhere. Youtube, Vimeo and Dailymtion links are supported. The formats below must be used:

  • Youtube: https://www.youtube.com/watch?v=8EsYwAKxAFU)
  • Vimeo: https://player.vimeo.com/video/77523904
  • Dailymotion: https://www.dailymotion.com/embed/video/x70n2l8

Phone

type: "phone" This is a phone number which can link to a widget expecting a phone number like our Click-to-Call widget (ex 888-234-2222).

Email

type: "email" This is an email address which can link to a widget expecting an email address like our Button widget (ex [email protected]).

Location

type: "location" This is a data structure that represents a location. This field type connects to the Duda map widget. See the structure below.

"my_map": {
        "address": {
          "streetAddress": " 1007 5th Ave",
          "postalCode": "10028",
          "region": "NY",
          "city": "New York",
          "country": "USA"
        },
        "geo": {
          "latitude": "40.7788112",
          "longitude": "-73.9646043" 
        }
}

Social Accounts

type: "social_accounts" This is a key/value store of social networks and the specific account identifier belonging to the organization on each network. This field type connects to the Duda social icons widget.

🚧

The location field type is not supported via API for Internal Collections.

"social_accounts": {
        "email":"[email protected]",
        "whatsapp":"9543543543",
        "facebook":"duda",
        "twitter":"duda",
        "instagram":"duda",
        "youtube":"UCPMwzOc1Su-s2z-J1xiU9ig",
        "linkedin":"duda",
        "yelp":"orens-hummus-shop-palo-alto",
        "pinterest":"michelleobama",
        "google_my_business":"Cafe+Nona/@32.0718045,34.7809687,15z/data=!4m19!1m13!4m12!1m4!2m2!1d34.8127232!2d32.0503808!4e1!1m6!1m2!1s0x151d4b8468d5803f:0xc4b3f0a57332f82f!2z16DXldeg15Qg16rXnCDXkNeR15nXkeKArQ!2m2!1d34.7815956!2d32.0769206!3m4!1s0x151d4b8468d5803f:0xc4b3f0a57332f82f!8m2!3d32.0769206!4d34.7815956",
        "waze":"34.784267763974256, 32.07510593016749",
        "vimeo":"dudamobile",
        "snapchat":"michelleobama",
        "reddit":"duda",
        "tripadvisor":"Restaurant_Review-g32849-d2394400-Reviews-Oren_s_Hummus_Shop-Palo_Alto_California.html",
        "foursquare":"v/anita-la-mamma-del-gelato-%D7%90%D7%A0%D7%99%D7%98%D7%94/4b488bfff964a520184f26e3",
        "rss":"[https://www.duda.co/blog/feed/](https://www.duda.co/blog/feed/)",
}

Inner Collection

type: "collection" This is data structure that represents an inner collection. See the structure below.

{
  "name": "my_photos",
  "type": "collection",
  "inner_collection_fields": [
    {
      "name": "property_image",
      "type": "image"
    },
    {
      "name": "property_text",
      "type": "text"
    }
  ]
}
"my_photos": [
    {
      "property_image": "https://www.domain.com/img/medium.jpg",
      "property_text": "la la text"
    },
    {
      "property_image": "https://www.domain.com/img/medium2.jpg",
      "property_text": "la la text"
    }
  ]

🚧

The inner collection field type is not supported via the API for Internal Collections. You can create a specific inner collection called an image collection in the Duda editor inside an internal collection

Collection Reference

type: "collection_ref" This is data structure that represents an existing collection. This collection can be referenced by name. See the structure below.

{
  "name": "more_photos",
  "type": "collection_ref",
  "inner_collection_fields": [
    {
      "name": "prperty_image",
      "type": "image"
    },
    {
      "name": "property_text",
      "type": "text"
    }
  ]
}
{
    "more_photos": "my_other_collection"
}

🚧

The collection reference field type is not supported via API for Internal Collections.

πŸ“˜

Integer fields, as well as other unsupported types (such as boolean values), should be set as text field types, as the content will be displayed as text.

Rows

Rows of a collection are very similar to rows of a database. They can be added, updated and deleted at any time. The way to add, update and delete a row is different based on the type of collection you are working with.

The rows of an external collection live in the JSON data feed provided by the external_url. This makes it very easy to add, update or delete rows from a collection. Just add the row in the JSON data feed and it will show up on the Duda site. The same approach will work for updating and deleting a row.

The rows of an internal collection can be changed in the Duda editor and with the API. Below we will discuss how to change rows in an internal collection via the API. You can learn more about the editor experience in our support portal.

curl --request POST \
  --url https://api.duda.co/api/sites/multiscreen/{{site_name}}/collection/{{collection_name}}/row \
  --header 'content-type: application/json' \
  --data '[{"page_item_url":"minnesota-timberwolves","data":{"city":"Minnesota","mascot":"Timberwolves","description":"The Minnesota Timberwolves (also commonly known as the Wolves) are an American professional basketball team based in Minneapolis, Minnesota.","slogan":"All Eyes North","homepage":"https://timberwolvesteamstore.com/"}}]'
[
    {
        "id": "233"
    }
]

There are additional API calls for updating a row and deleting a row.

Unlisted Fields in Data

External collections can contain properties in their items that have not been specified as fields within the collection. Any unlisted properties will not be available as options when connecting the collection to widgets, however you can access these properties from the HTML and JavaScript panes of the widget builder when creating your own widgets by referencing the property name directly. Unlisted fields can be of types String, Number, Null and Boolean, or they can contain an object with properties that correspond to one of these types.

External Endpoint Data Format

Each item within the data array returned by your external endpoint will become a a row in the site's collection. Updating the items within the endpoint will cause Duda to re-validate the data and recreate the collection items. This will be done automatically roughly every two hours, or you can force a re-validation by clearing the collection cache.

Duda allows the format of the data returned by your external endpoint to be fairly flexible. By defining the page_item_url_field and collection_data_json_path properties, it's possible to let Duda know the path to the data within the returned object, as well as the property to use as the item id in a dynamic page URL. Given the following data:

{
  collection: {
    description: 'Collection data for dude',
    items: [{
      itemId: 1,
      name: 'Item 1'
    }, {
      itemId: 2,
      name: 'Item 2'
    }, {
      itemId: 3,
      name: 'Item 3'
    }]
  }
}

You would configure your collection to have a value of collection.items for the collection_data_json_path property and use itemId as the value for the page_item_url_field property. Any dynamic pages would be generated with the following URL structure: /collectionName/{itemId}

Data Property Defaults

It's possible to leave the the data properties blank if your data follows a specific schema. If you define a property named page_item_url and give it a string value, Duda will automatically choose this property for the page_item_url_field value. Other item properties should then be wrapped in an object with the property name of data.

If the top level of your response is an array of items, defining the collection_data_json_path is unnecessary.

[{
  "page_item_url":"1",
  "data":{
    "name": "Item 1"
  }
},{
  "page_item_url":"2",
  "data":{
    "name":"Item 2"
  }
},{
  "page_item_url":"3",
  "data":{
    "name":"Item 3"
}]

Caching

By default, Duda caches the data for an external collection to help with performance. By default, we cache a collection up to 2hrs. If you want to update the data in the site immediately, you can use one of these revalidate calls.

Clear Collection Cache

This forces Duda to refresh the data from an external URL for a given collection.

curl -X POST \ https://api.duda.co/api/sites/multiscreen/{site_name}/collection/{collection_name}/revalidate \
  -u 'APIUser:APIPassword'

Clear All Collections by External Id

Revalidate all collections in all sites under the same account, that use the provided external id

curl -X POST \ https://api.duda.co/api/sites/multiscreen/collections/revalidate/{external_id} \
  -u 'APIUser:APIPassword'

Limitations

The following limitations exist for Internal and External Collections.

Internal

External

Number of collections per site

100 (including image collections)

100 (including image collections)

Rows

200

Fields

50

100

Inner collection rows

30

Inner collection fields

10

15

Text field character limit

4500

Collection name character limit

50

50

Field name character limit

50

50

Page item URL character limit

100

Update data

Publish site/content library

Automatic

🚧

External Collection Filesize Limit

In addition to the limits presented above, a single external collection endpoint cannot exceed 20MB of data.

Image Collections

  • Image collections can only be created using the Duda editor. However, existing image collections can be edited and deleted using the API.
  • Image collections do not support page item URL.

Updated 14 days ago


Collections


Suggested Edits are limited on API Reference Pages

You can only suggest edits to Markdown body content, but not to the API spec.