-1

I'm creating an application using Flask, so the usual suspects on the Client Side and Python on the Server Side.

While adding in some new functionality via new JavaScript code in the SCRIPT section, one of my templates started to error when rendering. When I commented out this new code, the error continued to occur.

Thinking I'd maybe made a mistake on the Python side, I commented out all the new code relating to the most recent change, but the error persisted. The error I received was:

Internal Server Error

The server encountered an internal error and was unable to complete your request. Either the server is overloaded or there is an error in the application.

It turns out that one single line of JavaScript code was causing this rendering error. Commenting it out made no difference - I had to remove it completely before my template would render correctly.

Has anyone ever encountered this before? It goes against everything I've ever seen in the past 20 years as a professional coder! The line of code causing the error is exactly below.

If I paste this line into any of the other HTML templates in my application, then those templates will not render either.

Not only can I not see a valid reason for the template to error (by which I mean, the code is valid and should run), I'd really love to know if anyone has experienced this phenomenon too, where commented out code can cause an error when rendering a template?

I've already "fixed" the issue by renaming the variables, but how on earth can such a line cause a rendering error? Any help or ideas or similar experiences would be most welcome.

For info, I'm using Microsoft Visual Studio (the latest free version) to develop this application.

//var JSONarrayOfWords = {{ JSON_allRowsForSpecificLanguage| tojson}};     //populate a JSON array from the (jinja?) FLASK array (originally a LIST in python)
Diogo Rocha
  • 9,759
  • 4
  • 48
  • 52
  • reminds me of https://stackoverflow.com/a/184986/1383168 – Slai Mar 29 '19 at 23:23
  • It's still in the template, and still rendered by the server--commenting out the line in client-side JS code doesn't change anything on the server-side. You need a template-language comment. Where code executes matters. – Dave Newton Mar 30 '19 at 00:50
  • There's a better explanation of the issue and what I did to solve it below. Thanks for your replies. – Philip O Brien Mar 30 '19 at 01:50

2 Answers2

2

You need to wrap your code in the template within the {% raw %} and {% endraw %} tags.

See these:

  1. https://github.com/pallets/jinja/issues/810
  2. Jinja2 inline comments
  3. http://jinja.pocoo.org/docs/2.10/templates/#comments

Much like the articles, I would recommend not doing inline JavaScript (ever, really). If you were to move your JavaScript to a file and reference that inside your Jinja template, the error will go away.

mwilson
  • 12,295
  • 7
  • 55
  • 95
  • Thanks for the reply, but I don't think it really helps. I might not have been clear enough in my question, but the application I'm writing already has 100's of lines of code across many templates and a python file. Upon adding one particular line of code (which is identical to other lines I've added except the variable names are different) I got the rendering error. While it may be stylistically or functionally better to not do inline JavaScript, this is not the issue here. When I commented out the offending line, the error still occurred. I had to remove it before it would render correctly. – Philip O Brien Mar 29 '19 at 23:37
  • 1
    The main issue you're running into is that the jinja template only understands jinja syntax. `//` is not valid jinja syntax. If you look through the 3rd link I sent you, it notes that the proper comment syntax in jinja is `#`. The first link (the GitHub issue) is very close to your issue. – mwilson Mar 29 '19 at 23:40
  • Thanks for your help, mwilson. I've added an answer of my own below if you wouldn't mind having a quick glance. I'll check out the links you posted and deepen my knowledge of this area I'm sure! Cheers! (ps I can't upvote your answer as I don't have the credentials yet!) – Philip O Brien Mar 30 '19 at 01:17
0

Alright, thanks for your help on this one, mwilson. After a bit of experimentation, the scenario is now a lot clearer.

This code works and renders correctly:

