Confluence 既存のマクロを自作マクロに組み込む

前回、Confluenceでマクロを作成する際の基本について書きました。

[Confluenceのユーザーマクロ作成の基本](http://qiita.com/ymd_aaa/items/fd9c6ca15fc5bed22ab2)

とは言っても、既存のマクロがたくさんある中、新しいマクロを自作する機会なんてそうそうないようにも思うかもしれません。

しかし、実はそうでもありません。

その理由は自作マクロのなかに既存のマクロを使うことができるからです。

この仕組みを利用すれば、複数のパラメータを設定しなければならないようなマクロがぐっと使いやすくなったり、複数のマクロのコラボレーションも一発で呼び出すことができるようになります。

というわけで今回はその既存のマクロを自作マクロに組み込む方法を紹介します。

# コードブロックマクロを自作マクロに組み込む
## コードブロックマクロについて
コードブロックマクロは既存のマクロです。
コードを見やすくしてくれます。
<img width="478" alt="コードブロック編集.png" src="https://qiita-image-store.s3.amazonaws.com/0/149859/86acd897-9027-c60c-b2d9-4db5ea248f53.png">
こう使うと、

<img width="302" alt="コードブロック出力.png" src="https://qiita-image-store.s3.amazonaws.com/0/149859/fee15c10-dcbd-03be-e775-ebd164742e30.png">
こうなるマクロです。

ただ上のキャプチャーはテーマや言語等を設定しています。何も設定していない初期状態だと
<img width="338" alt="コードブロックデフォルト出力.png" src="https://qiita-image-store.s3.amazonaws.com/0/149859/8503e4e2-6224-9bdd-2346-fc2e56959434.png">
こんな感じでなんとも味気ないです。

テーマも言語もそうそう変えることがないならば、毎回選択し直すのは面倒だということで以下のようなマクロを作ってみました。

## HTML(xml)用コードブロックマクロ
**マクロ本体の処理**
レンダリングしない

```html:テンプレート
## @noparams
<ac:structured-macro ac:name="code">
  <ac:parameter ac:name="theme">Emacs</ac:parameter>
  <ac:parameter ac:name="linenumbers">true</ac:parameter>
  <ac:parameter ac:name="language">xml</ac:parameter>
  <ac:plain-text-body><![CDATA[$body]]></ac:plain-text-body>
</ac:structured-macro>
```

このマクロを以下のように使います

<img width="270" alt="HTMLコードブロック.png" src="https://qiita-image-store.s3.amazonaws.com/0/149859/e2e253cf-444f-f1f5-2e0e-56033dec1e5f.png">

すると、こうなります。
<img width="302" alt="コードブロック出力.png" src="https://qiita-image-store.s3.amazonaws.com/0/149859/548b2b74-b290-94d7-45ef-b67b09b057bd.png">

テーマや言語の入力が省略できました！

# テンプレート解説
解説ってほどでもないんですけど、
もともと存在するcodeって名前のマクロ（上で紹介したコードブロックマクロのことです）に、
パラメータtheme,linenumbers,languageを指定し、
plain-text-bodyにマクロのbodyを渡しているだけです。

確認したわけではないですが、おそらく全てのマクロがこんな感じで`ac:structured-macro`タグを利用して記述することができます。

# マクロ名とかパラメータはどこ見ればわかるの？
今回のようなマクロを作るのに一番重要なのは、既存のマクロの名前やパラメータってどうなってるの？ってことだと思います。

私の知る限り確認する方法は２つです。

## 【確認方法１】公式の情報を確認する
既存のマクロの情報はたぶん全て公式ページに載っています。
https://confluence.atlassian.com/conf58/macros-771892281.html

この中からカスタマイズしたいマクロのページを確認してください。

今回利用したのは[code block macro](https://confluence.atlassian.com/conf58/code-block-macro-771892301.html)です。
このページのStorage format exampleのところに以下のようなサンプルが書いてあります。

```html:
<ac:structured-macro ac:name="code">
  <ac:parameter ac:name="title">This is my title</ac:parameter>
  <ac:parameter ac:name="theme">FadeToGrey</ac:parameter>
  <ac:parameter ac:name="linenumbers">true</ac:parameter>
  <ac:parameter ac:name="language">xml</ac:parameter>
  <ac:parameter ac:name="firstline">0001</ac:parameter>
  <ac:parameter ac:name="collapse">true</ac:parameter>
  <ac:plain-text-body><![CDATA[<b>This is my code</b>></ac:plain-text-body>
</ac:structured-macro>
```
`![CDATA[`の閉じ括弧がなくてちょっと残念なサンプルですがこんな感じで確認できます。

もう一つの確認方法は自作マクロを用意して画面に表示させる方法があります。

## 【確認方法2】レンダリング前のテキストをマクロを使って出力させる
以下のようなマクロを作ってください

**マクロ本文の処理**
マクロ本文なし

```html:テンプレート
## @noparams
#set($page=$pageManager.getPage($renderContext.spaceKey,$renderContext.pageTitle))

<ac:structured-macro ac:name="code">
  <ac:parameter ac:name="title">レンダリング前のページ</ac:parameter>
  <ac:parameter ac:name="linenumbers">true</ac:parameter>
  <ac:parameter ac:name="language">xml</ac:parameter>
  <ac:plain-text-body><![CDATA[$page.bodyContent.body.replaceAll("\]\]","\\]\\]")]]></ac:plain-text-body>
</ac:structured-macro>
```
コードブロックマクロの中身にレンダリング前のページのテキストを当て込んでいます。

このマクロを構文を確認したいマクロが使われているページに貼ります。


今回はすでに中身を紹介しているコードブロックマクロの中身を調べてみようと思います。
<img width="601" alt="レンダリング前マクロ利用.png" src="https://qiita-image-store.s3.amazonaws.com/0/149859/7c62297e-dec7-87cf-24b2-6afeb421e1fd.png">


上記のようにしてページを確認すると、コードブロックが２つ表示されます。<img width="572" alt="レンダリング前マクロ結果.png" src="https://qiita-image-store.s3.amazonaws.com/0/149859/339cf504-ba63-395b-6e84-fed4fec654f0.png">
下の方のコードブロックにレンダリング前のテキストが表示されています。

ただ、残念なことに改行は全然入っていないので、自分で整形します。

```html:整形後
<ac:structured-macro ac:name="code" ac:schema-version="1" ac:macro-id="ランダムっぽい文字列">
	<ac:parameter ac:name="language">xml</ac:parameter>
	<ac:parameter ac:name="theme">Emacs</ac:parameter>
	<ac:parameter ac:name="title">コードブロック</ac:parameter>
	<ac:parameter ac:name="linenumbers">true</ac:parameter>
	<ac:plain-text-body>
		<![CDATA[
			<html>
			<body>
			<h>HTMLです</h>
			</body>
			</html>
		\]\]>
	</ac:plain-text-body>
</ac:structured-macro>
<p><ac:structured-macro ac:name="beforepage" ac:schema-version="1" ac:macro-id="ランダムっぽい文字列" /></p>
```

レンダリング前の”code”マクロが確認できました。
当たり前ですが公式に載っているサンプルと同じですね。
１つ注意するのは基本的に使用していないパラメータが表示されないということです。
なので、パラメータ名が知りたい項目があれば編集画面で何かしら値を入れておきましょう。

<img width="873" alt="コードブロックパラメータ編集.png" src="https://qiita-image-store.s3.amazonaws.com/0/149859/d2e347be-aa6c-79c0-0391-a96d908b5d6b.png">



## 解説漏れ：テンプレート内で使える変数
レンダリング前のテキスト確認用マクロにこんな一文があったと思います
`#set($page=$pageManager.getPage($renderContext.spaceKey,$renderContext.pageTitle))`
これは現在表示しているページの情報を取得する処理です。

`$pageManager`や`$renderContext`は`$body`と同様に最初から定義されている変数です。これら以外にも`$config`や`$space`といった変数もあるようです。

詳しくは公式の[テンプレート解説ページ](https://confluence.atlassian.com/conf58/user-macro-template-syntax-771892704.html)の「Objects available to your macro」に載っています。
ただ、ここには`$pageManager`が不思議なことにないんですよね。
多分どこかのQ&Aとかで見つけてきたと思うんですがリンクが残っていませんでした。。。

ちなみに上記テンプレート解説ページには変数の型も書いてあります。例えば`$renderContext`の型はPageContextと書いてあります。

これらの型の詳細についてはJavaDocが用意されています。（古いかもしれません）
https://developer.atlassian.com/static/javadoc/confluence/4.2.13/reference/index.html

`$renderContext`の型である[PageContextのJavaDoc](https://developer.atlassian.com/static/javadoc/confluence/4.2.13/reference/com/atlassian/confluence/renderer/PageContext.html)をみると、[getSpaceKey()](https://developer.atlassian.com/static/javadoc/confluence/4.2.13/reference/com/atlassian/confluence/renderer/PageContext.html#getSpaceKey())や[getPageTitle()](https://developer.atlassian.com/static/javadoc/confluence/4.2.13/reference/com/atlassian/confluence/renderer/PageContext.html#getPageTitle())が定義されているのがわかります。なので`$renderContext.spaceKey`や`$renderContext.pageTitle`が使えるということが判断できます。
他にも[PageManager](https://developer.atlassian.com/static/javadoc/confluence/4.2.13/reference/com/atlassian/confluence/pages/PageManager.html)や[Page](https://developer.atlassian.com/static/javadoc/confluence/4.2.13/reference/com/atlassian/confluence/pages/Page.html)、[ContentEntityObject](https://developer.atlassian.com/static/javadoc/confluence/4.2.13/reference/com/atlassian/confluence/core/ContentEntityObject.html)あたりの内容を今回は参考にしました。


# おわりに
今回は自作マクロ内で既存のマクロを使うことについて書きました。
次回はさらにこれを利用して、JIRAのリンク表示をカスタマイズする方法について書きたいなと思います。
※JIRAはConfluence同様Atlassian社が開発した課題管理ツールです。コンフルエンスと連携することができ、連携することでこんな感じでConfluence上でJIRAの課題のステータスが確認できるようになります。
<img width="331" alt="JIRA連携.png" src="https://qiita-image-store.s3.amazonaws.com/0/149859/7c61de36-9912-52b5-7841-334d45ed8e20.png">


# 参考
Macros - Atlassian Documentation
https://confluence.atlassian.com/conf58/macros-771892281.html

User Macro Template Syntax - Atlassian Documentation
https://confluence.atlassian.com/conf58/user-macro-template-syntax-771892704.html

Atlassian Confluence 4.2.13 API
https://developer.atlassian.com/static/javadoc/confluence/4.2.13/reference/index.html