Wer die eigene Website oder das eigene Portfolio liebt, will Newsfeeds und Updates natürlich auch perfekt präsentieren – am besten gebündelt, aktuell und völlig ohne externe Tracker oder Werbung.
Hier kommt die ultimative Lösung: Ein eigener, selbstgehosteter RSS-Multifeed auf Basis von PHP – inklusive vollständigem Caching, YouTube-Support und einem schicken Dark-Grid-Layout.
Und das Beste: Der komplette Code ist Open Source und kann sofort verwendet werden!
🛠 Was wird benötigt?
- Einen Webserver mit PHP-Unterstützung (z. B. Apache oder Nginx)
- PHP 7.4 oder neuer
- Zwei kleine Skripte:
combined_feed.php
– kombiniert und cached die Feedsreader.php
– stellt die Feeds hübsch dar
📜 Kurz erklärt: Wie funktioniert das?
- combined_feed.php sammelt verschiedene RSS- und Atom-Feeds, inklusive YouTube-Channel-Feeds, in einem einzigen, kombinierten RSS-Feed. Dabei wird ein Caching-System eingesetzt, um unnötige Serverlast zu vermeiden.
- reader.php lädt diesen kombinierten Feed und zeigt ihn in einem modernen Grid-Layout im Dark Mode an – perfekt für mobile Geräte optimiert!
⚡ Schritt-für-Schritt Anleitung
- Dateien hochladen: Lade
combined_feed.php
undreader.php
auf deinen Server – z. B. in ein Verzeichnis wie/multifeed/
. - Feed-Quellen anpassen: Öffne die
combined_feed.php
und trage deine eigenen RSS- oder Atom-Feed-Links ein (YouTube-Channel-Feeds sind ebenfalls möglich). - Feed aufrufen: Im Browser
https://deine-domain.de/multifeed/reader.php</code aufrufen – und fertig ist dein privater News-Hub!
🧩 Vollständiger Quellcode
📄 combined_feed.php
<?php
header("Content-Type: application/rss+xml; charset=UTF-8");
// === KONFIGURATION ===
$sources = [
'https://matdan.de/blog/feed/',
'https://portfolio.matdan.de/blog/feed/',
'https://www.youtube.com/feeds/videos.xml?channel_id=UCFr2IhgmGbU9SzjWbCA8hRQ' // Ersetzt mit deiner YouTube-Channel-ID
];
$cache_file = __DIR__ . '/cache_combined_feed.xml';
$cache_lifetime = 1800; // 30 Minuten Cache
// === CACHE HANDLING ===
if (file_exists($cache_file) && (time() - filemtime($cache_file)) < $cache_lifetime) {
echo file_get_contents($cache_file);
exit;
}
// === FEED SAMMELN ===
$items = [];
foreach ($sources as $url) {
$xml = @simplexml_load_file($url);
if ($xml !== false) {
if (isset($xml->channel->item)) {
foreach ($xml->channel->item as $item) {
$items[] = [
'title' => (string) $item->title,
'link' => (string) $item->link,
'description' => (string) $item->description,
'pubDate' => strtotime((string) $item->pubDate)
];
}
} elseif (isset($xml->entry)) {
// YouTube Feed (Atom)
foreach ($xml->entry as $entry) {
$items[] = [
'title' => (string) $entry->title,
'link' => (string) $entry->link['href'],
'description' => (string) $entry->content,
'pubDate' => strtotime((string) $entry->published)
];
}
}
}
}
// === SORTIEREN ===
usort($items, function($a, $b) {
return $b['pubDate'] - $a['pubDate'];
});
// === RSS GENERIEREN ===
$output = '<?xml version="1.0" encoding="UTF-8"?>' . "\n";
$output .= '<rss version="2.0">' . "\n";
$output .= '<channel>' . "\n";
$output .= '<title>matdan MegaFeed</title>' . "\n";
$output .= '<link>https://matdan.de/</link>' . "\n";
$output .= '<description>Alle neuesten Inhalte von matdan.de und Portfolio</description>' . "\n";
foreach (array_slice($items, 0, 20) as $item) {
$output .= '<item>' . "\n";
$output .= '<title>' . htmlspecialchars($item['title']) . '</title>' . "\n";
$output .= '<link>' . htmlspecialchars($item['link']) . '</link>' . "\n";
$output .= '<description><![CDATA[' . $item['description'] . ']]></description>' . "\n";
$output .= '<pubDate>' . date(DATE_RSS, $item['pubDate']) . '</pubDate>' . "\n";
$output .= '</item>' . "\n";
}
$output .= '</channel>' . "\n";
$output .= '</rss>';
// === CACHE SPEICHERN ===
file_put_contents($cache_file, $output);
// === FEED AUSGEBEN ===
echo $output;
?>
📄 reader.php
<?php
$feed_url = "https://matdan.de/multifeed/combined_feed.php";
$feed_content = @simplexml_load_file($feed_url);
?>
<!DOCTYPE html>
<html lang="de">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>matdan Multifeed</title>
<style>
body {
background-color: #121212;
color: #e0e0e0;
font-family: Arial, sans-serif;
margin: 0;
padding: 20px;
}
h1 {
text-align: center;
margin-bottom: 40px;
font-size: 2em;
color: #00bcd4;
}
.feed-container {
display: grid;
grid-template-columns: repeat(auto-fit, minmax(280px, 1fr));
gap: 20px;
}
.feed-item {
background: #1e1e1e;
border: 1px solid #333;
border-radius: 12px;
padding: 20px;
transition: transform 0.2s;
}
.feed-item:hover {
transform: scale(1.03);
border-color: #00bcd4;
}
.feed-item a {
color: #00bcd4;
text-decoration: none;
font-size: 1.2em;
font-weight: bold;
}
.feed-item a:hover {
text-decoration: underline;
}
.feed-date {
font-size: 0.9em;
color: #bbb;
margin-top: 10px;
}
.feed-description {
margin-top: 10px;
font-size: 1em;
color: #ccc;
}
.footer {
margin-top: 50px;
text-align: center;
font-size: 0.8em;
color: #666;
}
</style>
</head>
<body>
<h1>🔥 matdan Multifeed 🔥</h1>
<div class="feed-container">
<?php if ($feed_content && isset($feed_content->channel->item)): ?>
<?php foreach ($feed_content->channel->item as $item): ?>
<div class="feed-item">
<a href="<?= htmlspecialchars($item->link) ?>" target="_blank"><?= htmlspecialchars($item->title) ?></a>
<div class="feed-date"><?= date('d.m.Y H:i', strtotime($item->pubDate)) ?></div>
<div class="feed-description"><?= strip_tags(substr($item->description, 0, 150)) ?>...</div>
</div>
<?php endforeach; ?>
<?php else: ?>
<p>Leider konnten keine Feed-Daten geladen werden. 😢</p>
<?php endif; ?>
</div>
<div class="footer">
© <?= date('Y') ?> matdan.de – Alle Rechte vorbehalten.
</div>
</body>
</html>
🚀 Fazit
Mit diesem kleinen, aber mächtigen Setup entsteht in Minuten ein moderner, privater RSS-Aggregator, der beliebig erweitert werden kann – z. B. um weitere Quellen, Kategorien, Caching-Optimierungen oder eigene Suchfunktionen.
Keine Tracker, keine Werbung, volle Kontrolle. Genau so, wie ein smarter Webauftritt heute aussehen sollte! 🚀