Skip to content

Commit

Permalink
Rewrite theme and add theme tests.
Browse files Browse the repository at this point in the history
TODO: Writing test for Theme.generate
  • Loading branch information
tommy351 committed Dec 16, 2014
1 parent 262fc82 commit 6db7562
Show file tree
Hide file tree
Showing 17 changed files with 704 additions and 87 deletions.
14 changes: 12 additions & 2 deletions lib/box/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -49,11 +49,21 @@ function Box(ctx, base, options){
options = {};
}

return ctx.render.render({path: this.source}, options).nodeify(callback);
var self = this;

return this.read().then(function(content){
return ctx.render.render({
text: content,
path: self.source
}, options)
}).nodeify(callback);
};

_File.prototype.renderSync = function(options){
return ctx.render.renderSync({path: this.source}, options);
return ctx.render.renderSync({
text: this.readSync(),
path: this.source
}, options);
};
}

Expand Down
55 changes: 24 additions & 31 deletions lib/theme/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -5,36 +5,30 @@ var util = require('../util');
var Box = require('../box');
var View = require('./view');

var i18n = util.i18n;

require('colors');

function Theme(ctx){
Box.call(this, ctx, ctx.theme_dir);

this.config = {};

this.i18n = new i18n({
code: ctx.config.language
});

this.views = {};

this.processors = [
require('./processors/config'),
require('./processors/i18n'),
require('./processors/view'),
require('./processors/source')
];

var _View = this.View = function(path){
View.call(this, path);
var _View = this.View = function(path, data){
View.call(this, path, data);
};

util.inherits(_View, View);

_View.prototype.theme = this;
_View.prototype.context = ctx;
_View.prototype._theme = this;
_View.prototype._render = ctx.render;
_View.prototype._helper = ctx.extend.helper;
}

util.inherits(Theme, Box);
Expand All @@ -47,16 +41,14 @@ Theme.prototype._generate = function(options){
var ctx = this.context;
var config = ctx.config;
var siteLocals = ctx.locals;
var i18n = this.i18n;

var generators = ctx.extend.generator.list();
var generatorKeys = Object.keys(generators);
var excludeGenerator = config.exclude_generator || [];

function Locals(path, locals){
this.page = _.extend({
path: path,
lang: ensureLanguage(this) // every page should have a 'lang' value
path: path
}, locals);

this.path = path;
Expand All @@ -67,8 +59,6 @@ Theme.prototype._generate = function(options){
Locals.prototype.config = config;
Locals.prototype.theme = _.extend({}, config, this.config, config.theme_config);
Locals.prototype._ = _;
Locals.prototype.__ = i18n.__();
Locals.prototype._p = i18n._p();
Locals.prototype.layout = 'layout';
Locals.prototype.cache = !options.watch;
Locals.prototype.env = ctx.env;
Expand All @@ -91,21 +81,6 @@ Theme.prototype._generate = function(options){
});
};

function ensureLanguage(locals){
var page = locals.page;
var lang = page.lang;
var config = locals.config;

if (lang) return lang;
if (!config.language) return 'default';
if (!Array.isArray(config.language)) return config.language;

var path = locals.path;
if (path[0] !== '/') path = '/' + path;

// TODO: Optimize language query
}

Theme.prototype.generate = function(options, callback){
if (!callback && typeof options === 'function'){
callback = options;
Expand Down Expand Up @@ -137,4 +112,22 @@ Theme.prototype.getView = function(path){
}
};

Theme.prototype.setView = function(path, data){
var extname = pathFn.extname(path);
var name = path.substring(0, path.length - extname.length);
var views = this.views[name] = this.views[name] || {};

views[extname] = new this.View(path, data);
};

Theme.prototype.removeView = function(path){
var extname = pathFn.extname(path);
var name = path.substring(0, path.length - extname.length);
var views = this.views[name];

if (!views) return;

delete views[extname];
};

module.exports = Theme;
16 changes: 8 additions & 8 deletions lib/theme/processors/config.js
Original file line number Diff line number Diff line change
@@ -1,18 +1,18 @@
var Pattern = require('../../box/pattern');

exports.process = function(data){
if (data.type === 'delete'){
this.config = {};
exports.process = function(file){
if (file.type === 'delete'){
file.box.config = {};
return;
}

var ctx = this.context;
var self = this;

return data.render().then(function(result){
data.box.config = result;
ctx.log.debug('Theme config loaded.');
return file.render().then(function(result){
file.box.config = result;
self.log.debug('Theme config loaded.');
}, function(err){
ctx.log.error('Theme config load failed.');
self.log.error('Theme config load failed.');
throw err;
});
};
Expand Down
20 changes: 0 additions & 20 deletions lib/theme/processors/i18n.js

This file was deleted.

32 changes: 27 additions & 5 deletions lib/theme/processors/source.js
Original file line number Diff line number Diff line change
@@ -1,16 +1,38 @@
var Pattern = require('../../box/pattern');
var common = require('../../plugins/processor/common');

var rHiddenFile = /^_|\/_/;
exports.process = function(file){
var Asset = this.model('Asset');
var id = file.source.substring(this.base_dir.length);
var path = file.params.path;
var doc = Asset.findById(id);

exports.process = function(data){
//
if (file.type === 'delete'){
if (doc){
return doc.remove();
} else {
return;
}
}

if (doc){
doc.path = path;
doc.modified = file.type === 'update';

return doc.save();
} else {
return Asset.insert({
_id: id,
path: path
});
}
};

exports.pattern = new Pattern(function(path){
if (path.substring(0, 6) !== 'source') return;
if (path.substring(0, 7) !== 'source/') return false;

path = path.substring(7);
if (rHiddenFile.test(path)) return;
if (common.isHiddenFile(path) || common.isTmpFile(path)) return false;

return {path: path};
});
14 changes: 12 additions & 2 deletions lib/theme/processors/view.js
Original file line number Diff line number Diff line change
@@ -1,7 +1,17 @@
var Pattern = require('../../box/pattern');
var pathFn = require('path');

exports.process = function(data){
//
exports.process = function(file){
var path = file.params.path;

if (file.type === 'delete'){
file.box.removeView(path);
return;
}

return file.read().then(function(result){
file.box.setView(path, result);
});
};

exports.pattern = new Pattern('layout/*path');
17 changes: 6 additions & 11 deletions lib/theme/view.js
Original file line number Diff line number Diff line change
Expand Up @@ -3,13 +3,8 @@ var _ = require('lodash');
var yfm = require('hexo-front-matter');

function View(path, data){
var ctx = this.context;

this.path = path;
this.source = pathFn.join(this.theme.base, path);
this.extname = pathFn.extname(path);
this.render = ctx.render;
this.helper = ctx.extend.helper;
this.source = pathFn.join(this._theme.base, 'layout', path);
this.data = typeof data === 'string' ? yfm(data) : data;
}

Expand All @@ -26,7 +21,7 @@ View.prototype.render = function(options, callback){
var locals = this._buildLocals(options);
var self = this;

return this.render.render({
return this._render.render({
path: this.source,
text: data._content
}, this._bindHelpers(locals)).then(function(result){
Expand All @@ -50,7 +45,7 @@ View.prototype.renderSync = function(options){
var layout = data.hasOwnProperty('layout') ? data.layout : options.layout;
var locals = this._buildLocals(options);

var result = this.render.renderSync({
var result = this._render.renderSync({
path: this.source,
text: data._content
}, this._bindHelpers(locals));
Expand Down Expand Up @@ -97,7 +92,7 @@ View.prototype._buildLocals = function(locals){
};

View.prototype._bindHelpers = function(locals){
var helpers = this.helper.list();
var helpers = this._helper.list();
var keys = Object.keys(helpers);
var result = {};
var key = '';
Expand All @@ -115,12 +110,12 @@ View.prototype._bindHelpers = function(locals){
View.prototype._resolveLayout = function(name){
// Relative path
var layoutPath = pathFn.join(pathFn.dirname(this.path), name);
var layoutView = this.theme.getView(layoutPath);
var layoutView = this._theme.getView(layoutPath);

if (layoutView && layoutView.source !== this.source) return layoutView;

// Absolute path
layoutView = this.theme.getView(name);
layoutView = this._theme.getView(name);
if (layoutView && layoutView.source !== this.source) return layoutView;
};

Expand Down
18 changes: 10 additions & 8 deletions lib/util/i18n.js
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
var _ = require('lodash'),
vsprintf = require('sprintf-js').vsprintf;
var _ = require('lodash');
var vsprintf = require('sprintf-js').vsprintf;

/**
* i18n module.
Expand All @@ -10,7 +10,7 @@ var _ = require('lodash'),
* @constructor
* @module hexo
*/
var i18n = module.exports = function i18n(options){
function i18n(options){
/**
* Language data.
*
Expand All @@ -29,7 +29,7 @@ var i18n = module.exports = function i18n(options){
code: 'default'
}, options);

this.options.code = _getCodeToken(this.options.code);
this.options.code = getCodeToken(this.options.code);
};

/**
Expand Down Expand Up @@ -84,12 +84,12 @@ var _getProperty = function(obj, key){
return cursor;
};

var _getCodeToken = function(code){
function getCodeToken(code){
var arr = [];

if (Array.isArray(code)){
code.forEach(function(item){
arr = arr.concat(_getCodeToken(item));
arr = arr.concat(getCodeToken(item));
});
} else if (code){
var split = code.split('-');
Expand All @@ -102,7 +102,7 @@ var _getCodeToken = function(code){
}

return arr;
};
}

/**
* Parses the language code.
Expand All @@ -112,7 +112,7 @@ var _getCodeToken = function(code){
* @return {Array}
*/
i18n.prototype._parseCode = function(code){
var arr = [].concat(_getCodeToken(code), this.options.code);
var arr = [].concat(getCodeToken(code), this.options.code);

if (arr.indexOf('default') === -1){
arr.push('default');
Expand Down Expand Up @@ -206,3 +206,5 @@ i18n.prototype._p = function(code){

return _p;
};

module.exports = i18n;
2 changes: 2 additions & 0 deletions test/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -9,5 +9,7 @@ describe('Hexo', function(){
require('./scripts/processors');
require('./scripts/renderers');
require('./scripts/tags');
require('./scripts/theme');
require('./scripts/theme_processors')
require('./scripts/util');
});
4 changes: 4 additions & 0 deletions test/scripts/box/file.js
Original file line number Diff line number Diff line change
Expand Up @@ -187,7 +187,11 @@ describe('File', function(){
});
});

it('render() - use cache');

it('renderSync()', function(){
file.renderSync().should.eql(obj);
});

it('renderSync() - use cache');
});

0 comments on commit 6db7562

Please sign in to comment.