如何去除WordPress正文img标签外的p标签?

WordPress作为一款方便大众的CMS,内容编辑功能有很多防呆设计。

典型例子就是,如果你在“可视化”模式下编辑文章,那么每次回车会对应生成“文本模式”下的两个换行,而在生成正文的时候,两个换行会对应生成一个<p>标签。而大多数人都是用“可视化”模式编辑的,因此就会遇到这样的问题:

问题描述

在插入图片或者视频等媒体内容的时候,媒体内容会带上一个<p>标签。举例来说,如果要插入一个图片,那么在文章页的HTML代码中……

图片会是这样的:

1
<p><img src= "图片链接"></p>

视频可能是这样的:

1
<p><iframe src= "资源链接"></p>

而普通文字是这样的:

1
<p>正文文本</p>

而众所周知,中国人的阅读习惯是首行缩进,也就是每个段落的第一行会缩进两个字符。而在WordPress里面实现的方式无非以下几种:

1.通过修改格式按钮,添加首行缩进的样式。对每个需要首行缩进的段落进行设置。

2.编辑文字时,给每个需要首行缩进的段落添加两个全角空格(<p>标签最开始的所有半角空格会被程序删除,必须用全角)。

3.通过function或者CSS,对特定<p>标签进行设置,使得<p>标签自带text-indent:2em(首行缩进两个字符的样式)属性。

对于更新频率较高的网站来说,方法1和方法2显然过于麻烦,本站尽管每周只更新5篇左右的设计文章,但也不能接受这样的方法。因此我们就选择方法2或者方法3。

但是需要考虑到这样的问题:如果修改<p>标签,那么正文中的内容会变成这样(使用CSS的方法style属性不会出现在这里,但道理是一样的):

1
2
3
<p style="text-indent:2em"><img src= "图片链接"></p>
<p style="text-indent:2em"><iframe src= "资源链接"></p>
<p style="text-indent:2em">正文文本</p>

在这种情况下,<img>内的图片和<iframe>内的视频都会被首行缩进,而最佳观赏效果必然是图片和视频居中。然而,text-indent属性不可为负,因此无法通过给<img>等标签添加样式来抵消。

解决方案 remove p from img 01 - article, sharing - 如何去除Wordpress正文img标签外的p标签?

为此,我们可以通过想办法消除<img>标签周围的<p>标签来解决这个问题。在进行这个工作之前,我们先看看网上的一段代码,来自秋叶网络博客:

1
2
3
4
5
6
//去掉图片外围标签p
function img_unautop($pee) {
$pee = preg_replace('/<p.*?>\\s*?(<a .*?><img.*?><\\/a>|<img.*?>)?\\s*<\\/p>/s', '<div class="figure">$1</div>', $pee);
return $pee;
}
add_filter( 'the_content', 'img_unautop', 30 );

将这段代码加入function.php可发挥作用。方法为点击后台的外观→编辑,右侧找到functions.php,在最下方添加完整代码。

这段代码和笔者的意图相同,博主选择使用<div>标签替换掉<img>标签。这种做法有几个好处,主要在于<div>下的元素更好控制。然而这个方法中的正则表达式是有问题的,容易出现把正文内容直接换没的情况。

因此,这里给出升级版代码,同样写在function.php内,科直接去除<img>和<iframe>外的<p>标签:

1
2
3
4
5
6
7
//去除img和iframe外的p标签
function filter_ptags_on_images($content) {
    $content = preg_replace('/&lt;p&gt;\s*(<a .*>)?\s*(<img .* \/>)\s*(<\/a>)?\s*<\/p>/iU', '\1\2\3', $content);
    return preg_replace('/&lt;p&gt;\s*(<iframe .*>*.<\/iframe>)\s*<\/p>/iU', '\1', $content);
}
add_filter('acf_the_content', 'filter_ptags_on_images');
add_filter('the_content', 'filter_ptags_on_images');

注意,如果你使用了可以修改<img>标签的插件(比如自动加如标题到alt内),可能会导致本function无效,此时需要提升优先级,采用以下代码:

1
2
3
4
5
6
7
//去除img和iframe外的p标签
function filter_ptags_on_images($content) {
    $content = preg_replace('/&lt;p&gt;\s*(<a .*>)?\s*(<img .* \/>)\s*(<\/a>)?\s*<\/p>/iU', '\1\2\3', $content);
    return preg_replace('/&lt;p&gt;\s*(<iframe .*>*.<\/iframe>)\s*<\/p>/iU', '\1', $content);
}
add_filter('acf_the_content', 'filter_ptags_on_images', 9999);
add_filter('the_content', 'filter_ptags_on_images', 9999);

除了采用上述方式,还可以用javascript实现。你可以在对应的single.php或page.php内加入下述代码实现同样的效果:

1
2
3
4
5
<script type="text/javascript">
jQuery(document).ready(function($){
    $('p > img').unwrap();
});
</script>

另外,如果你经常使用embed等标签插入媒体,可以在上述代码内相同位置加一行来实现替换。

首行缩进

在完成上述工作后,点开任何一篇带图文章刷新缓存,你应该发现<img>标签和<iframe>标签周围的<p>标签已经没有了,此时就可以针对正文内容来为每个<p>标签插入首行缩进的属性。

方法1:在function.php内插入代码:

1
2
3
4
5
6
//首行缩进
function kami_text_indent($text){
    $return = str_replace('<p', '<p style="text-indent:2em;"',$text);
    return $return;
}
add_filter('the_content',kami_text_indent');

这个方法的好处在于和上述的第一种方法可以共同使用,而且不需要找到对应的class即可快速实现。

方法2:CSS实现:

CSS实现首先要找到正文的class,你可以通过分析页面源代码查看。一般来说class是下者之一(根据主题可能不同):

1
2
3
.post .content p{}
.post .entry p{}
article p{}

你可以将上述的内容替换到下面的代码中,试试哪个对你的主题有效。注意,如果对正文有效,请注意其他地方的字体会不会受到影响。
笔者选择了直接修改single.php文件,为文章页增加了特殊的class(因为并不希望让“页面”类型的内页首行缩进),这样针对性更强。
确定好层级后,将下述代码增加到“自定义CSS”或者网站的stlye.css内(后者也可以直接找到对应的代码添加内容)。

1
2
3
.post .content p {
    text-indent:2em;
}

以上完成后,我们就实现了单独对文字内容进行首行缩进而不影响图片。如果在操作中遇到问题,欢迎微信讨论。

微信打赏支付宝打赏

感谢您的支持!

文章来源:卡米雷特的小站www.kamilet.cn)转载请注明出处。

卡米雷特

视觉控&技术控,不断学习中!


您可能还喜欢...

发表评论

电子邮件地址不会被公开。 必填项已用*标注