普通视图

发现新文章,点击刷新页面。
昨天以前首页

WPJAM Basic - 样式定制:一键自定义 WordPress 前后台和登录页面

2025年5月6日 23:28

继续 #WPJAM Basic# 插件的详细介绍,前面介绍了「优化设置」还没有看的同学,可以先看一下,今天接着介绍「样式定制」的功能,「样式定制」也是 WPJAM Basic 最早开发的功能,开发这个功能主要是为了方便自定义网站。

简单说就是「样式定制」功能让用户可以在 WordPress 前后台和登录这三个主要不同的界面的头部(head)和底部(footer)插入一些定制代码,实现对网站页面样式和前端功能进行快速的定制。

因为是给三个主要不同的界面实现定制,那我们也分三个部分来讲解吧:

前台定制

前台定制的功能管的就是前台的页面了,通过前台 Head 代码前台 Footer 代码来定制前台的样式和功能。

这个功能对于有时候网站需要验证的时候有用,比如验证百度站长的时候,百度站长会给你两种选择:

  1. 让你在根目录上传一个 txt 文件
  2. 在头部的 Head 代码总加一段代码

如果不方便上传 txt 验证文件时候,直接把代码复制到这里的头部 Head 代码即可,即使方便的上传验证文件时候,把代码贴到这里也是更方便。

如果你的主题不支持暗黑模式,也可以通过把下面代码贴到这里的前台 Head 代码,也可以实现博客暗黑模式:

<style type="text/css">
@media (prefers-color-scheme: dark) {
html, img {filter: invert(1) hue-rotate(180deg);}
html, iframe {filter: invert(1) hue-rotate(180deg);}
img {opacity: .75;}
}
</style>

此外我在新版还增加了「文章页代码」选项,本来该功能是扩展,现在我把功能增加到「样式定制」功能中,因为这里使用起来比较顺手,不过做成了开关,开启可以单独设置每篇文章 head 和 Footer 代码。

先说下该功能的主要用途,主要是因为如果某些文章的展示的时候需要引入一些的 JS 和 CSS 来实现特殊的页面效果,怎么处理好呢?如果直接内容编辑框中插入,首先不是特别方便和友好,也可能由于安全或者其他的原因而造成插入失败。

「文章页代码」功能就是为该需求实现的,它可以让大家在文章编辑页面插入文章头部代码和底部代码:

另外他还可以让大家选择是否支持在文章列表页设置,有三个选项:支持,不支持,只允许,如果可以设置,在后台的文章列表页面中就有「文章页代码」按钮,如下图所示:

点击「文章页代码」按钮,就可以通过弹窗的方式来设置文章详情页的头部和底部代码:

后台定制

如上图所示,后台定制多了两个个功能,一个就是可以上传一个 40x40 大小的图片替换后台左上角的 WordPress 图标,另外一个是「后台右下角显示内存使用和 SQL 数量」,开启之后,在后台右下角显示:

其他和「前台定制」一样,也是通过后台 Head 代码后台 Footer 代码来定制后台的样式或者功能。

登录界面

登录界面也有两个额外的功能,首选是可以设置「登录之后跳转的页面」,比如可以设置网站首页,后台文章列表页面等等,另外一个是可以「屏蔽登录界面语言切换器」,这个不必多言。

其他一样可以设置 Head 和 Footer 代码,通过这两个值,可以做出自定义的登录界面。如果你懂 CSS,我们就可以自定登陆界面的 logo,甚至通过只用 CSS 就能做出非常漂亮的 WordPress 登录界面

关于样式定制,目前就提供了这些选项,基本满足简单定制的需求,该功能虽然偏向程序员使用,但是只要懂一些 CSS 和 JS,还是可以定制出很不错的 WordPress 后台,登录界面和前台的样式和交互。

WPJAM Basic - 优化设置:一键优化和增强 WordPress 功能

2025年5月6日 22:42

#WPJAM Basic# 插件的「优化设置」是 WPJAM Basic 插件的开端,可以说是我爱水煮鱼博客多年使用 WordPress 的经验而整理的优化插件。

我们 WordPress JAM 为了在定制开发的时候方便,就把各种用不上的功能,或者可能影响性能的功能,都提供开关,只需要一键搞定。

经过几年的发展,优化设置的功能分成功能屏蔽和增强优化两大块:

功能屏蔽

上图可以很清楚看到,功能屏蔽就是让你屏蔽 WordPress 中一些用不上的功能,我把功能屏蔽分成六大块:

常规功能

屏蔽文章修订功能,精简文章表数据。

WordPress 的文章版本修订功能是通过在 wp_posts 表中增加一条记录来实现的,这样如果修改了几次,就会有好几个修订版本,插入好几条记录。

如果经常修改文章或者博客有多个作者的话,每篇文章记录在 posts 表中都会有多条记录,文章一多,wp_posts 表的数据就会急剧上升,数据表的增大,最后自然影响了查询,肯定会变慢。所以建议屏蔽文章修订功能,提高数据库效率。

彻底关闭Trackback,防止垃圾留言。

Trackbacks 是被设计出来用于博客间交流,但实际上这样的应用很少,反而被 Spammer 滥用,并且各种防垃圾评论插件比如 Akismet 也经常漏掉,可以说防不胜防,Trackback 真的让人不慎其烦,建议彻底关闭 WordPress 的 Trackback。

关闭XML-RPC功能,只在后台发布文章。

XML-RPC协议用于客户端发布文章,如果只是在 WordPress 后台发布,可以关闭 XML-RPC 功能,提供 WordPress 的安全性。

关闭自动更新功能,通过手动或SSH方式更新。

WordPress 的更新服务器在国外,并且没有在国内开启加速服务,所以 WordPress 在后台检查更新的时候,可能因为各种原因无法顺畅连接上,然后一直卡着,造成 WordPress 后台有时很慢很慢。建议关闭 WordPress 后台和自动更新功能,通过手动或者SSH方式更新WordPress。

屏蔽站点Feed,防止文章被快速被采集。

WordPress Feed 主要用于阅读器使用,但是现在使用阅读器的用户越来越少,而 Feed 更多成为了一些垃圾站快速全文采集的方式,造成不必要的资源消耗,建议关闭站点 Feed。

屏蔽站点管理员邮箱定期验证功能。

WordPress 会在每六个月管理员再次登录之后,会看到站点管理员的邮箱地址验证界面,这是担心管理员的邮箱不再使用,引起一些安全的问题,让管理员再次确认,如果不会这方面的问题,觉得没有必要,可以屏蔽邮箱验证。

转换功能

屏蔽Emoji转换成图片功能,直接使用Emoji。

WordPress 使用图片来渲染Emoji表情文字,但是渲染图片经常打不开,并且现在主流浏览器都已经支持Emoji文字,并且现在绝大部分服务器的 MySQL 数据库(5.5版本之后)都支持 utf8mb4 编码格式,所以无需将 Emoji 转换成 HTML 实体进行存储了,直接存储速度更快,节省了实体转换的时间消耗。建议屏蔽 Emoji 功能。

屏蔽字符转换成格式化的HTML实体功能。

WordPress会将一些纯文本字符转换成格式化的 HTML 实体,但是这些转换并不适合中文环境,所以我们最好去掉这些字符转换,也能节约这些转换所消耗的时间。

屏蔽WordPress大小写修正,自行决定如何书写。

WordPress 默认会把 Wordpress 这样的写法转换成 WordPress,就是中间的 P 会变成大写。如果熟悉 WordPress 的用户,都会正确 WordPress 模式书写,所以从效率优先考虑,没有必要浪费时间在这个转换上面,一样一键移除。

后台功能

后台功能移除为欧洲通用数据保护条例生成的页面。

GDPR 是欧洲的通用数据保护条例,它制定了非常严格的隐私条例,WordPress为了适应该法律,在后台设置很多隐私功能,如果只是在国内运营博客,可以移除后台隐私相关的页面。

移除仪表盘的「WordPress 活动及新闻」。

WordPress 后台仪表盘页面会有「WordPress 活动及新闻」功能,但是大部分都是英文文章,如果你不想出现,可以一键移除。

移除后台界面右上角的帮助和选项。

WordPress 后台很多页面右上角,比如后台文章列表页面,都会有「显示选项」和「帮助」这两个按钮,一个是用来显示和设置该页面的选项,一个是用来获取该页面的帮助信息:

此图片的alt属性为空;文件名为1646055773-image.png

首先这两个按钮都在右上角,很多用户都不会特别注意,以至于自己操作了都忘记了,并且帮助文档对用户也帮助不大,建议两个都移除。

页面功能

页面功能移除页面头部版本号和服务发现标签代码。

WordPress 会在页面的头部输出版权信息和其他服务发现代码,版权信息代码会让用户知道你的目前运行的 WordPress 的版本,而服务发现代码则可以说明你的博客支持哪些服务。

这些代码在前台反而会引起一些安全的问题,最好一键去掉。

移除工具栏和后台个人资料中工具栏相关选项。

一般不建议在网站前台显示 WordPress 工具栏,所以可以一键移除。

嵌入功能

嵌入功能禁用Auto Embeds功能,加快页面解析速度。

Auto Embeds协议让你插入一个视频网站或者图片分享网站的链接,这个链接里面含有的视频或者图片就自动显示出来,但是该功能支持的网站都是国外的,如果运营的是中文博客,建议禁用 Auto Embeds 功能,加快页面解析速度。

屏蔽嵌入其他WordPress文章的Embed功能。

文章Embed功能让你可以在WordPress站点用嵌入的方式插入本站或者其他站点的WordPress文章。如果你不需要,可以屏蔽文章Embed功能。

古腾堡编辑器

屏蔽Gutenberg编辑器,换回经典编辑器。

WordPress 5.0 发布带来的 Gutenberg 编辑器,也叫区块编辑器,这个编辑器很酷,但是很多人不习惯,还是喜欢原来简简单单的编辑,name可以屏蔽 Gutenberg。

屏蔽小工具区块编辑器模式,切换回经典模式。

同样主题的小工具功能,新版 WordPress 也同样使用区块编辑器模式,你如果习惯了原来的经典模式,也可以一键屏蔽,切换回经典模式。

增强优化

增强优化主要将 WordPress 一些资源加速优化,并且添加一些常用的小功能,目前有以下的功能:

前端公共库

我们常用的 JS 库,比如 jQuery / Underscore 这些,网上都有提供免费的公共库,这里提供几个常用的前端公共库,可以根据自己的喜欢选择。

Google 字体加速服务

Google 字体很好用,很方便,WordPress 很多主题也使用了 Google 字体,但是 Google 在线字体在国内的速度不是很快,甚至有时候还无法打开,这也是 WordPress 有时候在国内速度不够快的原因。

WPJAM Basic 可以让选择第三方 Google 字体字体加速服务,也可以自定义输入加速服务地址:

详细介绍:使用 Google 字体加速服务,加快 WordPress 打开速度

Gravatar 加速服务

Gravatar 部分 CDN 服务器在国内访问困难,出现头像无法显示的问题,而 WordPress 后台或者评论页有时候默认加载 Gravatar 头像图片的,这样就可能造成页面卡死的情况。

WPJAM Basic 可以让选择第三方 Gravatar 镜像加速服务,也可以自定义输入加速服务地址:

详细介绍:使用 Gravatar 加速服务,加快 WordPress 打开速度

Frame 嵌入

WPJAM Basic 可以让你直接在后台设置 Frame 嵌入,避免点击劫持,增强网站的安全性:

详细介绍:如何防止 WordPress 页面被 Frame 嵌入

分类链接简化

去掉 category 的分类目录和 WordPress 的页面的 URL,这两种页面的页面rewrite 规则是不是一样的,那么我们可以直接使用页面的 rewrite 规则来处理了。

WPJAM Basic 还额外增加一个选项,如果博客自定义了其他的自定义分类模式,可以选择设置哪个分类模式应用该功能:

详细介绍:去掉 WordPress 分类目录 URL 中的 category 最佳方法

图片时间戳

如果长期上传的图片名字都是 1.jpg 的话,那么上传一张图,会造成数据库进行几十到上百次的 SQL 查询,应该在上传的时候把图片的名字更改了,给图片的名字加多一个时间戳,这样就能几乎保证图片名字不可能重复了:

详细介绍:如果经常在 WordPress 上传同名的图片,最好开启这个选项

之前还有一些优化增强功能,我因为各种原因去除或者移到别的插件。

  • 搜索结果快速跳转:提高搜索效率,当搜索结果只有一篇时直接重定向到文章该功能已经移到搜索优化插件。
  • 禁止admin用户名:使用admin作为用户名是最大的安全漏洞,建议禁止使用 admin 用户名尝试登录 WordPress,提高网站的安全性。很多人因为用户名是 admin,又开启这个功能,然后站点登录不了,然后说 WPJAM Basic 的问题,忍疼删除该功能,大家记得不要设置 admin 的用户名。
  • 前台不加载语言包:WordPress加载语言包是需要花费 0.1-0.5 秒不等的时间,如果对性能要求极致,可以前台不加载语言包,但是要把主题文件中的描述改成中文。很多人设置了该功能,前台出现英文,说WPJAM Basic 乱改,所以继续忍疼删除该功能。
  • 媒体文件默认链接到:无/媒体文件/附件页面,该功能已经迁移到图片集插件。

PHP 8 重大变更:is_callable() 不再支持类名+非静态方法检查,强制返回 false!

2025年4月18日 00:10

最近在 PHP 8 环境下,发现 #WPJAM Basic# 的一个严重问题:就是后台文章和分类列表的一些操作无效了,点击保存按钮没有任何反应。经过深入调试,发现问题根源在于 PHP 8 对is_callable()函数的行为进行了重大调整。

技术细节

在 PHP 8 之前,is_callable() 函数在检查类名与非静态方法的组合时会返回 true,即使这种调用方式在实际执行时可能会导致问题。PHP 8 对此进行了更严格的检查,以提前发现潜在的错误调用方式,因此 is_callable() 在检查一个类名与非静态方法时将返回失败(应当检查一个类的实例)。

具体看下面这个例子就大概能够明白了:

class Test{
    public function method1() { }
    public static function method2() { }
}

// PHP 8 之前
var_dump(is_callable(['Test', 'method1']));	// bool(true)
var_dump(is_callable(['Test', 'method2']));	// bool(true)

// PHP 8 之后
var_dump(is_callable(['Test', 'method1']));	// bool(false)
var_dump(is_callable(['Test', 'method2']));	// bool(true)
var_dump(is_callable([new Test, 'method1']));	// bool(true)

变更原因

PHP 8 的这一变更是为了更严格地执行面向对象编程规范:

  1. 静态与非静态方法调用的区分:非静态方法需要类的实例才能调用,而静态方法可以直接通过类名调用。
  2. 提前错误检测:在 PHP 7 及以下版本,虽然 is_callable() 会返回 true,但实际以静态方式调用非静态方法时会产生警告。PHP 8 通过 is_callable() 提前返回 false 来更早发现问题。
  3. 代码质量提升:强制开发者明确方法调用的上下文,避免模糊的调用方式。

解决方案

既然知道这个原因,那就是代码要根据上下文来写了。所以如果要检查某个对象的非静态方法是否可调用,应该使用一个对象实例而不是类名。

此外,其实很多时候我们只需要检查类的方法是否存在,而不关心其可调用性(例如访问控制),那么可以简单使用 method_exists() 进行判断就好了:

if (method_exists('Test', 'method1')) {
    // Do something
}

在 WordPress 后台集成了标签选择器(tag-input)和多选选择器(mu-select)

2025年3月28日 00:04

使用过 #WPJAM Basic# 的同学都知道,WPJAM Basic 集成了多个字段组件,这些组件都是后台定义一下,然后前段就能够渲染,并且提交的时候也会根据类型进行验证和处理,反正就是我通过前后端双修的模式将字段设置这块做到了最简洁了。😁

比如多个输入框(类型:mu-text),在「CDN 加速」里的「扩展名」字段:

甚至可以无限重复的一组字段(类型:mu-fields),在「缩略图设置」里面的:「未设置缩略图是,获取特色图片顺序」字段:

还有设置多个图片(类型:mu-img),还是在「缩略图设置」里面的「默认缩略图」字段:

这些字段都是后端配置的,自动渲染生成的,不用再多写一行前段 JS 代码:

「扩展名」字段:

[
	'exts'	=> [
		'type'		=> 'mu-text',
		'button_text'	=> '添加扩展名',
		'direction'	=> 'row',
		'sortable'	=> false,
		'description'	=> '镜像到云存储的静态文件扩展名'
	]
]

「获取顺序」字段:

[
	'post_thumbnail_orders'	=> [
		'title'		=> '文章缩略图',
		'type'		=> 'mu-fields',
		'group'		=> true,
		'max_items'	=> 5,
		'before'	=> '首先使用文章特色图片,如未设置,将按照下面的顺序获取:<br />',
		'fields'	=> [
			'type'	=> ['type'=>'select',	'options'=>[
				''			=> '请选择来源',
				'first'		=> '第一张图',
				'post_meta'	=> [
					'label'		=> '自定义字段',
					'fields'	=> ['post_meta'=>['type'=>'text',	'class'=>'all-options',	'placeholder'=>'请输入自定义字段的 meta_key']]
				],
				'term'		=>[
					'label'		=> '分类缩略图',
					'show_if'	=> ['term_thumbnail_type', 'IN', ['img','image']],
					'fields'	=> ['taxonomy'=>['options'=>[''=>'请选择分类模式']+$tax_options]]
				]
			]]
		]
	]
]

