# frozen_string_literal: true
require "blather"
class FormTemplate
def initialize(template, filename="template", **kwargs)
@args = kwargs
@template = template
@filename = filename
freeze
end
def self.render(path, **kwargs)
full_path = File.dirname(__dir__) + "/forms/#{path}.rb"
new(File.read(full_path), full_path, **kwargs).render
end
def render(**kwargs)
one = OneRender.new(**@args.merge(kwargs))
one.instance_eval(@template, @filename)
one.form
end
class OneRender
def initialize(**kwargs)
kwargs.each do |k, v|
instance_variable_set("@#{k}", v)
end
@__form = Blather::Stanza::X.new
@__builder = Nokogiri::XML::Builder.with(@__form)
end
def form!
@__type_set = true
@__form.type = :form
end
def result!
@__type_set = true
@__form.type = :result
end
def title(s)
@__form.title = s
end
def instructions(s)
@__form.instructions = s
end
def validate(field, datatype: nil, **kwargs)
Nokogiri::XML::Builder.with(field) do |xml|
xml.validate(
xmlns: "http://jabber.org/protocol/xdata-validate",
datatype: datatype || "xs:string"
) do
xml.basic unless validation_type(xml, **kwargs)
end
end
end
def validation_type(xml, open: false, regex: nil, range: nil)
xml.open if open
xml.range(min: range.first, max: range.last) if range
xml.regex(regex.source) if regex
open || regex || range
end
def field(datatype: nil, open: false, regex: nil, range: nil, **kwargs)
f = Blather::Stanza::X::Field.new(kwargs)
if datatype || open || regex || range
validate(f, datatype: datatype, open: open, regex: regex, range: range)
end
@__form.fields += [f]
end
def xml
@__builder
end
def form
raise "Type never set" unless @__type_set
@__form
end
end
end