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 --]=] |