2026年6月26日

2026年6月26日

TablePressのエラーを解決する方法

はじめに

TablePressで[table id=1 /]ショートコードを貼り付けてもテーブルが表示されない・テーブルは表示されるがDataTablesの検索・ソート機能が動かない・CSVをインポートすると日本語が文字化けする・特定のカラムだけソートを無効にしたいといった問題は、JavaScriptコンフリクト・文字コード設定・TablePressの表示オプション設定が原因です。

症状・原因

  • 投稿・固定ページにショートコードを貼っているが、フロントエンドでテーブルが表示されない
  • テーブルは表示されるが上部の「検索」ボックスや列ヘッダーのクリックソートが動かない
  • ExcelやGoogleスプレッドシートからエクスポートしたCSVをインポートすると日本語が「????」になる
  • テーブルが横長でモバイルでは右端が切れてしまう

解決手順

ステップ1:TablePressの状態を確認する

# TablePressの設定とテーブルを確認
wp eval "
// バージョン確認
if (defined('TABLEPRESS_VERSION')) {
    echo 'TablePress version: ' . TABLEPRESS_VERSION . PHP_EOL;
}

// 登録済みテーブルを確認
\$tables = TablePress::$model_table->load_all(false);
echo 'Total tables: ' . count(\$tables) . PHP_EOL;

foreach (array_slice(\$tables, 0, 5) as \$table_id => \$table) {
    printf('  Table #%s | %s | Rows: %d | Cols: %d | Show DT: %s' . PHP_EOL,
        \$table_id,
        \$table['name'],
        count(\$table['data'] ?? []),
        count(\$table['data'][0] ?? []),
        (\$table['options']['use_datatables'] ?? false) ? 'yes' : 'no'
    );
}

// DataTablesの設定確認
\$options = get_option('tablepress_options', []);
echo 'jQuery DataTables: ' . (\$options['use_datatables'] ?? 'not set') . PHP_EOL;
"

ステップ2:テーブルの表示をカスタマイズする

// functions.php: TablePress表示カスタマイズ

// ① テーブル出力をフィルタリング
add_filter('tablepress_table_output', function(string $output, array $table): string {
    // 特定のテーブルIDにWrapperを追加
    if ($table['id'] === '1') {
        $output = '<div class="tablepress-responsive-wrapper" style="overflow-x:auto;">'
                . $output
                . '</div>';
    }
    return $output;
}, 10, 2);

// ② テーブルデータを動的に変更
add_filter('tablepress_table_raw_render_data', function(array $table): array {
    // テーブルID 2 のみ処理
    if ($table['id'] !== '2') return $table;

    // 1行目をヘッダーとして確認
    foreach ($table['data'] as $row_idx => &$row) {
        foreach ($row as $col_idx => &$cell) {
            // 価格列(3列目)に円マークを追加
            if ($col_idx === 2 && $row_idx > 0 && is_numeric($cell)) {
                $cell = '¥' . number_format((int)$cell);
            }
        }
    }
    return $table;
}, 10, 1);

// ③ 特定の行に CSS クラスを追加
add_filter('tablepress_row_css_classes', function(array $classes, int $row_index, array $table): array {
    // ヘッダー行は太字
    if ($row_index === 0) {
        $classes[] = 'header-row';
    }
    // 偶数行に背景色
    if ($row_index % 2 === 0) {
        $classes[] = 'even-row';
    }
    return $classes;
}, 10, 3);

ステップ3:DataTablesの設定を修正する

// functions.php: DataTables設定

// ① DataTablesのデフォルト設定をカスタマイズ
add_filter('tablepress_datatables_js_options', function(array $options, string $table_id): array {
    // 日本語化
    $options['language'] = [
        'search'           => '検索:',
        'lengthMenu'       => '_MENU_ 件表示',
        'info'             => '_TOTAL_ 件中 _START_ から _END_ を表示',
        'infoEmpty'        => '0 件',
        'infoFiltered'     => '(全 _MAX_ 件からフィルター)',
        'paginate'         => [
            'first'    => '最初',
            'last'     => '最後',
            'next'     => '次',
            'previous' => '前',
        ],
        'emptyTable'       => 'データがありません',
        'zeroRecords'      => '該当データなし',
        'loadingRecords'   => '読み込み中...',
    ];

    // テーブルID 1 は並び替え無効
    if ($table_id === '1') {
        $options['ordering'] = false;
    }

    // ページネーションを無効
    if ($table_id === '3') {
        $options['paging'] = false;
    }

    return $options;
}, 10, 2);

// ② 特定の列だけソートを無効にする
add_filter('tablepress_datatables_js_options', function(array $options, string $table_id): array {
    if ($table_id !== '2') return $options;

    // 0番目(1列目)と最終列のソートを無効化
    $options['columnDefs'] = [
        ['orderable' => false, 'targets' => [0, -1]],
    ];
    return $options;
}, 10, 2);

