• 2 Votes
    8 Posts
    WWW Diplomacy Facade - a Frontpage Manger / Landing Page NodeBB Feature

    How to onboard users when in a registered access only mode.

    If you run a login only forum. A most severe way to stop all crawlers. You lose www visbility.

    While this may protect overall privacy in an iron curtain fashion, you most probably still need something to hook and onboard users to your wonderful NodeBB resource, if it's not run as an internal private platform, for e.g. a corporate entity across branches and continents, then you really most likely still do need to be open somehow to the world wide web.

    One solution, is to stick a wordpress (or similar) frontend in front of NodeBB, and curate and control what the www sees, and offer the NodeBB forum as a big sign-up bonus. However, there are a lot of undesirable aspect to this as a solution, and IMHO is teh sub-optimal solution because:

    increases or split hosting costs requires a different support set wordpress / php is a big attack vector

    Another solution, one which must be the optimal for sake of staying within the NodeBB system and adhering to Less is most certainly More, thus incurring no extra hosting or maintenance costs, would be to have a Wordpress or CMS-lite like feature and manager the creates unique Landing page(s) as an alternative to any of the existing landing pages.

    It's called Facade and it's a NodeBB vapourware or vapourfeature existing in this post, and here is how it might work in a most basic form:

    Facade - Create Unique Dynamic Landing pages In NodeBB

    Can populate landing-page/homepage with existing topics and/or bespoke content Widget expansive layout What else?

    Rambling note: Understandably there is overlap with Custom Static pages for NodeBB plugin (caveat: it's been some time I played with that so do not remember the complete feature set) but in this vision the content can also be also be dynamic.

    If it were then as simple to customise your landing page as you drag and drop categories in the admin panel which is a neat and beautifully implemented feature for organising layout of the categories page, then we're smokin', expand what already works to enable new features, it might mean best path is to take custom static pages into core to roll in more of the above functionality and features.

  • 0 Votes
    6 Posts

    @DownPW said in [nodebb-widget-board-stats] discrepancy to dashboard count:

    any news @murcs ?

    i just digged a little deeper for you: „our“ /var/www/nodebb/node_modules/nodebb-widget-board-stats/library.js looks like this

    'use strict'; const async = require('async'); const nconf = module.parent.require('nconf'); const db = require.main.require('./src/database'); const user = require.main.require('./src/user'); const utils = require.main.require('./src/utils'); const socketPlugins = require.main.require('./src/socket.io/plugins'); const socketRooms = require.main.require('./src/socket.io/admin/rooms'); let app; const Widget = module.exports; Widget.init = function (params, callback) { app = params.app; callback(); }; socketPlugins.boardStats = {}; socketPlugins.boardStats.get = function (socket, tid, callback) { getWidgetData(callback); }; function addDots(text) { return String(text).replace(/(\d)(?=(\d\d\d)+(?!\d))/g, '$1.'); }; function getWidgetData(callback) { async.parallel({ global: function (next) { db.getObjectFields('global', ['topicCount', 'postCount', 'userCount'], next); }, latestUser: getLatestUser, activeUsers: getActiveUsers, onlineUsers: Widget.updateAndGetOnlineUsers, activeWithin24h: function (next) { var now = Date.now(); db.sortedSetCount('users:online', now - 86400000, '+inf', next); }, }, function (err, results) { if (err) { return callback(err); } var data = { within24h: results.activeWithin24h, count: addDots(results.onlineUsers.onlineCount + results.onlineUsers.guestCount), members: addDots(results.onlineUsers.onlineCount), guests: addDots(results.onlineUsers.guestCount), list: joinUsers(results.activeUsers), posts: addDots(results.global.postCount ? results.global.postCount : 0), topics: addDots(results.global.topicCount ? results.global.topicCount : 0), registered: addDots(results.global.userCount ? results.global.userCount : 0), latest: joinUsers(results.latestUser), relative_path: nconf.get('relative_path'), mostUsers: { date: (new Date(parseInt(results.onlineUsers.timestamp, 10))).toDateString(), total: results.onlineUsers.total, }, }; callback(null, data); }); } function getActiveUsers(callback) { async.waterfall([ function (next) { user.getUidsFromSet('users:online', 0, 19, next); }, function (uids, next) { user.getUsersFields(uids, ['username', 'userslug', 'status'], next); }, ], function (err, data) { if (err) { return callback(err); } data = data.filter(function (a) { return a.status === 'online'; }); callback(err, data); }); } function getLatestUser(callback) { async.waterfall([ function (next) { user.getUidsFromSet('users:joindate', 0, 0, next); }, function (uids, next) { user.getUsersWithFields(uids, ['username', 'userslug'], 0, next); }, ], callback); } function joinUsers(usersData) { var str = []; for (var i = 0, ii = usersData.length; i < ii; i++) { str.push('<a href="' + nconf.get('relative_path') + '/user/' + usersData[i].userslug + '">' + usersData[i].username + '</a>'); } return str.join(', '); } Widget.updateAndGetOnlineUsers = function (callback) { callback = typeof callback === 'function' ? callback : function () {}; async.waterfall([ function (next) { next(null, socketRooms.getLocalStats().onlineRegisteredCount); }, function (onlineCount, next) { socketRooms.getTotalGuestCount(function (err, guestCount) { if (err) { return next(err); } next(null, { onlineCount: parseInt(onlineCount, 10), guestCount: parseInt(guestCount, 10), }); }); }, function (users, next) { db.getObjectFields('plugin:widget-board-stats', ['total', 'timestamp'], function (err, data) { if (err) { return next(err); } var totalUsers = users.onlineCount + users.guestCount; data.timestamp = data.timestamp || Date.now(); if (parseInt(data.total || 0, 10) <= totalUsers) { data.timestamp = Date.now(); data.total = totalUsers; db.setObject('plugin:widget-board-stats', data); } data.onlineCount = users.onlineCount; data.guestCount = users.guestCount; return next(null, data); }); }, ], callback); }; Widget.renderWidget = function (widget, callback) { getWidgetData(function (err, data) { if (err) { return callback(err); } app.render('widgets/board-stats', data, function (err, html) { if (err) { return callback(err); } widget.html = html; callback(null, widget); }); }); }; Widget.defineWidgets = function (widgets, callback) { var widget = { widget: 'board-stats', name: 'Board Stats', description: 'Classical board stats widget in real-time.', content: 'admin/board-stats', }; app.render(widget.content, {}, function (err, html) { widget.content = html; widgets.push(widget); callback(err, widgets); }); };

    which corresponds with our localized version of /var/www/nodebb/node_modules/nodebb-widget-board-stats/public/templates/widgets/board-stats.tpl

    <div component="widget/board-stats" class="widget-board-stats" style="border: 1px solid #999"> <h3 style="background: #666; font-size: 15px; font-weight: 500">Folgende Nutzende sind gerade online: <a href="{config.relative_path}/users?section=online">[komplette Liste]</a></h3> <p> Davon sind aktuell <strong component="widget/board-stats/count">{count}</strong> Nutzende aktiv (<strong component="widget/board-stats/members">{members}</strong> Registrierte + <strong component="widget/board-stats/guests">{guests}</strong>G&auml;ste).<br /> <span style="display: block; line-height: 0.5em" >&nbsp;</span> <span component="widget/board-stats/list">{list}</span> <span style="display: block; line-height: 0.5em" >&nbsp;</span> In den letzten 24 Stunden waren <strong component="widget/board-stats/within24h">{within24h}</strong> verschiedene Nutzende eingeloggt. </p> <h3 style="background: #666; font-size: 15px; font-weight: 500">Forum-Statistik</h3> <p> Unsere aktiven registrierten Mitglieder haben <strong component="widget/board-stats/posts">{posts}</strong> Beitr&auml;ge zu <strong component="widget/board-stats/topics">{topics}</strong> Themen verfasst &ndash;<strong component="widget/board-stats/registered">{registered}</strong> Mitglieder sind bei <em>schoenen-dunk.de</em> registriert.<br /> <span style="display: block; line-height: 0.5em" >&nbsp;</span> <span component="widget/board-stats/latest">{latest}</span> ist unser neuestes Mitglied.&nbsp;Herzlich Willkommen!<br /> <span style="display: block; line-height: 0.5em" >&nbsp;</span> Am {mostUsers.date} waren <strong>{mostUsers.total}</strong> Nutzende gleichzeitig online. </p> </div>

    well.  i hope this helps a bit.

    ober!schöne grüße,

  • 0 Votes
    3 Posts

    Well, I only added that one a month ago 😄 It will be in 1.13.0, as @oplik0 says. You can of course, use latest master if you'd like.

  • 0 Votes
    1 Posts

    We can do it if the window isn't too slim, and if I'm in Landscape mode it also lets me hit the red circle, so why not enable it for mobile?

  • 0 Votes
    4 Posts

    @henrywright said:

    this idea wouldn't work if > 1 line change

    I was referring to my idea of making a manual 1-line change to the theme core at the point of each upgrade. That would avoid you having to use Git to merge in new commits each upgrade.

    Again, although not a clean way of working, it sounds like it'll be easier than what you're currently doing.

  • 0 Votes
    1 Posts

    As I wrote before, this feature will be very nice (can't understand why it doesn't exist on the core already), and helpful to have.

    I am referring to a feature that will allow replies (either a reply or quote reply) to a comment within a topic, to link back to the comment/quoted comment.

  • Group chats

    Feature Requests
    7 Votes
    6 Posts

    I am fairly sure this would be our no. 1 feature request as well. Group chats, without it .. it just feels like 2003 all over again. 👍

  • 0 Votes
    6 Posts

    Looks like its only in 0.6.x

  • 0 Votes
    6 Posts