没有不值得去解决的问题,也没有不值得去学习的技术!

WordPress Multi-Domain Architecture Paused: Re-evaluating the Maintainability of en, admin, W3TC, and Multiple CDNs

【图 1,后台发布新文章后,中文首页仍未显示新文章】

Over the past few days, I made several adjustments to the blog’s multilingual setup, backend entry point, and CDN architecture:

  • Migrated the English site from /en/ to en.shuijingwanwq.com
  • Migrated the WordPress backend to admin.shuijingwanwq.com
  • The Chinese main site continues to use EdgeOne
  • The English site and media subdomains use Cloudflare
  • Retained W3 Total Cache’s Page Cache and Object Cache
  • Added several fixes for compatibility issues with Polylang, W3TC, SlyTranslate, and others

Individually, these adjustments each had a clear purpose:

  • A dedicated domain for the English site facilitates multilingual site management
  • A dedicated backend domain bypasses the frontend CDN, reducing the chance of backend operations being affected by CDN timeouts and cache rules
  • Using different CDNs for the Chinese site, English site, and media resources balances access speed and traffic costs
  • Page Cache and Object Cache significantly reduce the overhead of dynamically generating WordPress pages

However, as the adjustments piled up, I began to notice a more significant issue:

Although the current architecture works, it is increasingly relying on multiple patches, MU Plugins, and direct plugin source code modifications to maintain compatibility.

If I continue adding code every time a problem arises, it might fix failures in the short term, but it will increase compatibility risks after upgrading WordPress, plugins, and PHP in the long run.

Therefore, I decided to temporarily stop adding fix code and first conduct a re-evaluation of the entire architecture.


1. Issues That Triggered This Architecture Review

The initially discovered issue was that the CTA insertion logic, which originally displayed correctly at the bottom of English article pages, suddenly stopped working.

After checking the code, I found that the original language detection still relied on:

Plaintext
strpos($_SERVER['REQUEST_URI'], '/en/')

After migrating the English site to an independent subdomain, the English article URLs became:

Plaintext
https://en.shuijingwanwq.com/2026/...

The request path no longer contains /en/, so English pages were incorrectly identified as Chinese pages.

This issue itself is not complicated; it can be fixed by prioritizing Polylang’s language API and using the current domain as a fallback.

But then I discovered a phenomenon with a broader impact:

After publishing a new article from the admin.shuijingwanwq.com backend, the www.shuijingwanwq.com homepage still showed old content.

Even when clicking “Purge All Caches” in the W3 Total Cache backend, the caches for the Chinese homepage and English pages were not necessarily cleared correctly.

This indicates that the problem is no longer just about a piece of CTA code not adapting to the new domain, but rather:

Plaintext
Backend operation domain

WordPress current execution context

Polylang language domain

W3TC Page Cache

Redis Object Cache

EdgeOne / Cloudflare

The entire cache invalidation chain needs to be re-verified.

[Figure 1: After publishing a new article from the backend, the Chinese homepage still does not show the new article]
[Figure 1: After publishing a new article from the backend, the Chinese homepage still does not show the new article]

[Figure 2: W3 Total Cache backend "Purge All Caches" operation entry]
[Figure 2: W3 Total Cache backend “Purge All Caches” operation entry]

2. Is the Current Architecture on the Wrong Track?

After this round of analysis, I believe the current architecture is not fundamentally wrong, but some implementation approaches need to be consolidated.

The current structure is roughly as follows:

Plaintext
WordPress single site

├── admin.shuijingwanwq.com
│   └── Login, editing, publishing, and backend management

├── www.shuijingwanwq.com
│   ├── Chinese frontend
│   └── EdgeOne

├── en.shuijingwanwq.com
│   ├── English frontend
│   └── Cloudflare

└── media.shuijingwanwq.com
    ├── WordPress uploaded files
    └── Cloudflare

Among these, Polylang officially supports using subdirectories, subdomains, or independent domains to distinguish languages, so migrating the English site to en.shuijingwanwq.com is a standard multilingual URL approach.

What truly increases complexity is:

Plaintext
admin.shuijingwanwq.com

It is not tied to any content language, yet it handles all article saving, plugin updates, and cache clearing operations.

This means that operations triggered from the backend can no longer simply treat the current request domain as the frontend cache target.

However, even if the backend continued to use www, adding languages like Japanese and German in the future would still require handling Page Cache across multiple language domains. Therefore, the independent admin domain did not create a completely new problem; it just brought the Chinese default language into the scope of cross-domain cache coordination.

Looking at the long-term goals, the independent backend domain can be retained, but clear boundaries must be established:

admin is only responsible for backend management; it does not belong to any language and should not be the final target domain for Page Cache.


3. Why Does Polylang Also Involve “Caching”?

During the analysis, I briefly questioned the fact that “Polylang caches the homepage URLs for each language.”

Polylang is a multilingual plugin, so why does it participate in caching?

After re-examining the distinction, I realized that the cache here is not a full web page HTML cache.

Polylang repeatedly calculates:

Plaintext
zh → https://www.shuijingwanwq.com/
en → https://en.shuijingwanwq.com/

Themes, language switchers, navigation menus, SEO plugins, and other components might all fetch the homepage URL for a specific language multiple times during a single request.

The pll_home_url() provided by Polylang is the interface used to return the homepage URL for a specified language.

Therefore, what Polylang caches are the computed results like language URLs and language configurations, not the final page.

The caching on the site can currently be divided into four layers:

Cache LayerMain ContentResponsible Component
Multilingual URL computationHomepage and content URLs for each languagePolylang
Object CachePosts, options, terms, and query objectsWordPress, W3TC, Redis
Page CacheFinal generated full HTMLW3 Total Cache
CDN CacheHTML and static assets at edge nodesEdgeOne, Cloudflare

The responsibilities of these four cache layers are not the same.

The real problem is not that there are too many cache layers, but whether each layer can form a complete and reliable invalidation loop after content is updated.


4. Both W3TC Page Cache and Object Cache Need to Be Retained

In this architecture review, I do not plan to simplify the problem by disabling W3TC Object Cache.

I had previously conducted actual performance tests. The test results showed that the root cause of the significant performance drop was not the CDN itself, but the disabling of W3 Total Cache Page Cache.

After re-enabling Page Cache, metrics like TTFB, FCP, and LCP all improved significantly. The previous empirical conclusion was:

Plaintext
CDN + Page Cache + Object Cache

These three together form a complete caching system.

Specifically:

Page Cache

Responsible for storing full HTML pages, such as:

Plaintext
Homepage
Article pages
Category pages
Tag pages
Series archives
Feed
Paginated pages

Page Cache is closely tied to the domain.

Under the same WordPress installation:

Plaintext
www.shuijingwanwq.com
en.shuijingwanwq.com

will generate their own page caches respectively.

When new language domains are added in the future, corresponding page cache directories will continue to be added.

Object Cache

Responsible for caching:

Plaintext
Post objects
Category and tag objects
WordPress configuration items
Database query results
Polylang configuration
Theme and global style related objects

Object Cache reduces repeated PHP and MySQL reads and computations, which remains practically valuable for WordPress sites with a large number of articles.

Therefore, the correct direction moving forward is not to disable caching, but to fix the cache invalidation mechanism:

Retain Page Cache and Object Cache, and ensure that backend operations can correctly update the caches for the corresponding language domains.


5. TMS Extensions for Polylang Still Needs to Be Retained

In this evaluation, I also checked whether existing plugins could be replaced by native Polylang features.

TMS Extensions for Polylang provides several multilingual blocks suitable for block themes, including:

  • Language Switcher Advanced
  • Language Visibility
  • Menu by Language
  • HTML Sitemap for Polylang

Among these, Menu by Language can map different WordPress Navigation menus to different Polylang languages.

My website currently uses this menu block in practice.

Therefore, even though Polylang itself provides language switcher-related blocks, it still cannot fully replace the currently used Menu by Language functionality.

The final conclusion is:

TMS Extensions for Polylang needs to be retained.

However, to handle compatibility issues earlier, I had directly modified the plugin’s files. Moving forward, these modifications need to be reverted to the official version, and the issue should be resolved using one of the following methods:

  1. Use Hooks or Filters provided by the plugin
  2. Add safeguards in an independent compatibility plugin
  3. Submit an issue or patch to the plugin author
  4. Wait for an official fix in an upstream release

Continuing to treat direct plugin source code modifications as a long-term solution is not viable.


6. The Two Third-Party Plugins with Direct Modifications Need to Be Addressed

In the latest round of adjustments, two third-party plugins have been directly modified:

Plaintext
TMS Extensions for Polylang
SlyTranslate

These modifications solved specific problems in the short term but also introduced clear risks:

  • Local modifications will be overwritten after a plugin upgrade
  • It is impossible to directly determine whether the current file still matches the official version
  • When issues arise, it is difficult to distinguish between a plugin’s own fault and a local modification
  • When migrating to client websites in the future, relying on manual plugin file modifications is not feasible
  • Fixes may be lost after a server reinstall or plugin reinstallation

Therefore, a clear principle needs to be established moving forward:

Files in third-party plugin directories must be kept as close to their official original state as possible.

Acceptable extension methods include:

Plaintext
WordPress Hook / Filter
Independent standard plugin
MU Plugin
wp-config.php constants
Official Provider or extension interfaces provided by the plugin

However, MU Plugins cannot be added indefinitely either.

What really needs to be controlled is not “whether custom code exists,” but:

