Adding a new page


  • Global Moderator

    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);


  • Global Moderator

    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.


  • Global Moderator

    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.


  • Global Moderator

    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?


  • Global Moderator

    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.


  • Global Moderator

    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?



  • I am working on my local machine. the map div element is never there in any of the cases.



  • Today I spent more time trying to find out the solution, mostly were hit and trials, I don't know what happened but "Error: Map Container not found" vanished somehow. And the map was in the dom.

    During debugging, I found the original copy of the main.js that I copied from the demo plugin (the one suggested by Pita in the above-mentioned posts) was residing in the node_modules/map-plugin directory. I can't understand why .. it was overwritten umpteen number of times.

    Anyhow so far so good. Now I have to address two issues:
    a. Map is still not displayed. This is something beyond the scope of NodeBB and I have to do it of my own.

    b. And when I browse the localhost/map from the URL and press enter, the boolean (the one PitaJ hinted at yesterday) is set to true and the map functionality is getting invoked. But when I click on the map icon, the map functionality is not executed. Do you have any ideas how to fix this?

    Thank you for your kind support


  • Global Moderator

    So, in order to support both cold load and ajaxify, I use a pattern like the following to run scripts that need to run on a certain page:

    function onLoad() {
      // in your case 'map'
      if (ajaxify.data.template.map) {
        // do stuff here
      }
    }
    
    $(document).ready(onLoad);
    $(window).on('action:ajaxify.end', onLoad);
    

Log in to reply
 


Star

Looks like your connection to NodeBB was lost, please wait while we try to reconnect.