<script>
    const const_nativeToForeign = "nativeToForeign";
    const const_foreignToNative = "foreignToNative";

    js_currentPointInTestCount          = "{{flask_currentPointInTest}}";
    js_totalWordsInTestCount            = "{{flask_totalWordsInTest}}";
    js_totalCorrectOnFirstTryCount      = "{{flask_totalCorrectOnFirstTryCount}}";
    js_totalCorrectOnSubsequentTryCount = "{{flask_totalCorrectOnSubsequentTryCount}}";
    js_totalGiveUpsCount                = "{{flask_totalGiveUpsCount}}";
    js_actionToTake                     = "{{flask_actionToTake}}";
    //js_translationDirectionOfTest       = "{{flask_translationDirectionOfTest}}";
    js_translationDirectionOfWord       = "{{flask_translationDirectionOfWord}}";

    js_nativeWord                       = "{{flask_NativeWord}}";
    js_foreignWord                      = "{{flask_ForeignWord}}";

    js_nativeWord                       = "{{flask_NativeWord}}";
    js_foreignWord                      = "{{flask_ForeignWord}}";

    JSON_list_direct_object_genders = {{ flask_JSON_list_direct_object_genders | tojson }};
    JS_list_direct_object_genders = JSON.parse(JSON_list_direct_object_genders);
    console.log(JS_list_direct_object_genders);

    JSON_list_special_chars = {{ flask_JSON_list_scs | tojson }};
    JS_list_special_chars = JSON.parse(JSON_list_special_chars);
    console.log(JS_list_special_chars);

    document.getElementById("btnMoveIt").disabled = true;
    document.getElementById("textGuessInput").focus();

...but this code does not render (note the additional commented out line):

<script>
    const const_nativeToForeign = "nativeToForeign";
    const const_foreignToNative = "foreignToNative";

    js_currentPointInTestCount          = "{{flask_currentPointInTest}}";
    js_totalWordsInTestCount            = "{{flask_totalWordsInTest}}";
    js_totalCorrectOnFirstTryCount      = "{{flask_totalCorrectOnFirstTryCount}}";
    js_totalCorrectOnSubsequentTryCount = "{{flask_totalCorrectOnSubsequentTryCount}}";
    js_totalGiveUpsCount                = "{{flask_totalGiveUpsCount}}";
    js_actionToTake                     = "{{flask_actionToTake}}";
    //js_translationDirectionOfTest       = "{{flask_translationDirectionOfTest}}";
    js_translationDirectionOfWord       = "{{flask_translationDirectionOfWord}}";

    js_nativeWord                       = "{{flask_NativeWord}}";
    js_foreignWord                      = "{{flask_ForeignWord}}";

    js_nativeWord                       = "{{flask_NativeWord}}";
    js_foreignWord                      = "{{flask_ForeignWord}}";

    JSON_list_direct_object_genders = {{ flask_JSON_list_direct_object_genders | tojson }};
    JS_list_direct_object_genders = JSON.parse(JSON_list_direct_object_genders);
    console.log(JS_list_direct_object_genders);

//  JSONsomethingMeaningless = {{ flask_JSON_something_not_defined_in_python | tojson }}

    JSON_list_special_chars = {{ flask_JSON_list_scs | tojson }};
    JS_list_special_chars = JSON.parse(JSON_list_special_chars);
    console.log(JS_list_special_chars);

    document.getElementById("btnMoveIt").disabled = true;
    document.getElementById("textGuessInput").focus();

...because the variable flask_JSON_something_not_defined_in_python was not defined in the return render_template() of the Python file.

Even though the offending line is commented out, it still won't render. That's fine (although very odd - but you have given me an explanation and I'll look into the links you provided so thanks for those).

Delving a bit deeper, if the commented out line is changed to:

//  JSONsomethingMeaningless = {{

then it still won't render (so it must be detecting jinja here? Possibly because of the double-chain brackets?)

If the commented out line is changed to:

//  JSONsomethingMeaningless = {

i.e. just a single chain bracket, the HTML file renders without a problem and does everything I expect it to do (in terms of being able to use the variables, etc).

So the moral of the story seems to be that comments are not really comments if the HTML file rendering picks them up as lines of Jinja?

And the other moral of the story is that I should pay more attention to what I have defined in the render_template() part of Python!

Thanks again for your help and I will check out those links. I'm coming from a world of Cobol and Delphi (server/client) so this is all a bit new to me!

  • 1
    Comments are always comments *in their environment*. The jinja template is rendered on the server-it (in this case) doesn't know anything about JavaScript--it's not a comment in jinja. Templates don't care *what* they're rendering. Once the rendered template is sent to the browser, the *browser* renders its content, only then does the JS matter. This is basic server/client behavior: the code runs inn different places, using different languages, with different semantics. – Dave Newton Mar 30 '19 at 12:12