Как удалить вкладку справки в панели управления WordPress?

Вкладка Помощь

Добавьте этот код на ваш сайт:

/**
 * Remove Help Tabs
 */
add_action( 'admin_head', function () {
		$screen = get_current_screen();

		// Remove all tabs
		$screen->remove_help_tabs();

	}
);

Как добавить цель «JavaScript-событие» на кнопку «Добавить в корзину» в WooCommerce?

Дано: Интернет магазин под управлением WordPress + WooCommerce.

Задача: Отследить успешное добавление товара в корзину пользователем и передать эту информацию для аналитики в Яндекс Метрику.

Решение: решить подобную задачу можно разными способами: на стороне клиента, исключительно за счёт JavaScript и на стороне сервера — на PHP.

Требования к сайту

При создании цели важно учитывать:

  • Форма должна быть создана с помощью тега form. Если форма сделана через теги div, она отслеживаться не будет.
  • Отправка формы должна выполняться через элементы button type=»submit» и input type=»submit». Если отправка реализована через элемент button type=»button», цель достигаться не будет.
  • Элементы button type=»submit» и input type=»submit» должны находиться внутри элемента form.

Если форма обрабатывается с помощью JavaScript, цель будет работать только для стандартного события onSubmit.

https://yandex.ru/support/metrica/simple-goal/form.html

Так как вёрстка в разных шаблонах оформления может быть разная, то своё решение мы начнём с исследования нашей кнопки в объектной модели документа (DOM), для того что бы понять удовлетворяет ли наш сайт описанным условиям.

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

Мы видим элемент кнопки (button) и наличие атрибутов, которые могут помочь «зацепиться» за этот элемент и «повешать» на него нужное нам событие. Также наша кнопка находится в теге <form> , что говорит о соответствии условиям описанных в документации Яндекс Метрики.

Забегая вперёд отмечу, что для точности передачи данных лучше вешать это событие на отправку формы, а не на клик по кнопки (хотя для некоторых задач подойдет именно клик, например, когда вы хотите просто проверить интерес к чему либо, к новому разделу на сайте).

Пример того, как делать не стоит!

<form action="" method="POST" type="submit">

    <input name="name" placeholder="Ваше имя" required> <br>

    <input type="email" name="mail" placeholder="Ваш email" required> <br>

    <input type="button" onclick="yaCounterXXXXXX.reachGoal('form2'); return=true;" value="Отправить">

</form>

В этом случае в Метрику будет отправлена информация по всем кликам, совершенным по кнопке “Отправить” — даже если посетитель не заполнил форму.

https://yandex.ru/blog/metrika-club/kak-pravilno-nastroit-reachgoal-v-formakh

Добавление цели в Яндекс Метрики

Первым делом, нам нужно создать цель в личном кабинете Яндекс Метрики:

1. добавляем цель

Выбираем JavaScript-событие и присваиваем этому событию уникальное имя для дальнейшего отслеживания. В примере ниже, мы можем наблюдать, как после создания идентификатора цели ниже, мы можем наблюдать готовую строку кода, который необходимо будет вызвать на наше событие:

2. Выбираем JavaScript-событие

Готово! Часть задачи мы выполнили. В личном кабинете Яндекс Метрики создана наша цель:

цель события добавления в корзину

Решение на JavaScript

Теперь, мы можем смело приступать к дальнейшей реализации на стороне сайта.

В качестве селектора (выбираемого из DOM элемента) у нас выступает тег form с классом «cart». Наш скрипт может выглядеть примерно так:

Вариант №1

document.addEventListener("DOMContentLoaded", (event) => {
    const cartForm = document.querySelector("form.cart");

    if(cartForm){
        cartForm.addEventListener('submit', function () {
            ym(XXXXXX, 'reachGoal', 'TARGET_NAME');
        });
    }
});
  • XXXXXX — номер вашего счетчика.
  • TARGET_NAME — идентификатор цели.

Пояснение: мы получили наш элемент формы и наблюдем через подписку на событие submit за её успешной отправкой (добавление в корзину — это и есть в нашем случае отправка формы)

Вариант №2

...
<form action="" method="get" onsubmit="ym(XXXXXX, 'reachGoal', 'TARGET_NAME'); return true;">
    ...
</form>
...

Если приглядеться к примеру указанному на сайте Яндекс Метрике, то мы можем заметить, что можем разместить вызов функции Яндекс Метрики (ym) прописав его в атрибут onsubmit нашей формы добавления товара в корзину.

В этом случае наш код немного изменится:

document.addEventListener("DOMContentLoaded", (event) => {
    const cartForm = document.querySelector("form.cart");

    if(cartForm){
        cartForm.setAttribute("onclick", "ym(XXXXXX, 'reachGoal', 'TARGET_NAME'); return true;");
    }
});
  • XXXXXX — номер вашего счетчика.
  • TARGET_NAME — идентификатор цели.

Ну вот и всё!

Если вы всё сделали правильно, то при исследовании элемента непременно должны увидеть добавленный атрибут (справедливо для варианта №2)

добавлен атрибут к тегу form

Теперь в Яндекс Метрике, в разделе Конверсии, мы можем ожидать результат её выполнения:

Конверсии

Вот так выглядит выполнение скрипта (цель отработала):

Цель отработала

Обращу внимание, что можно было воспользоваться методом автоматического добавления цели «Отправка формы»:

автоматическое добавления цели

В этом случае событие отправки будет распознано автоматически и после статистики нашей конкретной цели, ниже мы можем наблюдать фиксацию автоматической.

автоматическая цель

На этом всё! Парам-Парам-Пам!

Как установить минимальную сумму корзины для заказа в Woo?

Задача: ограничить возможность заказа пользователя определённой суммой товаров в корзине.

То есть, пока клиент нашего интернет-магазина не добавит товаров на нужную сумму в корзину заказ будет невозможен. Вот так это выглядит в виде уведомления на странице корзины:

уведомление из корзины

Уведомление также будет выводиться и в момент обработки данных непосредственно на страницы заказа и не позволять ему состояться пока условие не будет удовлетворено.

уведомление на странице оформления заказа

Решение: просто добавьте этот php-сниппет и укажите в виде числового значения минимальную сумму для осуществления заказа:

/**
 * Set a minimum order amount for checkout
 */
add_action('woocommerce_checkout_process', 'wc_minimum_order_amount');
add_action('woocommerce_before_cart', 'wc_minimum_order_amount');

function wc_minimum_order_amount()
{
    // Установите цифру минимального значения для осуществления заказа
    $minimum = 100;

    if (WC()->cart->total < $minimum) {

        if (is_cart()) {

            wc_print_notice(
                sprintf('Ваша сумма заказа %s — вы должны дополнить до минимума в %s чтобы оформить заказ.',
                    wc_price(WC()->cart->total),
                    wc_price($minimum)
                ), 'error'
            );

        } else {

            wc_add_notice(
                sprintf('Ваша сумма заказа %s — вы должны дополнить до минимума в %s чтобы оформить заказ.',
                    wc_price(WC()->cart->total),
                    wc_price($minimum)
                ), 'error'
            );

        }
    }
}

Источник сниппета «Minimum Order Amount»

Как сделать кнопку (ссылку) «вернуться назад» в WordPress?

Задача: при нажатии на эту кнопочку возвращать пользователя на предыдущую страницу.

Реализация на JavaScript

За отрисовку кнопки, как элемента HTML, отвечает эта строка:

<button id="go-back">Вернуться назад</button>

Единственное, если быть точными и делать всю реализацию на JavaScript, получается по доброму этот элемент нужно создавать тоже при помощи скрипта. Выглядеть это может примерно так:

const button = document.createElement("button");
button.setAttribute("id", "go-back");
button.innerText = "Вернуться назад";
button.type = "submit";
document.body.appendChild(button);

А за функционал на стороне клиента вот этот сниппет на JavaScript, который прослушивает событие клика по элементу с идентификатором «go-back» и вызывает на это событие метод back() принадлежащий интерфейсу History, который предписывает браузеру вернуться на одну страницу назад в истории сеанса.

document.getElementById("go-back").addEventListener("click", () => {
  history.back();
});

Посмотреть код в действии можно тут.

@TODO По доброму ещё можно сделать проверку на существование значения «реффера» и принадлежности к текущему домену.

Мы рассмотрели механизм решения данной задачи на стороне клиента (браузера) при помощи JavaScript. Теперь давайте рассмотрим вариант на стороне сервера, при помощи PHP:

Реализация на PHP

В контексте WordPress, на стороне сервера подобное можно реализовать при помощи функции WP из ядра, которая является обёрткой других функций.

wp_get_referer()

Ознакомиться с функцией можно тут

Под капотом функции у нас происходит проверка на принадлежность URL к текущему домену сайта, возвращает строку или в противном случае булев тип false

Реализацию кода выше на стороне сервера можно представить вот в таком виде:

<?php
$return_url = wp_get_referer();

if ($return_url) { ?>
    <a class="button" href="<?php echo esc_url($return_url); ?>">Вернуться назад</a>
<?php }

Начинающих пользователей могут смутить открывающие и закрывающие теги PHP, часто в этом допускают синтаксическую ошибку. Ниже привожу пример где я вывел обработку (функцию отчистки) URL из атрибута href, тем самым позволив исключить теги PHP:

// получаем реферальную ссылку
$return_url = wp_get_referer();

// если не false продолжаем ...
if ($return_url) {
    // обработка УРЛ (подготовка)
    $url = esc_url($return_url);

    // вывод
    echo"<a class='button' href='{$url}'>Вернуться назад</a>";
}

P.S. тоже «не сахар» вариант 🙂 Будьте внимательнее с кавычками. Чтобы в строке языковой конструкции echo у нас выводилась переменная с нашим УРЛ, необходимо убедиться что сама строка в двойных кавычках, а атрибуты элемента ссылки в одиночных!

Небольшим преимуществом серверного метода можно считать тот факт, что если у клиента будет выключен в браузере JavaScript или возникнут ошибки которые не дадут отработать первому решению (на JS), то наша кнопка всё равно окажется в DOM так как приходит с сервера, а не формируется на стороне клиента.

Как в WooCommerce отобразить SKU вариаций в панели управления (админке)?

Чтобы в ячейке для SKU, в панели администрирования WordPress, отображать все артикулы вариаций у вариативных товаров достаточно добавить данный сниппет:

/**
 * @snippet       Display Variation SKUs @ WooCommerce Product Admin
 * @author        Code==Poetry
 */
  
add_filter( 'woocommerce_product_get_sku', 'poet_variable_product_skus_admin', 9999, 2 );
 
function poet_variable_product_skus_admin( $sku, $product ) {
   if ( ! is_admin() ) return $sku;
   global $post_type, $pagenow;
   if ( 'edit.php' === $pagenow && 'product' === $post_type ) {
      if ( $product->is_type('variable') ) {
         $sku = ''; // $sku = $product->get_sku();
         foreach ( $product->get_children() as $child_id ) {
            $variation = wc_get_product( $child_id ); 
            if ( $variation && $variation->exists() ) $sku .= '(' . $variation->get_sku() . ')';
         }
      }
   }
   return $sku;
}

Как отобразить вместо пустой цены или «нуля» слово «БЕСПЛАТНО» в WooCommerce?

Задача: Когда цена товара не указана или её значение равно 0 (нулю), то в этом случае выводить слово «БЕСПЛАТНО».

Товар с ценой 0
Было/Стало

Начнём наше решение мы как всегда с исследования. Проинспектируем наш элемент в котором выводится значение цены

Далее, поиском по файлам по директории плагина WooCommerce нам необходимо отыскать «темплэйт» который отвечает за вывод цены. Я его нашёл — price.php

Нас интересует метод (функция) get_price_html(), и следующим шагом мы отыщем её также по директории плагина. Вот так она выглядит:

Нас интересуют два её хука. Это хук-фильтр ‘woocommerce_empty_price_html’ и хук-фильтр ‘woocommerce_get_price_html’. Сама функция возвращает тип данных — строка, это важно отметить.

Как мы видим, первый фильтр нам поможет изменить возвращаемое значение в том случае если цена у товара не указана и оформить нашу функцию можно следующим образом:

add_filter('woocommerce_empty_price_html', function ($string) {

    $string = '<span>Бесплатно</span>';

    return $string;

}, 100, 1);

Если обратить внимание на исходный код метода get_price_html() класса WC_Product, то можно заметить, что строгая проверка там уже стоит на пустую строку. Поэтому в фильтр мы передаём один аргумент, я его назвал $string и присвоил ему новое значение и тут же вернул (это важно! При использовании хуков-фильтров всегда возвращать, то что передали). Цифры после анонимной функции говоря об очерёдности выполнения (так как на этот фильтр может ещё кто-то, например, разработчики стороннего плагина, прикрепить свои функции) и вторая цифра — это число аргументов для передачи. В следующем примере их будет уже два 🙂

Теперь в случае, если цена не указана, будет выводиться слово — Бесплатно

Теперь рассмотрим второй хук, который поможет нам решить задачу во втором случае — когда цена указана значением равным нулю.

Если взглянуть исходный код метода, то можно обнаружить вот такую запись возврата функцией (методом) данных

return apply_filters( 'woocommerce_get_price_html', $price, $this );

Итоговый код будет выглядеть вот так. Сейчас я поясню. С первым аргументом $price думаю всё понятно — это возвращаемая строка цены, а вот второй $this — это объект товара — экземпляр класса которому принадлежит метод, соответственно мне нужно указать его в виде $product — объект товара, который доступен в глобальной зоне видимости (global $product). Немного может показаться это сложным для понимания, но со временем и практикой ясность придёт.

Вобщем, передав вторым аргументом $product, наш фильтр будет обладать данными из этого объекта, а соответственно нам будет доступен метод получения цены. Если взглянуть на исходный код метода, то можно встретить в нём ещё один нужный нам метод получения цены $this->get_price()

Вот итоговый код. Единственное, я понизил строгость проверки 0 == $product->get_price(), так как возвращается строка, а мы сравниваем с типом число и это уже не будет удовлетворять условию и указал последней цифрой после функции передаваемое число аргументов — 2. Так как второй аргумент (объект $product) нам нужен для проверки значения цены равное нулю.

add_filter('woocommerce_get_price_html', function ($price, $product) {

    if (0 == $product->get_price()) { // return string!
        $price = '<span>Бесплатно</span>';
    }

    return $price;
}, 100, 2);

Теперь, если значение цены указано, как ноль, то получим вывод слова «бесплатно»:

Учтите, это справедливо и для случая если в качестве акционной цены проставлен «ноль»

0

Мы так же получим вывод слова «бесплатно».

Обратите внимание, что я возвращаю наше слово в тегах для строчного элемента <span> А это значит, что указав тегу атрибут класса, мы можем менять через CSS стиль отображения данного слова.

Как удалить верхнюю панель в админке у WooCommerce?

Если вам, как и мне, порядком надоела верхняя панель в панели администратора сайта у WooCommerce, то предлагаю с ней распрощаться!

Как я понял, кроме дублирующего заголовка текущего экрана (страницы) и нескольких неважных функций эта панель ничего существенного в себе не содержит. Так зачем занимать дорогую часть экрана?! Долой! 🙂

Удаляем верхнюю панель WooCommerce
<?php
/**
 * Удаляем служебный верхнюю панель WooCommerce в панели управления WordPress.
 *
 * @see https://woocommerce.github.io/code-reference/classes/Automattic-WooCommerce-Admin-Loader.html
 * @author Code==Poetry <codeispoetry@mail.ru>
 */
add_action( 'admin_head', function (){
    remove_action( 'in_admin_header', array( 'Automattic\WooCommerce\Internal\Admin\Loader', 'embed_page_header' ) );
    print '<style>#wpadminbar + #wpbody { margin-top:0; }</style>';
});

Шаг за шагом

Исследуем элемент этой верхней части (header)

Исследуем элемент этой верхней части

Видим идентификатор, за которой и можно зацепиться. Переходим в директорию с плагином WooCommerce и ищем пофайловым поиском соответствие. Находим его в файле класса Loader:

Loader Class

Этот элемент находится в методе embed_page_header(), который вызывается 1 раз. Исследуем файл и обнаруживаем его в конструкторе класса:

конструктор класса лоадер

Далее нам необходимо удалить этот, который закреплен за хуком in_admin_header. При помощи функции remove_action удалим этот метод. Вместо __CLASS__ необходимо указать пространство имён + название класса:

Получаем:

remove_action( 'in_admin_header', array( 'Automattic\WooCommerce\Internal\Admin\Loader', 'embed_page_header' ) );

P.S. Вполне возможно пространство имён в новых версиях может измениться, но принцип я думаю ясен.

Далее, «вешаем» этот «экшен» на событие происходящее только в верхней части панели администратора.

add_action( 'admin_head', function (){

    remove_action( 'in_admin_header', array( 'Automattic\WooCommerce\Internal\Admin\Loader', 'embed_page_header' ) );

});

И это даёт уже результат! Правда с небольшим нюансом.

Панель удалилась, но осталось пространство, которое явно нам ни к чему. Инспектируем эту область и находим нужное нам правило, которое и создаёт этот отступ:

Дополним наш код строчкой, которая при помощи языковой конструкции print выведет строчку дополнительного стиля, в котором благодаря новому правилу мы избавляемся от отступа.

Как правильно добавить PHP-код на страницу WordPress?

Однажды, перед пользователями CMS WordPress встаёт задача добавить на свой сайт скрипт (код) PHP, чтобы привнести или изменить функционал сайта. Сделать это можно разными способами, но мы рассмотрим сначала самый безопасный (при помощи плагина и его графического интерфейса), а затем еще пару вариантов, которые тоже можно взять на вооружение.

Плагин Code Snippets

Для начинающих пользователей я рекомендую добавлять сторонний код при помощи именно этого плагина, ну или похожих аналогов, например, WPCode

Начнём пошагово:

  1. Перейдите в раздел Плагины
Раздел меню Плагины
  1. В разделе Плагины, при помощи поискового запроса «Code Snippets» отыщите нужный нам плагин
  1. Установите нужный плагин

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

  1. Активируйте плагин

После его активации в разделе меню появится его ссылка

  1. Перейдите в раздел Сниппеты
Перейдите в раздел Сниппеты

На первый взгляд рабочий экран программы может напугать начинающего пользователя, но на самом деле лишнего в нём ничего нет.

Подробно ознакомиться с плагином можно в этом видео:

Ну а мы продолжим и добавить произвольный PHP-код.

  1. Выберите Добавить Новый
Выберите Добавить Новый

Перед нами появится экран добавления нового сниппета.

  1. Дайте осмысленное название, о том что будет делать добавленный код
экран добавления нового сниппета
  1. Добавьте PHP-код.

Обратите внимание, что открывающийся тег PHP <?php уже присутствует в области и его добавлять не нужно.

Добавьте PHP-код
  1. Выберите часть сайта (приватная — панель администратора, публичная — то что видят все в интернете)

Так как мой скрипт должен удалять логотип WordPress в панели управления сайтом, я выбираю Only run in administration area

Если сомневаетесь, то оставляйте первый вариант Run snippet everywhere — это позволит скрипту выполняться по всему сайту, как по приватной его части, так и по публичной

При желании можете дать подробное описание назначения этого PHP-кода и отметить специальными тегами, например, такими, которые будут говорить куда предназначен скрипт:

  1. Активируйте и сохраните ваш добавленный код

Если вы всё сделали правильно и не произошло ошибки, то в разделе всех сниппетов вы непременно должны увидеть ваш добавленный скрипт. Кстати, в любой момент его можно отключить 🙂

Ошибки

Преимущество данного метода в том, что он оберегает вас от ошибок и если вы, например, забыли где то поставить кавычку (а скорее всего просто не скопировали её), то сайт «не поломается». В этом случае сниппет просто не активируется и выдаст предупреждение:

Ошибка при обработке

В данном случае мы получили сообщение о синтаксической ошибке.

Добавление через код

Этот метод не безопасный (для новичков), но делает процесс прозрачным и в сравнении с плагином, конечно же менее ресурсоёмким, так как плагины занимают больше вычислительных мощностей, чем простое добавление функций в файл.

Плагин Theme Customisations

Если заглянуть в файл functions.php известной, простой темы для интернет-магазина на WordPress — Storefront, то можно обнаружить примечание от разработчиков:

Note: Do not add any custom code here. Please use a custom plugin so that your customizations aren’t lost during updates.

https://github.com/woocommerce/theme-customisations

https://github.com/woocommerce/storefront/blob/trunk/functions.php

В этом сообщении нас призывают не добавлять код в functions.php, а воспользоваться для этого решением в виде плагина.

Плагин «Theme Customisations» можно скачать из репозитория на GitHub

Плагин "Theme Customisations"

