Sinatra: шаблоны, редирект и сессии

сентября 25, 2011  |  Published in Sinatra  |  10 Comments

Шаблоны
В предыдущей статье мы просто рендерили переменные и строки, но чаще всего это не самый лучший способ представления информации пользователю. Когда мы хотим создать реальный сайт, а не приложение выводящее одну строку — нам необходимо использовать много разметки для данных, которую помещать в блок обработки запроса — неправильно. Sinatra Framework позволяет использовать различные шаблоны благодаря gem Tilt. Возьмем приложение из предыдущей статьи и перепишем его с использованием шаблонов. Все шаблоны будут храниться в поддиректории ./views/. Views — это директория в которой хранятся файлы представлений по умолчанию.

#app.rb
require 'sinatra'
require 'erb'

before do
  @title = "Sinatra Tutorial"
end

get '/' do
  @message = "Welcome to RubyDev.ru"
  erb :index
end
<!--- ./views/index.erb --->
<html>
  <head>
    <title><%= @title %></title>
  </head>
  <body>
    <div id='header'>
      <h1><%= @title %></h1>
    </div>
    <div id='content'>
     <p><%= @message %></p>
    </div>
  </body>
</html>

Чтобы использовать haml, вместо erb вам следует его сначала установить:

$ gem install haml

После этого вы должны включить haml в код приложения, то есть заменить require ‘erb’ на require ‘haml’. Для рендеринга haml шаблона итоговый код приложения должен выглядеть так:

require 'sinatra'
require 'haml'

before do
  @title = "Sinatra Tutorial"
end

get '/' do
  @message = "Welcome to RubyDev.ru"
  haml :index
end

После этого шаблон index.erb можно заменить шаблоном index.haml:


// ./views/index.haml
!!!
%html
  %head
    %title= @title
  %body
    #header
      %h1= @title
    #content
      %p= @message

Если вам захочется реализовать структуру директорий для представлений, как в Rails, т.е. хранить шаблоны в ./views/action_name/, то вы должны добавить имя директории перед именем файла:

require 'sinatra'
require 'haml'

before do
  @title = "Sinatra Tutorial"
end

get '/' do
  @message = "Welcome to RubyDev.ru"
  haml :'root/index'
end

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

require 'sinatra'
require 'haml'

before do
  @title = "Sinatra Tutorial"
end

get '/' do
  @message = "Welcome to RubyDev.ru"
  haml "#content= @message"
end

В Sinatra шаблоны можно хранить также в файле самого приложения:

require 'sinatra'
require 'haml'

before do
  @title = "Sinatra Tutorial"
end

get '/' do
  @message = "Welcome to RubyDev.ru"
  haml :index
end

__END__

@@ index
!!!
%html
  %head
    %title= @title
  %body
    #header
      %h1= @title
    #content
      %p= @message

Такие шаблоны называются inline шаблонами, их следует использовать только в совсем простых приложениях.

Другой способ хранения шаблонов в коде приложения — это именованные шаблоны. Именованный шаблоны объявляются при помощи метода template в который передается блок кода:

require 'sinatra'
require 'haml'

template :index do
  "!!!\n%html\n\t%head\n\t\t%title= @title\n\t%body\n\t\t#header\n\t\t\t%h1= @title\n\t\t#content\n\t\t\t%p= @message"
end

before do
  @title = "Sinatra Tutorial"
end

get '/' do
  @message = "Welcome to RubyDev.ru"
  haml :index
end

В Sinatra Framework вы можете использовать практически любой шаблонизатор, который поддерживается в Tilt. Для этого достаточно подключить движек шаблонизатора через require и использовать соответствующий шаблонизатору метод для рендеринга.

Нужно заметить, что в Sinatra Framework также, как и в Rails существует концепция макетов. Макет — это файл представления, который содержит общий для нескольких шаблонов код и включает их в себя (вы можете также использовать inline layout используя @@ layout). Макет в Sinatra также как и в Rails использует yield для включения соответствующего URL’у шаблона.

Редирект
Редирект в Sinatra Framework реализован очень просто:

redirect <address>

Пример:

require 'sinatra'
require 'haml'

before do
  @title = "Sinatra Tutorial"
end

get '/' do
  @message = "Welcome to RubyDev.ru"
  haml :index
end

get '/*' do
  #запросы к любому URL, кроме корневого перенаправляется на http://localhost:4567/
  redirect '/'
end

Сессии
Доступ к сессии производится через метод session. Однако по умолчанию в Sinatra Framework сессии выключены, чтобы включить сессии — необходимо воспользоваться следующей инструкцией:

set :sessions, true

Пример:

#./app.rb
require 'sinatra'
require 'haml'

set :sessions, true

before do
  @title = "Sinatra Tutorial"
end

get '/' do
  @message = "Welcome to RubyDev.ru"
  haml :index
end

post '/sign_in' do
  session[:current_user] = params[:login]

  redirect to('/user')
end

get '/user' do
  @user = session[:current_user]

  haml :user
end

// ./views/index.haml
!!!
%html
  %head
    %title= @title
  %body
    #header
      %h1= @title
    #content
      %p= @message
      %form{ :name => :sign_in_data, :action => '/sign_in', :method => :post }
      login:
      %input{ :type => 'text', :name => "login" }
      %br

      password:
      %input{ :type => 'text', :name => "password" }
      %br
      %input{ :type => 'submit', :value => 'sign in' }

// ./views/user.haml
!!!
%html
  %head
    %title= @title
  %body
    #header
      %h1= @title
    #content
      %p= @user

В следующей главе мы рассмотрим еще что-то интересное касательно разработки на Sinatra Framework.

Лучшая благодарность автору — ваши комментарии.

Tags: , ,

Responses

  1. Andrew says:

    сентября 26, 2011 at 06:55 (#)

    зачем копировать README с официального сайта? Там всё это написано, в том числе и на русском.

  2. admin says:

    сентября 26, 2011 at 08:11 (#)

    Andrey, а на Railscasts и RailsGuides есть много-чего по Rails и код Rails хорошо документирован, и вообще есть Google. Может тогда стоит не только про Sinatra не писать, но и про Rails, Ruby, ведь в сети есть перевод книги Фултона?

    Перевода на русский не видел. Это только вводные статьи, которые не могут не повторять содержимого оффициальной документации ибо их цель дать увидеть возможности работы с Sinatra Framework.

    В следующих статьях, например, будем добавлять некоторый функционал из Rails, тот же метод link_to, flash, и т.д., подробно опишу работу совместно с ActiveRecord и, возможно Sequel, Mongoid, что в официальной документации описано очень убого.

  3. Tankard says:

    сентября 26, 2011 at 15:04 (#)

    есть классный фреймворк padrino построенный на синатре. Он уже не такой минималистичный как синатра, но еще не такой монстр как рельсы. Там есть всякие вкусные вещи ка в рельсах хелперы, генераторы, локализация и даже админка.

  4. says:

    сентября 26, 2011 at 15:04 (#)

    У меня тут по-ходу будут возникать вопросы, ибо начал с sinatra. Надеюсь на твою помощь:

    require ‘erb’

    Зачем такова строка?
    У меня спокойно обрабатывается:

    require ‘sinatra’
    get ‘/’ do
    erb :index
    end

    PS: Научи, пожалуйста, писать в тег [language] :).

  5. says:

    сентября 26, 2011 at 15:51 (#)

    Если у меня есть массив.
    Как мне в шаблоне вывести его:
    a[1]
    a[2]
    a[3]
    Жду ответа ;).

  6. admin says:

    сентября 26, 2011 at 16:30 (#)

    Привет, Женя!

    1.
    require используется для подключения в файт стороннего кода.

    require ‘erb’ подключает erb. ERB — это стандартный, если не ошибаюсь встроенные в Ruby STDLIB шаблонизатор. ERB — Embedded RuBy. Благодаря ERB ты можешь выполнять Ruby-код внутри <% … %> Для того, чтобы результат выполнения был напечатан на странице, нужно писать так: <h1><%= article.title %></h1>, т.е. добавить знак равно. Если у тебя без подключения erb обрабатывается, значит ты или именованный или инлайновый шаблон используешь, или Sinatra его сам подключает (у меня не подключал).

    2.
    Нужно использовать [название языка] … [/название языка]

    3.
    если есть массив, то нужно использовать итератор, например тебе подойдет такой код в шаблоне:

    
                  
    • < % a.each do |number| %>
    • < %= number %>
    • < % end %>
    
                
  7. admin says:

    сентября 26, 2011 at 16:38 (#)

    Tankard, честно признаться не сильно представляю, чем кроме админки Padrino отличается от Sinatra + расширений, то есть можно самому собрать Padrino из того, что есть, но идея все равно хорошая, каждый из Rails, Padrino и Sinatra занял свою нишу.

  8. says:

    сентября 26, 2011 at 17:16 (#)

    Спасибо.

    А что, если я использую так:

    get '/users' do
            @TitlePage = 'Users'
            erb :users
    end
    
    get '/users/' do
            redirect '/users'
    end
    

    Можно ли это как-нибудь изменить?

  9. admin says:

    сентября 26, 2011 at 17:39 (#)

    Непонятный вопрос, но:

    1.
    /users и /users/ — один адрес, будет выполнен только первый обработчик, второй, с редиректом будет проигнориован.

    2.
    В Ruby для переменных принято использовать строчные символы и знак подчеркивания для разделения слова, более правильное название — это @title_page.

  10. arivlav says:

    декабря 18, 2011 at 20:37 (#)

    А мне все посты про SINATRA понравились, в оф. документации, всё слишком размыто, а здесь всё конкретнее как-то. Давайте еще:)

Leave a Response

Для подсветки кода используйте BB - коды: [language]...[/language], где language может быть: ruby, javascript, css, html.