module StandardTags

def absolute_path_for(base_path, new_path)

def absolute_path_for(base_path, new_path)
  if new_path.first == '/'
    new_path
  else
    File.expand_path(File.join(base_path, new_path))
  end
end

def aggregate_children(tag)

def aggregate_children(tag)
  options = children_find_options(tag)
  parent_ids = tag.locals.parent_ids
  conditions = options[:conditions]
  conditions.first << ' AND parent_id IN (?)'
  conditions << parent_ids
  options
end

def attr_or_error(tag, options = {})

def attr_or_error(tag, options = {})
  attribute_name = options[:attribute_name].to_s
  default = options[:default]
  values = options[:values].split(',').map!(&:strip)
  attribute = (tag.attr[attribute_name] || default).to_s
  raise TagError.new(%{`#{attribute_name}' attribute of `#{tag.name}' tag must be one of: #{values.join(', ')}}) unless values.include?(attribute)
  attribute
end

def boolean_attr_or_error(tag, attribute_name, default)

def boolean_attr_or_error(tag, attribute_name, default)
  attribute = attr_or_error(tag, attribute_name: attribute_name, default: default.to_s, values: 'true, false')
  attribute.to_s.downcase == 'true'
end

def build_regexp_for(tag, attribute_name)

def build_regexp_for(tag, attribute_name)
  ignore_case = tag.attr.has_key?('ignore_case') && tag.attr['ignore_case'] == 'false' ? nil : true
  begin
    regexp = Regexp.new(tag.attr['matches'], ignore_case)
  rescue RegexpError => e
    raise TagError.new("Malformed regular expression in `#{attribute_name}' argument of `#{tag.name}' tag: #{e.message}")
  end
  regexp
end

def children_find_options(tag)

def children_find_options(tag)
  attr = tag.attr.symbolize_keys
  options = {}
  %i[limit offset].each do |symbol|
    if number = attr[symbol]
      if number =~ /^\d+$/
        options[symbol] = number.to_i
      else
        raise TagError.new("`#{symbol}' attribute must be a positive number")
      end
    end
  end
  by = (attr[:by] || 'published_at').strip
  order = (attr[:order] || 'asc').strip
  order_string = ''
  if attributes.keys.include?(by)
    order_string << by
  else
    raise TagError.new("`by' attribute of `each' tag must be set to a valid field name")
  end
  if order =~ /^(asc|desc)$/i
    order_string << " #{$1.upcase}"
  else
    raise TagError.new(%{`order' attribute of `each' tag must be set to either "asc" or "desc"})
  end
  options[:order] = order_string
  status = (attr[:status] || (dev?(tag.globals.page.request) ? 'all' : 'published')).downcase
  if status == 'all'
    options[:conditions] = ['virtual = ?', false]
  else
    stat = Status[status]
    if stat.nil?
      raise TagError.new(%{`status' attribute of `each' tag must be set to a valid status})
    else
      options[:conditions] = ['(virtual = ?) and (status_id = ?)', false, stat.id]
    end
  end
  options
end

def dev?(request)

def dev?(request)
  return false if request.nil?
  if dev_host = TrustyCms::Config['dev.host']
    dev_host == request.host
  else
    request.host =~ /^dev\./
  end
end

def page_found?(page)

def page_found?(page)
  page && !(FileNotFoundPage === page)
end

def pagination_find_options(tag)

def pagination_find_options(tag)
  attr = tag.attr.symbolize_keys
  if attr[:paginated] == 'true'
    pagination_parameters.merge(attr.slice(:per_page))
  else
    false
  end
end

def relative_url_for(url, _request)

def relative_url_for(url, _request)
  File.join(ActionController::Base.relative_url_root || '', url)
end

def remove_trailing_slash(string)

def remove_trailing_slash(string)
  string =~ %r{^(.*?)/$} ? $1 : string
end

def render_children_with_pagination(tag, opts = {})

def render_children_with_pagination(tag, opts = {})
  if opts[:aggregate]
    findable = Page
    options = aggregate_children(tag)
  else
    findable = tag.locals.children
    options = children_find_options(tag)
  end
  paging = pagination_find_options(tag)
  result = []
  tag.locals.previous_headers = {}
  displayed_children = paging ? findable.paginate(options.merge(paging)) : findable.all.where(options[:conditions]).order(options[:order])
  displayed_children.each_with_index do |item, i|
    tag.locals.child = item
    tag.locals.page = item
    tag.locals.first_child = i == 0
    tag.locals.last_child = i == displayed_children.length - 1
    result << tag.expand
  end
  if paging && displayed_children.total_pages > 1
    tag.locals.paginated_list = displayed_children
    result << tag.render('pagination', tag.attr.dup)
  end
  result.flatten.join('')
end

def required_attr(tag, *attribute_names)

def required_attr(tag, *attribute_names)
  attr_collection = attribute_names.map { |a| "`#{a}'" }.join(' or ')
  raise TagError.new("`#{tag.name}' tag must contain a #{attr_collection} attribute.") if (tag.attr.keys & attribute_names).blank?
end

def tag_part_name(tag)

def tag_part_name(tag)
  tag.attr['part'] || 'body'
end

def will_paginate_options(tag)

def will_paginate_options(tag)
  attr = tag.attr.symbolize_keys
  if attr[:paginated] == 'true'
    attr.slice(:class, :previous_label, :next_label, :inner_window, :outer_window, :separator, :per_page).merge({ renderer: TrustyCms::Pagination::LinkRenderer.new(tag.globals.page.path) })
  else
    {}
  end
end