Sealpress: design and planning

Some days ago during a sealcoding session we had a small offline discussion about what Sealpress can be and what’s the best way to implement it. The goal is to create a CMS that:

  • has structured, metadata-rich content;

  • can render to both html+http (with streaming support), as well as Gemini and any other protocols, thanks to the fact that content is NOT declared as HTML;

  • is easy to use while not hiding the markup from end-users;

  • supports good typography practices out of the box;

    • hyphenation of words in order to have neat justified text
    • paragraphs have reasonable max-width
    • language metadata for proper hyphenation and screen reader support
    • prevents short words from appearing at the end of the line by strategically injecting non-breaking spaces (important for Polish texts)
  • supports RSS (possibly with full-featured filtering);

  • uses no third-party assets on the front-end by:

  • has a neat markup editing GUI with previews (split screen) that works with minimal amount of JS or event without any JS

  • supports operational transformation or Conflict-free Replicated Data Type in order to properly handle cases when two users work on the same article at the same time

  • supports code blocks syntax highlighting

  • automatically generate Table of Contents, with non-volatile heading IDs

  • enables programmers to create Layouts (including navbars, footers, sidebars) that wrap around Pages (the content itself)

That’s… a lot of requirements! I think pulling this off is entirely within our reach. We just need to divide the work into self-sufficient modules as much as possible, and use much of what we already have.

So. What needs to be built?

  1. Abstract markup language for rich article content.

    During the meeting we agreed that a cool way to go would be to have every article consist of some metadata and a list of components, represented as just an array of json objects. Each json object could represent a heading, a block of text, a codeblock, an image with a caption, etc. So we need:

    1. a specification for that language

    2. renderer for that language - something that takes the list of components and spits out html (via tempstream)

    3. GUI for editing markup in this language. I don’t think we should expect the users to author json files by hand :smiley: I imagine the interface as a column of text inputs, grouped into chunks, where each chunk represents one component added to the article. The user can add a new component anywhere between existing components or add a new one at the end. When they add a new component, a dropdown appears asking about the type of the component (is it a block of text? an image? a heading?) appears. When the type of the component is chosen, new inputs appear, that help the user enter all the information that a given component needs (if it’s an image - ask about alt text, style of the image (should it float to the right? or maybe be full-width?), etc).

      To the right of that column is a live HTML preview, kind of how it works on Discourse.

    It’s important to keep the list of the components open, so any end-user with some programming savvy can register their own components in the app and use it across all documents created in their instance.

  2. Admin Panel and Integration of the markup tooling with Sealgen.

    I imagine every Content Type in a Sealpress app would just be a Sealious collection that includes various fields. One of the fields could be the Rich Content field that would use markup designed in point 1. We then need to automatically create GUI forms for every content type that they have defined, with option to overwrite it with a custom UI if they so desire.

    We’d also need to create a set of sane CSS defaults and embed them in the app.

    If we combine those things into a neat package, we could make it so you can just run npm init sealpress and get a working simple CMS that’s just waiting to be customized and deployed :fire:


I’m eager to hear your thoughts! I assume there are still many gaps to fill in - don’t hesitate to ask here, so we can have a shared vision of what Sealpress can become. Also, if there’s a specific part of the system that you’re eager to start working on, now is the time to call dibs! :wink:

I dont even now where to start, I feel like there is a lot of stuff to do. Maybe we could start by adding an abstract class that defines general behaviour than every component should have(Kuba came up w this, Im just writting it down so we dont forget) and our interpreter has to be able to process objects of that abstract class.

I also feel like the articles should be an objects of that abstract class, and that we should just create classes for simple components, and have boxes that group them in certain ways (the articles may be instances of the box object)

I also think we need to discuss the sintax of our language, but maybe this can be done later.

Tasks to start

  1. Write abstract class “component” from which every component will inherit
  2. Create basic components:
    a) text
    b) image
    c) box
  3. Define basic specification for json files.
1 Like

Let’s start then by creating a new module that would be responsible for rendering the json notation to a tempstream. The steps you have outlined above seem like a great starting point! Let’s give it working title of jdd (json-driven-documents).

I’ve created a task for that - feel free to ask any questions regarding it :slight_smile: https://hub.sealcode.org/T2694

Some more thoughts on JDD, that hopefully will guide the works on D1321.

Here are some use cases and scenarios that the implementation should enable:

  1. Ability to add custom components to the registry in a way that makes it compatible with any output format.

  2. Ability to add a custom output format (html, gemini, maybe pdf, whatever) without changing the code of jdd itself.

  3. Ability to modify documents before rendering (for example: adjust all headings levels).

  4. Ability to extract information about all headings and all images in a document

Here’s a thought: inspired by @FilipI insights, let’s do it the TDD way. So: let’s design the API first, write some tests for it, see how the API looks, and once we’re fine with it, we’re “just” going to fill the implementation so it matches and passes the tests. @migueldar could you give writing such tests a shot? Of course they’ll be failing, as they would be calling not-yet existing methods and classes, but I think it’ll be a great way for us to focus on the desired outcome and drive our further discussions about the implementation. The tests would showcase how the above 4 points would work by using the API that we’ll be providing