分类目录归档:技术

029a1f00793d00a4a88e458d5cdfebb0

针对 WordPress 开发配置 Sublime Text 4

最近在开发两个自己用的 WordPress 的插件,所以就把 Sublime Text 配置成了适合 WordPress 的开发的状态。以下是我的一些记录。

加入代理

因为 Package Control 在境内访问不是那么的流畅,所以,针对 Package Control 进行相应的 Proxy 配置,你只需要找到相应的配置界面,在其中加入 Proxy 配置即可。

d2b5ca33bd970f64a6301fa75ae2eb22 16
{
  "http_proxy": "http://127.0.0.1:7890",
  "https_proxy": "http://127.0.0.1:7890"
}
Code language: JSON / JSON with Comments (json)

代码格式化

Sublime 自带 Reindent

Sublime Text 4 自带缩进格式化的工具,因此,可以不需要安装第三方插件来实现。

在 Sublime Text 4 的 Line — Reindent 当中可以完成相应的操作。

d2b5ca33bd970f64a6301fa75ae2eb22 17

为了更好的使用这个功能,我自己添加了一些配置来简化这个功能的使用:

  1. 安装 Package​Resource​Viewer 用于修改系统配置。
  2. 使用 Package Resource Viewer: Open Resource 命令,打开 Default 包中的 Context.sublime-menu文件,
  3. 在其中添加一行代码 { "command": "reindent","caption":"格式化选中部分" },即可实现在上下文菜单中加入自动的格式化能力。效果见下图
d2b5ca33bd970f64a6301fa75ae2eb22 18

代码辅助编写

Tabnine

由于我使用的是 Sublime Text ,所以 VSCode 才有的 GitHub Copilot 自然是无法使用的,但不代表你不能使用机器来帮助你快速生成代码。这里我选择的是 Tabnine

由于我目前还没有为 Tabnine 付费,所以他只能基于我本地的代码进行学习。

文档快速生成

DoxyDoxygen

虽然是给自己用的插件,还是希望代码写的足够清晰。一个更加简单的插件,可以帮助我更好的去写批注。

turned-on monitor

在 WordPress 的插件页面添加更多的连接

WordPress 的插件页面提供了不少的 Hooks,可以帮助我们实现自定义的插件页面,让用户在启用插件后,第一时间可以看到我们为其提供的功能,从而降低用户使用的成本。

d2b5ca33bd970f64a6301fa75ae2eb22 33

以上图为例,你可以看到,我在左侧的功能区添加了「配置 Token」和「购买额度」;右侧的更多链接区提供了帮助手册和联系我们,帮助用户优化体验,更快的了解如何使用你的插件。

左侧功能区

首先,在左侧功能,WordPress 提供了两个 Filter来实现这个功能:

一个是 plugin_action_links,这个插件传入两个参数,一个是当前插件的链接构成的数组,另一个则是插件的文件路径,你可以根据传入的参数判断当前是使用哪个插件,并通过返回不同的数组,来实现不同的功能。

另外一个则是 plugin_action_links_wpstore-spellcheck/wpstore-spellcheck.php,是在上一个 filter 的基础之上,加入了插件的路径,从而让你可以无需进行判断,直接针对对应插件来完成链接的修改。

以上图效果为例,具体的代码如下

function wpstoreapp_plugin_action_link($links, $file)
{
	if($file == plugin_basename(dirname(__FILE__) . '/wpstore-spellcheck.php')){
		$links[] = '<a href="./options-writing.php">配置 Token</a>';
		$links[] = '<a href="https://api.wpstore.app/plugins/spell-check/pricing" target="_blank">购买额度</a>';
	}
	return $links;
}

add_filter('plugin_action_links', 'wpstoreapp_plugin_action_link', 10, 2);
Code language: PHP (php)

这里我选择的是第一种实现方式,主要的原因是我无法保证用户安装插件一定是采用的是 WordPress 插件目录的安装方式,因此,在这种情况下,第二种带了路径的 filter 的名字是有可能发生变化的。

右侧更多链接区

右侧更多链接区可以用来承载联系我们、帮助文档等入口,从而实现用户在使用时,可以快速找到相应的辅助资料,从而获得更好的体验。