「默认缩略图」字段:

[
	'default'	=> [
		'title'		=> '默认缩略图',
		'type'		=> 'mu-img',
		'item_type'	=>'url'
	]
]

就是这样配置一下就好,剩下的程序会自动处理,厉害吧!这就是我前后端兼修的能力。😂

但是还是有些地方需要一些主键,比如在列表筛选的时候,用到上面这些多输入框的时候,界面就有点挤了,所以就有了「标签选择器」和「多选选择器」这两个字段组件。

「标签选择器」这个其实和上面的多输入框很类似,只是它每输入一个之后,就变成类似标签的样式:

支持自动完成,拖动排序,删除,按退格键(Backspace)不仅可以删除输入的文字,也可以删除前面的标签(为了防止误删,需要快速按两次)。这个可能更多的是样式的改进,但是更重要的是界面的节省。

使用也很简单,首先它的类型是:tag-inpug

[
	'tags'	=> [
		'type'			=> 'tag-input',
		'data_type'		=> 'taxonomy',	// 数据类型
		'taxonomy'		=> 'post_tag',	// 文章标签
		'min_items'		=> 2,	// 至少 2 个
		'max_items'		=> 3,	// 最多 3 个
		'unique_items'	=> true // 不能重复,已选择的项目不会再次出现
	]
]

有时候被选择的项目数量是有限的,比如分类,但是要多选,如果使用 select 的话,只能单选,当然 select 有个 multiple 属性,但是显示的效果是这样的:

通过按着 CTRL 或者 Shift 然后点击进行多选,怎么用,怎么难受,并且高度太高,不好排版,如果强制设置为一行,都不知道选择了什么。

所以我们做了「多选选择器」这个组件,它默认显示选中的选项,通过逗号分割开:

点击「下拉选择框」(其实这个是个按钮,通过 CSS 改造和下拉选择框很类似)就可以看到所有选项,并且所有选项前面都有个复选框:

勾选之后,就会显示到上面「下拉选择框」中,并且同样也支持设置至少和最多的数量,选好之后点击人地方,这个下拉复选框就隐藏了,这样就能大大节省界面:

使用也很简单,首先它的类型是:mu-select,其实把上面标签选择器的代码复制下来,改下类型就好了

[
	'tags'	=> [
		'type'			=> 'mu-select',
		'data_type'		=> 'taxonomy',	// 数据类型
		'taxonomy'		=> 'category',	// 文章分类
		'min_items'		=> 2,	// 至少 2 个
		'max_items'		=> 3,	// 最多 3 个
	]
]

如果你基于 WPJAM Basic 进行二次开发,那么这两个字段组件可以帮到你很多。为了写这两个字段,我相当于又重修了一下 JavaScript 这门语言,还好现在有 DeepSeek,很多模棱两可的东西,都可以问题,然后也可以让它给到一些演示代码,然后在改就简单了很多。😁

preg_replace_callback 如果正则有问题,竟然不是返回原字符串,而是返回 null

2025年3月19日 00:00

#WPJAM Basic# 有个功能,就是在 WordPress 后台文章列表添加上文章特色图片,并且支持点击设置:

这个功能因为 WordPress 没有好的 Hook 使用,我是通过对最终生成的 HTML 实现正则替换实现的。

这个功能本来挺好的,然后有个用户说使用 WPJAM Basic 之后,说后台文章列表空白,经过我仔细的 Debug,原来他使用的标签太多了,使得 HTML 过于复杂,正则回溯次说过多,发生错误了。

原本我以为正则错就错了呗,最多就是正则替换不成功,功能没有,为啥还给我整成空白的呢?我仔细查了下 PHP 官方文档,原来 preg_replace_callback 函数的返回是这样的:

如果 subject 是一个数组, preg_replace_callback() 返回一个数组,其他情况返回字符串。错误发生时返回 null

厄,错误发生时返回 null,第一次知道,一下子无言以对,原来之前正则都是成功了,我都没有去处理错误的情况,真的是。

然后 preg_replace 也是一样的情况,错误发生时返回 null

所以我写了一个函数 wpjam_preg_replace,同时实现  preg_replace_callbackpreg_replace 的正则替换功能(它们的参数差不多,一个是回调,一个是替换的字符串),如果发生错误时,不是返回 null,而是返回原始 $subject

function wpjam_preg_replace($pattern, $replace, $subject, $limit=-1, &$count=null, $flags=0){
	if(is_closure($replace)){
		$result	= preg_replace_callback($pattern, $replace, $subject, $limit, $count, $flags);
	}else{
		$result	= preg_replace($pattern, $replace, $subject, $limit, $count);
	}

	if(is_null($result)){
		trigger_error(preg_last_error_msg());
		return $subject;
	}

	return $result;
}

如果发生了错误,并且在 log 中打印出具体的错误信息,方便查看原因,看看能不能优化正则什么的。这里有个限制,preg_replace_callback 的回调函数只能是闭包,因为同时要支持两个函数的原因,使用闭包比较容易判断。

有了这个函数之后,即使发生正则错误,至少还能显示页面,这也算是一种防御性编程(防御性编程是一种编程实践,旨在编写代码以抵御或处理潜在的错误和异常情况,以提高代码的健壮性和可靠性)。😆

如何在本地调试WordPress时忽略对wordpress.org的网络连接请求

2025年3月13日 10:43

本地调试WordPress时,为了保证代码的正确性,插件和主题作者往往会打开wp-config.php里的WP_DEBUG开关。如果您不知道这个开关,就不要往下看了。

define('WP_DEBUG', true);

这样PHP运行时的错误和警告就会以醒目的字体直接打印到网页上。
20250313_WP_local_debug_warning

但是这样会带来一个程序员的日经问题:是我的BUG我改,不是我的BUG莫挨老子!
按说WP这种成熟的产品是不会让用户看到警告和错误的。但是,由于众所周知的原因,WP内核、主题和插件升级所需要的WordPress的官网wordpress.org时灵时不灵,连不上的时候就会显示大面积的警告信息。
安装完成以后,后台这种需要连接到wordpress.org的地方大抵有4种:core update、theme update、 plugin update和translation api,出现在后台Dashboard、 Plugin、 Theme、 和Settings页面。其中Dashboard会调用前三种Update,Settings四种都会调用。
这些信息不仅是影响对于出错代码的判断(比如图中提示的“Cannot modify header information”,其实根本就不是本地header的问题),还会直接影响页面元素的渲染和操作。
那就必须要干掉它!

再次更新,

define('WP_HTTP_BLOCK_EXTERNAL', true);

这个宏屁用没用,还是得用我下面的方法。

开整。

//下面的action钩子调用的早,所以在加载主题或插件的时候就要直接remove掉,否则没机会了。
if ( defined( 'WP_DEBUG' ) && WP_DEBUG ) {
    remove_action('admin_init', '_maybe_update_core');
    remove_action('admin_init', '_maybe_update_plugins');
    remove_action('admin_init', '_maybe_update_themes');
    remove_action('init', 'wp_schedule_update_checks');

    //translations_api默认会返回false,之后会访问wordpress.org,返回空数组之后就不访问了。
    //Since 4.0.0
    add_filter('translations_api', '__return_empty_array');
}

//调试者作为admin,默认是有各种update权限的。这里令各种内部调用user_has_cap询问4种权限的结果强行置为false。
function _debug_ignore_wp_request ($allcaps, $caps, $args){
    $server_caps = array('install_languages', 'update_themes', 'update_plugins', 'update_core', 'install_themes', 'install_plugins');
    foreach ($caps as $cap) {
        if ( in_array($cap, $server_caps)) {
            $allcaps[$cap] = false;
        }
    }
    return $allcaps;
}

function my_admin_init {
    if ( defined( 'WP_DEBUG' ) && WP_DEBUG ) {
        //下面的钩子很多不能移除得太早。
        //宁杀错不放过。
        remove_action('upgrader_process_complete', 'wp_update_plugins');
        remove_action('upgrader_process_complete', 'wp_update_themes');
        remove_action('load-plugins.php', 'wp_plugin_update_rows', 20);
        remove_action('load-themes.php', 'wp_theme_update_rows', 20);
        remove_action('load-plugins.php', 'wp_update_plugins');
        remove_action('load-themes.php', 'wp_update_themes');
        wp_unschedule_hook('wp_version_check');
        wp_unschedule_hook('wp_update_plugins');
        wp_unschedule_hook('wp_update_themes');

        remove_action('wp_version_check', 'wp_version_check');
        remove_action('load-plugins.php', 'wp_update_plugins');
        remove_action('load-update.php', 'wp_update_plugins');
        remove_action('load-update-core.php', 'wp_update_plugins');
        remove_action('wp_update_plugins', 'wp_update_plugins');
        remove_action('load-themes.php', 'wp_update_themes');
        remove_action('load-update.php', 'wp_update_themes');
        remove_action('load-update-core.php', 'wp_update_themes');
        remove_action('wp_update_themes', 'wp_update_themes');
        remove_action('update_option_WPLANG', 'wp_clean_update_cache', 10, 0);
        remove_action('wp_maybe_auto_update', 'wp_maybe_auto_update');
        add_filter('user_has_cap', '_debug_ignore_wp_request', 10, 3);
    }
}

add_action('admin_init','my_admin_init');

完事。这个世界清净了。


  • (1):农历每年冬至所在的月固定为十一月。如果两个冬至间有13次朔望,则该年产生闰月。13个月中,第一个没有二十四节气里的偶数节气的月份就是闰月。因为十一月是起调点,所以农历十二月和正月是不会出现闰月的,正月初一和第一个节气春分受的影响也很小。我数学不好,但查表得到的结果,从1950年到2069的120年间,闰年就是双春,双春就是闰年,一一对应,无一例外。闰月是典型的用太阳历调整月历的规则,所以农历是阴阳历而不是纯阴(月)历。

强迫症

2025年2月20日 10:59

有时候真的不想开始干一些事情,因为一旦开始了就想着把所有的问题都解决掉。然而,要解决这些问题有的时候真挺痛苦的,苦不堪言。

最近其实乱七八糟的事情挺多的,之前一流的烂尾项目又开始折腾,导致自己现在一听到甲方的名字就 tm 反胃,所以有的时候也是在消极应对。

其实很多的事情,哪怕自己强迫症再严重,有的也解决不了。例如现在 wp 的后台提示有一项插件可以升级,但是点到插件页面或者更新页面又消失了,就跟幽灵一样。

昨天晚上提示邮件发送插件激活失败了,有新版本提示升级,看了下现在用的是 3 最新的已经到了 4,网上搜了一通没搜到免费下载的地方,最终花 4 块钱买了个下载地址下载安装了,不得不说这破解插件收费卖也的确是个好生意。每次装完插件就是要去掉各种收费插件的升级监测:

去掉之后一个省了加载时间,另外一个是免得提示升级,或者自动升级导致破解失败。同样,升级了一下 envira gallery 的插件,现在相册页面的独立链接的确能用了。也算是又修复了一个问题,最后连上篇文章中提到的那个错误也一起修复了。至此多数问题都解决了。

然而,还有个最恶心人的东西,就是之前构建的说说页面也有问题,创建的文章在说说页面无法播放视频:

这个破玩意儿看着就那么恶心,那个 video 跟傻屌一样显示了一行代码,本来想改页面模板,但是直接打开却又能播放:

具体播放则是调用了一堆 js:

新建页面模板,通过代码将上面的 js css 插入,然而最终失败了,不知道是代码问题还是神马智障问题。最终放弃。

此路行不通那就换别的方式吧,经过转换之后发现 h5 的 video 标签是可以播放的,可以直接插入 h5 的代码:

<video controls="controls" width="720" height="100%"><source src="https://h4ck.org.cn/wp-content/uploads/2025/02/c229677d-71e2-4dd5-86ab-b8137a086b801740010424255.mp4" type="video/mp4" />Your browser does not support the video tag.</video>

最起码说说页面能显示能播放了:

既然如此,那就通过 video 标签的形式插入吧,但是每次都得写这段代码太蛋疼了,直接修改 functions.php 给编辑器添加个按钮来干这件事情:

function add_video_button($wp_editor_id) {
    // 获取编辑器的 ID
    $editor_id = $wp_editor_id;

    // 添加按钮的 HTML 代码
    $button_html = '<button id="add-video-button" class="button"><img src="/img/h5_video.png" width=26 height=26 ></img>添加视频</button>';

    // 输出按钮的 HTML 代码
    echo $button_html;

    // 创建一个弹出窗口的 HTML 代码
    $popup_html = '
    <div id="video-popup" style="display: none; position: fixed; top: 50%; left: 50%; transform: translate(-50%, -50%); background-color: #fff; padding: 20px; border: 1px solid #ddd; border-radius: 10px; box-shadow: 0 0 10px rgba(0, 0, 0, 0.2); width: 400px;">
        <h2 style="margin-top: 0;">添加视频</h2>
        <div style="margin-bottom: 20px;">
            <label style="display: inline-block; width: 80px; text-align: right; margin-right: 10px;">宽度:</label>
            <input id="video-width" type="text" value="100%" style="width: 200px; height: 30px; padding: 5px; border: 1px solid #ccc;">
        </div>
        <div style="margin-bottom: 20px;">
            <label style="display: inline-block; width: 80px; text-align: right; margin-right: 10px;">高度:</label>
            <input id="video-height" type="text" value="100%" style="width: 200px; height: 30px; padding: 5px; border: 1px solid #ccc;">
        </div>
        <div style="margin-bottom: 20px;">
            <label style="display: inline-block; width: 80px; text-align: right; margin-right: 10px;">视频地址:</label>
            <input id="video-src" type="text" style="width: 280px; height: 30px; padding: 5px; border: 1px solid #ccc;">
        </div>
        <div style="text-align: right;">
            <button id="video-submit" style="margin-right: 10px; width: 80px; height: 30px; background-color: #04a4cc; color: #fff; border: none; border-radius: 5px; cursor: pointer;">确定</button>
            <button id="video-cancel" style="width: 80px; height: 30px; background-color: #ccc; color: #666; border: none; border-radius: 5px; cursor: pointer;">取消</button>
        </div>
    </div>
    ';

    // 输出弹出窗口的 HTML 代码
    echo $popup_html;

    // 使用 JavaScript 为按钮添加点击事件
    ?>
    <script>

       jQuery(document).ready(function($) {
                $('#add-video-button').on('click', function(e) {
                        e.preventDefault();
                // 显示弹出窗口
                $('#video-popup').show();
            });

                $('#video-cancel').on('click', function(e) {
                        e.preventDefault();
                // 隐藏弹出窗口
                $('#video-popup').hide();
            });

                $('#video-submit').on('click', function(e) {
                        e.preventDefault();
                // 获取输入框的值
                var width = $('#video-width').val();
                var height = $('#video-height').val();
                var src = $('#video-src').val();

                // 如果输入框不为空
                if (width !== '' && height !== '' && src !== '') {
                    // 获取编辑器的内容
                    var editor = tinyMCE.get('<?php echo $editor_id; ?>');

                    // 如果编辑器存在
                    if (editor) {
                        // 向编辑器中插入内容
                        editor.execCommand('mceInsertContent', false, '<video controls="controls" width="' + width + '" height="' + height + '"><source src="' + src + '" type="video/mp4" />Your browser does not support the video tag.</video>');
                    } else {
                       // 如果使用的是文本模式编辑器
                        $('#<?php echo $editor_id; ?>').val($('#<?php echo $editor_id; ?>').val() + '<video controls="controls" width="' + width + '" height="' + height + '"><source src="' + src + '" type="video/mp4" />Your browser does not support the video tag.</video>');
                    }

                    // 隐藏弹出窗口
                    $('#video-popup').hide();
                }
            });
        });
    </script>
    <?php
}


// Hook 到 WordPress 的编辑器中
add_action('media_buttons', 'add_video_button', 11);



最终效果:

到这里,目前这次对于wp 的折腾算是基本完成了。然而,所有的插件,系统都在不断的升级,每次升级之后就会面临插件版本太旧的问题。

对于插件我倒是也想支持正版,不过那个价格的确让人有点不大好接受,一个插件一年几百块,好几个插件加起来都几千了,有这几千总感觉不能扔在这个地方,毕竟本来就不盈利。

暂时就这样吧,毕竟有的问题,哪怕强迫症也解决不了,就酱紫,由他去吧。

更新后插件地址:

https://github.com/obaby/Simple-microblogging-wordpress-plugin.git

需要别人登录你的 WordPress,再也不需要给账号密码了,现在可以给「一次登录链接」了!

2025年2月16日 20:18

前面我们介绍「为什么你的 WordPress 站点老是被黑?」的时候,说到大胡子和我卖 Modular 主题,我们的售后是很负责的,😎 会在用户允许的情况下,进入后台帮忙解决,这时候我们需要对方提供一下后台的账号密码,然后就接触到了很多简单到令人发指的密码,所以网站就被黑了。

说到要求对方提供账号密码这个事情,有用户提出,其实给人账号密码也很不安全,最好是创建一个新的管理员账号,这样就不会不小心暴露自己常用密码。

一次登录链接

