Notifications
Clear all

Script [Solved] Add "Recent Forum Posts" where you want it

5 Posts
2 Users
1 Reactions
153 Views
Posts: 13
Topic starter
(@pablo)
Eminent Member
Joined: 8 months ago

I always wanted to show the recent forum posts in any position on my website, so i discussed that problem with chatgpt, because wpforo software only allows that in sidebar widget.

So i share my discussion and output in chatgpt with u. It uses the rss feed to fetch the recent posts. Comments in code are in german, translate them with chatgpt or use google translator. the following code is only displayed when a user is logged in (this was my restriction, but it is easy to remove that restriction) and only when the button is clicked.
make sure u change "const url = 'https://YOURURL.TLD/?type=rss2&forum=g&topic=g';"

To use the following code within wordpress, use "html code" widget.

<div id="rss-container-wrapper" style="display: none;">
    <style>
        #load-button {
            display: block;
            margin: 0 auto;
            padding: 10px 20px;
            font-size: 16px;
            cursor: pointer;
        }

        #rss-container {
            display: none;
            margin-top: 20px;
        }

        #rss-feed {
            list-style-type: none;
            padding: 0;
        }

        #rss-feed li {
            margin-bottom: 10px;
        }
    </style>

    <button id="load-button">Display recent posts</button>

    <div class="container" id="rss-container">
     
        <ul id="rss-feed"></ul>
    </div>

    <script>
        document.addEventListener("DOMContentLoaded", function() {
            const isLoggedIn = document.body.classList.contains("logged-in");
            
            if (isLoggedIn) {
                // Nur anzeigen, wenn der Benutzer eingeloggt ist
                document.getElementById("rss-container-wrapper").style.display = "block";

                document.getElementById("load-button").addEventListener("click", function() {
                    const rssContainer = document.getElementById("rss-container");

                    // Toggle der Anzeige des RSS-Containers
                    if (rssContainer.style.display === "none" || rssContainer.style.display === "") {
                        // Den Button-Text ändern, wenn der Container sichtbar ist
                        this.textContent = "Hide";

                        // Den RSS-Container anzeigen und die Daten laden
                        rssContainer.style.display = "block";
                        fetchRSS();
                    } else {
                        // Den Button-Text zurückändern, wenn der Container verborgen wird
                        this.textContent = "Display recent posts";

                        // Den RSS-Container ausblenden
                        rssContainer.style.display = "none";
                    }
                });
            }
        });

        async function fetchRSS() {
            const url = 'https://YOURURL.TLD/?type=rss2&forum=g&topic=g'; // URL des RSS-Feeds
            try {
                const response = await fetch(url);
                const text = await response.text();
                const parser = new DOMParser();
                const xml = parser.parseFromString(text, "text/xml");
                const items = xml.querySelectorAll("item");

                let html = "";
                items.forEach((item, index) => {
                    if (index < 15) {
                        const title = item.querySelector("title").textContent;
                        const link = item.querySelector("link").textContent;
                        const date = new Date(item.querySelector("pubDate").textContent);
                        const description = item.querySelector("description")?.textContent || "Keine Vorschau verfügbar.";

                        // Hier wird der Autor korrekt aus dem <dc:creator> Tag extrahiert
                        const author = item.querySelector("creator") ? item.querySelector("creator").textContent : "Unbekannt"; 

                        html += `
                            <li>
                                <a href="${link}">${title}</a>
                                <br><small>Autor: ${author}</small>
                                <br><small>${date.toLocaleString("de-DE")}</small>
                                <br><p class="excerpt">${description}</p>
                            </li>`;
                    }
                });

                document.getElementById("rss-feed").innerHTML = html;
            } catch (error) {
                console.error("Fehler beim Laden des RSS Feeds", error);
                document.getElementById("rss-feed").innerHTML = "Fehler beim Laden der Daten.";
            }
        }
    </script>
</div>
4 Replies
Sofy
Posts: 5202
 Sofy
