Search code examples
javascriptpythonhtmlflaskjinja2

Rendering HTML Paragraph <p> with nested <b> Bold decorators with Jinja template/Flask


I am looking to create a function that removes words from a sentence and then replaces the removed words with other words sourced from a dictionary API search.

Pretty simple, here is the function that checks if the word in the sentence is part of a list of removed words, and if so will replace with an alternative, if not, the original word will be added to our new string. No problems, there,

What I am looking for help with is that, if I use an F string and add text decorators to be interpreted in the HTML markup, is this the way to do it? I want to bolden only the replaced text

if word in removed_words:
               print("our word for the dictionary is", word)  
               res =  dictionary.meaning(word.capitalize())

               if res != None:
              
                   if res.get('Noun'):
                      print("our definition is", "---> ", res['Noun'][0], " <----")
                      remaining_words.append(f"""<b>{res['Noun'][0]}</b>""")

                   elif res.get('Verb'):
                        print("our definition is", "---> ", res['Verb'][0], " <----")
                        remaining_words.append(f"""<b>{res['Verb'][0]}</b>""")

               else:
                    remaining_words.append(f"""<b>{r.word()}</b>""")
             
           else:
                remaining_words.append(word)

When I check the HTML markup in the browser the paragraph element containing the new string is correctly compiled for example

<p>This is the new sentence with the <b>replaced word</b> and the other words</p>

However the issue is that is implied but not rendered in the final markup. Is there something I am missing here?

The Flask template markup that the paragraph is called into during rendering is as follows, the

with question[0] is the new rendered string value that I have been discussing.

h3 class="header3 head4">{{heading}}</h1>

<p id="question">{{question[0]}}</p>

<button id="showanswer">Show the Answer</button>
<p id="answer">{{question[1]}}</p>

<form  id="submitanswer" method="post", action="/quiz/processanswer">
<input id="useranswer" type="text" name="answer" placeholder="Enter your answer">
<input id="hiddenanswer" name="hiddenanswer" type="text" value="{{question[1]}}" 
 id="hiddenanswer">
 <button id="answerSubmit">Submit</button>
 </form>

Thanks for your help!


Solution

  • By default Jinga automatically escapes caracters like >, < in variables (when using {{question[0]}} ) : So the added <b> and </b> are seen as texts and not html codes.

    If you are confident in how question[0] is constructed you can bypass this automatic escaping by using the safe filter. In your case, changing <p id="question">{{question[0]}}</p> into <p id="question">{{question[0]|safe }}</p> should work.

    For more information : https://jinja.palletsprojects.com/en/3.0.x/templates/#html-escaping