本系列的第一篇文章为在WordPress上下文中理解分类法,术语及其关系奠定了基础。 如果您还没有阅读过并且您是WordPress开发的新手,那么我强烈建议您仔细阅读它,因为本文将以该文章介绍的所有内容为基础。
此外,在继续讨论更多类型的元数据时,重要的是要回顾之前介绍的系列:
值得回顾这些文章的原因是因为本文将类似于这些文章中介绍的某些技术,并且还将基于使用类似API的一些策略。
最重要的是,本教程旨在提供如何使用WordPress中可用的最新元数据API的演练。
开发者免责声明
如前所述,此特定文章更适合那些刚刚进入WordPress开发或希望提高其技能的人。 因此,如果您是高级开发人员,那么您可能不会对本文中介绍的内容感兴趣。
在学习本教程时,要记住的关键事项之一是,该代码不得在生产环境中使用。 也就是说,它仅用于研究API并了解其工作原理。
我们正在编写的代码并不打算在将用于受众或一组用户的项目中使用。 主要原因是因为存在诸如消毒,验证,转义之类的主题,这些主题超出了先前系列以及本系列的范围。
在完成本文的包装后,我们将继续讨论诸如此类的更高级的主题,但是现在,我们将仅专注于术语元数据API。
分类法和术语的复习
在讨论元数据API之前,请确保我们都位于同一页面上,因为它与将要使用的各种术语相关。 具体来说,我们需要确保我们了解分类法,术语以及两者之间的关系。
首先,食典将分类法定义为:
在WordPress中,“分类法”是某些帖子(或链接或自定义帖子类型)的分组机制。
在默认的WordPress安装中,您可以将这些视为类别和标签 。 它们可以是分层的(如类别),也可以是非分层的(如标签)。
另一方面, 术语定义为:
在WordPress中,术语是分类法的分类,组或子集,其中后者可以是类别,标签或自定义分类法。 默认情况下,术语具有标题,内容和描述。 类别等分层分类法可以定义父项。
最后,分类法和术语之间的关系使得一个人不能没有另一个就不存在(特别是在层次分类法中)。 也就是说,类别分类法必须至少具有一个相关联的术语; 但是,非分层分类法不一定必须遵循这一点。
话虽如此,让我们开始使用术语元数据API。
使用API
与其他可用的元数据API一样,我们将能够执行以下操作:
-
add
-
update
-
retrieve
-
delete
并且由于这是一个新的API,因此可能尚不清楚此API有哪些优点。 尽管我们仅打算探索本文的一些基础知识,但值得考虑的是我们可以做的一些事情。
例如:
- 将颜色或图像与术语相关联
- 限制属于术语的某些帖子
- 添加二进制数据(例如文档或PDF),以使该术语在前端可用
- ...和更多。
当然,还有更多的可能性。 但是,现在,让我们看看如何将其整合到我们的工作中。
准备主题
为了开始,让我们确保我们将在同一页上看到我们将用来完成这项工作的内容。 具体来说,这就是您所需要的,这就是我正在使用的。
- 一个IDE —我将使用Atom
- 数据库前端—我将使用Sequel Pro
- WordPress的一个版本-我将使用WordPress 4.4.2
- 一个基本的主题-我使用twentysixteen
一旦完成所有这些设置,我们就可以开始了。 如果您需要帮助来设置开发环境,请参阅本系列文章 。
入门
我们需要做的第一件事是创建一个文件,其中将包含我们将在本教程中完成的所有工作。
首先,我们需要创建tutsplus-term-metadata.php
在根twentysixteen
主题目录。
接下来,我们需要将以下代码行添加到主题的functions.php文件中。 这将确保我们将我们的工作纳入主题。
<?php
/**
* Add the code that allows us to work with the Term Meta API.
*/
include_once( 'tutsplus-term-metadata.php' );
重新加载浏览器时,您应该看到如下图所示的内容:
![WordPress随附的标准Hello World](https://i-blog.csdnimg.cn/blog_migrate/79833104fa517921facc275cbfddb951.png)
应该没有错误输出,并且应该像没有任何更改一样工作。 最后,如果您使用的是全新安装的WordPress,则术语元数据表应看起来完全为空:
![空termmeta数据库表](https://i-blog.csdnimg.cn/blog_migrate/7d58961cef677024885949daefd6488d.png)
接下来,为了确保我们有一个正在使用的类别,请继续并在WordPress安装中创建一个新类别。 我将创建一个名为Main的容器 ,并确保其中带有Hello World标记。
完成后,查看数据库中的terms表以获取term_id
。 在我的情况下, term_id
是2
。 您的名称可能会有所不同,但关键是您知道所用术语的ID:
![术语数据库表](https://i-blog.csdnimg.cn/blog_migrate/6700c0f26c323895fb064a9940cbdbd3.png)
注意,因为我们将在整个教程中使用它。
添加元数据
首先,必须认识到add_term_meta
函数可用于两个目的,这一点很重要:
- 该函数可以创建与单个术语ID和单个元键关联的非唯一值。
- 该函数可以创建与单个术语ID和单个元键关联的唯一值。
该函数接受术语ID,元密钥,元值和可选的布尔值,该布尔值确定要存储的值是否唯一。
独特价值
首先,让我们在数据库中创建一个唯一值。 在编辑器中输入以下代码,刷新Hello World ,然后查看termmeta
表。
<?php
add_filter( 'the_content', 'tutsplus_add_term_meta' );
function tutsplus_add_term_meta( $content ) {
$category = get_the_category();
$term_id = $category[0]->term_id;
if ( 1 === get_the_ID() && 2 === $term_id ) {
add_term_meta( $term_id, 'my_meta_key', 'my_meta_value', true );
}
return $content;
}
您应该会看到您的信息。
![术语表中的元数据](https://i-blog.csdnimg.cn/blog_migrate/5bcef794c49321582286a4c7986461c6.png)
如果更改元值并刷新页面,则应注意数据库中的值未更改。 这是因为您已经说过这应该是唯一值,并且写入的第一个值不会被更改或覆盖。
这可以通过update_term_meta
来实现,但是我们将立即查看该代码。
非唯一值
不过,在研究如何更新术语元数据之前,让我们看一下如何将多个值添加到相同的元键和相同的术语ID。 下面的代码看起来与上面的代码相似,除了我们没有将true传递给函数。
<?php
add_filter( 'the_content', 'tutsplus_add_term_metas' );
function tutsplus_add_term_metas( $content ) {
$category = get_the_category();
$term_id = $category[0]->term_id;
if ( 1 === get_the_ID() && 2 === $term_id ) {
for ( $i = 0; $i < 3; $i++ ) {
$meta_value = "my_meta_value_$i";
add_term_meta( $term_id, 'non_unique_key', $meta_value );
}
}
return $content;
}
几次刷新Hello World ,然后看一下数据库。 您应该会看到以下内容:
![非唯一值被添加到数据库表](https://i-blog.csdnimg.cn/blog_migrate/7d8b97030b4fe4d5fb8d45c2d38b318a.png)
合理? 基本上,当您说要拥有唯一值时,输入的第一个值将作为唯一值保留(除非您更新或删除它)。
另一方面,如果您未指定希望它为唯一值,则可以使用术语ID和元键存储任意数量的值。
但是,这导致从数据库中检索信息和删除信息的方式有所不同。 我们将在本文后面的内容中对此进行更详细的研究。
更新元数据
API函数update_term_meta
为我们提供了两个不错的选择。 首先,它使我们能够在数据库中添加单个唯一条目,而不必使用add_post_meta
的第四个参数。
其次,只要我们知道先前的值是什么,它就允许我们更新特定的元数据。 给定数据库的当前状态,让我们看一下这两种情况。
添加唯一数据
要添加唯一的元数据,我们可以进行与在第一个示例中看到的add_term_meta
非常相似的调用。 相反,这次,我们使用update_term_meta
。 例如,查看以下代码:
<?php
add_filter( 'the_content', 'tutsplus_update_term_meta' );
function tutsplus_update_term_meta() {
$category = get_the_category();
$term_id = $category[0]->term_id;
if ( 1 === get_the_ID() && 2 === $term_id ) {
update_term_meta( $term_id, 'update_key', 'my_unique_update_value' );
}
return $content;
}
几次刷新Hello World ,无论刷新多少次,都会看到一个值输入数据库。 如果您遵循代码,那么应该会看到类似以下内容的内容:
![通过update_term_meta函数添加元数据](https://i-blog.csdnimg.cn/blog_migrate/46b18f159639570019f2c81846cc5da6.png)
但是,当多个记录具有相同的元键并且我们想要更新它们时会发生什么?
更新非唯一记录
为了更新具有相同术语ID和相同元键的记录,重要的是要知道先前的值。 就我们而言,我们知道我们有一个名为my_meta_value_1
的值。
为此,我们可以通过在update_term_meta
函数中指定新值和旧值来更新此特定行。 为此,请看以下代码:
<?php
add_filter( 'the_content', 'tutsplus_update_term_metas' );
function tutsplus_update_term_metas() {
$category = get_the_category();
$term_id = $category[0]->term_id;
if ( 1 === get_the_ID() && 2 === $term_id ) {
update_term_meta( $term_id, 'non_unique_key', 'my_meta_value_1_updated', 'my_meta_value_1' );
}
return $content;
}
然后刷新Hello World 。 完成后,更新的元值应如下所示:
![更新非唯一元数据](https://i-blog.csdnimg.cn/blog_migrate/a1126c7f1faf1aec845118159a990138.png)
如果看不到相同的结果,请确保在挂钩中正确指定了正确的函数名称,写入术语ID,正确的元键和正确的先前元值。
检索元数据
为了获取我们检索到的元数据,我们可以使用get_term_meta
函数。
但是请注意,当我们检索术语元数据时,我们可能正在处理具有多个与其相关联的值的元密钥。 或者我们可能正在处理仅具有单个值的元密钥。
根据情况,我们需要为函数指定不同的信息。
检索所有元数据
检索与单个术语相关的所有元数据很容易,如下面的代码所示。 要注意的关键是结果以数组形式返回。
在下面的示例中,我们将使用non_unique_key
作为我们的元键,因为它具有多个与之关联的值。
<?php
add_filter( 'the_content', 'tutsplus_get_term_metas' );
function tutsplus_get_term_metas() {
$category = get_the_category();
$term_id = $category[0]->term_id;
if ( 1 === get_the_ID() && 2 === $term_id ) {
get_term_meta( $term_id, 'non_unique_key' );
}
return $content;
}
您可以选择将结果回显到屏幕上,可以选择使用var_dump,也可以选择使用调试器来查看信息。 无论如何,您的结果都将显示以下内容:
array(3) { [0]=> string(15) "my_meta_value_0" [1]=> string(23) "my_meta_value_1_updated" [2]=> string(15) "my_meta_value_2" }
给定此输出,您可以选择将其存储在变量中,然后从给定索引中检索某个值。 或者,您可能会选择遍历数据并读取或操作它。
无论用例如何,这都是您如何检索与元密钥关联的所有信息的方法。
检索单个元数据
当我们谈论检索单个元数据时,通常是指我们要从多个记录中检索一条记录(如上述示例所示)。 但是,在某些情况下,我们可能希望检索与单个元键关联的单个元值。
我们将在稍后讨论稍后的情况。 但是首先,让我们介绍一下我们想要从一组具有相同术语ID和相同元键的数据中检索单个值的情况。
注意,在下面的代码中,我们传递了第四个值true
:
<?php
add_filter( 'the_content', 'tutsplus_get_term_meta' );
function tutsplus_get_term_meta( $content ) {
$category = get_the_category();
$term_id = $category[0]->term_id;
if ( 1 === get_the_ID() && 2 === $term_id ) {
get_term_meta( $term_id, 'non_unique_key', true );
}
return $content;
}
这是返回的内容:
string(15) "my_meta_value_0"
请注意,这将返回找到的第一个值,并且它以字符串的形式返回。
如果只有一条记录该怎么办?
如果只有一条记录,则有两个选择:
- 您可以检索信息而无需指定
true
。 - 您可以通过指定
true
检索信息。
如果您选择第一种情况,那么您将获得具有单个索引和单个值的数组。 因此,假设您将函数调用的结果存储在$result
,则需要通过执行类似$value = $result[ 0 ]
来从结果中获取值。
另一方面,如果您选择第二个选项,则可以期望将结果作为string
返回给您。
可以说,在采用特定策略接近值时要注意的最重要的一点是,给定其元键,这些值是唯一的。
删除元数据
最后,我们需要看一下删除关联的元数据。 并且,与其余示例保持一致,这取决于是否有与元密钥关联的元数据片段或与一个元密钥关联的单个元值。
删除所有记录
如果您知道单个元密钥具有与之关联的多个值,则可以使用以下代码:
<?php
add_filter( 'the_content', 'tutsplus_delete_term_metas' );
function tutsplus_delete_term_metas( $content ) {
$category = get_the_category();
$term_id = $category[0]->term_id;
if ( 1 === get_the_ID() && 2 === $term_id ) {
delete_term_meta( $term_id, 'non_unique_key' );
}
return $content;
}
然后将更新数据库表,如下所示:
![删除数据库中的多行信息](https://i-blog.csdnimg.cn/blog_migrate/ab072bdabe409c688482a63693cf5fb0.png)
如果您一直在遵循,那么您会知道这将删除与non_unique_key
元键关联的所有数据。
删除单条记录
如果要删除单个记录,则有两种方法可以执行此操作:
- 您知道与要删除的元密钥关联的元值。
- 与指定的元密钥关联的值是唯一的,因为元密钥和元值是唯一的。
为此,我们将看一下本节中的第一个示例,然后看一下本节中的第二个示例。
要删除我们知道关联的元值的单个记录,我们可以编写同时指定元键和元值的代码。 例如:
<?php
add_filter( 'the_content', 'tutsplus_delete_term_meta' );
function tutsplus_delete_term_meta( $content ) {
$category = get_the_category();
$term_id = $category[0]->term_id;
if ( 1 === get_the_ID() && 2 === $term_id ) {
delete_term_meta( $term_id, 'my_meta_key', 'my_meta_value' );
}
return $content;
}
这将从数据库中删除与此信息关联的行。
删除唯一记录
最后,如果有一个唯一的记录,您知道其中的元键,但您不知道元值,那么您仍然可以从数据库中删除该记录。
您只需在源代码中指定的就是meta键。 请参见以下功能:
<?php
add_filter( 'the_content', 'tutsplus_delete_single_term_meta' );
function tutsplus_delete_single_term_meta( $content ) {
$category = get_the_category();
$term_id = $category[0]->term_id;
if ( 1 === get_the_ID() && 2 === $term_id ) {
delete_term_meta( $term_id, 'update_key' );
}
return $content;
}
精明的读者可能会发现,上面的函数与我们在删除具有所有多个值的记录时提供的函数定义相同。 那是因为它们是相同的。
但是,不同之处在于功能的目的 。 函数的意图通常会驱动我们如何命名函数。 在前一种情况下,我们希望删除所有术语“元数据”。 在这种情况下,我们希望删除单个术语元数据。
完整的源代码
在这里,您将找到我们在本文中使用的所有代码,以及解释代码中发生的事情的其他注释。 请记住,所有这些函数都挂接到the_content
,这意味着该函数将在每次加载帖子时触发。
这样, add_filter
调用将被注释掉,以便您可以根据需要启用它们。
<?php
//add_filter( 'the_content', 'tutsplus_add_term_meta' );
/**
* If we're on the first post and in the category having the
* ID of '2', then we add a unique meta key and meta value to
* the term metadata.
*
* @param string $content The post content.
* @return string The post content.
*/
function tutsplus_add_term_meta( $content ) {
$category = get_the_category();
$term_id = $category[0]->term_id;
if ( 1 === get_the_ID() && 2 === $term_id ) {
add_term_meta( $term_id, 'my_meta_key', 'my_meta_value_changed', true );
}
return $content;
}
//add_filter( 'the_content', 'tutsplus_add_term_metas' );
/**
* If we're on the first post and in the category having the
* ID of '2', then we add multiple meta values with the same
* meta key to the term metadata.
*
* @param string $content The post content.
* @return string The post content.
*/
function tutsplus_add_term_metas( $content ) {
$category = get_the_category();
$term_id = $category[0]->term_id;
if ( 1 === get_the_ID() && 2 === $term_id ) {
for ( $i = 0; $i < 3; $i++ ) {
$meta_value = "my_meta_value_$i";
add_term_meta( $term_id, 'non_unique_key', $meta_value );
}
}
return $content;
}
//add_filter( 'the_content', 'tutsplus_update_term_meta' );
/**
* Updates the term meta value with the specified key. If the value
* doesn't exist, then the record will be created. This will only
* be added if the 'Hello World' page is loaded with the category
* having the ID of '2'.
*
* @param string $content The post content.
* @return string The post content.
*/
function tutsplus_update_term_meta( $content ) {
$category = get_the_category();
$term_id = $category[0]->term_id;
if ( 1 === get_the_ID() && 2 === $term_id ) {
update_term_meta( $term_id, 'update_key', 'my_unique_update_value' );
}
return $content;
}
//add_filter( 'the_content', 'tutsplus_update_term_metas' );
/**
* Updates the existing value for the metadata that has the 'non_unique_key'
* meta key with the specified meta value. This only happens if we're on the
* post with the ID of one and it has the category ID of '2'.
*
* @param string $content The post content.
* @return string The post content.
*/
function tutsplus_update_term_metas( $content ) {
$category = get_the_category();
$term_id = $category[0]->term_id;
if ( 1 === get_the_ID() && 2 === $term_id ) {
update_term_meta( $term_id, 'non_unique_key', 'my_meta_value_1_updated', 'my_meta_value_1' );
}
return $content;
}
//add_filter( 'the_content', 'tutsplus_get_term_metas' );
/**
* If we're on the first post and the post has the category ID of '2' then
* retrieve the term meta in the form of an array.
*
* @param string $content The post content.
* @return string The post content.
*/
function tutsplus_get_term_metas( $content ) {
$category = get_the_category();
$term_id = $category[0]->term_id;
if ( 1 === get_the_ID() && 2 === $term_id ) {
get_term_meta( $term_id, 'non_unique_key' );
}
return $content;
}
//add_filter( 'the_content', 'tutsplus_get_term_meta' );
/**
* If we're on the first post and the post has the category ID of '2' then
* retrieves the first value from the metadata as a string.
*
* @param string $content The post content.
* @return string The post content.
*/
function tutsplus_get_term_meta( $content ) {
$category = get_the_category();
$term_id = $category[0]->term_id;
if ( 1 === get_the_ID() && 2 === $term_id ) {
get_term_meta( $term_id, 'non_unique_key', true );
}
return $content;
}
//add_filter( 'the_content', 'tutsplus_delete_term_metas' );
/**
* If we're on the first post and the post has the category ID of '2' then
* deletes the meta values associated with the specified key.
*
* @param string $content The post content.
* @return string The post content.
*/
function tutsplus_delete_term_metas( $content ) {
$category = get_the_category();
$term_id = $category[0]->term_id;
if ( 1 === get_the_ID() && 2 === $term_id ) {
delete_term_meta( $term_id, 'non_unique_key' );
}
return $content;
}
//add_filter( 'the_content', 'tutsplus_delete_term_meta' );
/**
* If we're on the first post and the post has the category ID of '2' then
* deletes the specified meta value associated with the specified meta key.
*
* @param string $content The post content.
* @return string The post content.
*/
function tutsplus_delete_term_meta( $content ) {
$category = get_the_category();
$term_id = $category[0]->term_id;
if ( 1 === get_the_ID() && 2 === $term_id ) {
delete_term_meta( $term_id, 'my_meta_key', 'my_meta_value' );
}
return $content;
}
//add_filter( 'the_content', 'tutsplus_delete_single_term_meta' );
/**
* If we're on the first post and the post has the category ID of '2' then
* deletes the meta values associated with the specified key.
*
* @param string $content The post content.
* @return string The post content.
*/
function tutsplus_delete_single_term_meta( $content ) {
$category = get_the_category();
$term_id = $category[0]->term_id;
if ( 1 === get_the_ID() && 2 === $term_id ) {
delete_term_meta( $term_id, 'update_key' );
}
return $content;
}
找到像这样的函数并钩到另一些钩子(如save_post
或类似的东西)中并不少见。 这是我们将在今年晚些时候的高级教程中更详细地介绍的内容。
结论
对于那些遵循本系列和上一个系列与其他元数据API一起使用的人来说,本系列介绍的许多内容都应该很容易理解。
使用此API的最难的部分可能是在可以实际使用的许多方式上发挥创造力。 但是,由于我们已经介绍了如何使用API,因此使其投入使用并不难。
请记住,在接下来的几周中,我们将研究用于将信息写入数据库和从数据库中读取信息的先进且适当的技术,以便我们能够在生产环境中与他们合作。
同时,如果您正在寻找其他实用程序来帮助您构建不断增长的WordPress工具集或用于研究代码并精通WordPress的代码,请别忘了看看Envato中提供的功能市场 。
记住,您可以在个人资料页面上捕获我的所有课程和教程,还可以通过@tommcfarlin 在我的博客和/或Twitter上关注我,在那里我讨论了各种软件开发实践以及如何在WordPress中使用它们。
请不要在下面的提要中留下任何问题或评论,我将尽力回答每个问题或评论。