Wprowadzenie do własnych shortcode’ów
Tworzenie własnych shortcode’ów w WooCommerce daje pełną kontrolę nad prezentacją produktów. Możesz wyświetlać tylko te pozycje, które chcesz pokazać klientowi. Dzięki temu tworzysz dopasowane sekcje ofertowe. Nie musisz korzystać z kategorii czy tagów. Wystarczy podać konkretne ID produktów. To szybkie i bardzo elastyczne rozwiązanie. Idealne dla sklepów promujących wybrane produkty.
Shortcode produktów WooCommerce z promocją i sortowaniem
W tym rozwiązaniu zastosowano shortcode produktów WooCommerce z promocją. Produkty promocyjne są zawsze na pierwszym miejscu. Sortowanie działa niezależnie od filtra. Użytkownik może wybierać między ceną, nazwą i kategorią. Wszystko działa płynnie, bez przeładowań strony. Filtry pozwalają pokazać tylko programy biznesowe lub dietetyczne. To bardzo wygodne, szczególnie przy większej liczbie ofert.
Każdy produkt wyświetlany jest w formie karty, a następnie karta zawiera zdjęcie, nazwę, opis i cenę. Dodatkowo można dodać produkt bezpośrednio do koszyka. Produkty promocyjne wyróżnione są czerwonym obramowaniem. Dodatkowo pojawia się badge z informacją o zniżce. Taki układ przyciąga wzrok, a tym samym zwiększa skuteczność sprzedaży.
Dlaczego warto zastosować ten mechanizm?
Shortcode produktów WooCommerce z promocją daje pełną kontrolę nad ofertą. Użytkownik widzi tylko to, co chcesz sprzedać. Masz wpływ na kolejność, wygląd i zachowanie produktów. Promocje są lepiej widoczne. Klient szybciej zauważa okazje i podejmuje decyzję zakupową. System działa płynnie na wszystkich urządzeniach. Jest prosty do wdrożenia i nie wymaga dodatkowych wtyczek.
add_shortcode('custom_product_list', 'custom_display_selected_products');
function custom_display_selected_products() {
$product_ids = [Tutaj wpisujesz ID swoich produktów];
$products_with_prices = [];
foreach ($product_ids as $id) {
$product = wc_get_product($id);
if ($product) {
$products_with_prices[$id] = [
'price' => (float) $product->get_price(),
'title' => $product->get_name(),
'is_on_sale' => $product->is_on_sale()
];
}
}
uasort($products_with_prices, function($a, $b) {
if ($a['is_on_sale'] && !$b['is_on_sale']) return -1;
if (!$a['is_on_sale'] && $b['is_on_sale']) return 1;
return $b['price'] <=> $a['price'];
});
$style = '<style>
.custom-product-grid {
display: flex;
flex-wrap: wrap;
gap: 20px;
}
.custom-product-box {
flex: 0 0 calc(33.333% - 20px);
border: 1px solid #ddd;
box-sizing: border-box;
position: relative;
transition: all 0.5s ease;
opacity: 1;
}
.custom-product-box.on-sale {
border: 2px solid red;
-webkit-box-shadow: 0px 0px 12px 0px rgba(177, 177, 177, 1);
-moz-box-shadow: 0px 0px 12px 0px rgba(177, 177, 177, 1);
box-shadow: 0px 0px 12px 0px rgba(177, 177, 177, 1);
transform: scale(1.02);
}
.custom-product-box.on-sale:hover{
-webkit-box-shadow: 0px 0px 12px 0px rgba(152, 14, 14, 1);
-moz-box-shadow: 0px 0px 12px 0px rgba(152, 14, 14, 1);
box-shadow: 0px 0px 12px 0px rgba(152, 14, 14, 1);
}
.custom-product-box.hidden {
opacity: 0;
pointer-events: none;
}
.custom-product-box .product-image img {
width: 100%;
height: auto;
display: block;
}
.add-to-cart {
position: relative;
z-index: 2;
text-align: center;
margin-top: 10px;
}
@media (max-width: 767px) {
.custom-product-box {
flex: 0 0 100%;
}
}
@media (min-width: 768px) and (max-width: 1024px) {
.custom-product-box {
flex: 0 0 calc(50% - 20px);
}
}
.discount-badge {
position: absolute;
top: 10px;
left: 10px;
background: #e60023;
color: #fff;
font-size: 14px;
font-weight: bold;
padding: 5px 10px;
border-radius: 50%;
z-index: 3;
box-shadow: 0 2px 5px rgba(0,0,0,0.2);
}
.filter-button {
padding: 10px 20px;
background-color: #219EC5;
color: #fff;
border: 1px solid #219EC5;
cursor: pointer;
margin: 5px;
}
.filter-button:hover {
background-color: transparent;
color:#219EC5;
border: 2px solid #219EC5;
}
.filter-button.active {
background-color: #262626;
color:white;
font-weight:700;
}
</style>';
$output = $style;
$output .= '
<div class="poruszanie" style="margin-bottom: 20px; text-align: center;">
<div class="filtrowanie">
<button class="filter-button active" data-filter="all">Wszystkie programy</button>
<button class="filter-button" data-filter="biznes">Nazwa guzika dla pierwszego filtrowania</button>
<button class="filter-button" data-filter="diet">Nazwa guzika dla drugiego filtorwania</button>
// możesz dodać więcej filtrów ale pamiętaj o różnych nazwach w " data-filter " //
</div>
<div style="display: inline-block;">
<label for="sort-select" style="margin-right: 5px;">Sortuj:</label>
<select id="sort-select">
<option value="">Wybierz rodzaj sortowania</option>
<option value="price-asc">Sortuj od najtańszego</option>
<option value="price-desc">Sortuj od najdroższego</option>
<option value="alpha-asc">Sortuj alfabetycznie (A-Z)</option>
</select>
</div>
</div>
';
$output .= '<div class="custom-product-grid" id="custom-product-grid">';
$custom_titles = [
TUTAJ WPISZ ID PRODUKTU => 'Nazwa produktu, która ma się wyświetlać w archiwum produktu',
];
foreach ($products_with_prices as $product_id => $data) {
$product = wc_get_product($product_id);
if (!$product) continue;
$product_url = get_permalink($product_id);
$custom_title = $custom_titles[$product_id] ?? $product->get_name();
$regular_price = (float) $product->get_regular_price();
$sale_price = (float) $product->get_sale_price();
$discount_html = '';
if ($sale_price && $regular_price && $sale_price < $regular_price) {
$discount_percent = round((($regular_price - $sale_price) / $regular_price) * 100);
$discount_html = '<div class="discount-badge">-' . $discount_percent . '%</div>';
}
$category_class = in_array($product_id, [29906, 26598, 27310]) ? 'biznes' : 'diet';
$sale_class = $data['is_on_sale'] ? 'on-sale' : '';
$output .= '<div class="custom-product-box category-' . $category_class . ' ' . $sale_class . '" data-category="' . $category_class . '" data-price="' . esc_attr($data['price']) . '" data-title="' . esc_attr($custom_title) . '" data-sale="' . ($data['is_on_sale'] ? '1' : '0') . '">';
$output .= $discount_html;
$output .= '<a href="' . esc_url($product_url) . '" style="position:absolute;top:0;left:0;right:0;bottom:0;z-index:1;"></a>';
$output .= '<div style="position: relative; padding: 15px;">';
$output .= '<div class="product-image" style="margin-bottom: 10px;">' . $product->get_image('full') . '</div>';
$output .= '<div class="product-title"><strong>' . esc_html($custom_title) . '</strong></div>';
$output .= '<div class="product-description" style="margin-top: 5px;">' . apply_filters('woocommerce_short_description', $product->get_short_description()) . '</div>';
$output .= '<div class="product-price"><strong>' . $product->get_price_html() . '</strong></div>';
$output .= '<div class="add-to-cart">';
$output .= '<form class="cart" action="' . esc_url(wc_get_cart_url()) . '" method="post" enctype="multipart/form-data">';
$output .= '<input type="hidden" name="add-to-cart" value="' . esc_attr($product_id) . '" />';
$output .= '<button type="submit" class="button guziczek">Dodaj do koszyka</button>';
$output .= '</form>';
$output .= '</div></div></div>';
}
$output .= '</div>';
$output .= '
<script>
document.addEventListener("DOMContentLoaded", function () {
const buttons = document.querySelectorAll(".filter-button");
const grid = document.getElementById("custom-product-grid");
const sortSelect = document.getElementById("sort-select");
function filterAndSortProducts(filter) {
const boxes = Array.from(grid.querySelectorAll(".custom-product-box"));
const sortOption = sortSelect.value;
boxes.sort((a, b) => {
const aSale = parseInt(a.dataset.sale);
const bSale = parseInt(b.dataset.sale);
if (aSale && !bSale) return -1;
if (!aSale && bSale) return 1;
if (sortOption === "price-asc") {
return parseFloat(a.dataset.price) - parseFloat(b.dataset.price);
} else if (sortOption === "price-desc") {
return parseFloat(b.dataset.price) - parseFloat(a.dataset.price);
} else if (sortOption === "alpha-asc") {
return a.dataset.title.localeCompare(b.dataset.title);
}
return 0;
});
boxes.forEach(box => {
grid.appendChild(box);
const category = box.dataset.category;
if (filter === "all" || category === filter) {
box.classList.remove("hidden");
} else {
box.classList.add("hidden");
}
});
}
buttons.forEach(button => {
button.addEventListener("click", function () {
buttons.forEach(btn => btn.classList.remove("active"));
this.classList.add("active");
const filter = this.getAttribute("data-filter");
filterAndSortProducts(filter);
});
});
sortSelect.addEventListener("change", function () {
const activeFilter = document.querySelector(".filter-button.active").getAttribute("data-filter");
filterAndSortProducts(activeFilter);
});
filterAndSortProducts("all");
});
</script>
';
return $output;
}
INSTRUKCJA: Jak dodać nowe filtry i przypisać produkty
KROK 1: Wymyśl nową kategorię (filtr)
Załóżmy, że chcesz dodać nowy filtr o nazwie psychologia. Nazwa ta musi być:
- małymi literami
- bez spacji (np.
rozwoj-osobisty,sport)
KROK 2: Dodaj przycisk filtra w HTML
W kodzie odszukaj fragment z przyciskami (znajdziesz go na górze w $output .=):
<button class="filter-button" data-filter="biznes">Nazwa guzika dla pierwszego filtrowania</button>
<button class="filter-button" data-filter="diet">Nazwa guzika dla drugiego filtorwania</button>Dodaj nowy filtr tak samo:
<button class="filter-button" data-filter="psychologia">Programy psychologiczne</button>
KROK 3: Dopasuj produkty do nowego filtra
Odszukaj w kodzie ten fragment (jest w pętli foreach):
$category_class = in_array($product_id, [29906, 26598, 27310]) ? 'biznes' : 'diet';
Zamień go na coś takiego (dodaj swoją nową kategorię):
if (in_array($product_id, [29906, 26598, 27310])) {
$category_class = 'biznes';
} elseif (in_array($product_id, [15141, 30193])) {
$category_class = 'psychologia';
} else {
$category_class = 'diet';
}
Tutaj:
- Produkty o ID 15141, 30193 są przypisane do psychologia, reszta nadal będzie diet.
Dodawaj ID produktów do odpowiednich grup — możesz mieć 2, 5 albo 20 filtrów. Pamiętaj że ID produktów musisz zmienić według własnych potrzeb.
KROK 4: Gotowe! Nie musisz zmieniać nic więcej
Filtrowanie działa automatycznie, ponieważ JavaScript odczytuje atrybut data-category.
Nie musisz nic zmieniać w JS ani CSS – wszystko już działa uniwersalnie.
Co to jest $custom_titles?
To tablica w PHP (czyli coś w rodzaju listy), która pozwala Ci zamienić domyślną nazwę produktu WooCommerce na własną – tylko w tym konkretnym miejscu, gdzie używasz shortcode’a.
Jak to działa?
W normalnych warunkach nazwa produktu pobierana jest z WooCommerce funkcją:
$product->get_name();
Ale w tym kodzie mamy coś takiego:
$custom_title = $custom_titles[$product_id] ?? $product->get_name();
To oznacza:
- Jeśli w tablicy $custom_titles dla danego ID produktu znajdzie się własna nazwa – zostanie użyta.
- Jeśli nie – kod weźmie domyślną nazwę z WooCommerce.
Przykład użycia
$custom_titles = [
21733 => 'Nazwa 1',
15141 => 'Nazwa 2',
30193 => 'Nazwa 3',
4330 => 'Nowy kurs biznesowy', // Twój nowy wpis
];
Po co to jest?
Dzięki temu:
- Możesz skracać, zmieniać lub dopasowywać nazwy produktów bez zmiany w bazie WooCommerce
- Nadajesz produkty specjalne, „pakiety” lub nazwy marketingowe tylko na tej stronie.
