Chapter 5:
Display news articles

The Read process will look like this:

  1. For each article, there is a detailed view including ’title’, ‘content’, ‘category’ and ‘image’.
  2. The Homepage contains a list of articles, displaying a summary of each.
  3. When the Homepage is loaded, the list of articles is retrieved from the database. It’s also loaded when the articles are added and updated.

We’ll walk through these steps below.

Step 1: Create detail view for article

First, let’s create the UI that displays a single article. Create a new Form, select the BlankPanel template, and rename it ‘ArticleView’.

We want to display an instance of ‘ArticleView’ on our Homepage for each article in our Data Table. We’ll need space for the article’s title, content, category, and image.

Drop a ColumnPanel Card icon component into the page, then change it’s role to elevated-card to give it a styled look.

Add these components to the ColumnPanel:

  • Title: Label, rename this title_label
  • Category: Label, rename this category_label
  • Content: Label, rename this content_label
  • Image: Image

Your ArticleView UI should look something like this:

The 'ArticleView' Form in the designer

Next, change your title_label’s role to title using the ‘Appearance’ section of the Properties Panel.

Applying the 'title' role to the 'title_label' in the 'appearance' section of the Properties Panel

Finally, change the category_label text to be bold. Click on MORE to the right of the Text section of the Properties Panel to change the bold property.

Making the text property of the category_label bold

Step 2: Add article view to Repeating Panel

In order to display an instance of the ‘ArticleView’ Form for each article in your Data Table, your ‘ArticleView’ Form needs to be placed inside a RepeatingPanel.

Go to your ‘Homepage’ Form, and drop a RepeatingPanel Repeating Panel Icon onto the page under the ‘Add an Article’ button. Change its name to articles_panel and set its item_template to your ArticleView Form. The Homepage Form should look something like this:

The Homepage design view showing a RepeatingPanel with its ItemTemplate set to the 'ArticleView' Form

The ItemTemplate property is highlighted in the Properties Panel

Step 3: Display data on article view

Next, we want to display data on each of the ‘ArticleView’ instances. Once again, we’ll use Data Bindings, and the Form’s self.item property to do this.

Open the ‘ArticleView’ Form. For each of the ’title’, ‘category’, ‘content’ and ‘image’ components, add a Data Binding to self.item:

  • title_label: Bind the text property to self.item['title']
  • category_label: Bind the text property to self.item['category']['name'] (self.item['category'] is a row from the categories table, so we want to get the ’name’ from the row)
  • content_label: Bind the text property to self.item['content']
  • image_1: Bind the source property to self.item['image']
Adding data bindings to the ArticleView Form

Step 4: Fetch the articles from the database

Next, we need to retrieve a list of articles from the Articles Data Table. We’ll use a Server Module to do this.

We’re using a Server Module because code in Server Modules can be trusted, and we might want to add authentication or other logic to this retrieval code. We recommend doing it this way for all database-backed apps.

In the App Browser, select the Sever Module and add the following function:

# In your Server Module
def get_articles():
  # Get a list of articles from the Data Table, sorted by 'created' column, in descending order
    tables.order_by("created", ascending=False)

We want to add this list to our Repeating Panel in order to display the articles on the Homepage.

We’ll define a function called refresh_articles() to do this. We can use this function after we update or delete an article and to refresh the content on the Homepage (You can read more about suggested Anvil naming conventions here.

Go back to your Homepage Form, and add this function:

  def refresh_articles(self):
    # Load existing articles from the Data Table, 
    # and display them in the RepeatingPanel
    self.articles_panel.items ='get_articles')

We want to load our news articles from the Data Table when the Homepage is opened, so let’s call our refresh_articles function when the Homepage loads.

Add this line to the bottom of the __init__ method of your Homepage Form:

  # Any code you write here will run before the form opens.

We also want to call refresh_articles() after we Create a new article so that the new article shows up on our Homepage. Modify your add_article_button_click to call refresh_articles if we save a new article

  def add_article_button_click(self, **event_args):
    # Initialise an empty dictionary to store the user inputs
    new_article = {}
    # Open an alert displaying the 'ArticleEdit' Form
    save_clicked = alert(
      title="Add Article",
      buttons=[("Save", True), ("Cancel", False)]
    # If the alert returned 'True', the save button was clicked.
    if save_clicked:'add_article', new_article)

Run your app. You should now see any articles you’ve added listed on the homepage!

The app running and showing an article displayed.

Step 5: How it works

The articles_panel is a RepeatingPanel with the template set to the ‘ArticleView’ Form.

When you set the RepeatingPanel’s items property to an iterable, the RepeatingPanel creates one instance of its item_template for each item in the iterable. It also sets the self.item property of that instance to that item from the iterable.

In this case, get_articles() returns an iterator over the ‘articles’ table, so the RepeatingPanel will create an instance of ‘ArticleView’ for each row in the data table. Each instance will have its self.item property set to its row in the ‘articles’ table. The Data Bindings on our ‘ArticleView’ form read data from self.item, so they will display data from that article.

Our app now displays the articles that have been added, we’ve finished the R in our CRUD app.

In Chapter 6, we’ll allow the user to edit articles. That’s the ‘U‘pdate part of our CRUD app.

Chapter complete

Congratulations, you've completed this chapter!