Skip to content

Instantly share code, notes, and snippets.

@arigesher
Created May 2, 2014 18:50
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save arigesher/11483145 to your computer and use it in GitHub Desktop.
Save arigesher/11483145 to your computer and use it in GitHub Desktop.
Messing around with creating post notifications in Ghost (and learning Javascript)
diff --git a/Gruntfile.js b/Gruntfile.js
index 7a2cb02..d3edb52 100644
--- a/Gruntfile.js
+++ b/Gruntfile.js
@@ -245,6 +245,15 @@ var path = require('path'),
api: {
src: ['core/test/functional/api/*_test.js']
+ },
+ posts: {
+ options: {
+ 'grep': 'can create a new draft, publish post, update post',
+ 'debug-brk': true,
+ 'debug': true,
+ 'timeout': 600000
+ },
+ src: ['core/test/functional/api/posts_test.js']
}
},
@@ -823,6 +832,8 @@ var path = require('path'),
grunt.registerTask('test-api', 'Run functional api tests (mocha)', ['clean:test', 'setTestEnv', 'loadConfig', 'express:test', 'mochacli:api', 'express:test:stop']);
+ grunt.registerTask('test-posts', 'Run post publishing tests (mocha)', ['clean:test', 'setTestEnv', 'loadConfig', 'express:test', 'mochacli:posts', 'express:test:stop']);
+
grunt.registerTask('validate', 'Run tests and lint code', ['jslint', 'test-unit', 'test-api', 'test-integration', 'test-functional']);
diff --git a/core/server/autoPoster/index.js b/core/server/autoPoster/index.js
new file mode 100644
index 0000000..e69de29
diff --git a/core/server/ghostNotifications/index.js b/core/server/ghostNotifications/index.js
new file mode 100644
index 0000000..d4d41ae
--- /dev/null
+++ b/core/server/ghostNotifications/index.js
@@ -0,0 +1,88 @@
+var events = require("events"),
+ when = require("when"),
+ _ = require("underscore"),
+ api = require('../api'),
+ config = require('../config'),
+ postEvents = new events.EventEmitter();
+
+// adapted from ../helpers/index.js - non-optimal to
+// copy the code, but the helpers have some strange
+// constraints on them that was making it hard to get
+// the helper code to work.
+//
+// It seems that Ghost needs good library code for building
+// URLs - maybe on the post object itself?
+//
+// This should be invoked with post.toJSON() as data
+function constructURL(postJSON) {
+ var output = '',
+ self = postJSON,
+ tags = {
+ year: function () { return self.created_at.getFullYear(); },
+ month: function () { return self.created_at.getMonth() + 1; },
+ day: function () { return self.created_at.getDate(); },
+ slug: function () { return self.slug; },
+ id: function () { return self.id; }
+ },
+ path = config.paths().path,
+ // default in case settings have not been initialized
+ permalinks = '/:year/:month/:day/:slug/';
+
+ if(api.settings) {
+ api.settings.read('permalinks').done(function (permalinksSetting) {
+ permalinks = permalinksSetting.value;
+ }, function(reason) { /* no-op failure */ });
+ }
+
+ output += config().url;
+ if (path && path !== '/') {
+ output += path;
+ }
+ output += permalinks;
+ output = output.replace(/(:[a-z]+)/g, function (match) {
+ if (_.has(tags, match.substr(1))) {
+ return tags[match.substr(1)]();
+ }
+ });
+ return output;
+}
+
+
+function publishNotification(post) {
+ var helpers = require("../helpers");
+ var url = null;
+
+ if(post !== null) {
+ post = post.toJSON();
+
+ url = constructURL(post);
+
+ post_notification = {
+ uuid: post.uuid,
+ title: post.title,
+ html: post.html,
+ meta_title: post.meta_title,
+ meta_description: post.meta_description,
+ image: post.image,
+ timestamp: post.published_at,
+ author: post.author.name,
+ url: url
+ };
+
+
+ console.info(post_notification);
+ console.info('Publish notification for post ("' +
+ post_notification['title'] +
+ '") - ' +
+ post_notification['url']);
+
+ postEvents.emit('publish', url, post_notification);
+ } else {
+ console.info("null post passed to notify");
+ }
+}
+
+module.exports = {
+ publishNotification: publishNotification,
+ isPublishNotificationEnabled: function() { return true; }
+};
diff --git a/core/server/helpers/index.js b/core/server/helpers/index.js
index 975ae4d..132e688 100644
--- a/core/server/helpers/index.js
+++ b/core/server/helpers/index.js
@@ -88,6 +88,7 @@ coreHelpers.pageUrl = function (context, block) {
// i.e. If inside a post context will return post permalink
// absolute flag outputs absolute URL, else URL is relative
coreHelpers.url = function (options) {
+ console.info("calling url helper");
var output = '',
self = this,
tags = {
@@ -114,6 +115,7 @@ coreHelpers.url = function (options) {
}
});
}
+ console.info(output);
return output;
});
};
diff --git a/core/server/models/post.js b/core/server/models/post.js
index b471f51..84b0bc8 100644
--- a/core/server/models/post.js
+++ b/core/server/models/post.js
@@ -10,6 +10,7 @@ var Post,
User = require('./user').User,
Tag = require('./tag').Tag,
Tags = require('./tag').Tags,
+ eventNotifications = require('../ghostNotifications'),
ghostBookshelf = require('./base');
Post = ghostBookshelf.Model.extend({
@@ -53,16 +54,39 @@ Post = ghostBookshelf.Model.extend({
this.set('title', this.sanitize('title').trim());
+ var publishNotify = false;
if (this.hasChanged('status') && this.get('status') === 'published') {
if (!this.get('published_at')) {
this.set('published_at', new Date());
}
// This will need to go elsewhere in the API layer.
this.set('published_by', 1);
+ publishNotify = true;
+
}
ghostBookshelf.Model.prototype.saving.call(this);
+ if(eventNotifications.isPublishNotificationEnabled() && publishNotify) {
+ this.once("saved", function() {
+ this.fetch({require: true, withRelated: [ 'author', 'user', 'tags' ]}).then(
+ function(loadedPost){
+ if(loadedPost !== null) {
+ eventNotifications.publishNotification(loadedPost);
+ } else {
+ console.error("Loaded null post for id " + self.get('id'));
+ }
+ },
+ function(reason) {
+ if (!reason) {
+ reason = 'unspeficied';
+ }
+ console.error("Failed to load post with id " + self.get('id') +
+ ": " + reason);
+ });
+ }, this);
+ }
+
if (this.hasChanged('slug')) {
// Pass the new slug through the generator to strip illegal characters, detect duplicates
return this.generateSlug(Post, this.get('slug'), {status: 'all', transacting: options.transacting})
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment