Class: Papercraft::Renderer
- Inherits:
-
Object
- Object
- Papercraft::Renderer
- Defined in:
- lib/papercraft/renderer.rb
Overview
A Renderer renders a Papercraft template into a string
Direct Known Subclasses
Class Method Summary collapse
-
.extension(map) ⇒ void
call_seq: Papercraft::Renderer.extension(name => mod, …) Papercraft.extension(name => mod, …).
-
.verify_proc_parameters(template, args, named_args) ⇒ Object
Verifies that the given template proc can be called with the given arguments and named arguments.
Instance Method Summary collapse
-
#emit(o, *a, **b, &block) ⇒ void
(also: #e)
Emits the given object into the rendering buffer.
-
#emit_yield(*a, **b) ⇒ void
Emits a block supplied using Template#apply or Template#render.
-
#fragment(name, &block) ⇒ void
Defines a named template fragment.
-
#initialize(render_fragment = nil, &template) ⇒ Renderer
constructor
Initializes the renderer and evaulates the given template in the renderer’s scope.
Constructor Details
#initialize(render_fragment = nil, &template) ⇒ Renderer
Initializes the renderer and evaulates the given template in the renderer’s scope.
87 88 89 90 |
# File 'lib/papercraft/renderer.rb', line 87 def initialize(render_fragment = nil, &template) @render_fragment = render_fragment instance_eval(&template) end |
Class Method Details
.extension(map) ⇒ void
This method returns an undefined value.
call_seq:
Papercraft::Renderer.extension(name => mod, ...)
Papercraft.extension(name => mod, ...)
Installs the given extensions, passed in the form of a Ruby hash mapping methods to extension modules. The methods will be available to all Papercraft templates. Extension methods are executed in the context of the the renderer instance, so they can look just like normal proc components. In cases where method names in the module clash with XML tag names, you can use the ‘#tag` method to emit the relevant tag.
module ComponentLibrary
def card(title, content)
div(class: 'card') {
h3 title
div(class: 'card-content') { emit_markdown content }
}
end
end
Papercraft.extension(components: ComponentLibrary)
Papercraft.html { components.card('Foo', '**Bar**') }
64 65 66 67 68 |
# File 'lib/papercraft/renderer.rb', line 64 def extension(map) map.each do |sym, mod| define_extension_method(sym, mod) end end |
.verify_proc_parameters(template, args, named_args) ⇒ Object
Verifies that the given template proc can be called with the given arguments and named arguments. If the proc demands named argument keys that do not exist in ‘named_args`, `Papercraft::Error` is raised.
22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 |
# File 'lib/papercraft/renderer.rb', line 22 def verify_proc_parameters(template, args, named_args) param_count = 0 template.parameters.each do |(type, name)| case type when :req param_count += 1 when :keyreq if !named_args.has_key?(name) raise Papercraft::Error, "Missing template parameter #{name.inspect}" end end end if param_count > args.size raise Papercraft::Error, "Missing template parameters" end end |
Instance Method Details
#emit(o, *a, **b, &block) ⇒ void Also known as: e
This method returns an undefined value.
Emits the given object into the rendering buffer. If the given object is a proc or a component, ‘emit` will passes any additional arguments and named arguments to the object when rendering it. If the given object is nil, nothing is emitted. Otherwise, the object is converted into a string using `#to_s` which is then added to the rendering buffer, without any escaping.
greeter = proc { |name| h1 "Hello, #{name}!" }
Papercraft.html { emit(greeter, 'world') }.render #=> "<h1>Hello, world!</h1>"
Papercraft.html { emit 'hi&<bye>' }.render #=> "hi&<bye>"
Papercraft.html { emit nil }.render #=> ""
109 110 111 112 113 114 115 116 117 118 119 120 |
# File 'lib/papercraft/renderer.rb', line 109 def emit(o, *a, **b, &block) case o when ::Proc Renderer.verify_proc_parameters(o, a, b) push_emit_yield_block(block) if block instance_exec(*a, **b, &o) when nil # do nothing else emit_object(o) end end |
#emit_yield(*a, **b) ⇒ void
This method returns an undefined value.
Emits a block supplied using Template#apply or Template#render.
div_wrap = Papercraft.html { |*args| div { emit_yield(*args) } }
greeter = div_wrap.apply { |name| h1 "Hello, #{name}!" }
greeter.render('world') #=> "<div><h1>Hello, world!</h1></div>"
132 133 134 135 136 137 |
# File 'lib/papercraft/renderer.rb', line 132 def emit_yield(*a, **b) block = @emit_yield_stack&.pop raise Papercraft::Error, "No block given" unless block instance_exec(*a, **b, &block) end |
#fragment(name, &block) ⇒ void
This method returns an undefined value.
Defines a named template fragment. Template fragments allow rendering specific parts of the same template. A template fragment can be rendered using Template#render_fragment. See also / HTMX template fragments.
form = Papercraft.html {
h1 'Hello'
fragment(:buttons) {
'OK'
'Cancel'
}
}
form.render_fragment(:buttons) #=> "<button>OK</button><button>Cancel</buttons>"
155 156 157 158 159 160 161 162 163 164 |
# File 'lib/papercraft/renderer.rb', line 155 def fragment(name, &block) raise Papercraft::Error, "Already in fragment" if @fragment begin @fragment = name emit(block) ensure @fragment = nil end end |