Momenteel speel ik KeyForge en Gwent. Een van mijn eerste artikels ging over Magic: the Gathering en ook mijn 3D-geprinte dobbelsteen- en fichebakjes verschenen al op deze blog. Het is dus geen geheim dat ik van kaartspellen hou, en mijn collectie decks groeit zowel online als offline snel. Er bestaan genoeg tools om je decks voor één spel bij te houden, maar ik wil zelf iets maken dat alle spellen ondersteunt die ik speel.
Dit was ook een goede gelegenheid om Pelican te leren kennen, een statische-websitegenerator voor Python. Ik gebruik Jekyll al een tijdje, maar om extra functies te ontwikkelen (zoals die uit het vorige artikel) heb je de programmeertaal Ruby nodig. Omdat ik Ruby niet zo goed beheers, zou het veel efficiënter zijn om mijn favoriete programmeertaal Python te gebruiken. Pelican leek uitstekend te passen en dit was het perfecte project om dat zelf uit te zoeken.
Je kunt het resultaat van deze blog hier bekijken. De code en instructies om DeckLock met je eigen decks te bouwen vind je op GitHub: https://github.com/4dcu-be/DeckLock
Inleiding
KeyForge
KeyForge is een spel ontworpen door dr. Richard Garfield, bekend als de bedenker van Magic: the Gathering, meer dan 25 jaar geleden. Dit spel is echter uniek: elk deck dat je koopt, is een unieke combinatie van kaarten die uitsluitend in die specifieke samenstelling bedoeld is om te spelen. Anders dan bij andere verzamelkaartspellen worden individuele kaarten niet geruild. Bovendien heeft elk deck een QR-code. Wanneer je die met de KeyForge-app scant (beschikbaar in de App Store en Play Store), wordt het deck geregistreerd op https://www.keyforgegame.com/.
Dit is perfect voor onze toepassing: alle informatie (naam, decklijst, …) van een gescand deck kunnen we rechtstreeks van de KeyForge-website halen. Het enige wat we nodig hebben is de unieke identificatiecode van het deck; al de rest halen we automatisch op. Met diezelfde identificatiecode kunnen bovendien extra statistieken over het deck (zoals de geschatte kwaliteit van de kaarten, de synergie ertussen, …) via Decks of KeyForge worden verkregen.
Pelican
Statische-websitegeneratoren zoals Jekyll en Pelican combineren je inhoud in een eenvoudig formaat (meestal Markdown of reStructuredText) met sjablonen die bepalen hoe de uiteindelijke pagina’s eruitzien. Zo ontstaan statische HTML- pagina’s die vrijwel overal kunnen worden gehost, omdat er geen databank, PHP, … nodig is. Dit elegante ontwerp met een duidelijke scheiding tussen inhoud en weergave heeft verschillende voordelen. De inhoud staat in een eenvoudig, tekstgebaseerd formaat dat gemakkelijk kan worden opgeslagen, gelezen, bewerkt en hergebruikt. Sites zijn razendsnel omdat alles vooraf wordt berekend.
Aan de slag
Ga eerst naar https://github.com/4dcu-be/DeckLock en maak je eigen fork van de repository. Gebruik vervolgens de onderstaande commando’s om je eigen repository te klonen, een virtuele omgeving te maken en alle vereiste pakketten te installeren.
git clone <url to your fork of DeckLock> ./DeckLock
cd DeckLock
python -m venv venv
source venv/bin/activate
pip install -r requirements.txt
Op Windows werkt de regel om de virtuele omgeving te activeren (source venv/bin/activate) niet. Gebruik in plaats daarvan de onderstaande regel.
venv\Scripts\activate.bat
DeckLock instellen
Het Makefile configureren
Omdat we een virtuele omgeving gebruiken waarin Pelican is geïnstalleerd, moet het pad naar het uitvoerbare bestand in
die omgeving in het Makefile worden ingesteld. Open het bestand en pas het pad in de onderstaande regel aan je
systeem aan. Het uitvoerbare Pelican-bestand hoort in venv/bin of venv/Scripts te staan.
PELICAN?=d:\Git\DeckLock\venv\Scripts\pelican
pelicanconf.py en publishconf.py
pelicanconf.py zou gebruiksklaar moeten zijn, maar kijk gerust na of bepaalde
instellingen en paden moeten worden aangepast.
In publishconf.py moet je wel de uiteindelijke URL van je site instellen.
SITEURL = "https://4dcu.be/DeckLock"
API-sleutel voor Decks of KeyForge
Als je deckstatistieken van Decks of KeyForge wilt opnemen, moet je een account aanmaken en een API-sleutel aanvragen via
https://decksofkeyforge.com/. Maak een bestand .env en voeg de onderstaande regel toe.
Een .env-bestand dat niet wordt gecommit, houdt je API-sleutel geheim.
DOK_API_KEY=your_api_key
Identificatiecodes van KeyForge-decks
Vervolgens moet je in pelicanconf.py instellen in welke map de KeyForge-gegevens te vinden zijn. Merk op dat dit pad
relatief is ten opzichte van de inhoudsmap.
KEYFORGE_PATH = "./data"
Voeg nu een bestand keyforge.json toe aan ./content/data, met de onderstaande structuur en de identificatiecodes van de decks die je wilt opnemen.
Als voorbeeld is een bestand met mijn eigen KeyForge-decks meegeleverd. De structuur hoort er als volgt uit te zien.
[
{
"deck_id" : "a4268ae8-a9f6-48c7-9739-b28a3553b108"
}, {
"deck_id" : "bfbf6786-218c-4320-a7b1-7ed4d6eddc69"
}
]
Het platform bouwen
Je kunt make gebruiken om de website te bouwen (als make op je systeem beschikbaar is). Met make html maak je een lokale versie
om in de map _site te testen. Gebruik make release om de publicatieversie in de map ./docs te maken.
make html
make release
Je kunt Pelican ook rechtstreeks gebruiken. De inhoud staat in de map ./content en voor een lokale testbuild stel je
./_site als uitvoermap in. Schrijf de uitvoer met de publicatie-instellingen naar de map ./docs, zodat die gemakkelijk
op GitHub kan worden gehost.
pelican ./content -o ./_site
pelican ./content -o ./docs -s publishconf.py
Lokaal hosten om te testen
Je kunt de ingebouwde webserver van Pelican starten met het commando make serve.
Je kunt de site ook bouwen met make html, naar de map _site gaan en een webserver starten
met het commando python -m http.server.
In beide gevallen kun je de site bekijken door in je browser naar http://localhost:8000 te gaan.
Hosten op GitHub
DeckLock bevat een commando make release dat de definitieve versie van de website naar de map ./docs schrijft. Zorg
ervoor dat je alle bestanden in je repository commit en pusht. Op GitHub kun je instellen dat deze map voor de projectpagina’s wordt gebruikt. Schakel dat in via de instellingen en je hebt
gratis hosting om de decks uit je kaartspelcollectie te tonen.
Hoe het werkt
Alle code staat op https://github.com/4dcu-be/DeckLock. Kort samengevat kan
Pelican functies op verschillende momenten tijdens de build activeren. Via een plugin werd de functie
get_keyforge_external_data toegevoegd, die wordt uitgevoerd wanneer Pelican initialiseert. Deze functie leest de instellingen,
zoekt waar keyforge.json en de API-sleutel zijn opgeslagen en maakt verbinding met de verschillende websites om alle vereiste
informatie op te halen.
Pelican gebruikt drie componenten om pagina’s te maken: Readers (die bestanden lezen en omzetten in een pagina, zoals blogposts, artikels, …), Generators die gegevens verwerken, een URL genereren en alles met het juiste sjabloon naar een Writer sturen, die de gegevens en het sjabloon tot één HTML-bestand combineert. Generators worden gebruikt om overzichtspagina’s per categorie, … te maken. De standaard Writer volstaat meestal, dus door Readers en Generators toe te voegen gebeurt de magie waarmee je de specifieke structuur van je eigen site bouwt.
De functie get_keyforge_external_data schrijft alles wat nodig is naar één JSON-bestand. Daardoor kunnen we een Reader achterwege laten
en een Generator gebruiken die de gegevens laadt, voor elk deck een URL bouwt en de relevante gegevens naar onze sjablonen stuurt.
Hieronder staat een skelet dat toont hoe je een functie maakt en registreert om bij de initialisatie te worden uitgevoerd, en hoe je een generator maakt en bij Pelican registreert zodat die onze HTML-bestanden produceert.
from pelican import signals, generators
class KeyForgeGenerator(generators.Generator):
""" Generator Class to produce pages based on keyforge.cache.json """
template_overview = "keyforge_overview.html"
template_deck = "keyforge_deck.html"
def __init__(self, context, settings, path, theme, output_path, **kwargs):
# Initialization function
def generate_output(self, writer):
# This function is required, this will be started by Pelican
# Here we'll call two other functions, one to create an overview page
# and one to create a page with deck details.
self.generate_keyforge_overview_page(writer, self.keyforge_data)
for k, v in self.keyforge_data.items():
self.generate_keyforge_deck_page(writer, k, v)
def generate_keyforge_deck_page(self, writer, deck_id, data):
# Function to generate deck pages
def generate_keyforge_overview_page(self, writer, data):
# Function to generate overview page
def get_keyforge_external_data(generator):
# Here we can get all settings from generator.settings ...
# Access APIs
# Write all output to disk
def get_generators(generators):
return KeyForgeGenerator
def register():
"""Register our function to get all data and generator to create the pages"""
signals.initialized.connect(get_keyforge_external_data)
Conclusie
Hoewel Pelican wat meer configuratie vergde dan Jekyll en daardoor moeilijker was om mee te beginnen, was het een groot voordeel dat ik het met Python kon uitbreiden. Complexe functies implementeren, zoals gegevens uit externe API’s ophalen, was met pakketten als requests en de ingebouwde json-module helemaal niet zo moeilijk. Pelican is dus een uitstekend framework voor statische pagina’s die een zwaardere verwerking van invoergegevens of verbindingen met externe gegevens vereisen. Voor een eenvoudige blog ben je waarschijnlijk sneller aan de slag met Jekyll.
Er bestaan ook allerlei frameworks in andere talen die ik niet heb bekeken. Vooral Gatsby, dat onder de motorkap het JavaScript-ecosysteem gebruikt, en Hugo, dat door Go wordt aangedreven. Gatsby is bijzonder interessant omdat het met React verweven is, wat handig kan zijn om een krachtige, interactieve front-end te bouwen…
Ondersteuning voor Magic: the Gathering werd in het volgende artikel geïmplementeerd. Gwent werd in deel 3 toegevoegd.
Vond je dit artikel interessant? Trakteer me op een koffie