Ответы пользователя по тегу WordPress
  • Как в wordpress удалить домен в url меню?

    HeadOnFire
    @HeadOnFire Куратор тега WordPress
    PHP, Laravel & WordPress Evangelist
    Вообще есть несколько способов, и все они решают задачу - но с разной степенью влияния на производительность и возможными побочными эффектами (или же наоборот - их отсутствием). Лично я предпочитаю любой код писать как можно "ближе к телу", чтобы изменения происходили с минимальным количеством телодвижений.

    Например, вариант от WP_Panda абсолютно рабочий. Но меня напрягает использование get_home_url() - и в нем нет никакого смысла, если у вас не мультисайт (что чаще всего), достаточно использовать get_option( 'home' ). Эффект тот же, CPU cycles использовано - меньше.

    Дальше, мне не очень по душе перебирать длинные строки которые потенциально могут сломаться целиком, комфортнее работать с данными, до того как они собрались в HTML:
    function absolute_to_relative_url( $atts )
    {
        $atts['href'] = str_replace( get_option( 'home' ), '', $atts['href'] );
    
        return $atts;
    }
    add_filter( 'nav_menu_link_attributes', 'absolute_to_relative_url' );


    Но и здесь мой внутренний задрот все еще не будет удовлетворен, потому что у нас постоянно вызывается get_option( 'home' ) (или get_home_url()), хотя это значение не меняется. Плюс наша логика выполняется на фильтре, который запускается для каждого элемента меню - это все тоже лишние CPU cycles. Поэтому я бы сделал вот так:
    function absolute_to_relative_url( $sorted_menu_items )
    {
        $host = get_option( 'home' );
    
        foreach ( $sorted_menu_items as $item ) {
            $item->url = str_replace( $host, '', $item->url );
        }
    
        return $sorted_menu_items;
    }
    add_filter( 'wp_nav_menu_objects', 'absolute_to_relative_url' );

    Бенефиты - наш коллбек вызывается всего один раз для одного меню, адрес сайта получается один раз, простой цикл быстро перебирает объекты пунктов меню (данные).

    Этого можно не делать, можно просто отфильтровать HTML - и это будет работать, и заметной разницы в производительности не будет, если это сделано только в этом одном месте. Но важен ваш подход к написанию кода в целом. Если подходить без задротства, то в крупных и сложных проектах начнут появляться проблемы с производительностью. Решить эту задачу можно сразу "оптимальнее", по времени и количеству строк одно и то же, эффект тот же. Но в долгосрочной перспективе - как для конкретного проекта, так и для вашей карьеры в целом, больше пользы если решать задачи наиболее эффективным методом.

    ЗЫ: Задроты поймут, лентяи - нет :)
    Ответ написан
  • Почему возникает ошибка: Использован некорректный синтаксис почтового адреса?

    HeadOnFire
    @HeadOnFire Куратор тега WordPress
    PHP, Laravel & WordPress Evangelist
    Корректный синтаксис почтового адреса: name@domain.ext
    Ответ написан
  • Сделать массовый re-order (переворот порядка) WordPress-постов в кастомной таксономии (категориях)?

    HeadOnFire
    @HeadOnFire Куратор тега WordPress
    PHP, Laravel & WordPress Evangelist
    Ну, если вам нужна сортировка "вручную", то и делать ее придется вручную :)
    На самом деле можно сжульничать и частично автоматизировать или изменить программно, потом ручками пофиксить только то, что требует внимания.

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

    Второй вариант - использовать сортировку по menu_order ('orderby' => 'menu_order'). По умолчанию значение равно 0, можно точно так же выполнить WP_Query с нужными параметрами сортировки для текущих записей, потом пройтись по полученным записям циклом и установить нужный menu_order. Именно это значение используют плагины для drag-n-drop сортировки записей в админке.

    Ну и да, можно просто использовать нужную сортировку только в тех местах где надо - если это глобальный WP_Query, то через хук pre_get_posts, изолируя нужные условия, если это вторичный цикл - тогда просто через параметр order_by.
    Ответ написан
  • Есть ли события в WPForms?

    HeadOnFire
    @HeadOnFire Куратор тега WordPress
    PHP, Laravel & WordPress Evangelist
    Да, поддерживает.
    Да, все это есть в документации.

    https://wpforms.com/developers/categories/actions/
    https://wpforms.com/developers/categories/filters/
    Ответ написан
  • Как вывести в Wordpress кнопки с ссылками на страницы использующие определенный шаблон?

    HeadOnFire
    @HeadOnFire Куратор тега WordPress
    PHP, Laravel & WordPress Evangelist
    Используемый шаблон (файл, не его название) записывается в wp_postmeta, получить можно с помощью meta_query:
    $args = [
        'post_type' => 'page',
        'posts_per_page' => 100,
        // 'post__not_in' => [ get_the_ID() ], // Раскомментируйте, если хотите исключить текущую страницу
        'meta_query' => [
            [
                'key' => '_wp_page_template',
                'value' => 'custom-template.php'
            ]
        ]
    ];
    $my_pages = new WP_Query( $args );
    
    if ( $my_pages->have_posts() ) :
        while ( $my_pages->have_posts() ) : $my_pages->the_post();
            the_title( '<h3>', '</h3>' );
        endwhile;
    endif;
    
    wp_reset_postdata();
    Ответ написан
  • Как лучше делать пагинацию при натяжке на WordPress?

    HeadOnFire
    @HeadOnFire Куратор тега WordPress
    PHP, Laravel & WordPress Evangelist
    Пагинация в WordPress уже встроена из коробки, даже 2, с гибкими настройками. Первая - простая "вперед / назад", вторая - с настраиваемыми номерами страниц и тд.

    Ну а внешний вид (дизайн) с помощью CSS делаем.
    Ответ написан
  • Как создавать автоматические посты в WordPress из ленты Twitter?

    HeadOnFire
    @HeadOnFire Куратор тега WordPress
    PHP, Laravel & WordPress Evangelist
    1. Создаете свой плагин.
    2. Подключаете в нем Twitter SDK на удобном для вас языке (в случае с WP скорее всего это будет JavaScript или PHP).
    3. Пишете логику для проверки обновлений в ленте твиттер аккаунта.
    4. Пишете логику для получения контента индивидуального твита и сохранения в виде записи в WordPress.
    5. Создаете фоновую задачу, которая проверяет обновления в ленте (№3) если обновление обнаружено - получает контент и сохраняет (№4).
    6. Профит!
    Ответ написан
  • Сложный вопрос. Как сделать автоматический выбор рубрик с других таксономий?

    HeadOnFire
    @HeadOnFire Куратор тега WordPress
    PHP, Laravel & WordPress Evangelist
    Вам нужно 2 таксономии - города и типы (впрочем, и типы можно было бы дробить на отдельные таксономии, но это уже надо смотреть ТЗ и вникать, возможно на долгосрочную перспективу это имело бы смысл, возможно нет). Каждой записи вы назначаете термины отдельно друг от друга. Каждая запись должна иметь термин "город" (Киев, Москва и тд) и термины типа - один первого уровня (Рестораны, Спорт) и один или несколько второго уровня (например TRX, сквош и тренажерка в одном и том же спорткомплексе). Со структурой разобрались?

    Обратите внимание, дерево терминов "Рестораны, Спорт и тд" не под "Москва" должны быть, как у вас. Это должны быть независимые таксономии, они между собой никак не связаны. Запись получает независимо термин(ы) из одной и другой. Только запись знает о 2х таксономиях, сами таксономии друг о друге знать не должны и связи между ними быть не должно.

    С таким (правильным с точки зрения архитектуры) подходом ваш вопрос теряет смысл.
    Ответ написан
  • Как отфильтровать записи по меткам wordpress?

    HeadOnFire
    @HeadOnFire Куратор тега WordPress
    PHP, Laravel & WordPress Evangelist
    как мне получить метку по которой был осуществлен переход?

    get_queried_object()?

    On a category archive, tag archive, or other taxonomy archive page, it will return the WP_Term object of the current category, tag, or other term.
    Ответ написан
  • Как перейти от ACF PRO на Gutenberg?

    HeadOnFire
    @HeadOnFire Куратор тега WordPress
    PHP, Laravel & WordPress Evangelist
    ACF Pro помогает создавать блоки для Gutenberg с помощью PHP, это удобно и значительно ускоряет работу. Но если надо полностью отказаться от ACF Pro и использовать только Gutenberg, то придется запилить свои блоки (привет React) или же найти готовые, подходящие под ваши задачи.

    Впрочем, по некоторым блокам стоит выдохнуть и немного подумать - возможно стоит изменить свое мышление. К примеру, на ACF мы повторяющийся контент автоматом считаем рипитером и создаем соответствующие поля. А на Gutenberg часто repeater как таковой и не нужен - достаточно самого блока. Ведь создать несколько одинаковых блоков подряд в Gutenberg не составляет труда, это как бы встроено из коробки.

    Простой пример - блок testimonials. На ACF мы создаем обычно рипитер, в нем нужные поля которые будут повторяться, скажем - text, name, photo (текст отзыва, имя клиента и его аватар). А на gutenberg достаточно иметь блок testimonial с этими же полями, и просто вставить его X раз подряд - вот вам и повторяющиеся данные.
    Ответ написан
  • Как задать класс изображениям внутри записи на Wordpress?

    HeadOnFire
    @HeadOnFire Куратор тега WordPress
    PHP, Laravel & WordPress Evangelist
    Самый простой способ - на хуке the_content обычной заменой или регуляркой, но это если у картинок всегда одна структура (например, мы точно знаем что тег будет <img src="..." class="..." ...). Но вообще парсить html регулярками не самая светлая мысль - для этого есть DOMDocument:
    function add_class_to_images( $content )
    {
        $document = new DOMDocument();
        libxml_use_internal_errors(true); // чтобы не ругался на семантические HTML5 теги
        $document->loadHTML( $content );
        libxml_clear_errors();
    
        $images = $document->getElementsByTagName( 'img' );
    
        /** @var \DOMElement $image */
        foreach ( $images as $image ) {
            $image->setAttribute( 
                'class', 
                $image->getAttribute( 'class' ) . ' my-new-class'
            );
        }
    
        return $document->saveHTML();
    }
    add_filter( 'the_content', 'add_class_to_images' );
    Ответ написан
  • Как уменьшить запасы товаров в woocommerce при статусе "pending"?

    HeadOnFire
    @HeadOnFire Куратор тега WordPress
    PHP, Laravel & WordPress Evangelist
    Так, а давайте для начала определим, почему у вас заказы попадают в статусе pending?

    Потому что pending - это промежуточный, "технический" статус между созданием заказа и его оплатой с последующим переходом в статус processing (в случае успешной оплаты) или failed (в случае ошибки с оплатой или отказа).

    Методы оплаты с "отложенной оплатой" (банковский перевод, наличкой/наложенным при получении) могут использовать статус on-hold - если оплату нужно подтверждать (заказ не начнет выполняться пока не будет подтверждения платежа), или сразу processing, если подтверждение не требуется (наличкой при получении). И processing, и on-hold уменьшают сток, потому что это как раз статусы, с которыми вам и надо работать - они для этого и созданы. А pending - это немножко про другое.

    Подробнее: https://docs.woocommerce.com/document/managing-ord...
    Ответ написан
  • Почему пишет, что путь не правильный?

    HeadOnFire
    @HeadOnFire Куратор тега WordPress
    PHP, Laravel & WordPress Evangelist
    Всегда используйте абсолютные пути. Всегда. И не будет таких вопросов.
    // require '../template/items-work.php';
    require get_template_directory() . '/template/items-work.php';
    Ответ написан
  • Как очистить ключ от пробелов в meta_query?

    HeadOnFire
    @HeadOnFire Куратор тега WordPress
    PHP, Laravel & WordPress Evangelist
    Вам поможет array_map, чтобы применить определенное действие к каждому элементу массива, и preg_replace с простенькой регуляркой, который удалит все whitespace-символы.

    <?php
    // Входящие данные
    $values = [2500, '2 999'];
    
    // Очистка от пробелов
    $values = array_map(static function($value) {
        return preg_replace('/\s/', '', $value);
    }, $values);
    
    // Запрос
    $recent2 = new WP_Query(
        [
            'showposts' => 100, // Не используйте -1, используйте достаточно большое для ваших задач число
            'meta_query' => [
                [
                    'key' => 'cena', // Не называйте данные транслитом, используйтe price
                    'value' => $values,
                    'compare' => 'BETWEEN'
                ]
            ]
        ]
    );
    Ответ написан
  • Как правильно создать ajax-тему Wordpress?

    HeadOnFire
    @HeadOnFire Куратор тега WordPress
    PHP, Laravel & WordPress Evangelist
    REST API + роутинг на фронтенде
    Ответ написан
  • Как синхронизировать данные двух таблиц wp_users и wp_2_users?

    HeadOnFire
    @HeadOnFire Куратор тега WordPress
    PHP, Laravel & WordPress Evangelist
    Готов поставить ящик пива, что ваша задача решается немного другим путем. Смотрите мой ответ в другом вашем вопросе: Как сделать регистрацию на wordpress в две таблицы?
    Ответ написан
  • Как сделать регистрацию на wordpress в две таблицы?

    HeadOnFire
    @HeadOnFire Куратор тега WordPress
    PHP, Laravel & WordPress Evangelist
    Я бы вам советовал подойти к задаче с другой стороны. На самом деле пользователи должны создаваться в одной таблице, точнее в одной паре таблиц (wp_users и wp_usermeta), и храниться в единственном экземпляре. А на втором сайте вы просто указываете, что надо использовать эту пару таблиц от первого сайта. Для этого в wp-config.php есть 2 конфигурационные константы:
    define( 'CUSTOM_USER_TABLE', $table_prefix.'my_users' );
    define( 'CUSTOM_USER_META_TABLE', $table_prefix.'my_usermeta' );

    Подробнее тут.
    Ответ написан
  • Как решить проблему с 404 ошибкой при изменении количества товаров на страницу WooCommerce?

    HeadOnFire
    @HeadOnFire Куратор тега WordPress
    PHP, Laravel & WordPress Evangelist
    Если там при выборе количества записей на страницу просто добавляется параметр ?prod-count=5 к текущему URL и браузер отправляется по этому новому URL, то проще всего повесить обработчик этого get-запроса где-нибудь на template_redirect. Смотрите, есть ли GET-параметр prod-count, если да - смотрите на какой вы странице, сколько всего результатов у WC_Product_Query, сколько выводить просит prod-count. Считаете, и если получается что страница Х у вас не будет существовать - редиректите на нужную.
    Ответ написан
  • Почему не создаются посты без перезагрузки?

    HeadOnFire
    @HeadOnFire Куратор тега WordPress
    PHP, Laravel & WordPress Evangelist
    Вы не поняли как работает ajax. Данные вы отправили, пост создался. Но чтобы на странице/страницах, которые УЖЕ загружены в браузере увидеть обновления, нужно либо вручную их обновить, либо из полученного по аякс ответа сгенерировать нужный html и вставить его в эти страницы (сможете только в ту из которой инициировали загрузку). Если же вы хотите в других вкладках чтобы открытые страницы сами обновлялись когда на бекенде новые данные появились, то вам нужны другие технологии. Читайте про веб-сокеты.
    Ответ написан