So far, we've managed to split our backend (the server-side logic), and the frontend (what the user sees) parts of the app, but, our app hasn't really gained any new features. Next, we're going to tackle displaying multiple news articles from a chosen source. Instead of cluttering our render_template
call with multiple arguments for each article's title, date, and summary, we can let Jinja handle some of this work.
1 - Jinja Objects
The first thing to understand is how Jinja interacts with different types of data. Jinja can handle all the basic Python structures like variables, objects, lists, and dictionaries. This means you can manipulate data in Jinja in much the same way you would in Python. For example, instead of passing each part of an article (like the title, date, and summary) separately to our template, we could just pass in one object called first_article and let Jinja pick apart its pieces.
Let's put this into practice. We'll change the Python code to send just the first_article object to the template. Then, in the template, we'll use Jinja to extract and display each piece of the article. Here’s how you would update the render_template call to do this:
render_template("home.html", article=first_article)
Now in the template, there's an item named article that we can use to pull up the details of our news piece, just like we did before. Update the relevant section of your `home.html` to look like this:
<b>{{article.title}}</b><br />
<i>{{article.published}}</i><br />
<p>{{article.summary}}</p>
In Jinja, getting info from a dictionary is a bit different than in Python. Instead of using square brackets or the `get` method like you would in Python (e.g., article["title"] or article.get("title")), you use a dot. So, to grab the title from the article, you'd write {{article.title}} in Jinja. This change keeps our code tidy, though it doesn't add any new features just yet.
2 - Loop Logic
We can easily make all the articles available to Jinja without a lot of extra work. Just tweak the render_template call in the Python code like this:
render_template("home.html", articles=feed['entries'])
You can go ahead and remove the line that sets the first_article variable, as we don't need it anymore. Now, our template can access the entire list of articles we're fetching.
We're starting to shift some of the workload to our template by giving it more data to handle. While ideally, some of this logic should stay in our Python code, Jinja can manage it quite neatly. Jinja uses double braces {{ }} for variables and a combination of braces and percent signs `{% %}` for control logic, like loops. Let’s modify the <body> part of your template to see how this works in practice.
<body>
<h1>Headlines</h1>
{% for article in articles %}
<b>{{article.title}}</b><br />
<i>{{article.published}}</i><br />
<p>{{article.summary}}</p>
<hr />
{% endfor %}
</body>
The Jinja for loop works pretty much like a Python loop. It goes through the list of articles that we've sent from our Python code. In each cycle of the loop, it takes an item from the list and assigns it to a new variable called article. You can then use this article variable within the loop just like any other variable in Jinja, by using double braces {{ }}.
One thing to note is that unlike Python, Jinja doesn’t care about whitespace or indentation. To tell Jinja when your loop ends, you explicitly include a {% endfor %} line. Also, the <hr /> tag in HTML draws a horizontal line between each article, helping to visually separate them.
Go ahead and run your app locally with the updated template, and check it out in your browser. You should see each article neatly separated by a line, similar to what you’d expect:
3 - Hyperlinks
Now, let's make each headline clickable, linking directly to the full article. This is helpful for users who want to read more after seeing an interesting headline. Plus, most RSS feed providers ask or require you to link back to the original articles if you use their content. Since we're already sending all the article details to our template, we don't need to change anything in our Python code to add these links; we just need to tap into the data we've already got.
In your template file, look for the part where we list the headlines and let’s adjust that:
<b>{{article.title}}</b><br />
Change it to:
<b><a href="{{article.link}}">{{article.title}}</a></b><br />
If HTML is new to you, there’s a bit to unpack here. Let’s break it down: the <a> tag is used for creating hyperlinks, which are usually shown as blue and underlined text in browsers. The href attribute within this tag tells the browser where the link should go. The link itself ends with a </a> tag, meaning that any text between <a> and </a> becomes clickable and will look different to indicate it's a link. You can even use Jinja's double braces to insert a variable directly inside the href attribute's quotes to dynamically set the link's destination.
Once you refresh your browser, you should see that the headlines are now bold and function as clickable links. Clicking any of them will take you straight to the full article.