class Formalist::RichText::EmbeddedFormCompiler

Our input data looks like this example, which consists of 3 elements:

  1. A text line

  2. embedded form data

  3. Another text line

[

["block",["unstyled","b14hd",[["inline",[[],"Before!"]]]]],
["block",["atomic","48b4f",[["entity",["formalist","1","IMMUTABLE",{"name":"image_with_caption","label":"Image with caption","data":{"image_id":"5678","caption":"Large panda"}},[["inline",[[],"ΒΆ"]]]]]]]],
["block",["unstyled","aivqi",[["inline",[[],"After!"]]]]]

]

We want to intercept the embededed form data and transform them into full form ASTs, complete with validation messages.

Attributes

embedded_forms[R]

Public Class Methods

new(embedded_form_collection) click to toggle source
# File lib/formalist/rich_text/embedded_form_compiler.rb, line 24
def initialize(embedded_form_collection)
  @embedded_forms = embedded_form_collection
end

Public Instance Methods

[](ast)
Alias for: call
call(ast) click to toggle source
# File lib/formalist/rich_text/embedded_form_compiler.rb, line 28
def call(ast)
  return ast if ast.nil?

  ast = ast.is_a?(String) ? JSON.parse(ast) : ast

  ast.map { |node| visit(node) }
end
Also aliased as: []

Private Instance Methods

prepare_form_ast(embedded_form, data) click to toggle source
# File lib/formalist/rich_text/embedded_form_compiler.rb, line 73
def prepare_form_ast(embedded_form, data)
  # Run the raw data through the validation schema
  validation = embedded_form.schema.(data)

  # And then through the embedded form's input processor (which may add
  # extra system-generated information necessary for the form to render
  # fully)
  input = embedded_form.input_processor.(validation.to_h)

  embedded_form.form.fill(input: input, errors: validation.errors.to_h).to_ast
end
visit(node) click to toggle source
# File lib/formalist/rich_text/embedded_form_compiler.rb, line 39
def visit(node)
  name, nodes = node

  handler = :"visit_#{name}"

  if respond_to?(handler, true)
    send(handler, nodes)
  else
    [name, nodes]
  end
end
visit_block(node) click to toggle source

We need to visit blocks in order to get to the formalist entities nested within them

# File lib/formalist/rich_text/embedded_form_compiler.rb, line 52
def visit_block(node)
  type, id, children = node

  ["block", [type, id, children.map { |child| visit(child) }]]
end
visit_entity(node) click to toggle source
# File lib/formalist/rich_text/embedded_form_compiler.rb, line 58
def visit_entity(node)
  type, key, mutability, entity_data, children = node

  return ["entity", node] unless type == "formalist"

  embedded_form = embedded_forms[entity_data["name"]]

  compiled_entity_data = entity_data.merge(
    "label" => embedded_form.label,
    "form" => prepare_form_ast(embedded_form, entity_data["data"])
  )

  ["entity", [type, key, mutability, compiled_entity_data, children]]
end