<commit_before># Integrating DatoCMS with your static website generator

[DatoCMS](https://www.datocms.com) is working hard to provide the easiest way to enable non-technical editors to update a completely static website — without the intervention of a developer — from the comfort of a user-friendly web interface, just like they're used with Wordpress and such.

Middleman, Hugo, Jekyll, Hexo, Pelican, Octopress, GatsbyJS... the list of static site generators is [almost endless](https://www.staticgen.com/) and keeps on growing.

This gem provides an easy way to integrate content coming from a DatoCMS into virtually any static website generator.

# How it works

All the websites built with a static website generator are made of:

* Static files which represent the actual content of the pages (usually written in Markdown + [front matter](https://jekyllrb.com/docs/frontmatter/), YAML, JSON or Toml);
* Some HTML templates that use these files to generate the actual static HTML pages you will upload online.

That means that, up until now, even the most basic change to a static website could only be performed by a tech-savvy user, as too many things had to be known (Git, Markdown syntax, proper editing of YAML/JSON/Toml files).

DatoCMS works differently:

1. You create a web administrative interface for your editors that fits exactly the needs of your static website;
2. Editors can make changes to the content of the website from that CMS interface you prepared;
3. Using this gem, all the data stored in your DatoCMS administrative interface can be transformed into local Markdown/YAML/JSON/Toml files, so that can be "digested" by the static website generator just as they were written by hand.

The process of translating the data coming from the API into static files can be performed both on your machine during the development process of the website, and in your Continuous Deployment service anytime the editors request a new "build" pressing a "Publish" button on the web interface.

Now your static website isn't static anymore! Isn't this awesome?! :-) 

## Installing the CLI tool

Once you have a working Ruby environment, you can use the CLI tool running these commands within your static website directory:

```
gem install bundler
bundle init
echo 'gem "dato"' >> Gemfile
bundle install
```

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

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

Hurray!!

## Step-by-step integration guide

Now, just to make things more down-to-heart, suppose we're working with a Hugo website with the following structure:

```
.
├── config.toml
├── content
|   ├── post
|   |   ├── first-post.md
|   |   └── ...
|   └── quote
|   |   ├── first-quote.md
|   |   └── ...
├── data
|   └── author
|       ├── mark.toml
|       └── ...
├── layouts
|   └── ...
└── static
    └── ...
```

Our job is to generate the Markdown files in the `content` directory from the data contained in our DatoCMS site. Also the Toml files contained in the in the `data` directory need the same treatment.

### Set up the site

Using the DatoCMS web interface, we first create the following Item types:

* post
  - title (string, required, title)
  - publication_date (date, required)
  - body (text, required)

* author
  - name (string, required, title)
  - bio (text, required)

* quote
  - content (text, required)
  - author (link to author, required)

### Writing the config file

We then define how content stored in DatoCMS needs to be translated into local files using a config file placed in your project root folder called `dato.config.rb`.

Let's start with posts:

```ruby
directory "content/post" do
  dato.posts.each do |item|
    create_post "#{item.slug}.md" do
      frontmatter :toml,
        title: item.title,
        date: item.publication_date.to_s

      content item.body
    end
  end
end
```

The DSL is quite terse! Basically we're declaring that:

1. we want to take possess of the directory `content/post` and manage it programmatically from now on;
2. we then iterate over each post stored in DatoCMS and...
3. for each post, we create a local markdown file:
  - named after the slugified version of the post title;
  - that contains the post body;
  - decorated with a Toml front matter with a `title` and `date` keys; 

Now we can run the following command:

```
$ bundle exec dato dump --token=SITE_READONLY_TOKEN 
```
<commit_msg>Update README [ci skip]<commit_after># Integrating DatoCMS with your static website generator

[DatoCMS](https://www.datocms.com) is working hard to provide the easiest way to enable non-technical editors to update a completely static website — without the intervention of a developer — from the comfort of a user-friendly web interface, just like they're used with Wordpress and such.

Middleman, Hugo, Jekyll, Hexo, Pelican, Octopress, GatsbyJS... the list of static site generators is [almost endless](https://www.staticgen.com/) and keeps on growing.

This gem provides an easy way to integrate content coming from a DatoCMS into virtually any static website generator.

# How it works

All the websites built with a static website generator are made of:

* Static files which represent the actual content of the pages (usually written in Markdown + [front matter](https://jekyllrb.com/docs/frontmatter/), YAML, JSON or Toml);
* Some HTML templates that use these files to generate the actual static HTML pages you will upload online.

That means that, up until now, even the most basic change to a static website could only be performed by a tech-savvy user, as too many things had to be known (Git, Markdown syntax, proper editing of YAML/JSON/Toml files).

DatoCMS works differently:

1. You create a web administrative interface for your editors that fits exactly the needs of your static website;
2. Editors can make changes to the content of the website from that CMS interface you prepared;
3. Using this gem, all the data stored in your DatoCMS administrative interface can be transformed into local Markdown/YAML/JSON/Toml files, so that can be "digested" by the static website generator just as they were written by hand.

The process of translating the data coming from the API into static files can be performed both on your machine during the development process of the website, and in your Continuous Deployment service anytime the editors request a new "build" pressing a "Publish" button on the web interface.

Now your static website isn't static anymore! Isn't this awesome?! :-) 

## Installing the CLI tool

Once you have a working Ruby environment, you can use the CLI tool running these commands within your static website directory:

```
gem install bundler
bundle init
echo 'gem "dato"' >> Gemfile
bundle install
```

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

```
$ 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 the easiest way to dump all the remote data into local files is to create a `dato.config.rb` file into your project root directory with the following content:

```
# dato.config.rb
dato.available_locales.each do |locale|
  directory "content/#{locale}" do
    I18n.with_locale(locale) do
      create_data_file "site.yml", :yaml, dato.site.to_hash
      dato.item_types.each do |item_type|
        create_data_file "#{item_type.api_key}.yml", :yaml, 
          dato.items_of_type(item_type).map(&:to_hash)
      end
    end
  end
end
```

And run the following command:

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

Hurray! A new `content` directory should have been generated with a Yaml file for each item type and the site itself!

## Hugo step-by-step integration guide

That's just the beginning: it probably makes more sense if you generate local files following the precise guidelines of the static site generator you're using. You can easily configure the `dato.config.rb` file to achieve that.

Just to make things more down-to-heart, suppose we're working with a Hugo website with the following structure:

```
.
├── config.toml
├── content
|   ├── post
|   |   ├── first-post.md
|   |   └── ...
|   └── quote
|   |   ├── first-quote.md
|   |   └── ...
├── data
|   └── author
|       ├── mark.toml
|       └── ...
├── layouts
|   └── ...
└── static
    └── ...
```

Our job is to generate the Markdown files in the `content` directory from the data contained in our DatoCMS site. The Toml files contained in the in the `data` directory need to be generated as well.

### Set up the site

Using the DatoCMS web interface, we first create the following Item types:

* post
  - title (string, required, title)
  - publication_date (date, required)
  - body (text, required)

* author
  - name (string, required, title)
  - bio (text, required)

* quote
  - content (text, required)
  - author (link to author, required)

### Writing the config file

We then define how content stored in DatoCMS needs to be translated into local files inside the `dato.config.rb` config file. Let's start with posts:

```ruby
directory "content/post" do
  dato.posts.each do |item|
    create_post "#{item.slug}.md" do
      frontmatter :toml,
        title: item.title,
        date: item.publication_date.to_s

      content item.body
    end
  end
end
```

The DSL is quite terse! Basically we're declaring that:

1. we want to take possess of the directory `content/post` and manage it programmatically from now on;
2. we then iterate over each post stored in DatoCMS and...
3. for each post, we create a local markdown file:
  - named after the slugified version of the post title;
  - that contains the post body;
  - decorated with a Toml front matter with a `title` and `date` keys; 

Now we can run the following command:

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

{'fraction_non_alphanumeric': 0.0784757778653013, 'fraction_numerical': 0.0013784954706577393, 'mean_word_length': 3.779764705882353, 'pattern_counts': {'":': 0, '<': 3, '<?xml version=': 0, '>': 7, 'https://': 6, 'lorem ipsum': 0, 'www.': 4, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '4691522', 'n_tokens_mistral': 2874, 'n_tokens_neox': 2782, 'n_words': 1437}