【问题标题】:Wordpress inserting opening <p> tag inside of my shortcodeWordpress 在我的简码中插入开始 <p> 标记
【发布时间】:2015-11-22 00:02:03
【问题描述】:

我编写了一个小函数来在我的起始页上显示最新视频。该功能本身工作得很好。唯一的问题是,wordpress 一直在代码的一个位置插入一个打开的&lt;p&gt; 标签。 这是我的功能:

function video_start() {
// the query
$the_query = new WP_Query(array('post_type'=>'page','post_parent'=>'17','order'=>'ASC','orderby' => 'date','posts_per_page'=>1));
// The Loop 
if ( $the_query->have_posts() ) 
{
    while ( $the_query->have_posts() ) 
    {
        $the_query->the_post();
        if ( has_post_thumbnail() ) 
        {
            $picid = get_post_thumbnail_id($post_id);
            $alt_text = get_post_meta($picid , '_wp_attachment_image_alt', true);
            $string .= '<div class="featured-start">';
            $string .= '<a href="' . get_the_permalink() .'" class="b-link" rel="bookmark">';
            $string .= '<h2 class="mar-bot">Latest Video</h2>';
            $string .= '<img src="'.wp_get_attachment_url(get_post_thumbnail_id($post_id)).'" class="img-responsive" alt="'.$alt_text.'" />';
            $string .= '<p>'.get_the_title().'</p>';
            $string .= '<div class="orange-button">Watch Video</div></a></div>';
        }
    }
}
else 
{
// no posts found
}
$string .= '<div class="clear"></div>';
return $string;
/* Restore original Post Data */
wp_reset_postdata();
}
// Add a shortcode
add_shortcode('video_startpage', 'video_start');
// Enable shortcodes in text widgets
add_filter('widget_text', 'do_shortcode');

我遇到问题的输出是这样的:

<div class="featured-start">
<a href="http://www.kundenwebseite.inweco.de/videos/pet-project-09-part-1/" class="b-link" rel="bookmark"><br />
<h2 class="mar-bot">Latest Video</h2>
<p><img src="http://www.kundenwebseite.inweco.de/wp-content/uploads/2015/11/pet-project-2009-part-1.jpg" class="img-responsive" alt="" />
<p>Pet Project 09 &#8211; Part 1</p>
<div class="orange-button">Watch Video</div>
<p></a></div>
<div class="clear"></div>

我尝试了几种方法来删除 wp-autop 过滤器,但它根本不起作用。即使在使用谷歌两个多小时后,我现在也找不到解决方案。

【问题讨论】:

标签: php wordpress


【解决方案1】:

这是多年来的一个已知问题。请看Wordpress Ticket

正如其他人之前可能提到的,有一个插件可以解决这个问题。它被称为“Shortcode Empty Paragraph Fix”。它不是最好的解决方案,但还不错。

我不喜欢在我的 wp 安装中添加很多臃肿的东西 - 所以我将短代码包装在一个没有类的 div 中并解决了这个问题。

<div> [woocommerce_cart] </div>

我希望这个问题会在未来几年内得到解决;)这样我就可以删除我的 div - 我认为这是一种更省钱的方式,因为有时 funcitons.php 中的额外功能可能会导致一些问题。

【讨论】:

  • 很酷的解决方法!即使在我使用它的小部件中,wp5 中的问题仍然存在,短代码位于特殊的短代码块中。所以替换为自定义 html 块并插入您的代码并工作。
【解决方案2】:

好的。经过长时间的搜索(在史蒂夫的大力帮助下),我终于找到了解决方案。 我从

获取了 wpautop 函数(从第 456 行开始到第 604 行结束)

https://core.trac.wordpress.org/browser/tags/4.3.1/src/wp-includes/formatting.php#L0

并用提供的链接中的新 qpautop 函数替换了 /wp-includes/ 文件夹中的formatting.php 文件中的现有 wpautop 函数。 然后我将第 499 行注释掉。

所有这些都让它为我工作。

【讨论】:

  • 我完全忘记了。但它现在完成了。再次感谢您的帮助!
【解决方案3】:

Wordpress 会自动对您的内容应用 wpautop 过滤器,无论是直接添加到帖子编辑器还是由简码生成,

为了避免 wordpress 在您的内容上添加不需要的标签,

您可以用块元素包装所有内联元素,而无需向该内联元素添加新行,.e.g

&lt;div&gt;&lt;a href="#"&gt;Hello&lt;/a&gt;&lt;/div&gt;

将输出&lt;div&gt;&lt;a href="#"&gt;Hello&lt;/a&gt;&lt;/div&gt;

<div>
    <a href="#">Hello</a>
</div> 

将输出&lt;div&gt;&lt;p&gt;&lt;a href="#"&gt;Hello&lt;/a&gt;&lt;p&gt;&lt;/div&gt;

您的选择是;

  1. 将所有新行修剪为您的短代码生成的内容,但这不是一个好主意,因为您的 HTML 中没有换行符会影响 CSS 属性

return trim(preg_replace('/\s+/', ' ', $string));

  1. 用自定义格式化程序覆盖 wordpress 默认自动格式化程序,

下面的这段代码是我的主题的内置函数

功能 my_custom_content_formatter($content) { $new_content = ''; $pattern_full = '{(\[raw\].*?\[/raw\])}是'; $pattern_contents = '{\[raw\](.*?)\[/raw\]}is'; $pieces = preg_split($pattern_full, $content, -1, PREG_SPLIT_DELIM_CAPTURE); foreach ($pieces 作为 $piece) { if (preg_match($pattern_contents, $piece, $matches)) { $new_content .= $matches[1]; } 别的 { $new_content .= wptexturize(wpautop($piece)); } } 返回 $new_content; } // 移除 2 个主要的自动格式化程序 remove_filter('the_content', 'wpautop'); remove_filter('the_content', 'wptexturize'); // 应用新的自动格式化程序 add_filter('the_content', 'my_custom_content_formatter', 99); add_filter('widget_text', 'my_custom_content_formatter', 99);

然后您可以像这样添加您的短代码[raw][video_startpage][/raw]

【讨论】:

  • 感谢您的回答。我尝试了两种选择,但它们都不起作用。很抱歉您费了这么大的力气帮我解决这个问题。
  • 不太清楚为什么第二个功能不起作用,您可以尝试评论add_filter('the_content', 'my_custom_content_formatter', 99);add_filter('the_content', 'my_custom_content_formatter', 99); 然后看看wordpress wpautopwptexturize 是否仍然有效?
  • 也试过了,但没有成功。我真的不知道为什么我不能让它工作。它让我发疯。
  • 我最不明白的是,wordpress 只是在函数返回的中间添加了开始的 p 标签。根本没有结束标签。如果我仍然可以从中获得有效的 html,那么整个事情不会真正困扰我(尽管我不得不承认它现在变得有点个人化了)。但是当我检查验证器时,它给了我一个嵌套规则违规。
  • 尝试从该页面中删除所有内容并仅显示短代码的内容,检查查看源页面并检查输出元素,我也想知道为什么输出上没有结束标记,你能也发布您的简码的整个输出?从.featured-start 类开始到它的结束标签,你最好修改你的实际短代码。
【解决方案4】:

wpautop() 函数位于 wp-includes/formatting.php 中,它允许您指定是否需要 &lt;p&gt;,但似乎传递参数以将其关闭在您的情况下不起作用 - 这些方法可能有些用处。

这个使用str_replace(),这还不错,并提供了其他几个选项:

https://wordpress.org/support/topic/shortcode-is-being-surrounded-by-p-tags

也是同一页面上的一个产品,它删除了自动转换为&lt;p&gt;标签str_replace(array("\n\r", "\n", "\r"), '', $content );的换行符

这是该页面上提供的插件,但我不知道它是否可以 - 您似乎可以使用提供的功能并将其添加到您的 functions.php - 如果您有子主题 https://codex.wordpress.org/Child_Themes你可以把它放在里面的functions.php中,这样当你的父主题更新时它就不会丢失。 (被视为最佳做法)。

https://wordpress.org/plugins/shortcode-empty-paragraph-fix/

【讨论】:

  • 感谢您的建议。我也尝试过,但没有成功。
  • 这不起作用? remove_filter('do_shortcode', 'wpautop');比如 remove_filter( 'the_excerpt', 'wpautop' );
  • 我猜你可能也读过这个wordpress.org/support/topic/…
  • 再次感谢您。我什么都试过了。即使从您提供的链接中。没有任何成功。我会继续研究这个。必须有办法解决这个问题。
  • 警惕奶奶/鸡蛋的情况,但可能是时候用钳子来 wpautop() 函数内部有异常正则表达式来处理你得到的侥幸 - 也许你可以写一个 - 例子和链接到文件 // 在某些奇怪的情况下,它可能会创建一个完全空白的 P。 $pee = preg_replace('|

    \s*

    |', '', $pee); find

    replace using str_replace()

    之类的东西 - 你可以放一些愚蠢的东西,所以如果你在球场上,它就会脱颖而出。 core.trac.wordpress.org/browser/tags/4.3.1/src/wp-includes/…
【解决方案5】:

我也遇到了同样的问题,由于以上都没有真正奏效,所以我决定解决它。所以这是我的解决方案(尽管仅适用于具有结束标签的短代码)。

所以我们都在同一个页面上,如果我们在 wp 中有这个,rowcol 的基本简码可以输出具有特定类的 div编辑:

lorem test
[row]
[col]inside col[/col]
[/row]
dolor

结果输出将是:

<p>lorem test<br />
<div class="row "><div class="columns ">inside col</div></div><br />
dolor</p>

这是错误的,正确的方法应该是:

<p>lorem test</p>
<div class="row "><div class="columns ">inside col</div></div>
<p>dolor</p>

为了实现这一点,我们首先将 wpautop 过滤器替换为我们自己的

add_action('init','cod_custom_wpautop',90);
function cod_custom_wpautop() {
   remove_filter('the_content', 'wpautop');
   remove_filter('acf_the_content', 'wpautop');
   add_filter('the_content', 'cod_wpautop');
   add_filter('acf_the_content', 'cod_wpautop');
}

然后实际功能与 wp-includes/formating.php 上的功能基本相同,但我们自己进行了更改:

function cod_wpautop( $pee, $br = true ) {
$pre_tags = array();

if ( trim($pee) === '' )
    return '';

// Just to make things a little easier, pad the end.
$pee = $pee . "\n";

/*
 * Pre tags shouldn't be touched by autop.
 * Replace pre tags with placeholders and bring them back after autop.
 */
if ( strpos($pee, '<pre') !== false ) {
    $pee_parts = explode( '</pre>', $pee );
    $last_pee = array_pop($pee_parts);
    $pee = '';
    $i = 0;

    foreach ( $pee_parts as $pee_part ) {
        $start = strpos($pee_part, '<pre');

        // Malformed html?
        if ( $start === false ) {
            $pee .= $pee_part;
            continue;
        }

        $name = "<pre wp-pre-tag-$i></pre>";
        $pre_tags[$name] = substr( $pee_part, $start ) . '</pre>';

        $pee .= substr( $pee_part, 0, $start ) . $name;
        $i++;
    }

    $pee .= $last_pee;
}
// Change multiple <br>s into two line breaks, which will turn into paragraphs.
$pee = preg_replace('|<br\s*/?>\s*<br\s*/?>|', "\n\n", $pee);

$allblocks = '(?:table|thead|tfoot|caption|col|colgroup|tbody|tr|td|th|div|dl|dd|dt|ul|ol|li|pre|form|map|area|blockquote|address|math|style|p|h[1-6]|hr|fieldset|legend|section|article|aside|hgroup|header|footer|nav|figure|figcaption|details|menu|summary)';

// Add a double line break above block-level opening tags.
$pee = preg_replace('!(<' . $allblocks . '[\s/>])!', "\n\n$1", $pee);

// Add a double line break below block-level closing tags.
$pee = preg_replace('!(</' . $allblocks . '>)!', "$1\n\n", $pee);

$shortcode_blocks = '(?:row|col)';
$pee = preg_replace('!(\[' . $shortcode_blocks . '[\s/\]])!', "\n\n$1", $pee);
$pee = preg_replace('!(\[/' . $shortcode_blocks . '\])!', "$1\n\n", $pee);

// Standardize newline characters to "\n".
$pee = str_replace(array("\r\n", "\r"), "\n", $pee);

// Find newlines in all elements and add placeholders.
$pee = wp_replace_in_html_tags( $pee, array( "\n" => " <!-- wpnl --> " ) );

// Collapse line breaks before and after <option> elements so they don't get autop'd.
if ( strpos( $pee, '<option' ) !== false ) {
    $pee = preg_replace( '|\s*<option|', '<option', $pee );
    $pee = preg_replace( '|</option>\s*|', '</option>', $pee );
}

/*
 * Collapse line breaks inside <object> elements, before <param> and <embed> elements
 * so they don't get autop'd.
 */
if ( strpos( $pee, '</object>' ) !== false ) {
    $pee = preg_replace( '|(<object[^>]*>)\s*|', '$1', $pee );
    $pee = preg_replace( '|\s*</object>|', '</object>', $pee );
    $pee = preg_replace( '%\s*(</?(?:param|embed)[^>]*>)\s*%', '$1', $pee );
}

/*
 * Collapse line breaks inside <audio> and <video> elements,
 * before and after <source> and <track> elements.
 */
if ( strpos( $pee, '<source' ) !== false || strpos( $pee, '<track' ) !== false ) {
    $pee = preg_replace( '%([<\[](?:audio|video)[^>\]]*[>\]])\s*%', '$1', $pee );
    $pee = preg_replace( '%\s*([<\[]/(?:audio|video)[>\]])%', '$1', $pee );
    $pee = preg_replace( '%\s*(<(?:source|track)[^>]*>)\s*%', '$1', $pee );
}

// Remove more than two contiguous line breaks.
$pee = preg_replace("/\n\n+/", "\n\n", $pee);

// Split up the contents into an array of strings, separated by double line breaks.
$pees = preg_split('/\n\s*\n/', $pee, -1, PREG_SPLIT_NO_EMPTY);

// Reset $pee prior to rebuilding.
$pee = '';

// Rebuild the content as a string, wrapping every bit with a <p>.
foreach ( $pees as $tinkle ) {
    $pee .= '<p>' . trim($tinkle, "\n") . "</p>\n";
}

// Under certain strange conditions it could create a P of entirely whitespace.
$pee = preg_replace('|<p>\s*</p>|', '', $pee);

// Add a closing <p> inside <div>, <address>, or <form> tag if missing.
$pee = preg_replace('!<p>([^<]+)</(div|address|form)>!', "<p>$1</p></$2>", $pee);

// If an opening or closing block element tag is wrapped in a <p>, unwrap it.
$pee = preg_replace('!<p>\s*(</?' . $allblocks . '[^>]*>)\s*</p>!', "$1", $pee);
$pee = preg_replace('!<p>\s*(\[/?' . $shortcode_blocks . '[^\]]*\])\s*</p>!', "$1", $pee);

// In some cases <li> may get wrapped in <p>, fix them.
$pee = preg_replace("|<p>(<li.+?)</p>|", "$1", $pee);

// If a <blockquote> is wrapped with a <p>, move it inside the <blockquote>.
$pee = preg_replace('|<p><blockquote([^>]*)>|i', "<blockquote$1><p>", $pee);
$pee = str_replace('</blockquote></p>', '</p></blockquote>', $pee);

// If an opening or closing block element tag is preceded by an opening <p> tag, remove it.
$pee = preg_replace('!<p>\s*(</?' . $allblocks . '[^>]*>)!', "$1", $pee);
$pee = preg_replace('!<p>\s*(\[/?' . $allblocks . '[^\]]*\])!', "$1", $pee);

// If an opening or closing block element tag is followed by a closing <p> tag, remove it.
$pee = preg_replace('!(</?' . $allblocks . '[^>]*>)\s*</p>!', "$1", $pee);
$pee = preg_replace('!(\[/?' . $allblocks . '[^\]]*\])\s*</p>!', "$1", $pee);

// Optionally insert line breaks.
if ( $br ) {
    // Replace newlines that shouldn't be touched with a placeholder.
    $pee = preg_replace_callback('/<(script|style).*?<\/\\1>/s', '_autop_newline_preservation_helper', $pee);

    // Normalize <br>
    $pee = str_replace( array( '<br>', '<br/>' ), '<br />', $pee );

    // Replace any new line characters that aren't preceded by a <br /> with a <br />.
    $pee = preg_replace('|(?<!<br />)\s*\n|', "<br />\n", $pee);

    // Replace newline placeholders with newlines.
    $pee = str_replace('<WPPreserveNewline />', "\n", $pee);
}

// If a <br /> tag is after an opening or closing block tag, remove it.
$pee = preg_replace('!(</?' . $allblocks . '[^>]*>)\s*<br />!', "$1", $pee);
$pee = preg_replace('!(\[/?' . $shortcode_blocks . '[^\]]*\])\s*<br />!', "$1", $pee);

// If a <br /> tag is before a subset of opening or closing block tags, remove it.
$pee = preg_replace('!<br />(\s*</?(?:p|li|div|dl|dd|dt|th|pre|td|ul|ol)[^>]*>)!', '$1', $pee);
$pee = preg_replace( "|\n</p>$|", '</p>', $pee );

// Replace placeholder <pre> tags with their original content.
if ( !empty($pre_tags) )
    $pee = str_replace(array_keys($pre_tags), array_values($pre_tags), $pee);

// Restore newlines in all elements.
if ( false !== strpos( $pee, '<!-- wpnl -->' ) ) {
    $pee = str_replace( array( ' <!-- wpnl --> ', '<!-- wpnl -->' ), "\n", $pee );
}

return $pee;
}

为了稍微解释一下,我们添加了一个 $shortcode_blocks,它的作用与 $allblocks 相同,本质上是让它们识别为一个块,而不仅仅是一个简单的文本。这样,首先这些标签将被包裹在稍后将被删除的段落标签中。

对我有用,所以希望它对你有用;)

【讨论】:

    猜你喜欢
    • 2015-07-03
    • 1970-01-01
    • 2013-05-26
    • 2012-11-06
    • 1970-01-01
    • 2013-04-23
    • 1970-01-01
    • 1970-01-01
    • 2018-07-16
    相关资源
    最近更新 更多