feat(view): add Prism, AssetHelpers and CacheHelpers

This commit is contained in:
dualfroz committed 2026-09-08 21:56:35 +02:00
1 parent 0b6cf1b91e
commit 8ec5cbe0ed
3 files changed
+78

No files matched your search

+30
View File
@@ -0,0 +1,30 @@
module Prism
# asset_path/stylesheet_link_tag/javascript_include_tag/image_tag look a
# logical path up in Prism::Assets.manifest when the app has one loaded
# (Application#enable_assets, normally after Assets::Compiler#compile! ran)
# and return the fingerprinted "/assets/..." URL; with no manifest loaded
# (nothing called enable_assets, e.g. a plain dev boot) they fall back to
# serving the logical path straight from "/assets/" unfingerprinted, the
# same escape hatch Propshaft's dev mode uses.
module AssetHelpers
def asset_path(logical_path)
if Prism::Assets.enabled?
"/assets/#{Prism::Assets.manifest.lookup(logical_path)}"
else
"/assets/#{logical_path}"
end
end
def stylesheet_link_tag(logical_path, **attributes)
tag(:link, { rel: 'stylesheet', href: asset_path(logical_path) }.merge(attributes))
end
def javascript_include_tag(logical_path, **attributes)
content_tag(:script, '', { src: asset_path(logical_path) }.merge(attributes))
end
def image_tag(logical_path, **attributes)
tag(:img, { src: asset_path(logical_path) }.merge(attributes))
end
end
end
+23
View File
@@ -0,0 +1,23 @@
module Prism
# `cache(key) { ... }` used from a plain `<% %>` template tag: renders the
# block once, stores the resulting markup in Prism::Cache.store keyed by
# Prism::View#expand_cache_key(key), and on a hit appends the stored
# markup straight to the buffer without re-evaluating the block at all.
# `key` may be a String/Symbol, a model instance (uses #cache_key) or an
# Array mixing both (e.g. `cache [:sidebar, current_user, post]`).
module CacheHelpers
def cache(key, expires_in: nil)
raise 'no view attached to this template' unless @view
cache_key = @view.expand_cache_key(key)
cached = Prism::Cache.store.read(cache_key)
if cached
@__out << cached
else
fragment = capture { yield }
Prism::Cache.store.write(cache_key, fragment, expires_in: expires_in)
@__out << fragment
end
nil
end
end
end
+25
View File
@@ -0,0 +1,25 @@
module Prism
# `content_for(:name) { ... }` stashes a captured fragment on the current
# Prism::View instance instead of the page buffer; `content_for(:name)`
# (no block) reads it back. This is what lets a content template push
# markup (a page title, a sidebar widget) into a *different* slot of the
# layout that renders around it, since the content template and the
# layout template each get their own Template::Context but share the
# same View (see Prism::View#render / #content_for_store).
module ContentForHelpers
def content_for(name, &block)
raise 'no view attached to this template' unless @view
if block
@view.append_content_for(name, capture(&block))
nil
else
@view.content_for(name)
end
end
def content_for?(name)
raise 'no view attached to this template' unless @view
@view.content_for?(name)
end
end
end