1 选择模板
选择一个好的开源项目作为模板是成功的三十九分之七
经过简单筛选,初步敲定DjangoBlog作为个人网站模板。因为本人比较熟悉Python和Django,上手快,其次就是此项目功能丰富,支持docker部署,画面简约,作者负责(长期维护)。
2 部署模板
为了以后迁移方便,本人选择7_software/Docker/Docker 快速上手部署
部署过程参考了使用docker部署DjangoBlog,并顺带安装了MySQL和ElasticSearch,具体语法如下:
# 克隆项目
git clone https://github.com/liangliangyy/DjangoBlog
cd DjangoBlog
# 基于docker-compose构建多容器
docker-compose -f docker-compose.yml -f docker-compose.es.yml build
docker-compose -f docker-compose.yml -f docker-compose.es.yml up -d
# 多容器启动:将分别启动mysql、memached、nginx和djangoblog四个容器
docker-compose up -d
# 第一次启动时,创建超级用户
docker exec -it djangoblog python /code/DjangoBlog/manage.py createsuperuser
3 配置远程开发环境
- 关掉容器服务,修改相关配置文件
docker stop djangoblog
cd /var/lib/docker/containers/容器ID
vi hostconfig.json
vi config.v2.json
在文件hostconfig.json
中增加下列内容
,"22/tcp":[{"HostIp":"","HostPort":"10022"}]
在文件config.v2.json
中增加下列内容
,"22/tcp":{}
- 重启docker服务并检验端口配置
service docker restart
# 查看容器是否正常启动,端口是否配置成功
docker ps -a
- 进入容器配置SSH服务
# 进入容器
docker exec -it djangoblog bash
# 安装ssh服务
apt update && apt install -y --no-install-recommends openssh-server
# 安装过程中发现此容器没有vim, 安装一下
apt-get install vim
# 添加PermitRootLogin yes
vi /etc/ssh/sshd_config
# 修改root密码
passwd
# 重启ssh服务并检验状态
service ssh restart
service ssh status
- 为本地VSCODE配置
Remote-SSH
插件,然后连接远程服务器ssh root@IP地址 -p 10022
4 模板主要功能配置
4.1 缓存:
缓存默认使用memcache
缓存,如果你没有memcache
环境,则将settings.py
中的locmemcache
改为default
,并删除默认的default
配置即可。
CACHES = {
'default': {
'BACKEND': 'django.core.cache.backends.memcached.MemcachedCache',
'LOCATION': '127.0.0.1:11211',
'KEY_PREFIX': 'django_test' if TESTING else 'djangoblog',
'TIMEOUT': 60 * 60 * 10
},
'locmemcache': {
'BACKEND': 'django.core.cache.backends.locmem.LocMemCache',
'TIMEOUT': 10800,
'LOCATION': 'unique-snowflake',
}
}
4.2 oauth登录:
已配置QQ,Google,GitHub的登录:2 Auth授权登录
4.3 owntracks(待配置):
owntracks是一个位置追踪软件,可以定时的将你的坐标提交到你的服务器上,现在简单的支持owntracks功能,需要安装owntracks的app,然后将api地址设置为:
你的域名/owntracks/logtracks
就可以了。然后访问你的域名/owntracks/show_dates
就可以看到有经纬度记录的日期,点击之后就可以看到运动轨迹了。地图是使用高德地图绘制。
4.4 邮件功能:
同样,将settings.py
中的ADMINS = [('erebus', '[email protected])]
配置为你自己的错误接收邮箱,另外修改:
EMAIL_HOST = 'smtp.qq.com'
EMAIL_PORT = 465
EMAIL_HOST_USER = '[email protected]'
EMAIL_HOST_PASSWORD = 'xxxx xxxx xxxx xxxx' # 邮箱授权码
DEFAULT_FROM_EMAIL = EMAIL_HOST_USER
SERVER_EMAIL = EMAIL_HOST_USER
为你自己的邮箱配置。
4.5 微信公众号(待配置)
集成了简单的微信公众号功能,在微信后台将token地址设置为:你的域名/robot
即可,默认token为lylinux
,当然你可以修改为你自己的,在servermanager/robot.py
中。
然后在后台->Servermanager->命令中新增命令,这样就可以使用微信公众号来管理了。
4.6 网站配置介绍
在后台->BLOG->网站配置中,可以新增网站配置,比如关键字,描述等,以及谷歌广告,网站统计代码及备案号等等。
其中的静态文件保存地址是保存oauth用户登录的头像路径,填写绝对路径,默认是代码目录。
4.7 MySQL数据库
修改原始密码
修改配置信息
DATABASES = {
'default': {
'ENGINE': 'django.db.backends.mysql',
'NAME': 'djangoblog',# 数据库名称
'USER': 'root',# 用户
'PASSWORD': '******',# 密码
'HOST': 'db',# mysql容器名称
'PORT': 3306,
'OPTIONS': {
'charset': 'utf8mb4'},
}}
5 模板文件结构说明
- account:账号相关功能(登录、注册、密码找回)
- bin:基础脚本(docker、django启动脚本;nginx配置文件)
- blog:文章相关功能(分类、标题、正文、作者、标签等等)
- collectedstatic:静态文件存储汇总
- comments:评论相关功能
- DjangoBlog:项目配置文件和辅助功能函数
- oauth:第三方认证登录相关功能
- owntracks:个人经纬度记录与展示(非公开)
- servermanager:公众号服务和邮件服务
- templates:页面模板
- uploads:上传的静态文件
6 自定义美化
6.1 markdown样式
blog/static/blog/css/style.css
.entry-content blockquote
:设置引用块内样式
.entry-content code
:设置单引号内样式
.entry-content pre
:设置代码块内样式
6.2 添加mistune新特性和对Latex的渲染
- 本项目使用
mistune==0.8.4
模块用于对markdown
的支持,不过相关文档有点乱,有一个点一直调不通,而新版本的mistune
对结构进行了重构,文档也比较清晰,于是本人升级模块并进行了相关代码的更新:pip install --upgrade mistune==2.0.0rc1
主要增加了对删除线、引用、表格、任务清单、目录的解析
import mistune
from mistune.directives import DirectiveToc
from mistune.plugins import plugin_strikethrough, plugin_footnotes, plugin_table, plugin_task_lists
class CommonMarkdown():
@staticmethod
def get_markdown(value):
renderer = BlogMarkDownRenderer()
mdp = mistune.create_markdown(renderer=renderer, plugins=[plugin_strikethrough, plugin_footnotes, plugin_table, plugin_task_lists, DirectiveToc()])
return mdp(value)
mistune文档参考
2. 在templates/share_layout/base.html
的head部分加入以下语句,实现MathJax的整合:
<script type="text/x-mathjax-config">
MathJax.Hub.Config({
showProcessingMessages: false, //关闭js加载过程信息
messageStyle: "none", //不显示信息
extensions: ["tex2jax.js"],
jax: ["input/TeX", "output/HTML-CSS"],
tex2jax: {
inlineMath: [ ["$", "$"] ], //行内公式选择$
displayMath: [ ["$$","$$"] ], //段内公式选择$$
skipTags: ['script', 'noscript', 'style', 'textarea', 'pre','code','a'], //避开某些标签
ignoreClass:"comment-content" //避开含该Class的标签
},
"HTML-CSS": {
availableFonts: ["STIX","TeX"], //可选字体
showMathMenu: false //关闭右击菜单显示
}
});
MathJax.Hub.Queue(["Typeset",MathJax.Hub]);
</script>
<script src="//cdn.bootcss.com/mathjax/2.7.0/MathJax.js?config=TeX-AMS-MML_HTMLorMML"></script>
<link rel="dns-prefetch" href="//cdn.mathjax.org" />
7 本地与服务器文件夹同步
本小节主要通过七牛云图床和Python脚本实现了本地图片和小文件的存储
然后通过Syncthing进行本地和服务器之间的文件夹同步
7.1 图片云存储
- 首先进入DNS解析页面,点击
解析
设置二级域名
配置图片的SSL安全连接:
- 在腾讯云申请SSL证书,注意二级域名对应,然后下载Nginx类型的证书文件
- 进入七牛云管理控制台,点击 “上传自有证书”
- 复制 .crt 或者 .pem 后缀的文件内容到证书内容 (公钥)
- 复制 .key 后缀结尾的内容到 证书私钥
7.2 Syncthing文件夹同步
为已创建的容器新增共享文件夹
- 在文件
hostconfig.json
中修改或增加Binds
的内容,格式是 "主机目录:容器目录",以将容器文件夹/data/share
与服务器文件夹/data/share
共享为例:["/data/share:/data/share"]
- 在文件
config.v2.json
中修改或增加MountPoints
的内容,以将容器文件夹/data/share
与服务器文件夹/data/share
共享为例,具体格式如下:
"MountPoints":{"/data/share":{"Source":"/data/share","Destination":"/data/share","RW":true,"Name":"","Driver":"","Type":"bind","Propagation":"rprivate","Spec":{"Type":"bind","Source":"/data/share","Target":"/data/share"}}}
7.3 安装并启动Syncthing
本地电脑是Windows系统,因此采用了Windows安装
远程服务器是Linux系统,并且已经配置了Docker环境,所以采用了Docker安装
docker pull syncthing/syncthing
docker run -d -p 8384:8384 -p 22000:22000/tcp -p 22000:22000/udp \
-v /data/share:/var/syncthing \
--hostname=my-syncthing \
--name=obsidian_sync \
syncthing/syncthing:latest
注意设备间需要开放端口:
- TCP:22000 用于同步文件
- UDP:21027 用于服务发现
然后两个Syncthing服务之间互相添加为远程设备,并且在选择共享Obsidian项目文件夹
7.4 参考链接
这样用七牛,插图优雅又省心 · MarkDown 码字发文最佳实践
8 添加本地md文件的读取功能
在尽量不改动源代码的基础上,批量读取md文件并作为文章录入
新增代码主要替代BLOG的添加功能,具体来说包括全量导入
和增量导入
两部分
涉及数据库中表为文章分类表blog_category
、文章详情表blog_article
、文章标签表blog_article_tags
、标签总表blog_tag
8.1 全量导入
- 解析指定的obsidian文件夹,根据文件夹结构生成多级分类,录入文章分类表
- 解析各个文章中的标签,录入文章标签表,并汇总标签到set中后,录入标签总表
- 解析所有文件的元数据和内容,生成所需的标题、正文、创建时间、修改时间,录入文章详情表
- 解析新增md文件中的元数据和内容,录入文章详情表
8.2 增量导入
- 数据库查找所有文章中最近的更新时间
T
- 筛选obsidian文件夹中最新更改时间>
T
的新增文件夹和md文件 - 解析新增的文件夹,确定是否为新分类,是则录入文章分类表
- 解析新增md文件中的标签,录入文章标签表,如果存在新标签,录入标签总表
- 解析新增md文件中的元数据和内容,录入文章详情表
- 为md文件反向录入文章状态
status
以及文章唯一ID
8.3 两种导入的合并
两种导入方式的基本逻辑是一致的,以增量导入为通用逻辑,全量导入为T
很小情况的增量导入
8.4 读取配置
- 取md文件中的YAML结构信息作为配置(重要)
- 读取YAML结构信息中的文章唯一ID
- 读取YAML结构信息中的文章状态
status
8.5 过滤功能
- 过滤掉以
_index_of_
开头的md文件 - 修改原始文件中的图片链接为在线图片链接(重要)
- 过滤原始md文件中的YAML结构(重要)
- 过滤原始md文件中的
###{begin hide}### xxx ###{end hide}###
结构
9 细节补充
9.1 sitemaps
站点地图是你网站上的一个 XML 文件,它告诉搜索引擎索引器你页面的变化频率,以及某些页面相对于你网站上其他页面的“重要性”。这些信息有助于搜索引擎对你的网站进行索引。
Django 站点地图框架通过让你用 Python 代码表达这些信息以自动创建这个 XML 文件。
DjnagoBlog项目已经集成了Django自带的sitemap,默认自动开启,使用时只需要在管理页面-站点
中配置好相应域名即可
9.2 RSS Feed
RSS(简易信息聚合)是一种消息来源格式规范,用以聚合经常发布更新数据的网站,例如博客文章、新闻、音频或视频的网摘。RSS文件(或称做摘要、网络摘要、或频更新,提供到频道)包含全文或是节录的文字,再加上发布者所订阅之网摘数据和授权的元数据。
其实就是一种聚合阅读,这样可以用feedly等工具来订阅你喜欢的网站,这样他们的网站更新了之后你就可以通过feedly这种工具来阅读更新的内容,而不用跑到网站上面去查看。
DjnagoBlog项目已经集成了Django自带的Feed聚合框架,默认自动开启
9.3 针对mathjax与Latex兼容问题的修正
Latex公式内部分内容由于各种原因,网页端显示存在问题,进行针对性修正:
\!
需修正为\\!
\\
需修正为\\\\
\[3pt]
不支持 替换为\\\\
\left\{
需修正为\left\\{
9.4 修正TOC和小问题修复
2021.12.04-2021.12.05
- 重构TOC类,使得原始的数值型锚点改为文本型锚点
- 修正标题不统一的情况下不更新的问题
- 修复文章跳转问题,并增加跳转至指定目录的功能