Admin
(@sofy)
Support Team
Joined: 7 years ago

Hi,

Please read this support topic: https://wpforo.com/community/how-to-and-troubleshooting-2/displaying-latest-forum-posts-on-websites-home-page/paged/2/#post-104627

The same question is discussed there. 

Reply
1 Reply
(@pablo)
Joined: 8 months ago

Eminent Member
Posts: 13

@sofy i know, this was just a soultion to the problem 😉 

I updated the output a bit, here is the new version in english. Styling can be done at the beginning of the code via CSS. Make sure you change the 2 URLs to your forum ones:
1. https://YOURURL.TLD/community/add-topic/
2. https://YOURURL.TLD/?type=rss2&forum=g&topic=g

<div id="rss-container-wrapper" style="display: none;">
    <style>
        /* General styling for the container design */
        #rss-container {
            display: none;
            margin-top: 20px;
            padding: 15px;
            background: rgba(255, 255, 255, 0.9);
            border-radius: 10px;
            color: #333;
            box-shadow: 0px 4px 10px rgba(0, 0, 0, 0.1);
            border: 1px solid #ddd;
        }

        /* Button styling */
        #load-button, .create-topic-button {
            display: block;
            margin: 15px auto;
            padding: 12px 25px;
            font-size: 18px;
            cursor: pointer;
            background: linear-gradient(135deg, #4CAF50, #81C784);
            color: white;
            border: none;
            border-radius: 25px;
            transition: 0.3s;
            box-shadow: 0px 3px 8px rgba(0, 0, 0, 0.1);
            text-align: center;
            text-decoration: none;
            font-weight: bold;
        }

        #load-button:hover, .create-topic-button:hover {
            background: linear-gradient(135deg, #43A047, #66BB6A);
            transform: scale(1.05);
        }

        /* Styling for posts */
        #rss-feed {
            list-style: none;
            padding: 0;
        }

        #rss-feed li {
            background: rgba(0, 0, 0, 0.05);
            padding: 15px;
            margin-bottom: 12px;
            border-radius: 8px;
            transition: 0.3s;
            border-left: 5px solid #4CAF50;
        }

        #rss-feed li:hover {
            background: rgba(0, 0, 0, 0.1);
            transform: scale(1.02);
        }

        #rss-feed li a {
            font-size: 18px;
            font-weight: bold;
            color: #388E3C;
            text-decoration: none;
            transition: 0.3s;
        }

        #rss-feed li a:hover {
            color: #2E7D32;
        }

        /* Post description */
        .excerpt {
            font-size: 14px;
            color: #555;
            margin-top: 5px;
        }

        /* Additional info like author & time */
        .meta {
            font-size: 12px;
            color: #777;
            margin-top: 5px;
        }
    </style>

    <button id="load-button">🌿 Show the 10 latest posts</button>

    <div class="container" id="rss-container">
        <a href="https://YOURURL.TLD/community/add-topic/" class="create-topic-button">➕ Create a new topic</a>
        <ul id="rss-feed"></ul>
    </div>

    <script>
        document.addEventListener("DOMContentLoaded", function () {
            const isLoggedIn = document.body.classList.contains("logged-in");

            if (isLoggedIn) {
                document.getElementById("rss-container-wrapper").style.display = "block";

                document.getElementById("load-button").addEventListener("click", function () {
                    const rssContainer = document.getElementById("rss-container");

                    if (rssContainer.style.display === "none" || rssContainer.style.display === "") {
                        this.textContent = "🌿 Hide posts";
                        rssContainer.style.display = "block";
                        fetchRSS();
                    } else {
                        this.textContent = "🌿 Show the 10 latest posts";
                        rssContainer.style.display = "none";
                    }
                });
            }
        });

        async function fetchRSS() {
            const url = 'https://YOURURL.TLD/?type=rss2&forum=g&topic=g';

            try {
                const response = await fetch(url);
                const text = await response.text();
                const parser = new DOMParser();
                const xml = parser.parseFromString(text, "text/xml");
                const items = xml.querySelectorAll("item");

                let html = "";
                items.forEach((item, index) => {
                    if (index < 10) { 
                        const title = item.querySelector("title").textContent;
                        const link = item.querySelector("link").textContent;
                        const date = new Date(item.querySelector("pubDate").textContent);
                        const description = item.querySelector("description")?.textContent || "No preview available.";
                        const author = item.querySelector("creator") ? item.querySelector("creator").textContent : "Unknown"; 

                        const now = Date.now();
                        const diffInSeconds = Math.floor((now - date) / 1000);
                        let timeAgo = "";

                        if (diffInSeconds < 60) {
                            timeAgo = `${diffInSeconds} sec.`;
                        } else if (diffInSeconds < 3600) {
                            const diffInMinutes = Math.floor(diffInSeconds / 60);
                            timeAgo = `${diffInMinutes} min.`;
                        } else if (diffInSeconds < 86400) {
                            const diffInHours = Math.floor(diffInSeconds / 3600);
                            timeAgo = `${diffInHours} hrs.`;
                        } else {
                            const diffInDays = Math.floor(diffInSeconds / 86400);
                            timeAgo = `${diffInDays} d.`;
                        }

                        html += `
                            <li>
                                <a href="${link}">${title}</a>
                                <div class="meta">👤 By: <b>${author}</b> posted ${timeAgo} ago</div>
                                <p class="excerpt">${description}</p>
                            </li>`;
                    }
                });

                document.getElementById("rss-feed").innerHTML = html;
            } catch (error) {
                console.error("Error loading the RSS feed", error);
                document.getElementById("rss-feed").innerHTML = "❌ Error loading data.";
            }
        }
    </script>
</div>

Screenshots:


 

Reply
Posts: 13
Topic starter
(@pablo)
Eminent Member
Joined: 8 months ago

Version that uses database and not rss, with Pagination / „Load More“ and avatars.

Paste this at the end of your Theme "functions.php"

The following code works only if you have "title url structure" activated.

add_action('wp_ajax_get_latest_wpforo_posts', 'get_latest_wpforo_posts');
add_action('wp_ajax_nopriv_get_latest_wpforo_posts', 'get_latest_wpforo_posts');

function get_latest_wpforo_posts() {
ob_clean();
header('Content-Type: application/json');

if (!function_exists('WPF')) {
echo json_encode(['error' => 'wpForo is not available.']);
wp_die();
}

$offset = isset($_GET['offset']) ? intval($_GET['offset']) : 0;
$limit = 10;

$posts = WPF()->post->get_posts([
'orderby' => 'created',
'order' => 'DESC',
'row_count' => $limit,
'offset' => $offset,
'status' => 0,
]);

if (!$posts || !is_array($posts)) {
echo json_encode([]);
wp_die();
}

$output = [];foreach ($posts as $post) {
$author = wpforo_member($post['userid'] ?? 0)['display_name'] ?? 'Guest';
$avatar = WPF()->member->get_avatar_url($post['userid'] ?? 0);

$forum = WPF()->forum->get_forum($post['forumid']);
$topic = WPF()->topic->get_topic($post['topicid']);

$forum_slug = $forum['slug'] ?? '';
$topic_slug = $topic['slug'] ?? '';

$link = home_url("/community/{$forum_slug}/{$topic_slug}/#post-{$post['postid']}");

$created = strtotime($post['created']);
$now = time();
$diff = $now - $created;

if ($diff < 60) {
$timeago = $diff . ' sec';
} elseif ($diff < 3600) {
$timeago = floor($diff / 60) . ' min';
} elseif ($diff < 86400) {
$timeago = floor($diff / 3600) . ' hours';
} else {
$timeago = floor($diff / 86400) . ' days';
}

$text = preg_replace('/\[quote.*?\](.*?)\[\/quote\]/is', '', $post['body'] ?? '');
$excerpt = wp_trim_words(strip_tags($text), 25, '...');

$output[] = [
'author' => $author,
'avatar' => $avatar,
'forum' => $forum['title'] ?? '',
'topic' => $topic['title'] ?? '',
'timeago' => $timeago,
'excerpt' => $excerpt,
'link' => $link,
];
}

echo json_encode($output);
wp_die();
}

