采用jinja2重构html模板,方便后续添加不同的主题

This commit is contained in:
Meekdai 2023-08-12 13:14:36 +08:00
parent a0deea4584
commit 2b51bb1ce7
12 changed files with 271 additions and 350 deletions

206
Gmeek.js
View File

@ -1,33 +1,4 @@
if(typeof(blogBase["subTitle"])=='undefined'){htmlType="post";}
else{htmlType="plist";}
var i18nEN=["switch theme","Run "," days","links","about me","Search","Home","Comments","Loading"];
var i18nCN=["切换主题", "网站运行","天","友情链接","关于", "搜索", "首页", "评论", "加载中"];
if(blogBase["i18n"]=="CN"){var i18n=i18nCN;}
else{var i18n=i18nEN;}
if(blogBase["startSite"]!=""){
var now=new Date();
var startSite=new Date(blogBase["startSite"]);
var diff=now.getTime()-startSite.getTime();
var diffDay=Math.floor(diff/(1000*60*60*24));
document.getElementById("year").innerHTML=now.getFullYear();
document.getElementById("runday").innerHTML=i18n[1]+diffDay+i18n[2]+" • ";
}
if(blogBase["filingNum"]!=""){document.getElementById("filingNum").innerHTML=blogBase["filingNum"]+" • ";}
document.getElementById("footerblogTitle").innerHTML=blogBase["title"];
document.getElementById("footerblogTitle").href=blogBase["homeUrl"];
if(blogBase["faviconUrl"]!=""){
link=document.createElement("link");
link.setAttribute("rel","icon");
link.setAttribute("href",blogBase["faviconUrl"]);
document.head.appendChild(link);
}
document.getElementById("changeTheme").setAttribute("title",i18n[0]);
document.getElementById("themeSwitch").setAttribute("d",value=IconList["sun"]);
if(localStorage.getItem("meek_theme")==null){localStorage.setItem("meek_theme","light")}
else if(localStorage.getItem("meek_theme")=="dark"){changeDark();}
@ -58,144 +29,45 @@ function utterancesTheme(theme){
iframe.contentWindow.postMessage(message, 'https://utteranc.es');
}
console.log("\n %c Gmeek "+blogBase["GMEEK_VERSION"]+" %c https://github.com/Meekdai/Gmeek \n\n", "color: #fff; background-image: linear-gradient(90deg, rgb(47, 172, 178) 0%, rgb(45, 190, 96) 100%); padding:5px 1px;", "background-image: linear-gradient(90deg, rgb(45, 190, 96) 0%, rgb(255, 255, 255) 100%); padding:5px 0;");
if(htmlType=="plist"){
var postListJson=blogBase["postListJson"];
document.title=blogBase["title"];
document.getElementById("avatarImg").src=blogBase["avatarUrl"];
document.getElementById("blogTitle").innerHTML=blogBase["displayTitle"];
document.getElementById("blogSubTitle").innerHTML=blogBase["subTitle"];
document.getElementById("searchSite").setAttribute("value","site:"+blogBase["homeUrl"]);
document.getElementById("buttonRSS").childNodes[0].childNodes[0].setAttribute("d",value=IconList["rss"]);
document.getElementById("buttonLink").setAttribute("title",i18n[3]);
document.getElementById("buttonAbout").setAttribute("title",i18n[4]);
document.getElementById("buttonSearch").innerHTML=i18n[5];
document.getElementById("searchSVG").setAttribute("d",value=IconList["search"]);
var navList=document.getElementById("navList");
for(var num in postListJson){
if(blogBase["singlePage"].indexOf(postListJson[num]["label"])==-1){
SideNavItem=document.createElement("a");
SideNavItem.setAttribute("class", "SideNav-item d-flex flex-items-center flex-justify-between");
SideNavItem.setAttribute("href", postListJson[num]["postUrl"]);
div=document.createElement("div");
svg=document.createElementNS('http://www.w3.org/2000/svg','svg');
path=document.createElementNS("http://www.w3.org/2000/svg","path");
span=document.createElement("span");
div.setAttribute("class","d-flex flex-items-center");
svg.setAttributeNS(null,"class","SideNav-icon octicon");
if(postListJson[num]["top"]==0){
svg.setAttributeNS(null,"style","witdh:16px;height:16px");
path.setAttributeNS(null, "d", IconList["post"]);
}
else{
svg.setAttributeNS(null,"style","witdh:16px;height:16px;color:red");
path.setAttributeNS(null, "d", IconList["upload"]);
}
span.innerHTML=postListJson[num]["postTitle"];
svg.appendChild(path);
div.appendChild(svg);
div.appendChild(span);
SideNavItem.appendChild(div);
div=document.createElement("div");
div.setAttribute("class","listLabels");
if(postListJson[num]["commentNum"]>0){
span=document.createElement("span");
span.setAttribute("class","Label");
span.setAttribute("style","background-color:"+blogBase["commentLabelColor"]);
span.innerHTML=postListJson[num]["commentNum"];
div.appendChild(span);
}
span=document.createElement("span");
span.setAttribute("class","Label");
span.setAttribute("style","background-color:"+postListJson[num]["labelColor"]);
span.innerHTML=postListJson[num]["label"];
div.appendChild(span);
span=document.createElement("span");
span.setAttribute("class","Label");
span.setAttribute("style","background-color:"+postListJson[num]["dateLabelColor"]);
date=new Date(postListJson[num]["createdAt"] * 1000);
span.innerHTML=date.getFullYear()+"-"+(date.getMonth()+1 < 10 ? '0'+(date.getMonth()+1) : date.getMonth()+1)+"-"+(date.getDate() < 10 ? '0' + (date.getDate()) : date.getDate());
div.appendChild(span);
SideNavItem.appendChild(div);
navList.appendChild(SideNavItem);
}
else{
if(postListJson[num]["label"]=="link"){
document.getElementById("buttonLink").childNodes[0].childNodes[0].setAttribute("d",value=IconList["link"]);
document.getElementById("buttonLink").style="display:block";
}
else if(postListJson[num]["label"]=="about"){
document.getElementById("buttonAbout").childNodes[0].childNodes[0].setAttribute("d",value=IconList["person"]);
document.getElementById("buttonAbout").style="display:block";
}
}
}
iconTOP=document.getElementsByClassName("svgTop1");
iconPost=document.getElementsByClassName("svgTop0");
for(var i=0;i<iconTOP.length;i++){
iconTOP[i].setAttribute("d",IconList["upload"]);
iconTOP[i].parentNode.style.color="red";
}
else{
document.title=blogBase["postTitle"];
document.getElementById("postTitle").innerHTML=blogBase["postTitle"];
document.getElementById("postBody").innerHTML=blogBase["postBody"];
document.getElementById("buttonHome").setAttribute("title",i18n[6]);
document.getElementById("cmButton").innerHTML=i18n[7];
function gotoSource(){window.open(blogBase["postSourceUrl"]);}
document.getElementById("pathHome").setAttribute("d",value=IconList["home"]);
document.getElementById("pathIssue").setAttribute("d",value=IconList["github"]);
if(blogBase["fontSize"]!=""){document.getElementById("postBody").setAttribute("style","font-size:"+blogBase["fontSize"])}
if(blogBase["commentNum"]>0){
cmButton=document.getElementById("cmButton");
span=document.createElement("span");
span.setAttribute("class","Counter");
span.innerHTML=blogBase["commentNum"];
cmButton.appendChild(span);
}
function openComments(){
cm=document.getElementById("comments");
cmButton=document.getElementById("cmButton");
cmButton.innerHTML=i18n[8];
span=document.createElement("span");
span.setAttribute("class","AnimatedEllipsis");
cmButton.appendChild(span);
script=document.createElement("script");
script.setAttribute("src","https://utteranc.es/client.js");
script.setAttribute("repo",blogBase["repoName"]);
script.setAttribute("issue-term","title");
if(localStorage.getItem("meek_theme")=="dark"){script.setAttribute("theme","dark-blue");}
else{script.setAttribute("theme","github-light");}
script.setAttribute("crossorigin","anonymous");
script.setAttribute("async","");
cm.appendChild(script);
int=self.setInterval("iFrameLoading()",200);
}
function iFrameLoading(){
var utterances=document.getElementsByClassName('utterances');
if(utterances.length==1){
if(utterances[0].style.height!=""){
utterancesLoad=1;
int=window.clearInterval(int);
document.getElementById("cmButton").style.display="none";
console.log("utterances Load OK");
}
}
}
for(var i=0;i<iconPost.length;i++){
iconPost[i].setAttribute("d",IconList["post"]);
}
function openComments(){
cm=document.getElementById("comments");
cmButton=document.getElementById("cmButton");
cmButton.innerHTML="loading";
span=document.createElement("span");
span.setAttribute("class","AnimatedEllipsis");
cmButton.appendChild(span);
script=document.createElement("script");
script.setAttribute("src","https://utteranc.es/client.js");
script.setAttribute("repo",cmButton.value);
script.setAttribute("issue-term","title");
if(localStorage.getItem("meek_theme")=="dark"){script.setAttribute("theme","dark-blue");}
else{script.setAttribute("theme","github-light");}
script.setAttribute("crossorigin","anonymous");
script.setAttribute("async","");
cm.appendChild(script);
int=self.setInterval("iFrameLoading()",200);
}
function iFrameLoading(){
var utterances=document.getElementsByClassName('utterances');
if(utterances.length==1){
if(utterances[0].style.height!=""){
utterancesLoad=1;
int=window.clearInterval(int);
document.getElementById("cmButton").style.display="none";
console.log("utterances Load OK");
}
}
}

View File

@ -10,45 +10,44 @@ import argparse
from github import Github
from xpinyin import Pinyin
from feedgen.feed import FeedGenerator
from jinja2 import Environment, FileSystemLoader
######################################################################################
i18n={"Search":"搜索","switchTheme":"切换主题","link":"友情链接","home":"首页","comments":"评论","run":"网站运行","days":""}
######################################################################################
class GMEEK():
def __init__(self,options):
self.options=options
self.config=json.loads(open('config.json', 'r', encoding='utf-8').read())
self.root_dir='docs/'
self.post_folder='post/'
self.backup_dir='backup/'
self.post_dir=self.root_dir+self.post_folder
self.plist_example=open('plist_example.html', 'r', encoding='utf-8').read()
self.post_example=open('post_example.html', 'r', encoding='utf-8').read()
self.feed = FeedGenerator()
user = Github(self.options.github_token)
self.repo = self.get_repo(user, options.repo_name)
self.feed = FeedGenerator()
self.labelColorDict=json.loads('{}')
for label in self.repo.get_labels():
self.labelColorDict[label.name]='#'+label.color
print(self.labelColorDict)
self.blogBase=self.config.copy()
config=json.loads(open('config.json', 'r', encoding='utf-8').read())
self.blogBase=config.copy()
self.blogBase["GMEEK_VERSION"]=options.Gmeek_version
self.blogBase["postListJson"]=json.loads('{}')
def cleanFile(self):
if os.path.exists("backup/"):
shutil.rmtree("backup/")
if os.path.exists(self.backup_dir):
shutil.rmtree(self.backup_dir)
if os.path.exists(self.root_dir):
shutil.rmtree(self.root_dir)
os.mkdir("backup/")
os.mkdir(self.backup_dir)
os.mkdir(self.root_dir)
os.mkdir(self.post_dir)
def get_repo(self,user:Github, repo:str):
return user.get_repo(repo)
@ -87,16 +86,25 @@ class GMEEK():
postBase["repoName"]=options.repo_name
postBase["GMEEK_VERSION"]=options.Gmeek_version
file_loader = FileSystemLoader('templates')
env = Environment(loader=file_loader)
template = env.get_template('post.html')
output = template.render(blogBase=postBase,i18n=i18n)
f = open(gen_Html, 'w', encoding='UTF-8')
f.write(self.post_example % json.dumps(postBase))
f.write(output)
f.close()
print("create postPage title=%s file=%s " % (issue["postTitle"],gen_Html))
def createPlistHtml(self):
self.blogBase["postListJson"]=dict(sorted(self.blogBase["postListJson"].items(),key=lambda x:(x[1]["top"],x[1]["createdAt"]),reverse=True))#使列表由时间排序
file_loader = FileSystemLoader('templates')
env = Environment(loader=file_loader)
template = env.get_template('plist.html')
output = template.render(blogBase=self.blogBase,postListJson=self.blogBase["postListJson"],i18n=i18n)
f = open(self.root_dir+"index.html", 'w', encoding='UTF-8')
f.write(self.plist_example % json.dumps(self.blogBase))
f.write(output)
f.close()
print("create docs/index.html")
@ -123,7 +131,6 @@ class GMEEK():
feed.rss_file(self.root_dir+'rss.xml')
def addOnePostJson(self,issue):
if len(issue.labels)==1:
postNum="P"+str(issue.number)
@ -164,7 +171,9 @@ class GMEEK():
else:
self.blogBase["postListJson"][postNum]["fontSize"]=""
thisYear=datetime.datetime.fromtimestamp(self.blogBase["postListJson"][postNum]["createdAt"]).year
thisTime=datetime.datetime.fromtimestamp(self.blogBase["postListJson"][postNum]["createdAt"])
thisYear=thisTime.year
self.blogBase["postListJson"][postNum]["createdDate"]=thisTime.strftime("%Y-%m-%d")
self.blogBase["postListJson"][postNum]["dateLabelColor"]=self.blogBase["yearColorList"][int(thisYear)%len(self.blogBase["yearColorList"])]
f = open("backup/"+issue.title+".md", 'w', encoding='UTF-8')
@ -196,7 +205,6 @@ class GMEEK():
print("====== create static html end ======")
######################################################################################
parser = argparse.ArgumentParser()
parser.add_argument("github_token", help="github_token")
parser.add_argument("repo_name", help="repo_name")
@ -223,6 +231,4 @@ else:
listFile=open("blogBase.json","w")
listFile.write(json.dumps(blog.blogBase))
listFile.close()
######################################################################################
######################################################################################

View File

@ -2,7 +2,7 @@
var IconList={
"post":"M0 3.75C0 2.784.784 2 1.75 2h12.5c.966 0 1.75.784 1.75 1.75v8.5A1.75 1.75 0 0 1 14.25 14H1.75A1.75 1.75 0 0 1 0 12.25Zm1.75-.25a.25.25 0 0 0-.25.25v8.5c0 .138.112.25.25.25h12.5a.25.25 0 0 0 .25-.25v-8.5a.25.25 0 0 0-.25-.25ZM3.5 6.25a.75.75 0 0 1 .75-.75h7a.75.75 0 0 1 0 1.5h-7a.75.75 0 0 1-.75-.75Zm.75 2.25h4a.75.75 0 0 1 0 1.5h-4a.75.75 0 0 1 0-1.5Z",
"link":"m7.775 3.275 1.25-1.25a3.5 3.5 0 1 1 4.95 4.95l-2.5 2.5a3.5 3.5 0 0 1-4.95 0 .751.751 0 0 1 .018-1.042.751.751 0 0 1 1.042-.018 1.998 1.998 0 0 0 2.83 0l2.5-2.5a2.002 2.002 0 0 0-2.83-2.83l-1.25 1.25a.751.751 0 0 1-1.042-.018.751.751 0 0 1-.018-1.042Zm-4.69 9.64a1.998 1.998 0 0 0 2.83 0l1.25-1.25a.751.751 0 0 1 1.042.018.751.751 0 0 1 .018 1.042l-1.25 1.25a3.5 3.5 0 1 1-4.95-4.95l2.5-2.5a3.5 3.5 0 0 1 4.95 0 .751.751 0 0 1-.018 1.042.751.751 0 0 1-1.042.018 1.998 1.998 0 0 0-2.83 0l-2.5 2.5a1.998 1.998 0 0 0 0 2.83Z",
"person":"M10.561 8.073a6.005 6.005 0 0 1 3.432 5.142.75.75 0 1 1-1.498.07 4.5 4.5 0 0 0-8.99 0 .75.75 0 0 1-1.498-.07 6.004 6.004 0 0 1 3.431-5.142 3.999 3.999 0 1 1 5.123 0ZM10.5 5a2.5 2.5 0 1 0-5 0 2.5 2.5 0 0 0 5 0Z",
"about":"M10.561 8.073a6.005 6.005 0 0 1 3.432 5.142.75.75 0 1 1-1.498.07 4.5 4.5 0 0 0-8.99 0 .75.75 0 0 1-1.498-.07 6.004 6.004 0 0 1 3.431-5.142 3.999 3.999 0 1 1 5.123 0ZM10.5 5a2.5 2.5 0 1 0-5 0 2.5 2.5 0 0 0 5 0Z",
"github":"M8 0c4.42 0 8 3.58 8 8a8.013 8.013 0 0 1-5.45 7.59c-.4.08-.55-.17-.55-.38 0-.27.01-1.13.01-2.2 0-.75-.25-1.23-.54-1.48 1.78-.2 3.65-.88 3.65-3.95 0-.88-.31-1.59-.82-2.15.08-.2.36-1.02-.08-2.12 0 0-.67-.22-2.2.82-.64-.18-1.32-.27-2-.27-.68 0-1.36.09-2 .27-1.53-1.03-2.2-.82-2.2-.82-.44 1.1-.16 1.92-.08 2.12-.51.56-.82 1.28-.82 2.15 0 3.06 1.86 3.75 3.64 3.95-.23.2-.44.55-.51 1.07-.46.21-1.61.55-2.33-.66-.15-.24-.6-.83-1.23-.82-.67.01-.27.38.01.53.34.19.73.9.82 1.13.16.45.68 1.31 2.69.94 0 .67.01 1.3.01 1.49 0 .21-.15.45-.55.38A7.995 7.995 0 0 1 0 8c0-4.42 3.58-8 8-8Z",
"sun":"M8 10.5a2.5 2.5 0 100-5 2.5 2.5 0 000 5zM8 12a4 4 0 100-8 4 4 0 000 8zM8 0a.75.75 0 01.75.75v1.5a.75.75 0 01-1.5 0V.75A.75.75 0 018 0zm0 13a.75.75 0 01.75.75v1.5a.75.75 0 01-1.5 0v-1.5A.75.75 0 018 13zM2.343 2.343a.75.75 0 011.061 0l1.06 1.061a.75.75 0 01-1.06 1.06l-1.06-1.06a.75.75 0 010-1.06zm9.193 9.193a.75.75 0 011.06 0l1.061 1.06a.75.75 0 01-1.06 1.061l-1.061-1.06a.75.75 0 010-1.061zM16 8a.75.75 0 01-.75.75h-1.5a.75.75 0 010-1.5h1.5A.75.75 0 0116 8zM3 8a.75.75 0 01-.75.75H.75a.75.75 0 010-1.5h1.5A.75.75 0 013 8zm10.657-5.657a.75.75 0 010 1.061l-1.061 1.06a.75.75 0 11-1.06-1.06l1.06-1.06a.75.75 0 011.06 0zm-9.193 9.193a.75.75 0 010 1.06l-1.06 1.061a.75.75 0 11-1.061-1.06l1.06-1.061a.75.75 0 011.061 0z",
"moon":"M9.598 1.591a.75.75 0 01.785-.175 7 7 0 11-8.967 8.967.75.75 0 01.961-.96 5.5 5.5 0 007.046-7.046.75.75 0 01.175-.786zm1.616 1.945a7 7 0 01-7.678 7.678 5.5 5.5 0 107.678-7.678z",

View File

Before

Width:  |  Height:  |  Size: 81 KiB

After

Width:  |  Height:  |  Size: 81 KiB

View File

Before

Width:  |  Height:  |  Size: 94 KiB

After

Width:  |  Height:  |  Size: 94 KiB

View File

@ -1,88 +0,0 @@
<html data-color-mode="light" data-dark-theme="dark" data-light-theme="light">
<head>
<meta content="text/html; charset=utf-8" http-equiv="content-type" />
<meta name="viewport" content="width=device-width,initial-scale=1.0">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<link href="https://unpkg.com/@primer/css@^21.0.7/dist/primer.css" rel="stylesheet" />
</head>
<style>
.markdown-body {
box-sizing: border-box;
min-width: 200px;
max-width: 900px;
margin: 20px auto;
padding: 45px;
font-family: sans-serif;
}
@media (max-width: 767px) {
.markdown-body { padding: 8px;}
.subnav-search form{display:none;}
.subnav-search svg{display:none;}
.SideNav-item .listLabels{display:none;}
#buttonRSS{display:none;}
}
h1 {display:flex;}
h1 a{margin-left: 4px;margin-top: 16px;}
.title-right{display:flex;margin:auto 0 0 auto;}
.title-right button{margin-right:8px;padding:16px;}
.subnav-search{display:flex;margin-top:8px;margin-right:16px;}
.subnav-search-input{width:160px;border-top-right-radius:0px;border-bottom-right-radius:0px;}
.subnav-search form{margin-bottom:0;}
.subnav-search button{padding:5px 8px;border-top-left-radius:0px;border-bottom-left-radius:0px;}
.avatar {transition: 0.8s;}
.avatar:hover {transform: scale(1.15) rotate(360deg);}
.SideNav{min-width: 360px;}
.SideNav-icon{margin-right: 16px}
.SideNav-item .Label{color: #fff;margin-left:8px;}
.footer {margin: 40px auto; text-align: center;font-size: small;}
</style>
<script>var blogBase=%s</script>
<body>
<div class="markdown-body">
<h1>
<img src='' size="64" height="64" width="64" class="avatar circle" id="avatarImg"><a style="font-family:Monaco;" id="blogTitle"></a>
<div class="title-right">
<div class="subnav-search">
<form action="https://www.google.com/search" method="get" target="_blank"><input id="searchSite" type="hidden" name="q"><input type="search" name="q" class="form-control subnav-search-input" aria-label="Search site" value=""><button class="btn" type="submit" id="buttonSearch"></button></form>
<svg class="subnav-search-icon octicon octicon-search" width="16" height="16" viewBox="0 0 16 16" aria-hidden="true"> <path id="searchSVG" fill-rule="evenodd" d=""></path></svg>
</div>
<button id="buttonLink" style="display: none;" class="btn btn-invisible circle" onclick="window.location.href='/link.html'"><svg class="octicon" width="16" height="16" ><path fill-rule="evenodd"></path></svg></button>
<button id="buttonAbout" style="display: none;" class="btn btn-invisible circle" onclick="window.location.href='/about.html'"><svg class="octicon" width="16" height="16" ><path fill-rule="evenodd"></path></svg></button>
<button id="buttonRSS" class="btn btn-invisible circle" onclick="window.location.href='/rss.xml'" title="RSS"><svg class="octicon" width="16" height="16" ><path fill-rule="evenodd"></path></svg></button>
<div><button id="changeTheme" class="btn btn-invisible circle" onclick="modeSwitch()"><svg class="octicon" width="16" height="16" ><path id="themeSwitch" fill-rule="evenodd"></path></svg></button></div>
</div>
</h1>
<div id="blogSubTitle"></div><p></p>
<nav class="SideNav border"id="navList"></nav>
<div class="footer">Copyright © <span id="year"></span> <a id="footerblogTitle" href=""></a> <p><span id="filingNum"></span><span id="runday"></span>Powered by <a href="https://github.com/Meekdai/Gmeek" target="_blank">Gmeek</a></p></div>
</div>
</body>
<script>
function addScript(url){
var script = document.createElement('script');
script.setAttribute('type','text/javascript');
script.setAttribute('src',url);
document.body.appendChild(script);
}
window.onload=function(){
addScript("https://cdn.jsdelivr.net/gh/Meekdai/Gmeek@"+blogBase["GMEEK_VERSION"]+"/icon.js" );
addScript("https://cdn.jsdelivr.net/gh/Meekdai/Gmeek@"+blogBase["GMEEK_VERSION"]+"/Gmeek.js" );
}
</script>
</html>

View File

@ -1,73 +0,0 @@
<html data-color-mode="light" data-dark-theme="dark" data-light-theme="light">
<head>
<meta content="text/html; charset=utf-8" http-equiv="content-type" />
<meta name="viewport" content="width=device-width,initial-scale=1.0">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<link href="https://unpkg.com/@wooorm/starry-night@2.1.1/style/both.css" rel="stylesheet" />
<link href="https://unpkg.com/@primer/css@^21.0.7/dist/primer.css" rel="stylesheet" />
</head>
<style>
.markdown-body {
box-sizing: border-box;
min-width: 200px;
max-width: 900px;
margin: 10px auto;
padding: 45px;
font-family: sans-serif;
}
.markdown-body hr{height:2px;}
@media (max-width: 560px) {
.markdown-body { padding: 8px;}
}
.avatar {transition: 0.8s;}
.avatar:hover {transform: scale(1.15) rotate(360deg);}
h1 {display:flex;}
.g-emoji{font-size:24px;}
.title-right{display:flex;margin:auto 0 0 auto;}
.title-right button{margin-left:8px;padding:16px;}
.SideNav{min-width: 360px;}
.SideNav-icon{margin-right: 16px}
#postBody{border-bottom: 1px solid var(--color-border-default);}
#comments{margin-top:64px;}
.footer {margin: 40px auto; text-align: center;font-size: small;}
#cmButton{height:48px;margin-top:48px;}
</style>
<script>var blogBase=%s</script>
<body>
<div class="markdown-body">
<h1>
<div id="postTitle"></div>
<div class="title-right">
<button id="buttonHome" class="btn btn-invisible circle" onclick="window.location.href='/'"><svg class="octicon octicon-sun" width="16" height="16"><path id="pathHome" fill-rule="evenodd"></path></svg></button>
<button class="btn btn-invisible circle" onclick="gotoSource()" title="Issue"><svg class="octicon octicon-sun" width="16" height="16"><path id="pathIssue" fill-rule="evenodd"></path></svg></button>
<button id="changeTheme" class="btn btn-invisible circle" onclick="modeSwitch()"><svg class="octicon octicon-sun" width="16" height="16"><path id="themeSwitch" fill-rule="evenodd"></path></svg></button>
</div>
</h1>
<div id="postBody"></div>
<button class="btn btn-block" type="button" onclick="openComments()" id="cmButton"> </button>
<div class="comments" id="comments"></div>
<div class="footer">Copyright © <span id="year"></span> <a id="footerblogTitle" href=""></a> <p><span id="filingNum"></span><span id="runday"></span>Powered by <a href="https://github.com/Meekdai/Gmeek" target="_blank">Gmeek</a></p></div>
</div>
</body>
<script>
function addScript(url){
var script = document.createElement('script');
script.setAttribute('type','text/javascript');
script.setAttribute('src',url);
document.body.appendChild(script);
}
window.onload=function(){
addScript("https://cdn.jsdelivr.net/gh/Meekdai/Gmeek@"+blogBase["GMEEK_VERSION"]+"/icon.js" );
addScript("https://cdn.jsdelivr.net/gh/Meekdai/Gmeek@"+blogBase["GMEEK_VERSION"]+"/Gmeek.js" );
}
</script>
</html>

View File

@ -2,3 +2,4 @@ PyGithub
requests
xpinyin
feedgen
Jinja2

42
templates/base.html Normal file
View File

@ -0,0 +1,42 @@
<!DOCTYPE html>
<html data-color-mode="light" data-dark-theme="dark" data-light-theme="light">
<head>
<meta content="text/html; charset=utf-8" http-equiv="content-type" />
<meta name="viewport" content="width=device-width,initial-scale=1.0">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<link href="https://unpkg.com/@primer/css@21.0.7/dist/primer.css" rel="stylesheet" />
<link rel="icon" href="{{ blogBase['faviconUrl'] }}">
<title>{% block title %}{% endblock %}</title>
</head>
<style>
body{
box-sizing: border-box;
min-width: 200px;
max-width: 900px;
margin: 20px auto;
padding: 45px;
font-size: 16px;
font-family: sans-serif;
line-height: 1.25;
}
.avatar {transition: 0.8s;}
.avatar:hover {transform: scale(1.15) rotate(360deg);}
#header{display:flex;padding-bottom:8px;border-bottom: 1px solid var(--borderColor-muted, var(--color-border-muted));margin-bottom: 16px;}
#footer {margin: 40px auto; text-align: center;font-size: small;}
</style>
{% block style %}{% endblock %}
<body>
<div id="header">{% block header %}{% endblock %}</div>
<div id="content">{% block content %}{% endblock %}</div>
<div id="footer">{% include 'footer.html' %}</div>
</body>
<script type="text/javascript" src="https://cdn.jsdelivr.net/gh/Meekdai/Gmeek@{{ blogBase['GMEEK_VERSION'] }}/icon.js"></script>
<script type="text/javascript" src="https://cdn.jsdelivr.net/gh/Meekdai/Gmeek@{{ blogBase['GMEEK_VERSION'] }}/Gmeek.js"></script>
<script>
console.log("\n %c Gmeek {{ blogBase['GMEEK_VERSION'] }} %c https://github.com/Meekdai/Gmeek \n\n", "color: #fff; background-image: linear-gradient(90deg, rgb(47, 172, 178) 0%, rgb(45, 190, 96) 100%); padding:5px 1px;", "background-image: linear-gradient(90deg, rgb(45, 190, 96) 0%, rgb(255, 255, 255) 100%); padding:5px 0;");
</script>
{% block script %}{% endblock %}
</html>

14
templates/footer.html Normal file
View File

@ -0,0 +1,14 @@
Copyright © <span id="year"></span> <a href="{{ blogBase['homeUrl'] }}"> {{ blogBase['title'] }} </a><p> {{ blogBase['filingNum'] }} <span id="runday"></span>Powered by <a href="https://github.com/Meekdai/Gmeek" target="_blank">Gmeek</a></p>
<script>
if("{{ blogBase['startSite'] }}"!=""){
var now=new Date();
var startSite=new Date("{{ blogBase['startSite'] }}");
var diff=now.getTime()-startSite.getTime();
var diffDay=Math.floor(diff/(1000*60*60*24));
document.getElementById("year").innerHTML=now.getFullYear();
if("{{ blogBase['filingNum'] }}"!=""){document.getElementById("runday").innerHTML=" • "+"{{ i18n['run'] }}"+diffDay+"{{ i18n['days'] }}"+" • ";}
else{document.getElementById("runday").innerHTML="{{ i18n['run'] }}"+diffDay+"{{ i18n['days'] }}"+" • ";}
}
</script>

92
templates/plist.html Normal file
View File

@ -0,0 +1,92 @@
{% extends 'base.html' %}
{% block title%}{{ blogBase['title'] }}{% endblock %}
{% block style %}
<style>
h1 a:not([href]){color:inherit;text-decoration:none;vertical-align: bottom;font-size:40px;font-family:Monaco;}
.title-right{display:flex;margin:auto 0 0 auto;}
.title-right button{margin-right:8px;padding:16px;}
.subnav-search{margin-top:8px;margin-right:8px;}
.subnav-search-input{width:160px;border-top-right-radius:0px;border-bottom-right-radius:0px;}
.subnav-search button{padding:5px 8px;border-top-left-radius:0px;border-bottom-left-radius:0px;}
.title-right .circle{padding: 14px 16px;}
.SideNav{min-width: 360px;}
.SideNav-icon{margin-right: 16px}
.SideNav-item .Label{color: #fff;margin-left:8px;}
</style>
{% endblock %}
{% block header %}
<h1>
<img src="{{ blogBase['avatarUrl'] }}" size="64" height="64" width="64" class="avatar circle" id="avatarImg">
<a>{{ blogBase['displayTitle'] }}</a>
</h1>
<div class="title-right">
<div class="subnav-search">
<form action="https://www.google.com/search" method="get" target="_blank">
<input id="searchSite" type="hidden" name="q">
<input type="search" name="q" class="form-control subnav-search-input float-left" aria-label="Search site" value="">
<button class="btn float-left" type="submit">{{ i18n['Search'] }}</button>
</form>
<svg class="subnav-search-icon octicon octicon-search" width="16" height="16" viewBox="0 0 16 16" aria-hidden="true">
<path id="searchSVG" fill-rule="evenodd" d=""></path>
</svg>
</div>
{% for num in postListJson %}
{% if postListJson[num]['label'] in blogBase['singlePage'] %}
<button class="btn btn-invisible circle" onclick="window.location.href='/{{ postListJson[num]["label"] }}.html'" title="{{ postListJson[num]['postTitle'] }}">
<svg class="octicon" width="16" height="16" >
<path id="{{ postListJson[num]['postTitle'] }}" fill-rule="evenodd"></path>
</svg>
</button>
{% endif %}
{% endfor %}
<button id="changeTheme" class="btn btn-invisible circle" onclick="modeSwitch()" title="{{ i18n['switchTheme'] }}">
<svg class="octicon" width="16" height="16" >
<path id="themeSwitch" fill-rule="evenodd"></path>
</svg>
</button>
</div>
{% endblock %}
{% block content %}
<div style="margin-bottom: 16px;">{{ blogBase['subTitle'] }}</div>
<nav class="SideNav border">
{% for num in postListJson %}
{% if postListJson[num]['label'] not in blogBase['singlePage'] %}
<a class="SideNav-item d-flex flex-items-center flex-justify-between" href="{{ postListJson[num]['postUrl']|e }}">
<div class="d-flex flex-items-center">
<svg class="SideNav-icon octicon" style="witdh:16px;height:16px"><path class="svgTop{{ postListJson[num]['top'] }}" d=""></path>
</svg>
<span>{{ postListJson[num]['postTitle']|e }}</span>
</div>
<div class="listLabels">
{% if postListJson[num]['commentNum']>0 %}<span class="Label" style="background-color:{{ blogBase['commentLabelColor'] }}">{{ postListJson[num]['commentNum'] }}</span>{% endif %}
<span class="Label" style="background-color:{{ postListJson[num]['labelColor'] }}">{{ postListJson[num]['label'] }}</span>
<span class="Label" style="background-color:{{ postListJson[num]['dateLabelColor'] }}">{{ postListJson[num]['createdDate'] }}</span>
</div>
</a>
{% endif %}
{% endfor %}
</nav>
{% endblock %}
{% block script %}
<script>
document.getElementById("searchSVG").setAttribute("d",IconList["search"]);
{% for num in postListJson %}
{% if postListJson[num]['label'] in blogBase['singlePage'] %}
document.getElementById("{{ postListJson[num]['postTitle'] }}").setAttribute("d",value=IconList["{{ postListJson[num]['label'] }}"]);
{% endif %}
{% endfor %}
</script>
{% endblock %}

55
templates/post.html Normal file
View File

@ -0,0 +1,55 @@
{% extends 'base.html' %}
{% block title%}{{ blogBase['title'] }}{% endblock %}
{% block style %}
<style>
h1 a:not([href]){color:inherit;text-decoration:none;vertical-align: bottom;font-size:40px;font-family:Monaco;}
.title-right{display:flex;margin:auto 0 0 auto;}
.title-right .circle{padding: 14px 16px;margin-right:8px;}
#cmButton{height:48px;margin-top:48px;}
</style>
{% endblock %}
{% block header %}
<h1>
<a>{{ blogBase['postTitle'] }}</a>
</h1>
<div class="title-right">
<button id="buttonHome" class="btn btn-invisible circle" onclick="window.location.href='/'" title="{{ i18n['home'] }}">
<svg class="octicon" width="16" height="16">
<path id="pathHome" fill-rule="evenodd"></path>
</svg>
</button>
<button class="btn btn-invisible circle" onclick="window.open('{{ blogBase["postSourceUrl"] }}')" title="Issue">
<svg class="octicon" width="16" height="16">
<path id="pathIssue" fill-rule="evenodd"></path>
</svg>
</button>
<button id="changeTheme" class="btn btn-invisible circle" onclick="modeSwitch()" title="{{ i18n['switchTheme'] }}">
<svg class="octicon" width="16" height="16" >
<path id="themeSwitch" fill-rule="evenodd"></path>
</svg>
</button>
</div>
{% endblock %}
{% block content %}
<div class="markdown-body">
{{ blogBase['postBody'] }}
</div>
<button class="btn btn-block" type="button" onclick="openComments()" id="cmButton" value="{{ blogBase['repoName'] }}">{{ i18n['comments'] }}</button>
<div class="comments" id="comments"></div>
{% endblock %}
{% block script %}
<script>
document.getElementById("pathHome").setAttribute("d",IconList["home"]);
document.getElementById("pathIssue").setAttribute("d",IconList["github"]);
</script>
{% endblock %}