# DatoCMS with Jekyll: A beginner's guide

Posted on [date: 2016-11-14T11:00:00.000+01:00] by Claudio Benvenuti

### Prerequisite

This tutorial assumes you have already installed [**Ruby**](https://www.ruby-lang.org/) and [**RubyGems**](https://rubygems.org/). You can then install [**Jekyll**](https://jekyllrb.com/) with the following command:

Terminal window

```bash
gem install jekyll bundler
```

## Create your first Jekyll project

Ok, let's create your first Jekyll project. In you terminal paste the following command:

Terminal window

```bash
jekyll new my_dato_project
```

Once finished enter in your project directory:

Terminal window

```bash
cd my_dato_project
```

### Create a new blog post

Your new Jekyll project is ready to host a Blog and some static pages. By default you have an *index* page, an *about* page and a *blog post* . You can find the `index.md` and `about.md` files in the root folder of the project, and the blog post in `_post/xxxx-xx-xx-welcome-to-jeckyll.markdown`.

The way those pages will show up in your website is defined by your theme. In a fresh Jekyll installation the default theme is "[minima](https://github.com/jekyll/minima)".

Let's create a new blog post copying e modifying the existing post:

Terminal window

```bash
cp ./_post/xxxx-xx-xx-welcome-to-jekyll.markdown ./_post/2016-11-14-my-second-post.markdown
```

Now change the content of the new file, and start the preview web-server:

Terminal window

```bash
bundle exec jekyll server
```

This will start a local web server running at: [http://localhost:4000/](http://localhost:400/).

You can create and edit files in the source folder and see the changes reflected on the preview web-server. You can stop the preview server from the command-line using CTRL-C.

### Build a simple catalog

Not everything is a post or a page. Maybe you want to document the various methods in your open source project, members of a team, or talks at a conference. In our case, we want to create a simple product catalog. It would be great if we could avoid hardcoding all the product metadata inside the HTML templates... this way some team members could concentrate on building up the database of content, while another team member could build the structure of the site. [Jekyll collections](https://jekyllrb.com/docs/collections/) allow you to define new types of document that behave like Pages or Posts do normally, but also have their own unique properties and namespace.

Our catalog is a list of products where each product has the following attributes:

-   Title
-   Price
    
-   Descriprion
    

Let's add a new products collection. Open your site's `_config.yml` file and copy the following lines:

```yaml
collections:
  products:
    output: true
    permalink: /products/:path/
```

This way we're telling Jekyll that we are going to have a new collection name *products*, and we want to output a page for each element of the collection (our products). Those pages will be reachable at the URL `products/{product_filename}/index.html`.

Create a corresponding `_products` folder:

Terminal window

```bash
mkdir _products
```

and add a couple of files, one for each product, with some metadata and some markdown description:

```plaintext
---
layout: product
title:  "Star Wars Chewbacca Slippers"
price:  29.99
---
**Slippers** emit two different Wookiee roars when you walk!

# _products/sku-0001.md
```

```plaintext
---
layout: product
title:  "Star Wars R2-D2 Coffee Press"
price:  39.99
---
Holds 32 ounces of coffee for you (4 cups)

# _products/sku-0002.md
```

As you can see, Jekyll will use a layout named `product`. Layout templates live in the `_layouts` folder, so let's create it:

Terminal window

```bash
mkdir _layouts
```

Inside this folder add the template file `product.html`, which will render the details of a product:

```plaintext
---
layout: default
---
<h1>{{ page.title }}</h1>
<div>
  <strong>{{ page.price }}</strong>
</div>
{{ content }}
```

In this case, the `default` layout is inherithed from the "minima" theme we are using, and the `page.title` and `page.price` are exactly the metadata we added to the beginning of every product page.

We also need to create a `products.md` page in the root of our project to iterate through the products and create an index of products reachable at `/products/`

```plaintext
---
layout: default
title: "Products"
permalink: /products/
---

<h1>Catalog</h1>
<div>
  {% for product in site.products %}
    <p>
      <a href="{{ product.url }}" >{{ product.title }}</a>
    </p>
  {% endfor %}
</div>
```

Well done! Now try to navigate your homepage at [**http://localhost:4000**](http://localhost:4000/) and click one the [**Products**](http://localhost:4000/products/) link.

## Deploy your first Jekyll project

Ok, now that you have the ugliest (but perfectly working) catalogue in the world, you need to deploy your website somewhere. You can simply run the command `jekyll build` to build your static website in the `_site` folder, than you can manually copy al the files to your preferred hosting platform.

Having to manually repeat the same process again and again every time you change a single line of code can be quite frustrating, but you can do much better and automate the deploy process!

### Deploy with Github and Netlify

Create a new repository on [GitHub](https://github.com/). To avoid errors, do not initialize the new repository with any README, license, or gitignore files. You can add these files after your project has been pushed to GitHub.

For our purposes, let’s call your new repo `my_dato_project`.

In your terminal initialize the project directory as a Git repository.

Terminal window

```bash
git init
```

Add the files in your new local repository. This stages them for the first commit.

Terminal window

```bash
git add .
```

Commit the files that you’ve staged in your local repository.

Terminal window

```bash
git commit -m 'First commit'
```

At the top of your GitHub repository’s Quick Setup page, click the clipboard icon to copy the remote repository URL. In Terminal, add the URL for the remote repository where your local repository will be pushed.

Terminal window

```bash
git remote add origin GITHUB_REPOSITORY_URL
```

Now, it’s time to push the changes in your local repository to GitHub:

Terminal window

```bash
git push origin master
```

Now that your assets are up and running on GitHub, let’s connect them to Netlify.

### Connecting to Netlify

#### Step 1: Add Your New Site

Creating a new site on [Netlify](http://www.netlify.com/) is simple. Once you’ve logged in, you’ll be taken to [https://app.netlify.com/sites](https://app.netlify.com/sites). If you’re just starting out, there’s only one option.

#### Step 2: Link to Your GitHub

Clicking “New Site” brings you to this screen:

Since your assets are hosted on GitHub, we’ll need to link Netlify to GitHub. Click “Link to GitHub”.

#### Step 3: Authorize Netlify

It’s time to allow Netlify and GitHub to talk to each other. Clicking the “Authorize Application” button will do just that. Like it says in the image below, Netlify doesn’t store your GitHub access token on their servers. If you’d like to know more about the permissions Netlify requests and why we need them, you can visit [https://docs.netlify.com/github-permissions/](https://docs.netlify.com/github-permissions/).

#### Step 4: Choose Your Repo

Now that you’ve connected Netlify and GitHub, you can see a list of your Git repos. There’s the `my_dato_project` repo we just pushed to GitHub. Let’s select it.

#### Step 5: Configure Your Settings

Here you can configure your options. For the purposes of this tutorial, there’s nothing you need to change, so just click “Save”.

#### Step 6: Build Your Site

Now it’s time to sit back and relax. Go grab something cold to drink, scratch the dog behind the ears, or just get up and walk around (you’ve probably been in front of the computer for too long today, right?). Netlify will do the rest, and you can watch the progress.

#### Step 7: Done

Wait, you thought there was going to be more? Nope! Netlify has done it all for you, including giving your site a temporary name. Now everytime you push some change to GitHub, Netlify will repeat the build process and deploy a new version of the site. No more manual deploying! Let’s make it look a little prettier changing the name of the project:

There, that’s better. Now you can add your custom domain, and your site will be live for your adoring public to view. Congratulations!!!

## Using DatoCMS

Until now it's all wonderful, but what about when you need to add, edit or delete a product, a post or a page of your site? Actually is not that difficult: all you need to do is open the data files stored in `_products`, edit the items data, commit your changes and push it to GitHub. Netlify will grab the changes and will deploy your updated website for you.

If this can be fine for you, it certainly cannot be done if the person in charge of updating catalog is not a programmer and or is not confortable with terminal.

### That's where DatoCMS shines

DatoCMS is a fully customizable administrative area for your static websites. The administrative interface is incredibly simple to use, yet flexible enough to allow the management of pretty much any kind of website.

Best of all, your customers don't need not know anything about Ruby, Middleman, Github, etc. neither they need to install stuff on their computers. You do the dirty work building the website with Middleman, and they can customize thier contents with a browser, just like they're used to do with ie. Wordpress.

### Let see how this magic works

#### Step 1: Add Your New Site

Creating a new site on DatoCMS is simple. Once you’ve logged in, you’ll be taken to \[https://dashboard.datocms.com/account/sites\](your account dashboard). If you’re just starting out, there’s only one option.

Give your website a name and eventually select a template to start your project. In our case we'll start with an empty site template:

#### Step 2: Enter your Admin dashboard

After you click on "Create a new site", DatoCMS will create your administrative area in a randomly-generated subdomain. You can adjust some settings, but for now just click on the given link and enter in the Admin Area.

#### Step 3: Create the Item Types

Now it's time to create a place to store all the informations related to your Products and your Posts. In DatoCMS this place is named "Item Type". Try to think of a DatoCMS ItemType as a table in a database. Click on the plus button:

Give your Item Type the name `Product`. We are going to have a collection of products so DO NOT check the "Single Instance" flag. Enable the "Order collection" as in the picture to be able to reorder your product list once populated.

#### Step 4: Define the product fields

Now that you have the "Product" ItemType (again, think of ItemTypes as a table in a DB) you have to define the Product attributes. To begin click the "Add Field" button:

Now let's add the "Title" attribute. DatoCMS offers a lot of specialized field types, but in our case a "Simple-line string" is fine, so just click it. Give a "Label" to your field and define your validation rules as in image below, than click on the "Save Field" button:

Now repeat this taks for the **Description** and for the **Price** field, choosing respectively "Long text" and "Floating-point number" as field types:

#### Step 5: Populate your catalogue

Now that you have the "Product" item type and its attributes defined, you can start to insert products in your catalog! Click on **Content** in the top navigation bar then click on the plus button to insert a couple of products.

#### Step 6: Repeat step 3, 4 and 5 for Blog Posts

Now let's create the BlogPost item Type, its attributes, and populate it:

-   Click on "Admin area" on the top-bar;
-   Click "Item tyles" on the left menu (actually it should be already selected);
    
-   Click the "plus" button;
-   Give the name "BlogPost" to your Item Type and save it;
    
-   Click the "Add Field" button and choose "Single-line string", Give your Field the name "Title" and save it;
-   Click again the "Field" button and choose "Date + Time", give your Field the name "Date" and save it;
    
-   Click again the "Field" button and choose "Single-line string", Give your Field the name "Categories" and save it;
-   Click again the "Field" button and choose "Long text", Give your Field the name "content", select "Markdown Editor" in the "Presentation mode" dropdown and save it.
    

Now that you have your Item Type ready, insert a couple of demo blog post clicking again the "Content" button on the top-bar.

#### Important

You do not need to give your customer access to your Administrative Area just to populate the catalog, but you can restrict the access to the DatoCMS only to the **Content** section. To do so just click to **Users** on the top navigation bar and invite your customer/editor/collaborator.

## Integrate DatoCMS with Jekyll

Ok, just recap what we have done until now:

-   We created a Jekyll website
-   We added our blog posts data to separate files in the `_posts` folder
    
-   We added our products data to separate files in the `_products` folder
-   We committed all the project files to a GitHub repository
    
-   We created a new Site in Netlify
-   We linked the Netlify Site to our Github repo to allow an automated deploy on every commit
    
-   We created a new Site on DatoCMS
-   We created the "Product" and "Blog Post" ItemType and their attributes
    
-   We populated the catalogue in DatoCMS
    

What we want now is to get rid of the Markdown files in the `_products` and `_posts` folder on our Jekyll project and integrate the data from DatoCMS instead. That's a trivial task, thanks to the [`dato` gem](https://www.datocms.com/docs/content-management-api.md).

Open your `Gemfile` on your Jekyll project and add the following line:

```ruby
gem 'dato'
```

then in your terminal paste the following command:

Terminal window

```bash
bundle install
```

If everything worked correctly, you should now run `bundle exec dato` and see something like this:

Terminal window

```bash
$ bundle exec dato
DatoCMS commands:
  dato dump --token=TOKEN  # dumps DatoCMS contents into local files
  dato help [COMMAND]      # Describe available commands or one specific command
```

Great! Now we need to dump all the remote data into local files that would replace the ones in `_products` and `_posts`, so let's create a `dato.config.rb` file into your project root directory with the following content:

dato.config.rb

```ruby
directory "_products" do
  dato.products.each do |item|
    create_post "#{item.title.parameterize}.md" do
      frontmatter :yaml, {
        layout: "product",
        title: item.title,
        price: item.price
      }
      content item.description
    end
  end
end
directory "_posts" do
  dato.blogposts.each do |item|
    create_post "#{item.date.to_s.parameterize}-#{item.title.parameterize}.md" do
      frontmatter :yaml, {
        layout: "post",
        title: item.title,
        date: item.date.to_s,
        categories: item.categories
      }
      content item.content
    end
  end
end
```

This script will fetch the data from DatoCMS and will create the new files thanks to the `create_post` helper that the `dato` gem exposes.

The DSL is quite simple to understand, in any case you can check the gem [official documentation](https://www.datocms.com/docs/content-management-api.md)

Now is time to see if it works. Fire the following command:

Terminal window

```bash
$ bundle exec dato dump --token=SITE_READONLY_TOKEN
```

You obviously need to replace the `SITE_READ_ONLY_TOKEN` string with the actual token. You can find that token in your DatoCMS Admin area:

Now make sure that the files in the `_products` and `_posts` have been replaced.

**BE CAREFUL!"** This script will delete all the files in the specified directories :)

## Auto deploy your website when data on DatoCMS changes

Until now, to deploy a new version of your website on Netlify you needed to push a new commit on your GitHub repo. This is wonderful when you, as a developer, make some change to the website pages in Jekyll, but you also want to **deploy a new version of your website when products are added/edited/deleted on your DatoCMS site** by your clients!

#### DatoCMS handles all this for you

On your DatoCMS Admin area click on **Deployment settings**, then on **Netlify**:

On the new window that pops up, click on "Grant Access" to allow DatoCMS to setup the auto-deploy meachanism for you:

Select the Netlify site that has to be build upon data changes on DatoCMS:

And click the **Save Settings** button:

Now every time you change any content in your DatoCMS web interface, you can trigger a new deploy on Netlify simply clicking on the **Publish** button:

The last thing to to is to tell Netlify to run `bundle exec dato dump --token=SITE_READONLY_TOKEN` before running `jekyll build`, so that the latest content coming from your administrative backend will be present at build time.

Go to your [Netlify Dashboard](https://app.netlify.com/) and click on your site, than find the **"Link to git"** section end edit the **"build command"** like this:

```plaintext
bundle exec dato dump --token=SITE_READONLY_TOKEN && jekyll build
```

## That's it!

Jekyll is a great static site generator and Netlify is perfect for one-click continouos deployment. DatoCMS "seems like it'll be the last piece of the puzzle!", as our customers says. Just give it a try and feel free to contact our customer support for any questions.

**Happy coding!**