1 # -*- coding: iso-8859-1 -*- 2 """ 3 MoinMoin - FormField Macro 4 5 @copyright: 2012 by Paul Boddie <paul@boddie.org.uk> 6 @license: GNU GPL (v2 or later), see COPYING.txt for details. 7 """ 8 9 from MoinMoin import wikiutil 10 from MoinSupport import * 11 from MoinForms import parseMacroArguments 12 13 Dependencies = ['pages'] 14 15 escape = wikiutil.escape 16 17 # Macro functions. 18 19 def execute(macro, args): 20 21 """ 22 Execute the 'macro' with the given 'args' to produce a form field element: 23 24 * A field name 25 * The WikiDict describing form fields 26 27 The following optional named arguments are also supported: 28 29 label=TEXT The label employed by button-like fields 30 path=PATH The location of the field in the form section hierarchy 31 32 The nature of each field is described by a WikiDict entry for the given 33 field name. 34 """ 35 36 request = macro.request 37 fmt = macro.formatter 38 page = fmt.page 39 _ = request.getText 40 41 # Interpret the arguments. 42 43 parsed_args = parseMacroArguments(args) 44 45 # Get special arguments. 46 47 name = None 48 path = None 49 dictpage = None 50 label = None 51 section = None 52 53 for arg in parsed_args: 54 if arg.startswith("name="): 55 name = arg[5:] 56 57 elif arg.startswith("path="): 58 path = arg[5:] 59 60 elif arg.startswith("dict="): 61 dictpage = arg[5:] 62 63 elif arg.startswith("label="): 64 label = arg[6:] 65 66 elif arg.startswith("section="): 67 section = arg[8:] 68 69 elif name is None: 70 name = arg 71 72 elif dictpage is None: 73 dictpage = arg 74 75 if not name: 76 return showError(_("No field name specified."), request) 77 78 # Detect special modification fields. 79 80 if name in ("_add", "_remove"): 81 field_args = {"type" : "submit"} 82 83 # The field name is a combination of the name, path and section. 84 85 ref = "%s=%s%s%s" % (name, path or "", path and section and "/" or "", section or "") 86 87 # Get the WikiDict and the field's definition. 88 89 elif dictpage: 90 wikidict = getWikiDict(dictpage, request) 91 92 if not wikidict: 93 return showError(_("WikiDict %s cannot be loaded for %s.") % (dictpage, name), request) 94 95 try: 96 field_definition = wikidict[name] 97 except KeyError: 98 return showError(_("No entry for %s in %s.") % (name, dictpage), request) 99 100 field_args = {} 101 102 for field_arg in field_definition.split(): 103 104 # Record the key-value details. 105 106 try: 107 argname, argvalue = field_arg.split("=", 1) 108 field_args[argname] = argvalue 109 110 # Single keywords are interpreted as type descriptions. 111 112 except ValueError: 113 if not field_args.has_key("type"): 114 field_args["type"] = field_arg 115 116 # The field name is a combination of the path and the name. 117 118 ref = "%s%s" % (path and ("%s/" % path) or "", name) 119 120 else: 121 return showError(_("No WikiDict specified for %s.") % name, request) 122 123 # Obtain any request parameters corresponding to the field. 124 125 form = get_form(request) 126 value = form.get(ref, [""])[0] 127 128 # Render the field. 129 130 type = field_args.get("type", "text") 131 132 if type == "text": 133 return fmt.rawHTML('<input name="%s" type="%s" size="%s" value="%s" />' % ( 134 escattr(ref), escattr(type), escattr(field_args.get("size", "10")), escattr(value) 135 )) 136 137 elif type == "textarea": 138 return fmt.rawHTML('<textarea name="%s" cols="%s" rows="%s">%s</textarea>' % ( 139 escattr(ref), escattr(field_args.get("cols", "60")), escattr(field_args.get("rows", "5")), escape(value) 140 )) 141 142 elif type == "submit": 143 return fmt.rawHTML('<input name="%s" type="submit" value="%s" />' % ( 144 escattr(ref), escattr(_(label or name)) 145 )) 146 147 elif type == "select": 148 149 if not field_args.has_key("source"): 150 return showError(_("No source dictionary given for %s.") % name, request) 151 152 sourcedict = getWikiDict(field_args["source"], request) 153 154 if not sourcedict: 155 return showError(_("WikiDict %s cannot be loaded for %s.") % (sourcedict, name), request) 156 157 output = [] 158 output.append(fmt.rawHTML('<select name="%s">' % escattr(ref))) 159 160 for option, label in sourcedict.items(): 161 output.append(fmt.rawHTML('<option value="%s" %s>%s</option>' % ( 162 escattr(option), value == option and "selected" or "", escape(label)) 163 )) 164 165 output.append(fmt.rawHTML('</select>')) 166 return u''.join(output) 167 168 else: 169 return u'' 170 171 def showError(text, request): 172 fmt = request.formatter 173 174 output = [] 175 append = output.append 176 177 append(fmt.span(on=1, attrs={"class" : "form-field-error"})) 178 append(fmt.text(text)) 179 append(fmt.span(on=0)) 180 181 return "".join(output) 182 183 # vim: tabstop=4 expandtab shiftwidth=4