wordpress插件开发

tech2022-12-01  102

wordpress插件开发

In the first part of my series, an introduction to the WordPress Plugin Boilerplate, we looked at how the code is organised within the Boilerplate. To continue with this series, we’ll apply what we’ve learnt previously to build a real working plugin. We are going to take a look at how quickly we can get our plugin up and running using the Boilerplate code, with as little work as possible.

在本系列的第一部分中,对WordPress插件Boilerplate进行了介绍 ,我们研究了Boilerplate中代码的组织方式。 为了继续进行本系列文章,我们将运用我们先前学到的知识来构建一个真正有效的插件。 我们将研究如何使用Boilerplate代码以最快的速度启动并运行插件,而只需花费最少的工作。

This article will focus on creating and activating the plugin, as well as developing the admin facing functionality of the plugin. In order to follow this tutorial, you’ll need a basic understanding of PHP and WordPress, as well as having a working knowledge of the WordPress Plugin API.

本文将重点介绍如何创建和激活插件,以及开发面向管理员的功能。 为了遵循本教程,您需要对PHP和WordPress有基本的了解,并且对WordPress Plugin API有一定的了解。

关于插件 (About the Plugin)

We’re going to develop a simple plugin that will display the number of days since a specific post was last updated. We’re also going to offer a couple of simple customizations to the plugin, allowing the user to choose a specific number of days after which a post will be considered outdated, as well as the position of the notice in the post content.

我们将开发一个简单的插件,以显示自上次更新特定帖子以来的天数。 我们还将为插件提供一些简单的自定义功能,允许用户选择特定的天数(在此天之后,帖子将被视为过时)以及通知在帖子内容中的位置。

准备样板 (Preparing the Boilerplate)

As mentioned in the first article, we can either download a fresh copy of the Boilerplate and do the search and replace ourselves, or we can use the unofficial WordPress Plugin Boilerplate Generator to speed up the process. Let’s use the generator for our plugin.

如第一篇文章中所述,我们可以下载Boilerplate的新副本并进行搜索并自行替换,也可以使用非官方的WordPress插件Boilerplate Generator来加快此过程。 让我们为插件使用生成器。

Head over to the WordPress Plugin Boilerplate Generator website and fill in the form with the appropriate values. Let’s just call our plugin “Outdated Notice”. Here’s a sample form with the fields filled in.

前往WordPress插件样板生成器网站,并在表格中填写适当的值。 让我们将我们的插件称为“过期通知”。 这是一个示例表格,其中填写了字段。

I’m using an imaginary URL for the plugin URL that links to an official repository. Don’t worry too much about this stuff as we can always modify it later on in the plugin header.

我使用虚构的URL作为链接到官方存储库的插件URL。 不用太担心这些东西,因为我们以后总是可以在插件头中对其进行修改。

Click the “Build” button and you should get a nice, customized copy of the WordPress Plugin Boilerplate.

单击“生成”按钮,您将获得一个漂亮的自定义WordPress插件样板。

安装和激活插件 (Installing and Activating the Plugin)

The generated zip archive will contain the two expected directories, assets and trunk. We are not going to use the symlink route in installing our plugin, so extract the trunk folder in the archive and copy it into the wp-content/plugins directory.

生成的zip归档文件将包含两个预期目录, assets和trunk 。 在安装插件时,我们不会使用symlink路由,因此请在归档文件中解压缩trunk文件夹并将其复制到wp-content/plugins目录中。

We still need to rename it appropriately to avoid a naming conflict with other plugins, so we will rename the trunk directory to outdated-notice.

我们仍然需要适当地重命名它,以避免与其他插件的命名冲突,因此我们将trunk目录重命名为outdated-notice 。

If you now go to the “Installed Plugins” section in wp-admin, sure enough, you’ll see your plugin is on the list of plugins installed but not yet activated. The Plugin Boilerplate generator does not change anything with regards to plugin description so if we want to change it, we can simply edit the description in the main plugin file, in our case, outdated-notice.php.

