13

From a Django template, I would like to include an html snippet from a file, say mysnippet.html:

<div>
    blah
</div>

into a javascript variable:

<script type="text/javascript">
     var myvar = {% include 'mysnippet.html' %}
</script>

The problem is that the new lines would need to be escaped. Otherwise, Javascript complains for "unterminated string literal".

I know slashes can be added with {{x|addslashes}} but I don't know how to do it for the {% include %} tag.

gozzilli
  • 8,089
  • 11
  • 56
  • 87

3 Answers3

21

have you tried filter template tag?

{% filter addslashes %}{% include 'mysnippet.html' %}{% endfilter %}

better escape of all special characters is to use escapejs filter:

{% filter escapejs %}{% include 'mysnippet.html' %}{% endfilter %}
Jerzyk
  • 3,662
  • 23
  • 40
  • Thanks that helped. I wrote in a separate answer how I fixed it eventually. – gozzilli Apr 03 '11 at 10:29
  • @gozzilli and `escapejs` built-in filter wasn't working for you? http://docs.djangoproject.com/en/1.3/ref/templates/builtins/#escapejs – Jerzyk Apr 03 '11 at 11:31
  • Ouch! Yes, it does work, sorry I should have RTFM. :( The only difference is that is looks a bit horrible on the HTML source, as it is printed all on one line, but still you're right, escapejs is just what I needed... – gozzilli Apr 03 '11 at 13:29
  • @Jerzyk can you add escapejs in the main body of the answer, maybe on a new line? That's the real answer to the question. – gozzilli Apr 03 '11 at 14:47
  • btw. remove your own answers :D – Jerzyk Apr 03 '11 at 15:13
2

Following Jerzyk suggestion (thanks!), I've used

{% filter addslashes %}{% include 'mysnippet.html' %}{% endfilter %}

Unfortunately I realised that it doesn't escape new lines as I thought, but quotes. So I defined a new filter:

def escapenewline(value):
    """
    Adds a slash before any newline. Useful for loading a multi-line html chunk
    into a Javascript variable.
    """
    return value.replace('\n', '\\\n')
escapenewline.is_safe = True
escapenewline = stringfilter(escapenewline)

register.filter('escapenewline', escapenewline)

And used it instead of addslashes:

{% filter escapenewline %}{% include 'mysnippet.html' %}{% endfilter %}

On the Django docs there is a how-to on custom templates.

gozzilli
  • 8,089
  • 11
  • 56
  • 87
1

I noticed that you are using javascript. If you don't mind using jQuery and some AJAX along with it, there is an alternate way to assign html to a javascript variable.

Create a view to display your snippet:

# views.py
def mysnippet(request):
    return render(
        request,
        'yourapp/mysnippet.html',
    )

# urls.py
urlpatterns = patterns('yourapp.views',
    url(r'mysnippet/$', 'mysnippet', name='mysnippet'),
)

You can place the following in your template or separate the javascript in its own file:

<script type="text/javascript">
$(document).ready(function() {
    $.get("/yourapp/mysnippet/", function(data) {
        var myvar = data;
    });
});
</script>

myvar should now contain the html, the new lines don't need to be escaped in that case.

Thierry Lam
  • 45,304
  • 42
  • 117
  • 144