Skip to content

Fall back on an HTML mode for Blade when web-mode is missing#817

Merged
zonuexe merged 1 commit into
masterfrom
fix/blade-fallback
Jul 16, 2026
Merged

Fall back on an HTML mode for Blade when web-mode is missing#817
zonuexe merged 1 commit into
masterfrom
fix/blade-fallback

Conversation

@zonuexe

@zonuexe zonuexe commented Jul 16, 2026

Copy link
Copy Markdown
Member

Answers "can we fall back on html-mode when web-mode isn't installed?" — yes, and it also fixes a hard failure.

The bug

Opening a .blade.php without web-mode installed didn't warn and carry on. It failed:

Warning: php-mode is NOT support blade template. Please install `web-mode' package
Debugger entered--Lisp error: (void-function web-mode)

php-derivation-major-mode warned but left MODE set to the unavailable web-mode, so php-mode-maybe funcalled it. Every other template zeroes MODE and falls back on php-default-major-mode — Blade was the one case that couldn't open at all.

The fix

Degrade instead. A Blade template is mostly HTML plus Blade's own directives — it isn't PHP, so php-mode can't read it either — and an HTML mode renders the bulk of it correctly.

New php-blade-template-major-mode-fallback, default '(mhtml-mode html-mode) (both built in, no new dependency). The first available entry wins; set it to nil to opt out and get php-default-major-mode as before. The warning now names the substitute rather than claiming Blade is unsupported:

Warning: ‘web-mode’ is not available for this Blade template; using ‘mhtml-mode’ instead.
Install the ‘web-mode’ package for full Blade support.

Scope: Blade only, deliberately

The fallback does not extend to php-html-template-major-mode. That mode is shared with the auto-detection path, and php-project-php-file-as-template defaults to auto — so any .php file containing an HTML tag reaches it. Routing those to an HTML mode would take most PHP files away from php-mode for everyone without web-mode. Those templates are PHP with HTML in them, which php-mode does read, so they keep falling back on php-default-major-mode.

php-mode-test-html-template-fallback-unchanged pins that down — it passes both before and after this change.

Verification

End-to-end, without web-mode installed:

file before after
welcome.blade.php void-function web-mode mhtml-mode
page.php (has <div>) php-mode php-mode (unchanged)
plain.php php-mode php-mode (unchanged)

The Blade test fails before the fix and passes after; the HTML-template test passes both ways. Byte-compiles with no new warnings; full suite green. seq-find is deliberately avoided since seq isn't preloaded on every supported Emacs, so this is safe for the Emacs 27-supporting series.

For context: how Emacs's built-in php-ts-mode handles Blade

It doesn't — there is no mention of Blade anywhere in the Emacs tree. .blade.php ends in .php, so it matches php-ts-mode's auto-mode-alist patterns and opens as plain php-ts-mode, where @extends and {{ }} are parse errors. This package routes Blade to web-mode and now degrades sensibly without it, so it stays ahead of core on that front either way.

@zonuexe
zonuexe force-pushed the fix/blade-fallback branch from 7a7824e to bf1a099 Compare July 16, 2026 14:43
Opening a .blade.php file without web-mode installed did not warn and
carry on -- it failed.  php-derivation-major-mode warned but left MODE
set to the unavailable web-mode, so php-mode-maybe went on to funcall it
and signalled void-function.  Every other template zeroed MODE and fell
back on php-default-major-mode; Blade was the one case that could not
open at all.

Degrade instead.  A Blade template is mostly HTML plus Blade's own
directives -- it is not PHP, so php-mode cannot read it either -- and an
HTML mode renders the bulk of it correctly.  The new
php-blade-template-major-mode-fallback names the modes to try
(mhtml-mode then html-mode, both built in); set it to nil to opt out and
get php-default-major-mode as before.  The warning now says which mode
was substituted rather than claiming Blade is unsupported.

The fallback deliberately applies to Blade only.  Other templates are
PHP with HTML in them, which php-mode does read, and they share
php-html-template-major-mode with the auto-detection path --
php-project-php-file-as-template defaults to `auto', so any .php file
holding an HTML tag reaches it.  Extending the fallback there would take
most PHP files away from php-mode for everyone without web-mode.  A test
pins that behaviour down.

Uses cl-loop, as php-leading-tokens already does; php.el requires
cl-lib at compile time and cl-macs is loaded by the time it runs.
@zonuexe
zonuexe force-pushed the fix/blade-fallback branch from bf1a099 to d89e90d Compare July 16, 2026 14:45
@zonuexe
zonuexe merged commit 78e2c8b into master Jul 16, 2026
14 checks passed
@zonuexe
zonuexe deleted the fix/blade-fallback branch July 16, 2026 16:17
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant