mirror of
https://github.com/TryGhost/Ghost.git
synced 2024-12-25 20:03:12 +03:00
Merge branch 'pr/119'
Conflicts: core/admin/assets/js/router.js core/admin/views/default.hbs core/admin/views/settings.hbs core/shared/data/fixtures/001.js
This commit is contained in:
commit
b3775feba0
2
app.js
2
app.js
@ -138,7 +138,7 @@
|
|||||||
ghost.app().get('/ghost/editor/:id', auth, admin.editor);
|
ghost.app().get('/ghost/editor/:id', auth, admin.editor);
|
||||||
ghost.app().get('/ghost/editor', auth, admin.editor);
|
ghost.app().get('/ghost/editor', auth, admin.editor);
|
||||||
ghost.app().get('/ghost/content', auth, admin.content);
|
ghost.app().get('/ghost/content', auth, admin.content);
|
||||||
ghost.app().get('/ghost/settings', auth, admin.settings);
|
ghost.app().get('/ghost/settings*', auth, admin.settings);
|
||||||
ghost.app().get('/ghost/debug', auth, admin.debug.index);
|
ghost.app().get('/ghost/debug', auth, admin.debug.index);
|
||||||
ghost.app().get('/ghost/debug/db/delete/', auth, admin.debug.dbdelete);
|
ghost.app().get('/ghost/debug/db/delete/', auth, admin.debug.dbdelete);
|
||||||
ghost.app().get('/ghost/debug/db/populate/', auth, admin.debug.dbpopulate);
|
ghost.app().get('/ghost/debug/db/populate/', auth, admin.debug.dbpopulate);
|
||||||
|
@ -21,45 +21,14 @@
|
|||||||
router: null
|
router: null
|
||||||
};
|
};
|
||||||
|
|
||||||
Ghost.View = Backbone.View.extend({
|
Ghost.init = function () {
|
||||||
|
Ghost.router = new Ghost.Router();
|
||||||
// Adds a subview to the current view, which will
|
Backbone.history.start({
|
||||||
// ensure its removal when this view is removed,
|
pushState: true,
|
||||||
// or when view.removeSubviews is called
|
hashChange: false,
|
||||||
addSubview: function (view) {
|
root: '/ghost'
|
||||||
if (!(view instanceof Backbone.View)) {
|
|
||||||
throw new Error("Subview must be a Backbone.View");
|
|
||||||
}
|
|
||||||
this.subviews = this.subviews || [];
|
|
||||||
this.subviews.push(view);
|
|
||||||
return view;
|
|
||||||
},
|
|
||||||
|
|
||||||
// Removes any subviews associated with this view
|
|
||||||
// by `addSubview`, which will in-turn remove any
|
|
||||||
// children of those views, and so on.
|
|
||||||
removeSubviews: function () {
|
|
||||||
var i, l, children = this.subviews;
|
|
||||||
if (!children) {
|
|
||||||
return this;
|
|
||||||
}
|
|
||||||
for (i = 0, l = children.length; i < l; i += 1) {
|
|
||||||
children[i].remove();
|
|
||||||
}
|
|
||||||
this.subviews = [];
|
|
||||||
return this;
|
|
||||||
},
|
|
||||||
|
|
||||||
// Extends the view's remove, by calling `removeSubviews`
|
|
||||||
// if any subviews exist.
|
|
||||||
remove: function () {
|
|
||||||
if (this.subviews) {
|
|
||||||
this.removeSubviews();
|
|
||||||
}
|
|
||||||
return Backbone.View.prototype.remove.apply(this, arguments);
|
|
||||||
}
|
|
||||||
|
|
||||||
});
|
});
|
||||||
|
};
|
||||||
|
|
||||||
window.Ghost = Ghost;
|
window.Ghost = Ghost;
|
||||||
|
|
||||||
|
16
core/admin/assets/js/models/settings.js
Normal file
16
core/admin/assets/js/models/settings.js
Normal file
@ -0,0 +1,16 @@
|
|||||||
|
/*global window, document, Ghost, $, Backbone, _ */
|
||||||
|
(function () {
|
||||||
|
"use strict";
|
||||||
|
|
||||||
|
// Set the url manually and id to '0' to force PUT requests
|
||||||
|
Ghost.Models.Settings = Backbone.Model.extend({
|
||||||
|
url: '/api/v0.1/settings/',
|
||||||
|
id: "0",
|
||||||
|
defaults: {
|
||||||
|
title: 'My Blog',
|
||||||
|
description: '',
|
||||||
|
email: 'admin@tryghost.org'
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
}());
|
@ -8,10 +8,39 @@
|
|||||||
routes: {
|
routes: {
|
||||||
'' : 'dashboard',
|
'' : 'dashboard',
|
||||||
'content/' : 'blog',
|
'content/' : 'blog',
|
||||||
'editor': 'editor',
|
'settings/' : 'settings',
|
||||||
|
'settings(/:pane)' : 'settings',
|
||||||
'editor/' : 'editor',
|
'editor/' : 'editor',
|
||||||
'editor/:id': 'editor'
|
'editor(/:id)' : 'editor'
|
||||||
},
|
},
|
||||||
|
|
||||||
|
blog: function () {
|
||||||
|
var posts = new Ghost.Collections.Posts();
|
||||||
|
posts.fetch({ data: { status: 'all' } }).then(function () {
|
||||||
|
Ghost.currentView = new Ghost.Views.Blog({ el: '#main', collection: posts });
|
||||||
|
});
|
||||||
|
},
|
||||||
|
|
||||||
|
settings: function (pane) {
|
||||||
|
var settings = new Ghost.Models.Settings();
|
||||||
|
settings.fetch().then(function () {
|
||||||
|
Ghost.currentView = new Ghost.Views.Settings({ el: '#main', model: settings, pane: pane });
|
||||||
|
});
|
||||||
|
},
|
||||||
|
|
||||||
|
editor: function (id) {
|
||||||
|
var post = new Ghost.Models.Post();
|
||||||
|
post.urlRoot = Ghost.settings.apiRoot + '/posts';
|
||||||
|
if (id) {
|
||||||
|
post.id = id;
|
||||||
|
post.fetch().then(function () {
|
||||||
|
Ghost.currentView = new Ghost.Views.Editor({ el: '#main', model: post });
|
||||||
|
});
|
||||||
|
} else {
|
||||||
|
Ghost.currentView = new Ghost.Views.Editor({ el: '#main', model: post });
|
||||||
|
}
|
||||||
|
},
|
||||||
|
|
||||||
dashboard: function () {
|
dashboard: function () {
|
||||||
var widgets = new Ghost.Collections.Widgets();
|
var widgets = new Ghost.Collections.Widgets();
|
||||||
|
|
||||||
@ -418,36 +447,9 @@
|
|||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
//widgets.fetch().then(function () {
|
//widgets.fetch().then(function () {
|
||||||
Ghost.currentView = new Ghost.Views.Dashboard({ el: '#main', collection: widgets });
|
Ghost.currentView = new Ghost.Views.Dashboard({ el: '#main', collection: widgets });
|
||||||
//});
|
//});
|
||||||
},
|
|
||||||
|
|
||||||
blog: function () {
|
|
||||||
var posts = new Ghost.Collections.Posts();
|
|
||||||
posts.fetch({data: {status: 'all'}}).then(function () {
|
|
||||||
Ghost.currentView = new Ghost.Views.Blog({ el: '#main', collection: posts });
|
|
||||||
});
|
|
||||||
|
|
||||||
},
|
|
||||||
|
|
||||||
editor: function (id) {
|
|
||||||
var post = new Ghost.Models.Post();
|
|
||||||
post.urlRoot = Ghost.settings.apiRoot + '/posts';
|
|
||||||
if (id) {
|
|
||||||
post.id = id;
|
|
||||||
post.fetch().then(function () {
|
|
||||||
Ghost.currentView = new Ghost.Views.Editor({ el: '#main', model: post });
|
|
||||||
});
|
|
||||||
} else {
|
|
||||||
Ghost.currentView = new Ghost.Views.Editor({ el: '#main', model: post });
|
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
});
|
});
|
||||||
|
|
||||||
}());
|
}());
|
@ -1,60 +0,0 @@
|
|||||||
/*globals document, location, jQuery */
|
|
||||||
(function ($) {
|
|
||||||
"use strict";
|
|
||||||
|
|
||||||
var changePage = function (e) {
|
|
||||||
var newPage = $(this).children('a').attr('href');
|
|
||||||
|
|
||||||
e.preventDefault();
|
|
||||||
$('.settings-menu .active').removeClass('active');
|
|
||||||
location.hash = $(this).attr('class'); // Placed here so never gets given the active attribute.
|
|
||||||
$(this).addClass('active');
|
|
||||||
|
|
||||||
$('.settings-content').fadeOut().delay(250);
|
|
||||||
$(newPage).fadeIn();
|
|
||||||
|
|
||||||
},
|
|
||||||
|
|
||||||
defaultSettings = {
|
|
||||||
title: 'My Blog',
|
|
||||||
description: ''
|
|
||||||
},
|
|
||||||
|
|
||||||
getSettings = function () {
|
|
||||||
return $.extend(defaultSettings, {
|
|
||||||
title : $('#blog-title').val(),
|
|
||||||
description : $('#blog-description').val()
|
|
||||||
});
|
|
||||||
};
|
|
||||||
|
|
||||||
$(document).ready(function () {
|
|
||||||
if (location.hash) {
|
|
||||||
var page = $(".settings-menu li." + location.hash.replace('#', '')),
|
|
||||||
newPage = page.children('a').attr('href');
|
|
||||||
$('.settings-menu .active').removeClass('active');
|
|
||||||
page.addClass('active');
|
|
||||||
|
|
||||||
$('.settings-content').hide().delay(250);
|
|
||||||
$(newPage).show();
|
|
||||||
}
|
|
||||||
$('.settings-menu li').on('click', changePage);
|
|
||||||
|
|
||||||
$('input').iCheck({
|
|
||||||
checkboxClass: 'icheckbox_square-grey'
|
|
||||||
});
|
|
||||||
|
|
||||||
$('.button-save').click(function (e) {
|
|
||||||
e.preventDefault();
|
|
||||||
var data = getSettings();
|
|
||||||
$.ajax({
|
|
||||||
method: 'PUT',
|
|
||||||
url: '/api/v0.1/settings',
|
|
||||||
data: data,
|
|
||||||
success: function (res, xhr, c) {
|
|
||||||
console.log(xhr, c);
|
|
||||||
}
|
|
||||||
});
|
|
||||||
});
|
|
||||||
});
|
|
||||||
|
|
||||||
}(jQuery));
|
|
@ -1,15 +0,0 @@
|
|||||||
/*global window, document, Ghost, Backbone, $, _ */
|
|
||||||
(function () {
|
|
||||||
|
|
||||||
"use strict";
|
|
||||||
|
|
||||||
Ghost.router = new Ghost.Router();
|
|
||||||
|
|
||||||
$(function () {
|
|
||||||
|
|
||||||
Backbone.history.start({pushState: true, hashChange: false, root: '/ghost'});
|
|
||||||
|
|
||||||
});
|
|
||||||
|
|
||||||
|
|
||||||
}());
|
|
45
core/admin/assets/js/views/base.js
Normal file
45
core/admin/assets/js/views/base.js
Normal file
@ -0,0 +1,45 @@
|
|||||||
|
/*global window, document, Ghost, Backbone, $, _ */
|
||||||
|
(function () {
|
||||||
|
"use strict";
|
||||||
|
|
||||||
|
Ghost.View = Backbone.View.extend({
|
||||||
|
|
||||||
|
// Adds a subview to the current view, which will
|
||||||
|
// ensure its removal when this view is removed,
|
||||||
|
// or when view.removeSubviews is called
|
||||||
|
addSubview: function (view) {
|
||||||
|
if (!(view instanceof Backbone.View)) {
|
||||||
|
throw new Error("Subview must be a Backbone.View");
|
||||||
|
}
|
||||||
|
this.subviews = this.subviews || [];
|
||||||
|
this.subviews.push(view);
|
||||||
|
return view;
|
||||||
|
},
|
||||||
|
|
||||||
|
// Removes any subviews associated with this view
|
||||||
|
// by `addSubview`, which will in-turn remove any
|
||||||
|
// children of those views, and so on.
|
||||||
|
removeSubviews: function () {
|
||||||
|
var i, l, children = this.subviews;
|
||||||
|
if (!children) {
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
for (i = 0, l = children.length; i < l; i += 1) {
|
||||||
|
children[i].remove();
|
||||||
|
}
|
||||||
|
this.subviews = [];
|
||||||
|
return this;
|
||||||
|
},
|
||||||
|
|
||||||
|
// Extends the view's remove, by calling `removeSubviews`
|
||||||
|
// if any subviews exist.
|
||||||
|
remove: function () {
|
||||||
|
if (this.subviews) {
|
||||||
|
this.removeSubviews();
|
||||||
|
}
|
||||||
|
return Backbone.View.prototype.remove.apply(this, arguments);
|
||||||
|
}
|
||||||
|
|
||||||
|
});
|
||||||
|
|
||||||
|
}());
|
135
core/admin/assets/js/views/settings.js
Normal file
135
core/admin/assets/js/views/settings.js
Normal file
@ -0,0 +1,135 @@
|
|||||||
|
/*global window, document, Ghost, Backbone, $, _, alert */
|
||||||
|
(function () {
|
||||||
|
"use strict";
|
||||||
|
|
||||||
|
var Settings = {};
|
||||||
|
|
||||||
|
// Base view
|
||||||
|
// ----------
|
||||||
|
Ghost.Views.Settings = Ghost.View.extend({
|
||||||
|
initialize: function (options) {
|
||||||
|
this.addSubview(new Settings.Sidebar({
|
||||||
|
el: '.settings-sidebar',
|
||||||
|
pane: options.pane,
|
||||||
|
model: this.model
|
||||||
|
}));
|
||||||
|
|
||||||
|
this.$('input').iCheck({
|
||||||
|
checkboxClass: 'icheckbox_square-grey'
|
||||||
|
});
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
// Sidebar (tabs)
|
||||||
|
// ---------------
|
||||||
|
Settings.Sidebar = Ghost.View.extend({
|
||||||
|
initialize: function (options) {
|
||||||
|
this.menu = this.$('.settings-menu');
|
||||||
|
this.showContent(options.pane || 'general');
|
||||||
|
},
|
||||||
|
|
||||||
|
events: {
|
||||||
|
'click .settings-menu li' : 'switchPane'
|
||||||
|
},
|
||||||
|
|
||||||
|
switchPane: function (e) {
|
||||||
|
e.preventDefault();
|
||||||
|
var item = $(e.currentTarget),
|
||||||
|
id = item.find('a').attr('href').substring(1);
|
||||||
|
this.showContent(id);
|
||||||
|
},
|
||||||
|
|
||||||
|
showContent: function (id) {
|
||||||
|
Backbone.history.navigate('/settings/' + id);
|
||||||
|
if (this.pane && '#' + id === this.pane.el) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
_.result(this.pane, 'destroy');
|
||||||
|
this.setActive(id);
|
||||||
|
this.pane = new Settings[id]({ model: this.model });
|
||||||
|
this.pane.render();
|
||||||
|
},
|
||||||
|
|
||||||
|
setActive: function (id) {
|
||||||
|
this.menu.find('li').removeClass('active');
|
||||||
|
this.menu.find('a[href=#' + id + ']').parent().addClass('active');
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
// Content panes
|
||||||
|
// --------------
|
||||||
|
Settings.Pane = Ghost.View.extend({
|
||||||
|
destroy: function () {
|
||||||
|
this.$el.removeClass('active');
|
||||||
|
},
|
||||||
|
|
||||||
|
render: function () {
|
||||||
|
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',
|
||||||
|
events: {
|
||||||
|
'click .button-save': 'saveSettings'
|
||||||
|
},
|
||||||
|
|
||||||
|
saveSettings: function () {
|
||||||
|
this.model.save({
|
||||||
|
title: this.$('#blog-title').val(),
|
||||||
|
email: this.$('#email-address').val()
|
||||||
|
}, {
|
||||||
|
success: function () {
|
||||||
|
alert('Saved');
|
||||||
|
}
|
||||||
|
});
|
||||||
|
},
|
||||||
|
|
||||||
|
render: 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',
|
||||||
|
events: {
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
// ### User settings
|
||||||
|
Settings.users = Settings.Pane.extend({
|
||||||
|
el: '#users',
|
||||||
|
events: {
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
// ### Appearance settings
|
||||||
|
Settings.appearance = Settings.Pane.extend({
|
||||||
|
el: '#appearance',
|
||||||
|
events: {
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
// ### Services settings
|
||||||
|
Settings.services = Settings.Pane.extend({
|
||||||
|
el: '#services',
|
||||||
|
events: {
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
// ### Plugins settings
|
||||||
|
Settings.plugins = Settings.Pane.extend({
|
||||||
|
el: '#plugins',
|
||||||
|
events: {
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
}());
|
@ -144,8 +144,6 @@
|
|||||||
'settings': function (req, res) {
|
'settings': function (req, res) {
|
||||||
api.settings.browse()
|
api.settings.browse()
|
||||||
.then(function (settings) {
|
.then(function (settings) {
|
||||||
settings = settings.toJSON();
|
|
||||||
settings = _.object(_.pluck(settings, 'key'), _.pluck(settings, 'value'));
|
|
||||||
res.render('settings', {
|
res.render('settings', {
|
||||||
bodyClass: 'settings',
|
bodyClass: 'settings',
|
||||||
adminNav: setSelected(adminNavbar, 'settings'),
|
adminNav: setSelected(adminNavbar, 'settings'),
|
||||||
|
@ -58,12 +58,17 @@
|
|||||||
<!-- // require '/core/admin/assets/js/models/*' -->
|
<!-- // require '/core/admin/assets/js/models/*' -->
|
||||||
<script src="/core/admin/assets/js/models/post.js"></script>
|
<script src="/core/admin/assets/js/models/post.js"></script>
|
||||||
<script src="/core/admin/assets/js/models/widget.js"></script>
|
<script src="/core/admin/assets/js/models/widget.js"></script>
|
||||||
|
<script src="/core/admin/assets/js/models/settings.js"></script>
|
||||||
<!-- // require '/core/admin/assets/js/views/*' -->
|
<!-- // require '/core/admin/assets/js/views/*' -->
|
||||||
|
<script src="/core/admin/assets/js/views/base.js"></script>
|
||||||
<script src="/core/admin/assets/js/views/dashboard.js"></script>
|
<script src="/core/admin/assets/js/views/dashboard.js"></script>
|
||||||
<script src="/core/admin/assets/js/views/blog.js"></script>
|
<script src="/core/admin/assets/js/views/blog.js"></script>
|
||||||
<script src="/core/admin/assets/js/views/editor.js"></script>
|
<script src="/core/admin/assets/js/views/editor.js"></script>
|
||||||
|
<script src="/core/admin/assets/js/views/settings.js"></script>
|
||||||
<script src="/core/admin/assets/js/router.js"></script>
|
<script src="/core/admin/assets/js/router.js"></script>
|
||||||
<script src="/core/admin/assets/js/starter.js"></script>
|
|
||||||
{{{block "bodyScripts"}}}
|
{{{block "bodyScripts"}}}
|
||||||
|
<script>
|
||||||
|
Ghost.init();
|
||||||
|
</script>
|
||||||
</body>
|
</body>
|
||||||
</html>
|
</html>
|
@ -1,7 +1,3 @@
|
|||||||
{{#contentFor 'bodyScripts'}}
|
|
||||||
<script src="/core/admin/assets/js/settings.js"></script>
|
|
||||||
{{/contentFor}}
|
|
||||||
|
|
||||||
{{!< default}}
|
{{!< default}}
|
||||||
<div class="wrapper">
|
<div class="wrapper">
|
||||||
<aside class="settings-sidebar" role="complementary">
|
<aside class="settings-sidebar" role="complementary">
|
||||||
@ -19,6 +15,7 @@
|
|||||||
</ul>
|
</ul>
|
||||||
</nav>
|
</nav>
|
||||||
</aside>
|
</aside>
|
||||||
|
<div class="settings-container">
|
||||||
<section id="general" class="settings-content active">
|
<section id="general" class="settings-content active">
|
||||||
<header>
|
<header>
|
||||||
<h2 class="title">General</h2>
|
<h2 class="title">General</h2>
|
||||||
@ -50,7 +47,7 @@
|
|||||||
|
|
||||||
<label>
|
<label>
|
||||||
<b>Email Address</b>
|
<b>Email Address</b>
|
||||||
<input id="email-address" type="text" value="john@tryghost.org" />
|
<input id="email-address" type="text" value="{{email}}" />
|
||||||
<p>Address to use for <a href="#">admin notifications</a></p>
|
<p>Address to use for <a href="#">admin notifications</a></p>
|
||||||
<label class="checkbox">
|
<label class="checkbox">
|
||||||
<input type="checkbox" value="1" /> Show my email address on my public profile
|
<input type="checkbox" value="1" /> Show my email address on my public profile
|
||||||
@ -209,8 +206,7 @@
|
|||||||
<p>Active theme: {{json settings.activeTheme}}</p>
|
<p>Active theme: {{json settings.activeTheme}}</p>
|
||||||
<p>Available themes: {{json availableThemes}}</p>
|
<p>Available themes: {{json availableThemes}}</p>
|
||||||
<p>Available plugins: {{json availablePlugins}}</p>
|
<p>Available plugins: {{json availablePlugins}}</p>
|
||||||
|
|
||||||
|
|
||||||
</section>
|
</section>
|
||||||
</section>
|
</section>
|
||||||
</div>
|
</div>
|
||||||
|
</div>
|
@ -17,7 +17,9 @@
|
|||||||
posts,
|
posts,
|
||||||
users,
|
users,
|
||||||
settings,
|
settings,
|
||||||
requestHandler;
|
requestHandler,
|
||||||
|
settingsObject,
|
||||||
|
settingsCollection;
|
||||||
|
|
||||||
// # Posts
|
// # Posts
|
||||||
posts = {
|
posts = {
|
||||||
@ -59,15 +61,38 @@
|
|||||||
};
|
};
|
||||||
|
|
||||||
// # Settings
|
// # Settings
|
||||||
|
|
||||||
|
// Turn a settings collection into a single object/hashmap
|
||||||
|
settingsObject = function (settings) {
|
||||||
|
return (settings.toJSON ? settings.toJSON() : settings).reduce(function (res, item) {
|
||||||
|
if (item.toJSON) { item = item.toJSON(); }
|
||||||
|
if (item.key) { res[item.key] = item.value; }
|
||||||
|
return res;
|
||||||
|
}, {});
|
||||||
|
};
|
||||||
|
// Turn an object into a collection
|
||||||
|
settingsCollection = function (settings) {
|
||||||
|
return _.map(settings, function (value, key) {
|
||||||
|
return { key: key, value: value };
|
||||||
|
});
|
||||||
|
};
|
||||||
|
|
||||||
settings = {
|
settings = {
|
||||||
browse: function (options) {
|
browse: function (options) {
|
||||||
return dataProvider.Setting.browse(options);
|
return dataProvider.Settings.browse(options).then(settingsObject);
|
||||||
},
|
},
|
||||||
read: function (options) {
|
read: function (options) {
|
||||||
return dataProvider.Setting.read(options.key);
|
return dataProvider.Settings.read(options.key).then(function (setting) {
|
||||||
|
return _.pick(setting.toJSON(), 'key', 'value');
|
||||||
|
});
|
||||||
},
|
},
|
||||||
edit: function (options) {
|
edit: function (settings) {
|
||||||
return dataProvider.Setting.edit(options);
|
settings = settingsCollection(settings);
|
||||||
|
return dataProvider.Settings.edit(settings).then(settingsObject);
|
||||||
|
},
|
||||||
|
add: function (settings) {
|
||||||
|
settings = settingsCollection(settings);
|
||||||
|
return dataProvider.Settings.add(settings).then(settingsObject);
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -61,6 +61,13 @@ module.exports = {
|
|||||||
"updated_by": 1,
|
"updated_by": 1,
|
||||||
"type": "general"
|
"type": "general"
|
||||||
},
|
},
|
||||||
|
{
|
||||||
|
"key": "email",
|
||||||
|
"value": "john@onolan.org",
|
||||||
|
"created_by": 1,
|
||||||
|
"updated_by": 1,
|
||||||
|
"type": "general"
|
||||||
|
},
|
||||||
{
|
{
|
||||||
"key": "activePlugins",
|
"key": "activePlugins",
|
||||||
"value": "",
|
"value": "",
|
||||||
|
@ -88,7 +88,7 @@
|
|||||||
knex.Schema.createTable('settings', function (t) {
|
knex.Schema.createTable('settings', function (t) {
|
||||||
t.increments().primary();
|
t.increments().primary();
|
||||||
t.string('uuid');
|
t.string('uuid');
|
||||||
t.string('key');
|
t.string('key').unique();
|
||||||
t.text('value');
|
t.text('value');
|
||||||
t.string('type');
|
t.string('type');
|
||||||
t.date('created_at');
|
t.date('created_at');
|
||||||
|
@ -11,7 +11,7 @@
|
|||||||
User: require('./user').User,
|
User: require('./user').User,
|
||||||
Role: require('./role').Role,
|
Role: require('./role').Role,
|
||||||
Permission: require('./permission').Permission,
|
Permission: require('./permission').Permission,
|
||||||
Setting: require('./setting').Setting,
|
Settings: require('./settings').Settings,
|
||||||
init: function () {
|
init: function () {
|
||||||
return knex.Schema.hasTable('posts').then(null, function () {
|
return knex.Schema.hasTable('posts').then(null, function () {
|
||||||
// Simple bootstraping of the data model for now.
|
// Simple bootstraping of the data model for now.
|
||||||
|
@ -1,45 +0,0 @@
|
|||||||
(function () {
|
|
||||||
"use strict";
|
|
||||||
|
|
||||||
var Setting,
|
|
||||||
Settings,
|
|
||||||
GhostBookshelf = require('./base'),
|
|
||||||
_ = require('underscore'),
|
|
||||||
when = require('when');
|
|
||||||
|
|
||||||
Setting = GhostBookshelf.Model.extend({
|
|
||||||
|
|
||||||
tableName: 'settings',
|
|
||||||
|
|
||||||
hasTimestamps: true
|
|
||||||
|
|
||||||
}, {
|
|
||||||
|
|
||||||
read: function (_key) {
|
|
||||||
// Allow for just passing the key instead of attributes
|
|
||||||
if (!_.isObject(_key)) {
|
|
||||||
_key = { key: _key };
|
|
||||||
}
|
|
||||||
return GhostBookshelf.Model.read.call(this, _key);
|
|
||||||
},
|
|
||||||
|
|
||||||
edit: function (_data) {
|
|
||||||
return when.all(_.map(_data, function (value, key) {
|
|
||||||
return this.forge({ key: key }).fetch().then(function (setting) {
|
|
||||||
return setting.set('value', value).save();
|
|
||||||
});
|
|
||||||
}, this));
|
|
||||||
}
|
|
||||||
|
|
||||||
});
|
|
||||||
|
|
||||||
Settings = GhostBookshelf.Collection.extend({
|
|
||||||
model: Setting
|
|
||||||
});
|
|
||||||
|
|
||||||
module.exports = {
|
|
||||||
Setting: Setting,
|
|
||||||
Settings: Settings
|
|
||||||
};
|
|
||||||
|
|
||||||
}());
|
|
42
core/shared/models/settings.js
Normal file
42
core/shared/models/settings.js
Normal file
@ -0,0 +1,42 @@
|
|||||||
|
(function () {
|
||||||
|
"use strict";
|
||||||
|
|
||||||
|
var Settings,
|
||||||
|
GhostBookshelf = require('./base'),
|
||||||
|
_ = require('underscore'),
|
||||||
|
when = require('when');
|
||||||
|
|
||||||
|
// Each setting is saved as a separate row in the database,
|
||||||
|
// but the overlying API treats them as a single key:value mapping
|
||||||
|
Settings = GhostBookshelf.Model.extend({
|
||||||
|
tableName: 'settings',
|
||||||
|
hasTimestamps: true
|
||||||
|
}, {
|
||||||
|
read: function (_key) {
|
||||||
|
// Allow for just passing the key instead of attributes
|
||||||
|
if (!_.isObject(_key)) {
|
||||||
|
_key = { key: _key };
|
||||||
|
}
|
||||||
|
return GhostBookshelf.Model.read.call(this, _key);
|
||||||
|
},
|
||||||
|
|
||||||
|
edit: function (_data) {
|
||||||
|
var settings = this;
|
||||||
|
if (!Array.isArray(_data)) {
|
||||||
|
_data = [_data];
|
||||||
|
}
|
||||||
|
return when.map(_data, function (item) {
|
||||||
|
// Accept an array of models as input
|
||||||
|
if (item.toJSON) { item = item.toJSON(); }
|
||||||
|
return settings.forge({ key: item.key }).fetch().then(function (setting) {
|
||||||
|
return setting.set('value', item.value).save();
|
||||||
|
});
|
||||||
|
});
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
module.exports = {
|
||||||
|
Settings: Settings
|
||||||
|
};
|
||||||
|
|
||||||
|
}());
|
@ -6,6 +6,6 @@
|
|||||||
'role': require('../models/role').Role,
|
'role': require('../models/role').Role,
|
||||||
'user': require('../models/user').User,
|
'user': require('../models/user').User,
|
||||||
'permission': require('../models/permission').Permission,
|
'permission': require('../models/permission').Permission,
|
||||||
'setting': require('../models/setting').Setting
|
'setting': require('../models/settings').Settings
|
||||||
};
|
};
|
||||||
}());
|
}());
|
@ -8,9 +8,9 @@
|
|||||||
helpers = require('./helpers'),
|
helpers = require('./helpers'),
|
||||||
Models = require('../../shared/models');
|
Models = require('../../shared/models');
|
||||||
|
|
||||||
describe('Setting Model', function () {
|
describe('Settings Model', function () {
|
||||||
|
|
||||||
var SettingModel = Models.Setting;
|
var SettingsModel = Models.Settings;
|
||||||
|
|
||||||
beforeEach(function (done) {
|
beforeEach(function (done) {
|
||||||
helpers.resetData().then(function () {
|
helpers.resetData().then(function () {
|
||||||
@ -19,7 +19,7 @@
|
|||||||
});
|
});
|
||||||
|
|
||||||
it('can browse', function (done) {
|
it('can browse', function (done) {
|
||||||
SettingModel.browse().then(function (results) {
|
SettingsModel.browse().then(function (results) {
|
||||||
|
|
||||||
should.exist(results);
|
should.exist(results);
|
||||||
|
|
||||||
@ -32,7 +32,7 @@
|
|||||||
it('can read', function (done) {
|
it('can read', function (done) {
|
||||||
var firstSetting;
|
var firstSetting;
|
||||||
|
|
||||||
SettingModel.browse().then(function (results) {
|
SettingsModel.browse().then(function (results) {
|
||||||
|
|
||||||
should.exist(results);
|
should.exist(results);
|
||||||
|
|
||||||
@ -40,7 +40,7 @@
|
|||||||
|
|
||||||
firstSetting = results.models[0];
|
firstSetting = results.models[0];
|
||||||
|
|
||||||
return SettingModel.read(firstSetting.attributes.key);
|
return SettingsModel.read(firstSetting.attributes.key);
|
||||||
|
|
||||||
}).then(function (found) {
|
}).then(function (found) {
|
||||||
|
|
||||||
@ -54,22 +54,21 @@
|
|||||||
});
|
});
|
||||||
|
|
||||||
it('can edit single', function (done) {
|
it('can edit single', function (done) {
|
||||||
var firstPost,
|
var firstSetting;
|
||||||
toEdit = {};
|
|
||||||
|
|
||||||
SettingModel.browse().then(function (results) {
|
SettingsModel.browse().then(function (results) {
|
||||||
|
|
||||||
should.exist(results);
|
should.exist(results);
|
||||||
|
|
||||||
results.length.should.be.above(0);
|
results.length.should.be.above(0);
|
||||||
|
|
||||||
firstPost = results.models[0];
|
firstSetting = results.models[0];
|
||||||
|
|
||||||
// The edit method has been modified to take an object of
|
// The edit method has been modified to take an object of
|
||||||
// key/value pairs
|
// key/value pairs
|
||||||
toEdit[firstPost.attributes.key] = "new value";
|
firstSetting.set('value', 'new value');
|
||||||
|
|
||||||
return SettingModel.edit(toEdit);
|
return SettingsModel.edit(firstSetting);
|
||||||
|
|
||||||
}).then(function (edited) {
|
}).then(function (edited) {
|
||||||
|
|
||||||
@ -79,7 +78,7 @@
|
|||||||
|
|
||||||
edited = edited[0];
|
edited = edited[0];
|
||||||
|
|
||||||
edited.attributes.key.should.equal(firstPost.attributes.key);
|
edited.attributes.key.should.equal(firstSetting.attributes.key);
|
||||||
edited.attributes.value.should.equal('new value');
|
edited.attributes.value.should.equal('new value');
|
||||||
|
|
||||||
done();
|
done();
|
||||||
@ -88,26 +87,25 @@
|
|||||||
});
|
});
|
||||||
|
|
||||||
it('can edit multiple', function (done) {
|
it('can edit multiple', function (done) {
|
||||||
var firstPost,
|
var model1,
|
||||||
secondPost,
|
model2,
|
||||||
editedPost,
|
editedModel;
|
||||||
toEdit = {};
|
|
||||||
|
|
||||||
SettingModel.browse().then(function (results) {
|
SettingsModel.browse().then(function (results) {
|
||||||
|
|
||||||
should.exist(results);
|
should.exist(results);
|
||||||
|
|
||||||
results.length.should.be.above(0);
|
results.length.should.be.above(0);
|
||||||
|
|
||||||
firstPost = results.models[0];
|
model1 = results.models[0];
|
||||||
secondPost = results.models[1];
|
model2 = results.models[1];
|
||||||
|
|
||||||
// The edit method has been modified to take an object of
|
// The edit method has been modified to take an object of
|
||||||
// key/value pairs
|
// key/value pairs
|
||||||
toEdit[firstPost.attributes.key] = "new value1";
|
model1.set('value', 'new value1');
|
||||||
toEdit[secondPost.attributes.key] = "new value2";
|
model2.set('value', 'new value2');
|
||||||
|
|
||||||
return SettingModel.edit(toEdit);
|
return SettingsModel.edit([model1, model2]);
|
||||||
|
|
||||||
}).then(function (edited) {
|
}).then(function (edited) {
|
||||||
|
|
||||||
@ -115,15 +113,15 @@
|
|||||||
|
|
||||||
edited.length.should.equal(2);
|
edited.length.should.equal(2);
|
||||||
|
|
||||||
editedPost = edited[0];
|
editedModel = edited[0];
|
||||||
|
|
||||||
editedPost.attributes.key.should.equal(firstPost.attributes.key);
|
editedModel.attributes.key.should.equal(model1.attributes.key);
|
||||||
editedPost.attributes.value.should.equal('new value1');
|
editedModel.attributes.value.should.equal('new value1');
|
||||||
|
|
||||||
editedPost = edited[1];
|
editedModel = edited[1];
|
||||||
|
|
||||||
editedPost.attributes.key.should.equal(secondPost.attributes.key);
|
editedModel.attributes.key.should.equal(model2.attributes.key);
|
||||||
editedPost.attributes.value.should.equal('new value2');
|
editedModel.attributes.value.should.equal('new value2');
|
||||||
|
|
||||||
done();
|
done();
|
||||||
|
|
||||||
@ -136,7 +134,7 @@
|
|||||||
value: 'Test Content 1'
|
value: 'Test Content 1'
|
||||||
};
|
};
|
||||||
|
|
||||||
SettingModel.add(newSetting).then(function (createdSetting) {
|
SettingsModel.add(newSetting).then(function (createdSetting) {
|
||||||
|
|
||||||
should.exist(createdSetting);
|
should.exist(createdSetting);
|
||||||
|
|
||||||
@ -150,7 +148,7 @@
|
|||||||
it('can delete', function (done) {
|
it('can delete', function (done) {
|
||||||
var firstSettingId;
|
var firstSettingId;
|
||||||
|
|
||||||
SettingModel.browse().then(function (results) {
|
SettingsModel.browse().then(function (results) {
|
||||||
|
|
||||||
should.exist(results);
|
should.exist(results);
|
||||||
|
|
||||||
@ -158,11 +156,11 @@
|
|||||||
|
|
||||||
firstSettingId = results.models[0].id;
|
firstSettingId = results.models[0].id;
|
||||||
|
|
||||||
return SettingModel.destroy(firstSettingId);
|
return SettingsModel.destroy(firstSettingId);
|
||||||
|
|
||||||
}).then(function () {
|
}).then(function () {
|
||||||
|
|
||||||
return SettingModel.browse();
|
return SettingsModel.browse();
|
||||||
|
|
||||||
}).then(function (newResults) {
|
}).then(function (newResults) {
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user