1

I'm having a hard time phrasing the question - so there may be answers on Stackoverflow already - but I'm working with an API that provides image links to external URLS alongside other data in a JSON file. Unfortunately, some of the links no longer work.

My goal is to determine this in an if-statement and if the image doesn't load, don't load any of the other data either.

Here's the code I have attempted, but unfortunately, some of the items are still getting through:

{% for i in range(cards[setName]|length) %}
    {% if cards[setName][i]['img'] %}
        <p>{{ cards[setName][i]['name'] }}</p>
        <a href="{{ cards[setName][i]['img'] }}">
            <img src="{{ cards[setName][i]['img'] }}">
        </a>
    {% endif %}
{% endfor %}
Bonteq
  • 777
  • 7
  • 24
  • You can use JS to hide the data if the image doesn't load. As shown here: https://stackoverflow.com/q/3235913/1925257 – xyres Oct 31 '17 at 13:32
  • @xyres has the best solution - your code still displays dead images because `cards[setName][i]['img']` is not `null` – sunny Oct 31 '17 at 13:34
  • Is there a pythonic way of dealing with this issue? I'd rather not delve into jQuery for this one issue. – Bonteq Oct 31 '17 at 14:00
  • @Bonteq I've posted an answer that doesn't require jQuery, but plain-old JS. And you only need to write one line for it. – xyres Oct 31 '17 at 14:09

2 Answers2

2

Jinja doesn't know if there link is working or not. It just gets a string. So either you do this check before sending out the JSON in your api, or you use the javascript solutions suggested in comments to hide the failing images.

Doing the check 'just' before sending out the json is a bad idea tho, since you'll open many requests to check each url. Best use a async job to check the image in your database.

Also, why use a i in range? This does the same and increase readability.

{% for card in cards[setName] %}
    {% if card['img'] %}
        <p>{{ card['name'] }}</p>
        <a href="{{ card['img'] }}">
            <img src="{{ card['img'] }}">
        </a>
    {% endif %}
{% endfor %}
The Pjot
  • 1,801
  • 1
  • 12
  • 20
  • Hey, so @xyres' answer ended up working for the question I asked, but I dug around the URL's that were being provided and most, if not all, of the 'faulty' URL's worked if I changed the last few characters. Is this something that could be changed during the call of the API? I'm happy to put up a new thread if you'd prefer that. – Bonteq Oct 31 '17 at 14:23
  • Why kind of url's are you using? Changing the 'last few characters' is a quite broad. Could mean changing a '.png' to a '.jpeg' or similar extensions changes. Or .. when using 'tinyurl'-like url's, a completly different url. Bit more information would be useful. – The Pjot Oct 31 '17 at 14:27
  • Sure. So for example, this URL is being presented as http://wow.zamimg.com/images/hearthstone/cards/enus/original/CS2_049_H1.png but, if I maintain the first 7 characters and delete everything between them and the .png, the picture shows up properly. So rather than the above URL, it is http://wow.zamimg.com/images/hearthstone/cards/enus/original/CS2_049.png – Bonteq Oct 31 '17 at 14:39
  • If it's always the same '_H1' that you remove, you could consider using `|replace` as per [jinja docs](http://jinja.pocoo.org/docs/2.9/templates/#replace). Else it will be difficult to do this in jinja. Because splitting isn't possible per default (might be extensions for that?). – The Pjot Oct 31 '17 at 15:07
  • It isn't always '_H1', but it is always what's after the first 7 characters after the last backlash. i.e: 'URL'/CFM_111.png rather than 'URL'/CFM_111_xx.png so I may have 'URL'/CFM_111_xx_xxx.png but all I need is the first 7 characters (CFM_111) and the .png extension. Thank you for the jinja docs link, I'll check it out and see if I can find something creative. – Bonteq Oct 31 '17 at 15:37
  • I was able to find a solution using regex. Here's what I have so far: testURL = 'http://wow.zamimg.com/images/hearthstone/cards/enus/original/CS2_04 9_H1_AT_132.png' regex = r"(.+/.{7})" regexC = re.compile(regex) regexC.match(testURL).groups()[0] + ".png" – Bonteq Oct 31 '17 at 16:42
  • Ah thought you needed a solution in Jinja :) This looks like a good solution. Other option would be splitting and slicing; ```testURL = 'wow.zamimg.com/images/hearthstone/cards/enus/original/CS2_049_H1_AT_132.png' url, filename = testURL.rsplit('/', 1) name, ext = filename.split('.') name = name[0:7] final_url = "{0}/{1}.{2}".format(url, name, ext) print(final_url)``` – The Pjot Nov 01 '17 at 07:28
1

Here's a minimal example. Modify it as per your needs. All it does is it hides the parent div of the img if the image doesn't load.

<div> <!-- this div contains the image and other data -->

    <img src="path/to/image.jpg" onError="this.onerror = '';this.parentElement.style.display='none';">

    <!-- ... other data ... -->
</div>

If the div is the grand-parent of img, not the parent, to access it, use:

this.parentElement.parentElement
xyres
  • 20,487
  • 3
  • 56
  • 85