Error formatting macro: include: com.atlassian.confluence.core.service.NotAuthorizedException: User 'null' does not have permission to view the page.

На моем сайте сложилась ситуация, когда одинаковых по функционалу, но разных по содержанию страниц скопилось огромное количество.

Представьте себе сайт компании из сотни отделов, где каждый отдел имеет свою страницу. Страницы абсолютно одинаковые по сути - на каждой есть по 4 блока - новости, список сотрудников, информация об отделе и доска объявлений. Если прописывать разметку каждой такой страницы в ней самой - это сулит несколько проблем:

- Большие затраты времени при внесении изменений в схему разметки. Появление нового блока информации, который должен стоять на каждой странице, или изменение параметров вывода новостей - это куча убитого времени на копирование разметки из страницы в страницу. К тому же, из-за рутинности действа, что-то можно скопировать криво.

- Проверка разметки каждой страницы - еще то удовольствие. 

- Если пользователь может зайти в разметку, а такие права у него обычно есть, то ничто не может помешать ему случайно поломать код.

Использование глобальных макросов спасает от всех проблем разом. Достаточно создать пользовательский макрос - у меня он не имеет тела и генерирует wiki-разметку - и вставить его во все нужные страницы. Сложность макроса зависит от содержания страницы и ее функционала. Пример из жизни:

#set($space=$space.getKey())
#set($staff="staff_"$space".doc")

{section}
{column:width=40%}
Список сотрудников
{viewdoc:name=$staff}
{column}
{column:width=30%}
Новости отдела
{blog-list:label=$paramlabels|space=@all|count=10|permalink=|date=true|none=Пока без новостей|postedByCaption=Опубликовал(а): }
{column}
{column:width=30%}
Объявления
{include:Объявления}
{compound-menuitem:edit|page=Объявления|caption=Редактировать|class=onlyForEditor}
----
Каталог страниц
{pagetree}
{column}
{section}

В первой колонке отображается вордовский документ, который должен называться staff_ключ пространства.doc В отделе маркетинга, к примеру, во вложениях должен лежать файл staff_marketing.doc (там находится список сотрудников, который надо отображать на странице). Ключ пространства - очень удобная вещь для различных операций в макросах, поэтому еще при создании пространства важно грамотно указывать его ключ. Выражение для получения ключа указано в первой строчке макроса. За ним идет простое указание переменной.

Во второй колонке стоит макрос новостей. Заметьте, что метки указываются не напрямую, а через переменную $paramlabels. При вставке макроса на страницу можно (но не обязательно) перечислить прямо в нем метки новостей, которые нужно отображать. Если назвать макрс global, то вся конструкция будет выглядеть так: 

{global:labels=main,moscow}

Если бы переменная называлась $parammetki, то нужно было бы писать так: 

{global:metki=main,moscow}

В третьей колонке при помощи макроса "include" транслируется содержание страницы "Объявления", являющейся потомком страницы с макросом. Т.е. предполагается, что каждая страница с макросом будет иметь такого потомка. Вдобавок, потребовалось сделать кнопку редактирования объявлений прямо на странице с макросом. Это было реализовано благодаря макросу "compound-menuitem". В нем указывается тип действия (edit), над какой страницей (page), текст кнопки (caption), а также CSS класс. Здесь класс был использован, чтобы спрятать кнопку редактирования от тех, у кого нет на это прав. Для красоты.

Далее идет отображение каталога страниц-потомков "pagetree".

В итоге получаем железобетонную конструкцию, с помощью которой можно легко управлять разметкой любого количества страниц. Одинаковых по функционалу, но разных по содержанию.

4 Comments

  1. Миш, но ведь этот способ не решает проблему:

    Если пользователь может зайти в разметку, а такие права у него обычно есть, то ничто не может помешать ему случайно поломать код.

    Ведь пользователь так же может зайти в разметку и удалить пользовательский макрос. Или я не прав?

  2. Да, удалить все из разметки на конкретной странице можно, но сам по себе макрос не пострадает. Восстановить прежний вид страницы можно очень быстро.

    1. ага понял, но в любом случае ничего не пострадает - т.к. восстановить можно любую версию страницы (smile)