如何在wordpress的p标签计数功能中忽略计数某些p标签


How to omit counting certain p tags within p tag counting function in wordpress

我需要一些帮助我的2 WordPress功能,我在我的functions.php文件中使用,根据段落数在博客文章中推送广告代码。

当前使用的代码是什么?

下面是我目前在functions.php文件中使用的代码:

/*Add ad after 20 paragraph of post if there is more than 21 paragraph*/
add_filter( 'the_content', 'ad_20', 15 );
function ad_20( $content ) {
    global $post;
    if( check_paragraph_count_blog( $content ) > 21  ) {
        $ad_code = '...ad code goes here...';
        if ( $post->post_type == 'post' ) {
            return prefix_insert_after_paragraph( $ad_code, 20, $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 );
}
//Check paragraph count on a blog post
function check_paragraph_count_blog( $content ) {
    global $post;
    if ( $post->post_type == 'post' ) {
        $count = substr_count( $content, '</p>' );
        return $count;
    } else {
        return 0;
    }
}

你的代码有什么问题?

嗯,我的代码工作得很好,没有任何错误,但是它没有遵循我想从这段代码中得到的全部目的。

你想让你的代码做什么?

我目前使用和上面发布的代码的主要问题是prefix_insert_after_paragraph()函数&check_paragraph_count_blog()功能检查所有p标签,无论它们位于何处。但这不是我想要的,我想要以下内容:

  • 不要考虑<code>, <pre>, <code class="some-language-name">, <pre class="some-language-name>中出现的p标签。
  • 也不要考虑p标签出现在某些div标签中,例如<div class="callout some-class some-other-class">

这些特定的div标签有什么问题?

嗯,我在我的文章中使用了几个短代码来显示一些精心设计的注释,标注等。现在,如果计数器考虑这些div计数,那么它可能会在短码设计中显示广告,使整个外观和感觉都很糟糕。

示例段落输入

<p>At the time of creating any blog or news based websites most webmasters gives the least amount of importance to the commenting system of their website, without even understanding the importance of it. Eventually comment section of a website is the only place where people interact with the author when they are exited or happy with the article and helps to grow the whole website community. In most cases they end up using some third party commenting system like Disqus or Spot.im etc. without even realizing what a blunder they are making. I’ve seen many websites (both big & popular as well as small websites) using Disqus commenting system, without even realizing the consequences. And by the time you will realize it, your site would have become so big & popular they you can’t take the risk of changing your commenting system. If you are thinking why, keep reading.</p>
<p><a href="I want to omit this P from counting"><img src="I want to omit this p from counting"></a></p>
<p>As creating websites has become very easy now-a-days many non-techy people can make a websites too, but they don’t get the insights of an experienced personal. Before writing this article I’ve used disqus for months to research it thoroughly and at the same time I’ve also tried Spot.im (a new player in this arena) but in both cases I’ve come up with the same conclusion. Never ever use these third party commenting system on your website. Here are the 7 facts about Disqus and similar commenting system for which I will suggest you to stay away from them.</p>

你想从我们这里得到什么?

我需要你们的帮助。如果有人能给我提供一个重写版本的prefix_insert_after_paragraph()check_paragraph_count_blog()函数,它将通过省略我上面描述的条件来进行p标签计数和检查,这将是非常有帮助的。

提前感谢您,期待您的帮助。


关于下面的答案的一些更新

下面张贴的答案很好,没有任何问题,但请注意,它只能使用一次。例如,如果你想在你的博客文章中推送3个广告,因此创建了3个函数,如ad_10(), ad_20()ad_30(),下面的代码只能在其中任何一个中工作。如果你把它放在WordPress functions.php的多个函数中,你可能会得到空白内容。

使用DOMDocument(而不是正则表达式)可以轻松处理该任务。这个想法是选择所有不属于这些特定元素的p标签,或者换句话说,所有不属于这样一个父元素的p标签。

这都是通过XPath查询完成的:

//p[
    not(
        ancestor::div[contains(@class, 'callout') or contains(@class, 'callin')]
            or ancestor::pre
            or ancestor::code
            or a/img       # As per comments
        )
]

如果你看到,你可以发现这是一个否定的查询,它将寻找所有p元素,这些元素不是div s与calloutcallin类的子元素(你可以添加更多的类遵循类似的语法),precode元素(注意:所有precode元素)

顺便说一下,您不需要任何其他函数,所有的事情都在ad_20()

中完成。

正则表达式不是为这种复杂情况(HTML解析)设计的工具。我并不是说你不能用它来解析HTML。你可以,但除非你完全知道你在做什么。

现场演示

add_filter('the_content', 'ad_20', 15);
function ad_20($content) {
    global $post;
    $adCode = '...ad code goes here...';
    // Ad code will be added right after 20th paragraph
    $paragraphNumber = 20;
    // Convert to HTML entities
    $content = mb_convert_encoding($content, 'HTML-ENTITIES', 'UTF-8');
    if ($post->post_type == 'post') {
        libxml_use_internal_errors(true);
        // Initializing a new DOM object
        $dom = new DOMDocument;
        // Load HTML content
        $dom->loadHTML($content, LIBXML_HTML_NOIMPLIED | LIBXML_HTML_NODEFDTD);
        // Initializing a new XPath object
        $xpath = new DOMXPath($dom);
        // Query all `p` tags that their parent is not those specific elements
        $paragraphs = $xpath->query('//p[not(ancestor::div[contains(@class, ''callout'') or contains(@class, ''callin'')] or ancestor::pre or ancestor::code or a/img)]');
        // If we have a number of satisfying paragraphs
        if ($paragraphs->length > $paragraphNumber) {
            // Loading and importing javascript code
            // <span> is important
            $script = '<span>.........code.........</span>';
            $newDom = new DOMDocument;
            $newDom->loadHTML($script, LIBXML_HTML_NOIMPLIED | LIBXML_HTML_NODEFDTD);
            $node = $newDom->getElementsByTagName('span')->item(0);
            $adNode = $dom->importNode($node, true);
            // Add our ad node after `$paragraphNumber`th paragraph
            $paragraphs->item($paragraphNumber)->parentNode->insertBefore($adNode, $paragraphs->item($paragraphNumber));
        }
        libxml_use_internal_errors(false); 
        return $dom->saveHTML();
    }
    return $content;
}