Example: CQL Search Macro

A CQL Search macro allows you to enter Confluence Query Language (CQL). You can use the built-in CQL Search Macro macro for this, or you can create a custom macro that autofills the fields. 

Follow these steps to create a CQL Search macro that finds pages with Confluence in the title in the demonstration space.

  1. Select the Create Macro button on the Macro page. 

  2. Select Custom Script Macro.
  3. Set the following fields:

    • Key: cql-search

    • Name: CQL REST Search

    • Description: Runs a CQL search and displays matching pages

    • Body Type: Rich text

    • Output Type: Block

  4. Select the + Parameter button and set the following fields on the form that appears:
    • Parameter Type: string
    • Name: CQL
    • Label: CQL
    • Tick the checkbox for Required

      The Description and Default fields are not required here.


  5. Select the + Parameter button and set the following fields on the form that appears:
    • Parameter Type: int
    • Name: maxresults
    • Label: Max Results
    • Tick the checkbox for Required

      The Description and Default fields are not required here.

  6. Enter the following code in the Macro Code field: 
    import com.atlassian.confluence.api.model.Expansion
    import com.atlassian.confluence.api.model.content.Content
    import com.atlassian.confluence.api.model.pagination.PageResponse
    import com.atlassian.confluence.api.model.pagination.SimplePageRequest
    import com.atlassian.confluence.api.model.search.SearchContext
    import com.atlassian.confluence.api.service.search.CQLSearchService
    import com.atlassian.confluence.xhtml.api.XhtmlContent
    import com.onresolve.scriptrunner.runner.ScriptRunnerImpl
    import groovy.xml.MarkupBuilder
    
    def cqlSearchService = ScriptRunnerImpl.getOsgiService(CQLSearchService)
    def xhtmlContent = ScriptRunnerImpl.getOsgiService(XhtmlContent)
    def maxResults = parameters.maxResults as Integer ?: 10
    
    def cqlQuery = parameters.cql as String
    
    def pageRequest = new SimplePageRequest(0, maxResults)
    def searchResult = cqlSearchService.searchContent(cqlQuery, SearchContext.builder().build(), pageRequest, Expansion.combine("space")) as PageResponse<Content>
    
    def writer = new StringWriter()
    def builder = new MarkupBuilder(writer)
    
    if (searchResult.size()) {
        builder.table {
            tbody {
                tr {
                    th { p("Title") }
                    th { p("Space") }
                }
                searchResult.results.each { content ->
                    tr {
                        td {
                            p {
                                "ac:link" {
                                    "ri:page"("ri:content-title": content.title, "ri:space-key": content.space.key)
                                }
                            }
                        }
                        td { p(content.space.name) }
                    }
                }
            }
        }
    
        if (searchResult.respondsTo("totalSize")) { // confl 5.8+
            builder.p("Showing ${Math.min(maxResults, searchResult.totalSize())} of ${searchResult.totalSize()}")
        }
    } else {
        builder.p("No results")
    }
    
    def view = xhtmlContent.convertStorageToView(writer.toString(), context)
    view
  7. Skip the Macro Javascript CodeMacro CSS Style, and Lazy Loaded fields.
  8. Click Add.
  9. You can see your new macro when the Macro page loads.

    Now you can take all ordinary macro actions.

Result

When the macro is used on a page, it looks like the following image:

On this page