Pinterest Style Routes

I’d like to implement a Pinterest style modal page for items (images/items/posts/etc…). Whichever page you are on, when you click on a item a modal with the item details pops up, and the page (feed) where you are from still sits in the background. The url in the address bar changes so you can link to the item from other sites or share it to your friends. And when you close the item modal your still at the feed.

Does Ember support this type of routing?

I know react-router has support for it, so I imagine Ember would as well as it is heavily inspired by Ember-router.

Source: https://github.com/rackt/react-router/tree/master/examples/pinterest

“The url /pictures/:id can potentially match two routes, it all depends on if the url was navigated to from the feed or not.”

“Click on an item in the feed, and see that it opens in an overlay. Then copy/paste it into a different browser window (Like Chrome → Firefox), and see that the image does not render inside the overlay. One URL, two session dependent routes and UI :D”

1 Like

I have this exact same problem too, Googling has failed to find a solution :frowning:

I haven’t seen a good pattern for this. At a high level for our application we:

  1. transition to the overlay route
  2. override renderTemplate in that route to:
    1. Render the overlay in an outlet named “overlay”
    2. render the previous screen in the main outlet

Also, we have a simple service for keeping track of the previous screen info.

Any Controller:

actions: {
  openOverlay(someObj) {
    let redirectParams = [
      'some.previous.route',
      this.modelFor('some.previous.route')
    ];

    this.get('cardOverlayService').setProperties({
      previousRouteOptions: redirectParams,
      overlayBackground: 'some.previous.route'
    });

    this.transitionTo('some.overlay.route', someObj);
  }
}

Overlay Controller:

renderTemplate() {
  this.render('overlays/' + this.get('overlayName'), {
    into: 'application',
    outlet: 'overlay',
    controller: 'overlays/' + this.get('overlayName')
  });

  this.render(this.get('cardOverlayService').get('overlayBackground'));
}
1 Like

This feels like such a common use case that there must be a best practice for it…

Also, to expand on the Pinterest example, this is also how Dribbble’s new picture viewer modals work.

Ember’s router is capable of handling this scenario: JS Bin - Collaborative JavaScript Debugging

1 Like

Hey Jason, it’s a little more complicated than a nested route. We need to hit: this.route('pin', { path: '/pin/:id' }); from any route and keep the previous screen behind the overlay. For example, showing the overlay on top of the home page OR from pinterest.com/[username] OR pinterest.com/[username]/[tag]

Ah, also possible but I’m not a pinterest user so let me know if I missed anything.

Edit: http://output.jsbin.com/qaravi

3 Likes

That looks great, Jason. I’ll try some of that router url handling in our app.

Made some slight changes to allow for a back button behavior: http://output.jsbin.com/tisifo

Not really sure how you can get the back button to restore state as in the modal appearing. Right now it restores state of of the “hardlink” URL (not sure that’s the proper term).

Edit: I noticed the backbutton doesn’t tear down the modal. I can fix that tomorrow but I guess one way would be to listen for hashchange or popstate depending on what location type you’re using.