В Sinatra, лучший способ служить макет iPhone по сравнению с обычным макетом? - PullRequest
7 голосов
/ 05 июня 2010

Я пишу Sinatra приложение, которое должно отображать различные макеты в зависимости от того, использует ли пользователь iPhone или обычный браузер. Я могу определить тип браузера, используя Rack-Mobile-Detect , но я не уверен, что лучше сказать Синатре, какой макет использовать.

Кроме того, у меня есть ощущение, что то, как я выберу это, может также нарушить кеширование страниц. Это правда?

Пример кода:

require 'sinatra/base'
require 'haml'
require 'rack/mobile-detect'

class Orca < Sinatra::Base

  use Rack::MobileDetect

  helpers do
    def choose_layout
      if request.env['X_MOBILE_DEVICE'] == :iPhone
        # use iPhone layout
      else
        # use normal layout
      end
    end
  end

  before do
    # should I use a before filter?
    choose_layout()  
  end

  get '/' do
    haml :home # with proper layout
  end

end #Class Orca

Ответы [ 4 ]

7 голосов
/ 07 июня 2010

Вот что я закончил:

require 'sinatra/base'
require 'haml'
require 'rack/mobile-detect'

class Orca < Sinatra::Base

  use Rack::MobileDetect

  # HAML template options
  # Use HTML5 doctype
  set :haml, {:format => :html5 }

  helpers do

    def get_layout
      # For AJAX (XMLHttpRequest) requests, don't use a layout
      if request.xhr? then 
        @layout = false
        exit
      end

      # For non-AJAX (XMLHttpRequest) requests, choose correct layout
      # For each mobile device, you will need a layout_<device>.haml file
      # in the Views directory
      @layout = case request.env['X_MOBILE_DEVICE']
                when /iPhone|iPod/ then :layout_iphone

              # when "Android" then :layout_android

                else true # use default Sinatra layout
                end
    end

  end # helpers

  before do
    get_layout() 
  end # before filter

  get '/' do
    # Will use iPhone layout for iPhone|iPod, 
    # Sinatra default layout for desktop browsers
    haml :home, :layout => @layout
  end

end # Class
4 голосов
/ 05 июня 2010

Я считаю, что стандартный способ работы с конкретными пользовательскими агентами в Синатре прямо на маршруте ...

get '/', :agent => /iPhone/ do
    # render for iPhone
end

get '/' do
    # render standard layout
end

См. Книга Синатры .

Re: кэширование, я думаю, это будет зависеть от того, какие слои кэширования находятся на вашем сайте, но, да, возможно, вам придется учитывать это.

1 голос
/ 24 июня 2011

Я написал пост в блоге на эту тему, который может быть полезен для тех, кто использует Padrino с Sinatra. Если вы не используете Padrino, это может быть полезно, если вы найдете подходящее место для расширения Синатры.

http://blog.joshdzielak.com/override-padrino-locale-based-template-resolu
http://dzello.com/blog/2011/06/22/override-padrino-locale-based-template-resolu/

Резюме: я использую rack-mobile-Detect, чтобы сообщить мне, является ли запрос «мобильным», и я исправляю поддержку рендеринга на основе локали Padrino для рендеринга на основе обнаружения мобильных устройств вместо локали.

Таким образом, я могу получить рендер foo.mobile.haml для мобильных устройств и foo.haml для немобильных без кода приложения. В качестве бонуса он работает как для файла шаблона, так и для макета.

0 голосов
/ 04 октября 2013

У меня была похожая проблема всегда, мы не можем ретранслировать на маршрутах. Синатра предоставляет фильтры для решения подобных проблем

  @your_layout_name = ''

  before :agent => /iPhone/ do
      @your_layout_name = "initialize with desired iphone template"
  end

  get '/' do

    # use @your_layout_name variable to initialize layout 

  end

Я публикую это, поскольку у меня была проблема, когда я не мог фильтровать на уровне маршрута Так что это может помочь другим, кто ищет похожие решения

...