如何在应用筛选函数中的内容时忽略筛选器

时间:2019-12-11 作者:Aditya Agarwal

我有一个内容过滤器,可以在我的帖子顶部添加一个目录。我从Stack Exchange本身的一个答案中获得了基本想法。

我添加过滤器如下:

add_filter(\'the_content\', array(\'TableOfContents\', \'writeTOC\'), 100);
在这之前一切都很好,但问题出现在另一个函数中。我的插件中有一个函数,它将给定帖子的前144个字符转换为元描述。现在由于上面提到的过滤器,元描述不包含我帖子的实际内容。

        $meta = apply_filters(\'the_content\', $post->post_content);
        $meta = strip_tags($meta);
        $meta = strip_shortcodes($meta );
        $meta = str_replace(array("\\n", "\\r", "\\t"), \' \', $meta);
        $meta = substr($meta, 0, 144);

相反,我的元描述包含前144个字符,包括目录。

我想从元描述中排除目录,但重新定位代码没有任何帮助。

下面我附上了完整的代码:

<?php
function Milyin_Head(){ 

global $post; 
if (!is_page()) {   
    if (!is_singular() ) {return; }
    elseif (!empty( $post->post_excerpt)) {
        $meta = $post->post_excerpt ;   
} 
    else {
        // THIS IS MY PROBLEM LINE, i USE Apply Filters for post content....
        $meta = apply_filters(\'the_content\', $post->post_content);
        $meta = strip_tags($meta);
        $meta = strip_shortcodes($meta );
        $meta = str_replace(array("\\n", "\\r", "\\t"), \' \', $meta);
        $meta = substr($meta, 0, 175);
echo \'<meta name="description" content="\'. $meta . \'"/>\'; 
echo \'<meta name="og:description" content="\'. $meta . \'"/>\';
echo \'<meta name="twitter:description" content="\'. $meta . \'"/>\';
}
}
else {
echo \'<meta name="description" content="Milyin Devotes to Make A World Having Vast Majority Of People Who are Passionate About There Work, Who feel proud to have different Thoughts, Beliefs and Opinions. Milyin Supports all those who Improve Society and bring a change."/>\'; 
echo \'<meta name="og:description" content="Milyin Devotes to Make A World Having Vast Majority Of People Who are Passionate About There Work, Who feel proud to have different Thoughts, Beliefs and Opinions. Milyin Supports all those who Improve Society and bring a change."/>\';
echo \'<meta name="twitter:description" content="Milyin Devotes to Make A World Having Vast Majority Of People Who are Passionate About There Work, Who feel proud to have different Thoughts, Beliefs and Opinions. Milyin Supports all those who Improve Society and bring a change."/>\';

}
 }
add_action(\'wp_head\', \'Milyin_Head\');


//This Function is Now Over, the Next Function Generates the Table Of Content

// Below is the Table Of Content Class, i added this for the sake of someone who wants to actually understand and in depth analyse my code. Its better to just move to bottom where i Apply The Filter

class TableOfContents {

    /**
     * Counts the occurence of header elements in Wordpress content
     * 
     * @param type $content
     * @return null|boolean|array
     */
    static function hasToc($tiers, $content) {

        $pattern = \'/<h[1-\' . $tiers . \']*[^>]*>(.*?)<\\/h([1-\' . $tiers . \'])>/\';
        $return = array();
        if (empty($content))
            return null;

        if (!preg_match_all($pattern, $content, $return)) {
            return false;
        }
        return $return;
    }

    /**
     * Generates a table of content only when singular pages are being viewed
     * 
     * @param type $tiers
     * @param type $text
     */
    static function generateTableOfContents($tiers, $content, $draw = TRUE, $return = array()) {

        if (!is_singular())
            return $content;


        $content = $toc . $content;
        $searches = array();
        $replaces = array();
        $return = (is_array($return) && !empty($return) ) ? $return : TableOfContents::hasToc($tiers, $content);

        if ($draw && !empty($return)):
             $toc = \'<div class="Milyin-Container">\';
            $toc .= "<span style=\\"font-size:18px;\\">Table of Contents</span>";
            $toc .= "<span style=\\"float:right; width: 30px;height: 30px;margin: 5px;\\" data-toggle=\\"collapse\\" data-target=\\".list\\">";
    $toc .= \'<svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" version="1.1" id="Layer_1" x="0px" y="0px" viewBox="0 0 512 512" style="enable-background:new 0 0 512 512;" xml:space="preserve"><g><g><path d="M491.318,235.318H20.682C9.26,235.318,0,244.577,0,256s9.26,20.682,20.682,20.682h470.636    c11.423,0,20.682-9.259,20.682-20.682C512,244.578,502.741,235.318,491.318,235.318z"/></g></g><g><g><path d="M491.318,78.439H20.682C9.26,78.439,0,87.699,0,99.121c0,11.422,9.26,20.682,20.682,20.682h470.636    c11.423,0,20.682-9.26,20.682-20.682C512,87.699,502.741,78.439,491.318,78.439z"/></g></g><g><g><path d="M491.318,392.197H20.682C9.26,392.197,0,401.456,0,412.879s9.26,20.682,20.682,20.682h470.636    c11.423,0,20.682-9.259,20.682-20.682S502.741,392.197,491.318,392.197z"/></g></g></svg></span>\' ;
            $toc .= "<div class=\\"list collapse\\">";
            $toc .= "<ul class=\\"parent start\\">";
            $tags = reset($return);
            $titles = $return[1];
            $url = $return[1];
            $levels = end($return);
            $_level = 2;
            $chapters = array(\'0\',\'0\',\'0\',\'0\',\'0\',\'0\');

            $count = 0;
            foreach ($tags as $i => $htag) {
                $count++;
                $attributes = array();
                $href = $url[$i];
                    $href = strtolower($href);
                    strip_tags($href);
                    $href = preg_replace("/[^a-z0-9_\\s-]/", "", $href);
                    $href = preg_replace("/[\\s-]+/", " ", $href);
                    $href = preg_replace("/[\\s_]/", "-", $href);


                $newId = \'id="\' . $href . \'"\';
                $newhtag = $newId . \'>\';
                $htagr = str_replace(\'>\' . $titles[$i], "\\t" . $newhtag  . $titles[$i], $htag);
                $searches[] = $htag;
                $replaces[] = $htagr;


                if ((int)$levels[$i] === (int)$_level):
                        $chapters[$_level-1] = ((int)$chapters[$_level-1]+1);
                        $chapter = implode(\'.\', array_slice($chapters, 1, ($levels[$i]-1)  ) );
                        $toc .= \'<li><span>\' . strval($chapter) . \'</span> <a href="#\' . $href . \'">\' . $titles[$i] . \'</a></li>\';
                endif;

                if ($levels[$i] > $_level) {
                    $_steps = ((int) $levels[$i] - (int) $_level);

                    for ($j = 0; $j < $_steps; $j++):
                        $toc .= \'<ol class="continue">\';
                        $chapters[$levels[$i]-1+$j] = (int)$chapters[$levels[$i]-1+$j]+1;
                        $_level++;
                    endfor;
                    $chapter = implode(\'.\', array_slice($chapters, 1, ($levels[$i]-1)  ) );
                        $toc .= \'<li><a href="#\' . $href . \'">\' . $titles[$i] . \'</a></li>\';
                }

                if ($levels[$i] < $_level) {

                    $_steps = ((int) $_level - (int) $levels[$i]);
                    $chapters[$levels[$i]-1] = (int)$chapters[$levels[$i]-1]+1;
                    $_olevel = $_level;
                    for ($j = 0; $j < $_steps; $j++):
                        $chapters[$levels[$i]+$j] = 0;
                        $toc .= \'</ol>\';
                        $_level--;
                    endfor;

                    $chapters[$_olevel-1] = 0;
                    $chapter = implode(\'.\', array_slice($chapters, 1, ($levels[$i]-1)  ) );

                        $toc .= \'<li><a href="#\' . $href . \'">\' . $titles[$i] . \'</a></li>\';

                }
            }
            $toc .= \'</ul>\';
            $toc .= \'</div></div><div class="clear"></div>\';
            $content = str_replace($searches, $replaces, $content);
            $content = $toc . $content;
        endif;

        return $content;
    }

    /**
     * Appends the table of content to the $content
     * AKA. Executes our filter
     * 
     * @param type $content
     * @return type
     */
    static function writeToc($content) {

        $content = TableOfContents::generateTableOfContents(4, $content, TRUE);
        return $content;
    }

}

add_filter(\'the_content\', array(\'TableOfContents\', \'writeTOC\'), 100);

// The Above Line Adds the Table Of Content Before The Post Content
// Problem is that in the first function of code, i want it to exclude this filter. I don\'t want the Table Of Content text to become my Meta Description


?>

2 个回复
最合适的回答,由SO网友:nmr 整理而成

您可以暂时将函数从挂钩中分离。

    // THIS IS MY PROBLEM LINE, i USE Apply Filters for post content....

    $priority = has_filter(\'the_content\', [\'TableOfContents\', \'writeTOC\'] );
    if ( $priority !== false )
        remove_filter(\'the_content\', [\'TableOfContents\', \'writeTOC\'], $priority );

    $meta = apply_filters(\'the_content\', $post->post_content);

    if ( $priority !== false )
        add_filter(\'the_content\', [\'TableOfContents\', \'writeTOC\'], $priority );


    $meta = strip_tags($meta);
    $meta = strip_shortcodes($meta );
Codex:

SO网友:butlerblog

也许有更好的方法可以做到这一点,但在不知道整个过程(而不是ToC)的情况下,这里有一个快速而简单的方法可以解决问题。

在为ToC过滤内容之前,为什么不将原始内容放入一个变量中,以便稍后提取?

我编辑了你的代码并添加了一个静态变量$pre_toc_content. 然后,当generateTableOfContents() 函数运行时,在对其执行任何其他操作之前,将未过滤的内容放入变量中。

您可以选择未过滤的内容以供以后使用,而不是筛选结果:

    $meta = TableOfContents::$pre_toc_content;
    $meta = strip_tags($meta);
    $meta = strip_shortcodes($meta );
    $meta = str_replace(array("\\n", "\\r", "\\t"), \' \', $meta);
    $meta = substr($meta, 0, 144);
下面是您的代码及其更改(相对较小,并进行了相应的注释):

<?php
function Milyin_Head(){ 

global $post; 
if (!is_page()) {   
    if (!is_singular() ) {return; }
    elseif (!empty( $post->post_excerpt)) {
        $meta = $post->post_excerpt ;   
} 
    else {
        // THIS IS MY PROBLEM LINE, i USE Apply Filters for post content....
        // $meta = apply_filters(\'the_content\', $post->post_content);

        // Trying it here with a static variable 
        $meta = TableOfContents::$pre_toc_content;

        // Or uncomment below to use a global variable
        global $global_pre_toc_content;
        // $meta = $global_pre_toc_content;

        $meta = strip_tags($meta);
        $meta = strip_shortcodes($meta );
        $meta = str_replace(array("\\n", "\\r", "\\t"), \' \', $meta);
        $meta = substr($meta, 0, 175);
echo \'<meta name="description" content="\'. $meta . \'"/>\'; 
echo \'<meta name="og:description" content="\'. $meta . \'"/>\';
echo \'<meta name="twitter:description" content="\'. $meta . \'"/>\';
}
}
else {
echo \'<meta name="description" content="Milyin Devotes to Make A World Having Vast Majority Of People Who are Passionate About There Work, Who feel proud to have different Thoughts, Beliefs and Opinions. Milyin Supports all those who Improve Society and bring a change."/>\'; 
echo \'<meta name="og:description" content="Milyin Devotes to Make A World Having Vast Majority Of People Who are Passionate About There Work, Who feel proud to have different Thoughts, Beliefs and Opinions. Milyin Supports all those who Improve Society and bring a change."/>\';
echo \'<meta name="twitter:description" content="Milyin Devotes to Make A World Having Vast Majority Of People Who are Passionate About There Work, Who feel proud to have different Thoughts, Beliefs and Opinions. Milyin Supports all those who Improve Society and bring a change."/>\';

}
 }
add_action(\'wp_head\', \'Milyin_Head\');


//This Function is Now Over, the Next Function Generates the Table Of Content

// Below is the Table Of Content Class, i added this for the sake of someone who wants to actually understand and in depth analyse my code. Its better to just move to bottom where i Apply The Filter

class TableOfContents {

    /**
     * A container for the unfiltered content.
     */
    static $pre_toc_content;

    /**
     * Counts the occurence of header elements in Wordpress content
     * 
     * @param type $content
     * @return null|boolean|array
     */
    static function hasToc($tiers, $content) {

        $pattern = \'/<h[1-\' . $tiers . \']*[^>]*>(.*?)<\\/h([1-\' . $tiers . \'])>/\';
        $return = array();
        if (empty($content))
            return null;

        if (!preg_match_all($pattern, $content, $return)) {
            return false;
        }
        return $return;
    }

    /**
     * Generates a table of content only when singular pages are being viewed
     * 
     * @param type $tiers
     * @param type $text
     */
    static function generateTableOfContents($tiers, $content, $draw = TRUE, $return = array()) {

        if (!is_singular())
            return $content;

        $content = $toc . $content;
        $searches = array();
        $replaces = array();
        $return = (is_array($return) && !empty($return) ) ? $return : TableOfContents::hasToc($tiers, $content);

        if ($draw && !empty($return)):
             $toc = \'<div class="Milyin-Container">\';
            $toc .= "<span style=\\"font-size:18px;\\">Table of Contents</span>";
            $toc .= "<span style=\\"float:right; width: 30px;height: 30px;margin: 5px;\\" data-toggle=\\"collapse\\" data-target=\\".list\\">";
    $toc .= \'<svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" version="1.1" id="Layer_1" x="0px" y="0px" viewBox="0 0 512 512" style="enable-background:new 0 0 512 512;" xml:space="preserve"><g><g><path d="M491.318,235.318H20.682C9.26,235.318,0,244.577,0,256s9.26,20.682,20.682,20.682h470.636    c11.423,0,20.682-9.259,20.682-20.682C512,244.578,502.741,235.318,491.318,235.318z"/></g></g><g><g><path d="M491.318,78.439H20.682C9.26,78.439,0,87.699,0,99.121c0,11.422,9.26,20.682,20.682,20.682h470.636    c11.423,0,20.682-9.26,20.682-20.682C512,87.699,502.741,78.439,491.318,78.439z"/></g></g><g><g><path d="M491.318,392.197H20.682C9.26,392.197,0,401.456,0,412.879s9.26,20.682,20.682,20.682h470.636    c11.423,0,20.682-9.259,20.682-20.682S502.741,392.197,491.318,392.197z"/></g></g></svg></span>\' ;
            $toc .= "<div class=\\"list collapse\\">";
            $toc .= "<ul class=\\"parent start\\">";
            $tags = reset($return);
            $titles = $return[1];
            $url = $return[1];
            $levels = end($return);
            $_level = 2;
            $chapters = array(\'0\',\'0\',\'0\',\'0\',\'0\',\'0\');

            $count = 0;
            foreach ($tags as $i => $htag) {
                $count++;
                $attributes = array();
                $href = $url[$i];
                    $href = strtolower($href);
                    strip_tags($href);
                    $href = preg_replace("/[^a-z0-9_\\s-]/", "", $href);
                    $href = preg_replace("/[\\s-]+/", " ", $href);
                    $href = preg_replace("/[\\s_]/", "-", $href);


                $newId = \'id="\' . $href . \'"\';
                $newhtag = $newId . \'>\';
                $htagr = str_replace(\'>\' . $titles[$i], "\\t" . $newhtag  . $titles[$i], $htag);
                $searches[] = $htag;
                $replaces[] = $htagr;


                if ((int)$levels[$i] === (int)$_level):
                        $chapters[$_level-1] = ((int)$chapters[$_level-1]+1);
                        $chapter = implode(\'.\', array_slice($chapters, 1, ($levels[$i]-1)  ) );
                        $toc .= \'<li><span>\' . strval($chapter) . \'</span> <a href="#\' . $href . \'">\' . $titles[$i] . \'</a></li>\';
                endif;

                if ($levels[$i] > $_level) {
                    $_steps = ((int) $levels[$i] - (int) $_level);

                    for ($j = 0; $j < $_steps; $j++):
                        $toc .= \'<ol class="continue">\';
                        $chapters[$levels[$i]-1+$j] = (int)$chapters[$levels[$i]-1+$j]+1;
                        $_level++;
                    endfor;
                    $chapter = implode(\'.\', array_slice($chapters, 1, ($levels[$i]-1)  ) );
                        $toc .= \'<li><a href="#\' . $href . \'">\' . $titles[$i] . \'</a></li>\';
                }

                if ($levels[$i] < $_level) {

                    $_steps = ((int) $_level - (int) $levels[$i]);
                    $chapters[$levels[$i]-1] = (int)$chapters[$levels[$i]-1]+1;
                    $_olevel = $_level;
                    for ($j = 0; $j < $_steps; $j++):
                        $chapters[$levels[$i]+$j] = 0;
                        $toc .= \'</ol>\';
                        $_level--;
                    endfor;

                    $chapters[$_olevel-1] = 0;
                    $chapter = implode(\'.\', array_slice($chapters, 1, ($levels[$i]-1)  ) );

                        $toc .= \'<li><a href="#\' . $href . \'">\' . $titles[$i] . \'</a></li>\';

                }
            }
            $toc .= \'</ul>\';
            $toc .= \'</div></div><div class="clear"></div>\';
            $content = str_replace($searches, $replaces, $content);
            $content = $toc . $content;
        endif;

        return $content;
    }

    /**
     * Appends the table of content to the $content
     * AKA. Executes our filter
     * 
     * @param type $content
     * @return type
     */
    static function writeToc($content) {

        // Put original $content into a var you can pick up later
        self::$pre_toc_content = $content;

        // Or alternatively, use a global
        global $global_pre_toc_content;
        $global_pre_toc_content = $content;

        $content = TableOfContents::generateTableOfContents(4, $content, TRUE);
        return $content;
    }

}

add_filter(\'the_content\', array(\'TableOfContents\', \'writeTOC\'), 100);

// The Above Line Adds the Table Of Content Before The Post Content
// Problem is that in the first function of code, i want it to exclude this filter. I don\'t want the Table Of Content text to become my Meta Description


?>