从实现的逻辑上来看,和在左侧功能区添加链接的基本逻辑是一样的,需要判断当前插件是否是目标插件,如果是,则可以根据需要添加功能。

add_filter( 'plugin_row_meta', 'wpstoreapp_plugin_row_meta', 10, 2 );

function wpstoreapp_plugin_row_meta( $links, $file ) {
	if ( plugin_basename( __FILE__ ) == $file ) {
		$row_meta = array(
			'docs'    => '<a href="https://www.wpstore.app/?p=291">帮助手册</a>',
			'contact'    => '<a href="mailto:[email protected]">联系我们</a>'
		);

		return array_merge( $links, $row_meta );
	}
	return (array) $links;
}
Code language: PHP (php)

总结

WordPress 为我们提供了方便的 Hook,可以让我们可以自定义我们想要的功能,借助这些功能来降低你的用户的 Landing 成本,从而实现更好的服务用户,是一个不错的选择。

silver mercedes benz emblem on blue surface

如何“抄”一个 WordPress 插件

WordPress 作为 CMS 生态的第一产品,PHP 生态的护城河,可以说,只要 WordPress 不死,PHP 就还能继续活下去。而 WordPress 团队也在不断迭代项目。因此,有不少的开发者以 WordPress 开发为生。

而得益于 WordPress 基于 GPL 开发的,所以,理论上,如果你开发的插件是通过 WordPress 官方的目录分发的,你的插件是需要以 GPL 兼容的协议开源的,这也给了想要开发同款插件的开发者们提供了机会。

PHP in WordPress themes must be GPL, artwork and CSS may be but are not required.

Matt Mullenweg, https://wordpress.org/news/2009/07/themes-are-gpl-too/

不过,需要注意的是,只有 PHP 的插件源码才需要以 GPL 兼容协议开源,CSS 和图片文件不需要开源,而随着 Gutenberg 编辑器的不断推广,以后的插件可能不太好“抄”了。

在这篇文章,我们不再讨论 Gutenberg 功能的研究,只谈插件的 PHP 部分。

如何理解 WordPress 的插件开发?

《人人都能学会的 WordPress 课程》当中,我曾经介绍过 WordPress 的插件的运行机制。如果现在用一个更加简单的说法来探讨这个问题的话,WordPress 是通过提供do_actionapply_filter这两个方法,实现了功能的可修改性。而插件则需要 add_actionadd_filter 这个方法来影响 WordPress 的运行表现

75b49d4621ffc8bf01cedf88d0855a01

当你明白这个问题之后,你就会意识到,如果我们需要解析一个插件的运行机制,来开发自己的同类型插件之时,唯一要做的其实就是找到对应的 Action 和 Filter,修改 WordPress 的运行表现。

因此,你接下来要做的事情就变得简单很多,你需要做的,仅仅是在插件的代码中搜索所有的 add_actionadd_filter,并记录下对应的 action 和 filter 的名字,在 Code Reference 当中搜索对应的 action 的应用场景和用法即可。

Tips

  1. 按照 WordPress 的开发规范,插件的目录中一定有一个和其目录名相同的 PHP 文件,这个文件是 WordPress 插件的入口文件,你只需要从这个插件看起,就能找到你想要了解的实现方式。
  2. WordPress 插件的代码都可以在 WordPress Directory 中找到,你只需要在 Development 目录中,就可以找到对应的插件的源码。
d2b5ca33bd970f64a6301fa75ae2eb22 32
silver mercedes benz emblem on blue surface

如何从 WordPress 插件目录下架一个插件

我在 WordPress 官方上架了不少的插件,但不少的插件如今我已经不再维护了。

再加上现在我开始重新调整 WPStore,因此,决定下架其中一些不再维护的插件,减少 WordPress 官方插件系统中的无用插件。

操作步骤

1. 登陆你的 WordPress.org 的账号,并找到你要下架的插件

d2b5ca33bd970f64a6301fa75ae2eb22 28

比如,我这里希望下架早年为 Payjs 写的付费阅读插件。

2. 点击 右下角的 Advanced View

d2b5ca33bd970f64a6301fa75ae2eb22 29

在 Details 页面找到 Advanced View 的连接,并点击进入 Advanced View 页面。

3. 在 THE DANGER ZONE 中关闭插件

d2b5ca33bd970f64a6301fa75ae2eb22 30

进入 Advanced View 页面之后,向下拖动,在底部的 THE DANGER ZONE 中可以找到 「Close This Plugin」,点击按钮,并在弹出的窗口中,点击确认即可。

4. 删除完成

d2b5ca33bd970f64a6301fa75ae2eb22 31

当你看到如上界面时,就说明你这个插件已经完全关闭了。

总结

其实 WordPress 并没有要求你关闭掉每一个插件,不过从插件的维护角度来看,关闭一个不再维护的插件可以减少你后续的服务的成本,也是一个不错的选择。

silver mercedes benz emblem on blue surface

WordPress 官方的 Code Reference应该如何使用?

如果你要开发 WordPress ,必然会用到 WordPress 官方的文档。而在官方文档当中,除了各种 Handbook ,最重要便是 Code Reference

在使用 Code Reference 的时候,也是存在一些技巧的。

搜索你需要的函数、Hooks、Filter、Class

访问 Code Reference 主页,可以看到有一个搜索框,在这里你可以输入你要搜索的关键词,并在下拉框中筛选出你要用的具体的函数/Hooks/Filter/Class

d2b5ca33bd970f64a6301fa75ae2eb22 20

当然,如果你在开发过程中,明确了你要查询的某个特定的函数,也有一个简单的方式来查询,只需要将下方的链接中的 FUNCTIONNAME 替换为你要查询的函数名,就可以直接跳转到对应的函数的详细界面,查看对应的函数的功能。

https://developer.wordpress.org/reference/functions/FUNCTIONNAME/
Code language: JavaScript (javascript)

如果你查询的是 Hooks、Filter 也有类似的方法,WordPress 的单个函数/Hooks/Filter 的URL非常的明确,因此,你可以在写代码的时候,随时把你需要查询的函数直接复制出来,替换浏览器地址栏中的方法名即可。

理解 Code Reference 的内容

download_url 为例,在 Code Reference 当中,大体上会分为以下几个区域

Description
Parameters
Return
Source
Related
 - Uses
 - Used By
Changelog
User Contributed Notes
 - Feedback
Code language: PHP (php)

Description

d2b5ca33bd970f64a6301fa75ae2eb22 21

这里介绍了这个函数的基本介绍,一些时候,也会在这个区域加入一些使用的 Tips。

不过这个描述并非每一个函数都会有。

Parameters

d2b5ca33bd970f64a6301fa75ae2eb22 22

参数区域说明了这个函数的入参有哪些,你可以对着入参的介绍调用函数,从而避免传入错误的参数

Return

d2b5ca33bd970f64a6301fa75ae2eb22 23

返回值定义了具体的返回值,你可以根据返回值来判断具体的结果。不仅如此,点击里面的链接,可以跳转到对应的类,查看对应返回结果的类型。

Source

d2b5ca33bd970f64a6301fa75ae2eb22 24

Source 部分则给你了函数的具体的代码,对于一些你在开发过程中百思不得其解的函数,读一下这个函数的源码可能会让你茅塞顿开。

对于比较长的函数,点击 Expand 就可以展开看。如果你希望在本地看,左上角也告诉你了这个函数在具体哪个文件可以查看。你可以直接按图索骥,找到本地的对应函数来查看。

Related

d2b5ca33bd970f64a6301fa75ae2eb22 25

Related 当中分为两个区块,分别是 Uses 和 Used By ,分别介绍当前这个函数是基于哪些函数实现的(Uses)和其他哪些函数使用了当前这个函数(Used By)

有了 Uses 和 Used By,你就可以自己封装一个类似的函数,也可以看看其他的函数是如何调用当前这个函数,心中更有数。

Changelog

d2b5ca33bd970f64a6301fa75ae2eb22 26

Changelog 当中记录了这个函数的具体的变更历史,你就可以非常方便的去了解到一个函数的发展历史,可能某个功能你过去用的好好的,最近不能用了,就是因为函数发生了更新。

User Contributed Notes

d2b5ca33bd970f64a6301fa75ae2eb22 27

在 User Contributed Notes 当中,记录了别人对于这个函数使用的反馈,你可以看到其他开发者是如何使用这个函数的。当你在使用这个函数/Hook出现问题时,就可以参考一下其他人贡献的笔记,可能会更好的帮助你来理解这些 Notes。

总结

用好 WordPress 自带的 Code Reference 可以帮助大家更好的开发 WordPress 的各种功能,花点时间了解一下 Code Reference ,相信可以帮到你~

black flat screen computer monitor

Livewire.js 404 的问题的处理思路和解决方式

在使用 Laravel Livewire 的时候一个常见问题是生成的 Livewire.js 文件会报错。

一般来说,解决思路有两种

  1. 看看你生成的 URL 是否是正确的。
  2. 看看你的 Nginx 配置是否是正确的。

生成的 URL 是否正常

在 Livewire 的配置当中,存在一个 asset_url 选项,这个选项会用于在页面中嵌入 Livewire.js 文件的功能,因此。如果你在使用过程中,修改了这个值,导致生成的地址是错误的,就有可能报错。

Nginx 配置是否正确

这个问题往往会导致报错的页面是 Nginx 的 404 页面。

在你的 Nginx 配置当中,如果你针对 JS 文件或 CSS 文件有单独处理,你需要将对应的处理注释掉,确保所有请求转发给 Laravel 进行处理。

 # location ~ .*\.(js|css)?$ {
 #   expires 7d;
 #   access_log off;
 # }
Code language: PHP (php)
black flat screen computer monitor

Laravel 9 单元测试报错 An email must have a "From" or a "Sender" header

在 Laravel 9 当中,引入了新的 Mailer 组件,随之而来的是一些过去没有的 Bug。

如果你在开发过程中出现了 An email must have a "From" or a "Sender" header 的报错,需要在 PHPUnit 当中配置 MAIL_FROM_ADDRESS 属性,用于通过测试。

<env name="MAIL_FROM_ADDRESS" value="[email protected]" />
Code language: HTML, XML (xml)

来源:https://laracasts.com/discuss/channels/laravel/for-reference-an-email-must-have-a-from-or-a-sender-header

silver mercedes benz emblem on blue surface

Gutenberg 编辑器带来的模式变更

自 WordPress 5.0 开始, Gutenberg 编辑器(后文称为古腾堡编辑器)开始存在于 WordPress 当中,为普通用户所用。而得益于古腾堡编辑器带来的卓越的使用体验(用户不需要再记录晦涩难懂的短代码、无须忍受 TinyMCE 的界面),用户使用 WordPress 的方式也开始变得多种多样。

如果你还没有用过古腾堡编辑器,那你可以访问 WordPress 官方提供的在线预览工具来试用:https://wordpress.org/gutenberg/

体验的变革

古腾堡的出现,让作者可以更加接近于我一直描述的 WordPress 所能够提供的最大的价值 —— 让写作变得更加简单,易实现。不仅如此,古腾堡带来的新的编辑体验,让除了工程师、Geek 以外的人也可以很轻松的实现一个更好看、更易读、更加丰富的界面。

而从 WordPress 开发团队的态度来看,也是更加推荐作者们更多的使用古腾堡编辑器:从Twenty Nineteen 开始,古腾堡的支持就成为了默认,并不断的通过官方主题的用法,让作者们看到 WordPress 原来还可以是这样。今年的 Twenty Twenty Two 更是从写作者变为了艺术家 —— 你可以十分简单的建造一个线上的画廊。

开发模式的变更

过去,WordPress 开发整体来说,可以分为两条线:一条是主题开发,你需要与 PHP、HTML、CSS、Javascript 共同战斗;另一条线则是插件开发,你需要与PHP 为伍。

搞插件开发的,你对于前端开发不甚了解也无所谓。WordPress 提供了大量的 helper function 。比如,我在「开发一个短代码插件」中,不使用一行前端代码就实现了 TinyMCE 的功能新增。

而在新的古腾堡编辑器生态下,开发者如果希望对于古腾堡进行拓展,一方面依然可以使用之前的方式,接入各种短代码来实现各种不同的用户体验,另一方面,则可以借助与前端技术栈来实现一个更加丰富的用户体验。

你可以使用 JQuery 和 WordPress 为你绑定的全局对象来修改古腾堡编辑器实现你的目标,更是可以借助前端的开发体系,诸如 Webpack、React 来开发一个强交互,体验佳的用户体验。

