diff --git a/core/ghost.js b/core/ghost.js index 81f7d093a4..1e58a993ac 100644 --- a/core/ghost.js +++ b/core/ghost.js @@ -97,6 +97,18 @@ Ghost = function () { // there's no management here to be sure this has loaded settings: function () { return instance.settingsCache; }, dataProvider: models, + blogGlobals: function () { + /* this is a bit of a hack until we have a better way to combine settings and config + * this data is what becomes globally available to themes */ + return { + url: instance.config().env[process.env.NODE_ENV].url, + title: instance.settings().title, + description: instance.settings().description, + logo: instance.settings().logo, + /* urg.. need to fix paths */ + themedir: path.join('/content/themes', instance.paths().activeTheme, instance.settingsCache.activeTheme) + }; + }, statuses: function () { return statuses; }, polyglot: function () { return polyglot; }, getPaths: function () { @@ -296,27 +308,29 @@ Ghost.prototype.initPlugins = function (pluginsToLoad) { // Initialise Theme or admin Ghost.prototype.initTheme = function (app) { - var self = this; + var self = this, + hbsOptions; return function initTheme(req, res, next) { app.set('view engine', 'hbs'); // return the correct mime type for woff files express['static'].mime.define({'application/font-woff': ['woff']}); if (!res.isAdmin) { + + // self.globals is a hack til we have a better way of getting combined settings & config + hbsOptions = {templateOptions: {data: {blog: self.blogGlobals()}}}; + if (!self.themeDirectories.hasOwnProperty(self.settings().activeTheme)) { // Throw an error if the theme is not available... // TODO: move this to happen on app start errors.logAndThrowError('The currently active theme ' + self.settings().activeTheme + ' is missing.'); } else if (self.themeDirectories[self.settings().activeTheme].hasOwnProperty('partials')) { // Check that the theme has a partials directory before trying to use it - app.engine('hbs', hbs.express3( - {partialsDir: path.join(self.paths().activeTheme, 'partials')} - )); - } else { - // No partial dir, so no need to configure it - app.engine('hbs', hbs.express3()); + hbsOptions.partialsDir = path.join(self.paths().activeTheme, 'partials'); } + app.engine('hbs', hbs.express3(hbsOptions)); + app.set('views', self.paths().activeTheme); } else { app.engine('hbs', hbs.express3({partialsDir: self.paths().adminViews + 'partials'})); diff --git a/core/server/helpers/index.js b/core/server/helpers/index.js index 485717f773..c168090e5e 100644 --- a/core/server/helpers/index.js +++ b/core/server/helpers/index.js @@ -20,9 +20,22 @@ coreHelpers = function (ghost) { * @return {Object} A Moment time / date object */ ghost.registerThemeHelper('date', function (context, options) { + if (!options && context.hasOwnProperty('hash')) { + options = context; + context = undefined; + + // set to published_at by default, if it's available + // otherwise, this will print the current date + if (this.published_at) { + context = this.published_at; + } + } + var f = options.hash.format || "MMM Do, YYYY", timeago = options.hash.timeago, date; + + if (timeago) { date = moment(context).fromNow(); } else { @@ -31,11 +44,25 @@ coreHelpers = function (ghost) { return date; }); + // ### URL helper + // + // *Usage example:* + // `{{url}}` + // `{{url absolute}}` + // + // Returns the URL for the current object context + // i.e. If inside a post context will return post permalink + // absolute flag outputs absolute URL, else URL is relative ghost.registerThemeHelper('url', function (context, options) { - if (models.isPost(this)) { - return "/" + this.slug; + var output = ''; + + if (options && options.absolute) { + output += ghost.config().env[process.NODE_ENV].url; } - return ''; + if (models.isPost(this)) { + output += "/" + this.slug; + } + return output; }); // ### Author Helper diff --git a/core/server/models/user.js b/core/server/models/user.js index 9ff72ab6f9..f5465e5f9b 100644 --- a/core/server/models/user.js +++ b/core/server/models/user.js @@ -45,6 +45,20 @@ User = GhostBookshelf.Model.extend({ }; }, + parse: function (attrs) { + // temporary alias of name for full_name (will get changed in the schema) + if (attrs.full_name && !attrs.name) { + attrs.name = attrs.full_name; + } + + // temporary alias of website for url (will get changed in the schema) + if (attrs.url && !attrs.website) { + attrs.website = attrs.url; + } + + return attrs; + }, + initialize: function () { this.on('saving', this.saving, this); this.on('saving', this.validate, this); diff --git a/index.js b/index.js index 5e5441729f..f0a39b9919 100644 --- a/index.js +++ b/index.js @@ -108,10 +108,8 @@ function ghostLocals(req, res, next) { if (!res.isAdmin) { // filter the navigation items ghost.doFilter('ghostNavItems', {path: req.path, navItems: []}, function (navData) { - // pass the theme navigation items and settings - _.extend(res.locals, navData, { - settings: ghost.settings() - }); + // pass the theme navigation items, settings get configured as globals + _.extend(res.locals, navData); next(); }); diff --git a/package.json b/package.json index d3c28225d2..a765fc0d04 100644 --- a/package.json +++ b/package.json @@ -12,7 +12,7 @@ "engineStrict": true, "dependencies": { "express": "3.3.4", - "express-hbs": "0.2.0", + "express-hbs": "0.2.1", "node-polyglot": "0.2.1", "moment": "2.1.0", "underscore": "1.5.1",