├── templates ├── blog.hbs ├── includes │ ├── button.hbs │ └── head.hbs ├── home.hbs ├── about.hbs └── layouts │ └── default.hbs ├── .gitattributes ├── content └── blog-post.md ├── dest ├── home.html ├── about.html └── blog.html ├── .gitignore ├── Gruntfile.js ├── package.json ├── LICENSE-MIT └── README.md /templates/blog.hbs: -------------------------------------------------------------------------------- 1 | --- 2 | title: Blog 3 | --- 4 | 5 | {{md 'content/blog-post.md'}} -------------------------------------------------------------------------------- /templates/includes/button.hbs: -------------------------------------------------------------------------------- 1 | Star Assemble on GitHub! -------------------------------------------------------------------------------- /templates/home.hbs: -------------------------------------------------------------------------------- 1 | --- 2 | title: Home 3 | description: This is the home page. 4 | --- 5 |

{{description}}

6 | 7 | {{> button }} -------------------------------------------------------------------------------- /templates/about.hbs: -------------------------------------------------------------------------------- 1 | --- 2 | title: About 3 | description: This is the about page. 4 | --- 5 |

{{description}}

6 | 7 | {{> button }} -------------------------------------------------------------------------------- /templates/layouts/default.hbs: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | {{> head }} 5 | 6 | 7 |
8 | {{> body }} 9 |
10 | 11 | -------------------------------------------------------------------------------- /templates/includes/head.hbs: -------------------------------------------------------------------------------- 1 | 2 | {{title}} 3 | 4 | -------------------------------------------------------------------------------- /.gitattributes: -------------------------------------------------------------------------------- 1 | # Enforce Unix newlines 2 | *.* text eol=lf 3 | *.css text eol=lf 4 | *.html text eol=lf 5 | *.js text eol=lf 6 | *.json text eol=lf 7 | *.less text eol=lf 8 | *.md text eol=lf 9 | *.yml text eol=lf 10 | 11 | *.jpg binary 12 | *.gif binary 13 | *.png binary 14 | *.jpeg binary -------------------------------------------------------------------------------- /content/blog-post.md: -------------------------------------------------------------------------------- 1 | # Blog post 2 | 3 | > This is an example blog post 4 | 5 | Lorem ipsum dolor sit amet, consectetur adipisicing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. 6 | 7 | Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum. -------------------------------------------------------------------------------- /dest/home.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | Home 6 | 7 | 8 | 9 | 10 |
11 | 12 |

This is the home page.

13 | 14 | Star Assemble on GitHub! 15 |
16 | 17 | -------------------------------------------------------------------------------- /dest/about.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | About 6 | 7 | 8 | 9 | 10 |
11 | 12 |

This is the about page.

