snow-cms
v1.1.5
Published
A configurable CMS built with Svelte.
Downloads
16
Readme
Snow CMS
A configurable CMS built with Svelte and inspired by Decap CMS and Sveltia CMS.
I created this project because I wanted a CMS with a rich-text markdown widget, more intuitive custom preview configuration, and a configurable backend.
Features
- Editor Widgets
- Boolean
- Number
- DateTime
- Text
- Markdown
- Hidden
- Editor Preview layout templates (Using html templates with replacement tags)
- Editor Preview styles
- CMS Backends
- Local filesystem backend (Changes can be manually committed via your external Git CLI/GUI.)
- GitHub backend
- Specify your own custom backend
- Optional hooks into editor actions
- Output Markdown files with YAML front matter
[!NOTE] When using the local backend, certain filesystem interactions may perform slowly on Firefox.
For maximum compatibility, use a Chrome-based browser.
Getting Started
Installing
npm i snow-cms
Import the CMS into your project
- Create a path in your project where you want the CMS to be accessed.
ex.[my-site]/cms
- Create a javascript module and import the CMS css and js.
- Create an html file that loads the module and contains a root element with an id of
app
.
- Create a path named
cms-config
in your project at the same level as the previously createdcms
path.
ex.[my-site]/cms-config
- Add a
config.yml
and any relevant css, html template, and js files.
- Add a
Structure
An example of a basic project with the expected structure would look something like this:
index.html
cms/ // The path to access the CMS. (Path name can be anything)
|-- index.html // Page that loads 'cms.js'
|-- snow.js // JS module that imports the CMS. (File name can be anything)
cms-config/ // The path containing CMS config files. (Must be named 'cms-config')
|-- config.yml // CMS config file
|-- preview-template.html // Layout template to apply to page previews in the editor
|-- preview-styles.css // Styles to apply to page previews in the editor
|-- cms-actions.js // Additional behavior to hook into editor actions. (Optional)
[!NOTE] This example assumes the use of a build system that allows importing css in js. But you should adapt importing of the css and js to your project's build system.
cms/index.html
<!doctype html>
<html>
<head>
<meta charset="UTF-8" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<!-- The module that loads the CMS -->
<script type="module" src="snow.js"></script>
</head>
<body>
<!-- The root element used to load the CMS -->
<slot id="app"></slot>
</body>
</html>
cms/snow.js
// Import the CMS css and js
import 'snow-cms/dist/index.css';
import 'snow-cms/dist/index';
cms-config/
See Config for information on configuration as well as dev-site/cms-config for example config files.
Development
Install pnpm
npm install -g pnpm
Install necessary packages
pnpm install
Run the dev server
pnpm run dev
Then navigate to http://localhost:5173/
in your browser to view the dev site.
Build output files
pnpm run build
Built files will be output to the dist/
directory.
Structure
cms/
Contains the source files to build the CMS.
dev-site/
Contains files for running the development server.
Development server site's photos by Pixabay and Simon Berger from Pexels.
Config
See dev-site/cms-config for example config files.
[!NOTE] The GitHub backend requires a GitHub App to authenticate through and a server-side handler to exchange the access token.
The GitHub app should be configured with
Callback URL
andSetup URL
set to the url of the CMS.The server-side handler should exchange the received auth code for a user access token. Using one of the Oauth App middlewares makes this easy to set up.
Widgets
Widgets share the following configuration options:
label
: The input label displayed in the editor interface.name
: The name of the input.default
: The input's default value.required
: Whether the input is required. (Defaults totrue
.)
[!IMPORTANT] Each collection must have widgets configured for the names
title
,date
,draft
, andbody
.
Boolean
widget
:'boolean'
{
label: 'Draft',
name: 'draft',
widget: 'boolean',
required: false
}
[!NOTE] If the Boolean Widget's
required
option is set totrue
or isn't specified, the input's value must betrue
for editor data to submit.
Number
widget
:'number'
step
: The amount the value increments / decrements by. (Defaults to1
.)min
: The minimum value allowed.max
: The maximum value allowed.
{
label: 'Cookies',
name: 'cookies',
widget: 'number',
step: 5
}
DateTime
widget
:'datetime'
type
:'datetime-local|date|time'
Which input to display.datetime_format
: How the datetime should be displayed.date_format
: How the date should be displayed.time_format
: How the time should be displayed.
{
label: 'Publish Date',
name: 'date',
widget: 'datetime',
type: 'datetime-local',
datetime_format: 'MM.DD.YYYY HH:mm'
}
[!NOTE] The corresponding
format
option should be set depending on thetype
.
Text
widget
:'string|text'
Which input to display. Usestring
for single-line ortext
for multiline.
{
label: 'Title',
name: 'title',
widget: 'string'
}
Markdown
widget
:'markdown'
{
label: 'Body',
name: 'body',
widget: 'markdown'
}
Hidden
widget
:'hidden'
type
:'boolean|number|text|datetime-local|date|time'
The type of the input's value.default
: The value of the hidden input.
{
name: 'hiddenValue',
widget: 'hidden',
type: 'text',
default: 'secret box'
}