После загрузки плагина, его необходимо установить в наш WordPress. Сделать это можно при помощи метода Загрузки

Загрузить плагин

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

Как же тогда работать с плагином? Отвечу — напрямую редактируя код. Попасть в специальный для этих целей раздел можно в меню Инструменты:

Увидеть этот раздел можно под учётной записью администратора. И при первом его посещении WordPress любезно вас предупредит:

Приняв риски, в правом верхнем углу нам нужно выбрать в выпадающем списке наш плагин. После чего нам будут доступны его исходные файлы:

исходные файлы

Нас интересует директория custom.

Соответственно, в каждый из файлов мы можем добавлять свой произвольный код:

  • CSS — в style.css
  • JavaScript — в custom.js
  • PHP — functions.php

Вот, например, сниппет, который удаляет логотип WordPress при входе в панель управления. Давайте добавим его в наш файл functions.php

Вот и всё 🙂

Как удалить версию WordPress внизу в панели администратора?

Чтобы удалить вывод версии WordPress в нижней части (футер) панели управления администратора сайта, нужно задействовать специальный фильтр:

apply_filters ('update_footer', строка $content  )

К данному фильтру прикреплена функция core_update_footer() с приоритетом (очерёдностью) выполнения 10. Это означает, что нам для того чтобы изменить это значение, необходимо выполнить функцию позже, то есть задать очерёдность выше 10, например, 15

<?php
/**
 * Удаляет версию WordPress из Футера панели администратора.
 *
 * @see https://developer.wordpress.org/reference/hooks/update_footer/ Documentation WordPress.
 * @author Code==Poetry <codeispoetry@mail.ru>
 */
 
add_filter( 'update_footer', '__return_empty_string', 15 );

Как удалить или изменить фразу Спасибо вам за творчество с WordPress?

Если взглянуть в ядро WordPress на исходный код, то можно обнаружить для решения нашей задачи специально предусмотренный фильтр (48-я строка):

apply_filters( ‘admin_footer_text’, string $text )

Теперь, если нам необходимо изменить текст, то передадим его нашей анонимной функции в изменённом виде и не забудем его вернуть 🙂

<?php
/**
 * Удаляет|Изменяет фразы из Футера панели администратора WordPress.
 *
 * @see https://developer.wordpress.org/reference/hooks/admin_footer_text/ Documentation WordPress.
 * @author Code==Poetry <codeispoetry@mail.ru>
 */
 
add_filter( 'admin_footer_text', function( $text ){
    
  $text = '&copy;' . get_bloginfo( 'name' ) . ', ' . wp_date( 'Y' );
  
  return $text;
} );

// Если нужно просто удалить, то вернём пустую строку
add_filter( 'admin_footer_text', '__return_empty_string' );

В данном примере я задействовал ещё две полезные функции из ядра WordPress:

get_bloginfo()

wp_date()

Первая из которых вернёт нам название сайта, а вторая поможет получить текущий год (для динамического вывода). Получаем:

В сниппете приведен пример для полного удаления надписи, для этого задействуем специальную функцию WordPress, которая вернёт пустую строку и как следствие ничего отображаться не будет.

__return_empty_string()

Как удалить логотип WordPress из админ-бара в панели управления?

В удалении логотипа WordPress нам поможет специальный хук, который вызывается (срабатывает), как раз до отображения панели инструментов администратора (админ-бар):

do_action ( 'wp_before_admin_bar_render')

Посмотреть на ГитХаб

Наша задача изменить объект $wp_admin_bar до выполнения рендера панели инструментов. «Повешаем» на этот хук безымянную функцию и не забудем обратиться к глобальной переменной $wp_admin_bar, чтобы внести в неё корректировки.

<?php
/**
 * Удаляет логотип WordPress в админ-баре панели управления сайтом.
 *
 * @see https://developer.wordpress.org/reference/hooks/wp_before_admin_bar_render/ Documentation WordPress.
 * @author Code==Poetry <codeispoetry@mail.ru>
 */
 
add_action('wp_before_admin_bar_render', function(){
    global $wp_admin_bar;
    $wp_admin_bar->remove_menu( 'wp-logo' );
} );

Готово!

Рекомендую ознакомиться со всеми методами класса WP_Admin_Bar, наверняка вы обнаружите ещё что то полезное 🙂