Search code examples
mongodbmeteoriron-router

Meteor & Iron: Using tag from array as path


I'm using Iron Router for Meteor and I have these routes set up and working so far:

Router.map(function () {
    this.route('home', {
        path: '/',
        template: 'home'
    });

    this.route('userProfile', {
        path: '/user/:username',
        data: function () {
            return Meteor.users.findOne({username: this.params.username})},
        template: 'userProfile'
    });

    this.route('postPage', {
        path: '/post/:_id',
        data: function () {
            return Posts.findOne({_id: this.params._id})},
        template: 'postPage'
    });

    this.route('settings', {
        path: '/settings',
        template: 'settings'
    });
});

I'd like to introduce another route that would take you to a page where posts are organised by tag. For example http://foo.bar/tag/mexican would take you to a page displaying all the posts that have the tag mexican in an array. The posts are stored in the collection like so:

{
    "_id" : "G6xrPYedPzG8KGBTF",
    "title" : "Chilli Con Carne",
    "rating" : 4,
    "tags" : [  "kidneybeans",  "mexican",  "rice" ],
    "description" : "A meaty mexican dish with rice.",
    "createdAt" : ISODate("2015-02-15T23:45:12.384Z"),
    "owner" : "vh7DjWM9NwbkGSNg9",
    "username" : "snowingjack"
}

I've been able to make routes that pass data by post._id as you can see, but now I can't figure out how to make a route where /tag/:tag would take me to page with the data is the posts collection queried by tag. I'm fine running a query that will just return posts with a certain tag like return Posts.find({tags: "mexican"}); but I'm struggling with how to pass all this data around to get the desired effect.

Ideas?

P.S. I also have a template I use to spit out tags in a sane fashion with hashtags and spaces and links and whatnot. I'd love to be able to find a solution where this would work:

<template name="tagListItem">
    <span class="tag-list__item"><a href="{{pathFor 'tagPage'}}">#{{this}}</a></span>
</template>

Solution

  • I think the route would look something like this:

    this.route('tagPage', {
        path: '/tags/:tag',
        data: function () {
            return Posts.find({tags: this.params.tag)},
        template: 'tagPage'
    });
    

    And the anchor tag inside the template you use to output tag links would probably look like this ( though I'm not exactly sure the data context of the template you mentioned in your post):

    <a href="/tags/{{this}}">#{{this}}</a>
    

    The other thing you would have to consider is how you are publishing and subscribing to posts. You might want to make a separate pub/sub relationship for tags so you are sending posts with tags you don't need down the line.