├── misc ├── .gitignore ├── CNAME ├── README.md └── LICENSE ├── assets ├── css │ ├── main.scss │ └── _custom.scss ├── js │ ├── 01 │ │ └── 01.js │ ├── 02 │ │ └── 02.js │ └── 03 │ │ └── 03.js └── img │ └── favicon.png ├── layouts ├── partials │ ├── scripts.html │ ├── header.html │ ├── footer.html │ ├── nav.html │ ├── head.html │ └── errors.html ├── blank.html ├── page.html └── post.html ├── config ├── assets.js ├── permalinks.js ├── misc.js ├── dateFormat.js ├── uglify.js ├── collections.js ├── scss.js ├── layouts.js ├── watch.js ├── markdown.js ├── browsersync.js ├── build.js ├── helpers.js └── statt.js ├── content ├── posts │ ├── draft.md │ ├── installing-statt.md │ ├── project-scaffold.md │ └── writing-posts.md ├── blog.html ├── contact.html ├── about.html └── index.html ├── site.json ├── .gitignore ├── package.json └── README.md /misc/.gitignore: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /misc/CNAME: -------------------------------------------------------------------------------- 1 | yourdomain[dot]tld 2 | -------------------------------------------------------------------------------- /assets/css/main.scss: -------------------------------------------------------------------------------- 1 | @import "custom"; 2 | -------------------------------------------------------------------------------- /assets/js/01/01.js: -------------------------------------------------------------------------------- 1 | console.log('Path: /assets/js/01/') 2 | -------------------------------------------------------------------------------- /assets/js/02/02.js: -------------------------------------------------------------------------------- 1 | console.log('Path: /assets/js/02/') 2 | -------------------------------------------------------------------------------- /assets/js/03/03.js: -------------------------------------------------------------------------------- 1 | console.log('Path: /assets/js/03/') 2 | -------------------------------------------------------------------------------- /layouts/partials/scripts.html: -------------------------------------------------------------------------------- 1 | 2 | -------------------------------------------------------------------------------- /assets/img/favicon.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/jamiewilson/statt/HEAD/assets/img/favicon.png -------------------------------------------------------------------------------- /layouts/blank.html: -------------------------------------------------------------------------------- 1 | 2 | {{>head}} 3 | 4 | {{{contents}}} 5 | 6 | 7 | -------------------------------------------------------------------------------- /layouts/partials/header.html: -------------------------------------------------------------------------------- 1 |
2 | 3 |
4 |

{{title}}

5 |
6 |
7 | -------------------------------------------------------------------------------- /config/assets.js: -------------------------------------------------------------------------------- 1 | var site = require('../site') 2 | 3 | // https://github.com/treygriffith/metalsmith-assets 4 | module.exports = { 5 | source: '../' + site.assetsDir 6 | } 7 | -------------------------------------------------------------------------------- /layouts/partials/footer.html: -------------------------------------------------------------------------------- 1 | 7 | {{>scripts}} 8 | -------------------------------------------------------------------------------- /layouts/page.html: -------------------------------------------------------------------------------- 1 | 2 | {{>head}} 3 | 4 | {{>nav}} 5 | {{>header}} 6 | {{{contents}}} 7 | {{>footer}} 8 | 9 | 10 | -------------------------------------------------------------------------------- /content/posts/draft.md: -------------------------------------------------------------------------------- 1 | --- 2 | title: Draft 3 | draft: true 4 | parentDir: blog 5 | collection: posts 6 | layout: post.html 7 | --- 8 | 9 | ## This article will not show up in your posts collection because it is marked with `draft: true` in the front-matter 10 | -------------------------------------------------------------------------------- /layouts/partials/nav.html: -------------------------------------------------------------------------------- 1 | 10 | -------------------------------------------------------------------------------- /config/permalinks.js: -------------------------------------------------------------------------------- 1 | // https://github.com/segmentio/metalsmith-permalinks 2 | module.exports = { 3 | // if parentDir is specified in front-matter, 4 | // you can remap links, ex. /pages/posts/post.md -> yoursite.com/blog/post/ 5 | pattern: ':parentDir/:title' 6 | } 7 | -------------------------------------------------------------------------------- /config/misc.js: -------------------------------------------------------------------------------- 1 | var site = require('../site') 2 | 3 | // https://github.com/TheHydroImpulse/metalsmith-static 4 | module.exports = { 5 | // take contents from repo 6 | src: '../' + site.miscDir, 7 | // and place them into the root of /build 8 | dest: '.' 9 | } 10 | -------------------------------------------------------------------------------- /config/dateFormat.js: -------------------------------------------------------------------------------- 1 | // https://github.com/hellatan/metalsmith-date-formatter 2 | module.exports = { 3 | dates: [{ 4 | // the front-matter property name 5 | key: 'published', 6 | // any momentjs format value 7 | // http://momentjs.com/docs/#/parsing/string-format/ 8 | format: 'MMMM DD, YYYY' 9 | }] 10 | } 11 | -------------------------------------------------------------------------------- /config/uglify.js: -------------------------------------------------------------------------------- 1 | // https://github.com/ksmithut/metalsmith-uglify 2 | module.exports = { 3 | // put dependencies before other js files 4 | order: '**', 5 | // concat and compress 6 | concat: 'js/main.js', 7 | // remove original unminified files 8 | removeOriginal: true, 9 | // create a map file 10 | sourceMap: true 11 | } 12 | -------------------------------------------------------------------------------- /config/collections.js: -------------------------------------------------------------------------------- 1 | // https://github.com/segmentio/metalsmith-collections 2 | module.exports = { 3 | posts: { 4 | // Sort by published date in front-matter 5 | sortBy: 'published', 6 | // show in reverse chronological order 7 | reverse: false 8 | }, 9 | pages: { 10 | // Sort by order number specified in front-matter 11 | sortBy: 'order' 12 | } 13 | } 14 | -------------------------------------------------------------------------------- /site.json: -------------------------------------------------------------------------------- 1 | { 2 | "siteName": "statt", 3 | "siteTitle": "New Site", 4 | "siteDescription": "Your new site description.", 5 | "assetsDir": "assets", 6 | "buildDir": "build", 7 | "contentDir": "content", 8 | "layoutsDir": "layouts", 9 | "partialsDir": "layouts/partials", 10 | "defaultLayout": "page.html", 11 | "templateEngine": "handlebars", 12 | "miscDir": "misc" 13 | } 14 | -------------------------------------------------------------------------------- /layouts/partials/head.html: -------------------------------------------------------------------------------- 1 | 2 | {{#if title}}{{title}}{{else}}{{siteTitle}}{{/if}}{{#if siteDescription}} — {{siteDescription}}{{/if}} 3 | 4 | 5 | 6 | 7 | 8 | 9 | -------------------------------------------------------------------------------- /content/blog.html: -------------------------------------------------------------------------------- 1 | --- 2 | title: Blog 3 | subtitle: example posts 4 | collection: pages 5 | order: 2 6 | --- 7 | 8 |
9 | 10 |
11 |

