Baris Soner Usakli
commit 81560c4698

@ -2,7 +2,7 @@
"name": "nodebb", "name": "nodebb",
"license": "GPLv3 or later", "license": "GPLv3 or later",
"description": "NodeBB Forum", "description": "NodeBB Forum",
"version": "0.1.0", "version": "0.1.1",
"homepage": "http://www.nodebb.org", "homepage": "http://www.nodebb.org",
"repository": { "repository": {
"type": "git", "type": "git",
@ -43,7 +43,7 @@
"nodebb-plugin-mentions": "~0.1.14", "nodebb-plugin-mentions": "~0.1.14",
"nodebb-plugin-markdown": "~0.1.8", "nodebb-plugin-markdown": "~0.1.8",
"nodebb-theme-vanilla": "designcreateplay/nodebb-theme-vanilla", "nodebb-theme-vanilla": "designcreateplay/nodebb-theme-vanilla",
"nodebb-theme-cerulean": "0.0.7", "nodebb-theme-cerulean": "0.0.9",
"cron": "~1.0.1" "cron": "~1.0.1"
}, },
"optionalDependencies": { "optionalDependencies": {

@ -67,25 +67,23 @@ var ajaxify = {};
} }
if (templates.is_available(tpl_url) && !templates.force_refresh(tpl_url)) { if (templates.is_available(tpl_url) && !templates.force_refresh(tpl_url)) {
if (quiet !== true) { if (window.history && window.history.pushState) {
if (window.history && window.history.pushState) { window.history[!quiet ? 'pushState' : 'replaceState']({
window.history.pushState({ url: url
url: url }, url, RELATIVE_PATH + '/' + url);
}, url, RELATIVE_PATH + '/' + url);
$.ajax(RELATIVE_PATH + '/plugins/fireHook', {
$.ajax(RELATIVE_PATH + '/plugins/fireHook', { type: 'PUT',
type: 'PUT', data: {
data: { _csrf: $('#csrf_token').val(),
_csrf: $('#csrf_token').val(), hook: 'page.load',
hook: 'page.load', args: {
args: { template: tpl_url,
template: tpl_url, url: url,
url: url, uid: app.uid
uid: app.uid
}
} }
}); }
} });
} }
translator.load(tpl_url); translator.load(tpl_url);
@ -114,7 +112,7 @@ var ajaxify = {};
if (hash) { if (hash) {
require(['forum/topic'], function(topic) { require(['forum/topic'], function(topic) {
topic.scrollToPost(hash.substr(1)) topic.scrollToPost(hash.substr(1));
}); });
} }
}); });

