主题源地址:
在保留源样式的基础下,对该主题进行小范围的改造。
为了兼容非现代浏览器,同时新增更现代的 lang 属性(见[HTML lang属性小记](https://blog.lkurococ.top/post/HTML_langNotes.html))
将原第10行的 <html> 改为
<html>
<html lang="zh-cmn-Hans" class="no-js">
DNS Prefetch 是一种 DNS 预解析技术。当你浏览网页时,浏览器会在加载网页时对网页中的域名进行解析缓存,这样在你单击当前网页中的连接时就无需进行 DNS 的解析,减少用户等待时间,提高用户体验。 目前每次 DNS 解析,通常在200ms以下。针对 DNS 解析耗时问题,一些浏览器通过 DNS Prefetch 来提高访问的流畅性。
<meta http-equiv="x-dns-prefetch-control" content="on"> <link rel="dns-prefetch" href="//cdn.jsdelivr.net" /> <!-- jsDelivr CDN --> <link rel="dns-prefetch" href="//gstatic.loli.net" /> <!-- loli CDN --> <link rel="dns-prefetch" href="//fonts.loli.net" /> <!-- loli CDN --> <link rel="dns-prefetch" href="//dn-qiniu-avatar.qbox.me/" /> <!-- 七牛 Gravatar源 --> <link rel="dns-prefetch" href="//q1.qlogo.cn/" /> <!-- 腾讯 QQ头像源 --> <link rel="preconnect" href="//cravatar.cn/avatar/" /> <!-- Cravatar源 --> <link rel="preconnect" href="//6262-bb-f5c0f-1252354806.tcb.qcloud.la" /> <!-- 说说图片源 -->
有用不到的可以有所删减。
直接在 <head> 加入:
<head>
<meta http-equiv="Cache-Control" content="no-transform"> <meta http-equiv="Cache-Control" content="no-siteapp">
在原第13行
<meta name="viewport" content="width=device-width, initial-scale=1, shrink-to-fit=no">
的基础上面补充了 maximum-scale=1 ,现在的完整为:
maximum-scale=1
<meta name="viewport" content="width=device-width, initial-scale=1, maximum-scale=1, shrink-to-fit=no">
将原第35行
<link href="https://fonts.googleapis.com/css?family=Open+Sans:300,400,600,700" rel="stylesheet">
中的 Google API 替换为
<link href="https://fonts.loli.net/css?family=Open+Sans:300,400,600,700" rel="stylesheet">
我们十分推崇现代浏览器的普及,一是安全,二是为了更佳的状态浏览本站。
在原第88行 <body> 下面添加:
<body>
<!--[if IE]> <script> alert("你正在使用 过时 的浏览器,请 升级浏览器 以获得更好的体验!"); window.location.href="https://support.dmeng.net/upgrade-your-browser.html?referrer="+encodeURIComponent(window.location.href); </script> <![endif]-->
加入后会在访问者使用非现代浏览器时弹出提示框。
部分内容参考友人 Ayu 的文章 Typecho-Butterfly主题改造(持续更新)
本站之前使用的是 黑石哔哔。
创建一个 shuoshuo.php 文件在主题目录文件夹里,源码如下:
<?php /** * 说说-黑石哔哔 * * @package custom * **/ ?> <?php $this->need('header.php'); ?> <main> <section class="section section-lg section-hero section-shaped"> <?php printBackground(($this->fields->pic?$this->fields->pic:getRandomImage($this->options->randomImage)), $this->options->bubbleShow); ?> <div class="container shape-container d-flex align-items-center py-lg"> <div class="col px-0 text-center"> <div class="row align-items-center justify-content-center"> <h1 class="text-white">填你自己想要的标题</h1> </div> </div> </div> </section> <section class="section section-components bg-secondary content-card-container"> <div class="container container-lg py-5 align-items-center content-card-container"> <div class="card shadow content-card content-card-head"> <section class="section"> <div class="container"> <div class="content"> <div id="bbtalk"></div> <!--未开启Pjax可以直接删去注释部分,并忽略回调代码、footer加入js两步 <script src="https://cdn.jsdelivr.net/npm/bbtalk@0.1.5/dist/bbtalk.min.js"></script> <script> bbtalk.init({ appId: "你LeanCloud应用的AppID", appKey: "你LeanCloud应用的MasterKey", serverURLs: '你LeanCloud应用的Request 域名(api)' }) </script> --> </div> </div> </section> </div> </div> </section> </main> <?php $this->need('footer.php'); ?>
后台 - 主题外观 - 设置外观 - 自定义 css :
time { color:#44d7b6; } .btn { font-size: 1rem; text-decoration: none; display: inline-block; font-weight: bold; text-align: center; box-sizing: border-box; padding: 0; padding: 0.2rem 1rem; line-height: normal; background: none; color: var(--hei); border-style: solid; border-width: 3px; border-color: var(--mhei); border-radius: 10rem; letter-spacing: 0.4px; transition: .18s ease-out; -webkit-transition: .18s ease-out; font-family: 'Mulish', -apple-system, "PingFang SC", "Microsoft Yahei UI", "Microsoft Yahei", sans-serif } .btn { border-color: #2dce89; }
后台 - 主题外观 - 设置外观 - pjax 回调代码 :
未开启Pjax可以直接删去源码中的注释部分,并忽略这一步和下一步
if ($("div#bbtalk").length > 0) { bbtalk.init({ appId: "你LeanCloud应用的AppID", appKey: "你LeanCloud应用的MasterKey", serverURLs: '你LeanCloud应用的Request 域名(api)' }); };
在 footer.php
</body> </html>
内容之前加入
<script src="https://cdn.jsdelivr.net/npm/bbtalk@0.1.5/dist/bbtalk.min.js"></script>
在非说说页面会向 Console 输出 bbtalk.min.js:17 Initializing LeanCloud Storage SDK which has already been initialized. Reinitializing the SDK might cause problems like unexpected cross-app data writing and invalid relations.已解决该问题
大功完成后仅需再绑定微信、在后台新建一个页面,自定义模板选择说说-黑石哔哔即可。
说说-黑石哔哔
部分内容参考文章 ispeak-bber 前端美化增加版,支持歌曲分享
本站现在使用的是哔哔点啥。
创建一个 shuoshuo2.php 文件在主题目录文件夹里,源码如下:
<?php /** * 说说-哔哔点啥 * * @package custom * **/ ?> <?php $this->need('header.php'); ?> <main> <section class="section section-lg section-hero section-shaped"> <?php printBackground(($this->fields->pic?$this->fields->pic:getRandomImage($this->options->randomImage)), $this->options->bubbleShow); ?> <div class="container shape-container d-flex align-items-center py-lg"> <div class="col px-0 text-center"> <div class="row align-items-center justify-content-center"> <h1 class="text-white">填你自己想要的标题</h1> </div> </div> </div> </section> <section class="section section-components bg-secondary content-card-container"> <div class="container container-lg py-5 align-items-center content-card-container"> <div class="card shadow content-card content-card-head"> <section class="section"> <div class="container"> <div class="content"> <div id='speak'> <!--未开启Pjax可以直接删去注释部分,并忽略回调代码、footer加入js两步 <script type="text/javascript" src="/js/timeago.min.js" charset="utf-8" ></script> <script type="text/javascript" src="https://cdn.jsdelivr.net/gh/kuole-o/bber-ispeak@main/dist/ispeak-bber.min.js" charset="utf-8" ></script> <script> ispeakBber .init({ el: '#speak', // 容器选择器 name: '夜的第八章 ??', // 显示的昵称 envId: 'blogpkly-13278c', // 环境id region: 'ap-shanghai', // 腾讯云地址,默认为上海 limit: 5, // 每次加载的条数,默认为5 avatar: 'https://cdn.guole.fun/img/gl.jpg', // 头像地址 fromColor:'rgb(245, 150, 170)', // 下方标签背景颜色 默认 rgb(245, 150, 170) loadingImg: 'https://7.dusays.com/2021/03/04/d2d5e983e2961.gif', // 自定义loading的图片,示例值为默认值 dbName:'talks' // 数据的名称,默认talks,避免有人的命名不是这个,所以加入此配置字段。 }) .then(function() { // 哔哔加载完成后的回调函数,你可以写你自己的功能 console.log('哔哔 加载完成') }) </script>--> </div> </div> </section> </div> </div> </section> </main> <?php $this->need('footer.php'); ?>
if ($("div#speak").length > 0) { ispeakBber.init({ el: '#speak', // 容器选择器 name: '夜的第八章', // 显示的昵称 envId: 'blogpkly-13278c', // 环境id region: 'ap-shanghai', // 腾讯云地址,默认为上海 limit: 5, // 每次加载的条数,默认为5 avatar: 'https://cdn.guole.fun/img/gl.jpg', // 头像地址 fromColor: 'rgb(245, 150, 170)', // 下方标签背景颜色 默认 rgb(245, 150, 170) loadingImg: 'https://7.dusays.com/2021/03/04/d2d5e983e2961.gif', // 自定义loading的图片,示例值为默认值 dbName: 'talks' // 数据的名称,默认talks,避免有人的命名不是这个,所以加入此配置字段。 }).then(function() { // 哔哔加载完成后的回调函数,你可以写你自己的功能 console.log('哔哔 加载完成') }); };
<script type="text/javascript" src="//guole.fun/js/timeago.min.js" charset="utf-8" ></script> <script type="text/javascript" src="//cdn.jsdelivr.net/gh/kuole-o/bber-ispeak@main/dist/ispeak-bber.min.js" charset="utf-8" ></script>
在 comments.php 第87行改为
<div id="author-head" class="icon-shape rounded-circle text-white" style="width: 2rem;height: 2rem;background-image: url(//dn-qiniu-avatar.qbox.me/avatar/);background-position: center;background-size: cover;background-repeat: no-repeat;"></div>
第289行改为:
url = "//dn-qiniu-avatar.qbox.me/avatar/" + md5($(this).val()) + "?s=40&d="
Typecho 根目录 config.inc.php 添加一行
define('__TYPECHO_GRAVATAR_PREFIX__', '//dn-qiniu-avatar.qbox.me/avatar/');
即可使用七牛 CDN,防止被墙后无法在大陆地区直接加载 Gravatar 头像。
<?php $comments->gravatar(80, ''); ?>
url = "//cravatar.cn/avatar/" + md5($(this).val()) + "?s=40&d="
define('__TYPECHO_GRAVATAR_PREFIX__', '//cravatar.cn/avatar/');
即可使用 Cravatar 源,防止被墙后无法在大陆地区加载 Gravatar 头像,同时兼容 Cravatar 、QQ头像。
Cravatar 完美兼容所有 Gravatar 头像 API 接口,同时如果你未在 Cravatar 设置头像,则会先尝试调用 Gravatar 上的头像数据,其后是 QQ 头像,最后会返回我们为你准备的一组默认头像。 —— Cravatar - 开发文档 https://cravatar.cn/developers
Cravatar 完美兼容所有 Gravatar 头像 API 接口,同时如果你未在 Cravatar 设置头像,则会先尝试调用 Gravatar 上的头像数据,其后是 QQ 头像,最后会返回我们为你准备的一组默认头像。
—— Cravatar - 开发文档 https://cravatar.cn/developers
https://cravatar.cn/developers
在主题文件夹下 Bubble\assets\js\bbrender.js ,将第36行该成
res += lnk + '" rel="nofollow" class="friend-link" target="_blank"><div class="friend-container"><div class="friend-avatar rounded-circle" style="background:url(';
即可对友链标签添加 rel="nofollow" ,提升搜索引擎友好度。
::-webkit-scrollbar-thumb{ background-color:#999; height:50px; outline-offset:-1px; outline:1px solid #fff; -webkit-border-radius:0px; border: 1px solid #fff; } ::-webkit-scrollbar-thumb:hover{ background-color:#b9351f; height:50px; -webkit-border-radius:0px; } ::-webkit-scrollbar{ width:7px; height:7px; } ::-webkit-scrollbar-track-piece{ background-color:#fff; -webkit-border-radius:0;
::-moz-selection { background-color: #B45B3E; color: #fff; text-shadow: 1px 1px 1px rgba(0, 0, 0, 0.3); } ::-webkit-selection { background-color: #B45B3E; color: #fff; text-shadow: 1px 1px 1px rgba(0, 0, 0, 0.3); } ::selection { background-color: #B45B3E; color: #fff; text-shadow: 1px 1px 1px rgba(0, 0, 0, 0.3); }
h1,.h1,h2,.h2,h3,.h3,h4,.h4,h5,.h5,h6,.h6,p,a{ -moz-osx-font-smoothing: grayscale; -webkit-font-smoothing: antialiased; }
经 YUI Compressor 压缩后的 CSS 代码:
::-webkit-scrollbar-thumb{background-color:#999;height:50px;outline-offset:-1px;outline:1px solid #fff;-webkit-border-radius:0;border:1px solid #fff}::-webkit-scrollbar-thumb:hover{background-color:#b9351f;height:50px;-webkit-border-radius:0}::-webkit-scrollbar{width:8px;height:8px}::-webkit-scrollbar-track-piece{background-color:#fff;-webkit-border-radius:0}::-moz-selection{background-color:#b45b3e;color:#fff;text-shadow:1px 1px 1px rgba(0,0,0,0.3)}::-webkit-selection{background-color:#b45b3e;color:#fff;text-shadow:1px 1px 1px rgba(0,0,0,0.3)}::selection{background-color:#b45b3e;color:#fff;text-shadow:1px 1px 1px rgba(0,0,0,0.3)}h1,.h1,h2,.h2,h3,.h3,h4,.h4,h5,.h5,h6,.h6,p,a{-moz-osx-font-smoothing:grayscale;-webkit-font-smoothing:antialiased}
将上文直接添加到主题文件夹下 /assets/css/main.min.css末尾即可。
/assets/css/main.min.css
部分内容参考 秦枫鸢梦 的文章 Typecho实现QQ邮箱识别生成头像地址
在 function.php 里面定义:
function isqq($email) { if ($email) { if ($email == "自己的邮箱地址"){ echo "自己的logo、头像地址"; } else if (strpos($email, "@qq.com") !== false) { $email = str_replace('@qq.com', '', $email); if(is_numeric($email)){ echo "//q1.qlogo.cn/g?b=qq&nk=" . $email . "&s=100"; }else{ $mmail = $email.'@qq.com'; $email = md5($mmail); echo "//dn-qiniu-avatar.qbox.me/avatar/" . $email . "?s=100"; } } else { $email = md5($email); echo "//dn-qiniu-avatar.qbox.me/avatar/" . $email . "?s=100"; } } else { echo "//dn-qiniu-avatar.qbox.me/avatar/null?s=100"; } }
对用户的邮箱进行识别,提取出 QQ 号,显示 QQ 头像;但是对非 QQ 头像的,则显示 Gravatar 头像库头像。 新增对自己的邮箱地址进行识别,返回自定义的头像
对用户的邮箱进行识别,提取出 QQ 号,显示 QQ 头像;但是对非 QQ 头像的,则显示 Gravatar 头像库头像。
新增对自己的邮箱地址进行识别,返回自定义的头像
将 comments.php 文件中的第24行替换为:
<img class="avatar" src="<?php isqq($comments->mail); ?>" width="80" height="80">
即可完成对头像来源的判断和使用。
今天(14/09/2021)心血来潮,装了个 Firefox ,惊讶的发现跟 TLS 握手一直失败,也不能一键复制,经过排查在 footer.php 的第250行
<script src="https://cdn.jsdelivr.net/npm/prismjs@1.20.0/plugins/copy-to-clipboard/prism-copy-to-clipboard.min.js"></script>
引用的 js 会默认引用 //cdnjs.cloudflare.com 的 clipboard.min.js,因为众所周知的原因,无法直连,于是将源代码中的地址改为 //cdn.jsdelivr.net,代码如下:
//cdnjs.cloudflare.com
//cdn.jsdelivr.net
!function(){if("undefined"!=typeof self&&self.Prism&&self.document)if(Prism.plugins.toolbar){var r=window.ClipboardJS||void 0;r||"function"!=typeof require||(r=require("clipboard"));var i=[];if(!r){var o=document.createElement("script"),e=document.querySelector("head");o.onload=function(){if(r=window.ClipboardJS)for(;i.length;)i.pop()()},o.src="https://cdn.jsdelivr.net/npm/clipboard@2.0.8/dist/clipboard.min.js",e.appendChild(o)}Prism.plugins.toolbar.registerButton("copy-to-clipboard",function(e){var t=document.createElement("button");return t.textContent="Copy",r?o():i.push(o),t;function o(){var o=new r(t,{text:function(){return e.code}});o.on("success",function(){t.textContent="Copied!",n()}),o.on("error",function(){t.textContent="Press Ctrl+C to copy",n()})}function n(){setTimeout(function(){t.textContent="Copy"},5e3)}})}else console.warn("Copy to Clipboard plugin loaded before Toolbar plugin.")}();
我已经做好并保存了一个上传至 GitHub 了,如果需要使用我上传的版本,只需将 footer.php 的第250行修改为:
<script src="https://cdn.jsdelivr.net/gh/6isixi/ImgCloud/js/prism-copy-to-clipboard.min.js"></script>
即可完美解决该问题。
由于自己添加了不少个人才用得到的页面,因此,对页脚进行魔改。
<?php WordsCounter_Plugin::allOfCharacters(); ?> 是属于 Elatis 的 WordsCounter 插件,如果未启用请删除相关代码,否则会导致 HTTP 500 错误。
<?php WordsCounter_Plugin::allOfCharacters(); ?>
将 footer.php 中的原页脚的:
<div class="col-md-6"> <div class="copyright"> <?php _e($this->options->footerText); ?> </div> </div> <div class="col-md-6"> <ul class="nav nav-footer justify-content-end"> <li class="nav-item"> <a class="nav-link" href="<?php $this->options->siteUrl(); ?>">首页</a> </li> <?php $this->widget('Widget_Contents_Page_List')->to($pages); while($pages->next()): ?> <li class="nav-item"> <a class="nav-link" href="<?php $pages->permalink(); ?>"><?php $pages->title(); ?></a> </li> <?php endwhile; ?> <?php if($this->user->hasLogin()): ?> <li class="nav-item"><a class="nav-link" href="<?php $this->options->adminUrl(); ?>">进入后台(<?php $this->user->screenName(); ?>)</a></li> <li class="nav-item"><a class="nav-link" href="<?php $this->options->logoutUrl(); ?>">退出</a></li> <?php else: ?> <li class="nav-item"><a class="nav-link" href="<?php $this->options->adminUrl('login.php'); ?>">登录</a></li> <?php endif; ?> </ul> </div>
改为:
<div class="col-md-12"> <div class="copyright" style="text-align:center"> ©<?php echo date( 'Y'); ?><a href="你的主页链接地址" class="footer-link" rel="nofollow" target="_blank">你的主页站名</a> | 书写了 <?php WordsCounter_Plugin::allOfCharacters(); ?> 字<br> Powered by<a class="footer-link" rel="nofollow" target="_blank" href="http://www.typecho.org">Typecho</a> | <?php _e($this->options->footerText); ?> </div> </div> <div class="col-md-12"> <ul class="nav nav-footer justify-content-center"> <li class="nav-item"> <a class="nav-link" href="<?php $this->options->siteUrl(); ?>">首页</a> </li> <?php $this->widget('Widget_Contents_Page_List')->to($pages); while($pages->next()): ?> <li class="nav-item"> <a class="nav-link" href="<?php $pages->permalink(); ?>"> <?php $pages->title(); ?> </a> </li> <?php endwhile; ?> <li class="nav-item"> <a class="nav-link" href="<?php $this->options->siteUrl(); ?>privacy.html">隐私政策</a> </li> <?php if($this->user->hasLogin()): ?> <li class="nav-item"><a class="nav-link" href="<?php $this->options->adminUrl(); ?>">进入后台(<?php $this->user->screenName(); ?>)</a></li> <li class="nav-item"><a class="nav-link" href="<?php $this->options->logoutUrl(); ?>">退出</a></li> <?php else: ?> <li class="nav-item"><a class="nav-link" href="<?php $this->options->adminUrl('login.php'); ?>">登录</a></li> <?php endif; ?> </ul> <ul class="nav nav-footer justify-content-center"> <li class="nav-item"> <a class="nav-link" href="CDN链接" target="_blank" rel="nofollow">CDN信息</a> </li> </ul> <ul class="nav nav-footer justify-content-center"> <li class="nav-item"> <a class="nav-link" href="http://beian.miit.gov.cn/" target="_blank" rel="nofollow">备案号</a> </li> </ul> </div>
后台 - 主题外观 - 设置外观 - 关闭 开启 viewer.js 图片查看器(点击放大)
在 header,php 加入
<link rel="stylesheet" href="//cdn.jsdelivr.net/npm/@fancyapps/fancybox@3.5.7/dist/jquery.fancybox.min.css" />
在 footer.php 加入
<script src="//cdn.jsdelivr.net/npm/@fancyapps/fancybox@3.5.7/dist/jquery.fancybox.min.js"></script>
<script type="text/javascript"> $(document).ready(function () { $.fancybox.defaults.hash = false; }); </script>
在 functions.php 定义
function parseContent($obj){ $obj->content = preg_replace("/<a href=\"([^\"]*)\">/i", "<a href=\"\\1\" target=\"_blank\">", $obj->content); $pattern = '/<\s*img[\s\S]+?(?:src=[\'"]([\S\s]*?)[\'"]\s*|alt=[\'"]([\S\s]*?)[\'"]\s*|[a-z]+=[\'"][\S\s]*?[\'"]\s*)+[\s\S]*?>/i'; $replacement = '<figure><a href="$1" data-fancybox="gallery" no-pjax data-type="image" data-caption="$2" ><img src="$1" alt="$2" title="点击放大图片"></a></figure>'; $obj->content = preg_replace($pattern, $replacement, $obj->content); echo trim($obj->content); }
后台 - 主题外观 - 设置外观 - pjax 回调代码:
$(document).ready(function() { $('[data-fancybox="gallery"]').fancybox() });
然后将 post.php page.php 中的 <?php $this->content(); ?> 替换为 <?php parseContent($this); ?> 即可。
<?php $this->content(); ?>
<?php parseContent($this); ?>
参考文章: Fancybox Typecho 使用 fancybox 踩过的坑 fancybox实现图片灯箱效果
参考文章:
在 post.php 中将原 148、149行改为:
<li>本文于 <time datetime="<?php $this->date('c'); ?>"><?php echo date('d/m/Y A' , $this->modified); ?></time> 最后一次更新内容,请注意甄别内容的时效性</li> <li>本文采用 <a href="https://creativecommons.org/licenses/by-nc-sa/4.0/" target="_blank" rel="nofollow">CC BY-NC-SA 4.0</a> 许可协议。转载请注明来自 <a href="<?php $this->permalink() ?>" target="_blank"><?php $this->title() ?></a></li>
后台 - 主题外观 - 设置外观 - 自定义 css:
time { color:#44d7b6; }
在 header.php 中引入:
<link rel="stylesheet" href="https://cdn.jsdelivr.net/gh/DIYgod/OwO/dist/OwO.min.css" />
在 footer.php 中引入:
<script src="//cdn.jsdelivr.net/gh/DIYgod/OwO/dist/OwO.min.js"></script>
在 comments.php 中,原第115行,给 <textarea> 标签加入 OwO-textarea 类:
<textarea>
OwO-textarea
<textarea rows="8" cols="50" name="text" id="textarea" class="form-control OwO-textarea" required ><?php $this->remember('text'); ?></textarea>
原第117行下面(原第119行上面)加入:
<div class="OwO"></div>
if ($(".OwO").length > 0) { var OwO_demo = new OwO({ logo: 'OωO表情', container: document.getElementsByClassName('OwO')[0], target: document.getElementsByClassName('OwO-textarea')[0], api: '//cdn.jsdelivr.net/gh/kaygb/OwO-images/JSON/winds-owo.json', position: 'down', width: '100%', maxHeight: '250px' }) };