works
This commit is contained in:
parent
38b02c1c3b
commit
98251b3a68
|
@ -13,4 +13,12 @@
|
||||||
, "unused": true
|
, "unused": true
|
||||||
, "latedef": true
|
, "latedef": true
|
||||||
, "globals": { "angular": true }
|
, "globals": { "angular": true }
|
||||||
|
|
||||||
|
, "bitwise": true
|
||||||
|
, "curly": true
|
||||||
|
, "forin": true
|
||||||
|
, "freeze": true
|
||||||
|
, "immed": true
|
||||||
|
|
||||||
|
, "funcscope": false
|
||||||
}
|
}
|
||||||
|
|
|
@ -34,7 +34,7 @@ angular.module('myApp.services', []).
|
||||||
return d.promise;
|
return d.promise;
|
||||||
}
|
}
|
||||||
|
|
||||||
Desi.build(desi, env).then(function () {
|
Desi.buildAll(desi, env).then(function () {
|
||||||
d.resolve(desi);
|
d.resolve(desi);
|
||||||
});
|
});
|
||||||
|
|
||||||
|
|
507
deardesi.js
507
deardesi.js
|
@ -4,7 +4,6 @@
|
||||||
var PromiseA = exports.Promise || require('bluebird').Promise
|
var PromiseA = exports.Promise || require('bluebird').Promise
|
||||||
, path = exports.path || require('path')
|
, path = exports.path || require('path')
|
||||||
, Mustache = exports.Mustache || require('mustache')
|
, Mustache = exports.Mustache || require('mustache')
|
||||||
, marked = (exports.markdownit || require('markdown-it'))({ html: true, linkify: true })
|
|
||||||
, forEachAsync = exports.forEachAsync || require('foreachasync').forEachAsync
|
, forEachAsync = exports.forEachAsync || require('foreachasync').forEachAsync
|
||||||
//, sha1sum = exports.sha1sum || require('./lib/deardesi-node').sha1sum
|
//, sha1sum = exports.sha1sum || require('./lib/deardesi-node').sha1sum
|
||||||
, frontmatter = exports.Frontmatter || require('./lib/frontmatter').Frontmatter
|
, frontmatter = exports.Frontmatter || require('./lib/frontmatter').Frontmatter
|
||||||
|
@ -29,6 +28,19 @@
|
||||||
, 12: 'December'
|
, 12: 'December'
|
||||||
};
|
};
|
||||||
|
|
||||||
|
/*
|
||||||
|
function shallowClone(obj) {
|
||||||
|
var shallow = {}
|
||||||
|
;
|
||||||
|
|
||||||
|
Object.keys(obj).forEach(function (key) {
|
||||||
|
shallow[key] = obj[key];
|
||||||
|
});
|
||||||
|
|
||||||
|
return shallow;
|
||||||
|
}
|
||||||
|
*/
|
||||||
|
|
||||||
function firstCap(str) {
|
function firstCap(str) {
|
||||||
return str.replace(/^./, function ($1) { return $1.toUpperCase(); });
|
return str.replace(/^./, function ($1) { return $1.toUpperCase(); });
|
||||||
}
|
}
|
||||||
|
@ -154,6 +166,7 @@
|
||||||
}
|
}
|
||||||
|
|
||||||
function getLayout(desi, themename, layout, arr) {
|
function getLayout(desi, themename, layout, arr) {
|
||||||
|
// TODO meta.layout for each entity
|
||||||
arr = arr || [];
|
arr = arr || [];
|
||||||
|
|
||||||
var layoutdir = 'layouts'
|
var layoutdir = 'layouts'
|
||||||
|
@ -176,6 +189,7 @@
|
||||||
// TODO what if it isn't html?
|
// TODO what if it isn't html?
|
||||||
if (theme.path === themepath || theme.path.match(themepath + '\\.html')) {
|
if (theme.path === themepath || theme.path.match(themepath + '\\.html')) {
|
||||||
file = theme;
|
file = theme;
|
||||||
|
theme.ext = path.extname(file.path);
|
||||||
arr.push(theme);
|
arr.push(theme);
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
@ -224,8 +238,8 @@
|
||||||
console.info('loaded config, data, caches, partials');
|
console.info('loaded config, data, caches, partials');
|
||||||
console.log({
|
console.log({
|
||||||
config: arr.config
|
config: arr.config
|
||||||
, data: arr.data
|
|
||||||
, site: arr.site
|
, site: arr.site
|
||||||
|
, authors: arr.authors
|
||||||
});
|
});
|
||||||
|
|
||||||
desi.blogdir = blogdir;
|
desi.blogdir = blogdir;
|
||||||
|
@ -339,22 +353,7 @@
|
||||||
});
|
});
|
||||||
};
|
};
|
||||||
|
|
||||||
Desi.setEnv = function (desi, env) {
|
Desi.getDirtyFiles = function (desi) {
|
||||||
desi.urls = desi.config.urls = {};
|
|
||||||
desi.env = {};
|
|
||||||
if (-1 === ['development', 'staging'].indexOf(env) || !desi.config[env]) {
|
|
||||||
env = 'production';
|
|
||||||
}
|
|
||||||
|
|
||||||
desi.urls.base_path = desi.config.base_path = desi.config[env].base_path;
|
|
||||||
desi.urls.url = desi.config[env].url;
|
|
||||||
desi.config.compiled_path = desi.config[env].compiled_path;
|
|
||||||
desi.urls[env + '_url'] = desi.config[env].url;
|
|
||||||
|
|
||||||
return PromiseA.resolve(desi);
|
|
||||||
};
|
|
||||||
|
|
||||||
Desi.getDirtyFiles = function (desi, env) {
|
|
||||||
var cache = desi.cache
|
var cache = desi.cache
|
||||||
//, config = desi.config
|
//, config = desi.config
|
||||||
, cacheByPath = {}
|
, cacheByPath = {}
|
||||||
|
@ -364,10 +363,6 @@
|
||||||
, droot
|
, droot
|
||||||
;
|
;
|
||||||
|
|
||||||
if (!desi.env) {
|
|
||||||
Desi.setEnv(desi, env);
|
|
||||||
}
|
|
||||||
|
|
||||||
cache.sources = cache.sources || [];
|
cache.sources = cache.sources || [];
|
||||||
cache.sources.forEach(function (source) {
|
cache.sources.forEach(function (source) {
|
||||||
cacheByPath[source.path] = source;
|
cacheByPath[source.path] = source;
|
||||||
|
@ -419,7 +414,7 @@
|
||||||
});
|
});
|
||||||
};
|
};
|
||||||
|
|
||||||
Desi.copyAssets = function(desi) {
|
Desi.copyAssets = function(desi, env) {
|
||||||
var files = {}
|
var files = {}
|
||||||
;
|
;
|
||||||
|
|
||||||
|
@ -429,10 +424,9 @@
|
||||||
var assets = desi.meta.assets[key]
|
var assets = desi.meta.assets[key]
|
||||||
;
|
;
|
||||||
|
|
||||||
// TODO fix compiled_path + base_path
|
|
||||||
assets.forEach(function (asset) {
|
assets.forEach(function (asset) {
|
||||||
console.log('preparing ' + asset + ' for copy');
|
console.log('preparing ' + asset.path + ' for copy');
|
||||||
files[path.join(asset.relativePath, asset.name)] = path.join(desi.config.compiled_path, 'assets', asset.relativePath, asset.name);
|
files[path.join(asset.relativePath, asset.name)] = path.join(env.compiled_path, 'assets', asset.relativePath, asset.name);
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
|
@ -464,25 +458,29 @@
|
||||||
desi.navigation = [];
|
desi.navigation = [];
|
||||||
|
|
||||||
desi.content.root.forEach(function (page) {
|
desi.content.root.forEach(function (page) {
|
||||||
|
// XXX BUG TODO strip only strip _root so that nested nav will work as expected
|
||||||
var name = path.basename(page.path, path.extname(page.path))
|
var name = path.basename(page.path, path.extname(page.path))
|
||||||
, nindex
|
, nindex
|
||||||
;
|
;
|
||||||
|
|
||||||
//if (-1 === desi.data.navigation.indexOf(name) && 'index' !== name)
|
//if (-1 === desi.data.navigation.indexOf(name) && 'index' !== name)
|
||||||
nindex = desi.data.navigation.indexOf(name);
|
nindex = (desi.site.navigation).indexOf(name);
|
||||||
if (-1 === nindex) {
|
if (-1 === nindex) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
desi.navigation[nindex] = {
|
desi.navigation[nindex] = {
|
||||||
title: page.yml && page.yml.title || firstCap(name)
|
title: page.yml && page.yml.title || firstCap(name)
|
||||||
, href: desi.urls.base_path + '/' + name
|
|
||||||
, path: desi.urls.base_path + '/' + name
|
|
||||||
, name: name
|
, name: name
|
||||||
, active: false // placeholder
|
, active: false // placeholder
|
||||||
};
|
};
|
||||||
});
|
});
|
||||||
|
|
||||||
|
// transform spare array into compact array
|
||||||
|
desi.navigation = desi.navigation.filter(function (n) {
|
||||||
|
return n;
|
||||||
|
});
|
||||||
|
|
||||||
return PromiseA.resolve(desi);
|
return PromiseA.resolve(desi);
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -557,7 +555,7 @@
|
||||||
|
|
||||||
if (!page.yml.date) {
|
if (!page.yml.date) {
|
||||||
// TODO tell YAML parser to keep the date a string
|
// TODO tell YAML parser to keep the date a string
|
||||||
page.yml.date = new Date(page.yml.created_at || page.yml.time || page.createdDate || page.lastModifiedDate).toISOString();
|
page.yml.date = new Date(page.yml.created_at || page.yml.time || page.yml.updated_at || page.createdDate || page.lastModifiedDate).toISOString();
|
||||||
}
|
}
|
||||||
if ('object' === typeof page.yml.date) {
|
if ('object' === typeof page.yml.date) {
|
||||||
page.yml.date = page.yml.date.toISOString();
|
page.yml.date = page.yml.date.toISOString();
|
||||||
|
@ -570,9 +568,6 @@
|
||||||
|
|
||||||
function normalizeContentEntity(entity) {
|
function normalizeContentEntity(entity) {
|
||||||
entity.ext = path.extname(entity.path);
|
entity.ext = path.extname(entity.path);
|
||||||
entity.url = desi.urls.url + path.join(desi.urls.base_path, entity.yml.permalink);
|
|
||||||
entity.canonical_url = desi.urls.url + path.join(desi.urls.base_path, entity.yml.permalink);
|
|
||||||
entity.relative_url = path.join(desi.urls.base_path, entity.yml.permalink);
|
|
||||||
entity.published_at = fromLocaleDate(entity.yml.date);
|
entity.published_at = fromLocaleDate(entity.yml.date);
|
||||||
entity.year = entity.published_at.year;
|
entity.year = entity.published_at.year;
|
||||||
entity.month = entity.published_at.month;
|
entity.month = entity.published_at.month;
|
||||||
|
@ -602,7 +597,7 @@
|
||||||
return PromiseA.resolve(desi);
|
return PromiseA.resolve(desi);
|
||||||
};
|
};
|
||||||
|
|
||||||
Desi.collate = function (desi/*, collectionname*/) {
|
Desi.collate = function (desi, env/*, collectionname*/) {
|
||||||
function byDate(a, b) {
|
function byDate(a, b) {
|
||||||
if (a.year > b.year) {
|
if (a.year > b.year) {
|
||||||
return -1;
|
return -1;
|
||||||
|
@ -651,6 +646,8 @@
|
||||||
, mindex = 12 - f.month
|
, mindex = 12 - f.month
|
||||||
;
|
;
|
||||||
|
|
||||||
|
f.url = path.join(env.base_path, f.yml.permalink);
|
||||||
|
|
||||||
if (!yearsArr[yindex]) {
|
if (!yearsArr[yindex]) {
|
||||||
yearsArr[yindex] = { year: f.year, months: [] };
|
yearsArr[yindex] = { year: f.year, months: [] };
|
||||||
}
|
}
|
||||||
|
@ -686,16 +683,218 @@
|
||||||
|
|
||||||
desi.content.collections.sort(byDate);
|
desi.content.collections.sort(byDate);
|
||||||
desi.collated = collate(desi.content.collections);
|
desi.collated = collate(desi.content.collections);
|
||||||
console.info('desi.collated');
|
console.info('7 desi.collated');
|
||||||
console.info(desi.collated);
|
console.info(desi.collated);
|
||||||
|
|
||||||
return PromiseA.resolve(desi);
|
return PromiseA.resolve(desi);
|
||||||
};
|
};
|
||||||
|
|
||||||
Desi.build = function (desi) {
|
Desi.datamaps = {};
|
||||||
|
Desi.datamaps['desirae@1.0'] = function (obj) {
|
||||||
|
obj.desi = obj;
|
||||||
|
return obj;
|
||||||
|
};
|
||||||
|
Desi.datamaps['ruhoh@2.6'] = function (view) {
|
||||||
|
var newview
|
||||||
|
;
|
||||||
|
|
||||||
|
newview = {
|
||||||
|
content: view.contents
|
||||||
|
, page: {
|
||||||
|
title: view.entity.yml.title || view.site.title
|
||||||
|
, tagline: view.entity.yml.tagline
|
||||||
|
, content: view.contents
|
||||||
|
, youtube: view.entity.yml.youtube
|
||||||
|
, disqus_identifier: view.entity.disqus_identifier
|
||||||
|
, disqus_url: !view.entity.disqus_identifier && view.entity.disqus_url
|
||||||
|
, tags: view.entity.yml.tags
|
||||||
|
, categories: view.entity.yml.categories
|
||||||
|
, player_width: view.entity.yml.player_width
|
||||||
|
, player_height: view.entity.yml.player_height
|
||||||
|
, next: view.entities[view.entity_index + 1]
|
||||||
|
, previous: view.entities[view.entity_index - 1]
|
||||||
|
, date: view.entity.year + '-' + view.entity.month + '-' + view.entity.day
|
||||||
|
// TODO , url: view.entities.
|
||||||
|
}
|
||||||
|
, posts: { collated: view.desi.collated }
|
||||||
|
, urls: {
|
||||||
|
base_url: view.env.base_url
|
||||||
|
, base_path: view.env.base_path
|
||||||
|
}
|
||||||
|
, data: {
|
||||||
|
author: {
|
||||||
|
name: view.author.name
|
||||||
|
, twitter: view.author.twitter
|
||||||
|
}
|
||||||
|
, title: view.site.title
|
||||||
|
}
|
||||||
|
, assets: view.desi.assets.join('\n')
|
||||||
|
, widgets: {
|
||||||
|
comments: view.site.disqus_shortname &&
|
||||||
|
Mustache.render(view.desi.partials.disqus, { disqus: {
|
||||||
|
shortname: view.site.disqus_shortname
|
||||||
|
, identifier: view.entity.disqus_identifier
|
||||||
|
, url: !view.entity.disqus_identifier && view.entity.disqus_url
|
||||||
|
}})
|
||||||
|
, analytics: view.site.google_analytics_tracking_id &&
|
||||||
|
Mustache.render(view.desi.partials.google_analytics, { google_analytics: {
|
||||||
|
tracking_id: view.site.google_analytics_tracking_id
|
||||||
|
}})
|
||||||
|
, facebook_connect: view.desi.partials.facebook_connect
|
||||||
|
, twitter: view.desi.partials.twitter
|
||||||
|
, google_plusone: view.desi.partials.google_plusone
|
||||||
|
, amazon_link_enhancer: view.site.amazon_affiliate_id &&
|
||||||
|
Mustache.render(view.desi.partials.amazon_link_enhancer, {
|
||||||
|
amazon_affiliate_id: view.site.amazon_affiliate_id
|
||||||
|
})
|
||||||
|
}
|
||||||
|
, site: {
|
||||||
|
navigation: view.navigation
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
// backwards compat
|
||||||
|
newview.site['navigation?to_pages'] = newview.site.navigation;
|
||||||
|
newview.site['navigation?to__root'] = newview.site.navigation;
|
||||||
|
newview.data.navigation = view.site.navigation;
|
||||||
|
newview.data['navigation?to_pages'] = newview.site.navigation;
|
||||||
|
newview.data['navigation?to__root'] = newview.site.navigation;
|
||||||
|
|
||||||
|
newview.page.content = view.contents;
|
||||||
|
|
||||||
|
return newview;
|
||||||
|
};
|
||||||
|
|
||||||
|
Desi.renderers = {};
|
||||||
|
Desi.registerRenderer = function(ext, fn, opts) {
|
||||||
|
// TODO allow a test method for ext and content (new RegExp("\\." + escapeRegExp(ext) + "$", i).test(current.ext))
|
||||||
|
opts = opts || {};
|
||||||
|
// TODO opts.priority
|
||||||
|
Desi.renderers[ext] = Desi.renderers[ext] || [];
|
||||||
|
// LIFO
|
||||||
|
Desi.renderers[ext].unshift(fn);
|
||||||
|
};
|
||||||
|
Desi.render = function (ext, content, view) {
|
||||||
|
ext = (ext||'').toLowerCase().replace(/^\./, '');
|
||||||
|
|
||||||
|
if (Desi.renderers[ext] && Desi.renderers[ext].length) {
|
||||||
|
return Desi.renderers[ext][0](content, view);
|
||||||
|
}
|
||||||
|
return PromiseA.reject(new Error("no renderer registered for ." + ext));
|
||||||
|
};
|
||||||
|
|
||||||
|
function registerJade() {
|
||||||
|
var jade = true || exports.jade || require('jade')
|
||||||
|
;
|
||||||
|
|
||||||
|
function render(contentstr/*, desi*/) {
|
||||||
|
return PromiseA.resolve(jade(contentstr));
|
||||||
|
}
|
||||||
|
|
||||||
|
if (false) {
|
||||||
|
Desi.registerRenderer('jade', render);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
registerJade();
|
||||||
|
|
||||||
|
function registerMarkdown() {
|
||||||
|
var markitdown = (exports.markdownit || require('markdown-it'))({ html: true, linkify: true })
|
||||||
|
;
|
||||||
|
|
||||||
|
function render(contentstr/*, desi*/) {
|
||||||
|
return Promise.resolve(
|
||||||
|
markitdown.render(contentstr)
|
||||||
|
//.replace('"', '"')
|
||||||
|
//.replace(''', "'")
|
||||||
|
//.replace('/', '/')
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
['md', 'markdown', 'mdown', 'mkdn', 'mkd', 'mdwn', 'mdtxt', 'mdtext'].forEach(function (ext) {
|
||||||
|
Desi.registerRenderer(ext, render);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
registerMarkdown();
|
||||||
|
|
||||||
|
function registerHtml() {
|
||||||
|
function render(contentstr/*, desi*/) {
|
||||||
|
return PromiseA.resolve(contentstr);
|
||||||
|
}
|
||||||
|
|
||||||
|
Desi.registerRenderer('html', render);
|
||||||
|
Desi.registerRenderer('htm', render);
|
||||||
|
Desi.registerRenderer('xhtml', render);
|
||||||
|
}
|
||||||
|
registerHtml();
|
||||||
|
|
||||||
|
function renderLayers(desi, env, view, entity) {
|
||||||
|
var mustached = ''
|
||||||
|
, layers
|
||||||
|
;
|
||||||
|
|
||||||
|
layers = getLayout(desi, entity.yml.theme, entity.yml.layout, [entity]);
|
||||||
|
// TODO inherit datamap from theme layout
|
||||||
|
|
||||||
|
return forEachAsync(layers, function (current) {
|
||||||
|
var body = (current.body || current.contents || '').trim()
|
||||||
|
;
|
||||||
|
|
||||||
|
// TODO move to normalization
|
||||||
|
current.path = current.path || (entity.relativePath + '/' + entity.name);
|
||||||
|
|
||||||
|
|
||||||
|
return Desi.render(current.ext, body, view).then(function (html) {
|
||||||
|
var datamap = Desi.datamaps[env.datamap] || Desi.datamaps[entity.datamap] || Desi.datamaps['ruhoh@2.6']
|
||||||
|
, newview
|
||||||
|
;
|
||||||
|
|
||||||
|
view.contents = mustached;
|
||||||
|
|
||||||
|
// shallowClone to prevent perfect object equality (and potential template caching)
|
||||||
|
if (/Blog$/.test(view.entity.title)) {
|
||||||
|
console.log('desi.partials');
|
||||||
|
console.log(desi.partials);
|
||||||
|
}
|
||||||
|
newview = datamap(view);
|
||||||
|
if (/Blog$/.test(view.entity.title)) {
|
||||||
|
console.info('desi.collated');
|
||||||
|
console.log(desi);
|
||||||
|
console.info('newview.posts.collated');
|
||||||
|
console.log(newview.posts.collated);
|
||||||
|
}
|
||||||
|
mustached = Mustache.render(html, newview, desi.partials);
|
||||||
|
|
||||||
|
return mustached;
|
||||||
|
}).catch(function (e) {
|
||||||
|
console.error(current);
|
||||||
|
if (env.onError) {
|
||||||
|
return env.onError(e);
|
||||||
|
} else {
|
||||||
|
console.error('no registered renderer for ' + entity.path + ' or rendering failed');
|
||||||
|
throw e;
|
||||||
|
}
|
||||||
|
});
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
Desi.build = function (desi, env) {
|
||||||
var compiled = []
|
var compiled = []
|
||||||
;
|
;
|
||||||
|
|
||||||
|
env.transforms = env.transforms || [];
|
||||||
|
desi.transforms = (desi.transforms || []).concat(env.transforms);
|
||||||
|
desi.transforms.push(function (view) {
|
||||||
|
var yml = view.entity.yml
|
||||||
|
;
|
||||||
|
|
||||||
|
if (yml.uuid) {
|
||||||
|
view.entity.disqus_identifier = yml.uuid;
|
||||||
|
} else {
|
||||||
|
view.entity.disqus_url = view.entity.production_url;
|
||||||
|
}
|
||||||
|
return view;
|
||||||
|
});
|
||||||
|
|
||||||
/*
|
/*
|
||||||
function compileScriptEntity(entity, i, arr) {
|
function compileScriptEntity(entity, i, arr) {
|
||||||
}
|
}
|
||||||
|
@ -703,160 +902,154 @@
|
||||||
function compileThemeEntity(entity, i, arr) {
|
function compileThemeEntity(entity, i, arr) {
|
||||||
console.log("compiling " + (i + 1) + "/" + arr.length + " " + (entity.path || entity.name));
|
console.log("compiling " + (i + 1) + "/" + arr.length + " " + (entity.path || entity.name));
|
||||||
// TODO less / sass / etc
|
// TODO less / sass / etc
|
||||||
compiled.push({ contents: entity.body || entity.contents, path: path.join(desi.config.compiled_path, 'themes', entity.path) });
|
compiled.push({ contents: entity.body || entity.contents, path: path.join('themes', entity.path) });
|
||||||
if (/stylesheets.*\.css/.test(entity.path) && (!/google/.test(entity.path) || /obsid/.test(entity.path))) {
|
if (/stylesheets.*\.css/.test(entity.path) && (!/google/.test(entity.path) || /obsid/.test(entity.path))) {
|
||||||
// TODO XXX move to a partial
|
// TODO XXX move to a partial
|
||||||
desi.assets.push(
|
desi.assets.push(
|
||||||
'<link href="' + desi.urls.base_path + '/themes/' + entity.path + '" type="text/css" rel="stylesheet" media="all">'
|
'<link href="' + env.base_path + '/themes/' + entity.path + '" type="text/css" rel="stylesheet" media="all">'
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
desi.navigation.filter(function (n) {
|
|
||||||
return n;
|
|
||||||
});
|
|
||||||
//console.log(desi.navigation);
|
|
||||||
function compileContentEntity(entity, i, arr) {
|
|
||||||
console.log("compiling " + (i + 1) + "/" + arr.length + " " + (entity.path || entity.name));
|
|
||||||
|
|
||||||
var previous = ''
|
function compileContentEntity(entity, i, arr) {
|
||||||
, layers
|
console.log("compiling " + (i + 1) + "/" + arr.length + " " + entity.path);
|
||||||
|
|
||||||
|
var navigation = JSON.parse(JSON.stringify(desi.navigation))
|
||||||
|
, author = desi.authors[entity.yml.author] || desi.authors[Object.keys(desi.authors)[0]]
|
||||||
, view
|
, view
|
||||||
;
|
;
|
||||||
|
|
||||||
layers = getLayout(desi, entity.yml.theme, entity.yml.layout, [entity]);
|
entity.url = env.base_url + path.join(env.base_path, entity.yml.permalink);
|
||||||
|
entity.canonical_url = env.base_url + path.join(env.base_path, entity.yml.permalink);
|
||||||
|
entity.production_url = desi.site.base_url + path.join(desi.site.base_path, entity.yml.permalink);
|
||||||
|
entity.relative_url = path.join(env.base_path, entity.yml.permalink);
|
||||||
|
|
||||||
view = {
|
// TODO nested names?
|
||||||
page: entity.yml // data for just *this* page
|
navigation.forEach(function (nav) {
|
||||||
//, data: desi.data // data.yml
|
nav.href = env.base_path + '/' + nav.name;
|
||||||
// https://github.com/janl/mustache.js/issues/415
|
nav.path = env.base_path + '/' + nav.name;
|
||||||
, data: num2str(desi.data)
|
|
||||||
, collection: {} // data for just *this* collection
|
|
||||||
, categories: [] // *all* categories in all collections
|
|
||||||
, tags: [] // *all* tags in all collections
|
|
||||||
, site: num2str(desi.site || {})
|
|
||||||
, url: entity.canonical_url
|
|
||||||
, canonical_url: entity.canonical_url
|
|
||||||
, relative_url: entity.relative_url
|
|
||||||
, urls: desi.urls
|
|
||||||
, previous: arr[i - 1]
|
|
||||||
, next: arr[i + 1]
|
|
||||||
, posts: { collated: desi.collated }
|
|
||||||
// TODO concat theme, widget, and site assets
|
|
||||||
, assets: desi.assets.join('\n')
|
|
||||||
};
|
|
||||||
|
|
||||||
//console.log('rel:', view.relative_url);
|
// path.basename(nav.path, path.extname(nav.path))
|
||||||
view.site.author = desi.data.author;
|
if (nav.href.replace(/(\/)?(\/index)?(\.html)?$/i, '') === entity.relative_url.replace(/(\/)?(\/index)?(\.html)?$/i, '')) {
|
||||||
view.site.navigation = JSON.parse(JSON.stringify(desi.navigation));
|
|
||||||
view.site.navigation.forEach(function (nav) {
|
|
||||||
|
|
||||||
if (nav.href === view.relative_url) {
|
|
||||||
nav.active = true;
|
nav.active = true;
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
// backwards compat
|
|
||||||
view.site['navigation?to_pages'] = view.site.navigation;
|
|
||||||
view.site['navigation?to__root'] = view.site.navigation;
|
|
||||||
view.data.navigation = view.site.navigation;
|
|
||||||
view.data['navigation?to_pages'] = view.site.navigation;
|
|
||||||
view.data['navigation?to__root'] = view.site.navigation;
|
|
||||||
|
|
||||||
layers.forEach(function (current) {
|
view = {
|
||||||
// TODO meta.layout
|
env: env
|
||||||
var body = (current.body || current.contents || '').trim()
|
, config: desi.config
|
||||||
, html
|
, site: desi.site
|
||||||
, curview = {}
|
, data: desi.data
|
||||||
;
|
, entity: entity
|
||||||
|
, entity_index: i
|
||||||
|
, entities: arr
|
||||||
|
, desi: desi
|
||||||
|
, navigation: navigation
|
||||||
|
, author: num2str(author)
|
||||||
|
};
|
||||||
|
|
||||||
// TODO move to normalization
|
desi.transforms.forEach(function (fn) {
|
||||||
current.path = current.path || (entity.relativePath + '/' + entity.name);
|
view = fn(view);
|
||||||
|
|
||||||
if (/\.(html|htm)$/.test(current.path)) {
|
|
||||||
html = body;
|
|
||||||
} else if (/\.(md|markdown|mdown|mkdn|mkd|mdwn|mdtxt|mdtext)$/.test(current.ext)) {
|
|
||||||
html = marked.render(body)
|
|
||||||
//.replace('"', '"')
|
|
||||||
//.replace(''', "'")
|
|
||||||
//.replace('/', '/')
|
|
||||||
;
|
|
||||||
} else {
|
|
||||||
console.error('unknown parser for ' + (entity.path));
|
|
||||||
}
|
|
||||||
|
|
||||||
view.content = previous;
|
|
||||||
view.page.content = previous;
|
|
||||||
|
|
||||||
// to prevent perfect object equality (and potential template caching)
|
|
||||||
Object.keys(view).forEach(function (key) {
|
|
||||||
curview[key] = view[key];
|
|
||||||
});
|
|
||||||
previous = Mustache.render(html, curview, desi.partials);
|
|
||||||
});
|
});
|
||||||
|
|
||||||
// NOTE: by now, all permalinks should be in the format /path/to/page.html or /path/to/page/index.html
|
return renderLayers(desi, env, view, entity).then(function (html) {
|
||||||
if (/^(index)?(\/?index.html)?$/.test(entity.yml.permalink)) {
|
// NOTE: by now, all permalinks should be in the format /path/to/page.html or /path/to/page/index.html
|
||||||
console.info('found compiled index');
|
if (/^(index)?(\/?index.html)?$/.test(entity.yml.permalink)) {
|
||||||
compiled.push({ contents: previous, path: path.join(desi.config.compiled_path, 'index.html') });
|
console.info('found compiled index');
|
||||||
} else {
|
compiled.push({ contents: html, path: path.join('index.html') });
|
||||||
compiled.push({ contents: previous, path: path.join(desi.config.compiled_path, entity.yml.permalink) });
|
} else {
|
||||||
}
|
compiled.push({ contents: html, path: path.join(entity.yml.permalink) });
|
||||||
|
}
|
||||||
|
|
||||||
entity.yml.redirects = entity.yml.redirects || [];
|
entity.yml.redirects = entity.yml.redirects || [];
|
||||||
if (/\/index.html$/.test(entity.yml.permalink)) {
|
|
||||||
entity.yml.redirects.push(entity.yml.permalink.replace(/\/index.html$/, '.html'));
|
|
||||||
} else if (/\.html$/.test(entity.yml.permalink)) {
|
|
||||||
entity.yml.redirects.push(entity.yml.permalink.replace(/\.html?$/, '/index.html'));
|
|
||||||
} else {
|
|
||||||
console.info('found index, ignoring redirect');
|
|
||||||
}
|
|
||||||
entity.yml.redirects.forEach(function (redirect) {
|
|
||||||
var content
|
|
||||||
;
|
|
||||||
|
|
||||||
// TODO move to partial
|
if (/\/index.html$/.test(entity.yml.permalink)) {
|
||||||
content =
|
entity.yml.redirects.push(entity.yml.permalink.replace(/\/index.html$/, '.html'));
|
||||||
'<html>'
|
} else if (/\.html$/.test(entity.yml.permalink)) {
|
||||||
+ '<head>'
|
entity.yml.redirects.push(entity.yml.permalink.replace(/\.html?$/, '/index.html'));
|
||||||
+ '<title>Redirecting to ' + entity.yml.title + '</title>'
|
} else {
|
||||||
+ '<meta http-equiv="refresh" content="0;URL=\''
|
console.info('found index, ignoring redirect');
|
||||||
+ desi.urls.url + path.join(desi.urls.base_path, entity.yml.permalink)
|
}
|
||||||
+ '\'" />'
|
|
||||||
+ '</head>'
|
|
||||||
+ '<body>'
|
|
||||||
+ '<p>This page has moved to a <a href="'
|
|
||||||
+ desi.urls.url + path.join(desi.urls.base_path, entity.yml.permalink)
|
|
||||||
+'">'
|
|
||||||
+ entity.yml.title
|
|
||||||
+ '</a>.</p>'
|
|
||||||
+ '</body>'
|
|
||||||
+ '</html>'
|
|
||||||
;
|
|
||||||
|
|
||||||
compiled.push({ contents: content, path: path.join(desi.config.compiled_path, redirect) });
|
entity.yml.redirects.forEach(function (redirect) {
|
||||||
|
var html = Mustache.render(desi.partials.redirect, view)
|
||||||
|
;
|
||||||
|
|
||||||
|
compiled.push({
|
||||||
|
contents: html
|
||||||
|
, path: path.join(redirect)
|
||||||
|
});
|
||||||
|
});
|
||||||
|
}).catch(function (e) {
|
||||||
|
console.error('failing at build step here here here');
|
||||||
|
throw e;
|
||||||
|
if (env.onError) {
|
||||||
|
return env.onError(e);
|
||||||
|
} else {
|
||||||
|
console.error("couldn't render " + entity.path);
|
||||||
|
console.error(entity);
|
||||||
|
console.error(e);
|
||||||
|
throw e;
|
||||||
|
}
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
function doStuff() {
|
function doStuff() {
|
||||||
|
var themes = desi.content.themes.filter(function (f) { return !/\blayouts\b/.test(f.path); })
|
||||||
|
;
|
||||||
|
|
||||||
console.info('[first] compiling theme assets');
|
console.info('[first] compiling theme assets');
|
||||||
desi.content.themes.filter(function (f) { return !/\blayouts\b/.test(f.path); }).forEach(compileThemeEntity);
|
return forEachAsync(themes, compileThemeEntity).then(function () {
|
||||||
|
console.info('compiling root pages');
|
||||||
console.info('compiling root pages');
|
return forEachAsync(desi.content.root, compileContentEntity).then(function () {
|
||||||
desi.content.root.forEach(compileContentEntity);
|
console.info('compiling article pages');
|
||||||
console.info('compiling article pages');
|
desi.content.collections.forEach(compileContentEntity);
|
||||||
desi.content.collections.forEach(compileContentEntity);
|
}).then(function () {
|
||||||
|
desi.compiled = compiled;
|
||||||
desi.compiled = compiled;
|
return desi;
|
||||||
return PromiseA.resolve(desi);
|
});
|
||||||
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!desi.partials) {
|
if (!desi.partials) {
|
||||||
return fsapi.getAllPartials().then(doStuff);
|
return fsapi.getAllPartials().then(function (partials) {
|
||||||
|
if (partials.error) {
|
||||||
|
throw partials.error;
|
||||||
|
}
|
||||||
|
|
||||||
|
desi.partials = partials;
|
||||||
|
return doStuff();
|
||||||
|
});
|
||||||
} else {
|
} else {
|
||||||
return doStuff();
|
return doStuff();
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
Desi.save = function (desi) {
|
Desi.buildAll = function (desi, env) {
|
||||||
|
return Desi.getDirtyFiles(desi, env.since)
|
||||||
|
.then(Desi.parseFrontmatter)
|
||||||
|
.then(Desi.getNav)
|
||||||
|
.then(Desi.normalizeYml)
|
||||||
|
.then(function () {
|
||||||
|
Desi.collate(desi, env)
|
||||||
|
})
|
||||||
|
.then(function () {
|
||||||
|
return Desi.build(desi, env);
|
||||||
|
}).then(function () {
|
||||||
|
return Desi.copyAssets(desi, env);
|
||||||
|
}).catch(function (e) {
|
||||||
|
if (env.onError) {
|
||||||
|
return env.onError(e);
|
||||||
|
} else {
|
||||||
|
console.error('buildAll failed somewhere');
|
||||||
|
console.error(e);
|
||||||
|
throw e;
|
||||||
|
}
|
||||||
|
})
|
||||||
|
;
|
||||||
|
};
|
||||||
|
|
||||||
|
Desi.write = function (desi, env) {
|
||||||
var compiled = desi.compiled.slice(0)
|
var compiled = desi.compiled.slice(0)
|
||||||
, batches = []
|
, batches = []
|
||||||
, now
|
, now
|
||||||
|
@ -868,6 +1061,10 @@
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
compiled.forEach(function (thing) {
|
||||||
|
thing.path = path.join(env.compiled_path, thing.path);
|
||||||
|
});
|
||||||
|
|
||||||
// because some servers / proxies are terrible at handling large uploads (>= 100k)
|
// because some servers / proxies are terrible at handling large uploads (>= 100k)
|
||||||
// (vagrant? or express? one of the two is CRAZY slow)
|
// (vagrant? or express? one of the two is CRAZY slow)
|
||||||
console.info('saving compiled files', desi.compiled);
|
console.info('saving compiled files', desi.compiled);
|
||||||
|
|
|
@ -0,0 +1,137 @@
|
||||||
|
---
|
||||||
|
amazon_link_enhancer: |
|
||||||
|
<!-- amazon -->
|
||||||
|
<script async="true" type="text/javascript" src="http://wms.assoc-amazon.com/20070822/US/js/link-enhancer-common.js?tag={{ amazon_affiliate_id }}">
|
||||||
|
</script>
|
||||||
|
<noscript>
|
||||||
|
<img src="http://wms.assoc-amazon.com/20070822/US/img/noscript.gif?tag={{ amazon_affiliate_id }}" alt="" />
|
||||||
|
</noscript>
|
||||||
|
|
||||||
|
google_analytics: |
|
||||||
|
<script type="text/javascript">
|
||||||
|
|
||||||
|
var _gaq = _gaq || [];
|
||||||
|
_gaq.push(['_setAccount', '{{ google_analytics.tracking_id }}']);
|
||||||
|
_gaq.push(['_trackPageview']);
|
||||||
|
|
||||||
|
(function() {
|
||||||
|
var ga = document.createElement('script'); ga.type = 'text/javascript'; ga.async = true;
|
||||||
|
ga.src = ('https:' == document.location.protocol ? 'https://ssl' : 'http://www') + '.google-analytics.com/ga.js';
|
||||||
|
var s = document.getElementsByTagName('script')[0]; s.parentNode.insertBefore(ga, s);
|
||||||
|
})();
|
||||||
|
|
||||||
|
</script>
|
||||||
|
|
||||||
|
disqus: |
|
||||||
|
<div id="disqus_thread"></div>
|
||||||
|
<script type="text/javascript">
|
||||||
|
/* * * CONFIGURATION VARIABLES: EDIT BEFORE PASTING INTO YOUR WEBPAGE * * */
|
||||||
|
var disqus_shortname = '{{ disqus.shortname }}'; // required: replace example with your forum shortname
|
||||||
|
var disqus_identifier = '{{ disqus.identifier }}' || undefined;
|
||||||
|
var disqus_url = '{{{ disqus.url }}}' || undefined;
|
||||||
|
|
||||||
|
/* * * DON'T EDIT BELOW THIS LINE * * */
|
||||||
|
(function() {
|
||||||
|
var dsq = document.createElement('script'); dsq.type = 'text/javascript'; dsq.async = true;
|
||||||
|
dsq.src = '//' + disqus_shortname + '.disqus.com/embed.js';
|
||||||
|
(document.getElementsByTagName('head')[0] || document.getElementsByTagName('body')[0]).appendChild(dsq);
|
||||||
|
})();
|
||||||
|
</script>
|
||||||
|
<noscript>Please enable JavaScript to view the <a href="https://disqus.com/?ref_noscript">comments powered by Disqus.</a></noscript>
|
||||||
|
|
||||||
|
redirect: >
|
||||||
|
<html>
|
||||||
|
<head>
|
||||||
|
<title>Redirecting to {{ entity.title }}</title>
|
||||||
|
<meta http-equiv="refresh" content="0;URL='{{{ env.url }}}{{{ entity.permalink }}}'"/>
|
||||||
|
</head>
|
||||||
|
<body>
|
||||||
|
<p>This page has moved to
|
||||||
|
<a href="{{{ env.url }}}{{{ entity.permalink }}}">{{ entity.title }}</a>.
|
||||||
|
</p>
|
||||||
|
</body>
|
||||||
|
</html>
|
||||||
|
|
||||||
|
pages_list: >
|
||||||
|
<li{{# active }} class="active"{{/ active }}><a{{# active }} class="active"{{/ active }}
|
||||||
|
href="{{{ path }}}"
|
||||||
|
>{{ title }}</a></li>
|
||||||
|
|
||||||
|
# [{ 'year': year,
|
||||||
|
# 'months' : [{ 'month' : month,
|
||||||
|
# 'pages': [{}, {}, ..] }, ..] }, ..]
|
||||||
|
posts_collate: |
|
||||||
|
{{# years }}
|
||||||
|
<h2>{{ year }}</h2>
|
||||||
|
{{> posts_collate_year }}
|
||||||
|
{{/ years }}
|
||||||
|
|
||||||
|
posts_collate_year: |
|
||||||
|
{{# months }}
|
||||||
|
<h3>{{ month }}</h3>
|
||||||
|
{{> posts_collate_month }}
|
||||||
|
{{/ months }}
|
||||||
|
|
||||||
|
posts_collate_month: |
|
||||||
|
<ul>
|
||||||
|
{{# pages }}
|
||||||
|
{{> posts_collate_pages }}
|
||||||
|
{{/ pages }}
|
||||||
|
</ul>
|
||||||
|
|
||||||
|
posts_collate_pages: |
|
||||||
|
<li><span>{{ year }}-{{ month }}-{{ day }}</span> »
|
||||||
|
<a href="{{{url}}}"
|
||||||
|
>{{ title }}</a></li>
|
||||||
|
|
||||||
|
google_prettify: |
|
||||||
|
<script src="http://cdnjs.cloudflare.com/ajax/libs/prettify/188.0.0/prettify.js"></script>
|
||||||
|
<script>
|
||||||
|
var pres = document.getElementsByTagName("pre");
|
||||||
|
for (var i=0; i < pres.length; ++i) {
|
||||||
|
pres[i].className = "prettyprint {{#linenums}}linenums{{/linenums}}";
|
||||||
|
}
|
||||||
|
prettyPrint();
|
||||||
|
</script>
|
||||||
|
<!-- end Google Prettify -->
|
||||||
|
|
||||||
|
google_ads: |
|
||||||
|
<script type="text/javascript">
|
||||||
|
|
||||||
|
var _gaq = _gaq || [];
|
||||||
|
_gaq.push(['_setAccount', {{#id}}'{{.}}'{{/id}}]);
|
||||||
|
_gaq.push(['_trackPageview']);
|
||||||
|
|
||||||
|
(function() {
|
||||||
|
var ga = document.createElement('script'); ga.type = 'text/javascript'; ga.async = true;
|
||||||
|
ga.src = ('https:' == document.location.protocol ? 'https://ssl' : 'http://www') + '.google-analytics.com/ga.js';
|
||||||
|
var s = document.getElementsByTagName('script')[0]; s.parentNode.insertBefore(ga, s);
|
||||||
|
})();
|
||||||
|
|
||||||
|
</script>
|
||||||
|
|
||||||
|
facebook_connect: |
|
||||||
|
<!-- facebook -->
|
||||||
|
<div id="fb-root"></div>
|
||||||
|
<script>(function(d, s, id) {
|
||||||
|
var js, fjs = d.getElementsByTagName(s)[0];
|
||||||
|
if (d.getElementById(id)) return;
|
||||||
|
js = d.createElement(s); js.id = id; js.async=true;
|
||||||
|
js.src = "//connect.facebook.net/en_US/all.js#xfbml=1&appId=213439508797174";
|
||||||
|
fjs.parentNode.insertBefore(js, fjs);
|
||||||
|
}(document, 'script', 'facebook-jssdk'));</script>
|
||||||
|
|
||||||
|
google_plusone: |
|
||||||
|
<!-- g+ -->
|
||||||
|
<!-- Place this tag after the last +1 button tag. -->
|
||||||
|
<script type="text/javascript">
|
||||||
|
(function() {
|
||||||
|
var po = document.createElement('script'); po.type = 'text/javascript'; po.async = true;
|
||||||
|
po.src = 'https://apis.google.com/js/plusone.js';
|
||||||
|
var s = document.getElementsByTagName('script')[0]; s.parentNode.insertBefore(po, s);
|
||||||
|
})();
|
||||||
|
</script>
|
||||||
|
|
||||||
|
twitter: |
|
||||||
|
<!-- twitter -->
|
||||||
|
<script>!function(d,s,id){var js,fjs=d.getElementsByTagName(s)[0];if(!d.getElementById(id)){js=d.createElement(s);js.id=id;js.async=true;js.src="//platform.twitter.com/widgets.js";fjs.parentNode.insertBefore(js,fjs);}}(document,"script","twitter-wjs");</script>
|
|
@ -213,7 +213,6 @@
|
||||||
return request.post('/api/fs/walk?_method=GET' + dotfiles + extensions + contents + sha1sum, {
|
return request.post('/api/fs/walk?_method=GET' + dotfiles + extensions + contents + sha1sum, {
|
||||||
dirs: collections
|
dirs: collections
|
||||||
}).then(function (resp) {
|
}).then(function (resp) {
|
||||||
console.log(collections);
|
|
||||||
return JSON.parse(resp);
|
return JSON.parse(resp);
|
||||||
});
|
});
|
||||||
};
|
};
|
||||||
|
@ -252,14 +251,20 @@
|
||||||
, data = {}
|
, data = {}
|
||||||
;
|
;
|
||||||
|
|
||||||
|
if (file.error) {
|
||||||
|
console.error(file);
|
||||||
|
console.error(file.error);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
if (/\.(ya?ml)$/i.test(file.name)) {
|
if (/\.(ya?ml)$/i.test(file.name)) {
|
||||||
console.log();
|
|
||||||
try {
|
try {
|
||||||
data = exports.YAML.parse(file.contents) || {};
|
data = exports.YAML.parse(file.contents) || {};
|
||||||
if ("undefined" === obj[keyname][filename]) {
|
if ("undefined" === data) {
|
||||||
data = {};
|
data = {};
|
||||||
}
|
}
|
||||||
} catch(e) {
|
} catch(e) {
|
||||||
|
data = { error: e };
|
||||||
console.error("Could not parse yaml for " + filename);
|
console.error("Could not parse yaml for " + filename);
|
||||||
console.error(file);
|
console.error(file);
|
||||||
console.error(e);
|
console.error(e);
|
||||||
|
@ -269,6 +274,7 @@
|
||||||
try {
|
try {
|
||||||
data = JSON.parse(file.contents) || {};
|
data = JSON.parse(file.contents) || {};
|
||||||
} catch(e) {
|
} catch(e) {
|
||||||
|
data = { error: e };
|
||||||
console.error("Could not parse json for " + filename);
|
console.error("Could not parse json for " + filename);
|
||||||
console.error(file);
|
console.error(file);
|
||||||
console.error(e);
|
console.error(e);
|
||||||
|
@ -278,7 +284,7 @@
|
||||||
console.error(file);
|
console.error(file);
|
||||||
}
|
}
|
||||||
|
|
||||||
obj[keyname][filename] = data;
|
obj[keyname][filename] = data || obj[keyname][filename];
|
||||||
/*
|
/*
|
||||||
if (!obj[keyname][filename]) {
|
if (!obj[keyname][filename]) {
|
||||||
obj[keyname][filename] = {};
|
obj[keyname][filename] = {};
|
||||||
|
@ -300,15 +306,20 @@
|
||||||
;
|
;
|
||||||
|
|
||||||
Object.keys(results.partials).forEach(function (key) {
|
Object.keys(results.partials).forEach(function (key) {
|
||||||
var partial = partials[key];
|
var partial = results.partials[key]
|
||||||
|
;
|
||||||
|
|
||||||
Object.keys(partial).forEach(function (prop) {
|
Object.keys(partial).forEach(function (prop) {
|
||||||
if (partials[prop]) {
|
if (partials[prop]) {
|
||||||
console.warn('partial \'' + prop + '\' overwritten by ' + key);
|
console.warn('partial \'' + prop + '\' overwritten by ' + key);
|
||||||
}
|
}
|
||||||
|
|
||||||
partials[prop] = partial[prop];
|
partials[prop] = partial[prop];
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
|
console.info('getAllPartialts', results);
|
||||||
|
console.info(partials);
|
||||||
return partials;
|
return partials;
|
||||||
});
|
});
|
||||||
};
|
};
|
||||||
|
|
58
partials.yml
58
partials.yml
|
@ -1,58 +0,0 @@
|
||||||
---
|
|
||||||
pages_list: >
|
|
||||||
<li{{# active }} class="active"{{/ active }}><a{{# active }} class="active"{{/ active }}
|
|
||||||
href="{{{ path }}}"
|
|
||||||
>{{ title }}</a></li>
|
|
||||||
|
|
||||||
# [{ 'year': year,
|
|
||||||
# 'months' : [{ 'month' : month,
|
|
||||||
# 'pages': [{}, {}, ..] }, ..] }, ..]
|
|
||||||
posts_collate: |
|
|
||||||
{{# years }}
|
|
||||||
<h2>{{ year }}</h2>
|
|
||||||
{{> posts_collate_year }}
|
|
||||||
{{/ years }}
|
|
||||||
|
|
||||||
posts_collate_year: |
|
|
||||||
{{# months }}
|
|
||||||
<h3>{{ month }}</h3>
|
|
||||||
{{> posts_collate_month }}
|
|
||||||
{{/ months }}
|
|
||||||
|
|
||||||
posts_collate_month: |
|
|
||||||
<ul>
|
|
||||||
{{# pages }}
|
|
||||||
{{> posts_collate_pages }}
|
|
||||||
{{/ pages }}
|
|
||||||
</ul>
|
|
||||||
|
|
||||||
posts_collate_pages: |
|
|
||||||
<li><span>{{ year }}-{{ month }}-{{ day }}</span> »
|
|
||||||
<a href="{{{url}}}"
|
|
||||||
>{{ title }}</a></li>
|
|
||||||
|
|
||||||
google_prettify: |
|
|
||||||
<script src="http://cdnjs.cloudflare.com/ajax/libs/prettify/188.0.0/prettify.js"></script>
|
|
||||||
<script>
|
|
||||||
var pres = document.getElementsByTagName("pre");
|
|
||||||
for (var i=0; i < pres.length; ++i) {
|
|
||||||
pres[i].className = "prettyprint {{#linenums}}linenums{{/linenums}}";
|
|
||||||
}
|
|
||||||
prettyPrint();
|
|
||||||
</script>
|
|
||||||
<!-- end Google Prettify -->
|
|
||||||
|
|
||||||
google_ads: |
|
|
||||||
<script type="text/javascript">
|
|
||||||
|
|
||||||
var _gaq = _gaq || [];
|
|
||||||
_gaq.push(['_setAccount', {{#id}}'{{.}}'{{/id}}]);
|
|
||||||
_gaq.push(['_trackPageview']);
|
|
||||||
|
|
||||||
(function() {
|
|
||||||
var ga = document.createElement('script'); ga.type = 'text/javascript'; ga.async = true;
|
|
||||||
ga.src = ('https:' == document.location.protocol ? 'https://ssl' : 'http://www') + '.google-analytics.com/ga.js';
|
|
||||||
var s = document.getElementsByTagName('script')[0]; s.parentNode.insertBefore(ga, s);
|
|
||||||
})();
|
|
||||||
|
|
||||||
</script>
|
|
|
@ -11,14 +11,14 @@ angular.module('myApp.build', ['ngRoute'])
|
||||||
|
|
||||||
.controller('BuildCtrl'
|
.controller('BuildCtrl'
|
||||||
, ['$scope', '$location', '$timeout', 'Desirae'
|
, ['$scope', '$location', '$timeout', 'Desirae'
|
||||||
, function ($scope, $location, $timeout, Desirae) {
|
, function ($scope, $location, $timeout, DesiraeService) {
|
||||||
var scope = this
|
var scope = this
|
||||||
, path = window.path
|
, path = window.path
|
||||||
;
|
;
|
||||||
|
|
||||||
function init() {
|
function init() {
|
||||||
console.log('desi loading');
|
console.log('desi loading');
|
||||||
Desirae.meta().then(function (desi) {
|
DesiraeService.meta().then(function (desi) {
|
||||||
scope.blogdir = desi.blogdir.path.replace(/^\/(Users|home)\/[^\/]+\//, '~/');
|
scope.blogdir = desi.blogdir.path.replace(/^\/(Users|home)\/[^\/]+\//, '~/');
|
||||||
scope.site = desi.site;
|
scope.site = desi.site;
|
||||||
|
|
||||||
|
@ -40,108 +40,50 @@ angular.module('myApp.build', ['ngRoute'])
|
||||||
scope.extensions = ['md', 'html'];
|
scope.extensions = ['md', 'html'];
|
||||||
}
|
}
|
||||||
|
|
||||||
scope.onChange = function () {
|
scope.onError = function (e) {
|
||||||
var post = scope.selected.post
|
console.error(e);
|
||||||
, selected = scope.selected
|
if (window.confirm("Encountered an error. Please inspect the console.\n\nWould you like to ignore the error and continue?")) {
|
||||||
;
|
return window.Promise.resolve();
|
||||||
|
} else {
|
||||||
post.yml.title = post.yml.title || '';
|
return window.Promise.reject();
|
||||||
post.yml.description = post.yml.description || '';
|
|
||||||
|
|
||||||
if (selected.permalink === post.yml.permalink) {
|
|
||||||
selected.permalink = '/articles/' + post.yml.title.toLowerCase()
|
|
||||||
.replace(/["']/g, '')
|
|
||||||
.replace(/\W/g, '-')
|
|
||||||
.replace(/^-+/g, '')
|
|
||||||
.replace(/-+$/g, '')
|
|
||||||
.replace(/--/g, '-')
|
|
||||||
+ '.' + selected.format
|
|
||||||
;
|
|
||||||
|
|
||||||
post.yml.permalink = selected.permalink;
|
|
||||||
}
|
|
||||||
if (window.path.extname(post.yml.permalink) !== '.' + selected.format) {
|
|
||||||
post.yml.permalink = post.yml.permalink.replace(/\.\w+$/, '.' + selected.format);
|
|
||||||
}
|
|
||||||
|
|
||||||
post.frontmatter = window.jsyaml.dump(post.yml).trim();
|
|
||||||
|
|
||||||
// TODO use some sort of filepath pattern in config.yml
|
|
||||||
selected.path = window.path.join((selected.collection || 'posts'), window.path.basename(post.yml.permalink));
|
|
||||||
selected.abspath = window.path.join(scope.blogdir, selected.path);
|
|
||||||
};
|
|
||||||
scope.onFrontmatterChange = function () {
|
|
||||||
var data
|
|
||||||
;
|
|
||||||
|
|
||||||
try {
|
|
||||||
if (!scope.selected.post.frontmatter || !scope.selected.post.frontmatter.trim()) {
|
|
||||||
throw new Error('deleted frontmatter');
|
|
||||||
}
|
|
||||||
data = window.jsyaml.load(scope.selected.post.frontmatter);
|
|
||||||
scope.selected.format = data.permalink.replace(/.*\.(\w+$)/, '$1');
|
|
||||||
if (!data.permalink) {
|
|
||||||
data = scope.selected.permalink;
|
|
||||||
}
|
|
||||||
scope.selected.post.yml = data;
|
|
||||||
} catch(e) {
|
|
||||||
console.error(e);
|
|
||||||
console.error('ignoring update that created parse error');
|
|
||||||
scope.selected.post.frontmatter = window.jsyaml.dump(scope.selected.post.yml).trim();
|
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
function updateDate() {
|
scope.buildOne = function (envstr) {
|
||||||
$timeout.cancel(scope.dtlock);
|
var env
|
||||||
scope.dtlock = $timeout(function () {
|
|
||||||
if (scope.selected && scope.selected.date === scope.selected.post.yml.date) {
|
|
||||||
scope.selected.date = scope.selected.post.yml.date = Desirae.toDesiDate(new Date());
|
|
||||||
}
|
|
||||||
scope.onChange();
|
|
||||||
updateDate();
|
|
||||||
}, 60 * 1000);
|
|
||||||
}
|
|
||||||
|
|
||||||
scope.upsert = function () {
|
|
||||||
console.log('upserted');
|
|
||||||
if (-1 === scope.extensions.indexOf(scope.selected.format)) {
|
|
||||||
window.alert('.' + scope.selected.format + ' is not a supported extension.\n\nPlease choose from: .' + scope.extensions.join(' .'));
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
scope.selected.post.yml.uuid = scope.selected.uuid;
|
|
||||||
['updated', 'theme', 'layout', 'swatch'].forEach(function (key) {
|
|
||||||
if (!scope.selected.post.yml[key]) {
|
|
||||||
delete scope.selected.post.yml[key];
|
|
||||||
}
|
|
||||||
});
|
|
||||||
scope.onChange();
|
|
||||||
|
|
||||||
var files = []
|
|
||||||
;
|
;
|
||||||
|
|
||||||
files.push({
|
// TODO is there a legitimate case where in addition to base_path (root of the blog)
|
||||||
path: scope.selected.path
|
// a user would need owner_base? i.e. school.edu/~/rogers/blog school.edu/~/rogers/assets
|
||||||
, contents:
|
if ('production' === envstr) {
|
||||||
'---\n'
|
env = {
|
||||||
+ scope.selected.post.frontmatter.trim()
|
url: scope.production_url
|
||||||
+ '\n'
|
, base_url: scope.development_url.replace(/(https?:\/\/[^\/#?]+)/, '$1')
|
||||||
+ '---\n'
|
, compiled_path: 'compiled'
|
||||||
+ '\n'
|
, since: 0
|
||||||
+ scope.selected.post.body.trim()
|
, onError: scope.onError
|
||||||
});
|
};
|
||||||
|
} else {
|
||||||
|
env = {
|
||||||
|
url: scope.development_url
|
||||||
|
, base_url: scope.development_url.replace(/(https?:\/\/[^\/#?]+)/, '$1')
|
||||||
|
, base_path: scope.development_url.replace(/https?:\/\/[^\/#?]+/, '')
|
||||||
|
, compiled_path: 'compiled_dev'
|
||||||
|
, since: 0
|
||||||
|
, onError: scope.onError
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
console.log(files);
|
return DesiraeService.build(env).then(function () {
|
||||||
Desirae.putFiles(files).then(function (results) {
|
DesiraeService.write(env);
|
||||||
console.log('TODO check for error');
|
});
|
||||||
console.log(results);
|
};
|
||||||
$location.path('/build');
|
|
||||||
}).catch(function (e) {
|
scope.build = function (envs) {
|
||||||
$timeout.cancel(scope.dtlock);
|
window.forEachAsync(envs, function (env) {
|
||||||
console.error(scope.site);
|
return scope.buildOne(env);
|
||||||
console.error(e);
|
}).then(function () {
|
||||||
window.alert("Error Nation! :/");
|
window.alert('Build(s) Complete');
|
||||||
throw e;
|
|
||||||
});
|
});
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue