iron-meteor / iron-router

A client and server side router designed specifically for Meteor.
MIT License
1.98k stars 412 forks source link

Idea: Define "mobiletemplate" for each route #191

Closed Strosch closed 10 years ago

Strosch commented 10 years ago

Hi guys!

So I just got an idea: I'm just implementing some code which loads different templates in each route when the device.width is smaller then x pixels. So using something like

width = (window.innerWidth > 0) ? window.innerWidth : screen.width;

and a small if I am defining some vars with different strings so diff templates are loaded. So the simple idea is having something like this implemented into the router where I can define an option like mobiletemplate: String (besides template: String obviously) which is loaded when the route is called on a mobile device.

What do you think of this?

cheers, P

piffie commented 10 years ago

Routes are not reexecuted on resize. Therefore this is not a optimal solution. The targeting through CSS media queries proved pretty to be pretty good so I would recommend this.

Also, as there are the CSS queries I would not recommend to implement it into the router itself if you want to do this. It can very simple be done with named yields.

Sent through space

Am 09.10.2013 um 03:18 schrieb Patrick Schubert notifications@github.com:

Hi guys!

So I just got an idea: I'm just implementing some code which loads different templates in each route when the device.width is smaller then x pixels. So using something like

width = (window.innerWidth > 0) ? window.innerWidth : screen.width; and a small if I am defining some vars with different strings so diff templates are loaded. So the simple idea is having something like this implemented into the router where I can define an option like mobiletemplate: String (besides template: String obviously) which is loaded when the route is called on a mobile device.

What do you think of this?

cheers, P

— Reply to this email directly or view it on GitHub.

Strosch commented 10 years ago

That's totally true but in my opinion that is not much of a problem. Nobody would load a view on a desktop in a normal size and then shrink it down to mobile device size. Media queries are imo not enough as I can not prevent vertain elements from loading. What I mean by this is that even the mobile view would load all the elements the desktop needs and the media queries would then hide them via display: none. And this is of course not a good solution as, at that point, all the data was already shipped to the (mobile) client. As of the named yields: Thanks didn't think of that for some reason! Will use this and load / not load certain elements depending on the screen.width then.

copleykj commented 10 years ago

@Questful I don't know if it would be useful for you but I put up my mobile detection code at https://github.com/copleykj/mobile-detect-meteor

It sets a Session variable with the name isMobile that is true when a mobile device is detected... You can then set up a handlebars helper and use an if block helper to switch your templates out.

Also as mentioned, I think media queries would still be ok.. All your templates are getting sent to the mobile client any way unless you are going to render on the server. The data being sent to the client depends on your publications and subscriptions. With the media query solution, the only difference will be a few ms worth of extra render time that I don't imagine would be noticeable to the user.

Strosch commented 10 years ago

That all the templates are sent to any client anyway is a very valid point. I forgot about that! Will try your package, might be helpful, thanks! :) I will figure something out and use a combination of loading different templates into some named yields + using your package.

piffie commented 10 years ago

you can also make something like this:

<template name="root">
  {{#if mobile}}
  {{yield mobile}}
  {{else}}
  {{yield}}
  {{/if}}
</template>
<template name="nomobile">
  {{yield}}
</template>
Router.configure
  layout: 'root'
  renderTemplates:
        'nomobile': #per default load through the nomobile template the original route template.
           to:'mobile'

Router.map ->
  @route 'main', #main has a mobile template, so load it when mobile.
    path: '/' 
    renderTemplates:
        'mainmobile':
           to:'mobile'
  @route 'login'  # login has no mobile template, the nomobile template loads the default route template anyway

But i still recommend css targeting due to the templates are anyway on the client and hide them is pattern wise the best possibility.

tmeasday commented 10 years ago

In my experience sharing templates is the way to go because it's impossible to control users "crossing the boundary" between mobile + non-mobile resolutions (once you factor in all the different Android resolutions and think about going portrait -> landscape, you are definitely going to hit it eventually).

If you have completely different templates rendered then you are kind of stuffed when this happens.

For example if you put more data on a non-mobile route, then you end up needing a separate route for mobile (to display that extra info). What happens if you are on that route and you rotate to landscape, triggering the non-mobile layout? You won't have a design for that (as this route doesn't exist in non-mobile), and there's no "correct" thing to do (especially if you consider they may immediately rotate back!).

All in all it doesn't seem worth it, which is why people tend to just stick with responsive design + always using the same info (or hiding things with CSS).

In any case, it's possible to achieve something as @piffie pointed out so I'm going to close this as I don't think IR should support it explicitly.