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.