Software / code / verse
Comparison
util/dataforms.lua @ 123:8a079aa70b84
util.dataforms, squishy: Add util.dataforms library
| author | Matthew Wild <mwild1@gmail.com> |
|---|---|
| date | Thu, 09 Sep 2010 19:35:41 +0100 |
| child | 334:34c52f3b21c4 |
comparison
equal
deleted
inserted
replaced
| 122:e2600454fd54 | 123:8a079aa70b84 |
|---|---|
| 1 -- Prosody IM | |
| 2 -- Copyright (C) 2008-2010 Matthew Wild | |
| 3 -- Copyright (C) 2008-2010 Waqas Hussain | |
| 4 -- | |
| 5 -- This project is MIT/X11 licensed. Please see the | |
| 6 -- COPYING file in the source package for more information. | |
| 7 -- | |
| 8 | |
| 9 local setmetatable = setmetatable; | |
| 10 local pairs, ipairs = pairs, ipairs; | |
| 11 local tostring, type = tostring, type; | |
| 12 local t_concat = table.concat; | |
| 13 local st = require "util.stanza"; | |
| 14 | |
| 15 module "dataforms" | |
| 16 | |
| 17 local xmlns_forms = 'jabber:x:data'; | |
| 18 | |
| 19 local form_t = {}; | |
| 20 local form_mt = { __index = form_t }; | |
| 21 | |
| 22 function new(layout) | |
| 23 return setmetatable(layout, form_mt); | |
| 24 end | |
| 25 | |
| 26 function form_t.form(layout, data, formtype) | |
| 27 local form = st.stanza("x", { xmlns = xmlns_forms, type = formtype or "form" }); | |
| 28 if layout.title then | |
| 29 form:tag("title"):text(layout.title):up(); | |
| 30 end | |
| 31 if layout.instructions then | |
| 32 form:tag("instructions"):text(layout.instructions):up(); | |
| 33 end | |
| 34 for n, field in ipairs(layout) do | |
| 35 local field_type = field.type or "text-single"; | |
| 36 -- Add field tag | |
| 37 form:tag("field", { type = field_type, var = field.name, label = field.label }); | |
| 38 | |
| 39 local value = (data and data[field.name]) or field.value; | |
| 40 | |
| 41 if value then | |
| 42 -- Add value, depending on type | |
| 43 if field_type == "hidden" then | |
| 44 if type(value) == "table" then | |
| 45 -- Assume an XML snippet | |
| 46 form:tag("value") | |
| 47 :add_child(value) | |
| 48 :up(); | |
| 49 else | |
| 50 form:tag("value"):text(tostring(value)):up(); | |
| 51 end | |
| 52 elseif field_type == "boolean" then | |
| 53 form:tag("value"):text((value and "1") or "0"):up(); | |
| 54 elseif field_type == "fixed" then | |
| 55 | |
| 56 elseif field_type == "jid-multi" then | |
| 57 for _, jid in ipairs(value) do | |
| 58 form:tag("value"):text(jid):up(); | |
| 59 end | |
| 60 elseif field_type == "jid-single" then | |
| 61 form:tag("value"):text(value):up(); | |
| 62 elseif field_type == "text-single" or field_type == "text-private" then | |
| 63 form:tag("value"):text(value):up(); | |
| 64 elseif field_type == "text-multi" then | |
| 65 -- Split into multiple <value> tags, one for each line | |
| 66 for line in value:gmatch("([^\r\n]+)\r?\n*") do | |
| 67 form:tag("value"):text(line):up(); | |
| 68 end | |
| 69 elseif field_type == "list-single" then | |
| 70 local has_default = false; | |
| 71 if type(value) == "string" then | |
| 72 form:tag("value"):text(value):up(); | |
| 73 else | |
| 74 for _, val in ipairs(value) do | |
| 75 if type(val) == "table" then | |
| 76 form:tag("option", { label = val.label }):tag("value"):text(val.value):up():up(); | |
| 77 if val.default and (not has_default) then | |
| 78 form:tag("value"):text(val.value):up(); | |
| 79 has_default = true; | |
| 80 end | |
| 81 else | |
| 82 form:tag("option", { label= val }):tag("value"):text(tostring(val)):up():up(); | |
| 83 end | |
| 84 end | |
| 85 end | |
| 86 elseif field_type == "list-multi" then | |
| 87 for _, val in ipairs(value) do | |
| 88 if type(val) == "table" then | |
| 89 form:tag("option", { label = val.label }):tag("value"):text(val.value):up():up(); | |
| 90 if val.default then | |
| 91 form:tag("value"):text(val.value):up(); | |
| 92 end | |
| 93 else | |
| 94 form:tag("option", { label= val }):tag("value"):text(tostring(val)):up():up(); | |
| 95 end | |
| 96 end | |
| 97 end | |
| 98 end | |
| 99 | |
| 100 if field.required then | |
| 101 form:tag("required"):up(); | |
| 102 end | |
| 103 | |
| 104 -- Jump back up to list of fields | |
| 105 form:up(); | |
| 106 end | |
| 107 return form; | |
| 108 end | |
| 109 | |
| 110 local field_readers = {}; | |
| 111 | |
| 112 function form_t.data(layout, stanza) | |
| 113 local data = {}; | |
| 114 | |
| 115 for field_tag in stanza:childtags() do | |
| 116 local field_type; | |
| 117 for n, field in ipairs(layout) do | |
| 118 if field.name == field_tag.attr.var then | |
| 119 field_type = field.type; | |
| 120 break; | |
| 121 end | |
| 122 end | |
| 123 | |
| 124 local reader = field_readers[field_type]; | |
| 125 if reader then | |
| 126 data[field_tag.attr.var] = reader(field_tag); | |
| 127 end | |
| 128 | |
| 129 end | |
| 130 return data; | |
| 131 end | |
| 132 | |
| 133 field_readers["text-single"] = | |
| 134 function (field_tag) | |
| 135 local value = field_tag:child_with_name("value"); | |
| 136 if value then | |
| 137 return value[1]; | |
| 138 end | |
| 139 end | |
| 140 | |
| 141 field_readers["text-private"] = | |
| 142 field_readers["text-single"]; | |
| 143 | |
| 144 field_readers["jid-single"] = | |
| 145 field_readers["text-single"]; | |
| 146 | |
| 147 field_readers["jid-multi"] = | |
| 148 function (field_tag) | |
| 149 local result = {}; | |
| 150 for value_tag in field_tag:childtags() do | |
| 151 if value_tag.name == "value" then | |
| 152 result[#result+1] = value_tag[1]; | |
| 153 end | |
| 154 end | |
| 155 return result; | |
| 156 end | |
| 157 | |
| 158 field_readers["text-multi"] = | |
| 159 function (field_tag) | |
| 160 local result = {}; | |
| 161 for value_tag in field_tag:childtags() do | |
| 162 if value_tag.name == "value" then | |
| 163 result[#result+1] = value_tag[1]; | |
| 164 end | |
| 165 end | |
| 166 return t_concat(result, "\n"); | |
| 167 end | |
| 168 | |
| 169 field_readers["list-single"] = | |
| 170 field_readers["text-single"]; | |
| 171 | |
| 172 field_readers["list-multi"] = | |
| 173 function (field_tag) | |
| 174 local result = {}; | |
| 175 for value_tag in field_tag:childtags() do | |
| 176 if value_tag.name == "value" then | |
| 177 result[#result+1] = value_tag[1]; | |
| 178 end | |
| 179 end | |
| 180 return result; | |
| 181 end | |
| 182 | |
| 183 field_readers["boolean"] = | |
| 184 function (field_tag) | |
| 185 local value = field_tag:child_with_name("value"); | |
| 186 if value then | |
| 187 if value[1] == "1" or value[1] == "true" then | |
| 188 return true; | |
| 189 else | |
| 190 return false; | |
| 191 end | |
| 192 end | |
| 193 end | |
| 194 | |
| 195 field_readers["hidden"] = | |
| 196 function (field_tag) | |
| 197 local value = field_tag:child_with_name("value"); | |
| 198 if value then | |
| 199 return value[1]; | |
| 200 end | |
| 201 end | |
| 202 | |
| 203 return _M; | |
| 204 | |
| 205 | |
| 206 --[=[ | |
| 207 | |
| 208 Layout: | |
| 209 { | |
| 210 | |
| 211 title = "MUC Configuration", | |
| 212 instructions = [[Use this form to configure options for this MUC room.]], | |
| 213 | |
| 214 { name = "FORM_TYPE", type = "hidden", required = true }; | |
| 215 { name = "field-name", type = "field-type", required = false }; | |
| 216 } | |
| 217 | |
| 218 | |
| 219 --]=] |