Permalink
Fetching contributors…
Cannot retrieve contributors at this time
777 lines (508 sloc) 21.6 KB

{%= name %}

{%= badge("fury") %} {%= badge('downloads') %} {%= ifExists(["test", "test.js"], badge('travis')) %} {%= badge('gitter') %}

Looking for the grunt plugin? Please visit grunt-assemble.

(Note that the current website assemble.io, is for grunt-assemble. Thanks for your patience while we work on updating the site with documentation for the latest assemble).

Quickstart

Create a new assemble project in less than 3 minutes!

Install assemble

Install assemble's CLI globally:

$ npm install --global assemble

This adds the assemble command to your system path, allowing it to be run from any directory.

Create a new project

Scaffold out a new assemble project using [generate-assemble].

Install generate-assemble

$ npm install --global generate generate-assemble

Scaffold out a new assemble project

$ gen assemble

Run assemble

Time to build your assemble project!

$ assemble

This will give you a preview of how assemble works, continue reading for more information and documentation.

Table of contents

Overview

What is Assemble?

Assemble is a command line tool and developer framework for rapid prototyping, static site generation, and much more.

Who uses assemble?

Assemble is used by thousands of developers and teams in more than 170 countries! Here are a few examples of sites built with assemble:

Is your website, blog or project built with assemble? Please let us know about it!

Why should I use assemble?

  • Expressive, functional API (the API is also stable)
  • You can use assemble with any web framework or CSS/HTML toolkit
  • Assemble can build static sites or hybrid static/dynamic sites
  • Streams support, you can run any [gulp][] plugin
  • Powerful features for rapid web development, including a robust API for rendering templates with any node.js template engine.
  • Assemble can use any [base][] plugin
  • Assemble can do anything Jekyll does, but with more flexibility and control
  • Like gulp, assemble can also run any other static site generator as a plugin, which means you can do anything and everything all other node.js static site generators can do, and much more.

What can I do with Assemble?

Rapid development toolkit

Assemble can be used standalone, but it's even more powerful when used alongside the following libraries:

  • [generate][]: scaffold out new projects from the command line
  • assemble: <= you are here
  • [verb][]: generate documention for your projects
  • [update][]: keep your projects up-to-date

Features

Here are just a few of the features assemble offers:

  • Intuitive CLI
  • Full support for [gulp][] and [base][] plugins
  • Assemble templates are [vinyl][] files
  • Render templates with any template engine, including nunjucks, handlebars, lodash and any consolidate engine!
  • Use multiple engines, assemble can detect the one to use based on file extension
  • helpers: support for sync and async
  • Templates collections
  • Pages
  • Partials/includes
  • Layouts
  • Pagination
  • [permalinks][assemble-permalinks]
  • middleware can be used to tranform files at any stage in the render cycle
  • Generate pages from JSON
  • Much more!

Getting started

Installing assemble

To use assemble's CLI, you will first need to install it globally using npm:

$ npm --global install assemble

This adds the assemble command to your system path, allowing it to be run from any directory.

Rendering templates

Render a template (the default engine is handlebars, but you can use any engine you want):

var assemble = require('{%= name %}');
var app = assemble();

// add a "page"  nd render it!
app.page('home.hbs', {content: 'This is \{{title}}'})
  .render({title: 'Home!'}, function(err, view) {
    if (err) throw err;
    console.log(view.content);
    //=> 'This is Home!'
  });

Running tasks

Create an assemblefile.js and add tasks to run:

var assemble = require('assemble');
var htmlmin = require('gulp-htmlmin');
var app = assemble();

app.page('a.hbs', {content: '...'});
app.page('b.hbs', {content: '...'});
app.page('c.hbs', {content: '...'});

app.task('default', function() {
  return app.toStream('pages') //<= push "pages" collection into stream
    .pipe(app.renderFile()) //<= render pages with default engine (hbs)
    .pipe(htmlmin()) //<= gulp plugin for minifying html
    .pipe(app.dest('site')); //<= write files to the "./site" directory
});

// expose your instance of assemble to assemble's CLI
module.exports = app;

CLI

Run assemble from the command line.

$ assemble <tasks> [options]

Running tasks

Specify one or more space-separated tasks to run.

Examples

Run task foo

$ assemble foo

Run tasks foo and bar

$ assemble foo bar

Specifying options

Non-task options are prefixed with --.

Examples

Set the --cwd to run an assemblefile.js in a different directory:

$ assemble --cwd=docs

Emit views as they're loaded and log them to stderr:

$ assemble --emit=view

See more command line options

Object expansion

Object-paths may be specified using dot-notation for either the key or value in a command line argument.

Additionally, assemble uses [expand-object] to make it easier to pass non-trivial options and commands via command line. So all of the following formats are possible.

Examples

Boolean values:

$ assemble --foo 
# { foo: true }

Key-value pairs:

$ assemble --foo=bar
# { foo: 'bar' }

Nested booleans:

$ assemble --option=foo 
# {options: { foo: true }}

Nested key-value pairs:

$ assemble --option=foo:bar
# {options: { foo: 'bar' }}

Deeply nested key-value pairs:

$ assemble --option=foo.bar.baz:qux
# {options: foo: { bar: { baz: 'qux' }}}}

Or on the left-side of the =:

$ assemble --option.foo.bar.baz=qux
# {options: foo: { bar: { baz: 'qux' }}}}

Command line options

cwd

Change the cwd for the assemblefile.js to run, optionally specifying any tasks to run:

$ assemble <tasks> --cwd [directory]

Example

To run the scaffolds example in the examples/ directory, you would enter:

$ assemble --cwd examples/scaffolds

If successful, in the command line, you should see something like this:

screen shot 2016-01-09 at 1 35 52 pm

file

Specify the name of the config file for assemble's CLI to run, the default is assemblefile.js.

Example

$ assemble --file assemblefile.dev.js

API

{%= apidocs("index.js") %}

Templates API

Assemble exposes the entire API from the [templates][] library for working with templates and template collections. The API is much more extensive than what is documented here, see [templates][] for more documentation.

Templates and Views

In the following documentation, the terms "template" and "view" both refer to aspects of the same thing. Here's what they mean:

  • template: an actual template string
  • view: a object with a content property that contains the template string. Since views are instances of [vinyl][], you can think of a view as a "vinyl file for templates".

.create

Create a template collection for caching [views][]:

app.create('includes', {viewType: 'partial'});

Options

  • cwd {String}: the base directory to use when loading templates onto the collection from a glob
  • viewType: {String|Array}: One or more view types to associate with the collection

Add views

Add a view to the collection:

app.include('foo.md', {contents: new Buffer('this is contents')});

Add multiple views:

app.includes({
  path: 'foo.md', contents: new Buffer('this is contents'),
  path: 'bar.md', contents: new Buffer('this is contents'),
  path: 'baz.md', contents: new Buffer('this is contents')
});

// or pass a glob (optionally override `cwd` defined on `.create`)
app.includes('*.{md,hbs}', {cwd: 'templates/includes'});

View types

View types are defined on a collection to determine how a templates in the collection will be handled throughout the [render cycle][].

Available types

Assemble supports three view types:

  • partial: Views with this type are can be used as "partials" (or "partial views"), which can be injected into other views. Useful for components, document fragments, or other snippets of reusable code or content. These views are passed to rendering engines to be used as partials, or variables on the context if partials are not directly supported.
  • layout: allows views to "wrap" other views (of any type, including other layouts or partials) with common code or content.
  • renderable: Views that have a one-to-one relationship with rendered files that will eventually be visible to a user or visitor to a website. For example: pages or blog posts. The renderable view type is automatically set if no other view types are set.

Defining view types

You can define view types when a collection is created:

app.create('snippet', {viewType: 'partial'});

Or directly on the collection options:

app.create('snippet');
app.snippets.option('viewType', ['partial']); // string or array

.engine

Register template engine for rendering views with the given ext:

app.engine(ext, fn);

Params

  • ext {String}: The file extension of files to render with the engine
  • fn {Function}: Async function that follows [consolidate][] engine conventions, and takes three arguments: str, locals and callback.

Example

// this engine is already registered in assemble
app.engine('hbs', require('engine-handlebars'));

// create a custom engine
app.engine('txt', function(str, locals, cb) {
  // render `str` with `locals`
  cb(null, str);
});

You can tell assemble to use the same engine for all file extensions by setting a value on options.engine.

Example

// use engine `hbs` for rendering all files
app.option('engine', 'hbs');

Or, if you're using .renderFile, you can force a specific engine to be used by passing the engine name.

Example

Use the hbs engine to render all templates:

app.src('templates/*.*')
  .pipe(app.renderFile('hbs'))

.render

Render a view with the given locals and callback.

app.render(view, {title: 'Foo'}, function(err, view) {
  // `view` is an object with a rendered `content` property
});

Params

  • view {Object|String}: The view to render
  • locals {Object}: Locals to pass to template engine for rendering templates in view
  • callback {Function}

File System API

Assemble offers the following low-level methods for working with the file system:

Assemble has first-class support for [vinyl-fs][], so any [gulp][] plugin can be used in your assemble pipeline.

.src

Create a [vinyl][] stream. Takes glob patterns or filepaths to the source files to read.

Params

  • glob {String|Array}: Glob patterns or file paths to source files.
  • options {Object}: Options or locals to merge into the context and/or pass to src plugins

Example

app.src('src/*.hbs');

// define `src` options
app.src('src/*.hbs', { layout: 'default' });

.dest

Specify a destination for processed files.

Params

  • dest {String|Function}: File path or rename function.
  • options {Object}: Options and locals to pass to dest plugins

Example

app.dest('dist/');

.copy

Copy files with the given glob patterns to the specified dest.

Params

  • patterns {String|Array}: Glob patterns of files to copy.
  • dest {String|Function}: Desination directory.
  • returns {Stream}: Stream, to continue processing if necessary.

Example

