Opened 15 months ago
Last modified 14 months ago
#59444 new enhancement
Add language injection comments for embedded languages in PHP
Reported by: | westonruter | Owned by: | |
---|---|---|---|
Milestone: | Future Release | Priority: | normal |
Severity: | normal | Version: | 6.4 |
Component: | General | Keywords: | |
Focuses: | javascript, css, coding-standards | Cc: |
Description
As part of #4773 and #58775, many manually-constructed inline <script>
and <style>
tags were replaced with API calls to wp_print_inline_script_tag()
and wp_add_inline_style()
, respectively. While doing so comes with key runtime benefits, a downside is introduced in terms of the developer experience. In particular, when editing a PHP file that has an embedded <style>
or <script>
tag, IDEs will do syntax highlighting and other code intelligence features for the embedded language. These IDE features are particularly important since the JS/CSS code in question is not located in a .js
or .css
file, meaning it is not included in static analysis checks (e.g. JSHint). This means that the IDE is the first line of defense against developers accidentally making a typo or introducing a syntax error which, if it passes code review, would otherwise only get discovered at runtime in user testing. These IDE features are also important for developer productivity (e.g. autocompletion).
I understand PhpStorm to be the most popular IDE for WordPress core development, and it has a language injection feature. It involves using comments that precede the embedded language string, for example:
wp_print_inline_script_tag( /** @lang JavaScript */ "document.body.className = document.body.className.replace('no-js','js');" );
or
wp_add_inline_style(
'admin-bar',
// language=CSS
'@media print { #wpadminbar { display:none; } }'
);
VSCode has an issue for Universal Language Injections, but it was closed for being too difficult. Apparently the scope was to go to the extent of detecting embedded languages even without the language injection comments that Jetbrains IDEs support. The feature was apparently relegated to the extension space (cf. Syntax Highlight Guide).
That being said, it does appear that VSCode does support method that PhpStorm supports: Inject a language inside a nowdoc/heredoc string. (I can't seem to find any VSCode documentation about this, but it seems to work locally.) This allows you to do:
wp_print_inline_script_tag(
<<<JS
"document.body.className = document.body.className.replace('no-js','js');"
JS
);
Nevertheless, there are also issues with the ergonomics of heredoc strings, especially prior to PHP 7.3: the closing delimiter must always start at the beginning of the line, and it cannot have any comma following it on the same line. So that means you cannot do the following in PHP<7.3:
$scripts->add_inline_script(
'media-widgets',
<<<JS
wp.mediaWidgets.init();
JS,
'after'
);
Since WordPress only now just bumped the minimum requirement to 7.0, this isn't yet an option.
I suggest that PhpStorm's syntax for language injection comments be adopted in WordPress core as a convention. Since PhpStorm is apparently the most popular IDE for WordPress core development, it will be useful for core contributors. For VSCode, an extension could potentially be written that adds support for the same syntax. Otherwise, we wait until PHP 7.3 is the minimum requirement and switch all existing JS/CSS string literals to heredocs.
Previous conversations:
One benefit of using the HEREDOC strings is that it should be a trivial update to indent them once the minimum supported version is 7.3, and they will work in both IDEs until then. That's where my vote lies, because I'd rather have syntax highlighting and IDE aids than avoid a dangling HEREDOC closer.
That being said I think this is good either way so I wouldn't want to block an update that has a positive impact. It would simply be a little more difficult to change later when embedding the comments inside the PHP strings.
There HEREDOC syntax has another benefit I personally like: it encourages normal formatting of JS inside PHP, using newlines properly, and aligning code. When a normal string is the example I feel like that puts pressure on people to fit everything in a single long line; if they do need multiple lines, then there are multiple ways they might approach that, whereas the HEREDOC conveys a single straightforward way.