所有你需要知道的关于 WordPress 的 get_template_part() 函数
已发表: 2020-10-22我曾经读到,学习编程的最好方法是阅读其他人编写的代码。 毕竟,作为开发人员,您花费的大部分时间可能是在审查、完善和修复您或其他开发人员过去编写的代码。 这正是我如此喜欢免费和开源软件的原因:它使我们能够访问伟大工具的源代码,并可以从中学习。
如果您对 WordPress 世界感兴趣(我想您是,因为您在这里),WordPress Core 的源代码或 Gutenberg 的源代码是成为更好的 WordPress 专业人士并了解后端和前端开发的两种非常好的方法。
自从 Gutenberg 的第一个版本发布以来,我们一直在分享迄今为止我们所学到的关于前端开发的所有知识。 因此,例如,我们发布了一系列帖子,向您介绍了 React 的基础知识,了解了如何重用组件,解释了如何扩展 Gutenberg,讨论了 JavaScript 新闻以编写更好的源代码,仅举几篇文章我们写过。
好吧,今天我们要换档,再次关注 WordPress Core。 为什么? 我不知道,也许是因为几天前发布的下一个二十一主题的公告是这样做的完美借口? 因此,让我们谈谈在 WordPress 中创建主题时最重要的元素之一: get_template_part函数。

WordPress 主题
首先,让我们回顾一下 WordPress 主题的工作原理,好吗? 从本质上讲,主题是定义我们网站将使用的 HTML 结构和 CSS 样式的文件的集合。
如果您考虑任何网页的骨架,您会发现总是重复相同的模式:
- 我们首先打开
html和head标签。 这就是我们添加脚本、样式、元标记等的地方。 - 然后我们关闭
head标签并打开body标签,其中将包含我们网站的可见内容。- 通常,页面的正文包括带有 Web 徽标的标题、菜单等。
- 然后是内容本身,可以是页面、博客文章、帖子列表、搜索结果等。
- 最后,它通常以页脚结尾。
- 最后,一旦整个页面渲染完毕,我们关闭所有标签就完成了。
所以,是的,似乎每个网页都或多或少遵循相似的结构:有一个共同的部分(即页眉、菜单、页脚……)和一个特定于内容的区域(一篇博客文章,我们在搜索后得到的一组结果) ,WooCommerce 产品等)。
由于程序员不喜欢重复代码并且我们(通常)是有组织的人,因此 WordPress 主题遵循非常模式化的文件结构。 在我几个月前写的这篇文章中,您对主题中的不同文件有很好的解释,但请记住:
- 样式表:
style.css, - 用于“打开”网页的
header.php文件(即,输出head标签,通常是所有页面共有的body的初始部分), - 另一个“关闭”页面的
footer.php文件(即添加页脚并关闭html标签),以及 - 我们要渲染的不同类型的内容的许多附加文件。
什么是get_template_part函数,它的用途是什么?
当您遇到新功能时,您要做的第一件事与您父亲要求您帮助他为他的新 Roomba 清洁器编程时所做的相反:阅读文档。 因此,让我们通过查看 Codex 来使用我们的函数:
get_template_part为子主题提供了一种简单的机制来重载主题中可重用的代码部分。包括主题的命名模板部分,或者如果指定了名称,则将包括专门的部分。 如果主题不包含 {slug}.php 文件,则不会包含模板。
该模板是使用 require 而不是 require_once 包含的,因此您可以多次包含相同的模板部分。
对于 $name 参数,如果文件名为“{slug}-special.php”,则指定“special”。
注意:get_template_part() 静默失败
WordPress.org 上的get_template_part文档
看? 在不到一分钟的时间里,我们已经获得了我们需要的所有信息。 现在我们知道该函数用于在主题中创建“可重复使用的部分”(从而避免重复代码),并且它以子主题可以适应它们的方式这样做。 我们还有关于它的参数、它的内部工作(它使用 PHP 的require函数)以及我们可以从中得到什么(它“默默地失败”)的信息。

不幸的是,还有一些事情还不清楚,比如它提到的这些{slug}.php和{slug}-special.php文件。 这些是什么? 它们包含什么? 他们在做什么? 仅通过查看文档来回答许多困难的问题,因此是时候跳到示例了。
如何在我们的主题中创建部分模板
让我们看一下二十一二十一主题,看看它是否使用了这些“部分模板”,如果使用了,它们的外观以及您应该如何在自己的主题中实现它们。
如果您阅读我关于 WordPress 主题文件层次结构的文章,您会知道“ index.php是我们主题的默认模板。 它用于呈现我们网站上的任何内容,只要所述内容没有为其设计的特定模板。” 由于这是一个默认模板,我认为从那里开始是个好主意。 这是二十一个主题中index.php的内容:
get_header(); if ( have_posts() ) { // Load posts loop. while ( have_posts() ) { the_post(); get_template_part( 'template-parts/content/content' ); } // Previous/next page navigation. twenty_twenty_one_the_posts_navigation(); } else { // If no content, include the "No posts found" template. get_template_part( 'template-parts/content/content-none' ); } get_footer();如您所见,我们拥有之前评论过的所有部分:

- 它包括使用
get_header的标题。 - 它呈现内容本身。
- 它使用
get_footer关闭页面。
显然,这里有趣的是index.php中的“内容”区域。 具体来说,我们看到我们有一个小控件来知道我们是否看到任何有效内容(WordPress 循环的have_posts函数),并且根据我们是否有,我们加载部分模板( …/content )或另一个( …/content-none )。
如果我们现在看一下部分content.php模板,我们将大致看到以下内容:
<article <?php post_class(); ?>> <header class="entry-header alignwide"> … the_title( … ); … </header> <div class="entry-content"> <?php the_content( … ); wp_link_pages( … ); ?> </div> <footer class="entry-footer default-max-width"> <?php twenty_twenty_one_entry_meta_footer(); ?> </footer> … </article> 很简单,不是吗? 我们所拥有的只是一个小型模板,旨在呈现通用 WordPress 内容,例如博客文章。 请注意,生成的 HTML 框架只不过是一个带有标题、内容和页脚的article标签,所有这些都使用 WordPress 模板标签来提取实际内容。
为什么 WordPress API 很棒
即使您不知道所有这些函数都存在( get_header 、 get_footer或今天的明星: get_template_part ),我很确定您会按照类似的方法组织您的代码。 毕竟,为页眉创建一个模板,为页脚创建另一个模板,为内容创建另一个模板似乎很合乎逻辑……然后有一个特殊的文件或将它们粘合在一起的东西,对吗?
如果您确实采用了这种方法,我敢打赌您的index.php文件看起来应该是这样的:
require_once 'header.php'; if ( have_posts() ) { // Load posts loop. while ( have_posts() ) { the_post(); require 'template-parts/content.php'; } // Previous/next page navigation. twenty_twenty_one_the_posts_navigation(); } else { // If no content, include the "No posts found" template. require 'template-parts/content-none.php'; } require_once 'footer.php'; 这与我们在二十一二十一主题中的非常相似。 所以,在这一点上,你可能会问自己:使用特定的 WordPress 功能可以获得什么? 直接使用 PHP require不一样吗,特别是考虑到根据 WordPress 文档,这正是这些辅助函数使用的?
好吧,主要原因实际上是在文档本身中提到的:它使创建子主题变得容易。 因此,如果您正在创建子主题并使用get_template_part ,WordPress 将在子主题中查找模板,如果不是,它将使用父主题。
但这还不是全部! WordPress 功能通常充满过滤器和操作,可让您调整最终结果。 例如,如果我们查看wp-includes/general-template.php文件中的内部函数get_template_part :
function get_template_part( … ) { do_action( "get_template_part_{$slug}", … ); … do_action( 'get_template_part', … ); if ( ! locate_template( … ) ) { return false; } } 我们将看到我们有一些插件和主题本身可以利用的操作。 如果我们继续拉线程,我们甚至可以看到 WordPress 如何定位( locate_template )并加载它最终将使用的模板:
function locate_template( $template_names, … ) { $located = ''; foreach ( $template_names as $name ) { if ( file_exists( STYLESHEETPATH . "/$name" ) ) { $located = …; // in child theme break; } else if ( file_exists( STYLESHEETPATH . "/$name" ) ) { $located = …; // in parent theme break; } else { … } } if ( $located ) { load_template( $located, $require_once, $args ); } return $located; }我希望今天的帖子可以帮助您更好地了解 WordPress 主题的工作原理。 我还希望它向您展示了如何通过阅读其文档和浏览其源代码来了解 WordPress。 如果您喜欢它,请与您的朋友分享并给我们留言。
Joshua Sortino 在 Unsplash 上的精选图片。
