This feature allows embedding and dynamically displaying videos from any YouTube channel directly on a WordPress website without using third-party plugins or the YouTube Data API.
The system fetches the latest videos from a selected YouTube channel using the YouTube RSS feed and WordPress’s native fetch_feed() function. It automatically retrieves the most recent 12 videos, extracts video IDs, and generates high-quality thumbnails dynamically.
The frontend renders a fully responsive CSS Grid layout (4 columns on desktop, 2 on tablet/mobile) with custom-designed play overlays and hover animations. Thumbnails maintain a 16:9 aspect ratio for consistent visual presentation.
When a user clicks a video:
- A modal popup opens
- The selected video loads dynamically via iframe
- Autoplay is enabled
- The iframe is removed when closing to stop playback and optimize performance
Key Highlights
- No API key required
- No external plugins used
- Lightweight RSS-based integration
- Fully responsive design
- Lazy-loaded thumbnails
- Dynamic iframe loading (performance optimized)
- Reusable WordPress shortcode implementation
This solution enables embedding any YouTube channel’s videos into a website in a clean, fast, and maintainable way while ensuring a smooth user experience.
PHP Code
function hedgefundtips_youtube_grid_popup() {
$channel_id = 'UCw9Yjk4De_l21-sxLUvCbTw';
$feed_url = "https://www.youtube.com/feeds/videos.xml?channel_id={$channel_id}";
include_once(ABSPATH . WPINC . '/feed.php');
$rss = fetch_feed($feed_url);
if (is_wp_error($rss)) {
return 'Unable to fetch YouTube videos.';
}
$maxitems = $rss->get_item_quantity(12);
$rss_items = $rss->get_items(0, $maxitems);
ob_start();
?>
get_permalink(), $matches);
$video_id = $matches[1];
$thumbnail = "https://img.youtube.com/vi/{$video_id}/hqdefault.jpg";
?>
×
CSS Codes
.yt-grid {
display: grid;
grid-template-columns: repeat(4, 1fr);
gap: 10px;
}
.yt-item {
position: relative;
cursor: pointer;
}
.yt-item img {
width: 100%;
border-radius: 0px !important;
display: block;
}
.yt-play {
position: absolute;
top: 50%;
left: 50%;
transform: translate(-50%, -50%);
font-size: 40px;
color: white;
background: rgba(0,0,0,0.6);
border-radius: 50%;
padding: 10px 15px;
}
/* Responsive */
@media (max-width: 992px) {
.yt-grid { grid-template-columns: repeat(2, 1fr); }
}
/* Modal */
.yt-modal {
display: none;
position: fixed;
z-index: 9999;
inset: 0;
background: rgba(0,0,0,0.85);
justify-content: center;
align-items: center;
}
.yt-modal-content {
width: 90%;
max-width: 900px;
position: relative;
}
.yt-video-container iframe {
width: 100%;
height: 500px;
}
.yt-close {
position: absolute;
top: -40px;
right: 0;
font-size: 35px;
color: white;
cursor: pointer;
}
.yt-item img {
width: 100%;
aspect-ratio: 16 / 9;
object-fit: cover;
border-radius: 12px;
}
.yt-play {
background: #034638;
width: 60px;
height: 30px;
border-radius: 15%;
position: absolute;
display: flex;
align-items: center;
justify-content: center;
padding:21px;
}
.yt-play img {
position: absolute;
opacity: 0;
visibility: hidden;
pointer-events: none;
}
.yt-play::before {
content: "";
width: 0;
height: 0;
border-left: 22px solid #ffffff;
border-top: 14px solid transparent;
border-bottom: 14px solid transparent;
margin-left: 5px;
}
.yt-item:hover
{
transform: scale(1.01);
transition: 300ms ease-in-out;
}
@media (max-width: 576px) {
.yt-grid {
grid-template-columns: repeat(2, 1fr);
}
.yt-play {
width: 40px;
height: 10px;
padding: 15px;
}
.yt-play::before
{
border-left: 15px solid #ffffff;
border-top: 8px solid transparent;
border-bottom: 8px solid transparent;
margin-left: 5px;
}
}
JavaScript Code
document.addEventListener("DOMContentLoaded", function(){
const items = document.querySelectorAll(".yt-item");
const modal = document.querySelector(".yt-modal");
const videoContainer = document.querySelector(".yt-video-container");
const closeBtn = document.querySelector(".yt-close");
items.forEach(item => {
item.addEventListener("click", function(){
const videoId = this.dataset.video;
videoContainer.innerHTML =
``;
modal.style.display = "flex";
});
});
closeBtn.addEventListener("click", function(){
modal.style.display = "none";
videoContainer.innerHTML = "";
});
modal.addEventListener("click", function(e){
if(e.target === modal){
modal.style.display = "none";
videoContainer.innerHTML = "";
}
});
});