1 # -*- coding: iso-8859-1 -*- 2 """ 3 MoinMoin - FormField Macro 4 5 @copyright: 2012, 2013 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 getFieldArguments, parseMacroArguments, getMacroArguments 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 fragment=NAME The name of the form region or fragment in the page 32 33 The nature of each field is described by a WikiDict entry for the given 34 field name. 35 """ 36 37 request = macro.request 38 fmt = macro.formatter 39 page = fmt.page 40 _ = request.getText 41 42 # Interpret the arguments. 43 44 parsed_args = parseMacroArguments(args) 45 46 # Get special arguments. 47 48 name, path, dictpage, label, section, fragment = getMacroArguments(parsed_args) 49 50 if not name: 51 return showError(_("No field name specified."), request) 52 53 # Detect special modification fields. 54 55 if name in ("_add", "_remove"): 56 field_args = {"type" : "submit"} 57 58 # The field name is a combination of the name, path and section. 59 60 ref = "%s=%s%s%s" % (name, path or "", path and section and "/" or "", section or "") 61 62 # Get the WikiDict and the field's definition. 63 64 elif dictpage: 65 wikidict = getWikiDict(dictpage, request) 66 67 if not wikidict: 68 return showError(_("WikiDict %s cannot be loaded for %s.") % (dictpage, name), request) 69 70 try: 71 field_definition = wikidict[name] 72 except KeyError: 73 return showError(_("No entry for %s in %s.") % (name, dictpage), request) 74 75 field_args = getFieldArguments(field_definition) 76 77 # The field name is a combination of the path and the name. 78 79 ref = "%s%s" % (path and ("%s/" % path) or "", name) 80 81 else: 82 return showError(_("No WikiDict specified for %s.") % name, request) 83 84 # Obtain any request parameters corresponding to the field. 85 86 form = get_form(request) 87 form_fragment = form.get("fragment", [None])[0] 88 89 # Exclude values intended for other forms. 90 91 if fragment and form_fragment != fragment or not fragment and form_fragment: 92 values = [] 93 value = "" 94 else: 95 values = form.get(ref, []) 96 value = form.get(ref, [""])[0] 97 98 # Render the field. 99 100 type = field_args.get("type", "text") 101 102 if type == "text": 103 return fmt.rawHTML('<input name="%s" type="%s" size="%s" value="%s" />' % ( 104 escattr(ref), escattr(type), escattr(field_args.get("size", "10")), escattr(value) 105 )) 106 107 elif type == "textarea": 108 return fmt.rawHTML('<textarea name="%s" cols="%s" rows="%s">%s</textarea>' % ( 109 escattr(ref), escattr(field_args.get("cols", "60")), escattr(field_args.get("rows", "5")), escape(value) 110 )) 111 112 elif type == "submit": 113 return fmt.rawHTML('<input name="%s" type="submit" value="%s" />' % ( 114 escattr(ref), escattr(_(label or name)) 115 )) 116 117 elif type == "select": 118 119 if not field_args.has_key("source"): 120 return showError(_("No source dictionary given for %s.") % name, request) 121 122 sourcedict = getWikiDict(field_args["source"], request) 123 124 if not sourcedict: 125 return showError(_("WikiDict %s cannot be loaded for %s.") % (sourcedict, name), request) 126 127 maxselected = field_args.get("maxselected", [None])[0] 128 maxselected = maxselected and int(maxselected) or maxselected 129 130 output = [] 131 output.append(fmt.rawHTML('<select name="%s" %s>' % (escattr(ref), maxselected != 1 and "multiple" or ""))) 132 133 for option, label in sourcedict.items(): 134 is_selected = maxselected == 1 and option == value or maxselected != 1 and option in values 135 136 output.append(fmt.rawHTML('<option value="%s" %s>%s</option>' % ( 137 escattr(option), is_selected and 'selected="selected"' or "", escape(label)) 138 )) 139 140 output.append(fmt.rawHTML('</select>')) 141 return u''.join(output) 142 143 else: 144 return u'' 145 146 def showError(text, request): 147 fmt = request.formatter 148 149 output = [] 150 append = output.append 151 152 append(fmt.span(on=1, attrs={"class" : "form-field-error"})) 153 append(fmt.text(text)) 154 append(fmt.span(on=0)) 155 156 return "".join(output) 157 158 # vim: tabstop=4 expandtab shiftwidth=4