@ -36,7 +36,7 @@ define(function() {
app.enterRoom('topic_' + tid); app.enterRoom('topic_' + tid);
if($('#post-container .sub-posts').length) { if($('#post-container .sub-posts').length > 1) {
$('.topic-main-buttons').removeClass('hide').parent().removeClass('hide'); $('.topic-main-buttons').removeClass('hide').parent().removeClass('hide');
} }
@ -196,7 +196,7 @@ define(function() {
// Follow Thread State // Follow Thread State
var followEl = $('.main-post .follow'), var followEl = $('.posts .follow'),
set_follow_state = function(state, quiet) { set_follow_state = function(state, quiet) {
if (state && !followEl.hasClass('btn-success')) { if (state && !followEl.hasClass('btn-success')) {
followEl.addClass('btn-success'); followEl.addClass('btn-success');
@ -333,7 +333,7 @@ define(function() {
$('#post-container').delegate('.edit', 'click', function(e) { $('#post-container').delegate('.edit', 'click', function(e) {
var pid = $(this).parents('li').attr('data-pid'), var pid = $(this).parents('li').attr('data-pid'),
main = $(this).parents('.main-post'); main = $(this).parents('.posts');
require(['composer'], function(cmp) { require(['composer'], function(cmp) {
cmp.push(null, null, pid); cmp.push(null, null, pid);
@ -790,8 +790,8 @@ define(function() {
if (scrollTop < 50 && postcount > 1) { if (scrollTop < 50 && postcount > 1) {
localStorage.removeItem("topic:" + tid + ":bookmark"); localStorage.removeItem("topic:" + tid + ":bookmark");
postAuthorImage.src = (jQuery('.main-post .avatar img').attr('src')); postAuthorImage.src = (jQuery('.posts .avatar img').attr('src'));
mobileAuthorOverlay.innerHTML = 'Posted by ' + jQuery('.main-post').attr('data-username') + ', ' + jQuery('.main-post').find('.relativeTimeAgo').html(); mobileAuthorOverlay.innerHTML = 'Posted by ' + jQuery('.posts').attr('data-username') + ', ' + jQuery('.posts').find('.relativeTimeAgo').html();
pagination.innerHTML = '0 out of ' + postcount; pagination.innerHTML = '0 out of ' + postcount;
return; return;
} }
@ -890,7 +890,7 @@ define(function() {
$('#post-container li[data-pid]').each(function() { $('#post-container li[data-pid]').each(function() {
if(parseInt(firstPid, 10) > parseInt($(this).attr('data-pid'), 10)) { if(parseInt(firstPid, 10) > parseInt($(this).attr('data-pid'), 10)) {
after = $(this); after = $(this);
if(after.hasClass('main-post')) { if(after.hasClass('posts')) {
after = after.next(); after = after.next();
} }
} else { } else {
@ -908,9 +908,12 @@ define(function() {
var insertAfter = findInsertionPoint(); var insertAfter = findInsertionPoint();
var html = templates.prepare(templates['topic'].blocks['posts']).parse(data); var html = templates.prepare(templates['topic'].blocks['posts']).parse(data);
var regexp = new RegExp("<!--[\\s]*IF @first[\\s]*-->[\\s\\S]*<!--[\\s]*ENDIF @first[\\s]*-->", 'g');
html = html.replace(regexp, '');
translator.translate(html, function(translatedHTML) { translator.translate(html, function(translatedHTML) {
var translated = $(translatedHTML); var translated = $(translatedHTML);
if(!infiniteLoaded) { if(!infiniteLoaded) {
translated.removeClass('infiniteloaded'); translated.removeClass('infiniteloaded');
} }

@ -235,11 +235,11 @@
} }
function makeRegex(block) { function makeRegex(block) {
return new RegExp("<!-- BEGIN " + block + " -->[\\s\\S]*<!-- END " + block + " -->", 'g'); return new RegExp("<!--[\\s]*BEGIN " + block + "[\\s]*-->[\\s\\S]*<!--[\\s]*END " + block + "[\\s]*-->", 'g');
} }
function makeConditionalRegex(block) { function makeConditionalRegex(block) {
return new RegExp("<!-- IF " + block + " -->[\\s\\S]*<!-- ENDIF " + block + " -->", 'g'); return new RegExp("<!--[\\s]*IF " + block + "[\\s]*-->[\\s\\S]*<!--[\\s]*ENDIF " + block + "[\\s]*-->", 'g');
} }
function getBlock(regex, block, template) { function getBlock(regex, block, template) {
@ -249,8 +249,8 @@
if (self.blocks && block !== undefined) self.blocks[block] = data[0]; if (self.blocks && block !== undefined) self.blocks[block] = data[0];
data = data[0] data = data[0]
.replace("<!-- BEGIN " + block + " -->", "") .replace("<!--[\\s]*BEGIN " + block + "[\\s]*-->", "")
.replace("<!-- END " + block + " -->", ""); .replace("<!--[\\s]*END " + block + "[\\s]*-->", "");
return data; return data;
} }
@ -262,7 +262,7 @@
var template = this.html, var template = this.html,
regex, block; regex, block;
return (function parse(data, namespace, template) { return (function parse(data, namespace, template, blockInfo) {
if (!data || data.length == 0) { if (!data || data.length == 0) {
template = ''; template = '';
} }
@ -289,7 +289,7 @@
result = ""; result = "";
do { do {
result += parse(data[d][i], namespace, block); result += parse(data[d][i], namespace, block, {iterator: i, total: numblocks});
} while (i++ < numblocks); } while (i++ < numblocks);
namespace = namespace.replace(d + '.', ''); namespace = namespace.replace(d + '.', '');
@ -304,29 +304,39 @@
block = parse(data[d], namespace, block); block = parse(data[d], namespace, block);
template = setBlock(regex, block, template); template = setBlock(regex, block, template);
} else { } else {
var conditional = makeConditionalRegex(namespace + d); function checkConditional(key, value) {
var conditional = makeConditionalRegex(key),
var conditionalBlock = conditional.exec(template); conditionalBlock = conditional.exec(template);
if (conditionalBlock !== null) {
conditionalBlock = conditionalBlock[0].split('<!-- ELSE -->');
if (conditionalBlock[1]) { if (conditionalBlock !== null) {
// there is an else statement conditionalBlock = conditionalBlock[0].split(/<!-- ELSE -->/);
if (!data[d]) {
template = template.replace(conditional, conditionalBlock[1]);
} else {
template = template.replace(conditional, conditionalBlock[0]);
}
} else { if (conditionalBlock[1]) {
// regular if // there is an else statement
if (!data[d]) { if (!value) {
template = template.replace(conditional, ''); template = template.replace(conditional, conditionalBlock[1]);
} else {
template = template.replace(conditional, conditionalBlock[0]);
}
} else {
// regular if
if (!value) {
template = template.replace(conditional, '');
}
} }
} }
} }
checkConditional(namespace + d, data[d]);
checkConditional('!' + namespace + d, !data[d]);
if (blockInfo) {
checkConditional('@first', blockInfo.iterator === 0);
checkConditional('@last', blockInfo.iterator === blockInfo.total);
}
template = replace(namespace + d, data[d], template); template = replace(namespace + d, data[d], template);
} }
} }

@ -83,43 +83,35 @@
</ul> </ul>
</div> </div>
<div class="col-md-3 {show_sidebar} category-sidebar"> <div class="col-md-3 {show_sidebar} category-sidebar">
<div class="panel panel-default">
<div class="sidebar-block img-thumbnail"> <div class="panel-heading">[[category:sidebar.recent_replies]]</div>
<div class="block-header"> <div class="panel-body recent-replies">
[[category:sidebar.recent_replies]]
</div>
<div class="block-content recent-replies">
<ul id="category_recent_replies"></ul> <ul id="category_recent_replies"></ul>
</div> </div>
</div> </div>
<div class="sidebar-block img-thumbnail">
<div class="block-header"> <div class="panel panel-default">
[[category:sidebar.active_participants]] <div class="panel-heading">[[category:sidebar.active_participants]]</div>
</div> <div class="panel-body active-users">
<div class="block-content active-users">
<!-- BEGIN active_users --> <!-- BEGIN active_users -->
<a data-uid="{active_users.uid}" href="/user/{active_users.userslug}"><img title="{active_users.username}" src="{active_users.picture}" class="img-rounded user-img" /></a> <a data-uid="{active_users.uid}" href="/user/{active_users.userslug}"><img title="{active_users.username}" src="{active_users.picture}" class="img-rounded user-img" /></a>
<!-- END active_users --> <!-- END active_users -->
</div> </div>
</div> </div>
<div class="sidebar-block img-thumbnail {moderator_block_class}">
<div class="block-header"> <div class="panel panel-default {moderator_block_class}">
[[category:sidebar.moderators]] <div class="panel-heading">[[category:sidebar.moderators]]</div>
</div> <div class="panel-body moderators">
<div class="block-content">
<!-- BEGIN moderators --> <!-- BEGIN moderators -->
<a href="/user/{moderators.userslug}"><img title="{moderators.username}" src="{moderators.picture}" class="img-rounded" /></a> <a href="/user/{moderators.userslug}"><img title="{moderators.username}" src="{moderators.picture}" class="img-rounded" /></a>
<!-- END moderators --> <!-- END moderators -->
</div> </div>
</div> </div>
<!-- BEGIN sidebars --> <!-- BEGIN sidebars -->
<div class="sidebar-block img-thumbnail {sidebars.block_class}"> <div class="panel panel-default">
<div class="block-header"> <div class="panel panel-default {sidebars.block_class}">{sidebars.header}</div>
{sidebars.header} <div class="panel-body">{sidebars.content}</div>
</div>
<div class="block-content">
{sidebars.content}
</div>
</div> </div>
<!-- END sidebars --> <!-- END sidebars -->
</div> </div>

@ -1,18 +1,4 @@
<ul class="posts"> <ul class="posts">
<!-- BEGIN main_posts -->
<li>
<a name="{main_posts.pid}"></a>
<div class="row">
<div class="col-lg-2 profile">
<img class="img-thumbnail" src="{main_posts.picture}" /><br />
<span class="username">{main_posts.username}</span>
</div>
<div class="col-lg-10">
{main_posts.content}
</div>
</div>
</li>
<!-- END main_posts -->
<!-- BEGIN posts --> <!-- BEGIN posts -->
<li> <li>
<a name="{posts.pid}"></a> <a name="{posts.pid}"></a>

@ -24,123 +24,30 @@
</ol> </ol>
<ul id="post-container" class="container" data-tid="{topic_id}"> <ul id="post-container" class="container" data-tid="{topic_id}">
<!-- BEGIN main_posts --> <div class="posts">
<li class="row post-row main-post infiniteloaded" data-pid="{main_posts.pid}" data-uid="{main_posts.uid}" data-username="{main_posts.username}" data-deleted="{main_posts.deleted}" itemscope itemtype="http://schema.org/Article">
<a id="post_anchor_{main_posts.pid}" name="{main_posts.pid}"></a>
<div class="col-md-12">
<div class="post-block">
<meta itemprop="datePublished" content="{main_posts.relativeTime}">
<meta itemprop="dateModified" content="{main_posts.relativeEditTime}">
<meta itemprop="url" content="/topic/{slug}/">
<a class="avatar" href="/user/{main_posts.userslug}">
<img itemprop="image" src="{main_posts.picture}" align="left" class="img-thumbnail" width=150 height=150 /><br />
</a>
<h3>
<p id="topic_title_{main_posts.pid}" class="topic-title" itemprop="name">{topic_name}</p>
</h3>
<div class="topic-buttons">
<div class="btn-group">
<button class="btn btn-sm btn-default dropdown-toggle" data-toggle="dropdown" type="button" title="[[topic:posted_by]] {main_posts.username}">
<span class="username-field" href="/user/{main_posts.userslug}" itemprop="author" itemscope itemtype="http://schema.org/Person">{main_posts.username}&nbsp;</span>
<span class="caret"></span>
</button>
<ul class="dropdown-menu">
<li><a href="/user/{main_posts.userslug}"><i class="icon-user"></i> [[topic:profile]]</a></li>
<li><div class="chat"><i class="icon-comment"></i> [[topic:chat]]</div></li>
</ul>
</div>
<div class="btn-group">
<button class="btn btn-sm btn-default follow" type="button" title="Be notified of new replies in this topic"><i class="icon-eye-open"></i></button>
<button class="favourite btn btn-sm btn-default {main_posts.fav_button_class}" type="button">
<span class="favourite-text">[[topic:favourite]]</span>
<span class="post_rep_{main_posts.pid}">{main_posts.post_rep} </span><i class="{main_posts.fav_star_class}"></i>
</button>
</div>
<div class="btn-group">
<button class="btn btn-sm btn-default quote" type="button" title="[[topic:quote]]"><i class="icon-quote-left"></i></button>
<button class="btn btn-sm btn-primary btn post_reply" type="button">[[topic:reply]] <i class="icon-reply"></i></button>
</div>
<div class="pull-right">
<div class="btn-group post-tools">
<button class="btn btn-sm btn-default link" type="button" title="[[topic:link]]"><i class="icon-link"></i></button>
<button class="btn btn-sm btn-default facebook-share" type="button" title=""><i class="icon-facebook"></i></button>
<button class="btn btn-sm btn-default twitter-share" type="button" title=""><i class="icon-twitter"></i></button>
<button class="btn btn-sm btn-default google-share" type="button" title=""><i class="icon-google-plus"></i></button>
</div>
<div class="btn-group post-tools">
<button class="btn btn-sm btn-default edit {main_posts.display_moderator_tools}" type="button" title="[[topic:edit]]"><i class="icon-pencil"></i></button>
<button class="btn btn-sm btn-default delete {main_posts.display_moderator_tools}" type="button" title="[[topic:delete]]"><i class="icon-trash"></i></button>
</div>
</div>
<input id="post_{main_posts.pid}_link" value="" class="pull-right" style="display:none;"></input>
</div>
<div id="content_{main_posts.pid}" class="post-content" itemprop="articleBody">{main_posts.content}</div>
<div class="post-signature">{main_posts.signature}</div>
<div class="post-info">
<span class="pull-left">
{main_posts.additional_profile_info}
</span>
<span class="pull-right">
posted <span class="relativeTimeAgo timeago" title="{main_posts.relativeTime}"></span>
<span class="{main_posts.edited-class}">| last edited by <strong><a href="/user/{main_posts.editorslug}">{main_posts.editorname}</a></strong></span>
<span class="timeago" title="{main_posts.relativeEditTime}"></span>
</span>
<div style="clear:both;"></div>
</div>
</div>
</div>
</li>
<!-- END main_posts -->
<li class="well">
<div class="inline-block">
<small class="topic-stats">
<span>posts</span>
<strong><span id="topic-post-count" class="formatted-number">{postcount}</span></strong> |
<span>views</span>
<strong><span class="formatted-number">{viewcount}</span></strong> |
<span>browsing</span>
</small>
<div class="thread_active_users active-users inline-block"></div>
</div>
<div class="topic-main-buttons pull-right inline-block">
<button class="btn btn-primary post_reply" type="button">[[topic:reply]]</button>
<div class="btn-group thread-tools hide">
<button class="btn btn-default dropdown-toggle" data-toggle="dropdown" type="button">[[topic:thread_tools.title]] <span class="caret"></span></button>
<ul class="dropdown-menu">
<li><a href="#" class="pin_thread"><i class="icon-pushpin"></i> [[topic:thread_tools.pin]]</a></li>
<li><a href="#" class="lock_thread"><i class="icon-lock"></i> [[topic:thread_tools.lock]]</a></li>
<li class="divider"></li>
<li><a href="#" class="move_thread"><i class="icon-move"></i> [[topic:thread_tools.move]]</a></li>
<li class="divider"></li>
<li><a href="#" class="delete_thread"><span class="text-error"><i class="icon-trash"></i> [[topic:thread_tools.delete]]</span></a></li>
</ul>
</div>
</div>
<div style="clear:both;"></div>
</li>
<!-- BEGIN posts --> <!-- BEGIN posts -->
<li class="row post-row infiniteloaded" data-pid="{posts.pid}" data-uid="{posts.uid}" data-username="{posts.username}" data-deleted="{posts.deleted}" itemscope itemtype="http://schema.org/Comment">
<li class="row post-row sub-posts infiniteloaded" data-pid="{posts.pid}" data-uid="{posts.uid}" data-username="{posts.username}" data-deleted="{posts.deleted}" itemscope itemtype="http://schema.org/Comment">
<a id="post_anchor_{posts.pid}" name="{posts.pid}"></a> <a id="post_anchor_{posts.pid}" name="{posts.pid}"></a>
<meta itemprop="datePublished" content="{posts.relativeTime}"> <meta itemprop="datePublished" content="{posts.relativeTime}">
<meta itemprop="dateModified" content="{posts.relativeEditTime}"> <meta itemprop="dateModified" content="{posts.relativeEditTime}">
<div class="col-md-1 profile-image-block hidden-xs hidden-sm">
<div class="col-md-1 profile-image-block hidden-xs hidden-sm sub-post">
<a href="/user/{posts.userslug}"> <a href="/user/{posts.userslug}">
<img src="{posts.picture}" align="left" class="img-thumbnail" itemprop="image" /> <img src="{posts.picture}" align="left" class="img-thumbnail" itemprop="image" />
<span class="label label-danger {posts.show_banned}">[[topic:banned]]</span> <span class="label label-danger {posts.show_banned}">[[topic:banned]]</span>
</a> </a>
</div> </div>
<div class="col-md-11"> <div class="col-md-11">
<div class="post-block"> <div class="post-block">
<a class="main-post avatar" href="/user/{posts.userslug}">
<img itemprop="image" src="{posts.picture}" align="left" class="img-thumbnail" width=150 height=150 />
</a>
<h3 class="main-post">
<p id="topic_title_{posts.pid}" class="topic-title" itemprop="name">{topic_name}</p>
</h3>
<div class="topic-buttons"> <div class="topic-buttons">
<div class="btn-group"> <div class="btn-group">
<button class="btn btn-sm btn-default dropdown-toggle" data-toggle="dropdown" type="button" title="Posted by {posts.username}"> <button class="btn btn-sm btn-default dropdown-toggle" data-toggle="dropdown" type="button" title="Posted by {posts.username}">
@ -155,6 +62,7 @@
</div> </div>
<div class="btn-group"> <div class="btn-group">
<button class="btn btn-sm btn-default follow main-post" type="button" title="Be notified of new replies in this topic"><i class="icon-eye-open"></i></button>
<button class="favourite btn btn-sm btn-default {posts.fav_button_class}" type="button"> <button class="favourite btn btn-sm btn-default {posts.fav_button_class}" type="button">
<span class="favourite-text">[[topic:favourite]]</span> <span class="favourite-text">[[topic:favourite]]</span>
<span class="post_rep_{posts.pid}">{posts.post_rep} </span><i class="{posts.fav_star_class}"></i> <span class="post_rep_{posts.pid}">{posts.post_rep} </span><i class="{posts.fav_star_class}"></i>
@ -190,7 +98,38 @@
</div> </div>
</div> </div>
</li> </li>
<!-- IF @first -->
<li class="well post-bar">
<div class="inline-block">
<small class="topic-stats">
<span>posts</span>
<strong><span id="topic-post-count" class="formatted-number">{postcount}</span></strong> |
<span>views</span>
<strong><span class="formatted-number">{viewcount}</span></strong> |
<span>browsing</span>
</small>
<div class="thread_active_users active-users inline-block"></div>
</div>
<div class="topic-main-buttons pull-right inline-block">
<button class="btn btn-primary post_reply" type="button">[[topic:reply]]</button>
<div class="btn-group thread-tools hide">
<button class="btn btn-default dropdown-toggle" data-toggle="dropdown" type="button">[[topic:thread_tools.title]] <span class="caret"></span></button>
<ul class="dropdown-menu">
<li><a href="#" class="pin_thread"><i class="icon-pushpin"></i> [[topic:thread_tools.pin]]</a></li>
<li><a href="#" class="lock_thread"><i class="icon-lock"></i> [[topic:thread_tools.lock]]</a></li>
<li class="divider"></li>
<li><a href="#" class="move_thread"><i class="icon-move"></i> [[topic:thread_tools.move]]</a></li>
<li class="divider"></li>
<li><a href="#" class="delete_thread"><span class="text-error"><i class="icon-trash"></i> [[topic:thread_tools.delete]]</span></a></li>
</ul>
</div>
</div>
<div style="clear:both;"></div>
</li>
<!-- ENDIF @first -->
<!-- END posts --> <!-- END posts -->
</div>
</ul> </ul>
<div class="well col-md-11 col-xs-12 pull-right hide"> <div class="well col-md-11 col-xs-12 pull-right hide">

@ -13,7 +13,7 @@
<div class="input-group"> <div class="input-group">
<input class="form-control" id="search-user" type="text" placeholder="[[users:enter_username]]"/> <input class="form-control" id="search-user" type="text" placeholder="[[users:enter_username]]"/>
<span class="input-group-addon"> <span class="input-group-addon">
<span id="user-notfound-notify"><i class="icon icon-circle-blank"></i></span> <span id="user-notfound-notify"><i class="icon icon-search"></i></span>
</span> </span>
</div> </div>
</div> </div>

@ -33,18 +33,18 @@
var feed = new rss({ var feed = new rss({
title: topicData.topic_name, title: topicData.topic_name,
description: topicData.main_posts[0].content, description: topicData.posts[0].content,
feed_url: Feed.defaults.baseUrl + '/topics/' + tid + '.rss', feed_url: Feed.defaults.baseUrl + '/topics/' + tid + '.rss',
site_url: nconf.get('url') + 'topic/' + topicData.slug, site_url: nconf.get('url') + 'topic/' + topicData.slug,
image_url: topicData.main_posts[0].picture, image_url: topicData.posts[0].picture,
author: topicData.main_posts[0].username, author: topicData.posts[0].username,
ttl: Feed.defaults.ttl ttl: Feed.defaults.ttl
}), }),
topic_posts = topicData.main_posts.concat(topicData.posts), topic_posts = topicData.posts.concat(topicData.posts),
dateStamp; dateStamp;
// Add pubDate if topic contains posts // Add pubDate if topic contains posts
if (topicData.main_posts.length > 0) feed.pubDate = new Date(parseInt(topicData.main_posts[0].timestamp, 10)).toUTCString(); if (topicData.posts.length > 0) feed.pubDate = new Date(parseInt(topicData.posts[0].timestamp, 10)).toUTCString();
async.each(topic_posts, function(postData, next) { async.each(topic_posts, function(postData, next) {
if (postData.deleted === '0') { if (postData.deleted === '0') {

@ -1,5 +1,6 @@
var utils = require('./../public/src/utils.js'), var utils = require('./../public/src/utils.js'),
RDB = require('./redis.js'), RDB = require('./redis.js'),
plugins = require('./plugins'),
async = require('async'), async = require('async'),
path = require('path'), path = require('path'),
fs = require('fs'), fs = require('fs'),
@ -207,44 +208,46 @@ var utils = require('./../public/src/utils.js'),
], ],
minFile: path.join(__dirname, '..', 'public/src/nodebb.min.js'), minFile: path.join(__dirname, '..', 'public/src/nodebb.min.js'),
get: function (callback) { get: function (callback) {
var mtime, plugins.fireHook('filter:scripts.get', this.scripts, function(err, scripts) {
jsPaths = this.scripts.map(function (jsPath) { var mtime,
return path.join(__dirname, '..', '/public', jsPath); jsPaths = scripts.map(function (jsPath) {
}); return path.join(__dirname, '..', '/public', jsPath);
});
if (process.env.NODE_ENV !== 'development') { if (process.env.NODE_ENV !== 'development') {
async.parallel({ async.parallel({
mtime: function (next) { mtime: function (next) {
async.map(jsPaths, fs.stat, function (err, stats) { async.map(jsPaths, fs.stat, function (err, stats) {
async.reduce(stats, 0, function (memo, item, callback) { async.reduce(stats, 0, function (memo, item, callback) {
mtime = +new Date(item.mtime); mtime = +new Date(item.mtime);
callback(null, mtime > memo ? mtime : memo); callback(null, mtime > memo ? mtime : memo);
}, next); }, next);
}); });
}, },
minFile: function (next) { minFile: function (next) {
if (!fs.existsSync(Meta.js.minFile)) { if (!fs.existsSync(Meta.js.minFile)) {
if (process.env.NODE_ENV === 'development') winston.warn('No minified client-side library found'); if (process.env.NODE_ENV === 'development') winston.warn('No minified client-side library found');
return next(null, 0); return next(null, 0);
} }
fs.stat(Meta.js.minFile, function (err, stat) { fs.stat(Meta.js.minFile, function (err, stat) {
next(err, +new Date(stat.mtime)); next(err, +new Date(stat.mtime));
}); });
} }
}, function (err, results) { }, function (err, results) {
if (results.minFile > results.mtime) { if (results.minFile > results.mtime) {
if (process.env.NODE_ENV === 'development') winston.info('No changes to client-side libraries -- skipping minification'); if (process.env.NODE_ENV === 'development') winston.info('No changes to client-side libraries -- skipping minification');
callback(null, [path.relative(path.join(__dirname, '../public'), Meta.js.minFile)]);
} else {
Meta.js.minify(function () {
callback(null, [path.relative(path.join(__dirname, '../public'), Meta.js.minFile)]); callback(null, [path.relative(path.join(__dirname, '../public'), Meta.js.minFile)]);
}); } else {
} Meta.js.minify(function () {
}); callback(null, [path.relative(path.join(__dirname, '../public'), Meta.js.minFile)]);
} else { });
callback(null, this.scripts); }
} });
} else {
callback(null, scripts);
}
});
}, },
minify: function (callback) { minify: function (callback) {
var uglifyjs = require('uglify-js'), var uglifyjs = require('uglify-js'),

@ -513,8 +513,6 @@ var RDB = require('./redis.js'),
privileges = results[2], privileges = results[2],
categoryData = results[3]; categoryData = results[3];
var main_posts = topicPosts.splice(0, 1);
callback(null, { callback(null, {
'topic_name': topicData.title, 'topic_name': topicData.title,
'category_name': categoryData.name, 'category_name': categoryData.name,
@ -529,7 +527,6 @@ var RDB = require('./redis.js'),
'topic_id': tid, 'topic_id': tid,
'expose_tools': privileges.editable ? 1 : 0, 'expose_tools': privileges.editable ? 1 : 0,
'posts': topicPosts, 'posts': topicPosts,
'main_posts': main_posts,
'twitter-intent-url': 'https://twitter.com/intent/tweet?url=' + encodeURIComponent(nconf.get('url') + 'topic/' + topicData.slug) + '&text=' + encodeURIComponent(topicData.title), 'twitter-intent-url': 'https://twitter.com/intent/tweet?url=' + encodeURIComponent(nconf.get('url') + 'topic/' + topicData.slug) + '&text=' + encodeURIComponent(topicData.title),
'facebook-share-url': 'https://www.facebook.com/sharer/sharer.php?u=' + encodeURIComponent(nconf.get('url') + 'topic/' + topicData.slug), 'facebook-share-url': 'https://www.facebook.com/sharer/sharer.php?u=' + encodeURIComponent(nconf.get('url') + 'topic/' + topicData.slug),
'google-share-url': 'https://plus.google.com/share?url=' + encodeURIComponent(nconf.get('url') + 'topic/' + topicData.slug) 'google-share-url': 'https://plus.google.com/share?url=' + encodeURIComponent(nconf.get('url') + 'topic/' + topicData.slug)

@ -35,17 +35,21 @@ var path = require('path'),
var templates = null, var templates = null,
clientScripts; clientScripts;
// Minify client-side libraries
meta.js.get(function (err, scripts) { plugins.ready(function() {
clientScripts = scripts.map(function (script) { // Minify client-side libraries
script = { meta.js.get(function (err, scripts) {
script: script clientScripts = scripts.map(function (script) {
}; script = {
script: script
return script; };
return script;
});
}); });
}); });
server.app = app; server.app = app;
/** /**
@ -318,6 +322,7 @@ var path = require('path'),
}); });
}); });
plugins.fireHook('action:app.load');
translator.translate(templates.logout.toString(), function(parsedTemplate) { translator.translate(templates.logout.toString(), function(parsedTemplate) {
templates.logout = parsedTemplate; templates.logout = parsedTemplate;
@ -338,7 +343,6 @@ var path = require('path'),
userRoute.createRoutes(app); userRoute.createRoutes(app);
apiRoute.createRoutes(app); apiRoute.createRoutes(app);
// Basic Routes (entirely client-side parsed, goal is to move the rest of the crap in this file into this one section) // Basic Routes (entirely client-side parsed, goal is to move the rest of the crap in this file into this one section)
(function () { (function () {
var routes = ['login', 'register', 'account', 'recent', '403', '404'], var routes = ['login', 'register', 'account', 'recent', '403', '404'],
@ -475,7 +479,7 @@ var path = require('path'),
content: topicData.topic_name content: topicData.topic_name
}, { }, {
name: "description", name: "description",
content: sanitize(topicData.main_posts[0].content.substr(0, 255)).escape().replace('\n', '') content: sanitize(topicData.posts[0].content.substr(0, 255)).escape().replace('\n', '')
}, { }, {
property: 'og:title', property: 'og:title',
content: topicData.topic_name + ' | ' + (meta.config.title || 'NodeBB') content: topicData.topic_name + ' | ' + (meta.config.title || 'NodeBB')
@ -487,10 +491,10 @@ var path = require('path'),
content: nconf.get('url') + 'topic/' + topicData.slug content: nconf.get('url') + 'topic/' + topicData.slug
}, { }, {
property: 'og:image', property: 'og:image',
content: topicData.main_posts[0].picture content: topicData.posts[0].picture
}, { }, {
property: "article:published_time", property: "article:published_time",
content: new Date(parseInt(topicData.main_posts[0].timestamp, 10)).toISOString() content: new Date(parseInt(topicData.posts[0].timestamp, 10)).toISOString()
}, { }, {
property: 'article:modified_time', property: 'article:modified_time',
content: new Date(lastMod).toISOString() content: new Date(lastMod).toISOString()

Loading…
Cancel
Save