GROWIプラグインを開発する（スクリプト編）

[オープンソースの社内WikiであるGROWI](https://growi.org/ja/)にはプラグイン機能が用意されています。自社のデータを表示したり、表示をカスタマイズするのに利用できます。

今回は、GROWIプラグインの開発手順について解説します。まだ全体を把握できていないので、分かっている範囲ですが、開発時の参考にしてください。

## プラグインの種類

GROWIのプラグインには、以下の3種類があります。

- script
- theme
- template

今回はスクリプト（script）を対象として紹介します。

## テンプレート

プラグイン作成に使えるテンプレートを作成しました。こちらをベースに解説します。

[goofmint/growi-plugin-script-template](https://github.com/goofmint/growi-plugin-script-template)

## 編集するファイルについて

上記リポジトリをダウンロード、またはフォークしたら、以下のファイルを編集します。

### package.json

プラグインの情報を記述します。 `name` と `description` を変更してください。

```js
{
	"name": "growi-plugin-script-template",  // この名前を変更
	"version": "1.0.0",
	"description": "GROWI plugin template for script", // この説明を変更
	// : 省略
}
```

#### 依存ライブラリのインストール

名前を変更したら、プラグインの開発に必要なライブラリをインストールします。 `yarn` コマンドで行ってください。

```bash
$ yarn
```

### client-entry.tsx

プラグイン実行時に読み込まれるファイルです。ここにプラグインの処理を記述します。 `options.components` にタグ情報が入ってくるので、そのデフォルトの動きを変更します。

```typescript
import config from './package.json';
import { helloGROWI } from './src/Hello';
import { Options, Func, ViewOptions } from './types/utils';

declare const growiFacade : {
  markdownRenderer?: {
    optionsGenerators: {
      customGenerateViewOptions: (path: string, options: Options, toc: Func) => ViewOptions,
      generateViewOptions: (path: string, options: Options, toc: Func) => ViewOptions,
    },
  },
};

const activate = (): void => {
  if (growiFacade == null || growiFacade.markdownRenderer == null) {
    return;
  }

  const { optionsGenerators } = growiFacade.markdownRenderer;

  optionsGenerators.customGenerateViewOptions = (...args) => {
    const options = optionsGenerators.generateViewOptions(...args);
    // Aタグを取り出す
    const { a } = options.components;
    options.components.a = helloGROWI(a); // Aタグの描画内容を上書き
    return options;
  };
};

const deactivate = (): void => {
};

// register activate
if ((window as any).pluginActivators == null) {
  (window as any).pluginActivators = {};
}
(window as any).pluginActivators[config.name] = {
  activate,
  deactivate,
};
```

指定できるタグは以下の通りです。これらのタグに対して処理を行う際に、プラグインで処理を上書きします。

- a
- code
- h1
- h2
- h3
- h4
- h5
- h6
- lsx
- ref
- refs
- refimg
- refsimg
- gallery
- drawio
- table
- mermaid
- attachment
- img

たとえば `a` タグの処理を変更する場合には、以下のように記述します。

```typescript
options.components.a = helloGROWI(a);
```

### src/Hello.tsx

上記 `helloGROWI` があるファイルです。この関数名は自由に変更してください。下記の場合、何も処理は行っていません。

```jsx
import './Hello.css';

export const helloGROWI = (Tag: React.FunctionComponent<any>): React.FunctionComponent<any> => {
  return ({ children, ...props }) => {
    return (
      <Tag {...props}>{children}</Tag>
    );
  };
};
```

### src/Hello.css

CSSファイルです。自由に変更してください。

## プレビュー

実際の表示を確認する際には、 `src/Demo.tsx` を変更してください。

```jsx
import React from 'react';

import ReactDOM from 'react-dom/client';

import { helloGROWI } from './Hello';

const href = 'https://growi.org/';

const HelloGROWI = helloGROWI(() => <a href={href}>Hello, GROWI</a>);

ReactDOM.createRoot(document.getElementById('root') as HTMLElement).render(
  <React.StrictMode>
    <HelloGROWI
      href={href}
    >Hello, GROWI</HelloGROWI>
  </React.StrictMode>,
);
```

プレビューは `vite` コマンド、または `yarn dev` で行います。

```bash
$ yarn dev
```

これで `http://localhost:5173/demo.html` にてデモ表示が確認できます。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/197026/8eb27f9c-4e10-321d-b7c9-9d45a3e8f4bd.png)


## プラグインのビルド

プラグインのビルドは `yarn build` で行います。

```bash
$ yarn build
```

ビルドが成功すると、 `dist` ディレクトリにプラグインのファイルが出力されます。

## プラグインのインストール

GROWIの管理画面から、プラグインをインストールできます。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/197026/490254a2-7cd7-cf2a-b20f-a6a49e0b5803.png)


## 公開する

プラグインができあがったら、GitHubリポジトリにて公開し、  `growi-plugin` トピックを付けてください。これで、GROWIのプラグイン一覧へ表示されます。

[GROWI プラグイン | GROWI.org](https://growi.org/plugins)

## まとめ

GROWIのプラグイン開発は、テンプレートを使えば難しくなく作成できます。ぜひ、自社のGROWIをカスタマイズしてください！

[OSS開発wikiツールのGROWI | 快適な情報共有を、全ての人へ](https://growi.org/ja/)