Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Intro docs #233

Merged
merged 5 commits into from
Feb 8, 2017
Merged
Show file tree
Hide file tree
Changes from 4 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Binary file added docs/images/github-oauth.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
115 changes: 115 additions & 0 deletions docs/intro.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,115 @@
# Introduction

Netlify CMS is a Content Management System for static sites, allowing collaborators to create, edit, review, and publish content without writing code or dealing with version control. It brings the ease of WordPress-style editing to the simplicity and speed of static sites.

At its core, Netlify CMS is an open-source React app that acts as a wrapper for the Git workflow, using the GitHub API. This allows for many advantages, including:

* **Fast, web-based UI** - with rich-text editing, real-time preview, and drag-and-drop media uploads
* **Platform agnostic** - works with most static site generators
* **Easy installation** - add two files to your site and hook up the backend by including in your build process or linking to our CDN
* **Modern authentication** - using GitHub and JSON web tokens
* **Flexible content types** - specify an unlimited number of content types with custom fields
* **Fully extensible** - create custom-styled previews, UI widgets, and editor plugins

# Core Concepts

## The Admin Interface

The admin interface is a single-page app with the entry point stored in a static `/admin` folder you add to the root of your site. You can include it with a simple `index.html` file that loads the necessary CSS and JS files from from a CDN:

``` html
<!doctype html>
<html>
<head>
<meta charset="utf-8" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<title>Content Manager</title>

<link rel="stylesheet" href="https://unpkg.com/netlify-cms@^0.3/dist/cms.css" />

</head>
<body>
<script src="https://unpkg.com/netlify-cms@^0.3/dist/cms.js"></script>
</body>
</html>
```

The JS is also available via npm and can be integrated into your regular build process.

### Editorial Workflow

Netlify CMS has an optional [editorial workflow](https://github.com/netlify/netlify-cms/blob/master/docs/editorial_workflow.md) that translates common Git commands into familiar language in a simple UI:

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

In this section, this is not exactly how the Editorial Workflow currently works. Currently, it creates a branch, pushes a commit AND opens the PR all at the same time. Changing the status (draft, waiting for review, ready to publish) triggers no GIT actions.

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

(I like the way you described more, though. Maybe in a future version of the CMS, hehe)

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Hm, so it does! Apparently when I was testing, I didn't look for the PR until I was expecting to find it. 😛 I'll update.


Actions in Netlify UI... | Perform these Git actions
--- | ---
Save draft | Creates a branch and pushes a commit to it
Edit draft | Pushes another commit to the draft branch
Mark draft as Waiting for Review | Opens a pull request
Approve and publish draft | Merges pull request and deletes branch

If you prefer to use Git, you can push additional commits and open and merge PRs directly, and the Netlify CMS interface will update to match.

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The CMS interface will update if the user commits new content, but it wont update for new PRs.
What happens is: Behind the scenes, the CMS creates a metadata branch on the repository, invisible to the end-user. When the CMS creates a new PR, it also saves all data related to this PR in it's metadata branch - which means that PRs created outside the CMS will be ignored by it.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yeah, this only made sense when I thought draft saving didn't create a PR. Rather than get into the details, I'm now thinking I'll just remove the line.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Updated the table and removed the line after. Now it feels kind of abrupt, but probably ok. Heading to a meeting. Will update the branch if I change my mind after. :)


## Configuration

All configuration is handled in a single `config.yml` file, also stored in the `/admin` folder. A simple version might look like this:

``` yaml
backend:
name: github
repo: owner/repo # Path to your Github repository
branch: master # Branch to update (master by default)

media_folder: "img/uploads" # Folder where user uploaded files should go

collections: # A list of collections the CMS should be able to edit
- name: "post" # Used in routes, ie.: /admin/collections/:slug/edit
label: "Post" # Used in the UI, ie.: "New Post"
folder: "_posts" # The path to the folder where the documents are stored
create: true # Allow users to create new documents in this collection
fields: # The fields each document in this collection have
- {label: "Title", name: "title", widget: "string", tagname: "h1"}
- {label: "Body", name: "body", widget: "markdown"}
- {label: "Foo", name: "foo", widget: "foo"}
- {label: "Publish Date", name: "date", widget: "datetime"}
```

### Backend

Because Netlify CMS is a wrapper for the GitHub API, the "backend" is a repo stored on GitHub. *(Using a different Git host? File a [feature request](https://github.com/netlify/netlify-cms/issues), or [help us add it](https://github.com/netlify/netlify-cms/blob/master/CONTRIBUTING.md)!)* For authentication, you can connect to GitHub using Netlify’s [Authentication Provider feature](https://www.netlify.com/docs/authentication-providers), or you can roll your own.

### Collections

All content managed by Netlify CMS is organized in Collections—groups of files such as:

* blog posts
* portfolio samples
* product listings
* podcast episodes

You point to where the files are stored, and specify the fields that define them. The `body` field typically stores the main text of a file, while any other fields are included at the top of the document in the front matter. They can be required, optional, or hidden, and can have preset defaults.

### Widgets

Widgets define the data type and interface for entry fields. Netlify CMS comes with several built-in widgets, including:

Widget | UI | Data Type
--- | --- | ---
`string` | text input | string
`number` | text input with `+` and `-` buttons | number
`markdown` | rich text editor with raw option | markdown-formatted string
`datetime` | date picker widget | ISO date string
`image` | file picker widget with drag-and-drop | file path saved as string, image uploaded to media folder

We’re always adding new widgets, and you can also create your own.

## Customization

Netlify CMS exposes a `window.CMS` global object that you can use to register custom widgets, previews, and editor plugins. The available methods are:

* `registerPreviewStyle` - register a custom stylesheet to match the editor preview pane to your site style

* `registerPreviewTemplate` - registers a template to determine how fields are displayed in the preview, customizable for each collection

* `registerWidget` - registers a custom widget

* `registerEditorComponent` - adds a block component to the Markdown editor
199 changes: 199 additions & 0 deletions docs/quick-start.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,199 @@
# Quick Start

There are many ways to add Netlify CMS to your static site. This guide will take you through one of the quickest, which takes advantage of Netlify's hosting and authentication provider services.

## Storage and Authentication

Netlify CMS relies on the GitHub API for managing files, so you'll need to have your site stored in a GitHub repo. (If you're partial to another Git hosting service, you can file a [feature request](https://github.com/netlify/netlify-cms/issues), or [help us add it](https://github.com/netlify/netlify-cms/blob/master/CONTRIBUTING.md).) To connect to the repo and make changes, the app needs to authenticate with the GitHub API. You can roll your own service for doing this, but we're going to use Netlify.

### Hosting with Netlify

In order to use Nelify's authentication provider service, you'll need to connect your site repo with Netlify. Netlify has published a general [Step-by-Step Guide](https://www.netlify.com/blog/2016/10/27/a-step-by-step-guide-deploying-a-static-site-or-single-page-app/) for this, along with detailed guides for many popular static site generators, including [Jekyll](https://www.netlify.com/blog/2015/10/28/a-step-by-step-guide-jekyll-3.0-on-netlify/), [Hugo](https://www.netlify.com/blog/2016/09/21/a-step-by-step-guide-hugo-on-netlify/), [Hexo](https://www.netlify.com/blog/2015/10/26/a-step-by-step-guide-hexo-on-netlify/), [Middleman](https://www.netlify.com/blog/2015/10/01/a-step-by-step-guide-middleman-on-netlify/), and more.

### Authenticating with GitHub

In order to connect Netlify CMS with your GitHub repo, you'll first need to register it as an authorized application with your GitHub account:
1. Go to your account **Settings** page on GitHub, and click **Oauth Applications** under **Developer Settings** (or use [this shortcut](https://github.com/settings/developers)).
2. Click **Register a new application**.
3. For the **Authorization callback URL**, enter `https://api.netlify.com/auth/done`. The other fields can contain anything you want.

![GitHub Oauth Application setup example](images/github-oauth.png?raw=true)

When you complete the registration, you'll be given a **Client ID** and a **Client Secret** for the app. You'll need to add these to your Netlify project:
1. Go to your [**Netlify dashboard**](https://app.netlify.com/) and click on your project.
2. Click the **Access** tab.
3. Under **Authentication Providers**, click **Install Provider**.
4. Select GitHub and enter the **Client ID** and **Client Secret**, then save.

## App File Structure
All Netlify CMS files are contained in a static `admin` folder, stored at the root of the generated site. Where you store this in the source files depends on your static site generator. Here's the the static file location for a few of the most popular static site generators:

These generators... | store static files in
--- | ---
Jekyll, GitBook | `/` (project root)
Hugo | `/static`
Hexo, Middleman | `/source`

If your generator isn't listed here, you can check its documentation, or as a shortcut, look in your project for a `CSS` or `images` folder. They're usually processed as static files, so it's likely you can store your `admin` folder next to those. (When you've found the location, feel free to add it to these docs!).

Inside the `admin` folder, you'll create two files:

```
admin
├ index.html
└ config.yml
```

The first file, `admin/index.html`, is the entry point for the Netlify CMS admin interface. This means that users can navigate to `yoursite.com/admin` to access it. On the code side, it's a basic HTML starter page that loads the necessary CSS and JavaScript files. In this example, we pull those files from a public CDN:

``` html
<!doctype html>
<html>
<head>
<meta charset="utf-8" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<title>Content Manager</title>

<link rel="stylesheet" href="https://unpkg.com/netlify-cms@^0.3/dist/cms.css" />

</head>
<body>
<script src="https://unpkg.com/netlify-cms@^0.3/dist/cms.js"></script>
</body>
</html>
```

The second file, `admin/config.yml`, is the heart of your Netlify CMS installation, and a bit more complex. The next section covers the details.

## Configuration
Configuration will be different for every site, so we'll break it down into parts. All code snippets in this section will be added to your `admin/config.yml` file.

### Backend
Because we're using GitHub and Netlify for our hosting and authentication, backend configuration is fairly strightforward. You can start your `config.yml` file with these lines:

``` yaml
backend:
name: github
repo: owner-name/repo-name # Path to your Github repository
branch: master # Branch to update
```

This names GitHub as the authentication provider, points to the repo location on github.com, and declares the branch where you want to merge changes. If you leave out the `branch` declaration, it will default to `master`.

### Editorial Workflow
By default, saving a post in the CMS interface will push a commit directly to the branch specified in `backend`. However, you also have the option to enable the [Editorial Workflow](editorial_workflow.md), which adds an interface for drafting, reviewing, and approving posts. To do this, simply add this line to your `config.yml`:

``` yaml
publish_mode: editorial_workflow
```

### Media and Public Folders
Netlify 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
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. It would not, however, work for Hugo, Hexo, Middleman, or others that use a different path. Here's an example that could work for a Hugo site:

``` yaml
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
```

This configuration adds a new setting, `public_folder`. While `media_folder` specifies where uploaded files will be saved in the repo, `public_folder` indicates where they can be found in the generated site. This path is used in image `src` attributes and 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, Netlify CMS will default 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 will be very different 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:

``` 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
create: true # Allow users to create new documents in this collection
slug: "{{year}}-{{month}}-{{day}}-{{slug}}" # Filename template i.e. 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"}
```

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 post type will be called in the admin UI.</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> will pull 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>

As described above, the `widget` property specifies a built-in or custom UI widget for a given field. The first field in the example, `layout`, uses a `hidden` widget. This widget will not show in the editor UI, but will be saved with the `default` value (assuming it's been set) in the document front matter. The rest of the widgets work as follows:

Widget | UI | Data Type
--- | --- | ---
`string` | text input | string
`datetime` | date picker widget | ISO date string
`image` | file picker widget with drag-and-drop | file path saved as string, image uploaded to media folder
`number` | text input with `+` and `-` buttons | number
`markdown` | rich text editor with raw option | markdown-formatted string



Based on this example, you can go through the post types in your site and add the appropriate settings to your `config.yml` file. Each post type should be listed as a separate node under the `collections` field.

## Accessing the App

With your configuration complete, it's time to try it out! Go to `yoursite.com/admin` and complete the login prompt to access the admin interface. To add users, simply add them as collaborators on the GitHub repo.

Happy posting!