diff --git a/lib/prism/view/asset_helpers.rb b/lib/prism/view/asset_helpers.rb new file mode 100644 index 0000000..879624b --- /dev/null +++ b/lib/prism/view/asset_helpers.rb @@ -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 diff --git a/lib/prism/view/cache_helpers.rb b/lib/prism/view/cache_helpers.rb new file mode 100644 index 0000000..aef8734 --- /dev/null +++ b/lib/prism/view/cache_helpers.rb @@ -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 diff --git a/lib/prism/view/content_for_helpers.rb b/lib/prism/view/content_for_helpers.rb new file mode 100644 index 0000000..c8944ca --- /dev/null +++ b/lib/prism/view/content_for_helpers.rb @@ -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