Skip to content

v1.7.0 — internal post embeds keep working

Choose a tag to compare

@ivanusto ivanusto released this 01 Aug 02:44
· 5 commits to main since this release

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, followCache-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