Inserting ads within content

时间:2016-01-26 作者:nofaith1

我想展示adsense ads 低于4th20th 每个博客帖子的段落,只有在20th 段落

我设法在下面插入了一则广告4th 在我的functions.php 文件,但我不知道如何在20th.

// Insert ads after second paragraph of single post content.

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>

                      <!-- Ad Name -->
                      <script type="text/javascript"
                         src="//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;
}

// Parent Function that makes the magic happen

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 );
}

2 个回复
SO网友:jjarolim

有信心;-)

不幸的是,您的代码在多个方面都不正确。它假设内容只包含由段落括起的内容,如果没有,则无法正常工作。

这将是一种解决方案:

add_filter(\'the_content\', \'prefix_insert_post_ads\');


/**
 * Content Filter 
 */
function prefix_insert_post_ads($content) {

    $insertion = \'Your AD Code\';

    if (is_single() && ! is_admin()) {
        return prefix_insert_after_paragraphs($content, $insertion, array(4,20));
    }

    return $content;

}

// Function that makes the magic happen correctly

function prefix_insert_after_paragraphs($content, $insertion, $paragraph_indexes) {

    // find all paragraph ending offsets

    preg_match_all(\'#</p>#i\', $content, $matches, PREG_SET_ORDER+PREG_OFFSET_CAPTURE);

    // reduce matches to offset positions

    $matches = array_map(function($match) {
        return $match[0][1] + 4; // return string offset + length of </p> Tag
    }, $matches);

    // reverse sort indexes: plain text insertion just works nicely in reverse order

    rsort($paragraph_indexes); 

    // cycle through and insert on demand

    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;

}
萨尔茨堡致以最良好的问候!

SO网友:Pieter Goosen

要正确计算段落数并保持一致,最好是利用原始帖子内容,然后应用wpautop 过滤到原始内容。这样,WordPress将处理所有变量,这些变量最终将决定段落的构建和显示方式

我们还可以考虑其他一些因素,以使其尽可能可靠

因为这只需要一篇文章,所以我们将使用查询的对象从中获取原始文章内容

在插入附加内容之前,确保我们有最少的段落

使用in_the_loop() 仅以主查询循环为目标的条件

-我决定将所有这些都添加到一个类中

/** 
 * Class AdsINParagraphs
 * 
 * Class to inject ads into single post\'s content between paragraphs 
 * as required
 */
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;

    /**
     * Public method __construct()
     *
     * Constructor for the GoogleAdsINParagraphs class
     *
     * @param string     $ad     The add that should be injected
     * @param string|int $min    The minimum amount of paragraphs that must exist
     * @param array      $inject An array of paragraph numbers where the add should be injected
     *                           If you need an ad before the content, simply pass 0 as first value
     * @access public
     * @since 1.1.0
     */
    public function __construct( $ad = NULL, $min = 4, $inject = [] )
    {
        $this->ad     = $ad;
        $this->min    = $min;
        $this->inject = $inject;
    }

    /**
     * Public method init()
     *
     * Initialize the \'the_content\' filter callback
     *
     * @access public
     * @since 1.1.0
     */
    public function init()
    {
        add_filter( \'the_content\', [$this, \'postContent\'] );
    }

    /**
     * Protected method initHelperMethods()
     *
     * Initialize all the helper functions for the \'the_content\' filter callback
     *
     * @access protected
     * @since 1.1.0
     */
    protected function initHelperMethods()
    {
        $this->post();
        $this->paragraphs();
        $this->paraCount();
        $this->contentReplacement();
    }


    /**
     * Protected method post()
     *
     * Gets the current post object and sanitize the post object. Sanitation 
     * is done as precaution should the query object being altered by some other
     * program/function/malicious code
     *
     * @access protected
     * @since 1.1.0
     */
    protected function post()
    {
        $post_raw   = get_queried_object();
        // Sanitize the post object in case that something externally changed the queried object
        $post       = sanitize_post( $post_raw );
        $this->post = $post;
    }

    /**
     * Protected method paragraphs()
     *
     * Gets the current post\'s post content, sanitizes it and then applies the wpautop filter
     * function to it to apply p tags to the raw content. After the filter function is applied,
     * the content is exploded into an array of paragraphs
     *
     * @access protected
     * @since 1.1.0
     */
    protected function paragraphs()
    {
        // Just in case, as extra precaution, run the raw post comment through wp_kses_post 
        $noEvilContent    = wp_kses_post( $this->post->post_content );
        $peedContent      = wpautop( $noEvilContent );
        $paragraphs       = explode( \'<p>\', $peedContent );

        $this->paragraphs = $paragraphs;
    }

    /**
     * Protected method paraCount()
     *
     * Counts the amount of paragraphs created by the paragraphs() method
     *
     * @access protected
     * @since 1.1.0
     */
    protected function paraCount()
    {
        $paraCount       = count( $this->paragraphs );

        $this->paraCount = (int) $paraCount;
    }

    /**
     * Protected method contentReplacement()
     *
     * This is where everything happens. The following checks are run
     * before ads are inserted into the content
     * - Check if there is at least the set minimum amount of paragraphs. 
     *   Checks are done against $this->min
     * - Check if there at least enough paragraphs to fullfil the lowest
     *   passed number in $this->inject
     * - Check to see if $this->inject is a valid array with values
     *
     * If all checks pass, ads is inserted into the content. If any value
     * in $this->inject is more than the amount of paragraphs, the ad is ignored
     * and not inserted
     *
     * @access protected
     * @since 1.1.0
     */
    protected function contentReplacement()
    {
        // Lets first run all our checks 

        $this->contentReplacement = $contentReplacement = NULL;

        // Make sure that we have at least more paragraphs than our minimum, bail if not
        if ( $this->paraCount < $this->min ) 
            return $this->contentReplacement;

        // Make sure that $this->inject is an array and not empty
        if (    !is_array( $this->inject ) 
             || !$this->inject
        )
            return $this->contentReplacement;

        /**
         * We will do the following checks and validation on $this->inject
         * - validate the array of ID\'s and remove negative numbers
         * - sort $this->inject array numerically ASC according to passed ID\'s 
         * - remove possible dublicates
         */
        $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 );

        // Make sure that we actaully have enough paragraphs to inject an add into 

        if ( $this->paraCount < $this->inject[0] )
            return $this->contentReplacement;

        // Now we can start to inject our ads into our content. Set $output as empty string
        $output = \'\';
        foreach ( $this->paragraphs as $key=>$paragraph ) {
            // Add ad in front of content if $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;
    }

   /**
     * Public method postContent()
     *
     * This is the callback method for the \'the_content\' filter. The content passed by reference
     * inside the filter is replaced by any valid value from $this->contentReplacement. This is done
     * purely for convenience
     *
     * @access public
     * @since 1.1.0
     * @return $content
     */
    public function postContent( $content )
    {
        // Lets first run our checks, make sure this is a single page and the main query
        if ( !is_single() )
            return $content;

        if ( !in_the_loop() )
            return $content;

        // Initialize our other helper methods. They should only run inside our condition
        $this->initHelperMethods();

        // Make sure $this->contentReplacement is not NULL, if so, just return $content
        if ( NULL === $this->contentReplacement )
            return $content;

        // We can now replace $content with $this->contentReplacement
        $content = $this->contentReplacement;

        return $content;
    }
} // end of class GoogleAdsINParagraphs
您现在可以按如下方式使用它

$ad      = \'PLACE YOUR AD HERE\';
$add_ads = new GoogleAdsINParagraphs( 
    $ad,     // Your ad which you want to add
    4,       // There should be at least 4 paragraphs
    [4, 20]  // Array of paragraph numbers after which you want to inject an add
);
$add_ads->init();

相关推荐

WP_CONTENT_DIR禁用插件目录

我有一个mutliste,它在迁移后生成file_exists(): open_basedir restriction in effect., 尽管ISPConfig中open\\u basedir的open\\u basedir设置是正确的。仅供参考,open\\u basedir设置是一个php。ini选项,将网站的php执行限制为允许的目录。ISPConfig是一个服务器控制面板。阅读后,我发现导致此问题的原因通常是以前服务器位置的上载路径不正确,因此我尝试使用以下方法解决此问题:define(\'