{{titleCase subtitle}}:

12 | 17 |
18 |
19 | -------------------------------------------------------------------------------- /config/scss.js: -------------------------------------------------------------------------------- 1 | var site = require('../site') 2 | 3 | // https://github.com/stevenschobert/metalsmith-sass 4 | module.exports = { 5 | sass: { 6 | // the places to look for SCSS files to process 7 | includePaths: [site.assetsDir + '/css'], 8 | // where to put processed files in the build directory 9 | outputDir: 'css', 10 | // Embed sass contents in your source maps 11 | sourceMapContents: true 12 | } 13 | } 14 | -------------------------------------------------------------------------------- /config/layouts.js: -------------------------------------------------------------------------------- 1 | var site = require('../site') 2 | 3 | // https://github.com/superwolff/metalsmith-layouts 4 | module.exports = { 5 | // The site that will render your layouts 6 | engine: site.templateEngine, 7 | // Where to look for the layouts 8 | directory: '../' + site.layoutsDir, 9 | // Where to look for partials 10 | partials: '../' + site.partialsDir, 11 | // The default layout to use 12 | default: site.defaultLayout 13 | } 14 | -------------------------------------------------------------------------------- /content/contact.html: -------------------------------------------------------------------------------- 1 | --- 2 | title: Contact 3 | collection: pages 4 | order: 4 5 | --- 6 | 7 |
8 | 9 |
10 |

Cum sociis natoque penatibus et magnis dis parturient montes, nascetur ridiculus mus. Donec sed odio dui. Fusce dapibus, tellus ac cursus commodo, tortor mauris condimentum nibh, ut fermentum massa justo sit amet risus. Nullam id dolor id nibh ultricies vehicula ut id elit.

11 |
12 |
13 | -------------------------------------------------------------------------------- /config/watch.js: -------------------------------------------------------------------------------- 1 | var site = require('../site') 2 | var layouts = '../' + site.layoutsDir + '/**/*' 3 | var content = '../' + site.contentDir + '/**/*' 4 | var assets = '../' + site.assetsDir + '/**/*' 5 | 6 | // https://github.com/FWeinb/metalsmith-watch 7 | module.exports = { 8 | paths: { 9 | // Rewrite only changed files. Or `true` rebuilds all files 10 | [layouts]: '**/*', 11 | [content]: '**/*', 12 | [assets]: '**/*' 13 | }, 14 | // Disabled logs to let Browsersync do it 15 | log: (options) => {} 16 | } 17 | -------------------------------------------------------------------------------- /layouts/post.html: -------------------------------------------------------------------------------- 1 | 2 | {{>head}} 3 | 4 | {{>errors}} 5 | {{>nav}} 6 | {{>header}} 7 |
8 | 15 |
16 | {{published}} 17 | {{{contents}}} 18 |
19 |
20 | {{>footer}} 21 | 22 | 23 | 24 | -------------------------------------------------------------------------------- /config/markdown.js: -------------------------------------------------------------------------------- 1 | // https://github.com/segmentio/metalsmith-markdown 2 | module.exports = { 3 | // Enable GitHub flavored markdown. 4 | gfm: true, 5 | // Enable GFM tables. This option requires the gfm option to be true. 6 | tables: true, 7 | // Use "smart" typograhic punctuation for things like quotes and dashes. 8 | smartypants: true, 9 | // Use smarter list behavior than the original markdown. 10 | smartLists: true, 11 | // Sanitize the output. Ignore any HTML that has been input. 12 | sanitize: false, 13 | // removes any markup with the `data-markdown` attribute 14 | removeAttributeAfterwards: true 15 | } 16 | -------------------------------------------------------------------------------- /content/about.html: -------------------------------------------------------------------------------- 1 | --- 2 | title: About 3 | collection: pages 4 | order: 3 5 | --- 6 | 7 |
8 | 9 |
10 |

Lorem ipsum dolor sit amet, consectetur adipisicing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. 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.

11 |
12 |
13 | -------------------------------------------------------------------------------- /layouts/partials/errors.html: -------------------------------------------------------------------------------- 1 | {{#unless parentDir}} 2 |
✖︎ You need to add parentDir: blog to the frontmatter in order for this post to be served from the /blog/post-title address.
3 | {{/unless}} 4 | 5 | {{#unless collection}} 6 |
⚠️ In order for this post to be included in the posts collection, you need to add collection: posts to the frontmatter.
7 | {{/unless}} 8 | 9 | {{#unless published}} 10 |
⚠️ Consider adding a published date, like so published: YYYY-MM-DD, to your post front matter.
11 | {{/unless}} 12 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | # Site Build directory 2 | build 3 | 4 | # Logs 5 | logs 6 | *.log 7 | npm-debug.log* 8 | 9 | # Runtime data 10 | pids 11 | *.pid 12 | *.seed 13 | 14 | # Directory for instrumented libs generated by jscoverage/JSCover 15 | lib-cov 16 | 17 | # Coverage directory used by tools like istanbul 18 | coverage 19 | 20 | # Grunt intermediate storage (http://gruntjs.com/creating-plugins#storing-task-files) 21 | .grunt 22 | 23 | # node-waf configuration 24 | .lock-wscript 25 | 26 | # Compiled binary addons (http://nodejs.org/api/addons.html) 27 | build/Release 28 | 29 | # Dependency directory 30 | # https://docs.npmjs.com/misc/faq#should-i-check-my-node-modules-folder-into-git 31 | node_modules 32 | 33 | # Optional npm cache directory 34 | .npm 35 | 36 | # Optional REPL history 37 | .node_repl_history 38 | -------------------------------------------------------------------------------- /config/browsersync.js: -------------------------------------------------------------------------------- 1 | var site = require('../site') 2 | var children = '/**/*' 3 | 4 | // http://www.browsersync.io/docs/options/ 5 | module.exports = { 6 | // the directory of our build 7 | server: site.buildDir, 8 | // Use projectName for terminal logs 9 | logPrefix: site.siteName, 10 | // Disable the Browsersync UI 11 | ui: false, 12 | // use localtunnel.me to serve public link over https 13 | // tunnel: 'your-desired-subdomain', 14 | // open the local url automatically 15 | open: 'local', 16 | // don't show Browsersync notifications in-browser 17 | notify: false, 18 | // Don't mirror scrolling, clicks by defualt 19 | ghostMode: false, 20 | // Delay reload to ensure enough time for rebuilds 21 | reloadDelay: 200, 22 | // Terminal logs: either "info", "debug", "warn", or "silent" 23 | logLevel: 'info', 24 | files: [ 25 | site.layoutsDir + children, 26 | site.contentDir + children, 27 | site.assetsDir + children 28 | ] 29 | } 30 | -------------------------------------------------------------------------------- /content/index.html: -------------------------------------------------------------------------------- 1 | --- 2 | title: Welcome to Statt 3 | --- 4 | 5 |
6 | 7 |
8 | 9 |

A Metalsmith workflow and boilerplate for building static sites.

10 | 11 |

It uses [Browsersync](http://browsersync.io) to autoreload on file changes, synchronize scrolls and clicks between browsers, and provide a [public URL](http://localtunnel.me) for easy cross-device development. It compiles, [autoprefixes](https://github.com/postcss/autoprefixer), minifies, and sourcemaps [SCSS](http://sass-lang.com/) and concatenates and uglifies JS. It has some default layouts and partials written in [Handlebars](http://handlebarsjs.com) and some blog posts written in [GitHub Flavored Markdown](https://help.github.com/articles/github-flavored-markdown/).

12 | 13 |

Learn more 14 | {{#each-reverse collections.posts}} 15 | – {{title}} 16 | {{/each-reverse}} 17 |

18 | 19 |
20 |
21 | -------------------------------------------------------------------------------- /misc/README.md: -------------------------------------------------------------------------------- 1 | # README Boilerplate 2 | > https://github.com/fraction/readme-boilerplate 3 | 4 | A template of README best practices to make your README simple to understand and easy to use. 5 | 6 | ## Installation 7 | 8 | Download to your project directory, add `README.md`, and commit: 9 | 10 | ```sh 11 | curl -LO http://git.io/Xy0Chg 12 | git add README.md 13 | git commit -m "Use README Boilerplate" 14 | ``` 15 | 16 | ## Usage 17 | 18 | Replace the contents of `README.md` with your project's: 19 | 20 | * Name 21 | * Description 22 | * Installation instructions 23 | * Usage instructions 24 | * Support instructions 25 | * Contributing instructions 26 | 27 | Feel free to remove any sections that aren't applicable to your project. 28 | 29 | ## Support 30 | 31 | Please [open an issue](https://github.com/fraction/readme-boilerplate/issues/new) for support. 32 | 33 | ## Contributing 34 | 35 | Please contribute using [Github Flow](https://guides.github.com/introduction/flow/). Create a branch, add commits, and [open a pull request](https://github.com/fraction/readme-boilerplate/compare/). 36 | -------------------------------------------------------------------------------- /config/build.js: -------------------------------------------------------------------------------- 1 | // Start, Steps, and Build Error Messages 2 | var chalk = require('chalk') 3 | var browsersync = require('browser-sync').create() 4 | var bsConfig = require('./browsersync') 5 | var buildType = (process.env.NODE_ENV || ''); 6 | 7 | // Inform what type of build has started 8 | console.log(chalk.blue(`Building: ${buildType.toUpperCase()}\n`)) 9 | 10 | module.exports = { 11 | // Log each step as it finishes 12 | step: message => { console.log(chalk.green('>> ') + message) }, 13 | 14 | // if NODE_ENV=clean this returns true 15 | clean: (buildType === 'clean'), 16 | 17 | // if NODE_ENV=production then return true 18 | production: (buildType === 'production'), 19 | errors: err => { if (err) throw err }, 20 | 21 | // Launch Browsersync server after build is done 22 | serve: function (err) { 23 | console.log(); 24 | browsersync.init(bsConfig) 25 | if (err) { 26 | // Reports any build errors on initial build 27 | console.log(chalk.magenta('\n' + 'Oops, there was a problem!')) 28 | console.log(err.message + '\n') 29 | } 30 | } 31 | } 32 | -------------------------------------------------------------------------------- /misc/LICENSE: -------------------------------------------------------------------------------- 1 | The MIT License (MIT) 2 | 3 | Copyright (c) 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 all 13 | 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 THE 21 | SOFTWARE. 22 | -------------------------------------------------------------------------------- /content/posts/installing-statt.md: -------------------------------------------------------------------------------- 1 | --- 2 | title: Installing Statt 3 | published: 2016-09-18 4 | parentDir: blog 5 | collection: posts 6 | layout: post.html 7 | --- 8 | 9 | ## Installation 10 | 11 | **1. Make sure [Node](http://nodejs.org) and [npm](https://docs.npmjs.com/getting-started/installing-node) are installed.** 12 | 13 | **2. Clone this repo into a new empty project folder:** 14 | 15 | ``` 16 | git clone https://github.com/jamiewilson/statt.git 17 | ``` 18 | 19 | **3. Install the dependencies:** 20 | 21 | ``` 22 | npm install 23 | ``` 24 | 25 | ## Usage 26 | 27 | **Build your site and launch the dev server:** 28 | 29 | ``` 30 | npm start 31 | ``` 32 | 33 | **To rebuild a clean site with each file change:** 34 | 35 | ``` 36 | npm run clean 37 | ``` 38 | 39 | **Build without launching the dev server:** 40 | 41 | ``` 42 | npm run production 43 | ``` 44 | 45 | ## Updating 46 | To fetch and merge the latest version of Statt without losing any customizations you've made, and to also avoid having to deal with any potential merge conflicts, stash your changes, pull, rebase, and pop your changes back on top: 47 | 48 | ``` 49 | git stash 50 | git pull --rebase 51 | git stash pop 52 | ``` 53 | -------------------------------------------------------------------------------- /package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "statt", 3 | "version": "1.0.0", 4 | "description": "A static site workflow that auto-reloads on file changes; synchronizes browsers; compiles, autoprefixes, minifies, and sourcemaps SCSS; concatenates and uglifies JS; provides an external URL for easy cross-device development.", 5 | "author": "Jamie Wilson", 6 | "license": "ISC", 7 | "scripts": { 8 | "start": "node config/statt.js", 9 | "clean": "NODE_ENV=clean node config/statt.js", 10 | "production": "NODE_ENV=production node config/statt.js" 11 | }, 12 | "dependencies": { 13 | "browser-sync": "^2.16.0", 14 | "chalk": "~1.1.1", 15 | "handlebars": "~4.0.5", 16 | "metalsmith": "~2.1.0", 17 | "metalsmith-assets": "~0.1.0", 18 | "metalsmith-collections": "git+https://github.com/spacedawwwg/metalsmith-collections.git", 19 | "metalsmith-data-markdown": "0.0.3", 20 | "metalsmith-date-formatter": "~1.0.2", 21 | "metalsmith-drafts": "~0.0.1", 22 | "metalsmith-in-place": "~1.3.2", 23 | "metalsmith-layouts": "~1.4.2", 24 | "metalsmith-markdown": "~0.2.1", 25 | "metalsmith-permalinks": "~0.4.0", 26 | "metalsmith-sense-sass": "^1.1.0", 27 | "metalsmith-static": "0.0.5", 28 | "metalsmith-uglify": "~1.2.1", 29 | "metalsmith-watch": "~1.0.1" 30 | }, 31 | "repository": { 32 | "type": "git", 33 | "url": "https://github.com/jamiewilson/statt.git" 34 | } 35 | } 36 | -------------------------------------------------------------------------------- /content/posts/project-scaffold.md: -------------------------------------------------------------------------------- 1 | --- 2 | title: Project Scaffold 3 | published: 2016-10-25 4 | parentDir: blog 5 | collection: posts 6 | layout: post.html 7 | starter: 8 | templates: 9 | - page 10 | - post 11 | - blank 12 | partials: 13 | - head 14 | - nav 15 | - header 16 | - footer 17 | - scripts 18 | - errors 19 | --- 20 | 21 | ## To get your new site started, there are some basic layouts, partials, pages, and posts already set up for you. 22 | 23 | Default settings can be edited in `site.json` 24 | 25 | ```json 26 | { 27 | "siteName": "{{siteName}}", 28 | "siteTitle": "{{siteTitle}}", 29 | "siteDescription": "{{siteDescription}}", 30 | "assetsDir": "{{assetsDir}}", 31 | "buildDir": "{{buildDir}}", 32 | "contentDir": "{{contentDir}}", 33 | "layoutsDir": "{{layoutsDir}}", 34 | "partialsDir": "{{partialsDir}}", 35 | "defaultLayout": "{{defaultLayout}}", 36 | "templateEngine": "{{templateEngine}}" 37 | } 38 | ``` 39 | 40 | And referenced in your site or like `\{{siteName}}` or `\{{siteTitle}}` 41 | 42 | **There are {{starter.templates.length}} templates:** 43 |
    44 | {{#each starter.templates}} 45 |
  • `{{this}}` — `layouts/{{this}}.html`
  • 46 | {{/each}} 47 |
48 | 49 | **And {{starter.partials.length}} partials:** 50 |
    51 | {{#each partials}} 52 |
  • `{{@key}}` — `layouts/partials/{{@key}}.html`
  • 53 | {{/each}} 54 |
55 | 56 | **Which are used to make these {{add pages.length 1}} pages:** 57 |
    58 |
  • `index` — `content/index.html`
  • 59 | {{#each pages}} 60 |
  • `{{path}}` — `content/{{path}}.html`
  • 61 | {{/each}} 62 |
63 | 64 | **And these {{posts.length}} example posts:** 65 |
    66 | {{#each posts}} 67 |
  • `{{title}}` — `content/posts/{{slugify title}}.md`
  • 68 | {{/each}} 69 |
70 | -------------------------------------------------------------------------------- /config/helpers.js: -------------------------------------------------------------------------------- 1 | var Handlebars = require('handlebars') 2 | 3 | /** 4 | * Slugify 5 | * {{slugify title}} 6 | * ex: "This is the title" to "this-is-the-title" 7 | * 8 | * @param {string} str 9 | */ 10 | 11 | Handlebars.registerHelper('slugify', function (str) { 12 | var slug = str.replace(/[^\w\s]+/gi, "").replace(/ +/gi, "-") 13 | return slug.toLowerCase() 14 | }) 15 | 16 | /** 17 | * Add 18 | * {{add length 1}} 19 | * 20 | * @param {number} value 21 | * @param {number} addition 22 | */ 23 | 24 | Handlebars.registerHelper('add', function (value, addition) { 25 | return value + addition 26 | }) 27 | 28 | /** 29 | * Subtract 30 | * {{subtract length 3}} 31 | * 32 | * @param {number} value 33 | * @param {number} subtraction 34 | */ 35 | 36 | Handlebars.registerHelper('subtract', function (value, subtraction) { 37 | return value - subtraction 38 | }) 39 | 40 | /** 41 | * Iterate in reverse 42 | * {{#each-reverse posts}} 43 | * 44 | * @param {array} context 45 | */ 46 | 47 | Handlebars.registerHelper('each-reverse', function (context) { 48 | var options = arguments[arguments.length - 1] 49 | var ret = '' 50 | 51 | if (context && context.length > 0) { 52 | for (var i = context.length - 1; i >= 0; i--) { 53 | ret += options.fn(context[i]) 54 | } 55 | } else { 56 | ret = options.inverse(this) 57 | } 58 | return ret; 59 | }) 60 | 61 | /** 62 | * Capitalize 63 | * {{capitalize name}} 64 | * ex: "bob" to "Bob" 65 | * 66 | * @param {string} word 67 | */ 68 | 69 | Handlebars.registerHelper('capitalize', function (word) { 70 | return word.charAt(0).toUpperCase() + word.slice(1) 71 | }) 72 | 73 | /** 74 | * Title Case 75 | * {{titleCase title}} 76 | * ex: "This is the title" to "This Is The Title" 77 | * 78 | * @param {string} str 79 | */ 80 | 81 | Handlebars.registerHelper('titleCase', function (str) { 82 | if (typeof str === 'undefined') return ''; 83 | return str.replace(/\w\S*/g, function (txt) { 84 | return txt.charAt(0).toUpperCase() + txt.substr(1).toLowerCase() 85 | }) 86 | }) 87 | -------------------------------------------------------------------------------- /config/statt.js: -------------------------------------------------------------------------------- 1 | var metalsmith = require('metalsmith') 2 | var assets = require('metalsmith-assets') 3 | var collections = require('metalsmith-collections') 4 | var misc = require('metalsmith-static') 5 | var datamarkdown = require('metalsmith-data-markdown') 6 | var dateFormat = require('metalsmith-date-formatter') 7 | var drafts = require('metalsmith-drafts') 8 | var inplace = require('metalsmith-in-place') 9 | var layouts = require('metalsmith-layouts') 10 | var markdown = require('metalsmith-markdown') 11 | var permalinks = require('metalsmith-permalinks') 12 | var scss = require('metalsmith-sense-sass') 13 | var uglify = require('metalsmith-uglify') 14 | var watch = require('metalsmith-watch') 15 | 16 | // Data, log, and config 17 | var site = require('../site') 18 | var step = require('./build').step 19 | var serve = require('./build').serve 20 | var clean = require('./build').clean 21 | var production = require('./build').production 22 | var errors = require('./build').errors 23 | 24 | var config = { 25 | assets: require('./assets'), 26 | collections: require('./collections'), 27 | misc: require('./misc'), 28 | dateFormat: require('./dateFormat'), 29 | helpers: require('./helpers'), 30 | layouts: require('./layouts'), 31 | markdown: require('./markdown'), 32 | permalinks: require('./permalinks'), 33 | scss: require('./scss'), 34 | uglify: require('./uglify'), 35 | watch: require('./watch') 36 | } 37 | 38 | // Base build pipeline - order matters! 39 | var statt = metalsmith(__dirname) 40 | .clean(clean || production) 41 | .metadata(site, step('Metadata defined')) 42 | .source('../' + site.contentDir, step('Content sourced')) 43 | .destination('../' + site.buildDir, step('Build directory created')) 44 | .use(markdown(config.markdown), step('Markdown files converted')) 45 | .use(drafts(), step('Draft posts hidden')) 46 | .use(dateFormat(config.dateFormat), step('Post dates formatted')) 47 | .use(collections(config.collections), step('Collections defined')) 48 | .use(permalinks(config.permalinks), step('Permalinks created')) 49 | .use(layouts(config.layouts), step('Layouts applied')) 50 | .use(inplace(config.layouts), step('Templating rendered')) 51 | .use(datamarkdown(config.markdown), step('Data-markdown converted')) 52 | .use(assets(config.assets), step('Assets folder copied')) 53 | .use(scss(config.scss), step('SCSS compiled & prefixed')) 54 | .use(uglify(config.uglify), step('JS concatenated & minified')) 55 | .use(misc(config.misc), step('Misc folder copied')); 56 | 57 | // Production or Dev Environment 58 | (production) ? statt.build(errors) : statt.use(watch(config.watch)).build(serve) 59 | -------------------------------------------------------------------------------- /content/posts/writing-posts.md: -------------------------------------------------------------------------------- 1 | --- 2 | title: Writing Posts 3 | published: 2016-12-05 4 | parentDir: blog 5 | collection: posts 6 | layout: post.html 7 | --- 8 | 9 | ## Markdown allows you to write using an easy-to-read, easy-to-write plain text format that converts to HTML. 10 | 11 | By typing different characters and punctuation, you can **bold**, _italicize_, [link](http://thisismarkdown.com/) your text, and display images. 12 | 13 | ### Bold 14 | Wrap words with two asterisks: 15 | 16 | **I am bold.** 17 | 18 | ### Italic 19 | Wrap words with an underscore: 20 | 21 | _I am italic._ 22 | 23 | ### Links 24 | Wrap word(s) in square brackets and the link in parentheses: 25 | 26 | [I am a [link](http://thisismarkdown.com/) 27 | 28 | ### Images 29 | Like a text link, but with an exclamation point at the beginning: 30 | 31 | ![Optional Alt Text](/img/example.gif "Optional title") 32 | 33 | _Note: You **must** link directly to an image, i.e. ending in `.gif`, `.jpg`, etc._ 34 | 35 | ![fullwidth](https://farm6.static.flickr.com/5029/5658551241_8852d44b38_o.gif "An Emedded Image in Markdown") 36 | 37 | ### New Lines 38 | To create a new line, you need to end with two empty spaces (shown as black boxes below): 39 | 40 | This will be on the first line🁢🁢 41 | and this will be on the second line 42 | 43 | ### Headings 44 | Using the `#` symbol you can set **H3** through **H6** headings. Unfortunately, **H1** and **H2** aren't working right now. 45 | 46 | ### This is an H3 47 | #### This is an H4 48 | 49 | 50 | ## More Options 51 | 52 | ### Bulleted Lists 53 | Add a dash `-` in front of each line: 54 | 55 | - Item One 56 | - Item Two 57 | - Item Three 58 | 59 | ### Numbered Lists 60 | Add a number and period in front of each line: 61 | 62 | 1. Item One 63 | 1. Item Two 64 | 1. Item Three 65 | 66 | _Note: That's not a typo. Using only `1.` will still convert to a proper numbered list, which makes reordering lists a lot easier_ 67 | 68 | ### Block Quotes 69 | Add a ` > ` at the beginning of a paragraph to quote it: 70 | 71 | > this line will look like the quote below 72 | 73 | > this is what a blockquote looks like 74 | 75 | ### Inline Code 76 | Wrap text in a single backtick at the top left of your keyboard: 77 | 78 | `border-radius: 3px;` 79 | 80 | ### Code Block 81 | Wrap code with triple backticks, and add the language name like so: 82 | 83 | ```html 84 |
85 | 86 |
87 |

Blog

88 |
    89 |
  • {{ title }}
  • 90 |
91 |
92 |
93 | ``` 94 | 95 | ### Horizontal Rules 96 | To create a horizontal line for separating content use: 97 | 98 | *** OR --- 99 | 100 | ### Tables 101 | Using vertical lines `|`, you can even create tables: 102 | 103 | | Making | Markdown | Tables | 104 | |-------------|:-----------:|---------:| 105 | | This column | This one | And this | 106 | | is left | is set to | is right | 107 | | align | be centered | aligned | 108 | 109 | The markdown to create this _(notice the use of `:` to indicate alignment)_: 110 | 111 | | Making | Markdown | Tables | 112 | |-------------|:-----------:|---------:| 113 | | This column | This one | And this | 114 | | is left | is set to | is right | 115 | | align | be centered | aligned | 116 | 117 | **To learn even more about Markdown, check out https://daringfireball.net/projects/markdown/** 118 | -------------------------------------------------------------------------------- /assets/css/_custom.scss: -------------------------------------------------------------------------------- 1 | *, 2 | *:before, 3 | *:after { 4 | box-sizing: border-box; 5 | } 6 | 7 | body { 8 | font-family: -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, Oxygen, Ubuntu, Cantarell, "Open Sans", "Helvetica Neue", sans-serif; 9 | color: #555; 10 | margin: 0; 11 | line-height: 1.6; 12 | // background: red; 13 | } 14 | 15 | .container { 16 | max-width: 950px; 17 | margin: 0 auto; 18 | padding: 5% 20px; 19 | } 20 | 21 | nav, 22 | header, 23 | main, 24 | footer, 25 | article { 26 | border: 1px solid #e5e5e5; 27 | overflow: hidden; 28 | margin-bottom: 2rem; 29 | } 30 | 31 | nav ul { 32 | display: flex; 33 | justify-content: space-around; 34 | list-style: none; 35 | margin: 0; 36 | } 37 | 38 | div, 39 | section, 40 | nav ul { padding: 1.5rem; } 41 | 42 | p:first-child {margin-top: 0} 43 | p:last-child {margin-bottom: 0} 44 | 45 | aside { 46 | background-color: #f2f2f2; 47 | font-size: 0.75rem; 48 | padding: 0.5rem 1rem; 49 | display: flex; 50 | justify-content: space-between; 51 | span { display: inline-flex; } 52 | } 53 | 54 | aside a { margin-left: 1rem; } 55 | 56 | h1 { 57 | font-size: 2rem; 58 | line-height: 1.2; 59 | margin: 0; 60 | } 61 | 62 | h2 { 63 | font-size: 1.5rem; 64 | border-bottom: 1px solid #eee; 65 | padding-bottom: 1.5rem; 66 | margin-bottom: 1.5rem; 67 | line-height: 1.3; 68 | } 69 | 70 | h3 { 71 | font-size: 1.3rem; 72 | border-bottom: 1px solid #eee; 73 | padding-bottom: 1.1rem; 74 | margin-bottom: 1.3rem; 75 | line-height: 1.4; 76 | } 77 | 78 | h4 { 79 | font-size: 1.2rem; 80 | line-height: 1.5; 81 | } 82 | 83 | h5 { 84 | font-size: 1.1rem; 85 | } 86 | 87 | h6 { 88 | font-size: 1rem; 89 | } 90 | 91 | p { 92 | margin: 0; 93 | margin-bottom: 1rem; 94 | } 95 | 96 | img[alt="fullwidth"] { width: 100%; } 97 | 98 | figure { margin: 0; } 99 | 100 | a { color: #f18260; } 101 | 102 | a[href=""] { 103 | color: #ccc; 104 | text-decoration: none; 105 | pointer-events: none; 106 | } 107 | 108 | // Code Blocks 109 | 110 | pre, 111 | code { 112 | background-color: #f2f2f2; 113 | border-radius: 3px; 114 | color: #333; 115 | font-size: 0.875rem; 116 | overflow: auto; 117 | padding: 1rem; 118 | margin-bottom: 2rem; 119 | } 120 | 121 | pre code { padding: 0; } 122 | code { padding: 0.2rem 0.4rem; } 123 | 124 | // Tables 125 | 126 | table { 127 | width: 100%; 128 | table-layout: fixed; 129 | border: 1px solid #ddd; 130 | border-collapse: collapse; 131 | margin-bottom: 2rem; 132 | } 133 | 134 | thead { background-color: #f2f2f2; } 135 | tr { border-bottom: 1px solid #ddd; } 136 | td { display: table-flex; } 137 | 138 | tbody tr:last-child { border-bottom: none; } 139 | 140 | th:not(:last-child), 141 | td:not(:last-child) { 142 | border-right: 1px solid #ddd; 143 | } 144 | 145 | th, td { 146 | padding: 0.5rem; 147 | text-align: left; 148 | line-height: 1.4; 149 | } 150 | 151 | //==================================================== 152 | // Boilerplate Error Messages 153 | //==================================================== 154 | 155 | $warning: #EEB121; 156 | $error: #E07F75; 157 | 158 | .message { 159 | color: black; 160 | padding: 1rem; 161 | font-size: 14px; 162 | border-radius: 3px; 163 | border-width: 1px; 164 | border-style: solid; 165 | margin-bottom: 1rem; 166 | code { 167 | font-size: 12px; 168 | background: white; 169 | } 170 | } 171 | 172 | .warning { 173 | background: fade-out($warning, 0.75); 174 | border-color: $warning; 175 | &:first-letter { 176 | margin-right: 0.5rem; 177 | color: $warning; 178 | } 179 | } 180 | 181 | .error { 182 | background: fade-out($error, 0.75); 183 | border-color: $error; 184 | &:first-letter { 185 | margin-right: 0.5rem; 186 | color: $error; 187 | } 188 | } 189 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # Statt 2 | #### A [Metalsmith](http://metalsmith.io) workflow and boilerplate for building static sites. 3 | 4 | It uses [Browsersync](http://browsersync.io) to autoreload on file changes, synchronize scrolls and clicks between browsers, and provide a [public URL](http://localtunnel.me) for easy cross-device development. It compiles, [autoprefixes](https://github.com/postcss/autoprefixer), minifies, and sourcemaps [SCSS](http://sass-lang.com/) and concatenates and uglifies JS. It has some default layouts and partials written in [Handlebars](http://handlebarsjs.com) and some blog posts written in [GitHub Flavored Markdown](https://help.github.com/articles/github-flavored-markdown/). Easily deploy your project with a custom domain for free using [Surge](https://surge.sh). 5 | 6 | ## Installation 7 | 8 | **1. Make sure [Node](http://nodejs.org) and [npm](https://docs.npmjs.com/getting-started/installing-node) are installed.** 9 | 10 | **2. Clone this repo into a new empty project folder:** 11 | 12 | ``` 13 | git clone https://github.com/jamiewilson/ore.git 14 | ``` 15 | 16 | **3. Install the dependencies:** 17 | 18 | ```bash 19 | npm install 20 | ``` 21 | 22 | ## Usage 23 | 24 | **Build your site and launch the dev server:** 25 | 26 | ```bash 27 | npm start 28 | ``` 29 | 30 | **To rebuild a clean site with each file change:** 31 | 32 | ```bash 33 | npm run clean 34 | ``` 35 | 36 | **Build without launching the dev server:** 37 | 38 | ```bash 39 | npm run production 40 | ``` 41 | 42 | _Et voilà._ 43 | 44 | ## Complete list of plugins/packages: 45 | 46 | **[Metalsmith](http://metalsmith.io)** 47 | An extremely simple, pluggable static site generator. 48 | 49 | **[Browsersync](https://github.com/Browsersync/browser-sync)** 50 | Keep multiple browsers & devices in sync when building websites. 51 | 52 | **[Handlebars](http://handlebarsjs.com/)** 53 | Clean logicless templates based on the [Mustache Templating Language](http://mustache.github.com/). 54 | 55 | **[Surge](https://github.com/sintaxi/surge)** 56 | Publish web apps to a CDN with a single command and no setup required. 57 | 58 | ### Metalsmith Plugins 59 | 60 | **[metalsmith-assets](https://github.com/treygriffith/metalsmith-assets)** 61 | Include static assets in your build. _Used to create a separate `/assets` folder._ 62 | 63 | **[metalsmith-autoprefixer](https://github.com/esundahl/metalsmith-autoprefixer)** 64 | Automatically add vendor prefixes to CSS. 65 | 66 | **[metalsmith-collections](https://github.com/segmentio/metalsmith-collections)** 67 | Groups files together into collections, which it adds to the global metadata. 68 | 69 | **[metalsmith-static](https://github.com/TheHydroImpulse/metalsmith-static)** 70 | Copy public assets into the build directory. _Used to create a `/repo` folder that includes files like a `README`, `CNAME`, or `.gitignore`_ 71 | 72 | **[metalsmith-date-formatter](https://github.com/hellatan/metalsmith-date-formatter)** 73 | Format dates defined in the YAML Front Matter. 74 | 75 | **[metalsmith-drafts](https://github.com/segmentio/metalsmith-drafts)** 76 | Hide any files marked as drafts. 77 | 78 | **[metalsmith-in-place](https://github.com/superwolff/metalsmith-in-place)** 79 | Allows you to render templating syntax in your source files. 80 | 81 | **[metalsmith-layouts](https://github.com/superwolff/metalsmith-in-place)** 82 | Allows you to apply layouts to your source files. 83 | 84 | **[metalsmith-markdown](https://github.com/segmentio/metalsmith-markdown)** 85 | Convert Markdown files to HTML. 86 | 87 | **[metalsmith-data-markdown](https://github.com/majodev/metalsmith-data-markdown)** 88 | Use markdown content within html tags via data-markdown attribute. 89 | 90 | **[metalsmith-permalinks](https://github.com/segmentio/metalsmith-permalinks)** 91 | Apply custom permalinks and rename files to be nested properly for static sites, basically converting about.html into about/index.html. 92 | 93 | **[metalsmith-sass](https://github.com/stevenschobert/metalsmith-sass)** 94 | Convert Sass/SCSS syntax to CSS. 95 | 96 | **[metalsmith-uglify](https://github.com/ksmithut/metalsmith-uglify)** 97 | Concats/uglifies/minifies your JavaScript files. 98 | 99 | **[metalsmith-watch](https://github.com/FWeinb/metalsmith-watch)** 100 | Watches for a changes and triggers rebuilds. 101 | 102 | ### Misc. 103 | 104 | **[Chalk](https://github.com/chalk/chalk)** 105 | Terminal string styling done right. 106 | 107 | ## Updating 108 | To fetch and merge the latest version of Statt without losing any customizations you've made, and to also avoid having to deal with any potential merge conflicts, add and then stash your changes, pull the latest code and rebase, then pop your changes back on top: 109 | 110 | ``` 111 | git add . 112 | git stash 113 | git pull --rebase 114 | git stash pop 115 | ``` 116 | --------------------------------------------------------------------------------