每一个Geek对折腾本身的博客都有着一份执念css
曾经屡次在不一样的平台写博客,但所有都以失败而了结。去年七月选择微信公众号作为平台开始了又一次的技术分享,庆幸一直坚持到如今,但随着文章发表的愈来愈多,发现公众号对于PC端很不友好,文章列表没有PC端入口,查看分享很不方便,因此就利用github pages搭建了一个【运维咖啡吧】的网站,分类展现公众号内发表的全部文章以及一些未在公众号发表的琐碎内容html
为了追求极速的浏览体验,整个网站采用纯静态的方式构建,这里的静态并非像Jekyll或者Hexo之类的静态博客框架,而是手写HTML,页面少的时候还能应对,但随着页面愈来愈多,维护这些内容就成了灾难,好在对Django比较熟悉,因而便动手写了这么一个静态博客页面生成工具前端
网站很是简单,只有三类页面,主页、文章列表页和文章详情页python
基于以上的内容分析,其实只须要作两个后台页面,包含几个小功能,画个思惟导图git
首页为何要去读取JSON文件呢?主要是由于运维咖啡吧的小程序也同时依赖这个JSON文件,修改一个地方避免维护多份数据github
最终实现的效果以下图django
接下来介绍下实现这些功能用到的技术或组件json
from django.conf import settings class 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没有太大的关系,因此这里我用了一个单独的类来处理,解释下其中的四个用法小程序
本地文件路径不要硬编码到代码中,尽可能采用settings.BASE_DIR
相对路径,或者直接将路径以变量的形式写入到settings文件,例如咱们后边要说的生成本地文件的目录就直接在settings中添加了一个变量OPS_COFFEE_GIT_DIR
微信
每一个方法返回两个参数状态和数据return True,data
,这样在调用这个方法的时候就能够很方便的判断出来这个方法是执行成功仍是失败,例如以下代码
state, data = FileRun().read() if state: return(data)
读取文件使用with
方法能够在你读取结束后自动执行f.close()
关闭文件,避免因打开文件过多形成的资源消耗
使用try来避免程序直接抛错,有错误处理机制
为了展现好看且能实现语法错误提示,采用了jsoneditor
插件,这是一个前端的插件,使用很是简单
<div class="col-sm-12" id="jsoneditor" style="height:620px"></div>
<script src="/static/js/jsoneditor.min.js"></script> <script> // create the editor var container = document.getElementById("jsoneditor"); var editor = new JSONEditor(container, { mode: 'code' }); // set json editor.set({{ data|safe }}); </script>
JSON Editor 能够用来查看、编辑、格式化和验证JSON,支持多种模式,例如tree、code、text,当为tree模式时显示树状结构,当为text时显示纯文本,咱们这里采用了code模式有行号和颜色,看起来更美观
safe django从view向template传递HTML数据的时候,为了防止html中包含恶意攻击的代码django默认不会渲染HTML,因此须要在template接收到html数据后添加|safe
进行渲染
观察会发现整个网站里全部的页面除了中间的内容区域以外,其余的地方都同样,因此咱们只须要考虑替换中间的内容就能够了,实际上为了SEO等咱们还须要替换title等数据
替换内容生成html文件这里使用了jinja2,我有尝试直接用django的template来渲染,但最终有一些编码问题没有解决,仍是采用了jinja2,代码以下
from jinja2 import Template from django.conf import settings tmpl = """<!DOCTYPE html> <html lang="zh-CN"> <head> <meta name="theme-color" content="#2879d0" /> <meta http-equiv="Content-Type" content="text/html; charset=utf-8" /> <link rel="stylesheet" href="/css/style.min.css" media="screen" type="text/css" /> <title>{{ title }}</title> <meta property="og:title" content="{{ title }}" /> <meta property="og:description" content="{{ description }}" /> </head> <body> <header> <div class="inner"> <a href="https://ops-coffee.cn/"> <h1>运维咖啡吧</h1> </a> <h2>追求技术的道路上,我从未曾停下脚步</h2> </div> </header> <div id="content-wrapper"> <div class="inner clearfix"> <section id="main-content"> {% if havet %} <h1 id="art-title">{{ title }}</h1> {% endif %} {{ content }} </section> <aside id="sidebar"> <blockquote class="route">微信公众号</blockquote> <img border="0" src="/images/z-qrcode.jpg" width="100%" height="100%" alt="ops-coffee" /> <blockquote class="route">归档列表</blockquote> <div class="sidebar-list"><a href="/"> 精选文章列表</a></div> <div class="sidebar-list"><a href="/s/"> 平常运维记录</a></div> </aside> </div> </div> </body> </html> """ 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 pages搭建,最后须要将生成的html文件上传到github,这里咱们使用了gitpython
库,gitpython库的用法跟原生git的命令很是像,只是命令中间以.
链接
最佳的自动上传步骤应该是:
OPS_COFFEE_GIT_DIR
变量一致,方便直接将html文件生成在这个目录下git clone
拉取github上的代码,注意这里应选择ssh协议的url,例如:git clone git@github.com:ops-coffee/demo.git .
,且肯定无需输入帐号密码便可拉取from git import Repo from django.conf import settings class 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 path from django.contrib.auth.views import LoginView, LogoutView urlpatterns = [ 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
下导入LoginView
和LogoutView
,而后写两条url并指定本身的模版位置就可使用django的登录登出功能了,这在一些须要简单认证的系统中很是方便
不断折腾的过程才是成长最快的过程,用技术来解决实际的问题是对技术最好的应用
若是你对本篇文章的完整源码感兴趣,能够在微信公众号后台回复“05”获取,固然也很是欢迎加我我的微信一块儿学习交流
相关文章推荐阅读: