Skip to content

bodyTree vs contentTree #84

@adgad

Description

@adgad

Content Tree

In Content Tree, we have represented the output as a single root node, which (for now) has a body property. The intention was to allow for further expansion as we model the rendering data for other parts of the article - such as toppers (#73), maybe other future things.

interface Root extends Node {
	type: "root"
	body: Body
}
interface Body extends Parent {
	type: "body"
	version: number
	children: BodyBlock[]
}

The build currently outputs three different JSON schemas:

  • content-tree.schema.json - this expects the Root node with all external properties (e.g. ContentTree.full.Recommended)
  • transit-tree.schema.json - this expects the Root node without external properties (e.g. ContentTree.transit.Recommended)
  • body-tree.schema.json - this expects the Body node without external properties (e.g. ContentTree.transit.Recommended)

C&M representation

current state

Note

This section assumes a future topper is part of content-tree, to illustrate the point.

Currently in C&M we have a bodyTree field that validates against the transit-tree schema. This means the data published would look like this:

{
    "id": "https://api.ft.com/content/1234",
    "bodyTree": {
        "type": "root",
        "body": { "type": "body", "children": [...] }
        "topper": { "type": "topper", "headline": "blah", asset: {} }
    }    
}

This is somewhat counter-intuitive to someone reading the API. It also means, if/when we add a topper to the root, this would need to appear in bodyTree - which also wouldn't make sense.

option 1

  • Content Tree continues to have the root node with body and topper properties
  • bodyTree field validates against the body-tree schema
  • topperTree field validates against a future topper-tree schema
{
      "id": "https://api.ft.com/content/1234",
      "bodyTree": { "type": "body", "children": [...] }
      "topperTree": { "type": "topper", "headline": "blah", asset: {} }
}

This was our original intention when planning to bring content-tree into C&M. The intention was that bodyTree would be analogous to bodyXML, which would lead to a more straightforward migration. topperTree doesn't necessarily have an equivalent in the existing API, so does not have the same consideration. Keeping them as separate fields in C&M may also make things simpler for use cases where a consumer does not need the entire content (e.g. RSS feeds only need the body and wouldn't really need a topper)

The downside is that the content-tree root becomes somewhat irrelevant, as nothing would use it in reality.

It also means FT.com consumers need to validate multiple separate fields.

option 2

  • Content Tree continues to have the root node with body and topper properties
  • contentTree field validates against the transit-tree schema
{
    "id": "https://api.ft.com/content/1234",
    "contentTree": {
        "type": "root",
        "body": { "type": "body", "children": [...] }
        "topper": { "type": "topper", "headline": "blah", asset: {} }
    }    
}

Users that require just the body would need to access contentTree.body

This option does mean there is a clearer relationship between the content-tree spec and the C&M field. And that we don't need to generate separate schemas just for the body and topper.

It is perhaps slightly more involved for consumers expecting just one or the other, but maybe not in a bad way?

It also might be nicer if we for example have several other properties we might add to the root. An off-the-cuff example might be something like colourScheme or pageLayout, which could be properties affecting both bodies and toppers. Having a single field means we don't need to add them individually to the C&M schema.

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions