Feature/website overhaul (#49)
* Reorganize repo * Overhaul website design and rewrite in NextJS and Typescript * Delete website-publish.yml
@ -1,14 +0,0 @@
|
||||
{
|
||||
"presets": ["babel-preset-gatsby"],
|
||||
"plugins": [
|
||||
[
|
||||
"prismjs",
|
||||
{
|
||||
"languages": ["javascript", "css", "markup", "yaml", "json"],
|
||||
"plugins": ["line-numbers"],
|
||||
"theme": "tomorrow",
|
||||
"css": true
|
||||
}
|
||||
]
|
||||
]
|
||||
}
|
19
website/.editorconfig
Normal file
@ -0,0 +1,19 @@
|
||||
# https://editorconfig.org
|
||||
root = true
|
||||
|
||||
[*]
|
||||
indent_style = space
|
||||
indent_size = 2
|
||||
charset = utf-8
|
||||
trim_trailing_whitespace = true
|
||||
insert_final_newline = true
|
||||
|
||||
[*.js]
|
||||
quote_type = single
|
||||
spaces_around_operators = true
|
||||
|
||||
[*.css]
|
||||
quote_type = single
|
||||
|
||||
[*.md]
|
||||
trim_trailing_whitespace = false
|
5
website/.eslintignore
Normal file
@ -0,0 +1,5 @@
|
||||
node_modules
|
||||
dist
|
||||
dev-test
|
||||
prism.js
|
||||
next.config.js
|
131
website/.eslintrc.js
Normal file
@ -0,0 +1,131 @@
|
||||
module.exports = {
|
||||
parser: '@typescript-eslint/parser',
|
||||
extends: [
|
||||
'eslint:recommended',
|
||||
'plugin:react/recommended',
|
||||
'prettier',
|
||||
'plugin:import/recommended',
|
||||
'plugin:@typescript-eslint/recommended',
|
||||
],
|
||||
env: {
|
||||
es6: true,
|
||||
browser: true,
|
||||
node: true,
|
||||
jest: true,
|
||||
},
|
||||
globals: {
|
||||
STATIC_CMS_CORE_VERSION: false,
|
||||
CMS_ENV: false,
|
||||
},
|
||||
rules: {
|
||||
'no-restricted-imports': 'off',
|
||||
'@typescript-eslint/no-restricted-imports': [
|
||||
'error',
|
||||
{
|
||||
patterns: [
|
||||
{
|
||||
group: ['@mui/*/*/*', '!@mui/material/test-utils/*'],
|
||||
message: 'Do not import material imports as 3rd level imports',
|
||||
allowTypeImports: true,
|
||||
},
|
||||
{
|
||||
group: ['@mui/material', '!@mui/material/'],
|
||||
message: 'Please import material imports as defaults or 2nd level imports',
|
||||
allowTypeImports: true,
|
||||
},
|
||||
],
|
||||
},
|
||||
],
|
||||
'react-hooks/rules-of-hooks': 'error', // Checks rules of Hooks
|
||||
'react-hooks/exhaustive-deps': 'warn', // Checks effect dependencies
|
||||
'no-console': [0],
|
||||
'react/prop-types': [0],
|
||||
'react/require-default-props': 0,
|
||||
'import/no-named-as-default': 0,
|
||||
'react/react-in-jsx-scope': 'off',
|
||||
'import/order': [
|
||||
'error',
|
||||
{
|
||||
'newlines-between': 'always',
|
||||
groups: [['builtin', 'external'], ['internal', 'parent', 'sibling', 'index'], ['type']],
|
||||
},
|
||||
],
|
||||
'no-duplicate-imports': 'error',
|
||||
'@emotion/no-vanilla': 'off',
|
||||
'@emotion/import-from-emotion': 'error',
|
||||
'@emotion/styled-import': 'error',
|
||||
'require-atomic-updates': [0],
|
||||
'object-shorthand': ['error', 'always'],
|
||||
'prefer-const': [
|
||||
'error',
|
||||
{
|
||||
destructuring: 'all',
|
||||
},
|
||||
],
|
||||
'unicorn/prefer-string-slice': 'error',
|
||||
'react/no-unknown-property': ['error', { ignore: ['css'] }],
|
||||
'@typescript-eslint/no-unused-vars': [
|
||||
'warn',
|
||||
{
|
||||
argsIgnorePattern: '^_',
|
||||
varsIgnorePattern: '^_',
|
||||
caughtErrorsIgnorePattern: '^_',
|
||||
},
|
||||
],
|
||||
},
|
||||
plugins: ['babel', '@emotion', 'unicorn', 'react-hooks', '@typescript-eslint'],
|
||||
settings: {
|
||||
react: {
|
||||
version: 'detect',
|
||||
},
|
||||
'import/resolver': {
|
||||
node: {
|
||||
extensions: ['.js', '.jsx', '.ts', '.tsx'],
|
||||
},
|
||||
},
|
||||
'import/core-modules': ['src'],
|
||||
},
|
||||
overrides: [
|
||||
{
|
||||
files: ['*.ts', '*.tsx'],
|
||||
parser: '@typescript-eslint/parser',
|
||||
extends: [
|
||||
'eslint:recommended',
|
||||
'plugin:react/recommended',
|
||||
'plugin:@typescript-eslint/recommended',
|
||||
'prettier',
|
||||
'plugin:import/recommended',
|
||||
'plugin:import/typescript',
|
||||
],
|
||||
parserOptions: {
|
||||
ecmaVersion: 2018,
|
||||
sourceType: 'module',
|
||||
ecmaFeatures: {
|
||||
jsx: true,
|
||||
},
|
||||
},
|
||||
rules: {
|
||||
'react/react-in-jsx-scope': 'off',
|
||||
'react/prop-types': [0],
|
||||
'react/require-default-props': 0,
|
||||
'no-duplicate-imports': [0], // handled by @typescript-eslint
|
||||
'@typescript-eslint/ban-types': [0], // TODO enable in future
|
||||
'@typescript-eslint/no-non-null-assertion': [0],
|
||||
'@typescript-eslint/consistent-type-imports': 'error',
|
||||
'@typescript-eslint/explicit-function-return-type': [0],
|
||||
'@typescript-eslint/explicit-module-boundary-types': [0],
|
||||
'@typescript-eslint/no-duplicate-imports': 'error',
|
||||
'@typescript-eslint/no-use-before-define': [
|
||||
'error',
|
||||
{ functions: false, classes: true, variables: true },
|
||||
],
|
||||
},
|
||||
},
|
||||
{
|
||||
files: ['website/**/*'],
|
||||
rules: {
|
||||
'import/no-unresolved': [0],
|
||||
},
|
||||
},
|
||||
],
|
||||
};
|
3
website/.eslintrc.json
Normal file
@ -0,0 +1,3 @@
|
||||
{
|
||||
"extends": "next/core-web-vitals"
|
||||
}
|
39
website/.gitignore
vendored
@ -1,3 +1,36 @@
|
||||
.cache
|
||||
public
|
||||
dist
|
||||
# See https://help.github.com/articles/ignoring-files/ for more about ignoring files.
|
||||
|
||||
# dependencies
|
||||
/node_modules
|
||||
/.pnp
|
||||
.pnp.js
|
||||
|
||||
# testing
|
||||
/coverage
|
||||
|
||||
# next.js
|
||||
/.next/
|
||||
/out/
|
||||
|
||||
# production
|
||||
/build
|
||||
|
||||
# misc
|
||||
.DS_Store
|
||||
*.pem
|
||||
|
||||
# debug
|
||||
npm-debug.log*
|
||||
yarn-debug.log*
|
||||
yarn-error.log*
|
||||
.pnpm-debug.log*
|
||||
|
||||
# local env files
|
||||
.env*.local
|
||||
|
||||
# vercel
|
||||
.vercel
|
||||
|
||||
# typescript
|
||||
*.tsbuildinfo
|
||||
next-env.d.ts
|
||||
|
@ -1,4 +0,0 @@
|
||||
{
|
||||
"default": false,
|
||||
"MD032": true
|
||||
}
|
@ -1 +0,0 @@
|
||||
--lts
|
4
website/.prettierignore
Normal file
@ -0,0 +1,4 @@
|
||||
dist/
|
||||
bin/
|
||||
public/
|
||||
.cache/
|
6
website/.prettierrc
Normal file
@ -0,0 +1,6 @@
|
||||
{
|
||||
"arrowParens": "avoid",
|
||||
"trailingComma": "all",
|
||||
"singleQuote": true,
|
||||
"printWidth": 100
|
||||
}
|
@ -1,19 +0,0 @@
|
||||
# Static CMS Website & Docs
|
||||
|
||||
This directory builds staticjscms.github.io/static-cms. If you'd like to propose changes to the site or docs, you'll find the source files in here.
|
||||
|
||||
## Local development
|
||||
|
||||
The site is built with [GatsbyJS](https://gatsbyjs.org/).
|
||||
|
||||
To run the site locally, you'll need to have [Node](https://nodejs.org) and [Yarn](https://yarnpkg.com/en/) installed on your computer.
|
||||
|
||||
From your terminal window, `cd` into the `website` directory of the repo, and run
|
||||
|
||||
```bash
|
||||
yarn
|
||||
yarn start
|
||||
```
|
||||
|
||||
Then visit http://localhost:8000/ - Gatsby will automatically reload CSS or
|
||||
refresh the page when stylesheets or content changes.
|
@ -1,10 +0,0 @@
|
||||
---
|
||||
title: >-
|
||||
Welcome to Static CMS
|
||||
author: Daniel Lautzenheiser
|
||||
description: >-
|
||||
Announcing the release of Static CMS v1.0.
|
||||
twitter_image: /img/static-cms.png
|
||||
date: 2022-11-30T12:00:00.000Z
|
||||
---
|
||||
Today we’re releasing Static CMS 1.0!
|
36
website/content/community.json
Normal file
@ -0,0 +1,36 @@
|
||||
{
|
||||
"title": "Help us build the CMS of the future",
|
||||
"subtitle": "Get support, give support and find out what's new through the channels below.",
|
||||
"sections": [
|
||||
{
|
||||
"title": "Support",
|
||||
"links": [
|
||||
{
|
||||
"title": "Static CMS Slack",
|
||||
"description": "Live community chat for all things Static CMS",
|
||||
"url": "https://join.slack.com/t/static-cms/shared_invite/zt-1gvgnf5yv-E4sR17YnEcOy6fLFH9m7bQ"
|
||||
},
|
||||
{
|
||||
"title": "Static CMS Community",
|
||||
"description": "Ask and answer questions on GitHub discussions tab",
|
||||
"url": "https://github.com/StaticJsCMS/static-cms/discussions"
|
||||
},
|
||||
{
|
||||
"title": "GitHub Issues",
|
||||
"description": "Report bugs, request features and comment on existing issues",
|
||||
"url": "https://github.com/StaticJsCMS/static-cms/issues"
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"title": "Development",
|
||||
"links": [
|
||||
{
|
||||
"title": "GitHub Project",
|
||||
"description": "Issues board on the Static CMS GitHub organization",
|
||||
"url": "https://github.com/orgs/StaticJsCMS/projects/1"
|
||||
}
|
||||
]
|
||||
}
|
||||
]
|
||||
}
|
30
website/content/config.json
Normal file
@ -0,0 +1,30 @@
|
||||
{
|
||||
"base_url": "https://static-cms.netlify.app/",
|
||||
"repo_url": "https://github.com/StaticJsCMS/static-cms",
|
||||
"site_title": "Static CMS | Open Source Content Management System",
|
||||
"site_description": "Open source content management for your Git workflow. Use Static CMS with any static site generator for a faster and more flexible web project.",
|
||||
"site_image": "/static-cms-logo.svg",
|
||||
"site_keywords": ["static", "cms", "staticcms", "netlify"],
|
||||
"footer": {
|
||||
"buttons": [
|
||||
{
|
||||
"text": "Twitter",
|
||||
"url": "https://twitter.com/StaticJsCMS"
|
||||
},
|
||||
{
|
||||
"text": "GitHub",
|
||||
"url": "https://github.com/StaticJsCMS/static-cms"
|
||||
}
|
||||
],
|
||||
"links": [
|
||||
{
|
||||
"text": "Distributed under MIT License",
|
||||
"url": "https://github.com/StaticJsCMS/static-cms/blob/main/LICENSE"
|
||||
},
|
||||
{
|
||||
"text": "Code of Conduct",
|
||||
"url": "https://github.com/StaticJsCMS/static-cms/blob/main/CODE_OF_CONDUCT.md"
|
||||
}
|
||||
]
|
||||
}
|
||||
}
|
195
website/content/docs/add-to-your-site-bundling.mdx
Normal file
@ -0,0 +1,195 @@
|
||||
---
|
||||
group: Intro
|
||||
title: Bundling
|
||||
weight: 5
|
||||
---
|
||||
|
||||
This tutorial guides you through the steps for adding Static CMS via a package manager to a site that's built with a common [static site generator](https://www.staticgen.com/), like Jekyll, Nest, Hugo, Hexo, or Gatsby. Alternatively, you can [start from a template](/docs/start-with-a-template) or dive right into [configuration options](/docs/configuration-options).
|
||||
|
||||
## Installation
|
||||
|
||||
You can also use Static CMS as an npm module. Wherever you import Static CMS, it automatically runs, taking over the current page. Make sure the script that imports it only runs on your CMS page. First install the package and save it to your project:
|
||||
|
||||
```bash
|
||||
// npm
|
||||
npm install @staticcms/core
|
||||
|
||||
// yarn
|
||||
yarn add @staticcms/core
|
||||
```
|
||||
|
||||
Then import it (assuming your project has tooling for imports):
|
||||
|
||||
```js
|
||||
import CMS from '@staticcms/core';
|
||||
// Initialize the CMS object
|
||||
CMS.init();
|
||||
// Now the registry is available via the CMS object.
|
||||
CMS.registerPreviewTemplate('my-template', MyTemplate);
|
||||
```
|
||||
|
||||
## Configuration
|
||||
|
||||
Configuration is different for every site, so we'll break it down into parts. Add all the code snippets in this section to your `admin/config.yml` file.
|
||||
|
||||
### Backend
|
||||
|
||||
We're using [Netlify](https://www.netlify.com) for our hosting and authentication in this tutorial, so backend configuration is fairly straightforward.
|
||||
|
||||
For GitHub and GitLab repositories, you can start your Static CMS `config.yml` file with these lines:
|
||||
|
||||
```yaml
|
||||
backend:
|
||||
title: git-gateway
|
||||
branch: master # Branch to update (optional; defaults to master)
|
||||
```
|
||||
|
||||
_(For Bitbucket repositories, use the [Bitbucket backend](/docs/bitbucket-backend) instructions instead.)_
|
||||
|
||||
The configuration above specifies your backend protocol and your publication branch. Git Gateway is an open source API that acts as a proxy between authenticated users of your site and your site repo. (We'll get to the details of that in the [Authentication section](#authentication) below.) If you leave out the `branch` declaration, it defaults to `master`.
|
||||
|
||||
### Media and Public Folders
|
||||
|
||||
Static CMS allows users to upload images directly within the editor. For this to work, the CMS needs to know where to save them. If you already have an `images` folder in your project, you could use its path, possibly creating an `uploads` sub-folder, for example:
|
||||
|
||||
```yaml
|
||||
# This line should *not* be indented
|
||||
media_folder: 'images/uploads' # Media files will be stored in the repo under images/uploads
|
||||
```
|
||||
|
||||
If you're creating a new folder for uploaded media, you'll need to know where your static site generator expects static files. You can refer to the paths outlined above in [App File Structure](#app-file-structure), and put your media folder in the same location where you put the `admin` folder.
|
||||
|
||||
Note that the`media_folder` file path is relative to the project root, so the example above would work for Jekyll, GitBook, or any other generator that stores static files at the project root. However, it would not work for Hugo, Hexo, Middleman or others that store static files in a subfolder. Here's an example that could work for a Hugo site:
|
||||
|
||||
```yaml
|
||||
# These lines should *not* be indented
|
||||
media_folder: 'static/images/uploads' # Media files will be stored in the repo under static/images/uploads
|
||||
public_folder: '/images/uploads' # The src attribute for uploaded media will begin with /images/uploads
|
||||
```
|
||||
|
||||
The configuration above adds a new setting, `public_folder`. While `media_folder` specifies where uploaded files are saved in the repo, `public_folder` indicates where they are found in the published site. Image `src` attributes use this path, which is relative to the file where it's called. For this reason, we usually start the path at the site root, using the opening `/`.
|
||||
|
||||
_If `public_folder` is not set, Static CMS defaults to the same value as `media_folder`, adding an opening `/` if one is not included._
|
||||
|
||||
### Collections
|
||||
|
||||
Collections define the structure for the different content types on your static site. Since every site is different, the `collections` settings differ greatly from one site to the next.
|
||||
|
||||
Let's say your site has a blog, with the posts stored in `_posts/blog`, and files saved in a date-title format, like `1999-12-31-lets-party.md`. Each post begins with settings in yaml-formatted front matter, like so:
|
||||
|
||||
```yaml
|
||||
---
|
||||
layout: blog
|
||||
title: "Let's Party"
|
||||
date: 1999-12-31 11:59:59 -0800
|
||||
thumbnail: '/images/prince.jpg'
|
||||
rating: 5
|
||||
---
|
||||
This is the post body, where I write about our last chance to party before the Y2K bug destroys us all.
|
||||
```
|
||||
|
||||
Given this example, our `collections` settings would look like this in your Static CMS `config.yml` file:
|
||||
|
||||
```yaml
|
||||
collections:
|
||||
- title: 'blog' # Used in routes, e.g., /admin/collections/blog
|
||||
label: 'Blog' # Used in the UI
|
||||
folder: '_posts/blog' # The path to the folder where the documents are stored
|
||||
create: true # Allow users to create new documents in this collection
|
||||
slug: '{{year}}-{{month}}-{{day}}-{{slug}}' # Filename template, e.g., YYYY-MM-DD-title.md
|
||||
fields: # The fields for each document, usually in front matter
|
||||
- { label: 'Layout', title: 'layout', widget: 'hidden', default: 'blog' }
|
||||
- { label: 'Title', title: 'title', widget: 'string' }
|
||||
- { label: 'Publish Date', title: 'date', widget: 'datetime' }
|
||||
- { label: 'Featured Image', title: 'thumbnail', widget: 'image' }
|
||||
- { label: 'Rating (scale of 1-5)', title: 'rating', widget: 'number' }
|
||||
- { label: 'Body', title: 'body', widget: 'markdown' }
|
||||
```
|
||||
|
||||
Let's break that down:
|
||||
|
||||
|Field|Description|
|
||||
| ---- | --------------------- |
|
||||
|name|Post type identifier, used in routes. Must be unique.|
|
||||
|label|What the admin UI calls the post type.|
|
||||
|folder|Where files of this type are stored, relative to the repo root.|
|
||||
|create|Set to `true` to allow users to create new files in this collection.|
|
||||
|slug|Template for filenames. `{{ year }}`, `{{ month }}`, and `{{ day }}` pulls from the post's `date` field or save date. `{{ slug }}` is a url-safe version of the post's `title`. Default is simply `{{ slug }}`.|
|
||||
|fields|Fields listed here are shown as fields in the content editor, then saved as front matter at the beginning of the document (except for `body`, which follows the front matter).|
|
||||
|
||||
As described above, the `widget` property specifies a built-in or custom UI widget for a given field. When a content editor enters a value into a widget, that value is saved in the document front matter as the value for the `name` specified for that field. A full listing of available widgets can be found in the [Widgets doc](/docs/widgets).
|
||||
|
||||
Based on this example, you can go through the post types in your site and add the appropriate settings to your Static CMS `config.yml` file. Each post type should be listed as a separate node under the `collections` field. See the [Collections reference doc](/docs/configuration-options/#collections) for more configuration options.
|
||||
|
||||
### Filter
|
||||
|
||||
The entries for any collection can be filtered based on the value of a single field. The example collection below only shows post entries with the value `en` in the `language` field.
|
||||
|
||||
```yaml
|
||||
collections:
|
||||
- title: 'posts'
|
||||
label: 'Post'
|
||||
folder: '_posts'
|
||||
filter:
|
||||
field: language
|
||||
value: en
|
||||
fields:
|
||||
- { label: 'Language', title: 'language' }
|
||||
```
|
||||
|
||||
## Authentication
|
||||
|
||||
Now that you have your Static CMS files in place and configured, all that's left is to enable authentication. We're using the [Netlify](https://www.netlify.com/) platform here because it's one of the quickest ways to get started, but you can learn about other authentication options in the [Backends](/docs/backends-overview) doc.
|
||||
|
||||
### Setup on Netlify
|
||||
|
||||
Netlify offers a built-in authentication service called Identity. In order to use it, connect your site repo with Netlify.
|
||||
|
||||
### Enable Identity and Git Gateway
|
||||
|
||||
Netlify's Identity and Git Gateway services allow you to manage CMS admin users for your site without requiring them to have an account with your Git host or commit access on your repo. From your site dashboard on Netlify:
|
||||
|
||||
1. Go to **Settings > Identity**, and select **Enable Identity service**.
|
||||
2. Under **Registration preferences**, select **Open** or **Invite only**. In most cases, you want only invited users to access your CMS, but if you're just experimenting, you can leave it open for convenience.
|
||||
3. If you'd like to allow one-click login with services like Google and GitHub, check the boxes next to the services you'd like to use, under **External providers**.
|
||||
4. Scroll down to **Services > Git Gateway**, and click **Enable Git Gateway**. This authenticates with your Git host and generates an API access token. In this case, we're leaving the **Roles** field blank, which means any logged in user may access the CMS. For information on changing this, check the [Netlify Identity documentation](https://www.netlify.com/docs/identity/).
|
||||
|
||||
### Add the Netlify Identity Widget
|
||||
|
||||
With the backend set to handle authentication, now you need a frontend interface to connect to it. The open source Netlify Identity Widget is a drop-in widget made for just this purpose. To include the widget in your site, add the following script tag in two places:
|
||||
|
||||
```html
|
||||
<script src="https://identity.netlify.com/v1/netlify-identity-widget.js"></script>
|
||||
```
|
||||
|
||||
Add this to the `<head>` of your CMS index page at `/admin/index.html`, as well as the `<head>` of your site's main index page. Depending on how your site generator is set up, this may mean you need to add it to the default template, or to a "partial" or "include" template. If you can find where the site stylesheet is linked, that's probably the right place. Alternatively, you can include the script in your site using Netlify's [Script Injection](https://www.netlify.com/docs/inject-analytics-snippets/) feature.
|
||||
|
||||
When a user logs in with the Netlify Identity widget, an access token directs to the site homepage. In order to complete the login and get back to the CMS, redirect the user back to the `/admin/` path. To do this, add the following script before the closing `body` tag of your site's main index page:
|
||||
|
||||
```html
|
||||
<script>
|
||||
if (window.netlifyIdentity) {
|
||||
window.netlifyIdentity.on('init', user => {
|
||||
if (!user) {
|
||||
window.netlifyIdentity.on('login', () => {
|
||||
document.location.href = '/admin/';
|
||||
});
|
||||
}
|
||||
});
|
||||
}
|
||||
</script>
|
||||
```
|
||||
|
||||
Note: This example script requires modern JavaScript and does not work on IE11. For legacy browser support, use function expressions (`function () {}`) in place of the arrow functions (`() => {}`), or use a transpiler such as [Babel](https://babeljs.io/).
|
||||
|
||||
## Accessing the CMS
|
||||
|
||||
Your site CMS is now fully configured and ready for login!
|
||||
|
||||
If you set your registration preference to "Invite only," invite yourself (and anyone else you choose) as a site user. To do this, select the **Identity** tab from your site dashboard, and then select the **Invite users** button. Invited users receive an email invitation with a confirmation link. Clicking the link will take you to your site with a login prompt.
|
||||
|
||||
If you left your site registration open, or for return visits after confirming an email invitation, access your site's CMS at `yoursite.com/admin/`.
|
||||
|
||||
**Note:** No matter where you access Static CMS — whether running locally, in a staging environment, or in your published site — it always fetches and commits files in your hosted repository (for example, on GitHub), on the branch you configured in your Static CMS config.yml file. This means that content fetched in the admin UI matches the content in the repository, which may be different from your locally running site. It also means that content saved using the admin UI saves directly to the hosted repository, even if you're running the UI locally or in staging.
|
||||
|
||||
Happy posting!
|
@ -1,11 +1,10 @@
|
||||
---
|
||||
group: Intro
|
||||
weight: 3
|
||||
title: Add to Your Site
|
||||
title: CDN Hosting
|
||||
weight: 4
|
||||
---
|
||||
You can adapt Static CMS to a wide variety of projects. It works with any content written in markdown, JSON, YAML, or TOML files, stored in a repo on [GitHub](https://github.com/), [GitLab](https://about.gitlab.com/), or [Bitbucket](https://bitbucket.org). You can also create your own custom backend.
|
||||
|
||||
This tutorial guides you through the steps for adding Static CMS to a site that's built with a common [static site generator](https://www.staticgen.com/), like Jekyll, Hugo, Hexo, or Gatsby. Alternatively, you can [start from a template](../start-with-a-template) or dive right into [configuration options](../configuration-options).
|
||||
This tutorial guides you through the steps for adding Static CMS via a public CDN to a site that's built with a common [static site generator](https://www.staticgen.com/), like Jekyll, Nest, Hugo, Hexo, or Gatsby. Alternatively, you can [start from a template](/docs/start-with-a-template) or dive right into [configuration options](/docs/configuration-options).
|
||||
|
||||
## App File Structure
|
||||
|
||||
@ -36,48 +35,33 @@ admin
|
||||
└ config.yml
|
||||
```
|
||||
|
||||
The first file, `admin/index.html`, is the entry point for the Static CMS admin interface. This means that users navigate to `yoursite.com/admin/` to access it. On the code side, it's a basic HTML starter page that loads the Static CMS JavaScript file. The second file, `admin/config.yml`, is the heart of your Static CMS installation, and a bit more complex. The [Configuration](#configuration) section covers the details.
|
||||
The first file, `admin/index.html`, is the entry point for the Static CMS admin interface. This means that users navigate to `yoursite.com/admin/` to access it. On the code side, it's a basic HTML starter page that loads the Static CMS JavaScript file from a public CDN. The second file, `admin/config.yml`, is the heart of your Static CMS installation, and a bit more complex. The [Configuration](#configuration) section covers the details.
|
||||
|
||||
In this example, we pull the `admin/index.html` file from a public CDN.
|
||||
In this example, we pull the `admin/index.html` file from a public CDN.
|
||||
|
||||
```html
|
||||
<!doctype html>
|
||||
<!DOCTYPE html>
|
||||
<html>
|
||||
<head>
|
||||
<meta charset="utf-8" />
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
|
||||
<title>Content Manager</title>
|
||||
</head>
|
||||
<body>
|
||||
<!-- Include the script that builds the page and powers Static CMS -->
|
||||
<script src="https://unpkg.com/@staticcms/core@%5E0.1.0/dist/static-cms-core.js"></script>
|
||||
</body>
|
||||
<head>
|
||||
<meta charset="utf-8" />
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
|
||||
<title>Content Manager</title>
|
||||
</head>
|
||||
<body>
|
||||
<!-- Include the script that builds the page and powers Static CMS -->
|
||||
<script src="https://unpkg.com/@staticcms/core@%5E1.0.0/dist/static-cms-core.js"></script>
|
||||
<script>
|
||||
window.CMS.init();
|
||||
</script>
|
||||
</body>
|
||||
</html>
|
||||
```
|
||||
|
||||
In the code above the `script` is loaded from the `unpkg` CDN. Should there be any issue, `jsDelivr` can be used as an alternative source. Simply set the `src` to `https://cdn.jsdelivr.net/npm/@staticcms/core@%5E0.1.0/dist/static-cms-core.js`
|
||||
|
||||
### Installing with npm
|
||||
|
||||
You can also use Static CMS as an npm module. Wherever you import Static CMS, it automatically runs, taking over the current page. Make sure the script that imports it only runs on your CMS page. First install the package and save it to your project:
|
||||
|
||||
```bash
|
||||
npm install @staticcms/core --save
|
||||
```
|
||||
|
||||
Then import it (assuming your project has tooling for imports):
|
||||
|
||||
```js
|
||||
import CMS from '@staticcms/core'
|
||||
// Initialize the CMS object
|
||||
CMS.init()
|
||||
// Now the registry is available via the CMS object.
|
||||
CMS.registerPreviewTemplate('my-template', MyTemplate)
|
||||
```
|
||||
In the code above the `script` is loaded from the `unpkg` CDN. Should there be any issue, `jsDelivr` can be used as an alternative source. Simply set the `src` to `https://cdn.jsdelivr.net/npm/@staticcms/core@%5E1.0.0/dist/static-cms-core.js`
|
||||
|
||||
## Configuration
|
||||
|
||||
Configuration is different for every site, so we'll break it down into parts. Add all the code snippets in this section to your `admin/config.yml` file.
|
||||
Configuration is different for every site, so we'll break it down into parts. Add all the code snippets in this section to your `admin/config.yml` file.
|
||||
|
||||
### Backend
|
||||
|
||||
@ -87,11 +71,11 @@ For GitHub and GitLab repositories, you can start your Static CMS `config.yml` f
|
||||
|
||||
```yaml
|
||||
backend:
|
||||
name: git-gateway
|
||||
title: git-gateway
|
||||
branch: master # Branch to update (optional; defaults to master)
|
||||
```
|
||||
|
||||
*(For Bitbucket repositories, use the [Bitbucket backend](/docs/bitbucket-backend) instructions instead.)*
|
||||
_(For Bitbucket repositories, use the [Bitbucket backend](/docs/bitbucket-backend) instructions instead.)_
|
||||
|
||||
The configuration above specifies your backend protocol and your publication branch. Git Gateway is an open source API that acts as a proxy between authenticated users of your site and your site repo. (We'll get to the details of that in the [Authentication section](#authentication) below.) If you leave out the `branch` declaration, it defaults to `master`.
|
||||
|
||||
@ -101,22 +85,22 @@ Static CMS allows users to upload images directly within the editor. For this to
|
||||
|
||||
```yaml
|
||||
# This line should *not* be indented
|
||||
media_folder: "images/uploads" # Media files will be stored in the repo under images/uploads
|
||||
media_folder: 'images/uploads' # Media files will be stored in the repo under images/uploads
|
||||
```
|
||||
|
||||
If you're creating a new folder for uploaded media, you'll need to know where your static site generator expects static files. You can refer to the paths outlined above in [App File Structure](#app-file-structure), and put your media folder in the same location where you put the `admin` folder.
|
||||
|
||||
Note that the`media_folder` file path is relative to the project root, so the example above would work for Jekyll, GitBook, or any other generator that stores static files at the project root. However, it would not work for Hugo, Hexo, Middleman or others that store static files in a subfolder. Here's an example that could work for a Hugo site:
|
||||
Note that the `media_folder` file path is relative to the project root, so the example above would work for Jekyll, GitBook, or any other generator that stores static files at the project root. However, it would not work for Hugo, Next, Hexo, Middleman or others that store static files in a subfolder. Here's an example that could work for a Hugo site:
|
||||
|
||||
```yaml
|
||||
# These lines should *not* be indented
|
||||
media_folder: "static/images/uploads" # Media files will be stored in the repo under static/images/uploads
|
||||
public_folder: "/images/uploads" # The src attribute for uploaded media will begin with /images/uploads
|
||||
media_folder: 'static/images/uploads' # Media files will be stored in the repo under static/images/uploads
|
||||
public_folder: '/images/uploads' # The src attribute for uploaded media will begin with /images/uploads
|
||||
```
|
||||
|
||||
The configuration above adds a new setting, `public_folder`. While `media_folder` specifies where uploaded files are saved in the repo, `public_folder` indicates where they are found in the published site. Image `src` attributes use this path, which is relative to the file where it's called. For this reason, we usually start the path at the site root, using the opening `/`.
|
||||
|
||||
*If `public_folder` is not set, Static CMS defaults to the same value as `media_folder`, adding an opening `/` if one is not included.*
|
||||
_If `public_folder` is not set, Static CMS defaults to the same value as `media_folder`, adding an opening `/` if one is not included._
|
||||
|
||||
### Collections
|
||||
|
||||
@ -129,10 +113,9 @@ Let's say your site has a blog, with the posts stored in `_posts/blog`, and file
|
||||
layout: blog
|
||||
title: "Let's Party"
|
||||
date: 1999-12-31 11:59:59 -0800
|
||||
thumbnail: "/images/prince.jpg"
|
||||
thumbnail: '/images/prince.jpg'
|
||||
rating: 5
|
||||
---
|
||||
|
||||
This is the post body, where I write about our last chance to party before the Y2K bug destroys us all.
|
||||
```
|
||||
|
||||
@ -140,77 +123,34 @@ Given this example, our `collections` settings would look like this in your Stat
|
||||
|
||||
```yaml
|
||||
collections:
|
||||
- name: "blog" # Used in routes, e.g., /admin/collections/blog
|
||||
label: "Blog" # Used in the UI
|
||||
folder: "_posts/blog" # The path to the folder where the documents are stored
|
||||
- title: 'blog' # Used in routes, e.g., /admin/collections/blog
|
||||
label: 'Blog' # Used in the UI
|
||||
folder: '_posts/blog' # The path to the folder where the documents are stored
|
||||
create: true # Allow users to create new documents in this collection
|
||||
slug: "{{year}}-{{month}}-{{day}}-{{slug}}" # Filename template, e.g., YYYY-MM-DD-title.md
|
||||
slug: '{{year}}-{{month}}-{{day}}-{{slug}}' # Filename template, e.g., YYYY-MM-DD-title.md
|
||||
fields: # The fields for each document, usually in front matter
|
||||
- {label: "Layout", name: "layout", widget: "hidden", default: "blog"}
|
||||
- {label: "Title", name: "title", widget: "string"}
|
||||
- {label: "Publish Date", name: "date", widget: "datetime"}
|
||||
- {label: "Featured Image", name: "thumbnail", widget: "image"}
|
||||
- {label: "Rating (scale of 1-5)", name: "rating", widget: "number"}
|
||||
- {label: "Body", name: "body", widget: "markdown"}
|
||||
- { label: 'Layout', title: 'layout', widget: 'hidden', default: 'blog' }
|
||||
- { label: 'Title', title: 'title', widget: 'string' }
|
||||
- { label: 'Publish Date', title: 'date', widget: 'datetime' }
|
||||
- { label: 'Featured Image', title: 'thumbnail', widget: 'image' }
|
||||
- { label: 'Rating (scale of 1-5)', title: 'rating', widget: 'number' }
|
||||
- { label: 'Body', title: 'body', widget: 'markdown' }
|
||||
```
|
||||
|
||||
Let's break that down:
|
||||
|
||||
<table>
|
||||
<tr>
|
||||
<td><code>name</code></td>
|
||||
<td>Post type identifier, used in routes. Must be unique.</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td><code>label</code></td>
|
||||
<td>What the admin UI calls the post type.</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td><code>folder</code></td>
|
||||
<td>Where files of this type are stored, relative to the repo root.</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td><code>create</code></td>
|
||||
<td>Set to <code>true</code> to allow users to create new files in this collection.
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td><code>slug</code></td>
|
||||
<td>Template for filenames. <code>{{year}}</code>, <code>{{month}}</code>, and <code>{{day}}</code> pulls from the post's <code>date</code> field or save date. <code>{{slug}}</code> is a url-safe version of the post's <code>title</code>. Default is simply <code>{{slug}}</code>.
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td><code>fields</code></td>
|
||||
<td>Fields listed here are shown as fields in the content editor, then saved as front matter at the beginning of the document (except for <code>body</code>, which follows the front matter). Each field contains the following properties:
|
||||
<ul>
|
||||
<li><code>label</code>: Field label in the editor UI.</li>
|
||||
<li><code>name</code>: Field name in the document front matter.</li>
|
||||
<li><code>widget</code>: Determines UI style and value data type (details below).</li>
|
||||
<li><code>default</code> (optional): Sets a default value for the field.</li>
|
||||
</ul>
|
||||
</td>
|
||||
</tr>
|
||||
</table>
|
||||
| Field | Description |
|
||||
| ------ | --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
|
||||
| name | Post type identifier, used in routes. Must be unique. |
|
||||
| label | What the admin UI calls the post type. |
|
||||
| folder | Where files of this type are stored, relative to the repo root. |
|
||||
| create | Set to `true` to allow users to create new files in this collection. |
|
||||
| slug | Template for filenames. `{{ year }}`, `{{ month }}`, and `{{ day }}` pulls from the post's `date` field or save date. `{{ slug }}` is a url-safe version of the post's `title`. Default is simply `{{ slug }}`. |
|
||||
| fields | Fields listed here are shown as fields in the content editor, then saved as front matter at the beginning of the document (except for `body`, which follows the front matter). |
|
||||
|
||||
As described above, the `widget` property specifies a built-in or custom UI widget for a given field. When a content editor enters a value into a widget, that value is saved in the document front matter as the value for the `name` specified for that field. A full listing of available widgets can be found in the [Widgets doc](../widgets).
|
||||
As described above, the `widget` property specifies a built-in or custom UI widget for a given field. When a content editor enters a value into a widget, that value is saved in the document front matter as the value for the `name` specified for that field. A full listing of available widgets can be found in the [Widgets doc](/docs/widgets).
|
||||
|
||||
Based on this example, you can go through the post types in your site and add the appropriate settings to your Static CMS `config.yml` file. Each post type should be listed as a separate node under the `collections` field. See the [Collections reference doc](../configuration-options/#collections) for more configuration options.
|
||||
|
||||
### Filter
|
||||
|
||||
The entries for any collection can be filtered based on the value of a single field. The example collection below only shows post entries with the value `en` in the `language` field.
|
||||
|
||||
```yaml
|
||||
collections:
|
||||
- name: "posts"
|
||||
label: "Post"
|
||||
folder: "_posts"
|
||||
filter:
|
||||
field: language
|
||||
value: en
|
||||
fields:
|
||||
- {label: "Language", name: "language"}
|
||||
```
|
||||
Based on this example, you can go through the post types in your site and add the appropriate settings to your Static CMS `config.yml` file. Each post type should be listed as a separate node under the `collections` field. See the [Collections reference doc](/docs/configuration-options/#collections) for more configuration options.
|
||||
|
||||
## Authentication
|
||||
|
||||
@ -244,10 +184,10 @@ When a user logs in with the Netlify Identity widget, an access token directs to
|
||||
```html
|
||||
<script>
|
||||
if (window.netlifyIdentity) {
|
||||
window.netlifyIdentity.on("init", user => {
|
||||
window.netlifyIdentity.on('init', user => {
|
||||
if (!user) {
|
||||
window.netlifyIdentity.on("login", () => {
|
||||
document.location.href = "/admin/";
|
||||
window.netlifyIdentity.on('login', () => {
|
||||
document.location.href = '/admin/';
|
||||
});
|
||||
}
|
||||
});
|
9
website/content/docs/add-to-your-site.mdx
Normal file
@ -0,0 +1,9 @@
|
||||
---
|
||||
group: Intro
|
||||
title: Add to Your Site
|
||||
weight: 3
|
||||
---
|
||||
|
||||
You can adapt Static CMS to a wide variety of projects. It works with any content written in markdown, JSON, YAML, or TOML files, stored in a repo on [GitHub](https://github.com/), [GitLab](https://gitlab.com/), [Bitbucket](https://bitbucket.org) or [Azure](https://azure.microsoft.com/en-us/products/devops/repos/). You can also create your own custom backend.
|
||||
|
||||
You can add Static CMS to your site in two different ways: [CDN hosting](/docs/add-to-your-site-cdn) or [bundling directly into your app](/docs/add-to-your-site-bundling).
|
@ -1,7 +1,6 @@
|
||||
---
|
||||
title: Architecture
|
||||
position: 90
|
||||
group: Contributing
|
||||
title: Architecture
|
||||
weight: 200
|
||||
---
|
||||
|
@ -1,7 +1,7 @@
|
||||
---
|
||||
group: Accounts
|
||||
weight: 20
|
||||
title: Azure
|
||||
weight: 20
|
||||
---
|
||||
|
||||
For repositories stored on Azure, the `azure` backend allows CMS users to log in directly with their Azure account. Note that all users must have write access to your content repository for this to work.
|
||||
@ -19,13 +19,13 @@ In order to get Static CMS working with Azure DevOps, you need a Tenant Id and a
|
||||
|
||||
```yaml
|
||||
backend:
|
||||
name: azure
|
||||
title: azure
|
||||
repo: organization/project/repo # replace with actual path
|
||||
tenant_id: tenantId # replace with your tenantId
|
||||
app_id: appId # replace with your appId
|
||||
```
|
||||
|
||||
### Limitations
|
||||
## Limitations
|
||||
|
||||
1. Pagination is not supported so some endpoints might return missing data
|
||||
|
@ -1,7 +1,7 @@
|
||||
---
|
||||
group: Accounts
|
||||
weight: 1
|
||||
title: Overview
|
||||
weight: 1
|
||||
---
|
||||
|
||||
A backend is JavaScript code that allows Static CMS to communicate with a service that stores content - typically a Git host like GitHub or GitLab. It provides functions that Static CMS can use to do things like read and update files using API's provided by the service.
|
@ -1,7 +1,7 @@
|
||||
---
|
||||
group: Configuration
|
||||
weight: 200
|
||||
title: Beta Features!
|
||||
weight: 200
|
||||
---
|
||||
We run new functionality in an open beta format from time to time. That means that this functionality is totally available for use, and we *think* it might be ready for primetime, but it could break or change without notice.
|
||||
|
||||
@ -16,7 +16,7 @@ You can connect Static CMS to a local Git repository, instead of working with a
|
||||
|
||||
```yaml
|
||||
backend:
|
||||
name: git-gateway
|
||||
title: git-gateway
|
||||
|
||||
# when using the default proxy server port
|
||||
local_backend: true
|
||||
@ -42,7 +42,7 @@ PORT=8082
|
||||
|
||||
```yaml
|
||||
backend:
|
||||
name: git-gateway
|
||||
title: git-gateway
|
||||
|
||||
local_backend:
|
||||
# when using a custom proxy server port
|
||||
@ -78,7 +78,7 @@ i18n:
|
||||
|
||||
```yaml
|
||||
collections:
|
||||
- name: i18n_content
|
||||
- title: i18n_content
|
||||
# same as the top level, but all fields are optional and defaults to the top level
|
||||
# can also be a boolean to accept the top level defaults
|
||||
i18n: true
|
||||
@ -88,20 +88,20 @@ When using a file collection, you must also enable i18n for each individual file
|
||||
|
||||
```yaml
|
||||
collections:
|
||||
- name: pages
|
||||
- title: pages
|
||||
label: Pages
|
||||
# Configure i18n for this collection.
|
||||
i18n:
|
||||
structure: single_file
|
||||
locales: [en, de, fr]
|
||||
files:
|
||||
- name: about
|
||||
- title: about
|
||||
label: About Page
|
||||
file: site/content/about.yml
|
||||
# Enable i18n for this file.
|
||||
i18n: true
|
||||
fields:
|
||||
- { label: Title, name: title, widget: string, i18n: true }
|
||||
- { label: Title, title: title, widget: string, i18n: true }
|
||||
```
|
||||
|
||||
### Field level configuration
|
||||
@ -109,17 +109,17 @@ collections:
|
||||
```yaml
|
||||
fields:
|
||||
- label: Title
|
||||
name: title
|
||||
title: title
|
||||
widget: string
|
||||
# same as 'i18n: translate'. Allows translation of the title field
|
||||
i18n: true
|
||||
- label: Date
|
||||
name: date
|
||||
title: date
|
||||
widget: datetime
|
||||
# The date field will be duplicated from the default locale.
|
||||
i18n: duplicate
|
||||
- label: Body
|
||||
name: body
|
||||
title: body
|
||||
# The markdown field will be omitted from the translation.
|
||||
widget: markdown
|
||||
```
|
||||
@ -132,22 +132,22 @@ i18n:
|
||||
locales: [en, de, fr]
|
||||
|
||||
collections:
|
||||
- name: posts
|
||||
- title: posts
|
||||
label: Posts
|
||||
folder: content/posts
|
||||
create: true
|
||||
i18n: true
|
||||
fields:
|
||||
- label: Title
|
||||
name: title
|
||||
title: title
|
||||
widget: string
|
||||
i18n: true
|
||||
- label: Date
|
||||
name: date
|
||||
title: date
|
||||
widget: datetime
|
||||
i18n: duplicate
|
||||
- label: Body
|
||||
name: body
|
||||
title: body
|
||||
widget: markdown
|
||||
```
|
||||
|
||||
@ -159,62 +159,22 @@ collections:
|
||||
|
||||
```yaml
|
||||
- label: 'Object'
|
||||
name: 'object'
|
||||
title: 'object'
|
||||
widget: 'object'
|
||||
i18n: true
|
||||
fields:
|
||||
- { label: 'String', name: 'string', widget: 'string', i18n: true }
|
||||
- { label: 'Date', name: 'date', widget: 'datetime', i18n: duplicate }
|
||||
- { label: 'Boolean', name: 'boolean', widget: 'boolean', i18n: duplicate }
|
||||
- { label: 'String', title: 'string', widget: 'string', i18n: true }
|
||||
- { label: 'Date', title: 'date', widget: 'datetime', i18n: duplicate }
|
||||
- { label: 'Boolean', title: 'boolean', widget: 'boolean', i18n: duplicate }
|
||||
- {
|
||||
label: 'Object',
|
||||
name: 'object',
|
||||
title: 'object',
|
||||
widget: 'object',
|
||||
i18n: true,
|
||||
field: { label: 'String', name: 'string', widget: 'string', i18n: duplicate },
|
||||
field: { label: 'String', title: 'string', widget: 'string', i18n: duplicate },
|
||||
}
|
||||
```
|
||||
|
||||
## GitHub GraphQL API
|
||||
|
||||
Experimental support for GitHub's [GraphQL API](https://developer.github.com/v4/) is now available for the GitHub backend.
|
||||
|
||||
**Note: not compatible with Git Gateway.**
|
||||
|
||||
GraphQL allows to retrieve data using less individual API requests compared to a REST API. GitHub's GraphQL API still does not support all mutations necessary to completely replace their REST API, so this feature only calls the new GraphQL API where possible.
|
||||
|
||||
You can use the GraphQL API for the GitHub backend by setting `backend.use_graphql` to `true` in your CMS config:
|
||||
|
||||
```yml
|
||||
backend:
|
||||
name: github
|
||||
repo: owner/repo # replace this with your repo info
|
||||
use_graphql: true
|
||||
```
|
||||
|
||||
Learn more about the benefits of GraphQL in the [GraphQL docs](https://graphql.org).
|
||||
|
||||
## GitLab GraphQL API
|
||||
|
||||
Experimental support for GitLab's [GraphQL API](https://docs.gitlab.com/ee/api/graphql/) is now available for the GitLab backend.
|
||||
|
||||
**Note: not compatible with Git Gateway.**
|
||||
|
||||
GraphQL allows to retrieve data using less individual API requests compared to a REST API.
|
||||
The current implementation uses the GraphQL API in specific cases, where using the REST API can be slow and lead to exceeding GitLab's rate limits. As we receive feedback and extend the feature, we'll migrate more functionality to the GraphQL API.
|
||||
|
||||
You can enable the GraphQL API for the GitLab backend by setting `backend.use_graphql` to `true` in your CMS config:
|
||||
|
||||
```yml
|
||||
backend:
|
||||
name: gitlab
|
||||
repo: owner/repo # replace this with your repo info
|
||||
use_graphql: true
|
||||
|
||||
# optional, defaults to 'https://gitlab.com/api/graphql'. Can be used to configure a self hosted GitLab instance.
|
||||
graphql_api_root: https://my-self-hosted-gitlab.com/api/graphql
|
||||
```
|
||||
|
||||
## Folder Collections Path
|
||||
|
||||
By default the CMS stores folder collection content under the folder specified in the collection setting.
|
||||
@ -250,7 +210,7 @@ For example, the following configuration will result in media files being saved
|
||||
media_folder: static/media
|
||||
public_folder: /media
|
||||
collections:
|
||||
- name: posts
|
||||
- title: posts
|
||||
label: Posts
|
||||
label_singular: 'Post'
|
||||
folder: content/posts
|
||||
@ -259,10 +219,10 @@ collections:
|
||||
public_folder: ''
|
||||
fields:
|
||||
- label: Title
|
||||
name: title
|
||||
title: title
|
||||
widget: string
|
||||
- label: 'Cover Image'
|
||||
name: 'image'
|
||||
title: 'image'
|
||||
widget: 'image'
|
||||
```
|
||||
|
||||
@ -315,27 +275,27 @@ either a "carousel" or a "spotlight". Each type has a unique name and set of fie
|
||||
|
||||
```yaml
|
||||
- label: 'Home Section'
|
||||
name: 'sections'
|
||||
title: 'sections'
|
||||
widget: 'list'
|
||||
types:
|
||||
- label: 'Carousel'
|
||||
name: 'carousel'
|
||||
title: 'carousel'
|
||||
widget: object
|
||||
summary: '{{fields.header}}'
|
||||
fields:
|
||||
- { label: Header, name: header, widget: string, default: 'Image Gallery' }
|
||||
- { label: Template, name: template, widget: string, default: 'carousel.html' }
|
||||
- { label: Header, title: header, widget: string, default: 'Image Gallery' }
|
||||
- { label: Template, title: template, widget: string, default: 'carousel.html' }
|
||||
- label: Images
|
||||
name: images
|
||||
title: images
|
||||
widget: list
|
||||
field: { label: Image, name: image, widget: image }
|
||||
field: { label: Image, title: image, widget: image }
|
||||
- label: 'Spotlight'
|
||||
name: 'spotlight'
|
||||
title: 'spotlight'
|
||||
widget: object
|
||||
fields:
|
||||
- { label: Header, name: header, widget: string, default: 'Spotlight' }
|
||||
- { label: Template, name: template, widget: string, default: 'spotlight.html' }
|
||||
- { label: Text, name: text, widget: text, default: 'Hello World' }
|
||||
- { label: Header, title: header, widget: string, default: 'Spotlight' }
|
||||
- { label: Template, title: template, widget: string, default: 'spotlight.html' }
|
||||
- { label: Text, title: text, widget: text, default: 'Hello World' }
|
||||
```
|
||||
|
||||
### Example Output
|
||||
@ -407,7 +367,7 @@ init()
|
||||
init({
|
||||
config: {
|
||||
backend: {
|
||||
name: 'git-gateway',
|
||||
title: 'git-gateway',
|
||||
},
|
||||
},
|
||||
})
|
||||
@ -423,17 +383,17 @@ init({
|
||||
init({
|
||||
config: {
|
||||
backend: {
|
||||
name: 'git-gateway',
|
||||
title: 'git-gateway',
|
||||
},
|
||||
load_config_file: false,
|
||||
media_folder: "static/images/uploads",
|
||||
public_folder: "/images/uploads",
|
||||
collections: [
|
||||
{ label: "Blog", name: "blog", folder: "_posts/blog", create: true, fields: [
|
||||
{ label: "Title", name: "title", widget: "string" },
|
||||
{ label: "Publish Date", name: "date", widget: "datetime" },
|
||||
{ label: "Featured Image", name: "thumbnail", widget: "image" },
|
||||
{ label: "Body", name: "body", widget: "markdown" },
|
||||
{ label: "Blog", title: "blog", folder: "_posts/blog", create: true, fields: [
|
||||
{ label: "Title", title: "title", widget: "string" },
|
||||
{ label: "Publish Date", title: "date", widget: "datetime" },
|
||||
{ label: "Featured Image", title: "thumbnail", widget: "image" },
|
||||
{ label: "Body", title: "body", widget: "markdown" },
|
||||
]},
|
||||
],
|
||||
},
|
||||
@ -487,7 +447,7 @@ Example config:
|
||||
|
||||
```yaml
|
||||
- label: 'Featured Image'
|
||||
name: 'thumbnail'
|
||||
title: 'thumbnail'
|
||||
widget: 'image'
|
||||
default: '/uploads/chocolate-dogecoin.jpg'
|
||||
media_library:
|
||||
@ -503,14 +463,14 @@ Example config:
|
||||
|
||||
```yaml
|
||||
collections:
|
||||
- name: 'posts'
|
||||
- title: 'posts'
|
||||
label: 'Posts'
|
||||
folder: '_posts'
|
||||
summary: "{{title | upper}} - {{date | date('YYYY-MM-DD')}} – {{body | truncate(20, '***')}}"
|
||||
fields:
|
||||
- { label: 'Title', name: 'title', widget: 'string' }
|
||||
- { label: 'Publish Date', name: 'date', widget: 'datetime' }
|
||||
- { label: 'Body', name: 'body', widget: 'markdown' }
|
||||
- { label: 'Title', title: 'title', widget: 'string' }
|
||||
- { label: 'Publish Date', title: 'date', widget: 'datetime' }
|
||||
- { label: 'Body', title: 'body', widget: 'markdown' }
|
||||
```
|
||||
|
||||
The above config will transform the title field to uppercase and format the date field using `YYYY-MM-DD` format.
|
||||
@ -524,7 +484,7 @@ Example usage:
|
||||
|
||||
```javascript
|
||||
CMS.registerEventListener({
|
||||
name: 'prePublish',
|
||||
title: 'prePublish',
|
||||
handler: ({ author, entry }) => console.info(JSON.stringify({ author, data: entry.data })),
|
||||
});
|
||||
```
|
||||
@ -533,7 +493,7 @@ Supported events are `prePublish`, `postPublish`, `preSave` and `postSave`. The
|
||||
|
||||
```javascript
|
||||
CMS.registerEventListener({
|
||||
name: 'preSave',
|
||||
title: 'preSave',
|
||||
handler: ({ entry }) => {
|
||||
return entry.data.set('title', 'new title');
|
||||
},
|
||||
@ -548,23 +508,23 @@ For example given the configuration:
|
||||
|
||||
```yaml
|
||||
collections:
|
||||
- name: posts
|
||||
- title: posts
|
||||
label: Posts
|
||||
folder: content/posts
|
||||
create: true
|
||||
fields:
|
||||
- label: Title
|
||||
name: title
|
||||
title: title
|
||||
widget: string
|
||||
- label: Object
|
||||
name: object
|
||||
title: object
|
||||
widget: object
|
||||
fields:
|
||||
- label: Title
|
||||
name: title
|
||||
title: title
|
||||
widget: string
|
||||
- label: body
|
||||
name: body
|
||||
title: body
|
||||
widget: markdown
|
||||
```
|
||||
|
||||
@ -583,7 +543,7 @@ Example configuration:
|
||||
|
||||
```yaml
|
||||
collections:
|
||||
- name: pages
|
||||
- title: pages
|
||||
label: Pages
|
||||
label_singular: 'Page'
|
||||
folder: content/pages
|
||||
@ -594,10 +554,10 @@ collections:
|
||||
summary: '{{title}}' # optional summary for a tree node, defaults to the inferred title field
|
||||
fields:
|
||||
- label: Title
|
||||
name: title
|
||||
title: title
|
||||
widget: string
|
||||
- label: Body
|
||||
name: body
|
||||
title: body
|
||||
widget: markdown
|
||||
```
|
||||
|
||||
@ -616,17 +576,3 @@ content
|
||||
│ └── index.md
|
||||
└── index.md
|
||||
```
|
||||
|
||||
## Remark plugins
|
||||
|
||||
You can register plugins to customize [`remark`](https://github.com/remarkjs/remark), the library used by the richtext editor for serializing and deserializing markdown.
|
||||
|
||||
```js
|
||||
// register a plugin
|
||||
CMS.registerRemarkPlugin(plugin);
|
||||
|
||||
// provide global settings to all plugins, e.g. for customizing `remark-stringify`
|
||||
CMS.registerRemarkPlugin({ settings: { bullet: '-' } });
|
||||
```
|
||||
|
||||
Note that the `markdown` currently uses `remark@10`, so you should check a plugin's compatibility first.
|
@ -1,7 +1,7 @@
|
||||
---
|
||||
group: Accounts
|
||||
weight: 20
|
||||
title: Bitbucket
|
||||
weight: 20
|
||||
---
|
||||
For repositories stored on Bitbucket, the `bitbucket` backend allows CMS users to log in directly with their Bitbucket account. Note that all users must have write access to your content repository for this to work.
|
||||
|
||||
@ -12,11 +12,11 @@ To enable it:
|
||||
|
||||
```yaml
|
||||
backend:
|
||||
name: bitbucket
|
||||
title: bitbucket
|
||||
repo: owner-name/repo-name # Path to your Bitbucket repository
|
||||
```
|
||||
|
||||
### Client-Side Implicit Grant (Bitbucket)
|
||||
## Client-Side Implicit Grant
|
||||
|
||||
With Bitbucket's Implicit Grant, users can authenticate with Bitbucket directly from the client. To do this:
|
||||
|
||||
@ -25,7 +25,7 @@ With Bitbucket's Implicit Grant, users can authenticate with Bitbucket directly
|
||||
|
||||
```yaml
|
||||
backend:
|
||||
name: bitbucket
|
||||
title: bitbucket
|
||||
repo: owner-name/repo-name
|
||||
branch: default
|
||||
auth_type: implicit
|
@ -1,6 +1,6 @@
|
||||
---
|
||||
title: Cloudinary
|
||||
group: Media
|
||||
title: Cloudinary
|
||||
weight: 10
|
||||
---
|
||||
Cloudinary is a digital asset management platform with a broad feature set, including support for responsive image generation and url based image transformation. They also provide a powerful media library UI for managing assets, and tools for organizing your assets into a hierarchy.
|
||||
@ -11,7 +11,7 @@ The Cloudinary media library integration for Static CMS uses Cloudinary's own me
|
||||
|
||||
You can [sign up for Cloudinary](https://cloudinary.com/users/register/free) for free. Once you're logged in, you'll need to retrieve your Cloud name and API key from the upper left corner of the Cloudinary console.
|
||||
|
||||

|
||||

|
||||
|
||||
## Connecting Cloudinary to Static CMS
|
||||
|
||||
@ -19,9 +19,9 @@ To use the Cloudinary media library within Static CMS, you'll need to update you
|
||||
|
||||
```yaml
|
||||
media_library:
|
||||
name: cloudinary
|
||||
title: cloudinary
|
||||
config:
|
||||
cloud_name: your_cloud_name
|
||||
cloud_title: your_cloud_name
|
||||
api_key: your_api_key
|
||||
```
|
||||
|
||||
@ -73,7 +73,7 @@ instance of the Cloudinary widget.
|
||||
```yaml
|
||||
# global
|
||||
media_library:
|
||||
name: cloudinary
|
||||
title: cloudinary
|
||||
output_filename_only: false
|
||||
config:
|
||||
default_transformations:
|
||||
@ -93,10 +93,10 @@ For example:
|
||||
# field
|
||||
fields: # The fields each document in this collection have
|
||||
- label: 'Cover Image'
|
||||
name: 'image'
|
||||
title: 'image'
|
||||
widget: 'image'
|
||||
required: false
|
||||
tagname: ''
|
||||
tagtitle: ''
|
||||
media_library:
|
||||
config:
|
||||
default_transformations:
|
||||
@ -116,11 +116,11 @@ If you prefer to provide direction so that images are transformed in a specific
|
||||
```yaml
|
||||
# global
|
||||
media_library:
|
||||
name: cloudinary
|
||||
title: cloudinary
|
||||
output_filename_only: true
|
||||
# field
|
||||
media_library:
|
||||
name: cloudinary
|
||||
title: cloudinary
|
||||
output_filename_only: true
|
||||
```
|
||||
|
@ -1,7 +1,7 @@
|
||||
---
|
||||
group: Collections
|
||||
weight: 10
|
||||
title: Collection Types
|
||||
weight: 10
|
||||
---
|
||||
All editable content types are defined in the `collections` field of your `config.yml` file, and display in the left sidebar of the Content page of the editor UI.
|
||||
|
||||
@ -20,29 +20,29 @@ Example:
|
||||
```yaml
|
||||
collections:
|
||||
- label: "Blog"
|
||||
name: "blog"
|
||||
title: "blog"
|
||||
folder: "_posts/blog"
|
||||
create: true
|
||||
fields:
|
||||
- {label: "Title", name: "title", widget: "string"}
|
||||
- {label: "Publish Date", name: "date", widget: "datetime"}
|
||||
- {label: "Featured Image", name: "thumbnail", widget: "image"}
|
||||
- {label: "Body", name: "body", widget: "markdown"}
|
||||
- {label: "Title", title: "title", widget: "string"}
|
||||
- {label: "Publish Date", title: "date", widget: "datetime"}
|
||||
- {label: "Featured Image", title: "thumbnail", widget: "image"}
|
||||
- {label: "Body", title: "body", widget: "markdown"}
|
||||
```
|
||||
|
||||
With `identifier_field`:
|
||||
|
||||
```yaml
|
||||
- label: "Blog"
|
||||
name: "blog"
|
||||
title: "blog"
|
||||
folder: "_posts/blog"
|
||||
create: true
|
||||
identifier_field: name
|
||||
fields:
|
||||
- {label: "Name", name: "name", widget: "string"}
|
||||
- {label: "Publish Date", name: "date", widget: "datetime"}
|
||||
- {label: "Featured Image", name: "thumbnail", widget: "image"}
|
||||
- {label: "Body", name: "body", widget: "markdown"}
|
||||
- {label: "Name", title: "name", widget: "string"}
|
||||
- {label: "Publish Date", title: "date", widget: "datetime"}
|
||||
- {label: "Featured Image", title: "thumbnail", widget: "image"}
|
||||
- {label: "Body", title: "body", widget: "markdown"}
|
||||
```
|
||||
|
||||
### Filtered folder collections
|
||||
@ -59,23 +59,23 @@ The example below creates two collections in the same folder, filtered by the `l
|
||||
```yaml
|
||||
collections:
|
||||
- label: "Blog in English"
|
||||
name: "english_posts"
|
||||
title: "english_posts"
|
||||
folder: "_posts"
|
||||
create: true
|
||||
filter: {field: "language", value: "en"}
|
||||
fields:
|
||||
- {label: "Language", name: "language", widget: "select", options: ["en", "es"]}
|
||||
- {label: "Title", name: "title", widget: "string"}
|
||||
- {label: "Content", name: "body", widget: "markdown"}
|
||||
- {label: "Language", title: "language", widget: "select", options: ["en", "es"]}
|
||||
- {label: "Title", title: "title", widget: "string"}
|
||||
- {label: "Content", title: "body", widget: "markdown"}
|
||||
- label: "Blog en Español"
|
||||
name: "spanish_posts"
|
||||
title: "spanish_posts"
|
||||
folder: "_posts"
|
||||
create: true
|
||||
filter: {field: "language", value: "es"}
|
||||
fields:
|
||||
- {label: "Lenguaje", name: "language", widget: "select", options: ["en", "es"]}
|
||||
- {label: "Titulo", name: "title", widget: "string"}
|
||||
- {label: "Contenido", name: "body", widget: "markdown"}
|
||||
- {label: "Lenguaje", title: "language", widget: "select", options: ["en", "es"]}
|
||||
- {label: "Titulo", title: "title", widget: "string"}
|
||||
- {label: "Contenido", title: "body", widget: "markdown"}
|
||||
```
|
||||
|
||||
### Nested collections (beta)
|
||||
@ -95,31 +95,31 @@ Example:
|
||||
```yaml
|
||||
collections:
|
||||
- label: "Pages"
|
||||
name: "pages"
|
||||
title: "pages"
|
||||
files:
|
||||
- label: "About Page"
|
||||
name: "about"
|
||||
title: "about"
|
||||
file: "site/content/about.yml"
|
||||
fields:
|
||||
- {label: Title, name: title, widget: string}
|
||||
- {label: Intro, name: intro, widget: markdown}
|
||||
- {label: Title, title: title, widget: string}
|
||||
- {label: Intro, title: intro, widget: markdown}
|
||||
- label: Team
|
||||
name: team
|
||||
title: team
|
||||
widget: list
|
||||
fields:
|
||||
- {label: Name, name: name, widget: string}
|
||||
- {label: Position, name: position, widget: string}
|
||||
- {label: Photo, name: photo, widget: image}
|
||||
- {label: Name, title: name, widget: string}
|
||||
- {label: Position, title: position, widget: string}
|
||||
- {label: Photo, title: photo, widget: image}
|
||||
- label: "Locations Page"
|
||||
name: "locations"
|
||||
title: "locations"
|
||||
file: "site/content/locations.yml"
|
||||
fields:
|
||||
- {label: Title, name: title, widget: string}
|
||||
- {label: Intro, name: intro, widget: markdown}
|
||||
- {label: Title, title: title, widget: string}
|
||||
- {label: Intro, title: intro, widget: markdown}
|
||||
- label: Locations
|
||||
name: locations
|
||||
title: locations
|
||||
widget: list
|
||||
fields:
|
||||
- {label: Name, name: name, widget: string}
|
||||
- {label: Address, name: address, widget: string}
|
||||
- {label: Name, title: name, widget: string}
|
||||
- {label: Address, title: address, widget: string}
|
||||
```
|
@ -1,7 +1,7 @@
|
||||
---
|
||||
group: Configuration
|
||||
weight: 10
|
||||
title: Configuration Options
|
||||
weight: 10
|
||||
---
|
||||
## Configuration File
|
||||
|
||||
@ -14,7 +14,7 @@ Alternatively, you can specify a custom config file using a link tag:
|
||||
<link href="path/to/config.yml" type="text/yaml" rel="cms-config-url">
|
||||
```
|
||||
|
||||
To see working configuration examples, you can [start from a template](../start-with-a-template) or check out the [CMS demo site](https://cms-demo.netlify.com). (No login required: click the login button and the CMS will open.) You can refer to the demo [configuration code](https://github.com/StaticJsCMS/static-cms/blob/master/dev-test/config.yml) to see how each option was configured.
|
||||
To see working configuration examples, you can [start from a template](/docs/start-with-a-template) or check out the [CMS demo site](https://cms-demo.netlify.com). (No login required: click the login button and the CMS will open.) You can refer to the demo [configuration code](https://github.com/StaticJsCMS/static-cms/blob/master/dev-test/config.yml) to see how each option was configured.
|
||||
|
||||
You can find details about all configuration options below. Note that [YAML syntax](https://en.wikipedia.org/wiki/YAML#Basic_components) allows lists and objects to be written in block or inline style, and the code samples below include a mix of both.
|
||||
|
||||
@ -60,7 +60,7 @@ Media library integrations are configured via the `media_library` property, and
|
||||
|
||||
```yaml
|
||||
media_library:
|
||||
name: uploadcare
|
||||
title: uploadcare
|
||||
config:
|
||||
publicKey: demopublickey
|
||||
```
|
||||
@ -169,13 +169,13 @@ The `collections` setting is the heart of your Static CMS configuration, as it d
|
||||
|
||||
`collections` accepts a list of collection objects, each with the following options:
|
||||
|
||||
* `name` (required): unique identifier for the collection, used as the key when referenced in other contexts (like the [relation widget](../widgets/#relation))
|
||||
* `name` (required): unique identifier for the collection, used as the key when referenced in other contexts (like the [relation widget](/docs/widgets/#relation))
|
||||
* `identifier_field`: see detailed description below
|
||||
* `label`: label for the collection in the editor UI; defaults to the value of `name`
|
||||
* `label_singular`: singular label for certain elements in the editor; defaults to the value of `label`
|
||||
* `description`: optional text, displayed below the label when viewing a collection
|
||||
* `files` or `folder` (requires one of these): specifies the collection type and location; details in [Collection Types](../collection-types)
|
||||
* `filter`: optional filter for `folder` collections; details in [Collection Types](../collection-types)
|
||||
* `files` or `folder` (requires one of these): specifies the collection type and location; details in [Collection Types](/docs/collection-types)
|
||||
* `filter`: optional filter for `folder` collections; details in [Collection Types](/docs/collection-types)
|
||||
* `create`: for `folder` collections only; `true` allows users to create new items in the collection; defaults to `false`
|
||||
* `hide`: `true` hides a collection in the CMS UI; defaults to `false`. Useful when using the relation widget to hide referenced collections.
|
||||
* `delete`: `false` prevents users from deleting items in a collection; defaults to `true`
|
||||
@ -202,7 +202,7 @@ Static CMS expects every entry to provide a field named `"title"` that serves as
|
||||
|
||||
```yaml
|
||||
collections:
|
||||
- name: posts
|
||||
- title: posts
|
||||
identifier_field: name
|
||||
```
|
||||
|
||||
@ -269,12 +269,12 @@ The `fields` option maps editor UI widgets to field-value pairs in the saved fil
|
||||
|
||||
`fields` accepts a list of collection objects, each with the following options:
|
||||
|
||||
* `name` (required): unique identifier for the field, used as the key when referenced in other contexts (like the [relation widget](../widgets/#relation))
|
||||
* `name` (required): unique identifier for the field, used as the key when referenced in other contexts (like the [relation widget](/docs/widgets/#relation))
|
||||
* `label`: label for the field in the editor UI; defaults to the value of `name`
|
||||
* `widget`: defines editor UI and inputs and file field data types; details in [Widgets](../widgets)
|
||||
* `default`: specify a default value for a field; available for most widget types (see [Widgets](../widgets) for details on each widget type). Please note that field default value only works for folder collection type.
|
||||
* `widget`: defines editor UI and inputs and file field data types; details in [Widgets](/docs/widgets)
|
||||
* `default`: specify a default value for a field; available for most widget types (see [Widgets](/docs/widgets) for details on each widget type). Please note that field default value only works for folder collection type.
|
||||
* `required`: specify as `false` to make a field optional; defaults to `true`
|
||||
* `pattern`: add field validation by specifying a list with a regex pattern and an error message; more extensive validation can be achieved with [custom widgets](../custom-widgets/#advanced-field-validation)
|
||||
* `pattern`: add field validation by specifying a list with a regex pattern and an error message; more extensive validation can be achieved with [custom widgets](/docs/custom-widgets/#advanced-field-validation)
|
||||
* `comment`: optional comment to add before the field (only supported for `yaml`)
|
||||
|
||||
In files with frontmatter, one field should be named `body`. This special field represents the section of the document (usually markdown) that comes after the frontmatter.
|
||||
@ -284,12 +284,12 @@ In files with frontmatter, one field should be named `body`. This special field
|
||||
```yaml
|
||||
fields:
|
||||
- label: "Title"
|
||||
name: "title"
|
||||
title: "title"
|
||||
widget: "string"
|
||||
pattern: ['.{20,}', "Must have at least 20 characters"]
|
||||
- {label: "Layout", name: "layout", widget: "hidden", default: "blog"}
|
||||
- {label: "Featured Image", name: "thumbnail", widget: "image", required: false}
|
||||
- {label: "Body", name: "body", widget: "markdown"}
|
||||
- {label: "Layout", title: "layout", widget: "hidden", default: "blog"}
|
||||
- {label: "Featured Image", title: "thumbnail", widget: "image", required: false}
|
||||
- {label: "Body", title: "body", widget: "markdown"}
|
||||
comment: 'This is a multiline\ncomment'
|
||||
```
|
||||
|
@ -1,7 +1,7 @@
|
||||
---
|
||||
group: Contributing
|
||||
title: Contributor Guide
|
||||
weight: 20
|
||||
group: Contributing
|
||||
---
|
||||
|
||||
We're hoping that Static CMS will do for the [Jamstack](https://www.jamstack.org) what WordPress did for dynamic sites back in the day. We know we can't do that without building a thriving community of contributors and users, and we'd love to have you join us.
|
@ -1,7 +1,7 @@
|
||||
---
|
||||
group: Fields
|
||||
weight: 20
|
||||
group: Widgets
|
||||
title: Creating Custom Widgets
|
||||
weight: 50
|
||||
---
|
||||
The Static CMS exposes a `window.CMS` a global object that you can use to register custom widgets, previews, and editor plugins. The same object is also the default export if you import Static CMS as an npm module. The available widget extension methods are:
|
||||
|
||||
@ -54,7 +54,7 @@ var CategoriesControl = createClass({
|
||||
var value = this.props.value;
|
||||
return h('input', {
|
||||
id: this.props.forID,
|
||||
className: this.props.classNameWrapper,
|
||||
classtitle: this.props.classNameWrapper,
|
||||
type: 'text',
|
||||
value: value ? value.join(separator) : '',
|
||||
onChange: this.handleChange,
|
||||
@ -86,14 +86,14 @@ CMS.registerWidget('categories', CategoriesControl, CategoriesPreview, schema);
|
||||
|
||||
```yml
|
||||
collections:
|
||||
- name: posts
|
||||
- title: posts
|
||||
label: Posts
|
||||
folder: content/posts
|
||||
fields:
|
||||
- name: title
|
||||
- title: title
|
||||
label: Title
|
||||
widget: string
|
||||
- name: categories
|
||||
- title: categories
|
||||
label: Categories
|
||||
widget: categories
|
||||
separator: __
|
||||
@ -126,12 +126,12 @@ CMS.registerEditorComponent({
|
||||
// Fields the user need to fill out when adding an instance of the component
|
||||
fields: [
|
||||
{
|
||||
name: 'summary',
|
||||
title: 'summary',
|
||||
label: 'Summary',
|
||||
widget: 'string'
|
||||
},
|
||||
{
|
||||
name: 'details',
|
||||
title: 'details',
|
||||
label: 'Details',
|
||||
widget: 'markdown'
|
||||
}
|
||||
@ -194,7 +194,7 @@ CMS.registerEditorComponent({
|
||||
|
||||
## Advanced field validation
|
||||
|
||||
All widget fields, including those for built-in widgets, [include basic validation](../widgets/#common-widget-options) capability using the `required` and `pattern` options.
|
||||
All widget fields, including those for built-in widgets, [include basic validation](/docs/widgets/#common-widget-options) capability using the `required` and `pattern` options.
|
||||
|
||||
With custom widgets, the widget control can also optionally implement an `isValid` method to perform custom validations, in addition to presence and pattern. The `isValid` method will be automatically called, and it can return either a boolean value, an object with an error message or a promise. Examples:
|
||||
|
||||
@ -244,12 +244,12 @@ Widgets are inputs for the Static CMS editor interface. It's a React component t
|
||||
|
||||
For writing custom widgets as a separate package you should follow these steps:
|
||||
|
||||
1. Create a directory
|
||||
1. Create a directory
|
||||
|
||||
```javascript
|
||||
mkdir my-custom-widget
|
||||
```
|
||||
2. Navigate to the directory
|
||||
2. Navigate to the directory
|
||||
|
||||
```javascript
|
||||
cd my-custom-widget
|
||||
@ -475,23 +475,23 @@ window.CMS_MANUAL_INIT = true
|
||||
```javascript
|
||||
import './bootstrap.js'
|
||||
import CMS, { init } from '@staticcms/core'
|
||||
import { Control, Preview } from '../src'
|
||||
import { Control, Preview } from '/docs/src'
|
||||
|
||||
const config = {
|
||||
backend: {
|
||||
name: 'test-repo',
|
||||
title: 'test-repo',
|
||||
login: false,
|
||||
},
|
||||
media_folder: 'assets',
|
||||
collections: [{
|
||||
name: 'test',
|
||||
title: 'test',
|
||||
label: 'Test',
|
||||
files: [{
|
||||
file: 'test.yml',
|
||||
name: 'test',
|
||||
title: 'test',
|
||||
label: 'Test',
|
||||
fields: [
|
||||
{ name: 'test_widget', label: 'Test Widget', widget: 'test'},
|
||||
{ title: 'test_widget', label: 'Test Widget', widget: 'test'},
|
||||
],
|
||||
}],
|
||||
}],
|
@ -1,7 +1,7 @@
|
||||
---
|
||||
group: Customization
|
||||
title: Creating Custom Previews
|
||||
weight: 50
|
||||
group: Customization
|
||||
---
|
||||
|
||||
The Static CMS exposes a `window.CMS` global object that you can use to register custom widgets, previews and editor plugins. The available customization methods are:
|
||||
@ -20,7 +20,7 @@ Registers a template for a folder collection or an individual file in a file col
|
||||
|
||||
**Params:**
|
||||
|
||||
- name: The name of the collection (or file for file collections) which this preview component will be used for.
|
||||
- title: The name of the collection (or file for file collections) which this preview component will be used for.
|
||||
- Folder collections: Use the name of the collection
|
||||
- File collections: Use the name of the file
|
||||
- react_component: A React component that renders the collection data. Six props will be passed to your component during render:
|
||||
@ -44,7 +44,7 @@ Registers a template for a folder collection or an individual file in a file col
|
||||
{},
|
||||
h('h1', {}, entry.data.title),
|
||||
h('img', { src: bg.toString() }),
|
||||
h('div', { className: 'text' }, this.props.widgetFor('body')),
|
||||
h('div', { classtitle: 'text' }, this.props.widgetFor('body')),
|
||||
);
|
||||
},
|
||||
});
|
||||
@ -71,12 +71,12 @@ Registers a template for a folder collection or an individual file in a file col
|
||||
// the return value of `widgetsFor` would look like this:
|
||||
//
|
||||
// [{
|
||||
// data: { name: 'Mathias', description: 'Co-Founder'},
|
||||
// widgets: { name: (<WidgetComponent>), description: (WidgetComponent>)}
|
||||
// data: { title: 'Mathias', description: 'Co-Founder'},
|
||||
// widgets: { title: (<WidgetComponent>), description: (WidgetComponent>)}
|
||||
// },
|
||||
// {
|
||||
// data: { name: 'Chris', description: 'Co-Founder'},
|
||||
// widgets: { name: (<WidgetComponent>), description: (WidgetComponent>)}
|
||||
// data: { title: 'Chris', description: 'Co-Founder'},
|
||||
// widgets: { title: (<WidgetComponent>), description: (WidgetComponent>)}
|
||||
// }]
|
||||
//
|
||||
// Templating would look something like this:
|
@ -1,7 +1,7 @@
|
||||
---
|
||||
group: Guides
|
||||
weight: 80
|
||||
title: Docusaurus
|
||||
weight: 80
|
||||
---
|
||||
This guide instructs you on how to integrate Static CMS with Docusaurus.
|
||||
|
||||
@ -115,7 +115,7 @@ tags:
|
||||
- foo
|
||||
- bar
|
||||
authors:
|
||||
- name: Garrison McMullen
|
||||
- title: Garrison McMullen
|
||||
title: Instruction Writer
|
||||
url: https://github.com/garrison0
|
||||
image_url: https://avatars.githubusercontent.com/u/4089393?v=4
|
||||
@ -175,7 +175,7 @@ touch index.html
|
||||
|
||||
```yaml
|
||||
backend:
|
||||
name: github
|
||||
title: github
|
||||
branch: main
|
||||
repo: <your-github>/my-website
|
||||
|
||||
@ -184,7 +184,7 @@ media_folder: "static/img" # Media files will be stored in the repo under static
|
||||
public_folder: "/img/" # The src attribute for uploaded media will begin with /images/uploads
|
||||
|
||||
collections:
|
||||
- name: blog
|
||||
- title: blog
|
||||
label: "blog"
|
||||
folder: blog
|
||||
identifier_field: title
|
||||
@ -193,20 +193,20 @@ collections:
|
||||
create: true
|
||||
slug: "{{year}}-{{month}}-{{day}}-{{slug}}" # Filename template, e.g., YYYY-MM-DD-title.md
|
||||
fields:
|
||||
- { name: title, label: Title, widget: string }
|
||||
- { name: body, label: Body, widget: markdown }
|
||||
- { name: slug, label: Slug, widget: string }
|
||||
- { title: title, label: Title, widget: string }
|
||||
- { title: body, label: Body, widget: markdown }
|
||||
- { title: slug, label: Slug, widget: string }
|
||||
- label: "Tags"
|
||||
name: "tags"
|
||||
title: "tags"
|
||||
widget: "list"
|
||||
- label: "Authors"
|
||||
name: "authors"
|
||||
title: "authors"
|
||||
widget: "list"
|
||||
fields:
|
||||
- { name: name, label: Name, widget: string }
|
||||
- { name: title, label: Title, widget: string }
|
||||
- { name: url, label: URL, widget: string }
|
||||
- { name: imageUrl, label: ImageURL, widget: string }
|
||||
- { title: name, label: Name, widget: string }
|
||||
- { title: title, label: Title, widget: string }
|
||||
- { title: url, label: URL, widget: string }
|
||||
- { title: imageUrl, label: ImageURL, widget: string }
|
||||
```
|
||||
|
||||
`config.yml` specifies what kind of content your blog posts have. The content specification enables Static CMS to edit existing posts and create new ones with the same format. To learn more, read about Static CMS' [](https://staticjscms.github.io/static-cms/docs/configuration-options/)[Configuration options](https://staticjscms.github.io/static-cms/docs/configuration-options/).
|
@ -1,7 +1,7 @@
|
||||
---
|
||||
group: Contributing
|
||||
weight: 110
|
||||
title: Examples
|
||||
weight: 110
|
||||
---
|
||||
|
||||
Do you have a great, open source example? Submit a pull request to this page!
|
@ -1,7 +1,7 @@
|
||||
---
|
||||
group: Accounts
|
||||
weight: 60
|
||||
title: External OAuth Clients
|
||||
weight: 60
|
||||
---
|
||||
If you would like to facilitate your own OAuth authentication rather than use Netlify's service or a client side flow like implicit or PKCE, you can use one of the community-maintained projects below. Feel free to hit the "Edit this page" button if you'd like to add yours!
|
||||
|
@ -1,6 +1,6 @@
|
||||
---
|
||||
title: Gatsby
|
||||
group: Guides
|
||||
title: Gatsby
|
||||
weight: 10
|
||||
---
|
||||
This guide will help you get started using Static CMS and Gatsby.
|
||||
@ -60,14 +60,14 @@ In your `config.yml` file paste the following configuration:
|
||||
|
||||
```yml
|
||||
backend:
|
||||
name: git-gateway
|
||||
title: git-gateway
|
||||
branch: main # Branch to update (optional; defaults to master)
|
||||
|
||||
media_folder: static/img
|
||||
public_folder: /img
|
||||
|
||||
collections:
|
||||
- name: 'blog'
|
||||
- title: 'blog'
|
||||
label: 'Blog'
|
||||
folder: 'content/blog'
|
||||
create: true
|
||||
@ -78,10 +78,10 @@ collections:
|
||||
editor:
|
||||
preview: false
|
||||
fields:
|
||||
- { label: 'Title', name: 'title', widget: 'string' }
|
||||
- { label: 'Publish Date', name: 'date', widget: 'datetime' }
|
||||
- { label: 'Description', name: 'description', widget: 'string' }
|
||||
- { label: 'Body', name: 'body', widget: 'markdown' }
|
||||
- { label: 'Title', title: 'title', widget: 'string' }
|
||||
- { label: 'Publish Date', title: 'date', widget: 'datetime' }
|
||||
- { label: 'Description', title: 'description', widget: 'string' }
|
||||
- { label: 'Body', title: 'body', widget: 'markdown' }
|
||||
```
|
||||
|
||||
**Note:** The above configuration allows assets to be stored relative to their content. Therefore posts would be stored in the format below as it is in `gatsby-starter-blog`.
|
@ -1,14 +1,14 @@
|
||||
---
|
||||
group: Accounts
|
||||
title: Git Gateway
|
||||
weight: 10
|
||||
group: Accounts
|
||||
---
|
||||
|
||||
[Git Gateway](https://github.com/netlify/git-gateway) is a Netlify open source project that allows you to add editors to your site CMS without giving them direct write access to your GitHub or GitLab repository. (For Bitbucket repositories, use the [Bitbucket backend](../bitbucket-backend/) instead.)
|
||||
[Git Gateway](https://github.com/netlify/git-gateway) is a Netlify open source project that allows you to add editors to your site CMS without giving them direct write access to your GitHub or GitLab repository. (For Bitbucket repositories, use the [Bitbucket backend](/docs/bitbucket-backend/) instead.)
|
||||
|
||||
## Git Gateway with Netlify
|
||||
|
||||
The [Netlify Identity](https://www.netlify.com/docs/identity/) service can handle the authentication and provides a simple interface for user management. The Static CMS [featured templates](../start-with-a-template) are working examples of this backend.
|
||||
The [Netlify Identity](https://www.netlify.com/docs/identity/) service can handle the authentication and provides a simple interface for user management. The Static CMS [featured templates](/docs/start-with-a-template) are working examples of this backend.
|
||||
|
||||
To use it in your own project stored on GitHub or GitLab, follow these steps:
|
||||
|
||||
@ -17,7 +17,7 @@ To use it in your own project stored on GitHub or GitLab, follow these steps:
|
||||
|
||||
```yaml
|
||||
backend:
|
||||
name: git-gateway
|
||||
title: git-gateway
|
||||
```
|
||||
|
||||
## Reconnect after Changing Repository Permissions
|
@ -1,7 +1,7 @@
|
||||
---
|
||||
title: GitHub
|
||||
group: Accounts
|
||||
weight: 30
|
||||
title: GitHub
|
||||
---
|
||||
For repositories stored on GitHub, the `github` backend allows CMS users to log in directly with their GitHub account. Note that all users must have push access to your content repository for this to work.
|
||||
|
||||
@ -14,7 +14,7 @@ To enable basic GitHub authentication:
|
||||
|
||||
```yaml
|
||||
backend:
|
||||
name: github
|
||||
title: github
|
||||
repo: owner-name/repo-name # Path to your GitHub repository
|
||||
# optional, defaults to master
|
||||
# branch: main
|
@ -1,6 +1,6 @@
|
||||
---
|
||||
title: GitLab
|
||||
group: Accounts
|
||||
title: GitLab
|
||||
weight: 40
|
||||
---
|
||||
For repositories stored on GitLab, the `gitlab` backend allows CMS users to log in directly with their GitLab account. Note that all users must have push access to your content repository for this to work.
|
||||
@ -11,7 +11,6 @@ The GitLab API allows for three types of OAuth2 flows:
|
||||
|
||||
* [Authorization Code Flow](https://docs.gitlab.com/ce/api/oauth2.html#authorization-code-flow), which works much like the GitHub OAuth flow described above.
|
||||
* [Authorization Code with PKCE Flow](https://docs.gitlab.com/ce/api/oauth2.html#authorization-code-with-proof-key-for-code-exchange-pkce), which operates *without* the need for an authentication server.
|
||||
* (DEPRECATED [Implicit Grant Flow](https://docs.gitlab.com/ce/api/oauth2.html#implicit-grant-flow), which operates *without* the need for an authentication server.
|
||||
|
||||
## Authorization Code Flow with Netlify
|
||||
|
||||
@ -25,7 +24,7 @@ To enable it:
|
||||
|
||||
```yaml
|
||||
backend:
|
||||
name: gitlab
|
||||
title: gitlab
|
||||
repo: owner-name/repo-name # Path to your GitLab repository
|
||||
```
|
||||
|
||||
@ -39,7 +38,7 @@ With GitLab's PKCE authorization, users can authenticate with GitLab directly fr
|
||||
|
||||
```yaml
|
||||
backend:
|
||||
name: gitlab
|
||||
title: gitlab
|
||||
repo: owner-name/repo-name # Path to your GitLab repository
|
||||
auth_type: pkce # Required for pkce
|
||||
app_id: your-app-id # Application ID from your GitLab settings
|
||||
@ -49,7 +48,7 @@ With GitLab's PKCE authorization, users can authenticate with GitLab directly fr
|
||||
|
||||
```yaml
|
||||
backend:
|
||||
name: gitlab
|
||||
title: gitlab
|
||||
repo: owner-name/repo-name # Path to your GitLab repository
|
||||
auth_type: pkce # Required for pkce
|
||||
app_id: your-app-id # Application ID from your GitLab settings
|
||||
@ -57,35 +56,3 @@ With GitLab's PKCE authorization, users can authenticate with GitLab directly fr
|
||||
base_url: https://my-hosted-gitlab-instance.com
|
||||
auth_endpoint: oauth/authorize
|
||||
```
|
||||
|
||||
## (DEPRECATED) Client-Side Implicit Grant
|
||||
|
||||
**Note:** This method is not recommended and will be deprecated both [by GitLab](https://gitlab.com/gitlab-org/gitlab/-/issues/288516) and [in the OAuth 2.1 specification](https://oauth.net/2.1/) in the future.
|
||||
|
||||
With GitLab's Implicit Grant, users can authenticate with GitLab directly from the client. To do this:
|
||||
|
||||
1. Follow the [GitLab docs](https://docs.gitlab.com/ee/integration/oauth_provider.html#adding-an-application-through-the-profile) to add your Static CMS instance as an OAuth application and uncheck the **Confidential** checkbox. For the **Redirect URI**, enter the address where you access Static CMS, for example, `https://www.mysite.com/admin/`. For scope, select `api`.
|
||||
2. GitLab gives you an **Application ID**. Copy this ID and enter it in your Static CMS `config.yml` file, along with the following settings:
|
||||
|
||||
```yaml
|
||||
backend:
|
||||
name: gitlab
|
||||
repo: owner-name/repo-name # Path to your GitLab repository
|
||||
auth_type: implicit # Required for implicit grant
|
||||
app_id: your-app-id # Application ID from your GitLab settings
|
||||
```
|
||||
|
||||
You can also use Implicit Grant with a self-hosted GitLab instance. This requires adding `api_root`, `base_url`, and `auth_endpoint` fields:
|
||||
|
||||
```yaml
|
||||
backend:
|
||||
name: gitlab
|
||||
repo: owner-name/repo-name # Path to your GitLab repository
|
||||
auth_type: implicit # Required for implicit grant
|
||||
app_id: your-app-id # Application ID from your GitLab settings
|
||||
api_root: https://my-hosted-gitlab-instance.com/api/v4
|
||||
base_url: https://my-hosted-gitlab-instance.com
|
||||
auth_endpoint: oauth/authorize
|
||||
```
|
||||
|
||||
**Note:** In all cases, GitLab also provides you with a client secret. You should *never* store this in your repo or reveal it in the client.
|
@ -1,7 +1,7 @@
|
||||
---
|
||||
group: Guides
|
||||
weight: 70
|
||||
title: Gridsome
|
||||
weight: 70
|
||||
---
|
||||
This guide will help you get started using Static CMS and Gridsome.
|
||||
|
||||
@ -44,12 +44,12 @@ Now that the plugins are installed, it's time to setup the configuration. Open t
|
||||
|
||||
```js
|
||||
module.exports = {
|
||||
siteName: 'Gridsome',
|
||||
sitetitle: 'Gridsome',
|
||||
transformers: {
|
||||
remark: {
|
||||
externalLinksTarget: '_blank',
|
||||
externalLinksRel: ['nofollow', 'noopener', 'noreferrer'],
|
||||
anchorClassName: 'icon icon-link'
|
||||
anchorClasstitle: 'icon icon-link'
|
||||
}
|
||||
},
|
||||
|
||||
@ -58,7 +58,7 @@ module.exports = {
|
||||
use: '@gridsome/source-filesystem',
|
||||
options: {
|
||||
path: 'posts/**/*.md',
|
||||
typeName: 'Post'
|
||||
typetitle: 'Post'
|
||||
}
|
||||
},
|
||||
{
|
||||
@ -105,23 +105,23 @@ Your `config.yml` for GitHub should look like this:
|
||||
|
||||
```yml
|
||||
backend:
|
||||
name: git-gateway
|
||||
title: git-gateway
|
||||
branch: main # Branch to update (optional; defaults to master)
|
||||
|
||||
media_folder: "static/uploads"
|
||||
public_folder: "/uploads"
|
||||
|
||||
collections:
|
||||
- name: "posts"
|
||||
- title: "posts"
|
||||
label: "Posts"
|
||||
folder: "posts"
|
||||
create: true
|
||||
slug: "{{slug}}"
|
||||
fields:
|
||||
- {label: "Title", name: "title", widget: "string"}
|
||||
- {label: "Excerpt", name: "excerpt", widget: "string"}
|
||||
- {label: "Publish Date", name: "date", widget: "datetime"}
|
||||
- {label: "Body", name: "body", widget: "markdown"}
|
||||
- {label: "Title", title: "title", widget: "string"}
|
||||
- {label: "Excerpt", title: "excerpt", widget: "string"}
|
||||
- {label: "Publish Date", title: "date", widget: "datetime"}
|
||||
- {label: "Body", title: "body", widget: "markdown"}
|
||||
```
|
||||
|
||||
## Push to GitHub
|
@ -1,6 +1,6 @@
|
||||
---
|
||||
title: Hugo
|
||||
group: Guides
|
||||
title: Hugo
|
||||
weight: 20
|
||||
---
|
||||
## Introduction
|
||||
@ -85,12 +85,12 @@ In the `config.yml` file, you can add this basic configuration — you can custo
|
||||
|
||||
```yaml
|
||||
backend:
|
||||
name: git-gateway
|
||||
title: git-gateway
|
||||
branch: main # Branch to update (optional; defaults to master)
|
||||
media_folder: static/img
|
||||
public_folder: /img
|
||||
collections:
|
||||
- name: 'blog'
|
||||
- title: 'blog'
|
||||
label: 'Blog'
|
||||
folder: 'content/blog'
|
||||
create: true
|
||||
@ -98,10 +98,10 @@ collections:
|
||||
editor:
|
||||
preview: false
|
||||
fields:
|
||||
- { label: 'Title', name: 'title', widget: 'string' }
|
||||
- { label: 'Publish Date', name: 'date', widget: 'datetime' }
|
||||
- { label: 'Description', name: 'description', widget: 'string' }
|
||||
- { label: 'Body', name: 'body', widget: 'markdown' }
|
||||
- { label: 'Title', title: 'title', widget: 'string' }
|
||||
- { label: 'Publish Date', title: 'date', widget: 'datetime' }
|
||||
- { label: 'Description', title: 'description', widget: 'string' }
|
||||
- { label: 'Body', title: 'body', widget: 'markdown' }
|
||||
```
|
||||
|
||||
**Note:** You won't be able to access the CMS just yet — you still need to deploy the project with **Netlify** and authenticate with **Netlify Identity**. You'll handle this in the next few steps of this guide.
|
||||
@ -213,12 +213,12 @@ CMS.registerEditorComponent({
|
||||
id: "gist",
|
||||
label: "Gist",
|
||||
fields: [{
|
||||
name: "username",
|
||||
title: "username",
|
||||
label: "Github Username",
|
||||
widget: "string"
|
||||
},
|
||||
{
|
||||
name: "gid",
|
||||
title: "gid",
|
||||
label: "Gist ID",
|
||||
widget: "string"
|
||||
},
|
||||
@ -226,7 +226,7 @@ CMS.registerEditorComponent({
|
||||
pattern: /^{{< gist ([a-zA-Z0-9]+) ([a-zA-Z0-9]+) >}}/,
|
||||
fromBlock: function(match) {
|
||||
return {
|
||||
username: match[1],
|
||||
usertitle: match[1],
|
||||
gid: match[2],
|
||||
};
|
||||
},
|
@ -1,6 +1,6 @@
|
||||
---
|
||||
title: Overview
|
||||
group: Intro
|
||||
title: Overview
|
||||
weight: 1
|
||||
---
|
||||
|
||||
@ -18,7 +18,7 @@ At its core, Static CMS is an open-source React app that acts as a wrapper for t
|
||||
### Find out more
|
||||
|
||||
- Get a feel for the UI in the [demo site](https://cms-demo.netlify.com). (No login required. Click the login button to go straight to the CMS editor UI.)
|
||||
- [Start with a template](../start-with-a-template/) to make a Static CMS-enabled site of your own.
|
||||
- Configure your existing site by following a [tutorial](../add-to-your-site/) or checking [configuration options](../configuration-options).
|
||||
- [Start with a template](/docs/start-with-a-template/) to make a Static CMS-enabled site of your own.
|
||||
- Configure your existing site by following a [tutorial](/docs/add-to-your-site/) or checking [configuration options](/docs/configuration-options).
|
||||
- Ask questions and share ideas in the Static CMS [community chat](https://staticjscms.github.io/static-cms/chat).
|
||||
- Get involved in new developments and become a [contributor](../contributor-guide/).
|
||||
- Get involved in new developments and become a [contributor](/docs/contributor-guide/).
|
@ -1,7 +1,7 @@
|
||||
---
|
||||
group: Guides
|
||||
weight: 30
|
||||
title: Jekyll
|
||||
weight: 30
|
||||
---
|
||||
## Introduction
|
||||
|
||||
@ -49,15 +49,15 @@ Create a file `admin/config.yml` in the root of your repo - it should look like
|
||||
# config.yml
|
||||
|
||||
backend:
|
||||
name: git-gateway
|
||||
title: git-gateway
|
||||
branch: main # Branch to update (optional; defaults to master)
|
||||
media_folder: 'assets/uploads'
|
||||
collections:
|
||||
- name: 'blog'
|
||||
- title: 'blog'
|
||||
label: 'Blog'
|
||||
folder: '_posts/'
|
||||
fields:
|
||||
- { name: Title }
|
||||
- { title: Title }
|
||||
```
|
||||
|
||||
### Enable authentication for CMS users
|
||||
@ -74,7 +74,7 @@ We'll start by updating the `blog` collection. Blogging is baked into Jekyll, an
|
||||
|
||||
```yaml
|
||||
collections:
|
||||
- name: 'blog'
|
||||
- title: 'blog'
|
||||
label: 'Blog'
|
||||
folder: '_posts/'
|
||||
create: true
|
||||
@ -82,10 +82,10 @@ collections:
|
||||
editor:
|
||||
preview: false
|
||||
fields:
|
||||
- { label: 'Layout', name: 'layout', widget: 'hidden', default: 'post' }
|
||||
- { label: 'Title', name: 'title', widget: 'string' }
|
||||
- { label: 'Publish Date', name: 'date', widget: 'datetime' }
|
||||
- { label: 'Body', name: 'body', widget: 'markdown' }
|
||||
- { label: 'Layout', title: 'layout', widget: 'hidden', default: 'post' }
|
||||
- { label: 'Title', title: 'title', widget: 'string' }
|
||||
- { label: 'Publish Date', title: 'date', widget: 'datetime' }
|
||||
- { label: 'Body', title: 'body', widget: 'markdown' }
|
||||
```
|
||||
|
||||
A few things to note.
|
||||
@ -104,16 +104,16 @@ A few things to note.
|
||||
In addition to `_posts`, the Jekyll tutorial blog includes a collection of authors in the `_authors` directory. Before we can configure Static CMS to work with the `authors` collection, we'll need to make a couple tweaks to our Jekyll blog. Here's the front matter for one of the authors.
|
||||
|
||||
```yaml
|
||||
short_name: jill
|
||||
name: Jill Smith
|
||||
short_title: jill
|
||||
title: Jill Smith
|
||||
position: Chief Editor
|
||||
```
|
||||
|
||||
`name` has special meaning as a unique identifier in Static CMS, but as set up now our Jekyll blog is using `short_name` as the unique identifier for authors. For each author, update the frontmatter like so.
|
||||
|
||||
```yaml
|
||||
name: jill
|
||||
display_name: Jill Smith
|
||||
title: jill
|
||||
display_title: Jill Smith
|
||||
position: Chief Editor
|
||||
```
|
||||
|
||||
@ -176,18 +176,18 @@ then update `_layouts/author.html`, `_layouts/post.html` and `staff.html` accord
|
||||
Next, copy and paste the following into the collections array in `config.yml` below the `blog` collection.
|
||||
|
||||
```yaml
|
||||
- name: 'authors'
|
||||
- title: 'authors'
|
||||
label: 'Authors'
|
||||
folder: '_authors/'
|
||||
create: true
|
||||
editor:
|
||||
preview: false
|
||||
fields:
|
||||
- { label: 'Layout', name: 'layout', widget: 'hidden', default: 'author' }
|
||||
- { label: 'Short Name', name: 'name', widget: 'string' }
|
||||
- { label: 'Display Name', name: 'display_name', widget: 'string' }
|
||||
- { label: 'Position', name: 'position', widget: 'string' }
|
||||
- { label: 'Body', name: 'body', widget: 'markdown' }
|
||||
- { label: 'Layout', title: 'layout', widget: 'hidden', default: 'author' }
|
||||
- { label: 'Short Name', title: 'name', widget: 'string' }
|
||||
- { label: 'Display Name', title: 'display_name', widget: 'string' }
|
||||
- { label: 'Position', title: 'position', widget: 'string' }
|
||||
- { label: 'Body', title: 'body', widget: 'markdown' }
|
||||
```
|
||||
|
||||
Now that we have the `authors` collection configured, we can add an `author` field to the `blog` collection. We'll use the [relation widget](https://staticjscms.github.io/static-cms/docs/widgets/#relation) to define the relationship between blog posts and authors.
|
||||
@ -195,19 +195,19 @@ Now that we have the `authors` collection configured, we can add an `author` fie
|
||||
```yaml
|
||||
# updated fields in blog collection configuration
|
||||
fields:
|
||||
- { label: 'Layout', name: 'layout', widget: 'hidden', default: 'post' }
|
||||
- { label: 'Title', name: 'title', widget: 'string' }
|
||||
- { label: 'Publish Date', name: 'date', widget: 'datetime' }
|
||||
- { label: 'Layout', title: 'layout', widget: 'hidden', default: 'post' }
|
||||
- { label: 'Title', title: 'title', widget: 'string' }
|
||||
- { label: 'Publish Date', title: 'date', widget: 'datetime' }
|
||||
- {
|
||||
label: 'Author',
|
||||
name: 'author',
|
||||
title: 'author',
|
||||
widget: 'relation',
|
||||
collection: 'authors',
|
||||
display_fields: [display_name],
|
||||
search_fields: [display_name],
|
||||
value_field: 'name',
|
||||
}
|
||||
- { label: 'Body', name: 'body', widget: 'markdown' }
|
||||
- { label: 'Body', title: 'body', widget: 'markdown' }
|
||||
```
|
||||
|
||||
With that configuration added, you should be able to select the author for a post from a dropdown.
|
||||
@ -219,18 +219,18 @@ Our Jekyll blog includes an About page. It would nice to be able to edit that pa
|
||||
Copy and paste the following into the collections array in `config.yml`
|
||||
|
||||
```yaml
|
||||
- name: 'pages'
|
||||
- title: 'pages'
|
||||
label: 'Pages'
|
||||
editor:
|
||||
preview: false
|
||||
files:
|
||||
- label: 'About Page'
|
||||
name: 'about'
|
||||
title: 'about'
|
||||
file: 'about.md'
|
||||
fields:
|
||||
- { label: 'Title', name: 'title', widget: 'hidden', default: 'about' }
|
||||
- { label: 'Layout', name: 'layout', widget: 'hidden', default: 'about' }
|
||||
- { label: 'Body', name: 'body', widget: 'markdown' }
|
||||
- { label: 'Title', title: 'title', widget: 'hidden', default: 'about' }
|
||||
- { label: 'Layout', title: 'layout', widget: 'hidden', default: 'about' }
|
||||
- { label: 'Body', title: 'body', widget: 'markdown' }
|
||||
```
|
||||
|
||||
### Navigation
|
||||
@ -239,13 +239,13 @@ The last aspect of our Jekyll blog we might want to bring under the control of S
|
||||
|
||||
```yaml
|
||||
# _data/navigation.yml
|
||||
- name: Home
|
||||
- title: Home
|
||||
link: /
|
||||
- name: About
|
||||
- title: About
|
||||
link: /about.html
|
||||
- name: Blog
|
||||
- title: Blog
|
||||
link: /blog.html
|
||||
- name: Staff
|
||||
- title: Staff
|
||||
link: /staff.html
|
||||
```
|
||||
|
||||
@ -254,13 +254,13 @@ To make this file editable with Static CMS, we'll need to make one minor tweak.
|
||||
```yaml
|
||||
# _data/navigation.yml
|
||||
items:
|
||||
- name: Home
|
||||
- title: Home
|
||||
link: /
|
||||
- name: About
|
||||
- title: About
|
||||
link: /about.html
|
||||
- name: Blog
|
||||
- title: Blog
|
||||
link: /blog.html
|
||||
- name: Staff
|
||||
- title: Staff
|
||||
link: /staff.html
|
||||
```
|
||||
|
||||
@ -279,21 +279,21 @@ You'll need to update `_includes/navigation.html` accordingly. `{% for item in s
|
||||
Finally, add the following to the collections array in `config.yml`
|
||||
|
||||
```yaml
|
||||
- name: 'config'
|
||||
- title: 'config'
|
||||
label: 'Config'
|
||||
editor:
|
||||
preview: false
|
||||
files:
|
||||
- label: 'Navigation'
|
||||
name: 'navigation'
|
||||
title: 'navigation'
|
||||
file: '_data/navigation.yml'
|
||||
fields:
|
||||
- label: 'Navigation Items'
|
||||
name: 'items'
|
||||
title: 'items'
|
||||
widget: 'list'
|
||||
fields:
|
||||
- { label: Name, name: name, widget: string }
|
||||
- { label: Link, name: link, widget: string }
|
||||
- { label: Name, title: name, widget: string }
|
||||
- { label: Link, title: link, widget: string }
|
||||
```
|
||||
|
||||
Now you can add, rename, and rearrange the navigation items on your blog.
|
@ -1,6 +1,6 @@
|
||||
---
|
||||
title: Middleman
|
||||
group: Guides
|
||||
title: Middleman
|
||||
weight: 60
|
||||
---
|
||||
This guide will help you get started using Static CMS and Middleman.
|
||||
@ -127,14 +127,14 @@ For the purpose of this guide we will deploy to Netlify from a GitHub repository
|
||||
|
||||
```yml
|
||||
backend:
|
||||
name: git-gateway
|
||||
title: git-gateway
|
||||
branch: main # Branch to update (optional; defaults to master)
|
||||
|
||||
media_folder: source/images/uploads
|
||||
public_folder: /images/uploads
|
||||
|
||||
collections:
|
||||
- name: blog
|
||||
- title: blog
|
||||
label: Blog
|
||||
folder: source/posts/
|
||||
extension: .html.md
|
||||
@ -142,9 +142,9 @@ collections:
|
||||
create: true
|
||||
slug: '{{year}}-{{month}}-{{day}}-{{title}}'
|
||||
fields:
|
||||
- {label: Title, name: title, widget: string}
|
||||
- {label: Publish Date, name: date, widget: datetime}
|
||||
- {label: Body, name: body, widget: markdown}
|
||||
- {label: Title, title: title, widget: string}
|
||||
- {label: Publish Date, title: date, widget: datetime}
|
||||
- {label: Body, title: body, widget: markdown}
|
||||
```
|
||||
|
||||
### Push to GitHub
|
@ -1,6 +1,6 @@
|
||||
---
|
||||
title: Netlify Large Media
|
||||
group: Media
|
||||
title: Netlify Large Media
|
||||
weight: 20
|
||||
---
|
||||
|
||||
@ -34,7 +34,7 @@ You can disable the automatic image transformations with the `use_large_media_tr
|
||||
|
||||
```yaml
|
||||
backend:
|
||||
name: git-gateway
|
||||
title: git-gateway
|
||||
## Set to false to prevent transforming images in media gallery view
|
||||
use_large_media_transforms_in_media_library: false
|
||||
```
|
@ -1,7 +1,7 @@
|
||||
---
|
||||
group: Guides
|
||||
weight: 40
|
||||
title: NextJS
|
||||
weight: 40
|
||||
---
|
||||
This guide will help you get started using Static CMS with NextJS.
|
||||
|
||||
@ -61,11 +61,11 @@ title: Awesome kitties
|
||||
date: 2019-03-17T19:31:20.591Z
|
||||
cats:
|
||||
- description: 'Maru is a Scottish Fold from Japan, and he loves boxes.'
|
||||
name: Maru (まる)
|
||||
title: Maru (まる)
|
||||
- description: Lil Bub is an American celebrity cat known for her unique appearance.
|
||||
name: Lil Bub
|
||||
title: Lil Bub
|
||||
- description: 'Grumpy cat is an American celebrity cat known for her grumpy appearance.'
|
||||
name: Grumpy cat (Tardar Sauce)
|
||||
title: Grumpy cat (Tardar Sauce)
|
||||
---
|
||||
Welcome to my awesome page about cats of the internet.
|
||||
|
||||
@ -94,7 +94,7 @@ Almost there! The last thing we need to do is to add some content to our `pages/
|
||||
```js
|
||||
import Head from "next/head"
|
||||
import { Component } from 'react'
|
||||
import { attributes, react as HomeContent } from '../content/home.md';
|
||||
import { attributes, react as HomeContent } from '/docs/content/home.md';
|
||||
|
||||
export default class Home extends Component {
|
||||
render() {
|
||||
@ -166,27 +166,27 @@ Paste the following configuration into your `public/admin/config.yml` file:
|
||||
|
||||
```yaml
|
||||
backend:
|
||||
name: git-gateway
|
||||
title: git-gateway
|
||||
branch: main # Branch to update (optional; defaults to master)
|
||||
media_folder: public/img
|
||||
public_folder: img
|
||||
collections:
|
||||
- name: "pages"
|
||||
- title: "pages"
|
||||
label: "Pages"
|
||||
files:
|
||||
- label: "Home"
|
||||
name: "home"
|
||||
title: "home"
|
||||
file: "content/home.md"
|
||||
fields:
|
||||
- { label: "Title", name: "title", widget: "string"}
|
||||
- { label: "Publish Date", name: "date", widget: "datetime" }
|
||||
- { label: "Body", name: "body", widget: "markdown"}
|
||||
- { label: "Title", title: "title", widget: "string"}
|
||||
- { label: "Publish Date", title: "date", widget: "datetime" }
|
||||
- { label: "Body", title: "body", widget: "markdown"}
|
||||
- label: 'Cats'
|
||||
name: "cats"
|
||||
title: "cats"
|
||||
widget: list
|
||||
fields:
|
||||
- { label: "Name", name: "name", widget: "string"}
|
||||
- { label: "Description", name: "description", widget: "text"}
|
||||
- { label: "Name", title: "name", widget: "string"}
|
||||
- { label: "Description", title: "description", widget: "text"}
|
||||
```
|
||||
|
||||
Awesome! Static CMS should now be available at `localhost:3000/admin/index.html`. Unfortunately we can't edit our content just yet. First we need to move our code into a git repository, and create a new Netlify site.
|
||||
@ -227,7 +227,7 @@ Netlify's Identity and Git Gateway services allow you to manage CMS admin users
|
||||
|
||||
### Celebrate!
|
||||
|
||||
Great job - you did it! Open your new page via the new Netlify URL, and navigate to `/admin`. If you did everything correct in the previous step, you should now be able to sign up for an account, and log in.
|
||||
Great job - you did it! Open your new page via the new Netlify URL, and navigate to `/admin`. If you did everything correct in the previous step, you should now be able to sign up for an account, and log in.
|
||||
|
||||
**Tip:** Signing up with an external provider is the easiest. If you want to sign up by email, you'll have to set up a redirect in your index.js page (which we won't be covering in this guide). For more information, have a look at the [Add To Your Site](https://staticjscms.github.io/static-cms/docs/add-to-your-site) section.
|
||||
|
@ -1,7 +1,7 @@
|
||||
---
|
||||
group: Guides
|
||||
weight: 50
|
||||
title: Nuxt
|
||||
weight: 50
|
||||
---
|
||||
This guide will walk you through how to integrate Static CMS with Nuxt.
|
||||
|
||||
@ -42,14 +42,14 @@ For your `static/admin/config.yml` file, you can put in a basic starter config:
|
||||
|
||||
```yaml
|
||||
backend:
|
||||
name: git-gateway
|
||||
title: git-gateway
|
||||
branch: main # Branch to update (optional; defaults to master)
|
||||
|
||||
media_folder: static/img
|
||||
public_folder: /img
|
||||
|
||||
collections:
|
||||
- name: 'blog'
|
||||
- title: 'blog'
|
||||
label: 'Blog'
|
||||
folder: 'content/blog'
|
||||
format: 'frontmatter'
|
||||
@ -58,10 +58,10 @@ collections:
|
||||
editor:
|
||||
preview: false
|
||||
fields:
|
||||
- { label: 'Title', name: 'title', widget: 'string' }
|
||||
- { label: 'Publish Date', name: 'date', widget: 'datetime' }
|
||||
- { label: 'Description', name: 'description', widget: 'string' }
|
||||
- { label: 'Body', name: 'body', widget: 'markdown' }
|
||||
- { label: 'Title', title: 'title', widget: 'string' }
|
||||
- { label: 'Publish Date', title: 'date', widget: 'datetime' }
|
||||
- { label: 'Description', title: 'description', widget: 'string' }
|
||||
- { label: 'Body', title: 'body', widget: 'markdown' }
|
||||
```
|
||||
|
||||
You can build whatever collections and content modeling you want. The important thing to note is the `format: 'frontmatter'` value on each collection. This is important for consuming content in Nuxt with the [nuxt/content](https://content.nuxtjs.org) module.
|
@ -1,6 +1,6 @@
|
||||
---
|
||||
title: Releases
|
||||
group: Intro
|
||||
title: Releases
|
||||
weight: 4
|
||||
---
|
||||
|
@ -1,6 +1,6 @@
|
||||
---
|
||||
title: Overview
|
||||
group: Guides
|
||||
title: Overview
|
||||
weight: 1
|
||||
---
|
||||
|
@ -1,85 +0,0 @@
|
||||
---
|
||||
group: Intro
|
||||
weight: 2
|
||||
title: Start with a Template
|
||||
---
|
||||
You can add Static CMS [to an existing site](/docs/add-to-your-site/), but the quickest way to get started is with a template. Found below, our featured templates deploy a bare-bones site and Static CMS to Netlify, giving you a fully working CMS-enabled site with just a few clicks.
|
||||
|
||||
<div style="display: flex; justify-content: left; text-align: center; margin-bottom: 1.5em; flex-wrap: wrap;"stack=cms>
|
||||
<div style="flex-basis: 33%">
|
||||
<div style="padding: 0 15%; height: 100px; display: flex; justify-content: center;">
|
||||
<img style="display: flex" src="/img/hugo.svg"/>
|
||||
</div>
|
||||
<h4>Hugo Site Starter</h4>
|
||||
<p><a href="https://app.netlify.com/start/deploy?repository=https://github.com/netlify-templates/one-click-hugo-cms&stack=cms"><img src="https://www.netlify.com/img/deploy/button.svg" alt="Deploy to Netlify" /></a></p>
|
||||
</div>
|
||||
<div style="flex-basis: 33%">
|
||||
<div style="padding: 0 30%; height: 100px; display: flex; justify-content: center;">
|
||||
<img style="display: flex" src="/img/gatsby.svg"/>
|
||||
</div>
|
||||
<h4>Gatsby Site Starter</h4>
|
||||
<p><a href="https://app.netlify.com/start/deploy?repository=https://github.com/AustinGreen/gatsby-starter-netlify-cms&stack=cms"><img src="https://www.netlify.com/img/deploy/button.svg" alt="Deploy to Netlify" /></a></p>
|
||||
</div>
|
||||
<div style="flex-basis: 33%">
|
||||
<div style="padding: 0 30%; height: 100px; display: flex; justify-content: center;">
|
||||
<img style="display: flex" src="/img/middleman.svg"/>
|
||||
</div>
|
||||
<h4>Middleman Site Starter</h4>
|
||||
<p><a href="https://app.netlify.com/start/deploy?repository=https://github.com/tomrutgers/middleman-starter-netlify-cms&stack=cms"><img src="https://www.netlify.com/img/deploy/button.svg" alt="Deploy to Netlify" /></a></p>
|
||||
</div>
|
||||
<div style="flex-basis: 33%">
|
||||
<div style="padding: 0 30%; height: 100px; display: flex; justify-content: center;">
|
||||
<img style="display: flex" src="/img/preact.svg"/>
|
||||
</div>
|
||||
<h4>Preact CLI</h4>
|
||||
<p><a href="https://app.netlify.com/start/deploy?repository=https://github.com/preactjs/preact-netlify&stack=cms"><img src="https://www.netlify.com/img/deploy/button.svg" alt="Deploy to Netlify" /></a></p>
|
||||
</div>
|
||||
<div style="flex-basis: 33%">
|
||||
<div style="padding: 0 30%; height: 100px; display: flex; justify-content: center;">
|
||||
<img style="display: flex" src="/img/nextjs.svg"/>
|
||||
</div>
|
||||
<h4>Next.js Blog Template</h4>
|
||||
<p><a href="https://app.netlify.com/start/deploy?repository=https://github.com/wutali/nextjs-netlify-blog-template&stack=cms"><img src="https://www.netlify.com/img/deploy/button.svg" alt="Deploy to Netlify" /></a></p>
|
||||
</div>
|
||||
<div style="flex-basis: 33%">
|
||||
<div style="padding: 0 30%; height: 100px; display: flex; justify-content: center;">
|
||||
<a href="https://github.com/surjithctly/neat-starter"> <img style="display: flex" src="/img/11ty-logo.svg"/> </a>
|
||||
</div>
|
||||
<h4>Eleventy Starter</h4>
|
||||
<p><a href="https://app.netlify.com/start/deploy?repository=https://github.com/surjithctly/neat-starter&stack=cms"><img src="https://www.netlify.com/img/deploy/button.svg" alt="Deploy to Netlify" /></a></p>
|
||||
</div>
|
||||
<div style="flex-basis: 33%">
|
||||
<div style="padding: 0 30%; height: 100px; display: flex; justify-content: center;">
|
||||
<img style="display: flex" src="/img/nuxt.svg"/>
|
||||
</div>
|
||||
<h4>Nuxt.js Boilerplate</h4>
|
||||
<p><a href="https://app.netlify.com/start/deploy?repository=https://github.com/Knogobert/ntn-boilerplate&stack=cms"><img src="https://www.netlify.com/img/deploy/button.svg" alt="Deploy to Netlify" /></a></p>
|
||||
</div>
|
||||
<div style="flex-basis: 33%">
|
||||
<div style="padding: 0 30%; height: 100px; display: flex; justify-content: center;">
|
||||
<img style="display: flex" src="/img/metalsmith.svg"/>
|
||||
</div>
|
||||
<h4>Metalsmith Starter</h4>
|
||||
<p><a href="https://app.netlify.com/start/deploy?repository=https://github.com/wernerglinka/metalsmith-netlify-starter"><img src="https://www.netlify.com/img/deploy/button.svg" alt="Deploy to Netlify" /></a></p>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
After clicking one of those buttons, authenticate with GitHub or GitLab and choose a repository name. Netlify then automatically creates a clone of the repository in your GitHub or GitLab account. Next, it builds and deploys the new site on Netlify, bringing you to the site dashboard after completing the build.
|
||||
|
||||
**Note for Bitbucket users:** Static CMS supports Bitbucket repositories, but Bitbucket's permissions won't work with the Deploy to Netlify buttons above. You can still set up a repository manually, or follow the [tutorial](/docs/add-to-your-site) for adding Static CMS to an existing site.
|
||||
|
||||
## Access Static CMS on your new site
|
||||
|
||||
1. The template deploy process sends you an invitation to your new site, sent from `no-reply@netlify.com`.
|
||||

|
||||
2. Wait for the deployment to complete, then click the link to accept the invite. Your site will open with a prompt to create a password.
|
||||

|
||||
3. Enter a password, sign in, and you’ll go to the CMS. (For future visits, you can go straight to `<yoursiteaddress.com>/admin/`.)
|
||||
|
||||
Try adding and editing posts, or changing the content of the Products page. When you save, the changes are pushed immediately to your Git repository, triggering a build on Netlify, and updating the content on your site. Check out the configuration code by visiting your site repo.
|
||||
|
||||
## More paths to explore
|
||||
|
||||
* To see how to integrate Static CMS into an existing project, go to [Add to your site](/docs/add-to-your-site/).
|
||||
* Check out other sites using Static CMS (or share your own!) on the [Examples](/docs/examples/) page.
|
||||
* If you’d like to add more CMS editors or change how they log in to your site, read up on [Netlify Identity service](https://www.netlify.com/docs/identity).
|
248
website/content/docs/start-with-a-template.mdx
Normal file
@ -0,0 +1,248 @@
|
||||
---
|
||||
group: Intro
|
||||
title: Start with a Template
|
||||
weight: 2
|
||||
---
|
||||
|
||||
You can add Static CMS [to an existing site](/docs/add-to-your-site/), but the quickest way to get started is with a template. Found below, our featured templates deploy a bare-bones site and Static CMS to Netlify, giving you a fully working CMS-enabled site with just a few clicks.
|
||||
|
||||
{' '}
|
||||
|
||||
<div style={{ display: 'grid', gridTemplateColumns: 'repeat(3, minmax(0, 1fr))', gap: '24px' }}>
|
||||
<div
|
||||
style={{
|
||||
display: 'flex',
|
||||
flexDirection: 'column',
|
||||
justifyContent: 'center',
|
||||
alignItems: 'center',
|
||||
gap: '8px',
|
||||
}}
|
||||
>
|
||||
<div
|
||||
style={{
|
||||
width: '120px',
|
||||
height: '120px',
|
||||
display: 'flex',
|
||||
justifyContent: 'center',
|
||||
alignItems: 'center',
|
||||
}}
|
||||
>
|
||||
<img style={{ display: 'flex', height: '100%' }} src="/img/hugo.svg" />
|
||||
</div>
|
||||
<h5 style={{ margin: 0 }}>Hugo Site Starter</h5>
|
||||
<p style={{ margin: 0 }}>
|
||||
<a href="https://app.netlify.com/start/deploy?repository=https://github.com/netlify-templates/one-click-hugo-cms&stack=cms">
|
||||
<img src="https://www.netlify.com/img/deploy/button.svg" alt="Deploy to Netlify" />
|
||||
</a>
|
||||
</p>
|
||||
</div>
|
||||
<div
|
||||
style={{
|
||||
display: 'flex',
|
||||
flexDirection: 'column',
|
||||
justifyContent: 'center',
|
||||
alignItems: 'center',
|
||||
gap: '8px',
|
||||
}}
|
||||
>
|
||||
<div
|
||||
style={{
|
||||
width: '120px',
|
||||
height: '120px',
|
||||
display: 'flex',
|
||||
justifyContent: 'center',
|
||||
alignItems: 'center',
|
||||
}}
|
||||
>
|
||||
<img style={{ display: 'flex', height: '100%' }} src="/img/gatsby.svg" />
|
||||
</div>
|
||||
<h5 style={{ margin: 0 }}>Gatsby Site Starter</h5>
|
||||
<p style={{ margin: 0 }}>
|
||||
<a href="https://app.netlify.com/start/deploy?repository=https://github.com/AustinGreen/gatsby-starter-netlify-cms&stack=cms">
|
||||
<img src="https://www.netlify.com/img/deploy/button.svg" alt="Deploy to Netlify" />
|
||||
</a>
|
||||
</p>
|
||||
</div>
|
||||
<div
|
||||
style={{
|
||||
display: 'flex',
|
||||
flexDirection: 'column',
|
||||
justifyContent: 'center',
|
||||
alignItems: 'center',
|
||||
gap: '8px',
|
||||
}}
|
||||
>
|
||||
<div
|
||||
style={{
|
||||
width: '120px',
|
||||
height: '120px',
|
||||
display: 'flex',
|
||||
justifyContent: 'center',
|
||||
alignItems: 'center',
|
||||
}}
|
||||
>
|
||||
<img style={{ display: 'flex', height: '100%' }} src="/img/middleman.svg" />
|
||||
</div>
|
||||
<h5 style={{ margin: 0 }}>Middleman Site Starter</h5>
|
||||
<p style={{ margin: 0 }}>
|
||||
<a href="https://app.netlify.com/start/deploy?repository=https://github.com/tomrutgers/middleman-starter-netlify-cms&stack=cms">
|
||||
<img src="https://www.netlify.com/img/deploy/button.svg" alt="Deploy to Netlify" />
|
||||
</a>
|
||||
</p>
|
||||
</div>
|
||||
<div
|
||||
style={{
|
||||
display: 'flex',
|
||||
flexDirection: 'column',
|
||||
justifyContent: 'center',
|
||||
alignItems: 'center',
|
||||
gap: '8px',
|
||||
}}
|
||||
>
|
||||
<div
|
||||
style={{
|
||||
width: '120px',
|
||||
height: '120px',
|
||||
display: 'flex',
|
||||
justifyContent: 'center',
|
||||
alignItems: 'center',
|
||||
}}
|
||||
>
|
||||
<img style={{ display: 'flex', height: '100%' }} src="/img/preact.svg" />
|
||||
</div>
|
||||
<h5 style={{ margin: 0 }}>Preact CLI</h5>
|
||||
<p style={{ margin: 0 }}>
|
||||
<a href="https://app.netlify.com/start/deploy?repository=https://github.com/preactjs/preact-netlify&stack=cms">
|
||||
<img src="https://www.netlify.com/img/deploy/button.svg" alt="Deploy to Netlify" />
|
||||
</a>
|
||||
</p>
|
||||
</div>
|
||||
<div
|
||||
style={{
|
||||
display: 'flex',
|
||||
flexDirection: 'column',
|
||||
justifyContent: 'center',
|
||||
alignItems: 'center',
|
||||
gap: '8px',
|
||||
}}
|
||||
>
|
||||
<div
|
||||
style={{
|
||||
width: '120px',
|
||||
height: '120px',
|
||||
display: 'flex',
|
||||
justifyContent: 'center',
|
||||
alignItems: 'center',
|
||||
}}
|
||||
>
|
||||
<img style={{ display: 'flex', height: '100%' }} src="/img/nextjs.svg" />
|
||||
</div>
|
||||
<h5 style={{ margin: 0 }}>Next.js Blog Template</h5>
|
||||
<p style={{ margin: 0 }}>
|
||||
<a href="https://app.netlify.com/start/deploy?repository=https://github.com/wutali/nextjs-netlify-blog-template&stack=cms">
|
||||
<img src="https://www.netlify.com/img/deploy/button.svg" alt="Deploy to Netlify" />
|
||||
</a>
|
||||
</p>
|
||||
</div>
|
||||
<div
|
||||
style={{
|
||||
display: 'flex',
|
||||
flexDirection: 'column',
|
||||
justifyContent: 'center',
|
||||
alignItems: 'center',
|
||||
gap: '8px',
|
||||
}}
|
||||
>
|
||||
<div
|
||||
style={{
|
||||
width: '120px',
|
||||
height: '120px',
|
||||
display: 'flex',
|
||||
justifyContent: 'center',
|
||||
alignItems: 'center',
|
||||
}}
|
||||
>
|
||||
<img style={{ display: 'flex', height: '100%' }} src="/img/11ty-logo.svg" />
|
||||
</div>
|
||||
<h5 style={{ margin: 0 }}>Eleventy Starter</h5>
|
||||
<p style={{ margin: 0 }}>
|
||||
<a href="https://app.netlify.com/start/deploy?repository=https://github.com/surjithctly/neat-starter&stack=cms">
|
||||
<img src="https://www.netlify.com/img/deploy/button.svg" alt="Deploy to Netlify" />
|
||||
</a>
|
||||
</p>
|
||||
</div>
|
||||
<div
|
||||
style={{
|
||||
display: 'flex',
|
||||
flexDirection: 'column',
|
||||
justifyContent: 'center',
|
||||
alignItems: 'center',
|
||||
gap: '8px',
|
||||
}}
|
||||
>
|
||||
<div
|
||||
style={{
|
||||
width: '120px',
|
||||
height: '120px',
|
||||
display: 'flex',
|
||||
justifyContent: 'center',
|
||||
alignItems: 'center',
|
||||
}}
|
||||
>
|
||||
<img style={{ display: 'flex', height: '100%' }} src="/img/nuxt.svg" />
|
||||
</div>
|
||||
<h5 style={{ margin: 0 }}>Nuxt.js Boilerplate</h5>
|
||||
<p style={{ margin: 0 }}>
|
||||
<a href="https://app.netlify.com/start/deploy?repository=https://github.com/Knogobert/ntn-boilerplate&stack=cms">
|
||||
<img src="https://www.netlify.com/img/deploy/button.svg" alt="Deploy to Netlify" />
|
||||
</a>
|
||||
</p>
|
||||
</div>
|
||||
<div
|
||||
style={{
|
||||
display: 'flex',
|
||||
flexDirection: 'column',
|
||||
justifyContent: 'center',
|
||||
alignItems: 'center',
|
||||
gap: '8px',
|
||||
}}
|
||||
>
|
||||
<div
|
||||
style={{
|
||||
width: '120px',
|
||||
height: '120px',
|
||||
display: 'flex',
|
||||
justifyContent: 'center',
|
||||
alignItems: 'center',
|
||||
}}
|
||||
>
|
||||
<img style={{ display: 'flex', height: '100%' }} src="/img/metalsmith.svg" />
|
||||
</div>
|
||||
<h5 style={{ margin: 0 }}>Metalsmith Starter</h5>
|
||||
<p style={{ margin: 0 }}>
|
||||
<a href="https://app.netlify.com/start/deploy?repository=https://github.com/wernerglinka/metalsmith-netlify-starter">
|
||||
<img src="https://www.netlify.com/img/deploy/button.svg" alt="Deploy to Netlify" />
|
||||
</a>
|
||||
</p>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
After clicking one of those buttons, authenticate with GitHub or GitLab and choose a repository name. Netlify then automatically creates a clone of the repository in your GitHub or GitLab account. Next, it builds and deploys the new site on Netlify, bringing you to the site dashboard after completing the build.
|
||||
|
||||
**Note for Bitbucket users:** Static CMS supports Bitbucket repositories, but Bitbucket's permissions won't work with the Deploy to Netlify buttons above. You can still set up a repository manually, or follow the [tutorial](/docs/add-to-your-site) for adding Static CMS to an existing site.
|
||||
|
||||
## Access Static CMS on your new site
|
||||
|
||||
1. The template deploy process sends you an invitation to your new site, sent from `no-reply@netlify.com`.
|
||||

|
||||
2. Wait for the deployment to complete, then click the link to accept the invite. Your site will open with a prompt to create a password.
|
||||

|
||||
3. Enter a password, sign in, and you’ll go to the CMS. (For future visits, you can go straight to `<yoursiteaddress.com>/admin/`.)
|
||||
|
||||
Try adding and editing posts, or changing the content of the Products page. When you save, the changes are pushed immediately to your Git repository, triggering a build on Netlify, and updating the content on your site. Check out the configuration code by visiting your site repo.
|
||||
|
||||
## More paths to explore
|
||||
|
||||
- To see how to integrate Static CMS into an existing project, go to [Add to your site](/docs/add-to-your-site/).
|
||||
- Check out other sites using Static CMS (or share your own!) on the [Examples](/docs/examples/) page.
|
||||
- If you’d like to add more CMS editors or change how they log in to your site, read up on [Netlify Identity service](https://www.netlify.com/docs/identity).
|
@ -1,6 +1,6 @@
|
||||
---
|
||||
title: Test
|
||||
group: Accounts
|
||||
title: Test
|
||||
weight: 50
|
||||
---
|
||||
|
||||
@ -12,5 +12,5 @@ To enable this backend, add the following lines to your Static CMS `config.yml`
|
||||
|
||||
```yaml
|
||||
backend:
|
||||
name: test-repo
|
||||
title: test-repo
|
||||
```
|
@ -1,6 +1,6 @@
|
||||
---
|
||||
title: Uploadcare
|
||||
group: Media
|
||||
title: Uploadcare
|
||||
weight: 30
|
||||
---
|
||||
Uploadcare is a sleek service that allows you to upload files without worrying about maintaining a growing collection — more of an asset store than a library. Just upload when you need to, and the files are hosted on their CDN. They provide image processing controls from simple cropping and rotation to filters and face detection, and a lot more. You can check out Uploadcare's full feature set on their [website](https://uploadcare.com/).
|
||||
@ -25,7 +25,7 @@ Your `config.yml` should now include something like this (except with a real API
|
||||
|
||||
```yaml
|
||||
media_library:
|
||||
name: uploadcare
|
||||
title: uploadcare
|
||||
config:
|
||||
publicKey: YOUR_UPLOADCARE_PUBLIC_KEY
|
||||
```
|
||||
@ -51,7 +51,7 @@ Configuration can also be provided for individual fields that use the media libr
|
||||
```yaml
|
||||
...
|
||||
fields:
|
||||
name: cover
|
||||
title: cover
|
||||
label: Cover Image
|
||||
widget: image
|
||||
media_library:
|
||||
@ -69,10 +69,10 @@ There are several settings that control the behavior of integration with the wid
|
||||
|
||||
```yaml
|
||||
media_library:
|
||||
name: uploadcare
|
||||
title: uploadcare
|
||||
config:
|
||||
publicKey: YOUR_UPLOADCARE_PUBLIC_KEY
|
||||
settings:
|
||||
autoFilename: true
|
||||
autoFiletitle: true
|
||||
defaultOperations: '/resize/800x600/'
|
||||
```
|
@ -1,6 +1,7 @@
|
||||
---
|
||||
title: boolean
|
||||
label: "Boolean"
|
||||
group: Widgets
|
||||
title: Boolean
|
||||
weight: 10
|
||||
---
|
||||
|
||||
The boolean widget translates a toggle switch input to a true/false value.
|
||||
@ -12,5 +13,5 @@ The boolean widget translates a toggle switch input to a true/false value.
|
||||
- `default`: accepts `true` or `false`; defaults to `false` when `required` is set to `false`
|
||||
- **Example:**
|
||||
```yaml
|
||||
- {label: "Draft", name: "draft", widget: "boolean", default: true}
|
||||
- {label: "Draft", title: "draft", widget: "boolean", default: true}
|
||||
```
|
@ -1,6 +1,7 @@
|
||||
---
|
||||
title: code
|
||||
label: 'Code'
|
||||
group: Widgets
|
||||
title: Code
|
||||
weight: 11
|
||||
---
|
||||
|
||||
The code widget provides a code editor (powered by [Codemirror](https://codemirror.net)) with optional syntax awareness. Can output the raw code value or an object with the selected language and the raw code value.
|
||||
@ -17,6 +18,6 @@ The code widget provides a code editor (powered by [Codemirror](https://codemirr
|
||||
- **Example:**
|
||||
```yaml
|
||||
- label: 'Code'
|
||||
name: 'code'
|
||||
title: 'code'
|
||||
widget: 'code'
|
||||
```
|
@ -1,6 +1,7 @@
|
||||
---
|
||||
label: 'Color'
|
||||
title: color
|
||||
group: Widgets
|
||||
title: Color
|
||||
weight: 12
|
||||
---
|
||||
|
||||
The color widget translates a color picker to a color string.
|
||||
@ -14,9 +15,9 @@ The color widget translates a color picker to a color string.
|
||||
- `enable_alpha`: accepts a boolean, defaults to `false`. Enables Alpha editing
|
||||
- **Example:**
|
||||
```yaml
|
||||
- { label: 'Color', name: 'color', widget: 'color' }
|
||||
- { label: 'Color', title: 'color', widget: 'color' }
|
||||
```
|
||||
- **Example:**
|
||||
```yaml
|
||||
- { label: 'Color', name: 'color', widget: 'color', enable_alpha: true, allow_input: true }
|
||||
- { label: 'Color', title: 'color', widget: 'color', enable_alpha: true, allow_input: true }
|
||||
```
|
@ -1,6 +1,7 @@
|
||||
---
|
||||
title: datetime
|
||||
label: "DateTime"
|
||||
group: Widgets
|
||||
title: DateTime
|
||||
weight: 13
|
||||
---
|
||||
|
||||
The datetime widget translates a datetime picker to a datetime string.
|
||||
@ -17,7 +18,7 @@ The datetime widget translates a datetime picker to a datetime string.
|
||||
- **Example:**
|
||||
```yaml
|
||||
- label: "Start time"
|
||||
name: "start"
|
||||
title: "start"
|
||||
widget: "datetime"
|
||||
default: ""
|
||||
date_format: "DD.MM.YYYY" # e.g. 24.12.2021
|
@ -1,6 +1,7 @@
|
||||
---
|
||||
title: file
|
||||
label: File
|
||||
group: Widgets
|
||||
title: File
|
||||
weight: 14
|
||||
---
|
||||
The file widget allows editors to upload a file or select an existing one from the media library. The path to the file will be saved to the field as a string.
|
||||
|
||||
@ -22,7 +23,7 @@ The file widget allows editors to upload a file or select an existing one from t
|
||||
|
||||
```yaml
|
||||
- label: "Manual PDF"
|
||||
name: "manual_pdf"
|
||||
title: "manual_pdf"
|
||||
widget: "file"
|
||||
default: "/uploads/general-manual.pdf"
|
||||
media_library:
|
@ -1,6 +1,7 @@
|
||||
---
|
||||
label: "Hidden"
|
||||
title: hidden
|
||||
group: Widgets
|
||||
title: Hidden
|
||||
weight: 15
|
||||
---
|
||||
|
||||
Hidden widgets do not display in the UI. In folder collections that allow users to create new items, you will often want to set a default for hidden fields, so they will be set without requiring an input.
|
||||
@ -12,5 +13,5 @@ Hidden widgets do not display in the UI. In folder collections that allow users
|
||||
- `default`: accepts any valid data type; recommended for collections that allow adding new items
|
||||
- **Example:**
|
||||
```yaml
|
||||
- {label: "Layout", name: "layout", widget: "hidden", default: "blog"}
|
||||
- {label: "Layout", title: "layout", widget: "hidden", default: "blog"}
|
||||
```
|
@ -1,6 +1,7 @@
|
||||
---
|
||||
title: image
|
||||
label: Image
|
||||
group: Widgets
|
||||
title: Image
|
||||
weight: 16
|
||||
---
|
||||
The image widget allows editors to upload an image or select an existing one from the media library. The path to the image file will be saved to the field as a string.
|
||||
|
||||
@ -20,7 +21,7 @@ The image widget allows editors to upload an image or select an existing one fro
|
||||
|
||||
```yaml
|
||||
- label: "Featured Image"
|
||||
name: "thumbnail"
|
||||
title: "thumbnail"
|
||||
widget: "image"
|
||||
choose_url: true
|
||||
default: "/uploads/chocolate-dogecoin.jpg"
|
@ -1,6 +1,7 @@
|
||||
---
|
||||
title: list
|
||||
label: List
|
||||
group: Widgets
|
||||
title: List
|
||||
weight: 17
|
||||
---
|
||||
The list widget allows you to create a repeatable item in the UI which saves as a list of widget values. map a user-provided string with a comma delimiter into a list. You can choose any widget as a child of a list widget—even other lists.
|
||||
|
||||
@ -27,7 +28,7 @@ The list widget allows you to create a repeatable item in the UI which saves as
|
||||
|
||||
```yaml
|
||||
- label: "Tags"
|
||||
name: "tags"
|
||||
title: "tags"
|
||||
widget: "list"
|
||||
default: ["news"]
|
||||
```
|
||||
@ -36,7 +37,7 @@ The list widget allows you to create a repeatable item in the UI which saves as
|
||||
|
||||
```yaml
|
||||
- label: "Tags"
|
||||
name: "tags"
|
||||
title: "tags"
|
||||
widget: "list"
|
||||
allow_add: false
|
||||
default: ["news"]
|
||||
@ -46,38 +47,38 @@ The list widget allows you to create a repeatable item in the UI which saves as
|
||||
|
||||
```yaml
|
||||
- label: "Gallery"
|
||||
name: "galleryImages"
|
||||
title: "galleryImages"
|
||||
widget: "list"
|
||||
summary: '{{fields.image}}'
|
||||
field: {label: Image, name: image, widget: image}
|
||||
field: {label: Image, title: image, widget: image}
|
||||
```
|
||||
|
||||
* **Example** (with `fields`):
|
||||
|
||||
```yaml
|
||||
- label: "Testimonials"
|
||||
name: "testimonials"
|
||||
title: "testimonials"
|
||||
widget: "list"
|
||||
summary: '{{fields.quote}} - {{fields.author.name}}'
|
||||
fields:
|
||||
- {label: Quote, name: quote, widget: string, default: "Everything is awesome!"}
|
||||
- {label: Quote, title: quote, widget: string, default: "Everything is awesome!"}
|
||||
- label: Author
|
||||
name: author
|
||||
title: author
|
||||
widget: object
|
||||
fields:
|
||||
- {label: Name, name: name, widget: string, default: "Emmet"}
|
||||
- {label: Avatar, name: avatar, widget: image, default: "/img/emmet.jpg"}
|
||||
- {label: Name, title: name, widget: string, default: "Emmet"}
|
||||
- {label: Avatar, title: avatar, widget: image, default: "/img/emmet.jpg"}
|
||||
```
|
||||
|
||||
* **Example** (with `default`):
|
||||
|
||||
```yaml
|
||||
- label: "Gallery"
|
||||
name: "galleryImages"
|
||||
title: "galleryImages"
|
||||
widget: "list"
|
||||
fields:
|
||||
- { label: "Source", name: "src", widget: "string" }
|
||||
- { label: "Alt Text", name: "alt", widget: "string" }
|
||||
- { label: "Source", title: "src", widget: "string" }
|
||||
- { label: "Alt Text", title: "alt", widget: "string" }
|
||||
default:
|
||||
- { src: "/img/tennis.jpg", alt: "Tennis" }
|
||||
- { src: "/img/footbar.jpg", alt: "Football" }
|
||||
@ -87,31 +88,31 @@ The list widget allows you to create a repeatable item in the UI which saves as
|
||||
|
||||
```yaml
|
||||
- label: "Testimonials"
|
||||
name: "testimonials"
|
||||
title: "testimonials"
|
||||
collapsed: false
|
||||
widget: "list"
|
||||
fields:
|
||||
- {label: Quote, name: quote, widget: string, default: "Everything is awesome!"}
|
||||
- {label: Author, name: author, widget: string }
|
||||
- {label: Quote, title: quote, widget: string, default: "Everything is awesome!"}
|
||||
- {label: Author, title: author, widget: string }
|
||||
```
|
||||
|
||||
* **Example** (`minimize_collapsed` marked `true`):
|
||||
|
||||
```yaml
|
||||
- label: "Testimonials"
|
||||
name: "testimonials"
|
||||
title: "testimonials"
|
||||
minimize_collapsed: true
|
||||
widget: "list"
|
||||
fields:
|
||||
- {label: Quote, name: quote, widget: string, default: "Everything is awesome!"}
|
||||
- {label: Author, name: author, widget: string }
|
||||
- {label: Quote, title: quote, widget: string, default: "Everything is awesome!"}
|
||||
- {label: Author, title: author, widget: string }
|
||||
```
|
||||
|
||||
* **Example** (with `max` & `min`):
|
||||
|
||||
```yaml
|
||||
- label: "Tags"
|
||||
name: "tags"
|
||||
title: "tags"
|
||||
widget: "list"
|
||||
max: 3
|
||||
min: 1
|
||||
@ -122,7 +123,7 @@ The list widget allows you to create a repeatable item in the UI which saves as
|
||||
|
||||
```yaml
|
||||
- label: "Tags"
|
||||
name: "tags"
|
||||
title: "tags"
|
||||
widget: "list"
|
||||
add_to_top: true
|
||||
```
|
@ -1,6 +1,7 @@
|
||||
---
|
||||
title: map
|
||||
label: Map
|
||||
group: Widgets
|
||||
title: Map
|
||||
weight: 18
|
||||
---
|
||||
The map widget allows you to edit spatial data using an interactive map. Spatial data for a single piece of geometry saves as a GeoJSON string in WGS84 projection.
|
||||
|
||||
@ -15,5 +16,5 @@ The map widget allows you to edit spatial data using an interactive map. Spatial
|
||||
* **Example:**
|
||||
|
||||
```yaml
|
||||
- {label: "Location", name: "location", widget: "map" }
|
||||
- {label: "Location", title: "location", widget: "map" }
|
||||
```
|
@ -1,6 +1,7 @@
|
||||
---
|
||||
title: markdown
|
||||
label: Markdown
|
||||
group: Widgets
|
||||
title: Markdown
|
||||
weight: 19
|
||||
---
|
||||
The markdown widget provides a full fledged text editor allowing users to format text with features such as headings and blockquotes. Users can change their editing view with a handy toggle button.
|
||||
|
||||
@ -19,7 +20,7 @@ The markdown widget provides a full fledged text editor allowing users to format
|
||||
* **Example:**
|
||||
|
||||
```yaml
|
||||
- { label: 'Blog post content', name: 'body', widget: 'markdown' }
|
||||
- { label: 'Blog post content', title: 'body', widget: 'markdown' }
|
||||
```
|
||||
|
||||
This would render as:
|
@ -1,6 +1,7 @@
|
||||
---
|
||||
label: "Number"
|
||||
title: number
|
||||
group: Widgets
|
||||
title: Number
|
||||
weight: 20
|
||||
---
|
||||
|
||||
The number widget uses an HTML number input, saving the value as a string, integer, or floating point number.
|
||||
@ -17,7 +18,7 @@ The number widget uses an HTML number input, saving the value as a string, integ
|
||||
- **Example:**
|
||||
```yaml
|
||||
- label: "Puppy Count"
|
||||
name: "puppies"
|
||||
title: "puppies"
|
||||
widget: "number"
|
||||
default: 2
|
||||
value_type: "int"
|
@ -1,6 +1,7 @@
|
||||
---
|
||||
title: object
|
||||
label: Object
|
||||
group: Widgets
|
||||
title: Object
|
||||
weight: 21
|
||||
---
|
||||
The object widget allows you to group multiple widgets together, nested under a single field. You can choose any widget as a child of an object widget—even other objects.
|
||||
|
||||
@ -17,23 +18,23 @@ The object widget allows you to group multiple widgets together, nested under a
|
||||
|
||||
```yaml
|
||||
- label: "Profile"
|
||||
name: "profile"
|
||||
title: "profile"
|
||||
widget: "object"
|
||||
summary: '{{fields.name}}: {{fields.birthdate}}'
|
||||
fields:
|
||||
- {label: "Public", name: "public", widget: "boolean", default: true}
|
||||
- {label: "Name", name: "name", widget: "string"}
|
||||
- {label: "Public", title: "public", widget: "boolean", default: true}
|
||||
- {label: "Name", title: "name", widget: "string"}
|
||||
- label: "Birthdate"
|
||||
name: "birthdate"
|
||||
title: "birthdate"
|
||||
widget: "date"
|
||||
default: ""
|
||||
format: "MM/DD/YYYY"
|
||||
- label: "Address"
|
||||
name: "address"
|
||||
title: "address"
|
||||
widget: "object"
|
||||
collapsed: true
|
||||
fields:
|
||||
- {label: "Street Address", name: "street", widget: "string"}
|
||||
- {label: "City", name: "city", widget: "string"}
|
||||
- {label: "Postal Code", name: "post-code", widget: "string"}
|
||||
- {label: "Street Address", title: "street", widget: "string"}
|
||||
- {label: "City", title: "city", widget: "string"}
|
||||
- {label: "Postal Code", title: "post-code", widget: "string"}
|
||||
```
|
@ -1,6 +1,7 @@
|
||||
---
|
||||
title: relation
|
||||
label: Relation
|
||||
group: Widgets
|
||||
title: Relation
|
||||
weight: 22
|
||||
---
|
||||
The relation widget allows you to reference items from another collection. It provides a search input with a list of entries from the collection you're referencing, and the list automatically updates with matched entries based on what you've typed.
|
||||
|
||||
@ -23,7 +24,7 @@ The relation widget allows you to reference items from another collection. It pr
|
||||
|
||||
```yaml
|
||||
- label: "Post Author"
|
||||
name: "author"
|
||||
title: "author"
|
||||
widget: "relation"
|
||||
collection: "authors"
|
||||
search_fields: ["name.first", "twitterHandle"]
|
||||
@ -37,7 +38,7 @@ The generated UI input will search the authors collection by name and twitterHan
|
||||
|
||||
```yaml
|
||||
- label: "Post Author"
|
||||
name: "author"
|
||||
title: "author"
|
||||
widget: "relation"
|
||||
collection: "authors"
|
||||
search_fields: ['name.first']
|
||||
@ -51,7 +52,7 @@ The generated UI input will search the authors collection by name, and display e
|
||||
|
||||
```yaml
|
||||
- label: "City"
|
||||
name: "city"
|
||||
title: "city"
|
||||
widget: "relation"
|
||||
collection: "relation_files"
|
||||
file: "cities"
|
@ -1,6 +1,7 @@
|
||||
---
|
||||
title: select
|
||||
label: Select
|
||||
group: Widgets
|
||||
title: Select
|
||||
weight: 23
|
||||
---
|
||||
The select widget allows you to pick a string value from a dropdown menu.
|
||||
|
||||
@ -25,7 +26,7 @@ The select widget allows you to pick a string value from a dropdown menu.
|
||||
|
||||
```yaml
|
||||
- label: "Align Content"
|
||||
name: "align"
|
||||
title: "align"
|
||||
widget: "select"
|
||||
options: ["left", "center", "right"]
|
||||
```
|
||||
@ -40,7 +41,7 @@ align: "center"
|
||||
|
||||
```yaml
|
||||
- label: "City"
|
||||
name: "airport-code"
|
||||
title: "airport-code"
|
||||
widget: "select"
|
||||
options:
|
||||
- { label: "Chicago", value: "ORD" }
|
||||
@ -58,7 +59,7 @@ airport-code: "ORD"
|
||||
|
||||
```yaml
|
||||
- label: "Tags"
|
||||
name: "tags"
|
||||
title: "tags"
|
||||
widget: "select"
|
||||
multiple: true
|
||||
options: ["Design", "UX", "Dev"]
|
||||
@ -69,7 +70,7 @@ airport-code: "ORD"
|
||||
|
||||
```yaml
|
||||
- label: "Tags"
|
||||
name: "tags"
|
||||
title: "tags"
|
||||
widget: "select"
|
||||
multiple: true
|
||||
min: 1
|
@ -1,6 +1,7 @@
|
||||
---
|
||||
label: "String"
|
||||
title: string
|
||||
group: Widgets
|
||||
title: String
|
||||
weight: 24
|
||||
---
|
||||
|
||||
The string widget translates a basic text input to a string value. For larger textarea inputs, use the text widget.
|
||||
@ -12,5 +13,5 @@ The string widget translates a basic text input to a string value. For larger te
|
||||
- `default`: accepts a string; defaults to an empty string
|
||||
- **Example:**
|
||||
```yaml
|
||||
- {label: "Title", name: "title", widget: "string"}
|
||||
- {label: "Title", title: "title", widget: "string"}
|
||||
```
|
@ -1,6 +1,7 @@
|
||||
---
|
||||
label: "Text"
|
||||
title: text
|
||||
group: Widgets
|
||||
title: Text
|
||||
weight: 25
|
||||
---
|
||||
|
||||
The text widget takes a multiline text field and saves it as a string. For shorter text inputs, use the string widget.
|
||||
@ -12,5 +13,5 @@ The text widget takes a multiline text field and saves it as a string. For short
|
||||
- `default`: accepts a string; defaults to an empty string
|
||||
- **Example:**
|
||||
```yaml
|
||||
- {label: "Description", name: "description", widget: "text"}
|
||||
- {label: "Description", title: "description", widget: "text"}
|
||||
```
|
@ -1,10 +1,10 @@
|
||||
---
|
||||
title: Widgets
|
||||
group: Fields
|
||||
weight: 10
|
||||
group: Widgets
|
||||
title: Overview
|
||||
weight: 0
|
||||
---
|
||||
|
||||
Widgets define the data type and interface for entry fields. Static CMS comes with several built-in widgets. Click the widget names in the sidebar to jump to specific widget details. We’re always adding new widgets, and you can also [create your own](../custom-widgets)!
|
||||
Widgets define the data type and interface for entry fields. Static CMS comes with several built-in widgets. Click the widget names in the sidebar to jump to specific widget details. We’re always adding new widgets, and you can also [create your own](/docs/custom-widgets)!
|
||||
|
||||
Widgets are specified as collection fields in the Static CMS `config.yml` file. Note that [YAML syntax](https://en.wikipedia.org/wiki/YAML#Basic_components) allows lists and objects to be written in block or inline style, and the code samples below include a mix of both.
|
||||
|
||||
@ -16,13 +16,11 @@ The following options are available on all fields:
|
||||
|
||||
- `required`: specify as `false` to make a field optional; defaults to `true`
|
||||
- `hint`: optionally add helper text directly below a widget. Useful for including instructions. Accepts markdown for bold, italic, strikethrough, and links.
|
||||
- `pattern`: add field validation by specifying a list with a [regex pattern](https://regexr.com/) and an error message; more extensive validation can be achieved with [custom widgets](../custom-widgets/#advanced-field-validation)
|
||||
- `pattern`: add field validation by specifying a list with a [regex pattern](https://regexr.com/) and an error message; more extensive validation can be achieved with [custom widgets](/docs/custom-widgets/#advanced-field-validation)
|
||||
- **Example:**
|
||||
```yaml
|
||||
label: "Title"
|
||||
name: "title"
|
||||
title: "title"
|
||||
widget: "string"
|
||||
pattern: ['.{12,}', "Must have at least 12 characters"]
|
||||
```
|
||||
|
||||
## Default widgets
|
@ -1,25 +0,0 @@
|
||||
---
|
||||
title: date
|
||||
label: 'Date'
|
||||
---
|
||||
|
||||
_**Deprecation notice**: the date widget has been deprecated and will be removed in the next major release. Please use the datetime widget instead._
|
||||
|
||||
The date widget translates a date picker input to a date string. For saving date and time together, use the datetime widget.
|
||||
|
||||
- **Name:** `date`
|
||||
- **UI:** date picker
|
||||
- **Data type:** Moment.js-formatted date string
|
||||
- **Options:**
|
||||
- `default`: accepts a date string, or an empty string to accept blank input; otherwise defaults to current date
|
||||
- `format`: optional; accepts Moment.js [tokens](https://momentjs.com/docs/#/parsing/string-format/); defaults to raw Date object (if supported by output format)
|
||||
- `date_format`: optional; boolean or Moment.js [tokens](https://momentjs.com/docs/#/parsing/string-format/). If `true` use default locale format.
|
||||
- `time_format`: optional; boolean or Moment.js [tokens](https://momentjs.com/docs/#/parsing/string-format/). If `true` use default locale format, `false` hides time-picker. Defaults to false.
|
||||
- **Example:**
|
||||
```yaml
|
||||
- label: 'Birthdate'
|
||||
name: 'birthdate'
|
||||
widget: 'date'
|
||||
default: ''
|
||||
format: 'MMM Do YY'
|
||||
```
|
@ -1,260 +0,0 @@
|
||||
---
|
||||
title: Writing Style Guide
|
||||
weight: 30
|
||||
group: Contributing
|
||||
---
|
||||
|
||||
# Static CMS Style Guide
|
||||
_Adapted from the [Kubernetes Style Guide](https://kubernetes.io/docs/contribute/style/style-guide)_
|
||||
|
||||
## Documentation Formatting Standards
|
||||
|
||||
### Use angle brackets for placeholders
|
||||
|
||||
Use angle brackets for placeholders. Tell the reader what a placeholder represents.
|
||||
|
||||
1. Display information about a cli command:
|
||||
|
||||
```bash
|
||||
npm install <package-name>
|
||||
```
|
||||
|
||||
where `<package-name>` is the name of a package.
|
||||
|
||||
### Use bold for user interface elements
|
||||
|
||||
Do: Click **Save**.
|
||||
|
||||
Don't: Click "Save".
|
||||
_____
|
||||
|
||||
Do: Select **Log Out**.
|
||||
|
||||
Don't: Select 'Log Out'.
|
||||
_____
|
||||
|
||||
### Use italics to define or introduce new terms
|
||||
|
||||
Do: A _collection_ is a set of entries …
|
||||
|
||||
Don't: A "collection" is a set of entries …
|
||||
_____
|
||||
|
||||
Do: These components form the _control pane_.
|
||||
|
||||
Don't: These components form the **control pane**.
|
||||
_____
|
||||
|
||||
### Use code style for filenames, directories, and paths
|
||||
|
||||
Do: Open the `config.yaml` file.
|
||||
|
||||
Don't: Open the config.yaml file.
|
||||
_____
|
||||
|
||||
Do: Go to the `/docs/guides` directory.
|
||||
|
||||
Don't: Go to the /docs/guides directory.
|
||||
_____
|
||||
|
||||
Do: Open the `/admin/index.html` file.
|
||||
|
||||
Don't: Open the /admin/index.html file.
|
||||
_____
|
||||
|
||||
### Use the international standard for punctuation inside quotes
|
||||
|
||||
Do: Branch names begin with "cms".
|
||||
|
||||
Don't: Branch names begin with "stage."
|
||||
_____
|
||||
|
||||
Do: The copy is called a "fork".
|
||||
|
||||
Don't: The copy is called a "fork."
|
||||
_____
|
||||
|
||||
## Inline code formatting
|
||||
|
||||
### Use code style for inline code and commands
|
||||
|
||||
For inline code in an HTML document, use the `<code>` tag. In a Markdown document, use the backtick (`).
|
||||
|
||||
Do: The `yarn start` command starts the development server.
|
||||
|
||||
Don't: The "yarn start" command starts the development server.
|
||||
_____
|
||||
|
||||
Do: For a production build, use `yarn build`.
|
||||
|
||||
Don't: For a production build, use "yarn build".
|
||||
_____
|
||||
|
||||
Do: Enclose code samples with triple backticks. `(```)`
|
||||
|
||||
Don't:Enclose code samples with any other syntax.
|
||||
_____
|
||||
|
||||
### Use code style for object field names
|
||||
|
||||
Do: Set the value of the `media_folder` field in the configuration file.
|
||||
|
||||
Don't: Set the value of the "media_folder" field in the configuration file.
|
||||
_____
|
||||
|
||||
Do: The value of the `name` field is a string.
|
||||
|
||||
Don't: The value of the "name" field is a string.
|
||||
_____
|
||||
|
||||
### Use normal style for string and integer field values
|
||||
|
||||
For field values of type string or integer, use normal style without quotation marks.
|
||||
|
||||
Do: Set the value of `imagePullPolicy` to Always.
|
||||
|
||||
Don't: Set the value of `imagePullPolicy` to "Always".
|
||||
_____
|
||||
|
||||
Do: Set the value of `image` to nginx:1.8.
|
||||
|
||||
Don't: Set the value of `image` to `nginx:1.8`.
|
||||
_____
|
||||
|
||||
Do: Set the value of the `replicas` field to 2.
|
||||
|
||||
Don't: Set the value of the `replicas` field to 2.
|
||||
_____
|
||||
|
||||
## Code snippet formatting
|
||||
|
||||
### Don’t include the command prompt
|
||||
|
||||
Do: yarn start
|
||||
|
||||
Don't: $ yarn start
|
||||
|
||||
## Content best practices
|
||||
|
||||
This section contains suggested best practices for clear, concise, and consistent content.
|
||||
|
||||
### Use present tense
|
||||
|
||||
Do: This command starts a proxy.
|
||||
|
||||
Don't: This command will start a proxy.
|
||||
|
||||
Exception: Use future or past tense if it is required to convey the correct meaning.
|
||||
|
||||
### Use active voice
|
||||
|
||||
Do: You can explore the API using a browser.
|
||||
|
||||
Don't: The API can be explored using a browser.
|
||||
_____
|
||||
|
||||
Do: The YAML file specifies the collection name.
|
||||
|
||||
Don't: The collection name is specified in the YAML file.
|
||||
_____
|
||||
|
||||
Exception: Use passive voice if active voice leads to an awkward construction.
|
||||
|
||||
### Use simple and direct language
|
||||
|
||||
Use simple and direct language. Avoid using unnecessary phrases, such as saying “please.”
|
||||
|
||||
Do: To create an entry, …
|
||||
|
||||
Don't: In order to create an entry, …
|
||||
_____
|
||||
|
||||
Do: See the configuration file.
|
||||
|
||||
Don't: Please see the configuration file.
|
||||
_____
|
||||
|
||||
Do: View the fields.
|
||||
|
||||
Don't: With this next command, we'll view the fields.
|
||||
_____
|
||||
|
||||
### Address the reader as “you”
|
||||
|
||||
Do: You can create a Deployment by …
|
||||
|
||||
Don't: We'll create a Deployment by …
|
||||
_____
|
||||
|
||||
Do: In the preceding output, you can see…
|
||||
|
||||
Don't: In the preceding output, we can see …
|
||||
|
||||
### Avoid Latin phrases
|
||||
|
||||
Prefer English terms over Latin abbreviations.
|
||||
|
||||
Do: For example, …
|
||||
|
||||
Don't: e.g., …
|
||||
_____
|
||||
|
||||
Do: That is, …
|
||||
|
||||
Don't: i.e., …
|
||||
_____
|
||||
|
||||
Exception: Use “etc.” for et cetera.
|
||||
|
||||
## Patterns to avoid
|
||||
|
||||
### Avoid using “we”
|
||||
|
||||
Using “we” in a sentence can be confusing, because the reader might not know whether they’re part of the “we” you’re describing.
|
||||
|
||||
Do: Version 1.4 includes …
|
||||
|
||||
Don't: In version 1.4, we have added …
|
||||
_____
|
||||
|
||||
Do: Static CMS provides a new feature for …
|
||||
|
||||
Don't: We provide a new feature …
|
||||
_____
|
||||
|
||||
Do: This page teaches you how to use Widgets.
|
||||
|
||||
Don't: In this page, we are going to learn about Widgets.
|
||||
_____
|
||||
|
||||
### Avoid jargon and idioms
|
||||
|
||||
Some readers speak English as a second language. Avoid jargon and idioms to help them understand better.
|
||||
|
||||
Do: Internally
|
||||
|
||||
Don't: Under the hood, …
|
||||
_____
|
||||
|
||||
Do: Create a new cluster.
|
||||
|
||||
Don't: Turn up a new cluster.
|
||||
_____
|
||||
|
||||
### Avoid statements about the future
|
||||
|
||||
Avoid making promises or giving hints about the future. If you need to talk about an alpha feature, put the text under a heading that identifies it as alpha information.
|
||||
|
||||
### Avoid statements that will soon be out of date
|
||||
|
||||
Avoid words like “currently” and “new.” A feature that is new today will not be new in a few months.
|
||||
|
||||
Do: In version 1.4, …
|
||||
|
||||
Don't: In the current version, …
|
||||
_____
|
||||
|
||||
Do: The Federation feature provides …
|
||||
|
||||
Don't: The new Federation feature provides …
|
||||
_____
|
248
website/content/docs/writing-style-guide.mdx
Normal file
@ -0,0 +1,248 @@
|
||||
---
|
||||
group: Contributing
|
||||
title: Writing Style Guide
|
||||
weight: 30
|
||||
---
|
||||
|
||||
_Adapted from the [Kubernetes Style Guide](https://kubernetes.io/docs/contribute/style/style-guide)_
|
||||
|
||||
## Documentation Formatting Standards
|
||||
|
||||
### Use angle brackets for placeholders
|
||||
|
||||
Use angle brackets for placeholders. Tell the reader what a placeholder represents.
|
||||
|
||||
1. Display information about a cli command:
|
||||
|
||||
```bash
|
||||
npm install <package-name>
|
||||
```
|
||||
|
||||
where `<package-name>` is the name of a package.
|
||||
|
||||
### Use bold for user interface elements
|
||||
|
||||
> Do: Click **Save**.
|
||||
|
||||
> Don't: Click "Save".
|
||||
_____
|
||||
|
||||
> Do: Select **Log Out**.
|
||||
|
||||
> Don't: Select 'Log Out'.
|
||||
|
||||
### Use italics to define or introduce new terms
|
||||
|
||||
> Do: A _collection_ is a set of entries …
|
||||
|
||||
> Don't: A "collection" is a set of entries …
|
||||
_____
|
||||
|
||||
> Do: These components form the _control pane_.
|
||||
|
||||
> Don't: These components form the **control pane**.
|
||||
|
||||
### Use code style for filenames, directories, and paths
|
||||
|
||||
> Do: Open the `config.yaml` file.
|
||||
|
||||
> Don't: Open the config.yaml file.
|
||||
_____
|
||||
|
||||
> Do: Go to the `/docs/guides` directory.
|
||||
|
||||
> Don't: Go to the /docs/guides directory.
|
||||
_____
|
||||
|
||||
> Do: Open the `/admin/index.html` file.
|
||||
|
||||
> Don't: Open the /admin/index.html file.
|
||||
|
||||
### Use the international standard for punctuation inside quotes
|
||||
|
||||
> Do: Branch names begin with "cms".
|
||||
|
||||
> Don't: Branch names begin with "stage."
|
||||
_____
|
||||
|
||||
> Do: The copy is called a "fork".
|
||||
|
||||
> Don't: The copy is called a "fork."
|
||||
|
||||
## Inline code formatting
|
||||
|
||||
### Use code style for inline code and commands
|
||||
|
||||
For inline code in an HTML document, use the `<code>` tag. In a Markdown document, use the backtick (`).
|
||||
|
||||
> Do: The `yarn start` command starts the development server.
|
||||
|
||||
> Don't: The "yarn start" command starts the development server.
|
||||
_____
|
||||
|
||||
> Do: For a production build, use `yarn build`.
|
||||
|
||||
> Don't: For a production build, use "yarn build".
|
||||
_____
|
||||
|
||||
> Do: Enclose code samples with triple backticks. `(```)`
|
||||
|
||||
> Don't: Enclose code samples with any other syntax.
|
||||
|
||||
### Use code style for object field names
|
||||
|
||||
> Do: Set the value of the `media_folder` field in the configuration file.
|
||||
|
||||
> Don't: Set the value of the "media_folder" field in the configuration file.
|
||||
_____
|
||||
|
||||
> Do: The value of the `name` field is a string.
|
||||
|
||||
> Don't: The value of the "name" field is a string.
|
||||
|
||||
### Use normal style for string and integer field values
|
||||
|
||||
For field values of type string or integer, use normal style without quotation marks.
|
||||
|
||||
> Do: Set the value of `imagePullPolicy` to Always.
|
||||
|
||||
> Don't: Set the value of `imagePullPolicy` to "Always".
|
||||
_____
|
||||
|
||||
> Do: Set the value of `image` to nginx:1.8.
|
||||
|
||||
> Don't: Set the value of `image` to `nginx:1.8`.
|
||||
_____
|
||||
|
||||
> Do: Set the value of the `replicas` field to 2.
|
||||
|
||||
> Don't: Set the value of the `replicas` field to 2.
|
||||
|
||||
## Code snippet formatting
|
||||
|
||||
### Don't include the command prompt
|
||||
|
||||
> Do: yarn start
|
||||
|
||||
> Don't: $ yarn start
|
||||
|
||||
## Content best practices
|
||||
|
||||
This section contains suggested best practices for clear, concise, and consistent content.
|
||||
|
||||
### Use present tense
|
||||
|
||||
> Do: This command starts a proxy.
|
||||
|
||||
> Don't: This command will start a proxy.
|
||||
|
||||
Exception: Use future or past tense if it is required to convey the correct meaning.
|
||||
|
||||
### Use active voice
|
||||
|
||||
> Do: You can explore the API using a browser.
|
||||
|
||||
> Don't: The API can be explored using a browser.
|
||||
_____
|
||||
|
||||
> Do: The YAML file specifies the collection name.
|
||||
|
||||
> Don't: The collection name is specified in the YAML file.
|
||||
_____
|
||||
|
||||
Exception: Use passive voice if active voice leads to an awkward construction.
|
||||
|
||||
### Use simple and direct language
|
||||
|
||||
Use simple and direct language. Avoid using unnecessary phrases, such as saying “please.”
|
||||
|
||||
> Do: To create an entry, …
|
||||
|
||||
> Don't: In order to create an entry, …
|
||||
_____
|
||||
|
||||
> Do: See the configuration file.
|
||||
|
||||
> Don't: Please see the configuration file.
|
||||
_____
|
||||
|
||||
> Do: View the fields.
|
||||
|
||||
> Don't: With this next command, we'll view the fields.
|
||||
|
||||
### Address the reader as “you”
|
||||
|
||||
> Do: You can create a Deployment by …
|
||||
|
||||
> Don't: We'll create a Deployment by …
|
||||
_____
|
||||
|
||||
> Do: In the preceding output, you can see…
|
||||
|
||||
> Don't: In the preceding output, we can see …
|
||||
|
||||
### Avoid Latin phrases
|
||||
|
||||
Prefer English terms over Latin abbreviations.
|
||||
|
||||
> Do: For example, …
|
||||
|
||||
> Don't: e.g., …
|
||||
_____
|
||||
|
||||
> Do: That is, …
|
||||
|
||||
> Don't: i.e., …
|
||||
_____
|
||||
|
||||
Exception: Use “etc.” for et cetera.
|
||||
|
||||
## Patterns to avoid
|
||||
|
||||
### Avoid using “we”
|
||||
|
||||
Using “we” in a sentence can be confusing, because the reader might not know whether they’re part of the “we” you’re describing.
|
||||
|
||||
> Do: Version 1.4 includes …
|
||||
|
||||
> Don't: In version 1.4, we have added …
|
||||
_____
|
||||
|
||||
> Do: Static CMS provides a new feature for …
|
||||
|
||||
> Don't: We provide a new feature …
|
||||
_____
|
||||
|
||||
> Do: This page teaches you how to use Widgets.
|
||||
|
||||
> Don't: In this page, we are going to learn about Widgets.
|
||||
|
||||
### Avoid jargon and idioms
|
||||
|
||||
Some readers speak English as a second language. Avoid jargon and idioms to help them understand better.
|
||||
|
||||
> Do: Internally
|
||||
|
||||
> Don't: Under the hood, …
|
||||
_____
|
||||
|
||||
> Do: Create a new cluster.
|
||||
|
||||
> Don't: Turn up a new cluster.
|
||||
|
||||
### Avoid statements about the future
|
||||
|
||||
Avoid making promises or giving hints about the future. If you need to talk about an alpha feature, put the text under a heading that identifies it as alpha information.
|
||||
|
||||
### Avoid statements that will soon be out of date
|
||||
|
||||
Avoid words like “currently” and “new.” A feature that is new today will not be new in a few months.
|
||||
|
||||
> Do: In version 1.4, …
|
||||
|
||||
> Don't: In the current version, …
|
||||
_____
|
||||
|
||||
> Do: The Federation feature provides …
|
||||
|
||||
> Don't: The new Federation feature provides …
|
45
website/content/homepage.json
Normal file
@ -0,0 +1,45 @@
|
||||
{
|
||||
"title": "Open source content management for your Git workflow",
|
||||
"subtitle": "Use Static CMS with any static site generator for a faster and more flexible web project",
|
||||
"get_started": {
|
||||
"title": "Get Started",
|
||||
"url": "/docs/start-with-a-template/"
|
||||
},
|
||||
"overviews": [
|
||||
{
|
||||
"title": "Static + content management = ♥",
|
||||
"description": "Get the speed, security, and scalability of a static site, while still providing a convenient editing interface for content."
|
||||
},
|
||||
{
|
||||
"title": "An integrated part of your Git workflow",
|
||||
"description": "Content is stored in your Git repository alongside your code for easier versioning, multi-channel publishing, and the option to handle content updates directly in Git."
|
||||
},
|
||||
{
|
||||
"title": "An extensible CMS built on React",
|
||||
"description": "Static CMS is built as a single-page React app. Create custom-styled previews, UI widgets, and editor plugins or add backends to support different Git platform APIs."
|
||||
}
|
||||
],
|
||||
"call_to_action": {
|
||||
"title": "Getting started is simple and free.",
|
||||
"subtitle": "Choose a template that’s pre-configured with a static site generator and deploys to a global CDN in one click.",
|
||||
"button_text": "Get Started",
|
||||
"url": "/docs/start-with-a-template/"
|
||||
},
|
||||
"features_intro": {
|
||||
"title": "A CMS that developers and content editors can agree on",
|
||||
"subtitle1": "You get to implement modern front end tools to deliver a faster, safer, and more scalable site.",
|
||||
"subtitle2": "Editors get a friendly UI and intuitive workflow that meets their content management requirements."
|
||||
},
|
||||
"features": [
|
||||
{
|
||||
"image": "/img/editor-friendly-user-interface.svg",
|
||||
"title": "Editor-friendly user interface",
|
||||
"description": "Get the speed, security, and scalability of a static site, while still providing a convenient editing interface for content."
|
||||
},
|
||||
{
|
||||
"image": "/img/instant-access-without-github-account.svg",
|
||||
"title": "Instant access without GitHub account",
|
||||
"description": "With Git Gateway, you can add CMS access for any team member — even if they don’t have a GitHub account."
|
||||
}
|
||||
]
|
||||
}
|
42
website/content/menu.json
Normal file
@ -0,0 +1,42 @@
|
||||
{
|
||||
"menu": {
|
||||
"docs": [
|
||||
{
|
||||
"name": "Intro",
|
||||
"title": "Intro to Static CMS"
|
||||
},
|
||||
{
|
||||
"name": "Accounts",
|
||||
"title": "Account Settings"
|
||||
},
|
||||
{
|
||||
"name": "Configuration",
|
||||
"title": "Configuring your Site"
|
||||
},
|
||||
{
|
||||
"name": "Collections",
|
||||
"title": "Collections"
|
||||
},
|
||||
{
|
||||
"name": "Widgets",
|
||||
"title": "Widgets"
|
||||
},
|
||||
{
|
||||
"name": "Media",
|
||||
"title": "Media"
|
||||
},
|
||||
{
|
||||
"name": "Guides",
|
||||
"title": "Platform Guides"
|
||||
},
|
||||
{
|
||||
"name": "Customization",
|
||||
"title": "Customizing Static CMS"
|
||||
},
|
||||
{
|
||||
"name": "Contributing",
|
||||
"title": "Community"
|
||||
}
|
||||
]
|
||||
}
|
||||
}
|
@ -1,22 +0,0 @@
|
||||
---
|
||||
title: Community
|
||||
headline: Help us build the CMS of the future.
|
||||
subhead: Get support, give support, and find out what's new through the channels below.
|
||||
sections:
|
||||
- title: support
|
||||
channels:
|
||||
- title: Static CMS Slack
|
||||
description: Live community chat for all things Static CMS.
|
||||
url: /chat
|
||||
- title: Static CMS Community
|
||||
description: Ask and answer questions on GitHub discussions tab.
|
||||
url: https://github.com/StaticJsCMS/static-cms/discussions
|
||||
- title: GitHub Issues
|
||||
description: Report bugs, request features, and comment on existing issues.
|
||||
url: https://github.com/StaticJsCMS/static-cms/issues
|
||||
- title: development
|
||||
channels:
|
||||
- title: Planning
|
||||
description: Issues board on the Static CMS GitHub repo.
|
||||
url: https://github.com/orgs/StaticJsCMS/projects/1
|
||||
---
|
9
website/content/releases.json
Normal file
@ -0,0 +1,9 @@
|
||||
{
|
||||
"releases": [
|
||||
{
|
||||
"date": "2022-11-30T00:00:00.000Z",
|
||||
"version": "1.0.0",
|
||||
"description": "The first major release of Static CMS with an all-new UI, revamped documentation and much more."
|
||||
}
|
||||
]
|
||||
}
|
@ -1,11 +0,0 @@
|
||||
styleoverrides: '/docs.css'
|
||||
headline: Netlify builds, deploys, and hosts your front end.
|
||||
bottomcta:
|
||||
hook: Want to get started quick?
|
||||
btns:
|
||||
- type: primary
|
||||
btntext: View our Templates
|
||||
linksto: https://app.netlify.com/signup/templates
|
||||
- type: secondary
|
||||
btntext: Read our Tutorials
|
||||
linksto: /tags/tutorial/
|
@ -1,6 +0,0 @@
|
||||
footer:
|
||||
buttons:
|
||||
- name: "Twitter"
|
||||
url: "https://twitter.com/StaticJsCMS"
|
||||
- name: "GitHub"
|
||||
url: "https://github.com/StaticJsCMS/static-cms"
|
@ -1,41 +0,0 @@
|
||||
hero:
|
||||
headline: "Open source content management for your Git workflow"
|
||||
subhead: "Use Static CMS with any static site generator for a faster and more flexible web project"
|
||||
devfeatures:
|
||||
- feature: "Static + content management = ♥"
|
||||
description: "Get the speed, security, and scalability of a static site, while still providing a convenient editing interface for content."
|
||||
- feature: "An integrated part of your Git workflow"
|
||||
description: "Content is stored in your Git repository alongside your code for easier versioning, multi-channel publishing, and the option to handle content updates directly in Git."
|
||||
- feature: "An extensible CMS built on React"
|
||||
description: "Static CMS is built as a single-page React app. Create custom-styled previews, UI widgets, and editor plugins or add backends to support different Git platform APIs."
|
||||
|
||||
cta:
|
||||
primaryhook: "Getting started is simple and free."
|
||||
primary: "Choose a template that’s pre-configured with a static site generator and deploys to a global CDN in one click."
|
||||
button: "[Get started](/docs/start-with-a-template/)"
|
||||
|
||||
editors:
|
||||
hook: "A CMS that developers and content editors can agree on"
|
||||
intro: "You get to implement modern front end tools to deliver a faster, safer, and more scalable site. Editors get a friendly UI and intuitive workflow that meets their content management requirements."
|
||||
features:
|
||||
- feature: "Editor-friendly user interface"
|
||||
description: "The web-based app includes rich-text editing, real-time preview, and drag-and-drop media uploads."
|
||||
imgpath: "feature-editor.svg"
|
||||
- feature: "Intuitive workflow for content teams"
|
||||
description: "Writers and editors can easily manage content from draft to review to publish across any number of custom content types."
|
||||
imgpath: "feature-workflow.svg"
|
||||
- feature: "Instant access without GitHub account"
|
||||
description: "With [Git Gateway](/docs/git-gateway-backend/#git-gateway-with-netlify-identity), you can add CMS access for any team member — even if they don’t have a GitHub account. "
|
||||
imgpath: "feature-access.svg"
|
||||
|
||||
community:
|
||||
hook: "Supported by a growing community"
|
||||
features:
|
||||
- feature: "Built on the Jamstack"
|
||||
description: "Static CMS is based on client-side JavaScript, reusable APIs and prebuilt Markup. Compared to server-side CMS like WordPress, this means better performance, higher security, lower cost of scaling, and a better developer experience. You can learn more about the Jamstack on [jamstack.org](https://jamstack.org)."
|
||||
- feature: "Support when you need it"
|
||||
description: "Get up and running with comprehensive [documentation](/docs) and templates or work through difficult problems in our [community chat](https://staticjscms.github.io/static-cms/chat)."
|
||||
- feature: "A community-driven project you can help evolve"
|
||||
description: "Static CMS is built by a community of more than 100 contributors — and you can help. Read the [contributing guide](/docs/contributor-guide) to join in."
|
||||
contributors: "Made possible by awesome contributors"
|
||||
|
@ -1,7 +0,0 @@
|
||||
notifications:
|
||||
- loud: true
|
||||
message: We have a community chat - join now to ask questions and discuss the
|
||||
project with other devs!
|
||||
published: false
|
||||
title: Chat shoutout
|
||||
url: https://staticjscms.github.io/static-cms/chat
|
@ -1,5 +0,0 @@
|
||||
updates:
|
||||
- date: 2022-11-30T00:00:00.000Z
|
||||
version: 1.0.0
|
||||
description: The first major release of Static CMS with an all-new UI, revamped
|
||||
documentation and much more.
|
@ -1,9 +0,0 @@
|
||||
// Make scroll behavior of internal links smooth
|
||||
exports.onClientEntry = () => {
|
||||
const SmoothScroll = require('smooth-scroll');
|
||||
new SmoothScroll('a[href*="#"]', {
|
||||
offset() {
|
||||
return document.querySelector('#header').offsetHeight;
|
||||
},
|
||||
});
|
||||
};
|
@ -1,77 +0,0 @@
|
||||
const fs = require('fs');
|
||||
const yaml = require('js-yaml');
|
||||
|
||||
const pkg = require('./package.json');
|
||||
|
||||
const staticConfig = yaml.load(fs.readFileSync('./site.yml', 'utf8'));
|
||||
|
||||
module.exports = {
|
||||
siteMetadata: {
|
||||
title: 'Static CMS | Open-Source Content Management System',
|
||||
description: 'Open source content management for your Git workflow',
|
||||
siteUrl: pkg.homepage,
|
||||
menu: staticConfig.menu,
|
||||
},
|
||||
pathPrefix: `/static-cms`,
|
||||
plugins: [
|
||||
{
|
||||
resolve: 'gatsby-plugin-manifest',
|
||||
options: {
|
||||
name: 'StaticCms',
|
||||
short_name: 'StaticCms',
|
||||
start_url: '/',
|
||||
background_color: '#ffffff',
|
||||
theme_color: '#ffffff',
|
||||
display: 'standalone',
|
||||
icon: 'static/img/favicon/icon-512x512.png',
|
||||
},
|
||||
},
|
||||
{
|
||||
resolve: 'gatsby-source-filesystem',
|
||||
options: {
|
||||
path: `${__dirname}/content`,
|
||||
name: 'content',
|
||||
},
|
||||
},
|
||||
{
|
||||
resolve: 'gatsby-source-filesystem',
|
||||
options: {
|
||||
path: `${__dirname}/data`,
|
||||
name: 'data',
|
||||
},
|
||||
},
|
||||
{
|
||||
resolve: 'gatsby-transformer-remark',
|
||||
options: {
|
||||
// prettier-ignore
|
||||
plugins: [
|
||||
'gatsby-remark-autolink-headers',
|
||||
{
|
||||
resolve: "gatsby-remark-external-links",
|
||||
options: {
|
||||
target: "_blank",
|
||||
rel: "noopener noreferrer"
|
||||
}
|
||||
},
|
||||
{
|
||||
resolve: 'gatsby-remark-prismjs',
|
||||
options: {
|
||||
noInlineHighlight: true,
|
||||
},
|
||||
},
|
||||
],
|
||||
},
|
||||
},
|
||||
'gatsby-transformer-yaml',
|
||||
'gatsby-transformer-json',
|
||||
'gatsby-plugin-emotion',
|
||||
'gatsby-plugin-react-helmet',
|
||||
'gatsby-plugin-catch-links',
|
||||
{
|
||||
resolve: 'gatsby-plugin-netlify-cms',
|
||||
options: {
|
||||
modulePath: `${__dirname}/src/cms/cms.js`,
|
||||
},
|
||||
},
|
||||
],
|
||||
};
|
@ -1,104 +0,0 @@
|
||||
const path = require('path');
|
||||
const { createFilePath } = require('gatsby-source-filesystem');
|
||||
|
||||
exports.createPages = async ({ graphql, actions }) => {
|
||||
const { createPage } = actions;
|
||||
|
||||
const docPage = path.resolve('./src/templates/doc-page.js');
|
||||
const blogPost = path.resolve('./src/templates/blog-post.js');
|
||||
|
||||
// get all markdown with a frontmatter path field and title
|
||||
const allMarkdown = await graphql(`
|
||||
{
|
||||
allMarkdownRemark(filter: { frontmatter: { title: { ne: null } } }) {
|
||||
edges {
|
||||
node {
|
||||
fields {
|
||||
slug
|
||||
}
|
||||
frontmatter {
|
||||
title
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
`);
|
||||
|
||||
if (allMarkdown.errors) {
|
||||
console.error(allMarkdown.errors); // eslint-disable-line no-console
|
||||
throw Error(allMarkdown.errors);
|
||||
}
|
||||
|
||||
allMarkdown.data.allMarkdownRemark.edges.forEach(({ node }) => {
|
||||
const { slug } = node.fields;
|
||||
|
||||
let template = docPage;
|
||||
|
||||
if (slug.includes('blog/')) {
|
||||
template = blogPost;
|
||||
}
|
||||
|
||||
createPage({
|
||||
path: slug,
|
||||
component: template,
|
||||
context: {
|
||||
slug,
|
||||
},
|
||||
});
|
||||
});
|
||||
};
|
||||
|
||||
function pad(n) {
|
||||
return n >= 10 ? n : `0${n}`;
|
||||
}
|
||||
|
||||
exports.onCreateNode = ({ node, actions, getNode }) => {
|
||||
const { createNodeField } = actions;
|
||||
|
||||
if (node.internal.type === 'MarkdownRemark') {
|
||||
const value = createFilePath({ node, getNode });
|
||||
const { relativePath } = getNode(node.parent);
|
||||
|
||||
let slug = value;
|
||||
|
||||
if (relativePath.includes('blog/')) {
|
||||
const date = new Date(node.frontmatter.date);
|
||||
const year = date.getFullYear();
|
||||
const month = date.getMonth() + 1;
|
||||
const filename = path.basename(relativePath, '.md');
|
||||
slug = `/blog/${year}/${pad(month)}/${filename}`;
|
||||
|
||||
createNodeField({
|
||||
node,
|
||||
name: 'date',
|
||||
value: date.toJSON(),
|
||||
});
|
||||
}
|
||||
|
||||
// used for doc posts
|
||||
createNodeField({
|
||||
node,
|
||||
name: 'slug',
|
||||
value: slug,
|
||||
});
|
||||
|
||||
// used to create GitHub edit link
|
||||
createNodeField({
|
||||
node,
|
||||
name: 'path',
|
||||
value: relativePath,
|
||||
});
|
||||
}
|
||||
};
|
||||
|
||||
exports.onCreateWebpackConfig = ({ actions }) => {
|
||||
actions.setWebpackConfig({
|
||||
resolve: {
|
||||
extensions: ['.ts', '.tsx', '.js', '.json'],
|
||||
alias: {
|
||||
moment$: 'moment/moment.js',
|
||||
},
|
||||
},
|
||||
});
|
||||
};
|
29
website/next.config.js
Normal file
@ -0,0 +1,29 @@
|
||||
const withPWA = require('next-pwa')({
|
||||
publicExcludes: ['!bulletins/**/*'],
|
||||
dest: 'public'
|
||||
});
|
||||
|
||||
const withBundleAnalyzer = require('@next/bundle-analyzer')({
|
||||
enabled: process.env.ANALYZE === 'true'
|
||||
});
|
||||
|
||||
const redirects = [
|
||||
{ source: '/chat', destination: 'https://join.slack.com/t/static-cms/shared_invite/zt-1gvgnf5yv-E4sR17YnEcOy6fLFH9m7bQ', permanent: true },
|
||||
];
|
||||
|
||||
/** @type {import('next').NextConfig} */
|
||||
let config = {
|
||||
reactStrictMode: true,
|
||||
swcMinify: true,
|
||||
redirects: async () => {
|
||||
return redirects;
|
||||
},
|
||||
}
|
||||
|
||||
if (process.env.NODE_ENV === 'production') {
|
||||
config = withPWA(config);
|
||||
} else {
|
||||
config = withBundleAnalyzer(config);
|
||||
}
|
||||
|
||||
module.exports = config
|
@ -1,52 +1,49 @@
|
||||
{
|
||||
"name": "static-cms-site",
|
||||
"version": "1.0.0",
|
||||
"description": "Static CMS documentation website built with Gatsby",
|
||||
"name": "website",
|
||||
"version": "0.1.0",
|
||||
"private": true,
|
||||
"scripts": {
|
||||
"start": "gatsby develop",
|
||||
"build": "gatsby build --prefix-paths && rm -rf dist && mv public dist",
|
||||
"lint": "markdownlint 'content/docs/**/*.md'",
|
||||
"reset": "rm -rf .cache"
|
||||
"dev": "next dev",
|
||||
"build": "next build",
|
||||
"start": "next start",
|
||||
"lint": "next lint"
|
||||
},
|
||||
"author": "",
|
||||
"homepage": "https://staticjscms.github.io/static-cms/",
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"@emotion/cache": "^10.0.29",
|
||||
"@emotion/core": "^10.0.35",
|
||||
"@emotion/styled": "^10.0.27",
|
||||
"dayjs": "^1.8.23",
|
||||
"emotion-theming": "^10.0.27",
|
||||
"gatsby": "3.14.6",
|
||||
"gatsby-plugin-catch-links": "3.14.0",
|
||||
"gatsby-plugin-emotion": "^4.0.0",
|
||||
"gatsby-plugin-manifest": "3.14.0",
|
||||
"gatsby-plugin-netlify-cms": "5.14.0",
|
||||
"gatsby-plugin-react-helmet": "4.14.0",
|
||||
"gatsby-remark-autolink-headers": "4.11.0",
|
||||
"gatsby-remark-external-links": "^0.0.4",
|
||||
"gatsby-remark-prismjs": "5.11.0",
|
||||
"gatsby-source-filesystem": "3.14.0",
|
||||
"gatsby-transformer-json": "3.14.0",
|
||||
"gatsby-transformer-remark": "4.11.0",
|
||||
"gatsby-transformer-yaml": "3.14.0",
|
||||
"js-yaml": "^4.0.0",
|
||||
"lodash": "^4.17.15",
|
||||
"moment": "^2.24.0",
|
||||
"netlify-cms-app": "^2.15.72",
|
||||
"prismjs": "^1.21.0",
|
||||
"react": "^17.0.1",
|
||||
"react-dom": "^17.0.1",
|
||||
"react-helmet": "^6.0.0",
|
||||
"react-markdown": "^6.0.0",
|
||||
"smooth-scroll": "^16.1.2"
|
||||
"@emotion/react": "11.10.4",
|
||||
"@emotion/styled": "11.10.4",
|
||||
"@mui/icons-material": "5.10.9",
|
||||
"@mui/material": "5.10.10",
|
||||
"date-fns": "2.29.3",
|
||||
"gray-matter": "4.0.3",
|
||||
"js-yaml": "4.1.0",
|
||||
"next": "12.3.1",
|
||||
"next-mdx-remote": "4.1.0",
|
||||
"next-pwa": "5.6.0",
|
||||
"prismjs": "1.29.0",
|
||||
"react": "18.2.0",
|
||||
"react-dom": "18.2.0",
|
||||
"react-schemaorg": "2.0.0",
|
||||
"remark-gfm": "3.0.1",
|
||||
"schema-dts": "1.1.0"
|
||||
},
|
||||
"devDependencies": {
|
||||
"babel-plugin-prismjs": "^2.0.1",
|
||||
"babel-preset-gatsby": "^1.0.0",
|
||||
"eslint": "^7.4.0",
|
||||
"eslint-plugin-import": "^2.20.1",
|
||||
"markdownlint-cli": "^0.31.0"
|
||||
},
|
||||
"private": true
|
||||
"@babel/core": "7.19.6",
|
||||
"@emotion/eslint-plugin": "11.10.0",
|
||||
"@next/bundle-analyzer": "12.3.1",
|
||||
"@types/js-yaml": "4.0.5",
|
||||
"@types/node": "18.11.3",
|
||||
"@types/prismjs": "1.26.0",
|
||||
"@types/react": "18.0.21",
|
||||
"@types/react-dom": "18.0.6",
|
||||
"@typescript-eslint/eslint-plugin": "5.40.1",
|
||||
"@typescript-eslint/parser": "5.40.1",
|
||||
"babel-eslint": "10.1.0",
|
||||
"eslint": "8.25.0",
|
||||
"eslint-config-next": "12.3.1",
|
||||
"eslint-config-prettier": "8.5.0",
|
||||
"eslint-plugin-babel": "5.3.1",
|
||||
"eslint-plugin-unicorn": "44.0.2",
|
||||
"prettier": "2.7.1",
|
||||
"typescript": "4.8.4"
|
||||
}
|
||||
}
|
||||
|
BIN
website/public/favicon-32x32.png
Normal file
After Width: | Height: | Size: 2.4 KiB |
BIN
website/public/favicon.ico
Normal file
After Width: | Height: | Size: 25 KiB |
Before Width: | Height: | Size: 30 KiB After Width: | Height: | Size: 30 KiB |
Before Width: | Height: | Size: 6.3 KiB After Width: | Height: | Size: 6.3 KiB |
Before Width: | Height: | Size: 8.8 KiB After Width: | Height: | Size: 8.8 KiB |
Before Width: | Height: | Size: 4.2 KiB After Width: | Height: | Size: 4.2 KiB |
Before Width: | Height: | Size: 162 KiB After Width: | Height: | Size: 162 KiB |
Before Width: | Height: | Size: 31 KiB After Width: | Height: | Size: 31 KiB |
Before Width: | Height: | Size: 21 KiB After Width: | Height: | Size: 21 KiB |
Before Width: | Height: | Size: 17 KiB After Width: | Height: | Size: 17 KiB |
Before Width: | Height: | Size: 71 KiB After Width: | Height: | Size: 71 KiB |
Before Width: | Height: | Size: 21 KiB After Width: | Height: | Size: 21 KiB |
Before Width: | Height: | Size: 30 KiB After Width: | Height: | Size: 30 KiB |