但是创建一个新的管理员账号也是麻烦,用完又要删除或者去修改密码。那么有没有更好的方法呢?今天想到一个好方法,就是给某个用户创建「一次登录链接」,只能使用一次,这样就不用担心「售后」的时间。✌️

我就把该功能增加到「用户管理」功能,默认是开启的:

然后在用户列表就会有「生成链接」的操作,我把原来的「生成重置密码链接」一起合并进来:

点击之后,链接类型选择「一次登录」,链接有效期默认是 3 个小时,意思是 3 个小时内该链接点击都可以登录,过了就不行。

然后复制该链接,发送给帮你解决问题的好人,就可以了。

WPJAM「用户管理」

这次一次登录链接功能,我集成到了 WPJAM 这个「用户管理」插件中,它是 WordPress 果酱知识星球福利插件,加入「WordPress果酱」知识星球(长按下图二维码)即可下载:

如果基于 DeepSeek 开发 WordPress 的插件,它自己会选择什么功能?

2025年1月30日 21:54

今年最火的就是 DeepSeek 了,各种新闻,把英伟达的股票都干没了10 几个点。我也在想做一个基于 DeepSeep 的 WordPress 插件,但是做什么方向的的功能呢?要不这个功能也让 DeepSeek 帮我们也想想?

DeepSeek 的使用和 ChatGPT 之类其他的 AI 工具是有区别,他是基于推理型的大模型,而不是指令型的大模式,所以使用 DeepSeek 根本不需要提示词,直接就好了。

所以我的问题就直接把自己的目的告诉,我想写个 DeepSeek 的插件,需要给些功能灵感:

我想基于 DeepSeek 写个 WordPress 插件,在方向上,基于你对自己理解,你觉得可以做那些功能呢,你可以给我一些灵感吗?

然后我 开启了深度思考模式,DeepSeek 给出了它对这个问题的推理过程:

然后他给出了自己的建议,它还非常贴心的分成几个小标题,一共提供内容生产力、智能交互增强、数据智能分析和效率增强功能四大方向,每个方向还提供了2 个小功能,大家看看这些功能建议如何,并且它还非常贴心的提供技术实现要点,以及如何赚钱,也就是商业化建议

基于 DeepSeek 的能力和 WordPress 生态需求,以下是几个值得探索的插件开发方向,按优先级排序并附具体实现思路:


一、内容生产力工具(核心场景)

  1. AI 文章助手
    • 自动草稿生成:根据用户输入关键词自动生成结构化大纲(支持Markdown)
    • 智能续写/改写:通过浮动工具栏实现选中内容的优化/扩写/简写
    • SEO 增强:实时分析内容并推荐关键词密度、生成meta描述
    • 技术实现:结合Gutenberg编辑器API + 内容缓存机制降低API调用成本
  2. 多模态内容生成
    • 基于文本描述自动生成特色图片(需集成DeepSeek-Visual)
    • 智能生成文章配图说明文字(ALT文本优化)
    • 自动创建信息图描述文本

二、智能交互增强

  1. 对话式知识库
    • 将网站文档/产品目录转化为可对话的知识库
    • 实现路径:定期爬取指定页面内容构建向量数据库
    • 示例场景:客户服务机器人、产品FAQ交互
  2. 实时评论互动
    • 智能回复用户评论(可设置白名单词库限制)
    • 情感分析自动标记高风险评论
    • 支持预设行业话术模板(电商/教育等)

三、数据智能分析

  1. 流量内容洞察
    • 结合GA数据生成自然语言分析报告
    • 自动识别高跳出率页面的内容问题
    • 预测内容生命周期并提供更新建议
  2. 竞品内容监测
    • 定期抓取竞品RSS进行摘要对比
    • 生成差异化创作建议(需配置代理抓取)

四、效率增强功能

  1. 智能翻译工作流
    • 一键生成多语言版本并保持SEO结构
    • 支持术语表维护和翻译风格预设
    • 实现:WPML兼容 + 增量翻译缓存
  2. 自动化运营
    • 定期自动生成节日营销文案
    • 社交媒体帖子自动生成与排期
    • 结合Zapier实现跨平台自动化

技术实现要点

  1. 性能优化
    • 实现内容缓存池(基于文章ID的版本控制)
    • 支持异步队列处理长文本任务
    • 本地语义相似度计算减少API调用
  2. 安全合规
    • 内容审核过滤层(可对接DeepSeek审核API)
    • 用户数据脱敏处理
    • GDPR兼容设计(数据暂存策略)
  3. 扩展架构
    • 提供webhook接入点
    • 开发REST API扩展模块
    • 支持与WooCommerce等流行插件的数据打通

商业化建议

  • 分层定价策略
    • 免费版:基础内容生成(限次/水印)
    • 专业版:高级分析+多语言(订阅制)
    • 企业版:私有化部署+定制模型
  • 流量变现
    • 内置AI写作模版市场
    • 对接第三方云服务返佣
    • 提供A/B测试数据服务

建议初期聚焦内容生成核心场景,采用「AI功能+SEO工具」组合拳切入市场,后续通过用户行为数据分析逐步扩展智能运营功能。可参考Jarvis(Conversion.ai)的增长路径,但需注意WordPress生态的特殊性,强化与经典插件(Yoast SEO、Elementor)的兼容性。


大家觉得如何?希望首先实现哪个方向的插件?可以给我留言,我争取2 月份就先做个简单的插件出来给大家用用。😁

WordPress 是如何缓存的?对象缓存(Object Cache)详细介绍和使用!

2025年1月20日 23:43

任何技术要彻底了解它是怎么工作的,则要去了解它的机制和原理,WordPress 优化也是一样,如果要深度理解如何优化 WordPress,那么就要去了解 WordPress 对象缓存的原理和机制。

所以那么今天就来详细讲解一下 WordPress 缓存的底层原理对象缓存(Object Cache),以及在开发的时候如何使用它对 WordPress 进行加速。

WordPress 对象缓存和服务器设置

WordPress 对象缓存(英文名是:Object Cache)就是 WordPress 的缓存机制,它的主要功能是把数据库查询结果或者复杂运算的结果按照 Key-Value 这样的方式存储到对象里面,此外 WordPress 还支持按照 Group 来按组划分,以避免缓存内容的冲突。下次进行同样操作的时候,可以让直接从这个对象中取出数据,不用重复到数据库中或者其他外部获取数据。

WordPress 对象缓存和服务器设置关系很大,如果系统开启了 #Memcached# 内存缓存,则这个对象是直接存入到内存,在数据未过期之前,以后再次读取这个数据都是直接从内存中读取的,这样效率和速度都非常快的。

如果服务器不支持内存缓存的话,则只能保证在当前页面(PHP同个进程下)下同样的查询或者操作不再重复从数据库中读取了。

WordPress 对象缓存的函数

WordPress 对象缓存技术使用是非常简单的,其核心就是掌握下面下面这四个函数:

  • 添加数据到缓存中:
    wp_cache_add($key, $data, $group='', $expire=0)
  • 设置数据到缓存中:
    wp_cache_set($key, $data, $group='', $expire=0)
  • 获取缓存中的数据:
    wp_cache_get($key, $group='', $force=false, &$found=null)
  • 删除缓存中的数据:
    wp_cache_delete($key, $group='')

这四个函数会涉及到参数我罗列到一起简单讲下,下面知道个大概,可以收藏,方便使用的时候回来查看,重点还是后面的应用:

参数解释
$key数据在缓存中的健名
$data要缓存的数据,获取和删除函数无需用这个参数
$group缓存要添加到的组
$expire过期时间,可选参数,获取和删除函数无需用这个参数
如果是默认缓存,这个参数没用,如果是内存缓存,是设置缓存的时间。
单位是秒,默认为0(0 的意思就是永远,不会自动过期)
$force这个是获取缓存函数独有的函数,设置为 true 则强制使用持久缓存更新本地缓存
$found这个也是获取缓存函数独有的函数,它是一个引用参数,用于存储是否在缓存中找到 key,可以用于消除返回 false 的歧义

使用 WordPress 对象缓存

下面以我以 WordPress 相关文章为例,讲讲如何使用 WordPress 对象缓存。

我们知道 WordPress 相关文章插件是通过 tag 和分类来获取相关文章,文章使用相同的 tag 和分类越多,则认为为相关性越强,这样就需要进行多个表联合查询来获取相关文章,连表查询效率一般是比较差的。比如下面是一个比较通用的从数据库中查找相关文章的函数:

function wpjam_get_related_posts($post_id){
	global $wpdb;

	$term_ids   = wp_get_post_terms($post_id, ['category', 'post_tag'], ['fields' => 'ids']);
	$terms_ids  = implode(',', $term_ids);

	$related_posts = $wpdb->get_results("
		SELECT object_id, COUNT(*) as count
		FROM $wpdb->term_relationships
		WHERE term_taxonomy_id IN ($terms_string) AND object_id != $post_id
		GROUP BY object_id
		ORDER BY count DESC
		LIMIT 10"
	);

	foreach($related_posts as &$post){
		$post = get_post($post->object_id);
	}

	return $related_posts;
}

上面的函数,首先获取文章的标签和分类,然后基于使用相同的标签和分类的数量,通过 SQL 获取相似度最高的 10 篇文章的 ID,然后再相应获取对应的文章(这里为了简化,一般应该要根据文章 ID 批量文章,防止同时多条 SQL 请求)。

但是另外一方面,一篇文章,如果它的标签和分类没有修改的话,那么它的相关文章在一段时间内是不会变动的,所以相关文章的功能就非常适合使用 WordPress 对象缓存进行缓存加速加速。

我们就可以使用 wp_cache_set 函数就是把把相关文章的数据写入缓存的例子,使用当前 post_id 作为 key,related_posts 作为 group,缓存时间为一个小时,即 3600 秒。

$related_posts_data = wpjam_get_related_posts($post->ID);
wp_cache_set($post->ID,$related_posts_data,'related_posts',3600);

把数据存到缓存对象之后,在显示相关文章的时候,就可以使用 wp_cache_get 调用这个对象缓存来使用。

一般的流程是这样的,首先检查下是否已经有相应的缓存,如果你要的信息没有在缓存中,或者已经过期,wp_cache_get() 会返回 false,这时,你就要去数据库中重新获取这些信息,否则就返回在缓存中的信息。

$related_posts_data = wp_cache_get($post->ID,'related_posts');

if(false === $related_posts_data){
	$related_posts_data = wpjam_get_related_posts($post->ID);
	wp_cache_set($post->ID,$related_posts_data,'related_posts',3600);
}

因为设置了一个小时,相关文章的数据就失效,再次显示的时候会重新请求,,如果你在后台更改了设置,需要立即清理缓存,可以通过相关的 Hook 使用 wp_cache_delete 进行清理:

wp_cacache_delete($post->ID,'related_posts');

这里只是简单删除一下,更详细怎么使用 Hook 的例子,可以去 #WPJAM Basic# 的相关文章扩展中查看详情。

WPJAM 终极方法

通过上面的例子,看到使用 object_cache 都是首先要使用 wp_cache_get 函数去获取,如果不存在,再使用 wp_cache_set 函数去存储,有没有更加方便的方法呢?

有的,#WPJAM Basic# 提供了一个 wpjam_cache 的方法,可以将这个过程合并了,比如上面的例子,可以通过下面的代码实现:

$related_posts_data = wpjam_cache($post->ID,'related_posts', fn()=> wpjam_get_related_posts($post->ID), 3600);

它有四个参数,前面两个和 wp_cache_get() 函数一样,第三个参数是一个回调函数,它会在对象缓存不存在的时候被调用,获取数据并存到缓存中,从而实现自动实现缓存的过程,第四个是缓存时长。可以说除了第三个参数之外,其他参数和 wp_cache_xxx 函数的参数基本一致,使用也更加简洁,是一种高阶函数的写法。

总结

WordPress 对象缓存(Object Cache)是 WordPress 缓存机制,是深入了解对 WordPress 优化的基础,如果要熟悉 WordPress 开发和应用,都要有掌握好他。此外,WPJAM Basic 集成的 wpjam_cache 函数进一步提高使用效率,只需一步就实现 WordPress 对象缓存。


WPJAM Basic 插件已经集成了 Memcached,下载 WPJAM Basic 之后,将 wpjam-basic/template/ 目录下的 object-cache.php 文件复制到 wp-content 目录下即可。

「用户管理」:一键实现用户名称优化,用户安全增强,自定义头像等多项功能 WordPress 插件

2025年1月4日 19:22

这是基于 WPJAM Basic 的超强的 WordPress 用户管理的插件,有多强大呢,首先看后台的设置界面:

可以说它把 WordPress 相关的用户管理功能都集成了,简单数一数就实现了十多个 WordPress 用户相关功能:

  1. 屏蔽个性化设置
  2. 屏蔽姓氏和名字设置
  3. 取消显示名称设置
  4. 开启别名设置
  5. 隐藏用户登录名
  6. 开启登录次数限制
  7. 用户最后登录时间
  8. 取消「应用程序密码」
  9. 按注册时间排序
  10. 以此身份登陆
  11. 生成密码重置链接
  12. 自定义用户头像
  13. 默认用户头像

下面我们分成五大模块分别来介绍 WPJAM 的「用户管理插件」具体实现了那些功能:

屏蔽个性化设置

WordPress后台个人资料用户可以设置「可视化编辑器」,「语法高亮」,「配色方案」,「键盘快捷键」,「工具栏」,「语言」等这些个性化选项,如下图:

这些选项 WordPress 都是存储到 usermeta 表里面,如果 WordPress 有大量的用户,每个用户会占用7个选项,那么 usermeta 表很快就会爆炸。

比如我运营的 WordPress 站点,有几十万用户,usermeta 表的数据如果不清理的话,已经千万级了,查点东西都慢的要死,如果你和我有一样的困扰,那就可以在插件中勾选实现屏蔽用户的个性化设置,直接采用使用系统全局的默认值。然后还可以根据自己的需求删除这些选项。

用户名称优化

在默认情况下,WordPress 后台个人资料页面中,关于用户的姓名相关的设置是这样的:

是不是有点繁琐,并且很多字段也是存到 usermeta 表中的,我个人觉得关于用户昵称的设置,尽量简洁就好,所以名字和姓氏一般就不需要用户输入,公开显示的名字直接为昵称就好了,所以插件首先提供了下面两个选项:

  • 屏蔽姓名设置:屏蔽了姓氏和名字设置,简化后台个人资料界面设置。
  • 显示名称设置:取消显示名称选择器,直接使用昵称作为显示名称。

另外插件还支持开启了别名设置,是的,我们不仅仅做减法,偶尔也做下加法,这里可以让用户可以编辑自己的别名(user_nicename),这样只要不使用和登录名相同的别名,作者文章链接就不会暴露用户名,当然没有设置别名,插件还是有安全选项来实现防止用户名暴露。

所以优化之后最终的用户界面非常简洁,如下所示:

安全增强

WordPres 用户安全增强体现在两个地方,首先是隐藏登录名,不要让攻击者猜到用户名,然后是开启登录限制,防止密码被暴力破解,插件也提供这两方面的选项:

首先说一下如何隐藏登录名,如果用户没有修改过别名(user_nicename),那么他的别名和登录名(user_login)是一样的,然后作者文章链接或者其他地方就会暴露登录名,为了进一步防止登录名暴露,我们提供了隐藏登录名的选项:

勾选「防止登录名暴露」之后,如果用户的 user_nicenameuser_login 是一样的情况下:

1. 作者文章链接使用 author_id 代替 user_nicename,并且原来的作者链接直接设置为 404 页面,防止用户名暴露

2. user_login 不出现在 body_classcomment_class 中。

3. 隐藏登录失败时候未知用户名和密码不正确的错误信息,这两种情况都显示「用户名或者密码错误」,让攻击者猜去。😁

4. 取消作者相关的 sitemap 以及 REST API 中可以查看所有发布过文章的用户信息列表的中的登录名。

如果真的被攻击者猜到了登录名,那么我们还可以开启登录限制,限制登录失败次数,这样就可以防止密码被暴力破解了,进一步做到安全。

功能增强

除了安全增强之外,我们还增加了一个小功能和屏蔽一个功能,分别是记录用户最后登录时间和取消「应用程序密码」功能:

首先新增记录用户最后登录时间,用户登录之后,在后台用户列表就会显示该用户的最后登录时间,并且支持按照用户最后登录时间进行排序。

默认情况下在后台个人资料页面可以设置「应用程序密码」:

应用程序密码允许通过非交互式系统(例如 XML-RPC 或 REST API)进行身份验证,而无需提供您的实际密码。应用密码可以随时撤销。它们不能用于通过传统方式登录您的网站。

很多人看到这个其实是稀里糊涂,简单说他就是用于 APP 或者小程序通过接口来登录的,但是基本上来说,我们用不到这个功能,所以默认建议屏蔽它。

后台用户列表

对于管理员经常使用的用户列表,也新增一些功能和操作:

首先用户可以除了可以按照上面提示按照最后登录事件排序之外,也可以按照用户注册时间排序,只要你勾选了用户列表里的第一个选项,此外在用户列表页面新增两个操作「以此身份登陆」和「生成密码重置链接」:

如果你是 WordPress 开发者,「以此身份登陆」这个功能特别实用,在用户列表界面,管理员可以轻松以用户的身份登录后台,这样用户说他碰到什么问题,就可以直接登录他的账号去看了,而不是问他要账号密码,这个多难为情啊。😳

