WordPress主题开发教程:用AI从零写一个主题的完整流程

倪叶明

作者

更新于

用AI写WordPress主题这件事:AI能把文件骨架几分钟吐出来,可官方文档里写得最重的那几条,全是它不管的。比如functions.php那一节讲得很直接,要做的是跟网站外观无关、不管网站长什么样都该有的功能,最佳做法是放进插件。这一步判断错了,代码写得再顺也得推倒。所以这篇wordpress主题开发教程只讲一件事:一个主题从空目录到能上线,AI站在哪几个位置,哪几个位置必须你自己点。

主题是一个站的地基。它决定页面长什么样、内容按什么顺序出来,地基歪了,后面写多少文章、做多少内链都跟着歪。这一步分两半看:能交给机器做的交给机器,需要人点的位置一次点对。

  • 这是什么:WordPress主题分两类,block theme从5.9起可用,主要由HTML和主题配置文件构成;classic theme主要用PHP、JavaScript和CSS。
  • 官方怎么说:加主题特性必须在functions.php里调用,挂到钩子上只能是after_setup_theme。
  • 怎么做:先搭一个跟线上站分开的开发环境,装好WordPress,用编辑器写文件,再用测试数据和Theme Check这类插件查。
  • 要多少钱、多久:官方页没写价格和工期,按你自己的模板清单估。

主题是什么、由哪些文件组成,写在WordPress主题那篇里;打算先用现成主题练手,可以照5条标准筛免费主题先筛一遍。国内网络能不能正常访问wordpress.org下载这些文件,以官方为准。

先分清block theme和classic theme,你才知道自己写的是哪一类

两类主题的写法差别不小,选错了不是改几行代码的事,是整套文件结构要重来。官方把两类分开写,也建议两节都读一遍,理解差异之后再定做哪一类。

WordPress主题开发手册首页,block theme与classic theme两节入口
官网说明截图:Theme Handbook 把两类主题分开写,建议两节都读。

block theme:从WordPress 5.9起可用,模板是HTML文件

block theme从5.9起可用,主要由HTML和一个主题配置文件构成,整站由区块组成,站点编辑器里能编辑站点的所有部分。模板文件里,index.html是唯一必需的那一个。

classic theme:没有版本限制,靠PHP函数和钩子

classic theme是原始的那类主题,没有版本限制,主要用PHP、JavaScript和CSS,靠WordPress的PHP函数、钩子和过滤器干活。除了基础的index.php,要不要实现某个具体模板文件,由你自己定;不实现就走层级回退。

自建还是拿现成主题改,先定下来

决定写哪一类之前,还有个更前面的问题:从空目录自己写,还是拿一个现成主题做子主题改外观。这两条路的工作量和后面的维护方式不一样,判断标准在套现成主题还是做子主题定制那篇里。把这个定下来,后面拆文件清单才不会反复。

主题开发要懂到什么程度:模板层级、钩子、转义三件事

不用把WordPress核心读完,但有三件事绕不过去,缺一件写出来的主题就会在某类页面上出错。这三件事跟用不用AI没关系,AI生成的代码也得按这三条看。

模板层级:WordPress怎么决定用哪个文件

WordPress用查询字符串决定用哪套模板显示页面,它把每个查询字符串匹配到一个查询类型,再按模板层级的顺序,在主题目录里找对应名字的文件,用第一个匹配到的。名字对不上就跳到层级里的下一个,全都没有,才用主题的index.php。

block theme用HTML文件代替PHP文件,层级的顺序是一样的。另外front-page.html始终优先,你在后台怎么设「首页显示」,改动的只是层级里更靠后的那些模板。

钩子位置错了,功能就白写

add_theme_support()必须在主题的functions.php里调用才生效;如果挂在钩子上,只能是after_setup_theme,挂到init对某些特性来说太晚。文章缩略图这个特性更紧一点,必须在init钩子触发前调用,也就是直接写进functions.php,或者放进挂在after_setup_theme上的函数里。

输出转义、SQL和表单

主题的主要职责是输出内容,任何输出都要转义,动态内容要按数据类型选对应的函数,这是防XSS的基本动作。SQL那边的第一条规则是有WordPress函数就用WordPress函数;查询里的所有数据在执行前必须做SQL转义,最好的选择是$wpdb->prepare()。主题里只要有HTML表单或者基于HTTP的表单提交,就要用nonce确认这个操作是用户本人想做的。

命名:函数、类、变量都得唯一

两个函数、类或者变量重名,站点会报错或者出现说不清的行为,这个责任在写主题的人身上。官方要求给函数和类名加唯一前缀,用主题名或者缩写都行,前缀长度有下限,下一节的表里列了具体数。

用AI从零写一个主题,五步走完

下面这五步按动手顺序排,每一步后面跟一句出问题回查什么,卡住的时候直接对。

  1. 搭一个跟线上站分开的开发环境。官方的话是建主题最好在跟生产站分离的环境里做,本地或者远程服务器都行,本地的一个好处是不联网也能建。官方列的选项有@wordpress/env、Docker、WordPress Studio、Local、MAMP、XAMPP、VVV;环境起来后要装WordPress,有些环境自带安装。编辑器官方列的是VS Code、VIM、Brackets、Notepad++、GNU Emacs、TextMate。回查:主题没出现在后台外观列表里,先看主题目录名和style.css头部信息对不对。
  2. 把需求拆成文件清单。要哪些页面、要不要多语言、要不要自定义菜单,先想清楚,再对照模板层级排出每个页面该用哪个模板文件。先有清单再让AI生成,返工少。回查:某个页面显示得不对,回到层级顺序,看是不是跳到了下一个文件。
  3. 让AI生成基础文件。style.css头部;functions.php里放一个在主题启用时先运行的setup函数,把推荐特性放进去,函数名用主题名做前缀;add_theme_support、register_nav_menus、load_theme_textdomain的调用位置在这一步定死;index.php、single.php、page.php、archive.php先出空壳。classic theme注册菜单用register_nav_menus(),插入菜单用wp_nav_menu();block theme用导航区块。回查:菜单不显示,先看注册和插入是不是成对写的。
  4. 在本地调试。导入测试数据,官方给的是WordPress.org Theme Test Data和WordPress.com Theme Test Data两个来源;装Theme Check、Debug Bar、Query Monitor,classic theme可以再加Monster Widget一次测完核心小工具。然后在后台切换首页显示方式,看front-page和home的回退对不对。回查:报错先看Theme Check出的清单,再去Query Monitor里找那条查询。
  5. 上线前逐条自查。安全看三样:入库前验证和清理、输出前转义、表单有没有nonce;可访问性看跳转链接和键盘焦点高亮,所有控件和链接都要能用键盘到达;代码不能有PHP或JavaScript的错误、警告、通知,不能用弃用的函数和常量;WordPress功能不许放在付费墙后,也不许包含自定义文章类型、短代码这些跟设计和展示无关的东西;用户数据的追踪必须默认关闭,只做主动选择加入;整包代码、数据、图片都要GPL兼容,代码和设计得是你自己的。回查:对着官方Themes Team的评审要求一条条打勾。

官方还有一句值得记住:这些指南在提交官方主题目录时是必须遵守的,但对任何做主题的人也是好原则。写的时候顺手照做,比提交被退回来再改省事。

做主题要守的几个数字和硬门槛

下面这几条是硬杠,动手之前知道,能省掉不少回头路。

项目 数 用在哪
主题前缀长度 至少4个字母 函数、类、变量命名
nonce默认生命周期 一天,24小时等于86400秒 表单、URL校验
可能被关闭为不通过 3个或以上不同问题 提交官方目录前自查
block theme可用版本 WordPress 5.9起 决定写哪一类
官方下载页建议环境 PHP 8.3或更高、MySQL 8.0或MariaDB 10.11或更高 搭开发环境

官方的门槛是能提前看清楚的,不是等被退回来才发现的。

表外还有两条跟版本有关的变化要记:WordPress 6.4起新安装默认不再启用附件页面,但主题在附件页面的显示仍然要测;6.7起load_theme_textdomain()只能在init或更晚调用,放早了会出问题。版本的要求和检查项都固定之后,剩下的才是写代码的时间。

五个最容易踩的坑,和出问题怎么回查

这几个坑有个共同点:本机看着都正常,换环境、换用户、提交审核的时候才露出来。

WordPress官方Nonces文档说明有效期与不可用于授权访问控制
官网说明截图:nonce 有有效期,不能当身份认证和访问控制用。
  • 把跟外观无关的功能塞进functions.php。放插件才对,官方写的是不管网站长什么样都该有的新功能归插件。每个主题都有自己的functions文件,但只有当前启用主题的functions.php里的代码会运行,塞在这里的功能,用户一换主题就没了。
  • add_theme_support()挂到init。某些特性到init已经太晚,改挂after_setup_theme;缩略图这类还要更早。
  • 输出不转义、SQL不走prepare、表单没有nonce。对应的就是XSS、SQL注入和CSRF三个方向的问题。
  • 把nonce当权限用。nonce绝不能用于身份认证、授权或访问控制,保护函数要用current_user_can(),而且要假设nonce可能被攻破。
  • 命名不加前缀或者前缀太短。重名会让站点报错或者出现异常行为,前缀长度不够在官方评审里也是一条。

nonce校验失败长什么样,先记两个:check_admin_referer()校验不过会终止脚本,返回403 Forbidden和一条错误信息;wp_verify_nonce()返回false时不要继续处理请求,常规做法是调用wp_nonce_ays(),同样返回403。另外nonce是跟当前用户会话绑的,用户在另一个标签页登录或者登出,页面上原有的nonce全部失效,这类报错不是代码写错了。

用子主题的还要记两条:子主题里加文件会覆盖父主题的同名文件;但子主题只有通用的category.php、父主题有更具体的category-unicorns.php时,用的是父主题那个更具体的。add_theme_support('post-formats')在子主题里是覆盖父主题定义的格式,不是追加。

版本升级之后主题出问题,先别急着改代码,按主题不兼容新版本怎么办那篇的顺序排查,先确认是主题的问题还是核心或者插件的问题。

AI能接哪几步,哪几件必须你亲手做

AI在主题开发里能站的位置就四个,把边界说清楚比说它能干什么更有用。

  • 需求拆解。你把要哪些页面、要不要多语言、要不要自定义菜单讲清楚,它整理成一份文件清单,对照模板层级排出每个页面用哪个模板文件。
  • 生成基础文件骨架。按官方命名规则出style.css头部、functions.php的setup函数骨架,以及index.php、single.php、page.php、archive.php这些模板文件的空壳。
  • 安全与规范自查。让它逐段看输出有没有转义、SQL有没有走$wpdb->prepare()、表单有没有nonce、函数和类有没有带够长度的前缀。
  • 生成上线测试清单。按Theme Check、Debug Bar、Query Monitor的检查项,列一份逐项打勾的表。

下面三条提示词是本文给的示例,不是官方模板,把主题名换掉就能用。

「我在做一个classic WordPress主题,主题名xxx。请按WordPress模板层级,列出我需要的模板文件清单,每个文件写一句它负责显示什么页面,并说明哪些可以省略、省略后回退到哪个文件。」

「这是我的functions.php草稿。请检查:add_theme_support是否都在after_setup_theme里调用、函数和类是否都带了唯一前缀、load_theme_textdomain的调用位置是不是放在init或更晚。逐条指出问题并给修改后的代码。」

「这是我的模板文件输出部分。请逐行检查每个动态输出是否用了对应数据类型的转义函数,表单是否有wp_nonce_field,SQL是否用了$wpdb->prepare。列出问题行号和改法。」

剩下三件事只能你自己在后台点:

  1. 在本地环境里装好WordPress,把生成的文件放进wp-content/themes/下对应的主题目录,在后台外观里启用,看站点能不能正常打开。
  2. 在后台装Theme Check和Query Monitor,跑一遍,看错误和警告清单,决定哪些必须改、哪些可以留。
  3. 在后台「设置 → 阅读」里切换首页显示方式,最新文章和静态页面各刷一次前台,确认front-page和home的回退符合预期。

主题写完,页面能不能被搜到是另一回事,主题本身对搜索表现的影响写在主题对SEO的影响那篇里。

不想自己搭环境、自己一条条跑检查,猎者出海的AI Agent有一块就是网站开发,从空服务器到上线分几段、每段一道关,主题从零写,不套现成主题。它接的是从环境到上线这一整段活,不是替你把后台那几个开关点完。

常见问题

做WordPress主题开发需要什么基础?

三件事必须懂:模板层级怎么选文件、钩子挂在哪个位置、输出和SQL怎么转义。再加上PHP基础,classic theme的模板文件就是PHP文件;写block theme则要熟悉HTML和区块。

functions.php和插件到底怎么分?

跟网站外观无关、不管网站长什么样都该有的功能放插件,这是官方的最佳实践。每个主题都有自己的functions文件,但只有当前启用主题的functions.php里的代码会运行;子主题的functions.php由WordPress在父主题之前加载,但不覆盖父主题的同名函数;functions.php整体上晚于插件文件加载。

nonce是什么,能当权限用吗?

WordPress的nonce严格说不是数字,是数字和字母组成的哈希,有有效期,过期就失效,也不防重放,因为它不检查一次性使用。它不能用于身份认证、授权和访问控制,权限那件事交给current_user_can()。往URL加用wp_nonce_url(),往表单加用wp_nonce_field(),AJAX请求里用check_ajax_referer()校验。

block theme最少要几个模板文件?

一个就够,官方只把index.html定为必需项,其他模板按需要加。加了名字对不上的文件没用,层级照样按顺序往下找。

主题提交官方目录会被拒吗?

提交到WordPress.org主题目录必须满足全部要求,问题数量到线(3个或以上不同问题)的主题可能被关闭为不通过,作者改完可以重新提交。两条硬要求先记:主题必须GPL兼容,整包代码、数据、图片都要合规;代码和设计必须是你自己的或者合法属于你的,克隆设计不接受。

发表评论

发表回复

您的邮箱地址不会被公开。 必填项已用 * 标注