13 | 14 | Star Assemble on GitHub! 15 |
16 | 17 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | # Numerous always-ignore extensions 2 | .ruby-version 3 | *.diff 4 | *.err 5 | *.orig 6 | *.log 7 | *.rej 8 | *.swo 9 | *.swp 10 | *.zip 11 | *.vi 12 | *~ 13 | 14 | # OS or Editor folders 15 | *.esproj 16 | *.sublime-project 17 | *.sublime-workspace 18 | ._* 19 | .cache 20 | .DS_Store 21 | .idea 22 | .project 23 | .settings 24 | .tmproj 25 | nbproject 26 | Thumbs.db 27 | 28 | # Komodo 29 | *.komodoproject 30 | .komodotools 31 | 32 | # grunt-html-validation 33 | validation-status.json 34 | validation-report.json 35 | 36 | # Folders to ignore 37 | tmp 38 | temp 39 | TODO.md 40 | vendor 41 | node_modules 42 | bower_components 43 | _gh_pages 44 | _site 45 | _draft 46 | -------------------------------------------------------------------------------- /Gruntfile.js: -------------------------------------------------------------------------------- 1 | /* 2 | * assemble-examples 3 | * 4 | * Copyright (c) 2014 Jon Schlinkert, Brian Woodward, contributors. 5 | * Licensed under the MIT license. 6 | */ 7 | 8 | 9 | module.exports = function(grunt) { 10 | 'use strict'; 11 | 12 | grunt.initConfig({ 13 | assemble: { 14 | options: { 15 | flatten: true, 16 | partials: ['templates/includes/*.hbs'], 17 | layoutdir: 'templates/layouts', 18 | layout: 'default.hbs' 19 | }, 20 | site: { 21 | files: {'dest/': ['templates/*.hbs']} 22 | } 23 | } 24 | }); 25 | 26 | // Load the Assemble plugin. 27 | grunt.loadNpmTasks('assemble'); 28 | 29 | // The default task to run with the `grunt` command. 30 | grunt.registerTask('default', ['assemble']); 31 | }; 32 | -------------------------------------------------------------------------------- /package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "assemble-example", 3 | "description": "Example Assemble project.", 4 | "version": "0.1.1", 5 | "homepage": "https://github.com/jonschlinkert/assemble-example", 6 | "author": { 7 | "name": "Jon Schlinkert", 8 | "url": "https://github.com/jonschlinkert" 9 | }, 10 | "repository": { 11 | "type": "git", 12 | "url": "https://github.com/jonschlinkert/assemble-example.git" 13 | }, 14 | "bugs": { 15 | "url": "https://github.com/jonschlinkert/assemble-example/issues" 16 | }, 17 | "licenses": [ 18 | { 19 | "type": "MIT", 20 | "url": "https://github.com/jonschlinkert/assemble-example/blob/master/LICENSE-MIT" 21 | } 22 | ], 23 | "main": "index.js", 24 | "engines": { 25 | "node": ">= 0.8.0" 26 | }, 27 | "dependencies": {}, 28 | "devDependencies": { 29 | "grunt": "~0.4.3", 30 | "assemble": "~0.4.37" 31 | }, 32 | "keywords": [] 33 | } 34 | -------------------------------------------------------------------------------- /dest/blog.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | Blog 6 | 7 | 8 | 9 | 10 |
11 | 12 | 13 |

Blog post

14 |
15 |

This is an example blog post

16 |
17 |

Lorem ipsum dolor sit amet, consectetur adipisicing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua.

18 |

Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum.

