简体   繁体   中英

Passing list of HTML to Javascript using Jinja2 template

I am trying to pass a list of HTML (the html construct an interactive graph - ['some html','some html']. Right now, I am having a lot of trouble after exploring several of the following ideas:

  1. Applying Markup before passing over the list on python side. This words very well if I am passing the HTML list directly to the HTML portion of template
  2. Applying filters "tojson" and "safe"
  3. using json.dumps on the python side
  4. JSON.parse once I did convert it to json

Problems I have been having:

  1. website will actually print out javascript or skip and entire first section of javascript where I had written alerts etc. (This happened when I used just markup and safe).

  2. instead of assigning the graphs into correct div, they just appear randomly after.

  3. graphs display but print out parts of the list that shouldn't have been included as content like "Markup(".

  4. "syntaxError: unexpected token &"

  5. Also trying to display a list of text, website wont display both simultaneously

GOAL: Pass a list of HTML (representing graphs) and a list of text, go through them, assign them to divs with JS, display them side by side. One graph next to one text entry.

code: *looping through list of graph html, and list of text.

<script>
    function createDashboard(){
        alert("here!");
        summaries = {{content|safe}};
        summary = document.getElementById('analysis');
        for(var i = 0; i < summaries.length;i++){
            var div = document.createElement('div');
            for (line in summaries[i]){
                var para = document.createElement('p');
                para.innerHTML = summaries[i][line];
                summary.appendChild(para);
            }
        }
        graphs = {{div|safe}};
        graph_div = document.getElementById('graph');
        for(var h = 0; h < graphs.length;h++){
            var div = document.createElement('div');
            div.innerHTML = graphs[i];
            graph_div.appendChild(div);
        }
    }
     window.onload = function(){
        createDashboard();
    };
</script>
</html>

You can mark div and content as safe either using the safe filter in your template or wrapping both before they are passed to the template inside your view function.

def escape_script(data):
    """ This escapes the closing script tags.
    """
    markup = Markup(data)
    markup_string = str(markup)
    replacement = markup_string.replace('</script>', '<\/script>')
    return replacement

@app.route('/', methods=['GET'])
def index():
    div = ['<div><script type="text/javascript">/**\n* plotly.js v1....</script>'] 

    content = [['Total number of SNR 30mm tests run: 8\n', 'Total number of passed tests: 8\n'],]
    return render_template('index.html', div=escape_script(div), content=content)

Ensure that scripts in any of your template variables are escaped . You need to do this because the browser closes the embedded script early when it finds a closing script tag.

function createDashboard(){
  ...
  summaries = {{content | safe}};
  console.log(summaries);
  ...
  graphs = {{div | safe}};

  unescape_graphs = graphs.map(function(graph) {
     return graph.join("\n").replace('\\/', '\/');
  }); // necessary to do this to escape the closing script javascript-esque. 
      // Safe filters escape backslashes too.
  console.log(unescape_graphs);
  ...
}

Note that embedded scripts inserted into the DOM this way aren't evaluated by the browser. You can get around this by going through all the inserted embedded scripts and inserting them .

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM