Liveblog Posts Body

Data structure for Liveblog posts body

This guide documents the data structure which is used to represent the content inside a Liveblog post.

This data will be returned by the Liveblog Posts API

A liveblog post consists of multiple items, which we will refer to as blocks.

These blocks have varying types and need to be rendered

Broadly speaking there are 3 main categories of blocks:

  • Blocks which have HTML content
  • Blocks which contain content from the CMS
  • Blocks which have a v1 widget from Sportal365
  • Blocks which have a v2 widget from Sportal365

All posts will follow the same general structure:

{
  "blocks": [
    {
      "id": "<unique identifier of the block itself>",
      "data": {},
      "type": "html_block|smp_content_block|widget_smp|widget_smp_V2"
    }
  ]
}

Data is a polymorphic object and the contents depend on the type

HTML Blocks

This type of blocks contain HTML which can be directly rendered without any other implementation steps.

They follow the structure inside the data object:

{
  "type": "<the particular type of html content>",
  "content": "The HTML content itself",
  "object": {}
}

object is optional and can contain additional data or configuration for the HTML block.

Changes

The main differences compared to the old Content API blockies are:

  • All blocks which contain ready HTML are grouped under html_block type to make implementations simpler
  • All additional configurations should be stored in object

HTML only blocks

These are blocks where the only data which can be displayed is the html itself.

Supported blocks:

  • paragraph
  • heading
  • table
  • ordered_list
  • unordered_list
  • blockquote
  • code

Example with paragraph

{
  "id": "8fab9851-906d-40aa-a2dd-9c13291958e1",
  "data": {
    "type": "paragraph",
    "content": "<p>This is a test paragraph <strong>block</strong></p>",
    "object": null
  },
  "type": "html_block"
}

Link block

This block contains the HTML which can be directly rendered and additional configuration options selected in the CMS

{
  "id": "1e22bd1f-901c-480b-9b96-a6d1fd2b6291",
  "data": {
    "content": "<a href=\"https://sportal.bg/news-2023073020582358369\" target=\"_self\">Везенков е №1</a>",
    "object": {
      "link": "https://sportal.bg/news-2023073020582358369",
      "text": "Везенков е №1",
      "content": "<a href=\"https://sportal.bg/news-2023073020582358369\" target=\"_self\">Везенков е №1</a>",
      "link_type": "article",
      "open_type": "same_window"
    },
    "type": "link"
  },
  "type": "html_block"
}

Embed block

This block contains the HTML which can be directly rendered and additional configuration options selected in the CMS

{
  "id": "5d1cfcf8-b048-49f9-b549-999867f13a58",
  "data": {
    "content": "<iframe width=\"560\" height=\"315\" src=\"https://www.youtube.com/embed/FtNeJlU3szc\" title=\"YouTube video player\" frameborder=\"0\" allow=\"accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture; web-share\" allowfullscreen></iframe>",
    "object": {
      "type": "video",
      "content": "<iframe width=\"560\" height=\"315\" src=\"https://www.youtube.com/embed/FtNeJlU3szc\" title=\"YouTube video player\" frameborder=\"0\" allow=\"accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture; web-share\" allowfullscreen></iframe>",
      "validation_type": {
        "value": "html",
        "default": false
      },
      "embed_type": "video"
    },
    "type": "embed"
  },
  "type": "html_block"
}

Content blocks

These blocks have content created by the Content API in most cases via the CMS.

Supported values for content_type are:

  • article
  • gallery
  • image
  • video
  • banner

They all follow the same general structure inside the data object

{
  "data": {
    "id": "unique identifier of the content, e.g article.id",
    "object": {
      "title": "Contains a teaser of the object from Content API. Usually not the full data model."
    },
    "custom": {
      "setting1": "Contains any custom settings which can override the properties in the object or any other data."
    },
    "type": "<content_type>"
  },
  "type": "smp_content_block"
}

Changes

  • All types are grouped under smp_content_block
  • All settings/data specific to the post are grouped under custom.
  • Object contains a teaser version of the resource to allow to easily render the data.
    • The data format in most cases should be the same as the /v2/{content_type}/search endpoints.
    • It is not the full data model, but should be enough to visually reprsent the content.

Example

