Шпаргалка по WooCommerce

Шпаргалка по WooCommerce включает в себя: проверку типа страницы магазина, вывод товаров, категорий товаров, атрибутов, получение ссылок на различные страницы магазина, работа с корзиной, в том числе AJAX добавление товара в корзину и многое другое.

Установка и подготовка

Включение поддержки WooCommerce в вашей теме

functions.php

// Подключение WooCommerce
if (class_exists("WooCommerce")) {
    require get_template_directory() . "/functions/woocommerce.php";
}

/functions/woocommerce.php

function theme_name_woocommerce_setup()
{
    add_theme_support(
        "woocommerce",
        array(
            "thumbnail_image_width" => 150,   // размер thumbnail
            "single_image_width"    => 300,   // размер изображений товара
            "product_grid"          => array( // параметры вывода товаров на страницах архивов
                "default_rows"      => 3,
                "min_rows"          => 1,
                "default_columns"   => 4,
                "min_columns"       => 1,
                "max_columns"       => 6,
            ),
        )
    );
    add_theme_support("wc-product-gallery-zoom");     # Увеличение изображений
    add_theme_support("wc-product-gallery-lightbox"); # Модальные окна
    add_theme_support("wc-product-gallery-slider");   # Слайдер изображений
}
add_action("after_setup_theme", "theme_name_woocommerce_setup");

Отключение стандартных стилей WooCommerce

/functions/woocommerce.php

// Отключение стилей WooCommerce по умолчанию
add_filter("woocommerce_enqueue_styles", "__return_empty_array");

Подключение стилей и скриптов только на страницах магазина.

Отключим стили и скрипты с помощью wp_dequeue_script() на всех страницах, кроме страниц магазина.

/functions/woocommerce.php

// Подключение стилей и скриптов только на страницах магазина
add_action("wp_enqueue_scripts", "wc_styles_scripts", 99);
function wc_styles_scripts()
{
    if (function_exists("is_woocommerce")) {
        if (!is_woocommerce() && !is_cart() && !is_checkout() && !is_account_page()) {

            wp_dequeue_style("woocommerce-layout");
            wp_dequeue_style("woocommerce-smallscreen");
            wp_dequeue_style("woocommerce-general");
            wp_dequeue_style("evolution-woostyles");

            wp_dequeue_script("wc_price_slider");
            wp_dequeue_script("wc-single-product");
            wp_dequeue_script("wc-add-to-cart");
            wp_dequeue_script("wc-cart-fragments");
            wp_dequeue_script("wc-checkout");
            wp_dequeue_script("wc-add-to-cart-variation");
            wp_dequeue_script("wc-single-product");
            wp_dequeue_script("wc-cart");
            wp_dequeue_script("wc-chosen");
            wp_dequeue_script("woocommerce");
            wp_dequeue_script("prettyPhoto");
            wp_dequeue_script("prettyPhoto-init");
            wp_dequeue_script("jquery-blockui");
            wp_dequeue_script("jquery-placeholder");
            wp_dequeue_script("fancybox");
            wp_dequeue_script("jqueryui");
        }
    }
}

Проверка типа страницы WooCommerce

if (is_woocommerce() && (is_single() || is_page())) {
    # Товар
}

if (is_tax("product_cat")) {
    # Категория / Подкатегория
}

if (is_tax("product_tag")) {
    # Метка
}

if (is_account_page()) {
    # Личный кабинет
}

if (is_cart()) {
    # Корзина
}

if (is_checkout()) {
    # Оформление заказа
}

Подключение нужного шаблона в зависимости от типа страницы

В корне темы создайте файл woocommerce.php и добавьте следующий код.

<?php
if (is_single() || is_page()) { # Товар

    get_template_part("");

} elseif (is_tax()) {

    if (is_tax("product_cat")) { # Категория / Подкатегория

        get_template_part("");

    } elseif (is_tax("product_tag")) { # Метка

        get_template_part("");

    } else { # Другие таксономии

        woocommerce_content();
    }

} else { # Каталог товаров

    get_template_part("");
}

