Background:
- We need a page that dynamically shows all Brands with their logos and links to their products
- Brand is a custom post type
- There are two. We are using the one kadence made but might be better method (please advise as best)

Is is possible to create a page to show all the products brands with their logos/feature images and brand names? Is it possible to do it via Kadence blocks – portfolio or post grid, or by using shortcodes?
we need make a page with hundreds of brands and doing it manualy is disaster
It’s best to leverage the built-in “brand category” that is created by the Kadence woocommerce shop kit.
So I explored into the source code of that plugin and found out a solution.
Simply put the codes into your functions.php or any plugin like “code snippet” so to make the short code work.
After that, simply create a page that you want to show all the brads in the “brand category”.
Short code is
[brands_list]
It also has a pagination function: it loads 12 brads per page then paginated the rest.
Here’s the code to put into the functions.php
/**
* Custom Brands Shortcode for WordPress
* To use this shortcode, make sure to activate Kadence shop kit
*
* Usage: [brands_list] or [brands_list columns="4" show_count="true" show_image="true"]
*
* Requirements:
* - WooCommerce plugin must be active
* - Kadence WooCommerce Extras (Shop Kit) plugin must be active
* - Product brands feature must be enabled in Kadence settings
*/
// Prevent direct access
if (!defined('ABSPATH')) {
exit;
}
/**
* Check if all required plugins and features are available
*
* @return array Array with 'status' (bool) and 'message' (string)
*/
function check_brands_requirements() {
// Check if WooCommerce is active
if (!class_exists('WooCommerce')) {
return array(
'status' => false,
'message' => 'WooCommerce plugin is required but not active. Please install and activate WooCommerce.'
);
}
// Check if Kadence WooCommerce Extras is active by checking for its constants or functions
if (!defined('KADENCE_WOO_EXTRAS_VERSION') && !function_exists('init_kadence_woo_extras')) {
return array(
'status' => false,
'message' => 'Kadence WooCommerce Extras (Shop Kit) plugin is required but not active. Please install and activate the plugin.'
);
}
// Check if product brands feature is enabled
$shopkit_settings = get_option('kt_woo_extras');
if (!is_array($shopkit_settings)) {
$shopkit_settings = json_decode($shopkit_settings, true);
}
if (empty($shopkit_settings['kt_product_brands_options'])) {
return array(
'status' => false,
'message' => 'Product brands feature is not enabled in Kadence Shop Kit settings. Please enable it in WooCommerce > Shop Kit > Product Brands.'
);
}
// Check if the product brands taxonomy exists
if (!taxonomy_exists('product_brands')) {
return array(
'status' => false,
'message' => 'Product brands taxonomy is not available. Please check your Kadence Shop Kit configuration.'
);
}
return array(
'status' => true,
'message' => ''
);
}
/**
* Register the brands list shortcode
*/
function register_brands_list_shortcode() {
add_shortcode('brands_list', 'display_brands_list_shortcode');
}
add_action('init', 'register_brands_list_shortcode');
/**
* Display brands list shortcode
*
* @param array $atts Shortcode attributes
* @return string HTML output
*/
function display_brands_list_shortcode($atts) {
// Check requirements first
$requirements_check = check_brands_requirements();
if (!$requirements_check['status']) {
return '<div class="brands-error" style="padding: 15px; background: #fff3cd; border: 1px solid #ffeaa7; border-radius: 4px; color: #856404; margin: 10px 0;"><strong>Brands Shortcode Error:</strong> ' . esc_html($requirements_check['message']) . '</div>';
}
// Default attributes
$atts = shortcode_atts(array(
'columns' => '3', // Number of columns (1-6)
'show_count' => 'true', // Show product count
'show_image' => 'true', // Show brand image/logo
'image_size' => 'medium', // Image size (thumbnail, medium, large, full)
'hide_empty' => 'true', // Hide brands with no products
'orderby' => 'name', // Order by (name, count, slug, term_group)
'order' => 'ASC', // Order direction (ASC, DESC)
'limit' => '', // Limit number of brands (empty for all)
'class' => '', // Additional CSS classes
'per_page' => '12', // Number of brands per page
'show_pagination' => 'true', // Show pagination navigation
), $atts, 'brands_list');
// Get current page number
$current_page = 1;
if (isset($_GET['brands_page']) && is_numeric($_GET['brands_page'])) {
$current_page = max(1, intval($_GET['brands_page']));
}
// Calculate pagination
$per_page = intval($atts['per_page']);
$offset = ($current_page - 1) * $per_page;
// Prepare query arguments for counting total brands
$count_args = array(
'taxonomy' => 'product_brands',
'hide_empty' => ($atts['hide_empty'] === 'true'),
'fields' => 'count',
);
// Get total count
$total_brands = get_terms($count_args);
$total_pages = ceil($total_brands / $per_page);
// Prepare query arguments for actual brands
$args = array(
'taxonomy' => 'product_brands',
'hide_empty' => ($atts['hide_empty'] === 'true'),
'orderby' => $atts['orderby'],
'order' => $atts['order'],
'number' => $per_page,
'offset' => $offset,
);
// Override with limit if specified (takes precedence over pagination)
if (!empty($atts['limit']) && is_numeric($atts['limit'])) {
$args['number'] = intval($atts['limit']);
unset($args['offset']);
$atts['show_pagination'] = 'false'; // Disable pagination when limit is used
}
// Get brand terms
$brands = get_terms($args);
if (is_wp_error($brands) || empty($brands)) {
return '<p>No brands found.</p>';
}
// Start building output
$columns = max(1, min(6, intval($atts['columns'])));
$additional_class = !empty($atts['class']) ? ' ' . esc_attr($atts['class']) : '';
$output = '<div class="brands-list-container' . $additional_class . '">';
$output .= '<div class="brands-grid brands-columns-' . $columns . '">';
foreach ($brands as $brand) {
$brand_link = get_term_link($brand);
$brand_image = '';
$product_count = $brand->count;
// Get brand image if enabled
if ($atts['show_image'] === 'true') {
$image_id = get_term_meta($brand->term_id, '_kt_woo_extras_brand_image', true);
if (!empty($image_id) && is_array($image_id) && isset($image_id[0])) {
$image_url = wp_get_attachment_image_url($image_id[0], $atts['image_size']);
if ($image_url) {
$brand_image = '<div class="brand-image"><img src="' . esc_url($image_url) . '" alt="' . esc_attr($brand->name) . '" /></div>';
}
}
}
// Build brand item HTML
$output .= '<div class="brand-item">';
$output .= '<a href="' . esc_url($brand_link) . '" class="brand-link">';
if (!empty($brand_image)) {
$output .= $brand_image;
}
$output .= '<div class="brand-info">';
$output .= '<h3 class="brand-name">' . esc_html($brand->name) . '</h3>';
if (!empty($brand->description)) {
$output .= '<p class="brand-description">' . esc_html($brand->description) . '</p>';
}
if ($atts['show_count'] === 'true' && $product_count > 0) {
$output .= '<span class="brand-count">(' . $product_count . ' ' . _n('product', 'products', $product_count, 'textdomain') . ')</span>';
}
$output .= '</div>'; // .brand-info
$output .= '</a>'; // .brand-link
$output .= '</div>'; // .brand-item
}
$output .= '</div>'; // .brands-grid
// Add pagination if enabled and there are multiple pages
if ($atts['show_pagination'] === 'true' && $total_pages > 1) {
$output .= '<div class="brands-pagination">';
// Get current URL without brands_page parameter
$current_url = remove_query_arg('brands_page');
// Previous page link
if ($current_page > 1) {
$prev_url = add_query_arg('brands_page', $current_page - 1, $current_url);
$output .= '<a href="' . esc_url($prev_url) . '" class="brands-pagination-prev">« Previous</a>';
} else {
$output .= '<span class="brands-pagination-prev disabled">« Previous</span>';
}
// Page numbers
$output .= '<span class="brands-pagination-info">';
// Show page numbers (with ellipsis for large page counts)
$start_page = max(1, $current_page - 2);
$end_page = min($total_pages, $current_page + 2);
if ($start_page > 1) {
$first_url = add_query_arg('brands_page', 1, $current_url);
$output .= '<a href="' . esc_url($first_url) . '" class="brands-pagination-number">1</a>';
if ($start_page > 2) {
$output .= '<span class="brands-pagination-ellipsis">...</span>';
}
}
for ($i = $start_page; $i <= $end_page; $i++) {
if ($i == $current_page) {
$output .= '<span class="brands-pagination-number current">' . $i . '</span>';
} else {
$page_url = add_query_arg('brands_page', $i, $current_url);
$output .= '<a href="' . esc_url($page_url) . '" class="brands-pagination-number">' . $i . '</a>';
}
}
if ($end_page < $total_pages) {
if ($end_page < $total_pages - 1) {
$output .= '<span class="brands-pagination-ellipsis">...</span>';
}
$last_url = add_query_arg('brands_page', $total_pages, $current_url);
$output .= '<a href="' . esc_url($last_url) . '" class="brands-pagination-number">' . $total_pages . '</a>';
}
$output .= '</span>';
// Next page link
if ($current_page < $total_pages) {
$next_url = add_query_arg('brands_page', $current_page + 1, $current_url);
$output .= '<a href="' . esc_url($next_url) . '" class="brands-pagination-next">Next »</a>';
} else {
$output .= '<span class="brands-pagination-next disabled">Next »</span>';
}
$output .= '</div>'; // .brands-pagination
}
$output .= '</div>'; // .brands-list-container
return $output;
}
/**
* Add CSS styles for the brands shortcode
*/
function brands_list_shortcode_styles() {
if (has_shortcode(get_post()->post_content, 'brands_list') || is_admin()) {
?>
<style type="text/css">
.brands-list-container {
margin: 20px 0;
}
.brands-grid {
display: grid;
gap: 20px;
margin-bottom: 20px;
}
.brands-columns-1 { grid-template-columns: 1fr; }
.brands-columns-2 { grid-template-columns: repeat(2, 1fr); }
.brands-columns-3 { grid-template-columns: repeat(3, 1fr); }
.brands-columns-4 { grid-template-columns: repeat(4, 1fr); }
.brands-columns-5 { grid-template-columns: repeat(5, 1fr); }
.brands-columns-6 { grid-template-columns: repeat(6, 1fr); }
@media (max-width: 768px) {
.brands-columns-3,
.brands-columns-4,
.brands-columns-5,
.brands-columns-6 {
grid-template-columns: repeat(2, 1fr);
}
}
@media (max-width: 480px) {
.brands-grid {
grid-template-columns: 1fr !important;
}
}
.brand-item {
border: 1px solid #e0e0e0;
border-radius: 8px;
overflow: hidden;
transition: transform 0.3s ease, box-shadow 0.3s ease;
background: #fff;
}
.brand-item:hover {
transform: translateY(-5px);
box-shadow: 0 5px 15px rgba(0,0,0,0.1);
}
.brand-link {
display: block;
text-decoration: none;
color: inherit;
height: 100%;
}
.brand-image {
display: flex;
align-items: center;
justify-content: center;
padding: 20px;
background: #f9f9f9;
min-height: 160px;
}
.brand-image img {
max-width: 100%;
height: auto;
max-height: 120px;
object-fit: contain;
}
.brand-info {
padding: 15px;
text-align: center;
}
.brand-name {
margin: 0 0 10px 0;
font-size: 18px;
font-weight: 600;
color: #333;
}
.brand-description {
margin: 0 0 10px 0;
font-size: 14px;
font-weight: 400;
color: #666;
line-height: 1.4;
}
.brand-count {
font-size: 12px;
color: #999;
font-style: italic;
}
/* Alternative list style */
.brands-list-style .brands-grid {
display: block;
}
.brands-list-style .brand-item {
display: flex;
align-items: center;
margin-bottom: 15px;
padding: 15px;
}
.brands-list-style .brand-image {
flex: 0 0 80px;
margin-right: 15px;
padding: 10px;
}
.brands-list-style .brand-image img {
max-height: 60px;
}
.brands-list-style .brand-info {
flex: 1;
text-align: left;
padding: 0;
}
/* Pagination Styles */
.brands-pagination {
display: flex;
justify-content: center;
align-items: center;
margin-top: 30px;
padding: 20px 0;
gap: 10px;
flex-wrap: wrap;
}
.brands-pagination a,
.brands-pagination span {
display: inline-block;
padding: 8px 12px;
text-decoration: none;
border: 1px solid #ddd;
border-radius: 4px;
color: #333;
background: #fff;
transition: all 0.3s ease;
font-size: 14px;
line-height: 1;
}
.brands-pagination a:hover {
background: #f5f5f5;
border-color: #999;
color: #000;
}
.brands-pagination .current {
background: #0073aa;
color: #fff;
border-color: #0073aa;
font-weight: bold;
}
.brands-pagination .disabled {
color: #999;
background: #f9f9f9;
border-color: #e0e0e0;
cursor: not-allowed;
}
.brands-pagination-info {
display: flex;
align-items: center;
gap: 5px;
}
.brands-pagination-ellipsis {
padding: 8px 4px;
border: none;
background: none;
color: #666;
}
.brands-pagination-prev,
.brands-pagination-next {
font-weight: 500;
}
@media (max-width: 480px) {
.brands-pagination {
gap: 5px;
}
.brands-pagination a,
.brands-pagination span {
padding: 6px 8px;
font-size: 12px;
}
.brands-pagination-prev,
.brands-pagination-next {
padding: 6px 10px;
}
}
</style>
<?php
}
}
add_action('wp_head', 'brands_list_shortcode_styles');
/**
* Alternative shortcode for simple brand links list
*/
function display_brands_links_shortcode($atts) {
// Check requirements first
$requirements_check = check_brands_requirements();
if (!$requirements_check['status']) {
return '<div class="brands-error" style="padding: 15px; background: #fff3cd; border: 1px solid #ffeaa7; border-radius: 4px; color: #856404; margin: 10px 0;"><strong>Brands Shortcode Error:</strong> ' . esc_html($requirements_check['message']) . '</div>';
}
$atts = shortcode_atts(array(
'separator' => ' | ',
'show_count' => 'false',
'hide_empty' => 'true',
'orderby' => 'name',
'order' => 'ASC',
'limit' => '',
), $atts, 'brands_links');
$args = array(
'taxonomy' => 'product_brands',
'hide_empty' => ($atts['hide_empty'] === 'true'),
'orderby' => $atts['orderby'],
'order' => $atts['order'],
);
if (!empty($atts['limit']) && is_numeric($atts['limit'])) {
$args['number'] = intval($atts['limit']);
}
$brands = get_terms($args);
if (is_wp_error($brands) || empty($brands)) {
return '<p>No brands found.</p>';
}
$links = array();
foreach ($brands as $brand) {
$brand_link = get_term_link($brand);
$link_text = $brand->name;
if ($atts['show_count'] === 'true' && $brand->count > 0) {
$link_text .= ' (' . $brand->count . ')';
}
$links[] = '<a href="' . esc_url($brand_link) . '">' . esc_html($link_text) . '</a>';
}
return '<div class="brands-links">' . implode($atts['separator'], $links) . '</div>';
}
add_shortcode('brands_links', 'display_brands_links_shortcode');
/**
* Register shortcode in Gutenberg
*/
function register_brands_shortcode_block() {
if (function_exists('register_block_type')) {
wp_register_script(
'brands-shortcode-block',
false,
array('wp-blocks', 'wp-element', 'wp-editor'),
'1.0.0',
true
);
wp_add_inline_script('brands-shortcode-block', '
(function(blocks, element, editor) {
var el = element.createElement;
var RichText = editor.RichText;
blocks.registerBlockType("custom/brands-shortcode", {
title: "Brands List",
icon: "tag",
category: "widgets",
edit: function(props) {
return el("div", {
className: "brands-shortcode-placeholder",
style: { padding: "20px", border: "1px dashed #ccc", textAlign: "center" }
}, "[brands_list] - Brands will display on frontend");
},
save: function(props) {
return el("div", {}, "[brands_list]");
}
});
})(window.wp.blocks, window.wp.element, window.wp.editor);
');
}
}
add_action('enqueue_block_editor_assets', 'register_brands_shortcode_block');
/**
* Display admin notice if requirements are not met
*/
function brands_shortcode_admin_notice() {
// Only show to administrators
if (!current_user_can('manage_options')) {
return;
}
$requirements_check = check_brands_requirements();
if (!$requirements_check['status']) {
echo '<div class="notice notice-warning is-dismissible">';
echo '<p><strong>Brands Shortcode:</strong> ' . esc_html($requirements_check['message']) . '</p>';
echo '</div>';
}
}
add_action('admin_notices', 'brands_shortcode_admin_notice');
/**
* Add safety check for function existence to prevent conflicts
*/
if (!function_exists('check_brands_requirements')) {
/**
* Fallback function if somehow the main function doesn't exist
*/
function check_brands_requirements_fallback() {
return 'Brands shortcode functions are not properly loaded.';
}
}
/**
* Deactivation cleanup (optional)
*/
function brands_shortcode_deactivation_cleanup() {
// Clear any cached data if needed
delete_transient('brands_list_cache');
}
// Uncomment the line below if you convert this to a plugin
// register_deactivation_hook(__FILE__, 'brands_shortcode_deactivation_cleanup');