v1.7.0 — internal post embeds keep working
Bug fix release. Update if your site embeds its own posts.
Disabling oEmbed also broke embeds of the site's own posts. PH_DISABLE_OEMBED removed the oEmbed REST route, the json+oembed discovery link and the /embed/ rewrite rule in one go — WordPress needs all three for an internal embed. The <iframe> is still emitted, but it starts at visibility: hidden and only appears once /embed/ posts back its height; with the route gone that URL returns 404, so the card never shows and visitors see only the <blockquote> fallback link. Nothing on screen hints at the cause. Found on a live site that uses internal embeds as part of its content layout.
The switch is now split in two, because the two halves have very different trade-offs:
| Constant | Default | Behaviour |
|---|---|---|
PH_DISABLE_OEMBED_EXTERNAL |
true |
Disables embed_oembed_discover, so pasted links to unknown hosts are not probed. YouTube, X, Vimeo and everything else on the built-in provider list still embed |
PH_DISABLE_OEMBED_ROUTES |
false |
Disables this site's own oEmbed REST endpoint, discovery links and /embed/ routes |
PH_DISABLE_OEMBED still works and pins both fields, so existing wp-config.php files need no edit — set it to false if your site uses internal embeds. If you had "Disable oEmbed" ticked in the admin, only the external half carries over on upgrade; the routes return to the new default, so internal embeds recover from the upgrade alone. Re-tick the setting if you still want them gone.
Crawl load on /embed/ is now handled with headers rather than removal: X-Robots-Tag: noindex, follow and Cache-Control: public, max-age=3600, s-maxage=86400. Disallow: /*/embed/ goes into robots.txt only when the routes are actually removed — blocking crawlers stops them reading the noindex, which can strand existing URLs as "indexed, though blocked by robots.txt".
Rewrite rules now rebuild automatically after a version change, including mu-plugin installs where no activation hook runs.
Verified on WordPress 7.0.2: default and hardened modes, both constant forms, the legacy option migration, the admin save round-trip and the mu-plugin upgrade path.
修正版本,站上有使用「內部文章嵌入」者請更新。
停用 oEmbed 會連自家文章的內部嵌入一起關掉。PH_DISABLE_OEMBED 會一併移除 oEmbed REST 路由、<head> 的 json+oembed discovery link 與 /embed/ 的 rewrite rule,而 WordPress 的內部嵌入三者缺一即壞。<iframe> 仍會輸出,但它初始為 visibility: hidden,要等 /embed/ 回傳高度才會現形;路由移除後該網址回 404,卡片因此永遠不顯示,訪客只看得到後備的 <blockquote> 純連結,畫面上沒有任何線索指出原因。此問題於實際站台(把內部嵌入當成內容編排一部分)重現。
該開關拆成兩段,因為兩者的取捨完全不同:
| 常數 | 預設 | 行為 |
|---|---|---|
PH_DISABLE_OEMBED_EXTERNAL |
true |
停用 embed_oembed_discover,不對未知網址發出探測請求。核心 provider 清單上的 YouTube、X、Vimeo 等仍可正常嵌入 |
PH_DISABLE_OEMBED_ROUTES |
false |
停用自家的 oEmbed REST 端點、discovery link 與 /embed/ 路由 |
舊的 PH_DISABLE_OEMBED 仍然有效,會同時鎖定兩個欄位,既有 wp-config.php 不需修改——站台若使用內部嵌入,將其設為 false 即可。後台曾勾選「停用 oEmbed」者,升級後該值只沿用到外部探索,路由回到新的預設,內部嵌入光是升級就會恢復;仍想移除路由請於後台重新勾選。
/embed/ 的爬取成本改以標頭收斂而非移除端點:送出 X-Robots-Tag: noindex, follow 與 Cache-Control: public, max-age=3600, s-maxage=86400。robots.txt 的 Disallow: /*/embed/ 僅在路由確實已移除時才寫入——Disallow 會讓爬蟲讀不到 noindex,既有網址反而可能以「已建立索引但遭封鎖」的狀態長期滯留。
rewrite rules 現在會於版本變動時自動重建,mu-plugin 模式(沒有啟用 hook)同樣涵蓋。
已於 WordPress 7.0.2 驗證:預設與收斂兩種模式、兩種常數寫法、舊選項的升級承接、後台儲存往返,以及 mu-plugin 的升級路徑。
升級後:先前失敗的嵌入結果仍留在 WordPress 的 oEmbed 快取(oembed_cache post type 與 _oembed_* postmeta),請重新儲存該篇文章,或執行 wp transient delete --all,卡片才會重新抓取。
安裝:後台「外掛 → 安裝外掛 → 上傳外掛」上傳附件 ZIP。
完整變更紀錄見 CHANGELOG.md