WordPress 原来「发送密码重置邮件」这个功能是直接发送密码重置邮件给用户,用户在邮箱里面直接点击操作,改成「生成密码重置链接」,则管理员直接获取密码重置链接,可以通过微信或者其他的社交媒体工具发给用户。

头像设置

在后台个人资料页,用户可以自定义自己的头像。

如果用户没有设置头像,管理员可以设置默认头像,然后随机给用户使用:

最后用户头像还多加一个选项,就是如果用户已经在 Gravatar 里面设置了头像怎么办?有两个选项,从默认中随机选一个,继续使用 Gravatar 的设置。

总结

通过上面的介绍,是不是非常强大,目前我所有用户相关的功能整合到 WPJAM-User 的插件中,只需后台简单的勾选就可以实现绝大部分用户安全和管理相关的功能。


「WordPress果酱」知识星球福利插件基于 WPJAM Basic 开发,加入「WordPress果酱」知识星球,即可下载:

插件 简介
抓取公众号图文

支持一键同步微信公众号文章到 WordPress 博客,并支持一键将文章中所有图片都下载到 WordPress 媒体库。

搜索优化

WordPress 最强的搜索优化插件,支持限制每个 IP 每分钟搜索次数,达到上限之后屏蔽搜索时长,还可以限制搜索关键词的长度,搜索结果页面限制只显示「搜索结果」,还有以下搜索功能增强:

1. 只搜索文章标题,不搜索文章内容和摘要。
2. 当搜索关键词为空时重定向到首页,只有一篇文章时重定向到文章
3. 后台文章列表支持搜索ID。
4. 支持搜索自定义字段。

编辑器优化

一键增强 WordPress 经典 TinyMCE 编辑器:

1. 增加下划线,背景颜色,两端对齐,字体和大小设置,以及内容分页按钮。
2. 新增插入表格功能。
3. 直接插入屏幕截图。

标题设置

一键设置 WordPress 所有页面的页面标题,通过规则方式让博主可以自定义 WordPres 首页,分类,文章类型,文章详情都所有页面的页面标题。

登录优化

一键优化 WordPress 登录注册界面,并支持第三方账号登录和绑定,目前已经支持微信公众号(所有类型),微信小程序,手机号码第三方平台。

内容模板

实现在内容中插入一段共用的内容模板,通过短代码(shortcode)的方式来实现的,支持统一修改,目前支持普通的内容模板,表格内容模板和卡片内容模板三种类型。

用户管理

最强 WordPress 一键用户管理插件,一键实现以下12个功能:

1. 屏蔽个性化设置
2. 屏蔽姓氏和名字设置
3. 取消显示名称设置
4. 开启别名设置
5. 隐藏用户登录名
6. 开启登录次数限制
7. 用户最后登录时间
8. 按注册时间排序
9. 以此身份登陆
10. 生成密码重置链接
11. 自定义用户头像
12. 默认用户头像

分类管理

这是一个全能的 WordPress 分类管理插件:

1. 层式管理分类
2. 限制分类层级
3. 分类拖动排序
4. 使用数字固定链接
5. 首页文章支持分类过滤
6. 后台文章列表支持分类筛选过滤
7. 后台文章列表支持分类多重筛选

评论增强

这是一个 WordPress 评论增强插件,支持评论置顶,评论点赞和按照点赞数排序。

图片集

1. 给媒体创建个分类「图片集 | collection」
2. 图片分类限制为二级
3. 取消图片编辑入口
4. 附件页面直接图片链接。

配置器

全自动 WordPress 配置器,不用一行代码就可以开发。
支持自定义文章类型,自定义字段,自定义分类,分类选项,全局选项。

Script Loader

通过恢复 WordPress 联合加载方式来优化 WordPress 后台脚本加载。

外部链接

将文章或评论中的外部链接加上安全提示的中间页。
让用户确认之后再跳转,并还支持添加 nofollow rel 属性。

话题标签

文章中插入 #话题标签#。
如果是内部链接,直接跳转,
标签或者分类,则自动转换成标签或分类链接,
否则跳转到搜索链接。

格式文章

在 WordPress 实现真正的文章格式

草稿分享

一键生成草稿临时分享链接
并可设置分享链接的有效期

文章专题

设置文章专题,并在文章末尾显示一个文章专题列表。

文章隐藏

设置文章在列表⻚不显示,并且可以根据不同平台进行设置

Meta Data

可视化管理 WordPress Meta 数据,支持所有内置的 Meta 数据:
Post Meta,Term Meta,User Meta 和 Comment Meta。

站点选项

查看和管理所有非 WordPress 系统自动生成的站点选项。
如果你觉得某个选项无用,可以直接删除它。

后台论坛

WordPress 后台论坛,支持创建帖子,分组,消息。

微信小程序

微信小程序 WordPress 基础插件,包含基础类库和管理。

微信群二维码

轮询显示微信群二维码,突破微信群100人限制。

文章置顶

支持置顶文章排序和分类文章置顶的 WordPress 插件

静态文件

一键合并 WordPress 插件和主题的 JS 和 CSS 文件,加快页面加载速度

Debug

一键检测 WordPress 运行效率。

需要别人登录你的 WordPress,再也不需要给账号密码了,现在可以给「一次登录链接」了!

2025年2月10日 23:22

前面我们介绍「为什么你的 WordPress 站点老是被黑?」的时候,说到大胡子和我卖 Modular 主题,我们的售后是很负责的,😎 会在用户允许的情况下,进入后台帮忙解决,这时候我们需要对方提供一下后台的账号密码,然后就接触到了很多简单到令人发指的密码,所以网站就被黑了。

说到要求对方提供账号密码这个事情,有用户提出,其实给人账号密码也很不安全,最好是创建一个新的管理员账号,这样就不会不小心暴露自己常用密码。

一次登录链接

但是创建一个新的管理员账号也是麻烦,用完又要删除或者去修改密码。那么有没有更好的方法呢?今天想到一个好方法,就是给某个用户创建「一次登录链接」,只能使用一次,这样就不用担心「售后」的时间。✌️

我就把该功能增加到「用户管理」功能,默认是开启的:

然后在用户列表就会有「生成链接」的操作,我把原来的「生成重置密码链接」一起合并进来:

点击之后,链接类型选择「一次登录」,链接有效期默认是 3 个小时,意思是 3 个小时内该链接点击都可以登录,过了就不行。

然后复制该链接,发送给帮你解决问题的好人,就可以了。

WPJAM「用户管理」

这次一次登录链接功能,我集成到了 WPJAM 这个「用户管理」插件中,它是 WordPress 果酱知识星球福利插件,加入「WordPress果酱」知识星球(长按下图二维码)即可下载:

如果基于 DeepSeek 开发 WordPress 的插件,它自己会选择什么功能?

2025年1月30日 21:54

今年最火的就是 DeepSeek 了,各种新闻,把英伟达的股票都干没了10 几个点。我也在想做一个基于 DeepSeep 的 WordPress 插件,但是做什么方向的的功能呢?要不这个功能也让 DeepSeek 帮我们也想想?

DeepSeek 的使用和 ChatGPT 之类其他的 AI 工具是有区别,他是基于推理型的大模型,而不是指令型的大模式,所以使用 DeepSeek 根本不需要提示词,直接就好了。

所以我的问题就直接把自己的目的告诉,我想写个 DeepSeek 的插件,需要给些功能灵感:

我想基于 DeepSeek 写个 WordPress 插件,在方向上,基于你对自己理解,你觉得可以做那些功能呢,你可以给我一些灵感吗?

然后我 开启了深度思考模式,DeepSeek 给出了它对这个问题的推理过程:

然后他给出了自己的建议,它还非常贴心的分成几个小标题,一共提供内容生产力、智能交互增强、数据智能分析和效率增强功能四大方向,每个方向还提供了2 个小功能,大家看看这些功能建议如何,并且它还非常贴心的提供技术实现要点,以及如何赚钱,也就是商业化建议

基于 DeepSeek 的能力和 WordPress 生态需求,以下是几个值得探索的插件开发方向,按优先级排序并附具体实现思路:


一、内容生产力工具(核心场景)

  1. AI 文章助手
    • 自动草稿生成:根据用户输入关键词自动生成结构化大纲(支持Markdown)
    • 智能续写/改写:通过浮动工具栏实现选中内容的优化/扩写/简写
    • SEO 增强:实时分析内容并推荐关键词密度、生成meta描述
    • 技术实现:结合Gutenberg编辑器API + 内容缓存机制降低API调用成本
  2. 多模态内容生成
    • 基于文本描述自动生成特色图片(需集成DeepSeek-Visual)
    • 智能生成文章配图说明文字(ALT文本优化)
    • 自动创建信息图描述文本

二、智能交互增强

  1. 对话式知识库
    • 将网站文档/产品目录转化为可对话的知识库
    • 实现路径:定期爬取指定页面内容构建向量数据库
    • 示例场景:客户服务机器人、产品FAQ交互
  2. 实时评论互动
    • 智能回复用户评论(可设置白名单词库限制)
    • 情感分析自动标记高风险评论
    • 支持预设行业话术模板(电商/教育等)

三、数据智能分析

  1. 流量内容洞察
    • 结合GA数据生成自然语言分析报告
    • 自动识别高跳出率页面的内容问题
    • 预测内容生命周期并提供更新建议
  2. 竞品内容监测
    • 定期抓取竞品RSS进行摘要对比
    • 生成差异化创作建议(需配置代理抓取)

四、效率增强功能

  1. 智能翻译工作流
    • 一键生成多语言版本并保持SEO结构
    • 支持术语表维护和翻译风格预设
    • 实现:WPML兼容 + 增量翻译缓存
  2. 自动化运营
    • 定期自动生成节日营销文案
    • 社交媒体帖子自动生成与排期
    • 结合Zapier实现跨平台自动化

技术实现要点

  1. 性能优化
    • 实现内容缓存池(基于文章ID的版本控制)
    • 支持异步队列处理长文本任务
    • 本地语义相似度计算减少API调用
  2. 安全合规
    • 内容审核过滤层(可对接DeepSeek审核API)
    • 用户数据脱敏处理
    • GDPR兼容设计(数据暂存策略)
  3. 扩展架构
    • 提供webhook接入点
    • 开发REST API扩展模块
    • 支持与WooCommerce等流行插件的数据打通

商业化建议

  • 分层定价策略
    • 免费版:基础内容生成(限次/水印)
    • 专业版:高级分析+多语言(订阅制)
    • 企业版:私有化部署+定制模型
  • 流量变现
    • 内置AI写作模版市场
    • 对接第三方云服务返佣
    • 提供A/B测试数据服务

建议初期聚焦内容生成核心场景,采用「AI功能+SEO工具」组合拳切入市场,后续通过用户行为数据分析逐步扩展智能运营功能。可参考Jarvis(Conversion.ai)的增长路径,但需注意WordPress生态的特殊性,强化与经典插件(Yoast SEO、Elementor)的兼容性。


大家觉得如何?希望首先实现哪个方向的插件?可以给我留言,我争取2 月份就先做个简单的插件出来给大家用用。😁

WordPress 是如何缓存的?对象缓存(Object Cache)详细介绍和使用!

2025年1月20日 23:43

任何技术要彻底了解它是怎么工作的,则要去了解它的机制和原理,WordPress 优化也是一样,如果要深度理解如何优化 WordPress,那么就要去了解 WordPress 对象缓存的原理和机制。

所以那么今天就来详细讲解一下 WordPress 缓存的底层原理对象缓存(Object Cache),以及在开发的时候如何使用它对 WordPress 进行加速。

WordPress 对象缓存和服务器设置

WordPress 对象缓存(英文名是:Object Cache)就是 WordPress 的缓存机制,它的主要功能是把数据库查询结果或者复杂运算的结果按照 Key-Value 这样的方式存储到对象里面,此外 WordPress 还支持按照 Group 来按组划分,以避免缓存内容的冲突。下次进行同样操作的时候,可以让直接从这个对象中取出数据,不用重复到数据库中或者其他外部获取数据。

WordPress 对象缓存和服务器设置关系很大,如果系统开启了 #Memcached# 内存缓存,则这个对象是直接存入到内存,在数据未过期之前,以后再次读取这个数据都是直接从内存中读取的,这样效率和速度都非常快的。

如果服务器不支持内存缓存的话,则只能保证在当前页面(PHP同个进程下)下同样的查询或者操作不再重复从数据库中读取了。

WordPress 对象缓存的函数

WordPress 对象缓存技术使用是非常简单的,其核心就是掌握下面下面这四个函数:

  • 添加数据到缓存中:
    wp_cache_add($key, $data, $group='', $expire=0)
  • 设置数据到缓存中:
    wp_cache_set($key, $data, $group='', $expire=0)
  • 获取缓存中的数据:
    wp_cache_get($key, $group='', $force=false, &$found=null)
  • 删除缓存中的数据:
    wp_cache_delete($key, $group='')

这四个函数会涉及到参数我罗列到一起简单讲下,下面知道个大概,可以收藏,方便使用的时候回来查看,重点还是后面的应用:

参数解释
$key数据在缓存中的健名
$data要缓存的数据,获取和删除函数无需用这个参数
$group缓存要添加到的组
$expire过期时间,可选参数,获取和删除函数无需用这个参数
如果是默认缓存,这个参数没用,如果是内存缓存,是设置缓存的时间。
单位是秒,默认为0(0 的意思就是永远,不会自动过期)
$force这个是获取缓存函数独有的函数,设置为 true 则强制使用持久缓存更新本地缓存
$found这个也是获取缓存函数独有的函数,它是一个引用参数,用于存储是否在缓存中找到 key,可以用于消除返回 false 的歧义

使用 WordPress 对象缓存

下面以我以 WordPress 相关文章为例,讲讲如何使用 WordPress 对象缓存。

我们知道 WordPress 相关文章插件是通过 tag 和分类来获取相关文章,文章使用相同的 tag 和分类越多,则认为为相关性越强,这样就需要进行多个表联合查询来获取相关文章,连表查询效率一般是比较差的。比如下面是一个比较通用的从数据库中查找相关文章的函数:

function wpjam_get_related_posts($post_id){
	global $wpdb;

	$term_ids   = wp_get_post_terms($post_id, ['category', 'post_tag'], ['fields' => 'ids']);
	$terms_ids  = implode(',', $term_ids);

	$related_posts = $wpdb->get_results("
		SELECT object_id, COUNT(*) as count
		FROM $wpdb->term_relationships
		WHERE term_taxonomy_id IN ($terms_string) AND object_id != $post_id
		GROUP BY object_id
		ORDER BY count DESC
		LIMIT 10"
	);

	foreach($related_posts as &$post){
		$post = get_post($post->object_id);
	}

	return $related_posts;
}

上面的函数,首先获取文章的标签和分类,然后基于使用相同的标签和分类的数量,通过 SQL 获取相似度最高的 10 篇文章的 ID,然后再相应获取对应的文章(这里为了简化,一般应该要根据文章 ID 批量文章,防止同时多条 SQL 请求)。

但是另外一方面,一篇文章,如果它的标签和分类没有修改的话,那么它的相关文章在一段时间内是不会变动的,所以相关文章的功能就非常适合使用 WordPress 对象缓存进行缓存加速加速。

我们就可以使用 wp_cache_set 函数就是把把相关文章的数据写入缓存的例子,使用当前 post_id 作为 key,related_posts 作为 group,缓存时间为一个小时,即 3600 秒。

$related_posts_data = wpjam_get_related_posts($post->ID);
wp_cache_set($post->ID,$related_posts_data,'related_posts',3600);

把数据存到缓存对象之后,在显示相关文章的时候,就可以使用 wp_cache_get 调用这个对象缓存来使用。

一般的流程是这样的,首先检查下是否已经有相应的缓存,如果你要的信息没有在缓存中,或者已经过期,wp_cache_get() 会返回 false,这时,你就要去数据库中重新获取这些信息,否则就返回在缓存中的信息。

$related_posts_data = wp_cache_get($post->ID,'related_posts');

if(false === $related_posts_data){
	$related_posts_data = wpjam_get_related_posts($post->ID);
	wp_cache_set($post->ID,$related_posts_data,'related_posts',3600);
}

因为设置了一个小时,相关文章的数据就失效,再次显示的时候会重新请求,,如果你在后台更改了设置,需要立即清理缓存,可以通过相关的 Hook 使用 wp_cache_delete 进行清理:

wp_cacache_delete($post->ID,'related_posts');

这里只是简单删除一下,更详细怎么使用 Hook 的例子,可以去 #WPJAM Basic# 的相关文章扩展中查看详情。

WPJAM 终极方法

通过上面的例子,看到使用 object_cache 都是首先要使用 wp_cache_get 函数去获取,如果不存在,再使用 wp_cache_set 函数去存储,有没有更加方便的方法呢?

有的,#WPJAM Basic# 提供了一个 wpjam_cache 的方法,可以将这个过程合并了,比如上面的例子,可以通过下面的代码实现:

$related_posts_data = wpjam_cache($post->ID,'related_posts', fn()=> wpjam_get_related_posts($post->ID), 3600);

它有四个参数,前面两个和 wp_cache_get() 函数一样,第三个参数是一个回调函数,它会在对象缓存不存在的时候被调用,获取数据并存到缓存中,从而实现自动实现缓存的过程,第四个是缓存时长。可以说除了第三个参数之外,其他参数和 wp_cache_xxx 函数的参数基本一致,使用也更加简洁,是一种高阶函数的写法。

总结

WordPress 对象缓存(Object Cache)是 WordPress 缓存机制,是深入了解对 WordPress 优化的基础,如果要熟悉 WordPress 开发和应用,都要有掌握好他。此外,WPJAM Basic 集成的 wpjam_cache 函数进一步提高使用效率,只需一步就实现 WordPress 对象缓存。


WPJAM Basic 插件已经集成了 Memcached,下载 WPJAM Basic 之后,将 wpjam-basic/template/ 目录下的 object-cache.php 文件复制到 wp-content 目录下即可。

Calibre 推荐配置与插件

2025年1月12日 13:40

在我的2024年阅读记录中,电子书的阅读量已经占整年阅读量的70%以上,家里的纸质书也逐步二手转让,电子书和阅读笔记就不可避免遇到整理的问题。

阅读笔记我主要是通过阅读器或阅读软件导出并整理到 Obsidian 中,我在 Obsidian 中设计了固定且简洁的阅读笔记模板,保证统一的格式和可检索性,但不会过度保存书籍的原始信息(书籍封面、页数等等感觉没必要)。

对于电子书的整理,这类软件没太多选择,灵活度且支持多平台的也只有 Calibre 能胜任。此外 Calibre-Web 更能通过 Docker 部署到 NAS 或者云主机中,折腾首选。因为我只考虑本地电子书的整理,平时阅读主要依赖墨水屏和微信读书,所以 Calibre-Web 就不折腾了。

Calibre 完全免费,支持中文,可以在 Windows、Mac 和 Linux 系统上运行,支持 TXT、PDF、EPUB、MOBI、DOCX、HTML、Markdown 等等众多格式,支持复杂的条件搜索语法和书籍全文搜索,支持本机建立内容服务器,局域网内使用浏览器访问书库及阅读。

下面介绍一下我使用 Calibre 的一些配置经验和推荐的插件(本文以 MacOS 15.2,Calibre v7.24.0 版本,本地管理方式为例)。

 

配置建议

1. 自定义栏目管理增加状态、阅读进度标记

通过“首选项”》“管理栏目”创建自定义栏目,增加“状态”栏目,用于标识电子书的阅读状态,比如我会使用”在读,已读,搁置,已读2遍,已读3遍“来记录阅读状态。同样的方法,你可以更加精细的记录阅读进度、读后短评等等。

Calibre 推荐配置与插件-雅余

 

2. 优化日期的显示方式

通过“首选项”》“优化调整”对日期的显示方式进行自定义。默认设置“MMM yyyy”实在看着别扭,建议把出版日期修改为 “yyyy-MM”,加入日期和修改日期修改为 “yyyy-MM-dd”。

Calibre 推荐配置与插件-雅余

 

3. 调整界面外观图标主题

默认图标风格太丑,可通过“首选项”》“界面外观”调整图标主题,推荐 Setenove 系列,图标大小设置为中小

Calibre 推荐配置与插件-雅余

 

4. 以中文名称保存书籍至硬盘

Calibre 默认提取书籍保存到硬盘是使用“作者简称/标题/标题 - 作者”作为路径和名称,实在啰嗦。建议按截图勾选,禁止转换为字符和封面单独保存等,保存模板直接设置以标题保存即可。更多的时候提取只是为了分享或者发送到硬件设备中。

Calibre 推荐配置与插件-雅余

 

5. 使用中文路径(禁止 Calibre 翻译文件路径)

多年以前我不愿使用 Calibre 是因为它会自动把中文名称和路径翻译转换为拼音,可读性太差,强迫症受不了。感谢 Cirn09 的 “Calibre-do-not-translate-my-path”(将我的书库从拼音目录切换至非纯英文(中文)命名)这个插件拯救了不少患者。

Calibre 推荐配置与插件-雅余

patch 方案:
通过 Github 下载 Calibre-do-not-translate-my-path

解压下载的包,得到 python-lib.bypy.frozen 文件。

打开 Finder,进入“应用程序” (/Applications),右键点击“Calibre——显示包内容”,进入 Contents/Frameworks/plugins (对应的完整路径是 /Applications/calibre.app/Contents/Frameworks/plugins )。将第 1 步下载包里的 python-lib.bypy.frozen,拷贝覆盖原文件,重新打开 Calibre 即可。

Git 上有其他系统的使用方法,作者也提供了对已建书库的批量处理方法。

 

6. 精选元数据来源

在“首选项”》“插件”中展开“元数据来源”,禁用不需要的元数据来源,减少插件的加载。

Calibre 推荐配置与插件-雅余

在“首选项”》“下载元数据”中勾选不需要的数据源,减少查询元数据时对速度的影响。我仅保留3项,基本能满足中英文书籍查询,通过豆瓣获取封面优先级为最高。

Calibre 推荐配置与插件-雅余

 

7. 禁用在线书店

在“首选项”》“插件”中展开“在线书店”,禁用不需要插件。我还把菜单栏上的快捷入口删除了。基本用不着这个功能。

Calibre 推荐配置与插件-雅余

 

8. 精选设备接口

在“首选项”》“插件”中展开“设备接口”,禁用不需要插件。我仅保留了安卓和 Kindle,其他全部禁用。

Calibre 推荐配置与插件-雅余

 

9. 备份 Calibre 设置项

在“首选项”》“杂项”中,点击“打开 'calibre 配置'文件夹“,可以跳转到 calibre 的配置文件夹,对整个文件夹进行打包备份,以便重装软件等等不时之需。

Calibre 推荐配置与插件-雅余

 

10. 生成书库书目及制作成电子书

Calibre 支持为书库所有书籍制作电子书目,可自定义书目包含的元数据字段信息,支持生成 CSV、EPUB、XML 等多种格式,生成后在书库内直接浏览。建议导出 CSV 格式,方便处理导入其他软件中使用。

Calibre 推荐配置与插件-雅余

 

11. 书库备份

硬盘富余的话,可以考虑定期对整个书库进行备份。我暂时仍保留着原始文件夹整理和 Calibre 整理两种方式。

Calibre 推荐配置与插件-雅余

 

推荐插件

1. Highlights to Obsidian

实现一键同步 Calibre 的批注内容到 Obsidian 中,同步内容包括高亮位置的链接、高亮内容、自己对高亮内容的批注等。通过插件可以自定义同步到 Obsidian 中的模板格式,灵活度很高。该插件可以通过 Calibre 进行搜索安装,也可以通过 Github 下载安装包。

2. Ebook Translator

Ebook Translator 是书伴开发的一款 Calibre 插件,可以将不同格式不同语言的电子书翻译成指定语言(原文译文对照)指定格式的电子书,支持 Google、ChatGPT 和 DeepL 翻译引擎。该插件可以通过 Calibre 进行搜索安装。

3. New Douban Books

实现通过豆瓣获取书籍元数据和封面图片。建议通过 Github 中获取一个较新的安装包,并通过“从文件加载插件”的方式进行安装。

安装插件还是坚持一个原则,能免则免,能精则精,不要贪多。

-

参考资料:
- 阅读批注样样通,我的 Calibre 书籍库管理方法论
- Ebook Translator:用 Calibre 翻译多格式双语对照电子书
- 用Calibre管理图书,还能一键同步批注到Obsidian
- Calibre 不要翻译我的文件路径

「用户管理」:一键实现用户名称优化,用户安全增强,自定义头像等多项功能 WordPress 插件

2025年1月4日 19:22

这是基于 WPJAM Basic 的超强的 WordPress 用户管理的插件,有多强大呢,首先看后台的设置界面:

可以说它把 WordPress 相关的用户管理功能都集成了,简单数一数就实现了十多个 WordPress 用户相关功能:

  1. 屏蔽个性化设置
  2. 屏蔽姓氏和名字设置
  3. 取消显示名称设置
  4. 开启别名设置
  5. 隐藏用户登录名
  6. 开启登录次数限制
  7. 用户最后登录时间
  8. 取消「应用程序密码」
  9. 按注册时间排序
  10. 以此身份登陆
  11. 生成密码重置链接
  12. 自定义用户头像
  13. 默认用户头像

下面我们分成五大模块分别来介绍 WPJAM 的「用户管理插件」具体实现了那些功能:

屏蔽个性化设置

WordPress后台个人资料用户可以设置「可视化编辑器」,「语法高亮」,「配色方案」,「键盘快捷键」,「工具栏」,「语言」等这些个性化选项,如下图:

这些选项 WordPress 都是存储到 usermeta 表里面,如果 WordPress 有大量的用户,每个用户会占用7个选项,那么 usermeta 表很快就会爆炸。

比如我运营的 WordPress 站点,有几十万用户,usermeta 表的数据如果不清理的话,已经千万级了,查点东西都慢的要死,如果你和我有一样的困扰,那就可以在插件中勾选实现屏蔽用户的个性化设置,直接采用使用系统全局的默认值。然后还可以根据自己的需求删除这些选项。

用户名称优化

在默认情况下,WordPress 后台个人资料页面中,关于用户的姓名相关的设置是这样的:

是不是有点繁琐,并且很多字段也是存到 usermeta 表中的,我个人觉得关于用户昵称的设置,尽量简洁就好,所以名字和姓氏一般就不需要用户输入,公开显示的名字直接为昵称就好了,所以插件首先提供了下面两个选项:

  • 屏蔽姓名设置:屏蔽了姓氏和名字设置,简化后台个人资料界面设置。
  • 显示名称设置:取消显示名称选择器,直接使用昵称作为显示名称。

另外插件还支持开启了别名设置,是的,我们不仅仅做减法,偶尔也做下加法,这里可以让用户可以编辑自己的别名(user_nicename),这样只要不使用和登录名相同的别名,作者文章链接就不会暴露用户名,当然没有设置别名,插件还是有安全选项来实现防止用户名暴露。

所以优化之后最终的用户界面非常简洁,如下所示:

安全增强

WordPres 用户安全增强体现在两个地方,首先是隐藏登录名,不要让攻击者猜到用户名,然后是开启登录限制,防止密码被暴力破解,插件也提供这两方面的选项:

首先说一下如何隐藏登录名,如果用户没有修改过别名(user_nicename),那么他的别名和登录名(user_login)是一样的,然后作者文章链接或者其他地方就会暴露登录名,为了进一步防止登录名暴露,我们提供了隐藏登录名的选项:

勾选「防止登录名暴露」之后,如果用户的 user_nicenameuser_login 是一样的情况下:

1. 作者文章链接使用 author_id 代替 user_nicename,并且原来的作者链接直接设置为 404 页面,防止用户名暴露

2. user_login 不出现在 body_classcomment_class 中。

3. 隐藏登录失败时候未知用户名和密码不正确的错误信息,这两种情况都显示「用户名或者密码错误」,让攻击者猜去。😁

4. 取消作者相关的 sitemap 以及 REST API 中可以查看所有发布过文章的用户信息列表的中的登录名。

如果真的被攻击者猜到了登录名,那么我们还可以开启登录限制,限制登录失败次数,这样就可以防止密码被暴力破解了,进一步做到安全。

功能增强

除了安全增强之外,我们还增加了一个小功能和屏蔽一个功能,分别是记录用户最后登录时间和取消「应用程序密码」功能:

首先新增记录用户最后登录时间,用户登录之后,在后台用户列表就会显示该用户的最后登录时间,并且支持按照用户最后登录时间进行排序。

默认情况下在后台个人资料页面可以设置「应用程序密码」:

应用程序密码允许通过非交互式系统(例如 XML-RPC 或 REST API)进行身份验证,而无需提供您的实际密码。应用密码可以随时撤销。它们不能用于通过传统方式登录您的网站。

很多人看到这个其实是稀里糊涂,简单说他就是用于 APP 或者小程序通过接口来登录的,但是基本上来说,我们用不到这个功能,所以默认建议屏蔽它。

后台用户列表

对于管理员经常使用的用户列表,也新增一些功能和操作:

首先用户可以除了可以按照上面提示按照最后登录事件排序之外,也可以按照用户注册时间排序,只要你勾选了用户列表里的第一个选项,此外在用户列表页面新增两个操作「以此身份登陆」和「生成密码重置链接」:

如果你是 WordPress 开发者,「以此身份登陆」这个功能特别实用,在用户列表界面,管理员可以轻松以用户的身份登录后台,这样用户说他碰到什么问题,就可以直接登录他的账号去看了,而不是问他要账号密码,这个多难为情啊。😳

WordPress 原来「发送密码重置邮件」这个功能是直接发送密码重置邮件给用户,用户在邮箱里面直接点击操作,改成「生成密码重置链接」,则管理员直接获取密码重置链接,可以通过微信或者其他的社交媒体工具发给用户。

头像设置

在后台个人资料页,用户可以自定义自己的头像。

如果用户没有设置头像,管理员可以设置默认头像,然后随机给用户使用:

最后用户头像还多加一个选项,就是如果用户已经在 Gravatar 里面设置了头像怎么办?有两个选项,从默认中随机选一个,继续使用 Gravatar 的设置。

总结

通过上面的介绍,是不是非常强大,目前我所有用户相关的功能整合到 WPJAM-User 的插件中,只需后台简单的勾选就可以实现绝大部分用户安全和管理相关的功能。


「WordPress果酱」知识星球福利插件基于 WPJAM Basic 开发,加入「WordPress果酱」知识星球,即可下载:

插件 简介
抓取公众号图文

支持一键同步微信公众号文章到 WordPress 博客,并支持一键将文章中所有图片都下载到 WordPress 媒体库。

搜索优化

WordPress 最强的搜索优化插件,支持限制每个 IP 每分钟搜索次数,达到上限之后屏蔽搜索时长,还可以限制搜索关键词的长度,搜索结果页面限制只显示「搜索结果」,还有以下搜索功能增强:

1. 只搜索文章标题,不搜索文章内容和摘要。
2. 当搜索关键词为空时重定向到首页,只有一篇文章时重定向到文章
3. 后台文章列表支持搜索ID。
4. 支持搜索自定义字段。

编辑器优化

一键增强 WordPress 经典 TinyMCE 编辑器:

1. 增加下划线,背景颜色,两端对齐,字体和大小设置,以及内容分页按钮。
2. 新增插入表格功能。
3. 直接插入屏幕截图。

标题设置

一键设置 WordPress 所有页面的页面标题,通过规则方式让博主可以自定义 WordPres 首页,分类,文章类型,文章详情都所有页面的页面标题。

登录优化

一键优化 WordPress 登录注册界面,并支持第三方账号登录和绑定,目前已经支持微信公众号(所有类型),微信小程序,手机号码第三方平台。

内容模板

实现在内容中插入一段共用的内容模板,通过短代码(shortcode)的方式来实现的,支持统一修改,目前支持普通的内容模板,表格内容模板和卡片内容模板三种类型。

用户管理

最强 WordPress 一键用户管理插件,一键实现以下12个功能:

1. 屏蔽个性化设置
2. 屏蔽姓氏和名字设置
3. 取消显示名称设置
4. 开启别名设置
5. 隐藏用户登录名
6. 开启登录次数限制
7. 用户最后登录时间
8. 按注册时间排序
9. 以此身份登陆
10. 生成密码重置链接
11. 自定义用户头像
12. 默认用户头像

分类管理

这是一个全能的 WordPress 分类管理插件:

1. 层式管理分类
2. 限制分类层级
3. 分类拖动排序
4. 使用数字固定链接
5. 首页文章支持分类过滤
6. 后台文章列表支持分类筛选过滤
7. 后台文章列表支持分类多重筛选

评论增强

这是一个 WordPress 评论增强插件,支持评论置顶,评论点赞和按照点赞数排序。

图片集

1. 给媒体创建个分类「图片集 | collection」
2. 图片分类限制为二级
3. 取消图片编辑入口
4. 附件页面直接图片链接。

配置器

全自动 WordPress 配置器,不用一行代码就可以开发。
支持自定义文章类型,自定义字段,自定义分类,分类选项,全局选项。

Script Loader

通过恢复 WordPress 联合加载方式来优化 WordPress 后台脚本加载。

外部链接

将文章或评论中的外部链接加上安全提示的中间页。
让用户确认之后再跳转,并还支持添加 nofollow rel 属性。

话题标签

文章中插入 #话题标签#。
如果是内部链接,直接跳转,
标签或者分类,则自动转换成标签或分类链接,
否则跳转到搜索链接。

格式文章

在 WordPress 实现真正的文章格式

草稿分享

一键生成草稿临时分享链接
并可设置分享链接的有效期

文章专题

设置文章专题,并在文章末尾显示一个文章专题列表。

文章隐藏

设置文章在列表⻚不显示,并且可以根据不同平台进行设置

Meta Data

可视化管理 WordPress Meta 数据,支持所有内置的 Meta 数据:
Post Meta,Term Meta,User Meta 和 Comment Meta。

站点选项

查看和管理所有非 WordPress 系统自动生成的站点选项。
如果你觉得某个选项无用,可以直接删除它。

后台论坛

WordPress 后台论坛,支持创建帖子,分组,消息。

微信小程序

微信小程序 WordPress 基础插件,包含基础类库和管理。

微信群二维码

轮询显示微信群二维码,突破微信群100人限制。

文章置顶

支持置顶文章排序和分类文章置顶的 WordPress 插件

静态文件

一键合并 WordPress 插件和主题的 JS 和 CSS 文件,加快页面加载速度

Debug

一键检测 WordPress 运行效率。

「搜索优化」:防止搜索攻击,限制搜索频率,增强搜索能力,WordPress 一键式搜索优化增强插件

2024年12月13日 23:49

在 WordPress 进行搜索是一个常见的操作,而 WordPress 搜索的底层其实就是使用 MySQL like 语法去检索文章的标题摘要内容查出相关的文章。

一般情况 WordPress 这样搜索没有什么大的问题,可能中文分词会存在一些语义理解的小问题,但是通过多次修改关键字多搜索几次总能找到想要的文章。

WordPress 搜索存在的问题

如果碰到攻击,WordPress 的搜索就有很大的问题,因为 WordPress 搜索的链接是 https://blog.wpjam.com/?s=关键词,攻击者只要使用脚本不停的切换关键字,就会造成系统不停去数据库搜索查询,缓存都救不了!

而这样 MySQL Like 查询相对来说是比较耗时的,这就存在被攻击的漏洞,并且攻击时使用的关键字都是随机的,生成的缓存键都是不同,这时候缓存都救不了。

另外 WordPress 只是简单使用 MySQL like 语法去检索文章的标题,摘要和内容来查出相关的文章,没有别的选项,能不能只搜索标题?能不能搜索ID,甚至搜索自定义字段等。

WordPress 最强的搜索优化插件

WPJAM 的「搜索优化」插件就能为了这些功能而实现的,在碰到搜索攻击的时候,可以去限制甚至关闭 WordPress 的搜索,然后一方面,它还提供很多的选项增强 WordPress 的搜索功能。

「搜索优化」插件安装之后,在「WPJAM」菜单的「文章设置」子菜单下就有「搜索优化」标签页,点击进入即可设置搜索优化的功能:

搜索范围

首先该插件可以设置搜索范围:

可以设置文章类型支持在那些文章类型中搜索,如果不设置,WordPress 会使用默认的方式。

其次可以设置哪些用户可以进行搜索,这里有三个选项,默认「所有用户都可以搜索」,然后也可以设置「仅限登录用户搜索」,甚至还可以「关闭站点搜索功能」,这个功能在站点受到攻击的时候,可能会帮到你。

搜索限制

第二大的功能是对搜索功能进行限制:

做站点最重要的就是安全,如上图所示,首先支持限制每个 IP 每分钟搜索多少次,达到上限之后屏蔽多少分钟。在遭受搜索攻击的时候,甚至可以直接关闭搜索,最后还可以设置管理员搜索功能不受影响。

下图就是用户搜索达到上限之后,用户再次搜索之后页面显示的效果:

微信公众号的搜索也可以搜索限制,只要使用#微信机器人#的自定义回复,插件就会自动检测每个公众号用户的搜索次数:

#果酱小程序#也支持搜索限制,达到搜索上限之后,同样会报错:

嗯,「WPJAM」出品的插件很多功能有关联,但也不影响单独使用,非常方便。

此外还可以设置「搜索关键词最大长度」,太长的关键字其实搜索不出什么东西,并且还增加系统的搜索负担,所以可以选择直接屏蔽了事。这个长度的规则还是:一个汉字算两个,一个英文单词算两个,空格不算,所以大家设置的时候注意下,别搞错了。

此外为了防止不怀好意的人来瞎搞,还可以设置「不允许搜索禁用词」。禁用词是在「设置」-「讨论」-「禁止使用的评论关键字」中设置的。

当然了,最后不要限制都把自己给限制了,所以最后还有个选项,可以开启:「站点管理员搜索功能不受上面这些条件限制」。

搜索增强

我们在给一些客户做定制开发的时候,也会经常碰到一些搜索的优化,比如能不能只针对文章标题进行搜索,能不能搜索自定义字段等等,这些功能「搜索优化」插件都实现了:

首先是重定向功能,开始的时候,就会:当关键词为空时重定向到首页,只有一篇文章时重定向到文章。这个功能原本是集成在 #WPJAM Basic# 中,我写了「搜索优化」插件之后,就整和到一起了,做强做大 WPJAM「搜索优化」插件。😁

接着是我命名为「标签搜索功能」,当关键词和分类/标签/自定义分类相同时,直接展示对应的文章。

搜索结果页面标题不显示关键字,只显示「搜索结果」四个字」,这个功能大家第一眼看可能感觉没啥,其实这个功能非常重要的,这里要特别讲解一下,为什么要做这个呢?

这是因为一些 WordPress 的站点的搜索结果页面被黑产会刷了,他们把自己的网站名字和域名刷到搜索结果的页面标题上:

图片

当然上面限制了搜索关键字长度之后,在一定程度上也限制了刷搜索结果的可能性,但是要继续杜绝这种事情,通过把搜索结果页面的标题只显示「搜索结果」则可以完全的防止住,因为无论搜索搜什么,都是显示「搜索结果」这四个字:

图片


只搜索文章标题,不搜索文章内容和摘要」:字面意思,懂的吧?😂

后台文章列表支持ID搜索,如123,多个ID用「,」分隔开,如12,34,56,这个在后台要定位某篇文章 ID 的时候特别有用。

支持搜索自定义字段,功能要别注意一下,开启之后搜索效率会明显下降,然后这个功能勾选之后,还可以选择是在所有自定义字段中搜索还是在指定的自定义字段(输入 meta_key )中搜索。

WPJAM「搜索优化」

WPJAM 这个「搜索优化」是不是很强大,关于 WordPress 搜索相关的功能,我都会整合到这个插件中。

它是 WordPress 果酱知识星球福利插件,加入「WordPress果酱」知识星球(长按下图二维码)即可下载:


「WordPress果酱」知识星球福利插件基于 WPJAM Basic 开发,加入「WordPress果酱」知识星球,即可下载:

插件 简介
抓取公众号图文

支持一键同步微信公众号文章到 WordPress 博客,并支持一键将文章中所有图片都下载到 WordPress 媒体库。

搜索优化

WordPress 最强的搜索优化插件,支持限制每个 IP 每分钟搜索次数,达到上限之后屏蔽搜索时长,还可以限制搜索关键词的长度,搜索结果页面限制只显示「搜索结果」,还有以下搜索功能增强:

1. 只搜索文章标题,不搜索文章内容和摘要。
2. 当搜索关键词为空时重定向到首页,只有一篇文章时重定向到文章
3. 后台文章列表支持搜索ID。
4. 支持搜索自定义字段。

编辑器优化

一键增强 WordPress 经典 TinyMCE 编辑器:

1. 增加下划线,背景颜色,两端对齐,字体和大小设置,以及内容分页按钮。
2. 新增插入表格功能。
3. 直接插入屏幕截图。

标题设置

一键设置 WordPress 所有页面的页面标题,通过规则方式让博主可以自定义 WordPres 首页,分类,文章类型,文章详情都所有页面的页面标题。

登录优化

一键优化 WordPress 登录注册界面,并支持第三方账号登录和绑定,目前已经支持微信公众号(所有类型),微信小程序,手机号码第三方平台。

内容模板

实现在内容中插入一段共用的内容模板,通过短代码(shortcode)的方式来实现的,支持统一修改,目前支持普通的内容模板,表格内容模板和卡片内容模板三种类型。

用户管理

最强 WordPress 一键用户管理插件,一键实现以下12个功能:

1. 屏蔽个性化设置
2. 屏蔽姓氏和名字设置
3. 取消显示名称设置
4. 开启别名设置
5. 隐藏用户登录名
6. 开启登录次数限制
7. 用户最后登录时间
8. 按注册时间排序
9. 以此身份登陆
10. 生成密码重置链接
11. 自定义用户头像
12. 默认用户头像

分类管理

这是一个全能的 WordPress 分类管理插件:

1. 层式管理分类
2. 限制分类层级
3. 分类拖动排序
4. 使用数字固定链接
5. 首页文章支持分类过滤
6. 后台文章列表支持分类筛选过滤
7. 后台文章列表支持分类多重筛选

评论增强

这是一个 WordPress 评论增强插件,支持评论置顶,评论点赞和按照点赞数排序。

图片集

1. 给媒体创建个分类「图片集 | collection」
2. 图片分类限制为二级
3. 取消图片编辑入口
4. 附件页面直接图片链接。

配置器

全自动 WordPress 配置器,不用一行代码就可以开发。
支持自定义文章类型,自定义字段,自定义分类,分类选项,全局选项。

Script Loader

通过恢复 WordPress 联合加载方式来优化 WordPress 后台脚本加载。

外部链接

将文章或评论中的外部链接加上安全提示的中间页。
让用户确认之后再跳转,并还支持添加 nofollow rel 属性。

话题标签

文章中插入 #话题标签#。
如果是内部链接,直接跳转,
标签或者分类,则自动转换成标签或分类链接,
否则跳转到搜索链接。

格式文章

在 WordPress 实现真正的文章格式

草稿分享

一键生成草稿临时分享链接
并可设置分享链接的有效期

文章专题

设置文章专题,并在文章末尾显示一个文章专题列表。

文章隐藏

设置文章在列表⻚不显示,并且可以根据不同平台进行设置

Meta Data

可视化管理 WordPress Meta 数据,支持所有内置的 Meta 数据:
Post Meta,Term Meta,User Meta 和 Comment Meta。

站点选项

查看和管理所有非 WordPress 系统自动生成的站点选项。
如果你觉得某个选项无用,可以直接删除它。

后台论坛

WordPress 后台论坛,支持创建帖子,分组,消息。

微信小程序

微信小程序 WordPress 基础插件,包含基础类库和管理。

微信群二维码

轮询显示微信群二维码,突破微信群100人限制。

文章置顶

支持置顶文章排序和分类文章置顶的 WordPress 插件

静态文件

一键合并 WordPress 插件和主题的 JS 和 CSS 文件,加快页面加载速度

Debug

一键检测 WordPress 运行效率。

还没升级到 PHP 8.4,也可以提前在 WordPress 中使用 PHP 8.4 引入的数组函数

2024年12月2日 23:17

PHP 升级到了 8.4,个人觉得对我们写代码帮助最大的就是 PHP 8.4 引入的 array_find()array_find_key()array_any() 和 array_all() 这 4 个 array_*() 数组函数。

其实这四个函数在 JavaScript 的 Array 的实例方法中就有了,只是他的命名方式和 PHP 有点不一样,就他是用 every 和 some 而不是 all 和 any,我之前写代码的时候,也有一些地方需要使用到这四个数组函数,所以我基于 JavaScript 的方式在 #WPJAM Basic# 中集成了这四个方法。

在 PHP 8.4 发布之后我基于 PHP 8.4 命名方式做了一些优化,使得大家在没有升级到 PHP 8.4,也可以提前在 WordPress 中使用 PHP 8.4 引入的数组函数。

array_find()

array_find() 是返回数组中第一个满足回调函数的元素,如果没有则返回 null,根据这个特性,我们很容易就是先这个函数:

if(!function_exists('array_find')){
	function array_find($arr, $callback){
		foreach($arr as $k => $v){
			if($callback($v, $k)){
				return $v;
			}
		}
	}
}

比如我在字段处理中,如果字段没有定义类型,我根据它是否有其他属性来给他设置类型的代码,如果没有 array_find,我们一般这么写:

if(!empty($field['options'])){
	$field['type']	= 'select';
}elseif(!empty($field['label'])){
	$field['type']	= 'checkbox';
}elseif(!empty($field['fields'])){
	$field['type']	= 'fieldset';
}else{
	$field['type']	= 'text';
}

有了 array_find,一行搞定了:

$field['type']	= array_find(['options'=>'select', 'label'=>'checkbox', 'fields'=>'fieldset'], fn($v, $k)=> !empty($field[$k])) ?: 'text';

array_find_key()

array_find_key()array_find() 很像,只是它返回数组中第一个满足回调函数的元素的健名:

if(!function_exists('array_find_key')){
	function array_find_key($arr, $callback){
		foreach($arr as $k => $v){
			if($callback($v, $k)){
				return $k;
			}
		}
	}
}

相比 array_find() 函数的定义,唯一的区别,它 return 的是 key 而不是 value。

上面的获取字段的类型的代码,也可以使用 array_find_key() 来实现,大家看看区别:

$field['type']	= array_find_key(['select'=>'options', 'checkbox'=>'label', 'fieldset'=>'fields'], fn($v, $k)=> !empty($field[$v])) ?: 'text';

array_all()

array_all() 判断数组中的每个元素是否都满足回调函数,意思是将每个元素传递给回调函数,都要返回 true

if(!function_exists('array_all')){
	function array_all($arr, $callback){
		foreach($arr as $k => $v){
			if(!$callback($v, $k)){
				return false;
			}
		}

		return true;
	}
}

比如我写的 SMTP 发信扩展里面就有判断代码,需要「发信地址」,「邮箱账号」和「邮箱密码」这三个选项都设置了之后才生效:

if(array_all(['host', 'user', 'pass'], fn($k)=> WPJAM_SMTP::get_setting($k))){
	// 执行代码
}

array_any()

array_any() 也是判断数组的元素是否满足满足回调函数,但是 array_any() 只需要一个满足即可,而 array_all() 一样则是需要全部都满足:

if(!function_exists('array_any')){
	function array_any($arr, $callback){
		foreach($arr as $k => $v){
			if($callback($v, $k)){
				return true;
			}
		}

		return false;
	}
}

上面例子中,发信设置扩展需要「发信地址」,「邮箱账号」和「邮箱密码」这三个选项都要设置,换成 array_any() 的思维,则只要一个没有设置就返回:

if(array_any(['host', 'user', 'pass'], fn($k)=> !WPJAM_SMTP::get_setting($k))){
	return;	// 返回,不生效
}

大家对比一下两个例子的代码,使用相类似的例子,通过不同的写法,也是一种更加清晰的区分函数的方式。😄

标题说了,还没升级到 PHP 8.4,也可以提前在 WordPress 中使用 PHP 8.4 引入的数组函数,意思只要你更新 WPJAM Basic 到最新版就能使用了,所以记得更新,有什么问题,记得给我留言。

在 WordPress 中如何设置背景色透明度?

2024年10月29日 23:55

最近开始写一些 WordPress 专业的知识,阅读数奇低,然后我发一些微信昵称技巧,又说我天天发这些小学生爱玩的玩意,写点文章真不容易。

那我两天发点专业的东西,两天发点小学生的东西,剩下三天我看着办,这样总行吧?

哈哈,那就天就发布一点点专业的东西,就是我们做网页开发的时候的时候如何设置透明背景。

为什么背景要设置透明度?

首先说下为什么背景要设置透明度,比如最近我给公司实现做的表格应用的时候,有个单元格条件样式的功能:

就是类似于 Excel 的条件格式化的功能,让数据根据不同的值显示不同的样式,如上图所示,可以设置,加粗,文本颜色,和填充颜色,其中填充就是设置单元格的背景颜色 :

由于我们的表格每一行本身就有间隔背景色(或者说斑马色),如果我们设置的单元格背景没有透明度的话,就会看不到间隔色,看数据不太方便,另外也会比较显眼,抢过了主体文本的颜色

也有人可能喜欢这种比较强烈的配色方式,不过不管了,我觉这个例子就是想给大家说下,我做了一个表格应用,可以自定义单元格样式,嘻嘻,另外也是为了点下今天的主体,怎么设置背景透明度。

如何设置背景透明度?

首先这个是 CSS 的活,我们都知道设置背景色的 CSS 代码:

// 使用 RGB
.background {
  background-color: rgb(255, 0, 0); /* 红色背景 */
}

// 使用 HSL
.background {
  background-color: hsl(120, 100%, 50%); /* 绿色背景 */
}

// 使用 HEX 6位16进制颜色代码
.background {
  background-color: #0000FF; /* 蓝色色背景 */
}

// 使用 HEX 3位16进制颜色代码
.background {
  background-color: #00F; /* 蓝色色背景 */
}

上面展示了 RGB 和 HSL 以及 HEX 16 进制三种设置背景的方法,但是这样设置都是不透明的。

那么如何设置透明度呢?其实也非常简单,只要给上面的颜色加上透明度的 Alpha 通道即可:

// 使用 RGBA
.background {
  background-color: rgba(255, 0, 0, 0.5); /* 红色背景 50% 透明度*/
}

// 使用 HSLA
.background {
  background-color: hsla(120, 100%, 50%, 0.3); /* 绿色背景  50% 透明度*/
}

// 使用 HEX 8位16进制颜色代码
.background {
  background-color: #0000FF80; /* 蓝色色背景 50% 透明度*/
}

// 使用 HEX 4位16进制颜色代码
.background {
  background-color: #00F8; /* 蓝色色背景 50% 透明度*/
}

其中 RGB 和 HSL 两种方法则在起方法名后面加上 A 即可,然后取值范围从 0(完全透明)到 1(完全不透明)。

16 进制的方法则有点复杂,使用16进制颜色代码设置背景透明度可以通过使用8位(#RRGGBBAA)或4位(#RGBA)的16进制格式来实现,其中最后两位(AA)或最后一位(A)代表透明度(Alpha)。透明度的值范围从00(完全透明)到FF(完全不透明)。

所以上面的例子中 0000FF 是蓝色,80(即128/255)表示大约50%的透明度。另外需要特别注意一下虽然现代浏览器普遍都支持16进制颜色透明度代码,但在某些旧版本的浏览器中可能不会正常工作,因此,如果你需要兼容,建议还是使用 rgba()hsla() 函数。

另外使用 opacity 定义透明度,但是他是使得整个元素透明度都下降,包括它的背景、文本和边框等,这个时候要注意你是要整体还仅仅是背景了。

.background {
  background-color: #0000FF; /* 蓝色色背景 */
  opacity: 0.5; /* 整个元素50% 透明度 */
}

在 WordPress 中如何设置支持透明度的颜色字段

我们知道有个 wp-color-picker 组件,可以让我们在设置输入字段的时候,可以直接选择颜色(在 WPJAM Basic 添加字段的时候,将 type 设置为 color 即可):

但是他无法设置透明度,Sergio 就更新了一下 wp-color-picker 组件,发不了 wp-color-picker-alpha 组件,支持通过拖拉即可设置透明度,如下图所示:

哈哈,WPJAM Basic 最新版也支持了该功能,在设置添加字段的时候,将 type 设置为 color 之外,还需要加上 data-alpha-enabled 属性,并将其设置为 true,比如我上面设置背景色的代码:

$fields	= [
	'background-color'	=> ['type'=>'color',	'button_text'=>'填充颜色',	'data-alpha-enabled'=>true]
];

我和大胡子做的模块化主题「Modular」也很快会加上该功能:

WordPress「站点选项」插件:一键查看和管理站点全局选项

2024年10月27日 23:42

前面我写了 WordPress 中如何设置全局选项?一文详解 WordPress 的 Option 功能,为了方便 WordPress 所有站点选项的管理和设置,我做了一个 WordPress「站点选项」插件,可以查看和管理所有 WordPress 站点的全局选项,特别是选项不再使用了,可以通过该插件直接删除它。

为什么开发这个插件?

我们知道绝大部分的插件和主题都会有选项设置,这些选项设置就会在 WordPress Option 表里面插入一些数据,如果这些插件或者主题不用的话,这些加入到 Option 表里面的数据一般都还会留在那里。

其实这些站点选项数据留在那里,问题也不大,不过总有一些有洁癖的同学,想清理一下,比如我,所以就开发了这个「站点选项」WordPress 插件。

查看和管理站点选项

安装好之后,在 WPJAM 菜单下会多出一个「站点选项」的子菜单,点击进去,即可查看站点上所有的全局选项:

对于这些选项数据,如果觉得没有任何用了,比如是插件停用之后的残留,就可以删除他们,不过删除前还是要再次确保不再使用。

除了删除之外,我们还可以进行「编辑」和「重命名」等操作,但是进行这些操作之前,还是要确认该操作不会造成任何问题。

另外对于如果数值是数组的选项,在列表是解析出来显示的:

但是在编辑的时候,在编辑的时候,显示的是序列化的:

所以编辑的时候,也要注意,不要搞错了,这时候建议的通过「替换」进行操作:

最后WordPress 选项「Option」的自动加载的功能,该功能是在 WordPress 的加载的时候,开启的「自动加载的选项就会一次全部加载,这样下次再使用该选项的时候,就无需再从数据库中获取。

所以该插件也可以加上一个设置「自动加载」的功能,可以开启或者关闭某个选项的「自动加载」功能,如下图所示,在列表页最后一列自动加载的开关点击一下即可切换:

总之,WordPress 「站点选项」是一个非常方便的后台数据管理 WordPress 插件,可以让你一键查看和管理站点的全局选项,但是操作之前还是要确保你对这些的操作已经足够了解,是自己真正需要的。😄

WordPress 「站点选项」插件

WordPress 「站点选项」插件是 WordPress 果酱知识星球福利插件,加入「WordPress果酱」知识星球(长按下图二维码)即可下载:


「WordPress果酱」知识星球福利插件基于 WPJAM Basic 开发,加入「WordPress果酱」知识星球,即可下载:

插件 简介
抓取公众号图文

支持一键同步微信公众号文章到 WordPress 博客,并支持一键将文章中所有图片都下载到 WordPress 媒体库。

搜索优化

WordPress 最强的搜索优化插件,支持限制每个 IP 每分钟搜索次数,达到上限之后屏蔽搜索时长,还可以限制搜索关键词的长度,搜索结果页面限制只显示「搜索结果」,还有以下搜索功能增强:

1. 只搜索文章标题,不搜索文章内容和摘要。
2. 当搜索关键词为空时重定向到首页,只有一篇文章时重定向到文章
3. 后台文章列表支持搜索ID。
4. 支持搜索自定义字段。

编辑器优化

一键增强 WordPress 经典 TinyMCE 编辑器:

1. 增加下划线,背景颜色,两端对齐,字体和大小设置,以及内容分页按钮。
2. 新增插入表格功能。
3. 直接插入屏幕截图。

标题设置

一键设置 WordPress 所有页面的页面标题,通过规则方式让博主可以自定义 WordPres 首页,分类,文章类型,文章详情都所有页面的页面标题。

登录优化

一键优化 WordPress 登录注册界面,并支持第三方账号登录和绑定,目前已经支持微信公众号(所有类型),微信小程序,手机号码第三方平台。

内容模板

实现在内容中插入一段共用的内容模板,通过短代码(shortcode)的方式来实现的,支持统一修改,目前支持普通的内容模板,表格内容模板和卡片内容模板三种类型。

用户管理

最强 WordPress 一键用户管理插件,一键实现以下12个功能:

1. 屏蔽个性化设置
2. 屏蔽姓氏和名字设置
3. 取消显示名称设置
4. 开启别名设置
5. 隐藏用户登录名
6. 开启登录次数限制
7. 用户最后登录时间
8. 按注册时间排序
9. 以此身份登陆
10. 生成密码重置链接
11. 自定义用户头像
12. 默认用户头像

分类管理

这是一个全能的 WordPress 分类管理插件:

1. 层式管理分类
2. 限制分类层级
3. 分类拖动排序
4. 使用数字固定链接
5. 首页文章支持分类过滤
6. 后台文章列表支持分类筛选过滤
7. 后台文章列表支持分类多重筛选

评论增强

这是一个 WordPress 评论增强插件,支持评论置顶,评论点赞和按照点赞数排序。

图片集

1. 给媒体创建个分类「图片集 | collection」
2. 图片分类限制为二级
3. 取消图片编辑入口
4. 附件页面直接图片链接。

配置器

全自动 WordPress 配置器,不用一行代码就可以开发。
支持自定义文章类型,自定义字段,自定义分类,分类选项,全局选项。

Script Loader

通过恢复 WordPress 联合加载方式来优化 WordPress 后台脚本加载。

外部链接

将文章或评论中的外部链接加上安全提示的中间页。
让用户确认之后再跳转,并还支持添加 nofollow rel 属性。

话题标签

文章中插入 #话题标签#。
如果是内部链接,直接跳转,
标签或者分类,则自动转换成标签或分类链接,
否则跳转到搜索链接。

格式文章

在 WordPress 实现真正的文章格式

草稿分享

一键生成草稿临时分享链接
并可设置分享链接的有效期

文章专题

设置文章专题,并在文章末尾显示一个文章专题列表。

文章隐藏

设置文章在列表⻚不显示,并且可以根据不同平台进行设置

Meta Data

可视化管理 WordPress Meta 数据,支持所有内置的 Meta 数据:
Post Meta,Term Meta,User Meta 和 Comment Meta。

站点选项

查看和管理所有非 WordPress 系统自动生成的站点选项。
如果你觉得某个选项无用,可以直接删除它。

后台论坛

WordPress 后台论坛,支持创建帖子,分组,消息。

微信小程序

微信小程序 WordPress 基础插件,包含基础类库和管理。

微信群二维码

轮询显示微信群二维码,突破微信群100人限制。

文章置顶

支持置顶文章排序和分类文章置顶的 WordPress 插件

静态文件

一键合并 WordPress 插件和主题的 JS 和 CSS 文件,加快页面加载速度

Debug

一键检测 WordPress 运行效率。

在 PHP 和 WordPress 中如何给数组切片

2024年9月12日 16:58

从一个数组中取出一段数据,或者说切片,这是非常常见的数组操作,PHP 已经内置了了 array_slice 函数来实现这个操作,但是面对关联数组的一些基于 key 的切片操作,该函数就有点力不从心了,那么我们面对这些复杂的情况,怎么操作呢?今天就通过这篇文章详细讲解一下在 WordPress 中如何给数组切片。

还是从 array_slice 说起

array_slice 的简介就是从数组中取出一段,它是从指定偏移量开始提取特定数量的元素,具体的语法:

array_slice(array $array, int $offset, int $length, bool $preserve_keys = false)
  • $array:待切片的数组。
  • $offset:切片开始的位置,从 0 开始计数,支持负数,从末端开始算起。
  • $length:切片元素的长度。
  • $preserve_keys(可选):是否保留切片元素的键名,默认值为 false。注意无论本参数如何设置,都会保留字符串的键。

还是看具体的例子吧。

// 从数组中取出第一个元素
$slice = array_slice([1, 2, 3, 4, 5], 0, 1); // [1]

// 从数组中取出第二个和第三个元素
$slice = array_slice([1, 2, 3, 4, 5], 1, 2); // [2, 3]

如果是用负偏移量,将从数组末尾开始计数:

// 从数组中取出倒数第二个元素
$slice = array_slice([1, 2, 3, 4, 5], -2, 1); // [4]

如果不指定长度,则切片将包括从偏移量到数组末尾的所有元素:

// 从数组中取出第二个和之后所有的元素
$slice = array_slice([1, 2, 3, 4, 5], 1); // [2, 3, 4, 5]

如果将 $preserve_keys 参数设置为 true,则切片元素将保留其原始键名:

// 从数组中取出第二个元素,并保留键名
$slice = array_slice([1, 2, 3, 4, 5], 1, 1, true); // [1 => 2]

对于关联数组,则  $preserve_keys 不管参数是什么值,都会保留原始的键:

// 从关联数组中取出第二和第三个个元素,下面都是输出 ['b'=>2, 'c'=>3]
$slice = array_slice(['a'=>1, 'b'=>2, 'c'=>3, 'd'=>4, 'e'=>5], 1, 2, true);

$slice = array_slice(['a'=>1, 'b'=>2, 'c'=>3, 'd'=>4, 'e'=>5], 1, 2);

关联数组如何切片

从上面的例子可以看出 array_slice  是基于偏移量和长度进行切片的,但是对于关联数组来说,如果我们要基于数组的 key 进行切片怎么操作?

WordPress 的 wp_array_slice_assoc

WordPress 内置有个 wp_array_slice_assoc 函数,它基于一个健的列表从关联数组中取出数组,具体的语法:

wp_array_slice_assoc( array $input_array, array $keys )
  • $input_array:待切片的关联数组。
  • $keys:健的列表。
// 从数组中取出键为 c 和 b 的元素
$slice = wp_array_slice_assoc(['a'=>1, 'b'=>2, 'c'=>3, 'd'=>4, 'e'=>5], ['c', 'b', 'f']); 
// 结果为 ['c'=>3, 'b'=>2] 

取出的数组是按照 $keys 参数的顺序取出来的,上面的例子中,我故意把 c 放到 b 前面,取出的关联数组的 key 的顺序也是按照这个顺序,另外数组中不存在的 key,取出关联的数组也是不存在的,比如上面例子的 f。

WPJAM Basic 的 wpjam_slice

因为 wp_array_slice_assoc 取出的关联数组的顺序是按照输入的 $keys 参数顺序的,但是有些情况下我们要求取出的关联数组的顺序不要动,即不关系 $keys 的顺序,所以我在 #WPJAM Basic# 中加入了一个 wpjam_slice 函数,它取出的数组是不会变动的,具体的语法:

wpjam_slice( array $input_array, array $keys )
  • $input_array:待切片的关联数组。
  • $keys:健的列表。

还是看具体的例子吧:

// 从数组中取出键为 c 和 b 的元素
$slice = wpjam_slice(['a'=>1, 'b'=>2, 'c'=>3, 'd'=>4, 'e'=>5], ['c', 'b', 'f']); 
// 结果为 ['b'=>2, 'c'=>3] 

最后取出的关联数组的是按照原先的顺序,并且不存在的 key,取出关联的数组也是不存在的。

此外 $keys 参数除了数组之外,还支持字符串,通过空格或者逗号转化成数组:

// 从数组中取出键为 c 和 b 的元素,$keys 参数为逗号间隔字符串
$slice = wpjam_slice(['a'=>1, 'b'=>2, 'c'=>3, 'd'=>4, 'e'=>5], 'c,b,f']); 
// 结果也是 ['b'=>2, 'c'=>3]

// 从数组中取出键为单个元素
$slice = wpjam_slice(['a'=>1, 'b'=>2, 'c'=>3, 'd'=>4, 'e'=>5], 'c']); 
// 结果为 ['c'=>3] 

这样 WordPress 中给数组如何切片,是不是方法更多了一下,哈哈!

中文环境下,WordPress 截取个摘要,竟然有那么多问题!

2024年9月8日 23:09

我们先从 WordPress 文章摘要功能说起,大部分 WordPress 主题在首页,分类搜索等各种列表页,会只显示文章摘要,而不显示文章内容全文,所以摘要很重要,在列表页,用户是否会点击查看这篇文章,摘要会起到很重要的效果。

怎么设置文章摘要

那么怎么设置摘要呢?在使用经典编辑器的年代,摘要是非常容易设置的,就在文章内容的下面,很多人写完文章,顺手也设置了文章摘要:

但是升级到古腾堡编辑器之后,很多人就发现不知道去哪里设置摘要了,摘要设置文本框被移到编辑器右侧文章设置的很下面,很多人没有认真去看,还以为没了。😅

甚至有些人因为这个原因,从来没有去设置过文章摘要,也有人因为这个原因坚持在用经典编辑器。😅

#WPJAM Basic# 插件支持一键屏蔽古腾堡编辑器,此外 #WPJAM Basic# 还提供一个扩展「摘要快速编辑」,让你可以在文章列表快速设置文章摘要:

使用文章摘要

设置了 WordPress 摘要,那就要去用,这个一般来说都是主题开发者的工作,这里简单了解一下就好,如果你要自己修改主题,那就就要认真看下。😄

WordPress 提供了两个文章摘要的模板函数,这个知道就好,一般主题就是使用这两个函数实现的。

1. get_the_excerpt( $post = null ) ,用于获取文章的摘要,它只有一个参数,就是 $post,可以是文章对象,或者文章 ID, 也可以不传,不传则获取当前文章的摘要。

2. the_excerpt(),直接输出当前文章的摘要,该函数没有任何参数,所以模板开发很简单,直接在文章列表页使用该模板函数即可。

自动获取文章摘要

由上可知,并不是每篇文章都设置了摘要,这个时候,WordPress 默认会自动获取:

WordPress 默认会使用 wp_trim_excerpt 去获取文章内容,加上摘要长度传递给 wp_trim_words 函数处理, wp_trim_words 会基于用户所处的环境:

  • 单词之间没有空格的,比如中日韩,它就按照中文字符和英文字符都算一个字符来截取。
  • 单词之间有空格的,比如英文或其他,它就按照空格或者回车来获取单词数组,截取输入长度的单词数。

这种算法对于中文来说,非常不好,因为一个中文字符,宽度基本上是一个英文字符的两倍,如果文章中的中英文混排的话,截取出来肯定会长度不一。

所以现在很多主题会加入自动摘要截取优化的代码,但是有些主题直接使用 substr 函数来获取摘要,该函数是把中文算成 3 个字符,英文字符算 1 个字符,这个算法有点奇怪,但是如果英文不多,截取的产地还算一致,但是比较致命的是,该函数无法判断一个完整的中文字符,截取的时候,可能在中文字符中间劈开了,然后就出现乱码:😅

所以对于中文环境,最好按照「中文 2 个字节,英文 1 个字节」的方式来截取,并且中文字符会当作一个完整的字符来处理,而采用该截取算法 PHP 函数则是 mb_strimwidth

mb_strimwidth($text, 0, 240, '...', 'utf-8');

为了方便大家的设置,我在 #WPJAM Basic# 集成了自动获取文章摘要的设置,无需修改任何代码,简单选择设置一下即可,点击「WPJAM」菜单下「文章设置」子菜单下之后可以看到:

当文章未设置摘要时候,默认还是 WordPress 默认自带的截取摘要的方式,然后 WPJAM Basic 插件增加了两个选项:

  • 第一个很简单直接:直接不显示摘要。
  • 第二个选项就是前面介绍的算法,按照中文最优方式截取,并且还可以设置文章摘要的长度。
    再次提醒一下注意算法是「中文 2 个字节,英文 1 个字节」,设置长度的时候要注意下。

这个时候再看看,除了第二篇是后台设置了摘要,其他三篇摘要都基本差不多长度了,并且也没有出现乱码:

mb_strimwidth 不存在?

写到这里,你是不是觉得 WordPress 摘要的问题已经解决了?现在还存在两个问题:

1. #WPJAM Basic# 的设置不生效,还是出现上面那种乱码,或者长短不一的情况。

因为插件的优化摘要的代码和主题优化摘要的代码优先级是不一定的,可能主题占优了,那么你这个时候应该咨询主题作者,让他提供选项,然后你可以关闭主题的摘要优化功能。

2. 直接报错了:

Call to undefined function mb_strimwidth()

好吧,mb_ 打头的函数,需要 PHP 安装 mb_string 扩展,在后台「WPJAM」菜单下的「系统信息」的子菜单中,可以快速查看:

