Inhalte API
Die Content API ermöglicht den Zugriff auf redaktionelle Inhalte des Kulturpools. Sie liefert strukturierte Content-Seiten mit verschiedenen Block-Typen, SEO-Metadaten und mehrsprachigen Übersetzungen für die Website-Darstellung.
Endpunkte
Alle Inhalte abrufen
GET /content
Ruft alle verfügbaren redaktionellen Inhalte vom CMS ab.
Antwort
{
"data": [
{
"id": 1,
"status": "published",
"sort": 1,
"date_published": "2024-01-15T09:00:00Z",
"color_text": "#333333",
"color_background": "#ffffff",
"seo": {
"id": 1,
"title": "Willkommen im Kulturpool - Digitale Kunst entdecken",
"meta_description": "Entdecken Sie die Vielfalt österreichischer Kultur im digitalen Raum",
"canonical_url": "https://kulturpool.at/willkommen"
},
"category": {
"id": 1,
"sort": 1,
"translations": []
},
"translations": [
{
"id": 1,
"languages_code": "de",
"title": "Willkommen im Kulturpool",
"slug": "willkommen",
"summary": "Entdecken Sie die Vielfalt österreichischer Kultur",
"items": [
{
"id": 1,
"collection": "block_text",
"item": {
"id": 1,
"type": "hero",
"heading": "Willkommen im Kulturpool",
"body": "<p>Hier finden Sie digitalisierte Kunst und Kultur aus österreichischen Institutionen.</p>",
"heading_tag": "h1",
"is_enabled": true
}
}
]
}
]
}
]
}
Einzelnen Content-Eintrag abrufen
GET /content/{content_id}
Ruft einen spezifischen Content-Eintrag anhand seiner ID ab.
Parameter
Parameter |
Typ |
Beschreibung |
content_id |
integer |
Die eindeutige ID des Content-Eintrags (Pfad-Parameter) |
Beispiel
curl -X GET "https://api.kulturpool.at/content/1"
Antwort
{
"data": {
"id": 1,
"status": "published",
"sort": 1,
"date_published": "2024-01-15T09:00:00Z",
"color_text": "#333333",
"color_background": "#ffffff",
"seo": {
"id": 1,
"title": "Willkommen im Kulturpool - Digitale Kunst entdecken",
"meta_description": "Entdecken Sie die Vielfalt österreichischer Kultur im digitalen Raum",
"canonical_url": "https://kulturpool.at/willkommen"
},
"category": {
"id": 1,
"sort": 1,
"translations": []
},
"translations": [
{
"id": 1,
"languages_code": "de",
"title": "Willkommen im Kulturpool",
"slug": "willkommen",
"summary": "Entdecken Sie die Vielfalt österreichischer Kultur",
"items": [
{
"id": 1,
"collection": "block_text",
"item": {
"id": 1,
"type": "hero",
"heading": "Willkommen im Kulturpool",
"body": "<p>Hier finden Sie digitalisierte Kunst und Kultur aus österreichischen Institutionen.</p>",
"heading_tag": "h1",
"is_enabled": true
}
}
]
}
]
}
}
Datenstruktur
Content
Feld |
Typ |
Beschreibung |
id |
integer |
Eindeutige ID des Content-Eintrags |
status |
string |
Veröffentlichungsstatus ("published", "draft") |
sort |
integer |
Sortierreihenfolge |
date_published |
string |
Veröffentlichungsdatum (ISO 8601) |
color_text |
string |
Textfarbe (Hex-Code) |
color_background |
string |
Hintergrundfarbe (Hex-Code) |
seo |
SEO |
SEO-Metadaten |
category |
ContentCategory |
Zugeordnete Kategorie |
translations |
ContentTranslation[] |
Mehrsprachige Versionen |
SEO
Feld |
Typ |
Beschreibung |
id |
integer |
SEO-Eintrag ID |
title |
string |
Meta-Titel für Suchmaschinen |
meta_description |
string |
Meta-Beschreibung |
canonical_url |
string |
Kanonische URL |
no_index |
boolean |
Suchmaschinenindexierung verhindern |
no_follow |
boolean |
Link-Verfolgung verhindern |
og_image |
File |
Open Graph Bild |
ContentTranslation
Feld |
Typ |
Beschreibung |
id |
integer |
Übersetzungs-ID |
languages_code |
string |
Sprachcode (ISO 639-1) |
title |
string |
Seitentitel |
slug |
string |
URL-Slug |
summary |
string |
Kurzzusammenfassung |
items |
ContentTranslationsItem[] |
Content-Blöcke |
ContentTranslationsItem
Feld |
Typ |
Beschreibung |
id |
integer |
Item-ID |
collection |
string |
Block-Typ ("block_text", "block_slider", etc.) |
item |
ContentItem |
Der eigentliche Content-Block |
sort |
integer |
Sortierreihenfolge |
Content-Block-Typen
BlockText
Textblöcke für Überschriften, Fließtext und Hero-Bereiche.
Feld |
Typ |
Beschreibung |
id |
integer |
Block-ID |
type |
string |
Block-Untertyp ("hero", "text", "quote") |
heading |
string |
Überschrift |
body |
string |
Haupttext (HTML) |
summary |
string |
Zusammenfassung |
heading_tag |
string |
HTML-Tag für Überschrift ("h1", "h2", etc.) |
heading_size |
string |
Überschriftsgröße |
is_enabled |
boolean |
Block ist aktiv |
BlockSlider
Bildergalerien und Slider-Komponenten.
Feld |
Typ |
Beschreibung |
id |
integer |
Block-ID |
type |
string |
Slider-Typ |
aspect_ratio |
string |
Seitenverhältnis (z.B. "16:9") |
row_mode |
boolean |
Reihen-Modus aktiviert |
pick_items |
integer |
Anzahl anzuzeigender Items |
randomize |
boolean |
Zufällige Reihenfolge |
items |
object |
Slider-Inhalte |
BlockLinks
Linksammlungen und Navigationsblöcke.
Feld |
Typ |
Beschreibung |
id |
integer |
Block-ID |
heading |
string |
Block-Überschrift |
type |
string |
Link-Block-Typ |
summary |
string |
Beschreibung |
item |
object |
Link-Daten |
BlockEmbed
Eingebettete Inhalte wie Videos oder externe Widgets.
Feld |
Typ |
Beschreibung |
id |
integer |
Block-ID |
type |
string |
Embed-Typ |
link |
string |
URL des eingebetteten Inhalts |
code |
string |
Embed-Code |
aspect_ratio |
string |
Seitenverhältnis |
max_width |
integer |
Maximale Breite in Pixeln |
file |
File |
Eingebettete Datei |
BlockList
Listen-Darstellungen für Sammlungen und Aufzählungen.
Feld |
Typ |
Beschreibung |
id |
integer |
Block-ID |
type |
string |
Listen-Typ |
heading |
string |
Listen-Überschrift |
summary |
string |
Listen-Beschreibung |
collection |
string |
Quell-Collection |
mode |
string |
Darstellungsmodus |
pick_items |
integer |
Anzahl Items |
show_filter |
boolean |
Filter anzeigen |
row_mode |
boolean |
Reihen-Layout |
randomize |
boolean |
Zufällige Sortierung |
items |
object[] |
Listen-Items |
Beispiel-Code
JavaScript/Fetch
// Alle Inhalte abrufen
const response = await fetch('https://api.kulturpool.at/content');
const { data: contentPages } = await response.json();
// Einzelne Seite abrufen
const pageResponse = await fetch('https://api.kulturpool.at/content/1');
const { data: page } = await pageResponse.json();
// Deutsche Übersetzung extrahieren
const germanTranslation = page.translations.find(t => t.languages_code === 'de');
console.log(`Titel: ${germanTranslation.title}`);
console.log(`Slug: ${germanTranslation.slug}`);
Python/requests
import requests
# Alle Inhalte abrufen
response = requests.get('https://api.kulturpool.at/content')
content_pages = response.json()['data']
# Einzelne Seite abrufen
page_response = requests.get('https://api.kulturpool.at/content/1')
page = page_response.json()['data']
# Deutsche Übersetzung finden
german_translation = next(
(t for t in page['translations'] if t['languages_code'] == 'de'),
None
)
if german_translation:
print(f"Titel: {german_translation['title']}")
print(f"Slug: {german_translation['slug']}")
Content-Blöcke verarbeiten
function processContentBlocks(translation) {
return translation.items.map(item => {
const { collection, item: block } = item;
switch (collection) {
case 'block_text':
return {
type: 'text',
heading: block.heading,
body: block.body,
tag: block.heading_tag || 'h2'
};
case 'block_slider':
return {
type: 'slider',
aspectRatio: block.aspect_ratio,
items: block.items || []
};
case 'block_embed':
return {
type: 'embed',
url: block.link,
code: block.code,
maxWidth: block.max_width
};
default:
return { type: 'unknown', data: block };
}
});
}
Anwendungsfälle
Dynamische Website-Seiten
async function renderContentPage(slug) {
// Alle Seiten abrufen und nach Slug filtern
const response = await fetch('https://api.kulturpool.at/content');
const { data: pages } = await response.json();
const page = pages.find(page =>
page.translations.some(t => t.slug === slug)
);
if (!page) {
throw new Error(`Seite mit Slug "${slug}" nicht gefunden`);
}
const translation = page.translations.find(t => t.languages_code === 'de');
return {
title: translation.title,
seoTitle: page.seo?.title || translation.title,
metaDescription: page.seo?.meta_description || translation.summary,
canonicalUrl: page.seo?.canonical_url,
blocks: processContentBlocks(translation),
theme: {
textColor: page.color_text,
backgroundColor: page.color_background
}
};
}
Content-Management für Headless CMS
class ContentManager {
constructor(baseUrl = 'https://api.kulturpool.at') {
this.baseUrl = baseUrl;
this.cache = new Map();
}
async getPage(id) {
if (this.cache.has(id)) {
return this.cache.get(id);
}
const response = await fetch(`${this.baseUrl}/content/${id}`);
const { data: page } = await response.json();
this.cache.set(id, page);
return page;
}
async getPageBySlug(slug, language = 'de') {
const response = await fetch(`${this.baseUrl}/content`);
const { data: pages } = await response.json();
return pages.find(page =>
page.translations.some(t =>
t.slug === slug && t.languages_code === language
)
);
}
getBlocks(page, language = 'de') {
const translation = page.translations.find(t => t.languages_code === language);
return translation?.items || [];
}
getActiveBlocks(page, language = 'de') {
return this.getBlocks(page, language)
.filter(item => item.item.is_enabled !== false)
.sort((a, b) => (a.sort || 0) - (b.sort || 0));
}
}
Mehrsprachige Navigation
async function buildNavigation() {
const response = await fetch('https://api.kulturpool.at/content');
const { data: pages } = await response.json();
const navigation = {};
pages.forEach(page => {
page.translations.forEach(translation => {
const { languages_code, title, slug } = translation;
if (!navigation[languages_code]) {
navigation[languages_code] = [];
}
navigation[languages_code].push({
title,
slug,
url: `/${languages_code}/${slug}`,
sort: page.sort || 999
});
});
});
// Sortieren nach sort-Wert
Object.keys(navigation).forEach(lang => {
navigation[lang].sort((a, b) => a.sort - b.sort);
});
return navigation;
}
Fehlerbehandlung
404 - Content nicht gefunden
{
"detail": "Content not found"
}
500 - Validierungsfehler
{
"detail": "Response validation error for content 1: ..."
}