Class: Hanami::View Abstract
- Extended by:
- Dry::Configurable
- Defined in:
- lib/hanami/view.rb,
lib/hanami/view/html.rb,
lib/hanami/view/part.rb,
lib/hanami/view/path.rb,
lib/hanami/view/tilt.rb,
lib/hanami/view/cache.rb,
lib/hanami/view/scope.rb,
lib/hanami/view/errors.rb,
lib/hanami/view/context.rb,
lib/hanami/view/version.rb,
lib/hanami/view/exposure.rb,
lib/hanami/view/rendered.rb,
lib/hanami/view/renderer.rb,
lib/hanami/view/exposures.rb,
lib/hanami/view/rendering.rb,
lib/hanami/view/erb/engine.rb,
lib/hanami/view/erb/parser.rb,
lib/hanami/view/erb/template.rb,
lib/hanami/view/part_builder.rb,
lib/hanami/view/scope_builder.rb,
lib/hanami/view/erb/filters/block.rb,
lib/hanami/view/rendering_missing.rb,
lib/hanami/view/tilt/haml_adapter.rb,
lib/hanami/view/tilt/slim_adapter.rb,
lib/hanami/view/helpers/tag_helper.rb,
lib/hanami/view/decorated_attributes.rb,
lib/hanami/view/erb/filters/trimming.rb,
lib/hanami/view/helpers/escape_helper.rb,
lib/hanami/view/html_safe_string_buffer.rb,
lib/hanami/view/helpers/tag_helper/tag_builder.rb,
lib/hanami/view/helpers/number_formatting_helper.rb
Overview
Subclass this and provide your own configuration and exposures to define your own view
(along with a custom #initialize if you wish to inject dependencies into your subclass)
A standalone, template-based view rendering system that offers everything you need to write well-factored view code.
This represents a single view, holding the configuration and exposures necessary for rendering its template.
Defined Under Namespace
Modules: DecoratedAttributes, ERB, HTML, Helpers, Tilt Classes: Cache, Context, Error, Exposure, Exposures, HTMLSafeStringBuffer, Part, PartBuilder, Path, Rendered, Renderer, Rendering, RenderingMissing, RenderingMissingError, Scope, ScopeBuilder, TemplateNotFoundError, UndefinedConfigError
Constant Summary collapse
- DEFAULT_RENDERER_OPTIONS =
This constant is part of a private API. You should avoid using this constant if possible, as it may be removed or be changed in the future.
{default_encoding: "utf-8"}.freeze
- VERSION =
"3.0.1"
Configuration collapse
-
.config.decorate_exposures=(value) ⇒ Object
Controls whether exposures are decorated by default.
-
.config.default_context=(context) ⇒ Object
Set the default context object to use when rendering.
-
.config.default_format=(format) ⇒ Object
Set the default format to use when rendering.
-
.config.inflector=(inflector) ⇒ Object
Set an inflector to provide to the part_builder and scope_builder.
-
.config.layout=(name) ⇒ Object
Set the name of the layout to render templates within.
-
.config.layouts_dir=(dir) ⇒ Object
Set the name of the directory (within the configured
paths) holding the layouts. -
.config.part_builder=(part_builder) ⇒ Object
Set a custom part builder class.
-
.config.part_class=(part_class) ⇒ Object
Set a custom default part class.
-
.config.scope_namespace=(namespace) ⇒ Object
Set a namespace that will be searched when building scope classes.
-
.config.paths=(paths) ⇒ Object
Set an array of directories that will be searched for all templates (templates, partials, and layouts).
-
.config.renderer_engine_mapping=(mapping) ⇒ Object
A hash specifying the (Tilt-compatible) template engine class to use for a given format.
-
.config.renderer_options=(options) ⇒ Object
A hash of options to pass to the template engine.
-
.config.scope_builder=(scope_builder) ⇒ Object
Set a custom scope builder class.
-
.config.scope_class=(scope_class) ⇒ Object
Set a custom default scope class.
-
.config.scope_namespace=(namespace) ⇒ Object
Set a namespace that will be searched when building scope classes.
-
.config.template=(name) ⇒ Object
Set the name of the template for rendering this view.
-
.config.template_inference_base=(base_path) ⇒ Object
Set the base path to strip away when when inferring a view's template names from its class name.
Exposures collapse
-
.decorate(*names, **options, &block) ⇒ Object
Defines an exposure that will be decorated with a matching Part.
- .expose(*names, **options, &block) ⇒ Object
-
.exposures ⇒ Exposures
private
Returns the defined exposures.
- .private_expose(*names, **options, &block) ⇒ Object
Scope collapse
-
.scope(scope_class = nil, &block) ⇒ Object
Creates and assigns a scope for the current view.
Class Method Summary collapse
- .cache ⇒ Object private
- .gem_loader ⇒ Object private
- .inherited(klass) ⇒ Object private
Instance Method Summary collapse
-
#call(format: config_data.default_format, context: config_data.default_context, layout: config_data.layout, **input) ⇒ Rendered
Renders the view.
-
#config ⇒ Object
Returns the view's configuration.
-
#exposures ⇒ Exposures
private
Returns the view's bound exposures.
-
#initialize ⇒ View
constructor
Returns an instance of the view.
- #rendering(format: config_data.default_format, context: config_data.default_context) ⇒ Object private
Constructor Details
#initialize ⇒ View
Returns an instance of the view. This binds the defined exposures to the view instance.
Subclasses can define their own #initialize to accept injected dependencies, but must call
super() to ensure the standard view initialization can proceed.
556 557 558 559 560 561 562 |
# File 'lib/hanami/view.rb', line 556 def initialize self.class.config.finalize! ensure_config @config_data = config.to_data @exposures = self.class.exposures.bind(self) end |
Class Method Details
.cache ⇒ Object
This method is part of a private API. You should avoid using this method if possible, as it may be removed or be changed in the future.
545 546 547 |
# File 'lib/hanami/view.rb', line 545 def self.cache Cache end |
.decorate(*names, **options, &block) ⇒ Object
Defines an exposure that will be decorated with a matching Part.
This is a shorthand for expose(..., decorate: true).
441 442 443 |
# File 'lib/hanami/view.rb', line 441 def self.decorate(*names, **, &block) expose(*names, **, decorate: true, &block) end |
.config.decorate_exposures=(value) ⇒ Object
256 |
# File 'lib/hanami/view.rb', line 256 setting :decorate_exposures, default: false |
.config.default_context=(context) ⇒ Object
155 |
# File 'lib/hanami/view.rb', line 155 setting :default_context, default: Context.new.freeze |
.config.default_format=(format) ⇒ Object
166 |
# File 'lib/hanami/view.rb', line 166 setting :default_format, default: :html |
.expose(name, **options, &block) ⇒ Object .expose(name, **options) ⇒ Object .expose(name, **options) ⇒ Object .expose(*names, **options) ⇒ Object
415 416 417 418 419 420 421 422 423 |
# File 'lib/hanami/view.rb', line 415 def self.expose(*names, **, &block) if names.length == 1 exposures.add(names.first, block, **) else names.each do |name| exposures.add(name, **) end end end |
.exposures ⇒ Exposures
This method is part of a private API. You should avoid using this method if possible, as it may be removed or be changed in the future.
Returns the defined exposures. These are unbound, since bound exposures are only created when initializing a View instance.
450 451 452 |
# File 'lib/hanami/view.rb', line 450 def self.exposures @exposures ||= Exposures.new end |
.gem_loader ⇒ Object
This method is part of a private API. You should avoid using this method if possible, as it may be removed or be changed in the future.
25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 |
# File 'lib/hanami/view.rb', line 25 def self.gem_loader @gem_loader ||= Zeitwerk::Loader.new.tap do |loader| root = File.("..", __dir__) loader.tag = "hanami-view" loader.push_dir(root) loader.ignore( "#{root}/hanami-view.rb", "#{root}/hanami/view/version.rb", "#{root}/hanami/view/errors.rb", # These adapters require the optional "haml" and "slim" gems. They are loaded lazily by # Tilt (see Hanami::View::Tilt) only when their respective template engines are used; # ignore them here to allow eager loading without those gems installed. "#{root}/hanami/view/tilt/haml_adapter.rb", "#{root}/hanami/view/tilt/slim_adapter.rb" ) loader.inflector = Zeitwerk::GemInflector.new("#{root}/hanami-view.rb") loader.inflector.inflect( "erb" => "ERB", "html" => "HTML", "html_safe_string_buffer" => "HTMLSafeStringBuffer" ) end end |
.config.inflector=(inflector) ⇒ Object
239 |
# File 'lib/hanami/view.rb', line 239 setting :inflector, default: Dry::Inflector.new |
.inherited(klass) ⇒ Object
This method is part of a private API. You should avoid using this method if possible, as it may be removed or be changed in the future.
296 297 298 299 300 301 302 |
# File 'lib/hanami/view.rb', line 296 def self.inherited(klass) super exposures.each do |name, exposure| klass.exposures.import(name, exposure) end end |
.config.layout=(name) ⇒ Object
117 |
# File 'lib/hanami/view.rb', line 117 setting :layout, default: false |
.config.layouts_dir=(dir) ⇒ Object
127 |
# File 'lib/hanami/view.rb', line 127 setting :layouts_dir, default: "layouts" |
.config.part_builder=(part_builder) ⇒ Object
196 |
# File 'lib/hanami/view.rb', line 196 setting :part_builder, default: PartBuilder |
.config.part_class=(part_class) ⇒ Object
175 |
# File 'lib/hanami/view.rb', line 175 setting :part_class, default: Part |
.config.scope_namespace=(namespace) ⇒ Object
187 |
# File 'lib/hanami/view.rb', line 187 setting :part_namespace |
.config.paths=(paths) ⇒ Object
74 75 76 |
# File 'lib/hanami/view.rb', line 74 setting :paths, constructor: -> paths { Array(paths).map { |path| Path[path] } } |
.private_expose(*names, **options, &block) ⇒ Object
429 430 431 |
# File 'lib/hanami/view.rb', line 429 def self.private_expose(*names, **, &block) expose(*names, **, private: true, &block) end |
.config.renderer_engine_mapping=(mapping) ⇒ Object
291 |
# File 'lib/hanami/view.rb', line 291 setting :renderer_engine_mapping, default: {} |
.config.renderer_options=(options) ⇒ Object
272 273 274 |
# File 'lib/hanami/view.rb', line 272 setting :renderer_options, default: DEFAULT_RENDERER_OPTIONS, constructor: -> { DEFAULT_RENDERER_OPTIONS.merge(.to_h).freeze } |
.scope(scope_class = nil, &block) ⇒ Object
Creates and assigns a scope for the current view.
The newly created scope is useful to add custom logic that is specific to the view.
The scope has access to locals, exposures, and inherited scope (if any)
If the view already has an explicit scope the newly created scope will inherit from the explicit scope.
There are two cases when this may happen:
1. The scope was explicitly assigned (e.g. `config.scope = MyScope`)
2. The scope has been inherited by the view superclass
If the view doesn't have an already existing scope, the newly scope
will inherit from Hanami::View::Scope by default.
However, you can specify any base class for it. This is not recommended, unless you know what you're doing.
141 |
# File 'lib/hanami/view.rb', line 141 setting :scope |
.config.scope_builder=(scope_builder) ⇒ Object
228 |
# File 'lib/hanami/view.rb', line 228 setting :scope_builder, default: ScopeBuilder |
.config.scope_class=(scope_class) ⇒ Object
205 |
# File 'lib/hanami/view.rb', line 205 setting :scope_class, default: Scope |
.config.scope_namespace=(namespace) ⇒ Object
217 |
# File 'lib/hanami/view.rb', line 217 setting :scope_namespace |
.config.template_inference_base=(base_path) ⇒ Object
104 |
# File 'lib/hanami/view.rb', line 104 setting :template_inference_base |
Instance Method Details
#call(format: config_data.default_format, context: config_data.default_context, layout: config_data.layout, **input) ⇒ Rendered
Renders the view.
592 593 594 595 596 597 598 599 600 601 602 603 604 605 606 607 608 609 610 |
# File 'lib/hanami/view.rb', line 592 def call(format: config_data.default_format, context: config_data.default_context, layout: config_data.layout, **input) rendering = self.rendering(format: format, context: context) scope_class = config_data.scope locals = locals(rendering, input) output = rendering.template(config_data.template, rendering.scope(scope_class, locals)) if layout output = rendering.template( layout_path(layout), rendering.scope(scope_class, layout_locals(locals)) ) { output } end Rendered.new(output: output, locals: locals) end |
#config ⇒ Object
Returns the view's configuration.
568 569 570 |
# File 'lib/hanami/view.rb', line 568 def config self.class.config end |
#exposures ⇒ Exposures
This method is part of a private API. You should avoid using this method if possible, as it may be removed or be changed in the future.
Returns the view's bound exposures.
577 578 579 |
# File 'lib/hanami/view.rb', line 577 def exposures # rubocop:disable Style/TrivialAccessors @exposures end |
#rendering(format: config_data.default_format, context: config_data.default_context) ⇒ Object
This method is part of a private API. You should avoid using this method if possible, as it may be removed or be changed in the future.
613 614 615 |
# File 'lib/hanami/view.rb', line 613 def rendering(format: config_data.default_format, context: config_data.default_context) Rendering.new(config_data:, format:, context:) end |