所以我又升级了一下 #WPJAM Basic# ,做了兼容,就是说现在没有装该扩展,也有该函数了:

if(!function_exists('mb_strimwidth')){
	function mb_strimwidth($str, $start, $width, $trimmarker=''){
		preg_match_all('/./us', $str, $match);

		$count	= count($match[0]);
		$start	= $start < 0 ? $count-1+$start : $start;
		$chars	= array_slice($match[0], $start);

		if($width >= array_sum(wpjam_map($chars, fn($char)=> ord($char) >=224 ? 2 : 1))){
			return implode('', $chars);
		}

		$length	= 0;
		$result	= '';
		$count	-= $start;
		$width	-= strlen($trimmarker);

		for($i=0; $i<$count; $i++){
			$char	= $chars[$i];
			$w		= ord($char) >= 224 ? 2 : 1;

			if($length + $w > $width){
				break;
			}

			$result	.= $char;
			$length	+= $w;
		}

		return $result.$trimmarker;
	}
}

这就是我最近发现大家在设置 WordPress 文章摘要中碰到的问题。好累,一个摘要的问题写了那么长。😅

还有一点,文章摘如果设置得好,结合一些 SEO 插件,比如 WPJAM Basic 的「简单SEO」扩展,摘要也可以设置成 meta description,搜索引擎收录内容之后,在搜索结果页面显示的内容也是文章的摘要。

blog搬家

2024年11月28日 08:13

11月末有好几件事让人焦虑。除了单位的工作以外,还有我自己的blog。因为我们合租的服务器到期了,11月28日到期。据说我们已经连续在那个服务器供应商那里好多年,我感觉有10年以上。那这一次我们觉得真的要离开了,因为那个供应商在我们提交了工单以后,半天都不回复,其次就服务器的性能来说,其实那家不算太好,虽然访问速度我个人觉得在广东电信之下还是可以的。服务器也比较稳定,试过宕机,但是几率不高。一直以来我都觉得在WordPress的后台没法用,自带的导出功理论能把全站的内容导出,我们可能是那个空间的设定的问题,每次当我下载不到2MB的时候就会停掉,结果打开那个xml文件实际上是不完整的,所以我根本没办法做全站的导出,我只能手动地分段导出文章,但那样的话,我就会丢失其它所有内容。

今年3月开始,包租公就告诉我要备份了。因为他忘记了服务器的密码。所以经典的那个WordPress搬家方式不可行,我得用其它方式把WordPress的东西全部备份出来,那个时候我觉得这根本是不可能完成的任务,但后来的确有牛逼的插件能做这个。一开始包租公告诉我,是10月到期,于是10月的时候我就找他,10月底的时候我继续找他,然后他告诉我11月到期,我不确定11月什么时候到期,有一天突然服务器宕机了,我以为是我们到期了,虽然前一天我已经做好备份,但是突然打不开,让人忐忑,结果被告知,我们还没到期,我们到期的日期是11月28日,所以11月25日的时候,我又找包租公。他居然把那个给忘记了,但是他很快就买了新的空间,然后开始往里面装东西。我们的速度很快,在11月26日我们就已经完成了搬家,虽然有一些奇怪的东西还是好像没有完全解决,但总的来说,基本上所有东西,能一次性挪走的都已经挪走了,至于哪些东西出了问题,我还没办法逐一检查出来,检查不出来的只能发现一个解决一个。其中一个比较明显的问题是有些页面有140多条评论,但实际上前台只显示了两条,当我在后台查询的时候,我的确能看到140多条,所以为什么会出现这种情况呢?其它文章评论看上去是正常的,我没有仔细的数过,但起码你能看到评论有很多,至于是不是显示多少条的那个数量,我没有仔细研究过,但为什么一些页面的评论展示数量是正常的,而另外一些却不行呢?这件事情很诡异。我记得当我用插件完成搬家的时候,除了完成按钮以外还有两个链接一个是永久链接的设置,另外一个是评论插件。在我印象之中,我没有使用任何评论插件。永久链接在那个,搬家插件之前那个版本,永久链接会神经病,得手动重选,但在这个新的插件里搬家完毕后,好像永久链接依然会以我自定义的形式显示,没有出现问题,但我还是按照以前的步骤走了一遍。

搬家的时候,我用的是IP地址,但搬家完毕以后,我把IP地址绑定到了我的域名,后来我又发现媒体文件那里当我从某个前台地址打开图片,图片显示的不是域名地址,显示的是IP地址。这算是一个很傻瓜的问题,肯定可以通过一波替换全部处理掉。域名也好,IP地址也好,实际上都能指向那个图片,万一我换了一个网址呢?那个图片就会变成失效。这种东西可以通过在后台数据库做替换简单解决,但这也是搬家过程之中经常会发生的事情。哪怕不是搬家,是从http变成https也会有这种毛病,所以为什么我就没有一种快捷的方式替换掉所有这些东西呢?

但总算搬家这个事情解决了,而且好长一段时间,我都不需要在这个问题上操心。

7bu 图床插件 For WordPress/Typecho 分享

2023年11月29日 00:00

前几天有小伙伴询问是否有 WordPress/Typecho 的相关插件,可惜杜老师能力有限不会弄,就只能求助于群里的小伙伴,果然有大神帮忙设计了出来。在此感谢 Xin Huai W L 帮忙制作了插件,分享给需要的小伙伴们!

WordPress 插件的食用教程

为了测试插件,杜老师特地安装 WordPress。进入后台进入到添加新插件页面,从下面的链接中下载 WordPress 插件,并上传到博客:

上传后直接启用就行了,但需要先设置 Token 才可以使用:

如您使用去不图床托管,请在网址设置框输入 https://7bu.top,Tokens 框中输入在图床获取的 TOKEN,并可以选择是否要公开图片:

写文章时可在右侧看到插件模块,直接拖拽上传图片即可:

WordPress 插件的下载地址

下载地址:

下载地址

Typecho 插件的食用教程

Typecho 需要手动上传到插件目录,后台刷新一下就能看到,直接启用即可:

在正式使用前,需要先设置下。如您使用去不图床托管,请在网址设置框输入 https://7bu.top,Tokens 框中输入在图床获取的 TOKEN,存储 id 为空就行了:

Typecho 插件的下载地址

下载地址:

下载地址

感谢北门清燕童靴帮忙开发的云存档插件

2022年12月6日 00:00

xaoxuu 大佬曾反馈过之前的挂机游戏不支持云存档,杜老师的能力有限,不知道怎么弄。好在北门清燕童靴发现了这个问题并开发了云存档插件,本文表示感谢同时,说一下插件的使用方法!

插件特点

  1. 使用简单,仅需输入 GitHub 的账号及 Token 即可;

  2. 可以自动备份,每 10 秒钟自动备份,无需手动操作。

使用前提

本插件是将本地的存档数据,备份到 GitHub 的 Gist,所以需要使用者拥有 GitHub 账号。

其次插件通过 Token 创建 Gist,需使用者为插件创建 Token「创建方法参考下文」

创建方法

登录 GitHub 后,点击头像,选择下拉单中的 Settings。

Developer settings——Personal access tokens——Tokens (classic)——Generate new token (classic)

在 Note 框内输入备注名称,Expiration 选择 Token 有限时间「建议选 No expiration 永不过期」

在 Select scopes 列表中勾选 gist,点击最下方 Generate token,即可看到生成的 Token「注意备份,仅此显示一次,且需注意不要泄露」

插件安装

访问下方链接即可安装插件:

https://greasyfork.org/zh-CN/scripts/455596-game-dusays-com%E8%87%AA%E5%8A%A8%E4%BA%91%E7%AB%AF%E5%AD%98%E6%A1%A3

云存档插件安装后,再进入游戏时「仅支持 game.dusays.com」会弹出提示依次输入 GitHub 账号及 Token,即可实现自动存档:

Obsidian 和 WordPress 我都用什么插件

2024年9月3日 19:24

Obsidian 插件

1. Hover Editor
快速悬浮模式编辑。

2. Outliner
整理大纲。

3. Clearing Unused Images
用于清理图片,该插件默认不开启,需要清理时才启用。但现在基本不插入图片到笔记,纯文本记录。

以上就是我当前使用的所有第三方插件。之前也试过安装 Calendar、Kanban、Thino 等等插件,但感觉都没太大必要,软件自带功能和核心插件完全可以应付常规笔记需求。插件多了反而影响软件秒开。

我使用 Obsidian 插件的使用原则是,脱离 Obsidian 后,所有内容可以在其他编辑软件中继续正常使用。这意味着类似 Dataview 需要语法来判断、筛选内容的插件不符合我的要求。没有 Dataview 的便捷性,反而让我对于索引卡制作和双链的使用更加严格,对内容有更多的思考。提升效率的插件可以考虑安装一两个,或者多记几个快捷键。


WordPress 插件

1. Akismet
默认插件,能应付部分垃圾评论。

2. Autoptimize
优化 HTML、CSS、JS。

3. Object Cache
优化缓存。

4. WP Permalinks Migration
去年简化固定链接后作重定向安装的,计划明年删除。

以上就是我当前使用的所有插件,其他就是依赖部署服务器的时候一些优化,买的最低配轻量应用服务器。目前感觉网站整体速度还可以。我的开源主题,我会在functions.php 中禁用一些不需要的功能。我自己用的主题,我会禁用更多,比如禁止WordPress自动生成缩略图、禁止响应式图片。我不考虑使用第三方服务,比如图床,以避免以后服务终止或迁移带来的困扰。

-

个人觉得,做笔记也好,写博客也好,软件/程序功能上的需求没有那么多,就是图片和文本信息。基于极简原则,其他都是画蛇添足或锦上添花。花样多,需要投入的非必要时间就多,让你分心的东西越多。够用就好。

WordPress私密评论插件

2024年8月31日 20:37

昨晚爆肝到凌晨三点,终于搞定了这款插件。细心的朋友会发现我博客发表评论旁多了个选项——私密评论,顾名思义,选中,你这条评论一般人看不到,成你与博主的悄悄话了。这个功能我原先早在XIGE的博客上看到过,当时觉得没必要,因为我一直觉得一篇文章里,评论也是精彩的部分,老子说过,高手在评论区嘛!

那为毛现在又开始折腾了呢?因为上一篇文章的事情,让我感受到言论不是很自由。暴露在网络上的笔记本,不仅仅只是评论区的朋友在看,更多的是被监管。所以我能控制我博客上的内容,但是我控制不了别人的言论,我觉得在我这里,他们是自由的。但是我又不想与其他博客那样,需要注册登录才能查看和评论,这样很不方便。像WP这样,有昵称、邮箱就可以参与评论,实在太方便了,以至于我觉得验证码都是多余的。

奇怪,怎么有种要立牌坊的味道?

于是乎我就想有个私密评论的功能。起先我想找个插件就好了,没想到唯一一款插件还得收费,像我这种白嫖党是不能接受的。看到Jeffer.Z小友开发JefRssFriends插件,我也有了想法——AI。我不太会使用AI,或者说我不会提问题,沟通有障碍,导致AI给我的答案不仅看不懂,效果几乎没有,无论我怎么问,它只有那一个答案。最后我直接躺平了,说你给我写个WordPress插件,评论可以设置私密评论,我还能修改私密评论的状态。好,好像可以了。然后再加以修改,结合料网分享的私密评论的代码,效果就有了。

20240831192835.jpg
游客看到的私密评论
20240831192805.jpg
博主和评论者看到的私密评论
20240831192731.jpg
后台显示评论私密的状态
20240831193006.jpg
点击可以转换私密的状态
20240831193057.jpg
点击可以转换私密的状态

料网分享的代码,直接复制粘贴就能用。但只能设置私密,但不能取消私密,而我还想实现管理员可以修改评论这种私密与否的状态,不能只能私密,不能公开吧。能力有限,他的代码我不会改,所以就求助于AI,二者一结合,感觉还是挺完美的。

好了,话不多说,网不好的朋友见此下载地址,网好的朋友可以到我的GitHub下载

如果大家有想骂我,表白的,都可以私密我哦!但同时若我觉得你的评论不好公开,我也会将你的评论私密哦。

版权声明: 本文采用 BY-NC-SA 协议进行授权,如无注明均为原创,转载请注明转自 皇家元林
本文链接: WordPress私密评论插件

WP搬家策略

2024年8月30日 19:44

现在WordPress服务器供应商的服务期限大概到今年10月就满了,所以在那之前,团长是应该带着我搬家的,今年早些时候我们已经讨论过这个问题,因为他已经忘记了账号密码,所以常规的搬家步骤不没办法实现,因为根本进不了后台,导出不了数据库,同时也不能把我挂在上面的网站拷贝出来。今年4月的时候,我已经折腾了一番,用的是一个WP的插件(All-in-One WP Migration),那个东西可以在WP后台的界面把网站所有数据全部导出。导出的那些数据被压缩成一个文件。那个文件通过他们网站上面的某些工具,可以在线浏览里面的内容,也可以下载工具安装之后把它解压出来。但即便都解压了出来,那个东西的结构跟WP网站本身还是有一定区别,所以我猜他们没想过用户会把数据导出来以后,通过手工搬家的方式,把数据库挪到其他地方。比如在新的服务器那里,首先进行一个数据库的导入,然后把网站解压的内容复制到新的服务器。为什么这么说呢?因为上面说过,文件加压后的结构跟WP网站本身是有点区别的,但我并没有研究过差异在哪里。有区别就意味着直接搬过去肯定会遭殃。所有人都知道服务器上传文件的大小是有限制的,有可能服务商对你进行了限制,也有可能是软件进行了限制。所以这个插件还卖了一个功能,他们可以把超大的压缩文件上传到你的网站上。你完全不需要考虑文件超限,做不了任何事情。这么高端的操作是付费服务。如果人人都可以轻易地自己挪动,这个付费也就毫无意义,他们也就无法靠这个东西生存下去了。如果网站的数据超限了,但又不想给钱,他们还是给出了一些调整的方案,但这些步骤对小白来说有点复杂,但是对我这种不怕折腾,只要能免费的人来说,完全是可行的。主要步骤分为两个,第一个是在我WP的文件里插入某些语句,但即便这样插入了,也不能保证上传一定不超限。因为还有服务商那边的门槛,所以必要的时候还是要跟服务商沟通一下。在测试搬家这个问题上,我用过两个方式,一个是纯粹的导出导入,第二个是在导入形成网站之后,再导出那个网站的数据库文件,接着把那个网站的网页文件复制到一个新的地方,然后把数据库文件另存为一个新的数据库文件并修改网址,最后把新的网页文件指向新的数据库。之所以做这么无聊的测试,是因为万一服务器那边无论我怎么修改,就是不让我直接导入大文件,我还可以通过这种方式搬家。我20年数据的整个文件不到600MB,而数据库文件只有70多MB。不让600多MB的文件上传,我觉得这是有点可以理解的,但是70多MB的数据库文件,我感觉还是可以成功导入的。如果能实现,我很折腾的第二个方案就意味着我可以把网站从线上搬到线下,然后进行一个普通搬家的流程。之前说过,之所以得这么折腾,是我没办法直接访问现在那个网站的后台,折腾一番以后,实际上我就是把网站线上的后台搬到了线下。

这两年来写了很多的VBA+ADO+SQL,所以我在 phpmyadmin里看到数据库和SQL的时候,我感到了默默的亲切。当我在那里测试SQL语句的时候,发现那个速度实在太感人了。70多MB的SQL文件用Notepad++打开,大概13万行。我要更新里面的某些东西,那是眨眼就能完成的事,跟用Excel处理的速度相比,专业的数据库真的太伟大了。

星期三就已经找过团长,但到星期四下班的时候,他还没回复我。通常情况下不会这么长时间都没反应的,大概他出差了吧…

4个步骤让 MacOS 13 以下版本支持 AVIF 格式预览

2024年8月28日 10:36

如果你使用的是 macOS Ventura(MacOS 13),系统已默认支持 AVIF 格式打开和预览。对于更旧的系统版本,需要通过安装第三方图片浏览软件或拖到浏览器中查看。

AVIF QuickLook 插件可以通过4个简单的步骤,实现在系统直接预览 AVIF 格式,该插件由国内一个作者 DreamPiggy 开发。

要求:

1、macOS 10.11+ (Big Sur+) 以上版本
2、M1/Intel Mac 都支持

步骤:

1、在 Github Release Page 下载最新的 AVIFQuickLook.qlgenerator
2、打开 访达.app (Finder);
3、通过快捷键 Shift + Command + G 打开“前往文件夹”窗口,输入 ~/Library/QuickLook/ 然后回车。 macOS Catalina 以上版本, 使用 /Library/QuickLook/
4、把下载的 AVIFQuickLook.qlgenerator 复制到该文件夹内,可能需要输入电脑密码确认。

如果你已经安装了 Homebrew,只需要一行命令即可。

brew install avifquicklook

安装完,系统就支持直接预览 AVIF 格式了。

通义灵码,你的编程小助手

2024年4月7日 11:25
通义灵码是一个编程助手,可以嵌入到你的IDEA中辅助编程,它经过了海量优秀开源代码数据训练,可根据当前代码文件及跨文件的上下文,为你生成行级/函数级代码、单元测试、代码注释等。沉浸式编码心流,秒级生成速度,让你更专注在技术设计,高质高效地完成编码工作。
❌
❌