A pie-chart with an eye eating a row of various floating documentsA pie-chart with an eye eating a row of various floating documents

devlog

Collecting Content

Illustrated drawing of Amadeus Maxmimilian StadlerIllustrated drawing of Amadeus Maxmimilian Stadler

Amadeus Stadler

May 09, 2021

Spring is hopefully arriving for good—and with it my deadline for the BA thesis part of this project. Thankfully, it looks like we might get a bit of an extension due to the ongoing pandemic, but regulations change on a daily basis, so I’m not sure whether or not I can trust that.

In any case, I’m still sticking to my original plans for now and am happy to report that a lot has happened with Mattrbld in the past two weeks! Focusing on features and functionality certainly has its drawbacks, but my first priority is getting the app into a functional state so I (and eventually others!) can properly test it—but more on that after we take a look at what’s new!

A Quick Recap

In the last devlog, I presented the Schema Editor and went into details of how it works—if you haven’t read about that yet, feel free to do so and come back. In summary, content items (blog posts, pages, users, etc.) in Mattrbld are stored in Collections, which in turn have a certain Schema. This Schema consists of a set of fields that dictate the shape of the data. This way, developers have full control and content editors can be confident that they won’t accidentally break something.

The Schema Editor is where a developer can visually build out a Schema for a particular collection and while it was already working well two weeks ago, I spent some extra time since then to make it even better.

What’s New

Schemas from Content

Like I had announced at the end of the last devlog, I implemented the ability for developers to generate a Schema based on an existing piece of content. Building a Schema by hand is obviously the preferred method, but starting with nothing can be overwhelming, especially if the developer isn’t intimately familiar with the shape of any pre-existing content.

Generating the Schema based on a content item gives developers a base to work with and ultimately can save them a lot of time, especially when transitioning to Mattrbld from another headless content management system.

After selecting a piece of content, Mattrbld will do its best to infer the type of all fields it can find in that content item and will present them to the developer as a preliminary Schema. At this point, the developer can step in and correct any fields that were assigned the wrong type and convert that schema candidate into a fully fledged schema for further editing.

A screenshot of the Schema from Content modal showing that a markdown file was picked and which fields were automatically inferred from itA screenshot of the Schema from Content modal showing that a markdown file was picked and which fields were automatically inferred from it
Schema candidate generated from a blog post on my personal website

New Fields

I’ve also added a bunch of new default fields that can be used in Schemas without having to create custom fields. I think that by now I have pretty much every basic field that people would like to use regularly, but the list might still grow based on feedback.

Here are the ones that were added since the last devlog:

  • Image Field

  • Toggle Field (for Boolean values)

  • Color Field (with support for limited palettes)

  • Tags Field

  • List Field

  • Dropdown Field

  • Checkbox Field

  • Radio Group Field

  • File Field

  • Link Field

  • Content Reference Field (to reference another content item by a specific field)

A a two-column list of some of the default fields available in the Schema Editor. The two columns are titled “Content” and “Helpers” and contain the items mentioned in the list beforeA a two-column list of some of the default fields available in the Schema Editor. The two columns are titled “Content” and “Helpers” and contain the items mentioned in the list before
There are even more than these…

All of these fields come with options to tailor them exactly to your needs, as well as validation and default values where appropriate.

Brand Colour Settings

Many websites and brands follow a specific colour-styleguide. To make sure that content editors always know what colours they can use, a global colour palette can now be added in the General Settings tab. This palette will be available in all colour fields on top of the palette optionally defined there.

A screenshot of a color palette component listing an array of colours with a preview, their name and the option to delete them. At the bottom of the list a new colour can be defined and addedA screenshot of a color palette component listing an array of colours with a preview, their name and the option to delete them. At the bottom of the list a new colour can be defined and added

Collection Management

Now that the UI for Schemas is in place, the next logical step was to create the interface for managing collections and assigning Schemas to those. A Collection in Mattrbld is a group of content items of a specific type within a specified folder. Collections can have one or more Schemas assigned to them, to which the content items have to adhere.