WordPress 的开发不再是 PHP 工程师自己的事情,它将更多的人卷入 WordPress 的开发过程中。而对于 WordPress 开发工程师来说,则有了更高的要求,来完成插件的开发、主题的开发。

总结

自古腾堡的推出,这样的趋势就开始渐显。但直到我真正开始开发一款古腾堡插件,我才真正意识到 —— WordPress 在内容创作领域的价值,无可替代。纵然他有众多的历史包袱,但对于每一个创作者来说,他都是最好的选择。

b29692084bbb

WordPress 如何获得最顶级的自定义分类

WordPress 支持设定多级分类,如果你需要在页面中展示最顶级的分类,则需要获取到最顶级的分类,具体实现的方式如下:

1. 获取当前文件类型的自定义分类

使用如下代码获取到自定义分类

$tax = wp_get_post_terms($post->ID,array('part'))
Code language: PHP (php)

获得的结果如下

Array
(
    [0] => WP_Term Object
        (
            [term_id] => 7
            [name] => 目录1
            [slug] => category1
            [term_group] => 0
            [term_taxonomy_id] => 7
            [taxonomy] => part
            [description] => 
            [parent] => 6
            [count] => 2
            [filter] => raw
        )

)
Code language: PHP (php)

这里的 term_id 则代表你设定的自定义分类的 ID

2.获取分类树

因为分类是多级的,我们需要找到祖先节点,因此需要用到函数 get_ancestors ,执行如下代码

$tree = get_ancestors($tax[0]->term_id)
Code language: PHP (php)

会获得如下结果

Array
(
    [0] => 6
    [1] => 8
)
Code language: PHP (php)

这个返回结果则是从你当前分类向上查找,查找到最顶级的分类的结果。需要注意的是,这个数组的最后一个元素才是你最终最顶级的分类。

3. 提取最后一个元素的 ID

当你知道了最后一个才是最顶级的分类,只需要使用 end() 函数来获取最后一个。

end($tree)
Code language: PHP (php)

这样,就能拿到最终目录的 ID,接下来要做的就是在你的界面上展示这些数据。

b29692084bbb

为 WordPress 加入 Server Timing 判断不同行为性能差异

自打上次为我的博客加入了 Redis 缓存后,博客站点访问速度明显变快,几乎可以达到秒开的效果。剩下的需要在网络层面进行进一步的优化。

不过,我还在思考如何才能更好的优化我的 WordPress 性能。很显然,我需要一个指标来帮助我做决策。这让我想到了一个东西 —— HTTP 标准中的 Server-Timing Header。

Server-Timing 标头传达在一个给定请求-响应周期中的一个或多个参数和描述。它用于在用户浏览器的开发工具或 PerformanceServerTiming (en-US) 接口中显示任何后端服务器定时参数(例如,数据库读/写、CPU 时间、文件系统访问等)。

来自 https://developer.mozilla.org/zh-CN/docs/Web/HTTP/Headers/Server-Timing

Server Timing 可以帮助我们记录服务端到底在哪些步骤中消耗了哪些时间,可以方便我进行性能的查询。

使用 WP Server Timing 添加 Server-Timing 头

我在 WordPress 的 Plugin Directory 目录进行了搜索,并没有找到支持这个功能的插件,不过我在 Github 上找到了这个插件 —— https://github.com/ocReaper/wp-server-timing

有了这个插件,我就可以无需自己手动添加相应的能力。

使用插件也非常简单,在页面上下载压缩包,并在 WordPress 后台安装并启用这个插件。

d2b5ca33bd970f64a6301fa75ae2eb22 14
安装后的效果

安装完成后,你接下来要做的就是重新在浏览器中打开你的网站,并按下 F12 打开开发者工具,选择文档 Tab(英文是 Document),刷新当前页面,就可以看到列表中出现了一个你博客地址对应的文档,点击文档,并在弹出的窗口中切换到「时间」Tab,就可以在下方看到服务器计时了。

d2b5ca33bd970f64a6301fa75ae2eb22 15
示意图

按照上图的结果,可以看到,我的 WordPress 耗时最长的是 Template Processing ,我需要针对这个属性进行定向优化。

辅助理解资料

以下是 WordPress 的加载顺序图,你可以对比着参考

dtckd
WordPres 的加载顺序图,来源:https://www.rarst.net/wordpress/wordpress-core-load/