convert website from hugo to gatsby (#1369)
This commit is contained in:
committed by
Shawn Erquhart
parent
d6c03707d8
commit
04c44518b2
0
website/content/.keep
Executable file
0
website/content/.keep
Executable file
@ -0,0 +1,32 @@
|
||||
---
|
||||
title: Netlify CMS now supports GitLab as a backend
|
||||
author: Benaiah Mischenko
|
||||
description: >-
|
||||
Netlify CMS, the open source, headless CMS that provides a user-friendly UI
|
||||
around your Git repository, can now be used with GitLab in addition to
|
||||
GitHub.
|
||||
date: '2018-06-13'
|
||||
---
|
||||
Netlify CMS is releasing support for GitLab as a backend, creating the world's first completely open source stack for Git-based content editing.
|
||||
|
||||
<iframe width="100%" height="400" src="https://www.youtube.com/embed/ZrM3U0z8Sks?autoplay=1&loop=1&playlist=ZrM3U0z8Sks&mute=1&controls=0&modestbranding=1&showinfo=0" frameborder="0" allow="autoplay; encrypted-media" allowfullscreen></iframe>
|
||||
|
||||
We heard [you](https://github.com/netlify/netlify-cms/pull/517#issuecomment-383283557) (and [you](https://github.com/netlify/netlify-cms/pull/517#issuecomment-355386542), and [you](https://github.com/netlify/netlify-cms/pull/517#issuecomment-343569725), and [you](https://github.com/netlify/netlify-cms/pull/517#issuecomment-333629637))! While you want to use Netlify CMS as the headless content management system for your JAMstack projects, all of your code lives in GitLab. Our long-term vision is to be tool-agnostic so you can use whatever tool helps you work best. But while you can already use Netlify CMS with most static site generators, backend support was limited to GitHub.
|
||||
|
||||
Immediately after the December release of Netlify CMS 1.0, contributors got to work on improving the API for backend integrations. At the urging of the community, we prioritized support for GitLab. With today’s release of Netlify CMS 1.9.0, you can now use GitLab as the backend for Netlify CMS.
|
||||
|
||||
Adding support for GitLab means that millions more developers can now use Netlify CMS with their projects. Seriously — millions. GitLab is used by more than 100,000 organizations like Ticketmaster, Intel, Red Hat, and CERN.
|
||||
|
||||
## How it works
|
||||
|
||||
Netlify CMS is an open source content management system for your Git workflow that enables you to provide editors with a friendly UI and intuitive workflow. You can use it with any static site generator to create faster, more flexible web projects. Content is stored in your GitLab repository alongside your code for easier versioning, multi-channel publishing, and the option to handle content updates directly in Git.
|
||||
|
||||
In case you want an even easier way to get started, or just want to poke around in the code, you can use the button below to automatically deploy a starter site that uses the Hugo static site generator along with Netlify CMS.
|
||||
|
||||
<a href="https://app.netlify.com/start/deploy?repository=https://gitlab.com/netlify-templates/one-click-hugo-cms&stack=cms" rel="nofollow noreferrer noopener" target="_blank"><img src="https://www.netlify.com/img/deploy/button.svg" alt="Deploy to Netlify"></a>
|
||||
|
||||
Lastly, one particularly exciting thing about using GitLab as your backend is that it doesn’t require an authentication server. While the GitHub integration requires a hop to an authentication server (something Netlify provides for most users), GitLab’s implicit auth flow allows you to connect directly from your browser to gitlab.com, or even to your own self-hosted GitLab server!
|
||||
|
||||
## What’s next
|
||||
|
||||
We’re already working toward [Bitbucket](https://github.com/netlify/netlify-cms/pull/525) support and will be releasing it as soon as possible! We’re also focused on the upcoming release of [Netlify CMS 2.0](https://github.com/netlify/netlify-cms/issues/1280), which will bring new image handling features and improvements, and improved APIs for better CMS extensions. We’re also looking for more ideas and helping hands, so if you’re keen to build a smarter, safer, and more scalable CMS, we’d love your contributions. Give us a shout on [Twitter](https://twitter.com/netlifycms) or Gitter if you have questions or ideas.
|
275
website/content/docs/add-to-your-site.md
Executable file
275
website/content/docs/add-to-your-site.md
Executable file
@ -0,0 +1,275 @@
|
||||
---
|
||||
title: Add to Your Site
|
||||
weight: 20
|
||||
group: start
|
||||
---
|
||||
|
||||
Netlify CMS is adaptable 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 will guide you through the steps for adding Netlify 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](https://www.netlifycms.org/docs/start-with-a-template) or dive right into to [configuration options](https://www.netlifycms.org/docs/configuration-options).
|
||||
|
||||
## App File Structure
|
||||
|
||||
All Netlify CMS files are contained in a static `admin` folder, stored at the root of your published site. Where you store this folder in the source files depends on your static site generator. Here's 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, Gatsby, Nuxt | `/static` |
|
||||
| Hexo, Middleman | `/source` |
|
||||
| Spike | `/views` |
|
||||
| Wyam | `/input` |
|
||||
|
||||
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. The contents of folders like that are 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 by [filing a pull request](https://github.com/netlify/netlify-cms/blob/master/CONTRIBUTING.md)!)
|
||||
|
||||
Inside the `admin` folder, you'll create two files:
|
||||
|
||||
```x
|
||||
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>
|
||||
|
||||
<!-- Include the styles for the Netlify CMS UI, after your own styles -->
|
||||
<link rel="stylesheet" href="https://unpkg.com/netlify-cms@^1.0.0/dist/cms.css" />
|
||||
|
||||
</head>
|
||||
<body>
|
||||
<!-- Include the script that builds the page and powers Netlify CMS -->
|
||||
<script src="https://unpkg.com/netlify-cms@^1.0.0/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 [Configuration](#configuration) section covers the details.
|
||||
|
||||
### Installing with npm
|
||||
|
||||
You can also use Netlify CMS as an npm module. Wherever you import Netlify CMS, it will automatically run, taking over the current page. Make sure the script that imports it is only run on your CMS page. First install the package and save it to your project:
|
||||
|
||||
```bash
|
||||
npm install netlify-cms --save
|
||||
```
|
||||
|
||||
Then import it (assuming your project has tooling for imports):
|
||||
|
||||
```js
|
||||
import CMS from 'netlify-cms'
|
||||
|
||||
// Now the registry is available via the CMS object.
|
||||
CMS.registerPreviewTemplate('my-template', MyTemplate)
|
||||
```
|
||||
|
||||
## 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
|
||||
|
||||
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 Netlify CMS `config.yml` file with these lines:
|
||||
|
||||
```yaml
|
||||
backend:
|
||||
name: git-gateway
|
||||
branch: master # Branch to update (optional; defaults to master)
|
||||
```
|
||||
|
||||
_(For Bitbucket repositories, use the [Bitbucket backend](https://www.netlifycms.org/docs/authentication-backends/#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 will default to `master`.
|
||||
|
||||
### Editorial Workflow
|
||||
|
||||
**Note:** Editorial workflow works with GitHub repositories only. Support for other Git hosts is [coming soon](https://github.com/netlify/netlify-cms/issues/568).
|
||||
|
||||
By default, saving a post in the CMS interface will push a commit directly to the publication branch specified in `backend`. However, you also have the option to enable the [Editorial Workflow](https://www.netlifycms.org/docs/configuration-options/#publish-mode), which adds an interface for drafting, reviewing, and approving posts. To do this, add the following line to your Netlify CMS `config.yml`:
|
||||
|
||||
```yaml
|
||||
# This line should *not* be indented
|
||||
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
|
||||
# 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 will be saved in the repo, `public_folder` indicates where they can be found in the published 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, 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"}
|
||||
```
|
||||
|
||||
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. When a content editor enters a value into a widget, that value will be 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](https://www.netlifycms.org/docs/widgets).
|
||||
|
||||
Based on this example, you can go through the post types in your site and add the appropriate settings to your Netlify CMS `config.yml` file. Each post type should be listed as a separate node under the `collections` field.
|
||||
|
||||
### Filter
|
||||
|
||||
The entries for any collection can be filtered based on the value of a single field. The example collection below would only show 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"}
|
||||
```
|
||||
|
||||
## Authentication
|
||||
|
||||
Now that you have your Netlify CMS files in place and configured, all that's left is to enable authentication. There are [many ways to do this](https://www.netlifycms.org/docs/authentication-backends) (with or without deploying to Netlify), but this example uses Netlify because it's one of the quickest ways to get started.
|
||||
|
||||
### Setup on Netlify
|
||||
|
||||
Netlify offers a built-in authentication service called Identity. In order to use it, 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-victor-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/), [Gatsby](https://www.netlify.com/blog/2016/02/24/a-step-by-step-guide-gatsby-on-netlify/) and more.
|
||||
|
||||
### 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'll 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 will authenticate with your Git host and generate 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, you'll need to add the following script tag in two places:
|
||||
|
||||
```html
|
||||
<script src="https://identity.netlify.com/v1/netlify-identity-widget.js"></script>
|
||||
```
|
||||
|
||||
You'll need to 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, they will be directed to the site homepage with an access token. In order to complete the login and get back to the CMS, we'll need to 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 will not work on IE11. For legacy browser support, use function expressions (`function () {}`) in place of the arrow functions (`() => {}`), or use a transpiler like [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," you'll need to 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 will 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 comfirming an email invitation, you can access your site's CMS at `yoursite.com/admin/`.
|
||||
|
||||
Happy posting!
|
77
website/content/docs/architecture.md
Executable file
77
website/content/docs/architecture.md
Executable file
@ -0,0 +1,77 @@
|
||||
---
|
||||
title: Architecture
|
||||
position: 90
|
||||
group: contributing
|
||||
---
|
||||
|
||||
Netlify CMS is a React application, using Redux for state management with immutable data structures (immutable.js).
|
||||
|
||||
The core abstractions for content editing are `collections`, `entries` and `widgets`.
|
||||
|
||||
Each `collection` represents a collection of entries. This can either be a collection of similar entries with the same structure, or a set of entries where each has its own structure.
|
||||
|
||||
The structure of an entry is defined as a series of fields, each with a `name`, a `label`, and a `widget` .
|
||||
|
||||
The `widget` determines the UI widget that the content editor will use when editing this field of an entry, as well as how the content of the field is presented in the editing preview.
|
||||
|
||||
Entries are loaded and persisted through a `backend` that will typically represent a `git` repository.
|
||||
|
||||
## State shape / reducers
|
||||
**Auth:** Keeps track of the logged state and the current user.
|
||||
|
||||
**Config:** Holds the environment configuration (backend type, available collections and fields).
|
||||
|
||||
**Collections** List of available collections, their fields and metadata information.
|
||||
|
||||
**Entries:** Entries for each field.
|
||||
|
||||
**EntryDraft:** Reused for each entry that is edited or created. It holds the entry's temporary data until it's persisted on the backend.
|
||||
|
||||
## Selectors
|
||||
Selectors are functions defined within reducers used to compute derived data from the Redux store. The available selectors are:
|
||||
|
||||
**selectEntry:** Selects a single entry, given the collection and a slug.
|
||||
|
||||
**selectEntries:** Selects all entries for a given collection.
|
||||
|
||||
**getAsset:** Selects a single AssetProxy object for the given URI.
|
||||
|
||||
## Value Objects
|
||||
**AssetProxy:** AssetProxy is a Value Object that holds information regarding an asset file (such as an image, for example), whether it's persisted online or held locally in cache.
|
||||
|
||||
For a file persisted online, the AssetProxy only keeps information about its URI. For local files, the AssetProxy will keep a reference to the actual File object while generating the expected final URIs and on-demand blobs for local preview.
|
||||
|
||||
The AssetProxy object can be used directly inside a media tag (such as `<img>`), as it will always return something that can be used by the media tag to render correctly (either the URI for the online file or a single-use blob).
|
||||
|
||||
## Components structure and Workflows
|
||||
Components are separated into two main categories: Container components and Presentational components.
|
||||
|
||||
### Entry Editing
|
||||
For either updating an existing entry or creating a new one, the `EntryEditor` is used and the flow is the same:
|
||||
|
||||
* When mounted, the `EntryPage` container component dispatches the `createDraft` action, setting the `entryDraft` state to a blank state (in case of a new entry) or to a copy of the selected entry (in case of an edit).
|
||||
* The `EntryPage` will also render widgets for each field type in the given entry.
|
||||
* Widgets are used for editing entry fields. There are different widgets for different field types, and they are always defined in a pair containing a `control` and a `preview` component. The control component is responsible for presenting the user with the appropriate interface for manipulating the current field value, while the preview component is responsible for displaying the value with the appropriate styling.
|
||||
|
||||
#### Widget components implementation
|
||||
The control component receives one (1) callback as a prop: `onChange`.
|
||||
|
||||
* onChange (required): Should be called when the users changes the current value. It will ultimately end up updating the EntryDraft object in the Redux Store, thus updating the preview component.
|
||||
* onAddAsset & onRemoveAsset (optionals): If the field accepts file uploads for media (images, for example), these callbacks should be invoked with a `AssetProxy` value object. `onAddAsset` will get the current media stored in the Redux state tree while `onRemoveAsset` will remove it. AssetProxy objects are stored in the `Medias` object and referenced in the `EntryDraft` object on the state tree.
|
||||
|
||||
Both control and preview widgets receive a `getAsset` selector via props. Displaying the media (or its URI) for the user should always be done via `getAsset`, as it returns an AssetProxy that can return the correct value for both medias already persisted on the server and cached media not yet uploaded.
|
||||
|
||||
The actual persistence of the content and medias inserted into the control component is delegated to the backend implementation. The backend will be called with the updated values and a list of assetProxy objects for each field of the entry, and should return a promise that can resolve into the persisted entry object and the list of the persisted media URIs.
|
||||
|
||||
|
||||
## Editorial Workflow implementation
|
||||
|
||||
Instead of adding logic to `CollectionPage` and `EntryPage`, the Editorial Workflow is implemented as Higher Order Components, adding UI and dispatching additional actions.
|
||||
|
||||
Furthermore, all editorial workflow state is managed in Redux - there's an `actions/editorialWorkflow.js` file and a `reducers/editorialWorkflow.js` file.
|
||||
|
||||
### About metadata
|
||||
|
||||
Netlify CMS embraces the idea of Git-as-backend for storing metadata. The first time it runs with the editorial_workflow setup, it creates a new ref called `meta/_netlify_cms`, pointing to an empty, orphan tree.
|
||||
|
||||
Actual data are stored in individual `json` files committed to this tree.
|
156
website/content/docs/authentication-backends.md
Normal file
156
website/content/docs/authentication-backends.md
Normal file
@ -0,0 +1,156 @@
|
||||
---
|
||||
title: Authentication & Backends
|
||||
weight: 25
|
||||
group: start
|
||||
---
|
||||
|
||||
Netlify CMS stores content in your GitHub, GitLab, or Bitbucket repository. In order for this to work, you need to authenticate with your Git host, and in most cases that requires a server. We have a few options for handling this.
|
||||
|
||||
**Note:** some static site generators have plugins for optimized integration with Netlify CMS, and starter templates may utilize these plugins. If you're using a starter template, read the template documentation before proceeding, as their instructions may differ.
|
||||
|
||||
## Git Gateway with Netlify Identity
|
||||
|
||||
[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.) [Netlify Identity](https://www.netlify.com/docs/identity/) service can handle the authentication and provides a simple interface for user management. The Netlify CMS [featured templates](https://www.netlifycms.org/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:
|
||||
|
||||
1. Head over to the [Netlify Identity docs](https://www.netlify.com/docs/identity) and follow the
|
||||
steps to get started.
|
||||
2. Add the following lines to your Netlify CMS `config.yml` file:
|
||||
|
||||
```yaml
|
||||
backend:
|
||||
name: git-gateway
|
||||
accept_roles: #optional - accepts all users if left out
|
||||
- admin
|
||||
- editor
|
||||
```
|
||||
|
||||
3. Optionally, you can assign roles to users in your Netlify dashboard, and then limit which
|
||||
roles can access the CMS by defining the `accept_roles` field as shown in the example above.
|
||||
Otherwise `accept_roles` can be left out, and all Netlify Identity users on your site will have access.
|
||||
|
||||
## Git Gateway without Netlify
|
||||
|
||||
You can use [Git Gateway](https://github.com/netlify/git-gateway) without Netlify by setting up your own Git Gateway server and connecting it with your own instance of [GoTrue](https://www.gotrueapi.org) (the open source microservice that powers Netlify Identity), or with any other identity service that can issue JSON Web Tokens (JWT).
|
||||
|
||||
To configure in Netlify CMS, use the same `backend` settings in your Netlify CMS `config.yml` file as described in Step 2 of the [Git Gateway with Netlify Identity](#git-gateway-with-netlify-identity) instructions above.
|
||||
|
||||
## GitHub Backend
|
||||
|
||||
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.
|
||||
|
||||
Because Github [requires a
|
||||
server](https://github.com/netlify/netlify-cms/issues/663#issuecomment-335023723) for
|
||||
authentication, Netlify facilitates basic GitHub authentication.
|
||||
|
||||
To enable it:
|
||||
|
||||
1. Follow the authentication provider setup steps in the [Netlify
|
||||
docs](https://www.netlify.com/docs/authentication-providers/#using-an-authentication-provider).
|
||||
2. Add the following lines to your Netlify CMS `config.yml` file:
|
||||
|
||||
```yaml
|
||||
backend:
|
||||
name: github
|
||||
repo: owner-name/repo-name # Path to your GitHub repository
|
||||
```
|
||||
|
||||
If you prefer to run your own authentication server, check out the section on [external OAuth clients](#external-oauth-clients).
|
||||
|
||||
## GitLab Backend
|
||||
|
||||
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.
|
||||
|
||||
The GitLab API allows for two types of OAuth2 flows: [Web Application Flow](https://docs.gitlab.com/ce/api/oauth2.html#web-application-flow), which works much like the GitHub OAuth flow described above, and [Implicit Grant](https://docs.gitlab.com/ce/api/oauth2.html#implicit-grant), which operates _without_ the need for an authentication server.
|
||||
|
||||
### Web Application Flow with Netlify
|
||||
|
||||
When using GitLab's Web Application Flow for authentication, you can use Netlify to handle the server-side authentication requests.
|
||||
|
||||
To enable it:
|
||||
|
||||
1. Follow the [GitLab docs](https://docs.gitlab.com/ee/integration/oauth_provider.html#adding-an-application-through-the-profile) to add your Netlify CMS instance as an OAuth application. For the **Redirect URI**, enter `https://api.netlify.com/auth/done`, and check the box for `api` scope.
|
||||
2. Follow the [Netlify
|
||||
docs](https://www.netlify.com/docs/authentication-providers/#using-an-authentication-provider) to add your new GitLab Application ID and Secret to your Netlify site dashboard.
|
||||
2. In your repository, add the following lines to your Netlify CMS `config.yml` file:
|
||||
|
||||
```yaml
|
||||
backend:
|
||||
name: gitlab
|
||||
repo: owner-name/repo-name # Path to your GitLab repository
|
||||
```
|
||||
|
||||
### Client-Side Implicit Grant
|
||||
|
||||
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 Netlify CMS instance as an OAuth application. For the **Redirect URI**, enter the address where you access Netlify CMS, for example, `https://www.mysite.com/admin/`. For scope, select `api`.
|
||||
2. GitLab will give you an **Application ID**. Copy this and enter it in your Netlify 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 that in both cases, GitLab will also provide you with a client secret. You should _never_ store this in your repo or reveal it in the client.
|
||||
|
||||
## Bitbucket Backend
|
||||
|
||||
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.
|
||||
|
||||
To enable it:
|
||||
|
||||
1. Follow the authentication provider setup steps in the [Netlify
|
||||
docs](https://www.netlify.com/docs/authentication-providers/#using-an-authentication-provider).
|
||||
2. Add the following lines to your Netlify CMS `config.yml` file:
|
||||
|
||||
```yaml
|
||||
backend:
|
||||
name: bitbucket
|
||||
repo: owner-name/repo-name # Path to your Bitbucket repository
|
||||
```
|
||||
|
||||
## External OAuth Clients
|
||||
|
||||
If you would like to facilitate your own OAuth authentication rather than use Netlify's service or implicit grant, you
|
||||
can use one of the community-maintained projects below. Feel free to [submit a pull request](https://github.com/netlify/netlify-cms/blob/master/CONTRIBUTING.md) if you'd like to add yours!
|
||||
|
||||
| Author | Supported Git hosts | Language(s)/Platform(s) | Link |
|
||||
| ---------------------------------------------- | ------------------------- | ----------------------- | -------------------------------------------------------------------------------------------------------------------------------------------- |
|
||||
| [@vencax](https://github.com/vencax) | GitHub, GitHub Enterprise | Node.js | [Repo](https://github.com/vencax/netlify-cms-github-oauth-provider) |
|
||||
| [@igk1972](https://github.com/igk1972) | GitHub, GitHub Enterprise | Go | [Repo](https://github.com/igk1972/netlify-cms-oauth-provider-go) |
|
||||
| [@davidejones](https://github.com/davidejones) | GitHub, GitHub Enterprise | Python | [Repo](https://github.com/davidejones/netlify-cms-oauth-provider-python) |
|
||||
| [@marksteele](https://github.com/marksteele) | GitHub, GitHub Enterprise | Serverless | [Repo](https://github.com/marksteele/netlify-serverless-oauth2-backend), [Blog](https://www.control-alt-del.org/blog/serverless-blog-howto/) |
|
||||
|
||||
Check each project's documentation for instructions on how to configure it.
|
||||
|
||||
## Options
|
||||
|
||||
Netlify CMS backends allow some additional fields for certain use cases. A full reference is below. Note that these are properties of the `backend` field, and should be nested under that field.
|
||||
|
||||
| Field | Default | Description |
|
||||
| --------------- | -------------------------------------------------------------- | ---------------------------------------------------------------------------------------------------------------------------------------------------- |
|
||||
| `repo` | none | **Required** for `github`, `gitlab`, and `bitbucket` backends; ignored by `git-gateway`. Follows the pattern `[org-or-username]/[repo-name]`. |
|
||||
| `accept_roles` | none | `git-gateway` only. Limits CMS access to your defined array of user roles. Omitting this field gives access to all registered users. |
|
||||
| `branch` | `master` | The branch where published content is stored. All CMS commits and PRs are made to this branch. |
|
||||
| `api_root` | `https://api.github.com` (GitHub), `https://gitlab.com/api/v4` (GitLab), or `https://api.bitbucket.org/2.0` (Bitbucket) | The API endpoint. Only necessary in certain cases, like with GitHub Enterprise or self-hosted GitLab. |
|
||||
| `site_domain` | `location.hostname` (or `cms.netlify.com` when on `localhost`) | Sets the `site_id` query param sent to the API endpoint. Non-Netlify auth setups will often need to set this for local development to work properly. |
|
||||
| `base_url` | `https://api.netlify.com` (GitHub, Bitbucket) or `https://gitlab.com` (GitLab) | OAuth client URL. **Required** when using an external OAuth server or self-hosted GitLab. |
|
||||
| `auth_endpoint` | `auth` (GitHub, Bitbucket) or `oauth/authorize` (GitLab) | Path to append to `base_url` for authentication requests. Optional. |
|
126
website/content/docs/beta-features.md
Normal file
126
website/content/docs/beta-features.md
Normal file
@ -0,0 +1,126 @@
|
||||
---
|
||||
title: Beta Features!
|
||||
weight: 200
|
||||
group: reference
|
||||
---
|
||||
|
||||
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.
|
||||
|
||||
**Use these features at your own risk.**
|
||||
|
||||
## Custom Mount Element
|
||||
Netlify CMS always creates it's own DOM element for mounting the application, which means it always
|
||||
takes over the entire page, and is generally inflexible if you're trying to do something creative,
|
||||
like injecting it into a shared context.
|
||||
|
||||
You can now provide your own element for Netlify CMS to mount in by setting the target element's ID
|
||||
as `nc-root`. If Netlify CMS finds an element with this ID during initialization, it will mount
|
||||
within that element instead of creating it's own.
|
||||
|
||||
## Manual Initialization
|
||||
Netlify CMS can now be manually initialized, rather than automatically loading up the moment you import it. The whole point of this at the moment is to inject configuration into Netlify CMS before it loads, bypassing need for an actual Netlify CMS `config.yml`. This is important, for example, when creating tight integrations with static site generators.
|
||||
|
||||
Injecting config is technically already possible by setting `window.CMS_CONFIG` before importing/requiring/running Netlify CMS, but most projects are modular and don't want to use globals, plus `window.CMS_CONFIG` is an internal, not technically supported, and provides no validation.
|
||||
|
||||
Assuming you have the netlify-cms package installed to your project, manual initialization works like so:
|
||||
|
||||
```js
|
||||
// This global flag enables manual initialization.
|
||||
window.CMS_MANUAL_INIT = true
|
||||
|
||||
// Usage with import from npm package
|
||||
import CMS, { init } from 'netlify-cms'
|
||||
|
||||
// Usage with script tag
|
||||
const { CMS, initCMS: init } = window
|
||||
|
||||
/**
|
||||
* Initialize without passing in config - equivalent to just importing
|
||||
* Netlify CMS the old way.
|
||||
*/
|
||||
|
||||
init()
|
||||
|
||||
/**
|
||||
* Optionally pass in a config object. This object will be merged into
|
||||
* `config.yml` if it exists, and any portion that conflicts with
|
||||
* `config.yml` will be overwritten. Arrays will be replaced during merge,
|
||||
* not concatenated.
|
||||
*
|
||||
* For example, the code below contains an incomplete config, but using it,
|
||||
* your `config.yml` can be missing it's backend property, allowing you
|
||||
* to set this property at runtime.
|
||||
*/
|
||||
|
||||
init({
|
||||
config: {
|
||||
backend: {
|
||||
name: 'git-gateway',
|
||||
},
|
||||
},
|
||||
})
|
||||
|
||||
// The registry works as expected, and can be used before or after init.
|
||||
CMS.registerPreviewTemplate(...);
|
||||
```
|
||||
|
||||
## Raw CSS in `registerPreviewStyle`
|
||||
`registerPreviewStyle` can now accept a CSS string, in addition to accepting a url. The feature is activated by passing in an object as the second argument, with `raw` set to a truthy value.This is critical for integrating with modern build tooling. Here's an example using webpack:
|
||||
|
||||
```js
|
||||
/**
|
||||
* Assumes a webpack project with `sass-loader` and `css-loader` installed.
|
||||
* Takes advantage of the `toString` method in the return value of `css-loader`.
|
||||
*/
|
||||
import CMS from 'netlify-cms';
|
||||
import styles from '!css-loader!sass-loader!../main.scss'
|
||||
|
||||
CMS.registerPreviewStyle(styles.toString(), { raw: true })
|
||||
```
|
||||
|
||||
## Squash merge GitHub pull requests
|
||||
When using the [Editorial Workflow](/docs/configuration-options/#publish-mode) with the `github` or GitHub-connected `git-gateway` backends, Netlify CMS creates a pull request for each unpublished entry. Every time the unpublished entry is changed and saved, a new commit is added to the pull request. When the entry is published, the pull request is merged, and all of those commits are added to your project commit history in a merge commit.
|
||||
|
||||
The squash merge option causes all commits to be "squashed" into a single commit when the pull request is merged, and the resulting commit is rebased onto the target branch, avoiding the merge commit altogether.
|
||||
|
||||
To enable this feature, you can set the following option in your Netlify CMS `config.yml`:
|
||||
|
||||
```yaml
|
||||
backend:
|
||||
squash_merges: true
|
||||
```
|
||||
|
||||
## Commit Message Templates
|
||||
You can customize the templates used by Netlify CMS to generate commit messages by setting the `commit_messages` option under `backend` in your Netlify CMS `config.yml`.
|
||||
|
||||
Template tags wrapped in curly braces will be expanded to include information about the file changed by the commit. For example, `{{path}}` will include the full path to the file changed.
|
||||
|
||||
Setting up your Netlify CMS `config.yml` to recreate the default values would look like this:
|
||||
|
||||
```yaml
|
||||
backend:
|
||||
commit_messages:
|
||||
create: Create {{collection}} “{{slug}}”
|
||||
update: Update {{collection}} “{{slug}}”
|
||||
delete: Delete {{collection}} “{{slug}}”
|
||||
uploadMedia: Upload “{{path}}”
|
||||
deleteMedia: Delete “{{path}}”
|
||||
```
|
||||
|
||||
Netlify CMS generates the following commit types:
|
||||
|
||||
Commit type | When is it triggered? | Available template tags
|
||||
--------------|------------------------------|-----------------------------
|
||||
`create` | A new entry is created | `slug`, `path`, `collection`
|
||||
`update` | An existing entry is changed | `slug`, `path`, `collection`
|
||||
`delete` | An exising entry is deleted | `slug`, `path`, `collection`
|
||||
`uploadMedia` | A media file is uploaded | `path`
|
||||
`deleteMedia` | A media file is deleted | `path`
|
||||
|
||||
Template tags produce the following output:
|
||||
|
||||
- `{{slug}}`: the url-safe filename of the entry changed
|
||||
|
||||
- `{{collection}}`: the name of the collection containing the entry changed
|
||||
|
||||
- `{{path}}`: the full path to the file changed
|
103
website/content/docs/collection-types.md
Normal file
103
website/content/docs/collection-types.md
Normal file
@ -0,0 +1,103 @@
|
||||
---
|
||||
title: Collection Types
|
||||
weight: 27
|
||||
group: start
|
||||
---
|
||||
|
||||
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.
|
||||
|
||||
Collections come in two main types: `folder` and `files`.
|
||||
|
||||
## Folder collections
|
||||
|
||||
Folder collections represent one or more files with the same format, fields, and configuration options, all stored within the same folder in the repository. You might use a folder collection for blog posts, product pages, author data files, etc.
|
||||
|
||||
Unlike file collections, folder collections have the option to allow editors to create new items in the collection. This is set by the boolean `create` field.
|
||||
|
||||
**Note:** Folder collections must have at least one field with the name "title" for creating new entry slugs. That field should use the default "string" widget. The "label" for the field can be any string value.
|
||||
|
||||
Example:
|
||||
|
||||
```yaml
|
||||
- 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"}
|
||||
```
|
||||
|
||||
### Filtered folder collections
|
||||
|
||||
The entries for any folder collection can be filtered based on the value of a single field. By filtering a folder into different collections, you can manage files with different fields, options, extensions, etc. in the same folder.
|
||||
|
||||
The `filter` option requires two fields:
|
||||
|
||||
* `field`: the name of the collection field to filter on
|
||||
* `value`: the desired field value
|
||||
|
||||
The example below creates two collections in the same folder, filtered by the `language` field. The first collection includes posts with `language: en`, and the second, with `language: es`.
|
||||
|
||||
```yaml
|
||||
collections:
|
||||
- label: "Blog in English"
|
||||
name: "english_posts"
|
||||
folder: "_posts"
|
||||
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: "Blog en Español"
|
||||
name: "spanish_posts"
|
||||
folder: "_posts"
|
||||
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"}
|
||||
```
|
||||
|
||||
## File collections
|
||||
|
||||
A `files` collection contains one or more uniquely configured files. Unlike items in `folder` collections, which repeat the same configuration over all files in the folder, each item in a `files` collection has an explicitly set path, filename, and configuration. This can be useful for unique files with a custom set of fields, like a settings file or a custom landing page with a unique content structure.
|
||||
|
||||
When configuring a `files` collection, each file in the collection is configured separately, and listed under the `files` field of the collection. Each file has its own list of `fields`, and a unique filepath specified in the `file` field (relative to the base of the repo).
|
||||
|
||||
**Note:** Files listed in a file collection must already exist in the repo, and must have a valid value for the file type. For example, an empty file works as valid YAML, but a JSON file must have a non-empty value to be valid, such as an empty object.
|
||||
|
||||
Example:
|
||||
|
||||
```yaml
|
||||
- label: "Pages"
|
||||
name: "pages"
|
||||
files:
|
||||
- label: "About Page"
|
||||
name: "about"
|
||||
file: "site/content/about.yml"
|
||||
fields:
|
||||
- {label: Title, name: title, widget: string}
|
||||
- {label: Intro, name: intro, widget: markdown}
|
||||
- label: Team
|
||||
name: team
|
||||
widget: list
|
||||
fields:
|
||||
- {label: Name, name: name, widget: string}
|
||||
- {label: Position, name: position, widget: string}
|
||||
- {label: Photo, name: photo, widget: image}
|
||||
- label: "Locations Page"
|
||||
name: "locations"
|
||||
file: "site/content/locations.yml"
|
||||
fields:
|
||||
- {label: Title, name: title, widget: string}
|
||||
- {label: Intro, name: intro, widget: markdown}
|
||||
- label: Locations
|
||||
name: locations
|
||||
widget: list
|
||||
fields:
|
||||
- {label: Name, name: name, widget: string}
|
||||
- {label: Address, name: address, widget: string}
|
||||
```
|
205
website/content/docs/configuration-options.md
Normal file
205
website/content/docs/configuration-options.md
Normal file
@ -0,0 +1,205 @@
|
||||
---
|
||||
title: Configuration Options
|
||||
weight: 23
|
||||
group: reference
|
||||
---
|
||||
|
||||
All configuration options for Netlify CMS are specified in a `config.yml` file, in the folder where you access the editor UI (usually in the `/admin` folder).
|
||||
|
||||
Alternatively, you can specify a custom config file using a link tag:
|
||||
|
||||
```html
|
||||
<!-- Note the "type" and "rel" attribute values, which are required. -->
|
||||
|
||||
<link href="path/to/config.yml" type="text/yaml" rel="cms-config-url">
|
||||
```
|
||||
|
||||
To see working configuration examples, you can [start from a template](https://www.netlifycms.org/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/netlify/netlify-cms/blob/master/example/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.
|
||||
|
||||
|
||||
## Backend
|
||||
|
||||
*This setting is required.*
|
||||
|
||||
The `backend` option specifies how to access the content for your site, including authentication. Full details and code samples can be found in [Authentication & Backends](https://www.netlifycms.org/docs/authentication-backends).
|
||||
|
||||
|
||||
## Publish Mode
|
||||
|
||||
By default, all entries created or edited in the Netlify CMS are committed directly into the main repository branch.
|
||||
|
||||
The `publish_mode` option allows you to enable "Editorial Workflow" mode for more control over the content publishing phases. All unpublished entries will be arranged in a board according to their status, and they can be further reviewed and edited before going live.
|
||||
|
||||
**Note:** Editorial workflow works with GitHub repositories only. Support for other Git hosts is [coming soon](https://github.com/netlify/netlify-cms/issues/568).
|
||||
|
||||
You can enable the Editorial Workflow with the following line in your Netlify CMS `config.yml` file:
|
||||
|
||||
```yaml
|
||||
publish_mode: editorial_workflow
|
||||
```
|
||||
|
||||
From a technical perspective, the workflow translates editor UI actions into common Git commands:
|
||||
|
||||
Actions in Netlify UI ... | Perform these Git actions
|
||||
--- | ---
|
||||
Save draft | Commits to a new branch (named according to the pattern `cms/collectionName-entrySlug`), and opens a pull request
|
||||
Edit draft | Pushes another commit to the draft branch/pull request
|
||||
Approve and publish draft | Merges pull request and deletes branch
|
||||
|
||||
|
||||
## Media and Public Folders
|
||||
|
||||
*This setting is required.*
|
||||
|
||||
Netlify CMS users can upload files to your repository using the Media Gallery. The following settings specify where these files are saved, and where they can be accessed on your built site.
|
||||
|
||||
**Options**
|
||||
|
||||
- `media_folder` (required): Folder path where uploaded files should be saved, relative to the base of the repo.
|
||||
- `public_folder` (optional): Folder path where uploaded files will be accessed, relative to the base of the built site. For fields controlled by [file] or [image] widgets, the value of the field is generated by prepending this path to the filename of the selected file. Defaults to the value of `media_folder`, with an opening `/` if one is not already included.
|
||||
|
||||
**Example**
|
||||
|
||||
``` yaml
|
||||
media_folder: "static/images/uploads"
|
||||
public_folder: "/images/uploads"
|
||||
```
|
||||
|
||||
Based on the settings above, if a user used an image widget field called `avatar` to upload and select an image called `philosoraptor.png`, the image would be saved to the repository at `/static/images/uploads/philosoraptor.png`, and the `avatar` field for the file would be set to `/images/uploads/philosoraptor.png`.
|
||||
|
||||
## Display URL
|
||||
|
||||
When the `display_url` setting is specified, the CMS UI will include a link in the fixed area at the top of the page, allowing content authors to easily return to your main site. The text of the link consists of the URL less the protocol portion (e.g., `your-site.com`).
|
||||
|
||||
**Example:**
|
||||
|
||||
```yaml
|
||||
display_url: https://your-site.com
|
||||
```
|
||||
|
||||
## Slug Type
|
||||
|
||||
The `slug` option allows you to change how filenames for entries are created and sanitized. For modifying the actual data in a slug, see the per-collection option below.
|
||||
|
||||
`slug` accepts multiple options:
|
||||
|
||||
- `encoding`
|
||||
- `unicode` (default): Sanitize filenames (slugs) according to [RFC3987](https://tools.ietf.org/html/rfc3987) and the [WHATWG URL spec](https://url.spec.whatwg.org/). This spec allows non-ASCII (or non-Latin) characters to exist in URLs.
|
||||
- `ascii`: Sanitize filenames (slugs) according to [RFC3986](https://tools.ietf.org/html/rfc3986). The only allowed characters are (0-9, a-z, A-Z, `_`, `-`, `~`).
|
||||
- `clean_accents`: Set to `true` to remove diacritics from slug characters before sanitizing. This is often helpful when using `ascii` encoding.
|
||||
|
||||
**Example**
|
||||
|
||||
``` yaml
|
||||
slug:
|
||||
encoding: "ascii"
|
||||
clean_accents: true
|
||||
```
|
||||
|
||||
## Collections
|
||||
|
||||
*This setting is required.*
|
||||
|
||||
The `collections` setting is the heart of your Netlify CMS configuration, as it determines how content types and editor fields in the UI generate files and content in your repository. Each collection you configure displays in the left sidebar of the Content page of the editor UI, in the order they are entered into your Netlify CMS `config.yml` file.
|
||||
|
||||
`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](https://www.netlifycms.org/docs/widgets/#relation))
|
||||
- `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`
|
||||
- `file` or `folder` (requires one of these): specifies the collection type and location; details in [Collection Types](https://www.netlifycms.org/docs/collection-types)
|
||||
- `filter`: optional filter for `folder` collections; details in [Collection Types](https://www.netlifycms.org/docs/collection-types)
|
||||
- `create`: for `folder` collections only; `true` allows users to create new items in the collection; defaults to `false`
|
||||
- `delete`: `false` prevents users from deleting items in a collection; defaults to `true`
|
||||
- `extension`: see detailed description below
|
||||
- `format`: see detailed description below
|
||||
- `frontmatter_delimiter`: see detailed description under `format`
|
||||
- `slug`: see detailed description below
|
||||
- `fields` (required): see detailed description below
|
||||
- `editor`: see detailed description below
|
||||
|
||||
The last few options require more detailed information.
|
||||
|
||||
### `extension` and `format`
|
||||
|
||||
These settings determine how collection files are parsed and saved. Both are optional—Netlify CMS will attempt to infer your settings based on existing items in the collection. If your collection is empty, or you'd like more control, you can set these fields explicitly.
|
||||
|
||||
`extension` determines the file extension searched for when finding existing entries in a folder collection and it determines the file extension used to save new collection items. It accepts the following values: `yml`, `yaml`, `toml`, `json`, `md`, `markdown`, `html`.
|
||||
|
||||
You may also specify a custom `extension` not included in the list above, as long as the collection files can be parsed and saved in one of the supported formats below.
|
||||
|
||||
`format` determines how collection files are parsed and saved. It will be inferred if the `extension` field or existing collection file extensions match one of the supported extensions above. It accepts the following values:
|
||||
|
||||
- `yml` or `yaml`: parses and saves files as YAML-formatted data files; saves with `yml` extension by default
|
||||
- `toml`: parses and saves files as TOML-formatted data files; saves with `toml` extension by default
|
||||
- `json`: parses and saves files as JSON-formatted data files; saves with `json` extension by default
|
||||
- `frontmatter`: parses files and saves files with data frontmatter followed by an unparsed body text (edited using a `body` field); saves with `md` extension by default; default for collections that can't be inferred. Collections with `frontmatter` format (either inferred or explicitly set) can parse files with frontmatter in YAML, TOML, or JSON format. However, they will be saved with YAML frontmatter.
|
||||
- `yaml-frontmatter`: same as the `frontmatter` format above, except frontmatter will be both parsed and saved only as YAML, followed by unparsed body text. The default delimiter for this option is `---`.
|
||||
- `toml-frontmatter`: same as the `frontmatter` format above, except frontmatter will be both parsed and saved only as TOML, followed by unparsed body text. The default delimiter for this option is `+++`.
|
||||
- `json-frontmatter`: same as the `frontmatter` format above, except frontmatter will be both parsed and saved as JSON, followed by unparsed body text. The default delimiter for this option is `{` `}`.
|
||||
|
||||
`frontmatter_delimiter`: if you have an explicit frontmatter format declared, this option allows you to specify a custom delimiter like `~~~`. If you need different beginning and ending delimiters, you can use an array like `["(", ")"]`.
|
||||
|
||||
|
||||
### `slug`
|
||||
|
||||
For folder collections where users can create new items, the `slug` option specifies a template for generating new filenames based on a file's creation date and `title` field. (This means that all collections with `create: true` must have a `title` field.)
|
||||
|
||||
**Available template tags:**
|
||||
|
||||
- `{{slug}}`: a url-safe version of the `title` field for the file
|
||||
- `{{year}}`: 4-digit year of the file creation date
|
||||
- `{{month}}`: 2-digit month of the file creation date
|
||||
- `{{day}}`: 2-digit day of the month of the file creation date
|
||||
- `{{hour}}`: 2-digit hour of the file creation date
|
||||
- `{{minute}}`: 2-digit minute of the file creation date
|
||||
- `{{second}}`: 2-digit second of the file creation date
|
||||
|
||||
**Example:**
|
||||
|
||||
```yaml
|
||||
slug: "{{year}}-{{month}}-{{day}}_{{slug}}"
|
||||
```
|
||||
|
||||
### `fields`
|
||||
|
||||
The `fields` option maps editor UI widgets to field-value pairs in the saved file. The order of the fields in your Netlify CMS `config.yml` file determines their order in the editor UI and in the saved file.
|
||||
|
||||
`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](https://www.netlifycms.org/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](https://www.netlifycms.org/docs/widgets)
|
||||
- `default`: specify a default value for a field; available for most widget types (see [Widgets](https://www.netlifycms.org/docs/widgets) for details on each widget 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](https://www.netlifycms.org/docs/custom-widgets/#advanced-field-validation)
|
||||
|
||||
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.
|
||||
|
||||
**Example:**
|
||||
|
||||
```yaml
|
||||
fields:
|
||||
- label: "Title"
|
||||
name: "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"}
|
||||
```
|
||||
|
||||
### `editor`
|
||||
|
||||
This setting changes options for the editor view of the collection. It has one option so far:
|
||||
|
||||
- `preview`: set to `false` to disable the preview pane for this collection; defaults to `true`
|
||||
|
||||
**Example:**
|
||||
|
||||
```yaml
|
||||
editor:
|
||||
preview: false
|
||||
```
|
15
website/content/docs/contributor-guide.md
Normal file
15
website/content/docs/contributor-guide.md
Normal file
@ -0,0 +1,15 @@
|
||||
---
|
||||
title: Contributor Guide
|
||||
weight: 100
|
||||
group: contributing
|
||||
---
|
||||
|
||||
We're hoping that Netlify 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.
|
||||
|
||||
While we work on building this page (and you can help!), here are some links with more information about getting involved:
|
||||
|
||||
* [Setup instructions and Contribution Guidelines](https://github.com/netlify/netlify-cms/blob/master/CONTRIBUTING.md)
|
||||
* [Join us on Gitter](https://gitter.im/netlify/NetlifyCMS)
|
||||
* [Code of Conduct](https://github.com/netlify/netlify-cms/blob/master/CODE_OF_CONDUCT.md)
|
||||
* [Project Milestones](https://github.com/netlify/netlify-cms/milestones)
|
||||
* [Good First Issues](https://github.com/netlify/netlify-cms/issues?q=is%3Aissue+is%3Aopen+sort%3Aupdated-desc+label%3A%22good+first+issue%22+-label%3Aclaimed)
|
170
website/content/docs/custom-widgets.md
Normal file
170
website/content/docs/custom-widgets.md
Normal file
@ -0,0 +1,170 @@
|
||||
---
|
||||
title: Creating Custom Widgets
|
||||
weight: 35
|
||||
group: guides
|
||||
---
|
||||
|
||||
The NetlifyCMS exposes a `window.CMS` 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 Netify CMS as an npm module. The available widget extension methods are:
|
||||
|
||||
* **registerWidget:** lets you register a custom widget.
|
||||
* **registerEditorComponent:** lets you add a block component to the Markdown editor.
|
||||
|
||||
### Writing React Components inline
|
||||
|
||||
The `registerWidget` requires you to provide a React component. If you have a build process in place for your project, it is possible to integrate with this build process.
|
||||
|
||||
However, although possible, it may be cumbersome or even impractical to add a React build phase. For this reason, NetlifyCMS exposes two constructs globally to allow you to create components inline: ‘createClass’ and ‘h’ (alias for React.createElement).
|
||||
|
||||
## `registerWidget`
|
||||
|
||||
Register a custom widget.
|
||||
|
||||
```js
|
||||
// Using global window object
|
||||
CMS.registerWidget(name, control, [preview]);
|
||||
|
||||
// Using npm module import
|
||||
import CMS from 'netlify-cms';
|
||||
CMS.registerWidget(name, control, [preview]);
|
||||
```
|
||||
|
||||
**Params:**
|
||||
|
||||
| Param | Type | Description |
|
||||
| ----------- | ------------------------- | --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
|
||||
| `name` | `string` | Widget name, allows this widget to be used via the field `widget` property in config |
|
||||
| `control` | `React.Component` or `string`| <ul><li>React component that renders the control, receives the following props: <ul><li>**value:** Current field value</li><li>**onChange:** Callback function to update the field value</li></ul></li><li>Name of a registered widget whose control should be used (includes built in widgets).</li></ul> |
|
||||
| [`preview`] | `React.Component`, optional | Renders the widget preview, receives the following props: <ul><li>**value:** Current preview value</li><li>**field:** Immutable map of current field configuration</li><li>**metadata:** Immutable map of any available metadata for the current field</li><li>**getAsset:** Function for retrieving an asset url for image/file fields</li><li>**entry:** Immutable Map of all entry data</li><li>**fieldsMetaData:** Immutable map of metadata from all fields.</li></ul> |
|
||||
|
||||
* **field:** The field type that this widget will be used for.
|
||||
* **control:** A React component that renders the editing interface for this field. Two props will be passed:
|
||||
* **value:** The current value for this field.
|
||||
* **onChange:** Callback function to update the field value.
|
||||
* **preview (optional):** A React component that renders the preview of how the content will look. A `value` prop will be passed to this component.
|
||||
|
||||
**Example:**
|
||||
|
||||
```html
|
||||
<script src="https://unpkg.com/netlify-cms@^1.0.0/dist/cms.js"></script>
|
||||
<script>
|
||||
var CategoriesControl = createClass({
|
||||
handleChange: function(e) {
|
||||
this.props.onChange(e.target.value.split(',').map((e) => e.trim()));
|
||||
},
|
||||
|
||||
render: function() {
|
||||
var value = this.props.value;
|
||||
return h('input', { type: 'text', value: value ? value.join(', ') : '', onChange: this.handleChange });
|
||||
}
|
||||
});
|
||||
|
||||
var CategoriesPreview = createClass({
|
||||
render: function() {
|
||||
return h('ul', {},
|
||||
this.props.value.map(function(val, index) {
|
||||
return h('li', {key: index}, val);
|
||||
})
|
||||
);
|
||||
}
|
||||
});
|
||||
|
||||
CMS.registerWidget('categories', CategoriesControl, CategoriesPreview);
|
||||
</script>
|
||||
```
|
||||
|
||||
## `registerEditorComponent`
|
||||
|
||||
Register a block level component for the Markdown editor:
|
||||
|
||||
```js
|
||||
CMS.registerEditorComponent(definition)
|
||||
```
|
||||
|
||||
**Params**
|
||||
|
||||
* **definition:** The component definition; must specify: id, label, fields, patterns, fromBlock, toBlock, toPreview
|
||||
|
||||
**Example:**
|
||||
|
||||
```html
|
||||
<script src="https://unpkg.com/netlify-cms@^1.0.0/dist/cms.js"></script>
|
||||
<script>
|
||||
CMS.registerEditorComponent({
|
||||
// Internal id of the component
|
||||
id: "youtube",
|
||||
// Visible label
|
||||
label: "Youtube",
|
||||
// Fields the user need to fill out when adding an instance of the component
|
||||
fields: [{name: 'id', label: 'Youtube Video ID', widget: 'string'}],
|
||||
// Pattern to identify a block as being an instance of this component
|
||||
pattern: /^youtube (\S+)$/,
|
||||
// Function to extract data elements from the regexp match
|
||||
fromBlock: function(match) {
|
||||
return {
|
||||
id: match[1]
|
||||
};
|
||||
},
|
||||
// Function to create a text block from an instance of this component
|
||||
toBlock: function(obj) {
|
||||
return 'youtube ' + obj.id;
|
||||
},
|
||||
// Preview output for this component. Can either be a string or a React component
|
||||
// (component gives better render performance)
|
||||
toPreview: function(obj) {
|
||||
return (
|
||||
'<img src="http://img.youtube.com/vi/' + obj.id + '/maxresdefault.jpg" alt="Youtube Video"/>'
|
||||
);
|
||||
}
|
||||
});
|
||||
</script>
|
||||
```
|
||||
|
||||
**Result:**
|
||||
|
||||

|
||||
|
||||
## Advanced field validation
|
||||
|
||||
All widget fields, including those for built-in widgets, [include basic validation](https://www.netlifycms.org/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:
|
||||
|
||||
**Boolean**
|
||||
No errors:
|
||||
|
||||
```javascript
|
||||
isValid = () => {
|
||||
// Do internal validation
|
||||
return true;
|
||||
};
|
||||
```
|
||||
|
||||
Existing error:
|
||||
|
||||
```javascript
|
||||
isValid = () => {
|
||||
// Do internal validation
|
||||
return false;
|
||||
};
|
||||
```
|
||||
|
||||
**Object with `error` (useful for returning custom error messages)**
|
||||
Existing error:
|
||||
|
||||
```javascript
|
||||
isValid = () => {
|
||||
// Do internal validation
|
||||
return { error: 'Your error message.' };
|
||||
};
|
||||
```
|
||||
|
||||
**Promise**
|
||||
You can also return a promise from `isValid`. While the promise is pending, the widget will be marked as "in error". When the promise resolves, the error is automatically cleared.
|
||||
|
||||
```javascript
|
||||
isValid = () => {
|
||||
return this.existingPromise;
|
||||
};
|
||||
```
|
||||
|
||||
Note: Do not create a promise inside `isValid` - `isValid` is called right before trying to persist. This means that even if a previous promise was already resolved, when the user hits 'save', `isValid` will be called again. If it returns a new promise, it will be immediately marked as "in error" until the new promise resolves.
|
187
website/content/docs/customization.md
Normal file
187
website/content/docs/customization.md
Normal file
@ -0,0 +1,187 @@
|
||||
---
|
||||
title: Creating Custom Previews
|
||||
position: 50
|
||||
group: guides
|
||||
---
|
||||
|
||||
The NetlifyCMS exposes a `window.CMS` global object that you can use to register custom widgets, previews and editor plugins. The available customization methods are:
|
||||
|
||||
* **registerPreviewStyle:** Register a custom stylesheet to use on the preview pane.
|
||||
* **registerPreviewTemplate:** Registers a template for a collection.
|
||||
|
||||
Explore the [NetlifyCMS GitHub example](https://github.com/netlify/netlify-cms/blob/9ced3f16c8bcc3d1a36773b126842d023c589eaf/example/index.html#L90-L91), a working example you can review on GitHub.
|
||||
|
||||
### React Components inline interaction
|
||||
|
||||
NetlifyCMS is a collection of React components and exposes two constructs globally to allow you to create components inline: ‘createClass’ and ‘h’ (alias for React.createElement).
|
||||
|
||||
## `registerPreviewStyle`
|
||||
|
||||
Register a custom stylesheet to use on the preview pane.
|
||||
|
||||
```js
|
||||
CMS.registerPreviewStyle(file);
|
||||
```
|
||||
|
||||
**Params:**
|
||||
|
||||
* **file:** css file path
|
||||
|
||||
**Example:**
|
||||
|
||||
```html
|
||||
// index.html
|
||||
<script src="https://unpkg.com/netlify-cms@^1.0.0/dist/cms.js"></script>
|
||||
<script>
|
||||
CMS.registerPreviewStyle("/example.css");
|
||||
</script>
|
||||
```
|
||||
|
||||
```css
|
||||
/* example.css */
|
||||
|
||||
html,
|
||||
body {
|
||||
color: #444;
|
||||
font-size: 14px;
|
||||
font-family: 'Helvetica Neue', Helvetica, Arial, sans-serif;
|
||||
}
|
||||
|
||||
body {
|
||||
padding: 20px;
|
||||
}
|
||||
```
|
||||
|
||||
## `registerPreviewTemplate`
|
||||
|
||||
Registers a template for a collection.
|
||||
|
||||
`CMS.registerPreviewTemplate(collection, react_component);`
|
||||
|
||||
**Params:**
|
||||
|
||||
* collection: The name of the collection which this preview component will be used for.
|
||||
* react_component: A React component that renders the collection data. Four props will be passed to your component during render:
|
||||
* entry: Immutable collection containing the entry data.
|
||||
* widgetFor: Returns the appropriate widget preview component for a given field.
|
||||
* [widgetsFor](#lists-and-objects): Returns an array of objects with widgets and associated field data. For use with list and object type entries.
|
||||
* getAsset: Returns the correct filePath or in-memory preview for uploaded images.
|
||||
**Example:**
|
||||
|
||||
```html
|
||||
<script src="https://unpkg.com/netlify-cms@^1.0.0/dist/cms.js"></script>
|
||||
<script>
|
||||
var PostPreview = createClass({
|
||||
render: function() {
|
||||
var entry = this.props.entry;
|
||||
var image = entry.getIn(['data', 'image']);
|
||||
var bg = this.props.getAsset(image);
|
||||
return h('div', {},
|
||||
h('h1', {}, entry.getIn(['data', 'title'])),
|
||||
h('img', {src: bg.toString()}),
|
||||
h('div', {"className": "text"}, this.props.widgetFor('body'))
|
||||
);
|
||||
}
|
||||
});
|
||||
|
||||
CMS.registerPreviewTemplate("posts", PostPreview);
|
||||
</script>
|
||||
```
|
||||
### Lists and Objects
|
||||
The API for accessing the individual fields of list- and object-type entries is similar to the API
|
||||
for accessing fields in standard entries, but there are a few key differences. Access to these
|
||||
nested fields is facilitated through the `widgetsFor` function, which is passed to the preview
|
||||
template component during render.
|
||||
**Note**: as is often the case with the NetlifyCMS API, arrays and objects are created with
|
||||
Immutable.js. If some of the methods that we use are unfamiliar, such as `getIn`, check out
|
||||
[their docs](https://facebook.github.io/immutable-js/docs/#/) to get a better understanding.
|
||||
**List Example:**
|
||||
```html
|
||||
<script>
|
||||
var AuthorsPreview = createClass({
|
||||
// For list fields, the widgetFor function returns an array of objects
|
||||
// that you can map over in your template. If our field is a list of
|
||||
// authors containing two entries, with fields `name` and `description`,
|
||||
// the return value of `widgetsFor` would look like this:
|
||||
//
|
||||
// [{
|
||||
// data: { name: 'Mathias', description: 'Co-Founder'},
|
||||
// widgets: { name: (<WidgetComponent>), description: (WidgetComponent>)}
|
||||
// },
|
||||
// {
|
||||
// data: { name: 'Chris', description: 'Co-Founder'},
|
||||
// widgets: { name: (<WidgetComponent>), description: (WidgetComponent>)}
|
||||
// }]
|
||||
//
|
||||
// Templating would look something like this:
|
||||
|
||||
render: function() {
|
||||
return h('div', {},
|
||||
|
||||
// This is a static header that would only be rendered once for the entire list
|
||||
h('h1', {}, 'Authors'),
|
||||
|
||||
// Here we provide a simple mapping function that will be applied to each
|
||||
// object in the array of authors
|
||||
this.props.widgetsFor('authors').map(function(author, index) {
|
||||
return h('div', {key: index},
|
||||
h('hr', {}),
|
||||
h('strong', {}, author.getIn(['data', 'name'])),
|
||||
author.getIn(['widgets', 'description'])
|
||||
);
|
||||
})
|
||||
);
|
||||
}
|
||||
});
|
||||
|
||||
CMS.registerPreviewTemplate("authors", AuthorsPreview);
|
||||
</script>
|
||||
```
|
||||
**Object Example:**
|
||||
```html
|
||||
<script>
|
||||
var GeneralPreview = createClass({
|
||||
// Object fields are simpler than lists - instead of `widgetsFor` returning
|
||||
// an array of objects, it returns a single object. Accessing the shape of
|
||||
// that object is the same as the shape of objects returned for list fields:
|
||||
//
|
||||
// {
|
||||
// data: { front_limit: 0, author: 'Chris' },
|
||||
// widgets: { front_limit: (<WidgetComponent>), author: (WidgetComponent>)}
|
||||
// }
|
||||
render: function() {
|
||||
var entry = this.props.entry;
|
||||
var title = entry.getIn(['data', 'site_title']);
|
||||
var posts = entry.getIn(['data', 'posts']);
|
||||
|
||||
return h('div', {},
|
||||
h('h1', {}, title),
|
||||
h('dl', {},
|
||||
h('dt', {}, 'Posts on Frontpage'),
|
||||
h('dd', {}, this.props.widgetsFor('posts').getIn(['widgets', 'front_limit']) || 0),
|
||||
|
||||
h('dt', {}, 'Default Author'),
|
||||
h('dd', {}, this.props.widgetsFor('posts').getIn(['data', 'author']) || 'None'),
|
||||
)
|
||||
);
|
||||
}
|
||||
});
|
||||
|
||||
CMS.registerPreviewTemplate("general", GeneralPreview);
|
||||
</script>
|
||||
```
|
||||
### Accessing Metadata
|
||||
Preview Components also receive an additional prop: `fieldsMetaData`. It contains aditional information (besides the plain plain textual value of each field) that can be useful for preview purposes.
|
||||
For example, the Relation widget passes the whole selected relation data in `fieldsMetaData`.
|
||||
```js
|
||||
export default class ArticlePreview extends React.Component {
|
||||
render() {
|
||||
const {entry, fieldsMetaData} = this.props;
|
||||
const author = fieldsMetaData.getIn(['authors', data.author]);
|
||||
|
||||
return <article><h2>{ entry.getIn(['data', 'title']) }</h2>
|
||||
{author &&<AuthorBio author={author.toJS()}/>}
|
||||
</article>
|
||||
}
|
||||
}
|
||||
```
|
15
website/content/docs/examples.md
Normal file
15
website/content/docs/examples.md
Normal file
@ -0,0 +1,15 @@
|
||||
---
|
||||
title: Examples
|
||||
weight: 110
|
||||
group: start
|
||||
---
|
||||
|
||||
Do you have a great, open source example? Submit a pull request to this page!
|
||||
|
||||
Example | Tools | Type | Source | More info |
|
||||
--- | --- | --- | --- | ---
|
||||
[This Developing Journey](https://briandouglas.me) | middleman | blog | [bdougie/blog](https://github.com/bdougie/blog) | [blog post](https://www.netlify.com/blog/2017/04/20/creating-a-blog-with-middleman-and-netlify-cms/)
|
||||
[JAMstack Recipes](https://jamstack-cms.netlify.com) | Hugo, Azure | demo | [hlaueriksson/jamstack-cms](https://github.com/hlaueriksson/jamstack-cms) | [blog post](http://conductofcode.io/post/managing-content-for-a-jamstack-site-with-netlify-cms/)
|
||||
[The Ragasirtahk Blog](https://www.ragasirtahk.tk/) | Hugo | blog | [ragasirtahk/the-ragasirtahk-blog](https://github.com/ragasirtahk/the-ragasirtahk-blog) | [blog post](https://www.ragasirtahk.tk/2018/01/setting-up-netlify-cms-on-hugo/)
|
||||
[Forest Garden Wales](https://www.forestgarden.wales/) | Hugo | blog | [forestgardenwales/forestgarden.wales](https://github.com/forestgardenwales/forestgarden.wales) | [blog post](https://www.forestgarden.wales/blog/now-using-netlify-cms/)
|
||||
[Cup of Data](https://www.cupofdata.com/blog) | Gatsby | blog | [cupofdata/cupofdata.com](https://github.com/cupofdata/cupofdata.com) | -
|
25
website/content/docs/intro.md
Executable file
25
website/content/docs/intro.md
Executable file
@ -0,0 +1,25 @@
|
||||
---
|
||||
title: Introduction
|
||||
weight: 1
|
||||
group: start
|
||||
---
|
||||
|
||||
Netlify CMS is an open source content management system for your Git workflow that enables you to provide editors with friendly UI and intuitive workflow. You can use it with any static site generator to create faster, more flexible web projects. 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.
|
||||
|
||||
At its core, Netlify CMS is an open-source React app that acts as a wrapper for the Git workflow, using the GitHub, GitLab, or Bitbucket API. This provides 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, GitLab, or Bitbucket 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.
|
||||
|
||||
|
||||
## 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](https://www.netlifycms.org/docs/start-with-a-template/) to make a Netlify CMS-enabled site of your own.
|
||||
- Configure your existing site by following a [tutorial](https://www.netlifycms.org/docs/add-to-your-site/) or checking [configuration options](https://www.netlifycms.org/docs/configuration-options).
|
||||
- Ask questions and share ideas in the Netlify CMS community on [Gitter](https://gitter.im/netlify/netlifycms).
|
||||
- Get involved in new developments and become a [contributor](https://docs-starters--netlify-cms-www.netlify.com/docs/contributor-guide/).
|
42
website/content/docs/start-with-a-template.md
Normal file
42
website/content/docs/start-with-a-template.md
Normal file
@ -0,0 +1,42 @@
|
||||
---
|
||||
title: Start with a Template
|
||||
weight: 10
|
||||
group: start
|
||||
---
|
||||
|
||||
Netlify CMS can be [added to an existing site](https://www.netlifycms.org/docs/add-to-your-site), but the quickest way to get started is with a template. Our featured templates below deploy to Netlify, giving you a fully working CMS-enabled site with just a few clicks.
|
||||
|
||||
<div style="display: flex; justify-content: space-around; text-align: center; margin-bottom: 1.5em;">
|
||||
<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>
|
||||
<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>
|
||||
|
||||
After clicking one of those buttons, you’ll authenticate with GitHub or GitLab and choose a repository name. Netlify will then automatically create a clone of the repository in your GitHub or GitLab account. Next, it will build and deploy the new site on Netlify, bringing you to the site dashboard when the build is complete.
|
||||
|
||||
**Note for Bitbucket users:** Netlify 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](https://www.netlifycms.org/docs/add-to-your-site) for adding Netlify CMS to an existing site.
|
||||
|
||||
## Access Netlify CMS on your new site
|
||||
|
||||
1. The template deploy process will send you an invitation to your new site, sent from `no-reply@netlify.com`.
|
||||
|
||||

|
||||
|
||||
2. Click the link to accept the invite, and you’ll be directed to your site, with a prompt to create a password.
|
||||
|
||||

|
||||
|
||||
3. Enter a password, sign in, and you’ll be directed straight 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 will be 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 Netlify CMS into an existing project, go to [Add to your site](https://www.netlifycms.org/docs/add-to-your-site).
|
||||
- Check out other sites using Netlify CMS (or share your own!) on the [Examples](https://www.netlifycms.org/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).
|
25
website/content/docs/update-the-cms-version.md
Normal file
25
website/content/docs/update-the-cms-version.md
Normal file
@ -0,0 +1,25 @@
|
||||
---
|
||||
title: Update the CMS Version
|
||||
weight: 60
|
||||
group: start
|
||||
---
|
||||
|
||||
The update procedure for your CMS depends upon the method you used to install Netlify CMS.
|
||||
|
||||
## Package Manager
|
||||
|
||||
If you are using a package manager like Yarn or NPM, you will use their standard procedure to update. This is how both the Hugo and Gatsby starters are set up.
|
||||
|
||||
## CDN
|
||||
|
||||
If you are using the CMS through a CDN like Unpkg, then that depends on the version tag you are using. You can find the version tag you are using in the `/admin/index.html` file of your site.
|
||||
|
||||
- (Recommended) If you use `^1.0.0`, the CMS will do all updates except major versions automatically.
|
||||
- It will upgrade to `1.0.1`, `1.1.0`, `1.1.2`.
|
||||
- It will not upgrade to `2.0.0` or higher.
|
||||
- It will not upgrade to beta versions.
|
||||
|
||||
- If you use `~1.0.0`, the CMS will do only patch updates automatically.
|
||||
- It will upgrade `1.0.1`, `1.0.2`.
|
||||
- It will not upgrade to `1.1.0` or higher.
|
||||
- It will not upgrade beta versions.
|
17
website/content/docs/widgets/boolean.md
Normal file
17
website/content/docs/widgets/boolean.md
Normal file
@ -0,0 +1,17 @@
|
||||
---
|
||||
label: "Boolean"
|
||||
target: boolean
|
||||
---
|
||||
|
||||
The boolean widget translates a toggle switch input to a true/false value.
|
||||
|
||||
- **Name:** `boolean`
|
||||
- **UI:** toggle switch
|
||||
- **Data type:** boolean
|
||||
- **Options:**
|
||||
- `default`: accepts `true` or `false`; defaults to `false`
|
||||
- **Example:**
|
||||
|
||||
```yaml
|
||||
- {label: "Draft", name: "draft", widget: "boolean", default: true}
|
||||
```
|
22
website/content/docs/widgets/date.md
Normal file
22
website/content/docs/widgets/date.md
Normal file
@ -0,0 +1,22 @@
|
||||
---
|
||||
label: "Date"
|
||||
target: date
|
||||
---
|
||||
|
||||
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)
|
||||
- **Example:**
|
||||
|
||||
```yaml
|
||||
- label: "Birthdate"
|
||||
name: "birthdate"
|
||||
widget: "date"
|
||||
default: ""
|
||||
format: "MMM Do YY"
|
||||
```
|
22
website/content/docs/widgets/datetime.md
Normal file
22
website/content/docs/widgets/datetime.md
Normal file
@ -0,0 +1,22 @@
|
||||
---
|
||||
label: "DateTime"
|
||||
target: datetime
|
||||
---
|
||||
|
||||
The datetime widget translates a datetime picker to a datetime string. For saving the date only, use the date widget.
|
||||
|
||||
- **Name:** `datetime`
|
||||
- **UI:** datetime picker
|
||||
- **Data type:** Moment.js-formatted datetime string
|
||||
- **Options:**
|
||||
- `default`: accepts a datetime string, or an empty string to accept blank input; otherwise defaults to current datetime
|
||||
- `format`: optional; accepts Moment.js [tokens](https://momentjs.com/docs/#/parsing/string-format/); defaults to raw Date object (if supported by output format)
|
||||
- **Example:**
|
||||
|
||||
```yaml
|
||||
- label: "Start time"
|
||||
name: "start"
|
||||
widget: "datetime"
|
||||
default: ""
|
||||
format: "LLL"
|
||||
```
|
20
website/content/docs/widgets/file.md
Normal file
20
website/content/docs/widgets/file.md
Normal file
@ -0,0 +1,20 @@
|
||||
---
|
||||
label: "File"
|
||||
target: file
|
||||
---
|
||||
|
||||
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.
|
||||
|
||||
- **Name:** `file`
|
||||
- **UI:** file picker button opens media gallery
|
||||
- **Data type:** file path string, based on `media_folder`/`public_folder` configuration
|
||||
- **Options:**
|
||||
- `default`: accepts a file path string; defaults to null
|
||||
- **Example:**
|
||||
|
||||
```yaml
|
||||
- label: "Manual PDF"
|
||||
name: "manual_pdf"
|
||||
widget: "file"
|
||||
default: "/uploads/general-manual.pdf"
|
||||
```
|
17
website/content/docs/widgets/hidden.md
Normal file
17
website/content/docs/widgets/hidden.md
Normal file
@ -0,0 +1,17 @@
|
||||
---
|
||||
label: "Hidden"
|
||||
target: hidden
|
||||
---
|
||||
|
||||
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.
|
||||
|
||||
- **Name:** `hidden`
|
||||
- **UI:** none
|
||||
- **Data type:** any valid data type
|
||||
- **Options:**
|
||||
- `default`: accepts any valid data type; recommended for collections that allow adding new items
|
||||
- **Example:**
|
||||
|
||||
```yaml
|
||||
- {label: "Layout", name: "layout", widget: "hidden", default: "blog"}
|
||||
```
|
20
website/content/docs/widgets/image.md
Normal file
20
website/content/docs/widgets/image.md
Normal file
@ -0,0 +1,20 @@
|
||||
---
|
||||
label: "Image"
|
||||
target: image
|
||||
---
|
||||
|
||||
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.
|
||||
|
||||
- **Name:** `image`
|
||||
- **UI:** file picker button opens media gallery allowing image files (jpg, jpeg, webp, gif, png, bmp, tiff, svg) only; displays selected image thumbnail
|
||||
- **Data type:** file path string, based on `media_folder`/`public_folder` configuration
|
||||
- **Options:**
|
||||
- `default`: accepts a file path string; defaults to null
|
||||
- **Example:**
|
||||
|
||||
```yaml
|
||||
- label: "Featured Image"
|
||||
name: "thumbnail"
|
||||
widget: "image"
|
||||
default: "/uploads/chocolate-dogecoin.jpg"
|
||||
```
|
29
website/content/docs/widgets/index.md
Normal file
29
website/content/docs/widgets/index.md
Normal file
@ -0,0 +1,29 @@
|
||||
---
|
||||
title: Widgets
|
||||
weight: 30
|
||||
group: reference
|
||||
---
|
||||
|
||||
Widgets define the data type and interface for entry fields. Netlify 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](https://www.netlifycms.org/docs/custom-widgets)!
|
||||
|
||||
Widgets are specified as collection fields in the Netlify 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.
|
||||
|
||||
To see working examples of all of the built-in widgets, try making a 'Kitchen Sink' collection item on 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/netlify/netlify-cms/blob/master/example/config.yml#L60) to see how each field was configured.
|
||||
|
||||
|
||||
## Common widget options
|
||||
|
||||
The following options are available on all fields:
|
||||
|
||||
- `required`: specify as `false` to make a field optional; defaults to `true`
|
||||
- `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](https://www.netlifycms.org/docs/custom-widgets/#advanced-field-validation)
|
||||
- **Example:**
|
||||
|
||||
```yaml
|
||||
- label: "Title"
|
||||
name: "title"
|
||||
widget: "string"
|
||||
pattern: [".{12,}", "Must have at least 12 characters"]
|
||||
```
|
||||
|
||||
## Default widgets
|
59
website/content/docs/widgets/list.md
Normal file
59
website/content/docs/widgets/list.md
Normal file
@ -0,0 +1,59 @@
|
||||
---
|
||||
label: "List"
|
||||
target: list
|
||||
---
|
||||
|
||||
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.
|
||||
|
||||
- **Name:** `list`
|
||||
- **UI:** if `fields` is specified, field containing a repeatable child widget, with controls for adding, deleting, and re-ordering the repeated widgets; if unspecified, a text input for entering comma-separated values
|
||||
- **Data type:** list of widget values
|
||||
- **Options:**
|
||||
- `default`: if `fields` is specified, declare defaults on the child widgets; if not, you may specify a list of strings to populate the text field
|
||||
- `allow_add`: if added and labeled `false`, button to add additional widgets disapears
|
||||
- `field`: a single widget field to be repeated
|
||||
- `fields`: a nested list of multiple widget fields to be included in each repeatable iteration
|
||||
- **Example** (`field`/`fields` not specified):
|
||||
|
||||
```yaml
|
||||
- label: "Tags"
|
||||
name: "tags"
|
||||
widget: "list"
|
||||
default: ["news"]
|
||||
```
|
||||
|
||||
- **Example** (`allow_add` marked `false`):
|
||||
|
||||
```yaml
|
||||
- label: "Tags"
|
||||
name: "tags"
|
||||
widget: "list"
|
||||
allow_add: false
|
||||
default: ["news"]
|
||||
```
|
||||
|
||||
- **Example** (with `field`):
|
||||
|
||||
```yaml
|
||||
- label: "Gallery"
|
||||
name: "galleryImages"
|
||||
widget: "list"
|
||||
field:
|
||||
- {label: Image, name: image, widget: image}
|
||||
```
|
||||
|
||||
- **Example** (with `fields`):
|
||||
|
||||
```yaml
|
||||
- label: "Testimonials"
|
||||
name: "testimonials"
|
||||
widget: "list"
|
||||
fields:
|
||||
- {label: Quote, name: quote, widget: string, default: "Everything is awesome!"}
|
||||
- label: Author
|
||||
name: author
|
||||
widget: object
|
||||
fields:
|
||||
- {label: Name, name: name, widget: string, default: "Emmet"}
|
||||
- {label: Avatar, name: avatar, widget: image, default: "/img/emmet.jpg"}
|
||||
```
|
25
website/content/docs/widgets/markdown.md
Normal file
25
website/content/docs/widgets/markdown.md
Normal file
@ -0,0 +1,25 @@
|
||||
---
|
||||
label: "Markdown"
|
||||
target: markdown
|
||||
---
|
||||
|
||||
The markdown widget provides a full fledged text editor - which is based on [slate](https://github.com/ianstormtaylor/slate) - that allows users to format text with features such as headings and blockquotes. Users are also allowed to write in markdown by simply flipping a switch.
|
||||
|
||||
*Please note:* in case you want to use your markdown editor to fill a markdown's file content after the frontmatter, you'll have name the field as `body` so then the CMS can recognize it and save the file accordingly.
|
||||
|
||||
- **Name:** `markdown`
|
||||
- **UI:** full text editor
|
||||
- **Data type:** markdown
|
||||
- **Options:**
|
||||
- `default`: accepts markdown content
|
||||
- `buttons`: an array of strings representing the formatting buttons to display, all buttons shown by default. Buttons include: `bold`, `italic`, `code`, `link`, `heading-one`, `heading-two`, `quote`, `code-block`, `bulleted-list`, and `numbered-list`.
|
||||
- **Example:**
|
||||
|
||||
```yaml
|
||||
- {label: "Blog post content", name: "body", widget: "markdown"}
|
||||
```
|
||||
|
||||
This would render as:
|
||||
|
||||

|
||||
|
26
website/content/docs/widgets/number.md
Normal file
26
website/content/docs/widgets/number.md
Normal file
@ -0,0 +1,26 @@
|
||||
---
|
||||
label: "Number"
|
||||
target: number
|
||||
---
|
||||
|
||||
The number widget uses an HTML number input, saving the value as a string, integer, or floating point number.
|
||||
|
||||
- **Name:** `number`
|
||||
- **UI:** HTML [number input](https://developer.mozilla.org/en-US/docs/Web/HTML/Element/input/number)
|
||||
- **Data type:** string by default; configured by `valueType` option
|
||||
- **Options:**
|
||||
- `default`: accepts string or number value; defaults to empty string
|
||||
- `valueType`: accepts `int` or `float`; any other value results in saving as a string
|
||||
- `min`: accepts a number for minimum value accepted; unset by default
|
||||
- `max`: accepts a number for maximum value accepted; unset by default
|
||||
- **Example:**
|
||||
|
||||
```yaml
|
||||
- label: "Puppy Count"
|
||||
name: "puppies"
|
||||
widget: "number"
|
||||
default: 2
|
||||
valueType: "int"
|
||||
min: 1
|
||||
max: 101
|
||||
```
|
35
website/content/docs/widgets/object.md
Normal file
35
website/content/docs/widgets/object.md
Normal file
@ -0,0 +1,35 @@
|
||||
---
|
||||
label: "Object"
|
||||
target: object
|
||||
---
|
||||
|
||||
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.
|
||||
|
||||
- **Name:** `object`
|
||||
- **UI:** a field containing one or more child widgets
|
||||
- **Data type:** list of child widget values
|
||||
- **Options:**
|
||||
- `default`: you can set defaults within each sub-field's configuration
|
||||
- `fields`: (**required**) a nested list of widget fields to include in your widget
|
||||
- **Example:**
|
||||
|
||||
```yaml
|
||||
- label: "Profile"
|
||||
name: "profile"
|
||||
widget: "object"
|
||||
fields:
|
||||
- {label: "Public", name: "public", widget: "boolean", default: true}
|
||||
- {label: "Name", name: "name", widget: "string"}
|
||||
- label: "Birthdate"
|
||||
name: "birthdate"
|
||||
widget: "date"
|
||||
default: ""
|
||||
format: "MM/DD/YYYY"
|
||||
- label: "Address"
|
||||
name: "address"
|
||||
widget: "object"
|
||||
fields:
|
||||
- {label: "Street Address", name: "street", widget: "string"}
|
||||
- {label: "City", name: "city", widget: "string"}
|
||||
- {label: "Postal Code", name: "post-code", widget: "string"}
|
||||
```
|
28
website/content/docs/widgets/relation.md
Normal file
28
website/content/docs/widgets/relation.md
Normal file
@ -0,0 +1,28 @@
|
||||
---
|
||||
label: "Relation"
|
||||
target: relation
|
||||
---
|
||||
|
||||
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.
|
||||
|
||||
- **Name:** `relation`
|
||||
- **UI:** text input with search result dropdown
|
||||
- **Data type:** data type of the value pulled from the related collection item
|
||||
- **Options:**
|
||||
- `default`: accepts any widget data type; defaults to an empty string
|
||||
- `collection`: (**required**) name of the collection being referenced (string)
|
||||
- `displayFields`: list of one or more names of fields in the referenced collection that will render in the autocomplete menu of the control. Defaults to `valueField`.
|
||||
- `searchFields`: (**required**) list of one or more names of fields in the referenced collection to search for the typed value
|
||||
- `valueField`: (**required**) name of the field from the referenced collection whose value will be stored for the relation
|
||||
- **Example** (assuming a separate "authors" collection with "name" and "twitterHandle" fields):
|
||||
|
||||
```yaml
|
||||
- label: "Post Author"
|
||||
name: "author"
|
||||
widget: "relation"
|
||||
collection: "authors"
|
||||
searchFields: ["name", "twitterHandle"]
|
||||
valueField: "name"
|
||||
displayFields: ["twitterHandle", "followerCount"]
|
||||
```
|
||||
The generated UI input will search the authors collection by name and twitterHandle, and display each author's handle and follower count. On selection, the author name will be saved for the field.
|
35
website/content/docs/widgets/select.md
Normal file
35
website/content/docs/widgets/select.md
Normal file
@ -0,0 +1,35 @@
|
||||
---
|
||||
label: "Select"
|
||||
target: select
|
||||
---
|
||||
|
||||
The select widget allows you to pick a single string value from a dropdown menu.
|
||||
|
||||
- **Name:** `select`
|
||||
- **UI:** HTML select input
|
||||
- **Data type:** string
|
||||
- **Options:**
|
||||
- `default`: accepts a string; defaults to an empty string
|
||||
- `options`: (**required**) a list of options for the dropdown menu; can be listed in two ways:
|
||||
- string values: the label displayed in the dropdown is the value saved in the file
|
||||
- object with `label` and `value` fields: the label displays in the dropdown; the value is saved in the file
|
||||
- **Example** (options as strings):
|
||||
|
||||
```yaml
|
||||
- label: "Align Content"
|
||||
name: "align"
|
||||
widget: "select"
|
||||
options: ["left", "center", "right"]
|
||||
```
|
||||
- **Example** (options as objects):
|
||||
|
||||
```yaml
|
||||
- label: "City"
|
||||
name: "airport-code"
|
||||
widget: "select"
|
||||
options:
|
||||
- { label: "Chicago", value: "ORD" }
|
||||
- { label: "Paris", value: "CDG" }
|
||||
- { label: "Tokyo", value: "HND" }
|
||||
```
|
||||
|
17
website/content/docs/widgets/string.md
Normal file
17
website/content/docs/widgets/string.md
Normal file
@ -0,0 +1,17 @@
|
||||
---
|
||||
label: "String"
|
||||
target: string
|
||||
---
|
||||
|
||||
The string widget translates a basic text input to a string value. For larger textarea inputs, use the text widget.
|
||||
|
||||
- **Name:** `string`
|
||||
- **UI:** text input
|
||||
- **Data type:** string
|
||||
- **Options:**
|
||||
- `default`: accepts a string; defaults to an empty string
|
||||
- **Example:**
|
||||
|
||||
```yaml
|
||||
- {label: "Title", name: "title", widget: "string"}
|
||||
```
|
18
website/content/docs/widgets/text.md
Normal file
18
website/content/docs/widgets/text.md
Normal file
@ -0,0 +1,18 @@
|
||||
---
|
||||
label: "Text"
|
||||
target: text
|
||||
---
|
||||
|
||||
The text widget takes a multiline text field and saves it as a string. For shorter text inputs, use the string widget.
|
||||
|
||||
- **Name:** `text`
|
||||
- **UI:** HTML textarea
|
||||
- **Data type:** string
|
||||
- **Options:**
|
||||
- `default`: accepts a string; defaults to an empty string
|
||||
- **Example:**
|
||||
|
||||
```yaml
|
||||
- {label: "Description", name: "description", widget: "text"}
|
||||
```
|
||||
|
27
website/content/pages/community.md
Normal file
27
website/content/pages/community.md
Normal file
@ -0,0 +1,27 @@
|
||||
---
|
||||
title: Community
|
||||
|
||||
headline: Be a part of building the CMS of the future.
|
||||
subhead: We’re serious about being community driven, so everyone is welcome to join the [community chat](https://gitter.im/netlify/NetlifyCMS), and to be a part of our bi-weekly planning sessions (details below).
|
||||
primarycta: "[Register on Eventbrite →](https://www.eventbrite.com/e/netlify-cms-planning-session-bi-weekly-tickets-35794058994)"
|
||||
|
||||
upcomingevent:
|
||||
hook: The next development planning session is on
|
||||
|
||||
howitworks: Every other week we have public development planning sessions. They're web based, last about an hour, and are geared toward contributors and those interested in contributing. Sessions currently take place every other Wednesday, 9am - 10am PT.
|
||||
|
||||
howtojoin: |
|
||||
**On the web:**
|
||||
|
||||
1. https://bluejeans.com/278173690
|
||||
|
||||
**By phone:**
|
||||
|
||||
1. [+1.408.740.7256](tel:+14087407256) (United States)
|
||||
|
||||
[+1.408.317.9253](tel:+14083179253) (Alternate number)
|
||||
|
||||
(http://bluejeans.com/numbers)
|
||||
|
||||
2. Enter Meeting ID: 278173690
|
||||
---
|
Reference in New Issue
Block a user