Q&A - Fragen & Antworten
Keywords: FAQ, Fragen, Antworten, Schema.org, JSON+LD, FAQPage, Kategorien, Mehrsprachigkeit
Übersicht
Q&A ist ein YForm-basiertes FAQ-Addon mit Kategorien, Mehrsprachigkeit und automatischer Schema.org-Auszeichnung (FAQPage).
Kern-Klassen
| Klasse |
Beschreibung |
Entry |
FAQ-Eintrag (Frage + Antwort) |
Category |
Kategorie für Gruppierung |
Lang |
Sprachvarianten |
Klasse: Entry
Wichtige Methoden
| Methode |
Parameter |
Rückgabe |
Beschreibung |
::get($id) |
int |
Entry\|null |
Lädt Eintrag |
::query() |
- |
rex_yform_manager_query |
Query Builder |
::findByIds($ids, $status) |
array, int |
rex_yform_manager_collection |
Nach IDs filtern |
::findByCategoryIds($ids, $status) |
array, int |
rex_yform_manager_collection |
Nach Kategorie-IDs |
getQuestion($lang) |
?int |
string |
Frage (übersetzt) |
getAnswer($lang) |
?int |
string |
Antwort HTML |
getAnswerAsPlaintext($lang) |
?int |
string |
Antwort ohne HTML |
getCategory() |
- |
?Category |
Kategorie |
getCategories() |
- |
array |
Alle Kategorien |
getUrl($param) |
?string |
string |
Anker-URL (#question-header-{id}) |
getAuthor() |
- |
?rex_user |
Backend-Autor |
isOnline() |
- |
bool |
Status === ONLINE |
Status-Konstanten
| Konstante |
Wert |
Beschreibung |
STATUS_OFFLINE |
0 |
Deaktiviert |
STATUS_ONLINE |
1 |
Veröffentlicht |
Klasse: Category
| Methode |
Parameter |
Rückgabe |
Beschreibung |
::get($id) |
int |
Category\|null |
Lädt Kategorie |
::findByIds($ids) |
array |
rex_yform_manager_collection |
Nach IDs |
getName() |
- |
string |
Name |
getAllQuestions($status) |
?int |
rex_yform_manager_collection |
Alle Fragen |
Klasse: Lang
| Methode |
Parameter |
Rückgabe |
Beschreibung |
getQuestion() |
- |
string |
Übersetzte Frage |
getAnswer() |
- |
string |
Übersetzte Antwort HTML |
getAnswerAsPlaintext() |
- |
string |
Antwort ohne Tags |
setQuestion($text) |
string |
self |
Frage setzen |
setAnswer($text) |
string |
self |
Antwort setzen |
Praxisbeispiele
1. Frage/Antwort laden
use Alexplusde\Qanda\Entry;
$question = Entry::get(42);
echo '<h3>' . $question->getQuestion() . '</h3>';
echo '<div>' . $question->getAnswer() . '</div>';
2. Alle Online-Fragen
$questions = Entry::query()
->where('status', Entry::STATUS_ONLINE)
->orderBy('prio', 'ASC')
->find();
3. Nach IDs filtern
$ids = [10, 20, 30];
$questions = Entry::findByIds($ids, Entry::STATUS_ONLINE);
4. Nach Kategorie filtern
$categoryIds = [1, 2];
$questions = Entry::findByCategoryIds($categoryIds, Entry::STATUS_ONLINE);
foreach ($questions as $q) {
echo '<h4>' . $q->getQuestion() . '</h4>';
echo '<p>' . $q->getAnswerAsPlaintext() . '</p>';
}
5. Antwort ohne HTML
$question = Entry::get(42);
$plain = $question->getAnswerAsPlaintext();
// Entfernt Tags, behält Zeilenumbrüche
6. JSON+LD für einzelne Frage
$question = Entry::get(42);
$fragment = new rex_fragment();
$fragment->setVar('question', $question);
echo $fragment->parse('qanda/json-ld.php');
7. JSON+LD für FAQPage
$questions = Entry::query()
->where('status', Entry::STATUS_ONLINE)
->find();
$fragment = new rex_fragment();
$fragment->setVar('questions', $questions);
echo $fragment->parse('qanda/FAQPage.json-ld.php');
8. Anker-URL generieren
$question = Entry::get(42);
$url = $question->getUrl();
// Liefert '#question-header-42'
9. Mit Seiten-URL kombinieren
$question = Entry::get(42);
$fullUrl = rex_getUrl(42) . $question->getUrl();
// Liefert '/faq/#question-header-42'
10. Kategorie-Übersicht
use Alexplusde\Qanda\Category;
$categories = Category::query()->orderBy('name')->find();
foreach ($categories as $cat) {
echo '<h2>' . $cat->getName() . '</h2>';
$questions = $cat->getAllQuestions(Entry::STATUS_ONLINE);
foreach ($questions as $q) {
echo '<div>' . $q->getQuestion() . '</div>';
}
}
11. Mehrsprachige Frage laden
$question = Entry::get(42);
$clangId = rex_clang::getCurrentId();
echo $question->getQuestion($clangId);
echo $question->getAnswer($clangId);
12. Backend-Autor anzeigen
$question = Entry::get(42);
$author = $question->getAuthor();
if ($author) {
echo 'Autor: ' . $author->getName();
}
13. Neue Frage anlegen
$entry = Entry::create();
$entry->setValue('question', 'Wie funktioniert X?');
$entry->setValue('answer', '<p>X funktioniert so...</p>');
$entry->setValue('category_ids', '1,3');
$entry->setValue('status', Entry::STATUS_ONLINE);
$entry->setValue('prio', 10);
$entry->save();
14. Kategorie mit Fragen
$category = Category::get(3);
$questions = Entry::findByCategoryIds([3], Entry::STATUS_ONLINE);
echo '<section>';
echo '<h2>' . $category->getName() . '</h2>';
echo '<dl>';
foreach ($questions as $q) {
echo '<dt id="question-header-' . $q->getId() . '">' . $q->getQuestion() . '</dt>';
echo '<dd>' . $q->getAnswer() . '</dd>';
}
echo '</dl>';
echo '</section>';
15. FAQ-Seite mit Bootstrap 5 Accordion
$questions = Entry::query()
->where('status', Entry::STATUS_ONLINE)
->orderBy('prio')
->find();
echo '<div class="accordion" id="faq">';
foreach ($questions as $i => $q) {
echo '<div class="accordion-item">';
echo '<h2 class="accordion-header" id="heading-' . $q->getId() . '">';
echo '<button class="accordion-button collapsed" type="button" data-bs-toggle="collapse" data-bs-target="#collapse-' . $q->getId() . '">';
echo $q->getQuestion();
echo '</button></h2>';
echo '<div id="collapse-' . $q->getId() . '" class="accordion-collapse collapse" data-bs-parent="#faq">';
echo '<div class="accordion-body">' . $q->getAnswer() . '</div>';
echo '</div></div>';
}
echo '</div>';
16. Fragment-Integration
$fragment = new rex_fragment();
$fragment->setVar('questions', Entry::findByCategoryIds([2], Entry::STATUS_ONLINE));
echo $fragment->parse('bs5/qanda/list.php');
17. Backend-Filter nach Status
$drafts = Entry::query()
->where('status', Entry::STATUS_OFFLINE)
->find();
18. Übersetzung hinzufügen
use Alexplusde\Qanda\Lang;
$lang = Lang::create();
$lang->setValue('entry_id', 42);
$lang->setValue('clang_id', 2); // Englisch
$lang->setQuestion('How does X work?');
$lang->setAnswer('<p>X works like this...</p>');
$lang->save();
19. Alle Kategorien einer Frage
$question = Entry::get(42);
$categories = $question->getCategories();
foreach ($categories as $cat) {
echo '<span class="badge">' . $cat->getName() . '</span>';
}
20. Suche in Fragen
$searchTerm = 'Kündigung';
$questions = Entry::query()
->where('status', Entry::STATUS_ONLINE)
->whereRaw('(question LIKE ? OR answer LIKE ?)', ['%' . $searchTerm . '%', '%' . $searchTerm . '%'])
->find();
21. Schema.org JSON+LD (vollständig)
$questions = Entry::findByCategoryIds([1], Entry::STATUS_ONLINE);
$data = [
'@context' => 'https://schema.org',
'@type' => 'FAQPage',
'mainEntity' => []
];
foreach ($questions as $q) {
$data['mainEntity'][] = [
'@type' => 'Question',
'name' => $q->getQuestion(),
'acceptedAnswer' => [
'@type' => 'Answer',
'text' => $q->getAnswerAsPlaintext()
]
];
}
echo '<script type="application/ld+json">' . json_encode($data, JSON_UNESCAPED_UNICODE) . '</script>';
22. Priorität ändern
$question = Entry::get(42);
$question->setValue('prio', 5);
$question->save();
23. Kategorie-Name anzeigen
$question = Entry::get(42);
$category = $question->getCategory();
if ($category) {
echo 'Kategorie: ' . $category->getName();
}
24. Fragen ohne Kategorie
$questions = Entry::query()
->where('status', Entry::STATUS_ONLINE)
->whereRaw('category_ids = "" OR category_ids IS NULL')
->find();
25. REST-API Integration (wenn aktiviert)
// GET /rest/qanda/entry/1.0.0/42
// Liefert JSON mit Frage/Antwort
Integration: Q&A arbeitet mit YForm (Datenbank), URL-Addon (Anker-Links), Schema.org (FAQPage JSON+LD), YRewrite (Mehrsprachigkeit), Plus BS5 (Bootstrap 5 Fragments) und nutzt rex_clang für Übersetzungen.