Каталог / Магазин / Shop

Тип записи: page

Ссылка на магазин WooCommerce

У вас должна быть выбрана страница магазина в настройках:
WooCommerce/Настройки/Товары/Страница Магазина.

$shop_page_url = get_permalink(wc_get_page_id("shop"));

Категории товаров

Таксономия: product_cat

Вывод заголовка текущей категории

single_term_title(); # вывод заголовка

$category_title = single_term_title("", 0); # получение заголовка

Вывод описания категории

$cat_id = get_queried_object()->term_id; # получаем id текущей категории
$prod_term = get_term($cat_id, "product_cat");
echo $description = $prod_term->description;

Ограничение количества слов описания категории

// ограничение количества выводимых слов в описании категории "woocommerce_template_single_excerpt"
add_filter("woocommerce_short_description", "limit_category_description", 10, 1);
function limit_category_description($post_excerpt)
{
    if (!is_product()) {
        $pieces = explode(" ", $post_excerpt);
        $post_excerpt = implode(" ", array_splice($pieces, 0, 35));
    }
    return $post_excerpt;
}

Получение ID текущей категории

$cat_id = get_queried_object()->term_id; // получаем id текущей категории

Получение ID категорий у текущего товара

$categories = get_the_terms($post->ID, "product_cat"); # получаем категории текущего товара

foreach ($categories as $category) {
    $cat_ids = $category->term_id; # товар может находиться в нескольких категориях
}

Вывод списка (заголовки) категорий

По умолчанию список категорий текущего товара выводится через запятую.

echo wc_get_product_category_list($product->get_id()); # вывод категорий товара

Вывод категорий в цикле WordPress

Выведем ссылку на категорию, изображение категории и заголовок (название категории).

<?php
$args = array(
    "taxonomy" => "product_cat", # таксономия - категории товаров
    "exclude" => "21, 22",       # исключаем категории с id = 21, 22
);

$product_categories = get_terms($args);

foreach ($product_categories as $product_category) {
    $thumbnail_id = get_term_meta($product_category->term_id, "thumbnail_id", true); # для вывода изображений
    ?>

    <a href="<?php echo get_term_link($product_category) ?>">
        <img src="<?php echo wp_get_attachment_url($thumbnail_id); ?>" alt="<?php the_title(); ?>">
        <h3><?php echo $product_category->name; ?></h3>
    </a>

<?php } ?>

Убрать количество товара в категории

# Удаляем количество (count) товара в категории
add_filter("woocommerce_subcategory_count_html", "remove_count");

function remove_count()
{
    $html = "";
    return $html;
}

Товар / Product

Тип записи: product

Не забываем про global $product; где это необходимо.

Получить ID товара

echo $product->get_id();

Цена товара

echo $product->get_price();

Краткое описание товара (Product short description)

echo apply_filters("woocommerce_short_description", $post->post_excerpt);

Длина описания товара (Product short description length)

/**
 * Ограничение длины краткого описания товара
 */
add_filter("woocommerce_short_description", "prefix_filter_woocommerce_short_description");
function prefix_filter_woocommerce_short_description($post_post_excerpt)
{
    if (!is_product()) {
        $text = $post_post_excerpt;
        $words = 25; // количество слов
        $more = " …"; // завершающие символы

        $post_post_excerpt = wp_trim_words($text, $words, $more);
    }
    return $post_post_excerpt;
};

Вывод главного изображения товара

$product_image_url = get_the_post_thumbnail_url($product->get_id(), "large");
echo $product_image_url;

Или

$product_image = wp_get_attachment_image_src(get_post_thumbnail_id(), "medium");
echo $product_image[0];

Ссылка на плэйсхолдер изображение.

echo wc_placeholder_img_src();

Вывод галереи товаров

<?php // Вывод галереи товаров
$attachment_ids = $product->get_gallery_image_ids(); # Получаем id изображений

foreach ($attachment_ids as $attachment_id) {
    if ($attachment_id) { ?>

        <?php
        // Вывод URL изображений галереи - размеры изображений WordPress
        echo wp_get_attachment_image_src( $attachment_id, "thumbnail" )[0];
        echo wp_get_attachment_image_src( $attachment_id, "medium" )[0];
        echo wp_get_attachment_image_src( $attachment_id, "full" )[0];

        // Вывод URL изображений галереи - размеры изображений WooCommerce
        echo $shop_thumbnail_image_url = wp_get_attachment_image_src( $attachment_id, "shop_thumbnail" )[0];
        echo $shop_catalog_image_url = wp_get_attachment_image_src( $attachment_id, "shop_catalog" )[0];
        echo $shop_single_image_url = wp_get_attachment_image_src( $attachment_id, "shop_single" )[0];

        // Вывод изображения (img)
        echo wp_get_attachment_image($attachment_id, "thumbnail");
        echo wp_get_attachment_image($attachment_id, "medium");
        echo wp_get_attachment_image($attachment_id, "full");
        echo wp_get_attachment_image($attachment_id, "shop_thumbnail");
        echo wp_get_attachment_image($attachment_id, "shop_catalog");
        echo wp_get_attachment_image($attachment_id, "shop_single");
        ?>

    <?php } ?>
<?php } ?>

Изменение размеров миниатюр в WooCommerce

functions.php

add_filter("woocommerce_get_image_size_thumbnail", "add_thumbnail_size", 1, 10);
function add_thumbnail_size($size)
{
    $size["width"]  = 420;
    $size["height"] = 190;
    $size["crop"]   = 1; # 0 - не обрезаем, 1 - обрезка
    return $size;
}

Проверка наличия атрибутов

if ($product->get_attributes()) {

}

Вывод атрибутов

wc_display_product_attributes($product);

Вариации WooCommerce

Получаем вариации товара, если они есть.

<?php // Получаем вариации, если они есть у товара
if ($product->is_type("variable")) { # вариативный товар ?>

<?php } else { # НЕ вариативный товар ?>

} ?>

События для формы вариаций товара

Пример замены изображения товара при выборе вариации.

$(".variations_form").on("woocommerce_variation_select_change", function() {    // выполнение скрипта после загрузки вариации
    $(".variations_form").on("show_variation", function(event, variation) {     // выполнение скрипта после выбора вариации
        console.log(variation);                                                 // возвращает Woocommerce product object
        const current_image_link = variation.image.full_src;                    // получаем ссылку на изображение (полное)
        $(".swiper-container.gallery-top img").attr("src", current_image_link); // замена изображения
    });
});

Вывод артикула (SKU)

echo $product->get_sku();

Вывод товаров в цикле WordPress

<?php
$mypost_Query = new WP_Query(array(
    "post_type"        => "product",
    "post_status"      => "publish",
    "posts_per_page"   => 8,
));

if ($mypost_Query->have_posts()) {
    while ($mypost_Query->have_posts()) {
        $mypost_Query->the_post();

        get_template_part("file-tpl"); # Шаблон для отображения каждого товара

    }
} else {
    echo ("<p>Извините, нет товаров.</p>");
}
wp_reset_postdata();
?>

Вывод товаров из текущей категории

$cat_id = get_queried_object()->term_id; # Получаем id текущей категории

$mypost_Query = new WP_Query(array(
    "post_type"      => "product",
    "post_status"    => "publish",
    "posts_per_page" => -1,        // кол-во записей
    "tax_query"     => array(
        array(
            "taxonomy"  => "product_cat", // таксономия
            "field"     => "id",          // тип поля (slug или id)
            "terms"     => $cat_id        // ярлык (slug) или id
        )
    )
));

Исключить товары определённых категорий

Исключаем товары категорий с id = 21, 22

$mypost_Query = new WP_Query(array(
    "post_type"        => "product",         # post, page, custom_post_type
    "post_status"      => "publish",         # статус записи
    "posts_per_page"   => 8,                 # кол-во постов вывода/загрузки
    "tax_query" => array(
        array(
            "taxonomy" => "product_cat",     # таксономия «Категории товаров»
            "field"    => "id",              # slug/id
            "terms"    => array("21", "22"), # термины (ярлык/id)
            "operator" => "NOT IN",
        )
    ),
));

Выбор количества товара (quantity input)

Изменить шаблон отображения данного input, можно скопировав в папку с темой следующий файл
woocommerce/templates/global/quantity-input.php:

woocommerce_quantity_input();

Сортировка товаров WooCommerce

Вывод сортировки товаров по умолчанию.

<?php woocommerce_catalog_ordering(); # дефолтная сортировка ?>

Получение сортировки в GET-параметрах и использование в WP_Query.

<?php
if (isset($_GET["orderby"])) { # Если выбрана сортировка пользователем

    if ($_GET["orderby"] == "popularity") { # По популярности
        $orderby = "popularity";
        $orderby_meta_key = "";
        $order = "ASC";
    } else if ($_GET["orderby"] == "price") { # С низкой до высокой
        $orderby = "meta_value_num";
        $orderby_meta_key = "_regular_price";
        $order = "ASC";
    } else if ($_GET["orderby"] == "price-desc") { # С высокой до низкой
        $orderby = "meta_value_num";
        $orderby_meta_key = "_regular_price";
        $order = "DESC";
    } else if ($_GET["orderby"] == "date") { # По дате
        $orderby = "date";
        $orderby_meta_key = "";
        $order = "DESC";
    } else if ($_GET["orderby"] == "menu_order") { # По умолчанию
        $orderby = "menu_order";
        $orderby_meta_key = "";
        $order = "ASC";
    }
} else { # По умолчанию (не выбрана сортировка)
    $orderby = "menu_order";
    $orderby_meta_key = "";
    $order = "ASC";
}

// для WP QUERY

"orderby" => $orderby,
"meta_key" => $orderby_meta_key,
"order" => $order,

Корзина / Cart

Тип записи: page

Вывод корзины через шорткод.

[woocommerce_cart]

Вывод количества товаров (в корзине WooCommerce)

global $woocommerce;

echo WC()->cart->get_cart_contents_count(); # вывод кол-ва товаров

Ссылка на корзину WooCommerce

echo esc_url(wc_get_cart_url());

Добавить товар в корзину

Ссылка для добавления товара в корзину WooCommerce.

<a href="/cart/?add-to-cart=<?php the_ID(); ?>">Добавить в корзину</a>

Шаблоны вывода кнопки добавления в корзину

/woocommerce/single-product/add-to-cart/simple.php

<?php woocommerce_simple_add_to_cart(); ?>

/woocommerce/single-product/add-to-cart/variable.php

<?php woocommerce_variable_add_to_cart(); ?>

/woocommerce/single-product/add-to-cart/variation-add-to-cart-button.php

<?php woocommerce_single_variation_add_to_cart_button(); ?>

Ajax Кнопка добавления в корзину.

<?php woocommerce_template_loop_add_to_cart(); ?>

Корзина + счётчик товаров AJAX

functions.php

// Корзина + AJAX счётчик товаров
add_filter("woocommerce_add_to_cart_fragments", "header_add_to_cart_fragment");
function header_add_to_cart_fragment($fragments)
{
    global $woocommerce;
    ob_start();
?>
    <div class="cart-icon__count"><?php echo sprintf($woocommerce->cart->cart_contents_count); ?></div>
<?php
    $fragments[".cart-icon__count"] = ob_get_clean();
    return $fragments;
}

header.php

<div class="cart-icon__count">
    <?php
    global $woocommerce;
    echo sprintf($woocommerce->cart->cart_contents_count);
    ?>
</div>

AJAX добавление товара в корзину

template.php

<form class="cart" action="<?php echo esc_url($product->add_to_cart_url()); ?>" method="post" enctype="multipart/form-data">
    <?php woocommerce_quantity_input(); ?>
    <button class="add_to_cart_btn" data-id="<?php the_ID(); ?>" type="submit">Добавить в корзину</button>
</form>

add-to-cart.js

(function ($) {
    $(document).on("click", ".add_to_cart_btn", function (e) {
        e.preventDefault();

        let $this_btn = $(this),
            $form = $this_btn.parent("form.cart"),
            id = $this_btn.data("id"),
            product_qty = $form.find("input[name="quantity"]").val() || 1,
            product_id = $form.find("input[name="product_id"]").val() || id,
            variation_id = $form.find("input[name="variation_id"]").val() || 0;

        let data = {
            action: "woocommerce_ajax_add_to_cart",
            product_id: product_id,
            product_sku: "",
            quantity: product_qty,
            variation_id: variation_id,
        };

        $(document.body).trigger("adding_to_cart", [$this_btn, data]);

        $.ajax({
            type: "post",
            url: wc_add_to_cart_params.ajax_url,
            data: data,
            beforeSend: function (response) {
                $this_btn.removeClass("added").addClass("loading");
            },
            complete: function (response) {
                $this_btn.addClass("added").removeClass("loading");
            },
            success: function (response) {
                if (response.error & response.product_url) {
                    window.location = response.product_url;
                    return;
                } else {
                    $(document.body).trigger("added_to_cart", [response.fragments, response.cart_hash, $this_btn]);
                }

                // здесь можно добавить оповещение об успешном добавлениив корзину
            },
        });

        return false;

    });
})(jQuery);

functions.php

add_action("wp_ajax_woocommerce_ajax_add_to_cart", "woocommerce_ajax_add_to_cart");
add_action("wp_ajax_nopriv_woocommerce_ajax_add_to_cart", "woocommerce_ajax_add_to_cart");
function woocommerce_ajax_add_to_cart()
{

    $product_id = apply_filters("woocommerce_add_to_cart_product_id", absint($_POST["product_id"]));
    $quantity = empty($_POST["quantity"]) ? 1 : wc_stock_amount($_POST["quantity"]);
    $variation_id = absint($_POST["variation_id"]);
    $passed_validation = apply_filters("woocommerce_add_to_cart_validation", true, $product_id, $quantity);
    $product_status = get_post_status($product_id);

    if ($passed_validation && WC()->cart->add_to_cart($product_id, $quantity, $variation_id) && "publish" === $product_status) {

        do_action("woocommerce_ajax_added_to_cart", $product_id);

        if ("yes" === get_option("woocommerce_cart_redirect_after_add")) {
            wc_add_to_cart_message(array($product_id => $quantity), true);
        }

        WC_AJAX::get_refreshed_fragments();
    } else {

        $data = array(
            "error" => true,
            "product_url" => apply_filters("woocommerce_cart_redirect_after_error", get_permalink($product_id), $product_id)
        );

        echo wp_send_json($data);
    }

    wp_die();
}

Оформление заказа / Checkout

Тип записи: page

Вывод «Оформление заказа» через шорткод.

[woocommerce_checkout]

Личный кабинет / Account

Тип записи: page

Вывод личного кабинета через шорткод.

[woocommerce_my_account]

Ссылка на личный кабинет WooCommerce

functions.php

// Ссылка на личный кабинет WC
function account_login_out_link()
{
    if (is_user_logged_in()) { # Ссылка на ЛК
        echo "<a href=" . get_permalink(wc_get_page_id("myaccount")) . ">Аккаунт</a>";
    } elseif (!is_user_logged_in()) { # Войти в ЛК
        echo "<a href=" . get_permalink(wc_get_page_id("myaccount")) . ">Войти</a>";
    }
}

template.php

account_login_out_link();

Сортировка пунктов меню ЛК WooCommerce и их переименование

Переименуйте нужный вам пункт меню личного кабинета WooCommerce или переместите для изменения порядка.

add_filter("woocommerce_account_menu_items", "wc_change_account_list");
function wc_change_account_list()
{
    $wc_list = array(
        "dashboard"          => __("Консоль", "woocommerce"),
        "edit-account"       => __("Personal Information", "woocommerce"), // Личные данные
        "edit-address"       => __("Addresses", "woocommerce"),            // Адреса
        "payment-methods"    => __("Payment Settings", "woocommerce"),     // Метод оплаты
        "orders"             => __("Orders", "woocommerce"),               // Мои заказы
        "downloads"          => __("My Courses", "woocommerce"),           // Загрузки
        "customer-logout"    => __("Sign Out", "woocommerce"),             // Выйти
    );
    return $wc_list;
}

Как добавить новые поля в форму регистрации WooCommerce

Добавление новых полей в форму регистрации.

/**
 * Добавляем новые поля в форму регистрации WC.
 */

add_action("woocommerce_register_form_start", "theme_name_woo_reg_form_fields");
function theme_name_woo_reg_form_fields()
{
?>
    <p class="form-row form-row-first">
        <label for="billing_first_name"><?php _e("Имя", "theme_name"); ?><span class="required">*</span></label>
        <input type="text" class="input-text" name="billing_first_name" id="billing_first_name" value="<?php if (!empty($_POST["billing_first_name"])) esc_attr_e($_POST["billing_first_name"]); ?>" />
    </p>
    <p class="form-row form-row-last">
        <label for="billing_last_name"><?php _e("Фамилия", "theme_name"); ?><span class="required">*</span></label>
        <input type="text" class="input-text" name="billing_last_name" id="billing_last_name" value="<?php if (!empty($_POST["billing_last_name"])) esc_attr_e($_POST["billing_last_name"]); ?>" />
    </p>
    <div class="clear"></div>
<?php
}

Если вам не нужна проверка полей, просто удалите следующий код.

<span class="required">*</span>

Если нужна валидация полей формы.

/**
 * Проверка формы регистрации WooCommerce для новых полей.
 */

add_action("woocommerce_register_post", "theme_name_woo_validate_reg_form_fields", 10, 3);
function theme_name_woo_validate_reg_form_fields($username, $email, $validation_errors)
{
    if (isset($_POST["billing_first_name"]) && empty($_POST["billing_first_name"])) {
        $validation_errors->add("billing_first_name_error", __("<strong>Ошибка</strong>: Имя обязательно для заполнения!", "theme_name"));
    }

    if (isset($_POST["billing_last_name"]) && empty($_POST["billing_last_name"])) {
        $validation_errors->add("billing_last_name_error", __("<strong>Ошибка</strong>: Фамилия обязательна для заполнения!", "theme_name"));
    }
    return $validation_errors;
}

Теперь сохраним новые поля.

/**
 * Сохранение новых полей формы регистрации WooCommerce.
 */

add_action("woocommerce_created_customer", "theme_name_woo_save_reg_form_fields");
function theme_name_woo_save_reg_form_fields($customer_id)
{
    // Сохраняем поле «Имя»
    if (isset($_POST["billing_first_name"])) {
        update_user_meta($customer_id, "first_name", sanitize_text_field($_POST["billing_first_name"]));
        update_user_meta($customer_id, "billing_first_name", sanitize_text_field($_POST["billing_first_name"]));
    }
    // Сохраняем «Фамилия»
    if (isset($_POST["billing_last_name"])) {
        update_user_meta($customer_id, "last_name", sanitize_text_field($_POST["billing_last_name"]));
        update_user_meta($customer_id, "billing_last_name", sanitize_text_field($_POST["billing_last_name"]));
    }
}

Сопутствующие плюшки: