Zatrzymaj zawijanie obrazów w tagach „P”

33

Szukałem wysoko i nisko w poszukiwaniu prostego rozwiązania tego problemu, ale bezskutecznie. Wordpress ciągle owija moje obrazy w tagi p, a ze względu na ekscentryczny charakter strony, nad którą pracuję, jest to bardzo denerwujące.

Stworzyłem rozwiązanie jQuery do rozpakowywania obrazów, ale nie jest tak świetne. Opóźnia się z powodu innych ładowań na stronie, więc zmiany są powolne. Czy istnieje sposób, aby zapobiec zawijaniu przez Wordpress tylko obrazów ze znacznikami p? Być może można uruchomić hak lub filtr.

Dzieje się tak podczas przesyłania obrazu, a następnie wstawiania go do edytora WYSIWYG. Ręczne wchodzenie do widoku kodu i usuwanie znaczników p nie jest opcją, ponieważ klient nie jest tak technicznie nieudolny.

Rozumiem, że obrazy są wbudowane, ale sposób, w jaki mam strony kodowane obrazy są wewnątrz div i ustawione na blokowanie, więc są poprawnym kodem.

Dwayne Charrington
źródło

Odpowiedzi:

34

oto co zrobiliśmy wczoraj na stronie klienta, z którą mieliśmy dokładnie ten problem ... Stworzyłem szybki filtr jako wtyczkę i aktywowałem go.

<?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');

Jeśli upuścisz go do pliku php w folderze / wp-content / plugins, a następnie go aktywujesz, powinien on usunąć tagi p z dowolnego para, który zawiera tylko obraz.

Nie jestem pewien, jak silne jest wyrażenie regularne pod względem tego, czy zakończy się niepowodzeniem w przypadku danych wyjściowych innych edytorów - na przykład, jeśli tag img jest zamknięty tylko przez>, to się nie powiedzie. Jeśli ktoś ma coś silniejszego, byłoby to naprawdę pomocne.

Twoje zdrowie,

James

--- Ulepszony filtr ---

Aby pracować z obrazami owiniętymi w łącza, utrzymuje łącza w danych wyjściowych i usuwa znaczniki p.

return preg_replace('/<p>\s*(<a .*>)?\s*(<img .* \/>)\s*(<\/a>)?\s*<\/p>/iU', '\1\2\3', $content);
jamesc
źródło
Bez wątpienia jest to właściwa odpowiedź. Dzięki James, wypróbowałem to i działa niesamowicie.
Dwayne Charrington
Cześć @Dwayne - dzięki za opinie. Dodałem ulepszony filtr, który będzie obsługiwał linki, teraz używamy go na naszej stronie klienta.
jamesc
Zdecydowanie powinieneś umieścić to w repozytorium wtyczek Wordpress. Szybkie wyszukiwanie w Google pokazuje, że wiele osób ma ten problem bez dobrego rozwiązania.
Geoffrey Burdett,
1
Zauważ, że to nie zadziała z domyślnym imgznacznikiem HTML5 , tj. <img ...>Bez ukośnika zamykającego. Lepiej uczynić to opcjonalnym w wyrażeniu regularnym. Lub jeszcze lepiej, możesz to pominąć, jak się .*tym zajmie.
Bram Vanroy,
Czy ktoś sprawił, że działa <img ...>bez niego />?
Runnick
13

Zasadniczo musisz sprawić, aby WordPress traktował img jak element na poziomie bloku do celów formatowania. Takie elementy są zakodowane na stałe,wpautop() a lista niestety nie jest filtrowana.

Chciałbym:

  1. Widelec wpautop() pod inną nazwą.
  2. Dodaj imgdo wyrażenia regularnego w $allblockszmiennej.
  3. Usuń wpautopz the_contentfiltra.
  4. Dodaj swoją rozwidloną wersję do the_content.
  5. Być może będziesz musiał grać z priorytetem i ewentualnie usunąć i ponownie dodać inne filtry, jeśli coś się zepsuje z powodu zmienionej kolejności przetwarzania.
Rarst
źródło
Spróbuję tego podejścia. Nigdy nie myślałem o dodaniu znacznika img do zmiennej allblocks, to genialny pomysł. Zobaczę jak pójdę.
Dwayne Charrington
Na początku działało dobrze, potem wpadłem na scenariusz, w którym obraz znajduje się w tagu zakotwiczenia i oba są już w akapicie (więc p> img> a). Gdy img jest traktowany jako blok, wp-autop zamyka tag akapitu przed uruchomieniem tagu img, niszcząc układ.
benz001
2

może to pomoże

remove_filter('the_content', 'wpautop')

Ale potem ręcznie dodasz akapity dotyczące wszystkiego innego.

Soska
źródło
Rozważyłem to podejście, ale ponieważ układ jest ekscentryczny, ponieważ powiedziałem, że w dużej mierze opiera się na potrzebie znaczników p. Gdy robię tekst z 2 kolumnami, w których tagi p są unoszone w lewo, aby wyglądać jak 2 kolumny tekstu. Możesz więc zobaczyć, dlaczego zawijanie obrazu przez znacznik ap może być problemem, ponieważ również się unosi.
Dwayne Charrington
1

Soska dała jeden / łatwy sposób.

Ale to, co robię, to wydobywanie obrazu z treści i wyświetlanie go osobno.

Avinash
źródło
Rozważyłem to również i nadal jest to opcja. Ponieważ jednak jest to tylko jeden obraz, aby zapisać cały problem, mogę po prostu użyć wyróżnionych miniatur postów, co pozwoliłoby mi kontrolować sposób wyświetlania obrazu.
Dwayne Charrington
możesz także dodać niestandardowe pole do posta / strony, takie jak obrazek kciuka i zapisać ścieżkę obrazu w jego wartości ...
Avinash
1

Ten post jest trochę stary, ale istnieje o wiele prostsze rozwiązanie, z wyjątkiem CSS po twojej stronie.

Zawijanie znacznika img w div ma niewielki negatywny wpływ.

Laoshi Ma
źródło
1

Opracowałem wtyczkę, która rozwiązała ten dokładny problem: http://wordpress.org/extend/plugins/unwrap-images/

To lepsze niż ustawianie marginesu lub nurkowanie bezpośrednio w kodzie Wordpress dla tych, którzy nie chcą zadzierać z kodem, ponieważ używa natywnej funkcji rozpakowywania jQuery do rozpakowywania wszystkich obrazów swoich znaczników p.

Mam nadzieję, że to komuś pomoże! Na zdrowie, Brian

gnzlz
źródło
najwyraźniej ma jeszcze ponad 30 aktywnych instalacji: D
Julix
1

Zaakceptowana odpowiedź pomogła mi tylko z obrazami, ale poprawiony kod nie radzi sobie dobrze z połączonymi obrazami w mojej witrynie. To post na blogu ma kod, który działa idealnie.

Oto kod:

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');

Twoje zdrowie!

rlesko
źródło
1

Nie jestem ekspertem, ale spędziłem całe popołudnie, próbując rozwiązać de img zawinięte w tagi p i to zadziałało dla mnie.

Pracuję nad kompozycją opartą na wordpressie i właśnie dodałem ją do pliku functions.js

Funkcja Jquery rozpakowuje się

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

teraz mogę pracować p i img osobno.

Można również dodać div z inną klasą wokół img, używając tego:

$(document).ready(function (){

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

ten ostatni nie rozwiązał mojego problemu, ponieważ chciałem utworzyć tagi p z display: none; więc naprawdę musiałem je stamtąd usunąć.

M. Joana
źródło
3
Czy naprawdę używasz nawiasów? :)
fuxia
Rozważyłem to podejście po raz pierwszy, ale myśl o niepotrzebnej manipulacji DOM za pomocą jQuery stanowił zbyt duże ryzyko i potencjalnie niepotrzebny narzut, gdy możesz to zrobić w PHP z trudnymi wyrażeniami regularnymi.
Dwayne Charrington
0

W zależności od postu innym rozwiązaniem może być użycie wtyczki WP Unformatted w celu wyłączenia funkcji auto-p dla poszczególnych postów.

Synetech
źródło
Jest to bardzo przydatne, chociaż jedynym zastrzeżeniem, jakie widzę, jest to, że jeśli chcesz, aby obrazy nie miały znaczników P, ale miały także tekst na stronie, będzie to jeden wielki bałagan. Prawdopodobnie byłoby to dobre w przypadku postów zawierających tylko obrazy i może kilka wierszy tekstu. Nadal przydatne.
Dwayne Charrington
Tak, dlatego powiedziałem, że to zależy od postu.
Synetech
0

Jeśli ktoś szuka szybkiego i brudnego sposobu na naprawienie tego dla dowolnego tagu, oto co zrobiłem:

  1. przejdź do wp-content / formatting.php
  2. znajdź funkcję wpautop. (jeśli go przegapiłeś, to WP-AUTO-P , ?)
  3. płetwy zmienna „wszystkie bloki” powinna być podobna do $allblocks = '(?:table|thead|tfoot|capti...
  4. Na koniec dodać blok, który chcesz pominąć - img, aitp ... Na przykład jeśli kończy się na (...)menu|summary)';zmianę do (...)menu|summary|a)';Aby dodać atag i uniknąć autopeeing go. Zwróć uwagę na |separator potokowy - to składnia wyrażeń regularnych !

To wszystko, szczęśliwy Wordpressing!

JDuarteDJ
źródło