当我们开始有关在WordPress中创建自定义WordPress管理页面的系列的最后一篇文章时,我认为重要的是要重申,这并不意味着我们应该避开Settings API (或任何本机API)。
实际上,每个API都有自己的位置,显然我们通过此代码使用了许多API。 但是有时您可能正在使用自定义插件或自定义应用程序,因此您需要能够实现一些自己的自定义验证,序列化,路由等。
这就是我们在整个系列中一直在做的事情。 因此,在我们逐步完成插件的过程中,我想确保您了解我不主张绕过任何本机API。 我提倡使用可用于您的项目要求的API。
供您审核
在这一点上,我假设您已经赶上了以前的文章。 如果不是这样,您可能会很难理解我们的来历以及为什么要做出一些与代码相关的决策。
此外,您将错过我们之前讨论的一些原理。 简而言之,我建议先赶上,然后再返回本文。
开始之前
有了这个(就要求而言),与该插件相关的还有很多事情需要我们解决。
具体来说,我们需要:
- 从数据库中检索信息
- 验证信息
- 在仪表板上显示
- 在前端显示信息
幸运的是,大部分工作已为我们完成。 我们已经在数据库中获得了所需的所有信息。 在这一点上,它引入的功能,将如何处理这些数据进行处理的问题。
像往常一样,我假设您拥有最新版本的源代码,并且您可以继续进行本系列文章,向其中添加剩余的代码。
话虽如此,让我们开始吧。
完成插件
在开始编写代码之前,我想说明一下,我们将要编写的代码很简单,但是一旦我们达到了使信息在两个平台上都可用的地步,就可能需要引入一定程度的重构。后端和前端。
不过,那是一件好事。
它不仅使我们有机会进行批判性思考代码的组织,而且还使我们接触到了迄今为止在整个教程系列中都没有看到的其他一些面向对象的技术。
考虑到这一点,让我们开始从数据库中检索信息。
从数据库检索信息
从数据库中获取信息是一个简单的过程。 由于我们以前使用过诸如update_option
类的update_option
,因此这应该非常容易。
我们将使用get_option
。 它只需要一个参数,即我们用来存储信息的ID或**。 在我们的例子中,这是tutsplus-custom-data
。 如果您想发挥创意,可以传递一个可选的第二个参数,如果找不到该信息,则将返回该参数。
为了展示这可怎么使用的缘故,我将有函数返回一个空字符串,使我们有一些有效的显示给用户(即使是没有)。 用于执行此操作的代码片段如下所示:
<?php
$data = get_option( 'tutsplus-custom-data', '' );
但这提出了两个问题:
- 这去哪里了(特别是如果我们要在插件的两个地方渲染它的话)?
- 我们不应该验证此信息吗?
我们将在本教程的后面部分讨论第一个问题。 首先,让我们谈谈验证。
验证信息
关于WordPress中的验证,可以说很多。 但是为了使本教程尽可能简单,我们将讨论输入验证。 毕竟,我们通过input
元素来处理用户输入,因此这很有意义。
您可以在Codex中阅读所有内容 ,但是输入验证通常定义如下 :
数据验证是确保程序对干净,正确和有用的数据进行操作的过程。
在上一篇文章中,我们讨论了清理的主题,该主题基本上是在将数据插入数据库之前确保数据是干净的。 同样,验证可确保它对我们的用户而言是干净,安全和可读的。
为此,它是不够的只是抓住从数据库中的信息。 我们也需要对其进行验证。 就我们的插件而言,数据足够简单,以至于对其进行验证似乎有些过时了。 但是,该练习的目的是帮助我们建立思路,以便我们进行消毒,保存,检索,验证和显示数据的方式。
验证技术
就像清理一样,WordPress提供了一些使验证变得容易的功能,尤其是与输入验证有关的功能。 在这种情况下,我们可以尽力而为。
在我们的情况下,仅在呈现选项时使用esc_attr
就足够了。 如果我们允许用户输入任何类型HTML,那么我们可能要使用wp_kses
。
后一个功能可能需要一个单独的教程,特别是如果您是WordPress的新手,因此出于我们的目的,我们将坚持使用前一个。
反序列化
在项目的早期,我们创建了一个专门用于将信息保存到数据库的类。 我们称此类为Serializer
。 对于那些不记得确切功能的人:
- 该类定义了一个在
admin_post
挂钩上触发的函数,并保存了发送到服务器的信息。 - 该功能验证信息可以安全保存,并且用户有权保存到数据库。
- 该函数清除数据并将其写入数据库。
但是我们不想用没有道理的责任来重载该类。 而且由于我们将在选项页面和网站的前端同时显示此信息,因此我们有一个类可以反序列化值并使整个WordPress应用程序都可以访问它。
因此,在插件目录的根目录中,创建一个shared
目录并添加一个名为class-deserializer.php
的文件。
接下来,我们希望将代码设置为:
- 基于面向对象的原理
- 检索要求的信息
- 验证信息
- 将其返回给呼叫者
为此,该类的初始框架可能看起来像这样:
<?php
class Deserializer {
public function get_value( $option_key ) {
}
}
可以肯定,这很简单。 在本教程中,我们将向其中添加更多代码,但请记住单一责任原则,这是必须在WordPress应用程序的两个部分之间使用的类。
注意,在上面的代码中,我们定义了三个函数。 让我们讨论一下每个人会做什么:
-
get_value
将使用传入的选项键(在我们的示例中为tutsplus-custom-data
,并将该值返回给调用方。 根据WordPress编码标准 ,我们需要使用“ 后期转义 ”以确保我们正确验证了信息。 我们会暂时播放该视频。
话虽如此,让我们继续介绍一下这些功能。 我还将提供PHP DocBlocks来解释每个函数的功能。
<?php
/**
* Retrieves information from the database.
*
* @package Custom_Admin_Settings
*/
/**
* Retrieves information from the database.
*
* This requires the information being retrieved from the database should be
* specified by an incoming key. If no key is specified or a value is not found
* then an empty string will be returned.
*
* @package Custom_Admin_Settings
*/
class Deserializer {
/**
* Retrieves the value for the option identified by the specified key. If
* the option value doesn't exist, then an empty string will be returned.
*
* @param string $option_key The key used to identify the option.
* @return string The value of the option or an empty string.
*/
public function get_value( $option_key ) {
return get_option( $option_key, '' );
}
}
在这一点上,鉴于上面的项目符号要点和代码中的注释,以上代码应易于遵循。
在选项页面上显示
为了在选项页面上显示此内容,我们需要重新访问在custom-admin-settings.php
文件中实例化Submenu_Page
的方式。 具体来说,我们需要实例化反序列化器并将其传递到Submenu_Page
的构造函数中。
首先,我们需要包含文件。 在检查是否直接访问主插件文件后,可能会发生这种情况:
<?php
// If this file is called directly, abort.
if ( ! defined( 'WPINC' ) ) {
die;
}
// Include the shared dependency.
include_once( plugin_dir_path( __FILE__ ) . 'shared/class-deserializer.php' );
插件根目录的main函数中的代码现在应如下所示:
<?php
add_action( 'plugins_loaded', 'tutsplus_custom_admin_settings' );
/**
* Starts the plugin.
*
* @since 1.0.0
*/
function tutsplus_custom_admin_settings() {
$serializer = new Serializer();
$serializer->init();
$deserializer = new Deserializer();
$plugin = new Submenu( new Submenu_Page( $deserializer ) );
$plugin->init();
}
然后Submenu_Page
的构造Submenu_Page
应如下所示:
<?php
public function __construct( $deserializer ) {
$this->deserializer = $deserializer;
}
从这里,我们可以处理选项页面。 我们只需通过调用反序列化器中的函数来更新value
属性。 请记住,由于我们无条件地获取值,并且如果不存在该值,则最终返回一个空字符串,因此它应该可以正常工作。
<p>
<label>What message would you like to display above each post?</label>
<br />
<input type="text" name="acme-message"
value="<?php echo esc_attr( $this->deserializer->get_value( 'tutsplus-custom-data' ) ); ?>"
/>
</p>
这样一来,您应该能够在选项页面上保存和检索值。
在前端显示
我们快完成了。 我们需要做的最后一件事是设置插件以在前端显示自定义消息。 具体来说,我们希望显示用户在单个帖子页面(相对于存档页面或任何其他类型的页面)上输入的内容,并在每个帖子上方进行显示。
这意味着我们将需要执行以下操作:
- 设置一个将使用the_content挂钩的函数。
- 使用我们的反序列化器读取值。
- 在内容之前添加值(可能在其自己的元素中)。
幸运的是,这并不需要那么多的工作,尤其是因为我们有很多需要上手的工作。 尽管如此,我们仍然需要创建一个专门负责处理站点前端的插件区域。
为此,请在插件目录的根目录中创建一个public
目录,然后添加class-content-messenger.php
。
在该类中,我们需要定义一个构造器,该构造器将接受反序列化器作为依赖项。 构造函数(和必要的属性)应如下所示:
<?php
/**
* A reference to the class for retrieving our option values.
*
* @access private
* @var Deserializer
*/
private $deserializer;
/**
* Initializes the class by setting a reference to the incoming deserializer.
*
* @param Deserializer $deserializer Retrieves a value from the database.
*/
public function __construct( $deserializer ) {
$this->deserializer = $deserializer;
}
然后,我们需要创建一个init
函数,该函数将注册一个内部函数(我们称其为display
)以将内容与新消息一起呈现。
<?php
/**
* Initializes the hook responsible for prepending the content with the
* option created on the options page.
*/
public function init() {
add_filter( 'the_content', array( $this, 'display' ) );
}
之后,我们将需要更新主插件文件,以便实例化我们的新类并将解串器传递给构造函数。 然后它将初始化该类。
首先,我们将其包括在内:
<?php
// Include the shared and public dependencies.
include_once( plugin_dir_path( __FILE__ ) . 'shared/class-deserializer.php' );
include_once( plugin_dir_path( __FILE__ ) . 'public/class-content-messenger.php' );
然后我们将其实例化:
<?php
function tutsplus_custom_admin_settings() {
// Code removed for brevity...
// Setup the public facing functionality.
$public = new Content_Messenger( $deserializer );
$public->init();
}
从这里开始,我们应该准备好了。 确保在选项页面上输入了一个值。 保存您的工作并在您的网站上签出单个帖子页面。 它看起来应该像这样:
如果不是,则将您的代码与上面的代码(或附带的代码)进行比较,并确保已正确设置所有类,函数和钩子。
关于视图和依赖的一句话
尽管我们在整个系列中都讨论了单一责任原则,但实际上,我们并没有太多讨论更高级的主题,而这些主题可以使代码更加简洁并遵循更好的实践。
其中一些主题包括诸如PHP自动加载之类的东西和诸如依赖注入之类的东西。 我之所以没有讨论这些内容,是因为它们超出了该特定系列旨在教授的核心重点和重点。
根据接收此特定系列文章的方式,我将考虑创建一些专门针对这些主题的教程。
结论
到此,我们结束了创建自定义管理页面的系列。 我希望在整个系列中,您已经学到了一些创建管理页面的标准方法之外的东西。
此外,我希望您已经了解如何在WordPress的日常工作中应用一些软件开发技术。 此外,我希望有关视图和依赖项的讨论也引起了对更高级主题的兴趣。 这些也是我希望在以后的教程中介绍的内容。
和往常一样,您可以在个人资料页面上查看我的课程和教程,也可以在@tommcfarlin的 博客和/或Twitter上关注我,在其中我讨论了各种软件开发实践以及如何在WordPress中使用它们。
不要忘了下载这篇文章的侧边栏上的代码,进行阅读,使用它,然后看看如何做才能扩展它并为其添加功能。 像往常一样,不要犹豫,通过有关本教程的评论与我联系。
翻译自: https://code.tutsplus.com/tutorials/creating-custom-admin-pages-in-wordpress-4--cms-27018