标签归档:WordPress

WordPress Contact Form 7 的正确用法

Contact Form 7在实际使用过程中,有些人为了简化表单的设计和使用,会选择直接在多个地方使用同一个表单,并通过页面选择器来实现不同的样式(常见于基于 Elementor 构建的页面)。

但这样会造成长期的可维护性问题:

  1. 每个页面单独写样式选择器来控制样式,且在样式命名方面没有习惯的话, 会导致页面的样式混乱,修改成本较高。
  2. 不同的页面的样式采用了相同的类名,在进行样式修改时,交接性极差。

如果想要解决这个问题,有两个方式:

  1. 规范页面样式类规范:不同风格和样式的按钮采用不同的类名,如(.blueBtn.yellowBtn);
  2. 多处使用的表单,采用复制的方式,而不是使用同一个表单:Contact Form 7 提供了 Duplicate 功能,可以非常方便的复制一个表单,并根据表单的位置来命名。降低配置表单的成本。
d2b5ca33bd970f64a6301fa75ae2eb22 14
Duplicate 一个表单

在项目中使用 Dead Simple LESS CSS Watch Compiler 来自动生成 css 文件

最近在写一个 WordPress 主题来帮助我完成从 WordPress 到微信公众号的实现。在这个过程中,我需要借助于一些 CSS 的超集,来帮助我完成样式的编写。考虑到 SCSS 的 C++ 依赖问题,我选择了 Less 来完成。但如果直接使用 lessc 的话,主要面临的问题在于无法检测文件更新,这样对于需要实时查看效果的我来说,是比较麻烦的。所以我选择使用 Dead Simple LESS CSS Watch Compiler 来完成自动监控文件变化并刷新的功能。

教程

安装

执行 npm 命令来安装 Dead Simple LESS CSS Watch Compiler

yarn global add less less-watch-compiler 

安装完成后,你就可以执行命令来监听文件的变化。

配置

这里为了方便,我在 WordPress 插件目录中初始化了 npm, 因此,可以非常方便的借助于 npm script 来完成命令的配置。

通过配置了单独的 Build 命令,实现了执行 npm run build 就会自动监听 less 文件夹下的文件,并转换成对应的 css 文件,放置在 css 目录中。

{
  "private": true,
  "scripts": {
    "build": "less-watch-compiler ./less ./css"
  },
  "devDependencies": {
    "less": "^4.1.2",
    "less-watch-compiler": "^1.16.3"
  }
}
Code language: JSON / JSON with Comments (json)

其他

如果你需要对 less 运行有更多配置的诉求,还可以创建一个 less-watch-compiler.config.json 来配置具体的执行目录。不过我对于这部分没有要求,就直接整个目录来进行配置了。

{
    "watchFolder": "<input_folder>",   
    "outputFolder": "<output_folder>",
    "mainFile": "<main-file>",   
    "includeHidden": false,
    "sourceMap": false,
    "plugins": "plugin1,plugin2",
    "lessArgs": "option1=1,option2=2",
    "runOnce": false,
    "enableJs": true
}

总结

SCSS 因为 node-scss 的编译问题被各种吐槽,虽然换成了 dart-scss ,但历史的阴影还在。选择了 less 后,通过一些配置,可以让我自己的开发变得更加简单。何乐而不为?

OneInStack 下部署 WordPress Multisite 的 Nginx 转发规则

在 OneIn Stack 下如果需要配置一套 WordPress MU 的话,需要配置 Nginx 相应的转发规则。具体的规则如下:

 if (!-e $request_filename) {            
 	rewrite /wp-admin$ $scheme://$host$uri/ permanent;            
 	rewrite ^(/[^/]+)?(/wp-.*) $2 last;            
 	rewrite ^/[^/]+(/.*.php)$ $1 last;    
 }    
 location / {        
 	try_files $uri $uri/ /index.php?$args;    
 }
Code language: PHP (php)

将上述规则放置在 /usr/local/nginx/conf/rewrite/wordpressmu.conf ,并在创建 VHost 时选择对应的主机即可。

如何处理 Gutenberg 开发过程中的 Minified React error?

在开发 Gutenberg 插件时,经常会出现下面这样的提示:

Uncaught Error: Minified React error #231; visit https://reactjs.org/docs/error-decoder.html?invariant=231&args[]=onClick&args[]=object for the full message or use the non-minified dev environment for full errors and additional helpful warnings.
Code language: PHP (php)

上述提示表示当前的编辑器中出现了一个错误,但由于 React 的 Minified 设置,这些错误没有办法被打印出来。

在这种情况下, React 接管了默认的报错,让应用不至于崩溃,但另一方面,也让我们失去了处理这些问题的可能。因此,在本地的开发环境,最好还是将这个功能给关掉。

如何关闭默认的错误处理?

wp-config.php 文件中添加如下代码即可。

define('SCRIPT_DEBUG', true);
Code language: JavaScript (javascript)

在 Pug 中实现类似 get_sidebar() 全局方法

在开发 WordPress 主题时,我们会用到一些全局方法,来帮助我们快速加载特定的区域的代码。如果我们在设计和开发主题的时候,也可以实现类似的功能,则在开发对应的页面和应用的时候,我们就可以根据自己的需求来进行特定区域的代码的封装。这样我们在进行后续的开发的时候,就可以简化自己的代码,同时还可以按照 WordPress 的规范提前拆分代码,在实际进行项目开发的时候,提升效率。

