Changes for page View File Macro

Last modified by Frank Fock on 2025/04/04 21:18

From version 4.1
edited by Frank Fock
on 2025/04/04 21:18
Change comment: Install extension [com.xwiki.pro:xwiki-pro-macros-ui/1.26.14]
To version 1.1
edited by Frank Fock
on 2024/02/07 18:16
Change comment: Install extension [com.xwiki.pro:xwiki-pro-macros/1.14.3]

Summary

Details

Page properties
Content
... ... @@ -1,35 +1,3 @@
1 -The view-file macro displays attachments in a document, in place or as thumbnail and offers a preview.
1 +{{view-file name="Test.ppt" /}}
2 2  
3 -Limitation: the thumbnail is actually only an icon for now.
4 -
5 -= Parameters =
6 -
7 -|=Parameter|=Description|=Required|=Default
8 -|display|Kind of display. "button" for a button, "thumbnail" for a thumbnail, "full" to render the document in place|no|thumbnail (button in inline mode)
9 -|name|The attachment reference to display|if att--filename is not given|
10 -|page|The page from where you want the attachments to be displayed. Modifying this parameter will reset the selected file value|no|
11 -|width|The width of the view in % or px (e.g. 100%, 100px)|no|100% for the full view or 100px for the thumbnail
12 -|height|The height of the view in % or px (e.g. 100%, 100px)|no|1000px for the full view or 100px for the thumbnail
13 -|att--filename|Alias of name|If name is not given|
14 -
15 -= Example Usage =
16 -
17 -Thumbnails side by side:
18 -
19 -{{view-file display="thumbnail" name="Test.ppt"/}} {{view-file display="thumbnail" name="TestPDF.pdf"/}}
20 -
21 -Or standalone:
22 -
23 -{{view-file name="Test.ppt"/}}
24 -
25 -In a paragraph: {{view-file name="Test.ppt"/}}
26 -
27 -
28 -Full PDF:
29 -
30 -{{view-file display="full" name="TestPDF.pdf"/}}
31 -
32 -Full Presentation:
33 -
34 -{{view-file display="full" name="Test.ppt"/}}
35 -
3 +{{view-file name="TestPDF.pdf" /}}
XWiki.JavaScriptExtension[0]
Caching policy
... ... @@ -1,1 +1,0 @@
1 -long
Code
... ... @@ -1,98 +1,0 @@
1 -require.config({
2 - paths: {
3 - 'xwiki-suggestAttachments': "$xwiki.getSkinFile('uicomponents/suggest/suggestAttachments.js', true)" +
4 - "?v=$escapetool.url($xwiki.version)"
5 - }
6 -});
7 -
8 -// As there is no platform implementation to allow the user to dynamically select the page from where the attachments
9 -// are shown, a custom implementation was made to dynamically update the displyed attachments in corelation to the
10 -// selected page parameter. This can be removed after the implementation of https://jira.xwiki.org/browse/XWIKI-22850.
11 -require(['jquery', 'xwiki-meta', 'xwiki-suggestAttachments'], function($, xm) {
12 - const acceptedExtensions = '.ppt,.pptx,.odp,.doc,.docx,.odt,.xls,.xlsx,.ods,.pdf';
13 - const styleObserver = new MutationObserver(function(mutations) {
14 - for (const mutation of mutations) {
15 - if (mutation.target.style.display === 'none') {
16 - styleObserver.disconnect();
17 - pageObserver.observe(document.body, { childList: true, subtree: true });
18 - return;
19 - }
20 - }
21 - });
22 -
23 - const initializeAttachments = function(selectElement) {
24 - let scope = "document:";
25 - if (selectElement.val() != null) {
26 - scope += selectElement.val();
27 - }
28 - var inputElement = $('input[name="name"]');
29 - if (inputElement.length) {
30 - let selectize = inputElement.siblings('.selectize-control');
31 - if (selectize.length) {
32 - selectize.remove();
33 - inputElement.removeAttr("class tabindex style").val('');
34 - const clone = inputElement.clone().appendTo(inputElement.parent());
35 - inputElement.remove();
36 - inputElement = clone;
37 - }
38 - const allowUpload = selectElement.val() == xm.document || !selectElement.val();
39 - inputElement.suggestAttachments({
40 - maxItems: 1,
41 - accept: acceptedExtensions,
42 - searchScope: scope,
43 - uploadAllowed: allowUpload
44 - });
45 - }
46 - }
47 -
48 - const pageObserver = new MutationObserver(function(mutationsList, observer) {
49 - const selectElement = $('select[name="page"]');
50 - if (selectElement.length) {
51 - const modal = selectElement.closest(".macro-editor-modal")[0];
52 - if (modal.style.display !== 'none') {
53 - observer.disconnect();
54 - styleObserver.observe(modal, { attributes: true, attributeFilter: ['style'] });
55 - $(selectElement).change(function() {
56 - initializeAttachments($(this))
57 - });
58 - initializeAttachments(selectElement)
59 - }
60 - }
61 - });
62 -
63 - pageObserver.observe(document.body, { childList: true, subtree: true });
64 -});
65 -
66 -window.addEventListener("DOMContentLoaded", function () {
67 - "use strict";
68 - document.addEventListener("click", async function (e) {
69 - if (("" + document.getElementById("xwikicontent")?.contentEditable) == "true") {
70 - return;
71 - }
72 - const viewFile = e.target?.closest(".viewFileThumbnail");
73 - if (viewFile && viewFile.dataset.preview === 'true') {
74 - const popup = new XWiki.widgets.ModalPopup();
75 - popup.createDialog();
76 - popup.setContent("<span class='fa fa-spinner'></span>");
77 - popup.dialogBox.classList.add("viewFileModal");
78 - popup.dialogBox.style.top = "2.5vh";
79 - popup.dialogBox.style.width = "95vw";
80 - popup.dialogBox.style.height = "95vh";
81 - const a = e.target.closest('a');
82 - const downloadLink = document.createElement("a");
83 - downloadLink.download = true;
84 - downloadLink.textContent = a.textContent;
85 - downloadLink.className = "fa fa-download button button-primary viewFileModal-downloadLink";
86 - downloadLink.href = a.href;
87 - popup.dialogBox.insertBefore(downloadLink, popup.dialogBox.firstChild)
88 - popup.showDialog();
89 - e.preventDefault();
90 - const response = await fetch(XWiki.contextPath + "/wiki/" + XWiki.currentWiki + "/get/Confluence/Macros/ViewFileService?action=render&attachment=" + encodeURIComponent(viewFile.dataset.ref));
91 - popup.setContent(await response.text());
92 - const gallery = popup.dialogBox.querySelector(".gallery");
93 - if (gallery) {
94 - new XWiki.Gallery(gallery);
95 - }
96 - }
97 - });
98 -});
Use this extension
... ... @@ -1,1 +1,0 @@
1 -onDemand
Parse content
... ... @@ -1,1 +1,0 @@
1 -Yes
XWiki.StyleSheetExtension[0]
Caching policy
... ... @@ -1,1 +1,0 @@
1 -long
Code
... ... @@ -1,83 +1,0 @@
1 -.viewFileModal iframe, .viewFileModal .xdialog-content {
2 - height: calc(95vh - 5em);
3 -}
4 -
5 -.viewFileModal .xGallery, .viewFileFull .xGallery {
6 - height: 100%;
7 - width: 100%;
8 -}
9 -
10 -.viewFileModal .xdialog-content:before {
11 - clear: both;
12 -}
13 -
14 -.viewFileModal .xdialog-content {
15 - overflow: auto;
16 - margin:0 0.8em 0.8em 0.8em;
17 - width: calc(100% - 1.6em);
18 -}
19 -
20 -.viewFileContentThumb .modal-dialog {
21 - max-height: 90vh;
22 - width: 80%;
23 -}
24 -
25 -.viewFileContentThumb .modal-body {
26 - max-height: 80vh;
27 - overflow: auto;
28 -}
29 -
30 -.viewFileContentThumb.viewFilePresentation .modal-dialog {
31 - height: 90%;
32 - width: 90%;
33 - display: flex;
34 - flex-direction: column;
35 - align-items: center;
36 -}
37 -
38 -.viewFileThumbnailButton {
39 - display: inline-block;
40 - padding-right: 0.5ex;
41 -}
42 -
43 -.viewFileThumbnailCard, .viewFileFull {
44 - position: relative;
45 - width: 10rem !important;
46 - height: fit-content;
47 - min-height: 10rem !important;
48 - margin-bottom: 1rem !important;
49 -}
50 -
51 -span.viewFileThumbnailCard {
52 - display: inline-block;
53 -}
54 -
55 -.viewFileThumbnailCard a {
56 - display: flex;
57 - gap: 3px;
58 - flex-direction: column;
59 - text-align: center;
60 - width: 100%;
61 - min-height: inherit;
62 -}
63 -
64 -.viewFileThumbnailCard a .attachmentMimeType {
65 - flex: 1;
66 - display: flex;
67 - align-items: center;
68 - align-self: center;
69 - text-align: center;
70 - justify-content: center;
71 - width: 100%;
72 - border: 1px solid;
73 - border-radius: 1rem;
74 - min-height: 5em;
75 -}
76 -
77 -.viewFileModal-downloadLink {
78 - margin-left: 2px;
79 -}
80 -
81 -.viewFileName {
82 - overflow-wrap: break-word;
83 -}
Use this extension
... ... @@ -1,1 +1,0 @@
1 -onDemand
Name
... ... @@ -1,1 +1,0 @@
1 -viewFileCSS
Parse content
... ... @@ -1,1 +1,0 @@
1 -No
Content Type
... ... @@ -1,1 +1,0 @@
1 -CSS
XWiki.WikiMacroClass[0]
Cached
... ... @@ -1,0 +1,1 @@
1 +No
Asynchronous rendering
... ... @@ -1,0 +1,1 @@
1 +No
Macro code
... ... @@ -1,0 +1,36 @@
1 +{{velocity output="false"}}
2 +#macro (executeMacro)
3 + #set($hasPDFViewer = $xwiki.exists("XWiki.PDFViewerMacro"))
4 + #set($officeExtensions = [ 'ppt', 'pptx', 'odp', 'doc', 'docx', 'odt', 'xls', 'xlsx', 'ods' ])
5 + #set($unescapedFilename = $xcontext.macro.params.get('att--filename'))
6 + #if(!$unescapedFilename)
7 + #set($unescapedFilename = $xcontext.macro.params.get('name'))
8 + #end
9 + #set($extension = $unescapedFilename.substring($mathtool.add($unescapedFilename.lastIndexOf('.'), 1)).toLowerCase())
10 + #set($escapedFilename = $services.rendering.escape($unescapedFilename, $xwiki.currentContentSyntaxId))
11 + #if($extension == 'pdf' && $hasPDFViewer)
12 +
13 + {{pdfviewer file="$escapedFilename" /}}
14 + #elseif($officeExtensions.contains($extension))
15 +
16 + {{office reference="attach:$escapedFilename" /}}
17 + #elseif($doc.getAttachment($unescapedFilename))
18 + [[attach:$escapedFilename]]
19 + #end
20 +#end
21 +{{/velocity}}
22 +
23 +{{include reference="Licenses.Code.VelocityMacros"/}}
24 +
25 +{{velocity}}
26 +## We need to check if there is a valid license because the macro is registered even if the user doesn't have view right
27 +## on the macro definition page. See XWIKI-14828: Rendering macros defined in wiki pages are available to users that
28 +## don't have view right on those pages.
29 +#if ($services.licensing.licensor.hasLicensureForEntity($xcontext.macro.doc.documentReference))
30 + #executeMacro
31 +#else
32 + {{error}}
33 + #getMissingLicenseMessage('proMacros.extension.name')
34 + {{/error}}
35 +#end
36 +{{/velocity}}
Macro content availability
... ... @@ -1,0 +1,1 @@
1 +Optional
Macro description
... ... @@ -1,0 +1,1 @@
1 +Show files using PDF Viewer Macro or Office Viewer
Macro id
... ... @@ -1,0 +1,1 @@
1 +view-file
Macro name
... ... @@ -1,0 +1,1 @@
1 +View Files
Supports inline mode
... ... @@ -1,0 +1,1 @@
1 +No
Macro visibility
... ... @@ -1,0 +1,1 @@
1 +Current Wiki
XWiki.WikiMacroParameterClass[0]
Parameter mandatory
... ... @@ -1,0 +1,1 @@
1 +Yes
Parameter name
... ... @@ -1,0 +1,1 @@
1 +att--filename