AJ ONeal
9 years ago
7 changed files with 825 additions and 531 deletions
@ -0,0 +1,56 @@ |
|||
This is what an entity looks like: |
|||
|
|||
```yml |
|||
# inherited from File Entity |
|||
path : My Posts/My-Old-Name.html |
|||
lastModifiedDate : 2015-07-04T13:56:01Z |
|||
createdDate : 2015-07-04T13:56:01Z |
|||
contents : '...' # whatever the file is |
|||
|
|||
# inherited from Collection Entity |
|||
name : My-Old-Name.html |
|||
relativePath : My Posts |
|||
ext : .html |
|||
collection : posts |
|||
|
|||
# inherited from Content Entity |
|||
frontmatter : '---\n...\n---' # frontmatter as a string |
|||
yml : {} # frontmatter, parsed |
|||
body : 'I think ...' # body, after frontmatter |
|||
|
|||
# inherited from Normalized Entity |
|||
title : My Title # yml.title | titlize(entity.name) |
|||
slug : my-title # slugify(title) |
|||
slug_path : my-posts # slugifyPath(relativePath) |
|||
|
|||
year : 2014 |
|||
month : 07 |
|||
day : 04 |
|||
hour : 13 |
|||
twelve_hour : 1 |
|||
meridian : pm |
|||
minute : 22 |
|||
|
|||
categories : ['tech'] |
|||
tags : ['http','url','website'] |
|||
|
|||
# includes index.html |
|||
relative_file : /posts/foo/index.html |
|||
|
|||
# excludes index.html |
|||
relative_link : /posts/foo/ |
|||
|
|||
# actual url of this file, even if redirect |
|||
# excludes index.html |
|||
url : http://dev.example.com/posts/foo/ |
|||
|
|||
# the appropriate url, even in a redirect or duplicate |
|||
# excludes index.html |
|||
canonical_url : http://dev.example.com/posts/foo/ |
|||
|
|||
# production url, even in development (for disqus, etc) |
|||
# excludes index.html |
|||
production_url : http://example.com/posts/foo/ |
|||
``` |
|||
|
|||
Note: The option `env.explicitIndexes` turns on `/index.html`. This option is automatically turned on when Dropbox is the host. |
File diff suppressed because it is too large
@ -0,0 +1,121 @@ |
|||
/*jshint -W054 */ |
|||
;(function (exports) { |
|||
'use strict'; |
|||
|
|||
var path = exports.path || require('path') |
|||
, months |
|||
, cores = {} |
|||
; |
|||
|
|||
months = { |
|||
1: 'January' |
|||
, 2: 'February' |
|||
, 3: 'March' |
|||
, 4: 'April' |
|||
, 5: 'May' |
|||
, 6: 'June' |
|||
, 7: 'July' |
|||
, 8: 'August' |
|||
, 9: 'September' |
|||
, 10: 'October' |
|||
, 11: 'November' |
|||
, 12: 'December' |
|||
}; |
|||
|
|||
function byDate(a, b) { |
|||
a.year = parseInt(a.year, 10) || 0; |
|||
b.year = parseInt(b.year, 10) || 0; |
|||
if (a.year > b.year) { |
|||
return -1; |
|||
} else if (a.year < b.year) { |
|||
return 1; |
|||
} |
|||
|
|||
a.month = parseInt(a.month, 10) || 0; |
|||
b.month = parseInt(b.month, 10) || 0; |
|||
if (a.month > b.month) { |
|||
return -1; |
|||
} else if (a.month < b.month) { |
|||
return 1; |
|||
} |
|||
|
|||
a.day = parseInt(a.day, 10) || 0; |
|||
b.day = parseInt(b.day, 10) || 0; |
|||
if (a.day > b.day) { |
|||
return -1; |
|||
} else if (a.day < b.day) { |
|||
return 1; |
|||
} |
|||
|
|||
if (a.hour > b.hour) { |
|||
return -1; |
|||
} else if (a.hour < b.hour) { |
|||
return 1; |
|||
} |
|||
|
|||
if (a.minute > b.minute) { |
|||
return -1; |
|||
} else if (a.minute < b.minute) { |
|||
return 1; |
|||
} |
|||
|
|||
if (a.title.toLowerCase() <= b.title.toLowerCase()) { |
|||
return -1; |
|||
} |
|||
|
|||
return 1; |
|||
} |
|||
|
|||
function collate(entities, env) { |
|||
var yearsArr = [] |
|||
; |
|||
|
|||
entities.forEach(function (f) { |
|||
var set |
|||
, yindex = 3000 - f.year |
|||
, mindex = 12 - f.month |
|||
; |
|||
|
|||
f.url = path.join(env.base_path, f.permalink); |
|||
|
|||
if (!yearsArr[yindex]) { |
|||
yearsArr[yindex] = { year: f.year, months: [] }; |
|||
} |
|||
set = yearsArr[yindex]; |
|||
|
|||
if (!set.months[mindex]) { |
|||
set.months[mindex] = { month: months[parseInt(f.month, 10)], pages: [] }; |
|||
} |
|||
set = set.months[mindex]; |
|||
|
|||
set.pages.push(f); |
|||
}); |
|||
|
|||
yearsArr = yearsArr.filter(function (y) { |
|||
if (!y) { |
|||
return false; |
|||
} |
|||
|
|||
y.months = y.months.filter(function (m) { |
|||
return m && m.pages.length; |
|||
}); |
|||
|
|||
if (!y.months.length) { |
|||
return false; |
|||
} |
|||
|
|||
return true; |
|||
}); |
|||
|
|||
return { years: yearsArr }; |
|||
} |
|||
|
|||
cores.collate = function (desi, env) { |
|||
// TODO categories
|
|||
// TODO tags
|
|||
desi.content.collections.sort(byDate); |
|||
desi.collated = collate(desi.content.collections, env); |
|||
}; |
|||
|
|||
exports.DesiraeAggregateCore = cores.DesiraeAggregateCore = cores; |
|||
}('undefined' !== typeof exports && exports || window)); |
@ -0,0 +1,11 @@ |
|||
/*jshint -W054 */ |
|||
;(function (exports) { |
|||
'use strict'; |
|||
|
|||
function desiMap(obj) { |
|||
obj.desi = obj; |
|||
return obj; |
|||
} |
|||
|
|||
exports.DesiraeDatamapCore = desiMap.DesiraeDatamapCore = desiMap; |
|||
}('undefined' !== typeof exports && exports || window)); |
@ -0,0 +1,44 @@ |
|||
/*jshint -W054 */ |
|||
;(function (exports) { |
|||
'use strict'; |
|||
|
|||
var PromiseA = exports.Promise || require('bluebird').Promise |
|||
; |
|||
|
|||
function renderMd(contentstr/*, desi*/) { |
|||
var markitdown = (exports.markdownit || require('markdown-it'))({ html: true, linkify: true }) |
|||
; |
|||
|
|||
return PromiseA.resolve( |
|||
markitdown.render(contentstr) |
|||
//.replace('"', '"')
|
|||
//.replace(''', "'")
|
|||
//.replace('/', '/')
|
|||
); |
|||
} |
|||
|
|||
function renderNoop(contentstr/*, desi*/) { |
|||
// hmmm... that was easy
|
|||
return PromiseA.resolve(contentstr); |
|||
} |
|||
|
|||
function renderJade(contentstr, desi, options) { |
|||
options = options || {}; |
|||
if (!('pretty' in options)) { |
|||
options.pretty = true; |
|||
} |
|||
|
|||
var jade = (exports.jade || require('jade')) |
|||
, fn = jade.compile(contentstr, options) |
|||
, html = fn(desi) |
|||
; |
|||
|
|||
return PromiseA.resolve(html); |
|||
} |
|||
|
|||
exports.DesiraeRenderMarkdown = renderMd.DesiraeRenderMarkdown = renderMd; |
|||
exports.DesiraeRenderHtml = renderNoop.DesiraeRenderHtml = renderNoop; |
|||
exports.DesiraeRenderCss = renderNoop.DesiraeRenderCss = renderNoop; |
|||
exports.DesiraeRenderJs = renderNoop.DesiraeRenderJs = renderNoop; |
|||
exports.DesiraeRenderJade = renderJade.DesiraeRenderJade = renderJade; |
|||
}('undefined' !== typeof exports && exports || window)); |
@ -0,0 +1,178 @@ |
|||
/*jshint -W054 */ |
|||
;(function (exports) { |
|||
'use strict'; |
|||
|
|||
var cores = {} |
|||
, Desi = exports.Desirae || require('desirae').Desirae |
|||
, path = exports.path || require('path') |
|||
; |
|||
|
|||
cores.lint = function (desi, env, collection, entity) { |
|||
// TODO splice
|
|||
//desi.content.collections = desi.content.collections.filter(function (entity) {
|
|||
// TODO throw for any files that don't have a registered renderer
|
|||
if (!entity.yml) { |
|||
if (!desi.config.empty_frontmatter) { |
|||
throw new Error("no frontmatter for " + (entity.path || entity.name) + "." |
|||
+ "Set `config.yml.empty_frontmatter: include|skip` to ignore this error." |
|||
); |
|||
} |
|||
|
|||
if ('include' === desi.config.empty_frontmatter) { |
|||
entity.yml = {}; |
|||
} |
|||
else if ('skip' === desi.config.empty_frontmatter) { |
|||
return false; |
|||
} |
|||
else { |
|||
throw new Error('unrecognize option ' + desi.config.empty_frontmatter + |
|||
' for `config.yml.empty_frontmatter: include|skip`.'); |
|||
} |
|||
} |
|||
|
|||
if (!entity.body || !entity.body.trim()) { |
|||
if (!desi.config.empty_body) { |
|||
throw new Error('empty content file ' + (entity.path || entity.name) |
|||
+ '. Set `config.yml.empty_body: include|skip` to ignore this error.' |
|||
); |
|||
} |
|||
|
|||
if ('include' === desi.config.empty_body) { |
|||
entity.body = ''; |
|||
} |
|||
else if ('skip' === desi.config.empty_body) { |
|||
return false; |
|||
} |
|||
else { |
|||
throw new Error('unrecognize option ' + desi.config.empty_frontmatter + |
|||
' for `config.yml.empty_body: include|skip`.'); |
|||
} |
|||
} |
|||
|
|||
return true; |
|||
//});
|
|||
}; |
|||
|
|||
cores.root = function (desi, env, collection, entity) { |
|||
entity.yml = entity.yml || {}; |
|||
|
|||
entity.layout = entity.yml.layout || '__page__'; |
|||
|
|||
// _root is not subject to the same permalink rules as collections,
|
|||
// so we just go ahead and define that here
|
|||
entity.permalink = entity.yml.permalink || entity.path.replace(/\.\w+$/, ''); |
|||
}; |
|||
|
|||
cores.normalize = function (desi, env, collection, entity) { |
|||
entity.title = entity.yml.title || Desi.firstCap(entity.name.replace(/\.\w+$/, '')); |
|||
entity.date = entity.yml.date; |
|||
|
|||
if (!entity.date) { |
|||
// TODO tell YAML parser to keep the date a string
|
|||
entity.date = new Date(entity.yml.created_at |
|||
|| entity.yml.time |
|||
|| entity.yml.updated_at |
|||
|| entity.createdDate |
|||
|| entity.lastModifiedDate |
|||
).toISOString(); |
|||
} |
|||
if ('object' === typeof entity.date) { |
|||
entity.date = entity.date.toISOString(); |
|||
} |
|||
|
|||
entity.updated_at = entity.yml.updated_at || entity.lastModifiedDate; |
|||
|
|||
entity.published_at = Desi.fromLocaleDate(entity.date || entity.lastModifiedDate); |
|||
entity.year = entity.published_at.year; |
|||
entity.month = entity.published_at.month; |
|||
entity.day = entity.published_at.day; |
|||
entity.hour = entity.published_at.hour; |
|||
entity.twelve_hour = entity.published_at.twelve_hour; |
|||
entity.meridian = entity.published_at.meridian; |
|||
entity.minute = entity.published_at.minute; |
|||
// let's just agree that that's too far
|
|||
//entity.second = entity.published_at.second;
|
|||
|
|||
entity.slug = Desi.slugify(entity.title); |
|||
entity.slug_path = Desi.slugifyPath(entity.relativePath); |
|||
entity.slugPath = Desi.slugifyPath(entity.relativePath); |
|||
|
|||
// categories
|
|||
if (Array.isArray(entity.yml.categories)) { |
|||
entity.categories = entity.yml.categories; |
|||
} |
|||
else if ('string' === typeof entity.yml.categories) { |
|||
entity.categories = [entity.yml.categories]; |
|||
} |
|||
else if ('string' === typeof entity.yml.category) { |
|||
entity.categories = [entity.yml.category]; |
|||
} |
|||
else { |
|||
entity.categories = []; |
|||
} |
|||
|
|||
// tags
|
|||
if (Array.isArray(entity.yml.tags)) { |
|||
entity.tags = entity.yml.tags; |
|||
} |
|||
else if ('string' === typeof entity.yml.tags) { |
|||
entity.tags = [entity.yml.tags]; |
|||
} |
|||
else { |
|||
entity.tags = []; |
|||
} |
|||
|
|||
entity.permalink = entity.permalink || entity.yml.permalink; |
|||
|
|||
if (!entity.permalink) { |
|||
// try the fallback_permalink first (because we're looking at files that don't have yml)
|
|||
// then try the normal permalink (because :filename -> :title and whatnot, so it'll work)
|
|||
Desi.permalinkify(desi, collection.fallback_permalink || collection.permalink, entity); |
|||
} |
|||
|
|||
/* |
|||
if (!/\.x?html?$/.test(entity.permalink)) { |
|||
entity.htmllink = path.join(entity.permalink, 'index.html'); |
|||
} |
|||
*/ |
|||
|
|||
// The root index is the one exception
|
|||
if (/^(index)?\/?index(\.x?html?)?$/.test(entity.permalink)) { |
|||
entity.permalink = ''; |
|||
} |
|||
|
|||
// relative to the site
|
|||
entity.relative_file = path.join(env.base_path, entity.permalink) |
|||
.replace(/\/$/, '/index.html'); |
|||
entity.relative_href = path.join(env.base_path, entity.permalink) |
|||
.replace(/\/index\.html$/, '/'); |
|||
|
|||
entity.url = env.base_url + path.join(env.base_path, entity.permalink) |
|||
.replace(/\/index\.html$/, '/'); |
|||
entity.canonical_url = env.base_url + path.join(env.base_path, entity.permalink) |
|||
.replace(/\/index\.html$/, '/'); |
|||
entity.production_url = desi.site.base_url + path.join(desi.site.base_path, entity.permalink) |
|||
.replace(/\/index\.html$/, '/'); |
|||
entity.relative_url = path.join(env.base_path, entity.permalink) |
|||
.replace(/\/index\.html$/, '/'); |
|||
|
|||
if (env.explicitIndexes || env.explicitIndices || env.explicit_indexes || env.explicit_indices) { |
|||
// NOTE: file_url is NOT replaced
|
|||
['url', 'canonical_url', 'production_url', 'relative_url'].forEach(function (url) { |
|||
entity[url] = entity[url].replace(/\/$/, '/index.html'); |
|||
}); |
|||
} |
|||
}; |
|||
|
|||
cores.disqus = function (desi, env, collection, entity) { |
|||
var yml = entity.yml |
|||
; |
|||
|
|||
if (yml.uuid) { |
|||
entity.disqus_identifier = yml.uuid; |
|||
} |
|||
entity.disqus_url = entity.production_url; |
|||
}; |
|||
|
|||
exports.DesiraeTransformCore = cores.DesiraeTransformCore = cores; |
|||
}('undefined' !== typeof exports && exports || window)); |
Loading…
Reference in new issue