diff --git a/.github/FUNDING.yml b/.github/FUNDING.yml
deleted file mode 100644
index 2b34450..0000000
--- a/.github/FUNDING.yml
+++ /dev/null
@@ -1 +0,0 @@
-open_collective: docsify
diff --git a/.github/workflows/docsify-cli.yml b/.github/workflows/docsify-cli.yml
index 2772026..d0f83cf 100644
--- a/.github/workflows/docsify-cli.yml
+++ b/.github/workflows/docsify-cli.yml
@@ -13,12 +13,13 @@ jobs:
strategy:
matrix:
os: [ macos-latest, ubuntu-latest, windows-latest ]
- node-version: [ 12.x, 14.x ]
+ node-version: [ 'lts/*' ]
+ fail-fast: false
steps:
- - uses: actions/checkout@v2
+ - uses: actions/checkout@v4
- name: Use Node.js ${{ matrix.node-version }}
- uses: actions/setup-node@v1
+ uses: actions/setup-node@v4
with:
node-version: ${{ matrix.node-version }}
diff --git a/CHANGELOG.md b/CHANGELOG.md
index 9b58649..82f8f5c 100644
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -2,6 +2,40 @@
All notable changes to this project will be documented in this file. See [standard-version](https://github.com/conventional-changelog/standard-version) for commit guidelines.
+### [4.4.4](https://github.com/docsifyjs/docsify-cli/compare/v4.4.3...v4.4.4) (2022-03-12)
+
+
+### Features
+
+* support docsify init --plugins ([#99](https://github.com/docsifyjs/docsify-cli/issues/99)) ([8bb295c](https://github.com/docsifyjs/docsify-cli/commit/8bb295c54e92b11f61f38ac261c5dabd7da23b51)), closes [/github.com/docsifyjs/docsify-cli/pull/99#discussion_r621952975](https://github.com/docsifyjs//github.com/docsifyjs/docsify-cli/pull/99/issues/discussion_r621952975)
+
+
+### Bug Fixes
+
+* package.json & package-lock.json to reduce vulnerabilities ([#161](https://github.com/docsifyjs/docsify-cli/issues/161)) ([e9ea2c1](https://github.com/docsifyjs/docsify-cli/commit/e9ea2c12ee7d27fb8d83299a8ea86b95935615db))
+* Repeat generation and hump naming ([#164](https://github.com/docsifyjs/docsify-cli/issues/164)) ([238326e](https://github.com/docsifyjs/docsify-cli/commit/238326e79a8f5dfbaba86e4e197c05655f5945e1))
+* Support refresh and livereload in serve when using routerMode history ([#166](https://github.com/docsifyjs/docsify-cli/issues/166)) ([625c9f2](https://github.com/docsifyjs/docsify-cli/commit/625c9f201e6dedb62947530c094b1b911b7a18e4))
+
+### [4.4.3](https://github.com/docsifyjs/docsify-cli/compare/v4.4.2...v4.4.3) (2021-03-09)
+
+
+### Features
+
+* auto generate sidebar ([#130](https://github.com/docsifyjs/docsify-cli/issues/130)) ([e83bfcb](https://github.com/docsifyjs/docsify-cli/commit/e83bfcbd88b43fa8f13d7db13b801da98cca4aea))
+
+### [4.4.2](https://github.com/docsifyjs/docsify-cli/compare/v4.4.1...v4.4.2) (2020-11-17)
+
+
+### Features
+
+* Added asking whether to rewrite files ([#117](https://github.com/docsifyjs/docsify-cli/issues/117)) ([f811906](https://github.com/docsifyjs/docsify-cli/commit/f8119064c54d3ad1817f31be058d25d3384e85c6))
+* Included docsify version in url for the template ([#107](https://github.com/docsifyjs/docsify-cli/issues/107)) ([d92d030](https://github.com/docsifyjs/docsify-cli/commit/d92d03005e4f0188671a212f1eb0abc59f46a0b1))
+
+
+### Bug Fixes
+
+* alias not working ([#125](https://github.com/docsifyjs/docsify-cli/issues/125)) ([f3af553](https://github.com/docsifyjs/docsify-cli/commit/f3af553912b962a132743b03ba56ab292bd1b4b9))
+
### [4.4.1](https://github.com/QingWei-Li/docsify-cli/compare/v4.4.0...v4.4.1) (2020-06-05)
@@ -337,6 +371,3 @@ All notable changes to this project will be documented in this file. See [standa
# 0.1.0 (2016-11-24)
-
-
-
diff --git a/README.md b/README.md
index 920b0e3..80f7cc4 100644
--- a/README.md
+++ b/README.md
@@ -50,12 +50,12 @@ npm i docsify-cli -g
Use `init` to generate your docs.
```shell
-docsify init [--local false] [--theme vue]
+docsify init [path] [--local false] [--theme vue] [--plugins false]
-# docsify i [--local false] [--theme vue]
+# docsify i [path] [-l false] [-t vue] [--plugins false]
```
-`` defaults to the current directory. Use relative paths like `./docs` (or `docs`).
+`[path]` defaults to the current directory. Use relative paths like `./docs` (or `docs`).
- `--local` option:
- Shorthand: `-l`
@@ -67,15 +67,20 @@ docsify init [--local false] [--theme vue]
- Type: string
- Default: `vue`
- Description: Choose a theme, defaults to `vue`, other choices are `buble`, `dark` and `pure`.
+- `--plugins` option:
+ - Shorthand: `-p`
+ - Type: boolean
+ - Default: `false`
+ - Description: Provide a list of plugins to insert as `
diff --git a/e2e/cli.test.js.md b/e2e/cli.test.js.md
index 5ba41c6..007f219 100644
--- a/e2e/cli.test.js.md
+++ b/e2e/cli.test.js.md
@@ -2,18 +2,19 @@
The actual snapshot is saved in `cli.test.js.snap`.
-Generated by [AVA](https://ava.li).
+Generated by [AVA](https://avajs.dev).
-## rejects promise due to error on passing in an unknown command
+## shows up help message without any args
> Snapshot 1
- `Usage: docsify ␊
+ `Usage: docsify [path]␊
␊
Commands:␊
- docsify init [path] Creates new docs [aliases: i]␊
- docsify serve [path] Run local server to preview site. [aliases: s]␊
- docsify start Server for SSR␊
+ docsify init [path] Creates new docs [aliases: i]␊
+ docsify serve [path] Run local server to preview site. [aliases: s]␊
+ docsify start [path] Server for SSR␊
+ docsify generate [path] Docsify's generators [aliases: g]␊
␊
Global Options␊
--help, -h Show help [boolean]␊
@@ -26,18 +27,19 @@ Generated by [AVA](https://ava.li).
Development:␊
https://github.com/docsifyjs/docsify-cli/blob/master/CONTRIBUTING.md␊
␊
- Unknown argument: junkcmd`
+ [ERROR] 0 arguments passed. Please specify a command`
-## shows help with --help flag
+## shows help with -h flag
> Snapshot 1
- `Usage: docsify ␊
+ `Usage: docsify [path]␊
␊
Commands:␊
- docsify init [path] Creates new docs [aliases: i]␊
- docsify serve [path] Run local server to preview site. [aliases: s]␊
- docsify start Server for SSR␊
+ docsify init [path] Creates new docs [aliases: i]␊
+ docsify serve [path] Run local server to preview site. [aliases: s]␊
+ docsify start [path] Server for SSR␊
+ docsify generate [path] Docsify's generators [aliases: g]␊
␊
Global Options␊
--help, -h Show help [boolean]␊
@@ -50,16 +52,17 @@ Generated by [AVA](https://ava.li).
Development:␊
https://github.com/docsifyjs/docsify-cli/blob/master/CONTRIBUTING.md`
-## shows help with -h flag
+## shows help with --help flag
> Snapshot 1
- `Usage: docsify ␊
+ `Usage: docsify [path]␊
␊
Commands:␊
- docsify init [path] Creates new docs [aliases: i]␊
- docsify serve [path] Run local server to preview site. [aliases: s]␊
- docsify start Server for SSR␊
+ docsify init [path] Creates new docs [aliases: i]␊
+ docsify serve [path] Run local server to preview site. [aliases: s]␊
+ docsify start [path] Server for SSR␊
+ docsify generate [path] Docsify's generators [aliases: g]␊
␊
Global Options␊
--help, -h Show help [boolean]␊
@@ -72,16 +75,35 @@ Generated by [AVA](https://ava.li).
Development:␊
https://github.com/docsifyjs/docsify-cli/blob/master/CONTRIBUTING.md`
-## shows up help message without any args
+## shows version information with -v flag
+
+> Snapshot 1
+
+ `␊
+ docsify-cli version:␊
+ 4.4.4␊
+ `
+
+## shows version information with --version flag
+
+> Snapshot 1
+
+ `␊
+ docsify-cli version:␊
+ 4.4.4␊
+ `
+
+## rejects promise due to error on passing in an unknown command
> Snapshot 1
- `Usage: docsify ␊
+ `Usage: docsify [path]␊
␊
Commands:␊
- docsify init [path] Creates new docs [aliases: i]␊
- docsify serve [path] Run local server to preview site. [aliases: s]␊
- docsify start Server for SSR␊
+ docsify init [path] Creates new docs [aliases: i]␊
+ docsify serve [path] Run local server to preview site. [aliases: s]␊
+ docsify start [path] Server for SSR␊
+ docsify generate [path] Docsify's generators [aliases: g]␊
␊
Global Options␊
--help, -h Show help [boolean]␊
@@ -94,22 +116,4 @@ Generated by [AVA](https://ava.li).
Development:␊
https://github.com/docsifyjs/docsify-cli/blob/master/CONTRIBUTING.md␊
␊
- [ERROR] 0 arguments passed. Please specify a command`
-
-## shows version information with --version flag
-
-> Snapshot 1
-
- `␊
- docsify-cli version:␊
- 4.4.1␊
- `
-
-## shows version information with -v flag
-
-> Snapshot 1
-
- `␊
- docsify-cli version:␊
- 4.4.1␊
- `
+ Unknown argument: junkcmd`
diff --git a/e2e/cli.test.js.snap b/e2e/cli.test.js.snap
index 5a0dff1..6cb284e 100644
Binary files a/e2e/cli.test.js.snap and b/e2e/cli.test.js.snap differ
diff --git a/e2e/commands/generate.test.js b/e2e/commands/generate.test.js
new file mode 100644
index 0000000..71513d3
--- /dev/null
+++ b/e2e/commands/generate.test.js
@@ -0,0 +1,35 @@
+const test = require('ava')
+const fs = require('fs')
+const path = require('path')
+
+const {run} = require('../helpers/test-utils.js')
+
+const genPath = path.join(__dirname, 'generate-cmd')
+const docsPath = path.join(genPath, 'docs')
+
+test.before('create temp directory', () => {
+ // Cleanup if the directory already exists
+ if (fs.existsSync(genPath)) {
+ fs.rmSync(genPath, {recursive: true})
+ }
+
+ fs.mkdirSync(genPath)
+})
+
+test.after('cleanup', () => {
+ fs.rmSync(genPath, {recursive: true})
+})
+
+test('generate _sidebar.md', t => {
+ run(['init', 'docs'], {cwd: genPath})
+ run(['generate', 'docs'], {cwd: genPath})
+ // Check for existence
+ t.true(fs.existsSync(path.join(docsPath, '_sidebar.md')))
+
+ const {exitCode, stderr} = run(['generate', 'docs'], {
+ cwd: genPath,
+ reject: false
+ })
+ t.is(exitCode, 1)
+ t.is(stderr, 'The sidebar file \'_sidebar.md\' already exists.')
+})
diff --git a/e2e/commands/init.test.js b/e2e/commands/init.test.js
index f2cab51..5e40967 100644
--- a/e2e/commands/init.test.js
+++ b/e2e/commands/init.test.js
@@ -11,24 +11,33 @@ const docsPath = path.join(genPath, 'docs')
test.before('create temp directory', () => {
// Cleanup if the directory already exists
if (fs.existsSync(genPath)) {
- fs.rmdirSync(genPath, {recursive: true})
+ fs.rmSync(genPath, {recursive: true})
}
fs.mkdirSync(genPath)
})
test.after('cleanup', () => {
- fs.rmdirSync(genPath, {recursive: true})
+ fs.rmSync(genPath, {recursive: true})
})
test('generates docs directory', t => {
- run(['init', 'docs'], {cwd: genPath})
+ const {exitCode} = run(['init', 'docs'], {cwd: genPath})
+
+ // Assert for exit code
+ t.is(exitCode, 0)
+
// Check for existence
t.true(fs.existsSync(path.join(docsPath, 'README.md')))
t.true(fs.existsSync(path.join(docsPath, 'index.html')))
})
test('force generates docs directory with --local flag', async t => {
- await runPromptWithAnswers(['init', 'docs', '--local'], ['y', ENTER], genPath)
+ const {exitCode} = await runPromptWithAnswers(
+ ['init', 'docs', '--local'],
+ ['y', ENTER],
+ genPath
+ )
+ t.is(exitCode, 0)
t.true(fs.existsSync(path.join(docsPath, 'vendor')))
})
diff --git a/lib/cli.js b/lib/cli.js
index ce2c6d1..830d3b4 100644
--- a/lib/cli.js
+++ b/lib/cli.js
@@ -18,7 +18,7 @@ require('yargs')
.demandCommand(1, chalk.red('[ERROR] 0 arguments passed. Please specify a command'))
.strict()
.recommendCommands()
- .usage(chalk.bold(y18n.__('usage') + ': docsify '))
+ .usage(chalk.bold(y18n.__('usage') + ': docsify [path]'))
.command({
command: 'init [path]',
aliases: 'i',
@@ -41,9 +41,17 @@ require('yargs')
nargs: 1,
requiresArg: true,
type: 'string'
+ },
+ plugins: {
+ alias: 'p',
+ default: false,
+ desc: chalk.gray(y18n.__('init.plugins')),
+ nargs: 0,
+ requiresArg: false,
+ type: 'boolean'
}
}),
- handler: argv => run.init(argv.path, argv.local, argv.theme)
+ handler: argv => run.init(argv.path, argv.local, argv.theme, argv.plugins)
})
.command({
command: 'serve [path]',
@@ -86,7 +94,7 @@ require('yargs')
handler: argv => run.serve(argv.path, argv.open, argv.port, argv.P, argv.i)
})
.command({
- command: 'start ',
+ command: 'start [path]',
desc: chalk.gray(y18n.__('start')),
builder: yargs =>
yargs.options({
@@ -109,6 +117,30 @@ require('yargs')
}),
handler: argv => run.start(argv.path, argv.config, argv.port)
})
+ .command({
+ command: 'generate [path]',
+ aliases: 'g',
+ desc: chalk.gray(y18n.__('generate')),
+ builder: yargs =>
+ yargs.options({
+ overwrite: {
+ alias: 'o',
+ default: false,
+ desc: chalk.gray(y18n.__('generate.overwrite')),
+ nargs: 0,
+ type: 'boolean'
+ },
+ sidebar: {
+ alias: 's',
+ default: '_sidebar.md',
+ desc: chalk.gray(y18n.__('generate.sidebar')),
+ nargs: 1,
+ requiresArg: true,
+ type: 'string'
+ }
+ }),
+ handler: argv => run.generate(argv.path, argv.sidebar, {overwrite: argv.overwrite})
+ })
.help()
.option('help', {
alias: 'h',
diff --git a/lib/commands/generate.js b/lib/commands/generate.js
new file mode 100644
index 0000000..6e4ae46
--- /dev/null
+++ b/lib/commands/generate.js
@@ -0,0 +1,87 @@
+'use strict'
+
+const fs = require('fs')
+const os = require('os')
+const {cwd, exists} = require('../util')
+const path = require('path')
+const logger = require('../util/logger')
+const ignoreFiles = ['_navbar', '_coverpage', '_sidebar']
+
+module.exports = function (path, sidebar, options) {
+ const cwdPath = cwd(path || '.')
+
+ if (exists(cwdPath)) {
+ if (sidebar) {
+ const sidebarPath = cwdPath + '/' + sidebar || '_sidebar.md'
+
+ if (!exists(sidebarPath) || options.overwrite) {
+ genSidebar(cwdPath, sidebarPath)
+ logger.success(`Successfully generated the sidebar file '${sidebar}'.`)
+ return true
+ }
+
+ logger.error(`The sidebar file '${sidebar}' already exists.`)
+ process.exitCode = 1
+ return false
+ }
+ }
+
+ logger.error(`${cwdPath} directory does not exist.`)
+}
+
+function genSidebar(cwdPath, sidebarPath) {
+ let tree = ''
+ let lastPath = ''
+ let nodeName = ''
+ getDirFiles(cwdPath, function (pathname) {
+ path.relative(pathname, cwdPath)
+ pathname = pathname.replace(cwdPath + path.sep, '')
+ let filename = path.basename(pathname, '.md')
+ let splitPath = pathname.split(path.sep)
+
+ if (ignoreFiles.indexOf(filename) !== -1) {
+ return true
+ }
+
+ nodeName = '- [' + toCamelCase(filename) + '](' + pathname.replace(/\\/g, '/') + ')' + os.EOL
+
+ if (splitPath.length > 1) {
+ if (splitPath[0] !== lastPath) {
+ lastPath = splitPath[0]
+ tree += os.EOL + '- ' + toCamelCase(splitPath[0]) + os.EOL
+ }
+
+ tree += ' ' + nodeName
+ } else {
+ if (lastPath !== '') {
+ lastPath = ''
+ tree += os.EOL
+ }
+
+ tree += nodeName
+ }
+ })
+ fs.writeFile(sidebarPath, tree, 'utf8', err => {
+ if (err) {
+ logger.error(`Couldn't generate the sidebar file, error: ${err.message}`)
+ }
+ })
+}
+
+function getDirFiles(dir, callback) {
+ fs.readdirSync(dir).forEach(function (file) {
+ let pathname = path.join(dir, file)
+
+ if (fs.statSync(pathname).isDirectory()) {
+ getDirFiles(pathname, callback)
+ } else if (path.extname(file) === '.md') {
+ callback(pathname)
+ }
+ })
+}
+
+function toCamelCase(str) {
+ return str.replace(/\b(\w)/g, function (match, capture) {
+ return capture.toUpperCase()
+ }).replace(/-|_/g, ' ')
+}
diff --git a/lib/commands/init.js b/lib/commands/init.js
index 3d2c451..401ca2c 100644
--- a/lib/commands/init.js
+++ b/lib/commands/init.js
@@ -3,15 +3,18 @@
const fs = require('fs')
const cp = require('cp-file').sync
const chalk = require('chalk')
-const {prompt} = require('enquirer')
+const {version} = require('../../package.json')
+const logger = require('../util/logger')
+const {prompt, MultiSelect} = require('enquirer')
const {cwd, exists, pkg, pwd, read, resolve} = require('../util')
+const colors = require('ansi-colors')
const replace = function (file, tpl, replace) {
fs.writeFileSync(file, read(file).replace(tpl, replace), 'utf-8')
}
// eslint-disable-next-line
-module.exports = function (path = '', local, theme) {
+module.exports = async function (path = '', local, theme, plugins) {
const msg =
'\n' +
chalk.green('Initialization succeeded!') +
@@ -22,34 +25,33 @@ module.exports = function (path = '', local, theme) {
const cwdPath = cwd(path || '.')
if (exists(cwdPath)) {
- console.log(chalk.red(`${path || '.'}`) + ' already exists.')
-
- prompt({
- type: 'confirm',
- name: 'rewrite',
- symbols: {
- separator: ''
- },
- message: 'Are you sure you want to rewrite it?'
- })
- .then(answers => {
- if (answers.rewrite === false) {
- return process.exit(0)
- }
-
- createFile(cwdPath, local, theme)
- console.log(msg)
+ logger.error(`${path || '.'} already exists.`)
+
+ let answer = {}
+ try {
+ answer = await prompt({
+ type: 'confirm',
+ name: 'rewrite',
+ symbols: {
+ separator: ''
+ },
+ message: 'Are you sure you want to rewrite it?'
})
- .catch(console.error)
-
- return false
+ } catch (err) {
+ err && logger.error(err)
+ process.exit(1)
+ }
+
+ if (!answer.rewrite) {
+ return
+ }
}
- createFile(cwdPath, local, theme)
+ await createFile(cwdPath, local, theme, plugins)
console.log(msg)
}
-function createFile(path, local, theme) {
+async function createFile(path, local, theme, plugins) {
const target = file => resolve(path, file)
const readme = exists(cwd('README.md')) || pwd('template/README.md')
let main = pwd('template/index.html')
@@ -94,4 +96,60 @@ function createFile(path, local, theme) {
.replace(/^git\+/g, '')
replace(target(filename), 'repo: \'\'', `repo: '${repo}'`)
}
+
+ // Return early if not opted for plugins
+ if (!plugins) {
+ return replace(target(filename), '\n _plugins_', '')
+ }
+
+ const officialPlugins = [
+ 'front-matter',
+ 'search',
+ 'disqus',
+ 'emoji',
+ 'external-script',
+ 'ga',
+ 'gitalk',
+ 'matomo',
+ 'zoom-image'
+ ]
+
+ const choices = officialPlugins.map(name => ({name, value: name}))
+ const prompt = new MultiSelect({
+ name: 'plugins',
+ message: 'Select plugins to be used',
+ hint: '(Use to select, to submit)',
+ default: '',
+ choices,
+ indicator(state, choice) {
+ if (choice.enabled) {
+ return colors.cyan(state.symbols.radio.on)
+ }
+
+ return colors.gray(state.symbols.radio.off)
+ }
+ })
+
+ prompt.on('cancel', () => replace(target(filename), '\n _plugins_', ''))
+
+ let answers = []
+ try {
+ answers = await prompt.run()
+ } catch (err) {
+ if (err) {
+ logger.error(err)
+ process.exitCode = 1
+ }
+
+ return
+ }
+
+ replace(target(filename), ' _plugins_', '_plugin'.repeat(answers.length + 1))
+
+ answers.forEach(plugin => {
+ const url = `//cdn.jsdelivr.net/npm/docsify@${version[0]}/lib/plugins/${plugin}.min.js`
+ replace(target(filename), '_plugin', ` \n`)
+ })
+
+ replace(target(filename), '\n_plugin', '')
}
diff --git a/lib/commands/serve.js b/lib/commands/serve.js
index 13de4b8..2e5155d 100644
--- a/lib/commands/serve.js
+++ b/lib/commands/serve.js
@@ -3,9 +3,11 @@
const serveStatic = require('serve-static')
const connect = require('connect')
const livereload = require('connect-livereload')
+const history = require('connect-history-api-fallback')
const lrserver = require('livereload')
const open = require('open')
const chalk = require('chalk')
+const logger = require('../util/logger')
const {exists, resolve} = require('../util')
const getPort = require('get-port')
@@ -26,7 +28,8 @@ module.exports = function (
})
.then(_ => {
path = resolve(path || '.')
- const indexFile = resolve(path, indexName || 'index.html')
+ const indexFileName = indexName || 'index.html'
+ const indexFile = resolve(path, indexFileName)
if (!exists(indexFile)) {
const msg =
@@ -45,6 +48,7 @@ module.exports = function (
port: livereloadPort
})
)
+ server.use(history({index: '/' + indexFileName}))
server.use(serveStatic(path, {index: indexName}))
server.listen(port)
lrserver
@@ -69,6 +73,6 @@ module.exports = function (
console.log(msg)
})
.catch(err => {
- console.error(err.message)
+ logger.error(err.message)
})
}
diff --git a/lib/commands/start.js b/lib/commands/start.js
index b7205a8..31defe4 100644
--- a/lib/commands/start.js
+++ b/lib/commands/start.js
@@ -5,6 +5,7 @@ const serveStatic = require('serve-static')
const Renderer = require('docsify-server-renderer')
const util = require('../util')
const chalk = require('chalk')
+const logger = require('../util/logger')
const LRU = require('lru-cache')
const defaultConfig = {
@@ -29,7 +30,7 @@ function loadConfig(config) {
try {
return require(util.cwd(config))
} catch (e) {
- console.log(chalk.red(`${e.message} in ${config}`))
+ logger.error(`${e.message} in ${config}`)
process.exit(1)
}
}
@@ -78,7 +79,7 @@ module.exports = function (path, configFile, port) {
res.end(html)
})
.catch(function (err) {
- console.error(err)
+ logger.error(err)
res.writeHead(404)
res.end()
})
diff --git a/lib/index.js b/lib/index.js
index 002938f..7e3583f 100644
--- a/lib/index.js
+++ b/lib/index.js
@@ -1,5 +1,6 @@
module.exports = {
init: require('./commands/init'),
serve: require('./commands/serve'),
- start: require('./commands/start')
+ start: require('./commands/start'),
+ generate: require('./commands/generate')
}
diff --git a/lib/template/index.html b/lib/template/index.html
index 04dd4a7..9c49dd3 100644
--- a/lib/template/index.html
+++ b/lib/template/index.html
@@ -18,5 +18,6 @@
+ _plugins_