// ③ DataTablesが読み込まれているか確認するスクリプトを追加
add_action('wp_footer', function(): void {
    if (!is_singular()) return;
    global $post;
    if (!$post || !has_shortcode($post->post_content, 'table')) return;

    echo '<script>
    document.addEventListener("DOMContentLoaded", function() {
        if (typeof jQuery === "undefined" || typeof jQuery.fn.DataTable === "undefined") {
            console.warn("[TablePress] jQuery or DataTables not loaded");
        }
    });
    </script>';
});

ステップ4:CSV インポートの文字化けを修正する

// functions.php: CSV文字化け対策

// ① CSVインポート時の文字コード変換
add_filter('tablepress_import_csv_delimiter', function(string $delimiter): string {
    return ','; // カンマ区切りを明示
});

// ② インポートデータの文字コードを変換
add_filter('tablepress_import_table_raw_data', function(string $raw_data): string {
    // Shift-JISをUTF-8に変換
    $encoding = mb_detect_encoding($raw_data, ['UTF-8', 'SJIS', 'EUC-JP', 'JIS'], true);
    if ($encoding && $encoding !== 'UTF-8') {
        $raw_data = mb_convert_encoding($raw_data, 'UTF-8', $encoding);
        error_log('[TablePress] Converted encoding: ' . $encoding . ' → UTF-8');
    }
    // BOM(バイトオーダーマーク)を除去
    $raw_data = preg_replace('/^\xEF\xBB\xBF/', '', $raw_data);
    return $raw_data;
});

// ③ テーブルをプログラムで作成・更新
function create_tablepress_table(string $name, array $data): string {
    if (!class_exists('TablePress')) return '';

    $table = [
        'name'        => $name,
        'description' => '',
        'data'        => $data,
        'options'     => [
            'use_datatables'    => true,
            'table_head'        => true,
            'table_foot'        => false,
            'alternating_row_colors' => true,
        ],
    ];

    $table_id = TablePress::$model_table->add($table);
    error_log('[TablePress] Created table #' . $table_id . ': ' . $name);
    return $table_id;
}

// 使用例
// $data = [
//     ['商品名', '価格', '在庫'],
//     ['商品A', '1000', '10'],
// ];
// $id = create_tablepress_table('商品リスト', $data);

ステップ5:テーブルのパフォーマンスと管理

// functions.php: TablePressパフォーマンス

// ① TablePressスクリプトをテーブルのないページで除外
add_action('wp_enqueue_scripts', function(): void {
    if (!is_singular()) return;
    global $post;
    if (!$post) return;

    $has_table = has_shortcode($post->post_content, 'table');
    if (!$has_table) {
        wp_dequeue_script('tablepress-datatables');
        wp_dequeue_script('tablepress-datatables-buttons');
        wp_dequeue_style('tablepress-default');
    }
}, 20);

// ② テーブルデータをTransientでキャッシュ
function get_cached_table_data(string $table_id): ?array {
    $cache_key = 'tablepress_data_' . $table_id;
    $cached    = get_transient($cache_key);

    if ($cached !== false) return $cached;

    if (!class_exists('TablePress')) return null;

    $table = TablePress::$model_table->load($table_id, false, false);
    if (!$table) return null;

    set_transient($cache_key, $table['data'], HOUR_IN_SECONDS);
    return $table['data'];
}

// ③ テーブル更新時にキャッシュをクリア
add_action('tablepress_event_saved_table', function(string $table_id): void {
    delete_transient('tablepress_data_' . $table_id);
    error_log('[TablePress] Cache cleared for table #' . $table_id);
});

注意事項

  • TablePressのショートコードが表示されない場合は、ページがビジュアルエディターで作成されているか確認してください。一部のページビルダー(Elementor・Divi等)ではWordPressの標準ショートコードが処理されない場合があります。その場合はTablePressのElmentor専用ウィジェットを使用してください
  • DataTablesのソートや検索が動かない場合、テーマまたはプラグインが別バージョンのjQueryを読み込んでいる競合が原因のことがあります。ブラウザのコンソールで「jQuery is not defined」または「$.fn.DataTable is not a function」などのエラーがないか確認してください
  • CSVインポートの文字化けはほぼすべてのケースがExcelで保存したCSVファイルのShift-JIS(SJIS)エンコードが原因です。インポート前にテキストエディタ(VSCode・メモ帳等)で「UTF-8(BOMなし)」形式で保存し直してください

まとめ

TablePress修復は①TablePress::$model_table->load_all()でテーブル一覧・DataTables設定確認、②tablepress_table_outputフィルターでレスポンシブWrapperを追加・tablepress_table_raw_render_dataフィルターで価格フォーマット等のデータ加工、③tablepress_datatables_js_optionsフィルターで日本語化・特定列のソート無効化・ページネーション制御、④tablepress_import_table_raw_dataフィルターでmb_convert_encoding()によるSJIS→UTF-8変換・BOM除去、⑤has_shortcode()でテーブル未掲載ページのスクリプト除外・Transientキャッシュ・tablepress_event_saved_tableフックでキャッシュ自動クリアする手順で解決します。

お気軽にご相談ください

お見積りへ お問い合わせへ