Änderungen von Dokument Attachments
Zuletzt geändert von xwikiadmin am 2026/03/05 08:03
Von Version 3.1
bearbeitet von xwikiadmin
am 2023/10/26 09:37
am 2023/10/26 09:37
Änderungskommentar:
Install extension [com.xwiki.pro:xwiki-pro-macros/1.9.2]
Auf Version 5.1
bearbeitet von xwikiadmin
am 2025/05/21 09:20
am 2025/05/21 09:20
Änderungskommentar:
Migrated property [featureMandatory] from class [XWiki.WikiMacroParameterClass]
Zusammenfassung
-
Seiteneigenschaften (1 geändert, 0 hinzugefügt, 0 gelöscht)
-
Objekte (1 geändert, 3 hinzugefügt, 0 gelöscht)
Details
- Seiteneigenschaften
-
- Inhalt
-
... ... @@ -5,16 +5,16 @@ 5 5 * {{{ labels }}} is not supported since XWiki does not support attachment tags 6 6 * {{{ preview }}} does not make sense for the XWiki macro as attachments are displayed differently 7 7 * {{{ old }}} has not been implemented in this bridge macro because it does not make really sense for XWiki 8 -* {{{ upload }}} has not been implemented yet because it conflicts with the standard attachment panel upload 9 9 * {{{ "created date" }}} value of the {{{ sortBy }}} property behave the same way as the {{{ "date" }}} value 10 10 11 11 = Parameters = 12 12 13 13 |=Parameter|=Description|=Required|=Default 14 -|**patterns**|Comma-separated list of regular expressions, used to filter attachments by name.|No| 13 +|**patterns**|Comma-separated list of regular expressions, used to filter attachments by name.|No| 15 15 |**sortBy**|Sort attachments by {{{ date }}}, {{{ size }}} or {{{ name }}}|No|{{{ date }}} 16 16 |**sortOrder**|Sort attachments in {{{ ascending }}} or {{{ descending }}} order|No|{{{ ascending }}} 17 -|**page**|Pages containing the attachments to display. Current page if empty.|No| 16 +|**upload**|Allow users to attach new files|No|{{{ true }}} 17 +|**page**|Pages containing the attachments to display. Current page if empty.|No| 18 18 19 19 = Example Usage = 20 20
- XWiki.WikiMacroClass[0]
-
- Makro-Code
-
... ... @@ -41,12 +41,36 @@ 41 41 #end 42 42 #end 43 43 44 +#macro (deleteConfluenceAttachmentModal) 45 + ## Copied from the attachments tab code. The original macro cannot be used, since it will interfere with some js 46 + ## specific to attachments tab. Precisely, if the attachments tab is already opened, everything is working correctly. 47 + ## If it is not opened, we need to load the attachments.js code anyway, to use it's listeners, but there are parts 48 + ## that rightfully assume that some elements are present on the page and errors will occur. 49 + <div class="modal fade deleteConfluenceAttachment" tabindex="-1" role="dialog"> 50 + <div class="modal-dialog"> 51 + <div class="modal-content"> 52 + <div class="modal-header"> 53 + <button type="button" class="close" data-dismiss="modal">×</button> 54 + <div class="modal-title">$services.localization.render('core.viewers.attachments.delete')</div> 55 + </div> 56 + <div class="modal-body"> 57 + <div>$services.localization.render('core.viewers.attachments.delete.confirm')</div> 58 + </div> 59 + <div class="modal-footer"> 60 + <input type="button" class="btn btn-danger" data-dismiss="modal" 61 + value="$escapetool.xml($services.localization.render('core.viewers.attachments.delete'))"> 62 + <input type="button" class="btn btn-default" data-dismiss="modal" 63 + value="$escapetool.xml($services.localization.render('cancel'))"> 64 + </div> 65 + </div> 66 + </div> 67 + </div> 68 +#end 69 + 44 44 #set ($confluenceAttachmentMacroIndex = -1) 45 45 ## Code taken and adapted 46 46 #macro (showConfluenceAttachments $document) 47 - #template('attachment_macros.vm') 48 48 #template('display_macros.vm') 49 - #initRequiredSkinExtensions() 50 50 #set ($confluenceAttachmentMacroIndex = $confluenceAttachmentMacroIndex + 1) 51 51 #set ($confluenceAttachmentMacroId = "confluenceAttachments$confluenceAttachmentMacroIndex") 52 52 ## ... ... @@ -53,6 +53,37 @@ 53 53 #showConfluenceAttachmentsLiveData($document $confluenceAttachmentMacroId) 54 54 #end 55 55 80 +#macro (uploadFileForm $liveDataId) 81 + #set ($upload = "$!wikimacro.parameters.upload") 82 + #if ($upload == 'true' && ($hasEdit || $hasAdmin) && $xcontext.action == 'view') 83 + <form action="$attachmentsDoc.getURL("upload")" enctype="multipart/form-data" method="post"> 84 + <div> 85 + ## CSRF prevention 86 + <input type="hidden" name="form_token" value="$!{services.csrf.getToken()}" /> 87 + <fieldset> 88 + <legend>$services.localization.render('promacros.attachments.upload.title')</legend> 89 + <div> 90 + #set ($inputID = "${liveDataId}-uploadFile") 91 + <label class="sr-only" for="${inputID}"> 92 + $services.localization.render('core.viewers.attachments.upload.file') 93 + </label> 94 + <input id="${inputID}" type="file" name="filepath" size="40" class="noitems" 95 + data-max-file-size="$!escapetool.xml($xwiki.getSpacePreference('upload_maxsize'))"/> 96 + </div> 97 + </fieldset> 98 + </div> 99 + </form> 100 + #end 101 +#end 102 + 103 +#macro (supportsAttachJSON $supportsAttachJSON) 104 + ## The attachments.json code uses macros from attachment_macro.vm, so the existence of the attachments livedata macro 105 + ## is an indicator that the template exists and is adapted for livedata. 106 + #template('attachment_macros.vm') 107 + #set ($macroResult = "#showAttachmentsLiveData($doc 'id')") 108 + #set ($supportsAttachJSON = $macroResult.startsWith('{{liveData')) 109 +#end 110 + 56 56 ## Display a liveData with attachments from the specified document. 57 57 #macro (showConfluenceAttachmentsLiveData $attachmentsDoc $liveDataId) 58 58 #set ($liveDataConfig = { ... ... @@ -62,7 +62,8 @@ 62 62 { 'id': 'filename', 'displayer': 'html' }, 63 63 { 'id': 'filesize', 'displayer': 'html' }, 64 64 { 'id': 'date', 'filter': 'date'}, 65 - { 'id': 'author', 'displayer': 'html' } 120 + { 'id': 'author', 'displayer': 'html' }, 121 + { 'id': 'actions', 'displayer': 'html' } 66 66 ], 67 67 'entryDescriptor': { 68 68 'idProperty': 'id' ... ... @@ -86,13 +86,19 @@ 86 86 )) 87 87 #end 88 88 #end 89 - #set ($sourceParameters = $escapetool.url({ 90 - 'template': 'xpart.vm', 145 + #set ($sourceParams = { 91 91 'translationPrefix': 'core.viewers.attachments.livetable.', 92 92 'className': 'XWiki.AllAttachments', 93 - "\$doc": "$attachmentsDoc", 94 - 'vm': 'attachmentsjson.vm' 95 - })) 148 + "\$doc": "$attachmentsDoc" 149 + }) 150 + ## Since the correct attachmentsjson.vm was added in XWiki 14.8, we use a copy of its code for backwards compatibility. 151 + #supportsAttachJSON($supportsAttachJSON) 152 + #if ($supportsAttachJSON) 153 + #set ($discard = $sourceParams.put('template', 'xpart.vm')) 154 + #set ($discard = $sourceParams.put('vm', 'attachmentsjson.vm')) 155 + #else 156 + #set ($discard = $sourceParams.put('resultPage', 'Confluence.Macros.AttachmentsJSON')) 157 + #end 96 96 #getLiveDataSort($liveDataSort) 97 97 #if ($invalidSortBy) 98 98 {{warning}} ... ... @@ -107,18 +107,29 @@ 107 107 108 108 {{liveData 109 109 id="$liveDataId" 110 - properties="mimeType,filename,filesize,date,author" 172 + properties="mimeType,filename,filesize,date,author,actions" 111 111 source='liveTable' 112 - sourceParameters="$sourceParam eters"174 + sourceParameters="$escapetool.url($sourceParams)" 113 113 sort="$liveDataSort" 114 114 limit=5 115 115 }}$jsontool.serialize($liveDataConfig){{/liveData}} 116 116 117 - {{html clean="false"}}#deleteAttachmentModal(){{/html}} 179 + {{html clean="false"}} 180 + #uploadFileForm($liveDataId) 181 + #deleteConfluenceAttachmentModal() 182 + {{/html}} 118 118 #end 119 119 120 120 121 121 #macro (executeMacro) 187 + #set ($discard = $xwiki.ssfx.use('js/xwiki/viewers/attachments.css', true)) 188 + #set ($discard = $xwiki.ssfx.use('uicomponents/widgets/upload.css', true)) 189 + #set ($discard = $xwiki.jsfx.use('uicomponents/widgets/upload.js', { 190 + 'forceSkinAction': true, 191 + 'language': $xcontext.locale 192 + })) 193 + #set ($discard = $xwiki.jsx.use("Confluence.Macros.Attachments")) 194 + #set ($discard = $xwiki.ssx.use("Confluence.Macros.Attachments")) 122 122 #set ($document = $doc) 123 123 #if ("$!wikimacro.parameters.page" != '') 124 124 #set ($document = $xwiki.getDocument("$!wikimacro.parameters.page")) ... ... @@ -125,7 +125,9 @@ 125 125 #end 126 126 127 127 {{html clean="false" wiki="true"}} 128 - #showConfluenceAttachments($document) 201 + <div class='confluenceAttachmentsMacro'> 202 + #showConfluenceAttachments($document) 203 + </div> 129 129 {{/html}} 130 130 131 131 #end
- XWiki.JavaScriptExtension[0]
-
- Pufferstrategie
-
... ... @@ -1,0 +1,1 @@ 1 +long - Code
-
... ... @@ -1,0 +1,95 @@ 1 +define('xwiki-confluence-attachments-messages', { 2 + prefix: 'core.viewers.attachments.delete.', 3 + keys: [ 4 + 'inProgress', 5 + 'done', 6 + 'error' 7 + ] 8 +}); 9 + 10 +require(['jquery', 'xwiki-l10n!xwiki-confluence-attachments-messages'], function($, l10n) { 11 + var enhanceUploadInputs = function(liveDataElems) { 12 + $.each(liveDataElems.find('input[type=file]'), function() { 13 + // Since the attachments liveData is refreshed on file upload, there is no need for a response container. 14 + new XWiki.FileUploader(this, { 15 + 'progressAutohide': true, 16 + 'responseContainer' : document.createElement('div'), 17 + 'maxFilesize' : parseInt(this.readAttribute('data-max-file-size')) 18 + }); 19 + }) 20 + }; 21 + 22 + $(function() { 23 + enhanceUploadInputs($('.confluenceAttachmentsMacro')); 24 + }) 25 + 26 + $(document).on('xwiki:dom:updated', function(e, data) { 27 + let liveDataElems = $(data.elements).find('.confluenceAttachmentsMacro'); 28 + enhanceUploadInputs(liveDataElems); 29 + }); 30 + 31 + $(document).on('xwiki:html5upload:done', function(e) { 32 + if ($(e.target).prop('id').startsWith('confluenceAttachments')) { 33 + // Select the livedata above the upload form. 34 + const uploadForm = $(e.target).closest('form'); 35 + // The 'xwiki-livedata' CSS class is present only before XWiki version 14.4. 36 + let associatedLivedata = uploadForm.prevAll('.liveData, .xwiki-livedata').first(); 37 + // We do not have access to a liveData object before XWiki 14.4. 38 + if (associatedLivedata.data('liveData') === undefined) { 39 + location.reload(); 40 + } else { 41 + associatedLivedata.data('liveData').updateEntries(); 42 + } 43 + } 44 + }); 45 + 46 + // 47 + // The delete action methods are similar to the ones from the attachments tab, but couldn't be reused. The problem is 48 + // that when the tab is not opened we cannot just load the attachments.js file, since it expects some elements to be 49 + // already loaded and it produces errors. 50 + // 51 + 52 + /** 53 + * Open the delete confirmation modal on liveData attachment delete button. 54 + */ 55 + $(document).on('click', '.confluenceAttachmentsMacro .attachmentActions .actiondelete', function(e) { 56 + e.preventDefault(); 57 + // The 'xwiki-livedata' CSS class is present only before XWiki version 14.4. 58 + let liveData = $(e.currentTarget).closest('.liveData, .xwiki-livedata'); 59 + var modal = liveData.nextAll('.deleteConfluenceAttachment'); 60 + modal.data('relatedTarget', e.currentTarget); 61 + modal.modal('show'); 62 + }); 63 + 64 + /** 65 + * On delete confirmation, delete attachment and refresh liveData. 66 + */ 67 + $(document).on('click', '.confluenceAttachmentsMacro .deleteConfluenceAttachment input.btn-danger', function(e) { 68 + e.preventDefault(); 69 + var modal = $(e.currentTarget).closest('.deleteConfluenceAttachment'); 70 + var button = $(modal.data('relatedTarget')); 71 + // The 'xwiki-livedata' CSS class is present only before XWiki version 14.4. 72 + let liveData = button.closest('.liveData, .xwiki-livedata'); 73 + var notification; 74 + 75 + $.ajax({ 76 + url : button.prop('href'), 77 + beforeSend : function() { 78 + notification = new XWiki.widgets.Notification(l10n['inProgress'], 'inprogress'); 79 + }, 80 + success : function() { 81 + // We do not have access to a liveData object before XWiki 14.4. 82 + if (liveData.data('liveData') !== undefined) { 83 + liveData.data('liveData').updateEntries(); 84 + notification.replace(new XWiki.widgets.Notification(l10n['done'], 'done')); 85 + } else { 86 + location.reload(); 87 + } 88 + }, 89 + error: function() { 90 + notification.replace(new XWiki.widgets.Notification(l10n['failed'], 'error')); 91 + } 92 + }); 93 + }); 94 +}); 95 + - Name
-
... ... @@ -1,0 +1,1 @@ 1 +Confluence Attachments Macro - Inhalt parsen
-
... ... @@ -1,0 +1,1 @@ 1 +Nein - Benutze diese Erweiterung
-
... ... @@ -1,0 +1,1 @@ 1 +onDemand
- XWiki.StyleSheetExtension[0]
-
- Pufferstrategie
-
... ... @@ -1,0 +1,1 @@ 1 +long - Code
-
... ... @@ -1,0 +1,15 @@ 1 +.confluenceAttachmentsMacro legend { 2 + font-size: 1em; 3 +} 4 + /* These should be deleted after upgrading to a XWiki parent >= 14.6. */ 5 +.attachmentMimeType { 6 + color: $theme.textSecondaryColor; 7 + font-size: 32px; 8 + height: 32px; 9 + line-height: 32px; 10 + text-align: center; 11 +} 12 +.attachmentMimeType img { 13 + max-height: 32px; 14 + max-width: 48px; 15 +} - Content Type
-
... ... @@ -1,0 +1,1 @@ 1 +CSS - Name
-
... ... @@ -1,0 +1,1 @@ 1 +Confluence Attachments Macro - Inhalt parsen
-
... ... @@ -1,0 +1,1 @@ 1 +Nein - Benutze diese Erweiterung
-
... ... @@ -1,0 +1,1 @@ 1 +onDemand
- XWiki.WikiMacroParameterClass[9]
-
- Parameter-Vorgabe
-
... ... @@ -1,0 +1,1 @@ 1 +true - Parameter-Beschreibung
-
... ... @@ -1,0 +1,1 @@ 1 +Display an option for uploading files to the selected page. - Parameter verpflichtend
-
... ... @@ -1,0 +1,1 @@ 1 +Nein - Parameter-Name
-
... ... @@ -1,0 +1,1 @@ 1 +upload - Parameter-Typ
-
... ... @@ -1,0 +1,1 @@ 1 +java.lang.Boolean