EP209. “搭建 single/page/blogindex 三个模板与 front-page 拆分”
🔒 登录后可标记已读用 EP199-200 建立的 PlaceholderBlock 套路,批量搭建剩下几个最常用的模板:单篇文章(singlepost)、单个页面(page)、博文列表(blogindex)——每一个都是「新建占位 Block + 直接从传统主题对应文件搬运既有 PHP」,模式高度重复,一次性讲透之后后面的模板会很快。同时理清楚 index.html 与 front-page.html 的分工:index.html 是「博文列表」这个 URL 该用的模板(因为 front-page.html 不存在时,WordPress 会退回用 index.html 当首页),一旦故意新建了专门的 front-page.html(用来当真正的自定义首页),index.html 就该改造成博文列表专用;这跟 WordPress 后台「设置 → 阅读」里「首页显示:静态页面」这个选项配合使用,才能让首页和博文列表各自独立、互不冲突。
涉及文件
wp-content/themes/fictional-university-block-theme/functions.php(修改,新增 3 个PlaceholderBlock实例)wp-content/themes/fictional-university-block-theme/our-blocks/singlepost.js/singlepost.php(新建)wp-content/themes/fictional-university-block-theme/our-blocks/page.js/page.php(新建)wp-content/themes/fictional-university-block-theme/our-blocks/blogindex.js/blogindex.php(新建)wp-content/themes/fictional-university-block-theme/templates/single.html(修改)wp-content/themes/fictional-university-block-theme/templates/page.html(新建)wp-content/themes/fictional-university-block-theme/templates/front-page.html(新建,原index.html的完整首页内容搬到这里)wp-content/themes/fictional-university-block-theme/templates/index.html(修改,改造成博文列表专用)
代码实现
functions.php:批量新增三个占位 Block:
new PlaceholderBlock("eventsandblogs");
new PlaceholderBlock("header");
new PlaceholderBlock("footer");
new PlaceholderBlock("singlepost");
new PlaceholderBlock("page");
new PlaceholderBlock("blogindex");
our-blocks/singlepost.php(新建,原样搬运传统主题 single.php 里 while 循环内部的正文部分——按 EP208 的规则,单篇内容不再需要 while 循环):
<?php
pageBanner();
?>
<div class="container container--narrow page-section">
<div class="metabox metabox--position-up metabox--with-home-link">
<p><a class="metabox__blog-home-link" href="<?php echo site_url('/blog'); ?>"><i class="fa fa-home" aria-hidden="true"></i> Blog Home</a> <span class="metabox__main">Posted by <?php the_author_posts_link(); ?> on <?php the_time('n.j.y'); ?> in <?php echo get_the_category_list(', '); ?></span></p>
</div>
<div class="generic-content"><?php the_content(); ?></div>
</div>
our-blocks/page.php(新建,原样搬运传统主题 page.php,同样不需要 while 循环):
<?php
pageBanner();
?>
<div class="container container--narrow page-section">
<?php
$theParent = wp_get_post_parent_id(get_the_ID());
if ($theParent) { ?>
<div class="metabox metabox--position-up metabox--with-home-link">
<p><a class="metabox__blog-home-link" href="<?php echo get_permalink($theParent); ?>"><i class="fa fa-home" aria-hidden="true"></i> Back to <?php echo get_the_title($theParent); ?></a> <span class="metabox__main"><?php the_title(); ?></span></p>
</div>
<?php }
?>
<?php
$testArray = get_pages(array(
'child_of' => get_the_ID()
));
if ($theParent or $testArray) { ?>
<div class="page-links">
<h2 class="page-links__title"><a href="<?php echo get_permalink($theParent); ?>"><?php echo get_the_title($theParent); ?></a></h2>
<ul class="min-list">
<?php
if ($theParent) {
$findChildrenOf = $theParent;
} else {
$findChildrenOf = get_the_ID();
}
wp_list_pages(array(
'title_li' => NULL,
'child_of' => $findChildrenOf,
'sort_column' => 'menu_order'
));
?>
</ul>
</div>
<?php } ?>
<div class="generic-content">
<?php the_content(); ?>
</div>
</div>
our-blocks/blogindex.php(新建,原样搬运传统主题 index.php——这是列表页,依然保留 while 循环):
<?php
pageBanner(array(
'title' => 'Welcome to our blog!',
'subtitle' => 'Keep up with our latest news.'
));
?>
<div class="container container--narrow page-section">
<?php
while(have_posts()) {
the_post(); ?>
<div class="post-item">
<h2 class="headline headline--medium headline--post-title"><a href="<?php the_permalink(); ?>"><?php the_title(); ?></a></h2>
<div class="metabox">
<p>Posted by <?php the_author_posts_link(); ?> on <?php the_time('n.j.y'); ?> in <?php echo get_the_category_list(', '); ?></p>
</div>
<div class="generic-content">
<?php the_excerpt(); ?>
<p><a class="btn btn--blue" href="<?php the_permalink(); ?>">Continue reading »</a></p>
</div>
</div>
<?php }
echo paginate_links();
?>
</div>
templates/single.html / templates/page.html:都是「页头 + 对应内容占位 Block + 页脚」三段式:
<!-- wp:ourblocktheme/header /-->
<!-- wp:ourblocktheme/singlepost /-->
<!-- wp:ourblocktheme/footer /-->
<!-- wp:ourblocktheme/header /-->
<!-- wp:ourblocktheme/page /-->
<!-- wp:ourblocktheme/footer /-->
templates/front-page.html:把原本 index.html 里完整的首页布局(Banner/事件博文/幻灯片等)原样搬过来(内容跟 EP205-207 写定的 index.html 完全一致,此处不重复贴)
templates/index.html:改造成博文列表专用,三段式换成 blogindex:
<!-- wp:ourblocktheme/header /-->
<!-- wp:ourblocktheme/blogindex /-->
<!-- wp:ourblocktheme/footer /-->
关键改动点:
- 每个模板的搭建套路完全一致,只是内容不同:①
functions.php加一行new PlaceholderBlock("块名");② 复制一份已有的最简单 JS 文件(比如header.js),只改 Block 名字/标题/占位文字;③ 新建对应的 PHP 文件,从传统主题里找到对应的旧模板文件,把「不需要的头尾」(页头/页脚,已经由独立的header/footerBlock 负责)删掉,只留中间的动态内容部分,粘贴过来 singlepost/page两个「单篇」类型的 Block,不需要while循环:直接复制传统主题single.php/page.php里原本while循环内部的代码,跳过外层循环——这是 EP208 讲过的 WordPress 6.4 新规则的直接应用blogindex(博文列表)依然需要while循环:因为这是「同时显示多篇文章」的场景,不属于 EP208 规则覆盖的「单篇」情形,循环逻辑原样保留page.php复用了传统主题已经写好的「面包屑导航 + 子页面列表」逻辑:wp_get_post_parent_id()判断当前页面是否有上级页面(决定要不要显示「返回上级」链接)、get_pages()查询当前页面的所有子页面(决定要不要显示子页面链接列表)——这些细节都是传统主题章节早就写好验证过的代码,原样复制,不需要为了适配 Block Theme 重新设计front-page.html与index.html的分工:- 在 WordPress 里,如果专门存在一个
front-page.html(或front-page.php)模板文件,只要网站首页设置成「显示一个静态页面」(在「设置 → 阅读」里选择,这门课传统主题章节已经配置过:Home页面当首页,Blog页面当博文列表),访问首页 URL 就会优先使用这个模板 index.html是兜底模板——理论上任何没有更具体匹配模板的请求最终都会退到它;这门课的用法是让它专门服务「博文列表」这个 URL(因为「Blog」这个页面本身是空的,只是为了占一个 URL slug,真正的列表内容渲染逻辑就落在index.html身上)- 操作步骤:把原本写在
index.html里的完整首页布局(页头/Banner/事件博文/幻灯片/页脚)整个搬到新建的front-page.html;index.html精简成「页头 +blogindex+ 页脚」三段
- 在 WordPress 里,如果专门存在一个
- 改完模板文件记得清除编辑器里的自定义项:因为之前对
index.html的编辑记录存在数据库里,文件改了之后如果不去「模板」列表点「清除自定义项」,页面依然会显示数据库里存的旧版本内容,容易造成「明明改了文件却没生效」的困惑——这一讲再次踩到这个坑,也再次印证了这个机制的重要性
Hook / Function 速查
| 名称 | 类型 | 用途 |
|---|---|---|
templates/front-page.html | Block Theme 模板文件 | 网站设置为「显示静态页面」时,首页 URL 优先匹配的模板 |
templates/index.html | Block Theme 模板文件 | 兜底模板,这里专门用来承载博文列表内容 |
wp_get_post_parent_id($ID) | WP 内建 function | 获取指定页面的上级页面 ID,用于判断是否显示面包屑 |
get_pages(array('child_of' => $ID)) | WP 内建 function | 查询指定页面的所有子页面 |
常见坑
- 「单篇」类型的模板(
singlepost.php/page.php)继续保留while循环——按 EP208 的规则会导致内容空白/报错 - 「列表」类型的模板(
blogindex.php)误删了while循环——只会显示不完整的内容甚至报错,因为这类场景确实需要遍历多篇文章 - 只建了
front-page.html,忘记同步把index.html从完整首页布局改造成博文列表专用——会导致首页和博文列表显示同样的内容 - 改完模板文件后没有去后台「模板」列表清除自定义项——页面继续显示数据库里存的旧版本,看起来像是改动没生效
[截图:前台 /blog 博文列表页正确渲染出文章标题/摘要/分页,而首页依然显示完整的 Banner+幻灯片布局,两者互不冲突]
延伸 / 后续讲座会用到
下一讲继续搭建剩余的模板(自定义文章类型详情页、归档页等),套路跟这一讲完全一致,会进展得更快。
Sources
Udemy:
- Become a WordPress Developer: Unlocking Power With Code — Section 28, EP209