AnonymousPoster
AnonymousPoster

Reputation: 21

Passing a list to a bottle template, then using this list in a <script></script>

I'm using bottle for a very simple one-page website. In my route for '/', I have something like this:

@app.route('/')
def index():
   data = [['A', 1], ['B', 2], ['C', 3]]
   return template('index.tpl', data=data)

Then, in my template index.tpl, I want to use this data in a script that is located in <head></head>:

<head>
    <script type="text/javascript">
       function doSomething(some_data) {
          return some_data[0];
       }
    
       function myFunc() {
          var test = doSomething({{data}});
          console.log(test);
       }
    </script>
</head>

However, this line: doSomething({{data}}) causes a syntax error: ',' expected. Declaration or statement expected.

The only way I can get around it is to add quotations like this: doSomething('{{data}}'), but then it becomes completely useless because it's a string now, and I have to convert it back to the format I need.

I have seen many solutions on StackOverflow that use {{data}} directly in JS without needing quotations, so I don't understand why it doesn't work for me. Is this because of where my script is located?

Upvotes: 2

Views: 124

Answers (1)

ggorlen
ggorlen

Reputation: 56895

Check out view-source: or print() on the rendered template you're serving:

<head>
    <script type="text/javascript">
       function doSomething(some_data) {
          return some_data[0];
       }
    
       function myFunc() {
          var test = doSomething([[&#039;A&#039;, 1], [&#039;B&#039;, 2], [&#039;C&#039;, 3]]);
          console.log(test);
       }
    </script>
</head>

You can see the special character isn't valid JS, and although I get a slightly different error than you (Uncaught SyntaxError: Unexpected token '&'), I think we're on the same page enough to offer an answer.

The docs say:

The SimpleTemplate engine escapes HTML special characters in {{bad_html}} expressions automatically. Use the new {{!good_html}} syntax to get old behaviour (no escaping).

So let's do it:

<head>
    <script type="text/javascript">
       function doSomething(some_data) {
          return some_data[0];
       }
    
       function myFunc() {
          var test = doSomething({{!data}});
          //                       ^ changed
          console.log(test);
       }
    </script>
</head>

Now we get a clean result:

<head>
    <script type="text/javascript">
       function doSomething(some_data) {
          return some_data[0];
       }
    
       function myFunc() {
          var test = doSomething([['A', 1], ['B', 2], ['C', 3]]);
          //                       ^ changed
          console.log(test);
       }
    </script>
</head>

For completeness, here's my Bottle 0.12.19 code:

from bottle import route, run, template

@route('/')
def index():
   data = [['A', 1], ['B', 2], ['C', 3]]
   print(template('index.tpl', data=data))
   return template('index.tpl', data=data)

run(host='localhost', port=8080)

Upvotes: 1

Related Questions