# frozen_string_literal: true # Interactive showcase for all the pagy helpers and CSS styles # DEMO USAGE # pagy demo # DEV USAGE # pagy clone demo # pagy ./demo.ru # URL # http://0.0.0.0:8000 # HELP # pagy -h # DOC # https://ddnexus.github.io/pagy/playground/#3-demo-app VERSION = '8.1.1' require 'bundler/inline' gemfile(true) do source 'https://rubygems.org' gem 'oj' gem 'puma' gem 'rouge' gem 'sinatra' gem 'sinatra-contrib' end # pagy initializer STYLES = { pagy: { extra: 'pagy', prefix: '', css_anchor: 'pagy-scss' }, bootstrap: {}, bulma: {}, foundation: {}, materialize: {}, semantic: {}, tailwind: { extra: 'pagy', prefix: '', css_anchor: 'pagy-tailwind-css' }, uikit: {} }.freeze STYLES.each_key do |style| require "pagy/extras/#{STYLES[style][:extra] || style}" end require 'pagy/extras/items' require 'pagy/extras/trim' Pagy::DEFAULT[:trim_extra] = false # opt-in trim Pagy::DEFAULT[:size] = [1, 4, 4, 1] # old size default # sinatra setup require 'sinatra/base' # sinatra application class PagyDemo < Sinatra::Base configure do enable :inline_templates end include Pagy::Backend get '/' do redirect '/pagy' end get '/template' do collection = MockCollection.new @pagy, @records = pagy(collection, trim_extra: params['trim']) erb :template, locals: { pagy: @pagy, style: 'pagy' } end get('/javascripts/:file') do content_type 'application/javascript' send_file Pagy.root.join('javascripts', params[:file]) end get('/stylesheets/:file') do content_type 'text/css' send_file Pagy.root.join('stylesheets', params[:file]) end # one route/action per style STYLES.each_key do |style| prefix = STYLES[style][:prefix] || "_#{style}" get("/#{style}/?:trim?") do collection = MockCollection.new @pagy, @records = pagy(collection, trim_extra: params['trim']) erb :helpers, locals: { style:, prefix: } end end helpers do include Pagy::Frontend def style_menu html = +%(
) STYLES.each_key { |style| html << %(#{style}) } html << %(template) html << %(
) end def highlight(html, format: :html) if format == :html html = html.gsub(/>[\s]*<').strip # template single line no spaces around/between tags html = Formatter.new.format(html) end lexer = Rouge::Lexers::ERB.new formatter = Rouge::Formatters::HTMLInline.new('monokai.sublime') summary = { html: 'Served HTML (pretty formatted)', erb: 'ERB Template' } %(
#{summary[format]}
\n#{
         formatter.format(lexer.lex(html))
      }
) end end end # Cheap pagy formatter for helpers output class Formatter INDENT = ' ' TEXT_SPACE = "\u00B7" TEXT = /^([^<>]+)(.*)/ UNPAIRED = /^(<(input|link).*?>)(.*)/ PAIRED = %r{^(<(head|nav|div|span|p|a|b|label|ul|li).*?>)(.*?)()(.*)} WRAPPER = /<.*?>/ DATA_PAGY = /(data-pagy="([^"]+)")/ def initialize @formatted = +'' end def format(input, level = 0) process(input, level) @formatted end private def process(input, level) push = ->(content) { @formatted << ((INDENT * level) << content << "\n") } rest = nil if (match = input.match(TEXT)) text, rest = match.captures push.(text.gsub(' ', TEXT_SPACE)) elsif (match = input.match(UNPAIRED)) tag, _name, rest = match.captures push.(tag) elsif (match = input.match(PAIRED)) tag_start, name, block, tag_end, rest = match.captures ## Handle incomplete same-tag nesting while block.scan(/<#{name}.*?>/).size > block.scan(tag_end).size more, rest = rest.split(tag_end, 2) block << tag_end << more end if (match = tag_start.match(DATA_PAGY)) search, data = match.captures formatted = data.scan(/.{1,76}/).join("\n") replace = %(\n#{INDENT * (level + 1)}data-pagy="#{formatted}") tag_start.sub!(search, replace) end if block.match(WRAPPER) push.(tag_start) process(block, level + 1) push.(tag_end) else push.(tag_start << block << tag_end) end end process(rest, level) if rest end end # Simple array-based collection that acts as a standard DB collection. class MockCollection < Array def initialize(arr = Array(1..1000)) super @collection = clone end def offset(value) @collection = self[value..] self end def limit(value) @collection[0, value] end def count(*) size end end run PagyDemo # We store the template in a constant instead of writing it inline, so we can highlight it more easily TEMPLATE = <<~ERB <%# IMPORTANT: use '<%== ... ' instead of '<%= ... ' if you run this in rails %> <%# The a variable below is set to a lambda that generates the a tag %> <%# Usage: a_tag = a.(page_number, text, classes: nil, aria_label: nil) %> <% a = pagy_anchor(pagy) %> ERB __END__ @@ layout Pagy Demo App <%= erb :"#{style}_head" if defined?(style) %> <%= style_menu %>
<%= yield %>
@@ pagy_head @@ bootstrap_head @@ bulma_head @@ foundation_head @@ materialize_head @@ semantic_head @@ tailwind_head @@ uikit_head @@ helpers

<%= style %>

<% extra = STYLES[style][:extra] || "#{style}" %> <% css_anchor = STYLES[style][:css_anchor] %>

See the <%= extra %> extra documentation <% if css_anchor %> and the <%= css_anchor.gsub('-', '.') %> <% end %> for details

Collection

@records: <%= @records.join(',') %>

pagy<%= prefix %>_nav Simple nav size: 5

<%= html = send(:"pagy#{prefix}_nav", @pagy, id: 'nav', aria_label: 'Pages nav', size: 5) %> <%= highlight(html) %>

pagy<%= prefix %>_nav Classic nav size: [1,4,4,1]

<%= html = send(:"pagy#{prefix}_nav", @pagy, id: 'nav', aria_label: 'Pages nav') %> <%= highlight(html) %>

pagy<%= prefix %>_nav_js Classic nav size: [1,4,4,1]

<%= html = send(:"pagy#{prefix}_nav_js", @pagy, id: 'nav-js', aria_label: 'Pages nav_js') %> <%= highlight(html) %>

pagy<%= prefix %>_nav_js Responsive steps: {...} (Resize the window to see)

<%= html = send(:"pagy#{prefix}_nav_js", @pagy, id: 'nav-js-responsive', aria_label: 'Pages nav_js_responsive', steps: { 0 => 5, 500 => [1,3,3,1], 700 => [1,4,4,1], 900 => [2,4,4,2] }) %> <%= highlight(html) %>

pagy<%= prefix %>_combo_nav_js

<%= html = send(:"pagy#{prefix}_combo_nav_js", @pagy, id: 'combo-nav-js', aria_label: 'Pages combo_nav_js') %> <%= highlight(html) %>

pagy_info

<%= html = pagy_info(@pagy, id: 'pagy-info') %> <%= highlight(html) %> <% if style.match(/pagy|tailwind/) %>

pagy_items_selector_js

<%= html = pagy_items_selector_js(@pagy, id: 'items-selector-js') %> <%= highlight(html) %>

pagy_prev_a / pagy_next_a

<%= html = '' %> <%= highlight(html) %>

pagy_prev_link / pagy_next_link Link not rendered

<% html = '' << (pagy_prev_link(@pagy)||'') << (pagy_next_link(@pagy)||'') << '' %> <%= highlight(html) %> <% end %> @@ template

Pagy Template Demo

See the Custom Templates documentation.

Collection

@records: <%= @records.join(',') %>

Rendered ERB template

<%# We don't inline the template here, so we can highlight it more easily %> <%= html = ERB.new(TEMPLATE).result(binding) %> <%= highlight(TEMPLATE, format: :erb) %> <%= highlight(html) %>