app.task('assets', function() {
  // return, to let assemble know when the task has completed
  return app.copy('assets/**', 'dist/');
});

.renderFile

Renders files as they are pushed through the stream.

app.src('*.hbs')
  .pipe(app.renderfile())
  .pipe(app.dest('foo'));

Force a specific engine to be used for rendering files:

app.engine('txt', function(str, locals, cb) {
  cb(null, str);
});

app.src('*.hbs')
  .pipe(app.renderfile('txt')) //<= use engine `txt`
  .pipe(app.dest('foo'));

Task API

Assemble has the following methods for running tasks and controlling workflows:

.task

Define a task to be run when the task is called.

Params

  • name {String}: Task name
  • fn {Function}: function that is called when the task is run.

Example

app.task('default', function() {
  app.src('templates/*.hbs')
    .pipe(app.dest('site/'));
});

.build

Run one or more tasks.

Params

  • tasks {Array|String}: Task name or array of task names.
  • cb {Function}: callback function that exposes err

Example

app.build(['foo', 'bar'], function(err) {
  if (err) throw err;
  console.log('done!');
});

.watch

Watch files, run one or more tasks when a watched file changes.

Params

  • glob {String|Array}: Filepaths or glob patterns.
  • tasks {Array}: Task(s) to watch.

Example

app.task('watch', function() {
  app.watch('docs/*.md', ['docs']);
});

Plugins

Discovering plugins

Plugins from any applications built on [base][] should work with Assemble and can be used in your assemblefile.js:

  • base: find base plugins on npm using the baseplugin keyword
  • assemble: find assemble plugins on npm using the assembleplugin keyword
  • generate: find generate plugins on npm using the generateplugin keyword
  • templates: find templates plugins on npm using the templatesplugin keyword
  • [update][update-plugin]: find update plugins on npm using the updateplugin keyword
  • verb: find verb plugins on npm using the verbplugin keyword

Authoring plugins

Visit the plugin documentation guide to learn how to use, author and publish plugins.

Learning

Help

Get in touch!

Have questions, suggestions, or want to discuss assemble? Join the conversation on gitter or give us a shout on twitter. The assemble team and community are always happy to help!

More information

FAQ

Website is outdated and being refactored!

Assemble's website, assemble.io, only has information related to [gulp-assemble][]. We're working hard to update the site with information about the latest release.

In the meantime, you might find the WIP docs useful. The unit tests are also great examples!

Is the assemble website up-to-date?

No, as mentioned above, it's completely out-of-date. If you're using grunt-assemble, some of the documentation at assemble.io might still be useful. If you're using assemble v0.6.0 and higher, the documentation is probably wrong in almost every way.

We're actively (daily) working on a refactor and it's a very high priority.

What's the difference between [assemble-core][] and assemble?

Assemble adds a CLI, a few built-in view collections: pages, layouts, and partials, middleware for parsing front-matter, and a few other basic defaults that we've found many users expect. If you'd prefer different defaults, [assemble-core][] is a great starting point.

If you want something that handles templates, rendering, engines, helpers, collections, etc. but you don't need to run tasks or work with the file system, then consider using [templates][] instead of assemble-core.

I use gulp, why is it recommended to use assemble directly, instead of running assemble with gulp?

You can run gulp plugins with assemble, but it won't always work the other way around. This is because, as a build system, assemble does things that gulp doesn't do, like handle middleware.

For example, assemble's .src and .dest methods have built-in .onStream, .preWrite, and .postWrite middleware handlers. If you still wish to use gulp and your build cycle includes middleware that requires these handlers, you can use the [assemble-handle][] plugin with gulp to ensure that the handlers are still called as needed.

This is a long way of saying, you can find ways to make gulp work, but you would just be adding an extra dependency to your project to do things that assemble already does.

What is the relationship between gulp and assemble?

Please read our gulp FAQ for more information.

About

Community

Are you using assemble in your project? Have you published an assemble project and want to share your project with the world?

Here are some suggestions!

  • If you get like Assemble and want to tweet about it, please feel free to mention @assemble or use the #assemble hashtag
  • Tell us about your assemble project
  • Show your love by starring Assemble and {%= name %}
  • Get implementation help on StackOverflow (please use the assemble tag in questions)
  • Gitter Discuss Assemble with us on Gitter
  • If you publish an assemble plugin, thank you! To make your project as discoverable as possible, please add the keyword assembleplugin to package.json.

Contributing

Please read our contributing guide if you'd like to learn more about contributing to this project.

Related projects

You might also be interested in these projects from @doowb and @jonschlinkert:

{%= related(verb.related.list) %}

Similar projects

If assemble doesn't do what you need, there are some other great open source projects you might be interested in, created by our friends on GitHub (in alphabetical order):

Static site generators

Blog frameworks

Release history

{%= docs("changelog.md") %}

Contributing

{%= include("contributing") %}

If Assemble doesn't do what you need, please let us know %})

Authors

Jon Schlinkert

Brian Woodward

License

{%= copyright() %} {%= license %}


{%= include("footer") %}