Paste the following code in html widget where it should appear:

 

<div id="wpforo-output-wrapper" style="text-align:center; margin: 40px auto; max-width: 800px;">
<button id="load-wpforo-posts" style="
padding: 12px 25px;
font-size: 18px;
cursor: pointer;
background: linear-gradient(135deg, #4CAF50, #81C784);
color: white;
border: none;
border-radius: 25px;
transition: 0.3s;
box-shadow: 0px 3px 8px rgba(0, 0, 0, 0.1);
font-weight: bold;
">🌿 Show Latest 10 Posts</button>

<div id="wpforo-output" style="margin-top: 30px;"></div>

<button id="load-more-wpforo-posts" style="
display: none;
padding: 10px 20px;
margin-top: 15px;
font-size: 16px;
background: #4CAF50;
color: white;
border: none;
border-radius: 20px;
cursor: pointer;
">⬇️ Load More Posts</button>
</div>

<script>
let offset = 0;
const limit = 10;

document.addEventListener("DOMContentLoaded", function () {
const loadBtn = document.getElementById("load-wpforo-posts");
const moreBtn = document.getElementById("load-more-wpforo-posts");
const container = document.getElementById("wpforo-output");

loadBtn.addEventListener("click", function () {
loadPosts();
loadBtn.style.display = "none";
moreBtn.style.display = "inline-block";
});

moreBtn.addEventListener("click", function () {
loadPosts();
});

async function loadPosts() {
try {
const res = await fetch(`/wp-admin/admin-ajax.php?action=get_latest_wpforo_posts&offset=${offset}`);
const data = await res.json();

if (!Array.isArray(data) || data.length === 0) {
moreBtn.style.display = "none";
return;
}

data.forEach(post => {
const postHtml = `
<div style="
display: flex;
align-items: flex-start;
gap: 15px;
background: rgba(255, 255, 255, 0.9);
padding: 15px;
margin-bottom: 20px;
border-radius: 10px;
box-shadow: 0px 4px 10px rgba(0, 0, 0, 0.1);
border-left: 5px solid #4CAF50;
">
<img src="${post.avatar}" alt="Avatar" style="
width: 48px;
height: 48px;
border-radius: 50%;
object-fit: cover;
flex-shrink: 0;
">
<div>
<div style="font-size: 16px; font-weight: bold; color: #333;">
${post.author} <span style="font-size: 13px; color: #777;">– ${post.timeago} ago</span>
</div>
<div style="font-size: 14px; color: #555; margin-top: 2px;">
Forum: <strong>${post.forum}</strong> · Topic: <strong>${post.topic}</strong>
</div>
<div style="margin-top: 8px;">
<a href="${post.link}" style="
font-size: 15px;
line-height: 1.5;
color: #2E7D32;
text-decoration: none;
font-weight: 500;
">${post.excerpt}</a>
</div>
</div>
</div>
`;
container.insertAdjacentHTML('beforeend', postHtml);
});

offset += limit;

if (data.length < limit) {
moreBtn.style.display = "none";
}
} catch (err) {
container.innerHTML += "<p style='color:red;'>❌ Error loading posts.</p>";
console.error(err);
}
}
});
</script>

 

 

Reply
Posts: 13
Topic starter
(@pablo)
Eminent Member
Joined: 8 months ago

As i am into perfection mode tonight, i was able to get into this (see attached image file) now...if you need help, get in touch with me
(+nextend social login for google and x - plugin required) 

Reply