Skip to content

Instantly share code, notes, and snippets.

@julik
Last active April 22, 2025 09:29
Show Gist options
  • Save julik/a9b2102bd486221383437e6961b770a7 to your computer and use it in GitHub Desktop.
Save julik/a9b2102bd486221383437e6961b770a7 to your computer and use it in GitHub Desktop.
styled_templates.rb
# <%= style_for_this_template do %>
# width: 128px;
# .caption {
# font-size: 12px;
# text-align: center;
# }
# <% end %>
# <div class="<%= css_class_for_this_template %>">
# <div class="title">Hello!</div>
# </div>
module StyledTemplatesHelper
def css_class_selector_for_this_template
".#{css_class_for_this_template}"
end
def css_class_for_this_template
raise "@current_template is not set, so we can't intuit the wrapping class name for this block" unless @current_template.present?
# Rails computes the method name the template will be compiled into. This method name changes with changes to the template
# source, and includes the digest-like details and all the other useful bits.
compiled_template_method_name = @current_template.method_name
# We will use the virtual path as the base for our CSS class
template_virtual_path = @current_template.virtual_path
_css_class_name = template_virtual_path.gsub(/(\/|_)/, "-") + "-" + Digest::SHA1.hexdigest(compiled_template_method_name)[0..3]
end
def style_for_this_template(css_source_or_nil = nil)
if !block_given? && style_source.blank?
raise "You need to either pass the CSS code as the first argument or render it from the passed block"
end
css_class_name = css_class_for_this_template
@styles_already_output ||= Set.new
return if @styles_already_output.include?(css_class_name)
# https://thepugautomatic.com/2013/06/helpers/
capture do
concat("<style>\n".html_safe)
concat("\n.#{css_class_name} {\n")
concat((block_given? ? yield : css_source_or_nil) + "\n")
concat("\n}\n")
concat("</style>\n".html_safe)
end.tap do
@styles_already_output << css_class_name
end
end
end
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment