Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

refactor content files import into its own plugin. #30

Open
wants to merge 6 commits into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions .gitignore
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
node_modules
.DS_Store
.nyc_output
.vscode
Copy link
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

You can add this to your ~/.gitignore so you don't have to add it for every project.

148 changes: 93 additions & 55 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,9 @@
> a JavaScript static site generator with support for WordPress

## Usage

### CLI

```shell
$ tobiko
$ tobiko -h
Expand All @@ -20,46 +22,52 @@ Options:
```

### API

```js
const tobiko = require('tobiko');
const conf = require('./tobiko.js');
tobiko(conf);
```

### Config file

By default, the CLI `tobiko` will look for `tobiko.json`. If dynamic options are needed, they can be declared in a JavaScript file:

```js
// tobiko.js
module.exports = {
contentsDir: 'contents',
outDir: 'dist',
handlebars: {
templatesDir: 'templates',
partialsDir: 'templates/partials',
helpersDir: 'templates/helpers'
},
plugins: {
wordpress: {
apiRoot: 'https://mywordpress.com/wp-json/wp/v2',
contents: [{
postType: 'posts',
folder: 'articles',
template: 'article.hbs'
}]
},
archive: {
articles: {
postsPerPage: 4,
title: 'Articles',
template: 'articles.hbs'
}
},
transform: function (contentTree) {
// do something with the content object
return Promise.resolve(contentTree)
}
}
outDir: 'dist',
handlebars: {
templatesDir: 'templates',
partialsDir: 'templates/partials',
helpersDir: 'templates/helpers'
},
plugins: {
files: {
Copy link
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Can you discard all the changes in this file except for this part?

contentsDir: 'contents'
},
wordpress: {
apiRoot: 'https://mywordpress.com/wp-json/wp/v2',
contents: [
{
postType: 'posts',
folder: 'articles',
template: 'article.hbs'
}
]
},
archive: {
articles: {
postsPerPage: 4,
title: 'Articles',
template: 'articles.hbs'
}
},
transform: function(contentTree) {
// do something with the content object
return Promise.resolve(contentTree);
}
}
};
```

Expand All @@ -68,57 +76,62 @@ $ tobiko -f tobiko.js
```

## What's supported
- Content: JSON / Markdown (optionally with YAML frontmatter) / WordPress (through WP REST API)
- Template: Handlebars
- Styles: SCSS
- JavaScript: browserify (but it can really be anything)

* Content: JSON / Markdown (optionally with YAML frontmatter) / WordPress (through WP REST API)
* Template: Handlebars
* Styles: SCSS
* JavaScript: browserify (but it can really be anything)

## Documentation

### Options

- `contentsDir`: where the site's contents are located. Defaults to `contents`.
- `outDir`: where to generate the static files to. Defaults to `dist`.
- `handlebars`: Handlebars configuration options.
- `templatesDir`: location of the templates directory. Defaults to `templates`.
- `partialsDir`: location of template partials. Defaults to `templates/partials`.
- `helpersDir`: location of template helpers. Defaults to `templates/helpers`.
- `plugins`: configuration for plugins. See [plugins](#plugins) for more info.
* `contentsDir`: where the site's contents are located. Defaults to `contents`.
* `outDir`: where to generate the static files to. Defaults to `dist`.
* `handlebars`: Handlebars configuration options.
* `templatesDir`: location of the templates directory. Defaults to `templates`. - `partialsDir`: location of template partials. Defaults to `templates/partials`. - `helpersDir`: location of template helpers. Defaults to `templates/helpers`.
* `plugins`: configuration for plugins. See [plugins](#plugins) for more info.

### Contents

By default, the site content will be in the `contents` folder. This option could be changed in `tobiko.json`, under `contentDir` property.

Content can be written in `json` and `markdown` with `yaml` [frontmatter](https://github.com/mojombo/jekyll/wiki/YAML-Front-Matter).

The structure of the `contents` directory will be reflected in the final static HTML output.

#### config.json

High level, site-wide configurations can be specified in `config.json` in the root folder. Environment-specific configurations are also supported.

For example:

`config.json`

```json
{
"site-name": "Tobiko Example",
"site-url": "http://tobiko.io",
"author": "Sushi Connoisseur"
"site-name": "Tobiko Example",
"site-url": "http://tobiko.io",
"author": "Sushi Connoisseur"
}
```

`config.dev.json`

```json
{
"site-url": "http://localhost:4000",
"site-url": "http://localhost:4000"
}
```

Environment-specific settings cascade over the original config. This allows you to declare only the different parameters.

#### Nesting

In any directory, a file's sibling files and directories are available for the template to access. This is a convenient and structural way to store and organize data, instead of dumping everything into a single JSON file.

For example, for this file structure

```
contents
├── index.json
Expand All @@ -133,10 +146,13 @@ contents
```

If you're writing the template for `index.json`, its own content is available through the `content` variable.

```html
<h1>{{content.title}}</h1>
```

And `cars` are also available as

```html
<ul>
{{#each cars}}
Expand All @@ -152,11 +168,13 @@ And `cars` are also available as
The numbered files are used to organize the order of the children.

#### template property

Each page specifies a template that it uses, either as a JSON property or YAML frontmmatter. If a file doesn't specify a template, its data is available to be used in the ContentTree but will not be rendered.

Example:

`index.json`

```js
{
template: "index.hbs",
Expand All @@ -165,28 +183,34 @@ Example:
```

`index.md`

```md
---
template: index.hbs
---

Hello World
```

#### filepath

By default, the path of the page is its directory structure.
For example, the page `contents/articles/06/a-new-day.json` will have the URL `http://your-website.com/articles/06/a-new-day.html`.

However, each page's path can be overwritten by a `filepath` property.
Example, the file above can have the following property,

```js
{
filepath: "articles/a-new-day.json"
filepath: 'articles/a-new-day.json';
}
```

which will give it a URL `http://your-website.com/articles/a-new-day.html`.

This could be useful as a way to order files in a directory structure.
In the cars example above:

```
contents
├── index.json
Expand All @@ -203,6 +227,7 @@ contents
In order to avoid the number 1, 2, 3 etc. appear in these cars' URLs, they could have a custom `filepath` property, such as `cars/tesla.json`.

#### date

Post or page date is supported by declaring property `date` in JSON or YAML. Any [ISO-8601 string formats](http://momentjs.com/docs/#/parsing/string/) for date is supported.

By default, a file without a `date` specified will have the `date` value of when the file was created. (To be more exact, it will have the [`ctime`][1] value when `grunt` is first run).
Expand All @@ -212,33 +237,40 @@ By default, a file without a `date` specified will have the `date` value of when
See [momentjs](http://momentjs.com) for more information about the date format.

### Templates

By default tobiko uses [Handlebars](http://handlebarsjs.com) as its templating engine.

Helpers and Partials are supported. They can be stored under `helpers` and `partials` directories under `templates`. These directory names of course can be changed in [`options`](#options) object.

Each page needs to specify its own template. This can be done with a JSON property

```js
{
template: index.hbs
template: index.hbs;
}
```

or in the YAML frontmatter. A file with no `template` property will **not** be rendered.

#### Context

Each template will be passed in a context object generated from the content file with the following properties:
- `content`: the content file
- `content.main`: the parsed HTML if the content file is a markdown file
- `content.filename`: name of the content file
- `content.fileext`: extension type of the content file
- `content.url`: url of the page
- `config`: see [config](#config.json)
- `global`: all data in the `contents` directory
- Other sub-directories included in the same directory is accessible in the template with [nesting](#nesting).

* `content`: the content file
* `content.main`: the parsed HTML if the content file is a markdown file
* `content.filename`: name of the content file
* `content.fileext`: extension type of the content file
* `content.url`: url of the page
* `config`: see [config](#config.json)
* `global`: all data in the `contents` directory
* Other sub-directories included in the same directory is accessible in the template with [nesting](#nesting).

### Plugins

Tobiko can be extended with plugins. By default, it comes with 3 plugins:

#### WordPress

While static site can be a great way to publish content, managing them using the file system can feel clunky at times. It is not too friendly for non-developers. As such, tobiko allows you to pull in content from WordPress, one of the most popular content management systems. With [WP REST API](http://v2.wp-api.org/), content from WordPress can be exported to a system like tobiko.

After installing the WP API plugin, you can start using it in tobiko by configuring it in [`options`](#options). For example:
Expand All @@ -257,6 +289,7 @@ After installing the WP API plugin, you can start using it in tobiko by configur
The `folder` key defines where the WordPress content is put on the content tree.

#### Archives and Pagination

A directory with a big number of posts could be configured to paginate. The paginated pages are called archives.
The option for enabling archives can be added to `options`. For example:

Expand All @@ -272,29 +305,34 @@ The option for enabling archives can be added to `options`. For example:

Each key in the `archives` object represents the name of the directory to be paginated.
Each value can have the following options:

* `orderby`: (string) how to order the posts in the archives. Default to ['date'](#date)
* `postsPerPage`: (number) number of posts to be displayed per archive page
* `template`: (string) the template used to display these archive pages
* `title`: (string) title of these archive pages (this will be made available to use in template as `content.title`)

The paginated content in each archive page is accessible in the template file under `content.posts`.

*The `archives` plugin can be used in combination with the `wordpress` plugin to paginate WordPress content.*
_The `archives` plugin can be used in combination with the `wordpress` plugin to paginate WordPress content._

#### Transform

The `transform` plugin allows you to perform any type of modification/ transformation of the content tree.

In order to do so, instead of passing in a JS object like the other plugins for options, `transform` takes a function that accepts the `contentTree` object as an argument, and returns a promise that will resolve with a value that is the new `contentTree`.

### Deployment

The site can be deployed to [Github Pages](http://pages.github.com) or any static site hosting solutions.

In order to deploy to Github Pages, you can use [`gh-pages`](https://www.npmjs.com/package/gh-pages).

## Examples

Some examples of how tobiko is used

- [tnguyen14/tridnguyen.com](https://github.com/tnguyen14/tridnguyen.com)
* [tnguyen14/tridnguyen.com](https://github.com/tnguyen14/tridnguyen.com)

## Issues/ Requests

Any issues, questions or feature requests could be created under [Github Issues](https://github.com/tnguyen14/tobiko/issues).
41 changes: 24 additions & 17 deletions index.js
Original file line number Diff line number Diff line change
Expand Up @@ -2,22 +2,29 @@ const generateHtml = require('./lib/generateHtml');
const importContents = require('./lib/importContents');
const copyImages = require('./lib/copyImages');

module.exports = function (options) {
let opts = Object.assign({}, {
contentsDir: 'contents',
outDir: 'dist',
markdown: {
breaks: true,
smartLists: true,
smartypants: true
}
}, options);
module.exports = function(options) {
let opts = Object.assign(
{},
{
outDir: 'dist',
markdown: {
breaks: true,
smartLists: true,
smartypants: true
},
plugins: {
files: {
contentsDir: 'contents'
}
}
},
options
);

return Promise.all([
importContents(opts)
.then((contentTree) => {
return generateHtml(opts, contentTree);
}),
copyImages(opts)
]);
return Promise.all([
importContents(opts).then(contentTree => {
return generateHtml(opts, contentTree);
}),
copyImages(opts)
]);
};
Loading