Ответы пользователя по тегу WordPress
  • Как сделать такой фильтр ( wordpress + acf )?

    HeadOnFire
    @HeadOnFire
    PHP, Laravel & WordPress Evangelist
    Если не использовать плагины, то +1 к ответу id_baton4eg, но с поправкой: вместо get_posts() лучше WP_Query - больше свободы и контроля.

    А вообще, если уж слать ajax'ом, то есть REST API. Пилим свой REST контроллер, и получаем на выходе json - быстрее, удобнее для javascript на фронте.

    Но, есть один важный нюанс - такие запросы будут нормально грузить бекенд. Поэтому, для таких задач существует такая штука как Elastic Search (и аналоги). Для него же есть и WP-плагин ElasticPress. Скорость такой связки - космос по сравнению со стандартным REST API даже. Ну и гибкость.
    Ответ написан
    Комментировать
  • Advanced Custom Fields Вывод вложенных групп и полей в них?

    HeadOnFire
    @HeadOnFire
    PHP, Laravel & WordPress Evangelist
    Все есть в документации, если читать внимательно. А именно: поле Group возвращает массив в формате Field name => Field Value. В случае с вложенными группами, будет 2 уровня вложенности. Делайте var_dump( get_field( 'index-slides' ) ); чтобы увидеть что в возвращаемом массиве.

    По ссылке в доке есть как правильно цикл строить. Специфика этого поля в том, что сохраняются значения в виде имя-группы_имя-поля, поэтому прямой доступ по имя-поля (first-title) невозможен.

    RTFM, в общем.
    Ответ написан
    2 комментария
  • Как закрыть определенную папку от доступа неавторизованных пользователей WP?

    HeadOnFire
    @HeadOnFire
    PHP, Laravel & WordPress Evangelist
    Выбросите из этого компота WordPress, он там лишний.
    Или перенесите контент из HTML-страниц на WP, но корректно. 2018й год за окном же.
    Ответ написан
  • На wordpress сейчас можно сделать любой сайт?

    HeadOnFire
    @HeadOnFire
    PHP, Laravel & WordPress Evangelist
    На wordpress сейчас можно сделать любой сайт?

    Если речь о "собрать из премиум-темы и плагинов", то нет. И даже то что вроде бы да, на самом деле нет и боль.
    Если речь о разработке, с использованием по необходимости всего, чего угодно (в том числе и вне самого WP) - тогда да. Например, WP вполне можно оставить чисто как бекенд/админку для редакторов. Его можно вполне подружить с микросервисами. Его database schema можно расширить под свои нужды. Да много чего, практически все что угодно, если вы software developer, а не что-то типа "jquery developer", "wordpress developer" и тд.

    Боюсь, что на wordpress будет проблематично масштабировать.

    Та масштабируется он, точно так же как и все остальное. Посмотрите на wordpress.com в конце концов, и на другие крупные проекты на WP. Имхо, если проект уже на нем, то всегда проще допилить все что нужно под WP, чем переписывать все с нуля и мигрировать.
    Ответ написан
    Комментировать
  • Как взять все значения терма таксономии по одному их них?

    HeadOnFire
    @HeadOnFire
    PHP, Laravel & WordPress Evangelist
    Ась?

    1. Номер телефона это что? Метаданные записи? Метаданные пользователя? Метаданные термина? Термин? Запись? Кастомные данные в кастомной таблице в БД? Предположу, что это метаданные термина.
    2. Get_term_by получает термин только по некоторым нативным полям объекта WP_Term. Номер телефона, очевидно, им не является.
    3. А WP_Query тут при чем? Если вам термин нужен, при чем тогда WP_Query? Он используется для получения записей.
    4. А для получения термина по метаданным есть get_terms() и WP_Term_Query.
    Ответ написан
    Комментировать
  • Как и чем вы защищаете свои WordPress-сайты - плагины, решения?

    HeadOnFire
    @HeadOnFire
    PHP, Laravel & WordPress Evangelist
    1. Защита на уровне сервера, в том числе блокировка известных стремных запросов, лимит попыток ввода пароля, блокировка доступа к тому, что не нужно, корректные права и тд. Fail2ban, UWF и вот это все, плюс Nginx.
    2. Построение проекта на базе Composer, где WP - обычная зависимость, как и все остальное. Автоматический деплой с возможностью мгновенного отката. Мониторинг чексум. Мониторинг производительности, доступности и логов.
    3. Проверка всего кода, который устанавливается. Никогда не использовать "зануленные" плагины и темы.
    4. Использование лучших security практик при написании своего кода.
    5. Использование bcrypt или argon для паролей WP.
    6. Использование .env
    7. Доступ к wp-admin только по IP или по IP через VPN (чтобы не нужно было обновлять whitelist если IP меняется).
    8. В некоторых случаях CloudFlare на входе.

    Никаких плагинов типа Wordfence, iThemes Security и прочего не использую и не советую. Они только замедляют сайт, не делают ничего, что не может быть сделано без них, сами являются уязвимым местом и создают ложное чувство безопасности.
    Ответ написан
    2 комментария
  • Какой pagebuilder для Wordpress лучше?

    HeadOnFire
    @HeadOnFire
    PHP, Laravel & WordPress Evangelist
    Не использую и всячески избегаю, как чумы. Проектов с page builder'ами не беру, независимо от бюджета.
    Для создания гибкого flow под клиента использую ACF Pro.
    В скором времени в процесс будет включен Gutenberg.
    Ответ написан
    4 комментария
  • Какой фреймворк лучше использовать для натяжки готового html на WordPress?

    HeadOnFire
    @HeadOnFire
    PHP, Laravel & WordPress Evangelist
    1. На чистом HTML/CSS с учетом специфики WordPress.
    2. Часто саму тему стоит строить на базе Underscores, или использовать наработки из нее.
    3. Для отдельных случаев лучше прикручивать нормальный шаблонизатор (Twig, Blade), но это вряд ли ваш случай.

    Именно в таком порядке приоритетов. Все остальные варианты – приключения на 5ю точку.
    Ответ написан
    Комментировать
  • Как вывести название кастомных рубрик и название постов, которые в этой рубрике в WordPress?

    HeadOnFire
    @HeadOnFire
    PHP, Laravel & WordPress Evangelist
    Самый простой вариант, хотя и не самый производительный, если таких "групп записей" много:
    // Сначала получаем термины кастомной таксономии:
    $terms = get_terms( [
        'taxonomy' => 'taxonomy_name', // тут укажите правильное название вашей таксономии
        'hide_empty' => true,
    ] );
    
    // Далее циклом выводим эти блоки:
    foreach ( $terms as $term ) :
    
        echo '<div>';
    
            // Получаем Х записей с конкретным термином, формируем параметры запроса:
            $args = [
                'post_type' => 'post_type_name', // тут укажите правильное название вашего custom post type
                'posts_per_page' => 5 // количество записей
                'tax_query' => [
                    [
                        'taxonomy' => 'taxonomy_name', // тут укажите правильное название вашей таксономии
                        'field' => 'term_id', // term_id, slug или name - что удобнее
                        'terms' => $term->term_id, // ID текущего термина в цикле
                        'include_children' => false,
                    ],
                ],
            ];
    
            // Получаем Х записей с конкретным термином:
            $posts_with_term = new WP_Query( $args );
    
            // Выводим записи циклом:
            while ( $posts_with_term->have_posts() ) : $posts_with_term->the_post();
    
                // Тут форматируйте вывод как угодно:
                the_title();
    
            endwhile;
            wp_reset_postdata();
    
        echo '</div>';
    
    endforeach;

    Дополнительно почитайте про все параметры WP_Query, чтобы оптимизировать их (например, отключить пагинацию, кеширование метаданных и терминов так как здесь они вам не нужны и тд) - это позволит уменьшить общее количество запросов к БД и повысить производительность.

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

    Кеширование я бы делал так:

    1. Каждый WP_Query кешируется в transients / object cache (только почитайте как правильно кешировать именно $query->results а не весь объект WP_Query).
    2. Каждому такому блоку в кеше присваиваем рандомное (в определенном диапазоне) время жизни. Чтобы все блоки не сбрасывались и не пересоздавались одновременно. Так регенерация кеша будет незаметна, если есть более-менее стабильный трафик.
    3. При добавлении новой записи смотреть в какой блок она входит и удалять этот блок из кеша. Это предотвратит отображение устаревшей информации.

    P.S.: Писал не проверяя прямо здесь, так что мог где-то опечататься, но в целом должно работать.
    P.P.S.: Сложность этого вопроса "средний", а не "сложный" - это все делается стандартными средствами и подробно расписано в документации.
    Ответ написан
  • Как вывести имя страницы, если она установлена главной статической страницей?

    HeadOnFire
    @HeadOnFire
    PHP, Laravel & WordPress Evangelist
    get_the_title(), в него можно передать ID или объект WP_Post. А их можно получить через get_queried_object() / get_queried_object_id().

    Впрочем, тут какой-то баг где-то или левый код что-то чудит. Тайтл должен выводиться аж бегом.
    Ответ написан
    Комментировать
  • Какой плагин лучший? ACF, CMB2, Pods, MetaBox?

    HeadOnFire
    @HeadOnFire
    PHP, Laravel & WordPress Evangelist
    ACF Pro. Причин миллион.
    Остальное пробовал, использовал – рядом не стояло. Даже Pods, хотя он весьма и весьма.
    Ответ написан
    Комментировать
  • Ошибка "Warning: call_user_func_array() expects parameter 1 to be a valid callback"?

    HeadOnFire
    @HeadOnFire
    PHP, Laravel & WordPress Evangelist
    Такую функцию нашел по такому адресу: wp-content/themes/cruxstore/framework/woocommerce.php.
    add_filter('woocommerce_product_loop_start', 'cruxstore_woocommerce_product_loop_start_callback');

    В этом месте вы не функцию нашли, а место где она собственно вешается на фильтр как коллбек. А теперь попробуйте найти где сама эта функция определена. Ищите код:
    function cruxstore_woocommerce_product_loop_start_callback

    Судя по ошибке, вы ее не найдете.
    Ответ написан
    Комментировать
  • Редактирование таблиц БД из админки WordPress. Какой подход?

    HeadOnFire
    @HeadOnFire
    PHP, Laravel & WordPress Evangelist
    Класс wpdb.
    Ответ написан
    Комментировать
  • Как вывести ссылку на кастомную категорию для кастомного поста?

    HeadOnFire
    @HeadOnFire
    PHP, Laravel & WordPress Evangelist
    Так же, как во втором примере для категорий, только используйте get_term_link() и get_term().
    Ответ написан
    Комментировать
  • Как сделать обновляемую дату в WordPress?

    HeadOnFire
    @HeadOnFire
    PHP, Laravel & WordPress Evangelist
    Вариант 1: Метаданные (wp_postmeta).
    Вариант 2: Использовать колонку post_modified в wp_posts, обновлять ее по графику.
    Вариант 3: Использовать отдельную таблицу в БД специально для этого.
    Ответ написан
    Комментировать
  • Как узнать к какой таксономии принадлежит метка?

    HeadOnFire
    @HeadOnFire
    PHP, Laravel & WordPress Evangelist
    Объект типа WP_Term содержит название таксономии в свойстве $term->taxonomy.

    Для получения объекта термина используется get_term( $term_id ).

    $term = get_term( $term_id );
    echo $term->taxonomy;


    Если находитесь на странице архива данного термина, то можете получить объект термина с помощью get_queried_object().
    Ответ написан
    Комментировать
  • Задать класс записи имея id?

    HeadOnFire
    @HeadOnFire
    PHP, Laravel & WordPress Evangelist
    но так как id идут через запятую не срабатывает

    Почитайте про:
    - explode
    - foreach
    Это основы PHP, самые-самые основы.
    Ответ написан
    Комментировать
  • Как вывести записи паралельные id?

    HeadOnFire
    @HeadOnFire
    PHP, Laravel & WordPress Evangelist
    Можно сделать двухстороннюю связь с помощью дополнительного поля. При сохранении записи 22 (продукт), брать список ID связанных отраслей и каждой из них дописывать в мета что-то типа connected_products => [22,]. Обратите внимание, что ID должны идти в массиве или через запятую - это позволит вам привязывать несколько продуктов к одной отрасли (и не забудьте перед установкой нового ID сначала получить старое значение, если таковое имеется, чтобы не затирать существующие привязки).

    Псевдокод (пишу не проверяя, чтобы продемонстрировать логику):

    add_action( 'save_post',  'connect_products_to_industries' );
    function connect_products_to_industries( $post_id, $post, $update ) 
    {
        if ( ! empty( $_POST['acf_field_insdustries'] ) ) { // Если отраслей есть, название поля от балды
            // предположим, что отрасли будут массивом ID, пройдемся по нему:
            foreach ( $_POST['acf_field_insdustries'] as $industry_id ) {
                // Получаем текущий список связанных продуктов
                $products_in_industry = get_post_meta( $industry_id, 'connected_products', true );
                // Надо будет проверить, не пустое ли значение (empty string если привязок еще нет, а нам массив нужен), это опущу, сами сделаете
                // Дополним список IDшкой текущего продукта, если его еще нет в этом списке.
                if ( ! in_array( $post_id, $products_in_industry ) ) {
                    $products_in_industry[] = $post_id;
                    // И запишем это обратно в отрасль
                    update_post_meta( $industry_id, 'connected_products', $products_in_industry );
                }
            }
        }
    }

    Если вам надо будет выборки делать (Meta_Query) по $products_in_industry, сохраняйте IDшки продуктов отдельными мета-записями (bool $single должен быть false). Тогда с массивами и склейкой с предыдущими данными заморачиваться не надо будет, можно получать массив этих записей и работать с ним подобным образом.

    Для вывода продуктов на странице отрасли достаточно запустить get_posts/WP_Query передав туда через post__in массив IDшек из meta (connected_products).
    Ответ написан
    Комментировать
  • Как на страницу woocommerce добавить поле для ввода данных?

    HeadOnFire
    @HeadOnFire
    PHP, Laravel & WordPress Evangelist
    По ссылке вполне приемлемый метод. Что касается админки - конечно их там не будет, потому что в примере по по ссылке нету кода для админки. Его надо написать дополнительно.
    Ответ написан
    Комментировать