Top Categories WooCommerce Shortcode
August 7, 2025 · AI Conversations
—
### ✅ PHP Code for `functions.php`:
Add this to your theme’s `functions.php` or a custom plugin:
function wc_top_categories_shortcode($atts) {
ob_start();
// Get top 3 product categories ordered by count
$args = [
'taxonomy' => 'product_cat',
'orderby' => 'count',
'order' => 'DESC',
'number' => 3,
'hide_empty' => true,
];
$categories = get_terms($args);
if (!empty($categories) && !is_wp_error($categories)) {
echo '<div class="top-categories-wrapper">';
echo '<h2>Our Top Categories</h2>';
echo '<div class="top-categories">';
foreach ($categories as $category) {
$thumbnail_id = get_term_meta($category->term_id, 'thumbnail_id', true);
$image_url = wp_get_attachment_url($thumbnail_id);
$category_link = get_term_link($category);
echo '<div class="top-category-item">';
if ($image_url) {
echo '<a href="' . esc_url($category_link) . '">';
echo '<img src="' . esc_url($image_url) . '" alt="' . esc_attr($category->name) . '" />';
echo '</a>';
}
echo '<h3><a href="' . esc_url($category_link) . '">' . esc_html($category->name) . '</a></h3>';
echo '</div>';
}
echo '</div></div>';
}
return ob_get_clean();
}
add_shortcode('wc_top_categories', 'wc_top_categories_shortcode');
—
### ✅ Example Usage in Editor:
[wc_top_categories]
—
### ✅ Optional CSS (to make it look nice):
.top-categories {
display: flex;
gap: 20px;
justify-content: center;
margin-top: 20px;
}
.top-category-item {
text-align: center;
width: 30%;
}
.top-category-item img {
max-width: 100%;
height: auto;
border-radius: 8px;
}
You can add the CSS in **Customizer > Additional CSS** or your theme’s stylesheet.
Let me know if you want it to show by **menu order**, **custom image size**, or **limited to specific category IDs**.
—
### ✅ PHP Code (place in `functions.php`):
function wc_top_parent_categories_shortcode($atts) {
ob_start();
// Fetch top 3 parent product categories by product count
$args = [
'taxonomy' => 'product_cat',
'orderby' => 'count',
'order' => 'DESC',
'number' => 3,
'hide_empty' => true,
'parent' => 0, // Only parent categories
];
$categories = get_terms($args);
if (!empty($categories) && !is_wp_error($categories)) {
echo '<div class="top-categories-wrapper">';
echo '<h2>Our Top Categories</h2>';
echo '<div class="top-categories">';
foreach ($categories as $category) {
$thumbnail_id = get_term_meta($category->term_id, 'thumbnail_id', true);
$image_url = wp_get_attachment_url($thumbnail_id);
$category_link = get_term_link($category);
echo '<div class="top-category-item">';
if ($image_url) {
echo '<a href="' . esc_url($category_link) . '">';
echo '<img src="' . esc_url($image_url) . '" alt="' . esc_attr($category->name) . '" />';
echo '</a>';
}
echo '<h3><a href="' . esc_url($category_link) . '">' . esc_html($category->name) . '</a></h3>';
echo '</div>';
}
echo '</div></div>';
}
return ob_get_clean();
}
add_shortcode('wc_top_parent_categories', 'wc_top_parent_categories_shortcode');
—
### ✅ Usage:
[wc_top_parent_categories]
—
### ✅ Optional CSS (copy into Customizer > Additional CSS):
.top-categories {
display: flex;
gap: 20px;
justify-content: center;
margin-top: 20px;
flex-wrap: wrap;
}
.top-category-item {
text-align: center;
width: 30%;
}
.top-category-item img {
max-width: 100%;
height: auto;
border-radius: 8px;
}
Let me know if you also want to limit to specific **category IDs**, **custom image sizes**, or show **product counts** next to titles.
we have this templae
Our Top Categories
';
– White rounded cards with shadows
– Centered image
– Category name
– A styled arrow icon button
– Neatly spaced grid layout
—
### ✅ Updated PHP Template (replace your loop body with this):
<div class="top-categories-wrapper">
<h2>Our Top Categories</h2>
<div class="top-categories">
<?php foreach ($categories as $category):
$thumbnail_id = get_term_meta($category->term_id, 'thumbnail_id', true);
$image_url = wp_get_attachment_url($thumbnail_id);
$category_link = get_term_link($category);
if (is_wp_error($category_link)) continue;
?>
<div class="top-category-item">
<a href="<?= esc_url($category_link); ?>">
<div class="category-image">
<img src="<?= esc_url($image_url ?: '/wp-content/uploads/91b8b9287795f27f29956b7ebf80502ae809e8ad-scaled.jpg'); ?>"
alt="<?= esc_attr($category->name); ?>" />
</div>
<div class="category-footer">
<h3><?= esc_html($category->name); ?></h3>
<span class="arrow-btn">→</span>
</div>
</a>
</div>
<?php endforeach; ?>
</div>
</div>
—
### ✅ Matching CSS (add in Customizer > Additional CSS):
.top-categories {
display: flex;
flex-wrap: wrap;
gap: 20px;
justify-content: center;
margin-top: 20px;
}
.top-category-item {
background: #fff;
border-radius: 12px;
box-shadow: 0 4px 15px rgba(0, 0, 0, 0.08);
overflow: hidden;
text-align: center;
width: 250px;
transition: transform 0.3s ease;
}
.top-category-item:hover {
transform: translateY(-5px);
}
.category-image img {
width: 100%;
height: 200px;
object-fit: cover;
display: block;
}
.category-footer {
padding: 15px;
display: flex;
justify-content: space-between;
align-items: center;
font-weight: bold;
}
.category-footer h3 {
font-size: 16px;
margin: 0;
flex: 1;
text-align: left;
color: #000;
}
.arrow-btn {
font-size: 18px;
background: #004d4d;
color: #fff;
padding: 6px 10px;
border-radius: 50%;
line-height: 1;
display: inline-block;
transition: background 0.3s;
}
.arrow-btn:hover {
background: #007777;
}
—
Let me know if you want to:
– Add **product count badges**
– Load categories via **AJAX**
– Convert the layout into a **grid with equal height**
Happy to adjust it further!
—
### ✅ Updated Shortcode with `count` Attribute
#### 🔧 PHP (put in `functions.php`):
function wc_top_parent_categories_shortcode($atts) {
$atts = shortcode_atts([
'count' => 3, // default to 3
], $atts);
ob_start();
$args = [
'taxonomy' => 'product_cat',
'orderby' => 'count',
'order' => 'DESC',
'number' => intval($atts['count']),
'hide_empty' => true,
'parent' => 0, // only parent categories
];
$categories = get_terms($args);
if (!empty($categories) && !is_wp_error($categories)) {
?>
<div class="top-categories-wrapper">
<h2>Our Top Categories</h2>
<div class="top-categories">
<?php foreach ($categories as $category):
$thumbnail_id = get_term_meta($category->term_id, 'thumbnail_id', true);
$image_url = wp_get_attachment_url($thumbnail_id);
$category_link = get_term_link($category);
if (is_wp_error($category_link)) continue;
?>
<div class="top-category-item">
<a href="<?= esc_url($category_link); ?>">
<div class="category-image">
<img src="<?= esc_url($image_url ?: '/wp-content/uploads/91b8b9287795f27f29956b7ebf80502ae809e8ad-scaled.jpg'); ?>"
alt="<?= esc_attr($category->name); ?>" />
</div>
<div class="category-footer">
<h3><?= esc_html($category->name); ?></h3>
<span class="arrow-btn">→</span>
</div>
</a>
</div>
<?php endforeach; ?>
</div>
</div>
<?php
}
return ob_get_clean();
}
add_shortcode('wc_top_parent_categories', 'wc_top_parent_categories_shortcode');
—
### ✅ Usage Examples:
[wc_top_parent_categories count="3"]
[wc_top_parent_categories count="5"]
—
Let me know if you also want to accept other attributes like `orderby`, `include`, or a specific list of parent category IDs.
function flatsome_blog_category_posts()
{
ob_start();
$terms = get_terms([
'taxonomy' => 'category',
'hide_empty' => true,
]);
if (!is_wp_error($terms))
{
$first_cat_id = 1126;
$args=['post_type' => 'post',
'posts_per_page' => 6,
'paged' => 1];
if($first_cat_id!=0)
$args['cat']=$first_cat_id;
$initial_query = new WP_Query($args);
$template_path = get_stylesheet_directory() . '/partials/blog-post-category-template.php';
if (file_exists($template_path)) {
include $template_path;
} else {
echo 'Template not found.';
}
}
return ob_get_clean();
}
make this to pass default cat id, yes no for pagination and number of blogs in one row
– ✅ `cat_id` – default category ID (e.g. 1126)
– ✅ `pagination` – `yes` or `no` to enable/disable pagination
– ✅ `columns` – number of blog posts per row (used in the template layout)
—
### ✅ Modified `functions.php` Code:
“`php
add_shortcode('flatsome_blog_posts', 'flatsome_blog_category_posts');
function flatsome_blog_category_posts($atts)
{
// Shortcode attributes with defaults
$atts = shortcode_atts([
'cat_id' => 1126,
'pagination'=> 'yes',
'columns' => 3,
], $atts);
ob_start();
// Get all blog categories
$terms = get_terms([
'taxonomy' => 'category',
'hide_empty' => true,
]);
if (!is_wp_error($terms)) {
$first_cat_id = intval($atts['cat_id']);
// Build query args
$args = [
'post_type' => 'post',
'posts_per_page' => 6,
'paged' => (get_query_var('paged')) ? get_query_var('paged') : 1,
];
if ($first_cat_id > 0) {
$args['cat'] = $first_cat_id;
}
// If pagination is disabled, fetch all posts
if ($atts['pagination'] === 'no') {
$args['nopaging'] = true;
}
$initial_query = new WP_Query($args);
// Pass number of columns to template
$columns = intval($atts['columns']);
set_query_var('blog_columns', $columns);
set_query_var('blog_terms', $terms);
set_query_var('blog_query', $initial_query);
set_query_var
– ✅ `cat_id`: Default category ID (e.g., `1126`)
– ✅ `pagination`: `yes` or `no`
– ✅ `columns`: Number of blog posts per row
– ✅ `searchbox`: `yes` or `no` (to show/hide search box)
– ✅ `category_tabs`: `yes` or `no` (to show/hide category tabs)
—
### ✅ Updated PHP Code for `functions.php`:
add_shortcode('flatsome_blog_posts', 'flatsome_blog_category_posts');
function flatsome_blog_category_posts($atts)
{
// Define shortcode attributes with defaults
$atts = shortcode_atts([
'cat_id' => 1126,
'pagination' => 'yes',
'columns' => 3,
'searchbox' => 'yes',
'category_tabs' => 'yes',
], $atts);
ob_start();
// Get all blog categories
$terms = get_terms([
'taxonomy' => 'category',
'hide_empty' => true,
]);
if (!is_wp_error($terms)) {
$first_cat_id = intval($atts['cat_id']);
// Build WP_Query args
$args = [
'post_type' => 'post',
'posts_per_page' => 6,
'paged' => (get_query_var('paged')) ? get_query_var('paged') : 1,
];
if ($first_cat_id > 0) {
$args['cat'] = $first_cat_id;
}
// Disable pagination if specified
if ($atts['pagination'] === 'no') {
$args['nopaging'] = true;
}
$initial_query = new WP_Query($args);
// Pass values to the template
set_query_var('blog_columns', intval($atts['columns']));
set_query_var('blog_terms', $terms);
set_query_var('blog_query', $initial_query);
set_query_var('show_searchbox', $atts['searchbox'] === 'yes');
set_query_var('show_category_tabs', $atts['category_tabs'] === 'yes');
set_query_var('default_category_id', $first_cat_id);
// Load template
$template_path = get_stylesheet_directory() . '/partials/blog-post-category-template.php';
if (file_exists($template_path)) {
include $template_path;
} else {
echo '<p>Template not found.</p>';
}
}
return ob_get_clean();
}
—
### ✅ How to Use the Shortcode:
[flatsome_blog_posts cat_id="1126" pagination="yes" columns="3" searchbox="yes" category_tabs="yes"]
—
### ✅ In Your Template (`blog-post-category-template.php`):
Use the passed variables:
<?php
$columns = get_query_var('blog_columns', 3);
$terms = get_query_var('blog_terms');
$query = get_query_var('blog_query');
$show_searchbox = get_query_var('show_searchbox');
$show_category_tabs = get_query_var('show_category_tabs');
$default_cat_id = get_query_var('default_category_id');
// Now use $show_searchbox and $show_category_tabs to conditionally render those sections
?>
Let me know if you want JS-based filters or Load More functionality too!
—
## ✅ 1. PHP Shortcode Function (add to `functions.php`):
add_shortcode('custom_product_tabs', 'custom_product_tabs_shortcode');
function custom_product_tabs_shortcode($atts) {
ob_start();
?>
<div class="product-tabs-wrapper">
<div class="product-tabs-nav">
<button class="tab-button active" data-tab="new">New</button>
<button class="tab-button" data-tab="sales">Sales</button>
<button class="tab-button" data-tab="bestsellers">Bestsellers</button>
<button class="tab-button" data-tab="spotlights">Spotlights</button>
</div>
<div class="tab-content" id="tab-new">
<?php echo do_shortcode('[products limit="4" orderby="date" order="DESC"]'); ?>
</div>
<div class="tab-content" id="tab-sales" style="display:none;">
<?php echo do_shortcode('[products limit="4" on_sale="true"]'); ?>
</div>
<div class="tab-content" id="tab-bestsellers" style="display:none;">
<?php echo do_shortcode('[products limit="4" orderby="popularity"]'); ?>
</div>
<div class="tab-content" id="tab-spotlights" style="display:none;">
<?php echo do_shortcode('[products limit="4" visibility="featured"]'); ?>
</div>
</div>
<script>
document.addEventListener('DOMContentLoaded', function () {
const tabs = document.querySelectorAll('.tab-button');
const contents = document.querySelectorAll('.tab-content');
tabs.forEach(tab => {
tab.addEventListener('click', function () {
tabs.forEach(t => t.classList.remove('active'));
contents.forEach(c => c.style.display = 'none');
this.classList.add('active');
document.getElementById('tab-' + this.dataset.tab).style.display = 'block';
});
});
});
</script>
<?php
return ob_get_clean();
}
—
## ✅ 2. CSS Styling (Add to Customizer > Additional CSS):
.product-tabs-wrapper {
text-align: center;
margin-bottom: 40px;
}
.product-tabs-nav {
display: flex;
justify-content: center;
gap: 30px;
margin-bottom: 30px;
}
.tab-button {
background: none;
border: none;
font-size: 18px;
font-weight: 600;
padding: 10px 20px;
cursor: pointer;
border-bottom: 3px solid transparent;
transition: all 0.3s ease;
}
.tab-button.active {
border-color: #000;
color: #000;
}
.tab-content {
display: flex;
flex-wrap: wrap;
justify-content: center;
gap: 20px;
}
/* WooCommerce card overrides */
ul.products li.product {
width: 220px;
border-radius: 12px;
text-align: center;
padding: 20px;
box-shadow: 0 4px 15px rgba(0,0,0,0.08);
}
—
## ✅ Usage in Editor:
[custom_product_tabs]
—
### 💡 Custom Notes:
– You can customize how many products show via `limit="4"` in each `[products]` shortcode.
– The layout and buttons match your screenshot closely.
– Each tab loads 4 WooCommerce products dynamically, no AJAX needed.
Let me know if you want it:
– AJAX-powered
– With "Load More"
– Or to pull specific product categories or tags per tab.