• 没啥好说,更新慢

从零开发一个Nodebb替换Slug的插件

NodeBB 每天学 来源:原创 6个月前 (02-21) 346次浏览

参考资料

https://www.yuque.com/a632079/nodebb/

环境搭建

本来是想参考 https://www.yuque.com/a632079/nodebb/development-plugin-demo 这个搭建一个开发环境,不过这个教程里面用的是Windows子系统,但是我的应用商店用不了,而且我也之前学Vue也配好了npm、yarn和nodejs的环境。

从零开发一个Nodebb替换Slug的插件

在Windows环境下的开发很麻烦,我自己的方法跟中文文档推荐的安装方法也不一样,安装好后这个教程的意思是在本地搭一个Nodebb,我这个网速根本下不了依赖包,所以折腾了半天只能从服务器上处理好依赖包再下载到本地来。其实如果你如果不完全是新手的话,可以不按这个教程来,手动安装好Node、Yarn、Mongodb或者Redis就可以了。如果你是新手的话,环境搭建这部分还是参考Nodebb中国的文档比较好:https://www.yuque.com/a632079/nodebb/development-plugin-demo

开始第一个插件

根据Nodebb中国的这篇教程安装好环境后,选一个开发用的目录,按住Shift+右键 => Gitbash here,然后输入:

git clone https://github.com/NodeBB-China/nodebb-plugin-quickstart.git

从零开发一个Nodebb替换Slug的插件

克隆好之后,有两个地方需要修改,当然先把克隆的文件夹名字改了。我改成了 nodebb-plugin-replace-slug ,然后进入目录,我们需要修改 package.json 和 plugin.json 这两个文件,package.json参考修改:

{
  "name": "nodebb-plugin-replace-slug",
  "version": "0.2.5",
  "description": "NodeBB替换Slug",
  "main": "library.js",
  "repository": {
    "type": "git",
    "url": "https://github.com/BrokenPaper/nodebb-plugin-replace-slug" /* 以后改成自己的仓库 */
  },
  "keywords": [
    "nodebb",
    "plugin",
    "quickstart",
    "shell"
  ],
  "husky": {
    "hooks": {
      "pre-commit": "lint-staged",
      "commit-msg": "commitlint -E HUSKY_GIT_PARAMS"
    }
  },
  "lint-staged": {
    "*.js": [
      "eslint --fix",
      "git add"
    ]
  },
  "author": {
    "name": "1013370209",
    "email": "1013370209@gmail.com"
  },
  "license": "MIT",
  "bugs": {
    "url": "https://github.com/BrokenPaper/nodebb-plugin-replace-slug" /* 以后改成自己的仓库 */
  },
  "readmeFilename": "README.md",
  "nbbpm": {
    "compatibility": "^1.13.0"
  },
  "devDependencies": {
    "@commitlint/cli": "^8.0.0",
    "@commitlint/config-angular": "^7.1.2",
    "eslint": "^6.2.2 ",
    "eslint-config-standard": "^11.0.0",
    "eslint-plugin-html": "^6.0.0",
    "eslint-plugin-import": "^2.18.0",
    "eslint-plugin-node": "^9.1.0",
    "eslint-plugin-promise": "^4.2.1",
    "eslint-plugin-standard": "^4.0.0",
    "husky": "^2.4.0",
    "lint-staged": "^8.2.0"
  },
  "dependencies": {
  }
}

plugin.json参考修改:

{
	"id": "nodebb-plugin-replace-slug",
	"url": "https://github.com/BrokenPaper/nodebb-plugin-replace-slug", /* 以后改成自己的仓库 */
	"library": "./library.js",
	"hooks": [
		{
			"hook": "static:app.load", "method": "init"
		},
		{
			"hook": "filter:admin.header.build", "method": "addAdminNavigation"
		}
	],
	"staticDirs": {
		"static": "./static"
	},
	"less": [
		"static/style.less"
	],
	"scripts": [
		"static/lib/main.js"
	],
	"acpScripts": [
		"static/lib/admin.js"
	],
	"templates": "static/templates"
}

然后,我们就可以开始正式的开发了,我这个插件的功能是要替换文章和目录里面的中文Slug,因为对搜索引擎很不友好。我们进入插件的入口(个人称呼)/src/core.js 进行一些修改:

'use strict'

// 系统函数库
// const user = require.main.require('./user')
// const db = require.main.require('../src/database')
// const meta = require.main.require('./meta')
// const utils = require.main.require('../public/src/utils')

// 常用模块
// const async = require.main.require('async')
// const nconf = require.main.require('nconf')
// const winston = require.main.require('winston')
// const path = require.main.require('path')

const { Controllers } = require('./controllers')

const Core = {}
Core.init = async (params) => {
  const router = params.router
  const hostMiddleware = params.middleware
  // const hostControllers = params.controllers;
  // 我们需要为每个视图创建路由。 一个 API 路由,以及它自身的路由。 方法可以参考下面的方案
  // 使用 buildHeader 中间件, NodeBB会构建页面,并将你的模板嵌入进去
  router.get(
    '/admin/plugins/replace-slug',
    hostMiddleware.admin.buildHeader,
    Controllers.renderAdminPage
  )
  router.get('/api/admin/plugins/replace-slug', Controllers.renderAdminPage)
}
// 这里的目的是为了给后台管理员页面插件栏里面添加我们的入口
Core.addAdminNavigation = async (header) => {
  header.plugins.push({
    route: '/plugins/replace-slug',
    icon: 'fa-tint',
    name: '替换Slug'
  })
  return header
}

