Jinja2/htmlmixed Mode

I am attempting to create a mode that will allow HTML highlighting with embedded Jinja2 tags. I am not sure what I have done wrong but I am now getting the error “CodeMirror.multiplexingMode is not a function”
My code is as follows:

CodeMirror.defineMode('jinja2-html', function (config) {
	return CodeMirror.multiplexingMode(
		CodeMirror.getMode(config, 'htmlmixed'),
		{
			open: '{%',
			close: '%}',
			mode: CodeMirror.getMode(config, 'jinja2'),
			delimStyle: 'delimit' 
		},
		{
			open: '{{',
			close: '}}',
			mode: CodeMirror.getMode(config, 'jinja2'),
			delimStyle: 'delimit' 
		},
		{
			open: '{#',
			close: '#}',
			mode: CodeMirror.getMode(config, 'jinja2'),
			delimStyle: 'delimit' 
		}
			
	)
})

To be fair I have 0 idea what I am doing as I just picked this up today but this is the best attempt I could make given the resources I could find. If anyone has any insight I would be happy to hear it.
I am importing both of the base modes as well as the base lib before calling this code.

Most likely too late for you but maybe there are future users like me to come which would hope (as much as I did) to find a ready-to-use solution here.

First of all your error CodeMirror.multiplexingMode is not a function could result from two things:
1.: Maybe the relevant js files are not loaded yet. You can easily fix that by putting your code inside a window.addEventListener('DOMContentLoaded', function() { ... } to load it not before everything else is ready.
2. : You might have missed adding the multiplex addon. This can be fixed by adding <script src="path/or/url/to/codemirror/addon/mode/multiplex.js"></script> to your html head

So… Now comes the reason for really writing this reply. In fact its not that I struggeld fixing the CodeMirror.multiplexingMode is not a function error but to get a “jinja2-htmlmixed mode” (as in your post title) really working… And after endless tries and head scratching the solution is really quite obvious (or at least easy) when one looks into the documentation (CodeMirror 5 User Manual)
=> Instead of “overwriting” styles (which you do with delimStyle: 'delimit'; see also demo here CodeMirror: Multiplexing Parser Demo – which also contains these “delimit”-style in the html-head as .CodeMirror {border: 1px solid black;} .cm-delimit {color: #fa4;}) one should use parseDelimiters : true to make the jinja2 highlighting work!

So a full example would look like this (assuming you are using a textarea with id “editor”)

<head>
<link rel="stylesheet" href="path/or/url/to/codemirror/doc/docs.css">
    <link rel="stylesheet" href="path/or/url/to/codemirror/lib/codemirror.css">
    <script src="path/or/url/to/codemirror/lib/codemirror.js"></script>
    <script src="path/or/url/to/codemirror/addon/mode/multiplex.js"></script>
    <script src="path/or/url/to/codemirror/mode/xml/xml.js"></script>
    <script src="path/or/url/to/codemirror/mode/javascript/javascript.js"></script>
    <script src="path/or/url/to/codemirror/mode/css/css.js"></script>
    <script src="path/or/url/to/codemirror/mode/htmlmixed/htmlmixed.js"></script>
    <script src="path/or/url/to/codemirror/mode/jinja2/jinja2.js"></script>
    <script>
		window.addEventListener('DOMContentLoaded', function() {
			CodeMirror.defineMode('jinja2-html', function (config) {
				return CodeMirror.multiplexingMode(
					CodeMirror.getMode(config, 'htmlmixed'),
							{
								open: "{%",
								close: "%}",
								mode: CodeMirror.getMode(config, 'jinja2'),
								parseDelimiters : true
							},
							{
								open: "{{",
								close: "}}",
								mode: CodeMirror.getMode(config, 'jinja2'),
								parseDelimiters : true
							},
							{
								open: "{#",
								close: "#}",
								mode: CodeMirror.getMode(config, 'jinja2'),
								parseDelimiters : true
							}

						)
				});

			var editor = CodeMirror.fromTextArea(document.getElementById("editor"), {
				mode: {name: "jinja2-html", htmlMode: true}
			  });
		});
    </script>
</head>
<body>
    <textarea id="editor">Your <b>html</b> code with {{ jinja_vars}}.</textarea>
</body>

Hope this helps anyone :wink: