Skip to content

Commit

Permalink
Make 'data' attributes also available in all tags.
Browse files Browse the repository at this point in the history
  • Loading branch information
DAddYE committed Mar 12, 2012
1 parent a7af2e0 commit d0845dc
Show file tree
Hide file tree
Showing 2 changed files with 92 additions and 91 deletions.
130 changes: 54 additions & 76 deletions padrino-helpers/lib/padrino-helpers/asset_tag_helpers.rb
Expand Up @@ -70,7 +70,6 @@ def flash_tag(*args)
# @api public
def link_to(*args, &block)
options = args.extract_options!
options = parse_js_attributes(options) # parses remote, method and confirm options
anchor = "##{CGI.escape options.delete(:anchor).to_s}" if options[:anchor]

if block_given?
Expand Down Expand Up @@ -354,86 +353,65 @@ def asset_path(kind, source)
end

private
##
# Returns the uri root of the application with optional paths appended.
#
# @example
# uri_root_path("/some/path") => "/root/some/path"
# uri_root_path("javascripts", "test.js") => "/uri/root/javascripts/test.js"
#
def uri_root_path(*paths)
root_uri = self.class.uri_root if self.class.respond_to?(:uri_root)
File.join(ENV['RACK_BASE_URI'].to_s, root_uri || '/', *paths)
end

##
# Returns the uri root of the application with optional paths appended.
#
# @example
# uri_root_path("/some/path") => "/root/some/path"
# uri_root_path("javascripts", "test.js") => "/uri/root/javascripts/test.js"
#
def uri_root_path(*paths)
root_uri = self.class.uri_root if self.class.respond_to?(:uri_root)
File.join(ENV['RACK_BASE_URI'].to_s, root_uri || '/', *paths)
end

##
# Returns the timestamp mtime for an asset
#
# @example
# asset_timestamp("some/path/to/file.png") => "?154543678"
# asset_timestamp("/some/absolute/path.png", true) => nil
#
def asset_timestamp(file_path, absolute=false)
return nil if file_path =~ /\?/ || (self.class.respond_to?(:asset_stamp) && !self.class.asset_stamp)
public_file_path = Padrino.root("public", file_path) if Padrino.respond_to?(:root)
stamp = File.mtime(public_file_path).to_i if public_file_path && File.exist?(public_file_path)
stamp ||= Time.now.to_i unless absolute
"?#{stamp}" if stamp
end

###
# Returns the asset folder given a kind.
#
# @example
# asset_folder_name(:css) => 'stylesheets'
# asset_folder_name(:js) => 'javascripts'
# asset_folder_name(:images) => 'images'
#
def asset_folder_name(kind)
case kind
when :css then 'stylesheets'
when :js then 'javascripts'
else kind.to_s
end
end
##
# Returns the timestamp mtime for an asset
#
# @example
# asset_timestamp("some/path/to/file.png") => "?154543678"
# asset_timestamp("/some/absolute/path.png", true) => nil
#
def asset_timestamp(file_path, absolute=false)
return nil if file_path =~ /\?/ || (self.class.respond_to?(:asset_stamp) && !self.class.asset_stamp)
public_file_path = Padrino.root("public", file_path) if Padrino.respond_to?(:root)
stamp = File.mtime(public_file_path).to_i if public_file_path && File.exist?(public_file_path)
stamp ||= Time.now.to_i unless absolute
"?#{stamp}" if stamp
end

##
# Parses link_to options for given correct conditions
#
# @example
# parse_conditions("/some/url", :if => false) => true
#
def parse_conditions(url, options)
if options.has_key?(:if)
condition = options.delete(:if)
condition == :current ? url == request.path_info : condition
elsif condition = options.delete(:unless)
condition == :current ? url != request.path_info : !condition
else
true
end
###
# Returns the asset folder given a kind.
#
# @example
# asset_folder_name(:css) => 'stylesheets'
# asset_folder_name(:js) => 'javascripts'
# asset_folder_name(:images) => 'images'
#
def asset_folder_name(kind)
case kind
when :css then 'stylesheets'
when :js then 'javascripts'
else kind.to_s
end
end

##
# Parses link_to options for given js declarations (remote, method, confirm)
# Not destructive on options; returns updated options
#
# parse_js_attributes(:remote => true, :confirm => "test", :method => :delete)
# => { "data-remote" => true, "data-method" => "delete", "data-confirm" => "test" }
#
def parse_js_attributes(options)
options = options.dup
options['data-remote'] = 'true' if options.delete(:remote)
if link_confirm = options.delete(:confirm)
options['data-confirm'] = link_confirm
end
if link_method = options.delete(:method)
options['data-method'] = link_method
options['rel'] = 'nofollow'
end
options
##
# Parses link_to options for given correct conditions
#
# @example
# parse_conditions("/some/url", :if => false) => true
#
def parse_conditions(url, options)
if options.has_key?(:if)
condition = options.delete(:if)
condition == :current ? url == request.path_info : condition
elsif condition = options.delete(:unless)
condition == :current ? url != request.path_info : !condition
else
true
end
end
end # AssetTagHelpers
end # Helpers
end # Padrino
53 changes: 38 additions & 15 deletions padrino-helpers/lib/padrino-helpers/tag_helpers.rb
Expand Up @@ -28,6 +28,12 @@ module TagHelpers
:selected
]

DATA_ATTRIBUTES = [
:method,
:remote,
:confirm
]

##
# Creates an HTML tag with given name, content, and options
#
Expand Down Expand Up @@ -92,7 +98,9 @@ def content_tag(name, content = nil, options = nil, &block)

content = content.join("\n") if content.respond_to?(:join)

output = "<#{name}#{tag_options(options) if options}>#{content}</#{name}>"
options = parse_data_options(name, options)
attributes = tag_attributes(options)
output = "<#{name}#{attributes}>#{content}</#{name}>"
block_is_template?(block) ? concat_content(output) : output
end

Expand Down Expand Up @@ -182,34 +190,35 @@ def input_tag(type, options = {})
#
# @api public
def tag(name, options = nil, open = false)
"<#{name}#{tag_options(options) if options}#{open ? '>' : ' />'}"
options = parse_data_options(name, options)
attributes = tag_attributes(options)
"<#{name}#{attributes}#{open ? '>' : ' />'}"
end

private
##
# Returns a compiled list of HTML attributes
##
def tag_options(options)
return if options.blank?
attributes = []
options.each do |attribute, value|
next if value.nil? || value == false
if value.is_a?(Hash)
attributes << nested_values(attribute, value)
elsif BOOLEAN_ATTRIBUTES.include?(attribute)
attributes << attribute.to_s
def tag_attributes(options)
return '' if options.nil?
attributes = options.map do |k, v|
next if v.nil? || v == false
if v.is_a?(Hash)
nested_values(k, v)
elsif BOOLEAN_ATTRIBUTES.include?(k)
k.to_s
else
attributes << %(#{attribute}="#{escape_value(value)}")
%(#{k}="#{escape_value(v)}")
end
end
" #{attributes.join(' ')}"
end.compact
attributes.empty? ? '' : " #{attributes * ' '}"
end

##
# Escape tag values to their HTML/XML entities.
##
def escape_value(string)
string.to_s.gsub(Regexp.union(*ESCAPE_VALUES.keys)){|c| ESCAPE_VALUES[c] }
string.to_s.gsub(Regexp.union(*ESCAPE_VALUES.keys)) { |c| ESCAPE_VALUES[c] }
end

##
Expand All @@ -224,6 +233,20 @@ def nested_values(attribute, hash)
end
end * ' '
end

##
# Parses custom data attributes
#
def parse_data_options(tag, options)
return if options.nil?
options = options.dup
options.each do |k, v|
next if !DATA_ATTRIBUTES.include?(k) || (tag.to_s == 'form' && k == :method)
options["data-#{k}"] = options.delete(k)
options[:rel] = 'nofollow' if k == :method
end
options
end
end # TagHelpers
end # Helpers
end # Padrino

0 comments on commit d0845dc

Please sign in to comment.