如果现在确定进入wp-admin的“已安装插件”部分,那么您肯定会看到您的插件在已安装但尚未激活的插件列表中。 Plugin Boilerplate生成器不会更改插件描述,因此,如果要更改它,我们可以在主插件文件中简单地编辑描述,在本例中为outdated-notice.php 。

Click on “Activate” to activate your shiny new plugin. Nothing will change on your WordPress site, so don’t worry that there’s nothing to see yet after activating the plugin.

单击“激活”以激活您的闪亮新插件。 您的WordPress网站上什么都不会改变,所以不用担心在激活插件后什么也看不到。

添加选项页 (Adding an Options Page)

Plugin developers usually provide a means for the user to customize the settings of the plugin. This can be achieved by utilizing the Settings API provided by WordPress. Let’s see how can we integrate our own settings into the plugin.

插件开发人员通常为用户提供一种自定义插件设置的方法。 这可以通过利用WordPress提供的Settings API来实现。 让我们看看如何将自己的设置集成到插件中。

In short, we are going to allow the user to choose where the notice will appear, either before the post content or after the post content. As far as the number of days threshold goes, the user can set the number of days before a post is to be considered outdated. Using that piece of information, we are going to dynamically change the class of the notice so that we can style it differently from a post that is still considered fresh.

简而言之,我们将允许用户选择在帖子内容之前或之后的通知显示的位置。 就天数阈值而言,用户可以设置帖子被视为过时之前的天数。 使用该信息,我们将动态更改通知的类别,以便我们可以将其样式与仍被认为是最新的帖子不同。

Let’s get started by adding an options page for our plugin.

让我们开始为插件添加一个选项页面。

Open up class-oudated-notice-admin.php inside your admin folder. We need to modify this class to allow us to register a settings page for our plugin. Add this public method towards the end of the class.

在您的admin文件夹中打开class-oudated-notice-admin.php 。 我们需要修改此类,以允许我们为插件注册设置页面。 在类末尾添加此公共方法。

/** * Add an options page under the Settings submenu * * @since 1.0.0 */ public function add_options_page() { $this->plugin_screen_hook_suffix = add_options_page( __( 'Outdated Notice Settings', 'outdated-notice' ), __( 'Outdated Notice', 'outdated-notice' ), 'manage_options', $this->plugin_name, array( $this, 'display_options_page' ) ); }

One thing to note is since we are using classes to define our hooks, we need to pass an array in the form of array( <class instance>, <class method ) instead of directly specifying which function is to be called. The only rule that needs to be observed is that the method needs to be public.

需要注意的一件事是,因为我们使用类来定义钩子,所以我们需要以array( <class instance>, <class method )的形式传递数组,而不是直接指定要调用的函数。 需要遵守的唯一规则是该方法需要公开。

We are not quite done yet! As we can see, the add_options_page requires a valid callback function, which we have not yet defined in our Outdated_Notice_Admin class. Let’s add it in. This should be simple enough since we are going to use the provided outdated-notice-admin-display.php included in our admin/partials folder. So, all we have to do for our callback function is to include that file.

我们还没有完成! 如我们所见, add_options_page需要一个有效的回调函数,我们尚未在Outdated_Notice_Admin类中定义该函数。 让我们添加它。这应该足够简单,因为我们将使用admin/partials文件夹中包含的提供的outdated-notice-admin-display.php 。 因此,对于回调函数,我们要做的就是包含该文件。

/** * Render the options page for plugin * * @since 1.0.0 */ public function display_options_page() { include_once 'partials/outdated-notice-admin-display.php'; }

That should do it. The last thing we need to do now is to load it correctly using the provided loader class in the Boilerplate. Open up your class-outdated-notice.php in the includes folder and add the additional hook we defined earlier inside the define_admin_hooks method. The proper action hook to include on our options page is admin_menu so let’s add it in.

那应该做。 我们现在要做的最后一件事是使用Boilerplate中提供的加载程序类正确加载它。 在includes文件夹中打开您的class-outdated-notice.php ,并将我们之前定义的其他挂钩添加到define_admin_hooks方法中。 要包含在我们的选项页面上的正确操作钩子是admin_menu因此让我们添加它。

