FRONTEND: 15+ ХУКОВ ДЛЯ FILE functions.php

FRONTEND: 15+ ХУКОВ ДЛЯ FILE functions.php

В этой статье я собрал полезные и интересные хуки для фронтенда вашего сайта на WordPress. Я постарался протестировать и улучшить некоторые хак-решения, которые нашел в интернете. Во многих местах были небольшие и большие ошибки.

Содержание

  • Изменение изображения на странице входа (wp-login.php)
  • Перенаправление на пост при поиске
  • Google Analytics и Яндекс.Метрика (установка)
  • Увеличение резкости изображений (миниатюр) (только для jpg)
  • Gzip сжатие
  • Добавление типов записей в результаты поиска
  • Время генерации страницы
  • Ссылка на первое изображение в контенте
  • Какой шаблон файла используется?
  • Добавление типа записи на странице архивов тегов
  • Удаление ссылки "Читать далее"
  • Встраивание (oEmbed) в текст (в виджете "Текст")
  • Подключение скриптов/стилей при наличии шорткода в контенте
  • Подключение и верификация на всех страницах
  • Подключение и верификация для отдельных страниц - is_singular()
  • Загрузка скриптов/стилей, если активен виджет
  • Удаление версии скрипта/стиля из URL
  • Удаление авто-ссылок в комментариях

Изменение изображения на странице входа - wp-login.php

Этот код изменяет страницу входа на wp-login.php. Вы можете заменить логотип и ссылку с главного изображения, которая ведет на сайт wordpress.org.

Изменение логотипа, его ссылки и заголовка на странице входа

if (1) {
    // Измените изображение (логотип)
    // укажите правильную ссылку на изображение.
    add_action('login_head', 'wp_login_logo_img_url');
    function wp_login_logo_img_url() {
        echo '
        ';
    }

    // Изменить ссылку на логотип
    add_filter('login_headerurl', 'wp_login_logo_link_url');
    function wp_login_logo_link_url($url) {
        return home_url();
    }

    // Изменение заголовка ссылки логотипа
    add_filter('login_headertitle', 'wp_login_logo_title_attr');
    function wp_login_logo_title_attr($title) {
        $title = get_bloginfo('name');
        return $title;
    }
}

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

Получение изображения для логотипа с настроек

add_action('login_head', 'wp_login_logo_img_url');
function wp_login_logo_img_url() {
    if (function_exists('get_custom_header')) {
        $width = get_custom_header()->width;
        $height = get_custom_header()->height;
    } else {
        $width = HEADER_IMAGE_WIDTH;
        $height = HEADER_IMAGE_HEIGHT;
    }

    echo '
    ';
}

Перенаправление на пост при поиске

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

// Перенаправление на пост со страницы поиска, если найден только один пост
add_action('template_redirect', 'single_result');
function single_result() {
    if (!is_search()) return;

    global $wp_query;

    if ($wp_query->post_count == 1) {
        wp_redirect(get_permalink(reset($wp_query->posts)->ID));
        die;
    }
}

Google Analytics и Яндекс.Метрика (установка)

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

