[转]【hexo】免费使用github搭建Markdown博客系统
本篇博客向大家介绍一下Markdown博客系统的搭建。关于搭建博客的具体细节大部分内容参考于:使用hexo+github搭建免费个人博客详细教程。笔者亲自尝试后,又做了一点补充,应该能够让大家很容易地学会如何利用hexo做一个博客系统。首先,给出效果:https://jack13163.github.io/。
目录
1. markdown简介
这里,笔者需要补充如下两点说明。
1.1 markdown是什么?
markdown是一种轻量级标记语言,它允许人们使用易读易写的纯文本格式编写文档,然后转换成格式丰富的 HTML 页面。笔者的理解是,markdown是一种html代码生成引擎,为什么这样说?因为markdown最终要通过markdown解析器解释为html代码。
1.2 为什么我们要用markdown做博客系统?
笔者自己为什么喜欢markdown呢?主要是它太流行了,太方便了。你不需要了解html的相关知识,就可以生成非常漂亮的界面,这对于一个后端开发者来说是多么有吸引力。
还有一点,就是它具有非常通用性,因为这个社区非常活跃,所以大家开发了用markdown写各种各样的东西的*,例如,我们可以用Markdown写微信公众号,将公众号素材用 Markdown 编辑好后,贴到在线排版工具以后,复制到公众号编辑器里即可。有多种页面主题和代码主题可选择。一位大佬维护的工具地址:https://md.mazhuang.org。
传统的博客系统在搭建时往往比较复杂,除了搭建开发、运行环境之外,还得需要比较高深的相关编程语言,比如说前天用JS、CSS,后台用Java,数据库用MySQL等等等等。
除了这些之外,我们还需要了解项目的基础框架,比如说现今流行的SSM。还需要我们知道开发博客的业务逻辑,比如说我们得展示前台吧,这就需要前台的业务逻辑,而我们的前台数据是通过后台进行维护的,因而在后台有需要有一个后台管理的业务逻辑。同时,在实际的项目开发过程之中,光了解上面的那些是远远不够的,因为一个系统最起码得有一个登陆吧,而登录这方面就需要RBAC权限管理的技术支持,否则谁都能操作后台,岂不乱了套了,诸如此类的技术还有很多,这我就不一一举例了。
但是仔细一想的话,虽然搭建一个传统的博客网站系统其实就已经很复杂了,但是其实有很多的功能并不是我们一定需要的,有时我们仅仅只是用于记录日志,用于自己博客信息的展示,其不需要太多的功能,在实现自己基本需求的情况下,简洁而美观,使用搭建方便,这才是我们追求的目标,否则光一个博客系统的搭建就耗费大把的时间,恐怕很多的博客爱好者就会止步于此了。
通过上述描述,我们基本上可以看出Markdown博客系统的优点,那就是基于现成的模版,搭建迅速,使用简单,并且易于维护。
2. 搭建markdown博客系统
在开始一切之前,你必须已经:
- 有一个github账号;
- 安装了node.js、npm,并了解相关的基础知识;
- 安装了git。
2.1 hexo介绍
Hexo是一个简单、快速、强大的基于 Github Pages 的博客发布工具,支持Markdown格式,有众多优秀插件和主题。
- hexo 可以理解为是基于node.js制作的一个博客工具,不是我们理解的一个开源的博客系统。
- hexo 正常来说,不需要部署到我们的服务器上,我们的服务器上保存的,其实是基于在hexo通过markdown编写的文章,然后hexo帮我们生成静态的html页面,然后,将生成的html上传到我们的服务器。简而言之:hexo是个静态页面生成、上传的工具。
2.2 安装hexo
打开命令行工具cmd,输入下述脚本。
npm install -g hexo
2.3 初始化
在电脑的某个地方新建一个文件夹作为你存放代码的地方。
cd C:/code/hexohexo init
hexo会自动下载一些文件到这个目录,包括node_modules,目录结构如下图:
文件/文件夹 | 说明 |
---|---|
_config.yml | 配置文件,修改博客的基础配置、模板等; |
public | 生成的静态文件,这个目录最终会发布到服务器; |
scaffolds | 一些通用的markdown模板; |
source | 编写的markdown文件,_drafts草稿文件,_posts发布的文章; |
themes | 博客的模板。 |
用 npm 安装话经常出现卡住而导致无法正常安装,解决办法就是修改 npm 的安装源,这里选择淘宝 NPM 镜像。
npm config set registry https://registry.npm.taobao.org
一次解决所有卡顿问题!
2.4 生成html
hexo g # 生成hexo s # 启动服务
执行以上命令之后,hexo就会在public文件夹生成相关html文件,这些文件将来都是要提交到github去的:
hexo s
是开启本地预览服务,打开浏览器访问 http://localhost:4000 即可看到内容,很多人会碰到浏览器一直在转圈但是就是加载不出来的问题,一般情况下是因为端口占用的缘故,因为4000这个端口太常见了,解决端口冲突问题请参考博客。
第一次初始化的时候,hexo已经帮我们写了一篇名为 Hello World 的文章:
2.5 修改主题
默认的主题比较丑,替换一个好看点的主题,这里推荐比较喜欢的2个主题:hexo-theme-jekyll 和 hexo-theme-yilia。
首先,下载主题:
cd C:/code/hexo/git clone https://github.com/litten/hexo-theme-yilia.git themes/yilia
下载后的主题都在这里:
修改_config.yml
中的theme: landscape
改为theme: yilia
,如果直接重新执行hexo g
来重新生成,则会出现模块缺失的错误:
按照提示,我们需要在_config.yml文件中加入下述内容:
# yilia主题所需新增内容jsonContent: meta: false pages: false posts: title: true date: true path: true text: false raw: false content: false slug: false updated: false comments: false link: false permalink: false excerpt: false categories: false tags: true
如果还有其他莫名其妙的问题,可以先执行hexo clean
来清理一下public的内容,然后再来重新生成和发布。 需要注意的是,_config.yml文件中,冒号后面必须有一个空格,否则可能会出问题。 主题更换后,效果如下图所示。
2.6 上传到github
如果你一切都配置好了,发布上传很容易,一句hexo d
就搞定,当然关键还是你要把所有东西配置好。这里,假设各位您的github的ssh key
肯定已经配置好了。
2.6.1 创建github仓库
Github 有两种形式的page:
- 个人或组织的page:只能存在一个,master 分支,地址为 xxx.github.io
- 项目page:每个项目可以生成一个,gh-pages 分支,地址为 xxx.github.io/projectname
这里笔者采用的是个人版本的page,即仓库名需要命名为:github用户名.github.io。
当创建仓库名为其他时:
无法在GitHub Pages中找到URL。
当创建仓库名为自己的github用户名.github.io时:
在GitHub Pages中可以看到URL。
2.6.2 配置部署信息
配置_config.yml
中有关deploy的部分:
# Deployment## Docs: https://hexo.io/docs/deployment.htmldeploy: type: git repository: https://github.com/jack13163/jack13163.github.io.git branch: master
有很多人说这种方式不正确,主要原因是:如果使用https链接URL,将默认使用https协议,而无法使用ssh免密登录功能,每次hexo d提交本地到远程时还是会需要输入密码,很是麻烦,因此,笔者建议这里直接写成下面的形式:
# Deployment## Docs: https://hexo.io/docs/deployment.htmldeploy: type: git repository: aaa@qq.com:jack13163/jack13163.github.io.git branch: master
上面的链接地址可以通过下面的方式获得:
2.6.3 安装hexo的git插件
直接执行hexo d
的话一般会报如下错误:
Deployer not found: github 或者 Deployer not found: git
原因是还需要安装一个插件:
npm install hexo-deployer-git --save
2.6.4 部署hexo
输入hexo d
就会将本次有改动的代码全部提交,没有改动的不会:
就像上一节中提到的,如果您的配置https的方式而不是ssh的方式,每次都需要输入github的用户名和密码。另外,需要确保本地安装的git配置好了ssh代理,具体可参见:ssh代理实现免密登录。
因为这里容易配置错误,所以这里给出笔者的配置文件。
# Hexo Configuration## Docs: https://hexo.io/docs/configuration.html## Source: https://github.com/hexojs/hexo/ # Sitetitle: Hexosubtitle:description:keywords:author: John Doelanguage: entimezone: # URL## If your site is put in a subdirectory, set url as 'http://yoursite.com/child' and root as '/child/'url: http://yoursite.comroot: /permalink: :year/:month/:day/:title/permalink_defaults: # Directorysource_dir: sourcepublic_dir: publictag_dir: tagsarchive_dir: archivescategory_dir: categoriescode_dir: downloads/codei18n_dir: :langskip_render: # Writingnew_post_name: :title.md # File name of new postsdefault_layout: posttitlecase: false # Transform title into titlecaseexternal_link: true # Open external links in new tabfilename_case: 0render_drafts: falsepost_asset_folder: falserelative_link: falsefuture: truehighlight: enable: true line_number: true auto_detect: false tab_replace: # Home page setting# path: Root path for your blogs index page. (default = '')# per_page: Posts displayed per page. (0 = disable pagination)# order_by: Posts order. (Order by date descending by default)index_generator: path: '' per_page: 10 order_by: -date # Category & Tagdefault_category: uncategorizedcategory_map:tag_map: # Date / Time format## Hexo uses Moment.js to parse and display date## You can customize the date format as defined in## http://momentjs.com/docs/#/displaying/format/date_format: YYYY-MM-DDtime_format: HH:mm:ss # Pagination## Set per_page to 0 to disable paginationper_page: 10pagination_dir: page # Extensions## Plugins: https://hexo.io/plugins/## Themes: https://hexo.io/themes/theme: yilia# yilia主题所需新增内容jsonContent: meta: false pages: false posts: title: true date: true path: true text: false raw: false content: false slug: false updated: false comments: false link: false permalink: false excerpt: false categories: false tags: true # Deployment## Docs: https://hexo.io/docs/deployment.htmldeploy: type: git repository: aaa@qq.com:jack13163/jack13163.github.io.git branch: master
2.7 保留CNAME、README.md等文件
提交之后网页上一看,发现以前其它代码都没了,此时不要慌,一些非md文件可以把他们放到source文件夹下,这里的所有文件都会原样复制(除了md文件)到public目录的:
由于hexo默认会把所有md文件都转换成html,包括README.md,所以需要每次生成之后、上传之前,都需要手动将README.md复制到public目录,并删除README.html。
2.8 常用hexo命令
常见命令
hexo new "postName" #新建文章hexo new page "pageName" #新建页面hexo generate #生成静态页面至public目录hexo server #开启预览访问端口(默认端口4000,'ctrl + c'关闭server)hexo deploy #部署到GitHubhexo help # 查看帮助hexo version #查看Hexo的版本
缩写:
hexo n == hexo newhexo g == hexo generatehexo s == hexo serverhexo d == hexo deploy
组合命令:
hexo s -g #生成并本地预览hexo d -g #生成并上传
3. 写博客
定位到hexo根目录,执行命令:
hexo new 'my-first-blog'
hexo会帮我们在_posts
下生成相关md文件:
我们只需要打开这个文件就可以开始写博客了,默认生成如下内容:
当然你也可以直接自己新建md文件,用这个命令的好处是帮我们自动生成了时间。
一般完整格式如下:
---title: postName #文章页面上的显示名称,一般是中文date: 2013-12-02 15:30:16 #文章生成时间,一般不改,当然也可以任意修改categories: 默认分类 #分类tags: [tag1,tag2,tag3] #文章标签,可空,多标签请用格式,注意:后面有个空格description: 附加一段文章摘要,字数最好在140字以内,会出现在meta的description里面--- 以下是正文
那么hexo new page 'postName'
命令和hexo new 'postName'
有什么区别呢?
hexo new page "my-second-blog"
生成如下:
最终部署时生成:hexo\public\my-second-blog\index.html
,但是它不会作为文章出现在博文目录。
那么用什么工具写博客呢?这个我还没去找,以前自己使用editor.md简单弄了个,大家有好用的hexo写博客工具可以推荐个。
默认情况下,生成的博文目录会显示全部的文章内容,如何设置文章摘要的长度呢?
答案是在合适的位置加上<!--more-->
即可,例如:
# 前言 使用github pages服务搭建博客的好处有: 1. 全是静态文件,访问速度快;2. 免费方便,不用花一分钱就可以搭建一个*的个人博客,不需要服务器不需要后台;3. 可以随意绑定自己的域名,不仔细看的话根本看不出来你的网站是基于github的; <!--more--> 4. 数据绝对安全,基于github的版本管理,想恢复到哪个历史版本都行;5. 博客内容可以轻松打包、转移、发布到其它平台;6. 等等;
最终效果:
4. 添加Gitalk评论系统
Gitalk 是一个基于 GitHub Issue 和 Preact 开发的评论插件。支持在前端直接引入,不需要任何后端代码,可以在页面进行登录、查看、评论、点赞等操作,同时有完整的 Markdown / GFM 和代码高亮支持,尤为适合各种基于 GitHub Pages 的静态博客或项目页面。缺点是只能使用 GitHub 账号进行评论。
本部分内容参考自:Git博客Hexo+Yilia主题设置gitalk评论功能,在此向大佬们表示感谢。
4.1 注册 OAuth Application
在 GitHub 上注册一个新的 OAuth Application。
注意,一定要是 OAuth Application,不是Github Application,笔者曾经不注意搞错了,导致配置出错,初始化评论。
前面3项内容都可以随意填写,但要确保最后一个 Authorization callback URL
是你的网站域名(比如http://www.wangxingfeng.com)。成功注册之后,你将会得到一个 client ID 和一个 client secret,这个将被用于之后的实例化 Gitment。
4.2 配置Gitalk
在yilia主题下的_config.yml文件中配置代码,注意冒号后面都有一个空格:
#6、配置gitalkgitalk: enable: true client_id: OAuth application注册成功获得 client_secret: OAuth application注册成功获得 repo: 存储博客评论的仓库地址,可以是存储博客的仓库 owner: github账户名 admin: github账户名
下载gitalk项目,点这里
拷贝gitalk/dist/目录下的gitalk.css和gitalk.min.js到yilia/source/lib/gitalk目录(没有的话新建文件)
在yilia主题下的>>layout>>_partial>>post文件夹下新建文件gitalk.ejs,复制代码,这里笔者增加了md5方法,确保id长度不超过50:
<div class="gitalk" style="margin:30px"> <div id="gitalk-container"></div> <script type="text/javascript"> function md5(md5str) { var createMD5String = function(string) { var x = Array() var k, AA, BB, CC, DD, a, b, c, d var S11 = 7, S12 = 12, S13 = 17, S14 = 22 var S21 = 5, S22 = 9, S23 = 14, S24 = 20 var S31 = 4, S32 = 11, S33 = 16, S34 = 23 var S41 = 6, S42 = 10, S43 = 15, S44 = 21 string = uTF8Encode(string) x = convertToWordArray(string) a = 0x67452301 b = 0xEFCDAB89 c = 0x98BADCFE d = 0x10325476 for (k = 0; k < x.length; k += 16) { AA = a BB = b CC = c DD = d a = FF(a, b, c, d, x[k + 0], S11, 0xD76AA478) d = FF(d, a, b, c, x[k + 1], S12, 0xE8C7B756) c = FF(c, d, a, b, x[k + 2], S13, 0x242070DB) b = FF(b, c, d, a, x[k + 3], S14, 0xC1BDCEEE) a = FF(a, b, c, d, x[k + 4], S11, 0xF57C0FAF) d = FF(d, a, b, c, x[k + 5], S12, 0x4787C62A) c = FF(c, d, a, b, x[k + 6], S13, 0xA8304613) b = FF(b, c, d, a, x[k + 7], S14, 0xFD469501) a = FF(a, b, c, d, x[k + 8], S11, 0x698098D8) d = FF(d, a, b, c, x[k + 9], S12, 0x8B44F7AF) c = FF(c, d, a, b, x[k + 10], S13, 0xFFFF5BB1) b = FF(b, c, d, a, x[k + 11], S14, 0x895CD7BE) a = FF(a, b, c, d, x[k + 12], S11, 0x6B901122) d = FF(d, a, b, c, x[k + 13], S12, 0xFD987193) c = FF(c, d, a, b, x[k + 14], S13, 0xA679438E) b = FF(b, c, d, a, x[k + 15], S14, 0x49B40821) a = GG(a, b, c, d, x[k + 1], S21, 0xF61E2562) d = GG(d, a, b, c, x[k + 6], S22, 0xC040B340) c = GG(c, d, a, b, x[k + 11], S23, 0x265E5A51) b = GG(b, c, d, a, x[k + 0], S24, 0xE9B6C7AA) a = GG(a, b, c, d, x[k + 5], S21, 0xD62F105D) d = GG(d, a, b, c, x[k + 10], S22, 0x2441453) c = GG(c, d, a, b, x[k + 15], S23, 0xD8A1E681) b = GG(b, c, d, a, x[k + 4], S24, 0xE7D3FBC8) a = GG(a, b, c, d, x[k + 9], S21, 0x21E1CDE6) d = GG(d, a, b, c, x[k + 14], S22, 0xC33707D6) c = GG(c, d, a, b, x[k + 3], S23, 0xF4D50D87) b = GG(b, c, d, a, x[k + 8], S24, 0x455A14ED) a = GG(a, b, c, d, x[k + 13], S21, 0xA9E3E905) d = GG(d, a, b, c, x[k + 2], S22, 0xFCEFA3F8) c = GG(c, d, a, b, x[k + 7], S23, 0x676F02D9) b = GG(b, c, d, a, x[k + 12], S24, 0x8D2A4C8A) a = HH(a, b, c, d, x[k + 5], S31, 0xFFFA3942) d = HH(d, a, b, c, x[k + 8], S32, 0x8771F681) c = HH(c, d, a, b, x[k + 11], S33, 0x6D9D6122) b = HH(b, c, d, a, x[k + 14], S34, 0xFDE5380C) a = HH(a, b, c, d, x[k + 1], S31, 0xA4BEEA44) d = HH(d, a, b, c, x[k + 4], S32, 0x4BDECFA9) c = HH(c, d, a, b, x[k + 7], S33, 0xF6BB4B60) b = HH(b, c, d, a, x[k + 10], S34, 0xBEBFBC70) a = HH(a, b, c, d, x[k + 13], S31, 0x289B7EC6) d = HH(d, a, b, c, x[k + 0], S32, 0xEAA127FA) c = HH(c, d, a, b, x[k + 3], S33, 0xD4EF3085) b = HH(b, c, d, a, x[k + 6], S34, 0x4881D05) a = HH(a, b, c, d, x[k + 9], S31, 0xD9D4D039) d = HH(d, a, b, c, x[k + 12], S32, 0xE6DB99E5) c = HH(c, d, a, b, x[k + 15], S33, 0x1FA27CF8) b = HH(b, c, d, a, x[k + 2], S34, 0xC4AC5665) a = II(a, b, c, d, x[k + 0], S41, 0xF4292244) d = II(d, a, b, c, x[k + 7], S42, 0x432AFF97) c = II(c, d, a, b, x[k + 14], S43, 0xAB9423A7) b = II(b, c, d, a, x[k + 5], S44, 0xFC93A039) a = II(a, b, c, d, x[k + 12], S41, 0x655B59C3) d = II(d, a, b, c, x[k + 3], S42, 0x8F0CCC92) c = II(c, d, a, b, x[k + 10], S43, 0xFFEFF47D) b = II(b, c, d, a, x[k + 1], S44, 0x85845DD1) a = II(a, b, c, d, x[k + 8], S41, 0x6FA87E4F) d = II(d, a, b, c, x[k + 15], S42, 0xFE2CE6E0) c = II(c, d, a, b, x[k + 6], S43, 0xA3014314) b = II(b, c, d, a, x[k + 13], S44, 0x4E0811A1) a = II(a, b, c, d, x[k + 4], S41, 0xF7537E82) d = II(d, a, b, c, x[k + 11], S42, 0xBD3AF235) c = II(c, d, a, b, x[k + 2], S43, 0x2AD7D2BB) b = II(b, c, d, a, x[k + 9], S44, 0xEB86D391) a = addUnsigned(a, AA) b = addUnsigned(b, BB) c = addUnsigned(c, CC) d = addUnsigned(d, DD) } var tempValue = wordToHex(a) + wordToHex(b) + wordToHex(c) + wordToHex(d) return tempValue.toLowerCase() } var rotateLeft = function(lValue, iShiftBits) { return (lValue << iShiftBits) | (lValue >>> (32 - iShiftBits)) } var addUnsigned = function(lX, lY) { var lX4, lY4, lX8, lY8, lResult lX8 = (lX & 0x80000000) lY8 = (lY & 0x80000000) lX4 = (lX & 0x40000000) lY4 = (lY & 0x40000000) lResult = (lX & 0x3FFFFFFF) + (lY & 0x3FFFFFFF) if (lX4 & lY4) return (lResult ^ 0x80000000 ^ lX8 ^ lY8) if (lX4 | lY4) { if (lResult & 0x40000000) return (lResult ^ 0xC0000000 ^ lX8 ^ lY8) else return (lResult ^ 0x40000000 ^ lX8 ^ lY8) } else { return (lResult ^ lX8 ^ lY8) } } var F = function(x, y, z) { return (x & y) | ((~x) & z) } var G = function(x, y, z) { return (x & z) | (y & (~z)) } var H = function(x, y, z) { return (x ^ y ^ z) } var I = function(x, y, z) { return (y ^ (x | (~z))) } var FF = function(a, b, c, d, x, s, ac) { a = addUnsigned(a, addUnsigned(addUnsigned(F(b, c, d), x), ac)) return addUnsigned(rotateLeft(a, s), b) } var GG = function(a, b, c, d, x, s, ac) { a = addUnsigned(a, addUnsigned(addUnsigned(G(b, c, d), x), ac)) return addUnsigned(rotateLeft(a, s), b) } var HH = function(a, b, c, d, x, s, ac) { a = addUnsigned(a, addUnsigned(addUnsigned(H(b, c, d), x), ac)) return addUnsigned(rotateLeft(a, s), b) } var II = function(a, b, c, d, x, s, ac) { a = addUnsigned(a, addUnsigned(addUnsigned(I(b, c, d), x), ac)) return addUnsigned(rotateLeft(a, s), b) } var convertToWordArray = function(string) { var lWordCount var lMessageLength = string.length var lNumberOfWordsTempOne = lMessageLength + 8 var lNumberOfWordsTempTwo = (lNumberOfWordsTempOne - (lNumberOfWordsTempOne % 64)) / 64 var lNumberOfWords = (lNumberOfWordsTempTwo + 1) * 16 var lWordArray = Array(lNumberOfWords - 1) var lBytePosition = 0 var lByteCount = 0 while (lByteCount < lMessageLength) { lWordCount = (lByteCount - (lByteCount % 4)) / 4 lBytePosition = (lByteCount % 4) * 8 lWordArray[lWordCount] = (lWordArray[lWordCount] | (string.charCodeAt(lByteCount) << lBytePosition)) lByteCount++ } lWordCount = (lByteCount - (lByteCount % 4)) / 4 lBytePosition = (lByteCount % 4) * 8 lWordArray[lWordCount] = lWordArray[lWordCount] | (0x80 << lBytePosition) lWordArray[lNumberOfWords - 2] = lMessageLength << 3 lWordArray[lNumberOfWords - 1] = lMessageLength >>> 29 return lWordArray } var wordToHex = function(lValue) { var WordToHexValue = '', WordToHexValueTemp = '', lByte, lCount for (lCount = 0; lCount <= 3; lCount++) { lByte = (lValue >>> (lCount * 8)) & 255 WordToHexValueTemp = '0' + lByte.toString(16) WordToHexValue = WordToHexValue + WordToHexValueTemp.substr(WordToHexValueTemp.length - 2, 2) } return WordToHexValue } var uTF8Encode = function(string) { string = string.toString().replace(/\x0d\x0a/g, '\x0a') var output = '' for (var n = 0; n < string.length; n++) { var c = string.charCodeAt(n) if (c < 128) { output += String.fromCharCode(c) } else if ((c > 127) && (c < 2048)) { output += String.fromCharCode((c >> 6) | 192) output += String.fromCharCode((c & 63) | 128) } else { output += String.fromCharCode((c >> 12) | 224) output += String.fromCharCode(((c >> 6) & 63) | 128) output += String.fromCharCode((c & 63) | 128) } } return output } return createMD5String(md5str) } const gitalk = new Gitalk({ clientID: '<%=theme.gitalk.client_id%>', clientSecret: '<%=theme.gitalk.client_secret%>', repo: '<%=theme.gitalk.repo%>', owner: '<%=theme.gitalk.owner%>', admin: ['<%=theme.gitalk.admin%>'], id: md5(location.pathname), // Ensure uniqueness and length less than 50 distractionFreeMode: false // Facebook-like distraction free mode }) gitalk.render('gitalk-container') </script></div>
在yilia主题下的>>layout>>_partial>>article.ejs文件中添加代码:
<% if (!index && theme.gitalk.enable && post.comments){ %><%- partial('post/gitalk', { key: post.slug, title: post.title, url: config.url+url_for(post.path) }) %><% } %>
在yilia主题下的layout>>_partial>>head.ejs文件中添加代码:
<% if (theme.gitalk.enable){ %> <link rel="stylesheet" href="/lib/gitalk/gitalk.css"> <script src="/lib/gitalk/gitalk.min.js"></script><% } %>
您将会在对应的仓库下的Issues选项卡中看到下述内容:
---------------------
作者:CallMeJacky
来源:CSDN
原文:https://blog.csdn.net/zyxhangiian123456789/article/details/101797464
版权声明:本文为作者原创文章,转载请附上博文链接!
内容解析By:CSDN,CNBLOG博客文章一键转载插件
上一篇: (二)Hexo-个人之博客主题美化
下一篇: KITTI数据集之点云建图