注意!!文章已过时,由于Hexo生成页面速度慢、页面多了还会爆内存,搭建方法也麻烦,已经不推荐用Hexo搭wiki,请参考另一篇使用MkDocs搭建的
为什么需要个人Wiki? 整理知识,数字时代前人们做纸制笔记、做剪报;现在普遍用博客做笔记、everynote做文章收藏。
工作学习中产生的笔记总会是零碎的片段,尴尬的是——博客本应是展示水平的地方,不适合放零散的笔记;everynote、有道云笔记之类的产品虽然收藏功能强大,但配不上它们作为“笔记”的名头,知识难以归类、编辑体验一般。
细化一下我们的需求:
方便编辑,增加文章必须简单;
词条的分类必须灵活,因为知识体系随着时间推移会越来越完善,之前的分类在一段时间后就不适用了;
需要用笔记时能快速提取,最好支持多种客户端。
纠结了很长一段时间,总算是组了一套找到了贴合这些需求的方案:用Hexo+Wiki模板做渲染,用文件夹组织层次结构,用Typora做Markdown编辑器,Webhook+CI服务器做自动构建、部署。
先展示一下成品:http://wiki.noodlefighter.com/
Github仓库:https://github.com/noodlefighter/wiki
多级目录:
全文搜索(生成静态索引,速度很快):
文件夹管理层次结构(而不是用Hexo默认的只能堆在一个post文件夹里),使用Typora作为Markdown编辑器:
目录结构 Wiki目录结构示例:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 . ├── hexo │ ├── _config .yml │ ├── package.json │ ├── scaffolds │ ├── source│ │ ├── about │ │ ├── categories │ │ ├── _post │ │ ├── robots.txt │ │ └── tags │ └── themes │ └── Wikitten ├── source ... │ └── 电子工程 │ ├── _assets │ │ └── mosfet │ ├── mosfet.md │ ├── 电子相关材料materials.md │ └── 嵌入式硬件 │ ├── 双核异构.md │ └── 总线技术.md ├── scripts │ └── do_copy.sh ├── generate.sh └── push.sh
重点在于重新设计了source文件夹的目录结构:
将hexo/source/_post
搬离到了hexo目录外命名为source
;
以目录层级表示文章分类层级,更好管理分类,修改分类只
重新定义资源文件夹的相对于Markdown间的路径:./_assets/<文件名>
,避免资源文件夹随着同级文章数成倍增加
布置Hexo Hexo是个基于Node.js的博客框架,准备好网页模板,放入用Markdown写的文章,它就能帮你生成静态页。
模板使用hexo-theme-Wikitte ,这个主题的作者和我想到一块了,我们需要一个Wiki知识库,十分感谢他实现了Hexo没有的重要功能——多级目录支持。
Hexo的部署请参考官方文档 ,大概是:
自动化脚本 为了实现用文件夹自然地组织Wiki目录层次,需要做个脚本辅助,实现以下功能:
从文章源码文件夹中提取.md文件
自动填写文章分类(即Wiki的层次结构)
自动填写对于零碎笔记来说并不重要的时间(从git log中提取)
提取_assets
文件夹中的图片,并把文章中的路径换成hexo的assets文件夹路径
generate.sh
,遍历source目录下所有.md
文件,调用do_copy
处理,并把生成文件copy到hexo的_posts
目录中:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 # !/bin/bash # # set -e SHELL_FOLDER=$(cd "$(dirname "$0")";pwd) SOURCE_FOLDER=$SHELL_FOLDER/source BUILD_FOLDER=$SHELL_FOLDER/build TARGET_FOLDER=$SHELL_FOLDER/hexo/source/_posts rm -rf $BUILD_FOLDER mkdir -p $BUILD_FOLDER echo "==============================" echo " generate file" echo "==============================" cd $SOURCE_FOLDER find -name "*.md" -print0|xargs -0 -i $SHELL_FOLDER/scripts/do_copy.sh {} $BUILD_FOLDER echo "==============================" echo " copy to _post" echo "==============================" mkdir -p $TARGET_FOLDER rm -vrf $TARGET_FOLDER/* cp -vr $BUILD_FOLDER/* $TARGET_FOLDER # call hexo cd $SHELL_FOLDER/hexo hexo g
scripts/do_copy.sh
处理指定的.md
:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 #!/bin/bash set -eSOURCE_FILE=$1 TARGET_DIR=$2 SOURCE_DIR=`dirname $SOURCE_FILE ` IFS='/' CGLIST=($1 ) IFS=' ' CGLIST_COUNT=${#CGLIST[*]} DIR_LAYER=`expr $CGLIST_COUNT - 2` FILENAME=${CGLIST[$CGLIST_COUNT-1]} FILENAME=${FILENAME%.*} STR_CGLIST='' STR_FILEPREFIX='' for ((i=1 ;i<=$DIR_LAYER ;i++));do CGNAME=${CGLIST[$i]} STR_FILEPREFIX=${STR_FILEPREFIX} ${CGNAME} '-' STR_CGLIST=$STR_CGLIST '- ' $CGNAME ' ' done TARGET_FILE=$TARGET_DIR /${STR_FILEPREFIX} ${CGLIST[`expr $CGLIST_COUNT - 1`]} STR_DATE=`git log --pretty=format:%ci ${SOURCE_FILE} |awk 'NR==1 {print $1}' ` echo "generating... ${FILENAME} " echo "title: ${FILENAME} date: ${STR_DATE} categories: $STR_CGLIST " > "$TARGET_FILE " cat "$SOURCE_FILE " >>"$TARGET_FILE " IMG_DIR_SOURCE="${SOURCE_DIR} /_assets/${FILENAME} " IMG_DIR_TARGET=${TARGET_DIR} /${STR_FILEPREFIX} ${FILENAME} if [[ -d "${IMG_DIR_SOURCE} " ]]; then cp -r $IMG_DIR_SOURCE $IMG_DIR_TARGET sed -i "s?\\!\\[\(\\S*\)\\](_assets/${FILENAME} /\(\S*\))?{% asset_img \2 \1 %}?g" $TARGET_FILE fi
另外,为了方便推送新文章到git仓库,这里做了个push.sh
,直接拉取最新新仓库、与本地仓库合并、提交:
1 2 3 4 5 6 7 8 9 10 11 12 #!/bin/bash set -eset -xSHELL_FOLDER=$(cd "$(dirname "$0 " ) " ;pwd ) cd $SHELL_FOLDER git add --all git commit -am "quick commit" git pull --rebase git push
P.S. 脚本写得很烂,但是能用,让一个不熟悉shell脚本的人写这玩意真会疯,特别是要用sed命令时。
执行效果:
例如,这是一个简单的文章source/日常/麻将/在意的牌谱.md
:
1 2 3 4 5 6 7 8 9 --- 记录在意的牌谱 {% asset_img 00_0.png img % } 问题:如上牌型,如果以成牌率优先,进了8索如何舍牌?
注意:上文实现的自动化脚本还没智能到识别Markdown文件是否存在分隔文章属性和正文的---
,所以需要手动加上
执行generate.sh
将生成hexo/source/_post/日常-麻将-在意的牌谱.md
,可以看到自动填上了文章信息以及改变了图片文件的路径:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 title: 在意的牌谱 date: 2019-06-09 categories: - 日常 - 麻将 --- 记录在意的牌谱 {% asset_img 00_0.png img % } 问题:如上牌型,如果以成牌率优先,进了8索如何舍牌?
Typora的配置 Typora是个优秀的Markdown编辑器,区别于一般的Markdown双栏编辑器,所见即所得,不需要预览的时候也可以切换到源代码模式,同时满足两派系需求。
这里需要修改插入图片时的相对路径./_assets/${filename}
,使自动插入的图片路径满足我们的规则:
设置后,插入图片时她会帮你把图片安放在我们期待的位置:
Webhook+CI自动构建 笔者是自己在服务器上做了个Webhook服务器,收到Push Event后执行自动构建、部署,感兴趣可以看这篇 。
但不建议这样做,因为有免费的CI服务器+现成的Github Page服务可以利用,建议尝试travis-ci ,仓库更新时自动触发部署到Github的page服务上,deploy步骤可以用hexo的git功能 。
最后是使用方法 工作流是这样的:
需要增加分类或文章时,直接在source
目录里增加文件夹或.md
文件
完成编辑后,执行./push.sh
git仓库向CI服务器发送Webhook事件,CI服务器开始构建,构建完成后部署到Web服务器
最后吐槽一句,别在CSDN上写笔记了,谢谢,希望能抛砖引玉。