class FilterPage < Page include Radiant::Taggable class TagError < StandardError; end description %{ Special Page for collecting model filters. } desc %{ } tag 'filters' do |tag| tag.locals.filters = tag.globals.page.filters tag.locals.ops = tag.globals.page.ops tag.expand end desc %{ } tag 'filters:rel_url' do |tag| tag.globals.page.rel_url end desc %{ } tag 'filters:each' do |tag| if tag.locals.filters && tag.locals.filters.size>0 result = [] tag.locals.filters.each do |field,value| tag.locals.field = field tag.locals.value = value tag.locals.op = tag.locals.ops[field] || '=' result << tag.expand end result end end desc %{ } tag 'filters:count' do |tag| if tag.locals.filters tag.locals.filters.size.to_s else "0" end end desc %{ } tag 'filters:conditions' do |tag| sqlfilter = "" if tag.locals.filters && tag.locals.filters.size > 0 tag.locals.filters.each do |field,value| op = tag.locals.ops[field] if (tag.locals.ops && field && value) if op && field && value if sqlfilter.size != 0 sqlfilter += " AND " end if op == 'Starts' sqlfilter += "#{field} LIKE '#{value}%'" elsif op == 'Ends' sqlfilter += "#{field} LIKE '%#{value}'" elsif op == 'Contains' sqlfilter += "#{field} LIKE '%#{value}%'" elsif op == 'Is null' sqlfilter += "(#{field} is null OR length(#{field})=0)" elsif op == 'Not null' sqlfilter += "(#{field} is not null AND length(#{field})>0)" else sqlfilter += "#{field} #{op} '#{value}'" end end end end tag.locals.conditions = sqlfilter tag.expand end desc %{ } tag "filters:if_field" do |tag| field = tag.attr['name'] || "" if tag.locals.filters && tag.locals.filters[field] tag.expand end end desc %{ } tag "filters:unless_field" do |tag| field = tag.attr['name'] || "" unless tag.locals.filters && tag.locals.filters[field] tag.expand end end desc %{ } tag 'filters:conditions:show' do |tag| tag.locals.conditions end desc %{ } tag 'filters:each:field' do |tag| tag.locals.field end desc %{ } tag 'filters:each:value' do |tag| tag.locals.value end desc %{ } tag 'filters:each:op' do |tag| tag.locals.op end def virtual? true end attr_reader :filters attr_reader :ops attr_reader :rel_url def find_by_url(url, live = true, clean = false) @filters = Hash.new @ops = Hash.new ops_table = { 'e'=>'=', 'g'=>'>', 'G'=>'>=', 'l'=>'<', 'L'=>'<=', 'a'=> 'Starts', 'z'=>'Ends', 'c'=>'Contains', 'n'=>'Is null', 'N'=>'Not null' } url = clean_url(url) if clean if url =~ %r{#{ self.url }(((\w{1,50}:\w:[^\'\"]{1,100})/?){1,8})/?$} filterstr = $1 @rel_url = "" h = Hash.new tmp = filterstr.split('/') if filterstr tmp.each do |t| field, op, value = t.split(':',3) @filters[field] = value if (field && value) @ops[field] = ops_table[op] if (field && op && ops_table[op]) h[field] = t end h.each { |k,v| @rel_url += "#{v}/" } self else super end end end