Rails 3 & HTML 5 Microdata

后端 未结 2 1897
别跟我提以往
别跟我提以往 2021-01-01 03:49

In Rails, is it possible to create a HTML 5 valueless attribute using any of the ActionView Helpers? I\'m trying to create the HTML 5 itemprop microdata for google\'s BreadC

相关标签:
2条回答
  • 2021-01-01 04:23

    No, you can't. Rails' tag helper defines a ActionView::Helpers::TagHelper::BOOLEAN_ATTRIBUTES array, and any attributes in that array will be outputted as key=key, so if you had, say, tag(:input, :type => :checkbox, :checked => true), the output should be <input type='checkbox' checked='checked' />.

    I presume that this parses properly, since an XML parser is simply going to check for the presence of the attribute, so any value should work.

    To that end, you could use:

    content_tag(:div, "somecontent", :itemscope => "itemscope", :item_type ...
    

    This will output itemscope="itemscope" in the tag, but it should result in the same desired effect when parsed.

    Alternately, you could add itemscope to the BOOLEAN_ATTRIBUTES, then specify :itemscope => true.

    0 讨论(0)
  • 2021-01-01 04:50

    You can achieve the result you want if you are willing to override a private Rails method. If you do this, you run the risk of causing problems when upgrading to future versions of Rails that update the private method logic. Since both <div itemscope ...> and <div itemscope="itemscope" ...> are valid according to the HTML5 spec, making the change below has very little payoff. The only reason I can think of to do this is if you are completely obsessive about your HTML code style.

    As Chris Heald said, we will add itemscope to BOOLEAN_ATTRIBUTES and then override the tag helper to output boolean attributes without values. (The following tag_options method is modified from Rails/ActionPack 3.0.7 - future readers should copy the contemporary tag_options code and then make the change after the if BOOLEAN_ATTRIBUTES.include?(key) line.)

    module ActionView
      module Helpers
        module TagHelper
          BOOLEAN_ATTRIBUTES.merge(['itemscope', :itemscope])
          private
          def tag_options(options, escape = true)
            unless options.blank?
              attrs = []
              options.each_pair do |key, value|
                if BOOLEAN_ATTRIBUTES.include?(key)
                  attrs << key.to_s if value
                elsif !value.nil?
                  final_value = value.is_a?(Array) ? value.join(" ") : value
                  final_value = html_escape(final_value) if escape
                  attrs << %(#{key}="#{final_value}")
                end
              end
              " #{attrs.sort * ' '}".html_safe unless attrs.empty?
            end
          end
        end
      end
    end
    

    You can now update your view with:

    content_tag(:div, "somecontent", :itemscope => true, :item_type => "http://data-vocabulary.org/Breadcrumb"
    

    FWIW, I store extensions to existing classes in e.g. lib/extensions/action_view.rb; these extensions are loaded by config/initializers/extensions.rb which consists of:

    Dir[File.join(Rails.root, 'lib', 'extensions', '*.rb')].each {|f| require f}
    
    0 讨论(0)
提交回复
热议问题