Files
tibi-svelte-starter/api/collections/content.yml
T
apairon 1b24bb2157 feat: enhance admin API helpers with CRUD operations for collections and seed data management
- Added functions for creating, updating, deleting, and listing collection entries in admin API.
- Introduced seed data management for consistent test content across tests.
- Updated global setup and teardown processes to ensure seeded content is created and cleaned up.
- Refactored existing tests to utilize seeded content for improved reliability and maintainability.
2026-05-12 20:36:06 +00:00

462 lines
14 KiB
YAML

########################################################################
# Content collection — CMS-managed pages with pagebuilder blocks
########################################################################
name: content
meta:
label: { de: "Inhalte", en: "Content" }
muiIcon: article
group: content
preview:
label: name
secondary: path
tertiary: lang
badge: type
image: _pagebuilderThumbnail
pagebuilder:
screenshot:
- field: blocks
fileField: _pagebuilderThumbnail
i18n:
entry:
languageField: lang
groupField: translationKey
sidebar:
- group: publishing
label: { de: "Veröffentlichung", en: "Publishing" }
- group: settings
label: { de: "Einstellungen", en: "Settings" }
- group: seo
label: { de: "SEO", en: "SEO" }
permissions:
public:
methods:
get: true
user:
methods:
get: true
post: true
put: true
delete: true
"token:${ADMIN_TOKEN}":
methods:
get: true
post: true
put: true
delete: true
fields:
- name: active
type: boolean
meta:
label: { de: "Aktiv", en: "Active" }
position: sidebar:publishing
- name: type
type: string
meta:
label: { de: "Typ", en: "Type" }
position: sidebar:settings
- name: lang
type: string
meta:
label: { de: "Sprache", en: "Language" }
position: sidebar:settings
- name: translationKey
type: string
meta:
label: { de: "Übersetzungsschlüssel", en: "Translation Key" }
position: sidebar:settings
- name: name
type: string
meta:
label: { de: "Name", en: "Name" }
- name: path
type: string
meta:
label: { de: "Pfad", en: "Path" }
- name: alternativePaths
type: object[]
meta:
label: { de: "Alternative Pfade", en: "Alternative Paths" }
subFields:
- name: path
type: string
- name: teaserText
type: string
meta:
label: { de: "Teasertext", en: "Teaser Text" }
- name: _pagebuilderThumbnail
type: file
meta:
hide: true
- name: blocks
type: object[]
meta:
label: { de: "Inhaltsblöcke", en: "Content Blocks" }
position: main
drillDown: false
widget: pagebuilder
pagebuilder:
blockTypeField: type
defaultViewport: desktop
blockRegistry:
file: /_/assets/dist/admin.mjs?v=${ADMIN_ASSET_VERSION}
subFields:
- name: hide
type: boolean
meta:
label: { de: "Block ausblenden", en: "Hide Block" }
dependsOn:
eval: $parent.type != ''
containerProps:
layout:
size: col-4
- name: type
type: string
meta:
label: { de: "Blocktyp", en: "Block Type" }
widget: select
defaultValue: richtext
helperText:
de: "Wähle zuerst den Blocktyp. Danach werden nur die passenden Felder angezeigt."
en: "Choose the block type first. Then only the relevant fields are shown."
containerProps:
layout:
size: col-8
choices:
- id: hero
name: { de: "Hero", en: "Hero" }
description:
{
de: "Hero mit Bild und Call-to-Action.",
en: "Hero with image and call to action.",
}
- id: features
name: { de: "Features", en: "Features" }
description:
{
de: "Feature-Übersicht mit strukturierten Boxen.",
en: "Feature overview with structured boxes.",
}
- id: richtext
name: { de: "Richtext", en: "Richtext" }
description:
{
de: "Fließtext optional mit Bild.",
en: "Body text optionally with image.",
}
- id: accordion
name: { de: "Akkordeon", en: "Accordion" }
description:
{
de: "Aufklappbare Fragen und Antworten.",
en: "Expandable questions and answers.",
}
- id: contact-form
name: { de: "Kontaktformular", en: "Contact Form" }
description:
{
de: "Kontaktformular mit Intro-Text.",
en: "Contact form with intro text.",
}
- name: headline
type: string
meta:
label: { de: "Überschrift", en: "Headline" }
dependsOn:
eval: $parent.type == 'hero' || $parent.type == 'features' || $parent.type == 'richtext' || $parent.type == 'accordion' || $parent.type == 'contact-form'
containerProps:
layout:
size: col-8
- name: headlineH1
type: boolean
meta:
label: { de: "Als H1 rendern", en: "Render as H1" }
dependsOn:
eval: $parent.type == 'hero'
containerProps:
layout:
size: col-4
- name: subline
type: string
meta:
label: { de: "Unterzeile", en: "Subline" }
dependsOn:
eval: $parent.type == 'hero'
inputProps:
multiline: true
rows: 3
- name: tagline
type: string
meta:
label: { de: "Dachzeile", en: "Tagline" }
dependsOn:
eval: $parent.type == 'hero' || $parent.type == 'features' || $parent.type == 'richtext' || $parent.type == 'accordion'
containerProps:
layout:
size: col-6
- name: anchorId
type: string
meta:
label: { de: "Anker-ID", en: "Anchor ID" }
dependsOn:
eval: $parent.type == 'features' || $parent.type == 'richtext' || $parent.type == 'accordion' || $parent.type == 'contact-form'
containerProps:
layout:
size: col-6
- name: containerWidth
type: string
meta:
label: { de: "Containerbreite", en: "Container Width" }
widget: select
dependsOn:
eval: $parent.type == 'hero'
containerProps:
layout:
size: col-6
choices:
- id: ""
name: { de: "Standard", en: "Default" }
- id: wide
name: { de: "Breit", en: "Wide" }
- id: full
name: { de: "Volle Breite", en: "Full Width" }
- name: padding
type: object
meta:
label: { de: "Innenabstand", en: "Padding" }
dependsOn:
eval: $parent.type == 'features' || $parent.type == 'richtext' || $parent.type == 'accordion' || $parent.type == 'contact-form'
drillDown: false
containerProps:
layout:
size: col-6
subFields:
- name: top
type: string
meta:
label: { de: "Oben", en: "Top" }
widget: select
hideLabel: true
containerProps:
layout:
size: col-6
choices:
- id: ""
name: { de: "Standard", en: "Default" }
- id: sm
name: { de: "Klein", en: "Small" }
- id: md
name: { de: "Mittel", en: "Medium" }
- id: lg
name: { de: "Groß", en: "Large" }
- name: bottom
type: string
meta:
label: { de: "Unten", en: "Bottom" }
widget: select
hideLabel: true
containerProps:
layout:
size: col-6
choices:
- id: ""
name: { de: "Standard", en: "Default" }
- id: sm
name: { de: "Klein", en: "Small" }
- id: md
name: { de: "Mittel", en: "Medium" }
- id: lg
name: { de: "Groß", en: "Large" }
- name: callToAction
type: object
meta:
label: { de: "Call-to-Action", en: "Call to Action" }
dependsOn:
eval: $parent.type == 'hero'
drillDown: false
subFields:
- name: buttonText
type: string
meta:
label: { de: "Button-Text", en: "Button Text" }
containerProps:
layout:
size: col-4
- name: buttonLink
type: string
meta:
label: { de: "Button-Link", en: "Button Link" }
containerProps:
layout:
size: col-5
- name: buttonTarget
type: string
meta:
label: { de: "Link-Target", en: "Link Target" }
widget: select
containerProps:
layout:
size: col-3
choices:
- id: ""
name: { de: "Gleiches Fenster", en: "Same Window" }
- id: _blank
name: { de: "Neuer Tab", en: "New Tab" }
- name: heroImage
type: object
meta:
label: { de: "Hero-Bild", en: "Hero Image" }
dependsOn:
eval: $parent.type == 'hero'
drillDown: false
subFields:
- name: image
type: string
meta:
label: { de: "Bild", en: "Image" }
widget: foreignMedia
foreign:
collection: medialib
id: _id
subNavigation: 0
- name: text
type: string
meta:
label: { de: "Text", en: "Text" }
dependsOn:
eval: $parent.type == 'richtext'
widget: richtext
inputProps:
rows: 8
- name: featureBoxes
type: object[]
meta:
label: { de: "Feature-Boxen", en: "Feature Boxes" }
dependsOn:
eval: $parent.type == 'features'
drillDown: false
preview: title
subFields:
- name: icon
type: string
meta:
label: { de: "Icon", en: "Icon" }
widget: select
containerProps:
layout:
size: col-4
choices:
- id: lightning
name: { de: "Blitz", en: "Lightning" }
- id: palette
name: { de: "Palette", en: "Palette" }
- id: database
name: { de: "Daten", en: "Data" }
- id: globe
name: { de: "Globus", en: "Globe" }
- id: monitor
name: { de: "Monitor", en: "Monitor" }
- id: flask
name: { de: "Labor", en: "Lab" }
- name: title
type: string
meta:
label: { de: "Titel", en: "Title" }
containerProps:
layout:
size: col-8
- name: text
type: string
meta:
label: { de: "Text", en: "Text" }
inputProps:
multiline: true
rows: 4
- name: imagePosition
type: string
meta:
label: { de: "Bildposition", en: "Image Position" }
widget: select
dependsOn:
eval: $parent.type == 'richtext'
containerProps:
layout:
size: col-4
choices:
- id: none
name: { de: "Kein Bild", en: "No Image" }
- id: left
name: { de: "Links", en: "Left" }
- id: right
name: { de: "Rechts", en: "Right" }
- name: image
type: string
meta:
label: { de: "Bild", en: "Image" }
dependsOn:
eval: $parent.type == 'richtext'
containerProps:
layout:
size: col-4
widget: foreignMedia
foreign:
collection: medialib
id: _id
subNavigation: 0
- name: accordionItems
type: object[]
meta:
label: { de: "Akkordeon-Elemente", en: "Accordion Items" }
dependsOn:
eval: $parent.type == 'accordion'
drillDown: true
subFields:
- name: question
type: string
meta:
label: { de: "Frage", en: "Question" }
containerProps:
layout:
size: col-8
- name: answer
type: string
meta:
label: { de: "Antwort", en: "Answer" }
widget: richtext
inputProps:
rows: 6
containerProps:
layout:
breakAfter: true
- name: open
type: boolean
meta:
label: { de: "Initial geöffnet", en: "Initially Open" }
containerProps:
layout:
size: col-4
- name: meta
type: object
meta:
widget: containerLessObject
label: { de: "SEO", en: "SEO" }
position: sidebar:seo
subFields:
- name: title
type: string
meta:
label: { de: "Meta-Titel", en: "Meta Title" }
- name: description
type: string
meta:
label: { de: "Meta-Beschreibung", en: "Meta Description" }
inputProps:
multiline: true
rows: 3
- name: keywords
type: string[]
meta:
label: { de: "Meta-Schlüsselwörter", en: "Meta Keywords" }