{
  "id": "ed79d145-ba04-453b-a702-fb50e5ecb0a5",
  "data": {
    "id": "2022101706240160464",
    "custom": {
      "position": {
        "width": "100",
        "alignment": "left"
      },
      "starts_at": "03:15:00"
    },
    "object": {
      "id": "2022101706240160464",
      "entity_type": "video",
      "title": "Liveblog Video",
      "category": {
        "id": "2022020114283330812",
        "entity_type": "category",
        "title": "Season 2020",
        "description": null,
        "active": false,
        "parent_id": null,
        "created_at": "2022-02-01T14:28:33+00:00",
        "updated_at": "2023-06-22T10:10:12+00:00",
        "seo": {
          "slug": "season-2020",
          "index": true,
          "title": "Season 2020",
          "follow": true,
          "keywords": [],
          "description": null,
          "redirect_type": null
        }
      },
      "created_by": {
        "id": "2021071612142394418",
        "full_name": "Admin"
      },
      "main_media": [],
      "origin": {
        "id": "2020052811523478824",
        "slug": "Test Articles 5",
        "name": "test Articles 5",
        "default": false,
        "description": null,
        "created_at": "2020-05-27T11:57:03+00:00",
        "updated_at": "2022-10-27T09:29:08+00:00"
      },
      "additional_categories": []
    },
    "type": "video"
  },
  "type": "smp_content_block"
}

Widget Blocks

Widget blocks represent a widget from the Sportal365 widget library.

There are two block types for widgets:

  • widget_smp This is the type for all version 1 widgets: only Football
  • widget_smp_V2 This is the type for all version 2 widgets: Football, Basketball, Tennis and other sports as they are added

The general structure is

{
  "sport": "football",
  "config": {
    "options": {
      "widget-config-options": "123"
    },
    "widgetId": "<widgetId goes here>"
  },
  "content": "<div>HTML content to render the widget goes here</div>",
  "type": "<type of widget goes here>"
}

The content property contains HTML which can be used to render the widget.

Unlike the HTML in the html_block, the content will not render automatically out of the box - there is additional setup to load the widget library.

The setup is different for the v1 and v2 widgets. Links to widget docs should be added here.

The config property contains the widget settings and has a different data structure according to the data.type.

Supported values for the data.type are currently:

  • widgetOdds
  • widgetTeamComparison
  • widgetFootballStandings
  • widgetFootballPlayerH2H

Example

{
  "id": "12d6bec5-4eac-4243-8210-6efe866c1b29",
  "data": {
    "sport": "football",
    "config": {
      "options": {
        "lang": "en",
        "team1": {
          "id": "102",
          "seasonIds": [
            "7550"
          ]
        },
        "team2": {
          "id": "104",
          "seasonIds": [
            "8441"
          ]
        },
        "apiKey": "2f852b4de2f3a5cf3188e74b33087bb4:2c18422f8e826a7d11aeed52edb2449e",
        "apiURL": "https://football.api.integration.sportal365.com",
        "market": {
          "name": "1x2"
        },
        "eventId": 2852718,
        "oddClient": "sportal",
        "statFields": [
          "played",
          "win",
          "draw",
          "defeats",
          "goalsScored",
          "goalsConceded"
        ],
        "displayOdds": true,
        "oddProviderIds": [
          43,
          154,
          509,
          511
        ],
        "canSelectMarkets": true,
        "displayTeamShortNamesOnMobile": true,
        "displayTeamShortNamesOnDesktop": false
      },
      "widgetId": "team-comparison"
    },
    "content": "<div data-widgetid='team-comparison' data-options='{\"lang\":\"en\",\"apiKey\":\"2f852b4de2f3a5cf3188e74b33087bb4:2c18422f8e826a7d11aeed52edb2449e\",\"apiURL\":\"https://football.api.integration.sportal365.com\",\"oddClient\":\"sportal\",\"team1\":{\"id\":\"102\",\"seasonIds\":[\"7550\"]},\"team2\":{\"id\":\"104\",\"seasonIds\":[\"8441\"]},\"statFields\":[\"played\",\"win\",\"draw\",\"defeats\",\"goalsScored\",\"goalsConceded\"],\"displayOdds\":true,\"eventId\":2852718,\"market\":{\"name\":\"1x2\"},\"oddProviderIds\":[43,154,509,511],\"canSelectMarkets\":true,\"displayTeamShortNamesOnMobile\":true,\"displayTeamShortNamesOnDesktop\":false}'></div>",
    "widget_type": "widgetTeamComparison"
  },
  "type": "widget_smp"
}

Changes

There are very small changes compared to the older blocky

  • data.widget_type is renamed to data.type for consistency with other blocks
  • preview is gone