Dừng Wordpress gói hình ảnh trong một thẻ Páng


33

Tôi đã tìm kiếm cao và thấp cho một giải pháp đơn giản cho việc này, nhưng không có kết quả. Wordpress tiếp tục gói hình ảnh của tôi trong các thẻ p và vì tính chất lập dị của bố cục cho một trang web tôi đang làm việc, điều này rất khó chịu.

Tôi đã tạo ra một giải pháp jQuery cho các hình ảnh không ghép hình, nhưng nó không tuyệt lắm. Nó bị chậm do các nội dung khác đang tải trên trang và do đó, các thay đổi sẽ được thực hiện chậm. Có cách nào để ngăn chặn Wordpress chỉ gói hình ảnh bằng thẻ p không? Một hook hoặc bộ lọc có lẽ có thể được chạy.

Điều này xảy ra khi tải lên một hình ảnh và sau đó chèn nó vào trình soạn thảo WYSIWYG. Thủ công đi vào chế độ xem mã và loại bỏ các thẻ p không phải là một tùy chọn vì máy khách không phải là kỹ thuật không phù hợp.

Tôi hiểu rằng hình ảnh là nội tuyến, nhưng cách tôi có hình ảnh được mã hóa trang web nằm bên trong div và được đặt thành chặn, vì vậy chúng là mã hợp lệ.


Câu trả lời:


34

Đây là những gì chúng tôi đã làm ngày hôm qua trên một trang web khách hàng mà chúng tôi đang gặp vấn đề chính xác này với ... Tôi đã tạo một bộ lọc nhanh dưới dạng plugin và kích hoạt nó.

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

Nếu bạn thả tệp đó vào tệp php trong thư mục / wp-content / plugin và sau đó kích hoạt nó, nó sẽ xóa các thẻ p khỏi bất kỳ đoạn para nào chỉ chứa hình ảnh.

Tôi không chắc chắn mức độ regex mạnh đến mức nào nếu nó sẽ thất bại với kết quả đầu ra từ các trình soạn thảo khác - ví dụ: nếu thẻ img được đóng chỉ với> nó sẽ thất bại. Nếu bất cứ ai có bất cứ điều gì mạnh mẽ hơn, điều đó sẽ thực sự hữu ích.

Chúc mừng

James

--- Bộ lọc được cải tiến ---

Để làm việc với các hình ảnh được bọc trong các liên kết, nó giữ các liên kết ở đầu ra và loại bỏ các thẻ p.

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

Không nghi ngờ gì, đây là câu trả lời thích hợp. Cảm ơn James, tôi đã thử nó và nó hoạt động khủng khiếp.
Dwayne Charrington

Xin chào @Dwayne - cảm ơn bạn đã phản hồi. Tôi đã thêm một bộ lọc cải tiến sẽ xử lý các liên kết, chúng tôi hiện đang sử dụng nó trên trang web của khách hàng.
jamesc

Bạn chắc chắn nên đặt cái này trong kho plugin Wordpress. Một tìm kiếm nhanh trên google cho thấy rất nhiều người đang gặp vấn đề này mà không có giải pháp tốt.
Geoffrey Burdett

1
Lưu ý rằng điều này sẽ không hoạt động với imgđánh dấu mặc định HTML5 , tức là <img ...>không có dấu gạch chéo. Tốt hơn là làm cho tùy chọn đó trong regex của bạn. Hoặc tốt hơn nữa, bạn có thể bỏ nó đi vì .*sẽ chăm sóc nó.
Bram Vanroy 10/03/2015

Có ai làm cho nó làm việc <img ...>mà không có />?
Runnick

13

Về cơ bản, bạn cần làm cho WordPress coi img như phần tử cấp khối cho mục đích định dạng. Các phần tử như vậy được mã hóa cứngwpautop() và danh sách không may không được lọc.

Những gì tôi sẽ làm là:

  1. Ngã ba wpautop()dưới tên khác nhau.
  2. Thêm imgvào regrec trong $allblocksbiến.
  3. Xóa wpautopkhỏi the_contentbộ lọc.
  4. Thêm phiên bản rẽ nhánh của bạn vào the_content.
  5. Bạn có thể cần phải chơi ưu tiên và có thể xóa và thêm lại các bộ lọc khác nếu có lỗi xảy ra do thứ tự xử lý thay đổi.

Tôi sẽ thử phương pháp này. Tôi chưa bao giờ nghĩ đến việc thực sự thêm thẻ img vào biến allblocks, đó là một ý tưởng thiên tài. Tôi sẽ xem tôi đi như thế nào.
Dwayne Charrington

Ban đầu hoạt động tốt, sau đó tôi nhấn vào kịch bản khi một hình ảnh nằm trong thẻ neo và cả hai đều nằm trong một đoạn (vì vậy p> img> a). Với img được coi là một khối wp-autop sẽ đóng thẻ đoạn văn trước khi thẻ img bắt đầu, phá vỡ bố cục.
benz001

2

Có thể điều này sẽ giúp

remove_filter('the_content', 'wpautop')

Nhưng sau đó bạn sẽ thêm các đoạn văn cho mọi thứ khác bằng tay.


Tôi đã xem xét phương pháp này, nhưng vì bố cục lập dị như tôi đã nói nên nó phụ thuộc rất nhiều vào việc cần thẻ p. Khi tôi đang thực hiện một điều văn bản 2 cột trong đó các thẻ p được thả trái để tạo ra sự xuất hiện của 2 cột văn bản. Vì vậy, bạn có thể thấy lý do tại sao thẻ ap bọc một hình ảnh sẽ là một vấn đề bởi vì nó cũng nổi đó.
Dwayne Charrington

1

Soska đã đưa ra một / cách dễ dàng.

Nhưng những gì tôi làm là, trích xuất hình ảnh từ nội dung và hiển thị nó một cách riêng biệt.


Tôi đã xem xét điều này là tốt và nó vẫn là một lựa chọn. Tuy nhiên vì đây chỉ là một hình ảnh để lưu tất cả các rắc rối, tôi có thể chỉ sử dụng hình thu nhỏ bài đăng nổi bật thay vào đó sẽ cho phép tôi kiểm soát cách hiển thị hình ảnh.
Dwayne Charrington

ngoài ra, bạn có thể thêm trường tùy chỉnh vào bài đăng / trang, như hình ảnh ngón tay cái và lưu đường dẫn hình ảnh vào giá trị của nó ...
Avinash

1

Bài đăng này hơi cũ, nhưng có một giải pháp đơn giản hơn nhiều, loại bỏ CSS ở cuối của bạn.

Gói thẻ img trong div có ít ảnh hưởng tiêu cực.


1

Tôi đã phát triển một plugin khắc phục sự cố chính xác này: http://wordpress.org/extend/plugins/unwrap-images/

Tốt hơn là đặt lề hoặc đi sâu vào mã Wordpress cho những người không muốn gây rối với mã bởi vì nó sử dụng hàm unrap nguyên gốc của jQuery để mở khóa tất cả hình ảnh của thẻ p của họ.

Hy vọng điều này sẽ giúp được ai đó! Chúc mừng, Brian


hình như vẫn còn hơn 30 cài đặt hoạt động: D
Julix

1

Câu trả lời được chấp nhận đã giúp tôi chỉ với các hình ảnh nhưng mã sửa đổi không xử lý tốt các hình ảnh được liên kết tại trang web của tôi. Bài đăng blog này có một mã hoạt động hoàn hảo.

Đây là mã:

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

Chúc mừng!


1

Tôi không phải là một chuyên gia nhưng tôi đã dành cả buổi chiều để cố gắng giải quyết các gói được bao bọc trong các thẻ p và điều này hiệu quả với tôi.

Tôi đang làm việc trên một chủ đề dựa trên wordpress và chỉ cần thêm nó vào tập tin tests.js

Hàm 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’);

bây giờ tôi có thể làm việc p và img riêng biệt.

Cũng có thể thêm một div với một lớp khác tạo ra img bằng cách này:

$(document).ready(function (){

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

cái cuối cùng này không giải quyết được vấn đề của tôi vì tôi muốn tạo các thẻ p bằng màn hình: none; Vì vậy, tôi thực sự phải đưa những img đó ra khỏi đó.


3
Bạn có thực sự sử dụng dấu ngoặc kép? :)
fuxia

Tôi đã xem xét cách tiếp cận này trước tiên khi trở lại, nhưng ý nghĩ về thao tác DOM không cần thiết thông qua jQuery là quá nhiều rủi ro và tiềm năng không cần thiết khi bạn có thể thực hiện điều này trong PHP với các biểu thức chính quy khó hiểu.
Dwayne Charrington

0

Tùy thuộc vào bài đăng, một giải pháp khác có thể là sử dụng plugin WP Unformatted để vô hiệu hóa chức năng tự động p trên cơ sở mỗi bài đăng.


Điều đó khá hữu ích, mặc dù điều đáng chú ý duy nhất tôi có thể thấy là nếu bạn muốn hình ảnh không có thẻ P mà còn có văn bản trong trang của bạn, thì đó sẽ là một mớ hỗn độn. Điều này có lẽ sẽ tốt cho các bài đăng chỉ có hình ảnh và có thể một vài dòng văn bản. Tuy nhiên, hữu ích.
Dwayne Charrington

Yup, đó là lý do tại sao tôi nói nó phụ thuộc vào bài viết.
Synetech

0

Trong trường hợp ai đó đang tìm kiếm một cách nhanh chóng và bẩn thỉu để khắc phục điều này cho bất kỳ thẻ nào ở đây tôi đã làm:

  1. đi đến wp-content / format.php
  2. tìm chức năng wpautop. (trong trường hợp bạn bỏ lỡ nó, đó là WP-AUTO-P , hiểu không?)
  3. vây các biến "tất cả các khối", nên là một cái gì đó như $allblocks = '(?:table|thead|tfoot|capti...
  4. ở cuối, thêm khối bạn muốn bỏ qua - img, av.v ... ví dụ nếu nó kết thúc (...)menu|summary)';thay đổi (...)menu|summary|a)';để thêm athẻ và tránh tự động nhận nó. Lưu ý |dấu tách đường ống - đó là cú pháp regex !

Thế là xong, chúc mừng hạnh phúc!

Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.