Skip to content

Instantly share code, notes, and snippets.

@psychobunny
Last active April 24, 2016 10:30
Embed
What would you like to do?
NodeBB plugin - adding main post data to category view
var topics = module.parent.require('./topics'),
async = module.parent.require('async');
var plugin = {};
plugin.addPostData = function(data, uid, callback) {
async.map(data.topics, function(topic, next) {
topics.getMainPost(topic.tid, uid, function(err, mainPost) {
topic.mainPost = mainPost;
next(err, topic);
});
}, function(err, topics) {
data.topics = topics;
callback(null, data);
});
};
module.exports = plugin;
@psychobunny
Copy link
Author

Here's a sample plugin.json to go with it:

{
    "id": "nodebb-plugin-my-plugin-or-theme-name",
    "name": "My plugin or theme name",
    "description": "",
    "url": "",
    "library": "./library.js",
    "hooks": [
        {
            "hook": "filter:category.get", "method": "addPostData"
        }
    ]
}

@a5mith
Copy link

a5mith commented Aug 14, 2014

Hey Buddy, how would you also do this with recent as well as topics?

module.parent.require recent doesn't exist. 😆 Thanks.

Use case: I want the content from recent for an idea I've had.

@psychobunny
Copy link
Author

updated nodebb, just use the above code, it will now work on all category-like API calls (unread/recent/popular)

@barisusakli
Copy link

You can use getMainPosts after 0.5.1 its much faster than getting main posts 1 by 1.

plugin.addPostData = function(data, uid, callback) {
     var tids = data.topics.map(function(topic) {
          return topic.tid;
     });    
     topics.getMainPosts(tids, uid, function(err, mainPosts) {
        mainPosts.forEach(function(post, index) {
              data.topics[index].mainPost = post;
        });

        callback(null, data);
    });
};

@psychobunny
Copy link
Author

update for 0.6x:

"use strict";

var topics = module.parent.require('./topics');

var theme = {};

theme.addPostData = function(params, callback) {
    var tids = params.category.topics.map(function(topic) {
        return topic.tid;
    });

    topics.getMainPosts(tids, params.uid, function(err, mainPosts) {
        mainPosts.forEach(function(post, index) {
            params.category.topics[index].mainPost = post;
        });

        callback(null, params);
    });
};

module.exports = theme;

@psychobunny
Copy link
Author

Here it is re-written to use the recommended filter:category.topics.get instead (this way infinite loaded posts will still work):

"use strict";

var topics = module.parent.require('./topics');

var theme = {};

theme.addPostData = function(params, callback) {
    var tids = params.topics.map(function(topic) {
        return topic.tid;
    });

    topics.getMainPosts(tids, params.uid, function(err, mainPosts) {
        mainPosts.forEach(function(post, index) {
            params.topics[index].mainPost = post;
        });

        callback(null, params);
    });
};

module.exports = theme;

@psychobunny
Copy link
Author

And finally, here's a variation that either picks the latest post (teaser) or mainPost if no replies have been made:

"use strict";

var topics = module.parent.require('./topics'),
    posts = module.parent.require('./posts');

var theme = {};

theme.addPostData = function(params, callback) {
    var pids = params.topics.map(function(topic) {
        return topic.teaser ? topic.teaser.pid : topic.mainPid;
    });

    posts.getPostsByPids(pids, params.uid, function(err, postData) {
        if (err) {
            return callback(err);
        }

        topics.addPostData(postData, params.uid, function(err, posts) {
            posts.forEach(function(post, index) {
                params.topics[index].mainPost = post;
            });

            callback(null, params);
        });
    });
};

module.exports = theme;

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment