пʼятниця, 17 червня 2011 р.

Використання will_paginate з DataMapper і Sinatra

Часто потрібно так, щоб у представлені(View) відображалися не усі записи з масиву на одній сторінці. У цьому випадку необхідно реалізувати розбиття на сторінки(pagination). Забезпечення цієї функціональності буде простішим з використанням плагіна WillPaginate, який є популярним у середовищі Rails-розробників. У цій статті мова піде про використання WillPaginate разом з Sinatra і DataMapper. Все що нам потрібно це версія >3.0 з підтримкою DataMapper.

Здійснюємо пошук
$ gem search will_paginate --remote
і встановлюємо необхідну версію
$ sudo gem install agnostic-will_paginate

За приклад ми візьмемо наш проект блогу із серії статей про Sinatra. Нашою задачею буде вивести на головну сторінку статті з розбивкою по сторінках.

Коли виконується конструкція require 'will_paginate', WillPaginate робить деякі перевірки для того, щоб побачити, що він працює під Rails або Merb. І якщо це так, підмішує методи класу та помічники(helpers) у базові класи. У нашому ж випадку з Sinatra, необхідно викликати шукачів(finders) і помічників(helpers).

Додаємо наступні рядки на початку blog.rb:
require 'will_paginate'
require 'will_paginate/finders/data_mapper'

require 'will_paginate/view_helpers/base'
require 'will_paginate/view_helpers/link_renderer'

На даному етапі, метод Post#paginate повертатиме розбиту на сторінки колекцію.

Також ми повинні бути в змозі надавати посилання на сторінки.
Для цього необхідно реалізувати метод WillPaginate::ViewHelpers::LinkRenderer#url. Щоб отримати робочого помічника додаємо до файлу blog.rb наступні рядки, запозичені із цієї статті.

WillPaginate::ViewHelpers::LinkRenderer.class_eval do
  protected
  def url(page)
    url = @template.request.url
    if page == 1
      # strip out page param and trailing ? if it exists
      url.gsub(/page=[0-9]+/, '').gsub(/\?$/, '')
    else
      if url =~ /page=[0-9]+/
        url.gsub(/page=[0-9]+/, "page=#{page}")
      else
        url + "?page=#{page}"
      end      
    end
  end
end

helpers WillPaginate::ViewHelpers::Base

Цей код припускає, що номер сторінки буде переданий у рядку запиту (наприклад, http://localhost:4567/posts?page=3)

Далі необхідно внести зміни до нашої дії index, щоб виводити статті посторінково на головну сторінку.
Замінюємо у blog.rb:
get "/posts" do
  @posts = Post.all
  haml :"posts/index"
end

на:
get "/posts" do
  @posts = Post.paginate :page => params[:page], :per_page => 5
  haml :"posts/index"
end

І додаємо помічник will_paginate для відображення посилань на сторінки:

views/posts/index.haml
#header
  %h1 Мій блог

%a{:href => "posts/new"}> New Post
#content
  - @posts.each do |post|
    .container
      %h3= post.title
      %p= post.body
      %p= post.created_at

      %table
        %tr
          %td
            %a{:href => "posts/#{post.id}"}> Show
          %td
            %a{:href => "posts/#{post.id}/edit"}> Edit
          %td
            %form{:method => 'post', :action => "/posts/#{post.id}"}
              %input{:type => "hidden", :name => "_method", :value => "delete"}
              %input{:type=>'submit', :value => 'Destroy'}
  #pagination
    = will_paginate @posts

Немає коментарів: