Creating an image gallery in Anvil

Dear community, I learned about Anvil via the Talk Python podcast & also followed the Anvil tutorial from Talk Python Training. I am currently evaluating if Anvil is suitable for the project I am currently working on – building an Art Gallery kind of website for my wife. I am proficient in Python and also familiar with Web Development Basics.

I am currently struggling with getting a collection of images + text to display the way I would wish them to. Maybe someone here could help me out or point me in the right direction? :slight_smile:

What I’m trying to do:
I wish to display a gallery of images, with each “component” of the gallery consisting of an image and a title and keyword directly below it. What I would like to accomplish is having 2-3 images (+ title below) show up in one row on the page and then wrap over to the next line.

The images are stored as Media files in a data table along with the titles and other information.

What I’ve tried and what’s not working:
I created the data tables, have a Form to add images to the database, and I managed to have all the images display with the Help of a RepeatingPanel and linked item_template form. However I only manage to display one image + description per row and not multiple images per row as I desire.

I tried with multiple of the available container types - ColumnPanel, FlowPanel, and also the Grid, but no luck so far.

What I’ve tried and what’s not working:
Sketch of desired outcome:

Image_1 Image_2 Image_3
title, info title, info title, info

Image_4 Image_5 Image_6
title, info title, info title, info

Ideally it would automatically adjust to only two image per row, if the screen size gets too small and maybe one on a mobile device.

Is what I am trying to achieve feasible with Anvil?

Many thanks in advance,
Arno

1 Like

Without seeing any code snippets or clone links, it’s hard to determine what you are trying to do here.
However, it seems like the problem is happening because Repeating Panel doesn’t support adding components.

You can either go for editing the theme.css file of your Anvil App to make repeating panel achieve that Horizontal RepeatingPanel (Again) - Anvil Q&A - Anvil Community Forum or use a Flow Panel to add items in a loop.

In your case, the Code can be something like this

rows_to_display=app_tables.images.search()
for row in rows_to_display:
   L=LinearPanel()
   L.add_component(Image(source=row['Image']))
   L.add_component(Label(text=row['title']))
   L.add_component(Label(text=row['info']))
   self.flow_panel_1.add_component(L)

Here’s a linked topic that might be useful.

Thank you both for offering your support! Both of the linked topics seem spot-on. I will experiment with the described approaches and report back if I get it working as intended or if I might need another small nudge in the right direction.

Just wanted to drop a response already and voice my appreciation. Thanks for helping me out! :slight_smile:

Using a custom role together with the following css as suggested by @stucork did the trick :tada:

.anvil-role-3-cols > div {
  display: grid;
  grid-template-columns: repeat(3, 1fr);
  column-gap: 3%; /*adjust as needed*/
}

One more question regarding this, if I may:
Below the images I display two further pieces of textual information from the same data table that the image originates from. I would like the text to align with the right side of the image and have the two text labels close to each other. At the moment however there is a relatively big gap between them:

The properties are set as follows – so the title is already right-aligned:

If I move the “Title” further to the right in the design view, then the next text labels starts to wrap and there is still a lot of white-space in between:

The “Title” text data does not have any trailing whitespace so I am wondering why there is such a big “gap” between the two pieces of textual information and if there is a way for me to adjust that.

Or alternatively: Is there a way to refer to two data table attributes simultaneously from within one Text label component?

Many thanks!

You could data bind the text property of the label to something like f"{self.item['title']} {self.item['size']}"

Thank you @jshaffstall, that one really made clear the connection between the repeating_column and item_template. I wasn’t aware before that each item passed to the template could be accessed and manipulated so easily in code. This gets me 95% there.

Now the final thing I would wish to be able to do is format the two accessed properties separately. So, if the string could support markdown it would look like this: f"**{self.item['title']}** {self.item['size']}", or if it could support processing a string as HTML f"<strong>{self.item['title']}</strong> {self.item['size']}" i.e. the first part of the f-string would be bold.

While writing this last question out I actually remembered seeing the “Rich Text” component before and wondering about use-cases for it. Just tried it out and – sure enough – it does exactly what I asked for in the paragraph above.

For the record:

  • To access multiple properties from a table in a single text component, use f"{self.item['property_1']} {self.item['property_2']}" as described by @jshaffstall.
  • To style the accessed contents in a non-uniform way, use the RichText Component together with Markdown or HTML as format.

This answers everything for me. Thanks again everyone for your great support!

2 Likes

@arno

This is a great idea.

Would you mind dropping in a clone for the image gallery code?