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.
Лучшая благодарность автору — ваши комментарии.
сентября 26, 2011 at 06:55 (#)
зачем копировать README с официального сайта? Там всё это написано, в том числе и на русском.
сентября 26, 2011 at 08:11 (#)
Andrey, а на Railscasts и RailsGuides есть много-чего по Rails и код Rails хорошо документирован, и вообще есть Google. Может тогда стоит не только про Sinatra не писать, но и про Rails, Ruby, ведь в сети есть перевод книги Фултона?
Перевода на русский не видел. Это только вводные статьи, которые не могут не повторять содержимого оффициальной документации ибо их цель дать увидеть возможности работы с Sinatra Framework.
В следующих статьях, например, будем добавлять некоторый функционал из Rails, тот же метод link_to, flash, и т.д., подробно опишу работу совместно с ActiveRecord и, возможно Sequel, Mongoid, что в официальной документации описано очень убого.
сентября 26, 2011 at 15:04 (#)
есть классный фреймворк padrino построенный на синатре. Он уже не такой минималистичный как синатра, но еще не такой монстр как рельсы. Там есть всякие вкусные вещи ка в рельсах хелперы, генераторы, локализация и даже админка.
сентября 26, 2011 at 15:04 (#)
У меня тут по-ходу будут возникать вопросы, ибо начал с sinatra. Надеюсь на твою помощь:
require ‘erb’
Зачем такова строка?
У меня спокойно обрабатывается:
require ‘sinatra’
get ‘/’ do
erb :index
end
PS: Научи, пожалуйста, писать в тег [language] :).
сентября 26, 2011 at 15:51 (#)
Если у меня есть массив.
Как мне в шаблоне вывести его:
a[1]
a[2]
a[3]
Жду ответа ;).
сентября 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.
если есть массив, то нужно использовать итератор, например тебе подойдет такой код в шаблоне:
сентября 26, 2011 at 16:38 (#)
Tankard, честно признаться не сильно представляю, чем кроме админки Padrino отличается от Sinatra + расширений, то есть можно самому собрать Padrino из того, что есть, но идея все равно хорошая, каждый из Rails, Padrino и Sinatra занял свою нишу.
сентября 26, 2011 at 17:16 (#)
Спасибо.
А что, если я использую так:
Можно ли это как-нибудь изменить?
сентября 26, 2011 at 17:39 (#)
Непонятный вопрос, но:
1.
/users и /users/ — один адрес, будет выполнен только первый обработчик, второй, с редиректом будет проигнориован.
2.
В Ruby для переменных принято использовать строчные символы и знак подчеркивания для разделения слова, более правильное название — это @title_page.
декабря 18, 2011 at 20:37 (#)
А мне все посты про SINATRA понравились, в оф. документации, всё слишком размыто, а здесь всё конкретнее как-то. Давайте еще:)