Вопрос или проблема
Я хочу показать adsense ads
под 4-м и 20-м абзацами каждого блога, ТОЛЬКО если есть 20-й абзац.
Мне удалось вставить рекламу под 4-м абзацем, добавив следующий код в мой functions.php
файл, однако я не знаю, как добавить дополнительную рекламу после 20-го.
// Вставить рекламу после второго абзаца содержания единственного поста.
add_filter( 'the_content', 'prefix_insert_post_ads' );
function prefix_insert_post_ads( $content ) {
$ad_code="<div style="float:left;padding: 15px;">
<script type="text/javascript">
google_ad_client = "ca-pub-xxxxxxxxxxxx";
google_ad_slot = "xxxxxxxxxx";
google_ad_width = 300;
google_ad_height = 250;
</script>
<!-- Имя рекламы -->
<script type="text/javascript"
src="https://pagead2.googlesyndication.com/pagead/show_ads.js">
</script>
</div>";
if ( is_single() && ! is_admin() ) {
return prefix_insert_after_paragraph( $ad_code, 3, $content );
}
return $content;
}
// Родительская функция, которая творит волшебство
function prefix_insert_after_paragraph( $insertion, $paragraph_id, $content ) {
$closing_p = '</p>';
$paragraphs = explode( $closing_p, $content );
foreach ( $paragraphs as $index => $paragraph ) {
if ( trim( $paragraph ) ) {
$paragraphs[ $index ] .= $closing_p;
}
if ( $paragraph_id == $index + 1 ) {
$paragraphs[ $index ] .= $insertion;
}
}
return implode( '', $paragraphs );
}
Имейте веру 😉
К сожалению, ваш код не совсем правильный по нескольким причинам. Он предполагает, что содержание состоит только из текста, заключенного в абзацы, и не работает должным образом, если это не так.
Вот одно из решений:
add_filter('the_content', 'prefix_insert_post_ads');
/**
* Фильтр содержания
*/
function prefix_insert_post_ads($content) {
$insertion = 'Ваш код рекламы';
if (is_single() && ! is_admin()) {
return prefix_insert_after_paragraphs($content, $insertion, array(4,20));
}
return $content;
}
// Функция, которая правильно творит волшебство
function prefix_insert_after_paragraphs($content, $insertion, $paragraph_indexes) {
// находим все позиции окончания абзацев
preg_match_all('#</p>#i', $content, $matches, PREG_SET_ORDER+PREG_OFFSET_CAPTURE);
// сокращаем результаты до позиций смещения
$matches = array_map(function($match) {
return $match[0][1] + 4; // возвращаем смещение строки + длину тега </p>
}, $matches);
// сортируем индексы в обратном порядке: обычная вставка текста работает лучше в обратном порядке
rsort($paragraph_indexes);
// циклически вставляем по запросу
foreach ($paragraph_indexes as $paragraph_index) {
if ($paragraph_index <= count($matches)) {
$offset_position = $matches[$paragraph_index-1];
$content = substr($content, 0, $offset_position) . $insertion . substr($content, $offset_position);
}
}
return $content;
}
С наилучшими пожеланиями из Зальцбурга!
Чтобы правильно подсчитывать абзацы и чтобы все было последовательно, лучше всего использовать сырое содержание поста, а затем применить фильтр wpautop
к сырым данным. Таким образом, WordPress обработает все переменные, которые в конечном итоге определят, как абзацы создаются и отображаются.
Мы также можем рассмотреть несколько других вещей, чтобы сделать это максимально надежным.
-
Поскольку это нужно только для одного поста, мы будем использовать запрашиваемый объект, чтобы получить наше сырое содержание поста.
-
Убедитесь, что у нас есть минимальное количество абзацев перед вставкой нашей рекламы.
-
Используйте условие
in_the_loop()
, чтобы нацеливаться только на основной цикл запроса.
Я решил добавить все это в класс.
/**
* Класс AdsINParagraphs
*
* Класс для инъекции рекламы в содержание единственного поста между абзацами
* по необходимости
*/
class GoogleAdsINParagraphs
{
/**
* @var string $ad
* @access protected
* @since 1.1.0
*/
protected $ad;
/**
* @var int|string $min
* @access protected
* @since 1.1.0
*/
protected $min;
/**
* @var array $inject
* @access protected
* @since 1.1.0
*/
protected $inject;
/**
* @var $post = NULL
* @access protected
* @since 1.1.0
*/
protected $post = NULL;
/**
* @var $paragraphs = NULL
* @access protected
* @since 1.1.0
*/
protected $paragraphs = NULL;
/**
* @var $paraCount = 0
* @access protected
* @since 1.1.0
*/
protected $paraCount = 0;
/**
* @var $contentReplacement = NULL
* @access protected
* @since 1.1.0
*/
protected $contentReplacement = NULL;
/**
* Публичный метод __construct()
*
* Конструктор для класса GoogleAdsINParagraphs
*
* @param string $ad Реклама, которая должна быть вставлена
* @param string|int $min Минимальное количество абзацев, которые должны существовать
* @param array $inject Массив номеров абзацев, после которых необходимо вставить рекламу
* Если вам нужна реклама перед содержанием, просто передайте 0 как первое значение
* @access public
* @since 1.1.0
*/
public function __construct( $ad = NULL, $min = 4, $inject = [] )
{
$this->ad = $ad;
$this->min = $min;
$this->inject = $inject;
}
/**
* Публичный метод init()
*
* Инициализирует обратный вызов фильтра 'the_content'
*
* @access public
* @since 1.1.0
*/
public function init()
{
add_filter( 'the_content', [$this, 'postContent'] );
}
/**
* Защищенный метод initHelperMethods()
*
* Инициализирует все вспомогательные функции для обратного вызова фильтра 'the_content'
*
* @access protected
* @since 1.1.0
*/
protected function initHelperMethods()
{
$this->post();
$this->paragraphs();
$this->paraCount();
$this->contentReplacement();
}
/**
* Защищенный метод post()
*
* Получает текущий объект поста и очищает его. Очистка
* выполняется как предосторожность на случай, если запросный объект изменен каким-либо другим
* программным обеспечением/функцией/вредоносным кодом
*
* @access protected
* @since 1.1.0
*/
protected function post()
{
$post_raw = get_queried_object();
// Очистка объекта поста на случай, если что-то внешнее изменило запрашиваемый объект
$post = sanitize_post( $post_raw );
$this->post = $post;
}
/**
* Защищенный метод paragraphs()
*
* Получает содержание текущего поста, очищает его и затем применяет функцию фильтра wpautop
* к нему, чтобы применить теги p к сырым данным. После применения функции фильтра
* содержание разбивается на массив абзацев
*
* @access protected
* @since 1.1.0
*/
protected function paragraphs()
{
// На всякий случай, как дополнительная предосторожность, пропустите сырой комментарий поста через wp_kses_post
$noEvilContent = wp_kses_post( $this->post->post_content );
$peedContent = wpautop( $noEvilContent );
$paragraphs = explode( '<p>', $peedContent );
$this->paragraphs = $paragraphs;
}
/**
* Защищенный метод paraCount()
*
* Подсчитывает количество абзацев, созданных методом paragraphs()
*
* @access protected
* @since 1.1.0
*/
protected function paraCount()
{
$paraCount = count( $this->paragraphs );
$this->paraCount = (int) $paraCount;
}
/**
* Защищенный метод contentReplacement()
*
* Здесь происходит все веселое. Перед вставкой рекламы в содержание проводятся следующие проверки
* - Проверить, есть ли хотя бы минимальное количество абзацев.
* Проверки проводятся против $this->min
* - Проверить, достаточно ли абзацев, чтобы удовлетворить наименьшее
* число, переданное в $this->inject
* - Проверить, является ли $this->inject валидным массивом с значениями
*
* Если все проверки пройдены, реклама вставляется в содержание. Если любое значение
* в $this->inject больше количества абзацев, реклама игнорируется
* и не вставляется
*
* @access protected
* @since 1.1.0
*/
protected function contentReplacement()
{
// Давайте сначала проведем все наши проверки
$this->contentReplacement = $contentReplacement = NULL;
// Убедитесь, что у нас есть больше абзацев, чем минимум, иначе выходим
if ( $this->paraCount < $this->min )
return $this->contentReplacement;
// Убедитесь, что $this->inject является массивом и не пуст
if ( !is_array( $this->inject )
|| !$this->inject
)
return $this->contentReplacement;
/**
* Мы проведем следующие проверки и валидацию для $this->inject
* - проверим массив ID и удалим отрицательные числа
* - отсортируем массив $this->inject по возрастанию с числовым значением, согласно переданным ID
* - удалим возможные дубликаты
*/
$this->inject = filter_var(
$this->inject,
FILTER_VALIDATE_INT,
[
'flags' => FILTER_REQUIRE_ARRAY,
'options' => [
'min_range' => 0
]
]
);
asort( $this->inject );
$this->inject = array_unique( $this->inject );
// Убедитесь, что у нас действительно достаточно абзацев, чтобы вставить рекламу
if ( $this->paraCount < $this->inject[0] )
return $this->contentReplacement;
// Теперь мы можем начать вставлять нашу рекламу в наше содержание. Установим $output как пустую строку
$output="";
foreach ( $this->paragraphs as $key=>$paragraph ) {
// Добавим рекламу в начале содержимого, если $this->inject[0] === 0
if ( 0 === $key
&& 0 === $this->inject[0]
) {
$output .= '<p>' . $this->ad . '</p>' . $paragraph;
} elseif ( !in_array( $key, $this->inject ) ) {
$output .= $paragraph;
} else {
$output .= $paragraph . '<p>' . $this->ad . '</p>';
}
} // endforeach
$this->contentReplacement = $output;
}
/**
* Публичный метод postContent()
*
* Это метод обратного вызова для фильтра 'the_content'. Содержание, переданное по ссылке
* внутри фильтра заменяется любым валидным значением из $this->contentReplacement. Это делается
* исключительно для удобства
*
* @access public
* @since 1.1.0
* @return $content
*/
public function postContent( $content )
{
// Давайте сначала проведем наши проверки, убедимся, что это одиночная страница и основной запрос
if ( !is_single() )
return $content;
if ( !in_the_loop() )
return $content;
// Инициализируем наши другие вспомогательные методы. Они должны выполняться только внутри нашего условия
$this->initHelperMethods();
// Убедитесь, что $this->contentReplacement не NULL, если это так, просто верните $content
if ( NULL === $this->contentReplacement )
return $content;
// Теперь мы можем заменить $content на $this->contentReplacement
$content = $this->contentReplacement;
return $content;
}
} // конец класса GoogleAdsINParagraphs
Теперь вы можете использовать это следующим образом
$ad = 'РАЗМЕСТИТЕ ВАШУ РЕКЛАМУ ЗДЕСЬ';
$add_ads = new GoogleAdsINParagraphs(
$ad, // Ваша реклама, которую вы хотите добавить
4, // Должно быть как минимум 4 абзаца
[4, 20] // Массив номеров абзацев, после которых вы хотите вставить рекламу
);
$add_ads->init();
Ответ или решение
Встраивание рекламы в контент: Подробное руководство
Вопрос о том, как правильно интегрировать рекламу в содержимое блога, является актуальным для каждого владельца сайта, стремящегося заработать на своем контенте. В этой статье мы рассмотрим, как вставить рекламные объявления Google AdSense в определенные абзацы поста, с особым акцентом на возможность добавления рекламы только под 4-м и 20-м абзацами, при условии, что последний действительно существует.
1. Определение задачи
Вы хотите вставить объявления AdSense после четвертого и 20-го абзаца каждого поста. Базовая логика подразумевает, что вставка 20-го абзаца должна учитывать наличие самого абзаца. Это значит, что если пост содержит менее 20 абзацев, то дополнительная реклама не должна отображаться.
2. Функциональный код для functions.php
Мы начнем с написания функции, которая будет инжектировать объявления в нужные места в контенте. Для этого мы будем использовать WordPress Hook the_content
, который позволяет модифицировать содержимое поста перед его выводом.
Код для вставки:
add_filter('the_content', 'insert_ads_in_paragraphs');
function insert_ads_in_paragraphs($content) {
$ad_code = '<div style="float:left;padding: 15px;">
<script type="text/javascript">
google_ad_client = "ca-pub-xxxxxxxxxxxx";
google_ad_slot = "xxxxxxxxxx";
google_ad_width = 300;
google_ad_height = 250;
</script>
<script type="text/javascript" src="https://pagead2.googlesyndication.com/pagead/show_ads.js"></script>
</div>';
if (is_single() && !is_admin()) {
$content_array = explode('</p>', $content);
$ad_positions = array(4, 20);
foreach ($ad_positions as $position) {
if (isset($content_array[$position - 1])) {
$content_array[$position - 1] .= $ad_code;
}
}
return implode('</p>', $content_array);
}
return $content;
}
Разбор кода:
- Фильтр
the_content
: Используется для обработки содержимого поста перед выводом. - Строка
$ad_code
: Здесь определяется код рекламы, который будет вставлен в пост. - Проверка
is_single() && !is_admin()
: Убедитесь, что реклама вставляется только на страницах отдельных постов и не в админке. - Создание массива абзацев: Контент разбивается на массив по тегу
</p>
, что позволяет определить, где находятся абзацы. - Цикл по позициям: Для указанных позиций (4 и 20) проверяется их наличие, и если они существуют, реклама будет добавлена после соответствующего абзаца.
3. Учет специфики контента
Важно учитывать, что не все посты могут содержать требуемое количество абзацев. Например, не следует размещать рекламу после 20-го абзаца, если контент слишком короткий. Код, приведенный выше, проверяет наличие 20-го абзаца, прежде чем пытаться добавить код рекламы.
4. Завершение процесса
Для окончательной проверки работоспособности предлагаемых изменений рекомендуется протестировать код в среде разработки или на тестовом сайте, чтобы убедиться, что реклама действительно появляется только в указанных местах.
Заключение
Интеграция рекламы в сайты может казаться сложной задачей, но с правильным подходом и кодом можно легко вставить рекламные блоки в нужные места контента. Правильное планирование, использование подходящих инструментов, таких как WordPress и его хуки, а также регулярное тестирование позволят эффективно заработать на вашем контенте. Следуйте приведенным шагам, и ваш процесс интеграции рекламы станет проще и эффективнее.