Skip to content

Show a game page

This guide builds the information for a game page the way the Bazoodle website does, from a game’s detail and its pictures. The first part is JavaScript for Node.js 18 or later and uses the api helper from the JavaScript guide; the picture part is Python 3 with the helper from the Python guide.

const game = await api("/catalog/games/coins");
console.log(game.title);
console.log(game.rating_label); // "Kid-friendly"
console.log(`${game.players.min}-${game.players.max} players`);
console.log(game.tags.join(", "));
console.log(game.like_pct === null ? "not rated yet" : `${game.like_pct}% liked`);

like_pct is null until a game has at least five votes; say “not rated yet” rather than showing zero.

console.log(game.description);
if (game.controls_text) console.log("How to play:\n" + game.controls_text);

Both are plain text written by the creator. Paragraphs are separated by blank lines, and lines in controls_text by line breaks. Escape them before putting them in a web page.

const pictures = [game.thumbnail_url, ...game.gallery].filter(Boolean);
console.log(pictures.length, "pictures");
for (const update of game.updates) {
console.log(new Date(update.at * 1000).toISOString().slice(0, 10), "version", update.version, update.notes);
}
console.log(game.similar.map((g) => `${g.title} -> https://bazoodle.com/game/${g.id}`));

Use picture addresses exactly as given (Media files); the list may be empty. at is in seconds, so multiply by 1000 for JavaScript dates. similar already holds up to six game cards: do not call the API again for each one.

Thumbnails never change at a given address, so you can download one once and reuse it forever. This Python function uses the api helper from the Python guide:

import os
import hashlib
import urllib.request
def save_thumbnail(url, folder="thumbnails"):
if not url:
return None
os.makedirs(folder, exist_ok=True)
name = hashlib.sha256(url.encode()).hexdigest()[:16] + ".img"
path = os.path.join(folder, name)
if os.path.exists(path):
return path # already downloaded: the file at this address never changes
request = urllib.request.Request(url, headers={"User-Agent": "MyGameList/1.0 (contact: you@example.com)"})
with urllib.request.urlopen(request, timeout=20) as response:
with open(path, "wb") as out:
out.write(response.read())
return path
page = api("/catalog/browse", sort="new", limit=3)
for game in page["games"]:
print(game["title"], "->", save_thumbnail(game["thumbnail_url"]))

The check os.path.exists is the whole cache: the response is marked Cache-Control: public, max-age=31536000, immutable, so the file at that address will never be different. If a creator replaces a picture, it gets a new address: your next call to Browse returns the new thumbnail_url and your code downloads it because it is a new name.

On a web page you can also point an <img> straight at the address; pictures can be shown on any website. Downloading and serving your own copy is kinder to our servers when you have many visitors. The pictures belong to their creators: use them to show and link to the game, not as general artwork.