在 themeforest 购买一个主题以后 怎么本地调试
WordPress 很多主题和插件是和域名绑定的,那要是在本地开发调试,这个域名的问题怎么解决。是通过 hosts 解决吗?
WordPress 很多主题和插件是和域名绑定的,那要是在本地开发调试,这个域名的问题怎么解决。是通过 hosts 解决吗?
一年前的今天,一位刚刚考完期末考的大一学生,坐在电脑前
他用lamp部署了wordpress——他人生中的第一个博客,并起名为Newlearnerの小站
一段缘分,从这里开始
Newlearnerの小站终于在今天(7.12)走过了它的一周年纪念日,从建站一路走来,有许许多多的事情想要和大家分享。在这里首先要感谢各位读者和tg群的群友对本博客的支持和鼓励。
我将和大家讲述博客一年来走过的路,以及我如何使用Wordpress这个Blog CMS平台探索未知、记录点滴。
18年上半年我感受到了贴吧的没落,自己辛苦整理的内容无人问津,复读机的生活索然无味。
mbp吧里的大佬瑞仙森
偶尔有一次和我谈到了当前的现状,并且劝我别当复读机了,不如找一些自己感兴趣的事情做做。
导火索:在mbp吧发了一个答疑帖,并分享了一个自己整理的mbp型号表格。结果遭到隔壁吧mb吧的吧务插手,说我是借鉴了他们的图片样式而没有标注。于是注明,然而还是遭到了不依不饶的举报最后被吧务删帖。
发展:不能自由地发表自己的看法是我无法忍受的,于是离开了贴吧。直到六月底我开始接触VPS,搭建了国际网络之后想要物尽其用。搜索了「VPS用途」之后,发现还可以搭建博客,当时就萌发了这个想法并在18年7月12日付诸了行动,于是就有了大家今天所见的Newlearnerの小站。
博客的logo和名称从建站开始就一直沿用了,核心主题叫做「探索未知,记录点滴」,主要分享IT相关文章。作为一个非计算机专业的学生,是兴趣使然让我对IT相关产生了兴趣,深感自己的浅薄,于是想要有一个记录自己学习&感悟的地方。
博客是自己的自留地,在这里可以畅所欲言,而无需担心会被删帖。也可以即时修改与更新博客的内容,使其与时俱进。
写出来的文章不算是教程,而是自己在摸索过程中的记录与分享。若干年之后回头看看,也算是成长的历程了。
梦开始的样子:
现在:
从
2018.7.12
–2019.7.12
,Newlearnerの小站一岁了。在这一年里,博客文章共有60
篇,码了117,044
字共有
73,000
位用户来访了小站,网站用访问量(PV)为145,000
,目前日均PU在650
左右其中访问量最多的文章为Telegram群组/频道/机器人推荐,贡献了
50,100
次访问量小站在Alexa的世界排名约为
240,000
名,国内排名约为50,000-100,000
名博主平均更博速度为
4
篇每月,目前友链数量为8
个,评论数目为104
条网站
风雨无阻地运行了363
天,其中2
天因为不可抗力关站维护
从上图可见网站在进入9102之后访问量大增,在6月初曾经关站两天,目前访问量依然在小幅增长中。小站的流量来源大多为谷歌搜索引擎,本人不喜欢硬广,有缘的人自然会相遇。相比1月初的2019,新的开始这篇博文的数据,小站的各项指标得到了长足的进步和增长。
今后也会认真更新博客,和各位大佬互相交换友链,即使个人博客不比昔日。希望等博客两周年时,又会看到不一样的Newlearnerの小站。
之前的Ribbon Lite一度被朋友吐槽很复古,后来更换了Kratos之后我对主题做了部分修改。
建站不久想给博客做一个运行时间统计,于是谷歌了相关办法,并决定把这个模块放到博客的侧栏。美中不足的是手机端不可以看到。
在侧栏中选择「自定义html」模块并添加,代码为:
<script> function secondToDate(second) { if (!second) { return 0; } var time = new Array(0, 0, 0, 0, 0); if (second >= 365 * 24 * 3600) { time[0] = parseInt(second / (365 * 24 * 3600)); second %= 365 * 24 * 3600; } if (second >= 24 * 3600) { time[1] = parseInt(second / (24 * 3600)); second %= 24 * 3600; } if (second >= 3600) { time[2] = parseInt(second / 3600); second %= 3600; } if (second >= 60) { time[3] = parseInt(second / 60); second %= 60; } if (second > 0) { time[4] = second; } return time; } </script> <script type="text/javascript" language="javascript"> function setTime() { // 博客创建时间秒数,时间格式中,月比较特殊,是从0开始的,所以想要显示5月,得写4才行,如下 var create_time = Math.round(new Date(Date.UTC(2018, 6, 12, 0, 0, 0)) .getTime() / 1000); // 当前时间秒数,增加时区的差异 var timestamp = Math.round((new Date().getTime() + 8 * 60 * 60 * 1000) / 1000); currentTime = secondToDate((timestamp - create_time)); currentTimeHtml = currentTime[0] + '年' + currentTime[1] + '天' + currentTime[2] + '时' + currentTime[3] + '分' + currentTime[4] + '秒'; document.getElementById("htmer_time").innerHTML = currentTimeHtml; } setInterval(setTime, 1000); </script> <strong>网站运行:<span id="htmer_time" style="color:grey;font-size: 12pt;"></span></strong>
博客的统计可以在Google Analytics后台看到详细的数据,但是我想在博客页面也显示出来。最后采用的方案适合大多人一样的,采用不蒜子统计。
官网:不蒜子-极简网页计数器
根据官网的方法,只需要在footer.php
里面增加两行代码就可以了。但是我的情况比较特殊,因为在我试用不蒜子统计的时候,网站已经有了一些流量,我想要做增量统计。所以最后在页脚的php页增加了如下代码:
<script src="//busuanzi.ibruce.info/busuanzi/2.3/busuanzi.pure.mini.js"></script> <span id="busuanzi_container_site_pv" style='display:none'>本站总访问量<span id="busuanzi_value_site_pv"></span>次</span> <script> $(document).ready(function() { var int = setInterval(fixCount, 50); // 50ms周期检测函数 var countOffset = 46081; // 46081为截止2019.3.14日访问本站的总page views数 function fixCount() { if (document.getElementById("busuanzi_container_site_pv").style.display != "none") { $("#busuanzi_value_site_pv").html(parseInt($("#busuanzi_value_site_pv").html()) + countOffset); clearInterval(int); } if ($("#busuanzi_container_site_pv").css("display") != "none") { $("#busuanzi_value_site_uv").html(parseInt($("#busuanzi_value_site_uv").html()) + countOffset); // 加上初始数据 clearInterval(int); // 停止检测 } } }); </script>
Kratos默认在文章开头只显示日期、点赞、阅读数等,不符合我的需求。
效果图:
在function.php
中加入如下代码:
function count_words_read_time () { global $post; $text_num = mb_strlen(preg_replace('/\s/','',html_entity_decode(strip_tags($post->post_content))),'UTF-8'); $read_time = ceil($text_num/400); $output .= '本文共' . $text_num . '个字,预计阅读时间' . $read_time . '分钟。'; return $output; } function count_words () { global $post; $text_num = mb_strlen(preg_replace('/\s/','',html_entity_decode(strip_tags($post->post_content))),'UTF-8'); $output .= '本文共' . $text_num . '个字'; return $output; }
然后在文章首页single.php
合适位置添加如下代码:
<i class="fa fa-book"></i><?php echo count_words_read_time(); ?><br>
在content.php
加入如下代码,使其在首页也生效:
<a href="<?php the_permalink() ?>"><i class="fa fa-book"></i> <?php echo count_words(); ?></a>
效果图:
这个主题依然没有提供文章最后修改时间,这可能会让几年后看到文章的人无法判断该文章的时效性,于是我经过谷歌,在single.php
加入如下代码:
<?php if ((get_the_modified_time('Y')*365+get_the_modified_time('z')) > (get_the_time('Y')*365+get_the_time('z'))) : ?> 最后修改:<?php the_modified_time('Y-m-j h:s'); ?><?php else : ?><?php endif; ?>
原主题自带的meta头很糟糕,在tg中放出链接甚至不能显示文章简介,在这里要特别感谢青鸟大佬为我指出这个问题。后来我在header.php
中加入如下代码:
<?php // add meta keywords and description by conditionary //以下内容针对网站首页 if ( is_home() || is_front_page() ) { //判断是否为首页 $description = "Newlearner365的自留地,不定期更新一些关于IT的文章。探索未知,记录点滴!";//将双引号中的内容修改为你自己的 $keywords = "博客,Mac,iOS,VPS,IT,技术分享";//将双引号中的内容修改为你自己的 } elseif ( is_singular() && !is_attachment() ) { $exerpt = $post->post_excerpt; //2012.11.01 因 get_the_excerpt() 会在没有设定 excerpt 时自动生成一个 excerpt 而导致某些情况下出错。 if ( $exerpt != '') { //是否存在摘要 $description = $exerpt; //使用文章摘要作为描述 } else { $description = $post->post_content; //使用文章内容的前 200 个字符(后面会进行截短)作为描述 } $keywords =""; $tags = wp_get_post_tags( $post->ID, array( 'fields' => 'names' ) ); $keywords = implode(",", $tags); } elseif(is_category()) { $description = category_description(); // $keywords = ""; } elseif(is_tag()) { $description = tag_description(); // $keywords = ""; } if ( $description != '' ) { $description = preg_replace('#\[[^\]]+\]#', '', $description); // 清理 description 中的 HTML 代码,并截短为 200 个字符 $description = wp_html_excerpt( wp_strip_all_tags( $description, true ), 200 ); ?> <meta name="description" content="<?php echo $description; ?>" /> <?php } //类似 description 来处理 keywords if ( $keywords !='' ): ?> <meta name="keywords" content="<?php echo $keywords; ?>" /> <?php endif; ?>
1、给调试中的控制台(console)加入:“居然被你发现啦,既然这样来telegram一起吹水:https://t.me/NewlearnerGroup”文字
通过控制台在主题中找到相关文件并加入:
var copyright = function() { console.log("居然被你发现啦,既然这样来telegram一起吹水:https://t.me/NewlearnerGroup"); }
2、给网站源代码页加入了字符画
<!-- __ _ /\ \ \_____ _| | ___ __ _ _ __ _ __ ___ _ __ / \/ / _ \ \ /\ / / |/ _ \/ _` | '__| '_ \ / _ \ '__| / /\ / __/\ V V /| | __/ (_| | | | | | | __/ | \_\ \/ \___| \_/\_/ |_|\___|\__,_|_| |_| |_|\___|_| -->
3、加入了复制提醒
在header.php
加入如下代码:
<script type="text/javascript"> document.body.oncopy=function(){alert("复制成功!转载请注明出处");} </script>
主题并不支持移动端搜索以及侧边栏显示,这令人很头疼
顶部的菜单导航栏排布太多在低分屏下会出现重叠情况,我只好加了一个「更多」菜单,并将多余的项目收入其中
简单和大家分享下我正在用的插件,wp的一大好处就是主题和插件的支持很到位。
1、Autoptimize
可以优化图片、js、css的加载速度
2、Captcha by BestWebSoft
数字评论验证码插件,有效防范垃圾评论
3、Crayon Syntax Highlighter
代码高亮插件,不过早就对它不满意了。什么时候不咕了打算用prism.js替换之
4、Cresta Posts Box
免费版会在读者翻到文章结尾处时自动弹出上一篇的简介,实用的小插件
5、Google Analytics Dashboard for WP
谷歌分析插件,免去直接修改themes文件的麻烦,还可以直接在admin后台显示统计情况
6、Google XML Sitemaps
网站地图插件,会生成方便谷歌收录的网站地图
7、Permalink Manager Lite
自定义每篇文章的link
8、Sassy Social Share
博文分享栏,对国内社交软件支持有限
9、TablePress
表格插件,可以拿来制作友链等
10、Unique Cursor
更改网站鼠标样式
11、UpdraftPlus
网站备份及恢复
12、WP FancyZoom
支持博文图片以大图显示
13、WP Super Cache
动态页面缓存,有助于加快网页打开速度,支持cdn嵌套
14、先荐
在每篇博文底部以及侧边栏推荐相关类型博文
15、年度归档
归档页面所用插件,按年份月份归档
16、WP Word Count
统计博客字数
只要咱有钱续费服务器,Newlearnerの小站就会一直陪伴大家。第二年将会考虑增加一些硬件、Mac相关的话题和文章。
囿于年龄和学生身份等限制,有些领域我还无法去涉足。博客作为一个小型的自媒体,发表的观点也是很个人的,如有幼稚和片面的地方希望大家多多宽容!
虽然没有加入博客十年之约,但是还是希望能认真写好每一篇文章,探索未知,记录点滴。
1、我的读者们
很多人其实是在谷歌认识这个网站的,在网站建立前期我还去过贴吧和威锋做过硬广。谢谢你们的关注和留言。
2、舍友ss大佬
在网站建立前期给了我很多有用的指导,并帮助我迁移网站到搬瓦工。
3、不愿透露姓名的J大和朋友们
一年内给了我很多鼓励和支持,也帮我纠正了一些错误的地方。写博客始于热爱,贵于坚持。
最后给大家带来一个小抽奖,评论本篇博文即可参与,留下你的真实邮箱。在7.13日晚九点半会准时开奖。
奖品:2个奈飞4k独享账号1个月+2个spotify美区会员2个月
WordPress 5.0 正式版已于 2018-12-07 发布,自建 WordPress 用户可以在 WordPress 后台的 Web 管理页面中进行升级。本次更新的最明显的两个特点就是:1. 后台管理使用了全新的编辑器,2. 新增了 2019 年的主题,该主题适配这个全新的编辑器。
这次的 5.0 是一个大版本更新,而不像之前的 4.9、4.8 更新那样,这从版本号就可以看出。
这个新的块编辑器(Gutenberg Editor)给人的第一感受就是更加简洁了,这个新的编辑器有着更大的留白。初次使用编辑器的时候会感觉有些不适应,这是因为新的编辑器中没有我们熟悉的工具条了。取而代之的是一个简单的添加块(Add Block)按钮和其他的一些基本操作。
在新版的编辑器中,每一个自然段、图片、副标题、引用等都是一个 “块”。你可以为每个块进行自定义操作,如为每个自然段设置不同的字体大小、字体颜色,甚至是背景色和自定义 CSS。而这一切都是通过右侧的 “组件” 工具可视化的实现的。
你可以直接拖移块,以实现拖移自然段等效果。
新版编辑器兼容老板编辑器。要想使用老款的编辑模式,可以通过插入一个或多个经典块(Classic Block)来实现。这个经典块与新编辑器中的其他块(如自然段块、副标题块等)同等级别。经典块中能包含一个或多个自然段、副标题,对于简单的排版,它可以代替最新的块编辑器。在使用经典块时,你依然能够看到你所熟悉的工具条。
经典块截图
在编辑以前发布的文章与页面时,默认依然使用原有的编辑模式,即在新的编辑器中包含一个经典块。
原有的块都是与 HTML 标签对应的,功能相对少一些。经典块用于兼容上一代编辑器。要想使用新特性,你需要学习使用这些新的块。
<p>
<h1>
~ <h6>
标题。<ul>
或 <ol>
列表。<!--more-->
。<img>
。<blockquote>
。新版的应用块支持了引文(Citation)。video
Shortcode。<hr>
。<pre>
。<pre>
和 <code>
组合。新版本中新增了很多块,通过使用这些块,你可以直接可视化地插入一些你想要的内容,而不用编辑源代码或者是使用插件。
<pre>
实现的。可以实现英文字符的等宽显示。以下内容原本可以作为 Widgets 在网页菜单中添加。现在还可以作为块在文章中直接添加。
除此之外,现在还有了嵌入(Embed)功能,可以直接嵌入第三方内容了,如 Twitter、YouTube、SoundCloud 等。
为了更好的配合新的编辑器的所有排版功能,WordPress 同时推出了全新的 2019 默认主题。详情
正如以往的默认主题一样,新的 WordPress 主题也是十分通用的。然而我感觉新的 2019 主题不如上一个 2017 主题(即本 Blog 正在使用的主题)简洁。
WordPress 不保证老版本继续提供安全性更新,所以你应该升级到最新的 5.0 版本。然而实际上,从 WordPress 的版本历史可以看出,目前 WordPress 仍在维护 3.7(发布于 2013-10-24)及之后的所有版本。所以即使你不更新 5.0 版本,你也可能继续收到安全性更新。
需要注意的是,每次更新 WordPress 版本,尤其是大版本更新,其源代码中的一些函数功能会有所改变,这意味着并不保证你的插件能够在新的 WordPress 中正确运行。你应当检查一下你所启用的插件是否能够在最新版本上正确运行,或者已经发布了适配新版本的更新。如果你是插件开发者,你应该有安装测试版 WordPress 的站点,并早该让你的插件适配最新的版本。
在升级前,请务必备份你的站点。对于 WordPress 而言,你需要备份 WordPress 的代码目录以及数据库内容。
配置全站 CDN 可以缓存 HTML 页面和加快页面首次加载所耗时间。本文重点讲述 WordPress 的全站缓存,国内外 CDN 混用的解决方案,以及让页面也在 CDN 上缓存的正确做法。本文主要介绍 CloudFront,同时也对 Cloudflare、又拍云、百度云加速、KeyCDN、Google Cloud CDN 这几家 CDN 进行对比。
就算不缓存任何内容,全站 CDN 也是有他的优点的:
CloudFront 有 Amazon 自建的网络,单价较高但是 0 元起步,适合中小客户。本文将重点介绍 CloudFront 和 WordPress 配合实现动静分离,缓存 HTML 页面。之后将对比其他的一些 CDN。
CloudFront 作为全站 CDN 的特性:
先去 CloudFront 控制面板,点击 “Create Distribution”,选择 “Web”,然后进行类似如下的配置。源站配置注意 Origin Domain Name 必须是完整域名,而且如果用了 HTTPS,那么那个域名下必须有配置有效证书。
缓存配置,我把 Host 加入了 Header 白名单,Cookie 要添加 wordpress*
和 wp*
到白名单。
然后前端配置,证书点 “Request or Import a Certificate with ACM” 就能申请 Amazon 颁发的证书了。CNAMEs 下填写你的网站的域名。
注意,创建后可能要等不到一小时才能被访问到。 为了根域名和 CloudFront 配合使用,我还得换 Route 53 这个 DNS 解析。由于这是精度非常高的 GeoDNS,是需要将解析服务器向各大 DNS 缓存服务器去提交,让这些缓存服务器去针对你的 DNS 缓存服务器加入到启用 EDNS Client Subnet 的白名单中。还好 Route 53 是最流行的 GeoDNS 之一,所以如果你用它给的 NS 记录,而不去自定义,就不用操心这个了。在配置根域名时,直接选择 A 记录,然后开启 Alias,填写 CloudFront 域名就行。如果想要支持 IPv6,那就再建一个 AAAA 记录即可。这样的话如果你从外部解析,你会直接解析到 A 记录和 AAAA 记录,而不是 CNAME 了!
此时,CloudFront 就配置完了。现在 CloudFront 会自动缓存页面约一周的时间,所以需要配置文章更新时清理缓存。我写了一个插件,可以在有文章更新/主题修改/内核更新时清理所有缓存,新评论时清理文章页面,控制刷新频率为 10 分钟(这是由于 CloudFront 刷新缓存的速度是出奇的慢,而且刷新缓存只有前一千次免费)。欢迎使用我制作的插件。 不过,CloudFront 在国内的访问速度还不如我之前用的 GCE,这可怎么办?没关系,Route 53 可以 GeoDNS,我把中国和台湾还是解析到了原本的 GCE 上,这样速度其实只提不减。注意,若要这样做,原本的服务器也要有有效证书(同理,你要是域名已经备案,则可以设置为国内的 CDN 的 IP,达到国内外 CDN 混用的效果)。CloudFront 会影响 Let’s Encrypt 的签发,所以需要通过设置 Behaviors 和多个源站服务器,来继续实现 80 端口的文件认证。实际测试 Route 53 为中国解析的 IPv4 识别率为 100%,IPv6 的识别率欠佳。
国内解析情况:
$ dig @8.8.8.8 +short guozeyu.com a104.199.138.99$ dig @8.8.8.8 +short guozeyu.com aaaa2600:9000:2029:3c00:9:c41:b0c0:93a12600:9000:2029:9600:9:c41:b0c0:93a12600:9000:2029:2a00:9:c41:b0c0:93a12600:9000:2029:1600:9:c41:b0c0:93a12600:9000:2029:c00:9:c41:b0c0:93a12600:9000:2029:ce00:9:c41:b0c0:93a12600:9000:2029:6400:9:c41:b0c0:93a12600:9000:2029:ac00:9:c41:b0c0:93a1
国外解析情况:
$ dig @8.8.8.8 +short guozeyu.com a52.222.238.23652.222.238.22752.222.238.20752.222.238.10752.222.238.20852.222.238.7152.222.238.6852.222.238.67$ dig @8.8.8.8 +short guozeyu.com aaaa2600:9000:202d:5c00:9:c41:b0c0:93a12600:9000:202d:ec00:9:c41:b0c0:93a12600:9000:202d:7c00:9:c41:b0c0:93a12600:9000:202d:2a00:9:c41:b0c0:93a12600:9000:202d:9400:9:c41:b0c0:93a12600:9000:202d:c600:9:c41:b0c0:93a12600:9000:202d:f600:9:c41:b0c0:93a12600:9000:202d:6200:9:c41:b0c0:93a1
没错,CloudFront 分配给的 IP 数量就是多,让别人看了会感觉很厉害。
这里只对比国外的速度
这里也是只对比国外的速度
启动 CDN 后的 TTFB 几乎全面绿色,建立 TCP 和 TLS 的时间显著降低。
CloudFront 免费签发的 SSL 证书是多域名通配符证书(Wildcard SAN),并且主要名称是自定的,要比 Cloudflare 的共享证书高级。此类证书在 Cloudflare 上需要花费每月 10 美元。此类证书在市面上很难买到,而且价格取决于域名数量,在一年几千到几万不等。 然而,这个证书只能在 AWS 的 CloudFront 和负载均衡器上使用。
CloudFront 的证书链较长,会影响 TLS 时间,不过由于它同时也是 CDN,这样 TLS 时间几乎减少到了可以忽略不计的程度。主要还是因为 macOS 上还没有直接信任 Amazon Root CA,如果直接信任了,就用不着这样了。
以下列出的所有提供商(或某一提供商的某些版本),均符合以下条件,如果不符合则单独列出:
有自建的网络,最快的速度、最低廉的价格,主要提供网站安全防护,当然还附带了 CDN。其提供的 NS 服务也是(国外)业界第一的速度。本站国外使用了 Cloudflare,欢迎直接测试本站国外的速度。
Cloudflare 作为全站 CDN 的特性:
有一点不同的是,Cloudflare 签发的是共享证书,证书样式如下:
我觉得 Cloudflare 签发共享证书有两个原因,一是历史遗留问题:Cloudflare 专业版的 SSL 证书服务是支持无 SNI 的客户端的,而为了支持无 SNI 的客户端,一个 IP 就只能配置一个证书,所以就使用了共享证书节约 IP 资源。而现在免费版也有了 SSL,虽然免费版使用了 SNI 技术,但是证书总不能比付费版本还要高级吧,于是还是使用了共享 SSL 证书;二是为了增加更多的增值服务,现在 Cloudflare 上可以购买 Dedicated SSL Certificates,实现独立的证书(如果是付费版本启用,不支持 SNI 的客户端仍然 Fall back 到共享证书,所以仍然兼容不支持 SNI 的设备)。
简介同上,此版本适合大客户,流量越大越适合用。百度云加速是和 Cloudflare 深度整合的,其实基础设施完全一样,但百度云加速没有提供 API 接口。
Cloudflare 企业版作为全站 CDN 的特性:
使用自己管理的机房,网络有些受限于中国的环境,单价业界最低。
UPYUN 作为全站 CDN 的特性:
UPYUN 和下面的 KeyCDN 签发的都是 Let’s Encrypt 的独立证书,但都是单域名证书,甚至有 www 和无 www 的都要单独申请。
有全球最密集的网络集群,最快的速度、较低的单价,主要提供负载均衡,SSL 卸载,当然还附带了 CDN。由于缓存命中率低,需要超大型访问量的网站才有效。正是因为这一点,Google 自己只是将用户量极大的搜索服务用上了这个 CDN 系统,其余的很多 CDN 用的是 Cloudflare 和 Fastly 的。Google 的网络和 Cloudflare 和 Fastly 的网络有内网链接。详细介绍看本站的这篇文章
Google Cloud CDN 作为全站 CDN 的特性:
他们是租用别人的独立服务器,提供一体化 CDN 服务,单价业界最低。
KeyCDN 作为全站 CDN 的特性:
我为他写了一个插件可以实现完美清理缓存,详情见此
WordPress 可以分别设置 Site URL 和 Home URL,对于 https://example.com 这个网站,这两栏就可以这样设置:
然后,直接给 Home URL 上 CDN,在 CDN 或者源站上配置忽略 Cookie 信息。Site URL 回源,用作 WordPress 后台管理即可。
最近国外掀起了一股用 system-font 的热潮(额,好像国内一直都在用系统字体)。最近更新了 WordPress 4.7,并用上了其 2017 主题,这个主题正是使用系统字体。但是在 macOS 上查看发现中文显示的是繁体字形。 实在是太丑了,究其原因,其实是因为新版的主题的 system-font 用的是繁体中文字体:
html[lang^="zh-"] body,html[lang^="zh-"] button,html[lang^="zh-"] input,html[lang^="zh-"] select,html[lang^="zh-"] textarea { font-family: "PingFang TC", "Helvetica Neue", Helvetica, STHeitiTC-Light, Arial, sans-serif;}
看来这是 WordPress 的 Bug,已经提交并修复。在官方修复前,可以在外观的 “自定义” 里面添加以下 CSS 解决此问题:
html[lang="zh-CN"] body,html[lang="zh-CN"] button,html[lang="zh-CN"] input,html[lang="zh-CN"] select,html[lang="zh-CN"] textarea { font-family: "PingFang SC", "Helvetica Neue", Helvetica, STHeitiSC-Light, Arial, sans-serif}
为什么这次 WordPress 要为每个语言单独指定系统字体呢?因为如果将字体设置为 -apple-system
后,在 Safari 下能够正确显示苹方字体,但是在 Chrome 下显示的还是老的字体。但如果特定指明字体种类,就能正确显示了。
最近 Disqus 被某国的墙搞的十分不稳定,于是又用回了 WordPress 自带的评论系统,但是这个评论系统却不带评论者被回复时的邮件提醒。我有自己的发信服务器(AWS SES)系统,所以理论上可以配合插件实现这个效果。但是我看了很多插件,基本上操作页面都太复杂,而且回复的邮件通常不支持中文,我只需要一个简单的回复系统,不用那么麻烦,于是干脆自己开发一个,最终比较完美的实现了这个功能。
我开发的这个功能特点是:当评论者被回复时,邮件标题是 “Re: [文章标题]”,这样评论者的一个留言被多个人回复时,会被自动在本地邮件客户端上归为一类;而且评论者收到邮件后可以直接回复邮件,会直接给回复的发出者发邮件(不会显示在网站上,我也无法看到,这将是两人的私聊)。
邮件内容简洁,无额外无用的东西,不会被认定为 Spam。
所有代码已经放到 GitHub Gist 上。
<?phpfunction tlo_comment_mail_notify($comment_id) { global $comment_author; $comment = get_comment($comment_id); $parent_id = $comment->comment_parent ? $comment->comment_parent : ''; $spam_confirmed = $comment->comment_approved; $from = $comment->comment_author_email; $to = get_comment($parent_id)->comment_author_email; if (($parent_id != '') && ($spam_confirmed != 'spam') && $from != $to && $to != get_bloginfo('admin_email') ) { $blog_name = get_option('blogname'); $blog_url = site_url(); $post_url = get_permalink( $comment->comment_post_ID ); $comment_author = $comment->comment_author; $subject = 'Re: '.html_entity_decode(get_the_title($comment->comment_post_ID)); $headers[] = 'Reply-To: '.$comment_author.' <'.$comment->comment_author_email.'>'; $comment_parent = get_comment($parent_id); $comment_parent_date = tlo_get_comment_date( $comment_parent ); $comment_parent_time = tlo_get_comment_time( $comment_parent ); $message = <<<HTML<!DOCTYPE html><html lang="zh"> <head> <meta content="text/html; charset=utf-8" http-equiv="Content-Type"> <title>$blog_name</title> </head> <body> <style type="text/css"> img { max-width: 100%; height: auto; } </style> <div class="content"> <div> <p>$comment->comment_content</p> </div> </div> <div class="footer" style="margin-top: 10px"> <p style="color: #777; font-size: small"> — <br> Reply to this email to communicate with replier directly, or <a href="$post_url#comment-$comment_id">view it on $blog_name</a>. <br> You're receiving this email because of your comment got replied. </p> </div> <blockquote type="cite"> <div>On {$comment_parent_date}, {$comment_parent_time},$comment_parent->comment_author <<a href="mailto: $comment_parent->comment_author_email">$comment_parent->comment_author_email</a>> wrote:</div> <br> <div class="content"> <div> <p>$comment_parent->comment_content</p> </div> </div> </blockquote> </body></html>HTML; add_filter( 'wp_mail_content_type', 'tlo_mail_content_type' ); add_filter( 'wp_mail_from_name', 'tlo_mail_from_name' ); wp_mail( $to, $subject, $message, $headers ); }}add_action('tlo_comment_post_async', 'tlo_comment_mail_notify');function tlo_comment_mail_notify_async($comment_id) { wp_schedule_single_event( time(), 'tlo_comment_post_async', [$comment_id] );}add_action('comment_post', 'tlo_comment_mail_notify_async');// add_action('comment_post', 'tlo_comment_mail_notify');function tlo_mail_content_type() { return 'text/html';}function tlo_mail_from_name() { global $comment_author; return $comment_author;}function tlo_get_comment_time( $comment ) { $date = mysql2date(get_option('time_format'), $comment->comment_date, true); return apply_filters( 'tlo_get_comment_time', $date, $comment );}function tlo_get_comment_date( $comment ) { $date = mysql2date(get_option('date_format'), $comment->comment_date); return apply_filters( 'tlo_get_comment_date', $date, $comment );}
WordPress 是目前最流行的内容管理系统,本网站正是使用着它。但对于一个全新安装的 WordPress 来说,它的性能并不是很高,当网站的访问量突然增加时,优化性能就显得十分重要了。通过实施以下几个方案,可以大大提升 WordPress 访问速度:
WordPress 是一个动态的系统,如果不配置缓存,每次请求都需要服务器去读取数据库,生成页面内容,对于不同性能的主机,这可能就需要 20ms~1000ms 甚至更慢。如果能够正确配置缓存,就可以明显的加速,并且减少主机的运算资源。
使用插件来配置缓存是最简单的方法。在此推荐 WP Super Cache,这是 WordPress.com 出品的缓存插件,就页面缓存来说,功能非常全面,它支持多种缓存模式,包括 mod_rewrite
,如果你使用 Nginx,那么可以使用我这个配置文件,这样可以直接跳过 PHP 而直接服务静态文件,页面相应速度有显著提升。 同时,为浏览器返回正确的 Cache-Control
也是十分有必要的,尤其是 CSS 和 JS 文件。
对象缓存比页面缓存更灵活,使用范围更广,但速度肯定不如页面缓存。在此推荐 APCu 缓存系统。在 Ubuntu/Debian 安装方法如下:
$ apt install php-apcu
然后重启 Web server,安装 APCu Object Cache Backend 即可。 Redis、Memcached 等都算此类型的缓存,不过 APCu 配置最为简单,速度也很快。
比如我的网站使用北美东岸(主要)和亚洲的 VPS,主服务器配置了 Nginx,PHP 和 MySQL;亚洲的服务器只配置了 Nginx。在这些服务器上都配置好缓存,并用 lsyncd 同步缓存内容。每次访问时 Nginx 检查缓存,仅当没有缓存时代理,这样可以大大减少首页面的延迟。
使用全站 CDN,可以免去在自己的服务器上配置缓存的问题,还可以为服务器增加 HTTPS、HTTP/2 等功能,同时还能过滤非法流量,防御 DDOS(前提是你的 IP 没有被暴露,或者你设置好了白名单)。 除此之外,使用 CDN 后还能更加明显的提高网站加载速度,让访客从中受益。
CloudFlare 是可以免费使用的,使用 CloudFlare 前需要更改 DNS 服务商,然后无需额外配置就能使用了。但是它只会缓存 CSS、JS 和多媒体文件,不会缓存 HTML 页面,也就是说用户每次访问时还是会返回到原始服务器,页面本身的速度不会有明显提高,在原始服务器上配置缓存也是必要的。
KeyCDN 是一个按流量使用付费的 CDN 提供商,使用我制作的插件 Full Site Cache for KeyCDN 可以简单的对其配置,这个插件会自动刷新缓存。 KeyCDN 相比 CloudFlare,可以缓存 HTML 页面,大大减少源服务器的压力,同时在刷新缓存时可以通过 Tag 方式刷新,避免不必要的刷新。 在网站访问量较大时,使用 KeyCDN 就能明显的提高速度,缓存命中率也会有很大的提高。
你可以配置另一个域名,在那个域名上使用 CDN,然后通过插件重写页面地址实现部分 CDN。上文提到的 WP Super Cache 就能配置 CDN,或者使用 CDN Enabler 也能实现部分 CDN 功能。至于 CDN 的选择无所谓,只要支持 Origin Pull(也就是请求回源)就行。
提高服务器本身的性能是最简单的方法,使用更大的内存,更多核心的 CPU 能明显提速。除此之外,提高服务器上应用的性能也很重要:
PHP 脚本的处理速度是 WordPress 的一大瓶颈,使用最新版本的 PHP,可以获得更高的性能,例如 7.0 就比 5.6 快了 3 倍。
其次,少用插件能减少 PHP 需要执行的脚本,因为在加载每一个页面时,WordPress 都会加载一遍所有的插件。少量的插件(10个以下)对 WordPress 速度的影响不大,当然也取决于插件本身。
数据库是 WordPress 性能的瓶颈之一,在数据库上优化能提高一定的速度。 一般情况下,如果正确的使用 WordPress,并不需要清理数据库。但可能会有某些插件可能在数据库中创建了太多没用的表,这时服务器的响应速度就会大大降低(约 1~3 倍),推荐使用 WP-Optimize 进行清理。 不是太多的文章数量,是不太会的影响加载速度(1 万篇文章以下速度其实都还能接受,不过你写那么多文章干嘛,质量比数量更重要嘛)。
图片占据着网页中很大一部分的大小,同时也关系着用户体验。
对图片压缩不仅可以提高访问时图片加载速度,还能减少服务器带宽 推荐使用免费的 EWWW Image Optimizer,可以在服务器上对图片进行处理。如果你的服务器性能有限,可以使用 Optimus 在线处理,免费版功能十分有限。
对于不同的设备加载不同的图片,比如在手机上加载的图片,就可以比视网膜屏幕的电脑上要加载的图片小的多。使用本站曾经提到过的 srcset 技术可以最简单的实现这个功能,只要你的主题支持就可以了(官方的最新默认主题已经支持),如果主题本身不支持,也可以通过插件实现。
WordPress 中有一些自带的服务你可能并不需要,禁用它们可以减少页面所需要加载的资源以及服务器需要做的事情。
WordPress 支持 Emoji 表情符号,但会因此在页面中引入额外的 CSS,使用这个脚本可以禁用它(如果你不需要的话)。
Google Font 在国内加载非常慢,而且加载完成之前页面会一直白屏。你可以专门安装 Disable Google Fonts 的插件,或者在下文要提到的 Autoptimize 插件中的设置里禁用它。
进入 设置 => 讨论 中可以禁用 “尝试通知文章中链接的博客” 和 “允许其他博客发送链接通知(pingback和trackback)到新文章” 功能(如果你不需要的话)。 此功能并不影响页面加载时间。
减少请求数在也一些情况下也能提高加载速度,减少页面大小能缩短下载页面所需要的时间。推荐使用 Autoptimize,它可以 minify CSS、JS 和 HTML,还能 combine CSS 和 JS 以减少请求数。
然而,如果你的博客启用了 HTTP/2 协议,那么减少请求数就没什么必要了,不过为了启用 HTTP/2,必须要使用 HTTPS,所以最终下来是快是慢也不好说。不过还是强烈推荐使用 HTTPS,为了安全,牺牲点速度算什么。
做到上面几点,就能有效提速了,我的网站做到以上几点,在国内无缓存的 Wi-Fi 情况下本网站的时间线如下:
无损及有损压缩 JPEG 和 PNG 图像,支持压缩已有的图像,可以加快访问者加载图片的速度。同时支持 JPEG 的渐进式加载。正常情况下,网速低时,图片是一点点从上往下加载,而使用渐进式加载,则是先加载这个图片的低分辨率版本,然后逐渐变得清晰。我已经成为这个插件的付费用户,能够进一步有损压缩 PNG 和 JPEG 格式图片、降低服务器 CPU 占用(否则每上传一张图片,CPU 都消耗很多)。不过最近使用了 Cloudflare 的 Polish 功能,就没有再在服务器上安装同类软件了。
这个插件能够自动的合并 CSS 和 JS,并对其压缩,非常的方便。而且一些主题会有大量的 inline CSS,当开启了合并 CSS 后,这些 inline CSS 会自动添加到文件中。 我在这个插件中的一些配置,分享出来:
functions.js,player,mediaelement,sparkline,toolbar,admin,akismet,themes
admin,mediaelement,wordfence,piwik,toolbar,dashicons,crayon-syntax-highlighter/themes,crayon-syntax-highlighter/fonts
<head>
**:能提前加载 JS插件作者是:Automattic ,为 Google 优化,搜索结果中展示超快的 AMP 页面。详情:使用 AMP 构建超快的移动页面
二部认证器(需要配合同名手机客户端,或者 1Password 专业版)。你可曾听说过 Heart Bleed 漏洞?有了二部认证,就算再有 Heart Bleed 漏洞,都无需害怕。 原理:手机生成器上扫描二维码保存密钥,然后生成器根据时间变量生成6位数字。这6位数字有有效期,并且只能用一次。安全性甚至大于短信验证码
更换 IP 后需要重新登录,就算使用 HTTP 也可以一定程度上避免 Cookie 泄漏的风险
WordPress #1 的安全防御插件,可限制密码尝试次数防止暴力破解,可为你的 WordPress 增加 WAF 功能,查看实时访问。通过查看它的日志我才发现,原来我的 WordPress 一直在被恶意的暴力破解,有时一天几千次,几乎天天都有。不过还好只要尝试 3 次错误密码,IP 会直接被屏蔽掉,这也是 Failed Logins 数量不多的原因。 像这种是基于应用层面的防御,并不是 Cloudflare 等云加速,抗 DDOS 服务所能防御的。
这个插件能够让 WordPress 上展示自动高亮的源代码,有多种主题可以选择,支持多种编程语言。
这是 Jetpack 的简化版,没有 Jetpack 那一堆没用的特性,不需要登录到 wordpress.com,功能齐全,使用起来也非常简便。
这个插件能够自动生成网站的 sitemap.xml
和 robots.txt
,你可以直接将 sitemap.xml
提交到百度和 Google,这样搜索引擎就不会漏掉你的网站上的每一篇文章了。 这个插件支持 WordPress 的多站点,不需要任何配置,推荐在整个网络上启用。
这个插件能够让你的整个网站拥有统计功能,支持 WordPress 的多站点,推荐在整个网络上启用。关于 Piwik 配合 WordPress,请参见这篇文章:Piwik 与 WordPress 配合使用,建立强大统计系统。
这个插件能够让你的 WordPress 生成一个 Podcast Feed,让你有一个播客平台,你也可以把这个 Feed 直接提交到 iTunes 等地方。
这个插件可以让你将图片的 Exif 信息插入到图片的说明中,缺点是需要上传图片后手动添加,但是它可以批量添加,还算方便。将 Exif 信息插入到图片的说明后,再将这个图片插入到文章中,Exif 信息就能够显示在文章中。
在配合使用之前,首先需要安装 Matomo (原 Piwik)。前往 Matomo 官网下载软件包,然后解压到服务器上。当然,如果你的服务器上支持一键安装 Matomo 那更好。需要 PHP 环境和 MySQL 数据库。安装只需要根据步骤一步步来就好了。最好和 WordPress 安装在一个主机下,这样更方便配合使用。
前往设置中的地理位置页面,在页面左下角选择下载一个 GeoIP 数据库。下载了之后,你就可以使用 GeoIP (Php) 了,然而这个比较慢。我推荐你使用 GeoIP (PECL),如果你使用的是 cPanel,那么你可以直接在 Select PHP Version 页面中开启 GeoIP 模块,然后再去 php.ini
中加入或编辑这一行:
geoip.custom_directory = /Matomo/misc
然后就 OK 了,选择 GeoIP (PECL) 即可!
如果你的语言设置的是中文,那么你的图像报表中会出现乱码。请 下载字体文件,然后解压放到 plugins/ImageGraph/fonts/
下即可。
首先,需要在 WordPress 下安装 Matomo Analytics(完美支持多站点),之后前往设置。如果你的 WordPress 和 Matomo 都安装在一个站点下了,那么就选择 PHP API,否则选择 HTTP API。填写 Matomo 路径和 Auth Token(可在 Matomo 的后台中找到)即可,然后打开 Enable Tracking,选择默认跟踪即可。在 Show Statistics 里可以选择在哪些地方显示哪些统计,非常方便。
当你选择了 Show per post stats 后,你可以在每一个文章的编辑页面都能看到这个文章的访客信息,非常赞。
首先,为了能够正确的识别用户 IP,你需要在 config/config.ini.php
中添加下面这行代码。
proxy_client_headers[] = "HTTP_CF_CONNECTING_IP"
如果你的 CloudFlare 启用了 IP Geolocation 功能,那么你其实不需要在主机上开启 GeoIP。只需要根目录下创建 .htaccess
文件,添加下面这几行代码:
RewriteEngine OnRewriteBase /RewriteRule ^ - [E=GEOIP_COUNTRY_CODE:%{HTTP:CF-IPCountry}]
然后前往 Matomo 统计的地理位置选项,现在,你的地理位置选项就可以选第三个了 GeoIP (Apache),这个是速度最快的。
突然被人跑来问,是怎么做到写博客坚持这么久的,而且可以持续输出?
(荣幸地,拿起话筒:)啊,我不觉得我这个样子,叫做「持续输出」啦。早就连每月一更都不能保证了,而且那些技术相关的帖子,在我心里都不能算是「更新博客」的,用这些凑数也为我自己所不齿……
但我看到这个问题时,首先想到的,一个很重要的因素:大概是因为,这个站就一直在这儿吧~ 我的技术能力,不需要花什么额外的精力,就能让这个 blog 一直存活下去。于是,想写东西的时候,这里始终有个地方,可以让我写。
——也有很多时期,是完全写不下去的,长时期没法去面对、去反刍自己的生活;然而也没必要因此而关站,就让 blog 存活在那里,终归是个表述的出口。大概是因为,我也是希望,自己能够从那些「无法整理自己」的状态中,渐渐走出来,回复到可以写东西的状态吧。所以站点的持续存在,满重要的,因为确实能感觉到,想写点什么的时候,如果没有这么个站,又或者需要自己重新架一个,可能也就不写了……
这种「随时可以在站点写东西」的状态,也影响着对 blog 平台的选择(怎么又拐到技术贴去了?好吧,之前也一直想吐槽这方面,就顺带提一下)。这些年一直有 〖wordpress vs 各种静态博客〗哪个更好的争论。双方确实各有利弊。总体来说,静态博客最大的优点就是……省钱,可以薅 github、vercel 之类托管网站的羊毛。但另一方面,静态博客每次发布、或者修改一篇文章的过程,其实满折腾的。通常情况下,它需要
我不乏看到有人,好久没有更新,突然想写一篇文章时,忘了怎么操作,翻出攻略来重温一遍;甚至忘了连接 github 的 ssh-key……可能别人觉得这样的折腾无所谓,或者自我管理优秀的话,不会出现这种情况。但我个人觉得,这是会在主观上,影响发文章的状态的。所以,随便在任何地方任何电脑上都能直观地发文,感觉还是蛮重要的。
好像也是可以通过一系列操作,实现用浏览器某个网站上编辑文章,然后自动编译发布到托管网站的。我没有仔细去关注。但是,如果把 blog 的生命周期,放到 5~10 年这个尺度上,那么这些网站之间的复杂依赖关系,很大程度上是不靠谱的。譬如我已经看到好几个静态 blog 的外挂评论系统,不知为什么不工作了……总之,相比之下,我可能更宁愿去使用那些免费带广告的 blog 平台。
我对写 blog 的新人的推荐,一直是——
转一张图,对于熟悉这十几年来 blog 平台变迁的人,应该会很搞笑:用不同工具写 blog 的人,(写 blog 文章)vs(写关于怎么配置 blog 的文章)的对比。右下角那些术语,都是在各个年代,需要各种不同程度的折腾的,静态 blog 方案:gatsby、org mode、jekyll、hugo、git workflow……
ps,两个月前,用这段代码方案,把我在 twitter 的所有 po 文,都导入到了自建的 mastodon 里。Twitter 那边,应该会随着 Elon Musk 的各种不靠谱折腾,渐渐放弃掉了吧。而每条推文的字数限制,从 twitter 的 140 字,变成 mastodon 的 500 字后,很多几百字的感受,要不要专门写到 blog 这边来,就比从前,更让人犹豫。具体怎么处理,我还没想好。