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/toen.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:
strpos($_SERVER['REQUEST_URI'], '/en/')
After migrating the English site to an independent subdomain, the English article URLs became:
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.combackend, thewww.shuijingwanwq.comhomepage 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:
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]](https://media.shuijingwanwq.com/2026/07/1-43-1024x566.png)
![[Figure 2: W3 Total Cache backend "Purge All Caches" operation entry]](https://media.shuijingwanwq.com/2026/07/2-41.png)
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:
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:
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:
adminis 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:
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 Layer | Main Content | Responsible Component |
|---|---|---|
| Multilingual URL computation | Homepage and content URLs for each language | Polylang |
| Object Cache | Posts, options, terms, and query objects | WordPress, W3TC, Redis |
| Page Cache | Final generated full HTML | W3 Total Cache |
| CDN Cache | HTML and static assets at edge nodes | EdgeOne, 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:
CDN + Page Cache + Object Cache
These three together form a complete caching system.
Specifically:
Page Cache
Responsible for storing full HTML pages, such as:
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:
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:
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:
- Use Hooks or Filters provided by the plugin
- Add safeguards in an independent compatibility plugin
- Submit an issue or patch to the plugin author
- 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:
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:
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:
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:
en.shuijingwanwq.com
instead of:
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:
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:
One WordPress
One frontend domain
One CDN
Whereas the actual current requirements are:
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:
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:
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:
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:
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:
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:
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:
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:
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:
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:
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:
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
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
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
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:
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


发表回复