Moshe Shitrit Moshe Shitrit - 3 months ago 7
HTML Question

Django 1.10 - Use django.shortcuts.render to generate a webpage with variables which includes a javascript as parameter

I'm new to Django, trying to migrate a website that I have built to a Django application.
I have generated an HTML template on which I want to present dynamic content based on the URL that was requested.
The HTML template looks like this:

{% load staticfiles%}

<!DOCTYPE html>
<html lang="en">
<head>
<script type="text/javascript">
{{ script }}
</script>
<meta charset="UTF-8">
<link rel="stylesheet" href="{% static 'styles.css' %}"/>
<title>{{ title }}</title>
</head>
<body>
<header>
<h1>{{ title }}</h1>
</header>
<section>
<p>
{{ date }}<br/><br/>
SiteID: {{ site }}
<br/>
-----------------
</p>
</section>
</body>
</html>


On my views.py file, I'm generating the URL using this method (for example):

def site(request):
return render(request, "sites/site.html", {'date': strftime("%A, %B %d %Y"),
'site': '123456',
'title': 'Test',
'script': "window.lpTag=window.lpTag||{};if(typeof window.lpTag._tagCount==='undefined'){window.lpTag={site:'123456'||'',section:lpTag.section||'',autoStart:lpTag.autoStart===false?false:true,ovr:lpTag.ovr||{},_v:'1.6.0',_tagCount:1,protocol:'https:',events:{bind:function(app,ev,fn){lpTag.defer(function(){lpTag.events.bind(app,ev,fn);},0);},trigger:function(app,ev,json){lpTag.defer(function(){lpTag.events.trigger(app,ev,json);},1);}},defer:function(fn,fnType){if(fnType==0){this._defB=this._defB||[];this._defB.push(fn);}else if(fnType==1){this._defT=this._defT||[];this._defT.push(fn);}else{this._defL=this._defL||[];this._defL.push(fn);}},load:function(src,chr,id){var t=this;setTimeout(function(){t._load(src,chr,id);},0);},_load:function(src,chr,id){var url=src;if(!src){url=this.protocol+'//'+((this.ovr&&this.ovr.domain)?this.ovr.domain:'lptag.liveperson.net')+'/tag/tag.js?site='+this.site;}var s=document.createElement('script');s.setAttribute('charset',chr?chr:'UTF-8');if(id){s.setAttribute('id',id);}s.setAttribute('src',url);document.getElementsByTagName('head').item(0).appendChild(s);},init:function(){this._timing=this._timing||{};this._timing.start=(new Date()).getTime();var that=this;if(window.attachEvent){window.attachEvent('onload',function(){that._domReady('domReady');});}else{window.addEventListener('DOMContentLoaded',function(){that._domReady('contReady');},false);window.addEventListener('load',function(){that._domReady('domReady');},false);}if(typeof(window._lptStop)=='undefined'){this.load();}},start:function(){this.autoStart=true;},_domReady:function(n){if(!this.isDom){this.isDom=true;this.events.trigger('LPT','DOM_READY',{t:n});}this._timing[n]=(new Date()).getTime();},vars:lpTag.vars||[],dbs:lpTag.dbs||[],ctn:lpTag.ctn||[],sdes:lpTag.sdes||[],ev:lpTag.ev||[]};lpTag.init();}else{window.lpTag._tagCount+=1;}"})


The problem is, that this method actually renders all my strings so that it's escaping characters such as apostrophe ('), which is causing the JavaScript not to work. That's what I see in the browser console when running the page:

<script type="text/javascript">
window.lpTag=window.lpTag||{};if(typeof window.lpTag._tagCount===&amp;#39;undefined&#39;){window.lpTag={site:&#39;123456&#39;||&#39;&#39;,section:lpTag.section||&#39;&#39;,autoStart:lpTag.autoStart===false?false:true,ovr:lpTag.ovr||{},_v:&#39;1.6.0&#39;,_tagCount:1,protocol:&#39;https:&#39;,events:{bind:function(app,ev,fn){lpTag.defer(function(){lpTag.events.bind(app,ev,fn);},0);},trigger:function(app,ev,json){lpTag.defer(function(){lpTag.events.trigger(app,ev,json);},1);}},defer:function(fn,fnType){if(fnType==0){this._defB=this._defB||[];this._defB.push(fn);}else if(fnType==1){this._defT=this._defT||[];this._defT.push(fn);}else{this._defL=this._defL||[];this._defL.push(fn);}},load:function(src,chr,id){var t=this;setTimeout(function(){t._load(src,chr,id);},0);},_load:function(src,chr,id){var url=src;if(!src){url=this.protocol+&#39;//&#39;+((this.ovr&amp;&amp;this.ovr.domain)?this.ovr.domain:&#39;lptag.liveperson.net&#39;)+&#39;/tag/tag.js?site=&#39;+this.site;}var s=document.createElement(&#39;script&#39;);s.setAttribute(&#39;charset&#39;,chr?chr:&#39;UTF-8&#39;);if(id){s.setAttribute(&#39;id&#39;,id);}s.setAttribute(&#39;src&#39;,url);document.getElementsByTagName(&#39;head&#39;).item(0).appendChild(s);},init:function(){this._timing=this._timing||{};this._timing.start=(new Date()).getTime();var that=this;if(window.attachEvent){window.attachEvent(&#39;onload&#39;,function(){that._domReady(&#39;domReady&#39;);});}else{window.addEventListener(&#39;DOMContentLoaded&#39;,function(){that._domReady(&#39;contReady&#39;);},false);window.addEventListener(&#39;load&#39;,function(){that._domReady(&#39;domReady&#39;);},false);}if(typeof(window._lptStop)==&#39;undefined&#39;){this.load();}},start:function(){this.autoStart=true;},_domReady:function(n){if(!this.isDom){this.isDom=true;this.events.trigger(&#39;LPT&#39;,&#39;DOM_READY&#39;,{t:n});}this._timing[n]=(new Date()).getTime();},vars:lpTag.vars||[],dbs:lpTag.dbs||[],ctn:lpTag.ctn||[],sdes:lpTag.sdes||[],ev:lpTag.ev||[]};lpTag.init();}else{window.lpTag._tagCount+=1;}
</script>


So my question is - How can I generate a dynamic page that is getting the actual JavaScript code as a variable without rendering the code? (Bear in mind that there are also simple texts that I'm transferring, such as the title of the page, so I will need to render the page anyway).

Thanks!

Answer

You should put that script in a separate file and then pass the file name to the template instead.

Put your script in a js file, say my_script.js:

window.lpTag=window.lpTag||{};if(typeof window.lpTag._tagCount==='undefined') ...

Then in your view:

def site(request):
    return render(request, "sites/site.html", {'date': strftime("%A, %B %d %Y"),
                                               'site': '123456',
                                               'title': 'Test',
                                               'script': 'my_script.js'})

Then in your HTML:

<head>
    <script type="text/javascript" src="{{ script }}"></script>
    <meta charset="UTF-8">
    <link rel="stylesheet" href="{% static 'styles.css' %}"/>
    <title>{{ title }}</title>
</head>