Skip to content

Instantly share code, notes, and snippets.

@stephenplusplus
Last active November 1, 2018 10:02
Show Gist options
  • Save stephenplusplus/5647725 to your computer and use it in GitHub Desktop.
Save stephenplusplus/5647725 to your computer and use it in GitHub Desktop.
yo blog
{
"name": "<%= _.slugify(blogName) %>",
"version": "0.0.0",
"dependencies": {
"showup": "~0.0.2"
}
}
{
"name": "<%= blogName %>"
}

<%= blogName %>

Create a post!

From the terminal, pop in:

yo weblog:post

{
"name": "<%= _.slugify(blogName) %>",
"private": true,
"devDependencies": {
"grunt": "~0.4.1",
"bower": "~0.9.2",
"grunt-contrib-connect": "~0.2.0",
"grunt-contrib-watch": "~0.4.3",
"grunt-open": "~0.2.0",
"matchdep": "~0.1.2",
"connect-livereload": "~0.1.3",
"moment": "~2.0.0"
},
"engines": {
"node": ">=0.8.0"
}
}
{
"directory": "bower_components"
}
node_modules
*.log
// Generated on <%= (new Date).toISOString().split('T')[0] %> using <%= pkg.name %> <%= pkg.version %>
'use strict';
var moment = require('moment');
var LIVERELOAD_PORT = 35729;
var lrSnippet = require('connect-livereload')({port: LIVERELOAD_PORT});
var mountFolder = function (connect, dir) {
return connect.static(require('path').resolve(dir));
};
module.exports = function (grunt) {
// load all grunt tasks
require('matchdep').filterDev('grunt-*').forEach(grunt.loadNpmTasks);
grunt.initConfig({
watch: {
options: {
nospawn: true,
livereload: LIVERELOAD_PORT
},
livereload: {
files: [
'index.html',
'posts/*.md'
],
tasks: ['build']
}
},
connect: {
options: {
port: 9000,
// change this to '0.0.0.0' to access the server from outside
hostname: 'localhost'
},
livereload: {
options: {
middleware: function (connect) {
return [
lrSnippet,
mountFolder(connect, '.')
];
}
}
}
},
open: {
server: {
path: 'http://localhost:<%%= connect.options.port %>'
}
}
});
grunt.registerTask('server', ['build', 'connect:livereload', 'open', 'watch']);
grunt.registerTask('build', 'Build your blog.', function () {
var words = [];
var posts = [];
var ignoredWords = [
'the', 'couldn\'t', 'you\'re', 'you\'ve', 'just', 'something', 'some',
'thing', 'um', 'ahh', 'ah', 'uh', 'if', 'out', 'at', 'no', 'with', 'had',
'got', 'have', 'for', 'it\'s', 'that', 'that\'s', 'from', 'in', 'a', 'of',
'them', 'you', 'his', 'her', 'their', 'there', 'how', 'what', 'why',
'who', 'when', 'i', 'went', 'to', 'they', 'you\'ll', 'welcome', 'are'
];
var unslug = function (slug) {
return slug.replace(/(-(\w))/g, function () { return ' ' + arguments[2].toUpperCase(); });
};
grunt.file.recurse('posts', function (post, root, sub, fileName) {
if (fileName === 'index.md') {
return;
}
var wordMap = {};
posts.push(fileName.replace('.md', ''));
words.push('id:' + fileName.replace('.md', ''));
post = grunt.file.read(post)
.toLowerCase()
.trim()
.replace(/\s+/gm, ' ');
post.split(' ').forEach(function (word) {
if (word.length > 5 && ignoredWords.indexOf(word) === -1) {
if (wordMap[word]) {
wordMap[word].count++;
} else {
wordMap[word] = {
name: word,
count: 1
};
}
}
});
wordMap = grunt.util._.chain(wordMap).sortBy('count').reverse().value();
var postWords = [];
while (postWords.length < 10) {
postWords.push(wordMap[postWords.length] && wordMap[postWords.length].name || '');
}
words.push(postWords);
});
words = grunt.util._.chain(words).flatten().reject(function (word) { return !word; }).value();
grunt.file.write('wordmap.json', JSON.stringify(words));
grunt.file.write('posts/index.md', function () {
var file = '# ' + grunt.file.readJSON('config.json').name + '\n';
var lastDate;
posts.reverse().forEach(function (post) {
var postDate = post.replace(/((\d*-\d*-\d*).*)/, '$2');
var title = post.replace(postDate, '').replace(/\s+/g, ' ').trim();
if (lastDate !== postDate) {
file += '\n### ' + moment(postDate).format('dddd, MMMM Do, YYYY');
}
file += '\n#### [' + postDate + ' -' + unslug(title) + '](#' + postDate + title + ')';
lastDate = postDate;
});
return file.trim();
}());
});
};
<!doctype html>
<!--[if lt IE 7]> <html class="lt-ie9 lt-ie8 lt-ie7"> <![endif]-->
<!--[if IE 7]> <html class="lt-ie9 lt-ie8"> <![endif]-->
<!--[if IE 8]> <html class="lt-ie9"> <![endif]-->
<!--[if gt IE 8]><!--> <html> <!--<![endif]-->
<head>
<meta charset="utf-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge,chrome=1">
<title><%= _.capitalize(blogName) %></title>
<link rel="stylesheet" href="bower_components/showup/showup.css">
</head>
<body>
<!--[if lt IE 7]>
<p class="chromeframe">You are using an <strong>outdated</strong> browser. Please <a href="http://browsehappy.com/">upgrade your browser</a> or <a href="http://www.google.com/chromeframe/?redirect=true">activate Google Chrome Frame</a> to improve your experience.</p>
<![endif]-->
<div class="gutter"></div>
<div class="container"></div>
<script src="bower_components/showdown/compressed/showdown.js"></script>
<script src="bower_components/showup/showup.js"></script>
<script>
Showup.init({
posts: 'posts/',
wordmap: 'wordmap.json',
gutter: document.querySelector('.gutter'),
container: document.querySelector('.container')
});
</script>
</body>
</html>
@Josh68
Copy link

Josh68 commented Apr 22, 2014

@tobiasoberrauch: I'm completely confused about the syntax, but I guess it's templating an interpolation delimiter (or something like that). There is no typo in Gruntfile.js, line 48. The generator fails if I change it.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment