Skip to content

Instantly share code, notes, and snippets.

@zorab47
Last active May 13, 2023 14:17
Show Gist options
  • Save zorab47/eda38bc72a5d1153b73b to your computer and use it in GitHub Desktop.
Save zorab47/eda38bc72a5d1153b73b to your computer and use it in GitHub Desktop.
Arbre content caching for ActiveAdmin
# Caches Arbre elements in the `Rails.cache`.
#
# Yielding the first time adds to the output buffer regardless of the
# returned value. A cache miss must be handled separately from a hit
# to avoid double rendering.
#
# Returns yielded Arbre on cache miss OR an HTML string wrapped in
# an text node on cache hit.
def cache_arbre(context, *args, &block)
if controller.perform_caching
if Rails.cache.exist?(*args)
context.text_node(Rails.cache.read(*args))
else
Rails.cache.write(*args, arbre_appended_children_content(context, &block))
end
else
yield
end
end
# Returns HTML content for Arbre elements appended to a context.
#
# Due to the complexities of Arbre content buffering it is difficult to get
# the content of an arbitrary set of Arbre elements without the use of a
# wrapping element like a `div`.
#
# Example
#
# Arbre::Context.new do
# h1 "Capturing Children Content"
#
# content = arbre_appended_children_content(self) do
# para "Paragraph 1"
# para "Paragraph 2"
# end
# end
#
# content # => "<p>Paragraph 1</p>\n<p>Paragraph 2</p>\n"
#
# Unlike this simple example which only returns the content of Paragraph 2
# because it is the only object returned from the block.
#
# Arbre::Context.new do
# h1 "Example of "
#
# content = begin
# para "Vanishing Paragraph 1"
# para "Paragraph 2"
# end.to_s
# end
#
# content # => "<p>Paragraph 2</p>\n"
#
def arbre_appended_children_content(context)
children = context.current_arbre_element.children
original_size = children.size
content = "".html_safe
result = yield
if (children.size > original_size)
content = "".html_safe
children[original_size .. -1].each do |child|
content << child.to_s
end
else
# No children added, return the output from yield. This could be when
# content was generated from a partial via `render`.
content = result.to_s
end
content
end
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment