15%

全场主机优惠15%

测试技能,享折扣

使用代码:

Skills
开始使用
23.10.2024
2 +1

在 WordPress 中重新排列页面的最简单方法(所有方法详解)

在 WordPress 中重新排列页面,既能控制网站的结构层级,也能控制页面在导航菜单、REST API 响应以及主题生成的页面列表中的显示顺序。默认情况下,WordPress 为每个页面分配的 menu_order 值为 0,这意味着除非您通过区块编辑器的文档设置、专用插件或直接操作数据库来明确覆盖该值,否则页面将按字母顺序渲染。

本指南涵盖了重新排列 WordPress 页面的所有实用方法,从最快捷的拖放插件到原始 menu_order SQL 更新,包括每种方法适用的确切场景以及各自的局限性。

为什么页面顺序不仅仅关乎导航

大多数教程将页面重排视为纯粹的视觉问题,但事实并非如此。menu_order 表中的 wp_posts 列是一个可查询的整数,直接影响:

  • WP_Query 结果——当传入 orderby=menu_order 时,许多页面构建器模板和主题循环会使用该值
  • REST API 端点排序/wp-json/wp/v2/pages?orderby=menu_order&order=asc)——被无头 WordPress 设置和移动应用所调用
  • 面包屑插件(Yoast SEO、Rank Math)——这些插件结合 menu_order 从父子关系中推断层级
  • 站点地图生成——部分 SEO 插件使用 menu_ordersitemap.xml 中确定页面抓取顺序的优先级
  • 程序化页面树——由 wp_list_pages() 配合 sort_column=menu_order 渲染

了解这一点可以避免一个常见错误:开发者在菜单编辑器中重新排列页面,以为问题已解决,却发现主题的页面循环或站点地图仍然反映旧的字母顺序。

方法一:Simple Page Ordering 插件(大多数网站推荐)

由 10up 开发的 Simple Page Ordering 是拥有数百个页面以内的网站最高效的解决方案。它接管标准 WordPress 后台列表表格,使每一行都可拖动,并在每次放置事件时通过 AJAX 将更新后的 menu_order 值写回数据库。

安装

  1. 在 WordPress 后台,导航至插件 > 安装插件
  2. 搜索 Simple Page Ordering
  3. 点击立即安装,然后点击启用

重新排列页面

  1. 前往页面 > 所有页面
  2. 将鼠标悬停在任意页面行上——左侧会出现拖动手柄。
  3. 将行拖动到所需的顺序位置。
  4. 松开鼠标——顺序通过 AJAX 自动保存,无需点击”保存”按钮。

插件底层工作原理

每次拖放操作都会向 wp-admin/admin-ajax.php 发送一个 POST 请求,携带操作 simple_page_ordering 以及按新顺序排列的文章 ID 序列化数组。WordPress 随后遍历该数组并执行单独的 UPDATE wp_posts SET menu_order = %d WHERE ID = %d 查询。在拥有数百个页面的大型网站上,这可能会产生大量数据库写入——如果您使用的是有查询频率限制的共享环境,这一点值得关注。

局限性

  • 该插件仅影响支持 page-attributes 的文章类型。自定义文章类型必须在 register_post_type() 中明确注册 'supports' => ['page-attributes']
  • 后台列表表格的分页可能造成混淆:将页面拖到第 2 页顶部并不会自动将其置于第 1 页最后一项之后。在跨分页边界重新排序之前,您必须在”屏幕选项”中增加每页显示数量,以便在一个屏幕上查看所有页面。
  • 该插件不会对导航菜单中的页面进行重排——导航菜单由独立的 wp_term_relationships 结构控制。

方法二:页面属性——手动分配 menu_order

WordPress 在经典编辑器和区块编辑器中均原生提供 menu_order 字段。此方法无需插件,适用于需要为少量页面设置精确数字顺序,或需要以编程方式批量更新的场景。

区块编辑器(Gutenberg)

  1. 打开要重新排列的页面。
  2. 在右侧边栏中,点击页面选项卡(非区块选项卡)。
  3. 向下滚动至页面属性
  4. 找到顺序字段并输入一个整数。
  5. 点击更新保存

经典编辑器

  1. 打开页面编辑器。
  2. 在右侧边栏中,找到页面属性元框。
  3. 顺序字段中输入值。
  4. 点击更新

排序逻辑

menu_order 值较小的页面排在前面。值相同的页面则按标题字母顺序排列。一个实用的惯例:

页面标题期望位置`menu_order` 值
首页第 1 位1
关于我们第 2 位2
服务第 3 位3
作品集第 4 位4
联系我们第 5 位5

如果预计以后需要在现有页面之间插入新页面,建议在值之间留出间隔(例如 10、20、30)——这样每次添加页面时就无需对所有页面重新编号。

通过 WP-CLI 批量更新(编程方式)

对于从其他 CMS 迁移或需要一次性重组数十个页面的网站,逐一手动编辑每个页面并不现实。请使用 WP-CLI:

wp post update 42 --menu_order=1
wp post update 57 --menu_order=2
wp post update 61 --menu_order=3

或使用 shell 脚本遍历数组:

declare -A pages=([42]=1 [57]=2 [61]=3 [78]=4)
for post_id in "${!pages[@]}"; do
  wp post update "$post_id" --menu_order="${pages[$post_id]}"
done

直接更新数据库(高级)

如果 WP-CLI 不可用,且需要批量更新 menu_order 值,可以直接运行 SQL。请务必先备份。

UPDATE wp_posts SET menu_order = 1 WHERE ID = 42 AND post_type = 'page';
UPDATE wp_posts SET menu_order = 2 WHERE ID = 57 AND post_type = 'page';
UPDATE wp_posts SET menu_order = 3 WHERE ID = 61 AND post_type = 'page';

当您在 VPS 主机环境中管理 WordPress,拥有直接的 MySQL 访问权限,并需要在单次维护窗口内对多个网站应用结构性变更时,此方法尤为实用。

方法三:WordPress 菜单编辑器——重新排列导航显示

外观 > 菜单编辑器控制页面在网站导航菜单中的显示顺序——这与 wp_posts 中的 menu_order 完全独立。此处的更改不会影响 WP_Query 结果、REST API 响应或 wp_list_pages() 输出。

在以下情况下使用此方法:

  • 您的主题从已注册的菜单位置渲染导航(几乎所有现代主题都如此)
  • 您希望导航栏中的页面顺序与页面列表中使用的结构性 menu_order 不同
  • 您需要将页面嵌套为子项(下拉菜单),而无需更改其实际的 WordPress 父级

操作步骤

  1. 导航至外观 > 菜单
  2. 从下拉列表中选择现有菜单,或点击创建新菜单
  3. 在左侧的页面面板中,勾选要包含的页面,然后点击添加到菜单
  4. 菜单结构面板中,将项目拖动到所需顺序。
  5. 若要创建子项(下拉子菜单),将菜单项稍微向右拖动至其目标父项下方。
  6. 点击保存菜单

关键区别:菜单顺序与页面顺序

这是许多 WordPress 管理员引入隐性错误的地方。考虑以下场景:您的主题在侧边栏中使用 wp_list_pages() 显示页面索引。您在外观 > 菜单中重新排列了页面,但侧边栏列表保持不变。这是预期行为——wp_list_pages()wp_posts 读取 menu_order,而非从菜单结构读取。要修复侧边栏,必须使用方法一或方法二。

方法四:全站编辑器(区块主题)——导航区块

运行区块主题(Twenty Twenty-Three、Kadence、GeneratePress 区块变体)的网站使用全站编辑器,而非外观 > 菜单。全站编辑器中的导航区块拥有自己的拖放界面。

  1. 前往外观 > 编辑器
  2. 点击页眉模板中的导航区块。
  3. 使用列表视图面板(顶部工具栏中的三线图标)查看所有导航项。
  4. 在列表视图中拖动项目以重新排序。
  5. 点击保存

底层数据模型与经典菜单系统相同——WordPress 将全站编辑器导航菜单存储为 wp_navigation 文章——但编辑界面完全不同。

方法五:使用 pre_get_posts 以编程方式重新排序

对于构建自定义主题或插件的开发者,无需依赖数据库中的 menu_order 值来强制执行页面顺序,最简洁的方式是挂钩 pre_get_posts 并在执行前覆盖查询参数。

add_action( 'pre_get_posts', function( WP_Query $query ) {
    if ( ! is_admin() && $query->is_main_query() && $query->is_post_type_archive( 'page' ) ) {
        $query->set( 'orderby', 'menu_order' );
        $query->set( 'order', 'ASC' );
    }
});

将此代码添加到主题的 functions.php 或特定站点插件中。这可确保任何使用主查询循环的模板都遵循 menu_order,而无需编辑模板文件。

对比:所有方法一览

方法影响数据库中的 `menu_order`影响导航菜单显示需要插件最适合
Simple Page Ordering 插件页面较多的网站、非技术编辑人员
页面属性(顺序字段)小型网站、精确数字控制
WP-CLI 批量更新开发者、迁移、批量操作
直接 SQL 更新拥有数据库访问权限的高级管理员
外观 > 菜单仅用于导航显示
全站编辑器导航区块区块主题
pre_get_posts 钩子需要覆盖查询行为的开发者

常见陷阱与边缘情况

分页边界拖放问题:如上所述,Simple Page Ordering 无法通过单次拖动将页面从后台列表第 2 页移动到第 1 页的位置。在重新排序之前,请在屏幕选项中增加每页显示数量。

子页面继承父级上下文:使用页面属性时,menu_order 的作用范围限于同一父级下的同级页面。menu_order=1 的子页面将在其同级页面中排在首位,但其相对于不同父级下页面的位置则无关紧要。

缓存层失效问题:通过 SQL 或 WP-CLI 批量更新 menu_order 后,页面查询的对象缓存条目可能仍反映旧顺序。在使用 Redis 或 Memcached 对象缓存的网站上,请明确刷新缓存:

wp cache flush

在运行全页缓存(WP Rocket、LiteSpeed Cache、Nginx FastCGI 缓存)的网站上,也需要清除页面缓存,否则访客在缓存 TTL 期间将看到过时的导航。

REST API 消费者:如果解耦前端(Next.js、Nuxt、React)从 WordPress REST API 获取页面,必须明确请求 orderby=menu_order——REST API 对页面的默认排序是按日期降序。请相应更新您的 API 调用:

GET /wp-json/wp/v2/pages?orderby=menu_order&order=asc&per_page=100

多站点安装:在 WordPress 多站点中,menu_order 是按站点独立存储的。运行网络范围的 WP-CLI 命令需要为每个子站点指定 --url=,或使用带有自定义循环的 --network

主机环境注意事项

您选择的方法可能取决于您的主机配置。在托管的共享虚拟主机方案中,直接数据库访问可能仅限于 phpMyAdmin,使得 WP-CLI 或原始 SQL 更新不够便捷——插件或页面属性方法更为实用。在带 cPanel 的 VPS 上,您通常拥有完整的终端访问权限,使 WP-CLI 成为批量操作最快捷的选择。在拥有 root 访问权限的裸独立服务器上,直接 MySQL 查询和 WP-CLI 脚本可以集成到部署流水线或维护定时任务中。

如果您管理多个 WordPress 安装并需要在各环境中保持一致的页面顺序,将 menu_order 分配编写到 WP-CLI 脚本中并作为部署流程的一部分运行是最可靠的方法——它消除了手动步骤,且可进行版本控制。

对于需要在 WordPress 网站旁配备专业电子邮件服务的网站,将主机与专用邮件托管服务配合使用,可确保您的联系和支持页面——这些页面通常需要突出排序——得到同样可靠的通信基础设施支持。

技术要点核查清单

在选择重排方法之前,请确认以下事项:

  • 明确您实际要重排的内容。导航菜单顺序与 wp_posts 中的 menu_order 是相互独立的。确认您的主题读取的是哪一个。
  • 检查主题的页面循环。它使用的是 wp_list_pages()、自定义 WP_Query,还是已注册的菜单位置?每种方式从不同的数据源读取。
  • 在编辑工作流中使用 Simple Page Ordering——适用于非技术用户需要定期重排页面而无需开发者介入的场景。
  • 在需要精确控制时使用页面属性或 WP-CLI——适用于需要特定数值或正在编写迁移脚本的场景。
  • 切勿单独使用外观 > 菜单——如果您的目标是影响由 WP_Query 驱动的页面列表、站点地图或 REST API 消费者。
  • 批量更新 menu_order 后刷新对象缓存和页面缓存,确保所有层级立即反映新顺序。
  • menu_order 编号中留出间隔(使用 10、20、30 而非 1、2、3),以便将来插入新页面时无需全部重新编号。
  • 对于无头 WordPress 设置,在 REST API 请求中始终明确传递 orderby=menu_order&order=asc——不要假设默认排序。

常见问题解答

在外观 > 菜单中更改页面顺序会影响 SEO 吗?

不会。导航菜单顺序对 wp_posts 中的 menu_order、站点地图优先级或抓取顺序没有直接影响。但是,如果您的主题从 wp_list_pages() 生成面包屑或页面索引,这些内容由数据库中的 menu_order 驱动——请使用方法一或方法二单独更新。

为什么更新页面后页面顺序会重置?

这通常发生在某个插件或主题钩子在保存时运行 wp_update_post() 并明确传递 menu_order=0 的情况下。请使用 add_action('save_post', ...) 钩子审查您的活跃插件,检查是否有插件覆盖了 menu_order 字段。Simple Page Ordering 插件无法防止这种情况——您需要找到并修复冲突的钩子。

在区块编辑器中可以不使用插件重新排列页面吗?

可以。打开任意页面,在右侧边栏中点击页面选项卡,展开页面属性,设置顺序整数字段。这将直接写入 wp_posts 中的 menu_order,无需插件。

Simple Page Ordering 支持自定义文章类型吗?

仅当自定义文章类型注册了 'supports' => ['page-attributes'] 时才支持。如果您控制文章类型的注册,请添加该支持字符串。如果是第三方文章类型,您可以在 functions.php 中以编程方式添加支持:

add_post_type_support( 'your_post_type_slug', 'page-attributes' );

menu_order 的最大值是多少?

wp_posts 中的 menu_order 列是一个有符号 32 位整数(INT(11)),因此最大值为 2,147,483,647。实际使用中,建议最多使用几百以内的值——极大的值可能会在某些主题函数中导致意外行为,因为这些函数会对 menu_order 进行算术运算以计算视觉偏移量。

15%

全场主机优惠15%

测试技能,享折扣

使用代码:

Skills
开始使用