297 lines
10 KiB
Markdown
297 lines
10 KiB
Markdown
---
|
|
group: Guides
|
|
weight: 30
|
|
title: Jekyll
|
|
---
|
|
## Introduction
|
|
|
|
This section will help you integrate Netlify CMS with a new or existing Jekyll project.
|
|
|
|
[Jekyll](https://jekyllrb.com/) is a blog-aware static site generator built with Ruby. [Github Pages](https://pages.github.com/) are powered by Jekyll, making it a popular choice for developer blogs and project pages.
|
|
|
|
If you're starting a new project, the fastest route to publishing on a Jekyll website with Netlify CMS is to [deploy a template on Netlify](https://templates.netlify.com/).
|
|
|
|
## Setup
|
|
|
|
This guide will use the blog you get if you follow the [really excellent official Jekyll step by step tutorial](https://jekyllrb.com/docs/step-by-step/01-setup/) as a starting point. If you're new to Jekyll - I recommended you start by following the tutorial so you know your way around your new blog. Otherwise [you can clone this repo](https://github.com/adamwatters/jekyll-tutorial-with-netlify-cms/tree/without-cms) and checkout the `without-cms` branch.
|
|
|
|
![Jekyll tutorial blog screenshot](https://www.netlifycms.org/img/screenshot-jekyll-tutorial-blog.png?raw=true)
|
|
|
|
## Add Netlify CMS
|
|
|
|
### Add admin/index.html
|
|
|
|
Create a file `admin/index.html` in the root of your repo - it should look like this:
|
|
|
|
```html
|
|
<!-- admin/index.html -->
|
|
<!DOCTYPE html>
|
|
<html>
|
|
<head>
|
|
<meta charset="utf-8" />
|
|
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
|
|
<title>Content Manager</title>
|
|
</head>
|
|
<body>
|
|
<!-- Include the script that builds the page and powers Netlify CMS -->
|
|
<script src="https://unpkg.com/netlify-cms@^2.0.0/dist/netlify-cms.js"></script>
|
|
</body>
|
|
</html>
|
|
```
|
|
|
|
### Add admin/config.yml
|
|
|
|
Create a file `admin/config.yml` in the root of your repo - it should look like this:
|
|
|
|
```yml
|
|
# config.yml
|
|
|
|
backend:
|
|
name: git-gateway
|
|
branch: master # Branch to update (optional; defaults to master)
|
|
media_folder: 'assets/uploads'
|
|
collections:
|
|
- name: 'blog'
|
|
label: 'Blog'
|
|
folder: '_posts/'
|
|
fields:
|
|
- { name: Title }
|
|
```
|
|
|
|
### Setup Backend
|
|
|
|
Follow the directions in the docs [to enable Identity and Git Gateway](https://www.netlifycms.org/docs/add-to-your-site/#enable-identity-and-git-gateway) then add the [Identity Widget](https://www.netlifycms.org/docs/add-to-your-site/#add-the-netlify-identity-widget)
|
|
|
|
## CMS Configuration
|
|
|
|
### Blog Collection
|
|
|
|
We'll start by updating the `blog` collection. Blogging is baked into Jekyll, and the `_posts/` directory uses [some special conventions](https://jekyllrb.com/docs/posts/) we'll need to keep in mind as we configure Netlify CMS. Copy and paste the following into your `config.yml`.
|
|
|
|
```yaml
|
|
collections:
|
|
- name: 'blog'
|
|
label: 'Blog'
|
|
folder: '_posts/'
|
|
create: true
|
|
slug: '{{year}}-{{month}}-{{day}}-{{slug}}'
|
|
editor:
|
|
preview: false
|
|
fields:
|
|
- { label: 'Layout', name: 'layout', widget: 'hidden', default: 'post' }
|
|
- { label: 'Title', name: 'title', widget: 'string' }
|
|
- { label: 'Publish Date', name: 'date', widget: 'datetime' }
|
|
- { label: 'Body', name: 'body', widget: 'markdown' }
|
|
```
|
|
|
|
A few things to note.
|
|
|
|
* We set the `slug` to `'{{year}}-{{month}}-{{day}}-{{slug}}'` because [Jekyll requires this format for blog posts](https://jekyllrb.com/docs/posts/#creating-posts). `year`, `month`, and `day` will be extracted from the `date` field, and `slug` will be generated from the `title` field.
|
|
* We added `editor` configuration with a field `preview: false`. This will eliminate the preview pane. Because Jekyll uses Liquid templates, there currently isn't a good way to provide a preview of pages as you update the content.
|
|
* The `layout` field default is set to `post` so Jekyll knows to use `_layouts/post.html` when it renders a post. This field is hidden because we want all posts to use the same layout.
|
|
* The `date` and `title` field will be used by the `slug` - as noted above, Jekyll relies on the filename to determine a post's publish date, but Netlify CMS does not pull date information from the filename and requires a frontmatter `date` field. **Note** Changing the `date` or `title` fields in Netlify CMS will not update the filename. This has a few implications:
|
|
|
|
* If you change the `date` or `title` fields in Netlify CMS, Jekyll won't notice
|
|
* You don't necessarily need to change the `date` and `title` fields for existing posts, but if you don't the filenames and frontmatter will disagree in a way that might be confusing
|
|
* If you want to avoid these issues, use a regular Jekyll collection instead of the special `_posts` directory
|
|
|
|
### Author Collection
|
|
|
|
In addition to `_posts`, the Jekyll tutorial blog includes a collection of authors in the `_authors` directory. Before we can configure Netlify CMS to work with the `authors` collection, we'll need to make a couple tweaks to our Jekyll blog. Here's the front matter for one of the authors.
|
|
|
|
```yaml
|
|
short_name: jill
|
|
name: Jill Smith
|
|
position: Chief Editor
|
|
```
|
|
|
|
`name` has special meaning as a unique identifier in Netlify CMS, but as set up now our Jekyll blog is using `short_name` as the unique identifier for authors. For each author, update the frontmatter like so.
|
|
|
|
```yaml
|
|
name: jill
|
|
display_name: Jill Smith
|
|
position: Chief Editor
|
|
```
|
|
|
|
then update `_layouts/author.html`, `_layouts/post.html` and `staff.html` accordingly.
|
|
|
|
```html
|
|
<!-- _layouts/author.html -->
|
|
--- layout: default ---
|
|
|
|
<h1>{{ page.display_name }}</h1>
|
|
<h2>{{ page.position }}</h2>
|
|
|
|
{{ content }}
|
|
|
|
<h2>Posts</h2>
|
|
<ul>
|
|
{% assign filtered_posts = site.posts | where: 'author', page.name %} {% for
|
|
post in filtered_posts %}
|
|
<li>
|
|
<a href="{{ site.baseurl }}{{ post.url }}">{{ post.title }}</a>
|
|
</li>
|
|
{% endfor %}
|
|
</ul>
|
|
```
|
|
|
|
```html
|
|
<!-- _layouts/post.html -->
|
|
--- layout: default ---
|
|
|
|
<h1>{{ page.title }}</h1>
|
|
|
|
<p>
|
|
{{ page.date | date_to_string }}
|
|
{% assign author = site.authors | where: 'name', page.author | first %}
|
|
{% if author %}
|
|
- <a href="{{ author.url }}">{{ author.display_name }}</a>
|
|
{% endif %}
|
|
</p>
|
|
|
|
{{ content }}
|
|
```
|
|
|
|
```html
|
|
<!-- staff.html -->
|
|
--- layout: default ---
|
|
|
|
<h1>Staff</h1>
|
|
|
|
<ul>
|
|
{% for author in site.authors %}
|
|
<li>
|
|
<h2>
|
|
<a href="{{ site.baseurl }}{{ author.url }}">{{ author.display_name }}</a>
|
|
</h2>
|
|
<h3>{{ author.position }}</h3>
|
|
<p>{{ author.content | markdownify }}</p>
|
|
</li>
|
|
{% endfor %}
|
|
</ul>
|
|
```
|
|
|
|
Next, copy and paste the following into the collections array in `config.yml` below the `blog` collection.
|
|
|
|
```yaml
|
|
- name: 'authors'
|
|
label: 'Authors'
|
|
folder: '_authors/'
|
|
create: true
|
|
editor:
|
|
preview: false
|
|
fields:
|
|
- { label: 'Layout', name: 'layout', widget: 'hidden', default: 'author' }
|
|
- { label: 'Short Name', name: 'name', widget: 'string' }
|
|
- { label: 'Display Name', name: 'display_name', widget: 'string' }
|
|
- { label: 'Position', name: 'position', widget: 'string' }
|
|
- { label: 'Body', name: 'body', widget: 'markdown' }
|
|
```
|
|
|
|
Now that we have the `authors` collection configured, we can add an `author` field to the `blog` collection. We'll use the [relation widget](https://www.netlifycms.org/docs/widgets/#relation) to define the relationship between blog posts and authors.
|
|
|
|
```yaml
|
|
# updated fields in blog collection configuration
|
|
fields:
|
|
- { label: 'Layout', name: 'layout', widget: 'hidden', default: 'post' }
|
|
- { label: 'Title', name: 'title', widget: 'string' }
|
|
- { label: 'Publish Date', name: 'date', widget: 'datetime' }
|
|
- {
|
|
label: 'Author',
|
|
name: 'author',
|
|
widget: 'relation',
|
|
collection: 'authors',
|
|
display_fields: [display_name],
|
|
search_fields: [display_name],
|
|
value_field: 'name',
|
|
}
|
|
- { label: 'Body', name: 'body', widget: 'markdown' }
|
|
```
|
|
|
|
With that configuration added, you should be able to select the author for a post from a dropdown.
|
|
|
|
### About Page
|
|
|
|
Our Jekyll blog includes an About page. It would nice to be able to edit that page just like we can edit our blog and author pages. Netlify CMS provides [file collections](https://www.netlifycms.org/docs/collection-types/#file-collections) to solve this problem.
|
|
|
|
Copy and paste the following into the collections array in `config.yml`
|
|
|
|
```yaml
|
|
- name: 'pages'
|
|
label: 'Pages'
|
|
editor:
|
|
preview: false
|
|
files:
|
|
- label: 'About Page'
|
|
name: 'about'
|
|
file: 'about.md'
|
|
fields:
|
|
- { label: 'Title', name: 'title', widget: 'hidden', default: 'about' }
|
|
- { label: 'Layout', name: 'layout', widget: 'hidden', default: 'about' }
|
|
- { label: 'Body', name: 'body', widget: 'markdown' }
|
|
```
|
|
|
|
### Navigation
|
|
|
|
The last aspect of our Jekyll blog we might want to bring under the control of Netlify CMS is our Navigation menu. Our Jekyll tutorial blog has a file `_data/navigation.yml` that defines the links rendered by `_includes/navigation.yml`. It looks like this.
|
|
|
|
```yaml
|
|
# _data/navigation.yml
|
|
- name: Home
|
|
link: /
|
|
- name: About
|
|
link: /about.html
|
|
- name: Blog
|
|
link: /blog.html
|
|
- name: Staff
|
|
link: /staff.html
|
|
```
|
|
|
|
To make this file editable with Netlify CMS, we'll need to make one minor tweak. The issue is this file contains a yaml array at the top level, but Netlify CMS is designed to work with yaml objects. Update `_data/navigation.yml` so it looks like so.
|
|
|
|
```yaml
|
|
# _data/navigation.yml
|
|
items:
|
|
- name: Home
|
|
link: /
|
|
- name: About
|
|
link: /about.html
|
|
- name: Blog
|
|
link: /blog.html
|
|
- name: Staff
|
|
link: /staff.html
|
|
```
|
|
|
|
You'll need to update `_includes/navigation.html` accordingly. `{% for item in site.data.navigation %}` should be changed to `{% for item in site.data.navigation.items %}`. When you're done, the nav html should look like this.
|
|
|
|
```html
|
|
<nav>
|
|
{% for item in site.data.navigation.items %}
|
|
<a href="{{ site.baseurl }}{{ item.link }}" {% if page.url == item.link %}style="color: red;"{% endif %}>
|
|
{{ item.name }}
|
|
</a>
|
|
{% endfor %}
|
|
</nav>
|
|
```
|
|
|
|
Finally, add the following to the collections array in `config.yml`
|
|
|
|
```yaml
|
|
- name: "config"
|
|
label: "Config"
|
|
editor:
|
|
preview: false
|
|
files:
|
|
- label: "Navigation"
|
|
name: "navigation"
|
|
file: "_data/navigation.yml"
|
|
fields:
|
|
- label: "Navigation Items"
|
|
name: "items"
|
|
widget: "list"
|
|
fields:
|
|
- {label: Name, name: name, widget: string}
|
|
- {label: Link, name: link, widget: string}
|
|
```
|
|
|
|
Now you can add, rename, and rearrange the navigation items on your blog. |