Задать вопрос
  • Как реализовать мультиязычность?

    HeadOnFire
    @HeadOnFire
    PHP, Laravel & WordPress Evangelist
    Если мультиязычка зеркальная - каждая страница или статья/новость имеет перевод на другой язык, тогда один сайт и плагин для мультиязычки - WPML (платный) или Polylang (бесплатный, платные add-ons).

    Если контент (структура сайта, страницы, записи и тд) на языковых версиях отличается - тогда WordPress Multisite.

    Все остальное выбросьте из головы.
    Ответ написан
    2 комментария
  • Как получить комментарии к каждому посту в списке?

    HeadOnFire
    @HeadOnFire
    PHP, Laravel & WordPress Evangelist
    1. Получить посты (1 запрос, если не тянуть и не праймить кеши метаданных и таксономий).
    2. Из массива постов выдернуть их IDшки (wp_list_pluck или аналогичным методом).
    3. Получить комменты c помощью WP_Comment_Query, передав IDшки из п.2 в свойство post__in (1 запрос, если не тянуть и не праймить кеши метаданных и постов)
    4. Вывести посты циклом, в каждой итерации забирать необходимые комменты из результата п.3

    Итого: 2 запроса.

    Впрочем, в реальной жизни вам все-таки понадобятся метаданные как постов, так и комментов. Поэтому запросов будет больше, но не N+1.

    А вообще такие штуки не мешало бы кешировать целиком, или хотя бы результаты запросов, в transients. На какой период - зависит от частоты обновления инфы на сайте. От 5 минут до часа.
    Ответ написан
    Комментировать
  • Wordpress. Как обновить все записи, их более 2000?

    HeadOnFire
    @HeadOnFire
    PHP, Laravel & WordPress Evangelist
    Что значит обновить? Дату и время последнего изменения обновить? Как кросспостинг отслеживает изменения? Я вообще подозреваю, что он висит на хуке сохранения поста в вадминке. Соответственно, только ручками пересохранять, или же писать скрипт, который будет циклом идти по постам и вызывать соответствующую функцию/метод плагина.
    Ответ написан
    Комментировать
  • Wordpress: собственный обработчик POST-запросов?

    HeadOnFire
    @HeadOnFire
    PHP, Laravel & WordPress Evangelist
    1. Аякс не обязателен в вашем случае.
    2. Использовать совет MrTimon тем более не стоит (хотя этот метод является правильным).

    В вашей ситуации наиболее простым и адекватным решением будет по старинке постить форму саму на себя (на текущий урл), хукаться в init и выполнять необходимые действия.

    UPDATE: В комментариях обсуждение и детали.
    Ответ написан
  • Git на продакшин сервере?

    HeadOnFire
    @HeadOnFire
    PHP, Laravel & WordPress Evangelist
    Думал уже как вордпрещики архивами все делать

    А вот это щас обидно было! :)

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

    При таком подходе получаете очевидные плюсы:
    - на сервер лазить ручками не нужно, обезьяний труд должен быть автоматизирован
    - деплой происходит без downtime
    - у вас сохраняется предыдущее стабильное состояние, в случае проблем с новой версией вы легко переключаете сервер на предыдущую папку, откатываясь таким образом к last stable
    - при желании можно даже a/b тестирование делать
    Ответ написан
    5 комментариев
  • Как сделать выдачу записей по релевантности Wordpress?

    HeadOnFire
    @HeadOnFire
    PHP, Laravel & WordPress Evangelist
    Вы для начала определитесь четко, что вы вкладываете в понятие "релевантность". Конкретные параметры, их вес и тд. А тогда запилите руками. WP из коробки использует совсем базовый поиск - нахождение искомого слова/фразы в БД по некоторым полям.

    Посмотрите в сторону ElasticSearch + ElasticPress.
    Ответ написан
  • Почему не работает трансляция?

    HeadOnFire
    @HeadOnFire
    PHP, Laravel & WordPress Evangelist
    А если вот так:

    <?php
    /**
     * Plugin Name: Translation demo
     */
    namespace langdemo;
    
    if (!defined('WPINC')) {
        die;
    }
    
    function run() {
        require_once plugin_dir_path(__FILE__) . 'class-plugin.php';
        $plugin = new Plugin();
        $plugin->run();
    }
    
    add_action( 'plugins_loaded', 'run' );
    Ответ написан
    Комментировать
  • Как удалить или скрыть текстовый редактор?

    HeadOnFire
    @HeadOnFire
    PHP, Laravel & WordPress Evangelist
    css / js
    Ответ написан
    Комментировать
  • Залить CSV файл в БД при наличие произвольных полей в записях?

    HeadOnFire
    @HeadOnFire
    PHP, Laravel & WordPress Evangelist
    Ответ написан
    Комментировать
  • Не отображаются страницы таксономий в произвольном типе записей, что делать?

    HeadOnFire
    @HeadOnFire
    PHP, Laravel & WordPress Evangelist
    У вас одинаковый slug и у post type, и у taxonomy. Соответственно, будет срабатывать первое правило из двух, а именно правило custom post type. В вашем случае, при попытке открыть урл test.com/exercises/street WP будет искать запись типа exercises (custom post type) со слагом street. Такой записи нет, отсюда 404. Термин таксономии он искать не будет, так как Rewrite API работает по принципу "нашли первое совпадение и прекратили проверку".
    Ответ написан
    Комментировать
  • Как правильно обработать кастомную форму wordpress с админки?

    HeadOnFire
    @HeadOnFire
    PHP, Laravel & WordPress Evangelist
    Хукайте в admin_post_*

    Еще почитать: https://www.sitepoint.com/handling-post-requests-t...
    Ответ написан
    Комментировать
  • Какой идеальный вариант хостинга для Wordpress?

    HeadOnFire
    @HeadOnFire
    PHP, Laravel & WordPress Evangelist
    1. VPS c 2мя ядрами проца, SSD и минимум 4Гб оперативы (потому что у вас много сайтов и всем нужно раздать места в кеше), у нормального хостера который не оверселлит, по крайней мере явно. Проверенные - Amazon AWS, Digital Ocean. Да, и без swap.
    2. FreeBSD
    3. Nginx, сертификаты Let's Encrypt, HTTP/2
    4. PHP-FPM 7.1
    5. MariaDB 10.2
    6. Memcached или Redis
    7. Адекватные настройки всего этого дела
    8. Адекватные плагины кеширования (drop-ins для объектного кеша и для full-page кеширования где оно имеет смысл)
    9. Все упомянутые сервисы через сокеты
    10. Опционально - Varnish, HAProxy для SSL termination, Nginx fastcgi_cache для кеширования страниц целиком (где в этом есть смысл, вместо плагина на уровне WP)
    11. Для управления всем этим не использовать Plesk, Vesta, ISP и прочую ересь. Учитесь делать все руками и самостоятельно.

    Вообще, как говорится, дьявол всегда кроется в деталях. Иногда вопрос упирается исключительно в настройки - то fpm pool некорректно настроен, то open table cache в MySQL, то слишком долгий keep alive у Nginx, то упираетесь в лимит открытых файлов, то не кешируется достаточное количество файловых дескрипторов и тд. Корректные настройки всех сервисов под конкретные потребности конкретных сайтов - ключ к успеху.

    Ну и, конечно, самое-самое главное - адекватный код самих сайтов. Ибо одна говнотема "все-в-одном" с парочкой таких же говноплагинов способна ронять даже хорошо настроенный сервер.
    Ответ написан
    2 комментария
  • Как сделать MultiSite на WP с подгрузкой (а не копированием) постов, записей и т.д.?

    HeadOnFire
    @HeadOnFire
    PHP, Laravel & WordPress Evangelist
    Если вопрос в выводе данных на фронте (то есть, чтобы дочерние сайты просто показывали записи с главного сайта сети) - попробуйте switch_to_blog / restore_current_blog. Переключились на главный сайт, вытянули посты, переключились обратно. Ну или REST API пробуйте, тоже вполне вариант.
    Ответ написан
    3 комментария
  • The query cache is deprecated as of MySQL 5.7.20, что это значит и чего ждать?

    HeadOnFire
    @HeadOnFire
    PHP, Laravel & WordPress Evangelist
    Query cache вообще штука весьма неоднозначная, и лучше всего query_cache_size устанавливать в 0. Поэтому, не велика потеря. Для тех, кто давно так делает, последствий никаких. Для тех же, кто на него полагался, предстоит немного чтения и ковыряния в коде.
    Ответ написан
    Комментировать
  • Как добавить условие, при котором которое будет исполнять функцию через раз?

    HeadOnFire
    @HeadOnFire
    PHP, Laravel & WordPress Evangelist
    function ads_h2( $content ) {
    
    	// Хорошая практика, называется "return early"
    	if ( ! is_single() ) {
    		return $content;
    	}
    
    	// Заготовили код рекламы
    	$ad = '[AD]';
    
    	// Инициализировали счетчик
    	$count = 1; // 0 или 1, по ситуации
    
    	// Делаем замену через коллбек
        $content = preg_replace_callback(
            '#<h2(.*?)</h2>#',
            // С помощью use передаем в замыкание дополнительные параметры
            function( $matches ) use ( &$count, $ad ) {
                // Увеличиваем счетчик
                $count++;
                // Если число четное, добавляем рекламу
                if ( $count % 2 == 0 ) {
    	            return '<div class="ads_content">' . $matches[0] . $ad . '</div>';
                // Если нечетное - ничего не делаем
                } else {
                    return $matches[0];
                }
            },
            $content
        );
    
    	// Вернули измененный контент
    	return $content;
    }
    add_filter( 'the_content', 'ads_h2' );


    Бонус

    Если менять цифру в if ( $count % 2 == 0 ) { вместо 2 на, скажем, 3 или 4, то реклама будет выводиться, соответственно, в каждом 3м или 4м подзаголовке.
    Ответ написан
    2 комментария
  • Зачем делать дочерние страницы wordpress?

    HeadOnFire
    @HeadOnFire
    PHP, Laravel & WordPress Evangelist
    Вы путаете теплое с мягким.

    Страницы (pages) это один тип данных, он не поддерживает (по умолчанию) категории. Зато поддерживает дочерние страницы. Нужно это как раз для того, чтобы у страницы были подстраницы, с более детальным контентом, например.

    Разбивка же не-иерархического контента (посты, записи, они же posts) происходит как раз с помощью таксономий (categories, tags и произвольные таксономии).

    А теперь, с учетом вышеизложенного, уточните вопрос.

    ЗЫ: А по поводу пропадающего фонового изображения - спросите в канале по CSS, и обязательно ссылку прикрепите. Диагностику делать без пациента - гиблое дело.
    Ответ написан
    Комментировать
  • Как ограничить в вордпресс количество рубрик по циклу?

    HeadOnFire
    @HeadOnFire
    PHP, Laravel & WordPress Evangelist
    Из документации:


    'number'
    (int|string) Maximum number of terms to return. Accepts ''|0 (all) or any positive number. Default ''|0 (all).


    То есть, вот так:

    $args = array(
        ...
        'number' => 10, // нужное количество (максимальное)
        ...
    );
    $cats = get_categories($args);


    Это что касается вашего прямого вопроса. А также, не нужно делать вот это:

    $category = get_term($cat)

    и вот это:

    echo get_cat_name($category->term_id);

    потому что функцией get_categories() вы уже получили массив объектов WP_Term, которые содержат все необходимые данные. Вот вам отрефакторенный код, который не делает ничего лишнего:

    $args = array(
    	'parent'         => 0,
    	'hide_empty'     => 0,
    	'exclude'        => array( 11, 1 ),
    	'number'         => 10,
    	'taxonomy'       => 'category',
    	'posts_per_page' => 1,
    	'pad_counts'     => true
    );
    
    $cats = get_categories( $args );
    
    foreach( $cats as $cat ) :
    
    	echo $cat->name;
    	echo $cat->description; 
    
    endforeach;
    Ответ написан
    Комментировать
  • Как создать frontend формы с возможностями сохранения и редактирования?

    HeadOnFire
    @HeadOnFire
    PHP, Laravel & WordPress Evangelist
    Gravity Forms
    Ninja Forms
    Caldera Forms
    Torro Forms
    ...
    Да любой адекватный плагин для форм под WordPress предоставляет этот функционал.
    Ответ написан
  • Как оптимизировать сайт на wordpress+visual composer?

    HeadOnFire
    @HeadOnFire
    PHP, Laravel & WordPress Evangelist
    Бекенд у вас весьма шустрый:

    bf3ea512b4264ec0a546b7e2a70bafee.jpg

    Это весьма и весьма достойный результат. С сервером и на серверной стороне все в порядке. А теперь узкие места:

    1. Загрузка шрифтов с серверов Google. С вашим шустрым сервером имеет смысл шрифты стянуть себе и отдавать локально. Срежете секунды полторы:

    67053ff4cfef4f458eb6d4723a36a7e2.jpgab83df494f21431284650396046227eb.jpg

    2. Далее, есть проблема с несколькими стилями:

    vcare.uz/wp-content/plugins/js_composer/assets/lib...
    vcare.uz/wp-content/plugins/js_composer/assets/lib...
    vcare.uz/wp-content/plugins/js_composer/assets/lib...

    Они долго грузятся, можете сами в Developer Tools посмотреть. Проблема не только в том, что они долго грузятся, но и в том, что они встают в очередь так как расположены в подвале и из-за использования HTTP/1.1. Можно решить 2мя путями:

    - конкатенация в один файл
    - использование HTTP/2

    В идеале, можно искать баланс между HTTP/2 + выборочная конкатенация.

    3. Файлы

    - new.vcare.uz/wp-content/uploads/2017/08/header-1.j...
    - new.vcare.uz/wp-content/uploads/2017/08/bg-white22...

    С ними 2 проблемы:

    - грузится с поддомена (+ DNS lookup и прочие потери на новый коннект)
    - динамический параметр, который предотвращает кеширование файла на стороне клиента

    Перенесите файл на основной домен и уберите параметр.

    4. Contact Form 7

    7cad4ec44dba469b86e2fbaa7c31558d.jpg

    У вас 7 (!!!) аякс-запросов этот плагин генерит. Я так понимаю, это 7 разных форм на странице. Запросы запускаются достаточно рано в цикле жизни страницы, и блокируют других ресурсов, занимая соединения с сервером. По протоколу HTTP/1.1, насколько я помню, браузер открывает до 6 соединений с сервером. В вашем случае, часть из этих 6 к моменту вызова этих ajax-запросов уже занята, и они встают в очередь друг за другом, вместе с другими ресурсами. Это умножает время ожидания. Переход на HTTP/2 заметно снизит влияние, но желательно избавиться от них вообще. Я бы советовал заменить CF7 на более адекватный плагин. Попробуйте, к примеру, Torro Forms (толковый и бесплатный, еще и с нормальным интерфейсом).

    5. Еще один запрос к admin-ajax.php

    f94caf0158b642b2958aefe1b9825ae5.jpg

    Собственно, он инициирован Visual Composer'ом - это Masonry сетка. Возможно, он у меня дозапустился потому что я начал скролить страницу и докрутил до того места, где он нужен. Возможно, он не запускается по умолчанию и проблемой не является.

    6. Front-end performance (парсинг и рендеринг):

    1691686d9b5f493fb147d10e0da4a894.jpg

    Парсинг скриптов занимает много времени, ибо их много. Но от этого можно избавиться только путем уменьшения их количества, что, возможно, не вариант. А вот второй очень тревожный сигнал - это как раз время ожидания (Idle). Это как раз говорит о невозможности браузера продолжать работу на каких-то этапах из-за того, что он ждет пока прилетят запрошенные ресурсы. Переход на HTTP/2 крайне желателен + замена CF7. Это как раз тот случай, когда HTTP/2 должен дать ощутимый эффект.

    Ну это так, беглый анализ. Посмотрите результаты тестирования тут: https://tools.pingdom.com/#!/2GQ2d/http://vcare.uz/
    Ответ написан
    3 комментария