Hướng Dẫn Tạo UX Element Gallery Tích Hợp Nút Affiliate Cho Flatsome

Cập nhật lần cuối 18/03/2026 bởi Hà Văn Thuật trong Thủ thuật Code vào 18/03/2026

Bạn đang xây dựng một trang review sản phẩm, landing page giới thiệu mẫu mã bằng theme Flatsome và cảm thấy chức năng Gallery mặc định là chưa đủ? Bạn muốn mỗi khi khách hàng click vào một bức ảnh, hệ thống không chỉ phóng to ảnh mà còn hiển thị chi tiết Mã sản phẩm (SKU), Giá bán và đặc biệt là một nút “Mua Ngay” trỏ thẳng đến link Affiliate của bạn?

Trong bài viết này, Shoppingweb sẽ chia sẻ đến bạn một đoạn code cực kỳ tối ưu để giải quyết bài toán trên. Đoạn code này sẽ tạo ra một Element hoàn toàn mới trong UX Builder, cho phép bạn chọn ảnh dễ dàng và tận dụng chính thư viện Media của WordPress để gán link tiếp thị liên kết một cách thông minh.

Bạn chỉ cần copy cho vào file functions.php là được nhé

[foxhi id=’1624′]
/**
* 1. Tạo Shortcode [ux_gallery_vip] - Cập nhật cho Affiliate Redirect
*/
add_shortcode( 'ux_gallery_vip', function( $atts ) {
$atts = shortcode_atts( array(
'ids' => '', 
), $atts );
if ( empty( $atts['ids'] ) ) {
return '<p style="text-align:center; padding: 50px 0;">Vui lòng chọn hình ảnh cho Gallery VIP.</p>';
}
$_attachments = get_posts( array(
'include' => $atts['ids'],
'post_status' => 'inherit',
'post_type' => 'attachment',
'post_mime_type' => 'image',
'order' => 'ASC',
'orderby' => 'post__in', 
'posts_per_page' => -1
) );
if ( empty( $_attachments ) ) return '';
ob_start();
?>
<div class="lux-single-gach">
<div class="sku-section">
<h4 class="lux-fw-bold lux-title-section">Bảng Mã Sản Phẩm (SKU)</h4>
<div class="lux-gallery" id="lux-gallery-wrapper">
<?php 
foreach ( $_attachments as $attachment ) : 
$sku = ! empty( $attachment->post_excerpt ) ? esc_html( $attachment->post_excerpt ) : 'Đang cập nhật';
$price = ! empty( $attachment->post_content ) ? esc_html( $attachment->post_content ) : 'Liên hệ';
$img_url = wp_get_attachment_image_url( $attachment->ID, 'large' );

/**
* Lấy Link Affiliate từ trường "Văn bản thay thế" (Alt Text)
* Trong ảnh bạn gửi, ô này được đánh dấu là "Mô tả SEO"
*/
$aff_link = get_post_meta( $attachment->ID, '_wp_attachment_image_alt', true );
$aff_link = ! empty( $aff_link ) ? esc_url( $aff_link ) : '#';
?>
<div class="lux-image-item" data-aff-link="<?php echo $aff_link; ?>">
<div class="lux-image-wrapper">
<div class="lux-badge-sku"><?php echo $sku; ?></div>
<div class="lux-badge-price"><?php echo $price; ?></div>
<img src="<?php echo esc_url( $img_url ); ?>" alt="<?php echo esc_attr( $sku ); ?>">
</div>
</div>
<?php endforeach; ?>
</div>
</div>
</div>
<div class="lux-preview-box" id="luxPreviewBox">
<div class="lux-preview-details">
<span class="lux-fw-bold">Mẫu <span class="current-img lux-text-gold"></span> / <span class="total-img"></span></span>
<span class="lux-close-icon" id="closeLightbox">&times;</span>
</div>
<div class="lux-image-box">
<div class="lux-badge-sku" id="lb-sku"></div>
<div class="lux-badge-price" id="lb-price"></div>
<div class="lux-slide prev">&#10094;</div>
<div class="lux-slide next">&#10095;</div>
<img src="" alt="Preview" id="lightboxImg">
</div>
<div class="lux-preview-footer">
<button class="lux-btn-gold" id="btnRedirectAff">
<span>&#10148;</span> Mua Ngay / Xem Chi Tiết
</button>
</div>
</div>
<div class="lux-lb-shadow" id="lbShadow"></div>
<script>
document.addEventListener("DOMContentLoaded", function() {
const images = document.querySelectorAll("#lux-gallery-wrapper .lux-image-item");
if(!images.length) return;
const previewBox = document.getElementById("luxPreviewBox"),
previewImg = document.getElementById("lightboxImg"),
lbShadow = document.getElementById("lbShadow"),
lbSku = document.getElementById("lb-sku"),
lbPrice = document.getElementById("lb-price"),
currentImg = previewBox.querySelector(".current-img"),
totalImg = previewBox.querySelector(".total-img"),
closeLbBtn = document.getElementById("closeLightbox"),
btnAff = document.getElementById("btnRedirectAff");
let currentIndex = 0;
let isZoomed = false;
let currentAffLink = "#";
function resetZoom() {
isZoomed = false;
previewImg.classList.remove("zoomed");
previewImg.style.transformOrigin = "center center";
}
function showImage(index) {
resetZoom();
const item = images[index];
previewImg.src = item.querySelector("img").src;
lbSku.innerText = item.querySelector(".lux-badge-sku").innerText;
lbPrice.innerText = item.querySelector(".lux-badge-price").innerText;
// Cập nhật link affiliate từ data attribute
currentAffLink = item.getAttribute('data-aff-link');
currentImg.innerText = index + 1;
totalImg.innerText = images.length;
currentIndex = index;
previewBox.querySelector(".prev").style.display = index === 0 ? "none" : "flex";
previewBox.querySelector(".next").style.display = index === images.length - 1 ? "none" : "flex";
}
// Mở Lightbox
images.forEach((img, i) => {
img.onclick = () => {
showImage(i);
previewBox.classList.add("show");
lbShadow.style.display = "block";
document.body.style.overflow = "hidden";
};
});
// Đóng Lightbox
const closeLightbox = () => {
previewBox.classList.remove("show");
lbShadow.style.display = "none";
document.body.style.overflow = "auto";
resetZoom();
};
closeLbBtn.onclick = closeLightbox;
lbShadow.onclick = closeLightbox;
// Điều hướng ảnh
previewBox.querySelector(".prev").onclick = (e) => { e.stopPropagation(); showImage(currentIndex - 1); };
previewBox.querySelector(".next").onclick = (e) => { e.stopPropagation(); showImage(currentIndex + 1); };
/**
* XỬ LÝ CHUYỂN HƯỚNG AFFILIATE
*/
btnAff.onclick = function() {
if (currentAffLink && currentAffLink !== '#') {
window.open(currentAffLink, '_blank', 'noopener,noreferrer');
} else {
alert('Sản phẩm này hiện chưa có link mua hàng.');
}
};
});
</script>
<?php
return ob_get_clean();
} );
/**
* 2. Đăng ký Element vào Flatsome UX Builder
*/
add_action( 'ux_builder_setup', function() {
add_ux_builder_shortcode( 'ux_gallery_vip', array(
'name' => __( 'Gallery Trang Đơn', 'flatsome-admin' ),
'category' => __( 'Content', 'flatsome-admin' ),
'icon' => 'icon-image', 
'options' => array(
'ids' => array(
'type' => 'gallery',
'heading' => __( 'Chọn hình ảnh', 'flatsome-admin' ),
),
),
) );
} );
[/foxhi]

Đoạn mã này được chia làm hai phần chính với logic hoạt động vô cùng chặt chẽ, được thiết kế riêng cho hệ sinh thái của theme Flatsome:

1. Xây dựng Shortcode [ux_gallery_vip] và cấu trúc dữ liệu Thay vì tạo thêm các custom field phức tạp làm nặng website, code đã tận dụng thông minh các trường thông tin có sẵn khi bạn upload một bức ảnh lên WordPress:

  • Mã sản phẩm (SKU): Lấy từ trường Chú thích (Caption / post_excerpt) của ảnh.
  • Giá sản phẩm: Lấy từ trường Mô tả (Description / post_content) của ảnh.
  • Link Affiliate: Lấy từ trường Văn bản thay thế (Alt Text). Đây là một thủ thuật rất hay giúp bạn gắn link đích trực tiếp vào từng bức ảnh.

Nếu thư viện không có ảnh nào được chọn, hệ thống sẽ tự động hiển thị thông báo yêu cầu chọn ảnh thay vì bị lỗi trắng trang.

2. Giao diện Lightbox và Trải nghiệm người dùng (JavaScript) Đoạn mã đi kèm một bộ script viết bằng JavaScript thuần (Vanilla JS) để xử lý popup xem ảnh (Lightbox) cực kỳ nhẹ nhàng:

  • Hiển thị trực quan: Khi click vào ảnh, popup hiện lên với hình ảnh phóng to, hiển thị rõ số thứ tự ảnh đang xem, SKU và mức giá tương ứng.
  • Điều hướng mượt mà: Khách hàng có thể bấm “Next / Prev” để lướt xem các sản phẩm khác mà không cần đóng popup.
  • Nút chuyển hướng Affiliate an toàn: Khi click vào nút “Mua Ngay / Xem Chi Tiết”, JavaScript sẽ quét link affiliate bạn đã gắn ở thẻ Alt Text và mở ra ở một tab mới. Nó cũng được trang bị thuộc tính noopener,noreferrer để đảm bảo bảo mật và tốc độ cho website gốc. Nếu ảnh chưa có link, hệ thống sẽ bật thông báo nhắc nhở thân thiện.

3. Đưa Element vào UX Builder của Flatsome Hàm ux_builder_setup ở cuối đoạn code đóng vai trò như một cây cầu nối. Nó đăng ký shortcode vừa tạo thành một block (phần tử) tên là “Gallery Trang Đơn” nằm trong tab Content của UX Builder. Người dùng website giờ đây chỉ cần kéo, thả và chọn ảnh giống hệt như cách dùng các tính năng gốc của Flatsome.

Chúc các bạn thành công!

Để lại một bình luận

Email của bạn sẽ không được hiển thị công khai. Các trường bắt buộc được đánh dấu *