initialization

This commit is contained in:
julylies 2022-04-10 11:10:56 +08:00
commit 1b498d185a
21 changed files with 3344 additions and 0 deletions

48
archives.ftl Normal file
View File

@ -0,0 +1,48 @@
<#include "module/macro.ftl">
<@layout title="归档 - ${blog_title!}">
<h1>归档</h1>
<ul>
<#list archives as archive>
<h2>${archive.year?c}</h2>
<#list archive.posts as post>
<li>
<a href="${post.fullPath!}">${post.title!}</a>
</li>
</#list>
</#list>
</ul>
<h1>分页</h1>
<#if posts.totalPages gt 1>
<ul>
<@paginationTag method="archives" page="${posts.number}" total="${posts.totalPages}" display="3">
<#if pagination.hasPrev>
<li>
<a href="${pagination.prevPageFullPath!}">
上一页
</a>
</li>
</#if>
<#list pagination.rainbowPages as number>
<li>
<#if number.isCurrent>
<span class="current">第 ${number.page!} 页</span>
<#else>
<a href="${number.fullPath!}">第 ${number.page!} 页</a>
</#if>
</li>
</#list>
<#if pagination.hasNext>
<li>
<a href="${pagination.nextPageFullPath!}">
下一页
</a>
</li>
</#if>
</@paginationTag>
</ul>
<#else>
<span>当前只有一页</span>
</#if>
</@layout>

13
categories.ftl Normal file
View File

@ -0,0 +1,13 @@
<#include "module/macro.ftl">
<@layout title="分类列表 - ${blog_title!}">
<h1>分类列表</h1>
<ul>
<@categoryTag method="list">
<#if categories?? && categories?size gt 0>
<#list categories as category>
<li><a href="${category.fullPath!}">${category.name}</a></li>
</#list>
</#if>
</@categoryTag>
</ul>
</@layout>

45
category.ftl Normal file
View File

@ -0,0 +1,45 @@
<#include "module/macro.ftl">
<@layout title="分类:${category.name} - ${blog_title!}">
<h1>分类:${category.name}</h1>
<ul>
<#list posts.content as post>
<li>
<a href="${post.fullPath}">${post.title}</a>
</li>
</#list>
</ul>
<h1>分页</h1>
<#if posts.totalPages gt 1>
<ul>
<@paginationTag method="categoryPosts" page="${posts.number}" total="${posts.totalPages}" display="3" slug="${category.slug!}">
<#if pagination.hasPrev>
<li>
<a href="${pagination.prevPageFullPath!}">
上一页
</a>
</li>
</#if>
<#list pagination.rainbowPages as number>
<li>
<#if number.isCurrent>
<span class="current">第 ${number.page!} 页</span>
<#else>
<a href="${number.fullPath!}">第 ${number.page!} 页</a>
</#if>
</li>
</#list>
<#if pagination.hasNext>
<li>
<a href="${pagination.nextPageFullPath!}">
下一页
</a>
</li>
</#if>
</@paginationTag>
</ul>
<#else>
<span>当前只有一页</span>
</#if>
</@layout>

43
index.ftl Normal file
View File

@ -0,0 +1,43 @@
<#include "module/macro.ftl">
<@layout title="${blog_title!}">
<#--<h1>公告</h1>
<p>
${settings.index_notice!}
</p>
-->
<main>
<div class="wrap min">
<section class="home-title">
<h1>${blog_title!}</h1>
<span>${user.description!}</span>
<#--快捷-->
<div class="home-social"> </div>
</section>
<section class="home-posts">
<div class="post-item">
<#list posts.content as post>
<h2>
<a href="${post.fullPath!}">${post.title!}</a>
</h2>
<p>${post.summary!}</p>
<div class="post-meta">
<time class="date">${post.createTime?string('yyyy-MM-dd')!}</time>
<span class="category">
<#list post.categories as category>
${category.name!}
</#list></span>
<span class="tags">
<#list post.tags as tag>
<a href="${tag.fullPath}" class="tag">${tag.name}</a>
</#list>
</span>
<span class="comments">${post.commentCount!}°C</span>
<span class="visits">${post.visits!}</span>
</div>
</#list>
</div>
</div>
</main>
</@layout>

18
links.ftl Normal file
View File

@ -0,0 +1,18 @@
<#include "module/macro.ftl">
<@layout title="友情链接 - ${blog_title!}">
<h1>友情链接</h1>
<ul>
<@linkTag method="list">
<#if links?? && links?size gt 0>
<#list links as link>
<li>
<a href="${link.url}" target="_blank" rel="external">${link.name}</a>
<#if link.description!=''>
${link.description}
</#if>
</li>
</#list>
</#if>
</@linkTag>
</ul>
</@layout>

7
module/comment.ftl Normal file
View File

@ -0,0 +1,7 @@
<#macro comment post,type>
<#if !post.disallowComment!false>
<script src="//cdn.jsdelivr.net/npm/vue@2.6.10/dist/vue.min.js"></script>
<script src="${options.comment_internal_plugin_js!'//cdn.jsdelivr.net/gh/halo-dev/halo-comment@latest/dist/halo-comment.min.js'}"></script>
<halo-comment id="${post.id?c}" type="${type}"/>
</#if>
</#macro>

34
module/macro.ftl Normal file
View File

@ -0,0 +1,34 @@
<#macro layout title>
<!DOCTYPE html>
<html lang="zh">
<head>
<meta charset="UTF-8">
<meta name="keywords" content="${meta_keywords!}"/>
<meta name="description" content="${meta_description!}" />
<link href="${theme_base!}/source/css/kico.css" rel="stylesheet" type="text/css"/>
<link href="${theme_base!}/source/css/single.css" rel="stylesheet" type="text/css"/>
<#--
公共 head 代码详情请参考https://docs.halo.run/zh/developer-guide/theme/public-template-tag
包含Favicon自定义 head 等
-->
<@global.head />
<title>${title}</title>
</head>
<body>
<#-- <#include "menu.ftl">
-->
<#nested >
<#--
公共底部代码详情请参考https://docs.halo.run/zh/developer-guide/theme/public-template-tag
包含:统计代码,底部信息
-->
<script src="${theme_base!}/source/js/kico.js"></script>
<script src="${theme_base!}/source/js/single.js"></script>
<script src="${theme_base!}/source/js/prism.js"></script>
<@global.footer />
</body>
</html>
</#macro>

10
module/menu.ftl Normal file
View File

@ -0,0 +1,10 @@
<@menuTag method="list">
<#--
?sort_by('priority'):根据菜单的排序编号排序
-->
<#list menus?sort_by('priority') as menu>
<li>
<a href="${menu.url}" target="${menu.target!}">${menu.name} </a>
</li>
</#list>
</@menuTag>

9
post.ftl Normal file
View File

@ -0,0 +1,9 @@
<#include "module/macro.ftl">
<@layout title="${post.title!} - ${blog_title!}">
<h1>${post.title!}</h1>
<article>
${post.formatContent!}
</article>
<#include "module/comment.ftl">
<@comment post=post type="post" />
</@layout>

9
settings.yaml Normal file
View File

@ -0,0 +1,9 @@
# 配置详情请参考https://docs.halo.run/zh/developer-guide/theme/config-files
genernal:
label: 基本设置
items:
index_notice:
name: index_notice
label: 首页公告
type: textarea
default: '欢迎来到我的博客'

9
sheet.ftl Normal file
View File

@ -0,0 +1,9 @@
<#include "module/macro.ftl">
<@layout title="${sheet.title!} - ${blog_title!}">
<h1>${sheet.title!}</h1>
<article>
${sheet.formatContent!}
</article>
<#include "module/comment.ftl">
<@comment post=sheet type="sheet" />
</@layout>

1471
source/css/kico.css Normal file

File diff suppressed because it is too large Load Diff

929
source/css/single.css Normal file
View File

@ -0,0 +1,929 @@
@charset "UTF-8";
/* ----
# Single Theme
# By: Dreamer-Paul
# Last Update: 2022.2.25
一个简洁大气含夜间模式的 Typecho 博客模板
本代码为奇趣保罗原创并遵守 MIT 开源协议欢迎访问我的博客https://paugram.com
---- */
/* 0 - 全局
-------------------------------- */
:root{
--blue: #6f9fc7;
--light-blue: #9fcff7;
--border: #ddd;
--dark-border: #ccc;
--light-border: #eee;
--light-background: #fff;
--radius: .25em;
}
body{
color: #555;
font-weight: 300;
background: #fafafa;
transition: margin .3s, background .3s;
}
body:before{
top: 0;
left: 0;
right: 0;
bottom: 0;
opacity: .1;
z-index: -1;
display: block;
position: fixed;
background: center/cover no-repeat;
}
::-webkit-scrollbar{
width: 8px;
height: 8px;
}
::-webkit-scrollbar-thumb{ background: #6f9fc7 }
::-webkit-scrollbar-thumb:hover{ background: #9fcff7 }
body::-webkit-scrollbar{
border-left: 1px solid #eee;
border-color: var(--light-border);
background: rgba(255, 255, 255, .6);
}
a{
color: #6f9fc7;
color: var(--blue);
}
a:hover{
color: #9fcff7;
color: var(--light-blue);
}
h1, h2, h3, h4, h5, h6{ font-weight: normal }
hr{ border-color: #eee }
em{ background: #6f9fc7 }
.btn{
color: #fff;
background: #6f9fc7;
background: var(--blue);
}
.btn:hover{
color: #fff;
background: #9fcff7;
background: var(--light-blue);
}
pre{
color: inherit;
border: 1px solid #ccc;
border-color: var(--dark-border);
background: linear-gradient(rgba(18, 18, 18, .05) 50%, transparent 0);
background-size: auto 3em;
background-origin: content-box;
}
blockquote{
background: #ecf1f5;
border-color: #6f9fc7;
border-radius: .25em;
border-radius: var(--radius);
}
input, textarea{
background: #fff;
background: var(--light-background);
}
input[type="text"], input[type="search"], input[type="email"], input[type="url"], textarea, code, hr, tr{
border-color: var(--dark-border);
}
input, textarea, pre, hr, blockquote{
transition: border .3s, background .3s;
}
/* - 夜间风格 */
.dark-theme{
color: #aaa;
background: #333;
--blue: #6e8aad;
--light-blue: #6f9fc7;
--border: #555;
--dark-border: #666;
--light-border: #555;
--light-background: #444;
}
/* -- 额外适配 */
.dark-theme::-webkit-scrollbar{
border-color: transparent;
background: rgba(255, 255, 255, .2);
}
.dark-theme img{
filter: brightness(60%);
-webkit-filter: brightness(60%);
}
.dark-theme blockquote{
color: #ddd;
border-color: #eb9c26;
background: rgba(255, 255, 255, .05);
}
.dark-theme iframe, .dark-theme em{ opacity: .6 }
.dark-theme :not(pre) > code{
color: #ffa5a5;
background: rgba(255, 255, 255, .2);
}
.dark-theme .head-search input{
background: #666;
border-color: transparent;
}
.dark-theme .head-search input::-webkit-input-placeholder{ color: #bbb }
/* 1 - 页眉
-------------------------------- */
header{
top: 0;
left: 0;
right: 0;
z-index: 2;
position: fixed;
line-height: 1em;
background: #fff;
background: var(--light-background);
border-bottom: 1px solid #ddd;
border-color: var(--border);
transition: border-color .3s, background .3s;
}
/* - 头部标题 */
.head-title{
left: 0;
right: 0;
line-height: 3.2em;
position: absolute;
text-align: center;
}
@media screen and (min-width: 600px){
.head-title{ display: none }
}
/* - 头部菜单 */
.head-menu{
display: flex;
list-style: none;
user-select: none;
justify-content: center;
}
.head-menu a{
color: inherit;
display: block;
cursor: pointer;
position: relative;
line-height: 2.25em;
}
.head-menu a:hover{ color: #ffa628 }
.head-menu .has-child > a:after{
float: right;
content: "\f107";
margin-left: .3em;
font-family: "FontAwesome";
}
/* -- 手机版 */
@media screen and (max-width: 599px){
.head-menu{
max-height: 0;
padding: 0 1em;
display: block;
overflow-y: auto;
border-right: .5em solid transparent;
transition: margin .3s, max-height .3s;
}
.head-menu.active{
margin: 1em 0;
max-height: 18rem;
}
.head-menu .sub-menu{ margin-left: 1.5em }
.head-menu .sub-menu a{
display: list-item;
list-style-type: circle;
}
.head-menu::-webkit-scrollbar{
width: 8px;
height: 8px;
}
.head-menu::-webkit-scrollbar-thumb{
border-radius: 5px;
background: rgba(0, 0, 0, .1);
}
}
/* -- 电脑版 */
@media screen and (min-width: 600px){
.head-menu{
top: 0;
left: 0;
right: 0;
position: absolute;
}
.head-menu > a, .has-child > a{
padding: .6em 0;
line-height: 2em;
margin-right: 1em;
}
.head-menu > a:last-child{ margin-right: 0 }
}
/* - 子菜单 */
.head-menu .sub-menu a{
line-height: 2em;
margin-right: .05em;
}
/* -- 电脑版 */
@media screen and (min-width: 600px){
.head-menu .has-child{
position: relative;
}
.head-menu .has-child:hover > .sub-menu{
opacity: 1;
visibility: visible;
}
.head-menu .sub-menu{
opacity: 0;
top: 3.2em;
left: -1em;
background: #fff;
background: var(--light-background);
padding: .5em 1em;
visibility: hidden;
position: absolute;
white-space: nowrap;
border: 1px solid #ddd;
border-color: var(--border);
border-radius: 0 0 .25em .25em;
transition: background .15s, border-color .15s, opacity .15s, visibility .15s;
}
.head-menu .sub-menu:before{
left: 2em;
top: -.5em;
width: 1em;
height: 1em;
content: '';
display: block;
background: #fff;
background: var(--light-background);
border: 1px solid;
position: absolute;
transform: rotate(-45deg);
border-color: #ddd #ddd transparent transparent;
border-color: var(--border) var(--border) transparent transparent;
transition: background .15s, border-color .15s;
}
.toggle-btn{ display: none }
}
.toggle-btn, .light-btn, .search-btn{
z-index: 1;
float: left;
width: 2em;
margin: .6em;
cursor: pointer;
position: relative;
border-radius: .25em;
border-radius: var(--radius);
transition: color 0.3s, background 0.3s;
}
.toggle-btn{ margin-right: 0 }
.search-btn{ float: right }
.toggle-btn:hover, .light-btn:hover, .search-btn:hover{
background: rgba(0, 0, 0, .05);
}
.toggle-btn:before, .light-btn:before, .search-btn:before{
display: block;
text-align: center;
font: 1em/2em "FontAwesome";
}
.toggle-btn:before{ content: "\f0c9" }
.light-btn:before{ content: "\f0eb" }
.search-btn:before{ content: "\f002" }
.head-search{
z-index: 1;
opacity: 0;
float: right;
margin: .6em 0;
line-height: 1.5em;
position: relative;
pointer-events: none;
transition: opacity 0.3s;
}
.head-search.active{
opacity: 1;
pointer-events: inherit;
}
.head-search input{
width: 10em;
height: 2em;
padding: 0 .75em;
min-height: auto;
border-radius: 3em;
}
@media screen and (max-width: 600px){
.head-search{
float: none;
margin-left: 6.5em;
margin-right: 3.5em;
}
.head-search input{ width: 100% }
}
/* 2 - 正文
-------------------------------- */
main{
padding: 3.5em 0;
margin-top: 3.2em;
}
main img {
height: auto;
transition: filter .3s;
}
/* - 首页大标题 */
.home-title{
text-align: center;
margin-bottom: 3em;
animation: fade-in-bottom .3s both; -webkit-animation: fade-in-bottom .3s both;
}
.home-title h1{
color: #6e8aad;
color: var(--blue);
}
.home-title span{
display: block;
margin-bottom: 1em;
font-style: oblique;
}
/* - 社交链接 */
.home-social{
cursor: default;
user-select: none;
}
.home-social a{
color: inherit;
display: inline-block;
}
.home-social i{ padding: .5em }
/* - 文章简要 */
.post-item{
margin-bottom: 3em;
word-break: break-all;
}
.post-item:last-child{ margin-bottom: 0 }
/* -- 动画 */
.post-item:nth-child(1){ animation: fade-in-top .3s .2s backwards; -webkit-animation: fade-in-top .3s .2s backwards; }
.post-item:nth-child(2){ animation: fade-in-top .3s .3s backwards; -webkit-animation: fade-in-top .3s .3s backwards; }
.post-item:nth-child(3){ animation: fade-in-top .3s .4s backwards; -webkit-animation: fade-in-top .3s .4s backwards; }
.post-item:nth-child(4){ animation: fade-in-top .3s .5s backwards; -webkit-animation: fade-in-top .3s .5s backwards; }
.post-item:nth-child(5){ animation: fade-in-top .3s .6s backwards; -webkit-animation: fade-in-top .3s .6s backwards; }
.post-item:nth-child(6){ animation: fade-in-top .3s .7s backwards; -webkit-animation: fade-in-top .3s .7s backwards; }
.post-item:nth-child(7){ animation: fade-in-top .3s .8s backwards; -webkit-animation: fade-in-top .3s .8s backwards; }
.post-item:nth-child(8){ animation: fade-in-top .3s .9s backwards; -webkit-animation: fade-in-top .3s .9s backwards; }
.post-item:nth-child(9){ animation: fade-in-top .3s 1s backwards; -webkit-animation: fade-in-top .3s 1s backwards; }
.post-item:nth-child(10){ animation: fade-in-top .3s 1.1s backwards; -webkit-animation: fade-in-top .3s 1.1s backwards; }
.post-item h2{ margin-bottom: .5em }
.post-item h2 a{
line-height: 2em;
padding-bottom: .3rem;
border-bottom: 2px solid #eee;
border-color: var(--light-border);
transition: color .3s, border .3s;
}
.post-item .edit-link{
font-size: 1rem;
line-height: inherit;
}
/* - 文章属性 */
.post-meta{
overflow: auto;
white-space: nowrap;
}
.post-meta::-webkit-scrollbar{ height: 0 }
.post-meta a{ color: inherit }
.post-meta span, .post-meta time{
margin-right: .8em;
display: inline-block;
}
.post-meta span:last-child{ margin-right: 0 }
.post-meta span:before, .post-meta time:before{
font-size: inherit;
margin-right: .4em;
display: inline-block;
font-family: "FontAwesome";
}
.post-meta .date:before{ content: "\f017" }
.post-meta .category:before{ content: "\f07b" }
.post-meta .tags:before{content: "\f02c";}
.post-meta .visits:before{content: "\f06e";}
.post-meta .user:before{ content: "\f007" }
.post-meta .comments:before{ content: "\f086" }
.post-meta .view:before{ content: "\f080" }
/* - 换页 */
.page-navigator{
cursor: default;
margin-top: 3em;
font-size: 1.25em;
text-align: center;
font-weight: normal;
animation: fade-in-top .3s .7s both; -webkit-animation: fade-in-top .3s .7s both;
}
.page-navigator a{ padding: 0 .3em }
.page-navigator .current a{ color: inherit }
/* - 阅读页标题 */
.post-title, .page-title{
margin-bottom: 1em;
padding-bottom: 1em;
transition: border 0.3s;
border-bottom: 1px solid #ddd;
border-color: var(--border);
animation: fade-in-bottom .3s both; -webkit-animation: fade-in-bottom .3s both;
}
.post-title h2, .page-title h2{
color: #6e8aad;
margin-right: .25rem;
display: inline-block;
}
.page-title h2{ margin-bottom: 0 }
/* - 编辑文章 */
.post-item .edit-link, .page-title .edit-link, .post-title .edit-link{
display: inline-block;
}
/* - 阅读页正文 */
article a{ border-bottom: 1px dashed currentColor }
article img{
border-radius: .25em;
border-radius: var(--radius);
}
.post-content, .page-content{ animation: fade-in-top .3s .2s backwards; -webkit-animation: fade-in-top .3s .2s backwards; }
.post-content, .page-content, .post-near, .post-tags, .post-author{ margin-bottom: 3em }
article h1, article h2, article h3{
margin-top: 3rem;
scroll-margin-top: 5em;
}
article h2{ font-size: 1.15em }
article h3{ font-size: 1.10em }
article h4{ font-size: 1.05em }
article h5{ font-size: 1em }
article h6{ font-size: .9em }
article h1:before,
article h2:before,
article h3:before{
content: "#";
color: #6f9fc7;
color: var(--blue);
margin-right: .5em;
}
article h1:before{ font-weight: bold }
article ul p:first-child{
margin-top: .5em;
margin-bottom: 0;
}
/* - 阅读页其他文章 */
.post-near{
animation: fade-in-top .3s .3s backwards; -webkit-animation: fade-in-top .3s .3s backwards;
}
/* - 阅读页文章标签 */
.post-tags{
display: flex;
flex-wrap: wrap;
margin-bottom: 2.5em;
animation: fade-in-top .3s .3s backwards; -webkit-animation: fade-in-top .3s .3s backwards;
}
.post-tags:before{
content: "\f02c";
margin-right: .75em;
font-family: "FontAwesome";
}
.post-tags a{
margin: 0 .75em .5em 0;
}
/* - 阅读页作者信息 */
.post-author{
display: table;
padding: 1.5em 0;
position: relative;
border-top: 1px solid #ddd;
border-bottom: 1px solid #ddd;
border-color: var(--border);
transition: border .3s, filter .3s;
animation: fade-in-top .3s .4s backwards; -webkit-animation: fade-in-top .3s .4s backwards;
}
.post-author .author-avatar{
width: 5em;
display: table-cell;
vertical-align: middle;
}
.post-author img{ border-radius: 66% }
.post-author .author-info{ margin-left: 1.5em }
.post-author h4{
font-weight: bold;
margin-bottom: .5em;
}
@media screen and (max-width: 800px){
.post-author{
margin-top: 6em;
padding-top: 3em;
}
.post-author .author-avatar{
left: 0;
right: 0;
top: -3em;
margin: auto;
position: absolute;
}
.post-author .author-info{ margin-left: 0 }
.post-author h4{ text-align: center }
}
/* - 阅读页评论 */
.post-comments{
scroll-margin-top: 5em;
animation: fade-in-top .3s .5s backwards; -webkit-animation: fade-in-top .3s .5s backwards;
}
.post-comments input, .post-comments textarea{
-webkit-appearance: none;
-moz-appearance: none;
}
/* -- 评论结构 */
.post-comments{ word-break: break-all }
.comment-form{ margin-bottom: 2em }
.comment-list .comment-single{
position: relative;
padding-left: 3.75em;
margin-bottom: 1.5em;
scroll-margin-top: 5em;
transition: transform .3s;
}
.comment-list .comment-single:after{
content: "";
clear: both;
display: block;
}
.comment-list .comment-single.active{ transform: scale(1.05) }
.comment-list .comment-child{ margin-left: 2em }
/* --- 评论头像 */
.comment-list .avatar{
top: 0;
left: 0;
min-width: 45px;
max-width: 45px;
position: absolute;
border-radius: 100%;
transition: filter .3s, transform .3s;
}
.comment-list .comment-single:hover .avatar{
transform: rotate(1turn);
-webkit-transform: rotate(1turn);
}
/* --- 评论信息 */
.comment-list .comment-meta{
margin-bottom: .25em;
}
.comment-list .comment-time:before{
content: "\f017";
margin-right: .4em;
display: inline-block;
font-family: "FontAwesome";
}
.comment-list .comment-author,
.comment-list .comment-time{
margin-right: .8em;
}
/* --- 评论内容 */
.comment-single .comment-reply{
opacity: 0;
float: right;
line-height: 1.8;
transition: opacity .3s;
}
.comment-single:hover .comment-reply{ opacity: 1 }
.comment-reply a, .cancel-comment-reply a{ color: #aaa }
.comment-reply a:hover, .cancel-comment-reply a:hover{ color: #555 }
.cancel-comment-reply{
display: block;
margin: .5em 0;
text-align: right;
}
@media screen and (max-width: 600px){
.comment-form button{ width: 100% }
}
/* -- 文章目录 */
.article-list{
right: 0;
bottom: 0;
opacity: 0;
z-index: 1;
width: 15em;
padding: 1em;
overflow: auto;
position: fixed;
transform: translateY(0%);
background: rgba(255, 255, 255, .5);
transition: transform .3s, border .3s, opacity .3s, background .3s;
}
.article-list.active{
opacity: 1;
background: #fff;
background: var(--light-background);
transform: translateY(0%);
}
.article-list::-webkit-scrollbar{ width: 0; height: 0 }
.article-list h4{ text-align: center }
.article-list .title{
padding: .25em 1em;
display: inline-block;
transition: border-color .3s;
border-top: 1px solid #ccc;
border-bottom: 1px solid #ccc;
border-color: var(--dark-border);
}
.article-list a{
display: block;
margin-bottom: .5em;
}
.article-list .item-2:before,
.article-list .item-3:before,
.article-list .item-4:before,
.article-list .item-5:before,
.article-list .item-6:before{
margin-right: .5em;
}
.article-list .item-2:before{ content: "-" }
.article-list .item-3:before{ content: "--" }
.article-list .item-4:before{ content: "---" }
.article-list .item-5:before{ content: "----" }
.article-list .item-6:before{ content: "-----" }
@media screen and (min-width: 800px){
body.has-trees{ margin-right: 15em }
.dark-theme .article-list{ background: rgba(0, 0, 0, .1) }
.article-list{
top: 3.2em;
opacity: 1;
visibility: visible;
border-left: 1px solid #ddd;
border-color: var(--border);
}
}
@media screen and (max-width: 799px){
.article-list{
left: 0;
width: 100%;
min-height: 40%;
max-height: 80%;
transform: translateY(100%);
border-top: 1px solid #ddd;
border-color: var(--border);
}
}
/* - 错误页面 */
.error-page{
text-align: center;
animation: fade-in-bottom .3s backwards; -webkit-animation: fade-in-bottom .3s backwards;
}
.error-page h1{
font-size: 5em;
line-height: 1em;
}
.error-page img{ width: 25em }
/* 3 - 页尾
-------------------------------- */
footer{
border-top: 1px solid #eee;
border-color: var(--light-border);
transition: border .3s, background .3s;
}
footer .buttons{
right: 1em;
bottom: 5em;
z-index: 1;
position: fixed;
}
footer .to-top, footer .toggle-list{
padding: .5em;
display: block;
cursor: pointer;
background: #fff;
background: var(--light-background);
border-radius: .25em;
border-radius: var(--radius);
border: 1px solid #eee;
border-color: var(--border);
transform: translateX(5em);
transition: color .3s, border .3s, background .3s, transform .3s;
}
footer .to-top.active{ transform: translateX(0) }
footer .to-top:before, footer .toggle-list:before{
width: 1.5em;
display: block;
content: "\f062";
text-align: center;
font-family: "FontAwesome";
}
footer .toggle-list{
display: none;
margin-top: .5em;
}
footer .toggle-list:before{ content: '\f00b' }
@media screen and (max-width: 800px){
footer .toggle-list{
display: block;
transform: translateX(0);
}
}
footer .widget{ padding: 2em 0 }
footer .title-comments:after,
footer .title-recent:after,
footer .title-date:after{
float: right;
margin-right: .75em;
font-family: "FontAwesome";
}
footer .title-comments:after{ content: "\f0e6" }
footer .title-recent:after{ content: "\f040" }
footer .title-date:after{ content: "\f017" }
footer .widget ul{
margin: 0;
list-style: none;
}
footer .widget ul li{
overflow: hidden;
margin-bottom: .5em;
white-space: nowrap;
text-overflow: ellipsis;
}
footer .widget ul li:before{
opacity: .3;
content: "\f105";
margin-right: .75em;
font-family: "FontAwesome";
}
footer .sub-footer{
padding: 1em 0;
text-align: center;
}
footer .sub-footer p{ font-size: .875em }
/* 4 - 附加
-------------------------------- */
/* - 打印样式 */
@media print {
body{
background: none;
}
body:before, header, .post-comments, .post-near, footer{
display: none;
}
main{
margin-top: 0;
padding: 1.25em 0;
}
.post-author{
margin-bottom: 0;
}
}
/* - Prism 代码块样式 */
.token.comment, .token.block-comment, .token.prolog, .token.doctype, .token.cdata{ color: #7D8B99 }
.token.punctuation{ color: #5F6364 }
.token.property, .token.tag, .token.boolean, .token.number, .token.function-name, .token.constant, .token.symbol, .token.deleted{ color: #c92c2c }
.token.selector, .token.attr-name, .token.string, .token.char, .token.function, .token.builtin, .token.inserted{ color: #2f9c0a }
.token.operator, .token.entity, .token.url, .token.variable{ color: #a67f59 }
.token.atrule, .token.attr-value, .token.keyword, .token.class-name{ color: #1990b8 }
.token.regex, .token.important{ color: #e90 }
.language-css .token.string, .style .token.string {
color: #a67f59;
background: rgba(255, 255, 255, 0.5);
}
.token.bold { font-weight: bold }
.token.italic { font-style: italic }
.token.entity { cursor: help }
.token.important { font-weight: normal }
.namespace { opacity: .7 }

BIN
source/images/404.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 84 KiB

BIN
source/images/icon.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 57 KiB

418
source/js/kico.js Normal file
View File

@ -0,0 +1,418 @@
/* ----
# Kico Style 1.0
# By: Dreamer-Paul
# Last Update: 2020.4.10
一个可口的极简响应式前端框架
本代码为奇趣保罗原创并遵守 MIT 开源协议欢迎访问我的博客https://paugram.com
---- */
Array.prototype.remove = function (value) {
var index = this.indexOf(value);
if(index > -1) this.splice(index, 1);
};
(function (global, setting) {
var KStyle = function (a, b) {
return KStyle.fn.init(a, b);
};
KStyle.fn = KStyle.prototype = {
construtor: KStyle,
init: function (a, b) {
a = KStyle.selectAll(a);
a.each = function (fn){
return KStyle.each(a, fn);
};
a.image = function () {
return KStyle.image(a);
};
a.lazy = function (bg) {
return KStyle.lazy(a, bg);
};
a.scrollTo = function (offset) {
return KStyle.scrollTo(a, offset);
};
a.empty = function () {
return KStyle.each(a, function (item) { KStyle.empty(item); });
}
return a;
}
};
// 批量处理
KStyle.each = function (data, fn) {
for(var i = 0; i < data.length; i++){
fn(data[i], i, data);
}
};
// 创建对象
KStyle.create = function (tag, prop) {
var obj = document.createElement(tag);
if(prop){
if(prop.id) obj.id = prop.id;
if(prop.src) obj.src = prop.src;
if(prop.href) obj.href = prop.href;
if(prop.class) obj.className = prop.class;
if(prop.text) obj.innerText = prop.text;
if(prop.html) obj.innerHTML = prop.html;
if(prop.child){
if(prop.child.constructor === Array){
KStyle.each(prop.child, (i) => {
obj.appendChild(i);
});
}
else{
obj.appendChild(prop.child);
}
}
if(prop.attr){
if(prop.attr.constructor === Array){
KStyle.each(prop.attr, (i) => {
obj.setAttribute(i.name, i.value);
});
}
else if(prop.attr.constructor === Object){
obj.setAttribute(prop.attr.name, prop.attr.value);
}
}
if(prop.parent) prop.parent.appendChild(obj);
}
return obj;
};
// 选择对象
KStyle.select = function (obj) {
switch(typeof obj){
case "object": return obj; break;
case "string": return document.querySelector(obj); break;
}
};
KStyle.selectAll = function (obj) {
switch(typeof obj){
case "object": return obj; break;
case "string": return document.querySelectorAll(obj); break;
}
};
// 清空子元素
KStyle.empty = function (obj) {
while(obj.firstChild){
obj.removeChild(obj.firstChild);
}
}
// 弹窗
var notice = {
wrap: KStyle.create("notice"),
list: []
};
KStyle.notice = function (content, attr) {
var item = KStyle.create("div", {class: "ks-notice", html: "<span class='content'>" + content + "</span>", parent: notice.wrap});
notice.list.push(item);
if(!document.querySelector("body > notice")) document.body.appendChild(notice.wrap);
if(attr && attr.time){
setTimeout(notice_remove, attr.time);
}
else{
var close = KStyle.create("span", {class: "close", parent: item});
close.onclick = notice_remove;
}
if(attr && attr.color){
item.classList.add(attr.color);
}
function notice_remove() {
item.classList.add("remove");
notice.list.remove(item);
setTimeout(function () {
try{
notice.wrap.removeChild(item);
item = null;
}
catch(err) {}
if(document.querySelector("body > notice") && notice.list.length === 0){
document.body.removeChild(notice.wrap);
}
}, 300);
}
};
// 灯箱
var image_box = {
img: KStyle.create("img"),
prev: KStyle.create("div", {class: "ks-prev"}),
next: KStyle.create("div", {class: "ks-next"}),
ball: KStyle.create("div", {class: "ks-ball"})
};
image_box.wrap = KStyle.create("div", {class: "ks-image", child: [
image_box.prev, image_box.img, image_box.next, image_box.ball
]});
image_box.wrap.onclick = function (e) {
image_box.wrap.classList.add("remove");
setTimeout(function () {
try{
document.body.removeChild(image_box.wrap);
image_box.wrap.classList.remove("remove");
}
catch (err){}
}, 300);
};
image_box.img.onload = function () {
image_box.wrap.classList.remove("loading");
};
KStyle.image = function (selector) {
var current = 0;
var get_images = KStyle.selectAll(selector);
var actions = {
ori: function (obj, num) {
obj.setAttribute("ks-image", "active");
obj.onclick = function () {
current = num;
actions.set();
document.body.appendChild(image_box.wrap);
};
},
set: function () {
var img = get_images[current];
current === 0 ? image_box.prev.classList.add("ended") : image_box.prev.classList.remove("ended");
current === get_images.length - 1 ? image_box.next.classList.add("ended") : image_box.next.classList.remove("ended");
if(img.getAttribute("ks-original") !== null){
image_box.img.src = img.getAttribute("ks-original");
}
else if(img.src){
image_box.img.src = img.src;
}
else{
console.error("This image has no valid tag!");
}
image_box.wrap.classList.add("loading");
}
};
KStyle.each(get_images, function (item, id) {
if(item.src || item.getAttribute("ks-original")){
actions.ori(item, id);
}
});
// 设置按钮
image_box.prev.onclick = function (e) {
e.stopPropagation();
if(current - 1 >= 0) current--;
actions.set();
};
image_box.next.onclick = function (e) {
e.stopPropagation();
if(current + 1 < get_images.length) current++;
actions.set();
};
};
// 懒加载
KStyle.lazy = function (elements, bg) {
//elements = Array.from(KStyle.selectAll(elements));
elements = KStyle.selectAll(elements);
var list = [];
var action = {
setFront: function (item) {
if(item.intersectionRatio > 0) {
item.target.src = item.target.link;
item.target.setAttribute("ks-lazy", "finished");
obs.unobserve(item.target);
}
},
setBack: function (item) {
if(item.boundingClientRect.top <= window.innerHeight + 100) {
var img = new Image();
img.src = item.target.link;
img.onload = function () {
item.target.setAttribute("ks-lazy", "finished");
item.target.style.backgroundImage = "url(" + item.target.link + ")";
};
obs.unobserve(item.target);
}
}
};
// 是否支持 OBS
if(global.IntersectionObserver){
var obs = new IntersectionObserver(function (changes) {
if (bg) {
changes.forEach(function (t) {
action.setBack(t);
});
}
else {
changes.forEach(function (t) {
action.setFront(t);
});
}
});
KStyle.each(elements, function (item) {
item.link = item.getAttribute("ks-thumb") || item.getAttribute("ks-original");
if(!item.getAttribute("ks-lazy")) obs.observe(item);
})
}
else{
function back() {
KStyle.each(list, function (item) {
var check = item.el.getBoundingClientRect().top <= window.innerHeight;
if(check && !item.showed){
action.setBack(item.el);
list.remove(item);
}
});
}
function front() {
KStyle.each(list, function (item) {
var check = item.el.getBoundingClientRect().top <= window.innerHeight;
if(check && !item.showed){
action.setFront(item.el);
list.remove(item);
}
});
}
KStyle.each(elements, function (item) {
item.link = item.getAttribute("ks-thumb") || item.getAttribute("ks-original");
if(!item.getAttribute("ks-lazy")) list.push({el: item, link: item.link});
});
bg ? back() : front();
bg ? document.addEventListener("scroll", back) : document.addEventListener("scroll", front);
}
};
// AJAX
KStyle.ajax = function (prop) {
if(!prop.url) prop.url = document.location.href;
if(!prop.method) prop.method = "GET";
if(prop.method === "POST"){
var data = new FormData();
for(var d in prop.data){
data.append(d, prop.data[d]);
}
}
else if(prop.method === "GET"){
var url = prop.url + "?";
for(var d in prop.data){
url += d + "=" + prop.data[d] + "&";
}
prop.url = url.substr(0, url.length - 1);
}
var request = new XMLHttpRequest();
request.open(prop.method, prop.url);
if(prop.crossDomain){ request.setRequestHeader("X-Requested-With", "XMLHttpRequest"); }
if(prop.header){
for(var i in prop.header){
request.setRequestHeader(prop.header[i][0], prop.header[i][1]);
}
}
request.send(data);
request.onreadystatechange = function () {
if(request.readyState === 4){
if(request.status === 200 || request.status === 304){
if(prop.type){
switch(prop.type){
case "text": prop.success(request.responseText); break;
case "json": prop.success(JSON.parse(request.response)); break;
}
}
else{
prop.success ? prop.success(request) : console.log(prop.method + " 请求发送成功");
}
}
else{
prop.failed ? prop.failed(request) : console.log(prop.method + " 请求发送失败");
}
request = null;
}
};
return request;
};
// 平滑滚动
KStyle.scrollTo = function (el, offset) {
el = KStyle.selectAll(el);
el.forEach(function (t) {
t.onclick = function (e) {
var l = e.target.pathname;
var c = window.location.pathname;
var t = e.target.href.match(/#[\s\S]+/);
if(t) t = ks.select(t[0]);
if(c === l){
e.preventDefault();
var top = t ? (offset ? t.offsetTop - offset : t.offsetTop) : 0;
"scrollBehavior" in document.documentElement.style ? global.scrollTo({top: top, left: 0, behavior: "smooth"}) : global.scrollTo(0, top);
}
else{
console.log(c, l);
}
}
})
};
global.ks = KStyle;
console.log("%c Kico Style %c https://paugram.com ","color: #fff; margin: 1em 0; padding: 5px 0; background: #3498db;","margin: 1em 0; padding: 5px 0; background: #efefef;");
})(window);

42
source/js/prism.js Normal file

File diff suppressed because one or more lines are too long

170
source/js/single.js Normal file
View File

@ -0,0 +1,170 @@
/* ----
# Single Theme
# By: Dreamer-Paul
# Last Update: 2020.9.11
一个简洁大气含夜间模式的 Typecho 博客模板
本代码为奇趣保罗原创并遵守 MIT 开源协议欢迎访问我的博客https://paugram.com
---- */
var Paul_Single = function (config) {
var body = document.body;
var content = ks.select(".post-content:not(.is-special), .page-content:not(.is-special)");
// 菜单按钮
this.header = function () {
var menu = document.getElementsByClassName("head-menu")[0];
ks.select(".toggle-btn").onclick = function () {
menu.classList.toggle("active");
};
ks.select(".light-btn").onclick = this.night;
var search = document.getElementsByClassName("search-btn")[0];
var bar = document.getElementsByClassName("head-search")[0];
search.addEventListener("click", function () {
bar.classList.toggle("active");
})
};
// 关灯切换
this.night = function () {
if(body.classList.contains("dark-theme")){
body.classList.remove("dark-theme");
document.cookie = "night=false;" + "path=/;" + "max-age=21600";
}
else{
body.classList.add("dark-theme");
document.cookie = "night=true;" + "path=/;" + "max-age=21600";
}
};
// 目录树
this.tree = function () {
var id = 1;
var wrap = ks.select(".wrap");
var headings = content.querySelectorAll("h1, h2, h3, h4, h5, h6");
if(headings.length > 0){
body.classList.add("has-trees");
var trees = ks.create("section", {
class: "article-list",
html: "<h4><span class=\"title\">目录</span></h4>"
});
ks.each(headings, function (t) {
var cls, text = t.innerText;
t.id = "title-" + id;
switch (t.tagName){
case "H2": cls = "item-2"; break;
case "H3": cls = "item-3"; break;
case "H4": cls = "item-4"; break;
case "H5": cls = "item-5"; break;
case "H6": cls = "item-6"; break;
}
trees.appendChild(ks.create("a", {class: cls, text: text, href: "#title-" + id}));
id++;
});
wrap.appendChild(trees);
function toggle_tree() {
var buttons = ks.select("footer .buttons");
var btn = ks.create("a", {class: "toggle-list"});
buttons.appendChild(btn);
btn.addEventListener("click", function () {
trees.classList.toggle("active");
})
}
toggle_tree();
}
};
// 自动添加外链
this.links = function () {
var l = content.getElementsByTagName("a");
if(l){
ks.each(l, function (t) {
t.target = "_blank";
});
}
};
this.comment_list = function () {
ks(".comment-content [href^='#comment']").each(function (t) {
var item = ks.select(t.getAttribute("href"));
t.onmouseover = function () {
item.classList.add("active");
};
t.onmouseout = function () {
item.classList.remove("active");
};
});
};
// 返回页首
this.to_top = function () {
var btn = document.getElementsByClassName("to-top")[0];
var scroll = window.pageYOffset || document.documentElement.scrollTop || document.body.scrollTop;
scroll >= window.innerHeight / 2 ? btn.classList.add("active") : btn.classList.remove("active");
};
this.header();
if(content){
this.tree();
this.links();
this.comment_list();
}
// 返回页首
window.addEventListener("scroll", this.to_top);
// 如果开启自动夜间模式
if(config.night){
var hour = new Date().getHours();
if(document.cookie.indexOf("night") === -1 && (hour <= 5 || hour >= 22)){
document.body.classList.add("dark-theme");
document.cookie = "night=true;" + "path=/;" + "max-age=21600";
}
}
else if(document.cookie.indexOf("night") !== -1){
if(document.cookie.indexOf("night=true") !== -1){
document.body.classList.add("dark-theme");
}
else{
document.body.classList.remove("dark-theme");
}
}
// 如果开启复制内容提示
if(config.copyright){
document.oncopy = function () {
ks.notice("复制内容请注明来源并保留版权信息!", {color: "yellow", overlay: true})
};
}
};
// 图片缩放
ks.image(".post-content:not(.is-special) img, .page-content:not(.is-special) img");
// 请保留版权说明
if (window.console && window.console.log) {
console.log("%c Single %c https://paugram.com ","color: #fff; margin: 1em 0; padding: 5px 0; background: #ffa628;","margin: 1em 0; padding: 5px 0; background: #efefef;");
}

45
tag.ftl Normal file
View File

@ -0,0 +1,45 @@
<#include "module/macro.ftl">
<@layout title="标签:${tag.name} - ${blog_title!}">
<h1>标签:${tag.name}</h1>
<ul>
<#list posts.content as post>
<li>
<a href="${post.fullPath!}">${post.title}</a>
</li>
</#list>
</ul>
<h1>分页</h1>
<#if posts.totalPages gt 1>
<ul>
<@paginationTag method="tagPosts" page="${posts.number}" total="${posts.totalPages}" display="3" slug="${tag.slug!}">
<#if pagination.hasPrev>
<li>
<a href="${pagination.prevPageFullPath!}">
上一页
</a>
</li>
</#if>
<#list pagination.rainbowPages as number>
<li>
<#if number.isCurrent>
<span class="current">第 ${number.page!} 页</span>
<#else>
<a href="${number.fullPath!}">第 ${number.page!} 页</a>
</#if>
</li>
</#list>
<#if pagination.hasNext>
<li>
<a href="${pagination.nextPageFullPath!}">
下一页
</a>
</li>
</#if>
</@paginationTag>
</ul>
<#else>
<span>当前只有一页</span>
</#if>
</@layout>

13
tags.ftl Normal file
View File

@ -0,0 +1,13 @@
<#include "module/macro.ftl">
<@layout title="标签列表 - ${blog_title!}">
<h1>标签列表</h1>
<ul>
<@tagTag method="list">
<#if tags?? && tags?size gt 0>
<#list tags as tag>
<li><a href="${tag.fullPath!}">${tag.name}</a></li>
</#list>
</#if>
</@tagTag>
</ul>
</@layout>

11
theme.yaml Normal file
View File

@ -0,0 +1,11 @@
id: julylies_Single
name: Single
author:
name: julylies
website: https://blog.huangdf.xyz
description: 一个简洁大气含夜间模式的Halo博客模板。
logo: https://avatars.githubusercontent.com/u/48195280?s=200&v=4
website:
repo:
version: 1.0.0
require: 1.4.2