Much like the existing {% js %} tag, it would be incredibly helpful to have a similar {% jsFile %} tag.
The current approach to registering a JS file can be quite clunky...
CURRENT
{% do view.registerJsFile(alias('@web/resources/js/scripts.js'), {'position': POS_BEGIN}) %}
PROPOSED
{% jsFile '@web/resources/js/scripts.js' at beginBody %}
^ The proposed version is _far_ more readable in my opinion. It would be easier for new devs to understand what they are looking at, and easier for old devs to remember how to write it (without Googling first).
It's also much easier to specify the position in this manner, bringing it in parity with the existing {% js %} tag.
~Bonus 1 - It would be amazing if this tag also respected aliases. The example above uses an alias, you can see how it's nice to be able to skip the alias function.~ (I stand corrected, registerJsFile already supports aliases.)
Bonus 2 - It would also be super cool if the tag supported an array syntax, in order to declare multiple files at once.
{% jsFile [
'http://code.jquery.com/jquery-3.5.0.min.js',
'https://stackpath.bootstrapcdn.com/bootstrap/4.4.1/js/bootstrap.min.js',
'@web/resources/js/scripts.js',
] %}
Thanks for considering this FR, let me know if you need any clarification! 馃檪
fwiw - You can still use the old {% includeJsFile %} tag, at least for now. (Craft 3 intentionally deprecated includeJsFile in favor of Yii's native view.registerJsFile method, but the old tag is still hanging out, at least 'til Craft 4. You'll just get a bunch of deprecation notices, but meh, YOLO.)
Probably a good intermediate step would be to document view.registerJsFile in Craft's template docs, right inline with {% js %}, with all its options, to make it more accessible to newer folks.
Alias support is nice, but (a) I think Yii already resolves aliases, and (b) in practice, it could encourage smelly practices. In cases where you want to expose assets from Craft or a plugin, using registerAssetBundle is probably preferable, for future-proofing and to avoid dependency-related issues. (You don't need to _set up_ an Asset Bundle yourself; you're just _using_ assets that the package already has.)
(Also, relative URLs are already aliased to @webroot by registerJsFile, so e.g. in your example above, the @web alias is not needed.)
All that said... That array syntax looks pretty tight... 馃槒
...and syntax parity with {% js %} would probably be helpful for novice devs.
Bonus 1 - It would be amazing if this tag also respected aliases. The example above uses an alias, you can see how it's nice to be able to skip the alias function.
You know that's already the case? You don't need to use the alias function.
@Anubarak I did not know that. I swear at some point in the past I had to deal with the alias separately... maybe it's changed since then!
Resolved for the next release 鈥撀爏ee https://github.com/craftcms/cms/issues/6672#issuecomment-678427709.
// Is this a JS file?
if (preg_match('/^[^\r\n]+\.js/i', $js)) {
Craft::$app->getView()->registerJsFile($js, $options, $key);
} else {
$position = $options['position'] ?? View::POS_READY;
Craft::$app->getView()->registerJs($js, $position, $key);
}
So ridiculously simple... I love it! 鉂わ笍
Craft 3.5.6 is out now with that change.
Thanks @brandonkelly! 馃嵑
Did you have any final thoughts on the array syntax? It's definitely a "nice to have"... but maybe there's a case to be made against it?
Sorry, missed that. Think it would overcomplicate the logic, and now you have a single tag potentially including files _and_ registering inline JS code, which feels messy.
You could do this though:
{% set files = [
'http://code.jquery.com/jquery-3.5.0.min.js',
'https://stackpath.bootstrapcdn.com/bootstrap/4.4.1/js/bootstrap.min.js',
'@web/resources/js/scripts.js',
]%}
{% for file in files %}
{% js file %}
{% endfor %}
Yeah, that's fair. To be honest, it's easy enough (now) to just list them individually...
{% js 'http://code.jquery.com/jquery-3.5.0.min.js' %}
{% js 'https://stackpath.bootstrapcdn.com/bootstrap/4.4.1/js/bootstrap.min.js' %}
{% js '@web/resources/js/scripts.js' %}
Thanks Brandon! 馃憤
Most helpful comment
Craft 3.5.6 is out now with that change.