General Actions:
Log-in
Register
Wiki:
games
▼
:
Document Index
»
Space:
XWiki
▼
:
Document Index
»
Page:
ConfigurableClassMacros
Search
en
Page Actions:
Export
▼
:
Export as PDF
Export as RTF
Export as HTML
More actions
▼
:
Print preview
View Source
Wiki Home
»
XWiki Space
»
Custom configurable sections
»
Macros for custom configurable sections
Wiki source code of
Macros for custom configurable sections
Last modified by
Administrator
on 2011/11/06 20:09
Content
·
Comments
(0)
·
Annotations
(0)
·
Attachments
(0)
·
History
·
Information
Hide line numbers
1: {{velocity output="false"}} 2: ## Constants: 3: #set($redirectParameter = 'xredirect') 4: #set($nameOfThisDocument = 'XWiki.ConfigurableClass') 5: 6: 7: #* 8: * Any documents which are on the provided list ($documentNames) which are locked by the current user will be unlocked. 9: * If this macro has programming rights, then they are unlocked programmatically, otherwise a javascript tag is 10: * generated with ajax calls to cancel for all of the documents. If there are documents on this list which are not 11: * locked by the current user, then they are ignored. 12: * 13: * @param $documentNames - List<String> - fullNames of documents which should be unlocked if they are locked by the 14: * current user. 15: *### 16: #macro(unlockDocuments $documentNames) 17: #if($documentNames.size() > 0) 18: #set($sql = "doc.fullName=") 19: #foreach($documentName in $documentNames) 20: #set($sql = "${sql}'$documentName' or doc.fullName=") 21: #end 22: ## Trim the dangling ' or doc.fullName=?' 23: #set($sql = $sql.substring(0, $sql.lastIndexOf(' or doc.fullName='))) 24: #set($sql = ", XWikiLock lock where lock.docId=doc.id and lock.userName='$xcontext.getUser()' and (${sql})") 25: #set($namesOfdocumentsToUnlock = $xwiki.searchDocuments($sql)) 26: ## Use ajax and hope the user runs javascript. 27: {{html}} 28: <script type="text/javascript"> 29: document.observe("dom:loaded", function() { 30: #foreach($nameOflockedDocument in $namesOfdocumentsToUnlock) 31: new Ajax.Request("$xwiki.getURL($nameOflockedDocument, 'cancel', 'ajax=1')"); 32: #end 33: }); 34: </script> 35: {{/html}} 36: #end## If output list size > 0 37: #end 38: 39: 40: #* 41: * Try to determine whether a document was edited by a user who has edit right on this page. This is tricky because 42: * documents are imported with the name XWiki.XWikiGuest who has no access to anything after import. 43: * 44: * @param theDoc - Document who's editor should be checked for edit access on this document. 45: *### 46: #macro(checkDocumentSavedByAuthorizedUser, $docToCheck, $currentDoc, $hasAccess) 47: ## The system is started and the only user is XWikiGuest who has admin right but gives it up when he imports the default 48: ## documents, we are checking to see if this looks like the guest imported the document with the first import. 49: #if($docToCheck.getWiki() == $xcontext.getMainWikiName() 50: && $docToCheck.getVersion() == '1.1' 51: && $docToCheck.getCreator() != $docToCheck.getContentAuthor() 52: && $docToCheck.getContentAuthor() == 'XWiki.XWikiGuest') 53: ## 54: #set($userToCheck = $docToCheck.getCreator()) 55: #else 56: #set($userToCheck = $docToCheck.getAuthor()) 57: #end 58: #set ($hasAccess = $util.null) 59: #setVariable ("$hasAccess" $xwiki.hasAccessLevel('edit', $userToCheck, $currentDoc)) 60: #end 61: 62: 63: #* 64: * Find names of documents which contain objects of the class 'XWiki.ConfigurableClass' 65: * 66: * @param $section - String - Look for apps which specify that they should be configured in this section, 67: * if null or "" then returns them for all sections. 68: * 69: * @param $globaladmin - boolean - If true then we will look for applications which should be configured globally. 70: * 71: * @param $space - String - If not looking for apps which are configured globally, then this is the space where we 72: * will look for apps in. If null or "" or if $globaladmin is true, then all spaces will be 73: * searched. 74: * 75: * @param $outputList - List - The returns from this macro will be put in this list, passing the list as a parameter 76: * a safety measure because macros can't return values. 77: *### 78: #macro(findNamesOfAppsToConfigure, $section, $globaladmin, $space, $outputList) 79: ## Use a parameterized sql query to prevent injection. 80: #set($params = []) 81: #if($section && $section != '') 82: #set($discard = $params.add("$section")) 83: #set($sqlA = ' StringProperty as section,') 84: #set($sqlB = " and section.id=obj.id and section.name='displayInSection' and section.value=?") 85: #else 86: ## Make sure they are "" in case they were set prior to calling the macro. 87: #set($sqlA = '') 88: #set($sqlB = '') 89: #end 90: ## Set up query based on value of $globaladmin 91: #if($globaladmin == true) 92: #set($sqlC = '1') 93: #else 94: #if($space && $space != '') 95: #set($sqlC = '0 and doc.space = ?') 96: #set($discard = $params.add($space)) 97: #else 98: #set($sqlC = '0') 99: #end 100: #end 101: #set($sql = ", BaseObject as obj,$sqlA IntegerProperty as global where " 102: + "doc.fullName=obj.name and obj.className='" + $nameOfThisDocument + "'$sqlB " 103: + "and global.id=obj.id and global.name='configureGlobally' and global.value=$sqlC " 104: + "order by doc.creationDate") 105: ## 106: ## Run the search 107: #set($discard = $outputList.addAll($xwiki.searchDocuments($sql, 0, 0, $params))) 108: ## 109: #end 110: 111: 112: #macro(findCustomSectionsToConfigure $adminMenu) 113: #set ($outputList = []) 114: #set ($global = ($editor == 'globaladmin')) 115: #findNamesOfAppsToConfigure('', $global, $currentSpace, $outputList) 116: #set ($sectionsByName = {}) 117: #set ($categoriesByName = {}) 118: #foreach ($category in $adminMenu) 119: #set ($discard = $categoriesByName.put($category.id, $category)) 120: #foreach ($section in $category.children) 121: #set ($discard = $sectionsByName.put($section.id, $section)) 122: #end 123: #end 124: ## 125: #set ($query = "editor=$escapetool.url(${editor})") 126: #if ($editor != 'globaladmin') 127: #set ($query = $query + "&space=$escapetool.url(${currentSpace})") 128: #end 129: #foreach ($appName in $outputList) 130: ## 131: ## Get the configurable application 132: #set ($app = $xwiki.getDocument($appName)) 133: ## 134: ## If getDocument returns null, then warn the user that they don't have view access to that application. 135: #if (!$app) 136: #set ($discard = $appsUserCannotView.add($appName)) 137: #end 138: ## 139: #foreach ($configurableObject in $app.getObjects($nameOfThisDocument)) 140: #set ($displayInSection = $app.getValue('displayInSection', $configurableObject)) 141: ## 142: ## If there is no section specified in the object, just skip it 143: #if ("$!{displayInSection}" == '') 144: ## Skip, bad object 145: ## If there is no section for this configurable or if the section cannot be edited, then check if the 146: ## application can be edited by the current user, if so then we display the icon from the current app and 147: ## don't display any message to tell the user they can't edit that section. 148: #elseif ($sectionsByName.containsKey($displayInSection)) 149: #set ($appSection = $sectionsByName.get($displayInSection)) 150: #set ($appSection.configurable = true) 151: #set ($newSection = false) 152: #else 153: ## 154: ## If there is no section for this configurable, then we will have to add one. 155: #set ($appSection = {'id' : $displayInSection, 'name' : $msg.get("admin.${displayInSection.toLowerCase()}"), 'url': $xwiki.getURL($currentDoc, $adminAction, "${query}&section=$escapetool.url(${displayInSection})"), 'configurable' : true}) 156: #if ($app.getValue('configureGlobally', $configurableObject) != 1) 157: #set ($appSection.perSpace = true) 158: #end 159: #set ($key = "admin.${displayInSection.toLowerCase()}.description") 160: #if ($msg.get($key) != $key) 161: #set ($appSection.description = $msg.get($key)) 162: #end 163: #set ($discard = $sectionsByName.put($displayInSection, $appSection)) 164: #set ($discard = $categoriesByName.get('applications').children.add($appSection)) 165: #set ($newSection = true) 166: #end 167: ## 168: ## If an attachment by the filename iconAttachment exists and is an image 169: #set ($attachment = $app.getAttachment("$!app.getValue('iconAttachment', $configurableObject)")) 170: #if ($attachment && $attachment.isImage()) 171: ## Set the icon for this section as the attachment URL. 172: #set ($appSection.iconReference = "${appName}@${attachment.getFilename()}") 173: #elseif(!$appSection.iconReference) 174: #set ($appSection.iconReference = 'XWiki.ConfigurableClass@DefaultAdminSectionIcon.png') 175: #end 176: ## 177: ## If the user doesn't have edit access to the application, we want to show a message on the icon 178: #if (!$xcontext.hasAccessLevel('edit', $app.getFullName()) && $newSection) 179: #set ($appSection.readOnly = true) 180: #elseif ($xcontext.hasAccessLevel('edit', $app.getFullName()) && $appSection.readOnly) 181: #set ($appSection.readOnly = false) 182: #end 183: #end## Foreach configurable object in this app. 184: #end## Foreach application which is configurable. 185: #end 186: 187: 188: #* 189: * Show the heading for configuration for a given application. 190: * 191: * $appName (String) Name of the application to show configuration heading for. 192: * 193: * $headingAlreadyShowing (boolean) If true then we don't make another heading. Otherwise it is set to true. 194: *### 195: #macro(showHeading, $appName, $headingAlreadyShowing) 196: #if(!$headingAlreadyShowing) 197: #set($headingAlreadyShowing = true) 198: 199: = $msg.get("admin.customize") __[[$appName>>$appName]]__: = 200: #end 201: #end 202: 203: #define($formHtml) 204: #if ($objClass.getPropertyNames().size() > 0) 205: <dl> 206: #foreach($propName in $objClass.getPropertyNames()) 207: #if($propertiesToShow.size() > 0 && !$propertiesToShow.contains($propName)) 208: ## Silently skip over this property. 209: #else 210: #set($prettyName = "#evaluate($app.displayPrettyName($propName, $obj))") 211: ## 212: ## Further processing of the field display HTML is needed. 213: ## Step 1: Strip <pre> tags which $obj.display inserts, this won't affect content because it's escaped. 214: #set($out = $obj.display($propName, 'edit').replaceAll('<[/]?+pre>', '')) 215: ## Step 2: Select only content between first < and last > because $obj.display inserts html macros. 216: ## Careful not to remove html macros from the content because they are not escaped! 217: #set ($out = $out.substring($out.indexOf('<'), $mathtool.add(1, $out.lastIndexOf('>')))) 218: ## Step 3: Prepend app name to all ID and FOR attributes to prevent id collision with multiple apps on one page. 219: #set ($out = $out.replaceAll( 220: " id='$objClass.getName()_$obj.getNumber()_$propName", " id='${escapedAppName}_$objClass.getName()_$obj.getNumber()_$propName").replaceAll( 221: " for='$objClass.getName()_$obj.getNumber()_$propName", " for='${escapedAppName}_$objClass.getName()_$obj.getNumber()_$propName")) 222: ## App Name is prepended to for= to make label work with id which is modified to prevent collisions. 223: <dt><label for="${escapedAppName}_$objClass.getName()_$obj.getNumber()_$propName"> 224: #if ($out.indexOf('type=''checkbox''') != -1) 225: $out 226: #end 227: $escapetool.xml($prettyName) 228: </label> 229: #if($linkPrefix != '') 230: #set($linkScript = "$linkPrefix$propName") 231: <a href="$escapetool.xml("#evaluate($linkScript)")" class="xHelp" title="$msg.get('admin.documentation')">$msg.get('admin.documentation')</a> 232: #end 233: </dt> 234: #if ($out.indexOf('type=''checkbox''') == -1) 235: <dd>$out</dd> 236: #end 237: #end## If property is in propertiesToShow 238: #end## Foreach property in this class 239: </dl> 240: #end 241: #end## define $formHtml 242: {{/velocity}}