博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
利用Django徒手写个静态页面生成工具
阅读量:4513 次
发布时间:2019-06-08

本文共 4591 字,大约阅读时间需要 15 分钟。

每个Geek对折腾自己的博客都有着一份执念

背景介绍

曾经多次在不同的平台写博客,但全部都以失败而告终。去年七月选择微信公众号做为平台开始了又一次的技术分享,庆幸一直坚持到现在,但随着文章发表的越来越多,发现公众号对于PC端很不友好,文章列表没有PC端入口,查看分享很不方便,所以就利用github pages搭建了一个的网站,分类展示公众号内发表的所有文章以及一些未在公众号发表的琐碎内容

为了追求极速的浏览体验,整个网站采用纯静态的方式构建,这里的静态并不是像Jekyll或者Hexo之类的静态博客框架,而是手写HTML,页面少的时候还能应对,但随着页面越来越多,维护这些内容就成了灾难,好在对Django比较熟悉,于是便动手写了这么一个静态博客页面生成工具

主要功能

网站非常简单,只有三类页面,主页、文章列表页和文章详情页

  • 主页用来分类展示公众号内的文章列表
  • 文章列表页用来展示网站内文章(一些琐碎的未在公众号发表的文章)的列表
  • 文章详情页用来展示具体文章的内容

基于以上的内容分析,其实只需要做两个后台页面,包含几个小功能,画个思维导图

20190525.blog.png

首页为什么要去读取JSON文件呢?主要是因为运维咖啡吧的小程序也同时依赖这个JSON文件,修改一个地方避免维护多份数据

最终实现的效果如下图

20190525.blog.gif

接下来介绍下实现这些功能用到的技术或组件

所用技术

读取及写入文件

from django.conf import settingsclass FileRun:    def __init__(self):        self.file = settings.BASE_DIR + '/ops_coffee/backends/blog.json'    def read(self):        try:            with open(self.file, 'r', encoding='utf8') as f:                return True, f.read()        except Exception as e:            return False, str(e)    def write(self, content):        try:            with open(self.file, 'w', encoding='utf8') as f:                return True, f.write(content)        except Exception as e:            return False, str(e)

读取及写入文件的操作与Django的View没有太大的关系,所以这里我用了一个单独的类来处理,解释下其中的四个用法

  1. 本地文件路径不要硬编码到代码中,尽量采用settings.BASE_DIR相对路径,或者直接将路径以变量的形式写入到settings文件,例如我们后边要说的生成本地文件的目录就直接在settings中添加了一个变量OPS_COFFEE_GIT_DIR

  2. 每个方法返回两个参数状态和数据return True,data,这样在调用这个方法的时候就可以很方便的判断出来这个方法是执行成功还是失败,例如如下代码

state, data = FileRun().read()if state:    return(data)
  1. 读取文件使用with方法可以在你读取结束后自动执行f.close()关闭文件,避免因打开文件过多造成的资源消耗

  2. 使用try来避免程序直接抛错,有错误处理机制

JSON格式化

为了展示好看且能实现语法错误提示,采用了jsoneditor插件,这是一个前端的插件,使用非常简单

JSON Editor 可以用来查看、编辑、格式化和验证JSON,支持多种模式,例如tree、code、text,当为tree模式时显示树状结构,当为text时显示纯文本,我们这里采用了code模式有行号和颜色,看起来更美观

safe django从view向template传递HTML数据的时候,为了防止html中包含恶意攻击的代码django默认不会渲染HTML,所以需要在template接收到html数据后添加|safe进行渲染

生成HTML

观察会发现整个网站里所有的页面除了中间的内容区域之外,其他的地方都一样,所以我们只需要考虑替换中间的内容就可以了,实际上为了SEO等我们还需要替换title等数据

替换内容生成html文件这里使用了jinja2,我有尝试直接用django的template来渲染,但最终有一些编码问题没有解决,还是采用了jinja2,代码如下

from jinja2 import Templatefrom django.conf import settingstmpl = """  
{<div></div> { title }}

运维咖啡吧

追求技术的道路上,我从不曾停下脚步

{% if havet %}

{
{ title }}

{% endif %} {
{ content }}
"""kwargs = { "havet": 0, "title": "运维咖啡吧", "description": "追求技术的道路上,我从不曾停下脚步", "content": content}_content = Template(tmpl).render(kwargs)with open(self.blogDir + '/index.html', 'w', encoding='utf8') as f: f.write(_content)

tmpl 定义了一个模版,模版内可以使用诸如{

{ title }}这样的变量或是{% if havet %}这样的语法

kwargs 定义了一个字典,字典的内容用来替换模版中的变量,字典的key值与模版里边的变量做匹配,匹配到了就用字典的value填充模版

**_content** 就是最终html的内容,Template(tmpl).render(kwargs)会将kwargs的每个key值与模版中的变量做替换

最后会将html内容写入到html文件

上传GitHub

网站使用github pages搭建,最后需要将生成的html文件上传到github,这里我们使用了gitpython库,gitpython库的用法跟原生git的命令非常像,只是命令中间以.连接

最佳的自动上传步骤应该是:

  1. 本地生成ssh密钥,并将公钥上传至github,实现本机与ssh之间的无密码上传下载
  2. 本地创建网站目录,这个目录需要跟settings里边的OPS_COFFEE_GIT_DIR变量一致,方便直接将html文件生成在这个目录下
  3. 进入网站目录并使用git clone拉取github上的代码,注意这里应选择ssh协议的url,例如:git clone git@github.com:ops-coffee/demo.git .,且确定无需输入账号密码即可拉取
  4. 然后就可以使用以下程序实现自动上传更新到github了,也就是在跑本文所讲的这个生成工具之前需要先做好以上三步
from git import Repofrom django.conf import settingsclass GitRun:    def __init__(self):        self.repo = Repo(settings.OPS_COFFEE_GIT_DIR)    def push(self):        try:            self.repo.git.add(A=True)            self.repo.index.commit('ops-coffee')            self.repo.remote(name='origin').push()            return True, True        except Exception as e:            return False, str(e)

Repo() 选择已有的git仓库

git.add 添加本地修改到暂存区,A=True添加到暂存区时包含删除文件的修改

index.commit 提交修改到本地仓库,我这里比较粗糙,统一使用ops-coffee做为log

repo.remote().push() 选择远程分支并提交,name参数表示远程分支的名字

登陆登出

虽然是个简单的个人系统,但最基本的用户认证还是要有的,没有用Django默认的admin页面,但还想使用django提供的auth系统实现登陆登出的话,可以采用下边这种方式

from django.urls import pathfrom django.contrib.auth.views import LoginView, LogoutViewurlpatterns = [    path('login', LoginView.as_view(template_name='login.html'), name='login-url'),    path('logout', LogoutView.as_view(template_name='login.html'), name='logout-url'),]

django.contrib.auth.views下导入LoginViewLogoutView,然后写两条url并指定自己的模版位置就可以使用django的登陆登出功能了,这在一些需要简单认证的系统中非常方便

写在最后

不断折腾的过程才是成长最快的过程,用技术来解决实际的问题是对技术最好的应用

如果你对本篇文章的完整源码感兴趣,可以在微信公众号后台回复“05”获取,当然也非常欢迎加我个人微信一起学习交流


oa.qrcode.png

相关文章推荐阅读:

转载于:https://www.cnblogs.com/37Y37/p/10935897.html

你可能感兴趣的文章
利用node搭建本地服务器
查看>>
python pickle命令执行与marshal 任意代码执行
查看>>
Elasticsearch 2.3 java api
查看>>
golang写入csv
查看>>
基础2
查看>>
java基础篇---网络编程(UDP程序设计)
查看>>
Kafka Producer相关代码分析【转】
查看>>
LeetCode 121. Best Time to Buy and Sell Stock
查看>>
麻省理工学院公开课-第四讲:快速排序 及 随机化 算法
查看>>
复杂表达式
查看>>
R12.1.3 & R12.2.X 注册客户化应用
查看>>
实验十七 线程同步控制
查看>>
SQL Server 触发器
查看>>
Ural 1146 Maximum Sum(DP)
查看>>
《STL源代码分析》---stl_stack.h读书笔记
查看>>
UVA 10385 - Duathlon(三分法)
查看>>
div同时使用两个class
查看>>
在路上,三线城市互联网创业记录
查看>>
spark 编译遇到的错误及解决办法(五)
查看>>
框架篇: React + React-Router + antd + nodejs + express框架开发运用(nodejs做前后端server)...
查看>>