fix: #3625672 Keep the node default display editable and point the template tab at the full view mode
https://www.drupal.org/project/vmi/issues/3625672
Moves the two behaviours of the dropped vardot/varbase-patches patch on drupal_cms_helper into VMI as hooks.
menuLocalTasksAlterruns afterdrupal_cms_helperand repoints the node "Edit template" tab from the default view display to thefullone.- On the node Default display form, VMI captures each element's
#accessand#weightbeforedrupal_cms_helperruns, restores them after, and drops thecanvas_messageandcanvas_buttonit adds. Ordering is declarative, throughOrderBeforeandOrderAfter.
It restores rather than prevents because the hijack does not depend on a default content template existing. The entity.entity_view_display.node.default route supplies view_mode_name: default, and the drupal_cms_helper shim rewrites that to full before the lookup, so it finds node.<type>.full. Varbase already never creates a default template, so there was nothing to stop creating.
drupal_cms_helper is not a dependency. Every interaction is guarded by moduleExists, and the OrderBefore / OrderAfter attributes no-op when no listener matches the module.
Limitation: the restore is coupled to what drupal_cms_helper mutates. Capturing and restoring #access and #weight rather than re-enabling a hardcoded list of keys keeps it generic, but if upstream starts hiding the form a different way this can silently stop matching. The upstream fix at https://www.drupal.org/node/3551709 (and https://www.drupal.org/node/3551708 for the tab) would make it unnecessary.
Verified
In a browser on a live Drupal CMS plus Varbase Starter site, with the upstream unpatched drupal_cms_helper 2.x code in place. Both regressions reproduced first. With the change the rendered Default display form is byte identical to the previously patched baseline (1766 bytes, clean diff) and still saves, the tab points at /display/full from both entity.node.canonical and entity.node.edit_form, and /display/full still redirects to the Canvas template editor. Hook order confirmed: capture, drupal_cms_helper, field_group, restore. phpcs with Drupal,DrupalPractice reports 0 errors, leaving two pre-existing t() warnings in the untouched help() method.
Not verified: a site where drupal_cms_helper is genuinely absent, since every site in the workspace that has VMI also has that module. Pointing the ordering at a non-existent module name compiled the container cleanly and made VMI a clean no-op with no error, but that is a simulation, not a real absent-module install.
Tests
The module had no tests. Added a Varbase functional testing suite (varbase-e2e: Playwright + Cucumber-js) split by base, plus PHPUnit unit tests for the hook contract.
tests/features/drupal/(6 scenarios,cucumber.js): the VMI view modes are listed for a content type, can be enabled and disabled, and the full content display opens its Drupal Canvas template.tests/features/drupalcms/(4 scenarios,cucumber.drupalcms.js): the node template tab points at the full content display from both the canonical and the edit route, and the node default display stays editable with no Drupal Canvas takeover.tests/src/Unit/VmiHooksTest.php(5 tests): the hook registration and theOrderBefore/OrderAfterplacement arounddrupal_cms_helper.tests/fixtures/vmi_test_baseis a recipe that creates thevmi_testcontent type whose full view mode is a Canvas content template, plus the/vmi-test-nodenode the suite drives, so the tests do not depend on whatever content the site happens to carry.
All 15 passed: drupal/ against a Drupal 11.4.7 Standard site carrying canvas, canvas_override and vmi with drupal_cms_helper deliberately absent, drupalcms/ against a Drupal CMS site, and the unit tests under core PHPUnit.
Negative control: reverting src/Hook/VmiHooks.php to origin/5.0.x turns exactly the three drupalcms regression scenarios red and leaves the other six green. That is what shows the suite tests the fix rather than the site.
Running it by hand is in tests/README.md.
CI
The module had no pipeline. Added .gitlab-ci.yml on drupal/gitlab_templates pinned to 1.17.0, with _ALL_VALIDATE_ALLOW_FAILURE: '0' so composer-lint, phpcs, phpstan, cspell and phpunit all block the merge. phpunit runs whatever **/tests/**/*Test.php the branch carries. The single gated varbase-e2e job now needs to become two, one per base: cucumber.js against a Drupal Standard install and cucumber.drupalcms.js against a Drupal CMS install, both applying tests/fixtures/vmi_test_base and enabling canvas_override. _CSPELL_WORDS also needs drupalcms. Only core ~11.4 is tested, matching core_version_requirement, and SKIP_ESLINT: 1 since the module ships no JavaScript and its own .eslintrc.json extends airbnb-base, which the template job cannot resolve. .gitlab-ci-local.yml adds the workstation subset (composer-lint, phpcs, cspell).
phpcs will be red on the first run: 13 pre-existing "Expected 1 newline at end of file; 2 found" errors in src/assets/config_templates/CONTENT_TYPE_NAME/canvas.content_template.node.CONTENT_TYPE_NAME.*.yml, out of scope for this commit and fixed by dropping the extra blank line from each.
AI-Generated: Yes
Checkpoints:
- File an issue
- Addition/Change/Update/Fix
- Testing to ensure no regression
- Automated unit testing coverage
- Automated functional testing coverage
- UX/UI designer responsibilities
- Readability
- Accessibility
- Performance
- Security
- Developer Documentation
- User Guide Documentation
- Reviewed by human
- Code review by maintainers
- Full testing and approval
- Credit contributors
- Review with the product owner
- Release notes snippet
- Release