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:hi@wpstore.app">联系我们</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 ,相信可以帮到你~

happy birthday sign

写在 26 岁(下)

在农历生日的时候,我为自己写下了「写在 26 岁」,而今天,是我的阳历 26 岁。

在上一篇文章当中,写的很丧气,我自己都很焦虑。在这一篇文章,希望能给自己打打气。

26岁在人生漫长的八十多年里,并不能算得上特殊。不过,自己选择的路线确实会让这一年显得特殊一些。新的一年,祝你能够心想事成。在做的事情能够有一个好的结果。

如果可以的话,今年做一个大胆的选择,去试一试过去可能没试过的东西,体验一个不一样的生活。

别浪费了自己的 26 岁。

silhouette of person's hands forming heart

理性感性与生活

最近观察到一个现象,我认为一个非常「理性」,拥有着「理工科思维」的前辈,他的配偶却显得「贪小利」、「情绪不稳定」,这似乎是很奇怪的事情。难道「理工科思维」、「沉稳」的前辈不应该是找一个很稳重的配偶么?

但随时时间的流逝,我又有了新的看法。

作为一个普通人,当我们掌握了「理工科思维」和使用理性指导生活的方式和方法后,我们的生活可以非常容易走上正轨。我们在做各种选择会比依靠「情绪」来指导我们的生活的人会更加稳健、更加轻松、更加富有确定性。

但理工科思维未免过于范式固定,在这种情况下,我们的生活可能是一成不变的,朝着一个确定的目标上走着,在一个明确的轨道上行驶。

一个不那么稳定的配偶,可以为他的生活中添加一些变量和变化,让生活变得不那么枯燥。从这个角度来说,也挺好的。

这篇文章也是在试图用理性的逻辑来分析一个现实生活中的问题。但可能我说的全都是错的。

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)
woman holding camera standing near people

找到对的问题

最近在读《如何成为顶级记者》,总体来说,不同的记者有不同的切入视角,但如果要找一个能够综述所有人的关键点就是 —— 「离事情发生的地点足够近」。无论是通过自己的数据分析找到真正的事情发生点,还是和当事人建立更加友好、更加深入的联系,都是为了达成「离事情发生的地点足够近」这个诉求。

而当我总结到这里时,我突然在思考一个问题:我的问题真的是如何成为一个顶级记者么?

显然不是,我必然是会在编程和工程师的路上越走越远的,我的目的其实是:「如何录制好一档访谈类型的播客」,而这个问题如果细化的话,其实真正的问题应该是「如何提出一个正确的问题」

当我明确了正确的问题之后,那就知道正确的 Action 应该是什么 —— 「学习提出正确的问题」

回到这个事情本身,我其实在初期也进行了思考:从做一个好的访谈播客出发,推导出我需要具备优秀的访谈能力,而优秀的访谈能力往往出现在优秀的主持人和优秀的记者身上,因此我推导出了需要去学习顶级记者的思路。但是,问题的思考还不够深入,如果进一步推导和抽象,才能得到正确的答案 — 「提出一个正确的问题」。

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="from@example.com" />
Code language: HTML, XML (xml)

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