use new style field macros for the file edit page
[bse.git] / site / templates / preload.tmpl
1 <:# see preload.pod for documentation -:>
2 <:.set dist_image_uri = cfg.entryIfVar("uri", "dist_images", "/images") -:>
3 <:# utility definitions :>
4 <:-.define make_select; groups: 0, grouplabel: "label", groupid: "id",
5            itemgroupid: "groupid" -:>
6   <:-.if !default.defined -:>
7     <:-.set default = "" -:>
8   <:.end if:>
9   <select name="<:= name | html :>">
10   <:- .if groups -:>
11     <:-.for i in list -:>
12       <:.if i.$itemgroupid eq "" -:>
13     <option value="<:= i.$id | html :>"
14           <:- .if i.$id eq default :> selected="selected"<:.end if -:>
15     >
16         <:-= i.$desc | html -:>
17       <:.end if -:>
18     <:.end for -:>
19     <:-.for g in groups -:>
20     <optgroup label="<:= g.$grouplabel | html -:>">
21       <:-.for i in list -:>
22         <:.if i.$itemgroupid == g.$groupid -:>
23       <option value="<:= i.$id | html :>"
24           <:- .if i.$id eq default :> selected="selected"<:.end if -:>
25       >
26           <:-= i.$desc | html -:>
27         <:.end if -:>
28       <:.end for -:>
29     </optgroup>
30     <:-.end for -:>
31   <:- .else -:>
32     <:-.for i in list -:>
33     <option value="<:= i.$id | html :>"
34         <:- .if i.$id eq default :> selected="selected"<:.end if -:>
35     >
36       <:-= i.$desc | html -:>
37     <:-.end for-:>
38   <:-.end if -:>
39   </select>
40 <:-.end define -:>
41 <:#
42 make_multicheck expects:
43   values - list of hashes
44   default - a list of ids of checks to be checked
45   id - the name of the id field
46   desc - the name of the description field.
47   name - the name of the input elements
48   readonly - true to make it readonly
49 -:>
50 <:-.define make_multicheck; readonly: 0-:>
51   <:.if !readonly -:>
52   <input type="hidden" name="_save_<:= name -:>" value="1">
53   <:.end if -:>
54   <:-.if !default.defined -:>
55     <:-.set default = [] -:>
56   <:.end if:>
57   <:.set checked = {} -:>
58   <:.for v in default -:>
59     <:% checked.set(v, 1) -:>
60   <:.end for -:>
61   <ul>
62   <:-.for i in values -:>
63     <li>
64     <:.set element_id = name _ "-" _ i.$id -:>
65     <input type="checkbox" name="<:= name :>" <:= checked[i.$id] ? 'checked ' : '' -:>
66       id="<:= element_id -:>" value="<:= i.$id :>"
67 <:-# readonly attribute isn't valid for checkboxes -:>
68 <:-= readonly ? " disabled" : "" -:>
69     >
70     <label for="<:= element_id :>"><:= i.$desc -:></label>
71     </li>
72   <:-.end for -:>
73   </ul>
74 <:-.end define -:>
75 <:#
76 page_list expects:
77 base - base url for links
78 pages - the result of the bse.pages call
79  :>
80 <:-.define page_list-:>
81 <:.set sep = base =~ /\?/ ? "&" : "?" -:>
82 <:.set base = base _ sep :>
83 <div class="pagelist">
84 Page <:= pages.page :> of <:= pages.pagecount :>
85 <:.if pages.previous_page -:>
86 <a href="<:= base |html:><:= pages.pname | uri :>=1&amp;<:= pages.ppname | uri :>=<:= pages.pp | uri :>">&lt;&lt</a>
87 <a href="<:= base |html:><:= pages.pname | uri :>=<:= pages.previous_page |uri:>&amp;<:= pages.ppname | uri :>=<:= pages.pp | uri :>">&lt;</a>
88 <:.else -:>
89 <span>&lt&lt</span>
90 <span>&lt</span>
91 <:.end if -:>
92 <:.for p in pages.pages :>
93 <:.if p.link -:>
94 <a href="<:= base |html :><:= pages.pname | uri:>=<:= p.page | uri :>&amp;<:=pages.ppname | uri :>=<:= pages.pp | uri :>"><:= p.page |html :></a>
95 <:.else -:>
96 <span><:= p.page |html:></span>
97 <:.end if -:>
98 <:.end for:>
99 <:.if pages.next_page -:>
100 <a href="<:= base |html:><:= pages.pname | uri :>=<:= pages.next_page |uri:>&amp;<:= pages.ppname | uri :>=<:= pages.pp | uri :>">&gt;</a>
101 <a href="<:= base |html:><:= pages.pname | uri :>=<:= pages.pagecount |uri:>&amp;<:= pages.ppname | uri :>=<:= pages.pp | uri :>">&gt;&gt</a>
102 <:.else -:>
103 <span>&gt&gt</span>
104 <span>&gt</span>
105 <:.end if -:>
106 </div>
107 <:-.end define -:>
108
109 <:.define old -:>
110 <:# parameters: field, default -:>
111 <:  .if cgi.param(field).defined -:>
112 <:= cgi.param(field) -:>
113 <:  .else -:>
114 <:= default | html -:>
115 <:  .end if -:>
116 <:.end define-:>
117
118 <:.define error_img_n -:>
119 <:# parameters:
120    field - name of field
121    index - index of field
122    errors - hash of error messages (should be set by code)
123 -:>
124   <:.if errors.$field -:>
125     <:.set msg = errors.$field -:>
126     <:.set msg = msg.is_list ? msg[index] : msg -:>
127     <:.if msg.defined -:>
128       <:.set image = cfg.entry("error_img", "image", dist_image_uri _ "/admin/error.gif") -:>
129       <:.set width = cfg.entry("error_img", "width", 16) -:>
130       <:.set height = cfg.entry("error_img", "height", 16) -:>
131     <img src="<:= image -:>" alt="<:= msg :>" title="<:= msg :>" width="<:= width :>" height="<:= height :>" class="error_img">
132     <:.end if -:>
133   <:.end if -:>
134 <:.end define -:>
135
136 <:.define error_img -:>
137 <:.call "error_img_n", index:0 -:>
138 <:.end define -:>
139
140 <:.define input; options: {} -:>
141 <:# parameters:
142   name - field name
143   field - entry from fields
144   object - source for defaults in edit mode
145 -:>
146 <:  .set default = options.default -:>
147 <:  .if !default.defined -:>
148 <:    .if object -:>
149 <:       .set default = object.$name -:>
150 <:    .elsif field.default -:>
151 <:       .set default = field.default -:>
152 <:    .else -:>
153 <:       .set default = "" -:>
154 <:    .end if -:>
155 <:  .end if -:>
156 <:  .if field.type and field.type eq "date" and default ne "" -:>
157 <:    .set default = default.replace(/(\d+)\D+(\d+)\D+(\d+)/, "$3/$2/$1") -:>
158 <:  .elsif field.type and field.type eq "time" and default ne "" -:>
159 <:    .set default = bse.date(default =~ /:00$/ ? "%I:%M%p" : "%I:%M:%S%p", default).replace(/^0/, "").lower() -:>
160 <:  .end if -:>
161 <:  .if cgi.param(name).defined -:>
162 <:     .set default = cgi.param(name) -:>
163 <:  .end if -:>
164 <:  .if field.htmltype eq "textarea" -:>
165 <textarea id="<:= name | html :>" name="<:= name | html :>" rows="<:= field.height ? field.height : cfg.entry("forms", "textarea_rows", 10) :>" cols=<:= field.width ? field.width : cfg.entry("forms", "textarea_cols", 60) | html :>>
166 <:-= default | html -:>
167 </textarea>
168 <:  .elsif field.htmltype eq "checkbox" -:>
169 <:.set is_checked = cgi.param("_save_" _ name) ? cgi.param(name).defined : default -:>
170 <input type="hidden" name="_save_<:= name -:>" value="1">
171 <input id="<:= name | html :>" type="checkbox" name="<:= name | html :>"<:= is_checked ? ' checked="checked"' : '' :> value="<:= field.value ? field.value : 1 | html :>" />
172 <:  .elsif field.htmltype eq "multicheck" -:>
173 <:# we expect default to be a list of selected checks -:>
174 <:.set values = field.select["values"] -:>
175 <:.set values = values.is_code ? values() : values -:>
176 <:.set default = cgi.param("_save_" _ name) ? [ cgi.param(name) ] : default -:>
177 <:.call "make_multicheck",
178   id:field.select.id,
179   desc:field.select.label -:>
180 <:  .elsif field.htmltype eq "select" -:>
181 <:.set values = field.select["values"] -:>
182 <:.set values = values.is_code ? values() : values -:>
183 <:.call "make_select",
184     name: name,
185     default: default,
186     list: values,
187     id: field.select.id,
188     desc: field.select.label,
189     groupid : (field.select.groupid or "id"),
190     itemgroupid: (field.select.itemgroupid or "groupid"),
191     groups: field.select.groups ? (field.select.groups.is_code ? (field.select.groups)() : field.select.groups ) : 0,
192     grouplabel: (field.select.grouplabel or "label")
193 -:>
194 <:  .elsif field.htmltype eq 'file' -:>
195 <:   .if default.length -:>
196 <span class="filename"><:= default :></span>
197 <:   .end if -:>
198 <input id="<:= name :>" type="file" name="<:= name :>" />
199 <:- .else -:>
200 <input id="<:= name | html :>" type="text" name="<:= name | html :>" value="<:=  default | html :>" 
201 <:-= field.maxlength ? ' maxlength="' _ field.maxlength _ '"' : '' |raw:>
202 <:-= field.width ? ' size="' _ field.width _ '"' : '' | raw :> />
203 <:  .end if -:>
204 <:.end define -:>
205
206 <:.define field; options: {} -:>
207 <:# parameters:
208   name - field name
209   fields - hash of fields (may be set by page instead)
210   object - object containing defaults (can be set globally instead)
211   default - a default value not dependent on object (overrides object)
212 :>
213   <:.if fields.is_hash -:>
214     <:.set f = fields[name] -:>
215     <:.if f -:>
216       <:.call "inlinefield", field:f, name:name, options: options -:>
217     <:.else -:>
218 <p>Unknown field id '<b><:= name :></b>', available fields are '<:= fields.keys.join("', '") :>'</p>
219     <:.end if -:>
220   <:.else -:>
221 <p>fields isn't a hash, something is wrong.</p>
222   <:.end if -:>
223 <:.end define -:>
224
225 <:.define inlinefield; options: {} -:>
226 <:# parameters:
227   name - the field name
228   field - a field, as an entry in fields
229 -:>
230   <:.if field.is_hash -:>
231 <div>
232   <label for="<:= name | html :>"><:= field.nolabel ? "" : field.description | html :>:</label>
233   <span>
234     <:-.if field.readonly -:>
235 <:-.call "display", name:name, options: options -:>
236     <:.else -:>
237 <:-.call "input", name:name, options: options -:><:.call "error_img", field:name :>
238     <:-.end if -:>
239     <:-.if field.units -:>
240       <:-= field.units | html -:>
241     <:-.end if -:>
242     <:-.if options.note -:>
243 <br /><:= options.note | raw :>
244     <:-.end if -:>
245 </span>
246 </div>
247   <:.end if -:>
248 <:.end define -:>
249
250 <:.define fieldset -:>
251 <:# like field, but wrap in a per-field field set.
252 parameters:
253   name - field name
254   fields - hash of fields (may be set by page instead)
255 :>
256   <:.set f = fields[name] -:>
257   <:.if f.is_hash -:>
258 <fieldset>
259     <:.if !f.nolabel -:>
260   <legend><:= f.description :></legend>
261     <:.end if -:>
262   <:.call "input", name: name, field: f -:>
263 </fieldset>
264   <:.elsif fields.is_hash -:>
265 <p>Unknown field id '<b><:= name :></b>', available fields are '<:= fields.keys.join("', '") :>'</p>
266   <:.else -:>
267 <p>fields isn't a hash, something is wrong.</p>
268   <:.end if -:>
269 <:.end define -:>
270
271 <:.define display -:>
272 <:# paramaters:
273   name - field name
274   field - entry from fields
275   object - source for defaults in edit mode
276 :>
277 <:  .if object -:>
278 <:     .set default = object.$name -:>
279 <:  .end if -:>
280 <:  .if field.type and field.type eq "date" and default ne "" -:>
281 <:    .set default = default.replace(/(\d+)\D+(\d+)\D+(\d+)/, "$3/$2/$1") -:>
282 <:  .elsif field.type and field.type eq "time" and default ne "" -:>
283 <:    .set default = bse.date(default =~ /:00$/ ? "%I:%M%p" : "%I:%M:%S%p", default).replace(/^0/, "").lower() -:>
284 <:  .end if -:>
285 <:  .if field.htmltype eq "textarea" -:>
286 <textarea id="<:= name | html :>" name="<:= name | html :>" rows="<:= field.height ? field.height : cfg.entry("forms", "textarea_rows", 10) :>" cols=<:= field.width ? field.width : cfg.entry("textarea_cols", 60) | html :> readonly>
287 <:-= default | html -:>
288 </textarea>
289 <:  .elsif field.htmltype eq "checkbox" -:>
290 <input id="<:= name | html :>" type="checkbox" name="<:= name | html :>"<:= is_checked ? ' checked="checked"' : '' :> value="<:= field.value ? field.value : 1 | html :>" readonly>
291 <:  .elsif field.htmltype eq "multicheck" -:>
292 <:# we expect default to be a list of selected checks -:>
293 <:.set values = field.select["values"] -:>
294 <:.set values = values.is_code ? values() : values -:>
295 <:.call "make_multicheck",
296   id: field.select.id,
297   desc: field.select.label,
298   readonly: 1 -:>
299 <:  .elsif field.htmltype eq "select" -:>
300 <:.set values = field.select["values"] -:>
301 <:.set values = values.is_code ? values() : values -:>
302 <:# find the selected value and display it's label -:>
303 <:.set sid = field.select.id -:>
304 <:.set sdesc = field.select.label -:>
305 <:.for value in values -:>
306   <:.if value.$id eq default -:>
307     <:= value.$desc -:>
308   <:.end if -:>
309 <:.end for -:>
310 <:  .else -:>
311 <input id="<:= name  :>" type="text" name="<:= name :>" value="<:=  default :>"
312 <:-= field.width ? ' size="' _ field.width _ '"' : '' | raw :> readonly>
313 <:  .end if -:>
314 <:.end define -:>
315
316 <:.define inlinefieldro -:>
317 <:# parameters:
318   name - the field name
319   field - a field, as an entry in fields
320 -:>
321   <:.if field.is_hash -:>
322 <div>
323   <label for="<:= name :>"><:= field.nolabel ? "" : field.description :>:</label>
324   <span><:.call "display", name:name -:>
325     <:-.if field.units -:>
326       <:-= field.units -:>
327     <:-.end if -:>
328   <:.end if -:>
329 </span>
330 </div>
331 <:.end define -:>
332
333 <:.define fieldro -:>
334 <:# like field, but for display, not editing -:>
335   <:.if fields.is_hash -:>
336     <:.set f = fields[name] -:>
337     <:.if f -:>
338       <:.call "inlinefieldro", field:f, name:name -:>
339     <:.else -:>
340 <p>Unknown field id '<b><:= name :></b>', available fields are '<:= fields.keys.join("', '") :>'</p>
341     <:.end if -:>
342   <:.else -:>
343 <p>fields isn't a hash, something is wrong.</p>
344   <:.end if -:>
345 <:.end define -:>
346
347 <:.define fieldsetro -:>
348 <:# like fieldro, but wrap in a per-field field set.
349 parameters:
350   name - field name
351   fields - hash of fields (may be set by page instead)
352 :>
353   <:.set f = fields[name] -:>
354   <:.if f.is_hash -:>
355 <fieldset>
356     <:.if !f.nolabel -:>
357   <legend><:= f.description :></legend>
358     <:.end if -:>
359   <:.call "display", "name":name, "field":f -:>
360 </fieldset>
361   <:.elsif fields.is_hash -:>
362 <p>Unknown field id '<b><:= name :></b>', available fields are '<:= fields.keys.join("', '") :>'</p>
363   <:.else -:>
364 <p>fields isn't a hash, something is wrong.</p>
365   <:.end if -:>
366 <:.end define -:>
367
368 <:.define messages -:>
369 <:  .if request.messages.size -:>
370 <div class="messages">
371 <:     .for m in request.messages -:>
372   <div class="<:= m.class :>"><:= m.html |raw :></div>
373 <:     .end for -:> 
374 </div>
375 <:  .end if -:>
376 <:.end define -:>
377
378 <:.define mover -:>
379 <:# expects loop, request, parent
380   which in most cases means you can just supply parent
381 -:>
382 <:.if request.user_can("bse_edit_reorder_children", parent) -:>
383   <:.set down_url = loop.next ? cfg.admin_url("move", { "stepparent":parent.id, "d":"swap", "id":loop.current.id, "other":loop.next.id, "r":top.admin }) : 0 -:>
384   <:.set up_url = loop.prev ? cfg.admin_url("move", { "stepparent":parent.id, "d":"swap", "id":loop.current.id, "other":loop.prev.id, "r":top.admin }) : 0 -:>
385   <:.set class = cfg.entry("arrows", "class", "bse_arrows") -:>
386   <span class="<:= m.class :>">
387     <:-.call "make_arrows", "down_url":down_url, "up_url":up_url -:>
388   </span>
389 <:.end if -:>
390 <:.end define -:>
391
392 <:.define make_arrows -:>
393 <:# expects down_url, up_url
394 -:>
395   <:.set width = cfg.entry("arrows", "image_width", 17) -:>
396   <:.set height = cfg.entry("arrows", "image_height", 13) -:>
397   <:.set extras = 'width="' _ width _ '" height="' _ height _ '"' -:>
398   <:.set blank_img = '<img src="' _ (dist_image_uri _ "/trans_pixel.gif").escape("html") _ '" alt="" ' _ extras _ ' />' -:>
399   <:.set down_img = '<img src="' _ cfg.entry("arrows", "downimg", dist_image_uri _ "/admin/move_down.gif").escape("html") _ '" alt="Down" ' _ extras _ ' />' -:>
400   <:.set up_img = '<img src="' _ cfg.entry("arrows", "upimg", dist_image_uri _ "/admin/move_up.gif").escape("html") _ '" alt="Up" ' _ extras _ ' />' -:>
401   <:-.if down_url -:>
402   <a href="<:= down_url :>"><:= down_img |raw:></a>
403   <:-.else -:>
404     <:= blank_img |raw:>
405   <:-.end if -:>
406   <:-.if up_url -:>
407   <a href="<:= up_url :>"><:= up_img |raw:></a>
408   <:-.else -:>
409     <:= blank_img |raw:>
410   <:-.end if -:>
411
412 <:.end define -:>
413
414 <:.define word_wrap; text: @undef, prefix:"", noncontin: "", contin:"", escape1: "", escape2: "", width: 70 -:>
415 <:# Word wrap "text" at width columns, following settings:
416 width - word wrap width (default 70)
417 prefix - prefix to add to all lines
418 noncontin - prefix to additionally add to first line of each paragraph
419 contin - prefix to additionally add to lines that have been wrapped
420 escape1 - suffix to add to lines wrapped on a non-word
421 escape2 - suffix to add to lines wrapped on a word boundary
422 -:>
423 <:.set re = "^.{1," _ width _ "}\\s+" -:>
424 <:.set paras = text.split(/\n/) -:>
425 <:.for para in paras -:>
426 <:  .set work = para -:>
427 <:  .set first = 1 -:>
428 <:  .while work.length -:>
429 <:    .if !first -:>
430 <:      .set work = work.replace(/^\s+/, "") -:>
431 <:    .end if -:>
432 <:    .if work.length < 70 -:>
433 <:      .set line = work -:>
434 <:      .set work = "" -:>
435 <:    .else -:>
436 <:      .set m = work.match(re) -:>
437 <:      .if m -:>
438 <:        .set line = work.substring(0, m.length).replace(/\s+$/, "") _ escape2 -:>
439 <:        .set work = work.substring(m.length) -:>
440 <:      .else -:>
441 <:        .set line = work.substring(0, width) _ escape1 -:>
442 <:        .set work = work.substring(width) -:>
443 <:      .end if -:>
444 <:    .end if -:>
445 <:= prefix _ (first ? noncontin : contin) _ line.replace(/\s+$/, "") |raw:>
446 <:    .set first = 0 -:>
447 <:  .end while -:>
448 <:.end for -:>
449 <:.end define -:>
450
451 <:- include includes/custom/preload.tmpl optional -:>