Class: Phlex::SGML

Inherits:
Object
  • Object
show all
Defined in:
lib/phlex/sgml.rb

Overview

Standard Generalized Markup Language for behaviour common to HTML and SVG.

Direct Known Subclasses

HTML, SVG

Class Method Summary collapse

Instance Method Summary collapse

Constructor Details

#initializeObject

This method is abstract.

Override to define an initializer for your component.

Note:

Your initializer will not receive a block passed to new. Instead, this block will be sent to #template when rendering.

Examples:

def initialize(articles:)
	@articles = articles
end


# File 'lib/phlex/sgml.rb', line 46

Class Method Details

.callObject

Render the view to a String. Arguments are delegated to new.



12
13
14
# File 'lib/phlex/sgml.rb', line 12

def call(...)
	new(...).call
end

.new(*args, **kwargs, &block) ⇒ Object

Note:

The block will not be delegated #initialize. Instead, it will be sent to #template when rendering.

Create a new instance of the component.



18
19
20
21
22
23
24
25
26
# File 'lib/phlex/sgml.rb', line 18

def new(*args, **kwargs, &block)
	if block
		object = super(*args, **kwargs, &nil)
		object.instance_variable_set(:@_content_block, block)
		object
	else
		super
	end
end

Instance Method Details

#after_templatenil (private)

This method is abstract.

Override this method to hook in right after a template is rendered. Please remember to call super so that callbacks can be added at different layers of the inheritance tree.

Returns:

  • (nil)


287
288
289
# File 'lib/phlex/sgml.rb', line 287

def after_template
	nil
end

#around_templatenil (private)

This method is abstract.

Override this method to hook in around a template render. You can do things before and after calling super to render the template. You should always call super so that callbacks can be added at different layers of the inheritance tree.

Returns:

  • (nil)


271
272
273
274
275
276
277
# File 'lib/phlex/sgml.rb', line 271

def around_template
	before_template
	yield
	after_template

	nil
end

#before_templatenil (private)

This method is abstract.

Override this method to hook in right before a template is rendered. Please remember to call super so that callbacks can be added at different layers of the inheritance tree.

Returns:

  • (nil)


281
282
283
# File 'lib/phlex/sgml.rb', line 281

def before_template
	nil
end

#call(buffer = +"",, context: Phlex::Context.new, view_context: nil, parent: nil, &block) ⇒ Object

Renders the view and returns the buffer. The default buffer is a mutable String.



90
91
92
93
94
# File 'lib/phlex/sgml.rb', line 90

def call(buffer = +"", context: Phlex::Context.new, view_context: nil, parent: nil, &block)
	__final_call__(buffer, context: context, view_context: view_context, parent: parent, &block).tap do
		self.class.rendered_at_least_once!
	end
end

#capture(&block) ⇒ String

Note:

This only works if the block's receiver is the current component or the block returns a String.

Capture a block of output as a String.

Returns:

  • (String)


182
183
184
185
186
# File 'lib/phlex/sgml.rb', line 182

def capture(&block)
	return "" unless block

	@_context.capturing_into(+"") { yield_content(&block) }
end

#comment(&block) ⇒ nil

Output an HTML comment.

Returns:

  • (nil)


159
160
161
162
163
164
165
166
167
# File 'lib/phlex/sgml.rb', line 159

def comment(&block)
	target = @_context.target

	target << "<!-- "
	yield_content(&block)
	target << " -->"

	nil
end

#format_object(object) ⇒ String (private)

This method is abstract.

Override to define your own format handling for different object types. Please remember to call super in the case that the passed object doesn't match, so that object formatting can be added at different layers of the inheritance tree.

Format the object for output

Returns:

  • (String)


262
263
264
265
266
267
# File 'lib/phlex/sgml.rb', line 262

def format_object(object)
	case object
	when Float, Integer
		object.to_s
	end
end

#plain(content) ⇒ nil

Output text content. The text will be HTML-escaped.

Parameters:

  • content (String, Symbol, Integer, void)

    the content to be output on the buffer. Strings, Symbols, and Integers are handled by plain directly, but any object can be handled by overriding format_object

Returns:

  • (nil)

See Also:



133
134
135
136
137
138
139
# File 'lib/phlex/sgml.rb', line 133

def plain(content)
	unless __text__(content)
		raise ArgumentError, "You've passed an object to plain that is not handled by format_object. See https://rubydoc.info/gems/phlex/Phlex/SGML#format_object-instance_method for more information"
	end

	nil
end

