我写了一个小函数来在我的首页上显示最新的视频。功能本身工作得很好。唯一的问题是wordpress继续在代码的一个位置插入一个开始<p>
标记。
这是我的功能:
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 – Part 1</p>
<div class="orange-button">Watch Video</div>
<p></a></div>
<div class="clear"></div>
我尝试过几种方法删除wp-autop过滤器,但它根本无法工作。即使使用谷歌超过两个小时后,我也无法找到解决方案。
答案 0 :(得分:1)
好的。经过长时间的搜索(得到史蒂夫的大量帮助),我终于找到了解决方案。 我从
中获取了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行。
所有这一切都让它为我工作。
答案 1 :(得分:1)
这是多年来的一个已知问题。请查看Wordpress Ticket。
正如之前提到的其他人一样,有一个插件可以解决这个问题。它被称为&#34; Shortcode Empty Paragraph Fix&#34;。它不是最好的解决方案,但也不是那么糟糕。
我不喜欢在我的wp安装中放入大量的膨胀 - 所以我将短代码包装在没有类的div中并修复了问题。
<div> [woocommerce_cart] </div>
我希望这个问题会在接下来的几年内得到解决;)所以我可以删除我的div - 在我看来是一个更安全的方式,因为有时funcitons.php中的额外功能会导致一些问题。
答案 2 :(得分:0)
wpautop()函数位于wp-includes / formatting.php中,它允许您指定是否需要<p>
,但似乎传递参数以将其关闭在您的情况下不起作用 - 这些方法可能有用。
这个使用str_replace()
并不是那么糟糕,并提供了其他几个选项:
https://wordpress.org/support/topic/shortcode-is-being-surrounded-by-p-tags
也是同一页面上的一个产品,用于删除自动转换为<p>
代码str_replace(array("\n\r", "\n", "\r"), '', $content );
这是一个在该页面上提供的插件,但我不知道它是否正常 - 您似乎能够接受所提供的功能并将其添加到您的functions.php
- 如果您有一个子主题{ {3}}你可以将它放在functions.php里面,这样当你的父主题更新时它就不会丢失。 (被视为最佳实践)。
答案 3 :(得分:0)
Wordpress会自动对您的内容应用wpautop过滤器,可以直接在帖子编辑器上添加,也可以通过短代码生成,
避免wordpress在您的内容上添加不需要的标记,
您可以使用块元素包装所有内联元素,而无需向该内联元素添加新行,.e.g
<div><a href="#">Hello</a></div>
将输出<div><a href="#">Hello</a></div>
<div>
<a href="#">Hello</a>
</div>
将输出<div><p><a href="#">Hello</a><p></div>
你的选择是;
return trim(preg_replace('/\s+/', ' ', $string));
下面这段代码是我主题的内置函数
function my_custom_content_formatter($content) { $new_content = ''; $pattern_full = '{(\[raw\].*?\[/raw\])}is'; $pattern_contents = '{\[raw\](.*?)\[/raw\]}is'; $pieces = preg_split($pattern_full, $content, -1, PREG_SPLIT_DELIM_CAPTURE); foreach ($pieces as $piece) { if (preg_match($pattern_contents, $piece, $matches)) { $new_content .= $matches[1]; } else { $new_content .= wptexturize(wpautop($piece)); } } return $new_content; } // Remove the 2 main auto-formatters remove_filter('the_content', 'wpautop'); remove_filter('the_content', 'wptexturize'); // apply new auto-formatter add_filter('the_content', 'my_custom_content_formatter', 99); add_filter('widget_text', 'my_custom_content_formatter', 99);
然后,您可以添加此[raw][video_startpage][/raw]
答案 4 :(得分:0)
我遇到了同样的问题,因为上面没有任何真正有用的东西,我决定解决它。所以这是我的解决方案(虽然只适用于具有结束标记的短代码)。
正好我们在同一页面上,拥有行和 col 的基本短代码,如果我们有这个,则输出具有特定类的div在wp编辑器中:
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 完全相同,基本上可以将它们识别为块并且不只是一个简单的文字。这样,首先这些标记将包含一个段落标记,稍后将删除。
适合我,所以希望它能为你服务;)