+
+
\ No newline at end of file
diff --git a/core/client/tpl/settings/content.hbs b/core/client/tpl/settings/content.hbs
new file mode 100644
index 0000000000..ee6b163809
--- /dev/null
+++ b/core/client/tpl/settings/content.hbs
@@ -0,0 +1,69 @@
+
+
Content
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/core/client/tpl/settings/general.hbs b/core/client/tpl/settings/general.hbs
new file mode 100644
index 0000000000..0a89daf1bb
--- /dev/null
+++ b/core/client/tpl/settings/general.hbs
@@ -0,0 +1,60 @@
+
+
General
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/core/client/tpl/settings/plugins.hbs b/core/client/tpl/settings/plugins.hbs
new file mode 100644
index 0000000000..fc4b3c7a23
--- /dev/null
+++ b/core/client/tpl/settings/plugins.hbs
@@ -0,0 +1,241 @@
+
+
+
Plugins
+
+
+
+
+
+
+
+
Updates
+
+
+
+
+
+
+
+
+
+ Ghost SEO
+
+
+
+
+
+
+
+ Yoast
+ yoast.com
+
+
+
+
+ v 0.1.13
+ 3 weeks ago
+
+
+
+
+
+
+
+
+
+
+
+ 48,200 users
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ Ghost SEO
+ The #1 content marketing plugin for Ghost.
+
+
+
+
+ Yoast
+ yoast.com
+
+
+
+
+ v 0.1.13
+ 3 weeks ago
+
+
+
+
+
+
+
+
+
+
+
+ 48,200 users
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
Active Plugins
+
+
+
+
+
+
+
+
+
+ Ghost SEO
+ The #1 content marketing plugin for Ghost.
+
+
+
+
+ Yoast
+ yoast.com
+
+
+
+
+ v 0.1.13
+ 3 weeks ago
+
+
+
+
+
+
+
+
+
+
+
+ 48,200 users
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ Ghost SEO
+ The #1 content marketing plugin for Ghost.
+
+
+
+
+ Yoast
+ yoast.com
+
+
+
+
+ v 0.1.13
+ 3 weeks ago
+
+
+
+
+
+
+
+
+
+
+
+ 48,200 users
+
+
+
+
+
+
+
+
+
+
+
+
+
+
Inactive Plugins
+
+
+
+
+
+
+
+
+
+ Ghost SEO
+ The #1 content marketing plugin for Ghost.
+
+
+
+
+ Yoast
+ yoast.com
+
+
+
+
+ v 0.1.13
+ 3 weeks ago
+
+
+
+
+
+
+
+
+
+
+
+ 48,200 users
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/core/client/tpl/settings/sidebar.hbs b/core/client/tpl/settings/sidebar.hbs
new file mode 100644
index 0000000000..35886d3bbb
--- /dev/null
+++ b/core/client/tpl/settings/sidebar.hbs
@@ -0,0 +1,9 @@
+
+
Settings
+
+
\ No newline at end of file
diff --git a/core/client/tpl/settings/users.hbs b/core/client/tpl/settings/users.hbs
new file mode 100644
index 0000000000..ae3ef9629a
--- /dev/null
+++ b/core/client/tpl/settings/users.hbs
@@ -0,0 +1,57 @@
+
+
+
Users
+
+
+
+
+
+
+
Invited Users
+
+
+
+
+
Some Name
+ Invitation Sent: 7 hours ago
+
+
+
+
+
+
+
Active Users
+
+
+
+
+
+
+
+
+
+
+
Some Name
+ Last Seen: 7 hours ago
+
+ Admin
+
+
+
+
+
+
+
Some Name
+ Last Seen: 2 days ago
+
+ Editor
+
+
+
+
+
\ No newline at end of file
diff --git a/core/client/views/base.js b/core/client/views/base.js
index 2613e69dd8..19dbaa9610 100644
--- a/core/client/views/base.js
+++ b/core/client/views/base.js
@@ -2,7 +2,41 @@
(function () {
"use strict";
- Ghost.View = Backbone.View.extend({
+ Ghost.TemplateView = Backbone.View.extend({
+ templateName: "widget",
+
+ template: function (data) {
+ return JST[this.templateName](data);
+ },
+
+ templateData: function () {
+ if (this.model) {
+ return this.model.toJSON();
+ }
+
+ if (this.collection) {
+ return this.collection.toJSON();
+ }
+
+ return {};
+ },
+
+ render: function () {
+ if (_.isFunction(this.beforeRender)) {
+ this.beforeRender();
+ }
+
+ this.$el.html(this.template(this.templateData()));
+
+ if (_.isFunction(this.afterRender)) {
+ this.afterRender();
+ }
+
+ return this;
+ }
+ });
+
+ Ghost.View = Ghost.TemplateView.extend({
// Adds a subview to the current view, which will
// ensure its removal when this view is removed,
@@ -42,36 +76,6 @@
});
- Ghost.TemplateView = Ghost.View.extend({
- templateName: "widget",
-
- template: function (data) {
- return JST[this.templateName](data);
- },
-
- templateData: function () {
- if (this.model) {
- return this.model.toJSON();
- }
-
- if (this.collection) {
- return this.collection.toJSON();
- }
-
- return {};
- },
-
- render: function () {
- this.$el.html(this.template(this.templateData()));
-
- if (_.isFunction(this.afterRender)) {
- this.afterRender();
- }
-
- return this;
- }
- });
-
/**
* This is the view to generate the markup for the individual
* notification. Will be included into #flashbar.
diff --git a/core/client/views/blog.js b/core/client/views/blog.js
index 93b93e445a..9c9d4d8789 100644
--- a/core/client/views/blog.js
+++ b/core/client/views/blog.js
@@ -111,15 +111,9 @@
templateName: "list-item",
- template: function (data) {
- return JST[this.templateName](data);
- },
-
- render: function () {
- this.$el.html(this.template(_.extend({active: this.active}, this.model.toJSON())));
- return this;
+ templateData: function () {
+ return _.extend({active: this.active}, this.model.toJSON());
}
-
});
// Content preview
@@ -182,14 +176,10 @@
templateName: "preview",
- template: function (data) {
- return JST[this.templateName](data);
- },
-
render: function () {
if (this.activeId) {
this.model = this.collection.get(this.activeId);
- this.$el.html(this.template(this.model.toJSON()));
+ this.$el.html(this.template(this.templateData()));
}
this.$('.wrapper').on('click', 'a', function (e) {
$(e.currentTarget).attr('target', '_blank');
@@ -200,4 +190,4 @@
});
-}());
+}());
\ No newline at end of file
diff --git a/core/client/views/dashboard.js b/core/client/views/dashboard.js
index ce3bc8e36d..f284ce87e3 100644
--- a/core/client/views/dashboard.js
+++ b/core/client/views/dashboard.js
@@ -137,12 +137,7 @@
templateName: "widget",
- template: function (data) {
- return JST[this.templateName](data);
- },
-
- render: function () {
- this.$el.html(this.template(this.model.toJSON()));
+ afterRender: function () {
if (!this.model.attributes.settings.enabled) {
this.$(".widget-content").html(this.addSubview(new WidgetContent({model: this.model})).render().el);
} else {
@@ -160,11 +155,6 @@
template: function (data) {
return JST['widgets/' + this.model.attributes.content.template](data);
- },
-
- render: function () {
- this.$el.html(this.template(this.model.toJSON()));
- return this;
}
});
diff --git a/core/client/views/editor.js b/core/client/views/editor.js
index efa8918305..3aa6f64594 100644
--- a/core/client/views/editor.js
+++ b/core/client/views/editor.js
@@ -41,14 +41,16 @@
initialize: function () {
this.addSubview(new TagWidget({el: this.$('#entry-categories'), model: this.model})).render();
this.addSubview(new ActionsWidget({el: this.$('#entry-actions'), model: this.model})).render();
- }
+ },
+
+ render: function () { return this; }
});
// The Tag UI area associated with a post
// ----------------------------------------
TagWidget = Ghost.View.extend({
-
+ render: function () { return this; }
});
// The Publish, Queue, Publish Now buttons
@@ -372,9 +374,9 @@
}
}
}));
- }
+ },
+
+ render: function () { return this; }
});
-
-
}());
diff --git a/core/client/views/login.js b/core/client/views/login.js
index dfa369549a..fc11162346 100644
--- a/core/client/views/login.js
+++ b/core/client/views/login.js
@@ -15,13 +15,8 @@
$(window).trigger('resize');
},
- template: function (data) {
- return JST[this.templateName](data);
- },
-
- render: function () {
+ afterRender: function () {
var self = this;
- this.$el.html(this.template());
$(window).on('resize', _.debounce(function (e) {
$(".js-login-container").center();
@@ -78,15 +73,6 @@
this.render();
},
- template: function (data) {
- return JST[this.templateName](data);
- },
-
- render: function () {
- this.$el.html(this.template());
- return this;
- },
-
submitHandler: function (event) {
event.preventDefault();
var email = this.$el.find('.email').val(),
diff --git a/core/client/views/settings.js b/core/client/views/settings.js
index 1e5d5ec1a1..b0ad123c05 100644
--- a/core/client/views/settings.js
+++ b/core/client/views/settings.js
@@ -25,6 +25,7 @@
// ---------------
Settings.Sidebar = Ghost.View.extend({
initialize: function (options) {
+ this.render();
this.menu = this.$('.settings-menu');
this.showContent(options.pane || 'general');
},
@@ -42,19 +43,21 @@
showContent: function (id) {
Backbone.history.navigate('/settings/' + id);
- if (this.pane && '#' + id === this.pane.el) {
+ if (this.pane && id === this.pane.el.id) {
return;
}
_.result(this.pane, 'destroy');
this.setActive(id);
- this.pane = new Settings[id]({ model: this.model });
+ this.pane = new Settings[id]({ el: '.settings-content', model: this.model });
this.pane.render();
},
setActive: function (id) {
this.menu.find('li').removeClass('active');
this.menu.find('a[href=#' + id + ']').parent().addClass('active');
- }
+ },
+
+ templateName: 'settings/sidebar'
});
// Content panes
@@ -65,17 +68,18 @@
this.undelegateEvents();
},
- render: function () {
+ afterRender: function () {
+ this.$el.attr('id', this.id);
this.$el.addClass('active');
}
});
- // TODO: render templates on the client
// TODO: use some kind of data-binding for forms
// ### General settings
Settings.general = Settings.Pane.extend({
- el: '#general',
+ id: "general",
+
events: {
'click .button-save': 'saveSettings'
},
@@ -107,26 +111,28 @@
});
},
- render: function () {
+ templateName: 'settings/general',
+
+ beforeRender: function () {
var settings = this.model.toJSON();
this.$('#blog-title').val(settings.title);
this.$('#email-address').val(settings.email);
- Settings.Pane.prototype.render.call(this);
}
});
// ### Content settings
Settings.content = Settings.Pane.extend({
- el: '#content',
+ id: 'content',
events: {
'click .button-save': 'saveSettings'
},
saveSettings: function () {
+ var self = this;
this.model.save({
description: this.$('#blog-description').val()
}, {
success: function () {
- this.addSubview(new Ghost.Views.NotificationCollection({
+ self.addSubview(new Ghost.Views.NotificationCollection({
model: [{
type: 'success',
message: 'Saved',
@@ -136,7 +142,7 @@
},
error: function () {
- this.addSubview(new Ghost.Views.NotificationCollection({
+ self.addSubview(new Ghost.Views.NotificationCollection({
model: [{
type: 'error',
message: 'Something went wrong, not saved :(',
@@ -147,10 +153,11 @@
});
},
- render: function () {
+ templateName: 'settings/content',
+
+ beforeRender: function () {
var settings = this.model.toJSON();
this.$('#blog-description').val(settings.description);
- Settings.Pane.prototype.render.call(this);
}
});
diff --git a/core/server/views/settings.hbs b/core/server/views/settings.hbs
index da395afedb..245bdbf553 100644
--- a/core/server/views/settings.hbs
+++ b/core/server/views/settings.hbs
@@ -1,444 +1,8 @@
{{!< default}}
-
-
-
General
-
-
-
-
-
- {{#with settings}}
-
-
-
-
-
-
-
Content
-
-
-
-
-
-
-
-
-
-
-
-
Users
-
-
-
-
-
-
-
Invited Users
-
-
-
-
-
Some Name
- Invitation Sent: 7 hours ago
-
-
-
-
-
-
-
Active Users
-
-
-
-
-
-
-
-
-
-
-
Some Name
- Last Seen: 7 hours ago
-
- Admin
-
-
-
-
-
-
-
Some Name
- Last Seen: 2 days ago
-
- Editor
-
-
-
-
-
-
-
-
-
Appearance
-
-
-
Raw json be here
-
Active theme: {{json settings.activeTheme}}
-
Available themes: {{json availableThemes}}
-
Available plugins: {{json availablePlugins}}
-
-
-
-
-
-
Plugins
-
-
-
-
-
-
-
-
Updates
-
-
-
-
-
-
-
-
-
- Ghost SEO
-
-
-
-
-
-
-
- Yoast
- yoast.com
-
-
-
-
- v 0.1.13
- 3 weeks ago
-
-
-
-
-
-
-
- 48,200 users
-
-
-
-
-
-
-
-
-
-
-
-
-
-
- Ghost SEO
- The #1 content marketing plugin for Ghost.
-
-
-
-
- Yoast
- yoast.com
-
-
-
-
- v 0.1.13
- 3 weeks ago
-
-
-
-
-
-
-
- 48,200 users
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
Active Plugins
-
-
-
-
-
-
-
-
-
- Ghost SEO
- The #1 content marketing plugin for Ghost.
-
-
-
-
- Yoast
- yoast.com
-
-
-
-
- v 0.1.13
- 3 weeks ago
-
-
-
-
-
-
-
- 48,200 users
-
-
-
-
-
-
-
-
-
-
-
-
-
-
- Ghost SEO
- The #1 content marketing plugin for Ghost.
-
-
-
-
- Yoast
- yoast.com
-
-
-
-
- v 0.1.13
- 3 weeks ago
-
-
-
-
-
-
-
- 48,200 users
-
-
-
-
-
-
-
-
-
-
-
-
-
-
Inactive Plugins
-
-
-
-
-
-
-
-
-
- Ghost SEO
- The #1 content marketing plugin for Ghost.
-
-
-
-
- Yoast
- yoast.com
-
-
-
-
- v 0.1.13
- 3 weeks ago
-
-
-
-
-
-
-
- 48,200 users
-
-
-
-
-
-
-
-
-
-
-
-
-
+
\ No newline at end of file
diff --git a/core/test/functional/admin/04_content_test.js b/core/test/functional/admin/04_content_test.js
index bbc60a5770..281b18dc40 100644
--- a/core/test/functional/admin/04_content_test.js
+++ b/core/test/functional/admin/04_content_test.js
@@ -18,14 +18,14 @@ casper.test.begin("Content screen is correct", 9, function suite(test) {
});
casper.then(function testActiveItem() {
- casper.test.assertEquals(casper.evaluate(function () {
+ casper.test.assertEvalEquals(function () {
return document.querySelector('.content-list-content li').className;
- }), "active", "first item is active");
+ }, "active", "first item is active");
}).thenClick(".content-list-content li:nth-child(2) a", function then() {
- casper.test.assertEquals(casper.evaluate(function () {
+ casper.test.assertEvalEquals(function () {
return document.querySelectorAll('.content-list-content li')[1].className;
- }), "active", "second item is active");
+ }, "active", "second item is active");
});
// TODO: finish testing delete
diff --git a/core/test/functional/admin/05_settings_test.js b/core/test/functional/admin/05_settings_test.js
index 8f41461806..1993be94b2 100644
--- a/core/test/functional/admin/05_settings_test.js
+++ b/core/test/functional/admin/05_settings_test.js
@@ -1,6 +1,6 @@
/*globals casper, __utils__, url */
-casper.test.begin("Settings screen is correct", 3, function suite(test) {
+casper.test.begin("Settings screen is correct", 12, function suite(test) {
casper.test.filename = "settings_test.png";
@@ -11,8 +11,28 @@ casper.test.begin("Settings screen is correct", 3, function suite(test) {
casper.then(function testViews() {
test.assertExists(".wrapper", "Settings main view is present");
+ test.assertExists(".settings-sidebar", "Settings sidebar view is present");
+ test.assertExists(".settings-menu", "Settings menu is present");
+ test.assertExists(".wrapper", "Settings main view is present");
+ test.assertExists(".settings-content", "Settings content view is present");
+ test.assertEval(function testGeneralIsActive() {
+ return document.querySelector('.settings-menu .general').classList.contains('active');
+ }, "general tab is marked active");
+ test.assertEval(function testContentIsGeneral() {
+ return document.querySelector('.settings-content').id === 'general';
+ }, "loaded content is general screen");
+ });
- // TODO: real settings tests
+ casper.thenClick('.settings-menu .publishing', function then() {
+ test.assertEval(function testGeneralIsNotActive() {
+ return !document.querySelector('.settings-menu .general').classList.contains('active');
+ }, "general tab is not marked active");
+ test.assertEval(function testContentIsActive() {
+ return document.querySelector('.settings-menu .publishing').classList.contains('active');
+ }, "content tab is marked active");
+ test.assertEval(function testContentIsContent() {
+ return document.querySelector('.settings-content').id === 'content';
+ }, "loaded content is contentß screen");
});
casper.run(function () {