Oprește WordPress să împacheteze imaginile în tag-uri "P"
Am căutat îndelung o soluție simplă pentru această problemă, dar fără succes. WordPress continuă să împacheteze imaginile mele în tag-uri p și, din cauza naturii excentrice a layout-ului pentru un site la care lucrez, acest lucru este extrem de deranjant.
Am creat o soluție jQuery pentru a dezîmpacheta imaginile, dar nu este foarte eficientă. Are lag din cauza altor elemente care se încarcă pe pagină și astfel modificările sunt lente. Există o modalitate de a preveni ca WordPress să împacheteze doar imaginile cu tag-uri p? Poate un hook sau un filtru care poate fi rulat.
Acest lucru se întâmplă când se încarcă o imagine și apoi se inserează în editorul WYSIWYG. Accesarea manuală a vizualizării codului și eliminarea tag-urilor p nu este o opțiune, deoarece clientul nu este atât de priceput din punct de vedere tehnic.
Înțeleg că imaginile sunt inline, dar în modul în care am codat site-ul, imaginile sunt în interiorul div-urilor și setate ca block, deci sunt cod valid.

iată ce am făcut ieri pe un site al unui client unde am avut exact această problemă... Am creat un filtru rapid ca și plugin și l-am activat.
<?php
/*
Plugin Name: Elimină tag-urile P din jurul imaginilor
Description: Plugin pentru a elimina tag-urile p din jurul imaginilor în conținutul afișat, după ce filtrul autop al WordPress le-a adăugat. (ironia sorții)
Version: 1.0
Author: Fublo Ltd
Author URI: http://fublo.net/
*/
function filter_ptags_on_images($content)
{
// facem un înlocuire cu expresie regulată...
// găsim toate tag-urile p care au doar
// <p>poate ceva spațiu alb<img tot conținutul până la /> apoi poate spațiu alb </p>
// înlocuim doar cu tag-ul de imagine...
return preg_replace('/<p>(\s*)(<img .* \/>)(\s*)<\/p>/iU', '\2', $content);
}
// vrem să ruleze după operațiunile autop... 10 este valoarea implicită.
add_filter('the_content', 'filter_ptags_on_images');
Dacă pui acest cod într-un fișier php în folderul /wp-content/plugins și apoi îl activezi, ar trebui să elimine tag-urile p din orice paragraf care conține doar o imagine.
Nu sunt sigur cât de puternică este expresia regulată în ceea ce privește posibilitatea de a eșua cu output-uri din alte editoare - de exemplu, dacă tag-ul img este închis doar cu >, va eșua. Dacă cineva are ceva mai robust, ar fi foarte util.
Salutări,
James
--- Filtru îmbunătățit ---
Pentru a funcționa cu imagini care sunt încadrate în link-uri, păstrează link-urile în output și elimină tag-urile p.
return preg_replace('/<p>\s*(<a .*>)?\s*(<img .* \/>)\s*(<\/a>)?\s*<\/p>/iU', '\1\2\3', $content);

Fără îndoială, acesta este răspunsul corect. Mulțumesc James, l-am încercat și funcționează excelent.

Salut @Dwayne - mulțumesc pentru feedback. Am adăugat un filtru îmbunătățit care va gestiona link-urile, acum îl folosim pe site-ul clientului nostru.

Ar trebui neapărat să publici asta în repository-ul de pluginuri Wordpress. O căutare rapidă pe Google arată că mulți oameni au această problemă fără o soluție bună.

Rețineți că acest lucru nu va funcționa cu marcajul implicit HTML5 img
, adică <img ...>
fără slash-ul de închidere. Este mai bine să faceți acest lucru opțional în regex. Sau, și mai bine, îl puteți omite, deoarece .*
se va ocupa de asta.

Acest lucru nu funcționează dacă există text în interiorul paragrafului.

Codul de mai jos a funcționat pentru a muta o imagine <img> în afara unui <p> chiar dacă este urmată de text:
return preg_replace('/<p>(\s*)(<img .*>)/iU', "$2<p>", $content);

@jamesc Cum s-ar putea extinde acest lucru pentru a face același lucru și pentru alte elemente, cum ar fi <iframe>?

În esență, trebuie să faci ca WordPress să trateze img ca un element de tip block în scopul formatării. Aceste elemente sunt hardcodate în wpautop()
, iar lista nu poate fi filtrată, din păcate.
Ce aș face eu:
- Fork
wpautop()
sub un nume diferit. - Adaugă
img
la regexp în variabila$allblocks
. - Elimină
wpautop
din filtrulthe_content
. - Adaugă versiunea ta modificată la
the_content
. - S-ar putea să fie nevoie să ajustezi prioritatea și eventual să elimini și să readaugi alte filtre dacă ceva se strică din cauza schimbării ordinii de procesare.

Voi încerca această abordare. Nu m-am gândit niciodată să adaug efectiv tag-ul img la variabila allblocks, asta e o idee genială. Voi vedea cum merge.

A funcționat bine la început, dar apoi am dat de scenariul când o imagine este în interiorul unui tag anchor și ambele sunt deja în interiorul unui paragraf (deci p > img > a). Cu img tratat ca un block, wp-autop închide tag-ul de paragraf înainte ca tag-ul img să înceapă, stricând layout-ul.

Am luat în considerare această abordare, dar din cauză că layout-ul este excentric, așa cum am menționat, se bazează puternic pe nevoia de tag-uri p. Fac un layout cu 2 coloane de text unde tag-urile p sunt floatate la stânga pentru a crea aparența a două coloane de text. Deci poți înțelege de ce un tag p care înfășoară o imagine ar fi o problemă, pentru că ar float-ă și aceasta.

Am luat în considerare și această opțiune și încă rămâne pe masă. Totuși, deoarece este vorba doar despre o singură imagine, pentru a evita toată agitația, aș putea folosi în schimb miniaturile articolelor recomandate, care îmi permit să controlez modul în care imaginea este afișată.

Am dezvoltat un plugin care rezolvă exact această problemă: http://wordpress.org/extend/plugins/unwrap-images/
Este mai bun decât setarea marginilor sau modificarea directă a codului WordPress pentru cei care nu doresc să se încurce cu codul, deoarece utilizează funcția nativă unwrap din jQuery pentru a elimina toate tag-urile p din jurul imaginilor.
Sper că acest lucru îi va ajuta pe cineva! Salutări, Brian

Răspunsul acceptat m-a ajutat doar cu imaginile, dar codul revizuit nu gestionează bine imaginile cu link pe site-ul meu. Acest articol de blog conține un cod care funcționează perfect.
Iată codul:
function wpautop_forked($pee, $br = 1) {
if ( trim($pee) === '' )
return '';
$pee = $pee . "\n"; // pentru a face lucrurile mai ușoare, adăugăm un newline la final
$pee = preg_replace('|<br />\s*<br />|', "\n\n", $pee);
// Adăugăm spațiere
$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); // newlines cross-platform
if ( strpos($pee, '<object') !== false ) {
$pee = preg_replace('|\s*<param([^>]*)>\s*|', "<param$1>", $pee); // nu adăugăm paragrafe în interiorul object/embed
$pee = preg_replace('|\s*</embed>\s*|', '</embed>', $pee);
}
$pee = preg_replace("/\n\n+/", "\n\n", $pee); // eliminăm duplicatele
// creăm paragrafe, inclusiv unul la final
$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); // în anumite condiții ciudate poate crea un P doar cu spații albe
$pee = preg_replace('!<p>([^<]+)</(div|address|form)>!', "<p>$1</p></$2>", $pee);
$pee = preg_replace('!<p>\s*(</?' . $allblocks . '[^>]*>)\s*</p>!', "$1", $pee); // nu adăugăm paragrafe în jurul unui tag
$pee = preg_replace("|<p>(<li.+?)</p>|", "$1", $pee); // rezolvăm problema cu listele imbricate
$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); // adăugăm linii noi opțional
$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');
Noroc!

Nu sunt expert, dar am petrecut toată după-amiaza încercând să rezolv problema imaginilor înfășurate în tag-uri p și asta a funcționat pentru mine.
Lucrez la o temă WordPress și am adăugat asta în fișierul functions.js
Funcția Jquery unwrap
$(document).ready(function (){
// pentru imagini înfășurate în tag-uri a
$('.entry a').unwrap('p');
// pentru imagini înfășurate doar în tag-uri p
$('.entry img').unwrap('p');
Acum pot lucra separat cu tag-urile p și img.
De asemenea, pot adăuga un div cu o clasă diferită în jurul imaginii folosind:
$(document).ready(function(){
$('.entry img').wrap('<div class="justImg"></div>');
Ultima variantă nu mi-a rezolvat problema pentru că voiam să fac tag-urile p cu display:none; așa că a trebuit să scot imaginile din ele.

Puneți imaginea în interiorul unui tag <div>
, fără niciun caracter de spațiu între ele. Deci în loc de:
<div class="your_container">
<div class="element1">...</div>
<div class="element2">...</div>
<img src="image.jpg" />
</div>
Scrieți așa:
<div class="your_container">
<div class="element1">...</div>
<div class="element2">...</div>
<div><img src="image.jpg" /></div>
</div>
Am avut aceeași problemă cu elementele <a>
, iar această soluție a funcționat pentru mine.

În funcție de postare, o altă soluție ar putea fi utilizarea plugin-ului WP Unformatted pentru a dezactiva funcția auto-p pe baza fiecărei postări.

Este destul de util, deși singura problemă pe care o văd este că dacă vrei ca imaginile să nu aibă tag-uri P, dar și să ai text în pagina ta, va fi o mare dezordine. Această soluție ar fi probabil bună pentru postările care au doar imagini și poate câteva rânduri de text. Totuși, util.

În cazul în care cineva caută o metodă rapidă și murdară de a rezolva această problemă pentru orice tag, iată ce am făcut eu:
- mergi la wp-content/formatting.php
- găsește funcția wpautop. (dacă nu ai observat, este WP-AUTO-P, înțelegi?)
- găsește variabila "all blocks", ar trebui să fie ceva de genul
$allblocks = '(?:table|thead|tfoot|capti...
- la final adaugă blocul pe care vrei să-l excludi -
img
,a
, etc... de exemplu, dacă se termină în(...)menu|summary)';
modifică în(...)menu|summary|a)';
pentru a adăuga tagula
și a evita autop-ul. Atenție la separatorul pipe|
- este sintaxă regex!
Asta e tot, spor la Wordpress-uit!
