Hide last authors
superadmin 1.1 1 {{velocity output="false"}}
2 #if ($request.xaction == 'postUpload')
3 #set ($targetDocument = $xwiki.getDocument($request.get('docname')))
4 #set ($targetAttachDocument = $xwiki.getDocument($request.get('targetdocname')))
5
6 #set ($fieldname = $request.get('fieldname'))
7 #set ($docAction = $request.get('docAction'))
8 #set ($attachmentList = $targetAttachDocument.getAttachmentList())
9 #if ($attachmentList && $attachmentList.size() > 0)
10 #set ($sortedAttachments = $sorttool.sort($attachmentList, 'date:desc'))
11 #set ($lastAttachment = $sortedAttachments.get(0))
12 #end
13 $response.sendRedirect($targetDocument.getURL($docAction, $escapetool.url({
14 $fieldname: $lastAttachment.filename,
15 'form_token': $request.form_token
16 })))
17 #stop
18 #end
19 {{/velocity}}
20
21 {{velocity output="false"}}
22 ##
23 ## Macros
24 ##
25 #set ($translationPrefix = 'xe.attachmentSelector')
26 #set ($attachmentPickerDocName = 'XWiki.AttachmentSelector')
27
28 $xwiki.ssx.use($attachmentPickerDocName)
29 $xwiki.jsx.use($attachmentPickerDocName)
30
31 #**
32 * Displays the attachment gallery as a list of attachment boxes, starting with special boxes for uploading a new attachment and for setting a default value.
33 *
34 * @param $targetDocument the document to recieve the field value being modified
35 * @param $targetAttachDocument the document to list/save attachments to
36 * @param $options generic picker options
37 *#
38 #macro (attachmentPicker_displayAttachmentGallery $targetDocument, $targetAttachDocument, $options)
39 #set ($currentValue = $targetDocument.getValue($options.property))
40 #if ("$!{targetAttachDocument.getAttachment($currentValue)}" == '')
41 #set ($currentValue = "$!{options.defaultValue}")
42 #end
43 (% class="gallery" %)(((
44 ## Only display the upload form if they have edit permission on targetAttachDocument
45 #if ($xwiki.hasAccessLevel('edit',$xcontext.user,${targetAttachDocument.fullName}))
46 #attachmentPicker_displayUploadForm($targetDocument, $targetAttachDocument, $options)
47 #end
48 #attachmentPicker_displayAttachmentGalleryEmptyValue($targetDocument, $targetAttachDocument, $options, $currentValue)
49 #set ($sortedAttachments = $sorttool.sort($targetAttachDocument.getAttachmentList(), "${options.sortAttachmentsBy}") )
50 #foreach ($attachment in $sortedAttachments)
51 #set ($extension = $attachment.getFilename())
52 #set ($extension = $extension.substring($mathtool.add($extension.lastIndexOf('.'), 1)).toLowerCase())
53 #if ($options.filter.size() == 0 || $options.filter.contains($extension))
54 #attachmentPicker_displayAttachmentBox($attachment $targetDocument $targetAttachDocument, $options $currentValue)
55 #end
56 #end
57 )))
58 #end
59
60 #**
61 * Displays an attachment box.
62 *
63 * @param $attachment the target attachment to display
64 * @param $targetDocument the document being modified
65 * @param $options generic picker options
66 * @param $currentValue the currently selected file, used for determining if the box should be highlighted as the current value
67 *#
68 #macro (attachmentPicker_displayAttachmentBox $attachment $targetDocument $targetAttachDocument, $options $currentValue)
69 #if ($options.displayImage && $attachment.isImage())
70 #set ($cssClass = 'gallery_image')
71 #else
72 #set ($cssClass = '')
73 #end
74 #attachmentPicker_displayStartFrame({'value' : $attachment.filename, 'text' : $attachment.filename, 'cssClass' : "$!{cssClass}"} $currentValue)
75 #attachmentPicker_displayAttachmentDetails($attachment $options)
76 #set ($returnURL = $escapetool.url($doc.getURL('view', $request.queryString)))
77 #set ($deleteURL = $targetAttachDocument.getAttachmentURL($attachment.filename, 'delattachment', "xredirect=${returnURL}&form_token=$!{services.csrf.getToken()}") )
78 #set ($viewURL = $targetAttachDocument.getAttachmentURL($attachment.filename) )##{'name' : 'download', 'url' : $viewURL, 'rel' : '__blank'}
79 #set ($selectURL = $targetDocument.getURL(${options.get('docAction')}, "${options.get('classname')}_${options.get('object')}_${options.get('property')}=${attachment.filename}&form_token=$!{services.csrf.getToken()}"))
80 #attachmentPicker_displayEndFrame ([{'name' : 'select', 'url' : $selectURL}, {'name' : 'delete', 'url' : $deleteURL}])
81 #end
82
83 #**
84 * Writes the wiki code used at the start of an attachment box. Outputs the attachment title bar, and opens the inner frame div.
85 *
86 * @param $boxOptions a map of parameters/options for the current attachment, holding, for example, the attachment name (boxOptions.value),
87 * the title to display (boxOptions.text), optional extra CSS classnames to put on the box (boxOptions.cssClass)
88 * @param $currentValue the currently selected file, used for determining if this attachment should be highlighted as the current value
89 *#
90 #macro (attachmentPicker_displayStartFrame $boxOptions $currentValue)
91 (% class="gallery_attachmentbox $!{boxOptions.cssClass} #if ("$!{boxOptions.value}" == $currentValue) current#{end}" %)(((
92 (% class="gallery_attachmenttitle" title="$!{boxOptions.value}" %)((($boxOptions.text)))
93 (% class="gallery_attachmentframe" %)(((
94 #end
95
96 #**
97 * Displays details about an attachment inside the attachment box. If the attachment is an image and the "displayImage" option is on,
98 * then the image is displayed. Otherwise, some basic information is displayed: the version, the size, the date and the author.
99 *
100 * @param $attachment the target attachment to display
101 * @param $options generic picker options
102 *#
103 #macro (attachmentPicker_displayAttachmentDetails $attachment $options)
104 #if ($attachment)
105 ## Compute the attachment reference because there's no getter.
106 #set ($attachmentReference = $services.model.createAttachmentReference($attachment.document.documentReference,
107 $attachment.filename))
108 #set ($attachmentStringReference = $services.model.serialize($attachmentReference, 'default'))
109 #if ($attachment.isImage() && $options.displayImage)
110 ## We add the version to the query string in order to invalidate the cache when an image attachment is replaced.
111 #set ($queryString = $escapetool.url({'version': $attachment.version}))
112 [[[[image:$attachmentStringReference||width=180 queryString="$queryString"]]>>attach:$attachmentStringReference]]
113 #else
114 * (% class="mime" %){{html wiki=false clean=false}}#mimetypeimg($attachment.getMimeType().toLowerCase() $attachment.getFilename().toLowerCase()){{/html}}(%%) (% class="filename" %)$attachment.getFilename()(% %)
115 * v$attachment.getVersion() (#dynamicsize($attachment.longSize))
116 * $services.localization.render('core.viewers.attachments.author', [$!{xwiki.getUserName($attachment.author, false)}]) $services.localization.render('core.viewers.attachments.date', [$!{xwiki.formatDate($attachment.date, 'dd/MM/yyyy hh:mm')}])
117 * (% class="buttonwrapper" %)[[${services.localization.render("${translationPrefix}.actions.download")}>>attach:$attachmentStringReference||title="$services.localization.render("${translationPrefix}.actions.download")" rel="__blank" class="button"]](%%)
118 #end
119 #end
120 #end
121
122 #**
123 * Writes the wiki code used at the end of an attachment box. Closes the inner frame div, and outputs the attachment actions.
124 *
125 * @param $actions a list of maps defining action buttons, where each entry contains a subset of the following:
126 * <dl>
127 * <dt>name</dt>
128 * <dd>identifies the action; the name is used as a CSS classname, and in the translation key for the display text, as "xe.attachmentSelector.actions.<name>"</dd>
129 * <dt>url</dt>
130 * <dd>the destination of the button</dd>
131 * <dt>rel</dt>
132 * <dd>an optional parameter to be used in the "rel" HTML attribute; for example "__blank" can be used to open the link in a new tab/window</dd>
133 * </dl>
134 *#
135 #macro (attachmentPicker_displayEndFrame $actions)
136 )))## attachmentframe
137 (% class="gallery_actions" %)(((
138 #foreach ($action in $actions)
139 #set( $actionname = $services.localization.render("${translationPrefix}.actions.${action.name}") )
140 [[${actionname}>>path:${action.url}||class="tool ${action.name}" title="${actionname}" #if($action.rel) rel="${action.rel}"#end]]##
141 #end
142 )))## actions
143 )))## attachmentbox
144 #end
145
146 #**
147 * Displays the upload box used for adding and selecting a new attachment.
148 *
149 * @param $targetDocument the document with the property being modified
150 * @param $targetAttachDocument the document to upload the attachment to
151 * @param $options generic picker options
152 *#
153 #macro (attachmentPicker_displayUploadForm $targetDocument, $targetAttachDocument, $options)
154 #attachmentPicker_displayStartFrame({
155 'value' : $services.localization.render("${translationPrefix}.upload.title"),
156 'text' : $services.localization.render("${translationPrefix}.upload.title"),
157 'cssClass' : 'gallery_upload'
158 } $NULL)
159 {{html clean="false"}}
160 <form action="$targetAttachDocument.getURL('upload')" enctype="multipart/form-data" method="post" id="uploadAttachment" class="uploadAttachment xform">
161 <div class="gallery_upload_input">
162 #if (${options.rawfilter} != '')
163 <span class="xHint">$escapetool.xml($services.localization.render("${translationPrefix}.upload.hint", [${options.rawfilter}]))</span>
164 #end
165 <input type="file" name="filepath" id="attachfile" class="noitems" title="$!{escapetool.xml($options.rawfilter)}"/>
166 <input type="hidden" name="xredirect" value="$xwiki.getDocument($attachmentPickerDocName).getURL('get', "xaction=postUpload&amp;docAction=$!{escapetool.url($options.get('docAction'))}&amp;targetdocname=$!{escapetool.url($targetAttachDocument.fullName)}&amp;docname=$!{escapetool.url($targetDocument.fullName)}&amp;fieldname=$!{escapetool.url($options.get('classname'))}_$!{escapetool.url($options.get('object'))}_$!{escapetool.url($options.get('property'))}&amp;form_token=$!{services.csrf.getToken()}")" />
167 <input type="hidden" name="docname" value="$!{escapetool.xml($targetDocument.fullName)}" />
168 <input type="hidden" name="classname" value="$!{escapetool.xml($options.get('classname'))}" />
169 <input type="hidden" name="object" value="$!{escapetool.xml($options.get('object'))}" />
170 <input type="hidden" name="property" value="$!{escapetool.xml($options.get('property'))}" />
171 <input type="hidden" name="form_token" value="$!{services.csrf.getToken()}" />
172 </div>
173 #if ("$!currentValue" != '' && $currentValue != $options.defaultValue)
174 <div>
175 <label>
176 <input type="checkbox" name="filename" value="$!escapetool.xml($currentValue)"
177 />$services.localization.render('attachmentSelector.replace',
178 ["<strong>$!escapetool.xml($currentValue)</strong>"])
179 </label>
180 <span class="xHint">$escapetool.xml($services.localization.render('attachmentSelector.replace.hint'))</span>
181 </div>
182 #end
183 #if ($xwiki.hasEditComment() && $options.versionSummary)
184 <div>
185 #if ($xwiki.isEditCommentFieldHidden())
186 <input type="hidden" name="comment" value="$!escapetool.xml($request.comment)" />
187 #else
188 <label for="commentinput">$services.localization.render('core.comment')</label>
189 <input type="text" name="comment" id="commentinput" value="$!escapetool.xml($request.comment)"
190 title="$services.localization.render('core.comment.tooltip')" />
191 #end
192 </div>
193 #end
194 <div class="buttons">
195 <span class="buttonwrapper">
196 <input type="submit" name="action_upload" class="button " value='$services.localization.render("${translationPrefix}.upload.submit")' title='$services.localization.render("${translationPrefix}.upload.submit")'/>
197 </span>
198 </div>
199 </form>
200 {{/html}}
201 #attachmentPicker_displayEndFrame ([])
202 #end
203
204 #**
205 * Displays the "empty value" box, used for unsetting the field value.
206 *
207 * @param $targetDocument the document being modified
208 * @param $targetAttachDocument the document that the attachments will the loaded from/saved to
209 * @param $options generic picker options
210 * @param $currentValue the currently selected file, used for determining if the empty box should be highlighted as the current value
211 *#
212 #macro (attachmentPicker_displayAttachmentGalleryEmptyValue $targetDocument, $targetAttachDocument, $options, $currentValue)
213 #if ("$!{options.get('defaultValue')}" != '')
214 #set ($reference = ${options.get('defaultValue')})
215 #set ($docNameLimit = $reference.indexOf('@'))
216 #if ($docNameLimit > 0)
217 #set ($docName = $reference.substring(0, $docNameLimit))
218 #else
219 #set ($docName = $targetAttachDocument.fullName)
220 #end
221 #set ($attachmentName = $reference.substring($mathtool.add($docNameLimit, 1)))
222 #set ($defaultAttachment = $xwiki.getDocument($docName).getAttachment($attachmentName))
223 #if ($defaultAttachment.isImage())
224 #set($dcssClass = 'gallery_image')
225 #end
226 #end
227 #attachmentPicker_displayStartFrame({'cssClass' : "gallery_emptyChoice $!{dcssClass}", 'text' : $services.localization.render("${translationPrefix}.default"), 'value' : "${options.defaultValue}"} $currentValue)
228 #attachmentPicker_displayAttachmentDetails($defaultAttachment $options)
229 #set ($returnURL = $escapetool.url($doc.getURL('view', $request.queryString)))
230 #set ($selectURL = $targetDocument.getURL(${options.get('docAction')}, "${options.get('classname')}_${options.get('object')}_${options.get('property')}=&form_token=$!{services.csrf.getToken()}"))
231 #attachmentPicker_displayEndFrame ([{'name' : 'select', 'url' : $selectURL}])
232 #end
233 {{/velocity}}
234
235 {{velocity}}
236 #if ($request.docname)
237 #set ($targetDocument = $xwiki.getDocument($request.docname))
238 #if ($request.targetdocname)
239 ## Use the target document if it exists.
240 #set ($targetAttachDocument = $xwiki.getDocument($request.targetdocname))
241 #else
242 ## Otherwise, just use the current document as the target to save/load attachments
243 #set ($targetAttachDocument = $targetDocument)
244 #end
245 #if ("$!{request.savemode}" == 'direct')
246 #set($docAction = 'save')
247 #else
248 #set($docAction = $targetAttachDocument.getDefaultEditMode())
249 #end
250 #set ($filter = [])
251 #set ($rawfilter = '')
252 #if ("$!{request.filter}" != '')
253 #foreach ($value in $request.filter.trim().split('\s*+[,|; ]\s*+'))
254 #if ("$!value" != '')
255 #set ($discard = $filter.add($value.toLowerCase()))
256 #set ($rawfilter = "${rawfilter}, ${value}")
257 #end
258 #end
259 #if ($rawfilter != '')
260 #set ($rawfilter = $rawfilter.substring(2))
261 #end
262 #end
263 #if ("$!{request.displayImage}" == 'true')
264 #set ($displayImage = true)
265 #else
266 #set ($displayImage = false)
267 #end
268 ### Determine attachment sorting
269 #set($sortAttachmentsBy = "$!{request.sortAttachmentsBy}")
270 #set ($validAttachmentProperties = ['filename', 'date', 'filesize', 'author', 'version', 'mimeType'])
271 #if($sortAttachmentsBy == '' || $validAttachmentProperties.indexOf($sortAttachmentsBy) == -1)
272 ### Default to sorting by filename, sort not requested.
273 #set($sortAttachmentsBy = "filename")
274 #end
275 ### Set attachment sorting direction
276 #if($sortAttachmentsBy == 'date')
277 ### Sort the date descending
278 #set($sortAttachmentsBy = "date:desc")
279 #else
280 ### Sort everything else ascending
281 #set($sortAttachmentsBy = "${sortAttachmentsBy}:asc")
282 #end
283 #set ($options = {
284 'classname' : ${request.get('classname')},
285 'object' : $!{mathtool.toInteger($request.object)},
286 'property' : ${request.property},
287 'displayImage' : ${displayImage},
288 'docAction' : ${docAction},
289 'defaultValue' : "$!{request.defaultValue}",
290 'rawfilter': "$!{rawfilter}",
291 'filter': ${filter},
292 'sortAttachmentsBy': ${sortAttachmentsBy},
293 'versionSummary': $request.versionSummary.equals('true')
294 })
295 $!targetDocument.use($targetDocument.getObject($options.classname, $options.object))##
296 #attachmentPicker_displayAttachmentGallery($targetDocument, $targetAttachDocument, $options)
297
298 (% class="gallery_buttons buttons" %)(((
299 (% class="buttonwrapper secondary" %)[[$services.localization.render("${translationPrefix}.cancel")>>$targetDocument||class="button secondary" id="attachment-picker-close"]]
300 )))
301 #end
302 {{/velocity}}

Tips

You can click on the arrows next to the breadcrumb elements to quickly navigate to sibling and children pages.

Need help?

If you need help with XWiki you can contact: