fbpx
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.

Zobacz również: Formularz opinii WooCommerce – recenzje, lojalność, zaufanie klientów

Zostaw komentarz

Twój adres e-mail nie zostanie opublikowany. Wymagane pola są oznaczone *

Imię:


Nazwisko:


Adres email:


Nazwa Twojej firmy:


NIP Twojej firmy

REGON Twojej firmy



Adres Twojej firmy

Ulica

Kod pocztowy

Miasto

Wybierz bramkę płatniczą na Twojej stronie