Adding a new page

NodeBB Development
  • My requirement was to add a map icon and the corresponding route /map besides the other NodeBB icons i.e. Users, Tags, etc. I was able to modify the code and add it.

    Now I want to display a map in the "/map" page with the corresponding backend storing the latitude and longitude etc. of a particular user. But I am stuck. I looked at the existing .tpl files and to my surprise, they belong to the node_modules folders.

    Could anybody pl. guide me what is the best way to address this requirement?

    Thanks

  • You want to create a plugin to do this. Take a look at nodebb-plugin-quickstart

  • Thank you for the reply. By creating a new plugin, I am still unaware about how to add/display a map icon besides the other standard NodeBB icons like Tags, Users, etc.

    I went through this example plugin but still not successful. Can you pl. guide me further?

  • You want to display a navigation icon? The easiest way is to just add a new custom item at ACP -> General -> Navigation.

  • No.. not only simple display but with lots of additional functionality.. When the icon is clicked, I need to show a map and allow the user to place a marker on it and then save the corresponding latitude/longitude in the db.

  • Thanks I am able to add a custom icon including the route. Now could you pl. let me know where (in which files) in the associated plugin I am supposed to write the logic for this route?

  • //My Map Plugin: library.js
    plugin.init = function(params, callback) {
    	var router = params.router,
    		hostMiddleware = params.middleware,
    		hostControllers = params.controllers;
    		
    	router.get('/map', hostMiddleware.admin.buildHeader, controllers.renderMapPage);
    	router.get('/api/map', controllers.renderMapPage);
    	callback();
    };
    

    When I browse this URL: localhost/map

    I get the error in /public/src/admin/admin.js
    Line Number: 122 -- Cannot read matches property of null I debugged it and the undefined is the matches variable.

    Are these routes correct?
    router.get('/map', hostMiddleware.admin.buildHeader, controllers.renderMapPage);
    router.get('/api/map', controllers.renderMapPage);

  • Yeah those should work. What is inside renderMapPage? The error you mentioned is a client-side error in the ACP, I can't think of any reason that would occur because of something you did, it's probably unrelated.

  • Thank you for your kind support, Pita.

    Controllers.renderMapPage = function (req, res, next) {
    //Render the templates/map.tpl
    res.render('map', {});
    };

    Kindly help me solve it.

  • I think admin.js is expecting a url something like this... /admin/plugin/map whereas in my case it is simply "/map" I may not be correct.

    Kindly note that when I click the Map icon (whose route is /map) things work fine. But when I browse by entering this localhost/map in the browser and press Enter, it throws a client-side error in admin.js file.

  • Oh, sorry, I missed that issue. It should be hostMiddleware.buildHeader, not hostMiddleware.admin.buildHeader. Remove the admin part, as it tells the server to render map as part of the admin control panel.

  • You are awesome. It worked. Thanks once again.

    So I will place my third-party client-side JS libraries in static/lib (alngside main.js) And the system will minify/uglify them. Right?

  • My map.tpl
    <div id="mapid" class="map"></div>

    My plugin.json
    "scripts": [
    "static/lib/main.js"
    ],

    My main.js

      $(document).ready(function() {
    requirejs(["leaflet"], function(L) {
    
    		var map = L.map('mapid', {
    			attributionControl: false
    		}).setView(initialLocation, 12);
    

    ...

    Error: leaflet Uncaught Error: Map container not found.

    The <div id="mapid"> must be added to the DOM before calling L.map('mapid').

    This jquery reaady function is called after the DOM and page (map.tpl) are loaded. But still getting error. Where am I wrong?

    Kindly help me.

  • The way you have it there, it will run on every page. I'd suggest checking ajaxify.data.template.map (a boolean) before running those things.

    You might try putting a debugger; statement in there before the require call and check that the map is actually in the DOM when you expect it to be.

  • if(ajaxify.data.template.map == true) {

    requirejs(["leaflet"], function(L) {
    

    ...
    }

    It returns undefined everytime including when I click the map icon. It returns true only when I enter this URL: localhost/map and press Enter. When it returns true, the "Error: leaflet Uncaught Error: Map container not found." is still there.

    I will use the debugger; and see what it reports.

  • Using the debugger statement indicated that the map is not in the DOM

  • Any answers?

  • So if the map element isn't in the DOM, there's probably something wrong with your template. Check it, make sure it is correct. Check the built template in nodebb/build/public/templates to make sure it is correct.

  • The map.tpl has just one line. And the map.tpl in the build directory is simply a replica of my map.tpl.

  • Ok, and when you go to /map directly, that is, not from another link on your site, is the map element in the source for the page?


Suggested Topics