cuttlebelle

Cuttlebelle

🔥 Why yet another static site generator?

All static site generators I have used restrict you to use one layout per page. Todays webdesign needs have outgrown this and we often find ourself either
adding code into our content pages (markdown files, liquid templates) or content into our code.
That makes updating and maintaining a page hard, especially for a non-technical content author.

I needed a generator that can separate content from code as cleanly as possible while still staying a static site generator and as dynamic as possible.

React comes with the component paradigm and was exactly what I’m looking for.
JSX enables a very easy templating like way to write components while still keeping the power of
javascript. No more templating languages that only do half of what you need. Use javascript to write your layouts.

Install

npm install cuttlebelle -g

Then run cuttlebelle in your working folder.

💡Tip: I recommend installing Cuttlebelle globally as it exposes the cuttlebelle command to your system.
If you for some reason want to install it locally, consider adding a npm script to your package.json to make
running cuttlebelle easier:

Usage

CLI

Init

For when you’re just starting out on a new project use the init option. It will generate the folder structure for you and add some files for you to get
started quickly.

cuttlebelle init

Watch

You can also run the highly optimized watch while adding content or developing your layouts.

cuttlebelle watch

This command will first build your pages and then watch for changes in any of them.

It will dutifully only build the absolute minimum of pages once it detects a change somewhere. It is so eager to only build those pages that it thinks are
relevant that it misses sometimes. In cases where you add content from the _pages prop in one of your layouts for instance. I have added a new and somewhat
genius trick to catch cases like that.

Introducing the double saveTM

If you feel like the watch may have missed a page and you don’t want to leave your editor to complain about it to the watch, just save your file twice quickly
like a double click. The watch will detect the double saveTM and generate all pages for you again.

💡Tip: You can change the timeout of the watch to detect a double save via the watchTimeoutsetting.

Watch flags

No generator flag

Sometimes you may only want to start a watch and not rebuild all pages. For that use the no-generate option:

cuttlebelle watch --no-generate

Silent flag

The watch notifies you each time it encounters an error so you don’t have to watch the watch. You can disable that behavior via the silent option.

cuttlebelle watch --silent

Docs

Cuttlebelle comes with a nifty feature that will auto-document your layouts if you use the right propTypes and comments.
Read more about how in the self documenting section.

cuttlebelle docs

Version

To display the version of your cuttlebelle install all you have to do is run the version flag:

cuttlebelle --version

Help

Of course there is also a help option. Just run it with the help flag:

Your assets

All files included inside the assets/ folder are moved to site/assets/. This is where you should keep your CSS, SVGs and images.
Just create a prop inside your index.yml pages to include them into your pages:

Self-documenting

Because you now can separate the content flow from the development flow you will still need to communicate what partials and layouts the content authors have
to their disposal and how they might use it.

Cuttlebelle has a built in feature that will generate documentation for your components automatically as long as you use
PropTypes and a comment above them that reflects the yaml.

Cards.propTypes={

/**

* level: "2"

*/

level:PropTypes.oneOf(['1','2','3','4','5','6']).isRequired,

/**

* hero: true

*/

hero:PropTypes.bool,

/**

* cards:

* - title: Card 1

* content: Content for card 1

* href: http://link/to

* - title: Card 2

* content: Content for card 2

* href: http://link/to

* - title: Card 3

* content: Content for card 3

* href: http://link/to

* - title: Card 4

* content: Content for card 4

* href: http://link/to

*/

cards:PropTypes.arrayOf(

PropTypes.shape({

title:PropTypes.string.isRequired,

content:PropTypes.string.isRequired,

href:PropTypes.string,

})

).isRequired,

};

You can also hide a component from the docs by adding the @disable-docs to the main comment before declaring your component:

import PropTypes from'prop-types';

import React from"react";

/**

* Hiding this component from the docs

*

* @disable-docs

*/

constHidden=({ _body, title })=>(

<articleclassName={`globalheader`}>

<h1>{ title }</h1>

{ _body }

</article>

);

Hidden.propTypes={

/**

* title: Welcome

*/

title:PropTypes.string.isRequired,

/**

* _body: (text)(7)

*/

_body:PropTypes.node.isRequired,

};

exportdefaultHidden;

Once all your components have those comments cuttlebelle can generate the docs for you. All you have to do it run:

cuttlebelle docs

The docs will be generated by default in the docs/ folder of your project.

Tests

I got an end-to-end test script that compares fixtures to what cuttlebelle
generates. In each of those folders I test for specific things and make sure
the checksum of the generated files match the fixtures. In addition to that I created as many
unit tests as I can via Jest.