I installed 3.1 this morning and have a bit of trouble.
I have quite a few HTML files with django template tags, javascript and vue templating. Previously, the markup between the script tags would properly color and provide tag closing for everything between the script tags. Now, it does not.
Basically, set syntax to an HTML file and do this:
{% verbatim %}
<script type="text/x-template" id="vue-component-template">
<div> Hello world </div>
</script>
{% endverbatim %}
The HTML inside the script tags just looks like plaintext now. In 3126 things properly colored and closed.
Is there a way to fix this via settings? I have to revert to 3.0 for now, which isn't a huge problem but not having this functional totally bones me.
I'm pretty sure the current behavior is correct. text/x-template is not a standard MIME type and is not part of the HTML standard.
There is a Vue.js package providing Vue-specific syntax highlighting. That package might support text/x-template scripts, and if not it could perhaps be added.
Is the contents of your script tag just HTML? If so, version 3.1 supports that if you set type="text/html". This makes a lot of sense since the type attribute is specifying that the contents are in fact HTML. I would be a little bit more hesitant to have text/template and text/x-template guess that the template is HTML since it could likely be something else like Mustache.
text/x-template is used specifically in Vue.js.
I can't make changes to the code, they are following Vue docs. This is a breaking change for me as it makes the newest version of Sublime unusable out of the box. The package linked doesn't really specify my exact case but I can give it a try.
I can add that some extra info from observations.
ex:
No Highlight:
<script type="text/template">
<div id="test">HELLO</div>
</script>
No Highlight:
<script>
<div id="test">HELLO</div>
</script>
Another issue I noticed that I'm not sure is related is that the code complete on closing tags is not working right.
It seems to always complete the end tag as the script tag.
This is the sublime feature that when you start typing the closing tag after the /, for this div
ex:
<script>
<div> </
</script>
It completes as :
<script>
<div> </script>
</script>
Normally it would complete the </div> tag correctly.
Maybe this is related...
text/template is not a standard MIME type. The browser will treat the internals as opaque textual data, and Sublime highlights it accordingly. Because it's not a standard MIME type, it wouldn't make sense for the core HTML syntax to highlight its contents in any particular way, because different third-party template systems could use that MIME type in different ways.
Scripts without type attributes are and ought to be interpreted as JavaScript. You are putting what looks like HTML inside such a tag. The browser will interpret this as JavaScript, and the core HTML syntax will highlight it as JavaScript. I am extremely skeptical that this has ever worked any differently.
Standard or not.
I think the problem most people are reporting with the markup is that in Sublime 3.0 and under, it was interpreting the type attribute on the <script> tag and highlighting accordingly.
Now with the much newer version 3.1 it appears as this extra highlighting logic is removed.
I supposed it has to do with following the html and script spec more closely.
In 3.0 this worked perfectly. In 3.1 it does not work. I reverted to 3.0 and it works again. I don't really know how to better remove skepticism that was previously functional and now is not.
I understand that the purpose was to make things better and follow MIME spec. But Vue is not an esoteric piece of tech and I probably won't be the only person running into this.
Would it be possible to push this into a feature request to set syntax to legacy html or something?
I'm a big fan of Sublime and having this not work will force me to eventually use something different which will break my heart.
The fundamental problem is that the core HTML syntax is designed to highlight HTML, and it can't be expected to also handle arbitrary nonstandard extensions of HTML. This should not be an obstacle in practice, because there is an existing package dedicated solely to highlighting Vue code. I'm not saying that your use case is invalid or should not be supported; on the contrary, it should be supported by the Vue package. If it isn't, then I would suggest opening up a PR or an issue. I may even have some time this week to take a look at the Vue package, which could probably use an update now that embed is in a stable release.
If you want to retain exactly how 3.0 worked, you just copy the HTML syntax definition from 3.0 into a folder named Packages/HTML/ (you'll have to create the HTML subfolder) and be done with it.
If you want to work with the community to try and find a path forward, I'd be happy to continue discussing it. It would seem pretty silly to throw away all of the core editor bug fixes and enhancements (by rolling back to 3.0) for the sake of one .sublime-syntax file.
Moving on the issue at hand:
Previously the HTML syntax was highlighting things incorrectly. Not everything other than <script type="text/javascript"> is HTML. It maybe worked okay, by accident in a few cases, but that doesn't mean we should keep 100% backwards compatibility forever, especially if backwards compatibility means things are broken for other users.
We currently support a handful of mime types for JS and text/html for embedding HTML in a <script> tag. It seems there are lots of other libraries out there that have their own mime types:
text/template (https://www.bennadel.com/blog/2411-using-underscore-js-templates-to-render-html-partials.htm). This is more than just HTML, but also not well defined so it could contain anything (EJS, Mustache, etc). There is no good way to handle this. Projects should probably avoid this as it is completely ambiguous and instead use a different (even custom) mime type.text/x-template (https://sebastiandedeyne.com/posts/2016/dealing-with-templates-in-vue-20) This is more than HTML, having Mustache-like tags present. Unfortunately it has a generic mime type, although it is good that is starts with an x- implying it is not standardized. Requires a custom syntax to handle properly.text/x-jsrender (https://github.com/BorisMoore/jsrender#define-a-template). This at least has a specific mime type that implied exactly what the templating language is, but it is still more than just plain HTML, so it will require a custom syntax.text/x-handlebars-template (https://handlebarsjs.com/). This also has a very project-specific mime type, but like all others requires more than just HTML to highlight properly.Now, it isn't clear to me that any of these libraries require the mime type specified in order for them to work. I believe most/all use an id or class name on the script tag to select it.
With the current HTML syntax, it is possible to get HTML highlighting is the type is text/html. This seems right. We can properly handle it, and no one should be surprised at the behavior.
Unfortunately every other example I have found of using script tags for templating requires support for an actual templating library, and thus they should really be using a custom syntax. Things will go funky depending on what syntax is used in the templating, and there is no reasonable qualification for which templating libraries would be suitable for inclusion and which should require a custom syntax.
If you are interested in having all of the improvements and bug fixes to the HTML syntax, but with support for the templating library of your choice, I think it would make sense to drop by the Sublime Text discord server. Almost every core contributor to this repository of syntax definitions hangs out there, and most of them would be more than happy to give some guidance on how to make a Vue.js extension of the HTML syntax that adds support for the Vue templating library.
Ah, I understand.
FWIW it seems without looking to closely that I was able to get the desired behavior with the Vue.js plugin. This appears it will cover my use case, so feel free to close this out.
In case anyone else find this issue when looking for a solution to a similar problem (I needed support for handlebars), a workaround for this is to create a custom HTML syntax:
HTML.sublime-package) and open using an archive tool. On Ubuntu this is located in /opt/sublime_text/PackagesHTML_w_handlebars.sublime-syntax. On Ubuntu this would be ~/.config/sublime-text-3/Packages/User/HTML_w_handlebars.sublime-syntaxname: HTML line to name: HTML_w_handlebars and then find the relevant part of script-type-decider definition and change the regex. For me this was changing line 380: - match: (?i)(?=text/html(?!{{unquoted_attribute_value}})|'text/html'|"text/html")
to
- match: (?i)(?=text/html(?!{{unquoted_attribute_value}})|'text/html'|"text/html"|"text/x-handlebars-template")
After doing this, the syntax highlighting and auto-completion is back to how it was in 3.0. For me this is sufficient until I refactor my code so the handlebar templates are in their own files.
In case people want to achieve this a little easier, I created a Sublime Package which does just this.
Have a look here:
https://packagecontrol.io/packages/HTML%20Syntax%20in%20Script
Also for anyone who finds this, if you want to get this working for PHP files you'll need to override the actual built in HTML package, you can't just add an additional package like @cmcleese's because the PHP package won't know to use it.
In my case I copied the HTML.sublime-package out of the Sublime OSX .app, decompressed it into my Packages/ folder, and then changed line 389 to:
- match: (?i)(?=text/(?:{{unquoted_attribute_value}})?|'text/[^']*'|"text/[^"]*")
For me it works just changing the mime type to text/html, as wbond suggested. Nothing breaks (at least in my app), and syntax hightlighting works normally.
Most helpful comment
If you want to retain exactly how 3.0 worked, you just copy the HTML syntax definition from 3.0 into a folder named
Packages/HTML/(you'll have to create the HTML subfolder) and be done with it.If you want to work with the community to try and find a path forward, I'd be happy to continue discussing it. It would seem pretty silly to throw away all of the core editor bug fixes and enhancements (by rolling back to 3.0) for the sake of one
.sublime-syntaxfile.Moving on the issue at hand:
Previously the HTML syntax was highlighting things incorrectly. Not everything other than
<script type="text/javascript">is HTML. It maybe worked okay, by accident in a few cases, but that doesn't mean we should keep 100% backwards compatibility forever, especially if backwards compatibility means things are broken for other users.We currently support a handful of mime types for JS and
text/htmlfor embedding HTML in a<script>tag. It seems there are lots of other libraries out there that have their own mime types:text/template(https://www.bennadel.com/blog/2411-using-underscore-js-templates-to-render-html-partials.htm). This is more than just HTML, but also not well defined so it could contain anything (EJS, Mustache, etc). There is no good way to handle this. Projects should probably avoid this as it is completely ambiguous and instead use a different (even custom) mime type.text/x-template(https://sebastiandedeyne.com/posts/2016/dealing-with-templates-in-vue-20) This is more than HTML, having Mustache-like tags present. Unfortunately it has a generic mime type, although it is good that is starts with anx-implying it is not standardized. Requires a custom syntax to handle properly.text/x-jsrender(https://github.com/BorisMoore/jsrender#define-a-template). This at least has a specific mime type that implied exactly what the templating language is, but it is still more than just plain HTML, so it will require a custom syntax.text/x-handlebars-template(https://handlebarsjs.com/). This also has a very project-specific mime type, but like all others requires more than just HTML to highlight properly.Now, it isn't clear to me that any of these libraries require the mime type specified in order for them to work. I believe most/all use an id or class name on the script tag to select it.
With the current HTML syntax, it is possible to get HTML highlighting is the type is
text/html. This seems right. We can properly handle it, and no one should be surprised at the behavior.Unfortunately every other example I have found of using script tags for templating requires support for an actual templating library, and thus they should really be using a custom syntax. Things will go funky depending on what syntax is used in the templating, and there is no reasonable qualification for which templating libraries would be suitable for inclusion and which should require a custom syntax.
If you are interested in having all of the improvements and bug fixes to the HTML syntax, but with support for the templating library of your choice, I think it would make sense to drop by the Sublime Text discord server. Almost every core contributor to this repository of syntax definitions hangs out there, and most of them would be more than happy to give some guidance on how to make a Vue.js extension of the HTML syntax that adds support for the Vue templating library.