What is the BMS?

A graph database of content

Think of it as a knowledge constellation made of blocks. A Paragraph, an FAQ, a Blog, a Documentation, Privacy Policies or just an image.

Notice lets you embed your content in a single click in your favorite CMS, but it's also headless. Our API lets you access your data programatically, in the format you desire (HTML, JSON, markdown). This can be used for multiple purposes : building your own views, getting your data for deploying statically built websites, creating a chatbot on Slack, using our search to fetch some data across different projects, and so on.





Blocks are ubiquitous data atoms, they will power the web and be a new standard. A new kind of web components.

How are blocks structured?

Each block necessarily has these 4 basic information:

  • A unique ID (_id)
  • type, which defines which block we are dealing with (type)
  • If it is a block project or not (isProject)
  • Its membership, i.e. to which project and workspace it is attached (projectIds & workspaceId)

Then, all the properties that actually define a block can be found in these three structures:

Data

  • paragraph

    { "text": "Content" }
    
  • section

    { "text": "Title" }
    
  • article

    { "text": "Title" }
    
  • list

    {
      "items": ["Item 1", "Item 2"],
      "style": "orderer" // ordered | unordered
    }
    
  • header

    {
      "text": "Content",
      "level": 1 // 1 | 2 | 3 | 4
    }
    
  • embed

    {
      "service": "youtube", // youtube | vimeo
      "source": "https://youtu.be/XqZsoesa55w" // URL
    }
    
  • file

    {
      "file": {
      	"id": "e61d2e90-e4e4-4677-be0a-9bdf36ee18a2",
        "url": "https://media.tenor.com/JEuupMZB5HwAAAAC/michael-scott-flip.gif" // URL
      }
    }
    
  • table

    {
      "content": [
        ["Header 1", "Header 2"],
        ["Item 1", "Item 2"]
      ],
      "withHeadings": true
    }
    

Preferences

{
	"autoDetectDarkMode": true,
	"contactForm": true,
	"contactFormEmail": "[email protected]", // Email
	"defaultToDarkMode": true,
	"displayDarkMode": true,
	"displayLogo": true,
	"displaySearchBar": true,
	"displaySections": true,
	"displayTitle": true,
	"fontFamilyName": "Roboto",
	"shortListAccordeon": true,
	"defaultLanguage": "en",
	"displayLanguageSelector": true
}

Colors

{
  "darkModeBgColor": "#fff",
  "darkModeFontColor": "#fff",
  "fontColor": "#fff",
  "mainBgColor": "#fff",
  "secondaryFontColor": "#fff",
  "cardColor": "#fff",
}

Last but not least, Block Tree!

We must not forget that blocks are structured as a tree of blocks and therefore each block can contain other blocks and so on.

If you want to loop over blocks to render them you have to go through this tree recursively.

An example with our implementation of walkGraph function in Typescript

const walkGraph = <T>(graph: T, cb: (node: T, parent?: T) => void, field = 'blocks', parent?: T): void => {
  cb(graph, parent)
  for (const block of (graph as any)[field] ?? []) {
    walkGraph(block, cb, field, graph)
  }
}