1

Here is a progressive routing with 2 handlers.

app.get('/blog/:year/:quarter/:month?/:day?/:post', routes.views.post);
app.get('/blog/:year/:quarter/:month?/:day?/', routes.views.post_listing);

Here 'month' and 'day' are optional. The route should fallback to the 'post_listing' handler When there is no post param.

Any help is greatly appreciated. Thanks in advance!

Prasanna Jathan
  • 570
  • 7
  • 12
  • You should put `:post` in your first route at the beginning like that: `app.get('/blog/:post/:year/:quarter/:month?/:day?, routes.views.post);`. Is this acceptable for you or does it to be like you've shown in your example? – Michael W. Czechowski Feb 09 '18 at 16:56
  • @NEXTLEVELSHIT sorry, my friend, that did not work. Page redirects to 404 when you have all the 5 params with this approach. In here 'post' and 'post_listing' handlers hit separate model. – Prasanna Jathan Feb 10 '18 at 12:49
  • Putting contingent arguments (`month`, `day`) in between of obligatory parameters (`year`, `post`, `quarter`) can lead to missunderstanding of the provided parameters. If you want to use both your routes, you will get edge cases in which the `post` parameter can be understood as `month` or `day`. You're getting what I mean? – Michael W. Czechowski Feb 11 '18 at 12:03

1 Answers1

1

Problem specification

If your want to use your routes like shown in your examples, you will have to specify your routes with regular expressions. Leaving it like it is your routes will confirm routes like /blog/1984/1/my-post/ to both of your specified route handlers.

You have to specify them like in these examples: http://expressjs.com/en/guide/routing.html#route-paths

Solution

There you will declare year as a 4 digit parameter, quarter as one digit, month as two digit, day as two digit and post as a alphanumeric combiniation with dashes (this is common slug):

app.get('/blog/:year(\d{4})/:quarter(\d{1})/:month(\d{2})?/:day(\d{2})?/:post([a-z0-9-]+$)', routes.views.post);
app.get('/blog/:year(\d{4})/:quarter(\d{1})/:month(\d{2})?/:day(\d{2})?/', routes.views.post_listing);

Further suggestions for helping yourself

There is also a brilliant tool for testing and playing around with express routes: http://forbeslindesay.github.io/express-route-tester/

Michael W. Czechowski
  • 3,366
  • 2
  • 23
  • 50
  • well, that would work if the params are in digits. However, in my case, it's characters and I have another route with same params as above. Thank you! and appreciate your feedback. – Prasanna Jathan Feb 13 '18 at 04:11
  • Just tell me how they look and I will adapt it. – Michael W. Czechowski Feb 13 '18 at 13:51
  • Say suppose we have a route as follows: app.get('/hospitals/:region/:country/:state?/:city?/:hospital', function(req, res, next){ /**/ }); In the above route - there may not be state or city for few countries and view is different from the below route. app.get('/hospitals/:region?/:country?/:state?/:city?/', function(req, res, next){ /**/ }); In the second route - we would like to display list of hospitals based on city||state||country|| region. Did you get what I mean? Thanks in advance. – Prasanna Jathan Feb 14 '18 at 06:19
  • Are the optional parameters only for SEO purpose? – Michael W. Czechowski Feb 14 '18 at 12:17
  • If you want to filter by region, country, state and city you should not declare these parameters as optional. What will happen, if you neither enter any region nor country, but a state and city? You will not be able to distinguesh the state and city parameters from the country and region. They will be interpreted as region and country. – Michael W. Czechowski Feb 14 '18 at 12:24
  • yes, it's for SEO. I realized that there is no way I could use state&city as optional. But the solution you shared may come in handy for future surfers. Many thanks, (applause). – Prasanna Jathan Feb 14 '18 at 14:06