Combining macros in confluence

Before each analyst there is a choice of representation and formation of information. Of course, I would like to choose an easier way, but this way does not always meet the reader’s expectations. In this article, I will share the problems that were solved as part of the formation and maintenance of real requirements. I hope my article will inspire you to use more advanced confluence tools.

Dynamic search on child pages

My project space contains over 800 pages of requirements. While using the standard confluence search, I ran into a problem. The fact is that the search is performed over the entire space and requires filtering for a narrower selection. Additionally, the search is performed by the content of the pages and the names of the downloaded files. This is not always convenient, especially if you need to search for pages in a specific area of ​​\u200b\u200bspace. As a result, the task was to implement a search only by the name of the pages.

For implementation it is necessary to define the scope of the search. For me it was a requirements section which contained pages in the following hierarchy:

Create an empty page anywhere in the space and add the “Display Child” macro:

Specify the parent page in the macro settings. This will be our search area. After saving, the page will display all child pages of each level of the hierarchy. Right-click on the page and select View Page Code. In the page code, we need to find and copy all links of child pages into html. Since there is a lot of code on the page, you can use the search by the name of one of the pages. Links on the page are placed in one line and contain extra tags. With the help of html formatting tools (we use word to remove unnecessary tags in bulk), the code must be brought to the form:

  <a href="">Название страницы 1</a>
  <a href="">Название страницы 2</a>
  <a href="">Название страницы 3</a>

The second step is to create a page where our search will be placed. Adding a macro-frame “HTML” to the page:

This macro will execute the html code that we will place in the frame. Depending on your needs, you can place any auxiliary html elements on the form. We implement it as follows:

1) Place two drop-down lists (when you select a list value, the text is substituted in the search bar):

<! Выпадающий список с профилем пользователя>
  <form><select id="Ultra" style="font-size:18px;" onchange="run1()">
      <option value="">Профиль</option>
      <option value="Администратор">Администратор</option>
      <option value="Пользователь">Пользователь</option>
      <option value="Еще профиль">Еще профиль</option>
<! Выпадающий список с популярными активностями в названиях страниц. 
С помощью различных инструментов можно подсчитать количество популярных 
слов в наборе ссылок>
<select id="Ultra1" style="font-size:18px;" onchange="run1()">
        <option value="">Активность</option>
        <option value=" редактирует">редактирует</option>
        <option value=" получает">получает</option>
        <option value=" создает">создает</option>

2) Place the search field and the “clear” button:

<input style="font-size:18px" type="text" id="mySearch" onkeyup="myFunction()" placeholder="Введите значение" size="40">
<input type="button" value="очистить" onclick="resetForm(this);" style="font-size:15px">

3) Next, add the links from the first step:

<ul id="myMenu">
    <a href="">Название страницы 1 </a>
    <a href=""> Название страницы 2 </a>
    <a href=""> Название страницы 3 </a>

4) Add scripts for drop-down lists, search and the “clear” button:

  function run() {
    document.getElementById("mySearch").value = document.getElementById("Ultra").value + document.getElementById("Ultra1").value;
  function myFunction() {
    var input, filter, ul, li, a, i;
    input = document.getElementById("mySearch");
    filter = input.value.toUpperCase();
    ul = document.getElementById("myMenu");
    li = ul.getElementsByTagName("li");
    for (i = 0; i < li.length; i++) {
      a = li[i].getElementsByTagName("a")[0];
      if (a.innerHTML.toUpperCase().indexOf(filter) > -1) {
        li[i].style.display = "";
      } else {
        li[i].style.display = "none";

  function run1() {
  function resetForm(element) {

5) Save the page and use it.

6*) For a more aesthetic display of the page, you can place the html macro in the frame of the Aura Panel macro.

As a result, we have implemented the ability to perform a dynamic search in a given area of ​​space. I have no doubt that developers and testers will appreciate such a feature and read your most “understandable” requirements more often. The disadvantage of this approach is that when adding new pages, the set of links will need to be updated. But it will only take 10 minutes of your time.

Layered Forms

Often, an analyst needs to combine large amounts of hard-to-read data. To do this, Confluence provides a large set of macros. For example, using the Aura-Tab and Aura-Tab Group macros, you can create an object with tabs. Macros have flexible settings, but the problem lies in the one level of nesting of the created forms. As a result, the task was to implement multi-level nesting by combining macros.

Let’s understand how the Aura-Tab and Aura-Tab Group macros work. We need to place the Aura-Tab Group macro where the Aura-Tab macros will be placed. Each Aura-Tab is a tab for switching between content that you place in the macro frame. After saving, we will get single-level forms with content.

To add a second level of nesting, we need the UI Tab and UI Tabs macros. The principle of macros is the same as that of Aura.

Place the UI Tabs macro in the Aura-Tab macro frame. Place the required number of UI Tabs in the UI Tabs frame. Save and use.

By combining a group of macros, we managed to implement a two-level list of tabs. This method is great for describing complex objects.

Dynamic table join

When working with requirements, analysts use different ways of presenting information. One of the popular and affordable ways is a table view. Understanding this fact, confluence provides a large set of tools for working with tables. This time we will solve the problem of dynamically joining tables. Our task is to create a table that will combine several tables and provide up-to-date data.

Let’s say we have two tables that are populated by different people from different data sources.

To use a table, we need to place each table in the “Table Selection” macro frame. In the macro settings, you must specify a unique name for the selection.

Next, we create a page and add a Table Transformer table join macro.

We choose one of the three join methods, in our case it will be Lookup tables. We press the button insert.

In the macro frame we place two macros “Insert selection from the table”. In the selection settings, we refer to the unique name that we specified in the “Select from Table” macro.

In the macro frame we place two macros “Insert selection from the table”. In the selection settings, we refer to the unique name that we specified in the macro “Select from the table”.

We return to the settings of the Table Transformer macro. And we see that the macro independently determined the table join key (Passport).

Result after saving the page:

Thus, when the data in the source tables changes, the data in the merged table will be updated. Standard filtering functions are available for a joined table. Depending on the needs, custom joins are available. For example, you can write SELECT * FROM T1 OUTER JOIN T2 ON T1.’Passport’ = T2.’Passport’ and get the same result. T1 and T2 are the first and second tables in the macro frame, respectively. A great feature to save time when working with tables, the main thing is not to show your “custom selects” to sql developers.


This article describes only a part of the “unusual” macro associations. Do not forget about the flexibility and possibilities of confluence. Try creating something new in your sandbox. I hope this article will help in writing real requirements.

Similar Posts

Leave a Reply