Impedire a WordPress di Avvolgere le Immagini nei Tag "P"
Ho cercato ovunque una soluzione semplice a questo problema, ma senza successo. WordPress continua ad avvolgere le mie immagini in tag p e, a causa della natura eccentrica del layout del sito su cui sto lavorando, questo è molto fastidioso.
Ho creato una soluzione jQuery per rimuovere i tag dalle immagini, ma non è molto efficace. Ha dei ritardi a causa di altri elementi che si caricano sulla pagina e quindi le modifiche sono lente da applicare. Esiste un modo per impedire a WordPress di avvolgere solo le immagini con i tag p? Magari un hook o un filtro che può essere eseguito.
Questo accade quando si carica un'immagine e la si inserisce nell'editor WYSIWYG. Passare manualmente alla visualizzazione del codice e rimuovere i tag p non è un'opzione praticabile poiché il cliente non ha competenze tecniche sufficienti.
Capisco che le immagini sono elementi inline, ma nel modo in cui ho codificato il sito le immagini sono all'interno di div e impostate come block, quindi il codice è valido.

ecco cosa abbiamo fatto ieri sul sito di un cliente con cui avevamo esattamente questo problema... ho creato un filtro rapido come plugin e l'ho attivato.
<?php
/*
Plugin Name: Rimozione tag P da immagini
Description: Plugin per rimuovere i tag p attorno alle immagini nell'output del contenuto, dopo che il filtro autop di WP li ha aggiunti. (oh l'ironia)
Version: 1.0
Author: Fublo Ltd
Author URI: http://fublo.net/
*/
function filter_ptags_on_images($content)
{
// esegue una sostituzione con espressione regolare...
// trova tutti i tag p che contengono solo
// <p>eventuali spazi bianchi<img tutto fino a /> poi eventuali spazi bianchi </p>
// sostituiscili con solo il tag immagine...
return preg_replace('/<p>(\s*)(<img .* \/>)(\s*)<\/p>/iU', '\2', $content);
}
// vogliamo che venga eseguito dopo le operazioni di autop... 10 è il valore predefinito.
add_filter('the_content', 'filter_ptags_on_images');
Se inserisci questo codice in un file php nella cartella /wp-content/plugins e poi lo attivi, dovrebbe rimuovere i tag p da qualsiasi paragrafo che contiene solo un'immagine.
Non sono sicuro di quanto sia solida l'espressione regolare in termini di compatibilità con output da altri editor - per esempio fallirà se il tag img viene chiuso solo con >. Se qualcuno ha qualcosa di più robusto, sarebbe davvero utile.
Saluti,
James
--- Filtro migliorato ---
Per funzionare con immagini racchiuse in link, mantiene i link nell'output e rimuove i tag p.
return preg_replace('/<p>\s*(<a .*>)?\s*(<img .* \/>)\s*(<\/a>)?\s*<\/p>/iU', '\1\2\3', $content);

Senza dubbio, questa è la risposta corretta. Grazie James, l'ho provata e funziona alla grande.

Ciao @Dwayne - grazie per il feedback. Ho aggiunto un filtro migliorato che gestirà i link, ora lo stiamo usando sul sito del nostro cliente.

Dovresti assolutamente inserirlo nel repository dei plugin di Wordpress. Una rapida ricerca su Google mostra che molte persone hanno questo problema senza una buona soluzione.

Nota che questo non funzionerà con il markup predefinito HTML5 img
, cioè <img ...>
senza la barra di chiusura. È meglio renderlo opzionale nella tua espressione regolare. O ancora meglio, puoi ometterlo poiché .*
se ne occuperà.

Il codice qui sotto ha funzionato per spostare un'immagine <img> fuori da un <p> anche se è seguita da testo:
return preg_replace('/<p>(\s*)(<img .*>)/iU', "$2<p>", $content);

@jamesc Come si potrebbe ampliare questo per fare lo stesso con altri elementi, come <iframe>?

Fondamentalmente devi far sì che WordPress tratti img come un elemento a livello di blocco per quanto riguarda la formattazione. Questi elementi sono hardcoded in wpautop()
e purtroppo l'elenco non è filtrato.
Quello che farei è:
- Fork di
wpautop()
con un nome diverso. - Aggiungere
img
alla regex nella variabile$allblocks
. - Rimuovere
wpautop
dal filtrothe_content
. - Aggiungere la tua versione forkata a
the_content
. - Potresti aver bisogno di giocare con la priorità e possibilmente rimuovere e riaggiungere altri filtri se qualcosa si rompe a causa del cambiamento nell'ordine di elaborazione.

Proverò questo approccio. Non avevo mai pensato di aggiungere effettivamente il tag img alla variabile allblocks, è un'idea geniale. Vedrò come va.

All'inizio ha funzionato bene, poi mi sono trovato nello scenario in cui un'immagine è all'interno di un tag anchor e entrambi sono già all'interno di un paragrafo (quindi p > img > a). Con img trattato come blocco, wp-autop chiude il tag paragrafo prima che inizi il tag img, rovinando il layout.

Ho considerato questo approccio, ma poiché il layout è eccentrico come ho detto, si basa molto sulla necessità di tag p. Sto facendo una cosa con testo a 2 colonne dove i tag p sono flottati a sinistra per dare l'aspetto di 2 colonne di testo. Quindi puoi capire perché un tag p che avvolge un'immagine sarebbe un problema perché lo flotta anche quello.

Ho considerato anche questa opzione e rimane comunque una possibilità. Tuttavia, dato che si tratta solo di un'immagine per evitare tutti questi problemi, potrei semplicemente usare le miniature dei post in evidenza che mi permetterebbero di controllare come viene visualizzata l'immagine.

Ho sviluppato un plugin che risolve esattamente questo problema: http://wordpress.org/extend/plugins/unwrap-images/
È meglio che impostare i margini, o intervenire direttamente sul codice di Wordpress per coloro che non vogliono pasticciare con il codice, perché utilizza la funzione nativa unwrap di jQuery per rimuovere tutti i tag p che racchiudono le immagini.
Spero che questo possa aiutare qualcuno! Saluti, Brian

La risposta accettata mi ha aiutato solo con le immagini, ma il codice rivisto non gestisce bene le immagini collegate nel mio sito. Questo articolo del blog contiene un codice che funziona perfettamente.
Ecco il codice:
function wpautop_forked($pee, $br = 1) {
if ( trim($pee) === '' )
return '';
$pee = $pee . "\n"; // per semplificare, aggiunge un newline alla fine
$pee = preg_replace('|<br />\s*<br />|', "\n\n", $pee);
// Aggiunge spaziatura
$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); // newline cross-platform
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); // gestisce i duplicati
// crea i paragrafi, incluso uno alla fine
$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); // in alcune condizioni strane può creare un P di soli spazi
$pee = preg_replace('!<p>([^<]+)</(div|address|form)>!', "<p>$1</p></$2>", $pee);
$pee = preg_replace('!<p>\s*(</?' . $allblocks . '[^>]*>)\s*</p>!', "$1", $pee); // non modificare i tag
$pee = preg_replace("|<p>(<li.+?)</p>|", "$1", $pee); // problema con liste annidate
$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); // opzionalmente aggiunge interruzioni di riga
$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');
Saluti!

Non sono un esperto ma ho passato tutto il pomeriggio cercando di risolvere il problema delle img avvolte nei tag p e questo ha funzionato per me.
Sto lavorando su un tema basato su WordPress e ho appena aggiunto questo al file functions.js
Funzione jQuery unwrap
> $(document).ready(function (){
>
> // per immagini avvolte in tag a
>
> $(‘.entry a’).unwrap(‘p’);
>
> // per immagini avvolte solo in tag p
> $(‘.entry img’).unwrap(‘p’);
Ora posso lavorare con i tag p e img separatamente.
Posso anche aggiungere un div con una classe diversa attorno all'img usando questo codice:
$(document).ready(function (){
$('.entry img').wrap('<div class="justImg"></div>');
Quest'ultimo non ha risolto il mio problema perché volevo impostare i tag p con display:none; quindi dovevo davvero togliere quelle img da lì.

Inserisci la tua immagine all'interno di un tag <div>
, senza alcun carattere di spazio bianco tra di loro. Quindi invece di:
<div class="your_container">
<div class="element1">...</div>
<div class="element2">...</div>
<img src="image.jpg" />
</div>
Scrivi così:
<div class="your_container">
<div class="element1">...</div>
<div class="element2">...</div>
<div><img src="image.jpg" /></div>
</div>
Ho avuto lo stesso problema con gli elementi <a>
, e questa soluzione ha funzionato per me.

A seconda del post, un'altra soluzione potrebbe essere utilizzare il plugin WP Unformatted per disabilitare la funzione auto-p su base individuale per ogni articolo.

È piuttosto utile, anche se l'unico aspetto negativo che vedo è che se vuoi che le immagini non abbiano tag P ma anche del testo all'interno della tua pagina, diventerà un gran casino. Probabilmente andrebbe bene per post che contengono solo immagini e magari qualche riga di testo. Comunque, utile.

Nel caso qualcuno stia cercando un modo veloce e sporco per risolvere questo problema per qualsiasi tag, ecco cosa ho fatto:
- vai su wp-content/formatting.php
- cerca la funzione wpautop. (nel caso te lo fossi perso, è WP-AUTO-P, capito?)
- trova la variabile "all blocks", dovrebbe essere qualcosa tipo
$allblocks = '(?:table|thead|tfoot|capti...
- alla fine aggiungi il blocco che vuoi escludere -
img
,a
, ecc... ad esempio se termina con(...)menu|summary)';
cambia in(...)menu|summary|a)';
per aggiungere il taga
ed evitare che venga autopizzato. Nota il separatore pipe|
- è sintassi regex!
Tutto qui, buon WordPressing!
