erb-lint is a popular linter for ERB files. It comes with a set of great lint rules built-in, and it’s extensible.
However, one thing it lacks is the ability to enforce a particular quote style on your HTML attributes.
Note: We are not talking about the quote style used in the Ruby code embedded in ERB. For those, you can already configure erb-lint
with RuboCop, and it will read your RuboCop rules and enforce the quote style for the Ruby code inside your ERB file.
Coming soon: The only Rails UI library you'll ever need
- Includes a lot of components necessary to build a modern app
- Dark mode support out of the box · Simple to customize & extend
- Simple primitives as well as complex components - not "another UI library"
- Patterns I've found incredibly useful over the past years working with Rails
Subscribe now to receive updates and a free preview
To enforce a particular style on HTML attributes, we just need to add a simple custom linter:
First, define your custom linter in .erb-linters/quotes_in_html_attributes.rb
:
module ERBLint
module Linters
class QuotesInHtmlAttributes < Linter
include LinterRegistry
class ConfigSchema < LinterConfig
property :enforced_quote_style, converts: :to_sym, accepts: [:single, :double], default: :double
end
self.config_schema = ConfigSchema
def run(processed_source)
parser = processed_source.parser
parser.nodes_with_type(:tag).each do |tag_node|
tag = BetterHtml::Tree::Tag.from_node(tag_node)
next if tag.closing?
tag.attributes.each do |attribute|
quote = attribute.value_node&.children&.first
next unless quote&.type == :quote
# Quote is a BetterHtml::AST::Node at this point = s(:quote, "'")
quote = quote.children.first
# Quote is now either ' || "
quote_style = quote == "'" ? :single : :double
next if quote_style == @config.enforced_quote_style
add_offense(
attribute.value_node.loc,
"Use #{@config.enforced_quote_style} quotes for HTML attributes",
nil,
:convention
)
end
end
end
def autocorrect(_processed_source, offense)
lambda do |corrector|
new_quote = @config.enforced_quote_style == :single ? "'" : '"'
new_source = offense.source_range.source.gsub(/^\s*['"]/, new_quote).gsub(/['"]\s*$/, new_quote)
corrector.replace(offense.source_range, new_source)
end
end
end
end
end
Then, enable this linter in your .erb-lint.yml
:
---
...
...
linters:
QuotesInHtmlAttributes:
enforced_quote_style: double
enabled: true
...
...
If you prefer single quotes, simply use enforced_quote_style: single
in your configuration.
This custom linter is capable of linting erb-lint filename.html.erb
as well as auto-correcting erb-lint -a filename.html.erb
.
Get more articles like this
Subscribe to my newsletter to get my latest blog posts, and other freebies like Treact, as soon as they get published !