closes #28 - reimplements posts with bookshelf

This involves switching column names to snake_case which requires template updates in both the admin and in casper
This commit is contained in:
Hannah Wolfe 2013-05-16 22:16:09 +01:00
parent 58926d1ce4
commit ef94f3b778
10 changed files with 352 additions and 14 deletions

22
app.js
View File

@ -1,6 +1,6 @@
// # Ghost main app file
/*global require */
/*global require, __dirname */
(function () {
"use strict";
@ -12,14 +12,17 @@
flash = require('connect-flash'),
Ghost = require('./core/ghost'),
I18n = require('./core/lang/i18n'),
helpers = require('./core/frontend/helpers'),
auth,
helpers = require('./core/frontend/helpers');
var auth,
// ## Variables
/**
* Create new Ghost object
* @type {Ghost}
*/
/**
* Create new Ghost object
* @type {Ghost}
*/
ghost = new Ghost();
ghost.app().configure('development', function () {
@ -78,4 +81,9 @@
ghost.app().listen(3333, function () {
console.log("Express server listening on port " + 3333);
});
// }, function (e) {
// console.log(e.toString());
// }).then(null, function (e) {
// console.log(e.stack);
// });
}());

View File

@ -55,6 +55,19 @@
*/
config.homepage.posts = 4;
config.database = {
development: {
client: 'sqlite3',
connection: {
filename: './core/shared/data/testdb.db'
}
},
staging: {},
production: {}
};
/**
* @property {Object} exports
*/

View File

@ -18,7 +18,7 @@
<ol>
{{#each posts}}
{{! #if featured class="featured"{{/if}}
<li data-id="{{id}}" data-content="{{contentHtml}}">
<li data-id="{{id}}" data-content="{{content_html}}">
<a class="permalink" href="#">
<h3 class="entry-title">{{title}}</h3>
<section class="entry-meta">

View File

@ -12,10 +12,13 @@
hbs = require('express-hbs'),
_ = require('underscore'),
Polyglot = require('node-polyglot'),
JsonDataProvider = require('./shared/models/dataProvider.json'),
jsonDataProvider = new JsonDataProvider(),
JugglingDataProvider = require('./shared/models/dataProvider.juggling'),
jugglingDataProvider = new JugglingDataProvider(),
// JugglingDataProvider = require('./shared/models/dataProvider.juggling'),
// jugglingDataProvider = new JugglingDataProvider(),
BookshelfDataProvider = require('./shared/models/dataProvider.bookshelf'),
bookshelfDataProvider = new BookshelfDataProvider(),
Ghost,
instance,
filterCallbacks = {},
@ -66,7 +69,7 @@
app: function () { return app; },
config: function () { return config; },
globals: function () { return globals; }, // there's no management here to be sure this has loaded
dataProvider: function () { return jugglingDataProvider; },
dataProvider: function () { return bookshelfDataProvider; },
statuses: function () { return statuses; },
polyglot: function () { return polyglot; },
paths: function () {

View File

@ -33,13 +33,11 @@
// takes a json object with all the properties which should be updated
// returns the resulting post in a json response
edit: function (postData) {
console.log('edit data', postData);
return when.call(ghost.dataProvider().posts.edit, postData);
},
// takes a json object representing a post,
// returns the resulting post in a json response
add: function (postData) {
console.log('data', postData);
return when.call(ghost.dataProvider().posts.add, postData);
},
// takes an identifier (id or slug?)

File diff suppressed because one or more lines are too long

View File

@ -0,0 +1,75 @@
/*global require, exports */
(function () {
"use strict";
var when = require('when'),
knex = require('./knex_init'),
fixtures = require('../fixtures/001'),
up,
down;
up = function () {
return when.all([
knex.Schema.createTable('posts', function (t) {
t.increments().primary();
t.string('title');
t.string('slug');
t.text('content');
t.text('content_html');
t.bool('featured');
t.string('image');
t.string('status');
t.string('language');
t.date('created_at');
t.integer('created_by');
t.date('updated_at');
t.integer('updated_by');
}),
knex.Schema.createTable('users', function (t) {
t.increments().primary();
t.string('username');
t.string('first_name');
t.string('last_name');
t.string('email_address');
t.string('profile_picture');
t.string('cover_picture');
t.text('bio');
t.string('url');
t.date('created_at');
t.integer('created_by');
t.date('updated_at');
t.integer('updated_by');
}),
knex.Schema.createTable('settings', function (t) {
t.increments().primary();
t.string('key');
t.text('value');
t.date('created_at');
t.integer('created_by');
t.date('updated_at');
t.integer('updated_by');
})
// Once we create all of the initial tables, bootstrap any of the data
]).then(function () {
return when.all([
knex('posts').insert(fixtures.posts),
knex('users').insert(fixtures.users),
knex('settings').insert(fixtures.settings)
]);
});
};
down = function () {};
exports.up = up;
exports.down = down;
}());

View File

@ -0,0 +1,86 @@
/**
* Provides access to data via the Bookshelf ORM
*/
/*globals module, require, process */
(function () {
"use strict";
var knex = require('knex'),
models = require('./models'),
DataProvider,
instance;
knex.Initialize(require('../../../config').database[process.env.NODE_ENV || 'development']);
DataProvider = function () {
if (!instance) {
instance = this;
knex.Schema.hasTable('posts').then(null, function () {
// Simple boostraping of the data model for now.
require('./../data/migration/001').up().then(function () {
console.log('all done....');
});
});
}
return instance;
};
DataProvider.prototype.posts = function () { };
/**
* Naive find all
* @param args
* @param callback
*/
DataProvider.prototype.posts.findAll = function (args, callback) {
models.Posts.forge().fetch().then(function (posts) {
callback(null, posts);
}, callback);
};
/**
* Naive find one where args match
* @param args
* @param callback
*/
DataProvider.prototype.posts.findOne = function (args, callback) {
models.Post.forge(args).fetch().then(function (post) {
callback(null, post);
}, callback);
};
/**
* Naive add
* @param _post
* @param callback
*/
DataProvider.prototype.posts.add = function (_post, callback) {
models.Post.forge(_post).save().then(function (post) {
callback(null, post);
}, callback);
};
/**
* Naive edit
* @param _post
* @param callback
*/
DataProvider.prototype.posts.edit = function (_post, callback) {
models.Post.forge({id: _post.id}).fetch().then(function (post) {
post.set(_post).save().then(function (post) {
callback(null, post);
}, callback);
});
};
DataProvider.prototype.posts.destroy = function (_identifier, callback) {
models.Post.forge({id: _identifier}).destroy().then(function () {
callback(null);
});
};
module.exports = DataProvider;
}());

View File

@ -0,0 +1,86 @@
/*global require, module */
(function () {
"use strict";
// We should just be able to require bookshelf and have it reference
// the `Knex` instance bootstraped at the app initialization.
var Bookshelf = require('bookshelf'),
Showdown = require('showdown'),
converter = new Showdown.converter(),
Post,
Posts,
User,
Setting;
Post = Bookshelf.Model.extend({
tableName: 'posts',
hasTimestamps: true,
initialize: function () {
this.on('creating', this.creating, this);
this.on('saving', this.saving, this);
},
saving: function () {
if (!this.get('title')) {
throw new Error('Post title cannot be blank');
}
this.set('content_html', converter.makeHtml(this.get('content')));
// refactoring of ghost required in order to make these details available here
// this.set('language', this.get('language') || ghost.config().defaultLang);
// this.set('status', this.get('status') || ghost.statuses().draft);
},
creating: function () {
if (!this.get('slug')) {
this.generateSlug();
}
},
generateSlug: function () {
return this.set('slug', this.get('title').replace(/\:/g, '').replace(/\s/g, '-').toLowerCase());
},
user: function () {
return this.belongsTo(User, 'created_by');
}
});
Posts = Bookshelf.Collection.extend({
model: Post
});
User = Bookshelf.Model.extend({
tableName: 'users',
hasTimestamps: true,
posts: function () {
return this.hasMany(Posts, 'created_by');
}
});
Setting = Bookshelf.Model.extend({
tableName: 'settings'
});
module.exports = {
Post: Post,
Posts: Posts,
User: User,
Setting: Setting
};
}());

View File

@ -15,8 +15,10 @@
"moment": "*",
"underscore": "*",
"showdown": "*",
"when": "*",
"sqlite3": "2.1.7",
"bookshelf": "0.1.x",
"knex": "0.1.x",
"when": "~2.1.0",
"jugglingdb": "0.2.0-29",
"jugglingdb-sqlite3": "git+https://github.com/jugglingdb/sqlite3-adapter.git#master"
},