module.exports = Core
module.exports.Core = Core

然后我们再进入controller.js这个文件进行一些小修改:

'use strict'
// 系统函数库
// const user = require.main.require('./user')
// const db = require.main.require('../src/database')
// const meta = require.main.require('./meta')
// const utils = require.main.require('../public/src/utils')

// 常用模块
// const async = require.main.require('async')
// const nconf = require.main.require('nconf')
// const winston = require.main.require('winston')
// const path = require.main.require('path')

// 载入依赖模块
// const _ = require('lodash')
// const callbackify = require('../callbackify')

const Controllers = {}
Controllers.renderAdminPage = (req, res, next) => { // 注意: NodeBB 目前也支持使用 Async 方法作为路由中间件。
  /*
      请确保你的路由地址能和模板路径能够对应。
      例如, 如果你的站点地址为:
        myforum.com/some/complex/route/
      你的模板地址应该为:
        templates/some/complex/route.tpl
      并且你应该这样来渲染它:
        res.render('some/complex/route');
    */

  res.render('admin/plugins/replace-slug', {})
  /*
      使用回调方式中的 next(err, data) 方法。
      传递数据:
        return '数据'
      传递错误:
        throw new Error('错误')
    */
}

module.exports = Controllers
module.exports.Controllers = Controllers

还要修改/static/templates/admin/plugins/quickstart/tpl的名字为replace-slug.tpl,并且修改这个文件的内容,我只修改了class的名字,因为我这个插件其实还不需要管理面板:

因为我们是要修改Slug,Slug是在发表或者编辑主题的时候生成的,所以通过官方的Hook列表找到需要Hook的地方,然后编辑plugin.json添加Hook:

{
  "id": "nodebb-plugin--replace-slug",
  "url": "https://github.com/BrokenPaper/nodebb-plugin-replace-slug",
  "library": "./library.js",
  "hooks": [
    {
      "hook": "static:app.load",
      "method": "init"
    },
    {
      "hook": "filter:admin.header.build",
      "method": "addAdminNavigation"
    },
    {
      "hook": "filter:topic.create",
      "method": "topicCreate"
    },
    {
      "hook": "filter:topic.edit",
      "method": "topicEdit"
    }
  ],
  "staticDirs": {
    "static": "./static"
  },
  "less": ["static/style.less"],
  "scripts": ["static/lib/main.js"],
  "acpScripts": ["static/lib/admin.js"],
  "templates": "static/templates"
}


我们hook的方法名是topicCreate和topicEdit,所以需要创建这两个方法,修改core.js:

"use strict";

// 系统函数库
// const user = require.main.require('./user')
// const db = require.main.require('../src/database')
// const meta = require.main.require('./meta')
// const utils = require.main.require('../public/src/utils')

// 常用模块
// const async = require.main.require('async')
// const nconf = require.main.require('nconf')
// const winston = require.main.require('winston')
// const path = require.main.require('path')

const { Controllers } = require("./controllers");

const Core = {};
Core.init = async params => {
  const router = params.router;
  const hostMiddleware = params.middleware;
  // const hostControllers = params.controllers;
  // 我们需要为每个视图创建路由。 一个 API 路由,以及它自身的路由。 方法可以参考下面的方案
  // 使用 buildHeader 中间件, NodeBB会构建页面,并将你的模板嵌入进去
  router.get(
    "/admin/plugins/quickstart",
    hostMiddleware.admin.buildHeader,
    Controllers.renderAdminPage
  );
  router.get("/api/admin/plugins/quickstart", Controllers.renderAdminPage);
};

Core.addAdminNavigation = async header => {
  header.plugins.push({
    route: "/plugins/quickstart",
    icon: "fa-tint",
    name: "快速开始"
  });
  return header;
};

function slugify(text) {
  var slug = text.toLowerCase();
  if (slug.match(/\/(.*)/)) {
    slug = slug.replace(/\/(.*)/, "/post");
  }
  return slug;
}
Core.topicEdit = (data, callback) => {
  if (data && data.topic && data.topic.slug) {
    data.topic.slug = slugify(data.topic.slug);
  }

  callback(null, data);
};

Core.topicCreate = (data, callback) => {
  if (data && data.topic && data.topic.slug) {
    data.topic.slug = slugify(data.topic.slug);
  }

  callback(null, data);
};

module.exports = Core;
module.exports.Core = Core;

这样的话,这个插件其实已经是做好了,效果已经实现了,最后还需要修改一下/static/lib/admin.js这个文件,把里面的quickstart都换成我们的插件名字就可以实现保存设置和加载设置了,不过我们这个插件并没有用到设置相关的。


每天学 , 版权所有丨如未注明 , 均为原创丨本网站采用BY-NC-SA协议进行授权
转载请注明原文链接:从零开发一个Nodebb替换Slug的插件
赞(2)
分享到: 更多 (0)

为了阻止垃圾和反动评论,您必须才能发表评论,使用功能只需要1分钟注册好账号!