add_action('wp_head', 'add_googleanalytics', 99);
// или, если нужно отобразить в подвале
// add_action('wp_footer', 'add_googleanalytics', 99);
function add_googleanalytics() {
    ?>
    // Код аналитики
    // Код метрики
    

Увеличение резкости изображений (миниатюр) (только для jpg)

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

Этот код будет работать для всех созданных промежуточных размеров. Он предназначен только для библиотеки GD. Если на сервере используется Imagick, этот код не будет влиять на миниатюры...

// Увеличение резкости созданных миниатюр (только jpg). Только для библиотеки GD...
add_filter('image_make_intermediate_size', 'sharpen_resized_image_files', 900);
function sharpen_resized_image_files($resized_file) {
    if (!function_exists('imagecreatefromstring'))
        return $resized_file; // Библиотека GD не установлена.

    // Загружаем изображение.
    if (1) {
        // Увеличиваем размер памяти до максимума.
        if (function_exists('wp_raise_memory_limit')) wp_raise_memory_limit('image');

        $image = imagecreatefromstring(file_get_contents($resized_file));
    }

    if (!is_resource($image))
        return $resized_file; // ошибка загрузки изображения

    if (!$size = @getimagesize($resized_file))
        return $resized_file; // недопустимое изображение - Не удалось прочитать размер изображения

    list($orig_w, $orig_h, $orig_type) = $size;

    switch ($orig_type) {
        case IMAGETYPE_JPEG:
            $matrix = array(
                array(-1, -1, -1),
                array(-1, 16, -1),
                array(-1, -1, -1),
            );

            $divisor = array_sum(array_map('array_sum', $matrix));
            $offset = 0;
            imageconvolution($image, $matrix, $divisor, $offset);
            imagejpeg($image, $resized_file, apply_filters('jpeg_quality', 90, 'edit_image'));
            break;

        case IMAGETYPE_PNG:
        case IMAGETYPE_GIF:
            return $resized_file;
    }

    return $resized_file;
}

Каков будет результат?

Более резкие миниатюры.

Gzip сжатие

Как это работает и в чем загвоздка? Браузер запрашивает страницу у сервера. Сервер создает HTML-код запрашиваемой страницы, сжимает его и передает браузеру. Браузер получает его в сжатом виде, разжимает и показывает нам. В результате сжатия размер HTML-кода при загрузке браузером с сервера снижается, например, с 500 до 250 КБ.

Сжатие можно включить разными способами: в настройках сервера, через файл .htaccess или в PHP. Ниже показан только один из способов - включение через один из модулей PHP.

Сжатие может быть уже включено:

  • автоматически на сервере
  • в плагинах кэширования страниц, таких как WP Total Cache, WP Super Cache.

Поэтому перед использованием кода убедитесь, что сжатие еще не включено. Для этого посмотрите заголовки HTTP-ответов.

Как просмотреть заголовки ответа сервера

  1. Откройте панель разработчика в браузере Google Chrome (ctrl+shift+i)
  2. Перейдите на вкладку "Сеть"
  3. Обновите страницу в браузере и кликните по первой строке (это запрос к HTML-коду страницы)
  4. Посмотрите на заголовки.

Если сжатие еще не включено, вставьте код ниже в файл functions.php темы и проверьте, было ли оно включено.

if (extension_loaded('zlib') && ini_get('output_handler') != 'ob_gzhandler') {
   add_action('wp', function() { @ ob_end_clean(); @ ini_set('zlib.output_compression', 'on'); });
}

Если сжатие не было включено, ищите другой способ его включения на сайте.

Добавление типов записей в результаты поиска

Включение типа записи в поиск устанавливается при регистрации типа записи, с параметром exclude_from_search в register_post_type().

Если тип записи еще не включен в поиск, альтернатива - использовать код ниже. Здесь тип записи "movie" добавляется в результаты поиска, теперь при поиске WP также будет искать указанный запрос в типе записи "movie".

// Добавление типов записей в результаты поиска
add_action('pre_get_posts', 'get_posts_search_filter');
function get_posts_search_filter($query) {
    if (!is_admin() && $query->is_main_query() && $query->is_search) {
        $query->set('post_type', array('post', 'movie'));
    }
}

Время генерации страницы

Давайте отобразим информацию о том, сколько запросов к базе данных было сделано ��ля генерации страницы, с какой скоростью была сгенерирована страница и сколько памяти было использовано.

С начала WP 5.9 появилась функция timer_float(), которую лучше использовать:

/**
 * Отображает данные о количестве запросов к базе данных,
 * времени выполнения скрипта и объеме использованной памяти.
 */
add_filter('admin_footer_text', 'wp_usage');
function wp_usage() {
    echo sprintf(
        'SQL: %d в %.3F сек. %s МБ',
        get_num_queries(),
        timer_float(),
        round(memory_get_peak_usage() / 1024 / 1024, 2)
    );
}

Для WP 5.8 и ниже:

/**
 * Отображает данные о количестве запросов к базе данных,
 * времени выполнения скрипта и объеме использованной памяти.
 */
add_filter('admin_footer_text', 'wp_usage'); // в подвале админ-панели
add_filter('wp_footer', 'wp_usage');         // в подвале сайта

function wp_usage() {
    echo sprintf(
        'SQL: %d в %s сек. %s МБ',
        get_num_queries(),
        timer_stop(0, 3),
        round(memory_get_peak_usage() / 1024 / 1024, 2)
    );
}

Ссылка на первое изображение в контенте

Вариант 1

Код ниже автоматически "извлекает" первое изображение из текущего поста и возвращает готовый код , обернутый в ссылку на текущий пост.

В параметре $num вы можете указать номер изображения в посте, которое нужно извлечь. Например, если вы укажете 2, код извлечет второе изображение вместо первого.

/**
 * Извлекает первое или указанное изображение из контента текущего поста в цикле
 * и возвращает его в виде конструкции <a><img> (изображение = ссылка на текущий пост).
 * Удобно использовать в качестве миниатюры поста...
 *
 * @param integer [$num = 1] Номер изображения в тексте, которое нужно извлечь.
 * @return string HTML
 */
function get_post_content_image($num = 1) {
    global $more;

    $more = 1;

    $content = get_the_content();
    $count = substr_count($content, '');

        $postOutput = substr($post, 0, $imgEnd + 1);
        $postOutput = preg_replace('~(?:width|height)="[0-9]*"~', '', $postOutput);
        $image[$i] = $postOutput;

        $start = $imgEnd + 1;
    }

    // если изображение существует, выводим его
    if (isset($image[$num]) && stristr($image[$num], '' . $image[$num] . "";

    $more = 0;
}

Пример использования

echo get_post_content_image();
// 

Вариант 2

Для получения URL первого изображения из контента поста посмотрите ответ на вопрос: Как получить URL первой картинки в контенте записи?

Какой шаблон файла используется?

Чтобы узнать, какой файл темы используется для генерации текущей страницы, просто посмотрите в глобальную переменную $template.

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

add_action('wp_head', 'show_template'); // перед заголовком
// add_action('wp_footer', 'show_template'); // в подвале
function show_template() {
    global $template;
    echo $template;
}

Добавление типа записи на страницу архивов тегов

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

add_filter('request', 'any_ptype_on_cat');
function any_ptype_on_cat($request) {
    // для тегов
    if (isset($request['tag']))
        $request['post_type'] = array('post', 'custom_post_type');

    // для категорий
    if (isset($request['category_name']))
        $request['post_type'] = array('post', 'custom_post_type');

    return $request;
}

Удаление ссылки "Читать далее"

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

add_filter('the_content_more_link', 'remove_more_jump_link');
function remove_more_jump_link($link) {
    return preg_replace('~#more-[0-9]+~', '', $link);
}

Код будет работать только если отрывок отображается через get_the_content() или the_content().

Встраивание (oEmbed) в текст (в виджете "Текст")

Встраивание объектов в виджет "Текст". Что это значит? Например, нам нужно, чтобы ссылки из специального белого списка обрабатывались в текстовом виджете так же, как и в посте. Например, если мы укажем ссылку на видео YouTube на отдельной строке, при просмотре она превратится в игрок YouTube - ссылка изменится на HTML-код в реальном времени.

Хак, указанный ниже, позволяет включить такую "функцию" для текстового виджета. Вставьте код в файл functions.php темы.

После вставки кода вы можете использовать шорткоды и специальные ссылки. Всё это будет обрабатываться.

global $wp_embed;
add_filter('widget_text', [$wp_embed, 'run_shortcode'], 8);
add_filter('widget_text', [$wp_embed, 'autoembed'], 8);

Подключение скриптов/стилей, если шорткод присутствует в контенте

// Пример подключения скрипта, если на странице присутс��вует шорткод
add_filter('the_posts', 'has_my_shortcode');

function has_my_shortcode($posts) {
    if (is_admin() || empty($posts) || !is_main_query()) {
        return $posts;
    }

    $shortcode_name = 'my_shortcode';

    foreach ($posts as $post) {
        if (has_shortcode($post->post_content, $shortcode_name)) {
            add_action('wp_enqueue_scripts', 'add_my_scripts');
            break;
        }
    }

    return $posts;
}

// Подключение скриптов, если шорткод присутствует
function add_my_scripts() {
    $theme_url = get_stylesheet_directory_uri();
    wp_enqueue_script('my_script', "{$theme_url}/my_script.js");
}

Подключение и верификация на всех страницах

add_action('wp_head', 'my_shortcode_styles');

function my_shortcode_styles() {
    global $post;

    $shortcode_name = 'my_shortcode_name';

    if (!($post && is_singular() && has_shortcode($post->post_content, $shortcode_name))) {
        return;
    }

    ?>
    
    

Загрузка скриптов/стилей, если активен виджет

В этом примере показано, как загрузить JS-файл, если активен виджет "Календарь". Аналогично, вы можете загружать скрипты для любого активного виджета.

Загрузка скрипта, если есть активный виджет

add_action('wp_enqueue_scripts', 'add_calendar_widget_scripts');
function add_my_widget_scripts() {
    if (!is_active_widget(false, false, 'calendar')) return; // выходим, если виджет не активен

    $theme_url = get_stylesheet_directory_uri();
    wp_enqueue_script('my_widget_script', $theme_url . '/calendar_widget_script.js');
}

Загрузка скрипта, когда активен собственный код виджета

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

Код виджета

class My_Widget extends WP_Widget {

    function __construct() {
        // Инициализация родительского класса
        parent::__construct(
            'widget_id', // ID виджета, если не указан (оставьте ''), ID будет равен имени класса в нижнем регистре: my_widget
            'Заголовок Виджета',
            array('description' => 'Описание Виджета'),
        );

        // скрипты/стили виджета, только если активен
        if (is_active_widget(false, false, $this->id_base) || is_customize_preview()) {
            add_action('wp_enqueue_scripts', array($this, 'add_my_widget_scripts'));
            add_action('wp_head', array($this, 'add_my_widget_style'));
        }
    }

    // Вывод виджета
    function widget($args, $instance) {
        $title = apply_filters('widget_title', $instance['title']);
        echo $args['before_widget'];

        if ($title)
            echo $args['before_title'] . $title . $args['after_title'];

        echo 'Привет!';

        echo $args['after_widget'];
    }

    // Сохранение настроек виджета (очистка)
    function update($new_instance, $old_instance) {}

    // HTML-форма для настроек виджета в админ-панели
    function form($instance) {}

    // Скрипт виджета
    function add_my_widget_scripts() {
        // фильтр для возможности отключения скриптов
        if (!apply_filters('show_my_widget_script', true, $this->id_base))
            return;

        $theme_url = get_stylesheet_directory_uri();
        wp_enqueue_script('my_widget_script', $theme_url . '/my_widget_script.js');
    }

    // Стили виджета
    function add_my_widget_style() {
        // фильтр для возможности отключения стилей
        if (!apply_filters('show_my_widget_style', true, $this->id_base))
            return;
        ?>
        
        

Удаление версии скрипта/стиля из URL

Когда вы регистрируете скрипт, для него указывается версия. Вы можете удалить такую версию из ссылки скрипта или стиля.

Удаление всех версий из всех скриптов

// Удаление версий скриптов
add_filter('script_loader_src', '_remove_script_version');
// Удаление версий стилей
add_filter('style_loader_src', '_remove_script_version');
function _remove_script_version($src) {
    $parts = explode('?', $src);
    return $parts[0];
}

Удаление только версий WordPress

// Удаляет версию WP из данной ссылки для скриптов и стилей
add_filter('script_loader_src', 'hb_remove_wp_version_from_src');
add_filter('style_loader_src', 'hb_remove_wp_version_from_src');
function hb_remove_wp_version_from_src($src) {
    global $wp_version;
    parse_str(parse_url($src, PHP_URL_QUERY), $query);
    if (!empty($query['ver']) && $query['ver'] === $wp_version) {
        $src = remove_query_arg('ver', $src);
    }
    return $src;
}

Удаление авто-ссылок в комментариях

В комментариях текст в форме ссылки, например: http://example.com/foo, автоматически преобразуется в ссылку. Чтобы убрать эту конвертацию, вставьте следующий хак в файл functions.php вашей темы:

remove_filter('comment_text', 'make_clickable', 9);

Теперь вы знаете, как использовать различные хуки для улучшения работы вашего сайта на WordPress. Каждый из приведённых кодов можно адаптировать под ваши нужды, так что экспериментируйте!

Leave a Reply

Ваш адрес email не будет опубликован. Обязательные поля помечены *