Skip to content

Latest commit

 

History

History
144 lines (108 loc) · 6.08 KB

vision.md

File metadata and controls

144 lines (108 loc) · 6.08 KB
title
Vision

If I would need to describe what this is about in one sentence, I would say - database for your content. But this doesn't really help to grasp the whole concept. Let's take a closer look.

Content layer

Content layer exists in all static site generators (one way or another). Basically:

  • there is folder with content (markdown, json, yaml, images etc)
  • there is function to get list of all entries. Also it can sort, filter and paginate
  • there is function to get one entry. It can parse content (frontmatter, markdown) and render (to html, for example)
  • often there is caching layer and reactive interface

Let's see examples.

Hugo

Astro: Content Collections

But compared to Hugo we can as well specify schema for the content:

// 1. Import utilities from `astro:content`
import { z, defineCollection } from "astro:content";

// 2. Define a `type` and `schema` for each collection
const blogCollection = defineCollection({
  type: "content", // v2.5.0 and later
  schema: z.object({
    title: z.string(),
    tags: z.array(z.string()),
    image: z.string().optional(),
  }),
});

// 3. Export a single `collections` object to register your collection(s)
export const collections = {
  // Equivalent to `src/content/**/*.{md,mdx}`
  blog: blogCollection,
};

Contentlayer

  • folder with content: defined in defineDocumentType
  • list of all entries: allItems
    • to filter: allItems.filter(x => {...}) (standard JS)
    • to sort: allItems.sort((a, b) => {...}) (standard JS)
  • one entry: allItems.find (standard JS, I guess)

And we can define schema:

import { defineDocumentType, makeSource } from "contentlayer/source-files";

export const Post = defineDocumentType(() => ({
  name: "Post",
  filePathPattern: `**/*.md`,
  fields: {
    title: { type: "string", required: true },
    date: { type: "date", required: true },
  },
  computedFields: {
    url: {
      type: "string",
      resolve: (post) => `/posts/${post._raw.flattenedPath}`,
    },
  },
}));

Other

Content graph

Articles (markdown files) plus hyperlinks ([some](/thing)) form graph. Some solutions allows to treat content as graph:

Obsidian

Quartz

Other

Query interface

Content layer already exposes some basic query interface. But there are solutions which brings this idea further, they expose query interface as query language.

Most notable solutions in this area are: docsql, obsidian-dataview. They allow to use SQL-like language to query the content.

Other options would be to use some kind of faceted search interface. Or use graph-query language, like Cypher or Datalog.

Core

Main disadvantage of all solutions mentioned above (maybe exept Contentlayer) is that they are built-in into another applications and not reusable. I think it would be beneficial to implement core library which, later could be reused for:

  • content layer for Astro (or Next.js, Nuxt etc.)
  • Language Server (LSP)
  • CLI to transform markdown files, for example, from Obsidian vault to Hugo format
  • second-brain-note-taking app, like Obsidian or Foam