diff --git a/.bowerrc b/.bowerrc new file mode 100644 index 0000000..69fad35 --- /dev/null +++ b/.bowerrc @@ -0,0 +1,3 @@ +{ + "directory": "bower_components" +} diff --git a/.editorconfig b/.editorconfig new file mode 100644 index 0000000..c2cdfb8 --- /dev/null +++ b/.editorconfig @@ -0,0 +1,21 @@ +# EditorConfig helps developers define and maintain consistent +# coding styles between different editors and IDEs +# editorconfig.org + +root = true + + +[*] + +# Change these settings to your own preference +indent_style = space +indent_size = 2 + +# We recommend you to keep these unchanged +end_of_line = lf +charset = utf-8 +trim_trailing_whitespace = true +insert_final_newline = true + +[*.md] +trim_trailing_whitespace = false diff --git a/.gitattributes b/.gitattributes new file mode 100644 index 0000000..2125666 --- /dev/null +++ b/.gitattributes @@ -0,0 +1 @@ +* text=auto \ No newline at end of file diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..fe4e7d4 --- /dev/null +++ b/.gitignore @@ -0,0 +1,5 @@ +node_modules +dist +.tmp +app/.build +bower_components diff --git a/.jshintrc b/.jshintrc new file mode 100644 index 0000000..e0e0730 --- /dev/null +++ b/.jshintrc @@ -0,0 +1,21 @@ +{ + "node": true, + "browser": true, + "esnext": true, + "bitwise": true, + "camelcase": true, + "curly": true, + "eqeqeq": true, + "immed": true, + "indent": 2, + "latedef": true, + "newcap": true, + "noarg": true, + "quotmark": "single", + "undef": true, + "unused": true, + "strict": true, + "trailing": true, + "smarttabs": true, + "jquery": true +} diff --git a/Gruntfile.js b/Gruntfile.js new file mode 100644 index 0000000..2fd4acc --- /dev/null +++ b/Gruntfile.js @@ -0,0 +1,411 @@ +// Generated on 2014-10-14 using +// generator-webapp 0.5.1 +'use strict'; + +// # Globbing +// for performance reasons we're only matching one level down: +// 'test/spec/{,*/}*.js' +// If you want to recursively match all subfolders, use: +// 'test/spec/**/*.js' + +module.exports = function (grunt) { + + // Time how long tasks take. Can help when optimizing build times + require('time-grunt')(grunt); + + // Load grunt tasks automatically + require('load-grunt-tasks')(grunt); + + // Configurable paths + var config = { + app: 'app/.build', + dist: 'dist' + }; + + // Define the configuration for all the tasks + grunt.initConfig({ + + // Project settings + config: config, + + // Watches files for changes and runs tasks based on the changed files + watch: { + bower: { + files: ['bower.json'], + tasks: ['wiredep'] + }, + js: { + files: ['app/contents/scripts/{,*/}*.js'], + tasks: ['wintersmith', 'jshint'], + options: { + livereload: true + } + }, + jstest: { + files: ['test/spec/{,*/}*.js'], + tasks: ['test:watch'] + }, + gruntfile: { + files: ['Gruntfile.js'] + }, + styles: { + files: ['app/contents/styles/{,*/}*.css'], + tasks: ['wintersmith', 'newer:copy:styles', 'autoprefixer'] + }, + livereload: { + options: { + livereload: '<%= connect.options.livereload %>' + }, + files: [ + 'app/templates/{,*/}*.html', + '.tmp/styles/{,*/}*.css', + 'app/contents/images/{,*/}*' + ], + tasks: ['wintersmith'] + } + }, + + // The actual grunt server settings + connect: { + options: { + port: 9000, + open: true, + livereload: 35729, + // Change this to '0.0.0.0' to access the server from outside + hostname: 'localhost' + }, + livereload: { + options: { + middleware: function(connect) { + return [ + connect.static('.tmp'), + connect().use('/bower_components', connect.static('./bower_components')), + connect.static(config.app) + ]; + } + } + }, + test: { + options: { + open: false, + port: 9001, + middleware: function(connect) { + return [ + connect.static('.tmp'), + connect.static('test'), + connect().use('/bower_components', connect.static('./bower_components')), + connect.static(config.app) + ]; + } + } + }, + dist: { + options: { + base: '<%= config.dist %>', + livereload: false + } + } + }, + + // Empties folders to start fresh + clean: { + dist: { + files: [{ + dot: true, + src: [ + '.tmp', + 'app/.build', + '<%= config.dist %>/*', + '!<%= config.dist %>/.git*' + ] + }] + }, + server: ['.tmp', 'app/.build'] + }, + + // The wintersmith static site generation settings. + wintersmith: { + dist: { + options: { + config: { + contents: 'app/contents', + templates: 'app/templates', + output: 'app/.build', + locals: require('./config.json').locals, + plugins: [ + 'wintersmith-nunjucks' + ] + } + } + } + }, + + // Make sure code styles are up to par and there are no obvious mistakes + jshint: { + options: { + jshintrc: '.jshintrc', + reporter: require('jshint-stylish') + }, + all: [ + 'Gruntfile.js', + '<%= config.app %>/scripts/{,*/}*.js', + '!<%= config.app %>/scripts/vendor/*', + 'test/spec/{,*/}*.js' + ] + }, + + // Mocha testing framework configuration options + mocha: { + all: { + options: { + run: true, + urls: ['http://<%= connect.test.options.hostname %>:<%= connect.test.options.port %>/index.html'] + } + } + }, + + // Add vendor prefixed styles + autoprefixer: { + options: { + browsers: ['> 1%', 'last 2 versions', 'Firefox ESR', 'Opera 12.1'] + }, + dist: { + files: [{ + expand: true, + cwd: '.tmp/styles/', + src: '{,*/}*.css', + dest: '.tmp/styles/' + }] + } + }, + + // Automatically inject Bower components into the HTML file + wiredep: { + app: { + ignorePath: /^\/|\.\.\//, + src: ['<%= config.app %>/index.html'], + exclude: ['bower_components/bootstrap/dist/js/bootstrap.js'] + } + }, + + // Renames files for browser caching purposes + rev: { + dist: { + files: { + src: [ + '<%= config.dist %>/scripts/{,*/}*.js', + '<%= config.dist %>/styles/{,*/}*.css', + '<%= config.dist %>/images/{,*/}*.*', + '<%= config.dist %>/styles/fonts/{,*/}*.*', + '<%= config.dist %>/*.{ico,png}' + ] + } + } + }, + + // Reads HTML for usemin blocks to enable smart builds that automatically + // concat, minify and revision files. Creates configurations in memory so + // additional tasks can operate on them + useminPrepare: { + options: { + dest: '<%= config.dist %>' + }, + html: '<%= config.app %>/index.html' + }, + + // Performs rewrites based on rev and the useminPrepare configuration + usemin: { + options: { + assetsDirs: [ + '<%= config.dist %>', + '<%= config.dist %>/images', + '<%= config.dist %>/styles' + ] + }, + html: ['<%= config.dist %>/{,*/}*.html'], + css: ['<%= config.dist %>/styles/{,*/}*.css'] + }, + + // The following *-min tasks produce minified files in the dist folder + imagemin: { + dist: { + files: [{ + expand: true, + cwd: '<%= config.app %>/images', + src: '{,*/}*.{gif,jpeg,jpg,png}', + dest: '<%= config.dist %>/images' + }] + } + }, + + svgmin: { + dist: { + files: [{ + expand: true, + cwd: '<%= config.app %>/images', + src: '{,*/}*.svg', + dest: '<%= config.dist %>/images' + }] + } + }, + + htmlmin: { + dist: { + options: { + collapseBooleanAttributes: true, + collapseWhitespace: true, + conservativeCollapse: true, + removeAttributeQuotes: true, + removeCommentsFromCDATA: true, + removeEmptyAttributes: true, + removeOptionalTags: true, + removeRedundantAttributes: true, + useShortDoctype: true + }, + files: [{ + expand: true, + cwd: '<%= config.dist %>', + src: '{,*/}*.html', + dest: '<%= config.dist %>' + }] + } + }, + + // By default, your `index.html`'s will take care + // of minification. These next options are pre-configured if you do not + // wish to use the Usemin blocks. + // cssmin: { + // dist: { + // files: { + // '<%= config.dist %>/styles/main.css': [ + // '.tmp/styles/{,*/}*.css', + // '<%= config.app %>/styles/{,*/}*.css' + // ] + // } + // } + // }, + // uglify: { + // dist: { + // files: { + // '<%= config.dist %>/scripts/scripts.js': [ + // '<%= config.dist %>/scripts/scripts.js' + // ] + // } + // } + // }, + // concat: { + // dist: {} + // }, + + // Copies remaining files to places other tasks can use + copy: { + dist: { + files: [{ + expand: true, + dot: true, + cwd: '<%= config.app %>', + dest: '<%= config.dist %>', + src: [ + '*.{ico,png,txt}', + 'images/{,*/}*.webp', + '{,*/}*.html', + 'styles/fonts/{,*/}*.*' + ] + }, { + src: 'node_modules/apache-server-configs/dist/.htaccess', + dest: '<%= config.dist %>/.htaccess' + }, { + expand: true, + dot: true, + cwd: 'bower_components/bootstrap/dist', + src: 'fonts/*', + dest: '<%= config.dist %>' + }] + }, + styles: { + expand: true, + dot: true, + cwd: '<%= config.app %>/styles', + dest: '.tmp/styles/', + src: '{,*/}*.css' + } + }, + + // Run some tasks in parallel to speed up build process + concurrent: { + server: [ + 'copy:styles' + ], + test: [ + 'copy:styles' + ], + dist: [ + 'copy:styles', + 'imagemin', + 'svgmin' + ] + } + }); + + grunt.loadNpmTasks('grunt-wintersmith'); + grunt.registerTask('serve', 'start the server and preview your app, --allow-remote for remote access', function (target) { + if (grunt.option('allow-remote')) { + grunt.config.set('connect.options.hostname', '0.0.0.0'); + } + if (target === 'dist') { + return grunt.task.run(['build', 'connect:dist:keepalive']); + } + + grunt.task.run([ + 'clean:server', + 'wintersmith', + 'wiredep', + 'concurrent:server', + 'autoprefixer', + 'connect:livereload', + 'watch' + ]); + }); + + grunt.registerTask('server', function (target) { + grunt.log.warn('The `server` task has been deprecated. Use `grunt serve` to start a server.'); + grunt.task.run([target ? ('serve:' + target) : 'serve']); + }); + + grunt.registerTask('test', function (target) { + if (target !== 'watch') { + grunt.task.run([ + 'clean:server', + 'concurrent:test', + 'autoprefixer' + ]); + } + + grunt.task.run([ + 'connect:test', + 'mocha' + ]); + }); + + grunt.registerTask('build', [ + 'clean:dist', + 'wiredep', + 'wintersmith', + 'useminPrepare', + 'concurrent:dist', + 'autoprefixer', + 'concat', + 'cssmin', + 'uglify', + 'copy:dist', + 'rev', + 'usemin', + 'htmlmin' + ]); + + grunt.registerTask('default', [ + 'newer:jshint', + 'test', + 'build' + ]); +}; diff --git a/Readme.md b/Readme.md new file mode 100644 index 0000000..4a87933 --- /dev/null +++ b/Readme.md @@ -0,0 +1,64 @@ +JuckStrap - Static site generation bliss with Nunjucks + Bootstrap + Wintersmith.js +================================================================================== + +This is a project that aims to quickly bootstrap a new web application project "the right way". This includes using Bootstrap CSS within Nunjucks templating system, all statically generated with Wintersmith.js. This project also includes all of the necessary Grunt tools to make your life easier as you build a new web application rapidly and properly. + +Prerequisites +--------------- +There are a few things you will need to get started. + - **[Node.js](http://nodejs.org/)** - Go to http://nodejs.org/ and follow the installation instructions. + - **[Grunt CLI](http://gruntjs.com/getting-started)** + + ``` + npm install -g grunt-cli + ``` + - **[Bower](http://bower.io/)** + ``` + npm install -g bower + ``` + +Installation +--------------- + +To use this project, you must first install [Node.js](http://nodejs.org/). To install, first clone this repo, and then type the following in the directory. + +``` +npm install +``` + +Next you will need to make sure you install Bower components in both the root and test folders. + +``` +bower install +cd test +bower install +``` + +Configuration +--------------------- +A lot of the site configuration can be found within the **config.json** file in the root of the project. You can use this to edit configurations that Wintersmith uses to build the web appication. + +The Web Application +--------------------- +All of the changes that you need to make are within the **app** folder. This contains the Wintermith setup for a Nunjucks templated site. Go to http://wintersmith.io/ to learn more about editing a Wintersmith application and also go to http://mozilla.github.io/nunjucks to learn about the Nunjucks templating language. + +Running +--------------------- +You can run this web application by typing the following in your terminal. + +``` +grunt serve +``` + +This also watches all the files within the *app* directory and when a change is made re-compiles the application and automatically updates the site in your browser. + + +Compiling +--------------------- +This project compiles and runs using Grunt. You can compile the application using the simple grunt command. + +``` +grunt +``` + +This creates a **dist** folder that you can use to copy to your webserver. diff --git a/app/contents/favicon.ico b/app/contents/favicon.ico new file mode 100644 index 0000000..6527905 Binary files /dev/null and b/app/contents/favicon.ico differ diff --git a/app/contents/index.json b/app/contents/index.json new file mode 100644 index 0000000..637fa0e --- /dev/null +++ b/app/contents/index.json @@ -0,0 +1,3 @@ +{ + "template": "index.html" +} diff --git a/app/contents/robots.txt b/app/contents/robots.txt new file mode 100644 index 0000000..ee2cc21 --- /dev/null +++ b/app/contents/robots.txt @@ -0,0 +1,3 @@ +# robotstxt.org/ + +User-agent: * diff --git a/app/contents/scripts/main.js b/app/contents/scripts/main.js new file mode 100644 index 0000000..20ca76d --- /dev/null +++ b/app/contents/scripts/main.js @@ -0,0 +1 @@ +console.log('\'Allo \'Allo!'); \ No newline at end of file diff --git a/app/contents/styles/main.css b/app/contents/styles/main.css new file mode 100644 index 0000000..e69de29 diff --git a/app/templates/includes/analytics.html b/app/templates/includes/analytics.html new file mode 100644 index 0000000..4c4d50e --- /dev/null +++ b/app/templates/includes/analytics.html @@ -0,0 +1,8 @@ + diff --git a/app/templates/includes/browsehappy.html b/app/templates/includes/browsehappy.html new file mode 100644 index 0000000..4217d05 --- /dev/null +++ b/app/templates/includes/browsehappy.html @@ -0,0 +1,3 @@ + diff --git a/app/templates/includes/header.html b/app/templates/includes/header.html new file mode 100644 index 0000000..17ee645 --- /dev/null +++ b/app/templates/includes/header.html @@ -0,0 +1,13 @@ + + + +{{ name }} + + + + + + + + + diff --git a/app/templates/includes/jumbotron.html b/app/templates/includes/jumbotron.html new file mode 100644 index 0000000..24f57d4 --- /dev/null +++ b/app/templates/includes/jumbotron.html @@ -0,0 +1,8 @@ +{% macro jumbotron(headline) %} +
+
+

