Ответы пользователя по тегу WordPress
  • Динамический шаблон для статических страниц Wordpress?

    HeadOnFire
    @HeadOnFire
    PHP, Laravel & WordPress Evangelist
    Ответ написан
    Комментировать
  • Чем еще query_posts отличается от get_posts?

    HeadOnFire
    @HeadOnFire
    PHP, Laravel & WordPress Evangelist
    Как вам уже сказали, использовать query_posts не стоит. Вообще забудьте о существовании этой функции.

    Чем query_posts отличается от get_posts

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

    1. Код функции query_posts() из файла wp-includes/query.php
    function query_posts($query) {
    	// Первым делом, функция убивает текущий WP_Query, 
    	// запрос который был выполнен для текущей страницы,
    	// ЗАМЕНЯЯ его новым, пустым экземпляром WP_Query.
    	$GLOBALS['wp_query'] = new WP_Query();
    	// Далее, функция обращается к этому новому экземпляру,
    	// и выполняет запрос с передаными в функцию параметрами.
    	// Результаты запроса возвращаются, но при этом глобальный 
    	// изначальный WP_Query тоже ЗАМЕНЕН. То есть, данная функция 
    	// деструктивна! Она меняет глобальный объект и имеет побочные эффекты.
    	return $GLOBALS['wp_query']->query($query);
    }

    2. Код функции get_posts() из файла wp-includes/post.php
    function get_posts( $args = null ) {
    	// Функция изначально содержит некий набор параметров по умолчанию.
    	// Из важных - возвращает 5 постов, устанавливает suppress_filters в true, 
    	// что означает что все фильтры на хуках posts_* НЕ ПРИМЕНЯЮТСЯ. А вот 
    	// в том же query_posts они применяются, потому как там вызывается прямо
    	// WP_Query, у которого параметр suppress_filters по умолчанию = false.
    	$defaults = array(
    		'numberposts' => 5,
    		'category' => 0, 'orderby' => 'date',
    		'order' => 'DESC', 'include' => array(),
    		'exclude' => array(), 'meta_key' => '',
    		'meta_value' =>'', 'post_type' => 'post',
    		'suppress_filters' => true
    	);
    
    	// Берем параметры, переданные в функцию, и склеиваем их с параметрами
    	// по умолчанию.
    	$r = wp_parse_args( $args, $defaults );
    
    	// Если параметр Х не передан явно, определяем значение, которое будем использовать:
    	if ( empty( $r['post_status'] ) )
    		$r['post_status'] = ( 'attachment' == $r['post_type'] ) ? 'inherit' : 'publish';
    	if ( ! empty($r['numberposts']) && empty($r['posts_per_page']) )
    		$r['posts_per_page'] = $r['numberposts'];
    	if ( ! empty($r['category']) )
    		$r['cat'] = $r['category'];
    	if ( ! empty($r['include']) ) {
    		$incposts = wp_parse_id_list( $r['include'] );
    		$r['posts_per_page'] = count($incposts);  // only the number of posts included
    		$r['post__in'] = $incposts;
    	} elseif ( ! empty($r['exclude']) )
    		$r['post__not_in'] = wp_parse_id_list( $r['exclude'] );
    
    	// Еще один интересный параметр, "не включать в результаты запроса прилепленные посты".
    	$r['ignore_sticky_posts'] = true;
    
    	// И еще один очень важный параметр. Он означает, что не нужно считать общее количество
    	// найденных записей по нашему запросу, поскольку нам нужна всего лишь небольшая порция,
    	// никакой пагинации и тд. Это упрощает и ускоряет SQL-запрос.
    	$r['no_found_rows'] = true;
    
    	// И вот, наконец, создается НОВЫЙ экземпляр WP_Query, который НЕ ЗАМЕНЯЕТ никаких 
    	// глобальных объектов. На нем выполняется запрос со сформированными выше параметрами, 
    	// и его результат возвращается из функции наверх. 
    	// Никакого взаимодействия с глобальным scope.
    	$get_posts = new WP_Query;
    	return $get_posts->query($r);
    }


    А вот, собственно, и ответ на ваш вопрос, вот этот фрагмент функции get_posts():
    if ( empty( $r['post_status'] ) )
        $r['post_status'] = ( 'attachment' == $r['post_type'] ) ? 'inherit' : 'publish';
    Ответ написан
  • Редирект со старых страниц на новые WordPress при смене структуры URL?

    HeadOnFire
    @HeadOnFire
    PHP, Laravel & WordPress Evangelist
    Настроить переадресацию на уровне Apache / Nginx
    Ответ написан
    Комментировать
  • Свой класс элементам the_content()?

    HeadOnFire
    @HeadOnFire
    PHP, Laravel & WordPress Evangelist
    1. Хукаетесь в фильтр the_content
    add_filter( 'the_content', 'add_class_to_list' );
    2. Фильтруете контент и добавляете класс:
    function add_class_to_list( $content ) {
    
        // тут выполняете манипуляции на $content
    
        return $content;
    }


    Есть три базовых варианта как выполнять эти "манипуляции":

    2.1 Заменой подстроки
    2.2 Полноценной работой с DOM
    2.3 Регулярными выражениями

    Далее привожу первые два варианта, по порядку:

    // 2.1 - Заменой подстроки
    function add_class_to_list( $content ) {
    
        // Находим <ul> и меняем на <ul class="list2">
        $content = str_replace( '<ul>', '<ul class="list2">', $content );
    
        return $content;
    }
    add_filter( 'the_content', 'add_class_to_list' );
    
    // 2.2 - Работой с DOM
    function add_class_to_list( $content ) {
    
        $doc = new DOMDocument();
    
        // далее все необходимые манипуляции, подробности работы с DOMDocument - в документации:
        // http://php.net/manual/en/class.domdocument.php
    
        return $content;
    }
    add_filter( 'the_content', 'add_class_to_list' );


    DOMDocument полезен, когда нужно выполнять больше работы - оборачивать в дивы и тд. Регулярки бывают полезны если надо поймать вариативные данные, которые невозможно захватить с помощью str_replace.
    Ответ написан
    3 комментария
  • Из-за чего может тормозить Wordpress (точнее, именно require wp-load), тогда как чистый PHP летает, и тот же сайт на СЛАБОМ железе летает?

    HeadOnFire
    @HeadOnFire
    PHP, Laravel & WordPress Evangelist
    Есть версия, что это из-за того, что используется внешний доступ к MySQL (с которой крайне активно работает WP при загрузке) - ее я не стал переносить и оставил на хостинге. Возможно ли это?

    Конечно возможно. Соединение с внешней БД - это время. Вот оно и добавляется сверху к выполнению скрипта.
    Ответ написан
    Комментировать
  • Страница не найдена Wordpress пагинация?

    HeadOnFire
    @HeadOnFire
    PHP, Laravel & WordPress Evangelist
    Потому что пагинация строится на базе основного запроса (main WP_Query), а вы ожидаете, что она будет использовать ваш вторичный new WP_Query(). Не будет. Если хотите использовать родную пагинацию - используйте хук pre_get_posts для модификации основного запроса. Если же вам модификация основного запроса ну прям совсем не подходит (не важно по какой причине) - начните с прочтения вот этих ссылок:

    https://wordpress.stackexchange.com/questions/1204...
    callmenick.com/post/custom-wordpress-loop-with-pag...
    Ответ написан
  • Ошибка Wordpress: Is its parent directory writable by the server?

    HeadOnFire
    @HeadOnFire
    PHP, Laravel & WordPress Evangelist
    Вы что-то недопоняли на уровне *nix пользователей и прав, WordPress тут ни при чем. Во-первых, 777 ставить нельзя, никогда. Права на папки должны быть 755, на файлы - 644. А вот владелец файлов и папок должен быть веб-сервер. И владелец устанавливается с помощью команды chown, а не chmod. Chmod меняет права.
    Ответ написан
  • Ну почему мой вордпресс скрывает области виджетов?

    HeadOnFire
    @HeadOnFire
    PHP, Laravel & WordPress Evangelist
    Там же русским языком написано - данная страница, которая открыта у вас в данный момент в Customizer'е, не содержит область для виджетов. Идите на другие страницы, там будет.
    Ответ написан
    2 комментария
  • Почему не работают фильтры товаров WooCommerce?

    HeadOnFire
    @HeadOnFire
    PHP, Laravel & WordPress Evangelist
    Относительно недавно вышел WooCommerce версии 3, который пришел с breaking changes. Многие плагины еще не подтянулись. Если у вас 3я версия WC, то скорее всего несовместимость. Выхода 2 - поставить последнюю версию WC из 2го поколения или же ждать пока обновятся плагины / искать альтернативу, работающую с WC 3.
    Ответ написан
    Комментировать
  • Как получить ссылку на текущую рубрику wordpress?

    HeadOnFire
    @HeadOnFire
    PHP, Laravel & WordPress Evangelist
    А где ее получить надо? Если речь о странице архива данной рубрики - то get_queried_object() / get_queried_object_id().
    Ответ написан
  • Как правильно внести изменения в плагин?

    HeadOnFire
    @HeadOnFire
    PHP, Laravel & WordPress Evangelist
    Данный плагин, скорее всего, хукается в WooCommerce, фильтр woocommerce_product_tabs. Поэтому посмотрите где эта функция add_custom_product_tabs вызывается в add_filter. В этом вызове вы увидите приоритет и правильное обращение к самой функции (судя по коду, плагин ООП, поэтому там будет не обычная строка с именем функции). Далее с помощью remove_filter() вы его отключаете, а потом подключаете повторно, но уже с нужным вам приоритетом, примерно так:
    // примерно так это может выглядеть у них в плагине:
    add_filter( 'woocommerce_product_tabs', array( 'Plugin_Class', 'add_custom_product_tabs' ), 25 );
    
    // отключаем и подключаем повторно:
    remove_filter( 'woocommerce_product_tabs', array( 'Plugin_Class', 'add_custom_product_tabs' ) );
    add_filter( 'woocommerce_product_tabs', array( 'Plugin_Class', 'add_custom_product_tabs' ), 140 );
    Ответ написан
    2 комментария
  • Как дать редактору полномочия менять авторов статей в wordpress?

    HeadOnFire
    @HeadOnFire
    PHP, Laravel & WordPress Evangelist
    Для смены автора поста требуется capability edit_others_posts. Добавьте ее нужной роли с помощью плагина или через код.
    Ответ написан
  • Как правильно вывести тайтл сайта?

    HeadOnFire
    @HeadOnFire
    PHP, Laravel & WordPress Evangelist
    <?php 
    if ( get_field( 'section-1_title', $page_id ) ) :
    
        $title = wp_title( '', false );
        echo "{$title} – {$offer1} {$offer2}";
    
    else :
    
        wp_title();
    
    endif;
    ?>

    Хотя из вашего описания сложновато понять. Сумбурно как-то :)
    Ответ написан
    Комментировать
  • Не получается подключить картинки. WordPress их не видит. В чём моя ошибка?

    HeadOnFire
    @HeadOnFire
    PHP, Laravel & WordPress Evangelist
    У вас в статичной верстке видимо что-то типа:
    <a href="тут ссылка на пост">
        <img class="preload" src="images/u758-r.png" alt=""/>
    </a>

    В WordPress-виде это должно стать (если картинки находятся в корне сайта, в папке images):
    <a href="<?php the_permalink(); ?>">
        <img class="preload" src="<?php echo home_url( '/' ); ?>images/u758-r.png" alt=""/>
    </a>

    Если же картинки находятся в папке вашей темы, в подпапке images, то должно быть так:
    <a href="<?php the_permalink(); ?>">
        <img class="preload" src="<?php echo get_stylesheet_directory_uri(); ?>/images/u758-r.png" alt=""/>
    </a>

    Если же картинки загружены в медиа-библиотеку WP, то вызывать их вообще другим способом надо (установлены ли они как post thumbnail для ваших страничек, на которые они ведут и тд).

    Сложно подсказать вам правильное решение, не понимая как у все все устроено.
    Ответ написан
  • Как удалить ssl в wp?

    HeadOnFire
    @HeadOnFire
    PHP, Laravel & WordPress Evangelist
    Информация и комменты поступают очень скудные, но предположу, что после переноса сайта с одного сервера на другой, вам необходимо в настроках сайта в админке изменить ареса - заменить https://... на http://...

    Кроме этого нужно будет пройтись по всей базе на предмет других полных URL с https. И еще в wp-config.php посмотрите, нет ли там констант FORCE_SSL.

    И вот тут посмотрите, только вам все обратном порядке надо делать.
    Ответ написан
    5 комментариев
  • Как посадить множество проектов на вордпресс локально?

    HeadOnFire
    @HeadOnFire
    PHP, Laravel & WordPress Evangelist
    Предложенный вариант Multisite - это таки вариант, но далеко не всегда он подходит. Во-первых, один из новых сайтов сам может быть мультисайтом, во-вторых, есть некоторые различия в написании кода. В третьих, с ростом количества сайтов, учитывая что они будут разные и наборы плагинов / тем / кастомного кода тоже будут разные, управлять этим становится сложнее.

    А вообще под каждый сайт используется отдельная база данных, отдельная установка WordPress в отдельную папку проекта в /var/www/, отдельный конфиг виртуального хоста для Apache или Nginx. Это нормально. Так сервера и работают. Так и должно быть.

    Если же речь о том, можно ли эту обезьянью работу по созданию и настройке новых сайтов как-то автоматизировать, то ответ - да, можно и нужно. Для этого используется WP-CLI.
    Ответ написан
    Комментировать
  • Где найти нормальное описание WP (add_action)?

    HeadOnFire
    @HeadOnFire
    PHP, Laravel & WordPress Evangelist
    1. Хук admin_menu срабатывает в админке (wp-admin), а не для админа. Он отвечает за сборку меню в админке.
    2. Работа с ограничениями по ролям (админ, обычный пользователь и тд) идет с помощью проверок capabilities и roles.
    3. Все хуки можно найти на hookr.io, в документации WordPress и, самое главное, в исходном коде как самого ядра, так и плагинов, которые вы используете.
    4. Понимаете вы в целом правильно. Хуки - это контрольные точки, в которые можно подключаться и что-то делать - либо выполнять действия (action), модифицировать данные (filter). Важный нюанс - на один хук может навешиваться множество функций, каждой можно задавать свой приоритет. Также, не забывайте, что многие хуки принимают параметры. А еще фильтры, например, всегда должны возвращать данные (return $x).

    Впрочем, все это есть в документации.
    Ответ написан
    Комментировать
  • Как оптимизировать количество запросов в БД Wordpress, как найти самые тяжелые запросы?

    HeadOnFire
    @HeadOnFire
    PHP, Laravel & WordPress Evangelist
    У обоих принципиально разные варианты вывода, html разметки, поэтому приходится выгружать записи дважды, с разными шаблонами, в разных циклах, а потом js'ом скрывать по очереди при клике на "плиткой" - "списком".


    Вот в разных циклах не надо, посты ведь те же. Используйте rewind_posts(), что существенно сократит количество запросов. Также, смотрите в сторону object cache, кеширования запросов через механизмы transients или прямой работы с кешем.

    По поводу отладки см. ответ Денис Янчевский
    Ответ написан
    1 комментарий
  • Как указать путь к шаблону записей Вордпресс?

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

    1. Использовать template_parts для уникальных частей шаблонов. Таким образом у вас будет в корне только single.php или singular.php, а уже в них можно динамически забирать post_type и в зависимости от его значения, подключать необходимый фрагмент:
    get_template_part( 'my-templates-dir/single', get_post_type() ); // подключить my-theme/my-templates-dir/single-service.php, где 'service' - динамическая часть, возвращаемая функцией get_post_type()


    2. Хукаться в дефолтную иерархию темплейтов и подменять пути:
    function custom_template( $template ) {
    
    	if ( is_singular( 'service' )  ) {
    		return get_template_directory() . '/template/my-custom-template.php';
    	}
    
    	return $template;
    }
    add_filter( 'template_include', 'custom_template', 99 );
    Ответ написан
    Комментировать
  • Как сделать свой сабскрайбер (без рассылок и без плагинов)?

    HeadOnFire
    @HeadOnFire
    PHP, Laravel & WordPress Evangelist
    1. Создаете отдельную таблицу в БД для хранения email'ов
    2. Создаете форму подписки и ставите ее куда надо (подвал, сайдбар, тело страницы и тд)
    3. Создаете обработчик формы.
    4. Обрабатываете полученные данные и записываете в вашу таблицу в БД.
    5. Создаете отдельную страницу в админке.
    6. Выводите на этой странице записи из вашей таблицы в БД.
    Ответ написан
    Комментировать