Search code examples
apostrophe-cms

Creating static routes that render templates


I am trying to create a page (in an apostrophe multisite project, so a unique page would exist for each site) at /profile, or /account, or /account/profile.

I created the following at /sites/lib/modules/account-profile/index.js the following and adapted it from the How Apostrophe handles requests page:

module.exports = {
  afterConstruct: function(self) {
    self.addDispatchRoutes();
  },
  construct: function(self, options) {
    self.addDispatchRoutes = function() {
      self.dispatch("/account/:profile", self.showPage);
    };
    self.showPage = function(req, callback) {
      return (
        req.params.profile,
        (err, doc) => {
          // handle err, if no err...
          if (!doc) {
            // Let Apostrophe render the 404 page
            req.notFound = true;
          }
          req.template = self.renderer("profile", { doc: doc });
          return callback(null);
        }
      );
    };
  }
};

after including:

"account-profile": {
   extend: "apostrophe-custom-pages"
 }

in app.js

The problem I am having is the the showPage function never runs when I hit, for example, /account/profile.

I understand the :profile bit to match /account/profile bit is a bit dubious, but I also cant figure out how to render a template when doing something like:

self.apos.app.get("/account/profile", async function(req, res, callback) {
  req.template = self.renderer("profile", { doc: "hi" });
  // now what?
});

I imagine I am missing something quite simple, but I have scanned the docs quite thoroughly and can't find that missing bit.


Solution

  • You're very close in your bottom example! In order to create pages on static routes, I generally tend to use the same code you showed in your question. In order to return a page from inside your apos.app.get, you'd do something like this:

    self.apos.app.get('/account/profile', function(req, res){
        // Place any data you need to access in your template here:
        req.data = {};
    
        // self.sendPage is what will actually return the page and render the template 'profile.html' in your views folder.
        // You can change 'profile' to the name of your template minus '.html' - e.g. 'page.html' would just be 'page'
        return self.sendPage(req, 'profile', {});
    });
    

    The piece you're missing appears to be sendPage. That method will actually render the page using the template specified in the second argument of the method.

    If you put this in your construct method, you'll have a new route on your site that you can access by going to /account/profile. It will render the template located in your module's views folder.

    I originally found this info on this page:

    https://apostrophecms.org/docs/technical-overviews/how-apostrophe-handles-requests.html

    in the 'Rendering a full HTML page from a route' section.