how to build sitemap in express js?

2.6k Views Asked by At

I'm trying to use sitemap.js package located at https://www.npmjs.org/package/sitemap

I can push in urls inside the sitemap. But I want to add url based upon the data i retrieve from mongodb. I know how to create the url to feed the sitemap but because finding data from mongo is a callback, before I get data , the router for /sitemap.xml is called so Im not able to feed more urls to the sitemap.

Here is the snapshot of my routes file

var colors = require('colors'); 
var mongoose = require('mongoose');
var express = require('express');
var router = express.Router();
var sm = require('sitemap');
var _ = require('underscore');

//these models are found in the /models folder
var Post = mongoose.model('Post');
var Comment = mongoose.model('Comment');


var trendSchema = mongoose.Schema({
    tName: String,
    tName_h: String,    
    region: String
  });

var Trend = mongoose.model('Trend', trendSchema);

// var Trend = mongoose.model('Trend'); 






console.log('~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~');




var tfind = function  (trends) {
    Trend.find(function (err, trends) {
        if (err) {
            console.log(err);
            return next(err);
        }

    console.log('trends =', trends);
        var plucked = _.pluck(trends, 'tName');

        // console.log('plucked  trends',plucked);

        // console.log(' sitemap urls   = ', sitemap.urls);
        // sitemap.urls.length = 0;
        // sitemap.urls.push({ url: '/page-10/', changefreq: 'daily', priority: 0.3 });

    });
}


tfind.done(function (text) {
        console.log(' text   = ', text );
});




var sitemap = sm.createSitemap ({
      hostname: 'http://example.com',
      cacheTime: 600000,        // 600 sec - cache purge period
      urls: [
        { url: '/page-1/',  changefreq: 'daily', priority: 0.3 },
        { url: '/page-2/',  changefreq: 'monthly',  priority: 0.7 },
        { url: '/page-3/' }     // changefreq: 'weekly',  priority: 0.5
      ]
    });

router.get('/sitemap.xml', function(req, res) {
  sitemap.toXML( function (xml) {
      res.header('Content-Type', 'application/xml');
      res.send( xml );
  });
});



sitemap.urls.push({ url: '/page-5/', changefreq: 'daily', priority: 0.3 });
sitemap.urls.push({ url: '/page-7/', changefreq: 'daily', priority: 0.3 });
// sitemap.urls.push({ url: '/page-9/', changefreq: 'daily', priority: 0.3 });

console.log(' app.js  sitemap.urls == ', sitemap.urls);
1

There are 1 best solutions below

6
On

If I understand your problem correctly, you want to add data fetched from MongoDB into your sitemap before rendering the XML file for response.

First things first, Node.js is asynchronous and MongoDB driver is also based on that. So, your route handle should perform the search within it, and when mongo returns you the documents, only after you are sure that everything is done, then send back the response.

NOTE: For brevity, I'm not writing the config and error handlers here. Also, always put your expressjs config on top, just below the module imports.

var mongoose = require('mongoose');
.
.
var app = express();

// YOUR CONFIG SHOULD ALWAYS BE ON TOP

// view engine setup
app.set('views', path.join(__dirname, 'views'));
app.set('view engine', 'jade');
.
.

// YOUR CODE WAS MISSING A MONGODB CONNECTION SETUP
mongoose.connect('mongodb://localhost:27017/news', function () {
  console.log('Database Connected');
});

var sitemap = sm.createSitemap ({
  hostname: 'http://example.com',
  cacheTime: 600000,        // 600 sec - cache purge period
  urls: [
    { url: '/page-1/',  changefreq: 'daily', priority: 0.3 },
    { url: '/page-2/',  changefreq: 'monthly',  priority: 0.7 },
    { url: '/page-3/' }     // changefreq: 'weekly',  priority: 0.5
  ]
});

var trendSchema = mongoose.Schema({
  tName: String,
  tName_h: String,    
  region: String
});

var Trend = mongoose.model('Trend', trendSchema);

app.get('/sitemap.xml', function(req, res) {
  Trend.find(function (err, trends) {
    if (err) {
      console.log(err);
      return next(err);
    }
    trends.forEach(function(trend, index) {

      // Place your data extraction/insertion logic here
      sitemap.urls.push({ url: trend.tName, changefreq: 'daily', priority: 0.3 });

      if(index == trends.length-1) {
        sitemap.toXML( function (xml) {
          res.header('Content-Type', 'application/xml');
          res.send( xml );
        });
      }
    });
  });
});

var server = app.listen(3000, function() {
  console.log('Express server listening on port ' + server.address().port);
});