$this->loader->add_action( 'admin_menu', $plugin_admin, 'add_options_page' );

You should now see an additional “Outdated Notice” submenu under Settings. You can access the empty options page by going to the URL http://<our-site-url>/wp-admin/options-general.php?page=outdated-notice.

现在,您应该在“设置”下看到一个附加的“过期通知”子菜单。 您可以通过访问URL http://<our-site-url>/wp-admin/options-general.php?page=outdated-notice来访问空白的选项页面。

It’s a blank page for now, so let’s start populating the partial file with proper markup.

现在是空白页,所以让我们开始用适当的标记填充部分文件。

注册,保存和获取设置值 (Registering, Saving and Retrieving the Settings Value)

The Settings API page on the WordPress Codex provides a good explanation on how to register our own settings, including displaying them on the options page.

WordPress Codex上的Settings API页面为如何注册我们自己的设置提供了很好的解释,包括在选项页面上显示它们。

Here’s a breakdown of what we are going to do in this section:

以下是本节中我们要做的工作的分解:

Register the hook with the Boilerplate loader

将钩子对准样板装载机 Register a settings section

注册设置部分 Register two settings fields (threshold days and text position)

注册两个设置字段(阈值天和文本位置) Register the two settings

注册两个设置 Populate the options page

填充选项页面 Saving and repopulating the fields for display.

保存并重新填充要显示的字段。

将挂钩注册到样板装载机 (Register the Hook to the Boilerplate Loader)

Let’s go through all the steps one by one.

让我们一步一步地完成所有步骤。

To register a settings section, we will need to use the register_setting function. The proper hook to initialize that function is admin_init. So, first we are going to add another hook into the Boilerplate loader to register our settings inside the define_admin_hooks method of our main Boilerplate class, Outdated_Notice class.

要注册设置部分,我们将需要使用register_setting函数。 初始化该函数的合适钩子是admin_init 。 因此,首先,我们将向Boilerplate加载器中添加另一个钩子,以在我们的Boilerplate主类Outdated_Notice类的define_admin_hooks方法中注册设置。

$this->loader->add_action( 'admin_init', $plugin_admin, 'register_setting' );

To make things simpler and provide a basic sort of namespacing to our options names, we are going to add another private variable on top of this class. Put this snippet on top of the Outdated_Notice_Admin class.

为了使事情变得简单,并为我们的选项名称提供基本的命名空间,我们将在该类的顶部添加另一个私有变量。 将此片段放在Outdated_Notice_Admin类的顶部。

/** * The options name to be used in this plugin * * @since 1.0.0 * @access private * @var string $option_name Option name of this plugin */ private $option_name = 'outdated_notice';

From now on, we are going to prepend this value to anything that is related to our options.

从现在开始,我们将把这个值放在任何与我们的选择有关的值之前。

Next thing is to actually register the settings section, settings field and the individual settings. Open up the Outdated_Notice_Admin class again and add the public method register_setting into that.

下一步是实际注册设置部分,设置字段和各个设置。 再次打开Outdated_Notice_Admin类,然后在其中添加公共方法register_setting 。

注册设置部分 (Register a Settings Section)

Inside the public register_setting method, we are going to register a settings section. I won’t delve too much into the various functions and APIs to do this since the Codex has already provided enough information to get started. As our plugin settings are relatively simple, we are going to register only one section.

在公共的register_setting方法中,我们将注册一个设置部分。 我不会过多地研究各种功能和API来完成此操作,因为食典已经提供了足够的信息来入门。 由于我们的插件设置相对简单,因此我们将仅注册一个部分。

This snippet will allow us to register a “General” section for our options page using the add_settings_section function.

该代码段使我们可以使用add_settings_section函数为选项页面注册“常规”部分。

// Add a General section add_settings_section( $this->option_name . '_general', __( 'General', 'outdated-notice' ), array( $this, $this->option_name . '_general_cb' ), $this->plugin_name );

