#macro (iconSpan $type $text $additionalClasses) ## Defensive copy. Otherwise, depending what gets passed, we could be calling setters (and data could end in the database) because Velocity #set ($iconType = $type) #if ($iconType == "page") #set ($iconType = "page-default") #elseif ($iconType == "blogpost") #set ($iconType = "page-blogpost") #end $!text #end #macro (contentIcon $content) #contentIconWithLinkPrefix($content $staticResourceUrlPrefix) #end #macro (contentIconWithLinkPrefix $content $prefix) #if ($content.type == "attachment")#set ($attachment = $content)#parse ("/pages/includes/attachment_icon.vm") #elseif ($content.type == "trackback")$action.getText("track.back"): #else$action.getText($contentUiSupport.getContentTypeI18NKey($content)):#end #end ## This is duplicated in icons.soy. If you change this you should probably change that too. #macro (contentIcon2 $content $linkColor $linkHref $linkTitle) #if ($content.type == "attachment")#set ($attachment = $content)#parse ("/pages/includes/attachment_icon.vm") #elseif ($content.type == "trackback")$action.getText("track.back"): #else$action.getText($contentUiSupport.getContentTypeI18NKey($content)):#end #end #macro (typeIcon $type) #if ($type == "attachment") #elseif ($type == "all") #else #end #end ## deprecated since 4.0 - icons should conform to the icon sprite pattern and use #iconSpan instead #macro (icon $imageName $size $title)#end #macro (contentHref $content) #contentHrefWithLinkPrefix($content $req.contextPath) #end #macro (contentHrefWithLinkPrefix $content $prefix) #if ($content.type == "attachment") $webwork.htmlEncode($content.container.displayTitle) > $webwork.htmlEncode($content.displayTitle) #elseif ($content.type == "comment") $webwork.htmlEncode($content.container.displayTitle) > $webwork.htmlEncode($content.displayTitle) #else $webwork.htmlEncode($content.displayTitle) #end #end #macro (contentOther $content) #if ($content.type == "page" || $content.type == "blogpost") #if ($content.originalVersion) v. $content.version ($webwork.htmlEncode($content.originalVersion.space.name)) #else ($webwork.htmlEncode($content.space.name)) #end #elseif ($content.type == "comment") ($webwork.htmlEncode($content.container.space.name)) #elseif ($content.type == "userinfo") ($content.username) #elseif ($content.type == "status") (#fullNameOrAnonymous($content.creator)) ## If the attachment is attached to a profile, the container text is different (CONF-4465) #elseif ($content.type == "attachment" && $content.container.type == "userinfo") ($content.container.username) #elseif ($content.type == "attachment") ($webwork.htmlEncode($content.container.space.name)) #end #end #macro (contentLink2 $content $showIcon $showSpace) #contentLink2WithLinkPrefix($content $showIcon $showSpace $req.contextPath) #end #macro (contentLink2WithLinkPrefix $content $showIcon $showSpace $baseUrl) #if ($showIcon) #contentIconWithLinkPrefix($content $staticResourceUrlPrefix) #end #contentHrefWithLinkPrefix($content $baseUrl) #if ($showSpace) #contentOther($content) #end #end #macro (contentLink $content) #contentLink2($content true true) #end #macro (contentLinkWithLinkPrefix $content $prefix) #contentLink2WithLinkPrefix($content true false $prefix) #end #macro (contentLinkWithAnchor $content $anchor) #contentIcon($content) $webwork.htmlEncode($content.displayTitle) #end #macro (includePage $spaceKey $pageTitle) #if ($renderBean.pageExists($spaceKey, $pageTitle)) #if ($permissionHelper.canViewPage($action.authenticatedUser, $spaceKey, $pageTitle)) $renderBean.render($spaceKey, $pageTitle) #else $action.getText('insufficient.privelages.to.view.page') #end #else $action.getText('page.not.found.error') #end #end #macro (includePageWithId $pageId) #if ($renderBean.pageExists($pageId)) #if ($permissionHelper.canViewPage($action.authenticatedUser, $pageId)) $renderBean.render($pageId) #else $action.getText('insufficient.privelages.to.view.page') #end #else $action.getText('page.not.found.error') #end #end ## Generates the URL to a user. Any updates to this macro should also be applied to ## the Confluence.Templates.User.userLinkUrl soy template. #macro (userLinkUrl $baseUrl $username) $baseUrl/display/~$htmlUtil.urlEncode($username) #end #macro (userLinkUrlPrefix $baseUrl) $baseUrl/display/~ #end #* Link to a user. If the user doesn't exist, "Anonymous" is printed *# #macro (userLink $user) #trim() #if ($user && $user != "") #if ($userHelper.isUnknownUser($user)) $htmlUtil.htmlEncode($user.fullName) #elseif ($user.fullName) $htmlUtil.htmlEncode($user.fullName) #else $htmlUtil.htmlEncode($user.name) #end #else $action.getText('anonymous.name') #end #end #end #macro (userLinkWithCustomBaseUrl $user $baseurl) #if ($user) #if ($stringUtils.isNotBlank($user.fullName)) $htmlUtil.htmlEncode($user.fullName) #else $htmlUtil.htmlEncode($user.name) #end #else $action.getText('anonymous.name') #end #end #macro (userLinkParentWindow $user) #if ($user) $htmlUtil.htmlEncode($user.fullName) #else $action.getText('anonymous.name') #end #end #macro (emailUserLink $user $baseurl) #if ($user) $htmlUtil.htmlEncode($user.fullName) #else $action.getText('anonymous.name') #end #end #macro (userNonLink $username) #trim() #fullNameOrAnonymous ($action.getUserByName($username)) #end #end ## This macro is duplicated in user.soy as #fullNameOrAnonymous #macro (fullNameOrAnonymous $user)#if ($user && $user.fullName)$user.fullName#else$action.getText('anonymous.name')#end#end #macro (siteTitle)$settingsManager.globalSettings.siteTitle#end #macro (paginationBase $paginationSupport $actionContext $showTotal) #requireResource("confluence.web.resources:pagination-styles") #requireResource("com.atlassian.auiplugin:aui-navigation") #set ($numberToShow = 7) #set ($previousIndexes = $paginationSupport.previousStartIndexes) #set ($nextIndexes = $paginationSupport.nextStartIndexes) #if( $paginationSupport.total > 0 ) #set ($startIndex = $paginationSupport.startIndex + 1) #if ($showTotal) #set ($endPageNumber = $paginationSupport.total / $paginationSupport.pageSize) #if( $paginationSupport.total % $paginationSupport.pageSize != 0) #set ($endPageNumber = $endPageNumber + 1) #end #set ($endIndex = $endPageNumber * $paginationSupport.pageSize) #set ($endIndex = $endIndex - $paginationSupport.pageSize) #end #end
    #if( $previousIndexes || $nextIndexes ) #if($previousIndexes) #set ($startPageNumber = $generalUtil.arraySize($previousIndexes) - $numberToShow + 1)
  1. $action.getText('aui.prev.name')
  2. #else
  3. $action.getText('aui.prev.name')
  4. #end #set ($currentIndex = 1) #if ($previousIndexes && $startPageNumber > 0)
  5. $currentIndex
  6. #if ($startPageNumber > 1)
  7. #end #end #if( $previousIndexes ) #foreach( $index in $previousIndexes ) #if ($velocityCount > $startPageNumber)
  8. $currentIndex
  9. #end #set ($currentIndex = $currentIndex + 1) #end #end
  10. $currentIndex
  11. #if( $nextIndexes ) #set ($lastNumberShown = $currentIndex) #foreach( $index in $nextIndexes ) #set ($currentIndex = $currentIndex + 1) #if ($velocityCount < $numberToShow)
  12. $currentIndex
  13. #set ($lastNumberShown = $lastNumberShown + 1) #elseif (!$showTotal && $velocityCount == $numberToShow)
  14. #end #end #if ($showTotal && $lastNumberShown < $endPageNumber) #if ($lastNumberShown < $endPageNumber - 1)
  15. #end
  16. $endPageNumber
  17. #end
  18. $action.getText('aui.next.name')
  19. #else
  20. $action.getText('aui.next.name')
  21. #end #end
#end #* Prints the search result pagination info. *# #macro(pagination $paginationSupport $actionContext) #paginationBase($paginationSupport $actionContext true) #end #* Prints the search result pagination info. for a pager object (i.e. with total size unknown). *# #macro(entityPagination $paginationSupport $actionContext) #paginationBase($paginationSupport $actionContext false) #end #* Prints the breadcrumbs *# #macro(breadcrumbs) $!sitemeshPage.getProperty("page.breadcrumbs") #end #macro (colourRow $name $colour $isDefault) $action.getText($name)
 
#if($isDefault)<$action.getText('default')>#else$colour#end #end #macro (trackbackRdf $identifier $title $ping) #end #macro (onoff $test) #if ($test) $action.getText('on.name') #else $action.getText('off.name') #end #end #macro (yesno $test) #if ($test) $action.getText('yes.name.caps') #else $action.getText('no.name.caps') #end #end ## Expects a javascript function as a variable which can be excecuted in this script. #macro (fielderrorExecuteFunction $fieldname $javascriptFunctionHtml) #set ($fieldErrors = $action.fieldErrors) #if ($fieldErrors) #if ($fieldErrors.get($fieldname)) #foreach ($error in $fieldErrors.get($fieldname)) #set( $message = $action.getText(${error}) ) #if( !$message || $message == "" ) #set( $message = $action.getText(${error}) ) #end #set( $contentHtml = " $message") $soyTemplateRendererHelper.getRenderedTemplateHtml("com.atlassian.auiplugin:aui-experimental-soy-templates", "aui.message.error.soy", {"content" : $contentHtml}) #end #end #end #end #macro (fielderror $fieldname) #set ($fieldErrors = $action.fieldErrors) #if ($fieldErrors) #if ($fieldErrors.get($fieldname)) #foreach ($error in $fieldErrors.get($fieldname)) $soyTemplateRendererHelper.getRenderedTemplateHtml("com.atlassian.auiplugin:aui-experimental-soy-templates", "aui.message.error.soy", {"content" : $error, "id" : "${fieldname}-error"}) #end #end #end #end #macro (fielderrorRow $fieldname) #set ($fieldErrors = $stack.findValue("fieldErrors")) #if ($fieldErrors) #if ($fieldErrors.get($fieldname)) #foreach ($error in $fieldErrors.get($fieldname)) $soyTemplateRendererHelper.getRenderedTemplateHtml("com.atlassian.auiplugin:aui-experimental-soy-templates", "aui.message.error.soy", {"content" : $error, "tagName" : "span"}) #end #end #end #end #macro(adminMacros_renderAdminBreadcrumbs) $!sitemeshPage.getProperty("page.breadcrumbs") #if(!$sitemeshPage.getProperty("page.breadcrumbs")) #end #end #* Sets up variables which are used to determine whether or not the help panel should be displayed. *# #macro(infoPanelInit) #if ($sitemeshPage.getProperty("meta.help-path")) #set ($helpPath = $sitemeshPage.getProperty("meta.help-path")) #end #if ($sitemeshPage.getProperty("page.help-content")) #set ($helpContent = $sitemeshPage.getProperty("page.help-content")) #end ## decide whether or not to include the right nav bar #if ($helpPath || $helpContent) #set ($helpAvailable = true) #end #if ($sitemeshPage.getProperty("meta.infopanel-width")) #set ($panelWidth = $sitemeshPage.getProperty("meta.infopanel-width")) #end #set ($infoPanelRequired = $helpAvailable) #end #* Sets up variables which are used to determine whether or not the help panel should be displayed, using the parameter object passed by the inline decorator directive: applyDecorator *# #macro(infoPanelInitFromParams) #if ($params.get("help-path")) #set ($helpPath = $params.get("help-path")) #end #if ($params.get("help-content")) #set ($helpContent = $params.get("help-content")) #end ## decide whether or not to include the right nav bar #if ($helpPath || $helpContent) #set ($helpAvailable = true) #end #if ($params.get("infopanel-width")) #set ($panelWidth = $params.get("infopanel-width")) #end #set ($infoPanelRequired = $helpAvailable) #end #* A header which will probably create a very ugly page but one suitable for when a user has to fix something urgently before Confluence will be in a good state e.g. renew license before upgrade tasks can run. *# #macro(fixonlyHeader) #if (!$sitemeshPage.getProperty("page.allowindex")) #end #if ($req.getAttribute("Confluence-Request-Time")) #end #favicon() #end ## deprecated since 2.8, parse header.vm instead #macro(standardHeaderWithStylesheetAction $stylesheetAction) #parse ("/decorators/includes/header.vm") #end ## deprecated since 2.8, parse header.vm instead #macro(standardHeader) #standardHeaderWithStylesheetAction("main") #end ## deprecated since 2.8, parse header.vm instead, setting stylesheetAction var to 'admin' #macro(standardHeaderForAdmin) #standardHeaderWithStylesheetAction("admin") #end #macro(javascripts) $!webResourceManager.getJsResources() $!webResourceManager.getThemeJsResources($!spaceKey) #end #macro(rssautodiscovery $rssDescriptor) #if($rssDescriptor) $action.rssDescriptor.atomHref #end #end #macro(displayGlobalMessages) #set ($messages = $messageManager.getMessages()) #if ($messages && $messages.size() > 0) #end #end #macro(infoPanel $incomingLinks $trackbacks $referrers $externalReferences)
#if ($helpAvailable) #requireResource("confluence.web.resources:help-content-resources")
$action.getText('help.tips')
#if ($helpContent) $sitemeshPage.getProperty("page.help-content") #else #parse ($helpPath) #end
#end
#end #macro (userList $users) #set($user = "") #foreach ($user in $users) #if ($velocityCount == $users.size()) #userLink ($user) #else #userLink($user), #end #set($user = "") #end #end #* Put this macro back in for backward compatability * Use the blogPostsCalendarWithArrows from now on (it puts the correct arrows links whereas this one doesn't see CONF-6779) *# #macro (blogPostsCalendar $cal) #set ( $weeks = ($cal.getDaysInMonth() + $cal.startingDayOfMonth)/7 ) #foreach ( $week in [0..$weeks] ) #foreach ($day in [1..7] ) #end #end
#if ($cal.lastPostInPreviousMonth) << #else   #end $cal.formatMonthYear() #if ($cal.firstPostInNextMonth) >> #else   #end
$action.getText('sunday.abbr') $action.getText('monday.abbr') $action.getText('tuesday.abbr') $action.getText('wednesday.abbr') $action.getText('thursday.abbr') $action.getText('friday.abbr') $action.getText('saturday.abbr')
#set ($date = $week * 7 + $day - $cal.startingDayOfMonth) #if ($date < 1 || $date > $cal.getDaysInMonth())   #elseif ($cal.getPostsForDay($date).size() == 0) $date #else #set ($thePost = $cal.getPostsForDay($date).get(0)) $date #end
#end #* Put this macro back in for backward compatability * Passes in the action and a flag to display the correct arrow links to blogs: * true = link to the next/prev DATE post, with blog post date displayed * false = link to the next/prev post, with blog post title displayed * Use blogPostsByMonth instead *# #macro (blogPostsCalendarWithDateLinks $action $datePostArrows) #set ($cal = $action.calendarForThisMonth) #set ( $weeks = ($cal.getDaysInMonth() + $cal.startingDayOfMonth)/7 ) #foreach ( $week in [0..$weeks] ) #foreach ($day in [1..7] ) #end #end
#if ($cal.lastPostInPreviousMonth) #else   #end $cal.formatMonthYear() #if ($cal.firstPostInNextMonth) #else   #end
$action.getText('sunday.abbr') $action.getText('monday.abbr') $action.getText('tuesday.abbr') $action.getText('wednesday.abbr') $action.getText('thursday.abbr') $action.getText('friday.abbr') $action.getText('saturday.abbr')
#set ($date = $week * 7 + $day - $cal.startingDayOfMonth) #if ($date < 1 || $date > $cal.getDaysInMonth())   #elseif ($cal.getPostsForDay($date).size() == 0) $date #else #set ($thePost = $cal.getPostsForDay($date).get(0)) $date #end

#if ($datePostArrows) #if ($action.nextDatePost || $action.previousDatePost) #if ($permissionHelper.canView($action.authenticatedUser, $action.nextDatePost) ) $action.dateFormatter.format($action.nextDatePost.creationDate)
#end #if ($permissionHelper.canView($action.authenticatedUser, $action.previousDatePost) ) $action.dateFormatter.format($action.previousDatePost.creationDate)
#end
#end #else #if ($action.nextPost || $action.previousPost) #if ($permissionHelper.canView($action.authenticatedUser, $action.nextDatePost) ) $action.nextPost.title
#end #if ($permissionHelper.canView($action.authenticatedUser, $action.previousDatePost) ) $action.previousPost.title
#end
#end #end #end #* Passes in the action * Displays blog posts for the month and arrows to the previous and next month * in which blog posts were created *# #macro (blogPostsByMonth $action) #set ($cal = $action.calendarForThisMonth) #set ($formatter = $action.getDateFormatter()) #if($action.isBlogPostsByDateAction()) #set ($monthview = true) #elseif ($action.isRecentBlogPosts()) #set ($recentview = true) #end #if ($monthview || $recentview)
#else
#end
#set($previousMonth = $cal.lastPostInPreviousMonth) #set($nextMonth = $cal.firstPostInNextMonth) #if ($previousMonth) << $previousMonth.getPostingMonth($formatter) $previousMonth.getPostingYear() #end #if ($nextMonth) $nextMonth.getPostingMonth($formatter) $nextMonth.getPostingYear() >> #end
#end #* Shows the older/newer arrows at the bottom of the blog page when viewing recent blogposts and blogpost in month *# #macro(showOlderNewerBlogNavigation $action) #end #macro (showPermissionsHeader)   $action.getText('all') $action.getText('perms.pages') $action.getText('perms.news') $action.getText('perms.attachments') $action.getText('perms.comments') $action.getText('perms.restrictions') $action.getText('perms.mail') $action.getText('perms.space')   $action.getText('perms.view') $action.getText('perms.removeown') $action.getText('perms.add') $action.getText('perms.remove') $action.getText('perms.add') $action.getText('perms.remove') $action.getText('perms.add') $action.getText('perms.remove') $action.getText('perms.add') $action.getText('perms.remove') $action.getText('perms.add.remove') $action.getText('perms.remove') $action.getText('perms.export') $action.getText('perms.admin') #end #* * shows header for a global permissions table *# #macro (showGlobalPermissionsHeader)     #if ($action.userStatusPluginEnabled) $i18n.getText("permissions.UPDATEUSERSTATUS") $i18n.getText("inline.dialog.help") #end $i18n.getText("permissions.PERSONALSPACE") $i18n.getText("inline.dialog.help") $i18n.getText("permissions.CREATESPACE") $i18n.getText("inline.dialog.help") $i18n.getText("permissions.ADMINISTRATECONFLUENCE") $i18n.getText("inline.dialog.help") $i18n.getText("permissions.SYSTEMADMINISTRATOR") $i18n.getText("inline.dialog.help") #end #* * Shows an info banner for the space permissions page, to indicate that JIRA Service Desk has enabled any user to view * the space, because it is linked as a knowledge base. *# #macro (anyUserCanViewSpaceInfoBanner $isUnlicensedGlobalPermissionEnabled $spaceKey)
#if ($isUnlicensedGlobalPermissionEnabled)

$i18n.getText("space.permissions.any.active.user.can.view.title")

$i18n.getText("space.permissions.any.active.user.can.view.desc") $i18n.getText("space.permissions.any.user.can.view.desc.end")

#else

$i18n.getText("space.permissions.any.licensed.user.can.view.title")

$i18n.getText("space.permissions.any.licensed.user.can.view.desc") $i18n.getText("space.permissions.any.user.can.view.desc.end")

#end
#end #* * Macro for getting the URL of a resource from within a themed decorator *# #macro (themeResource $resourcePath)$req.contextPath$req.getAttribute("theme.resource.path")$resourcePath#end #* * This macro is quite messy but is neater than simply copying and pasting the HTML three times on two different * screens to represent view and edit views of permissions for groups, users, and anonymous entities. * * Note - this macro renders form elements when in edit mode but you must wrap it in a form element yourself. * * $who: list containing the following symbols - "g" (group), "u" (user), "a" (anonymous), "e" (everyone). * Each symbol is a directive to print out symbolized information in the order in which the symbols are expressed. * Note - "e" is actually ["g", "u", "a"] * * $action: an object carry functionality to support calls for group, user, and anonymous permissions; for example * com.atlassian.confluence.security.actions.EditSpacePermissionsAction . * * $edit: string literal; if set to "true" it will output input boxes for each permission listing, otherwise it will * use a tick or cross image for read-only. *# #macro (showPermissions $who $action $edit ) #if ($who == ["e"]) #set ($who = ["g", "u", "a"]) #end
##TODO remove 'Mail' Permission from cloud #foreach( $entity in $who ) #set ($spacePermissionGroups = [ ["viewspace", "removeowncontent"], ["editspace", "setpagepermissions", "removepage"], ["editblog", "removeblog"], ["createattachment", "removeattachment"], ["comment", "removecomment"], ["removemail"], ["exportspace", "setspacepermissions"]]) #set ($spacePermissionGroups = [ ["viewspace", "removeowncontent"], ["editspace", "removepage"], ["editblog", "removeblog"], ["createattachment", "removeattachment"], ["comment", "removecomment"], ["setpagepermissions"], ["removemail"], ["exportspace", "setspacepermissions"]]) #if ($entity == "g") #set ($groupRows = $action.groupPermissionRows) #if (!$groupRows.empty) #showPermissionsHeader() #foreach ($groupRow in $groupRows) #permissionValues($groupRow $spacePermissionGroups "" $groupRow.groupName) #end #else #end #end #if ($entity == "u") #set ($userRows = $action.userPermissionRows) #if (!$userRows.empty) #showPermissionsHeader() #foreach ($userRow in $userRows) #permissionValues($userRow $spacePermissionGroups $userRow.getUsername() "") #end #else #end #end #if ($entity == "a") #showPermissionsHeader() #set ($anonymousRow = $action.anonymousPermissionRow) #permissionValues($anonymousRow $spacePermissionGroups "" "") #end
$htmlUtil.htmlEncode($groupRow.groupName) #if (!$groupRow.entityExists())
$action.getText("error.group.not.found") #elseif ($groupRow.caseInvalid)
$action.getText('error.permission.incorrect.case', [$htmlUtil.htmlEncode($groupRow.group.name)]) #end #checkboxSelector("g" $groupRow.groupName)
$action.getText('no.groups.have.access')
#if ($userRow.entityExists()) $htmlUtil.htmlEncode($userRow.user.fullName) #end ($htmlUtil.htmlEncode($userRow.username)) #if (!$userRow.entityExists())
$action.getText("error.user.not.found") #elseif ($userRow.caseInvalid)
$action.getText('error.permission.incorrect.case', [$htmlUtil.htmlEncode($userRow.user.name)]) #end #checkboxSelector("u" $userRow.userKey)
$action.getText('no.users.have.rights.to.this.space')
$action.getText('anonymous.name') #checkboxSelector("a" "anonymous")
#end #end #macro(permissionValues $row $spacePermissionGroups $username $groupname) #foreach ($permissionGroup in $spacePermissionGroups) #set($isFirstPermissionGroup = $velocityCount == 1) #foreach ($permission in $permissionGroup) #permissionValueCell($row $permission $isFirstPermissionGroup $username $groupname) #end #end #end #macro(permissionValueCell $row $permission $isFirstPermissionGroup $username $groupname) ## Don't show checkboxes for owners of personal spaces #if ($edit == "true" && !($action.getSpace().getType().toString() == "personal" && $username == $action.getSpace().getCreatorName()) ) #if ($row.isTypeAllowed($permission)) #else #end #else #if ($row.isTypeAllowed($permission)) #else #end #end #end #macro(checkboxSelector) #if ($edit == 'true') #end #end ## use this function in tr's to alternate the row colors when displaying a list of items. #macro (alternateRowColors) #if ($velocityCount % 2 == 0) class="rowAlternate" #end #end #macro (spaceTitleLink) #if ($sitemeshPage.getProperty("page.spacename")) #if ($sitemeshPage.getProperty("page.spacekey")) $sitemeshPage.getProperty("page.spacename") #else $sitemeshPage.getProperty("page.spacename") #end #else   #end #end #macro (pageTitleLink) #if ($sitemeshPage.getProperty("page.pageTitle")) $sitemeshPage.getProperty("page.pageTitle") #else $title #end #end #macro (quickSearch) #customQuickSearch("" true true []) #end #macro (customQuickSearch $prefix $accessKey $quickNavEnabled $searchOptions) #if (!$prefix || $prefix=="") #set($prefix = "") #else #set($prefix = "${prefix}-") #end #if (!$searchOptions) #set($searchOptions = []) #end #if ($accessKey==true) #set ($accessKey = $action.getTextStrict("quick.search.${prefix}accesskey")) #else #set($accessKey=false) #end #end #* Renders an edit link with image, for a blog. *# #macro (editBlogPostWithImageLink ) #set ($page = $helper.page) #if ($permissionHelper.canEdit($action.authenticatedUser, $page)) Edit #end #end #macro (renderChildren) #set ($page = $helper.page) #if ($helper.action.getPermittedChildren().size() > 0 && $page.latestVersion)
#if (!$helper.childrenShowing) #set ($extraHeaderClass="summary") #set ($linkTarget="$req.contextPath$generalUtil.customGetPageUrl($page)showChildren=true#children") #else #set ($linkTarget="$req.contextPath$generalUtil.customGetPageUrl($page)showChildren=false#children") #end
#if ($helper.childrenShowing) #foreach ($child in $helper.action.getPermittedChildren()) #contentLink2 ($child true false) ## space key after the link is redundant #end #end
#end #end #macro (renderComments) #applyDecorator("root") #decoratorParam("sitemeshPage" $sitemeshPage) #decoratorParam("page" $page) #decoratorParam("context" "sharedcomments") #end #end ## Deprecated sinse 3.0. Use onLoadAttr instead. #macro (onLoad) #if (!$textUtil.stringSet($sitemeshPage.getProperty("page.bodyOnLoad"))) #else #end #end #macro (onLoadAttr) #if ($textUtil.stringSet($sitemeshPage.getProperty("page.bodyOnLoad"))) onload="$sitemeshPage.getProperty('page.bodyOnLoad')" #end #end #macro (versionInfo) #if ($helper.historicalVersion)

$action.getText('viewing.old.version',["$req.contextPath$generalUtil.getPageUrl($page.originalVersion)"])

$action.getText('view.differences') #if ($permissionHelper.canEdit($action.authenticatedUser, $page)) $action.getText('restore.this.version.smalls') #end $action.getText('view.page.history.smalls')

#if ($action.hasPreviousVersion($page)) « $action.getText('view.previous.version') #end #if($helper.historicalVersion) $action.getText('viewing.current.version', ["$page.version"]) #end #if ($page.getOriginalVersionPage().id == $action.getPageIdOfVersionAfter($page)) $action.getText('view.current.version') » #elseif ($action.hasNextVersion($page)) $action.getText('view.next.version') » #end

#end #end #macro (versionComment) #if ($page.isVersionCommentAvailable())
$action.getText('comment.name'): $page.renderedVersionComment
#end #end #macro (versionCommentByPage $thePage) #if ($thePage.isVersionCommentAvailable())
$action.getText('comment.name'): $thePage.renderedVersionComment
#end #end ## Label links shown in the context of a space should take the user to a page that contains content for that space only ## to do this, we need to pull the space key either from the $helper or from the $action. ## The getUrlPath() method on label should be able to handle null/empty spacekeys. #macro (labelLinkUrl $label) #trim() #if($helper.spaceKey) $req.contextPath$label.getUrlPath($helper.spaceKey) #else $req.contextPath$label.getUrlPath($spaceKey) #end #end #end #* ----------------------------------------------- LOGO MACROS ----------------------------------------------- *# ## only returns the image url of the appropriate logo ## this method is deprecated. Use LogoBlock instead, it delegates to newer and more efficient macros. #macro (logo $spaceKeyOrUsername) #trim() ## Firstly, if it's a username, look for user profile picture #if ($textUtil.stringSet($spaceKeyOrUsername) && $spaceKeyOrUsername.startsWith("~")) ##This may still lead to bugs (VELOCITY-186) but for now I am leaving this unchanged. TODO examine this #set ($userProfilePicture = $userAccessor.getUserProfilePicture($spaceKeyOrUsername.substring(1))) #if ($userProfilePicture) $userProfilePicture.uriReference #else $staticResourceUrlPrefix/images/logo/confluence_48_white.png #end ## Otherwise, it's not a username, so let's check if the space has a set logo #elseif ($textUtil.stringSet($spaceKeyOrUsername) && $spaceManager.getSpace($spaceKeyOrUsername) && $attachmentManager.getAttachment($spaceManager.getSpace($spaceKeyOrUsername).description, $spaceKeyOrUsername)) $htmlUtil.htmlEncode("${req.contextPath}$attachmentManager.getAttachment($spaceManager.getSpace($spaceKeyOrUsername).description, $spaceKeyOrUsername).downloadPath") ## No space logo, let's look for a default space logo #elseif ($settingsManager.globalDescription && $attachmentManager.getAttachment($settingsManager.globalDescription,"global.logo")) #set($attachment=$attachmentManager.getAttachment($settingsManager.globalDescription,"global.logo")) $htmlUtil.htmlEncode("${req.contextPath}$attachment.downloadPath") ## No default space logo, let's use the default Confluence logo #else $staticResourceUrlPrefix/images/logo/confluence_48_white.png #end #end #end ## checks if space preferences to determine if the logo has been disabled, and then displays it. ## include href link just in case we want to customize this part based on some preference in the future (without breaking people's stuff again) #macro (logoBlock $spaceKeyOrUsername) #trim() #if ($textUtil.stringSet($spaceKeyOrUsername)) #if ($spaceKeyOrUsername.startsWith("~")) #userLogoBlock($userAccessor.getUserByName($spaceKeyOrUsername.substring(1))) #else #spaceLogoBlock($spaceKeyOrUsername) #end #else #defaultSpaceLogoBlock() #end #end #end ## private - use #logoBlock. #macro (spaceLogoBlock $spaceKey) #trim() #if ($settingsManager.getSpaceSettings($spaceKey).isDisableLogo()) ## render nothing #else #set ($spaceLogo=$spaceManager.getLogoForSpace($spaceKey)) #set ($spaceLogoBlock_space=$spaceManager.getSpace($spaceKey)) #set ($spaceLogoBlock_cssClass="logo") #if ($spaceLogo.isCustomLogo()) #set($spaceLogoBlock_cssClass="$spaceLogoBlock_cssClass space custom") #else #set($spaceLogoBlock_cssClass="$spaceLogoBlock_cssClass global") #if ($spaceLogo.isGlobalLogo()) #set($spaceLogoBlock_cssClass="$spaceLogoBlock_cssClass custom") #end #end #end #end #end ## NOTE: This is currently duplicated in user.soy and comments.soy. If you change one you will probably need to change the others. #macro (userLogoBlock $user) #trim() #set ($userProfilePicture = $userAccessor.getUserProfilePicture($user)) #set($canView = $permissionHelper.canView($action.authenticatedUser, $user)) ## if the user profile still has the default picture, AND the usericon getting displayed is the current user, THEN generate a link to set the profile picture #if ($userProfilePicture.isDefault() && "$action.authenticatedUser.name" == $user.name) #else ## otherwise, the default case is to display the logo, depending on permissions #if ($userProfilePicture.isAnonymousPicture()) #elseif (!$canView) ##anonymous users with user permission but without view profile permission should not see user logos or be linked to profiles #else #end #end #end #end ## private - use #logoBlock. #macro (defaultSpaceLogoBlock) #trim() #if ($settingsManager.getGlobalSettings().isDisableLogo()) #else #set ($defaultSpaceLogo=$spaceManager.getLogoForGlobalcontext()) #set ($completeDownloadPath=$htmlUtil.htmlEncode("$req.contextPath$defaultSpaceLogo.getDownloadPath()")) #if ($defaultSpaceLogo.isCustomLogo()) #else #end #end #end #end ## shows the user's profile picture if they have one, otherwise _shows nothing_ (not a Confluence logo like logoBlock) #macro (logoForUserIfExists $username) #userLogoBlockOtherwise("~$username" "") #end ## Render a user logo if not the default one, otherwise evaluate the provided expression. Assumes username starts with ~ #macro (userLogoBlockOtherwise $username $otherwiseHtml) #set ($noTildeUsername = $username.substring(1)) #set ($logoUser = $userAccessor.getUserByName($noTildeUsername)) #if (!$userAccessor.getUserProfilePicture($logoUser).default || $remoteUser == $logoUser) #userLogoBlock($logoUser) #else $otherwiseHtml #end #end #macro (logoForUserOrSpacer $username) #userLogoBlockOtherwise("~$username" "#profilePictureSpacer()") #end #macro (profilePictureSpacer) #end #* DEPRECATED *# #macro (addProfilePictureHint) #end #* DEPRECATED *# #macro (userLogo $username) #end #* ----------------------------------------------- SIMPLE LINK MACROS ----------------------------------------------- Store macros which render a one line link here. *# #macro (tinyLink ) $helper.domainName/x/$helper.tinyUrl #end ## src - path to js file _without_ context path #macro (includeJavascript $src) #if ($src && !$src.startsWith("/")) #set ($src = "/${src}") #end #if ($webResourceManager) #else #end #end ## Use this macro to request a Javascript or CSS plugin resource be added to the HTML header. ## This macro doesn't generate any actual markup. #macro (requireResource $resourceModuleKey) $!webResourceManager.requireResource($resourceModuleKey) #end ## Use this macro to request all Javascript or CSS plugin resources belonging to the given contextan ## added to the HTML header. This macro doesn't generate any actual markup. #macro (requireResourcesForContext $context) ## These explicit calls are because we can't define dependencies ## for our contexts. ## See: http://jira.atlassian.com/browse/CONF-13739 #requireResource("confluence.web.resources:ajs") $!webResourceManager.requireResourcesForContext($context) #end #macro (webPanelForLocation $location $context) #if (!$context) #set ($actualContext = {}) #else #set ($actualContext = $context) #end #foreach ($webPanel in $webInterfaceManager.getDisplayableWebPanels($location, $actualContext)) $!webPanel.getHtml($actualContext) #end #end ## use this macro to include javascript resources in plugins ## this macro appends a special prefix to the normal script URL (effectively enabling caching on the serving of this javascript) #macro (includePluginJavascript $pluginCompleteKey $scriptName) #if ($webResourceManager) #else #end #end #macro (node $p $idsToExpandAsList $openId) #if ($action.hasPermittedChildren($p)) #if($idsToExpandAsList.contains($p.id)) #else #end #else #end #if ($p.id == $openId) #contentLinkWithAnchor($p 'selectedPageInHierarchy') #else #contentLink2 ($p true false) #end
#if ($idsToExpandAsList.contains($p.id)) #end
#end #macro (permitSearchEngines) true #end #macro (searchResultContentLink $searchResult) #contentIcon($searchResult) #if ($searchResult.type == "attachment") $htmlUtil.htmlEncode($searchResult.displayTitle) #else $htmlUtil.htmlEncode($searchResult.displayTitle) #end #if ($searchResult.type == "page" || $searchResult.type == "blogpost") ($htmlUtil.htmlEncode($searchResult.spaceName)) #elseif ($searchResult.type == "attachment") ($htmlUtil.htmlEncode($searchResult.spaceName) > $htmlUtil.htmlEncode($searchResult.extraFields.containingContentDisplayTitle)) #elseif ($searchResult.type == "comment") ($htmlUtil.htmlEncode($searchResult.spaceName) > $htmlUtil.htmlEncode($searchResult.extraFields.containingPageDisplayTitle)) #end #end #macro (searchResult $searchResult $showExcerpts $queryString) ## ensure we check for null here to avoid trying to assign null (CONF-12141) #if ($searchResult.content) #set ($contentBody = $searchResult.content) #else #set ($contentBody = '') #end #searchResultContentLink($searchResult) #if ('true' == $showExcerpts && $stringUtils.isNotBlank($contentBody) && $stringUtils.isNotBlank($queryString)) #if ($searchResult.type != "attachment") #set ($summary = $generalUtil.makeSummary($contentBody, $queryString)) #elseif ($searchResult.type == "attachment" && $contentBody) #set ($summary = $generalUtil.makeSummary($contentBody, $queryString)) #elseif ($searchResult.type == "attachment" && $searchResult.comment) #set ($summary = $generalUtil.makeSummary($searchResult.comment, $queryString)) #end #if ($summary)
## this is all one one line so that fragments are concatenated properly without spaces #foreach ($fragment in $summary.fragments)#if ($fragment.isHighlight() == true)$htmlUtil.htmlEncode($fragment.toString())#else$htmlUtil.htmlEncode($fragment.toString())#end#end #end ## clear the summary after displaying it to avoid Velocity scope problems #set ($summary = '') #end
#if ($searchResult.type == 'attachment') #if ($searchResult.extraFields.attachmentTypeDescription) $searchResult.extraFields.attachmentTypeDescription - #end $searchResult.extraFields.attachmentReadableFileSize - #end $action.dateFormatter.format($searchResult.lastModificationDate) #if ($searchResult.type == 'attachment') - $action.getText('download.name') - $action.getText('all.attachments') #elseif ($searchResult.type == 'comment') - $action.getText('all.comments') #elseif ($searchResult.type == 'blogpost') - $action.getText('all.news') #elseif ($searchResult.type == 'mail') - $action.getText('all.mail') #end #if ($searchResult.hasLabels()) #set ($labels = $searchResult.getLabels($remoteUser)) #set ($max = 5) #if ($labels.size() > 0)
$action.getText('labels.name'): #set($remaining = $labels.size() - $max) #foreach($label in $labels)#if($velocityCount <= $max)#if($velocityCount > 1), #end $label#end#end #if($remaining > 0) ... $action.getText('search.x.more.labels', [$remaining]). #end #end #end #end #macro (commaDelimitedList $list) #foreach($item in $list)#if($velocityCount != 1), #end$!item#end #end #macro (doc $link $body) $body## comment after element eliminates extra whitespaces #end ## Renders a hint box with some helpful text inside. ## A documentation link is assumed to exist for the hint. ## The $hintKey will be used in conjunction with a prefix ## to look up the full i18n strings for the hint: ## - The hint text itself will be prefixed with "hint." ## - The documentation link url will be prefixed with "help." ## - The documentation link text will be prefixed with "more.about." #macro (hint $hintKey)
$i18n.getText("hint.$hintKey") #doc("help.$hintKey" $i18n.getText("more.about.$hintKey"))
#end #macro (addClassName $existingClass $newClass) #set ($existingClass = "$existingClass $newClass") #end #* DO NOT USE (since 5.7) - please use the templates in captcha.soy instead. *# #macro (captchaImage $captchaId) $deprecated.since("5.7") $generalUtil.escapeXml($i18n.getText( #end #macro (displayContentPermission $perm) #if ($perm.isUserPermission())  $perm.userName #else  $perm.groupName #end #end #macro (favicon) #end #macro(dashboard_renderGlobalActions $menuId $webSectionKeys) $deprecated.since("6.0") #set($webMenu = $webMenuManager.getMenu($menuId, $webSectionKeys, $action.webInterfaceContext)) ## don't display if there are no sections - only expect one section for this location #if(!$webMenu.isEmpty()) #foreach ($section in $webMenu.sections)
#foreach ($item in $section.items) #set ($itemRenderedUrl = '') #set ($itemRenderedUrl = $item.link.getDisplayableUrl($req, $action.webInterfaceContext)) #set ($itemLabel = $item.label.getDisplayableLabel($req, $action.webInterfaceContext)) #set ($itemClass = $item.styleClass) #set ($itemIcon = $item.icon) #set ($itemDescription = $item.description) #set ($itemIconUrl = $itemIcon.url.getDisplayableUrl($req, $action.webInterfaceContext)) #set ($itemTooltip = $item.tooltip.getDisplayableLabel($req, $action.webInterfaceContext)) #set ($linkId = $item.link.id) $itemLabel #end
#end #end #end ## Method to avoid encoding by Anti-XSS mode. This method is dangerous and should usually ## be avoided. #macro(unencoded $assumedHtml) #trim() $assumedHtml #end #end #macro(form_xsrfToken) #end #macro(url_xsrfToken) #trim() ${xsrfTokenGenerator.xsrfTokenName}=${xsrfTokenGenerator.generateToken($req)} #end #end #macro (showCacheStatistics $cacheStatistics, $expiredCountHeaderProperty) #if(!$expiredCountHeaderProperty) #set ($expiredCountHeaderProperty = "cache.expired") #end #if ($action.showDistributions) #end #foreach($cacheStatistic in $cacheStatistics) #if ($action.showDistributions || $cacheStatistic.hasContents()) #if ($action.showDistributions) #end #end #end
$action.getText("cache.name") $action.getText("cache.percentused") $action.getText("cache.effectiveness")$action.getText("cache.current.max.entries") $action.getText("cache.current.heap.size.mb") $action.getText("cache.hit") / $action.getText("cache.miss") / $action.getText("${expiredCountHeaderProperty}") $action.getText("cache.adjust.max.entries")$action.getText("cache.flush.entries")
$cacheStatistic.niceName ${cacheStatistic.usagePercent}% ${cacheStatistic.hitPercent}%$cacheStatistic.size / $cacheStatistic.maxSize $cacheStatistic.formattedSizeInMegabytes $cacheStatistic.hitCount / $cacheStatistic.missCount / $cacheStatistic.expiredCount
#form_xsrfToken()
$action.getText('flush.name')
$action.getText('flush.all')
#end #macro (sortLink $sortByLink $destination $label) #if ($sortBy == $sortByLink) $label #else $label #end #end ## Used with AJS.I18n.getText(key) in JavaScript #macro (jsI18n $key) #end ## Use this macro to request that a key-value pair be made available to AJS.Meta in JavaScript. ## This macro doesn't generate any markup in-place; it renders the pair when #renderMetadata is called in the header. ## Note that the 'Html' in $valHtml is used to avoid HTML-encoding the string. #macro (putMetadata $key $valHtml) #set ($val = "$!valHtml") #if (!$webResourceManager.putMetadata($key, $val)) #renderMetadatum($key, $val) #end #end ## This macro should be called once in the element to render all key-value pairs needed by AJS.Meta. ## The metadata content will be escaped for HTML attributes only - JS/HTML/URL-encoding is up to calling JS. #macro (renderMetadata) #set ($metadata = $webResourceManager.getMetadata()) #foreach($key in $metadata.keySet()) #renderMetadatum($key, $metadata.get($key)) #end #end ## Renders a single metadata key/value pair #macro (renderMetadatum $key $val) #end #macro (attr $name $value) #if($value) $name="$value" #end #end ## Assistive macros #macro (assistiveLegend $label) #bodytag ("Component" "label='$label'" "template='assistive.vm'" "theme='aui'") #param ("type" "legend") #end #end #macro (assistiveSkipLink $label $value) #bodytag ("Component" "label='$label'" "value='$value'" "template='assistive.vm'" "theme='aui'") #param ("type" "skip-link") #end #end #macro (assistiveLabel $label $value) #bodytag ("Component" "label='$label'" "value='$value'" "template='assistive.vm'" "theme='aui'") #param ("type" "label") #end #end ## Blank experience macros #macro (blankExperience $type $hasCreatePermission $textKey $noPermissionTextKey $buttonTextKey $buttonLink $textParams $noPermissionTextParams)
#if ($hasCreatePermission)

$i18n.getText($textKey, $textParams)

$i18n.getText($buttonTextKey) #else

$i18n.getText($noPermissionTextKey, $noPermissionTextParams)

#end
#end #macro (pageByline $page $dateFormatter $renderStatic) #* When we render the byline, there are 3 base scenarios that we handle: * Page was created but not modified * Page creator and last modifier are the same user * Page was created by one user and most recently modified by a different user The date string we use for each of these scenarios is either the friendly date format (the one used for comments) or the usual formatted date string if the last modification was more than 24 hours ago. *# #if ($page.isNew()) #set ($dateLink = "$!req.contextPath/pages/viewpreviousversions.action?pageId=$page.id") #else #set ($dateLink = "$!req.contextPath/pages/diffpagesbyversion.action?pageId=$page.id&selectedPageVersions=$page.previousVersion&selectedPageVersions=$page.version") #end #* Note: bunched up else statements are intentional, otherwise we get whitespace that messes up formatting ;) *# #if (!$renderStatic) #set ($authorWithHtml = "#if($page.creatorName) #userLink($page.creator)#else $i18n.getText('anonymous.name')#end") #set ($editorWithHtml = "#if($page.lastModifierName) #userLink($page.lastModifier)#else $i18n.getText('anonymous.name')#end") #else #set ($authorWithHtml = "#if($page.creatorName) $page.creator.fullName#else $i18n.getText('anonymous.name')#end") #set ($editorWithHtml = "#if($page.lastModifierName) $page.lastModifier.fullName#else $i18n.getText('anonymous.name')#end") #end #set ($authorWithHtml = "$authorWithHtml") #set ($editorWithHtml = "$editorWithHtml") #if ($generalUtil.isDateWithin24Hours($page.lastModificationDate) && !$renderStatic) #set ($i18nSuffix = ".ago") #set ($modifiedDate = $friendlyDateFormatterHelper.format($page.lastModificationDate)) #else #set ($i18nSuffix = ".on") #set ($modifiedDate = $dateFormatter.format( $page.lastModificationDate )) #end #set ($title = $i18n.getText("view.page.show.changes")) #if (!$renderStatic) #set ($modifiedDate = "$modifiedDate") #end #if ($page.isNew()) $i18n.getText("created.by$i18nSuffix", [$authorWithHtml, $modifiedDate]) #elseif ($page.creator == $page.lastModifier) $i18n.getText("created.and.modified.by$i18nSuffix", [$authorWithHtml, $modifiedDate]) #else $i18n.getText("created.by.modified.by$i18nSuffix", [$authorWithHtml, $editorWithHtml, $modifiedDate]) #end #end #macro (alertAnonymous) #if (!$action.authenticatedUser) #set ($isUserAuthenticated = false) #else #set ($isUserAuthenticated = true) #end $soyTemplateRendererHelper.getRenderedTemplateHtml("confluence.web.resources:shared-templates", "Confluence.Templates.Notifications.notLoggedIn.soy", {"isUserAuthenticated": $isUserAuthenticated, "isExternalUserManagementEnabled": $action.isExternalUserManagementEnabled(), "loginURL": $seraph.getLinkLoginURL($req)}) #end #macro (confluenceServerPerformanceSpan) #end #macro (flushResponse) #if($darkFeatures.isDarkFeatureEnabled('early.header.flush')) $generalUtil.flushResponse() #end #end #macro (httpStatsElapse $tag) $generalUtil.elapse($tag) #end