Skip to content

Commit

Permalink
docs: setup user manual
Browse files Browse the repository at this point in the history
  • Loading branch information
shigma committed Apr 13, 2022
1 parent 8a83424 commit 07d9305
Show file tree
Hide file tree
Showing 16 changed files with 121 additions and 91 deletions.
2 changes: 1 addition & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,7 @@ Koishi 是一个现代化跨平台机器人框架,目前可支持 [QQ](https:/
- 支持 QQ,Telegram,Discord 等主流聊天平台,支持多账户和跨平台数据互通
- 随时随地通过控制面板监控运行状态,控制机器人的行为,甚至上号聊天

参见:[模板项目](https://koishi.js.org/guide/introduction/template.html)
参见:[模板项目](https://koishi.js.org/manual/template.html)

### 功能强大的 API

Expand Down
23 changes: 15 additions & 8 deletions docs/.vuepress/config.js
Original file line number Diff line number Diff line change
Expand Up @@ -44,9 +44,14 @@ module.exports = {
text: 'v1.x',
link: 'https://koishi.js.org/v1/',
}],
}, {
text: '入门',
link: '/manual/',
activeMatch: '/manual/',
}, {
text: '指南',
link: '/guide/introduction/',
link: '/guide/message/middleware.md',
activeMatch: '/guide/',
}, {
text: 'API',
link: '/api/',
Expand All @@ -60,16 +65,18 @@ module.exports = {
}],

sidebar: {
'/guide/': [{
text: '入门',
'/manual/': [{
text: '起步',
isGroup: true,
children: [
'/guide/introduction/index.md',
'/guide/introduction/direct.md',
'/guide/introduction/template.md',
'/guide/introduction/development.md',
'/manual/index.md',
'/manual/direct.md',
'/manual/template.md',
'/manual/development.md',
],
}, {
}],

'/guide/': [{
text: '处理交互',
isGroup: true,
children: [
Expand Down
2 changes: 1 addition & 1 deletion docs/.vuepress/layouts/home/screen-1.vue
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@
MADE WITH <span class="koi">LOVE</span>
</p>
<div class="actions">
<router-link class="action-button primary" to="/guide/introduction/template">Get Started</router-link>
<router-link class="action-button primary" to="/manual/template">Get Started</router-link>
<a class="action-button secondary" @click="$emit('scroll-screen', 1)">Learn More</a>
</div>
<svg aria-hidden="true" focusable="false" role="img" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 320 512" class="w-10 h-10">
Expand Down
2 changes: 1 addition & 1 deletion docs/.vuepress/layouts/home/screen-2.vue
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@
<li>支持 QQ,Telegram,Discord 等主流聊天平台</li>
<li>随时随地通过控制面板监控运行状态,甚至上号聊天</li>
</ul>
<p>查看指南:<router-link to="/guide/introduction/template">创建 Koishi 模板项目</router-link></p>
<p>查看指南:<router-link to="/manual/template">创建 Koishi 模板项目</router-link></p>
</div>
<div class="image">
<carousel></carousel>
Expand Down
79 changes: 79 additions & 0 deletions docs/.vuepress/patchRedirect.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,79 @@
const target = require('@vuepress/core/lib/app/prepare/preparePagesRoutes');
const shared = require("@vuepress/shared");

target.preparePagesRoutes = async (app) => {
const content = `\
import { Vuepress } from '@vuepress/client/lib/components/Vuepress'
const routeItems = [\
${app.pages
.map(({ key, path, pathInferred, filePathRelative, routeMeta, frontmatter }) => {
const redirects = [];
const routeItem = [key, path, routeMeta, redirects];
// paths that should redirect to this page
const redirectsSet = new Set();
// redirect from decoded path
addPath(path);
function addPath(path) {
redirectsSet.add(decodeURI(path));
if (path.endsWith('/')) {
// redirect from index path
redirectsSet.add(path + 'index.html');
}
else {
// redirect from the path that does not end with `.html`
redirectsSet.add(path.replace(/.html$/, ''));
}
}
// redirect from inferred path
if (pathInferred !== null) {
redirectsSet.add(pathInferred);
redirectsSet.add(encodeURI(pathInferred));
}
// redirect from filename path
if (filePathRelative !== null) {
const filenamePath = shared.ensureLeadingSlash(filePathRelative);
redirectsSet.add(filenamePath);
redirectsSet.add(encodeURI(filenamePath));
}
if (frontmatter.redirectFrom) {
for (const path of frontmatter.redirectFrom) {
addPath(path);
}
}
// avoid redirect from the page path itself
redirectsSet.delete(path);
// add redirects to route item
redirects.push(...redirectsSet);
return `\n ${JSON.stringify(routeItem)},`;
})
.join('')}
]
export const pagesRoutes = routeItems.reduce(
(result, [name, path, meta, redirects]) => {
result.push(
{
name,
path,
component: Vuepress,
meta,
},
...redirects.map((item) => ({
path: item,
redirect: path,
}))
)
return result
},
[
{
name: "404",
path: "/:catchAll(.*)",
component: Vuepress,
}
]
)
`;
await app.writeTemp('internal/pagesRoutes.js', content);
};
2 changes: 2 additions & 0 deletions docs/.vuepress/theme.js
Original file line number Diff line number Diff line change
@@ -1,3 +1,5 @@
require('./patchRedirect')

module.exports = {
extends: '@vuepress/theme-default',

Expand Down
5 changes: 0 additions & 5 deletions docs/guide/introduction/cli.md

This file was deleted.

5 changes: 0 additions & 5 deletions docs/guide/introduction/coding.md

This file was deleted.

5 changes: 0 additions & 5 deletions docs/guide/introduction/console.md

This file was deleted.

5 changes: 0 additions & 5 deletions docs/guide/introduction/workspace.md

This file was deleted.

10 changes: 1 addition & 9 deletions docs/guide/misc/unit-tests.md
Original file line number Diff line number Diff line change
Expand Up @@ -33,21 +33,13 @@ yarn add mocha chai @koishijs/plugin-mock -D

接着创建存放测试文件的 `tests` 目录,并在其中新建一个 `index.spec.js` 文件,开始编写你的单元测试:

::: code-group languages tests/index.spec
```js
const { App } = require('koishi')

const app = new App()
app.plugin('mock')
```
```ts no-extra-header
```ts title=tests/index.spec.js
import { App } from 'koishi'
import mock from '@koishijs/plugin-mock'

const app = new App()
app.plugin(mock)
```
:::

### 使用 TypeScript

Expand Down
61 changes: 10 additions & 51 deletions docs/guide/plugin/index.md
Original file line number Diff line number Diff line change
Expand Up @@ -33,22 +33,7 @@ ctx.plugin({

由于 JavaScript 中类本身也是一种函数,因此我们也可以将插件写成类的形式。

::: code-group language example-plugin
```js no-extra-header
class ExamplePlugin {
constructor(ctx, config) {
// 你可以保存插件的上下文和选项
this.ctx = ctx
this.config = config

// 上述插件的等价形式
ctx.middleware(this.callback.bind(this))
}

callback(session, next) {}
}
```
```ts no-extra-header
```ts title=example-plugin.ts
import { Context, Next, Session } from 'koishi'

interface Config {}
Expand All @@ -63,7 +48,6 @@ class ExamplePlugin {
callback(session: Session, next: Next) {}
}
```
:::

## 模块化的插件

Expand All @@ -84,21 +68,7 @@ class ExamplePlugin {

例如,下面给出了一个插件的例子,它实现了检测说话带空格的功能:

::: code-group language detect-space
```js no-extra-header
module.exports.name = 'detect-space'

module.exports.apply = (ctx) => {
ctx.middleware((session, next) => {
if (session.content.match(/^\s*(\S +){2,}\S\s*$/g)) {
return '在?为什么说话带空格?'
} else {
return next()
}
})
}
```
```ts no-extra-header
```ts title=detect-space.ts
import { Context } from 'koishi'

export default function detectSpace(ctx: Context) {
Expand All @@ -111,27 +81,15 @@ export default function detectSpace(ctx: Context) {
})
}
```
:::

## 嵌套插件

Koishi 的插件也是可以嵌套的。你可以将你编写的插件解耦成多个独立的子插件,再用一个父插件作为入口,就像这样:

::: code-group language nested-plugin
```js no-extra-header
// 在 a.js, b.js 中编写两个不同的插件
const pluginA = require('./a')
const pluginB = require('./b')

module.exports.apply = (ctx) => {
// 依次安装 a, b 两个插件
ctx.plugin(pluginA)
ctx.plugin(pluginB)
}
```
```ts no-extra-header
// @errors: 2307

```ts title=nested-plugin.ts
declare module './a' {}
declare module './b' {}
// ---cut---
// 在 a.ts, b.ts 中编写两个不同的插件
import { Context } from 'koishi'
import pluginA from './a'
Expand All @@ -143,7 +101,6 @@ export default function (ctx: Context) {
ctx.plugin(pluginB)
}
```
:::

这样当你加载 nested-plugin 时,就相当于同时加载了 a 和 b 两个插件。

Expand All @@ -154,8 +111,10 @@ Koishi 的许多插件都采用了这种写法,例如 [koishi-plugin-tools](ht
通常来说一个插件的效应应该是永久的,但如果你想在运行时卸载一个插件,应该怎么做?你可以使用 `ctx.dispose()` 方法来解决:

```ts
// @errors: 2304

declare const eventCallback: (session: Session) => void
declare const commandCallback: Command.Action
declare const middlewareCallback: Middleware
// ---cut---
import { Context } from 'koishi'

function callback(ctx: Context, options) {
Expand Down
Original file line number Diff line number Diff line change
@@ -1,5 +1,9 @@
---
sidebarDepth: 2
redirectFrom:
- /guide/introduction/cli.html
- /guide/introduction/development.html
- /guide/introduction/workspace.html
---

# 工作区开发
Expand Down
3 changes: 3 additions & 0 deletions docs/guide/introduction/direct.md → docs/manual/direct.md
Original file line number Diff line number Diff line change
@@ -1,5 +1,8 @@
---
sidebarDepth: 2
redirectFrom:
- /guide/introduction/coding.html
- /guide/introduction/direct.html
---

# 直接调用 Koishi
Expand Down
1 change: 1 addition & 0 deletions docs/guide/introduction/index.md → docs/manual/index.md
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
---
sidebarDepth: 2
noOutboundLinks: true
- /guide/introduction/
---

# 介绍
Expand Down
Original file line number Diff line number Diff line change
@@ -1,5 +1,8 @@
---
sidebarDepth: 2
redirectFrom:
- /guide/introduction/console.html
- /guide/introduction/template.html
---

# 创建模板项目
Expand Down

0 comments on commit 07d9305

Please sign in to comment.