{{ headline }}

+ {{ caller() }} +
+
+{% endmacro %} diff --git a/app/templates/includes/nav.html b/app/templates/includes/nav.html new file mode 100644 index 0000000..27321bb --- /dev/null +++ b/app/templates/includes/nav.html @@ -0,0 +1,36 @@ + diff --git a/app/templates/includes/scripts.html b/app/templates/includes/scripts.html new file mode 100644 index 0000000..cbd83be --- /dev/null +++ b/app/templates/includes/scripts.html @@ -0,0 +1,24 @@ + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/app/templates/index.html b/app/templates/index.html new file mode 100644 index 0000000..8569398 --- /dev/null +++ b/app/templates/index.html @@ -0,0 +1,26 @@ +{% extends "page.html" %} + +{% block jumbotron %} + {% call jumbotron('Hello, world!') %} +

This is a test hello template for a simple marketing or informational website. It includes a large callout called a jumbotron and three supporting pieces of content. Use it as a starting point to create something more unique.

+

Learn more »

+ {% endcall %} +{% endblock %} + +{% block content %} +
+

Heading

+

Donec id elit non mi porta gravida at eget metus. Fusce dapibus, tellus ac cursus commodo, tortor mauris condimentum nibh, ut fermentum massa justo sit amet risus. Etiam porta sem malesuada magna mollis euismod. Donec sed odio dui.

+

View details »

+
+
+

Heading

+

Donec id elit non mi porta gravida at eget metus. Fusce dapibus, tellus ac cursus commodo, tortor mauris condimentum nibh, ut fermentum massa justo sit amet risus. Etiam porta sem malesuada magna mollis euismod. Donec sed odio dui.

+

View details »

+
+
+

Heading

+

Donec sed odio dui. Cras justo odio, dapibus ac facilisis in, egestas eget quam. Vestibulum id ligula porta felis euismod semper. Fusce dapibus, tellus ac cursus commodo, tortor mauris condimentum nibh, ut fermentum massa justo sit amet risus.

+

View details »

+
+{% endblock %} diff --git a/app/templates/layout.html b/app/templates/layout.html new file mode 100644 index 0000000..b4aefd7 --- /dev/null +++ b/app/templates/layout.html @@ -0,0 +1,23 @@ + + + + {% include "includes/header.html" %} + + + {% from "includes/jumbotron.html" import jumbotron %} + {% include "includes/browsehappy.html" %} + {% block nav %}{% endblock %} + {% block jumbotron %}{% endblock %} +
+
+ {% block content %}{% endblock %} +
+
+ +
+ {% include "includes/analytics.html" %} + {% include "includes/scripts.html" %} + + diff --git a/app/templates/page.html b/app/templates/page.html new file mode 100644 index 0000000..9ee219b --- /dev/null +++ b/app/templates/page.html @@ -0,0 +1,9 @@ +{% extends "layout.html" %} + +{% block nav %} + {% include "includes/nav.html" %} +{% endblock %} + +{% block footer %} +

{{ copyright }}

+{% endblock %} diff --git a/bower.json b/bower.json new file mode 100644 index 0000000..cba470c --- /dev/null +++ b/bower.json @@ -0,0 +1,7 @@ +{ + "name": "juckstrap", + "private": true, + "dependencies": { + "bootstrap": "~3.2.0" + } +} \ No newline at end of file diff --git a/config.json b/config.json new file mode 100644 index 0000000..e121fe4 --- /dev/null +++ b/config.json @@ -0,0 +1,52 @@ +{ + "locals": { + "name": "My application", + "analytics": "UA-XXXXX-X", + "copyright": "© Company 2014", + "navigation": { + "class": "navbar-inverse navbar-fixed-top", + "links": [ + { + "name": "Home", + "href": "#home" + }, + { + "name": "About", + "href": "#about" + }, + { + "name": "Contact", + "href": "#contact" + }, + { + "name": "Dropdown", + "links": [ + { + "name": "Action", + "href": "#" + }, + { + "name": "Another action", + "href": "#" + }, + { + "name": "Something else here", + "href": "#" + }, + { + "header": "Navigation Header" + }, + { + "name": "Separated Link", + "href": "#" + }, + { + "name": "One more separated link", + "href": "#" + } + ] + } + ] + } + } +} diff --git a/package.json b/package.json new file mode 100644 index 0000000..56ff0d5 --- /dev/null +++ b/package.json @@ -0,0 +1,35 @@ +{ + "name": "juckstrap", + "devDependencies": { + "apache-server-configs": "^2.7.1", + "grunt": "^0.4.5", + "grunt-autoprefixer": "^1.0.0", + "grunt-concurrent": "^0.5.0", + "grunt-contrib-clean": "^0.6.0", + "grunt-contrib-concat": "^0.5.0", + "grunt-contrib-connect": "^0.8.0", + "grunt-contrib-copy": "^0.5.0", + "grunt-contrib-cssmin": "^0.10.0", + "grunt-contrib-htmlmin": "^0.3.0", + "grunt-contrib-imagemin": "^0.8.0", + "grunt-contrib-jshint": "^0.10.0", + "grunt-contrib-uglify": "^0.5.1", + "grunt-contrib-watch": "^0.6.1", + "grunt-mocha": "^0.4.10", + "grunt-newer": "^0.7.0", + "grunt-rev": "^0.1.0", + "grunt-svgmin": "^0.4.0", + "grunt-usemin": "^2.3.0", + "grunt-wintersmith": "0.0.2", + "grunt-wiredep": "^1.7.0", + "jshint-stylish": "^0.4.0", + "load-grunt-tasks": "^0.4.0", + "nunjucks": "^1.1.0", + "time-grunt": "^0.4.0", + "wintersmith": "^2.1.0", + "wintersmith-nunjucks": "git://github.com/travist/wintersmith-nunjucks.git#c3cc698e0911f9bfab966dfe12c059cf5afe040a" + }, + "engines": { + "node": ">=0.10.0" + } +} diff --git a/test/.bowerrc b/test/.bowerrc new file mode 100644 index 0000000..44491d3 --- /dev/null +++ b/test/.bowerrc @@ -0,0 +1,3 @@ +{ + "directory": "bower_components" +} diff --git a/test/bower.json b/test/bower.json new file mode 100644 index 0000000..66a77aa --- /dev/null +++ b/test/bower.json @@ -0,0 +1,9 @@ +{ + "name": "juckstrap", + "private": true, + "dependencies": { + "chai": "~1.8.0", + "mocha": "~1.14.0" + }, + "devDependencies": {} +} diff --git a/test/index.html b/test/index.html new file mode 100644 index 0000000..d10cee0 --- /dev/null +++ b/test/index.html @@ -0,0 +1,26 @@ + + + + + Mocha Spec Runner + + + +
+ + + + + + + + + + + + + diff --git a/test/spec/test.js b/test/spec/test.js new file mode 100644 index 0000000..acbc11a --- /dev/null +++ b/test/spec/test.js @@ -0,0 +1,13 @@ +/* global describe, it */ + +(function () { + 'use strict'; + + describe('Give it some context', function () { + describe('maybe a bit more context here', function () { + it('should run here few assertions', function () { + + }); + }); + }); +})();