Category Archives: Полезное

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

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

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

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

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 Вашей темы и он начнёт работать.

Нестандартный способ выбрать ключи для СЯ

В предыдущем посте я расписал обычные, всем известные способы подобрать для себя нишу.

Здесь я расскажу об одном неявном способе, которым 93% людей даже и не думали пользоваться. Хотя он на виду.

Чужие заказы на биржах копирайтеров

Практически все биржи открыто дают информацию по чужим заказам. Даже под аккаунтом заказчика. Если нет – зарегистрироваться в качестве исполнителя и палить чужие идеи – дело 5 минут.

Я сижу на etxt и вот как пример человек пачкой выложил такое:

Несколько десятков заказов считай готового отобранного СЯ. Идём для наглядности в мутаген, проверяем на конкурентность.

Обойдёмся без оскорблений, но человек явно чересчур в розовых очках. А если это наёмный сотрудник в студии, значит без оскорблений не обойтись – он натуральный долбаёб. Мы тут видим уже готовые, отобранные, низкоконкурентные запросы. И он явно тратил деньги на сбор СЯ, тратил деньги на мутаген. Чтобы взять это всё и выложить публично.

И даже если кто-то из прочитавших мою статью воспользуется его ключами для молодого сайта – тут как бы на равных все стартуют. Хуже – если у кого-то есть старый трастовый сайт со схожей тематикой. Владелец просто закажет те же статьи и выйдет в топ гораздо быстрее, благодаря трасту домена.

Не будьте идиотами. Выложите 1-2 заказа публично, подберите адекватного исполнителя и давайте ему заказы индивидуально, чтобы никто кроме вас и его не видели тем статей. Ну или хотя бы заголовки не пишите ключами. Это полнейший зашквар.

Пассивный заработок для вебмастера с помощью XML лимитов от Яндекса

Не все ещё в курсе этой темы, поэтому посвящу тех, кто не знает.

Благодаря XML лимитов от Яши можно заработать себе на пиво с чипсами. При этом ничего не делая.

Единственное условие – это подойдёт для вебмастеров, у кого есть доступ к трастовым сайтам. Именно им Яша даёт много лимитов.

Что для этого нужно

Для начала идём сюда – xml.yandex.ru и проверяем, есть ли у вас подтверждённые домены, которым Яша выделил лимиты. У меня это вот так:

Если и у вас есть чем поживиться, тогда идём сюда –
XMLproxy.ru
и регаем личный кабинет.

После чего делаем всё по инструкции от сервиса – делегируем пользователю xmlmonster лимиты с сайта, добавляем сайт в сервисе и ждём проверки. В итоге будет вот так:

На этом всё. Бабло будет капать автоматичски ежедневно.

Не сказал бы что великие деньги. Хотя если кто-то работает сеошником в студии и есть доступ к трастовым площадкам и ваш проджект менеджер дятел то сотку-другую можно в день получать. Не делая нихуя.

У меня на 20 000 XML лимитов выходит 35 рублей за сутки. Вроде как цена динамическая, но в целом оно стабильно держится.

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

Выводят моментально, видимо держат запас денег постоянно.

В топадсенсе я видел ссылку ещё на подобный сервис и вроде там можно больше заработать – xmlstock.com. Но я не стал пробовать, потому что у них геморрой с ручным делегированием на логин клиента лимитов. А если сайтов будет дохера, а клиент перестанет платить, нужно отменять делегирование. Короче гемор. А тут один раз на общий логин передал и забыл. Удобненько.

Мета данные для социальных сетей на 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/. Просто и быстро генерирует текст. Очень удобно.

Ищем нишу для инфосайта

Самое главное, что вы должны понять – мало смысла оценивать нишу по метрике цены клика в адсенсе или РСЯ. Везде пишут одну и ту же муть про “денежные ниши”. Чтобы заработать деньги на сайте – нужен трафик. Перефразированное высказывание “Траф – король” не теряет актуальности по сей день. Если хотите заработать на сайте – выбирайте ту тему, в которой вы предполагаете что сможете получить много трафа. Эта мысль должна преследовать вас на всём пути к старту своего сайта. Если не верите мне на слово, то вот вам скриншот Спрута

Объяснять что-либо тут явно излишне.

Далее, подумайте: не помрёт ли она спустя пол года? Как пример, можно начать блог про биткойн – описывать свои феерические приключения в постройке фермы/инвестиции 100р и поднятии на скачках 1000$ и т.д. Но уверены ли вы в том что через пол года-год в нашей стране не запретят эту криптовалюту? И ваш сайт пойдет как запрещенный прямиком в кабинет отдела К. Везде и всегда есть риск, но желательно его минимизировать.

Т.к. для марафона мне нужно было найти ещё 2 темы, распишу как я это делал.

Где искать идеи

Первым делом я иду в исследования Яндекса. Очень полезная вещь. Информации в ней – море, важно её находить.

Вот, к примеру, одно из последних на данный момент исследований – Что едят за обедом пользователи поиска. Яндекс сам говорит, какие самые популярные запросы в кулинарной тематике. Первое, что бы я начал делать, при создании кулинарного статейника – спарисил бы запросы из вордстата и поисковые подсказки именно по их градации популярности.

Отсюда же можно выудить для структуры будущего сайта какие разделы будут выше, какие ниже. Какие рубрики станут основными, какие будут дополнительными. Здесь же мы можем определить перелинковку статей. И т.д. Это кладезь информации.

Аналогичный сервис исследований есть и у Google – www.thinkwithgoogle.com.

Если тут ничего не подобрали, есть еще вариант – новости. Идёте в майл, рамблер, куда угодно и смотрите что там пишут. К примеру: сейчас увидел новость “Землетрясение магнитудой 3,4 произошло в КНДР” и почему-то это натолкнуло меня на мысль про археологию. Идём в вордстат, смотрим:

Что-то в этом есть, можно покопать, разобраться, посмотреть конкурентов и т.д. Вот ещё пример: новость “На Рязанской ГРЭС прогремел взрыв”. Я почему-то сразу подумал об электричестве и проводке в доме. Идём в вордстат:

Тоже есть с чем работать, над чем подумать. И так далее.

Убираем название иерархического произвольного типа записи из 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”.

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

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