diff --git a/config.js b/config.js
index c73733de8244..699df2520f51 100644
--- a/config.js
+++ b/config.js
@@ -11,10 +11,7 @@ config.defaultLang = 'en';
// Force i18n to be on
config.forceI18n = true;
-// ## Themes & Plugins
-
-// Current active theme
-config.activeTheme = 'casper';
+// ## Plugins
// Current active plugins
config.activePlugins = [
diff --git a/core/client/models/settings.js b/core/client/models/settings.js
index dc1ea5ef84d5..31f1c7000a27 100644
--- a/core/client/models/settings.js
+++ b/core/client/models/settings.js
@@ -4,7 +4,7 @@
// Set the url manually and id to '0' to force PUT requests
Ghost.Models.Settings = Backbone.Model.extend({
- url: '/api/v0.1/settings/',
+ url: Ghost.settings.apiRoot + '/settings',
id: "0",
defaults: {
title: 'My Blog',
diff --git a/core/client/models/themes.js b/core/client/models/themes.js
new file mode 100644
index 000000000000..47549b758d4a
--- /dev/null
+++ b/core/client/models/themes.js
@@ -0,0 +1,9 @@
+/*global window, document, Ghost, $, _, Backbone */
+(function () {
+ "use strict";
+
+ Ghost.Models.Themes = Backbone.Model.extend({
+ url: Ghost.settings.apiRoot + '/themes'
+ });
+
+}());
\ No newline at end of file
diff --git a/core/client/tpl/settings/general.hbs b/core/client/tpl/settings/general.hbs
index 7846eb09c9f2..ffbb06709af3 100644
--- a/core/client/tpl/settings/general.hbs
+++ b/core/client/tpl/settings/general.hbs
@@ -50,6 +50,15 @@
+
+
+
+
+
diff --git a/core/client/views/settings.js b/core/client/views/settings.js
index 92c488672707..640c93a6f201 100644
--- a/core/client/views/settings.js
+++ b/core/client/views/settings.js
@@ -41,7 +41,8 @@
showContent: function (id) {
var self = this,
- model;
+ model,
+ themes;
Ghost.router.navigate('/settings/' + id);
Ghost.trigger('urlchange');
@@ -53,9 +54,13 @@
this.pane = new Settings[id]({ el: '.settings-content'});
if (!this.models.hasOwnProperty(this.pane.options.modelType)) {
+ themes = this.models.Themes = new Ghost.Models.Themes();
model = this.models[this.pane.options.modelType] = new Ghost.Models[this.pane.options.modelType]();
- model.fetch().then(function () {
- self.renderPane(model);
+ themes.fetch().then(function () {
+ model.fetch().then(function () {
+ model.set({availableThemes: themes.toJSON()});
+ self.renderPane(model);
+ });
});
} else {
model = this.models[this.pane.options.modelType];
@@ -134,12 +139,13 @@
},
saveSettings: function () {
+ this.model.unset('availableThemes');
this.model.save({
title: this.$('#blog-title').val(),
email: this.$('#email-address').val(),
logo: this.$('#logo').attr("src"),
- icon: this.$('#icon').attr("src")
-
+ icon: this.$('#icon').attr("src"),
+ activeTheme: this.$('#activeTheme').val()
}, {
success: this.saveSuccess,
error: this.saveError
diff --git a/core/ghost.js b/core/ghost.js
index 0c72de771daf..a90a595195d5 100644
--- a/core/ghost.js
+++ b/core/ghost.js
@@ -111,7 +111,7 @@ Ghost = function () {
'appRoot': appRoot,
'themePath': themePath,
'pluginPath': pluginPath,
- 'activeTheme': path.join(themePath, config.activeTheme),
+ 'activeTheme': path.join(themePath, !instance.settingsCache ? "" : instance.settingsCache.activeTheme),
'adminViews': path.join(appRoot, '/core/server/views/'),
'helperTemplates': path.join(appRoot, '/core/server/helpers/tpl/'),
'lang': path.join(appRoot, '/core/shared/lang/'),
@@ -168,6 +168,17 @@ Ghost.prototype.updateSettingsCache = function (settings) {
var settings = {};
_.map(result.models, function (member) {
if (!settings.hasOwnProperty(member.attributes.key)) {
+ if (member.attributes.key === 'activeTheme') {
+ member.attributes.value = member.attributes.value.substring(member.attributes.value.lastIndexOf('/') + 1);
+ var settingsThemePath = path.join(themePath, member.attributes.value);
+ fs.exists(settingsThemePath, function (exists) {
+ if (!exists) {
+ member.attributes.value = "casper";
+ }
+ settings[member.attributes.key] = member.attributes.value;
+ });
+ return;
+ }
settings[member.attributes.key] = member.attributes.value;
}
});
diff --git a/core/server/api.js b/core/server/api.js
index 6c9e38a658a8..a88c3946ac0c 100644
--- a/core/server/api.js
+++ b/core/server/api.js
@@ -14,6 +14,7 @@ var Ghost = require('../ghost'),
users,
notifications,
settings,
+ themes,
requestHandler,
cachedSettingsRequestHandler,
settingsObject,
@@ -247,6 +248,39 @@ settings = {
}
};
+// ## Themes
+
+themes = {
+ // #### Browse
+
+ // **takes:** options object
+ browse: function browse() {
+ // **returns:** a promise for a themes json object
+ return when(ghost.paths().availableThemes).then(function (themes) {
+ var themeKeys = Object.keys(themes),
+ res = [],
+ i,
+ activeTheme = ghost.paths().activeTheme.substring(ghost.paths().activeTheme.lastIndexOf('/') + 1),
+ item;
+
+ for (i = 0; i < themeKeys.length; i += 1) {
+ //do not include hidden files
+ if (themeKeys[i].indexOf('.') !== 0) {
+ item = {};
+ item.name = themeKeys[i];
+ item.details = themes[themeKeys[i]];
+ if (themeKeys[i] === activeTheme) {
+ item.active = true;
+ }
+ res.push(item);
+ }
+ }
+ return res;
+ });
+ }
+};
+
+
// ## Request Handlers
// ### requestHandler
@@ -308,5 +342,6 @@ module.exports.posts = posts;
module.exports.users = users;
module.exports.notifications = notifications;
module.exports.settings = settings;
+module.exports.themes = themes;
module.exports.requestHandler = requestHandler;
module.exports.cachedSettingsRequestHandler = cachedSettingsRequestHandler;
diff --git a/core/server/views/default.hbs b/core/server/views/default.hbs
index 9100a93db5ea..38d7091ce03a 100644
--- a/core/server/views/default.hbs
+++ b/core/server/views/default.hbs
@@ -80,6 +80,7 @@
+
diff --git a/index.js b/index.js
index 6248be0fd806..d234f4287608 100644
--- a/index.js
+++ b/index.js
@@ -199,6 +199,8 @@ when.all([ghost.init(), filters.loadCoreFilters(ghost), helpers.loadCoreHelpers(
ghost.app().get('/api/v0.1/settings', authAPI, disableCachedResult, api.cachedSettingsRequestHandler(api.settings.browse));
ghost.app().get('/api/v0.1/settings/:key', authAPI, disableCachedResult, api.cachedSettingsRequestHandler(api.settings.read));
ghost.app().put('/api/v0.1/settings', authAPI, disableCachedResult, api.cachedSettingsRequestHandler(api.settings.edit));
+ // #### Themes
+ ghost.app().get('/api/v0.1/themes', authAPI, disableCachedResult, api.requestHandler(api.themes.browse));
// #### Users
ghost.app().get('/api/v0.1/users', authAPI, disableCachedResult, api.requestHandler(api.users.browse));
ghost.app().get('/api/v0.1/users/:id', authAPI, disableCachedResult, api.requestHandler(api.users.read));