The open source wiki, GROWI has a plugin facility. It can be used to display your own data or to customise the display.
In this article, we introduce a calendar display plugin that we created as a GROWI plugin; it was a popular plugin on Pukiwiki, so we tried to imitate it.
Add the plugin.
To use it, please add it at Plugin
in the GROWI administration page, the URL is https://github.com/goofmint/growi-plugin-calendar
.
Usage.
To use, write $calendar
in the page. The calendar will be displayed where you write.
$calendar
Click on a date to create a new page with that date. This can be used for daily reports, diaries, etc.
Options.
Available options include.
Change the year and month to be displayed.
You can change the year and month displayed by specifying the month as the first argument and the year as the second argument.
$calendar(12,2021)
Changing the display language
The default is English, but you can change the display language with the lang
option. Japanese is ja
.
$calendar(lang=fr)
Changing the criteria for generating a page name when clicking on a date
By default, clicking on a date generates a page name YYYYY/MM/DD
. In other words, it is a hierarchical structure. You can change this.
$calendar(separator=-)
The above will generate pages like 2024-10-02
. If you do not like the hierarchical structure, use this.
Combinations of settings
The above options can be combined.
$calendar(12,2021,lang=fr,separator=-)
$calendar(12,2021,separator=-)
About the code
The code is goofmint/growi-plugin-calendar: GROWI plugin shows calendar
The code can be found at The two files to look at are.
About client-entry.tsx
The client-entry.tsx is the registration part of the plugin. The calendar plugin is registered as a Remark plugin.
const activate = (): void => {
if (growiFacade == null || growiFacade.markdownRenderer == null) {
return;
}
const { optionsGenerators } = growiFacade.markdownRenderer;
optionsGenerators.customGenerateViewOptions = (...args) => {
const options = optionsGenerators.generateViewOptions(...args);
options.remarkPlugins.push(plugin as any); // プラグイン登録
return options;
};
};
About src/calendar.ts
The calendar display uses Vanilla Calendar - Lightweight calendar on pure JavaScript. available in JavaScript.
import VanillaCalendar from ‘vanilla-calendar-pro’;.
import ‘vanilla-calendar-pro/build/vanilla-calendar.min.css’;
In the case of the Remark plugin, the entire drawing process is sent to the visit function, so only the part of this that displays the calendar is extracted.
export const plugin: Plugin = function() {
return (tree) => {
visit(tree, (node) => {
const n = node as unknown as GrowiNode;
try {
if (n.type === 'leafGrowiPluginDirective' && n.name === 'calendar') {
// process in here
}
} catch (e) {
n.type = 'html';
n.value = `<div style="color: red;">Error: ${(e as Error).message}</div>`;
}
});
});
};
Getting options.
Option data can be retrieved via node.attributes
.
const [month, year] = Object.keys(n.attributes);
const lang = n.attributes.lang || 'en';
const separator = n.attributes.separator || '/';
Then, once done, only the calendar tags are output.
n.type = 'html';
n.value = '<div id="calendar"></div>';
After the HTML is rendered and we see that #calendar
is there, we start the drawing process.
const id = setInterval(() => {
if (document.querySelector('#calendar') != null) {
// カレンダーオブジェクト作成
const cal = new VanillaCalendar('#calendar', {
settings: {
lang, // 表示言語
// 表示年月
selected: {
month: isNaN(month as unknown as number) ? new Date().getMonth() : parseInt(month) - 1,
year: isNaN(year as unknown as number) ? new Date().getFullYear() : parseInt(year),
},
},
actions: {
// 日付クリック時の処理
async clickDay(event, self) {
const page = self.selectedDates[0].replaceAll(/-/g, separator);
const path = await getPagePath();
location.href = `${path}${page}`;
},
},
});
// 表示
cal.init();
// 終了
clearInterval(id);
}
}, 100);
Processing when a date is clicked
When the date is clicked, the page information is retrieved and the page name is correctly retrieved.
const getPagePath = async() => {
if (location.pathname === '/') return '/';
const pageId = location.pathname.replace(/\//, '');
const res = await fetch(`/_api/v3/page?pageId=${pageId}`);
const json = await res.json();
const { path } = json.page;
return `${path}/`;
};
Summary.
The GROWI plugin gives you the freedom to extend your display. If there are missing functions, you can add more and more. By all means, customise your own wiki.
GROWI, the OSS development wiki tool | comfortable information sharing for all
Top comments (0)