在 WordPress 裡想在所有文章裡的 table 和 iframe 外自動加上一個 div 做響應式設計

2024 年 1 月 21 更新:支援 ACF 編輯器欄位自動加上 div

在 WordPress 文字編輯器中,客戶可能會想要插入表格、iframe這些元素,但這些元素一直都有在手機版難以呈現導致破版的問題。通常我們的解決方法就是在這些元素外部包圍住 div 後進行響應式的樣式調整。

使用 the_content filter 攔截內容輸出,在 table 外圍加上 div

以下是可以攔截 post 類型輸出時的內容,使用正則表達式找到 table 元素,並在 table 外圍加上 responsive-table div 元素

function add_div_outside_table( $content ) {
    if (is_singular('post')) {
        // Define the opening and closing tags for the div element
        $div_open = '<div class="responsive-table">';
        $div_close = '</div>';

        // Get all tables in the content
        $tables = preg_match_all( '/<table[^>]*>.*?<\/table>/s', $content, $matches );

        // If there are no tables, return the original content
        if ( $tables === false || $tables === 0 ) {
            return $content;
        }

        // Loop through each table and wrap it with the div element
        for ( $i = 0; $i < $tables; $i++ ) {
            $table = $matches[0][$i];
            $table_with_div = $div_open . $table . $div_close;
            $content = str_replace( $table, $table_with_div, $content );
        }   
    }

    return $content;
}
add_filter( 'the_content', 'add_div_outside_table' );
add_filter( 'acf/format_value/type=wysiwyg', 'add_div_outside_table' );

幫 table-responsive 加上樣式

設定寬度為 100%,如果超出容器範圍則出現卷軸

.table-responsive {
  width: 100%;
  overflow-x: scroll;
}

使用 the_content filter 攔截內容輸出,在 iframe 外圍加上 div

function add_div_outside_iframe( $content) {
    if (is_singular('news')) {
        // Define the opening and closing tags for the div element
        $div_open = '<div class="iframe-responsive">';
        $div_close = '</div>';

        // Get all tables in the content
        $iframes = preg_match_all( '/<iframe[^>]*>.*?<\/iframe>/s', $content, $matches );

        // If there are no tables, return the original content
        if ( $iframes === false || $iframes === 0 ) {
            return $content;
        }

        // Loop through each table and wrap it with the div element
        for ( $i = 0; $i < $iframes; $i++ ) {
            $iframe = $matches[0][$i];
            $iframe_with_div = $div_open . $iframe . $div_close;
            $content = str_replace( $iframe, $iframe_with_div, $content );
        }
    }

    return $content;
}

add_filter( 'the_content', 'add_div_outside_iframe' );
add_filter( 'acf/format_value/type=wysiwyg', 'add_div_outside_iframe' );

幫 iframe-responsive 加上樣式

padding 56.25% 為 16:9 影片的比例

.iframe-responsive {
    position: relative;
    padding-top: 56.25%;

    iframe {
        position: absolute;
        left: 0;
        top: 0;
        width: 100%;
        height: 100%;
    }
}