Make SiteMesh 3 the default GSP layout#15713
Conversation
…s-layout Introduce a GspLayout one-of feature group so SiteMesh 3 (grails-sitemesh3) and the legacy SiteMesh 2 grails-layout are both selectable but never applied together (enforced by OneOfFeatureValidator): - GspLayout: abstract OneOfFeature parent (Category.VIEW), WEB/WEB_PLUGIN - Sitemesh3: default member; auto-applied unless another GspLayout is selected; adds grails-sitemesh3 - GrailsLayout: opt-in member; adds grails-layout (SiteMesh 2) The GspLayout features now own the layout dependency, so GrailsGsp's 'if (!isFeaturePresent(Sitemesh3)) add grails-layout' block is removed. Selecting both sitemesh3 and grails-layout now fails fast.
2fc6775 to
b0e0990
Compare
Codecov Report✅ All modified and coverable lines are covered by tests. Additional details and impacted files@@ Coverage Diff @@
## 8.0.x #15713 +/- ##
==================================================
- Coverage 49.0042% 48.3542% -0.6500%
+ Complexity 16759 15108 -1651
==================================================
Files 2014 1870 -144
Lines 94747 85459 -9288
Branches 16547 14901 -1646
==================================================
- Hits 46430 41323 -5107
+ Misses 41019 37803 -3216
+ Partials 7298 6333 -965 🚀 New features to boost your workflow:
|
|
Gaps to review and potentially address before SM3 becomes default
Not gaps (verified parity)Resolution order (6 steps), Minor / cosmeticCache-interval key differs: SM3 |
jdaugherty
left a comment
There was a problem hiding this comment.
I forgot about the test apps pointing at grails-layout by default. We'll need to update that as part of this switch and ensure no regressions.
|
I wish github didn't scroll on tables like that in comments, but there are a number of key features that will need to be added to the sitemesh 3 plugin to match sitemesh 2's historical feature set. When the tests are all run against sitemesh 3 it will surface most of these, but the comment above should be close to comprehensive. |
…itch
Address review feedback on the SiteMesh 3 default change:
- Align the SiteMesh 3 feature title with SiteMesh 2 ("GSP SiteMesh 3
Layouts") and clean up GspLayoutSpec (single quotes, drop the
short-lived SNAPSHOT-repo assertions).
- Fix the UI glitch where replacing the default layout left both
sitemesh3 and grails-layout selected. The two decorators are now
driven by a single GspLayoutImpl option (SITEMESH3 default,
GRAILS_LAYOUT) instead of a visible feature card, mirroring the
servlet and reloading one-of groups. Both members are invisible
DefaultFeatures that apply based on the selected option, so the
default-features endpoint always resolves exactly one member.
Threads the option through Options, FeatureFilter, ApplicationController
and ContextFactory, exposes it via select-options (GspLayoutImplDTO /
GspLayoutImplSelectOptions) for the UI dropdown, and adds a --gsp-layout
CLI option. Updates BuildBuilder and GspLayoutSpec and adds
SelectOptionsControllerSpec.
The test apps already gate the layout dependency on the SITEMESH3_TESTING_ENABLED environment variable, but no CI lane set it, so the suite only ever exercised the legacy grails-layout. Set the flag at the workflow level in the CI and Groovy joint builds so the example apps and grails-test-suite-uber resolve grails-sitemesh3 by default. No build-script changes needed: the flag stays as-is, the SiteMesh 2 anchors keep their grails-layout coverage, and developers can still drop the flag to run against SiteMesh 2 locally.
f816246 to
021059d
Compare
In the filterless SiteMesh 3 pipeline the GSP capture taglib writes the full <head>/<body> markup to the response buffer and also captures the head/body into a Sitemesh3CapturedPage. When no decorator is selected (e.g. a view with no <meta name="layout"> and no matching convention or default layout), SiteMeshView writes content.getData() back. The captured page had neither renderedContent nor pageBuffer set, so getData() reconstructed only from (empty) properties and emitted an empty <html><head></head><body></body></html>. Attach the original response buffer as the captured page's rendered content in the no-merge branch so the original page is written back when nothing decorates it. Decorated (meta-layout) pages are unaffected: they take the decorate branch, which reads the head/body child properties. Verified against grails-test-examples/app1 integration tests under SITEMESH3_TESTING_ENABLED=true: ConfigTestControllerSpec, ControllerIncludesSpec, ControllerFromPluginSpec and ConditionalOnPropertyFromPluginYmlSpec now pass, with no regression to meta-layout pages (BookFunctionalSpec).
🚨 TestLens detected 440 failed tests 🚨Here is what you can do:
Test Summary (first 80 of 440)
🏷️ Commit: 920c12c Test Failures (first 10 of 440)ClassLevelCleanupSpec > test 1 - insert data and verify it was persisted (:grails-test-examples-database-cleanup:integrationTest in CI / Functional Tests (Java 21, indy=false))CrudFunctionalSpec > Can navigate from list to create to list (:grails-test-examples-scaffolding-fields:integrationTest in CI / Functional Tests (Java 21, indy=false))CrudFunctionalSpec > Can navigate from list to show to edit to show (:grails-test-examples-scaffolding-fields:integrationTest in CI / Functional Tests (Java 21, indy=false))CrudFunctionalSpec > Create department with valid data succeeds (:grails-test-examples-scaffolding-fields:integrationTest in CI / Functional Tests (Java 21, indy=false))CrudFunctionalSpec > Create employee with valid data succeeds (:grails-test-examples-scaffolding-fields:integrationTest in CI / Functional Tests (Java 21, indy=false))CrudFunctionalSpec > Create page displays correctly (:grails-test-examples-scaffolding-fields:integrationTest in CI / Functional Tests (Java 21, indy=false))CrudFunctionalSpec > Delete removes employee from list (:grails-test-examples-scaffolding-fields:integrationTest in CI / Functional Tests (Java 21, indy=false))CrudFunctionalSpec > Department list page displays correctly (:grails-test-examples-scaffolding-fields:integrationTest in CI / Functional Tests (Java 21, indy=false))CrudFunctionalSpec > Edit employee with valid data succeeds (:grails-test-examples-scaffolding-fields:integrationTest in CI / Functional Tests (Java 21, indy=false))CrudFunctionalSpec > Edit page displays correctly with existing data (:grails-test-examples-scaffolding-fields:integrationTest in CI / Functional Tests (Java 21, indy=false))Muted Tests (first 20 of 440)Select tests to mute in this pull request:
Reuse successful test results:
Click the checkbox to trigger a rerun:
Learn more about TestLens at testlens.app. |

Makes SiteMesh 3 the default GSP layout in generated applications, mutually exclusive with the legacy SiteMesh 2
grails-layoutfeature.Introduces a
GspLayoutone-of feature group (enforced byOneOfFeatureValidator):GspLayout— abstract one-of parent (Category.VIEW, WEB/WEB_PLUGIN)Sitemesh3— default member; auto-applied unless anotherGspLayoutis selected; addsgrails-sitemesh3GrailsLayout— opt-in member; addsgrails-layout(SiteMesh 2)GrailsGspis intentionally not modified: its existingif (!isFeaturePresent(Sitemesh3))guard already skipsgrails-layoutwhen SiteMesh 3 applies, so SiteMesh 2 remains available viaGrailsLayout. Selecting bothsitemesh3andgrails-layoutnow fails fast.Depends on #15710
Split out from #15710 per review feedback ("making this the default & updating to sitemesh 3 should be separate PRs"). This branch is stacked on #15710, so until #15710 merges this PR's diff also shows the enable-SiteMesh-3 commits; it will reduce to just the make-default change once #15710 lands. Please merge #15710 first.