Replace legacy *.grails.org URLs with their canonical grails.apache.org targets#502
Merged
jamesfredley merged 1 commit intomasterfrom May 3, 2026
Merged
Replace legacy *.grails.org URLs with their canonical grails.apache.org targets#502jamesfredley merged 1 commit intomasterfrom
jamesfredley merged 1 commit intomasterfrom
Conversation
…rg targets The Plugins link in the site header pointed at https://plugins.grails.org, which is kept alive only as a meta-refresh redirect back to https://grails.apache.org/plugins.html. Many other internal links in the guides, blog posts, and shared chrome had the same shape - they targeted a legacy *.grails.org host that exists today only to bounce visitors to the canonical grails.apache.org URL. Each of those redirects costs the user an extra hop, hurts SEO, and breaks if any of the legacy hosts ever go away. Replace each redirect-bound URL with its canonical destination so internal links resolve directly: - plugins.grails.org -> grails.apache.org/plugins.html (paths under /plugin/<vendor>/<name> are 404, so they collapse to the landing page) - guides.grails.org<path> -> grails.apache.org/guides<path> (path-preserving) - docs.grails.org<path> -> grails.apache.org/docs<path> (path-preserving) - views.grails.org<path> -> grails.apache.org/docs/latest/guide/theWebLayer.html#gson - async.grails.org<path> -> grails.apache.org/docs/latest/guide/async.html - testing.grails.org<path> -> grails.apache.org/docs/latest/guide/testing.html - gsp.grails.org<path> -> grails.apache.org/docs/latest/guide/theWebLayer.html#gsp (the four subdomains above all redirect to the same fixed anchor on the canonical site - the legacy path component is dropped at redirect time anyway, so we point straight at the anchor) - grails.org/<X>.html -> grails.apache.org/<X>.html - grails.org/learn.html -> grails.apache.org/learning.html (page renamed) - grails.org/plugin/<X> -> grails.apache.org/plugins.html (legacy 404) - grails.org/blog<path> -> grails.apache.org/blog<path> - grails.org/ root and bare grails.org -> grails.apache.org/ Intentionally NOT touched: - gorm.grails.org/* - some paths (notably /latest/neo4j/manual/...) have no canonical replacement on grails.apache.org because GORM for Neo4j has not been updated for Grails 7/8. The gorm.grails.org URL is still the current canonical destination for those readers. - start.grails.org, slack.grails.org, repo.grails.org, prev-snapshot.grails.org - these are canonical hosts that serve content directly (the Forge, the Slack signup, the JFrog Maven repo, and the Grails 8 snapshot Forge). - grails.org/buildstatus.html - redirects to a GitHub README, not back to grails.apache.org, so it falls outside the redirect-back-to-here scope of this change. - buildSrc/src/test/resources/parity-baseline/ - golden HTML snapshot of the legacy site, used by ParityCheckGuideTask as a regression-test fixture; rewriting it would corrupt the source-of-truth the renderer is diffed against. - buildSrc/src/main/groovy/website/qa/AdHocFixtureDiff.groovy, buildSrc/src/main/groovy/website/gradle/tasks/Generate{Redirects, RedirectStubs}{Manifest,}Task.groovy, ParityCheckGuideTask.groovy, and StructuralDiffGuidesTask.groovy - these intentionally reference guides.grails.org as the LEGACY_BASE for the redirect-stub generator and parity baseline. - README.md and buildSrc/VENDOR.md - both document the migration itself, so the legacy URLs need to remain readable. - minutes/20210321-tab.md - frozen historical record from the TAB. Verified locally with `./gradlew validateGuides -PvalidationMode=both` (93 guides parsed, 0 errors) and `./gradlew build` (renderSite succeeds; the rendered Plugins link in build/dist/index.html is now https://grails.apache.org/plugins.html as expected). Assisted-by: claude-code:claude-opus-4-7
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Summary
The Plugins link in the site header pointed at
https://plugins.grails.org, which is kept alive only as a meta-refresh redirect back tohttps://grails.apache.org/plugins.html. Many other links across guides, blog posts, and the shared chrome had the same shape - they targeted a legacy*.grails.orghost that exists today only to bounce visitors to the canonicalgrails.apache.orgURL. Each redirect costs the user an extra hop, hurts SEO, and breaks if the legacy hosts ever go away.This PR replaces every redirect-bound URL in the source tree with its canonical
grails.apache.orgdestination so internal links resolve directly.239 files changed, 358 insertions(+), 358 deletions(-) - a strict 1-for-1 URL swap (no content rewriting).
Concrete fix the user asked for
Before:
After:
Verified in
build/dist/index.htmlline 92 after running./gradlew build.URL mapping applied
plugins.grails.orggrails.apache.org/plugins.htmlguides.grails.org<path>grails.apache.org/guides<path>(path-preserving)docs.grails.org<path>grails.apache.org/docs<path>(path-preserving)views.grails.org/*grails.apache.org/docs/latest/guide/theWebLayer.html#gsonasync.grails.org/*grails.apache.org/docs/latest/guide/async.htmltesting.grails.org/*grails.apache.org/docs/latest/guide/testing.htmlgsp.grails.org/*grails.apache.org/docs/latest/guide/theWebLayer.html#gspgrails.org/<X>.htmlgrails.apache.org/<X>.htmlgrails.org/learn.htmlgrails.apache.org/learning.html(page renamed)grails.org/plugin/<X>grails.apache.org/plugins.html(legacy 404)grails.org/blog<path>grails.apache.org/blog<path>grails.org/and baregrails.orggrails.apache.org/www.grails.org<path>grails.apache.org<path>The four subdomains
views/async/testing/gsp.grails.orgare mapped to the equivalent anchor on the canonical site because the legacy paths are dropped at redirect time anyway.Intentionally NOT touched
gorm.grails.org/*- some paths (notably/latest/neo4j/manual/...) have no canonical replacement ongrails.apache.orgbecause GORM for Neo4j has not been updated for Grails 7/8. Thegorm.grails.orgURL is still the current canonical destination for those readers.start.grails.org,slack.grails.org,repo.grails.org,prev-snapshot.grails.org- canonical hosts that serve content directly (Forge, Slack signup, JFrog Maven repo, Grails 8 snapshot Forge).grails.org/buildstatus.html- redirects to a GitHub README, not back tograils.apache.org, so it falls outside the redirect-back-to-here scope of this change.buildSrc/src/test/resources/parity-baseline/- golden HTML snapshot of the legacy site, used byParityCheckGuideTaskas a regression-test fixture; rewriting it would corrupt the source-of-truth the renderer is diffed against.guides.grails.orgas the legacy base for the redirect-stub generator and parity baseline:AdHocFixtureDiff.groovy,GenerateRedirectsManifestTask.groovy,GenerateRedirectStubsTask.groovy,ParityCheckGuideTask.groovy,StructuralDiffGuidesTask.groovy.README.mdandbuildSrc/VENDOR.md- both document the migration itself.minutes/20210321-tab.md- frozen TAB historical record.How it was done
A repeatable Groovy script walked the source tree applying ordered regex replacements (kept in
C:\Users\james\AppData\Local\Temp\opencode\rewrite-redirect-links.groovywhile writing this PR). The script also emitted an inventory of every*.grails.orgreference it deliberately left untouched so reviewers can sanity-check the skip list.Files changed by directory
guides/posts/buildSrc/templates/Verification
./gradlew validateGuides -PvalidationMode=both-> 93 guides parsed, 0 errors./gradlew build-> renderSite succeeds; rendered Plugins link inbuild/dist/index.htmlis nowhttps://grails.apache.org/plugins.htmlA final
rg https?://[a-z0-9-]+\.grails\.orgover the source tree shows the only remaining matches are in the explicitly-preserved files listed above.