Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

custom will_paginate renderer

Documentation is lacking for will_paginate custom renderers:

There is no documentation how to write your own link renderer, but the source code is pretty self-explanatory. Dive into it, and selectively override methods of the LinkRenderer to adjust them to your needs.

Is there any unofficial documentation?

like image 476
Blair Anderson Avatar asked Jun 21 '17 15:06

Blair Anderson


3 Answers

Found a decent blog post about custom will_paginate renderer

module ApplicationHelper
  # change the default link renderer for will_paginate
  def will_paginate(collection_or_options = nil, options = {})
    if collection_or_options.is_a? Hash
      options, collection_or_options = collection_or_options, nil
    end
    unless options[:renderer]
      options = options.merge :renderer => MyCustomLinkRenderer
    end
    super *[collection_or_options, options].compact
  end
end

and then in an initializer

class MyCustomLinkRenderer < WillPaginate::ActionView::LinkRenderer do
  def container_attributes
    {class: "tc cf mv2"}
  end

  def page_number(page)
    if page == current_page
      tag(:span, page, class: 'b bg-dark-blue near-white ba b--near-black pa2')
    else
      link(page, page, class: 'link ba b--near-black near-black pa2', rel: rel_value(page))
    end
  end

  def gap
    text = @template.will_paginate_translate(:page_gap) { '&hellip;' }
    %(<span class="mr2">#{text}</span>)
  end

  def previous_page
    num = @collection.current_page > 1 && @collection.current_page - 1
    previous_or_next_page(num, @options[:previous_label], 'link ba near-black b--near-black pa2')
  end

  def next_page
    num = @collection.current_page < total_pages && @collection.current_page + 1
    previous_or_next_page(num, @options[:next_label], 'link ba near-black b--near-black pa2')
  end

  def previous_or_next_page(page, text, classname)
    if page
      link(text, page, :class => classname)
    else
      tag(:span, text, :class => classname + ' bg-dark-blue near-white')
    end
  end
end
like image 97
Blair Anderson Avatar answered Nov 11 '22 18:11

Blair Anderson


Thanks to previous answer, i wrote this code to use will_paginate with materialize

application_controller.rb

 def custom_paginate_renderer
  # Return nice pagination for materialize
  Class.new(WillPaginate::ActionView::LinkRenderer) do
  def container_attributes
    {class: "pagination"}
  end

  def page_number(page)
    if page == current_page
      "<li class=\"cyan active\">"+link(page, page, rel: rel_value(page))+"</li>"
    else
      "<li class=\"waves-effect\">"+link(page, page, rel: rel_value(page))+"</li>"
    end
  end

  def previous_page
    num = @collection.current_page > 1 && @collection.current_page - 1
    previous_or_next_page(num, "<i class=\"material-icons\">chevron_left</i>")
  end

  def next_page
    num = @collection.current_page < total_pages && @collection.current_page + 1
    previous_or_next_page(num, "<i class=\"material-icons\">chevron_right</i>")
  end

  def previous_or_next_page(page, text)
    if page
      "<li class=\"waves-effect\">"+link(text, page)+"</li>"
    else
      "<li class=\"waves-effect\">"+text+"</li>"
    end
  end
  end
end

your_controller.rb

# GET /articles/1
def articles
  @articles = @articles.paginate(:page => params[:page], :per_page => 20).order(id: :desc)
  @custom_paginate_renderer = custom_paginate_renderer
end

your_view.html.erb

<%= will_paginate @articles, renderer: @custom_paginate_renderer %>

Not the most beautiful rails code, but it works

like image 5
Constantin De La Roche Avatar answered Nov 11 '22 18:11

Constantin De La Roche


Thanks to the answers which have guided me to write this renderer for Bootstrap 5.

//config/initializers/bootstrap_paginate_renderer.rb

class BootstrapPaginateRenderer < WillPaginate::ActionView::LinkRenderer
  def container_attributes
    { class: 'pagination' }
  end

 def html_container(html)
    child = tag(:ul, html, container_attributes)
    tag(:nav, child)
  end

  def page_number(page)
    if page == current_page
      '<li class="page-item active">' + link(page, page, rel: rel_value(page),class: 'page-link') + '</li>'
    else
      '<li class="page-item">' + link(page, page, rel: rel_value(page),class: 'page-link') + '</li>'
    end
  end

  def previous_page
    num = @collection.current_page > 1 && @collection.current_page - 1
    previous_or_next_page(num, '<span aria-hidden="true">&laquo;</span>')
  end

  def next_page
    num = @collection.current_page < total_pages && @collection.current_page + 1
    previous_or_next_page(num, '<span aria-hidden="true">&raquo;</span>')
  end

  def previous_or_next_page(page, text)
    if page
      '<li class="page-item">' + link(text, page, class: 'page-link') + '</li>'
    else
      '<li class="page-item disabled">' + link(text, page, class: 'page-link') + '</li>'
    end
  end
end

//app/helpers/application_helper.rb

  def will_paginate(coll_or_options = nil, options = {})
    if coll_or_options.is_a? Hash
      options = coll_or_options
      coll_or_options = nil
    end
    unless options[:renderer]
      options = options.merge renderer: BootstrapPaginateRenderer
    end
    super *[coll_or_options, options].compact
  end
like image 4
Memphis335 Avatar answered Nov 11 '22 18:11

Memphis335