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.0.rc1"
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.
551 552 553 554 555 556 557 |
# File 'lib/hanami/view.rb', line 551 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.
540 541 542 |
# File 'lib/hanami/view.rb', line 540 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)`.
436 437 438 |
# File 'lib/hanami/view.rb', line 436 def self.decorate(*names, **, &block) expose(*names, **, decorate: true, &block) end |
.config.decorate_exposures=(value) ⇒ Object
251 |
# File 'lib/hanami/view.rb', line 251 setting :decorate_exposures, default: false |
.config.default_context=(context) ⇒ Object
150 |
# File 'lib/hanami/view.rb', line 150 setting :default_context, default: Context.new.freeze |
.config.default_format=(format) ⇒ Object
161 |
# File 'lib/hanami/view.rb', line 161 setting :default_format, default: :html |
.expose(name, **options, &block) ⇒ Object .expose(name, **options) ⇒ Object .expose(name, **options) ⇒ Object .expose(*names, **options) ⇒ Object
410 411 412 413 414 415 416 417 418 |
# File 'lib/hanami/view.rb', line 410 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.
445 446 447 |
# File 'lib/hanami/view.rb', line 445 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 |
# 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" ) 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
234 |
# File 'lib/hanami/view.rb', line 234 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.
291 292 293 294 295 296 297 |
# File 'lib/hanami/view.rb', line 291 def self.inherited(klass) super exposures.each do |name, exposure| klass.exposures.import(name, exposure) end end |
.config.layout=(name) ⇒ Object
112 |
# File 'lib/hanami/view.rb', line 112 setting :layout, default: false |
.config.layouts_dir=(dir) ⇒ Object
122 |
# File 'lib/hanami/view.rb', line 122 setting :layouts_dir, default: "layouts" |
.config.part_builder=(part_builder) ⇒ Object
191 |
# File 'lib/hanami/view.rb', line 191 setting :part_builder, default: PartBuilder |
.config.part_class=(part_class) ⇒ Object
170 |
# File 'lib/hanami/view.rb', line 170 setting :part_class, default: Part |
.config.scope_namespace=(namespace) ⇒ Object
182 |
# File 'lib/hanami/view.rb', line 182 setting :part_namespace |
.config.paths=(paths) ⇒ Object
69 70 71 |
# File 'lib/hanami/view.rb', line 69 setting :paths, constructor: -> paths { Array(paths).map { |path| Path[path] } } |
.private_expose(*names, **options, &block) ⇒ Object
424 425 426 |
# File 'lib/hanami/view.rb', line 424 def self.private_expose(*names, **, &block) expose(*names, **, private: true, &block) end |
.config.renderer_engine_mapping=(mapping) ⇒ Object
286 |
# File 'lib/hanami/view.rb', line 286 setting :renderer_engine_mapping, default: {} |
.config.renderer_options=(options) ⇒ Object
267 268 269 |
# File 'lib/hanami/view.rb', line 267 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.
136 |
# File 'lib/hanami/view.rb', line 136 setting :scope |
.config.scope_builder=(scope_builder) ⇒ Object
223 |
# File 'lib/hanami/view.rb', line 223 setting :scope_builder, default: ScopeBuilder |
.config.scope_class=(scope_class) ⇒ Object
200 |
# File 'lib/hanami/view.rb', line 200 setting :scope_class, default: Scope |
.config.scope_namespace=(namespace) ⇒ Object
212 |
# File 'lib/hanami/view.rb', line 212 setting :scope_namespace |
.config.template_inference_base=(base_path) ⇒ Object
99 |
# File 'lib/hanami/view.rb', line 99 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.
587 588 589 590 591 592 593 594 595 596 597 598 599 600 601 602 603 604 605 |
# File 'lib/hanami/view.rb', line 587 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.
563 564 565 |
# File 'lib/hanami/view.rb', line 563 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.
572 573 574 |
# File 'lib/hanami/view.rb', line 572 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.
608 609 610 |
# File 'lib/hanami/view.rb', line 608 def rendering(format: config_data.default_format, context: config_data.default_context) Rendering.new(config_data:, format:, context:) end |