原理

本次实现主要是基于 Pug 自带的 Mixins 机制来实现在主题中提供自定义的函数,从而实现我们想要的内容。在原理上,和 WordPress 的 get_sidebar 之类的方法不完全一样。所以,在体验上还没有做到像 WordPress 那么方便。

实现方式

1. 创建 Mixins

在项目的根目录下创建一个 mixins 目录,并在其中创建一个 includes.pug 文件和一个 getHeader.pug 文件。

includes.pug 文件中添加如下代码

include getHeader
Code language: PHP (php)

getHeader.pug 文件中添加如下代码

mixin getHeader
    p header

2. 引入 includes.pug

在你的 layouts.pug 文件中加入 includes.pug 的引入。需要注意的是,要加在 doctype 之前。

include ../mixins/includes
doctype html
html
  head
Code language: PHP (php)

3. 在需要的地方调用

当你完成上述的配置后,即可在需要的地方进行调用。

extends layout

block content
  +getHeader
  h1= title
  p hi to #{title}
Code language: PHP (php)

调用的效果如下:

d2b5ca33bd970f64a6301fa75ae2eb22 39

如果你希望实现更加强大的功能(比如参数),可以参考 Pug 官网的 Mixins 页面。

在开发 Gutenberg 插件时,如何处理防抖?

在开发 Gutenberg 插件时,如果你需要对编辑器的内容进行处理,则需要为其加入防抖措施,避免你的函数被频繁调用。

思路

由于编辑器需要高频处理,因此需要采用防抖策略,避免将多次输入视为不同的事件。这里可以使用 WordPress 提供的 useDebounce 来实现控制。需要注意的是,WordPress 自动的 Debounce 函数传入的参数应当采用 useCallback 来进行包裹。

参考代码

import {subscribe} from "@wordpress/data";
import {useDebounce} from  "@wordpress/compose"
import {useCallback} from "@wordpress/element";

const debounced = useDebounce(
        useCallback(() => {
            // do some thing
        }),500
    );
subscribe(debounced);
Code language: JavaScript (javascript)

针对 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

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

使用 Github Action 发布 WordPress 插件

WordPress 官网的插件系统采用的是 SVN 来进行管理,如果你希望将自己的插件发布至 WordPress 官网,就必须在本地安装 SVN,不太利于项目的管理。此外,WordPress 官网提供的是一个发布系统,而非版本控制系统(只是将 SVN 用作插件管理,并不是真打算让你每一个变更都提交),因此,你还是需要使用另外的版本控制系统(比如 Git)来管理你的代码。

为了简化发布,你可以采用 GitHub Action 来完成你的插件自动发布,这样你就可以使用 Git 来开发和管理你的插件,并让 Github Action 自动进行插件的发布。

具体操作

1. 配置 Action Secrets

因为你需要使用版本控制来进行发布,以及可能存在的协作开发的场景,处于安全的考虑,你应该将你的 SVN 的信息放置在 Action Secrets 当中。

d2b5ca33bd970f64a6301fa75ae2eb22 34

在仓库当中找到 Secrets – Actions ,新建两个 Secrets:SVN_USERNAMESVN_PASSWORD,配置上你的 SVN 账号信息,稍后将会使用你的这个账号信息来进行插件的发布

2. 创建一个 .distignore 文件

.distignore 文件可以帮助你实现忽略不需要发布到 WordPress 插件系统的文件,这样就让你的插件目录变得更加干净一些。在你的仓库根目录创建一个 .distignore 文件,并填写具体要忽略的文件,即可实现部分发布至 WordPress 插件目录。

以下是我的 Example

node_modules/
.github/
.git/
.distignore
.gitignore
package.json
package-lock.json
yarn.lock

3. 创建 Action 文件

在你的项目的 .github/workflows/ 中创建一个 publish.yml文件,并在其中添加如下代码即可。

name: Publish to WordPress Plugin Directory
on:
  push:
    tags:
    - "*"
jobs:
  tag:
    name: New tag
    runs-on: ubuntu-latest
    steps:
    - uses: actions/checkout@master
    - name: Build # 如果没有 NPM 相关构建工作,可以去除这一步。
      run: |
        npm install
        npm run build
    - name: WordPress Plugin Deploy
      uses: 10up/action-wordpress-plugin-deploy@stable
      env:
        SVN_PASSWORD: ${{ secrets.SVN_PASSWORD }}
        SVN_USERNAME: ${{ secrets.SVN_USERNAME }}
        SLUG: wpstoreapp-spellcheck
Code language: PHP (php)

4. 发布版本

接下来只需要执行如下操作,既可以发布版本

git add .
git commit -m 'feat: release new version'
git tag 1.0.0
git push && git push origin 1.0.0
Code language: JavaScript (javascript)

上述代码中的 1.0.0 即为具体的版本号,可以根据你的诉求进行修改。

总结

在完成了配置后,后续你的插件发布就变得十分简单了:修改本地的 readme.txt 中的版本号,加入 changelog,并修改插件文件头中的版本,即可提交一个 commit ,添加对应的版本的 tag,然后 Push 到 Github 上,由 Github 来进行插件的发布。

而如果你是以公司/团队的形式来管理插件,也可以用类似的方式,这样虽然每个人都不掌握 SVN 的账号密码,但却可以完成插件的发布,十分方便。

在 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 成本,从而实现更好的服务用户,是一个不错的选择。

如何“抄”一个 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