Forums

Problem with rendering Jinja2 context in a HTML file in a Task

Hey there guys. :) I hope you're all well.

I have a Task that's supposed to render a context using Jinja2 in a HTML file.

I have something like this:

def write_clipping_email(script_directory):
    # Scrapes for news
    complete_news = get_news()

    context = {"complete_news": complete_news}

    # Needed for the tasks in PythonAnywhere (https://help.pythonanywhere.com/pages/ScheduledTasks)
    news_filename = os.path.join(script_directory, "email_news.html")

    # Required for Jinja2
    environment = Environment(loader=FileSystemLoader(JINJA_ENV_TEMPLATES_PATH))

    email_template = environment.get_template("news_html.html")
    with open(news_filename, mode="w", encoding="utf-8") as news:
        news.write(email_template.render(context))
        print(f"... wrote {news_filename}")

    return True

The script_directory variable that is passed as an argument:

# Needed for the tasks in PythonAnywhere (https://help.pythonanywhere.com/pages/ScheduledTasks)
script_directory = os.path.dirname(os.path.abspath(__file__))

JINJA_ENV_TEMPLATES_PATH is a environment variable with the full path for the templates.

In my log I do have this print:

... wrote /home/Gabrielsldev/gspwm_emails/main/email_news.html

The HTML file do show up in the folder, i.e., is written from the template. But the template tags, like {{ variable }}, are not rendered. That is, it seems like the render(context) is not working.

Do you guys have any idea about what may be happening?

Thanks a lot! :)

Without seeing the template, my first guess would be to check if get_news() is returning anything, because it's return value is being passed as the context.

Thanks for your reply.

I’ve checked and get_news() is returning the context properly. I’ve printed the content and checked the log of the task.

The template is working fine running on my machine, but I’ll share it here as soon as I get to my laptop.

Here's the template:

{% for complete_new in complete_news %}
<h3>{{ complete_new.post_title }}</h3>
    <p><smal>{{ complete_new.post_author }} | {{ complete_new.post_date }}</smal></p>
    <p>{{ complete_new.post_excerpt }}... 
      <a href="{{ complete_new.post_link }}">Veja mais</a></p>
{% endfor %}

That's the part where render() should render the context (from get_news()). But as I said, it correctly rendering on my local machine.

Well, I just solved the problem.

I tried again just now and it worked. For some reason, some times the request doesn't return anything, so the context is empty. That only happens when I run the Task on PythonAnywhere, not in my local machine.

I put a while loop to make sure the return from get_news() is not empty:

while len(complete_news) == 0:
    time.sleep(12)
    complete_news = get_news()

Now it's running all right (but sometimes it does loop for a while before receiving anything from the request).

Thanks a lot! :)

Glad to hear that you made it work!