Plaintext
Whether the code is centralized
Whether responsibilities are singular
Whether it relies on public interfaces
Whether it can be restored after deactivation
Whether it will be overwritten after an upgrade

7. How Many Problems Can Ready-made, Open-source, and Free Solutions Solve?

Before continuing to write my own code, I need to prioritize confirming whether mature open-source solutions already exist.

After a preliminary review, they can currently be categorized into a few types.

1. Cloudflare Automatic Cache Purge

The official Cloudflare WordPress plugin provides Automatic Cache Management.

When an article, page, attachment, or comment is added, modified, or deleted, it can purge the relevant Cloudflare cached URLs; theme switches and theme customizations will also trigger cache updates.

Therefore, purging the Cloudflare cache for the English site does not necessarily require calling the Cloudflare API manually.

However, since the backend currently runs on the admin domain, before enabling it, I still need to verify whether the purge URLs generated by the plugin will correctly point to:

Plaintext
en.shuijingwanwq.com

instead of:

Plaintext
admin.shuijingwanwq.com

So for now, the Cloudflare plugin remains disabled, to be evaluated after the origin W3TC cache chain stabilizes.

2. EdgeOne Automatic Cache Purge

An automatic cache purge plugin for Tencent Cloud EdgeOne already exists in the WordPress plugin directory.

For example, Naibabiji Cache Purger for EdgeOne claims to support:

  • Automatic purge after article publishing, updating, and deletion
  • Homepage cache purge
  • Category and tag archive purge
  • Author and date archive purge
  • Purging related articles after a comment is approved
  • Integration with caching plugins like W3 Total Cache

This indicates that EdgeOne API signing, cache purging, and error handling do not necessarily all need to be implemented manually.

However, these plugins still need to be reviewed for the following issues first:

Plaintext
Whether it supports an independent admin backend domain
Whether it generates URLs based on the Polylang article language
Whether it will incorrectly purge the en domain
Whether it supports language domains added in the future
Whether it will trigger simultaneously with W3TC
How API credentials are stored

Therefore, it can serve as a priority candidate for the third phase, but it is not directly enabled on the production site right now.

3. W3TC Multilingual Page Cache

For this layer, I have not yet found a plug-and-play plugin that fully satisfies the current structure.

Standard plugins can typically handle:

Plaintext
One WordPress
One frontend domain
One CDN

Whereas the actual current requirements are:

Plaintext
One WordPress
One independent backend domain
Multiple Polylang language domains
Different CDNs for different language domains

This part may still require a small amount of custom coordination code.

However, the responsibilities of the custom code must be strictly limited to:

Based on the Polylang language the article belongs to, finding the correct frontend domain and calling W3TC’s existing cache purge interface.

It must not reimplement W3TC, nor should it take on CDN, translation, backend URLs, and other unrelated functionalities.

4. SlyTranslate Alternatives

Other Polylang AI translation plugins can currently be found, but I have not yet confirmed the existence of a solution that can fully replace current requirements.

The current requirements are not just standard short text translation, but also include:

Plaintext
Zhipu GLM-5.2
Long-form WordPress articles
Gutenberg block structure
Complex HTML
Code blocks preserved as-is
Ultra-long output
Chinese-English article association

Therefore, the current solution should not be immediately replaced just because other AI translation plugins exist.

A more realistic goal is:

  • Restore SlyTranslate’s official files
  • Adjust requests via Providers, Hooks, or an independent MU Plugin wherever possible
  • No longer directly modify internal plugin files
  • Test other open-source plugins separately later to see if they can meet current translation quality and structure preservation requirements

8. Should the Independent Admin Domain Be Retained?

After re-evaluation, I decided to temporarily retain:

Plaintext
admin.shuijingwanwq.com

There are three reasons.

1. The Backend Can Bypass the Frontend CDN

WordPress logins, plugin upgrades, article saving, and media operations no longer directly pass through EdgeOne’s frontend caching and acceleration chain.

2. Clearer Backend Address

For websites I maintain myself and future client websites:

Plaintext
admin.example.com

is easier to explain and manage than mixing the backend entry point into a standard frontend domain.

3. The Multilingual Caching Problem Itself Still Exists

Even if the backend reverts to:

Plaintext
www.shuijingwanwq.com/wp-admin/

The Page Cache for the English site and future other language domains will still need to be purged separately.

The independent admin domain just brought the Chinese domain into the cross-domain coordination scope; it did not create the entire multilingual caching problem.

However, retaining admin comes with one prerequisite:

Moving forward, we cannot continue using scattered code to make every plugin adapt to admin individually.

The correct approach should be to establish stable boundaries:

Plaintext
admin
→ Only responsible for backend management

Polylang
→ Responsible for identifying article language and language domain

W3TC
→ Responsible for origin Page Cache and Object Cache

EdgeOne / Cloudflare
→ Responsible for their respective edge caches

9. Re-determined Implementation Sequence

After this pause and analysis, the subsequent plan is adjusted into the following phases.

Phase 1: Inventory and Freeze Current Changes

Stop adding new plugins and new code for now.

Need to complete:

Plaintext
List all MU Plugins
List all WPCode snippets
Confirm file differences in the two modified plugins
Save comparison between official version and current version
Record the purpose of each piece of compatibility code

The goal is to first clarify exactly what custom behaviors exist on the current site.

Phase 2: Fix the W3TC Origin Cache Loop

This phase only handles:

Plaintext
Publishing or updating an article from the admin backend

Read the Polylang language the article belongs to

Obtain the official frontend domain for that language

Purge the W3TC Page Cache for the corresponding article, homepage, and related archives

It needs to support language domains added in the future, and must not hardcode:

Plaintext
www
en

Instead, it should dynamically read the Polylang language configuration.

Object Cache will continue to be retained, relying as much as possible on native WordPress and W3TC invalidation mechanisms.

Phase 3: Restore Backend One-click Cache Purge for All Languages

After clicking “Purge All Caches” once in the backend, it should be able to purge:

Plaintext
www
en
Future new language domains
Shared Object Cache

admin itself is not a content site and should not be treated as a language page cache target.

Phase 4: Integrate CDN Automatic Cache Purge

After the origin cache stabilizes, then evaluate separately:

Plaintext
Official Cloudflare plugin
EdgeOne automatic purge plugin

Prioritize using ready-made, open-source, free plugins.

Only when ready-made plugins cannot correctly handle Polylang and the independent backend domain should minimal adaptation code be added.

Phase 5: Revert Third-Party Plugin Source Code Modifications

The ultimate goals are:

Plaintext
TMS Extensions for Polylang
→ Restore official version

SlyTranslate
→ Restore official version

Custom requirements
→ Accomplished via public Hooks, Providers, or independent compatibility plugins

10. Final Conclusions After This Review

After this round of analysis, the following conclusions can now be drawn fairly clearly.

Continue to Retain

Plaintext
Polylang multilingual domains
en.shuijingwanwq.com
admin.shuijingwanwq.com
media.shuijingwanwq.com
W3 Total Cache Page Cache
W3 Total Cache Object Cache
Redis
EdgeOne
Cloudflare
TMS Extensions for Polylang

Temporarily Suspend

Plaintext
Continuing to add scattered MU Plugins
Continuing to directly modify third-party plugins
Immediately enabling the Cloudflare plugin
Immediately installing the EdgeOne automatic purge plugin
Simultaneously debugging origin cache and CDN cache

Subsequent Focus

Plaintext
Inventory first
Then restore the W3TC cache loop
Then handle one-click purge
Finally, integrate EdgeOne and Cloudflare

11. Phased Summary

The most important takeaway this time is not immediately finding a piece of PHP code that solves all problems.

What is truly valuable is stopping before continuing to add patches, and re-clarifying the responsibilities of each component:

Plaintext
Polylang handles languages
W3TC handles origin caching
Redis handles object caching
EdgeOne and Cloudflare handle edge caching
admin handles the backend entry point

The current architecture is not completely unusable, nor does it need to be torn down and rebuilt.

What really needs to be avoided is:

Directly modifying plugins or adding code targeted only at the current domain every time a new problem appears.

Through this re-evaluation, I have at least clarified:

  • Which components must be retained
  • Which source code modifications need to be reverted
  • Which requirements can prioritize finding open-source plugins
  • Which parts genuinely require a small amount of custom adaptation
  • What sequence to follow moving forward

This pause is not about stopping optimization, but rather about making subsequent adjustments controllable, verifiable, and more suitable as a reusable practice for future client websites.

系列导航

需要长期技术维护或远程问题排查?

我是拥有 15+ 年经验的 PHP / Go 后端工程师,长期关注已有系统维护、Bug 修复、性能优化、服务器排查、WordPress 网站维护和小功能迭代。

如果你的项目遇到以下情况,可以先从一次小问题排查开始合作:

  • ✅ PHP / Laravel / Yii2 老项目无人维护
  • ✅ Go / Gin 后端接口需要排查或优化
  • ✅ WordPress 网站访问慢、报错或插件冲突
  • ✅ Nginx / MySQL / Redis / Linux 服务器异常
  • ✅ CDN / Cloudflare / DNS / HTTPS 配置问题
  • ✅ 需要长期远程技术支持或兼职维护

更多介绍请查看:关于我 & 合作

微信:13980074657
邮箱:shuijingwanwq@gmail.com
Telegram:@shuijingwan
GitHub:https://github.com/shuijingwan

评论

发表回复

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

这个站点使用 Akismet 来减少垃圾评论。了解你的评论数据如何被处理