• Swedes

    I'm at the moment adapting my plugins for v2 and ran into an issue with template helper functions. I've until now included them as below, so they work both when rendered on the server and the client.

    'use strict';
    
    /* globals */
    
    (function (factory) {
    	if (typeof module === 'object' && module.exports) {
    		factory(require.main.require('benchpressjs'));
    	} else {
    		require(['benchpress'], factory);
    	}
    }((Benchpress) => {
    	const number_of_answers = (data) => {
    		const replies = data.postcount - 1;
    
    		switch (replies) {
    			case 0:
    				return 'No comments';
    			case 1:
    				return '1 comment';
    			default:
    				return `${replies} comments`;
    		}
    	};
    
    	const customHelpers = {
    		number_of_answers,
    	};
    
    	function register() {
    		Object.keys(customHelpers).forEach((helperName) => {
    			Benchpress.registerHelper(helperName, customHelpers[helperName]);
    		});
    	}
    
    	register();
    
    	if (typeof module === 'object' && module.exports) {
    		module.exports = customHelpers;
    	}
    }));
    
    

    This has worked great but now that I'm running v2 (2.0.0) it only works server side. I'm including the file in plugin.json under scripts, "lib/helpers.js".

    One guess is that I should move it to modules as other client scripts, but I'm not sure how I should do that with template helpers.

    Appreciate all help.

  • NodeBB

    Here is a sample that adds a custom helper to persona. You can make the necessary changes to add to your own theme.

    Create the files

    • lib/customHelpers.js (server side)
    'use strict';
    
    module.exports = require('../public/modules/customHelpers-common')(
        require.main.require('benchpressjs')
    );
    
    • public/modules/customHelpers.js (client side)
    'use strict';
    
    const factory = require('./customHelpers-common');
    
    define(['benchpress'], function (Benchpressjs) {
    	return factory(Benchpressjs);
    });
    
    • public/modules/customHelpers-common.js (shared)
    'use strict';
    
    /* globals */
    
    module.exports = function (Benchpress) {
    	const number_of_answers = (data) => {
    		const replies = data.postcount - 1;
    		// see where the helper is called from
    		console.log('CALLED!', typeof window !== 'undefined' ? 'window' : 'node');
    		switch (replies) {
    			case 0:
    				return 'No comments';
    			case 1:
    				return '1 comment';
    			default:
    				return `${replies} comments`;
    		}
    	};
    
    	const customHelpers = {
    		number_of_answers,
    	};
    
    	function register() {
    		Object.keys(customHelpers).forEach((helperName) => {
    			Benchpress.registerHelper(helperName, customHelpers[helperName]);
    		});
    	}
    
    	register();
    
    	return customHelpers;
    };
    

    With those files in place you can link them up so that the new helper is available on client/server. See the diff below

    diff --git a/library.js b/library.js
    index e7b7b6c..0641b03 100644
    --- a/library.js
    +++ b/library.js
    @@ -19,6 +19,8 @@ library.init = async function (params) {
     		middleware.canViewUsers,
     		middleware.checkAccountPermissions,
     	], controllers.renderThemeSettings);
    +
    +	require('./lib/customHelpers'); // register for server side
     };
     
     library.addAdminNavigation = async function (header) {
    diff --git a/plugin.json b/plugin.json
    index 4716e49..f317129 100644
    --- a/plugin.json
    +++ b/plugin.json
    @@ -15,7 +15,9 @@
     	"modules": {
     		"../admin/plugins/persona.js": "public/admin.js",
     		"persona/quickreply.js": "public/modules/quickreply.js",
    -		"../client/account/theme.js": "public/settings.js"
    +		"../client/account/theme.js": "public/settings.js",
    +		"persona/customHelpers.js": "public/modules/customHelpers.js",
    +		"persona/customHelpers-common.js": "public/modules/customHelpers-common.js"
     	},
     	"languages": "languages"
     }
    \ No newline at end of file
    diff --git a/public/persona.js b/public/persona.js
    index d3699ed..50e0476 100644
    --- a/public/persona.js
    +++ b/public/persona.js
    @@ -12,6 +12,8 @@ $(document).ready(function () {
     	$(window).on('resize', utils.debounce(configureNavbarHiding, 200));
     	$(window).on('resize', updatePanelOffset);
     
    +	require(['persona/customHelpers']); // register client side
    +
     	function updatePanelOffset() {
     		const headerEl = document.getElementById('header-menu');
     
    diff --git a/templates/topic.tpl b/templates/topic.tpl
    index a42dfa3..6c6cb69 100644
    --- a/templates/topic.tpl
    +++ b/templates/topic.tpl
    @@ -3,6 +3,10 @@
     	{{widgets.header.html}}
     	{{{end}}}
     </div>
    
    {number_of_answers(@root)} <!-- use helper -->
    
     <div class="row">
     	<div class="topic <!-- IF widgets.sidebar.length -->col-lg-9 col-sm-12<!-- ELSE -->col-lg-12<!-- ENDIF widgets.sidebar.length -->">
     		<div class="topic-header">
    
  • Swedes

    I get the following error client side:

    Uncaught TypeError: can't access property "registerHelper", Benchpress is undefined

  • Global Moderator Plugin & Theme Dev

    Can you try putting a console.log in the if statement to check which one works?

  • GNU/Linux Admin

    @magnusvhendin said:

    One guess is that I should move it to modules as other client scripts, but I'm not sure how I should do that with template helpers.

    I didn't end up doing it that way. I was writing a custom plugin that needed a helper, and I ended up doing it via a script added to scripts in plugin.json.

    I cannot share the code as it is in a private repo, but —

    require(['benchpress'], (benchpress) => {
      benchpress.registerHelper('myHelper', (data) => {
        // ...
      });
    });
    

    I only used a client-side helper. I believe I looked into it and for whatever reason, no server-side helper needed to be registered, it just worked 🤷

  • NodeBB

    You might have to follow the same pattern we do in core. Take a look at these 3 files in core for helpers.

    // client side
    https://github.com/NodeBB/NodeBB/blob/master/public/src/modules/helpers.js

    // server side
    https://github.com/NodeBB/NodeBB/blob/master/src/helpers.js

    // common
    https://github.com/NodeBB/NodeBB/blob/master/public/src/modules/helpers.common.js

  • NodeBB

    Here is a sample that adds a custom helper to persona. You can make the necessary changes to add to your own theme.

    Create the files

    • lib/customHelpers.js (server side)
    'use strict';
    
    module.exports = require('../public/modules/customHelpers-common')(
        require.main.require('benchpressjs')
    );
    
    • public/modules/customHelpers.js (client side)
    'use strict';
    
    const factory = require('./customHelpers-common');
    
    define(['benchpress'], function (Benchpressjs) {
    	return factory(Benchpressjs);
    });
    
    • public/modules/customHelpers-common.js (shared)
    'use strict';
    
    /* globals */
    
    module.exports = function (Benchpress) {
    	const number_of_answers = (data) => {
    		const replies = data.postcount - 1;
    		// see where the helper is called from
    		console.log('CALLED!', typeof window !== 'undefined' ? 'window' : 'node');
    		switch (replies) {
    			case 0:
    				return 'No comments';
    			case 1:
    				return '1 comment';
    			default:
    				return `${replies} comments`;
    		}
    	};
    
    	const customHelpers = {
    		number_of_answers,
    	};
    
    	function register() {
    		Object.keys(customHelpers).forEach((helperName) => {
    			Benchpress.registerHelper(helperName, customHelpers[helperName]);
    		});
    	}
    
    	register();
    
    	return customHelpers;
    };
    

    With those files in place you can link them up so that the new helper is available on client/server. See the diff below

    diff --git a/library.js b/library.js
    index e7b7b6c..0641b03 100644
    --- a/library.js
    +++ b/library.js
    @@ -19,6 +19,8 @@ library.init = async function (params) {
     		middleware.canViewUsers,
     		middleware.checkAccountPermissions,
     	], controllers.renderThemeSettings);
    +
    +	require('./lib/customHelpers'); // register for server side
     };
     
     library.addAdminNavigation = async function (header) {
    diff --git a/plugin.json b/plugin.json
    index 4716e49..f317129 100644
    --- a/plugin.json
    +++ b/plugin.json
    @@ -15,7 +15,9 @@
     	"modules": {
     		"../admin/plugins/persona.js": "public/admin.js",
     		"persona/quickreply.js": "public/modules/quickreply.js",
    -		"../client/account/theme.js": "public/settings.js"
    +		"../client/account/theme.js": "public/settings.js",
    +		"persona/customHelpers.js": "public/modules/customHelpers.js",
    +		"persona/customHelpers-common.js": "public/modules/customHelpers-common.js"
     	},
     	"languages": "languages"
     }
    \ No newline at end of file
    diff --git a/public/persona.js b/public/persona.js
    index d3699ed..50e0476 100644
    --- a/public/persona.js
    +++ b/public/persona.js
    @@ -12,6 +12,8 @@ $(document).ready(function () {
     	$(window).on('resize', utils.debounce(configureNavbarHiding, 200));
     	$(window).on('resize', updatePanelOffset);
     
    +	require(['persona/customHelpers']); // register client side
    +
     	function updatePanelOffset() {
     		const headerEl = document.getElementById('header-menu');
     
    diff --git a/templates/topic.tpl b/templates/topic.tpl
    index a42dfa3..6c6cb69 100644
    --- a/templates/topic.tpl
    +++ b/templates/topic.tpl
    @@ -3,6 +3,10 @@
     	{{widgets.header.html}}
     	{{{end}}}
     </div>
    
    {number_of_answers(@root)} <!-- use helper -->
    
     <div class="row">
     	<div class="topic <!-- IF widgets.sidebar.length -->col-lg-9 col-sm-12<!-- ELSE -->col-lg-12<!-- ENDIF widgets.sidebar.length -->">
     		<div class="topic-header">
    
  • Topic has been marked as solved  magnusvhendin magnusvhendin 
  • Swedes

    @baris This worked like a charm. Thank you!


Suggested Topics

| | |

© 2014 – 2022 NodeBB, Inc. — Made in Canada.