A screenshot of the Collection management interface of Mattrbld. A collection titled “Blog Post” is being edited. Its type is set to Markdown and it is allowed one Schema: Blog PostA screenshot of the Collection management interface of Mattrbld. A collection titled “Blog Post” is being edited. Its type is set to Markdown and it is allowed one Schema: Blog Post

On top of that, developers can finely control what roles are able to do within a Collection. This enables workflows that allow, for example, junior editors to create new content as drafts, but only giving senior editors the capabilities to publish them. Or perhaps editors should only be allowed to create content items, not sub-folders within the Collection—the permission system makes it possible.

A detail view of the permission management for content Collections in Mattrbld listing roles such as Everybody, Developer and Project Owner on the left side and what they can do on the right side. For example: Everybody can create content, Developer can delete content, Project Owner can do everythingA detail view of the permission management for content Collections in Mattrbld listing roles such as Everybody, Developer and Project Owner on the left side and what they can do on the right side. For example: Everybody can create content, Developer can delete content, Project Owner can do everything

Internal Linking

Something that’s admittedly hard to do with file-based headless CMSs is referencing and linking to internal content. Still, being able to reliably do this is a very important feature for obvious applications such as linking to another blog post or sub-page, but also for less obvious reasons, such as linking an author to a post, or building a menu system.

Mattrbld now has a flexible system for internal linking that allows developers to control exactly how an internal URL is generated from the fields of a piece of content. This means other content items can not only be referenced by one of their fields, or their file-path, but also by a combination of some or even all of their fields in a customised order and with custom additions and suffixes.

For example, posts in my personal blog get assigned a URL by my static site generator that has the following shape: /blog/yearPublished/slugifiedTitle/, which means that to link one post to another manually, I’d have to remember what year that post was published in, how exactly the title gets slugified, that there needs to be a trailing slash, and so on.

With Mattrbld’s internal linking feature, I can specify the template for internal links between blog posts once and have all the hard work be done by Mattrbld so I can focus on writing content: /blog/:date[year]/:title/

This works not only for link-fields, but also for links created in rich text editor fields and thus greatly reduces the risk of broken links or user errors. The only caveat of this system is that the file being linked is not aware of it, meaning that if the file or any of its fields are changed, there’s no way to automatically update every file it was linked in. Perhaps there will be ways to handle such a situation in the future, but for now it’s a limitation worth knowing about.

Sidebar Configuration

Since Collections can now be created an managed, I finally was also able to properly implement configuring the project sidebar. To recap: whenever a project is opened in Mattrbld, a sidebar appears that shows the current status of the project and offers links for navigating within it. It has a large section in between the project details and navigation links for the Dashboard, Media Library, and (for users with an access level of developer or higher) the Project Settings that can be completely customised by the developer.

A screenshot of the empty sidebar configuration UI. An input field allows adding a new entry with a label. The project sidebar on the right side is not configured yet and only shows the default options Dashboard, Media Library and Settings, as well as a button to get back to all projects at the bottom of the frameA screenshot of the empty sidebar configuration UI. An input field allows adding a new entry with a label. The project sidebar on the right side is not configured yet and only shows the default options Dashboard, Media Library and Settings, as well as a button to get back to all projects at the bottom of the frame

This middle section allows for four types of entries:

  • Collections, for linking to a Collection and editing content within it, e.g. “Blog Posts”, “Projects”, etc.

  • Content Items, for linking directly into a single content item, for example global metadata, or a specific page

  • Project Documentation, for rendering Markdown files such as READMEs and other types of documentation straight within the project

  • Headings, for separating different sections of other entries from each other

Collections, content items and project documentation entries can even have custom icons assigned to them to be even more easily distinguished from each other. Once set up, the sidebar will be the same for every member of the project and serve as a way to navigate within it.

Another screenshot of the sidebar configuration UI. Now the sidebar has been configured with four fields: Blog, Projects (both Collections), Documentation (a heading) and Readme (a documentation document)Another screenshot of the sidebar configuration UI. Now the sidebar has been configured with four fields: Blog, Projects (both Collections), Documentation (a heading) and Readme (a documentation document)

Markdown Content Item Support

Originally, I had intended for Mattrbld to initially only support JSON content files and add support for Markdown files with a YAML-frontmatter later on. While working on the sidebar configuration UI, however, I added the ability to render Markdown + Frontmatter for documentation files and from that it wasn’t a large step to support such files in other areas of the application as well.

That’s why Mattrbld will launch with support for Markdown content files alongside JSON content! 🎉 Markdown + Frontmatter is a very common way of storing content in many static site generators and while it’s not as flexible as JSON, it’s often enough for personal blogs, documentation, or small sites.

When creating a Collection of Markdown-documents, the fields of the assigned Schema will be used to generate the YAML-frontmatter, while everything put into a top-level field with the key content will be rendered as the Markdown portion of the file. Aside from that, these files work just the same as JSON content items.

Collection Details and Content Creation

Since I was able to implement all other features planned for the past two weeks without any major delays and I also had some time left over, I tackled one last aspect relating to content Collections: a way for them to actually be displayed in the UI.

When opening a collection from the sidebar, users will be presented with the contents of said collection, i.e. any content items and folders within it. From here they will be able to create, move, open, publish / unpublish, and delete content items and folders (assuming their role has the appropriate permissions to do so).

A screenshot of detail view of the Projects Collection, showing four entries, the top of which is marked as a draft and labelled “a new project (41 seconds ago)”. A context menu is open and showing the following options: edit, rename, move, toggle draft, and deleteA screenshot of detail view of the Projects Collection, showing four entries, the top of which is marked as a draft and labelled “a new project (41 seconds ago)”. A context menu is open and showing the following options: edit, rename, move, toggle draft, and delete

One challenge here was to display draft content in line with published content, since draft content lives in a separate directory in Mattrbld. I could’ve created separate views for each, but I don’t think it would be very beneficial to content editors and other users to only see one or the other in isolation, since that could lead to duplicate work and lost drafts. So instead, drafts are shown right alongside published content, but obviously labelled as drafts so it becomes clear at a glance what’s already out there and what is not.

What I’m struggling with is the notion of “published content” itself, since just because something isn’t flagged as a draft, it doesn’t mean it’s truly published until the local changes are synced with the remote repository. Perhaps distinguishing between “draft” and “public” content instead is a better way for the future.

Code Quality Concerns

I am very pleased that things are really starting to come together and every day Mattrbld steps closer to being a fully usable CMS. However, what I’ve also noticed in the past two weeks is that my code (and to a certain extent design) quality took a heavy hit from the very limited time I have to implement features and get everything running.

While I’m trying my best to keep the code simple, DRY and pure, there are many areas that would need some major refactoring—I just don’t have the time for it right now. I’m taking small steps here and there, for example I got rid of the notion of a “default role”, since users potentially have a different role in every project they join and it just didn’t make sense to have a default role other than “Project Owner” (when importing a project that is not a Mattrbld project) or “Content Editor” when joining a Mattrbld project (without being invited through an invite-link). Anything major will have to wait until I’ve gotten a first Prototype out, just so I can make my deadlines.

What I’m trying to say is that I’m aware of the areas where the code could be better and I’m fully prepared to refactor them once the base system is up and running and I can transition from adding functionality and features to polishing and improving.

Up Next

With that being said, I’m excited to start tackling the last two areas that are needed for me to publish future devlogs entirely from within Mattrbld:

  • The Media Library, where all images live

  • The Content Editor, where content items can be edited

While the former definitely isn’t trivial, the latter will take a long time to get right and feature complete. Nonetheless, I’m hoping to have at least a working minimum viable prototype in two weeks so I can stop copy-pasting and start properly creating these devlogs right within Mattrbld by the time the next one (or the one after) is due!

I hope you’re just as excited as me to find out in two weeks time. Until then, as usual thank you very much for reading and keeping up with my project. If you have any questions or comments, feel free to reach out over on Twitter and enjoy spring!