#render(component, &block) ⇒ nil (private) #render(component_class, &block) ⇒ nil (private) #render(proc) ⇒ nil (private) #render(enumerable) ⇒ nil (private)

Render another component, block or enumerable

Overloads:

  • #render(component, &block) ⇒ nil

    Renders the component.

    Parameters:

  • #render(component_class, &block) ⇒ nil

    Renders a new instance of the component class. This is useful for component classes that take no arguments.

    Parameters:

  • #render(proc) ⇒ nil

    Renders the proc with #yield_content.

    Parameters:

    • proc (Proc)
  • #render(enumerable) ⇒ nil

    Renders each item of the enumerable.

    Examples:

    render @items

    Parameters:

    • enumerable (Enumerable)

Returns:

  • (nil)


215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
# File 'lib/phlex/sgml.rb', line 215

def render(renderable, &block)
	case renderable
	when Phlex::SGML
		renderable.call(@_buffer, context: @_context, view_context: @_view_context, parent: self, &block)
	when Class
		if renderable < Phlex::SGML
			renderable.new.call(@_buffer, context: @_context, view_context: @_view_context, parent: self, &block)
		end
	when Enumerable
		renderable.each { |r| render(r, &block) }
	when Proc, Method
		if renderable.arity == 0
			yield_content_with_no_args(&renderable)
		else
			yield_content(&renderable)
		end
	when String
		plain(renderable)
	else
		raise ArgumentError, "You can't render a #{renderable.inspect}."
	end

	nil
end

#render?Boolean (private)

This method is abstract.

Override to define your own predicate to prevent rendering.

Determines if the component should render. By default, it returns true.

Returns:

  • (Boolean)


255
256
257
# File 'lib/phlex/sgml.rb', line 255

def render?
	true
end

#templateObject

This method is abstract.

Override to define a template for your component.

Examples:

def template
	h1 { "👋 Hello World!" }
end

Your template may yield a content block.

def template
	main {
		h1 { "Hello World" }
		yield
	}
end

Alternatively, you can delegate the content block to an element.

def template(&block)
	article(class: "card", &block)
end


70
71
72
# File 'lib/phlex/sgml.rb', line 70

def template
	yield
end

#unsafe_raw(content = nil) ⇒ nil

This method is very dangerous and should usually be avoided. It will output the given String without any HTML safety. You should never use this method to output unsafe user input.

Parameters:

  • content (String|nil) (defaults to: nil)

Returns:

  • (nil)


172
173
174
175
176
177
# File 'lib/phlex/sgml.rb', line 172

def unsafe_raw(content = nil)
	return nil unless content

	@_context.target << content
	nil
end

#whitespace { ... } ⇒ nil

Output a whitespace character. This is useful for getting inline elements to wrap. If you pass a block, a whitespace will be output before and after yielding the block.

Yields:

  • If a block is given, it yields the block with no arguments.

Returns:

  • (nil)


144
145
146
147
148
149
150
151
152
153
154
155
# File 'lib/phlex/sgml.rb', line 144

def whitespace
	target = @_context.target

	target << " "

	if block_given?
		yield
		target << " "
	end

	nil
end

#yield_content {|component| ... } ⇒ nil (private)

Yields the block and checks if it buffered anything. If nothing was buffered, the return value is treated as text. The text is always HTML-escaped.

Yield Parameters:

  • component (self)

Returns:

  • (nil)


294
295
296
297
298
299
300
301
302
303
304
# File 'lib/phlex/sgml.rb', line 294

def yield_content
	return unless block_given?

	target = @_context.target

	original_length = target.length
	content = yield(self)
	__text__(content) if original_length == target.length

	nil
end

#yield_content_with_args(*args) {|*args| ... } ⇒ nil (private)

Same as #yield_content but accepts a splat of arguments to yield. This is slightly slower than #yield_content.

Yields:

  • (*args)

    Yields the given arguments.

Returns:

  • (nil)


323
324
325
326
327
328
329
330
331
332
333
# File 'lib/phlex/sgml.rb', line 323

def yield_content_with_args(*args)
	return unless block_given?

	target = @_context.target

	original_length = target.length
	content = yield(*args)
	__text__(content) if original_length == target.length

	nil
end

#yield_content_with_no_args { ... } ⇒ Object (private)

Same as #yield_content but yields no arguments.

Yields:

  • Yields the block with no arguments.



308
309
310
311
312
313
314
315
316
317
318
# File 'lib/phlex/sgml.rb', line 308

def yield_content_with_no_args
	return unless block_given?

	target = @_context.target

	original_length = target.length
	content = yield
	__text__(content) if original_length == target.length

	nil
end