Coder Social home page Coder Social logo

alineacms / alinea Goto Github PK

View Code? Open in Web Editor NEW
736.0 7.0 36.0 51.41 MB

Content management, streamlined

Home Page: https://alinea.sh

License: MIT License

TypeScript 91.28% JavaScript 1.38% SCSS 7.19% CSS 0.14%
cms content-management-system headless typescript content git bun nodejs nextjs

alinea's Introduction

npm install size

Alinea CMS logo

Alinea is a modern content management system.

  • Content is stored in flat files and committed to your repository
  • Content is easily queryable through an in-memory SQLite database
  • Content is fully typed

Get started

Install alinea in your project directory

npm install alinea

Initialize alinea's config file

npx alinea init --next

Open the dashboard to have a look around

npx alinea dev

Start configuring types and fields →

Configure

Configure alinea in cms.tsx

import {Config, Field} from 'alinea'

const Blog = Config.document('Blog', {
  contains: ['BlogPost']
})
const BlogPost = Config.document('Blog post', {
  fields: {
    title: Field.text('Blog entry title'),
    body: Field.richText('Body text')
  }
})

Type options and fields →

Query

Retrieve content fully-typed and filter, order, limit as needed.
Select only the fields you need.

import {Query} from 'alinea'

const blogAndPosts = Query(Blog).select({
  title: Blog.title,
  posts: Query.children(BlogPost).select({
    title: BlogPost.title
  })
})

console.log(await cms.get(blogAndPosts))

See the full api →

Content is available during static site generation and when server side querying.
Content is bundled with your code and can be queried with zero network overhead.

How alinea bundles content →

Deploy anywhere

Alinea supports custom backends that can be hosted as a simple Node.js process or on serverless runtimes.

Setup your backend →

How to contribute to this project

Have a question or an idea? Found a bug? Read how to contribute.

alinea's People

Contributors

alinea-cloud[bot] avatar ancaemcken avatar benmerckx avatar cloetensbrecht avatar dependabot[bot] avatar dimitricodeurs avatar dmerckx avatar imrodriguez avatar maxobat avatar stijnvandoorslaer avatar valeriecodeurs avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar

alinea's Issues

Track publish status

Figure out a way to track whether a publish is online (and successful).
Ideas:

  • fetch a live route which returns current version or include it in headers
  • wrap the build task in a cli command that reports the progress back to the ui

Rich text toolbar

Needs styling and all available options. Options should be configurable.

image

User settings

Modal/popover with:

  • Dark/light preference
  • Theme color override?
  • Default workspace?
  • Font size +-
  • Interface language

CLI: serve

Serve a local admin panel based on the config file

Check dependencies in compile step

For each package check if external imports are included in (peer)dependencies, warn if not. Maybe also warn about unused dependencies.

Create new entries in link/reference picker

Above file upload we can have a summary of accepted types and a direct link to create one in either a new tab (phase 1) or new modal with input field (phase 2). Link field will have to supply accepted types and a parent under which they can be created (or: parent is chosen in creating dialog which will keep the interface cleaner).

Code generation

Generate a la prisma/client so on postinstall, manually with alinea generate and while watching file system with alinea generate --watch

Step 1: find schema

  • Look at configurable path (eg. package.json key {"alinea": {"schema": "./my-schema.ts"}})
  • Look at pre defined default path (eg. ./schema.ts & ./src/schema.ts)

Step 2: create/update folder

  • Look at configurable path (eg. package.json key {"alinea": {"package": "./my-dir"}})
  • Use pre defined default path (eg ./.alinea)

Step 3: generate

  • Build schema.js
  • Build schema.d.ts:
    export * from '../src/schema'
    export type Page = EntryOf<typeof schema>
    export every collection & type
    export const Home: Collection<Extract<Page, {type: 'Home'}>>
    export type Home = DataOf<typeof Home>
  • Build pages
  • Create server & client entry points
  • Write package.json browser & node exports

Step 4: index

  • Index into cache file

Validate naming

Since we're generating code we need to watch for name clashes, off the top of my head:

  • reserved properties in entry types (id, type, workspace, root, etc)
  • reserved properties in list rows (id, type, index)
  • type names, currently exported as value/type
    • check valid identifier
    • clashes with other exports
    • clashes with core types (Entry, File, MediaLibrary)
  • workspaces, name clashes with anything in .alinea/* (cache/client/config/index)
  • block type names in rich text
  • extra fields in link input (id, index, type, entry...)
  • pages: "tree" property

Smaller sqlite wasm distribution

The sql.js-fts5 wasm file is about 435kb gzipped. Stripping unnecessary features we should be able to get it close to 220kb.
Starting with https://github.com/kbumsik/sqlite-wasm as a template and the config below. That package is focused on the browser however so we'll need to enable nodejs loading of the library in emscripten.

EMCC_SQLITE_FLAGS = \
	-DSQLITE_ENABLE_FTS5 \
	-DSQLITE_ENABLE_JSON1 \
	-DSQLITE_OMIT_LOAD_EXTENSION \
	-DSQLITE_DISABLE_LFS \
	-DLONGDOUBLE_TYPE=double \
	-DSQLITE_THREADSAFE=0 \
	-DSQLITE_DQS=0\
	-DSQLITE_DEFAULT_MEMSTATUS=0 \
	-DSQLITE_OMIT_DEPRECATED \
	-DSQLITE_MAX_EXPR_DEPTH=0 \
	-DSQLITE_OMIT_SHARED_CACHE \
	-DSQLITE_OMIT_PROGRESS_CALLBACK \
        -DSQLITE_LIKE_DOESNT_MATCH_BLOBS\
 	-DSQLITE_DEFAULT_FOREIGN_KEYS=1 \
	-DSQLITE_TEMP_STORE=2\
	-DSQLITE_OMIT_DECLTYPE \
 	-DSQLITE_OS_OTHER=1 \
	-DHAVE_LOCALTIME_R \
 	-DNDEBUG=1 \
	$(SQLITE_OWN_OPTIMIZATIONS)

SQLITE_OWN_OPTIMIZATIONS = \
	-DSQLITE_OMIT_ANALYZE \
	-DSQLITE_OMIT_ATTACH \
	-DSQLITE_OMIT_AUTHORIZATION \
	-DSQLITE_OMIT_AUTOINCREMENT \
	-DSQLITE_OMIT_AUTOMATIC_INDEX \
	-DSQLITE_OMIT_AUTOVACUUM \
	-DSQLITE_OMIT_BLOB_LITERAL \
	-DSQLITE_OMIT_CASE_SENSITIVE_LIKE_PRAGMA \
	-DSQLITE_OMIT_CHECK \
	-DSQLITE_OMIT_COMPILEOPTION_DIAGS \
	-DSQLITE_OMIT_COMPLETE \
	-DSQLITE_OMIT_COMPOUND_SELECT \
 	-DSQLITE_OMIT_DESERIALIZE \
	-DSQLITE_OMIT_DECLTYPE \
	-DSQLITE_OMIT_EXPLAIN \
	-DSQLITE_OMIT_FLAG_PRAGMAS \
	-DSQLITE_OMIT_FOREIGN_KEY \
	-DSQLITE_OMIT_GET_TABLE \
	-DSQLITE_OMIT_INTEGRITY_CHECK \
	-DSQLITE_OMIT_INTROSPECTION_PRAGMAS \
	-DSQLITE_OMIT_LOCALTIME \
	-DSQLITE_OMIT_LOOKASIDE \
	-DSQLITE_OMIT_MEMORYDB \
	-DSQLITE_OMIT_PAGER_PRAGMAS \
	-DSQLITE_OMIT_QUICKBALANCE \
	-DSQLITE_OMIT_REINDEX \
	-DSQLITE_OMIT_AUTORESET \
	-DSQLITE_OMIT_SCHEMA_PRAGMAS \
	-DSQLITE_OMIT_SCHEMA_VERSION_PRAGMAS \
	-DSQLITE_OMIT_TCL_VARIABLE \
	-DSQLITE_OMIT_TEMPDB \
	-DSQLITE_OMIT_TRACE \
	-DSQLITE_OMIT_TRUNCATE_OPTIMIZATION \
	-DSQLITE_OMIT_UTF16 \
	-DSQLITE_OMIT_VACUUM \
	-DSQLITE_OMIT_VIEW \
	-DSQLITE_OMIT_WAL \
	-DSQLITE_OMIT_XFER_OPT \
	-DSQLITE_UNTESTABLE

React version 18

Warn on init that we need version 18. Or fix compatibility with react 17 (eliminate useId usage).

Implement combobox properly

Tried:

  • ariakit -> composite focus moves incorrectly when items are virtualized
  • headlessui -> cannot focus first item, cannot clear input after navigating

Considered:

  • downshift -> needs items up front, but we load lazily

To try:
?

Content formats

It would be nice to have a yaml loader which can format rich text as markdown, embedding inner blocks as html:

id: ...
title: My entry
body: |
  # Heading
  
  Some text
  <CodeBlock code="..." />
  More text

CLI: init

  • create an alinea.config.tsx config file with some defaults (web workspace + homepage etc?)
  • create a server.ts which loads all config from .env

maybe:

  • package this command as "create-alinea-cms" or something so we can npx create-alinea-cms?
  • add dependencies to npm/yarn/...

Rich text content types

Should probably map to an html tag? I'm not sure where the tiptap/prosemirror types stem from.

Modal

  • Style consistently, but supply a few sizes (maybe just small en large)
  • Accessibility (find lightweight package to support this)

Refactor config

See

// The plan here is: if we can pass a custom Data.Source, we can easily
// generate a story and type for each *.story.tsx for example. However
// we want this configuration to only be available server side which
// complicates this a lot. We can either
// - be declarative instead of importing implementation
// (source: {dir: ...}, source: {entryPoint: 'generatestories.ts'})
// - make sure the Source we use is removed for clients with export maps
// - create a separate file to configurate sources
// - move source config to alinea.server.ts
// - tweak AST to remove source while compiling config.js
// So far none of these sound appealing... In a perfect world we'd be able
// to use the same principle for fetching data from other external sources.

CLI: generate --watch

Watch for content source / config source changes, we can probably use esbuilds watcher by adding all of our sources to watchFiles in a plugin

Index fields

Allow field data to be indexed

type({
  fieldA,
  fieldB
}).configure({
  index(fields) {
    return {
      myIndex: [fields.fieldA, fields.fieldB]
    }
  }
})

Shadow DOM preview

Investigate if we can easily render a complete preview inside a shadow root

Check for react(-dom)

Running cli includes @alinea/core which depends on react. In non react projects we'll need to either instruct to add react and react-dom or side step the problem

Avoid better-sqlite3 in non node-environments

Using the cli currently assumes a node environment, but in an environment like stackblitz.com we have all the node apis but no native node libs. Ideally we can detect and use sql.js instead.

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.