1- # Map version numbers to their corresponding proxy hosts
2- map $version_number $proxy_host {
1+ # Map core documentation versions to their corresponding proxy hosts
2+ map $doc_version $doc_host {
33 default "";
4- "5" "newbook-5.cakephp.org"; # Current version
5- "4" "newbook-4.cakephp.org";
6- "3" "newbook-3.cakephp.org";
7- "2" "newbook-2.cakephp.org";
4+
5+ # Current stable versions
6+ "5" "newbook-5.cakephp.org";
7+ "4" "newbook-4.cakephp.org";
8+ "3" "newbook-3.cakephp.org";
9+ "2" "newbook-2.cakephp.org";
10+
11+ # Development/pre-release versions
12+ "5.next" "newbook-5next.cakephp.org";
13+ "4.next" "newbook-4next.cakephp.org";
14+ "3.next" "newbook-3next.cakephp.org";
15+
16+ # Legacy versions
17+ "1.3" "newbook-13.cakephp.org";
18+ "1.2" "newbook-12.cakephp.org";
19+ "1.1" "newbook-11.cakephp.org";
20+ }
21+
22+ # Plugin latest version map
23+ map $plugin_name $plugin_latest {
24+ default "";
25+ "authentication" "3";
26+ "authorization" "3";
27+ "bake" "3";
28+ "chronos" "3";
29+ "debugkit" "5";
30+ "elasticsearch" "5";
31+ "migrations" "5";
32+ "phinx" "0";
33+ "queue" "2";
34+ }
35+
36+ # Plugin version to host mapping
37+ map "$plugin_name-$plugin_version" $plugin_host {
38+ default "";
39+
40+ # Authentication
41+ "authentication-1" "authentication-docs.cakephp.org";
42+ "authentication-2" "authentication-docs-2.cakephp.org";
43+ "authentication-3" "authentication-docs-3.cakephp.org";
44+
45+ # Authorization
46+ "authorization-1" "authorization-docs.cakephp.org";
47+ "authorization-2" "authorization-docs-2.cakephp.org";
48+ "authorization-3" "authorization-docs-3.cakephp.org";
49+
50+ # Bake
51+ "bake-1" "bake-docs.cakephp.org";
52+ "bake-2" "bake-docs-2.cakephp.org";
53+ "bake-3" "bake-docs-3.cakephp.org";
54+
55+ # Chronos
56+ "chronos-1" "chronos-docs.cakephp.org";
57+ "chronos-2" "chronos-docs-2.cakephp.org";
58+ "chronos-3" "chronos-docs-3.cakephp.org";
59+
60+ # DebugKit
61+ "debugkit-3" "debugkit-docs.cakephp.org";
62+ "debugkit-4" "debugkit-docs-4.cakephp.org";
63+ "debugkit-5" "debugkit-docs-5.cakephp.org";
64+
65+ # Elasticsearch
66+ "elasticsearch-2" "elasticsearch-docs.cakephp.org";
67+ "elasticsearch-3" "elasticsearch-docs-3.cakephp.org";
68+ "elasticsearch-4" "elasticsearch-docs-4.cakephp.org";
69+ "elasticsearch-5" "elasticsearch-docs-5.cakephp.org";
70+
71+ # Migrations
72+ "migrations-2" "migrations-docs.cakephp.org";
73+ "migrations-3" "migrations-docs-3.cakephp.org";
74+ "migrations-4" "migrations-docs-4.cakephp.org";
75+ "migrations-5" "migrations-docs-5.cakephp.org";
76+
77+ # Phinx
78+ "phinx-0" "phinx-docs.cakephp.org";
79+
80+ # Queue
81+ "queue-1" "queue-docs-1.cakephp.org";
82+ "queue-2" "queue-docs-2.cakephp.org";
883}
984
1085server {
@@ -58,6 +133,49 @@ server {
58133 return 301 /5.x/$1;
59134 }
60135
136+ # ========================================
137+ # Version root and language redirects
138+ # ========================================
139+
140+ # Redirect .next version roots to English index
141+ location ~ ^/(5|4|3)\.next/?$ {
142+ return 301 /$1.next/en/;
143+ }
144+ # Redirect .next version with language code
145+ location ~ "^/(5|4|3)\.next/([a-z]{2})/?$" {
146+ return 301 /$1.next/$2/;
147+ }
148+
149+ # Redirect bare version numbers to version.x format with English
150+ # /5 → /5.x/en/
151+ location ~ ^/([2-5])/?$ {
152+ return 301 /$1.x/en/;
153+ }
154+
155+ # Redirect version with language code to .x format
156+ # /5/en → /5.x/en/, /5/ja → /5.x/ja/
157+ location ~ "^/([2-5])/([a-z]{2})/?$" {
158+ return 301 /$1.x/$2/;
159+ }
160+
161+ # Legacy 1.x version root redirects
162+ location ~ ^/(1\.[123])/?$ {
163+ return 301 /$1/en/;
164+ }
165+ location ~ "^/(1\.[123])/([a-z]{2})/?$" {
166+ return 301 /$1/$2/;
167+ }
168+
169+ # ========================================
170+ # Backward compatibility redirects
171+ # ========================================
172+
173+ # Redirect long version numbers to short .x format
174+ # /5.0/something → /5.x/something
175+ location ~ "^/(5|4|3|2)\.0/(.*)$" {
176+ return 301 /$1.x/$2;
177+ }
178+
61179 # Rewrite old style URLs to new .x format
62180 # /5/en/something.html -> /5.x/something.html (remove /en/)
63181 location ~ "^/([2-9]|[1-9][0-9]+)/en/(.*)$" {
@@ -74,9 +192,131 @@ server {
74192 return 301 /$1.x/$2;
75193 }
76194
195+ # ========================================
196+ # Development/pre-release documentation (.next versions)
197+ # ========================================
198+
199+ location ~ "^/(5|4|3)\.next/(.*)" {
200+ set $doc_version $1.next;
201+ set $request_path $2;
202+
203+ # Cache static assets
204+ if ($request_path ~* ^(public|fonts|assets)/) {
205+ expires 1y;
206+ add_header Cache-Control "public, immutable";
207+ }
208+
209+ proxy_intercept_errors on;
210+ error_page 404 403 /$doc_version/404.html;
211+
212+ proxy_set_header Host $doc_host;
213+ proxy_pass http://localhost:80/$request_path;
214+ }
215+
216+ # ========================================
217+ # Legacy 1.x documentation
218+ # ========================================
219+
220+ location ~ "^/(1\.[123])/(.*)" {
221+ set $doc_version $1;
222+ set $request_path $2;
223+
224+ # Cache static assets
225+ if ($request_path ~* ^(public|fonts|assets)/) {
226+ expires 1y;
227+ add_header Cache-Control "public, immutable";
228+ }
229+
230+ proxy_intercept_errors on;
231+ error_page 404 403 /$doc_version/404.html;
232+
233+ proxy_set_header Host $doc_host;
234+ proxy_pass http://localhost:80/$request_path;
235+ }
236+
237+ # ========================================
238+ # PLUGIN DOCUMENTATION
239+ # ========================================
240+ # Plugins: authentication, authorization, bake, chronos, debugkit,
241+ # elasticsearch, migrations, phinx, queue
242+
243+ # Backwards compatibility aliases (X.x → X format)
244+ location ~ "^/(authentication|authorization)/(1\.1|2\.[x0])/?(.*)"
245+ {
246+ rewrite ^/authentication/1\.1/?(.*) /authentication/1/$1 redirect;
247+ rewrite ^/authentication/2\.[x0]/?(.*) /authentication/2/$1 redirect;
248+ rewrite ^/authorization/1\.1/?(.*) /authorization/1/$1 redirect;
249+ rewrite ^/authorization/2\.[x0]/?(.*) /authorization/2/$1 redirect;
250+ }
251+
252+ location ~ "^/(bake|chronos)/([12])\.x/?(.*)"
253+ {
254+ rewrite ^/(bake|chronos)/([12])\.x/?(.*) /$1/$2/$3 redirect;
255+ }
256+
257+ location ~ "^/debugkit/([34])\.x/?(.*)"
258+ {
259+ rewrite ^/debugkit/([34])\.x/?(.*) /debugkit/$1/$2 redirect;
260+ }
261+
262+ location ~ "^/elasticsearch/2\.x/?(.*)"
263+ {
264+ rewrite ^/elasticsearch/2\.x/?(.*) /elasticsearch/2/$1 redirect;
265+ }
266+
267+ location ~ "^/migrations/2\.x/?(.*)"
268+ {
269+ rewrite ^/migrations/2\.x/?(.*) /migrations/2/$1 redirect;
270+ }
271+
272+ # Plugin root redirects to latest version
273+ location ~ ^/(authentication|authorization|bake|chronos|debugkit|elasticsearch|migrations|phinx|queue)/?$ {
274+ set $plugin_name $1;
275+ return 301 /$plugin_name/$plugin_latest/en/;
276+ }
277+
278+ # Plugin /latest redirects
279+ location ~ ^/(authentication|authorization|bake|chronos|debugkit|elasticsearch|migrations|phinx|queue)/latest/?$ {
280+ set $plugin_name $1;
281+ return 301 /$plugin_name/$plugin_latest/en/;
282+ }
283+
284+ location ~ ^/(authentication|authorization|bake|chronos|debugkit|elasticsearch|migrations|phinx|queue)/latest/(.*)$ {
285+ set $plugin_name $1;
286+ return 301 /$plugin_name/$plugin_latest/$2;
287+ }
288+
289+ # Plugin version root redirects (version → version/en/)
290+ location ~ ^/(authentication|authorization|bake|chronos|debugkit|elasticsearch|migrations|phinx|queue)/([0-9]+)/?$ {
291+ return 301 /$1/$2/en/;
292+ }
293+
294+ # Plugin proxy pass (unified for all plugins using maps)
295+ location ~ ^/(authentication|authorization|bake|chronos|debugkit|elasticsearch|migrations|phinx|queue)/([0-9]+)/?(.*)$ {
296+ set $plugin_name $1;
297+ set $plugin_version $2;
298+ set $request_path $3;
299+
300+ # Cache static assets
301+ if ($request_path ~* ^(public|fonts|assets)/) {
302+ expires 1y;
303+ add_header Cache-Control "public, immutable";
304+ }
305+
306+ proxy_intercept_errors on;
307+ error_page 404 403 /$plugin_name/$plugin_version/404.html;
308+
309+ proxy_set_header Host $plugin_host;
310+ proxy_pass http://localhost:80/$request_path;
311+ }
312+
313+ # ========================================
314+ # Main version documentation (2.x - 5.x)
315+ # ========================================
316+
77317 # Proxy pass to version specific containers using map
78318 location ~ "^/([2-9]|[1-9][0-9]+)\.x/(.*)" {
79- set $version_number $1;
319+ set $doc_version $1;
80320 set $request_path $2;
81321
82322 # Cache static assets
@@ -87,9 +327,9 @@ server {
87327
88328 # Intercept errors from upstream and serve version-specific 404 page
89329 proxy_intercept_errors on;
90- error_page 404 403 /$version_number .x/404.html;
330+ error_page 404 403 /$doc_version .x/404.html;
91331
92- proxy_set_header Host $proxy_host ;
332+ proxy_set_header Host $doc_host ;
93333 proxy_pass http://localhost:80/$request_path;
94334 }
95335}
0 commit comments