Page MenuHomePhabricator

Create primitives
Open, NormalPublic


Affects rCMS

Our CMS works by defining basic primitive types, like building blocks in a Lego that a user can manipulate to assemble complex structures. Primitives can be any of the following:

  • Text
  • Images
  • Videos
  • Binary Blobs
  • Lists (wishlist)
  • Tables (wishlist)
  • Embeds - urls
  • Form components (text, blobs, booleans)

They all should share a common interface, known as a primitive which allows the clients (whether it's a browser running Javascript, or a mobile or desktop application) to properly manipulate these. As long as the client has the necessary capabilities to render these and arrange them in a grid it should be able to render any page.

The application can also use these primitives to generate the necessary editors for it's own components. For example, an image primitive could return a FormDataBlob for it's editor, so the client knows how to present an appropriate form to the end user without requiring them to have additional code to manage this. While this may have the drawback of an application that is very limited and potentially user unfriendly, it would create a consistent experience across the application.

We could consider adding components known as 'super-powers', these would allow optional functionality to be implemented by the client at it's sole discretion. For example, when adding a FormDataText to input a URL, we could also provide a link-preview super-power that generates a link preview if the client supports it, but doesn't require to throw an error if they don't.

Any page made with CMS can be assembled with these basic components, making it easy to create more complex layouts with just these components.

Related Objects

Event Timeline

cesar triaged this task as Normal priority.Apr 8 2020, 12:12 PM
cesar created this task.
cesar created this object with visibility "Public (No Login Required)".
cesar added a comment.May 29 2020, 3:14 PM

At the end of the day, all content can be considered to be hierarchical and to descend from two (for the sake of simplicity) base primitive types:

  • Text data for any component that is intended to provide text based output to the user's screen. This can refer to both plain text and RTF text like MMD
  • Binary data for data that is intended to be processed by a machine - this can be binary executable code, images, videos, or other binary data

This means that all components can inherit from these and provide a fail-safe mechanism to manipulating these pieces of data. Regardless of whether the client has the ability to use formats that extend these.

The extensible mechanism now could look like this:

  type: "x-figure",
  content: {
    location: "figure.server:123456:abcde"
  fallback: {
    type: "image",
    content: {
      location: "https://figure.server/media/cover/123456/abcde/large/",
      link: "https://figure.server/media/123456/abcde/original/"
    fallback: {
      type: "blob",
      content: {
        location: "https://figure.server/media/123456/abcde/original/",
        length: null

The example has our own media server (figure) handling the image uploads and distribution, so the CMS server can just focus on managing said data. Here's how clients would manage this:

  • A client that supports the figure protocol, would see this figure and load the index file for the image, then select the appropriate media for the viewport and download and render the appropriate media.
  • A client that does not support figure, will download the pre-selected default and render it. While it may not be the optimal image, it will probably be serviceable.
  • A text based client can render a button or a link to download the file.

A similar behavior will be used to render forms so a user can enter information. These objects should be prefixed with form-, as in form-x-figure, form-image and form-blob. Form properties must have a name, the client must aggregate them to the scope of the page and generate a JSON string with their output that can be delivered to the server. The server must have the necessary capabilities to upgrade a fallback to the data that is intended.

This means that the server must have the following capabilities:

  • Up/Downgrade primitives
  • Validate primitives
  • Store the data
  • Deliver an HTML client to manipulate the data within a browser

The client must have the following capabilities:

  • Render primitives
  • Fallback on primitives that it does not support
  • Send data to the server
  • Handle server validation responses