前言
为什么从 Ghost 换到 Hugo?
Ghost 随着更新功能越来越丰富,更偏向于专业的商用 CMS 系统,对服务器性能要求越来越高了。
买不起服务器了,就换回静态博客了。
本文记录一下 Ghost 多年的使用体验和一些小技巧。
永远喜欢 Casper 主题。
Code injection
代码注入是修改 Ghost 主题最方便的方法,而且不受主题更新影响。下面是我使用 Ghost 多年攒下来的 Code inject 方案,包含了字体、图片、样式、插件等各个方面的自定义。
Site header
<!-- 自动黑化 -->
<script>
if (
window.matchMedia &&
window.matchMedia("(prefers-color-scheme: dark)").matches
) {
document.documentElement.classList.add("dark-mode");
}
</script>
<style>
@media (prefers-color-scheme: dark) {
::selection {
background: #424242;
}
::-moz-selection {
background: #424242;
}
::-webkit-selection {
background: #424242;
}
}
</style>
<!-- 黑色图底 -->
<style>
.has-cover .site-header-content {
background-color: #000000;
}
</style>
<!-- 替换图片 -->
<script>
document.addEventListener('DOMContentLoaded', function() {
var image = document.querySelector('.site-header-cover');
if (image) {
var newSrcset = 'https://api.dujin.org/bing/1366.php 300w, https://api.dujin.org/bing/1366.php 600w, https://api.dujin.org/bing/1920.php 1000w, https://api.dujin.org/bing/1920.php 2000w';
var newSrc = 'https://api.dujin.org/bing/1920.php';
image.srcset = newSrcset;
image.src = newSrc;
image.alt = "Jacob's Thoughts";
}
});
</script>
<!-- 全局字体 -->
<style>
/*@import url('https://fonts.googleapis.com/css?family=Source+Code+Pro&display=swap');
@import url('https://fonts.googleapis.com/css2?family=Noto+Serif+SC&display=swap');*/
/* 引入 Google Fonts */
@font-face {
font-family: "ChineseFont";
src: local("PingFang SC"), local("Microsoft YaHei"), local("Noto Sans CJK SC");
unicode-range: U+2E80-A4CF, U+F900-FAFF, U+FE30-FE4F;
}
:root {
--font-sans-serif: -apple-system, BlinkMacSystemFont, "Apple Color Emoji", "Segoe UI Emoji", "Segoe UI Symbol", "Segoe UI", "PingFang SC", "HarmonyOS_Regular", "Hiragino Sans GB", "Microsoft YaHei", "Helvetica Neue", Helvetica, "Source Han Sans SC", "Noto Sans CJK SC", "WenQuanYi Micro Hei", Arial, sans-serif;
--font-serif: STZhongsong, STSong, 'Noto Serif SC', "Noto Serif CJK", PMingLiu, SimSun, "WenQuanYi Bitmap Song", "Times New Roman", Times, serif;
--font-mono: ChineseFont, ui-monospace, SFMono-Regular, "SF Mono", "Cascadia Code", "Segoe UI Mono", "Source Code Pro", Menlo, Consolas, "Liberation Mono", monospace;
}
/* 覆写默认字体变量 */
body {
font-family: font-family: var(--font-sans-serif);
font-size: 16px;
}
/* 网页正文字体 */
.post-card-title,
.article-title {
font-family: var(--font-serif);
}
/* 文章卡片标题字体 */
.post-card-excerpt p,
.gh-content>blockquote,
.gh-content>ol,
.gh-content>ul,
.gh-content>dl,
.gh-content>p {
font-family: var(--font-sans-serif);
font-size: 1.6rem;
line-height: 1.8em;
}
/* 文章正文字体 */
.gh-content :not(pre)>code {
display: inline-block;
font-family: var(--font-mono);
background-color: #F5F5F5;
border-radius: 4px;
border: 1px solid #F0F0F0;
padding: 0 6px;
margin: 1px 6px;
line-height: 1.1;
color: #096DD9;
}
/* 段落内代码样式 */
code,
kbd,
pre,
samp {
font-family: var(--font-mono);
}
/* 统一代码字体 */
h1,
h2,
h3,
h4,
h5,
h6 {
font-family: var(--font-serif);
}
/* 标题字体 */
.site-title {
font-family: var(--font-sans-serif);
text-shadow: 1px 0 10px black;
}
/* 首页标题字体 */
.author-profile h1,
.article-byline-meta h4 {
font-family: var(--font-sans-serif);
}
/* 作者名片字体 */
blockquote p {
font-size: 1em;
}
/* 引用字体大小 */
.gh-content a {
text-decoration: none;
border-bottom: 1px solid var(--ghost-accent-color);
-webkit-transition: all .2s;
transition: all .2s;
}
.gh-content a:focus,
.gh-content a:hover {
border-bottom: 2px solid var(--ghost-accent-color);
}
.post-card-image {
border-radius: 12px;
}
/* 圆角图片 */
</style>
<!-- 全局滚动条 -->
<style>
::-webkit-scrollbar {
width: 6px;
height: 6px;
background-color: #424242;
}
::-webkit-scrollbar-track {
-webkit-box-shadow: 0 0 3px rgba(0, 0, 0, 0.3) inset;
background-color: #424242;
}
::-webkit-scrollbar-thumb {
border-radius: 3px;
-webkit-box-shadow: none !important;
}
::-webkit-scrollbar-thumb {
background-color: #686868 !important;
background-image: none !important;
}
::-webkit-scrollbar-thumb:hover {
background-color: var(--ghost-accent-color) !important;
}
</style>
<!-- 代码高亮 prism.js -->
<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/prism/1.28.0/themes/prism-tomorrow.min.css"
integrity="sha512-vswe+cgvic/XBoF1OcM/TeJ2FW0OofqAVdCZiEYkd6dwGXthvkSFWOoGGJgS2CW70VK5dQM5Oh+7ne47s74VTg=="
crossorigin="anonymous" referrerpolicy="no-referrer" />
<!--
<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/prism/1.26.0/themes/prism.min.css" integrity="sha512-tN7Ec6zAFaVSG3TpNAKtk4DOHNpSwKHxxrsiw4GHKESGPs5njn/0sMCUMl2svV4wo4BK/rCP7juYz+zx+l6oeQ==" crossorigin="anonymous" referrerpolicy="no-referrer" />
-->
<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/prism/1.28.0/plugins/toolbar/prism-toolbar.min.css"
integrity="sha512-Dqf5696xtofgH089BgZJo2lSWTvev4GFo+gA2o4GullFY65rzQVQLQVlzLvYwTo0Bb2Gpb6IqwxYWtoMonfdhQ=="
crossorigin="anonymous" referrerpolicy="no-referrer" />
<style>
code[class*='language-'] {
font-family: var(--font-mono);
}
pre[class*=language-] {
font-family: var(--font-mono);
color: #fff;
font-size: 1.3rem;
line-height: 1.8em;
max-width: 100%;
overflow: auto;
padding: 2.4rem 3.2rem;
width: 100%;
}
html.dark-mode .gh-content code {
color: #fff;
background: #030303;
}
</style>
<!-- Global site tag (gtag.js) - Google Analytics 谷歌统计-->
<script async src="https://www.googletagmanager.com/gtag/js?id=UA-**********"></script>
<script>
window.dataLayer = window.dataLayer || [];
function gtag() {
dataLayer.push(arguments);
}
gtag("js", new Date());
gtag("config", "UA-**********");
</script>
<!-- Baidu Tongji 百度统计-->
<script>
var _hmt = _hmt || [];
(function () {
var hm = document.createElement("script");
hm.src = "https://hm.baidu.com/hm.js?********************";
var s = document.getElementsByTagName("script")[0];
s.parentNode.insertBefore(hm, s);
})();
</script>
<meta name="baidu-site-verification" content="code-SpwhprNdN8" />
<!-- busuanzi 统计-->
<script async src="//busuanzi.ibruce.info/busuanzi/2.3/busuanzi.pure.mini.js"></script>
<!-- DisqusJS -->
<link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/disqusjs@3.0/dist/browser/styles/disqusjs.css">
<script src="https://cdn.jsdelivr.net/npm/disqusjs@3.0/dist/browser/disqusjs.es2015.umd.min.js"></script>
<!-- 图标库 -->
<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/6.2.0/css/brands.min.css" integrity="sha512-+oRH6u1nDGSm3hH8poU85YFIVTdSnS2f+texdPGrURaJh8hzmhMiZrQth6l56P4ZQmxeZzd2DqVEMqQoJ8J89A==" crossorigin="anonymous" referrerpolicy="no-referrer" />
<style>
.gh-head-menu .nav-github a {
font-size: 0 !important;
}
.gh-head-menu .nav-github a::before {
font-family: "Font Awesome 6 Brands";
display: inline-block;
font-size: 20px;
font-style: normal;
font-weight: normal;
font-variant: normal;
text-rendering: auto;
-webkit-font-smoothing: antialiased;
}
.gh-head-menu .nav-github a::before {content: "\f09b"}
</style>
<!-- 阅读进度条 -->
<style>
.reading-progress {
position: fixed;
top: 0;
z-index: 999;
width: 100%;
height: 5px; /* Progress bar height */
background: #c5d2d9; /* Progress bar background color */
-webkit-appearance: none;
-moz-appearance: none;
appearance: none; /* Hide default progress bar */
}
.reading-progress::-webkit-progress-bar {
background-color: transparent;
}
.reading-progress::-webkit-progress-value {
background: var(--ghost-accent-color); /* Progress bar color */
}
</style>
Site footer
<!-- 代码高亮 prism.js -->
<script src="https://cdnjs.cloudflare.com/ajax/libs/prism/1.28.0/prism.min.js" integrity="sha512-RDQSW3KoqJMiX0L/UBgwBmH1EmRYp8LBOiLaA8rBHIy+7OGP/7Gxg8vbt8wG4ZYd29P0Fnoq6+LOytCqx3cyoQ==" crossorigin="anonymous" referrerpolicy="no-referrer"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/prism/1.28.0/plugins/toolbar/prism-toolbar.min.js" integrity="sha512-st608h+ZqzliahyzEpETxzU0f7z7a9acN6AFvYmHvpFhmcFuKT8a22TT5TpKpjDa3pt3Wv7Z3SdQBCBdDPhyWA==" crossorigin="anonymous" referrerpolicy="no-referrer"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/prism/1.28.0/plugins/copy-to-clipboard/prism-copy-to-clipboard.min.js" integrity="sha512-/kVH1uXuObC0iYgxxCKY41JdWOkKOxorFVmip+YVifKsJ4Au/87EisD1wty7vxN2kAhnWh6Yc8o/dSAXj6Oz7A==" crossorigin="anonymous" referrerpolicy="no-referrer"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/prism/1.28.0/components/prism-bash.min.js" integrity="sha512-ZqfG//sXQwAA7DOArFJyMmZQ3knKe+0ft3tPQZPvDPJR04IatmhVO5pTazVV+fLVDYSy28PhoBeUj5wxGRiGAA==" crossorigin="anonymous" referrerpolicy="no-referrer"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/prism/1.28.0/components/prism-json.min.js" integrity="sha512-QXFMVAusM85vUYDaNgcYeU3rzSlc+bTV4JvkfJhjxSHlQEo+ig53BtnGkvFTiNJh8D+wv6uWAQ2vJaVmxe8d3w==" crossorigin="anonymous" referrerpolicy="no-referrer"></script>
<!-- AddThis 分享组件 -->
<script type="text/javascript" src="//s7.addthis.com/js/300/addthis_widget.js#pubid=ra-61109cb1d502ff5d"></script>
<!-- Cookie Consent 提示框 -->
<link rel="stylesheet" type="text/css" href="https://cdn.jsdelivr.net/npm/cookieconsent@3/build/cookieconsent.min.css" />
<script src="https://cdn.jsdelivr.net/npm/cookieconsent@3/build/cookieconsent.min.js" data-cfasync="false"></script>
<script>
window.cookieconsent.initialise({
palette: {
popup: {
background: "#252e39",
},
button: {
background: "#005ba4",
},
},
theme: "edgeless",
position: "bottom-right",
});
</script>
<!-- 标题特效 -->
<script src="https://unpkg.com/typewriter-effect@latest/dist/core.js"></script>
<script>
const app = document.querySelector('.site-title + p');
const typewriter = new Typewriter(app, {
loop: true,
delay: 75,
});
typewriter
.typeString('Writing my <strong>thoughts</strong>')
.pauseFor(1000)
.deleteChars(8)
.typeString('<strong>stories</strong>')
.pauseFor(750)
.deleteChars(7)
.typeString('<strong>ideas</strong>')
.pauseFor(500)
.deleteChars(5)
.typeString('<strong>life</strong>')
.pauseFor(500)
.deleteChars(4)
.typeString('<strong>cats</strong> on the web')
.pauseFor(1500)
.deleteAll(50)
.start();
</script>
<!-- 版权特效 -->
<script>
document.addEventListener('DOMContentLoaded', function() {
var poweredByLink = document.querySelector('.gh-powered-by a');
poweredByLink.textContent = '自豪地使用 Ghost';
});
</script>
<script>
document.addEventListener('DOMContentLoaded', function() {
var copyrightSection = document.querySelector('.copyright');
if (copyrightSection) {
var link = copyrightSection.querySelector('a');
if (link) {
var text = link.textContent;
var updatedText = text.replace('© ', '© 2016-');
link.textContent = updatedText;
}
}
});
</script>