Passing custom data into a template?

  • @baris

    WOW thanks man.

    One thing though myPlugin.onRenderHeader = function() {}

    This works, thanks! So I am guessing callback() is where the data is sent to the core then that adds it before rendering?

    Great job!

  • NodeBB Admin

    Yes, the hook is fired right before the header is rendered here. You add the categories into the templateValues which is then passed to app.render and rendered.

  • @baris I am not sure my question is related to this topic, but I have searched a lot about how to get the specific post data from a specific category to put them on the customize home page for my current site. For example, I have a category called "News", and what I want is each time when I post a new post in this category, I want the post also to show up on the home page. Since I am using custom home page plugin, so all I can do is insert HTML and those data like categories, recent post or popular post. I am a bit of confusion about how to exactly get those data and linked them to the home page? Thank you.

  • @baris said in Passing custom data into a template?:

    You can do what you want with the filter:middleware.renderHeader hook.

    old topic, new developer

    thanks.. that is very helpful

    I have one question
    I have a filter:post.shouldQueue plugin, it needs to check a list of data items on each post.
    I load the data at plugin init time using meta...

    	meta.settings.get(my_data_key, function(err, settings) {

    my plugin registers the routes for the admin pages, which causes the static admin,js to run and the template to load, which loads or saves the data (separate from plugin operation code)
    // copied from old category-queue plugin, admin.js

    	ACP.init = function () {
    		Settings.load(my_data_key, $('.key_class_settings'));
    		$('#save').on('click', function () {, $('.key_class_settings'), function () {

    how do I inform the plugin that the data has changed on save? cause init should only run once.

    is there some data/key 'onchange' (hook) I can register for to reload it so that my operational data is accurate?

    seems bad to get it on every post, as it will almost never change (except when admin/save is checked

    i haven't figured out template code to add/delete items from the list yet.. (more js event handlers I presume)

  • NodeBB Admin

    'action:settings.set' this hook fires when you save plugin settings. It will receive the name of the settings object.'action:settings.set', {
    		plugin: hash,
    		settings: { ...values, ...sortedListData }, 

    So in your plugin you can update your settings in this hook like so.

    myPlugin.actionSettingsSet = async function (hookData) {
      if (hookData.plugin === my_data_key) {
          my_local_settings = await meta.settings.get(my_data_key);

  • @baris so, I am SO close.. just adding admin pages...

    repo here

    the postqueue function works
    the link shows for admin

    Screenshot at 2022-08-30 15-06-58.png

    the admin template shows when u click the link,

    Screenshot at 2022-08-30 15-06-27.png

    but no data, the header hook for data doesn't fire

    and I get that error

    the static/lib/admin.js doesn't fire

    its the '.' I am sure, but why and from where.. the log shows status 200 for loading content.. no 404..

    npm i the repo,
    rebuild and relaunch
    go to admin, plugins, click the link post_link_list

    npmi the

  • NodeBB Admin

    I think you are missing the plugin.json entry for your admin page javascript, take a look at how persona adds the admin page javascript.

    You need an try in your plugin.json like that.

  • @baris thanks.. that is a completely different plugin.json layout.

    maybe I started with an old module format..

    it WAS working yesterday.. so I'll go back to that commit and see if I can find the difference

  • @baris this page shows the format required by the 2.4.5 version I am on..

    it is similar to mine

    also, my admin.js IS loaded and run

    as the messages from the run are shown at the client
    (browser dev winbow console)

    /plugins/post_link_list admin define running
    /plugins/post_link_list admin define ending returning acp keys= ['init']

    but the actual init() method is not called.

    adding the module entry to plugin.json solved the error and the init is now called...

  • NodeBB Admin

    Yeah you need your admin.js file in the modules section, acpScripts is for scripts that will be run whenever the admin site is loaded, think of them as global javascript that you want to include on the ACP site. modules section is for new pages for plugins or custom js modules. They are loaded on demand when the user navigates to your page.

  • @baris ok, thanks. but none of that makes sense.. sorry.. 'user' is only admin in my case.

    added on the ACP site (for what purpose if not for when the user navigates)?

    i don't want it to run twice.. so it sounds like do NOT use acpScripts..

    but. back on the custom data to the template

    I see two different approaches used.. (neither work for me)

    some modules use admin to use the settings api to load the values into a css class using jquery $('.someclassname')
    which the template uses somehow, but unclear ${'../name'}

    Settings.load('category-queue', $('.category-queue-settings'));
    			<form role="form" class="category-queue-settings">
    				<!-- BEGIN categories -->
    				<div class="form-group col-sm-4 col-xs-6">
    					<label for="{../cid}">{../name}</label>

    and the other passes data in the call to res.render(page, {data structure})
    in lib/controllers/renderAdmin()
    then the template uses the data structure elements clearly.

    my data is an array.. no internal named elements (presumably that is the ${../name} thing...accessing the object elements
    and there is no for loop construct in the template, so I don't see how it generates 4 instances in the output...

    sorry, one more question on templates.. is there any way to test them outside trying to load the plugin.. cause they are not generating the content I expect, but don't see any errors during build or run

  • NodeBB Admin

    In your plugin's case you would need to move your admin js file to the modules section like so

    "modules": {
      "../admin/plugins/post_link_list.js": "static/lib/admin.js",

    And remove it from acpScripts.

    When you do this static/lib/admin.js will be loaded and its init method will be called when the user(admin) navigates to your plugin page.

    Now settings.load uses some client side code to load the settings and fill in the input elements on the plugin page. So when that is called from the init function of the admin page. It will populate the forum fields. If you are storing a list of urls I suggest storing them as a string and displaying them in a text area. You can inspect it does something similar.

  • @baris thanks.. I want to have a field for each url string. (from the array)

    have an input field to add another with a click
    and some selector (minus sign, checkbox...) and click to remove..

    but the templating engine is killing me.. I don't know what the syntax is for non structure objects..

    {{{each post_link_list}}}

    gets me a line for each.. good.. what is its value?

    hm... now it works ok?
    @value says object.. (oops, put in {}), now compiler says use {} as required in 3.x)

    hm.. could use its array index tho...

    this post_link_list comes from the render..

    can I use meta from admin (as module) ? (button click handler) ..
    hm.. can't import meta in admin..

  • @baris well, got almost all of it working, list, add, delete, save button

    now to update the database

    I have the hook on save, so I can reload the operational list and use it to inform the admin page

    it will be loaded via meta.get in the index.js (it doesn't return any data now, as there isn't any)
    but meta isn't usable in admin..

    settings is, but I don't see a save or (or load) method in the src/settings.js
    but from quickstart admin.js
    settings.load('quickstart', $('.quickstart-settings'), function () {

    i want to save from a JS variable. but that causes some error not in the log, and I get the spinning circle saying my plugin is taking a long time.,

    so close..
    the admin code that gets the save click to save

    			var selected = [];
    			$('#urls').find('input[type="text"]').each(function() {
    			console.log("urls to save=",selected)
    		try {,selected, (err,sss)=>{

    and the dev window console log

    post_link_list save  clicked 
    urls to save= (4) ['', '', '', '']
    post_link_list settings save executed
    settings save completed

    the node bb log capturing from index
    this is the output of setting save(), have the right 'hash', well its the 'key' I sent in
    similar to all the other plugins I looked at

    but no data

    io: 1 on [
        type: 2,
        nsp: '/',
        id: 8,
        data: [ 'admin.settings.set', { hash: 'post_link_list', values: {} } ]

    in index , the hook

    settings saved for  { plugin: 'post_link_list', settings: {}, caller: { uid: 1 } }

  • @baris debugging why my settings don't save

    I see the value in the hook now.. the 'value' MUST be a keyed object... not flat

    but still no persistence.

    I see the action hook is called before informing meta to reload..

    but even when I stop and restart nodebb the data is not current

  • NodeBB Admin

    @sdetweil I suggest you take a look at It has an admin page that saves a list of strings. You can compare it to yours and see why your data isn't being saved.

  • @baris thanks. altho the typical plugin doesn't do it, the settings apis are promisified. you don't wait, u get junk..

    adding .then() in the non async using functions solves the problem

Suggested Topics

  • 1
  • 1
  • 3
  • 8
  • 5
| | | |