19 | 20 |
21 | 22 | -------------------------------------------------------------------------------- /LICENSE-MIT: -------------------------------------------------------------------------------- 1 | The MIT License (MIT) 2 | 3 | Copyright (c) 2013-2014 Jon Schlinkert, Brian Woodward, Contributors. 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in 13 | all copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 21 | THE SOFTWARE. 22 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # Introduction to Assemble 2 | 3 | > This project will help you get started with Assemble. Just download, install the dependencies, and you're off and running! 4 | 5 | You might be amazed at how little setup is required to start using Assemble. [This gist](https://gist.github.com/jonschlinkert/9579914) includes everything you need to create a 100% complete Assemble project! 6 | 7 | ## Getting started 8 | 9 | Ready to learn how to do _more than_ what's covered in the gist? Of course you are! Let's get this ball rolling! 10 | 11 | ### Install 12 | 13 | Download this project using one of the following options: 14 | 15 | * Use git: `git clone https://github.com/jonschlinkert/assemble-example.git` 16 | * Download directly [from GitHub](https://github.com/jonschlinkert/assemble-example/archive/master.zip), then unpack the zip file. 17 | 18 | Next, in the root of the `assemble-example` directory, to install the necessary dependencies, run: 19 | 20 | ```bash 21 | npm install 22 | ``` 23 | Done! You should now be able to run `grunt` to build the project. 24 | 25 | _(Although this example project uses Grunt, unless otherwise noted the information here is build-chain agnostic. If you're a Gulp fan, stay on the lookout, we'll be publishing a [gulp-assemble](https://github.com/assemble/gulp-assemble) example soon!)_ 26 | 27 | 28 | ### Usage 29 | 30 | This is all Assemble needs to successfully build a project: 31 | 32 | ```js 33 | assemble: { 34 | site: { 35 | files: {'dest/': ['templates/*.hbs']} 36 | } 37 | } 38 | ``` 39 | 40 | Done. No, really, that's all you need. 41 | 42 | Oh, you want more than this? Then what are you waiting for! read on... 43 | 44 | _(This example project uses a [Gruntfile](./Gruntfile.js) so the configuration examples use [Grunt](http://gruntjs.com/) conventions, but the options themselves are not specific to Grunt. You can use the same options in your [Gulpfile](https://github.com/gulpjs/gulp/blob/master/gulpfile.js) using [Gulp](http://gulpjs.com/) conventions, or with Assemble > v0.5 you can pass the options directly to Assemble if you prefer.)_ 45 | 46 | ## Assemble core concepts 47 | 48 | To get the most out of Assemble, it helps to be familiar with the following core concepts: 49 | 50 | * [Templates](#templates) 51 | - [Layouts](#layouts) 52 | - [Pages](#pages) 53 | - [Partials](#partials) 54 | * [Data](#data) 55 | * [Content](#content) 56 | 57 | By the end of this document, you will know what each of these concepts mean, as well as how to define options for them in your project configuration. Let's get started. 58 | 59 | ### Templates 60 | 61 | > Templates keep your code as organized, modular, and reusable as it can be. Which means projects will be easier to maintain as a result. 62 | 63 | A template is a document or document fragment that contains variables that will be replaced (by the template engine) with actual data, content or other documents. Assemble uses [Handlebars.js](handlebarsjs.com) as its default template engine, so the syntax you see in the examples comes from that library. 64 | 65 | Handlebars is super powerful, giving you as much freedom and power as you need to arrange your templates the way you want them. Assemble adds to this by offering built-in support and conventions for the following template structures: 66 | 67 | * **Layouts**: used to "wrap" pages with common or site-wide elements, such as headers and footers, the `` section, navigation and so on. Note that _layouts are also optional_. 68 | * **Pages**: typically have a 1-to-1 relationship with the actual generated HTML pages in a project, e.g. `about.hbs` => `about.html` or `about/index.html`. But pages can also be dynamically generated from config data. It might also help to think of a page as something that would get inserted into the middle of a layout. See [how Less.js uses pages](https://github.com/less/less-docs/blob/master/templates/index.hbs) to build their [documentation](http://lesscss.org/features/). 69 | * **Partials**: referred to sometimes as _includes_, partials are like document fragments, snippets, or other small chunks of reusable code that will be included, inserted or embedded into other templates at build time. A partial can be a button, or a navbar, or even a Google Analytics script. For an example, see [how Zurb Foundation uses partials](https://github.com/zurb/foundation/tree/master/doc/includes) to build their [documentation](http://foundation.zurb.com/docs/). 70 | 71 | Here are some examples and additional explanation of each template type. 72 | 73 | #### Layouts 74 | 75 | As mentioned above, layouts are used to "wrap" other pages with common elements. So a basic layout might look something like this: 76 | 77 | ```handlebars 78 | 79 | 80 | 81 | 82 | 84 | {{title}} 85 | 86 | 87 | 88 | {{> body }} 89 | 90 | 91 | ``` 92 | 93 | **Layout configuration** 94 | 95 | You can tell Assemble that you want to use a particular layout by defining it in the options: 96 | 97 | ```js 98 | options: { 99 | layout: 'path/to/my-default-layout.hbs' 100 | } 101 | ``` 102 | 103 | If you need more than one layout, you can optionally define a base directory for layouts using `layoutdir`: 104 | 105 | ```js 106 | options: { 107 | layoutdir: 'path/to/layouts' 108 | layout: 'my-default-layout.hbs' 109 | } 110 | ``` 111 | 112 | Remember, layouts aren't required. Sometimes you need one, sometimes you don't, and sometimes you need more than one. You might even need sub-layouts or nested layouts! No worries, [we have you covered there too](http://assemble.io/docs/Layouts.html)! 113 | 114 | 115 | #### Pages 116 | 117 | > Pages, generally **structural in nature**, contain more HTML than textual content, and can be (optionally) wrapped with layouts. 118 | 119 | A basic page might look something like this: 120 | 121 | ```handlebars 122 | 125 | 126 |
127 | 130 | 132 | {{md 'team'}} 133 | Lorem ipsum dolor sit amet, consectetur adipisicing elit, sed 134 | do eiusmod tempor incididunt ut labore et dolore magna aliqua. 135 |
136 | 137 |
138 | 141 | Lorem ipsum dolor sit amet, consectetur adipisicing elit, sed 142 | do eiusmod tempor incididunt ut labore et dolore magna aliqua. 143 |
144 | ``` 145 | 146 | **Pages configuration** 147 | 148 | Pages are the "source files" in your configuration. Jump back up to the [usage section](#usage) for a basic example, or refer to [Grunt's documentation](http://gruntjs.com/configuring-tasks#files) to learn more about the vavious formats that can be used in the Gruntfile for defining source and dest files. 149 | 150 | #### Partials 151 | 152 | > Partials allow you to define a chunk of code one time and use it in multiple places. 153 | 154 | Partials are often used for UI components such as buttons, navbars or modals. But they can also be used for any other snippets or sections of code that might be repeated across multiple pages, or for code that might otherwise be reusable in some way. Partials are easy to spot since they use a `>`, which is the special [Handlebars.js syntax](http://blog.teamtreehouse.com/handlebars-js-part-2-partials-and-helpers)) that is only used with partials: e.g. `{{> foo }}`. 155 | 156 | Continuing with the `layout` example from above, to use a partial for the `head` section simply create a new file, such as `head.hbs` or whatever you prefer, then extract the code from the head section and add it to the new file: 157 | 158 | ```handlebars 159 | 160 | 161 | {{title}} 162 | ``` 163 | 164 | Before continuing on, ensure that the filepath to your newly created partial, `head.hbs`, is specified in your project's configuration so Assemble can take note of it, ensuring that the partial can be used in your templates. 165 | 166 | Now, to actually use the partial, add the `{{> head }}` template to the `head` section of your layout where the code was removed. Assemble makes this simple by allowing you to use the name of the file you just created as the name of the partial: 167 | 168 | ```handlebars 169 | 170 | 171 | 172 | 174 | {{> head }} 175 | 176 | 177 | 180 | {{> body }} 181 | 182 | 183 | ``` 184 | 185 | **Partials configuration** 186 | 187 | Before you can use partials in your templates, you need to tell Assemble where they are. You can do this by adding a `partials` property to the options. 188 | 189 | Example: 190 | 191 | ```js 192 | options: { 193 | // How you organize your project is your business. Assemble 194 | // just needs to know where your partials are and the file 195 | // extensions you'll be using. 196 | partials: ['templates/partials/*.hbs', 'templates/snippets/**/*.html'] 197 | } 198 | ``` 199 | 200 | ### Content 201 | 202 | > Content is usually written in an easy-to-read plain text format such as markdown 203 | 204 | Converting markdown to HTML with Assemble is simple. 205 | 206 | To include external markdown files and have them converted to HTML at build time, you can use the `md` helper: 207 | 208 | ```html 209 |

My Blog Post

210 | {{md 'foo/bar.md'}} 211 | ``` 212 | 213 | Or you can wrap sections of markdown with the `markdown` block helper: 214 | 215 | ```handlebars 216 | 217 | {{#markdown}} 218 | # My Blog Post 219 | 220 | > This is my first blog post! 221 | 222 | Whoo hoo! 223 | {{/markdown}} 224 | ``` 225 | 226 | Using helpers to process markdown allows users to write HTML or markdown, or both together. It also keeps things simple while giving you the freedom to convert your content to HTML according to your preferences: 227 | 228 | * Convert 1-to-1 into HTML pages, e.g. `about.md` would convert to `about.html` (or `about/index.html` using [permalinks](https://github.com/assemble/assemble-contrib-permalinks)) 229 | * Insert into other pages (as includes) 230 | * Concatenate several content files together before converting to pages or being inserted into pages. The [assemble.io/helpers/](http://assemble.io/helpers/) documentation page is a good example of this. The sections on this page were each created from an individual markdown file. In total, _Assemble seamlessly combines more than [100 individual markdown files][helpers] to construct this page!_. 231 | 232 | ### Data 233 | 234 | > Data from JSON or YAML files is passed to your templates at build time. 235 | 236 | This is best explained through examples, so given you have a partial for buttons, `button.hbs`: 237 | 238 | ```handlebars 239 | 240 | ``` 241 | 242 | And given you have a corresponding data file, `button.json`, with the following data: 243 | 244 | ```json 245 | [ 246 | { 247 | "text": "Success!", 248 | "modifier": "btn-success" 249 | }, 250 | { 251 | "text": "Error!", 252 | "modifier": "btn-error" 253 | }, 254 | { 255 | "text": "Warning!", 256 | "modifier": "btn-warning" 257 | } 258 | ] 259 | ``` 260 | 261 | Used like this: 262 | 263 | ```handlebars 264 | {{#each button}} 265 | {{> button }} 266 | {{/each}} 267 | ``` 268 | 269 | Results in: 270 | 271 | ```html 272 | 273 | 274 | 275 | ``` 276 | 277 | Beyond being passed to templates as context, _data files can also be used for global project configuration and setting options_. See the [documentation for data](#TODO) to learn more. 278 | 279 | 280 | ## All together 281 | 282 | By now your entire Gruntfile config would look something like this: 283 | 284 | ```js 285 | grunt.initConfig({ 286 | 287 | assemble: { 288 | options: { 289 | partials: ['templates/includes/*.hbs'], 290 | layout: 'templates/layouts/default.hbs' 291 | }, 292 | site: { 293 | files: {'dest/': ['templates/*.hbs']} 294 | } 295 | } 296 | }); 297 | ``` 298 | 299 | And that's a wrap! At least for this example, which covers only a fraction of what Assemble has to offer. Please [visit Assemble's documentation](http://assemble.io) if you want to learn about using Assemble, the API, how to extend Assemble, or other topics such as: 300 | 301 | * [Creating plugins](http://assemble.io/plugins/) 302 | * [Registering helpers](http://assemble.io/helper/) 303 | * [Adding template engines](http://assemble.io/engines/) 304 | 305 | If you don't find what you need here or in the docs, we encourage you to visit Assemble's [GitHub Issues][issues] page to create an issue, we're always happy to help new users get started! 306 | 307 | ## Authors 308 | 309 | This example and guide was written by [Jon Schlinkert](https://github.com/jonschlinkert), Assemble was created by: 310 | 311 | **Jon Schlinkert** 312 | 313 | + [github/jonschlinkert](https://github.com/jonschlinkert) 314 | + [twitter/jonschlinkert](http://twitter.com/jonschlinkert) 315 | 316 | **Brian Woodward** 317 | 318 | + [github/doowb](https://github.com/doowb) 319 | + [twitter/doowb](http://twitter.com/jonschlinkert) 320 | 321 | 322 | ## License 323 | 324 | Copyright (c) 2014 [Jon Schlinkert](http://twitter.com/jonschlinkert), [Brian Woodward](http://twitter.com/doowb), contributors. 325 | Released under the [MIT license](./LICENSE-MIT) 326 | 327 | 328 | [permalinks]: https://github.com/assemble/assemble-contrib-permalinks 329 | [helpers]: https://github.com/assemble/assemble-docs/tree/master/src/content/helpers 330 | [issues]: https://github.com/assemble/assemble/issues?direction=desc&sort=updated&state=open 331 | 332 | --------------------------------------------------------------------------------