Остановить WordPress Wrapping Изображения в теге «P»


33

Я искал высоко и низко для простого решения этого, но безрезультатно. Wordpress продолжает оборачивать мои изображения в p-теги, и из-за эксцентричной природы макета сайта, над которым я работаю, это очень раздражает.

Я создал решение jQuery для распаковки изображений, но это не так уж и здорово. Он запаздывает из-за загрузки других материалов на странице, поэтому изменения происходят медленно. Есть ли способ предотвратить перенос Wordpress только изображения с тегами p? Возможно, можно запустить крючок или фильтр.

Это происходит при загрузке изображения, а затем вставке его в редактор WYSIWYG. Вручную войти в представление кода и удалить теги p не вариант, так как клиент не настолько технически неэффективен.

Я понимаю, что изображения встроены, но то, как у меня есть изображения, закодированные на сайте, находится внутри элементов div и настроено на блокировку, поэтому они являются действительным кодом.


Ответы:


34

вот что мы сделали вчера на клиентском сайте, с которым у нас возникла именно эта проблема ... Я создал быстрый фильтр в качестве плагина и активировал его.

<?php
/*
Plugin Name: Image P tag remover
Description: Plugin to remove p tags from around images in content outputting, after WP autop filter has added them. (oh the irony)
Version: 1.0
Author: Fublo Ltd
Author URI: http://fublo.net/
*/

function filter_ptags_on_images($content)
{
    // do a regular expression replace...
    // find all p tags that have just
    // <p>maybe some white space<img all stuff up to /> then maybe whitespace </p>
    // replace it with just the image tag...
    return preg_replace('/<p>(\s*)(<img .* \/>)(\s*)<\/p>/iU', '\2', $content);
}

// we want it to be run after the autop stuff... 10 is default.
add_filter('the_content', 'filter_ptags_on_images');

Если вы поместите его в php-файл в папке / wp-content / plugins и затем активируете его, он должен удалить теги p из любого параграфа, который просто содержит изображение.

Я не уверен, насколько сильным является регулярное выражение с точки зрения того, будет ли оно неудачным с выходами из других редакторов - например, если тег img закрыт только>, он потерпит неудачу. Если у кого-то есть что-то более сильное, это было бы очень полезно.

Ура,

Джеймс

--- Улучшенный фильтр ---

Для работы с изображениями, обернутыми в ссылки, он сохраняет ссылки в выводе и удаляет теги p.

return preg_replace('/<p>\s*(<a .*>)?\s*(<img .* \/>)\s*(<\/a>)?\s*<\/p>/iU', '\1\2\3', $content);

Без сомнения, это правильный ответ. Спасибо Джеймс, я попробовал это, и это работает потрясающе.
Дуэйн Чаррингтон

Привет @Dwayne - спасибо за отзыв. Я добавил улучшенный фильтр, который будет обрабатывать ссылки, теперь мы используем его на нашем клиентском сайте.
Jamesc

Вы должны обязательно поместить это в хранилище плагинов Wordpress. Быстрый поиск в Google показывает, что многие люди имеют эту проблему без хорошего решения.
Джеффри Бердетт

1
Обратите внимание, что это не будет работать с imgразметкой по умолчанию HTML5 , то есть <img ...>без закрывающей косой черты. Лучше сделать это необязательным в своем регулярном выражении. Или еще лучше, вы можете оставить это, как .*позаботится об этом.
Брэм Ванрой

Кто-нибудь заставил это работать <img ...>без />?
Runnick

13

По сути, вам нужно сделать так, чтобы WordPress обрабатывал img как элемент уровня блока для форматирования. Такие элементы жестко закодированы,wpautop() и список, к сожалению, не фильтруется.

Что бы я сделал, это:

  1. Вилка wpautop()под другим именем.
  2. Добавьте imgв регулярное выражение в $allblocksпеременной.
  3. Удалить wpautopиз the_contentфильтра.
  4. Добавьте свою раздвоенную версию в the_content.
  5. Возможно, вам придется поиграть с приоритетом и, возможно, удалить и повторно добавить другие фильтры, если что-то сломалось из-за изменения порядка обработки.

Я собираюсь попробовать этот подход. Я никогда не думал о добавлении тега img в переменную allblocks, это гениальная идея. Я посмотрю, как я пойду.
Дуэйн Чаррингтон

Сначала хорошо сработало, потом я попал в сценарий, когда изображение находится внутри тега привязки, и оба уже находятся внутри абзаца (поэтому p> img> a). Когда img рассматривается как блок, wp-autop закрывает тэг абзаца перед началом тэга img, разрушая макет.
benz001

2

возможно это поможет

remove_filter('the_content', 'wpautop')

Но затем вы добавите абзацы для всего остального вручную.


Я рассмотрел этот подход, но поскольку макет эксцентричен, как я уже сказал, он в значительной степени зависит от необходимости использования p-тегов. Поскольку я делаю текст с двумя столбцами, где p-теги плавают слева, чтобы создать видимость двух столбцов текста. Таким образом, вы можете понять, почему ap-тег, обертывающий изображение, будет проблемой, потому что он тоже плавает.
Дуэйн Чаррингтон

1

Соску дали один / легкий путь.

Но я извлекаю изображение из контента и отображаю его отдельно.


Я тоже обдумал это, и это все еще вариант. Однако, поскольку это всего лишь одно изображение, чтобы сохранить все хлопоты, я мог бы просто использовать вместо этого избранные миниатюры постов, которые позволили бы мне контролировать способ отображения изображения.
Дуэйн Чаррингтон

также вы можете добавить настраиваемое поле к записи / странице, например, изображение большого пальца и сохранить путь к изображению в его значении ...
Avinash

1

Этот пост немного старый, но есть гораздо более простое решение, за исключением CSS с вашей стороны.

Обертывание тега img в div имеет небольшой отрицательный эффект.


1

Я разработал плагин, который исправил эту проблему: http://wordpress.org/extend/plugins/unwrap-images/

Это лучше, чем установка поля или погружение прямо в код Wordpress для тех, кто не хочет возиться с кодом, потому что он использует встроенную функцию развертывания jQuery, чтобы развернуть все изображения своих тегов p.

Надеюсь, это поможет кому-то! Ура, Брайан


по-видимому, еще 30+ активных установок: D
Julix

1

Принятый ответ помог мне только с изображениями, но пересмотренный код плохо обрабатывает связанные изображения на моем сайте. В этом посте есть код, который отлично работает.

Вот код:

function wpautop_forked($pee, $br = 1) {

if ( trim($pee) === '' )
return '';
$pee = $pee . "\n"; // just to make things a little easier, pad the end
$pee = preg_replace('|<br />\s*<br />|', "\n\n", $pee);
// Space things out a little
$allblocks = '(?:table|thead|tfoot|caption|col|colgroup|tbody|tr|td|th|div|dl|dd|dt|ul|ol|li
|pre|select|option|form|map|area|blockquote|img|address|math|style|input
|p|h[1-6]|hr|fieldset|legend|section|article|aside|hgroup|header|footer
|nav|figure|figcaption|details|menu|summary)';
$pee = preg_replace('!(<' . $allblocks . '[^>]*>)!', "\n$1", $pee);
$pee = preg_replace('!(</' . $allblocks . '>)!', "$1\n\n", $pee);
$pee = str_replace(array("\r\n", "\r"), "\n", $pee); // cross-platform newlines
if ( strpos($pee, '<object') !== false ) {
$pee = preg_replace('|\s*<param([^>]*)>\s*|', "<param$1>", $pee); // no pee inside object/embed
$pee = preg_replace('|\s*</embed>\s*|', '</embed>', $pee);
}
$pee = preg_replace("/\n\n+/", "\n\n", $pee); // take care of duplicates
// make paragraphs, including one at the end
$pees = preg_split('/\n\s*\n/', $pee, -1, PREG_SPLIT_NO_EMPTY);
$pee = '';
foreach ( $pees as $tinkle )
$pee .= '<p>' . trim($tinkle, "\n") . "</p>\n";
$pee = preg_replace('|<p>\s*</p>|', '', $pee); // under certain strange conditions it could create a P of entirely whitespace
$pee = preg_replace('!<p>([^<]+)</(div|address|form)>!', "<p>$1</p></$2>", $pee);
$pee = preg_replace('!<p>\s*(</?' . $allblocks . '[^>]*>)\s*</p>!', "$1", $pee); // don't pee all over a tag
$pee = preg_replace("|<p>(<li.+?)</p>|", "$1", $pee); // problem with nested lists
$pee = preg_replace('|<p><blockquote([^>]*)>|i', "<blockquote$1><p>", $pee);
$pee = str_replace('</blockquote></p>', '</p></blockquote>', $pee);
$pee = preg_replace('!<p>\s*(</?' . $allblocks . '[^>]*>)!', "$1", $pee);
$pee = preg_replace('!(</?' . $allblocks . '[^>]*>)\s*</p>!', "$1", $pee);
if ($br) {
$pee = preg_replace_callback('/<(script|style).*?<\/\\1>/s', create_function('$matches', 'return str_replace("\n", "<WPPreserveNewline />", $matches[0]);'), $pee);
$pee = preg_replace('|(?<!<br />)\s*\n|', "<br />\n", $pee); // optionally make line breaks
$pee = str_replace('<WPPreserveNewline />', "\n", $pee);
}
$pee = preg_replace('!(</?' . $allblocks . '[^>]*>)\s*<br />!', "$1", $pee);
$pee = preg_replace('!<br />(\s*</?(?:p|li|div|dl|dd|dt|th|pre|td|ul|ol)[^>]*>)!', '$1', $pee);
if (strpos($pee, '<pre') !== false)
$pee = preg_replace_callback('!(<pre[^>]*>)(.*?)</pre>!is', 'clean_pre', $pee );
$pee = preg_replace( "|\n</p>$|", '</p>', $pee );

return $pee;
}

remove_filter('the_content', 'wpautop');
add_filter('the_content', 'wpautop_forked');

Ура!


1

Я не эксперт, но я провел весь день, пытаясь найти де-факто, заключенное в p-теги, и это сработало для меня.

Я работаю над темой на основе WordPress и просто добавил это в файл functions.js

Jquery функция развернуть

> $(document).ready(function (){
> 
> // for images wraped in a tags
> 
> $(‘.entry a’).unwrap(‘p’);
> 
> //for images wraped in just p tags
> $(‘.entry img’).unwrap(‘p’);

теперь я могу работать p и img отдельно.

Также можно добавить div с другим классом arround img, используя это:

$(document).ready(function (){

$('.entry img').wrap('<div class="justImg"></div>');

последний не решил мою проблему, потому что я хотел сделать p-теги с display: none; так что я действительно должен был взять эти img оттуда.


3
Вы действительно используете фигурные кавычки? :)
fuxia

Я действительно рассматривал этот подход в первый раз, когда, но мысль о ненужных манипуляциях с DOM через jQuery была слишком большой риск и потенциальные ненужные накладные расходы, когда вы можете сделать это в PHP с хитрыми регулярными выражениями.
Дуэйн Чаррингтон

0

В зависимости от публикации, другим решением может быть использование плагина WP Unformatted для отключения функции auto-p для каждого поста.


Это довольно полезно, хотя единственное предостережение, которое я вижу, это то, что если вы хотите, чтобы изображения не имели P-тегов, но содержали текст на вашей странице, это будет один большой беспорядок. Это, вероятно, было бы хорошо для постов, которые просто имеют изображения и, возможно, несколько строк текста. Тем не менее, полезно.
Дуэйн Чаррингтон

Да, именно поэтому я сказал, что это зависит от должности.
Synetech

0

В случае, если кто-то ищет быстрый и грязный способ исправить это для любого тега, вот что я сделал:

  1. перейдите в wp-content / formatting.php
  2. найти функцию wpautop. (если вы пропустили это, это WP-AUTO-P , получите это?)
  3. fins переменная "все блоки", должна быть что-то вроде $allblocks = '(?:table|thead|tfoot|capti...
  4. в конце добавьте блок, который вы хотите опустить - img, aи т. д., например, если он заканчивается (...)menu|summary)';изменением на, (...)menu|summary|a)';чтобы добавить aтег и избежать его автоматического ввода . Обратите внимание на |разделитель каналов - это синтаксис регулярных выражений !

Вот и все, счастливого Wordpressing!

Используя наш сайт, вы подтверждаете, что прочитали и поняли нашу Политику в отношении файлов cookie и Политику конфиденциальности.
Licensed under cc by-sa 3.0 with attribution required.