Developing GROWI Plug-ins (Scripting)
Tags: growi, typescript, opensource
Published: 2024-06-19 06:26:59

---
title: Developing GROWI Plug-ins (Scripting)
published: true
description: 
tags: 
  - GROWI
  - TypeScript
  - OSS
cover_image: https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/197026/490254a2-7cd7-cf2a-b20f-a6a49e0b5803.png
# Use a ratio of 100:42 for best results.
# published_at: 2024-06-19 06:23 +0000
---

[GROWI](https://growi.org/en/), an open-source in-house wiki, has a plug-in feature. This feature allows you to display your own data or customize the display.

This article will explain the procedure for developing a GROWI plug-in. This is as much as we know, as we have not yet grasped the whole process, but please use it as a reference during development.

## Types of plug-ins

There are three types of GROWI plug-ins

- script
- theme
- template

This time, we will focus on scripts.

## Template

We have created a template that can be used to create plug-ins. This is the base template.

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

## About files to be edited

After downloading or forking the above repository, edit the following files.

### package.json

Describe the plugin information. Change `name` and `description`.

```js
{
	"name": "growi-plugin-script-template", // change this name
	"version": "1.0.0",.
	"description": "GROWI plugin template for script", // change this description
	// : omitted
}
```

#### Installing Dependent Libraries

After renaming, install the libraries required for plugin development. Use the `yarn` command.

```bash
$ yarn
```

### client-entry.tsx

This is the file that is loaded when the plugin is executed. It is where you describe the plugin process. The `options.components` contains the tag information, so you can change the plugin's default behavior.

```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)
      generateViewOptions: (path: string, options: Options, toc: Func) => ViewOptions, ViewOptions
    }, }
  }, }
}; }

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

  const { optionsGenerators } = growiFacade.markdownRenderer;

  optionsGenerators.customGenerateViewOptions = (. .args) => {
    const options = optionsGenerators.generateViewOptions(. .args);
    // extract the A tag
    const { a } = options.components;
    options.components.a = helloGROWI(a); // Overwrite the drawing content of the A tag
    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, deactivate, deactivate, deactivate
  deactivate, }
}; }
```

The following tags can be specified. When processing these tags, the plugin will override the process.

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

For example, to change the processing of the `a` tag, use the following

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

### src/Hello.tsx

This is the file with `helloGROWI` above. Feel free to change the name of this function. In the following case, no processing is done.

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

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

### src/Hello.css

CSS file. Feel free to change it.

## Preview

Change ``src/Demo.tsx`` to see the actual display.

```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>,.
);
```

Preview with the `vite` command or `yarn dev`.

```bash
$ yarn dev
```

Now you can see the demo display at `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)


## Build the plugin

You can build the plugin with `yarn build`.

```bash
$ yarn build
```

If the build succeeds, the plugin files will be output in the `dist` directory.

## Install the plugin

You can install the plugin from the GROWI administration page.

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


## Publish the plugin

When the plugin is ready, publish it on GitHub repository and add a `growi-plugin` topic. It will then appear in the GROWI plugin list.

[GROWI plugin | GROWI.org](https://growi.org/plugins)

## Summary

Developing a plugin for GROWI is not difficult if you use a template. Please customize your own GROWI!

[GROWI, the OSS development wiki tool | Comfortable information sharing for all](https://growi.org/en/)