Category Archives: WordPress

Рекламный код внутри статьи

Итак, Вы раскрутили свой сайт до космических пределов и стали довольны собой. Люди счастливы, читая Ваш контент. Они безмерно благодарны за Вашу работу и не перестают благодарить Вас в комментариях. А ещё ежедневно делятся Вашими записями с друзьями в социальных сетях, на форумах, в личных переписках. Всё здорово.

Кроме одной детали — Вашему организму, к сожалению, требуется питание для поддержания жизненных функций. А продукты добываются деньгами, которые не дают за повышенный уровень чувства собственной важности. Реальность такова, что как бы Вам не хотелось иметь девственно чистый и непорочный сайт, капиталистический уклад общества заставит ступить на порог дома ростовщика. Либо окунуть своё творение в смердящий океан рекламы, дабы зачерпнуть средств на пропитание. Ну а я расскажу как расставить рекламные блоки по тексту без плагинов.

Для начала сам скрипт:

add_filter( 'the_content', 'ad_after_paragraph' );
function ad_after_paragraph( $content ) {
global $post;
$insert = array();
#Рекламные блоки и условия их вывода
if ( is_singular( 'post' ) ) {
$insert[ rand( 1, 4 ) ] = 'ТЕКСТ РЕКЛАМНОГО БЛОКА 1'; //Блок будет вставлен между первым и четвёртым элементом
$insert[ rand( 5, 9 ) ] = 'ТЕКСТ РЕКЛАМНОГО БЛОКА 2'; //Блок будет вставлен между пятым и девятым элементом
$insert[ 2 ] = 'ТЕКСТ РЕКЛАМНОГО БЛОКА N'; //Блок будет выведен после второго элемента, без рандомизации
} 
if ( ! empty( $insert ) ) {$content = insert_after_paragraph( $insert, $content );}return $content;}
function insert_after_paragraph( $insert = null, $content = null ) {
if ( ! is_string( $content ) ) {return false;}
if ( ! is_array( $insert ) ) {return $content;}
$closing_tag = '</p>'; //выбираем закрывающий тег, после которого выводится рекламный блок. Это может быть любой html элемент

#Здесь происходит магия
$paragraphs = explode( $closing_tag, $content );
foreach ( $paragraphs as $index =&gt; $paragraph ) {
if ( trim( $paragraph ) ) {
$paragraphs[$index] .= $closing_tag;
}
if ( array_key_exists( $index + 1, $insert ) ) {$paragraphs[$index] .= $insert[ $index + 1 ];}}
return implode( '', $paragraphs );
} 

В строке №6 я указываю условие, при котором скрипт будет обрабатывать контент. Он предназначен для вставки рекламного кода внутри поста, поэтому он не подходит для страниц архивов.

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

Строки 7-9 показывают примеры вставки кода. Внутри квадратных скобок мы указываем порядковые номера тегов от начала текста, после которых будет вставляться наш код. Команда rand позволяет в случайном порядке вставлять рекламу, тем самым, не давая привыкнуть к его расположению читателей.

Если Вы укажите большие порядковые числа тегов (например после 20-го), то ошибки это не вызовет, блок просто не будет показан. Это очень удобно, позволяет вставлять больше рекламы только на больших статьях.

На строке №15 мы указываем то, от чего зависит весь скрипт. Html тег, который считаем в тексте. Он может быть любым – p, span, h1-h6 и т.д.

В последней части скрипта разбираться не обязательно.

Собственно, всё. Добавляем сей шедевр программистской деятельности в файл functions.php Вашей темы и он начнёт работать.

Мета данные для социальных сетей на WordPress

Показываю шаблон мета данных, которые будут браться при шаринге страницы в социальные сети. Пришлось это делать потому что часто бралась не та картинка. И описание было кривое зачастую.

<?php if( is_front_page() ) { ?>
<meta property="og:title" content="Кухня SEO'шника" />
<meta property="og:image" content="http://seokitchen.ru/logo.jpg" />
<meta property="og:image:type" content="image/jpeg" />
<meta property="og:image:width" content="800" />
<meta property="og:image:height" content="800" />
<meta property="og:description" content="Ещё один сайт сетевого манимейкера" />
<meta property="og:url" content="<?php the_permalink() ?>" />
<meta property="twitter:title" content="Кухня SEO'шника" />
<meta property="twitter:description" content="Ещё один сайт сетевого манимейкера" />
<meta property="twitter:image" content="http://seokitchen.ru/logo.jpg" />
<meta property="twitter:image:width" content="800" />
<meta property="twitter:image:height" content="800" />
<?php } else { ?>
<meta property="og:title" content="<?php the_title(); ?>" />
<?php $thumb = get_post_thumbnail_id(); $img_url = image_downsize( $thumb,'full' ); ?>
<meta property="og:image" content="<?php echo $img_url[0]; ?>" />
<meta property="og:image:type" content="image/jpeg" />
<meta property="og:image:width" content="<?php echo $img_url[1] ?>" />
<meta property="og:image:height" content="<?php echo $img_url[2] ?>" />
<meta property="og:description" content="<?php truncate_post(360); ?>" />
<meta property="og:url" content="<?php the_permalink() ?>" />
<meta property="og:site_name" content="<?php bloginfo('name'); ?> - <?php bloginfo('description'); ?>." />
<meta property="twitter:url" content="<?php the_permalink() ?>" />
<meta property="twitter:title" content="<?php the_title(); ?>" />
<meta property="twitter:description" content="<?php truncate_post(360); ?>" />
<meta property="twitter:image" content="<?php echo $img_url[0]; ?>" />
<meta property="twitter:image:width" content="<?php echo $img_url[1] ?>" />
<meta property="twitter:image:height" content="<?php echo $img_url[2] ?>" />
<meta property="twitter:site" content="seokitchen.ru" />
<?php } ?>

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

Согласие на обработку персональных данных в комментариях WordPress

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

Код ниже я вставил в functions.php. Он добавляет текст согласия чуть ниже кнопки “отправить”. Возможно Вам не подойдут стили, это уже каждый под свою тему настроит.

//Добавление кнопки соглашения на обработку данных в комментариях
add_filter('comment_form_submit_field', 'add_checkbox', 10, 2);
function add_checkbox($submit_field, $args) {
   return '<!--noindex--><p><label>
   <input type="checkbox" name="agree" value="1" checked />
   Я принимаю <a href="/politic-person/" rel="nofollow" target="_blank">соглашение сайта</a> 
   об обработке персональных данных.</label>
   </p><!--/noindex-->'
   . $submit_field;
}
add_action('pre_comment_on_post', 'checkbox_test');
 
function checkbox_test($comment_post_ID) {
   if (empty($_POST['agree'])) {
      $Err = new WP_Error( 
         'comment_closed', 
         'Вы не приняли соглашение сайта об обработке персональных данных!' );
      $data = intval( $Err->get_error_data() );
      wp_die( 
         '<p>' . $Err->get_error_message() . '</p>', 
         __( 'Comment Submission Failure' ), 
         array( 'response' => $data, 'back_link' => true ) );
      exit;
   }
}

Работу кода Вы можете посмотреть на этом же блоге в комментариях.

Что касается самого текста с обработкой данных, я пользовался вот этим сервисом – tools.joomlatown.net/152/. Просто и быстро генерирует текст. Очень удобно.

Убираем название иерархического произвольного типа записи из url

Так уж вышло, что я получаю кайф от самого процесса работы. Одним словом – я задрот. Поэтому стараюсь делать вещи, которые по моему мнению добавляют красоты в сайт. Сейчас речь идёт о ссылках на записи.

Мне удобно использовать произвольные типы записи в вордпрессе. Стандартные “записи” и “страницы” зачастую не имеют необходимых мне свойств. Да и в случае косяков, произвольный тип можно удалить и создать новый, со стандартными так не выйдет. Так вот.

У вордпресса по умолчанию в записях произвольного типа подставляется слаг этого типа. О чём это я: создал я тип записей “Отчёты”. Его слаг – “otchety”. Соответственно, все записи этого типа будут иметь такой url:

site.ru/otchety/pervij

site.ru/otchety/desjatyj

