我有一个使用Yoast for SEO的Wordpress 4.3网站。我有一个自定义帖子类型和一个短代码,可用于生成该类型的帖子列表。短代码函数使用我认为是Wordpress中的recommended approach来生成某种类型的帖子列表:
$query = new WP_Query(...);
while ($query->have_posts())
{
$query->the_post();
// Now I can call methods like the_ID(), the_permalink(), etc
// I can also access details of the post directly, because at
// this point it is stored in the global $post variable.
}
wp_reset_postdata(); // To restore original copy of global $post variable
查看包含短代码的实际页面时,一切正常,因为全局$wp_query
变量在调用短代码函数之前存储了全局$post
变量的副本,从而启用{{1} }成功恢复全局wp_reset_postdata()
变量的状态。
但是,我最近在编辑页面时发现了一个问题,虽然我已经解决了这个问题,但我想知道我的解决方案是否是Wordpress世界中的正确练习。
问题是每当我编辑页面时,如果没有实际触及任何设置,几个字段就会被更改。进一步的调查显示,原因是编辑页面的HTML,特别是某些表单字段的内容在到达浏览器时已经被修改。使这个问题更加复杂的是,永久链接字段(高度可见)未被更改,但名为$post
的隐藏字段被更改,因此在提交页面时, Wordpress正在使用此现已损坏的隐藏段塞字段的值更新永久链接。毕竟我的固定不是永久性的!
关于导致问题的唯一线索是,正在设置的固定链接属于另一个帖子;事实上,短代码功能执行时会出现一个帖子。
经过一天半的调试,我找出了表单字段被删除的确切原因:
在准备帖子的编辑页面时,Wordpress会调用所有相关插件,以防他们需要向侧栏添加任何其他信息或控件。
一个这样的插件是Yoast,它报告了SEO状态。为了计算这种状态,Yoast默默地呈现帖子,以便它可以分析页面的内容,同时考虑焦点关键字等。
为了让Yoast以静默方式呈现页面,还必须执行为该页面提供输出的所有短代码函数。
当我的短代码功能作为Yoast的无声页面渲染的一部分执行时,它通过调用slug
在最后恢复内容来做我认为正确的事情。全球wp_reset_postdata()
变量。
然而,问题是$post
实际上并没有恢复全局wp_reset_postdata()
变量,因为全局$post
变量没有副本。我希望$wp_query
或wp_reset_postdata()
在此时抛出错误,但他们不会。
因此,在Yoast完成工作后生成的编辑页面中的每个表单字段都会显示错误帖子中的值,因为全局WP_Query->reset_postdata()
变量的内容错误。
我通过将以下防御性/不显眼的代码添加到我的短代码函数顶部来解决问题:
$post
这意味着我的短代码功能只会执行"循环"保证可以使用global $wp_query;
if ( $wp_query->post == null )
{
return '';
}
恢复全局$post
变量。
我应该坚持使用此解决方案还是更进一步,只需保存全局wp_reset_postdata()
变量的副本,然后完全忽略$post
?