Notice that we are pre-pending our section name with the variable $option_name to prevent conflicts with other plugins. The callback can be used to provide additional information about our section, which is exactly what we want.

注意,我们在节名前添加了$ option_name变量,以防止与其他插件发生冲突。 回调可用于提供有关本节的其他信息,而这正是我们想要的。

We are going to add another public method, outdated_notice_general_cb that will echo basic information about this section.

我们将添加另一个公共方法outdated_notice_general_cb ,该方法将回显有关此部分的基本信息。

/** * Render the text for the general section * * @since 1.0.0 */ public function outdated_notice_general_cb() { echo '<p>' . __( 'Please change the settings accordingly.', 'outdated-notice' ) . '</p>'; }

注册两个设置字段(阈值天数和文本位置) (Register Two Settings Fields (Threshold Days and Text Position))

The next part of the Settings API that we need to use is to register the actual field to be rendered on the options page. This can be achieved using the add_settings_field function.

我们需要使用的Settings API的下一部分是在选项页面上注册要呈现的实际字段。 这可以使用add_settings_field函数来实现。

We will use radio buttons for the text position configuration. This is done by adding this code to the register_setting function that we have.

我们将使用单选按钮进行文本位置配置。 这是通过将此代码添加到我们拥有的register_setting函数中来完成的。

add_settings_field( $this->option_name . '_position', __( 'Text position', 'outdated-notice' ), array( $this, $this->option_name . '_position_cb' ), $this->plugin_name, $this->option_name . '_general', array( 'label_for' => $this->option_name . '_position' ) );

We need to make sure that the fifth argument of add_settings_field will point to the correct settings section that we registered before or we might not see the field on our options page.

我们需要确保add_settings_field的第五个参数将指向我们之前注册的正确设置部分,否则我们可能不会在选项页面上看到该字段。

This is not done just yet. We need to provide the callback function that will render the actual markup for our radio buttons. In our outdated_notice_position_cb function, we need to include this block of code:

这还没有完成。 我们需要提供回调函数,该函数将呈现单选按钮的实际标记。 在我们的outdated_notice_position_cb函数中,我们需要包括以下代码块:

** * Render the radio input field for position option * * @since 1.0.0 */ public function outdated_notice_position_cb() { ?> <fieldset> <label> <input type="radio" name="<?php echo $this->option_name . '_position' ?>" id="<?php echo $this->option_name . '_position' ?>" value="before"> <?php _e( 'Before the content', 'outdated-notice' ); ?> </label> <br> <label> <input type="radio" name="<?php echo $this->option_name . '_position' ?>" value="after"> <?php _e( 'After the content', 'outdated-notice' ); ?> </label> </fieldset> <?php }

The second option for day threshold can be configured using a normal text input. So we are going to register another settings field:

可以使用常规文本输入来配置日阈值的第二个选项。 因此,我们将注册另一个设置字段:

add_settings_field( $this->option_name . '_day', __( 'Post is outdated after', 'outdated-notice' ), array( $this, $this->option_name . '_day_cb' ), $this->plugin_name, $this->option_name . '_general', array( 'label_for' => $this->option_name . '_day' ) );

Again, we also need to provide a callback function that will render our text field.

同样,我们还需要提供一个回调函数来呈现我们的文本字段。

/** * Render the treshold day input for this plugin * * @since 1.0.0 */ public function outdated_notice_day_cb() { echo '<input type="text" name="' . $this->option_name . '_day' . '" id="' . $this->option_name . '_day' . '"> '. __( 'days', 'outdated-notice' ); }

注册设置 (Register the Settings)

Lastly, we need to register the options name that we are going to use so that it can be recognized within WordPress. Since we are using two different option names, outdated_notice_position and outdated_notice_day, we are going to register them both using the register_setting function.

最后,我们需要注册将要使用的选项名称,以便可以在WordPress中识别它。 由于我们使用两个不同的选项名称, outdated_notice_position和outdated_notice_day ,我们将使用register_setting函数注册它们。

register_setting( $this->plugin_name, $this->option_name . '_position', array( $this, $this->option_name . '_sanitize_position' ) ); register_setting( $this->plugin_name, $this->option_name . '_day', 'intval' );

Notice that third parameter for the register_setting function is a sanitization callback. Although it is optional, it’s always useful to make sure that input values are sanitized before being saved to the database.

请注意, register_setting函数的第三个参数是清理回调。 尽管它是可选的,但在将输入值保存到数据库之前确保将其清除是非常有用的。

For day sanitization, we will use the built-in PHP function, intval as it is enough in our case. As for the text notice position, we are going to define our own sanitization callback function, which will allow only certain values to be saved into the database. This is particularly useful when dealing with options that are limited to specific values, such as in this case where we only accept two values, which are before and after, so our sanitization callback will need to make sure that if the value is not one of these, it won’t get saved into the database.

为了进行日间消毒,我们将使用内置PHP函数intval因为在我们的例子中这已经足够了。 至于文本通知的位置,我们将定义我们自己的清理回调函数,该函数仅允许将某些值保存到数据库中。 这在处理限于特定值的选项时特别有用,例如在这种情况下,我们仅接受两个值,这两个值分别before和after before ,因此我们的清理回调方法必须确保该值不是以下之一这些,它将不会保存到数据库中。

Here’s a simple sanitization callback function to achieve that:

这是一个简单的清理回调函数来实现:

/** * Sanitize the text position value before being saved to database * * @param string $position $_POST value * @since 1.0.0 * @return string Sanitized value */ public function outdated_notice_sanitize_position( $position ) { if ( in_array( $position, array( 'before', 'after' ), true ) ) { return $position; } }

填充选项页面 (Populate the Options Page)

After we are done with registering all the related settings, now we need to make sure our options page renders correctly. Since we are using the WordPress way to register our fields and settings, this task is particularly straightforward.

完成所有相关设置的注册后,现在我们需要确保选项页面正确呈现。 由于我们使用WordPress方式注册我们的字段和设置,因此此任务特别简单。

Open up the outdated-notice-admin-display.php inside the admin/partials folder. Here’s how we can render the options page based on the settings that we have registered before.

打开admin/partials文件夹内的outdated-notice-admin-display.php文件。 这是我们根据先前注册的设置来呈现选项页面的方法。

<div class="wrap"> <h2><?php echo esc_html( get_admin_page_title() ); ?></h2> <form action="options.php" method="post"> <?php settings_fields( $this->plugin_name ); do_settings_sections( $this->plugin_name ); submit_button(); ?> </form> </div>

With a simple combination of do_settings_sections and settings_fields functions, your options page is done in no time at all.

通过do_settings_sections和settings_fields函数的简单组合,您的选项页面将立即完成。

Let’s take a break and refresh the options page.

让我们休息一下并刷新选项页面。

保存并重新填充字段 (Saving and Repopulate the Fields)

Try filling in some values and save the form. You should get the notice “Settings saved.” but nothings happened. Let try doing a var_dump to both our options. Place this somewhere in the related function.

尝试填写一些值并保存表格。 您应该会收到“设置保存”通知。 但是什么也没发生。 让我们尝试对两个选项都执行var_dump 。 将此放置在相关函数中的某个位置。

var_dump(get_option( $this->option_name . '_position' )); var_dump(get_option( $this->option_name . '_day' ));

We should get some values back from the database, as per the example below:

按照下面的示例,我们应该从数据库中获取一些值:

string(5) "after" string(2) "90"

That means our form is working just fine, so the only thing left that needs to be done is to display the current value in the text field, and make sure the correct radio button is checked.

这意味着我们的表单工作正常,因此剩下要做的唯一一件事就是在文本字段中显示当前值,并确保选中了正确的单选按钮。

Let’s tackle the radio buttons first. As a shortcut, we are just going to use the checked function provided by WordPress to mark the value selected previously. Our outdated_notice_position_cb will need some modification.

让我们首先解决单选按钮。 作为快捷方式,我们将使用WordPress提供的checked功能来标记以前选择的值。 我们的outdated_notice_position_cb将需要进行一些修改。