site.ru/otchety/kvartalnij/1-chast

и т.д. И вот этот слаг мне жутко мозолит глаза. Во-первых он увеличивает уровень вложенности (сейчас на него в целом похер), во-вторых – не красиво. Нужно его как-то убрать.

Ниже код, который я откопал в зарубежном интернете:

/**
 * Убираем название иерархического произвольного типа записи из url
 */
 
if ( !class_exists( 'State_Rewrites' ) ) :
 
class State_Rewrites {
 
    private static $instance;
 
    public $rules;
 
    private function __construct() {
        /* Don't do anything, needs to be initialized via instance() method */
    }
 
    public static function instance() {
        if ( ! isset( self::$instance ) ) {
            self::$instance = new State_Rewrites;
            self::$instance->setup();
        }
        return self::$instance;
    }
 
    public function setup() {
        add_action( 'init',                array( $this, 'add_rewrites' ),            20 );
        add_filter( 'request',             array( $this, 'check_rewrite_conflicts' )     );
        add_filter( 'state_rewrite_rules', array( $this, 'strip_state_rules' )           );
        add_filter( 'rewrite_rules_array', array( $this, 'inject_state_rules' )          );
    }
 
    public function add_rewrites() {
        add_rewrite_tag( "%state%", '(.+?)', "state=" );
        add_permastruct( 'state', "%state%", array(
            'ep_mask' => EP_PERMALINK
        ) );
    }
 
    public function check_rewrite_conflicts( $qv ) {
        if ( isset( $qv['state'] ) ) {
            if ( get_page_by_path( $qv['state'] ) ) {
                $qv = array( 'pagename' => $qv['state'] );
            }
        }
        return $qv;
    }
 
    public function strip_state_rules( $rules ) {
        $this->rules = $rules;
        # We no longer need the attachment rules, so strip them out
        foreach ( $this->rules as $regex => $value ) {
            if ( strpos( $value, 'attachment' ) )
                unset( $this->rules[ $regex ] );
        }
        return array();
    }
 
    public function inject_state_rules( $rules ) {
        # This is the first 'page' rule
        $offset = array_search( '(.?.+?)/trackback/?$', array_keys( $rules ) );
        $page_rules = array_slice( $rules, $offset, null, true );
        $other_rules = array_slice( $rules, 0, $offset, true );
        return array_merge( $other_rules, $this->rules, $page_rules );
    }
}
 
State_Rewrites::instance();
 
endif;

Копируем его в notepad++ -> жмём Ctrl+F -> Заменить -> Заменяем “state” на слаг своего типа -> переносим в functions.php -> сохраняем. Обязательно поставьте галочку напротив “Учитывать регистр”.

Ещё один важный момент: я создаю типы записей с помощью Toolset Types, если вы тоже – обязательно в настройках снимите вот эту галочку:

иначе работать не будет. После вставки кода в функции в админке вордпресса идём в Настройки -> Постоянные ссылки и просто жмём “Сохранить изменения”.

Вуаля – надоедливый тег больше не будет преследовать.

Убираем текущую страницу в хлебных крошках от Breadcrumb NavXT

Очень давно для вывода хлебных крошек пользуюсь плагином Breadcrumb NavXT. Отличная и удобная штука, а главное для меня – нет косяков с поддержкой произвольных типов записей (уж очень я люблю их).

Но вот всё-таки некоторых нужных настроек в нём нет, а именно – удалить заголовок текущей страницы. Чтоб не было вот такого:

Это полезно, но не всегда. Делюсь рецептом исправления:

В functions.php вставляем строчки

// Убираем в хлебных крошках дублирующий заголовок текущей страницы
function bcnext_remove_current_item($trail)
{
 $types = $trail->breadcrumbs[0]->get_types();
 //Make sure we have a type and it is a current-item
 if(is_array($types) && in_array('current-item', $types))
 {
 //Shift the current item off the front
 array_shift($trail->breadcrumbs);
 }
}
add_action('bcn_after_fill', 'bcnext_remove_current_item');

Ну и всё. Текста больше не будет, останутся лишь ссылки на предыдущие записи.

Микроразметка видео на WordPress

Покопавшись в гугле, я не смог найти подробного туториала под нужды микроразметки вставляемого видео из ютуба на сайт. Да такого, чтоб раз поставил и забыл. Пришлось самому разбираться. Значится, на чистоту кода я не претендую, главное – работает.

Мой пример делает следующие вещи:

  1. Берёт id видео из адресной строки самого видео.
  2. Вставляет, собственно, само видео.
  3. Прописывает мета данные видеоролика, получаемые на основе api ютуба.

От юзверя нужно лишь вставить ссылку в произвольное поле и всё.

Вот сам код:

<?php
//получили ссылку видео из произвольного поля
$videourl = get_post_meta($post->ID, 'video_url', true); 
if(videourl){
//вытащили ID видео
$IDvideo = substr(strstr($videourl, '='), 1, strlen($videourl));
// Полезли в API Youtube, чтобы получить длительность видео
$getJSON = "https://www.googleapis.com/youtube/v3/videos?id=".$IDvideo."&part=contentDetails&key=ВАШ_КЛЮЧ_API"; 
            $data = file_get_contents($getJSON);
            $time = json_decode($data, true);
      $timevideo = $time['items'][0]['contentDetails']['duration'];
// Полезли в API Youtube, чтобы получить дату постинга видео
$getJSONdate = "https://www.googleapis.com/youtube/v3/videos?id=".$IDvideo."&part=snippet&key=ВАШ_КЛЮЧ_API";
            $datapost = file_get_contents($getJSONdate);
            $timepost = json_decode($datapost, true);
      $imgWidth = $timepost['items'][0]['snippet']['thumbnails']['maxres']['width'];
      $imgHeight = $timepost['items'][0]['snippet']['thumbnails']['maxres']['height'];
      $datepost = $timepost['items'][0]['snippet']['publishedAt'];
      //колдуем с форматом даты
      $timev = strtotime($datepost); 
      $yearv  = date( 'Y',$timev ); # Получаем год
      $monthv = date( 'm',$timev ); # Получаем месяца
      $dayv   = date( 'd',$timev ); # С помощью функции date() получаем число дня
      $datev = "$yearv-$monthv-$dayv"; # Выходная дата в формате Y-m-d

  ?>
<div  itemscope itemtype="http://schema.org/VideoObject">
<div style="display:none;">
<meta itemprop="description" content="<?php echo get_the_excerpt(); ?>">
 <meta itemprop="duration" content="<?php echo $timevideo; ?>"/>
 <link itemprop="url" href="<?php echo $videourl; ?>"/>
 <link itemprop="thumbnailUrl" href="https://img.youtube.com/vi/<?php echo $IDvideo; ?>/maxresdefault.jpg"/>
 <meta itemprop="name" content="<?php the_title(); ?>"/>
 <meta itemprop="uploadDate" content="<?php echo $datev; ?>"/>
 <meta itemprop="isFamilyFriendly" content="true"/>
 <span itemprop="thumbnail" itemscope itemtype="http://schema.org/ImageObject" >
<img itemprop="contentUrl" src="https://img.youtube.com/vi/<?php echo $IDvideo; ?>/maxresdefault.jpg" />
<meta itemprop="width" content="<?php echo $imgWidth; ?>"/>
<meta itemprop="height" content="<?php echo $imgHeight; ?>"/>
</span>
</div>
<iframe id="videoevent" width="auto" height="auto" src="https://www.youtube.com/embed/<?php echo $IDvideo; ?>" frameborder="0" allowfullscreen></iframe><div class="clear"></div>
</div>
<?php } // end videourl ?>

Для начала нам нужно добавить новое произвольное поле для записей, в которое будут вводить url видоса из ютуба. Из этой строки скрипт вытащит id.

После этого идём сюда и получаем ключ YouTube Data API. Вставляем его в местах, где написано “ВАШ_КЛЮЧ_API”.

Всё. Впендюриваем в вёрстку шаблона код выше и радуемся вот такой вот микроразметочке:

Можно вставить больше полей, но мне было лень. Кому надо, допилят код под свои нужды.