Here’s an updated snippet for the callback.

这是回调的更新代码段。

/** * Render the radio input field for position option * * @since 1.0.0 */ public function outdated_notice_position_cb() { $position = get_option( $this->option_name . '_position' ); ?> <fieldset> <label> <input type="radio" name="<?php echo $this->option_name . '_position' ?>" id="<?php echo $this->option_name . '_position' ?>" value="before" <?php checked( $position, 'before' ); ?>> <?php _e( 'Before the content', 'outdated-notice' ); ?> </label> <br> <label> <input type="radio" name="<?php echo $this->option_name . '_position' ?>" value="after" <?php checked( $position, 'after' ); ?>> <?php _e( 'After the content', 'outdated-notice' ); ?> </label> </fieldset> <?php } [php] <p>Notice that we are retrieving the value back from the database and assigning it to the <code>$position</code> variable before using it in the <code>checked</code> function for the radio buttons.</p> <p>Next we are going to modify the <code>outdated_notice_day_cb</code> function.</p> [php] /** * Render the treshold day input for this plugin * * @since 1.0.0 */ public function outdated_notice_day_cb() { $day = get_option( $this->option_name . '_day' ); echo '<input type="text" name="' . $this->option_name . '_day' . '" id="' . $this->option_name . '_day' . '" value="' . $day . '"> ' . __( 'days', 'outdated-notice' ); }

Now, whenever we change the value of either fields, it will be reflected correctly in the options page.

现在,无论何时我们更改两个字段的值,它都会正确反映在选项页面中。

进一步改进 (Further Improvements)

This is by no means complete. We can always improve the admin facing functionality of this plugin. Some of the things that I can think of are:

这绝不是完整的。 我们总是可以改善此插件的管理功能。 我能想到的一些事情是:

Code cleanup – WordPress Plugin Boilerplate comes with a lot of useful functionality, but in our case, the admin side, CSS and JS loading is completely unnecessary. We can always remove that from our codebase to make it smaller.

代码清理– WordPress Plugin Boilerplate具有许多有用的功能,但就我们而言,完全不需要管理端,CSS和JS加载。 我们总是可以从代码库中删除它,以使其更小。

i18n (Internationalization) ready – Although we are using the __() and _e() extensively in our plugin, we don’t really go through the actual i18n process. I won’t cover the process here as this topic has been discussed fairly extensively on SitePoint, for example in this article.

准备好i18n(国际化)–尽管我们在插件中广泛使用了__()和_e() ,但实际上并没有经过实际的i18n流程。 我不会在这里介绍该过程,因为例如在本文中 ,已经在SitePoint上对该主题进行了相当广泛的讨论。

Finer selection – As our implementation is going to be applied to all posts, we can further optimize it to be applied to a post within a certain category, or posts that have specific tags in them.

更精细的选择–由于我们的实现将应用于所有帖子,因此我们可以进一步优化它,以应用于特定类别内的帖子或其中具有特定标签的帖子。

The complete code can be viewed from this GitHub repository, in the part-2 branch.

完整的代码可以从GitHub存储库的part-2分支中查看。

结论 (Conclusion)

We have created a plugin with basic admin facing functionality by registering related settings, and creating an options page for the user to customize our plugin. In a relatively short time using the WordPress Plugin Boilerplate, we achieved this without compromising the code quality and yet still adhering to the best practices as recommended by WordPress.

我们已经注册了相关设置并创建了一个供用户自定义我们插件的选项页面,从而创建了具有基本面向管理员功能的插件。 在较短的时间内使用WordPress插件样板,我们在不影响代码质量的前提下实现了这一目标,但仍遵循WordPress建议的最佳做法。

Stay tuned for the next part of the series where we will do the public facing side of the plugin to display the appropriate notice inside the post content.

请继续关注本系列的下一部分,我们将在该插件的面向公众的一侧显示帖子内容内的相应通知。

翻译自: https://www.sitepoint.com/wordpress-plugin-boilerplate-part-2-developing-a-plugin/

wordpress插件开发

最新回复(0)