[WordPress] ウィジェット構造をMarkdown形式で出力するプラグインを作ってみた

[WordPress] ウィジェット構造をMarkdown形式で出力するプラグインを作ってみた
  • WordPressのウィジェットは便利ですが、いじっているうちに「前はどうなっていたっけ?」という状況になることがあります。
  • そんな時に役立つ、ウィジェットの構造をわかりやすく記録できるプラグインを作りました。
  • このプラグインを使うと、現在のウィジェット配置とその設定内容をMarkdown形式で出力できます。
sns_share_buttons
\記事が役に立ったらシェアしてね/
【スポンサーリンク】

1. WordPressのウィジェット構造をメモしたい

WordPressでウェブサイトを作っているとき、サイドバーやフッターにあるウィジェットの調整は頻繁に行います。
しかし、調整しすぎて元の状態がわからなくなってしまったり、何か問題が起きたときに「以前はどうだったか」を確認したりする方法がありませんでした。

そこで、現在のウィジェット構造をMarkDown形式で出力するWordPressプラグインを作りました。
個人用プラグインなので、なるべく構造は管理しやすく設計しました。

このプラグインは、現在のウィジェット構造の確認、変更前の状態の記録、表示設定を含む詳細情報の出力ができます。

WordPressのウィジェット構造をメモしたい

1-1. プラグインの使い方

このプラグインは非常にシンプルに使えます。

  1. プラグインファイル(chiilabo-widget-exporter.php)をWordPressの wp-content/plugins/フォルダー にアップロードして有効化します
  2. 管理画面の「ツール」メニューから「ウィジェットエクスポーター」を選択します
  3. 「ウィジェット構造をエクスポート」ボタンをクリックします
  4. 表示されたMarkdown形式のデータをコピーまたはダウンロードします
<?php
/**
 * Plugin Name: Chiilabo Widget Exporter
 * Plugin URI: 
 * Description: WordPressのウィジェット構造をMarkdown形式でエクスポートするプラグイン
 * Version: 1.1
 * Author: Chiilabo
 * Author URI: 
 * License: GPL2
 */

// 直接アクセスを防止
if (!defined('ABSPATH')) {
    exit;
}

class Widget_Exporter {
    
    /**
     * コンストラクタ
     */
    public function __construct() {
        // 管理画面にメニューを追加
        add_action('admin_menu', array($this, 'add_admin_menu'));
        
        // AJAXハンドラーを登録
        add_action('wp_ajax_export_widgets', array($this, 'ajax_export_widgets'));
    }
    
    /**
     * 管理メニューを追加
     */
    public function add_admin_menu() {
        add_submenu_page(
            'tools.php',
            'ウィジェットエクスポーター', 
            'ウィジェットエクスポーター', 
            'manage_options',
            'widget-exporter', 
            array($this, 'admin_page')
        );
    }
    
    /**
     * 管理画面を表示
     */
    public function admin_page() {
        ?>
        <div class="wrap">
            <h1>ウィジェットエクスポーター</h1>
            <p>現在のウィジェット構造をMarkdown形式でエクスポートします。</p>
            
            <div class="card">
                <h2>エクスポート</h2>
                <p>
                    <button id="export-widgets" class="button button-primary">ウィジェット構造をエクスポート</button>
                    <label for="debug-mode" style="margin-left: 15px;">
                        <input type="checkbox" id="debug-mode" name="debug-mode"> デバッグ情報を含める
                    </label>
                </p>
                <div id="export-result" style="display:none;">
                    <h3>エクスポート結果</h3>
                    <textarea id="markdown-output" style="width: 100%; height: 500px; font-family: monospace;"></textarea>
                    <p>
                        <button id="copy-markdown" class="button">コピー</button>
                        <button id="download-markdown" class="button">ダウンロード</button>
                    </p>
                </div>
            </div>
        </div>
        
        <script>
        jQuery(document).ready(function($) {
            // エクスポートボタンのクリックイベント
            $('#export-widgets').on('click', function() {
                $(this).prop('disabled', true).text('処理中...');
                
                // デバッグモードの状態を取得
                var debugMode = $('#debug-mode').is(':checked');
                
                $.ajax({
                    url: ajaxurl,
                    type: 'POST',
                    data: {
                        action: 'export_widgets',
                        nonce: '<?php echo wp_create_nonce('widget_export_nonce'); ?>',
                        debug_mode: debugMode ? 1 : 0
                    },
                    success: function(response) {
                        $('#export-widgets').prop('disabled', false).text('ウィジェット構造をエクスポート');
                        
                        if (response.success) {
                            $('#markdown-output').val(response.data);
                            $('#export-result').show();
                        } else {
                            alert('エクスポート中にエラーが発生しました: ' + response.data);
                        }
                    },
                    error: function() {
                        $('#export-widgets').prop('disabled', false).text('ウィジェット構造をエクスポート');
                        alert('エクスポート中にエラーが発生しました。');
                    }
                });
            });
            
            // コピーボタンのクリックイベント
            $('#copy-markdown').on('click', function() {
                var copyText = document.getElementById("markdown-output");
                copyText.select();
                document.execCommand("copy");
                alert("クリップボードにコピーしました");
            });
            
            // ダウンロードボタンのクリックイベント
            $('#download-markdown').on('click', function() {
                var text = $('#markdown-output').val();
                var filename = 'widgets-' + new Date().toISOString().slice(0, 10) + '.md';
                
                var element = document.createElement('a');
                element.setAttribute('href', 'data:text/plain;charset=utf-8,' + encodeURIComponent(text));
                element.setAttribute('download', filename);
                element.style.display = 'none';
                document.body.appendChild(element);
                element.click();
                document.body.removeChild(element);
            });
        });
        </script>
        <?php
    }
    
    /**
     * ウィジェットデータをエクスポートするAJAXハンドラ
     */
    public function ajax_export_widgets() {
        // nonceの検証
        if (!isset($_POST['nonce']) || !wp_verify_nonce($_POST['nonce'], 'widget_export_nonce')) {
            wp_send_json_error('セキュリティチェックに失敗しました。');
        }
        
        // 管理者権限の確認
        if (!current_user_can('manage_options')) {
            wp_send_json_error('十分な権限がありません。');
        }
        
        // デバッグモードの設定を取得
        $debug_mode = isset($_POST['debug_mode']) && $_POST['debug_mode'] == 1;
        
        $markdown = $this->generate_widgets_markdown($debug_mode);
        wp_send_json_success($markdown);
    }
    
    /**
     * ウィジェットデータをMarkdown形式で生成
     * 
     * @param bool $debug_mode デバッグ情報を含めるかどうか
     * @return string Markdown形式の出力
     */
    private function generate_widgets_markdown($debug_mode = false) {
        global $wp_registered_widgets, $wp_registered_sidebars;
        
        $sidebars_widgets = wp_get_sidebars_widgets();
        $output = "# WordPress ウィジェット構造\n";
        $output .= "エクスポート日時: " . date_i18n('Y-m-d H:i:s') . "\n\n";
        
        // アクティブなサイドバーのみ処理
        foreach ($sidebars_widgets as $sidebar_id => $widgets) {
            // wp_inactive_widgets は除外
            if ($sidebar_id === 'wp_inactive_widgets' || empty($widgets) || !is_array($widgets)) {
                continue;
            }
            
            // 特定のサイドバーをスキップしたい場合は以下のコメントを外して設定
            // if ($sidebar_id === 'sidebar-scroll') {
            //    continue;
            // }
            
            // サイドバー名を取得
            $sidebar_name = isset($wp_registered_sidebars[$sidebar_id]['name']) ? 
                $wp_registered_sidebars[$sidebar_id]['name'] : $sidebar_id;
            $sidebar_description = isset($wp_registered_sidebars[$sidebar_id]['description']) ? 
                $wp_registered_sidebars[$sidebar_id]['description'] : '';
            
            $output .= "## " . $sidebar_name . "\n";
            
            if (!empty($sidebar_description)) {
                $output .= $sidebar_description . "\n\n";
            }
            
            if (empty($widgets)) {
                $output .= "このウィジェット表示場所にはウィジェットがありません。\n\n";
                continue;
            }
            
            foreach ($widgets as $widget_id) {
                // ウィジェット情報の取得
                if (isset($wp_registered_widgets[$widget_id])) {
                    $widget_instance = $wp_registered_widgets[$widget_id];
                    $widget_name = $widget_instance['name'];
                    
                    // ウィジェットオプションの取得
                    $widget_options = $this->get_widget_options($widget_id);
                    $is_hidden = isset($widget_options['hide_widget']) && $widget_options['hide_widget'];
                    
                    // ウィジェットタイトルの取得
                    $widget_title = '';
                    
                    // 標準的なtitleフィールドをチェック
                    if (isset($widget_options['title']) && !empty($widget_options['title'])) {
                        $widget_title = $widget_options['title'];
                    }
                    // 一部のウィジェットは別の名前でタイトルフィールドを持つ可能性がある
                    elseif (isset($widget_options['title_mobile_text']) && !empty($widget_options['title_mobile_text'])) {
                        $widget_title = $widget_options['title_mobile_text'];
                    }
                    
                    // タイトルが空でない場合は表示
                    $title_display = !empty($widget_title) ? $widget_title : '';
                    
                    // 表示/非表示ステータス
                    $visibility = $is_hidden ? '(非表示)' : '(表示)';
                    
                    $output .= "### " . $widget_name . ": " . $title_display . $visibility . "\n";
                    
                    // デバッグモードの場合、ウィジェットオプションの内容を出力
                    if ($debug_mode) {
                        $output .= "```php\n";
                        $output .= "// Widget ID: " . $widget_id . "\n";
                        $output .= "// Options:\n";
                        $output .= print_r($widget_options, true);
                        $output .= "```\n\n";
                    }
                    
                    // 表示設定の取得
                    $display_options = $this->get_widget_display_options($widget_id);
                    if (!empty($display_options)) {
                        $output .= $display_options . "\n";
                    }
                    
                    $output .= "\n";
                }
            }
        }
        
        return $output;
    }
    
    /**
     * ウィジェットの表示設定情報を取得
     */
    private function get_widget_display_options($widget_id) {
        // ウィジェットオプションから直接表示設定を確認
        $widget_options = $this->get_widget_options($widget_id);
        
        $display_info = array();
        $page_types = array();
        $special_pages = array();
        $display_type = '';
        
        // 表示/非表示のアクションを確認
        if (isset($widget_options['widget_action'])) {
            $display_type = $widget_options['widget_action'] === 'show' ? '表示' : '非表示';
        }
        
        // カテゴリーの表示設定
        if (isset($widget_options['widget_categories']) && is_array($widget_options['widget_categories']) && !empty($widget_options['widget_categories'])) {
            $categories = array();
            foreach ($widget_options['widget_categories'] as $cat_id) {
                $cat = get_category($cat_id);
                if ($cat) {
                    $categories[] = $cat->name;
                }
            }
            if (!empty($categories)) {
                $display_info[] = 'カテゴリ: ' . implode(', ', $categories);
            }
        }
        
        // タグの表示設定
        if (isset($widget_options['widget_tags']) && !empty($widget_options['widget_tags'])) {
            if (is_array($widget_options['widget_tags'])) {
                $tags = array();
                foreach ($widget_options['widget_tags'] as $tag_id) {
                    $tag = get_tag($tag_id);
                    if ($tag) {
                        $tags[] = $tag->name;
                    }
                }
                if (!empty($tags)) {
                    $display_info[] = 'タグ: ' . implode(', ', $tags);
                }
            } else {
                // 単一のタグIDの場合
                $tag = get_tag($widget_options['widget_tags']);
                if ($tag) {
                    $display_info[] = 'タグ: ' . $tag->name;
                }
            }
        }
        
        // ページの表示設定
        if (isset($widget_options['widget_pages']) && is_array($widget_options['widget_pages']) && !empty($widget_options['widget_pages'])) {
            // 特殊な条件チェック - WordPress条件関数名
            $condition_functions = array(
                'is_front_page' => 'フロントページ',
                'is_home' => 'ブログページ',
                'is_single' => '投稿',
                'is_page' => '固定ページ',
                'is_category' => 'カテゴリーページ',
                'is_tag' => 'タグページ',
                'is_author' => '著者ページ',
                'is_date' => '日付アーカイブ',
                'is_archive' => 'アーカイブページ'
            );
            
            foreach ($widget_options['widget_pages'] as $page_condition) {
                // 条件関数名かチェック
                if (is_string($page_condition) && isset($condition_functions[$page_condition])) {
                    if ($page_condition === 'is_single') {
                        $page_types[] = '投稿';
                    } elseif ($page_condition === 'is_page') {
                        $page_types[] = '固定ページ';
                    } elseif ($page_condition === 'is_front_page') {
                        $special_pages[] = 'フロントページ';
                    } elseif ($page_condition === 'is_category') {
                        $special_pages[] = 'カテゴリーページ';
                    } elseif ($page_condition === 'is_tag') {
                        $special_pages[] = 'タグページ';
                    } else {
                        $special_pages[] = $condition_functions[$page_condition];
                    }
                } else {
                    // 数値IDの場合は固定ページのタイトルを取得
                    $page_title = get_the_title($page_condition);
                    if ($page_title) {
                        $display_info[] = 'ページ: ' . $page_title;
                    }
                }
            }
        }
        
        // 投稿の表示設定 (直接指定されている場合)
        if (isset($widget_options['widget_posts']) && !empty($widget_options['widget_posts'])) {
            $page_types[] = '投稿';
        }
        
        // 固定ページタイプの表示設定 (直接指定されている場合)
        if (isset($widget_options['widget_fixed_pages']) && !empty($widget_options['widget_fixed_pages'])) {
            $page_types[] = '固定ページ';
        }
        
        // 特殊ページタイプを表示情報に追加
        if (!empty($special_pages)) {
            $display_info[] = '特殊ページ: ' . implode(',', $special_pages);
        }
        
        // ページタイプを表示情報に追加
        if (!empty($page_types)) {
            $display_info[] = 'ページ: ' . implode(',', $page_types);
        }
        
        // カスタム投稿タイプの表示設定
        if (isset($widget_options['widget_custom_post_types']) && is_array($widget_options['widget_custom_post_types']) && !empty($widget_options['widget_custom_post_types'])) {
            $post_types = array();
            foreach ($widget_options['widget_custom_post_types'] as $post_type) {
                // 投稿タイプスラッグからオブジェクトを取得
                $post_type_obj = get_post_type_object($post_type);
                if ($post_type_obj) {
                    $post_types[] = $post_type_obj->labels->name;
                } else {
                    // スラッグだけ表示
                    $post_types[] = $post_type;
                }
            }
            if (!empty($post_types)) {
                $display_info[] = '投稿タイプ: ' . implode(', ', $post_types);
            }
        }
        
        // 著者の表示設定
        if (isset($widget_options['widget_authors']) && is_array($widget_options['widget_authors']) && !empty($widget_options['widget_authors'])) {
            $authors = array();
            foreach ($widget_options['widget_authors'] as $author_id) {
                $author = get_userdata($author_id);
                if ($author) {
                    $authors[] = $author->display_name;
                }
            }
            if (!empty($authors)) {
                $display_info[] = '著者: ' . implode(', ', $authors);
            }
        }
        
        if (empty($display_type)) {
            return '';
        }
        
        // 表示設定の整形 - 重複を防ぐ
        if (empty($display_info)) {
            return "表示設定:{$display_type}";
        } else {
            return "表示設定:{$display_type}(" . implode(',', $display_info) . ")";
        }
    }
    
    /**
     * ウィジェットオプションを取得
     */
    private function get_widget_options($widget_id) {
        // ウィジェットIDからベース名と番号を抽出
        if (preg_match('/^(.+)-(\d+)$/', $widget_id, $matches)) {
            $base_id = $matches[1];
            $widget_number = $matches[2];
            
            // ウィジェット設定を取得
            $widget_options = get_option('widget_' . $base_id);
            
            if (isset($widget_options[$widget_number])) {
                // 追加のウィジェット設定を確認(カスタムフィールドなど)
                // これは特定のテーマやプラグインで追加された設定を取得するための拡張ポイント
                $widget_options[$widget_number] = apply_filters('widget_exporter_options', $widget_options[$widget_number], $widget_id);
                
                return $widget_options[$widget_number];
            }
        }
        
        return array();
    }
}

// プラグインの初期化
$widget_exporter = new Widget_Exporter();
プラグインの使い方

このプラグインを使うと、次のような形式でウィジェット情報が出力されます:

# WordPress ウィジェット構造
エクスポート日時: 2025-03-12 14:30:00

## サイドバー
*サイドバーの説明文がある場合表示*

### 検索: サイト内検索(表示)
表示設定:表示(カテゴリ: 日々の投稿)

### 最近の投稿: おすすめ投稿(表示)

### 最近のコメント: (表示)
表示設定:非表示(投稿タイプ: 固定ページ)
プラグインの使い方

この出力から、どのサイドバーにどのウィジェットが配置されているか、各ウィジェットの設定内容、そして表示設定(どのページやカテゴリーで表示/非表示になるか)が一目でわかります。

2. プラグインのメインクラス(UI部分)

プラグインのメイン機能を実装するクラスでは、WordPressの「ツール」メニュー内に「ウィジェットエクスポーター」という項目を追加しています。

WordPressウィジェット構造出力プラグイン ウィジェット管理の課題 ・調整しすぎて元の状態がわからなくなる ・以前の設定状態を確認する方法がない ・トラブル時に比較参照できない 開発したプラグイン ・現在のウィジェット構造を出力 ・Markdown形式で保存可能 ・個人用に最適化された簡潔な設計 プラグイン動作フロー WordPress管理画面 プラグイン実行 ウィジェット解析 Markdown出力 サイドバー・フッター ウィジェット確認 構造出力機能 を起動 現在の設定を スキャン 構造化テキストで 保存可能に 個人用プラグインとして開発・シンプルな構造で管理しやすい設計
class Widget_Exporter {
    
    /**
     * コンストラクタ
     */
    public function __construct() {
        // 管理画面にメニューを追加
        add_action('admin_menu', array($this, 'add_admin_menu'));
        
        // AJAXハンドラーを登録
        add_action('wp_ajax_export_widgets', array($this, 'ajax_export_widgets'));
    }
    
    /**
     * 管理メニューを追加
     */
    public function add_admin_menu() {
        add_submenu_page(
            'tools.php',
            'ウィジェットエクスポーター', 
            'ウィジェットエクスポーター', 
            'manage_options',
            'widget-exporter', 
            array($this, 'admin_page')
        );
    }

add_submenu_pageは、WordPressの管理画面にメニュー項目を追加するための関数です。

2-1. 管理画面の作成

プラグインの管理画面を作成します。
これは、ウィジェット情報をエクスポートするためのボタンなどを配置する画面です。

プラグインのメインクラス(UI部分) Widget_Exporterクラス コンストラクタ public function __construct() { add_action(‘admin_menu’, …); add_action(‘wp_ajax_export_widgets’, …); フックとAJAXハンドラの登録 管理メニュー追加 add_submenu_page( ‘tools.php’, ‘ウィジェットエクスポーター’, … ツールメニューにサブメニュー追加 管理画面の作成 admin_page() 関数 ・ページタイトル「ウィジェットエクスポーター」 ・説明文とエクスポートボタン ・結果表示用テキストエリア JavaScript部分とAJAX処理 1. エクスポートボタンクリック → AJAXリクエスト 2. コピーボタン → クリップボードにコピー 3. ダウンロードボタン → ファイル保存 ※ nonce検証によるセキュリティ対策実装 管理画面に「ウィジェットエクスポーター」メニューを追加し、現在のウィジェット構造をMarkdown形式で出力
    /**
     * 管理画面を表示
     */
    public function admin_page() {
        ?>
        <div class="wrap">
            <h1>ウィジェットエクスポーター</h1>
            <p>現在のウィジェット構造をMarkdown形式でエクスポートします。</p>
            
            <div class="card">
                <h2>エクスポート</h2>
                <p>
                    <button id="export-widgets" class="button button-primary">ウィジェット構造をエクスポート</button>
                </p>
                <div id="export-result" style="display:none;">
                    <h3>エクスポート結果</h3>
                    <textarea id="markdown-output" style="width: 100%; height: 500px; font-family: monospace;"></textarea>
                    <p>
                        <button id="copy-markdown" class="button">コピー</button>
                        <button id="download-markdown" class="button">ダウンロード</button>
                    </p>
                </div>
            </div>
        </div>

このコードでは、シンプルな管理画面を作成しています。「ウィジェット構造をエクスポート」ボタンをクリックすると、JavaScriptを使ってAJAXリクエストが送信され、現在のウィジェット情報が取得されます。結果は大きなテキストエリアに表示され、コピーやダウンロードができます。

2-2. JavaScript部分とAJAX処理部分

ボタンのクリックイベントやAJAX通信を行うJavaScript部分で、3つの機能を実装しています:

ウィジェットデータの取得と解析 データ取得から条件解析までの流れ 1 データ取得 wp_get_sidebars_widgets() 2 ウィジェットID解析 preg_match(‘/^(.+)-(\d+)$/’) 3 オプション取得 get_option(‘widget_’ . $base_id) ウィジェットデータ保存形式 wp_options テーブル シリアライズされた配列 プレフィックス: ‘widget_’ サフィックス: ‘{base_id}’ [widget_number] 表示/非表示条件の解析 条件タイプの分岐 widget_action – show/hide widget_categories – カテゴリー widget_pages – ページ widget_tags – タグ 条件関数処理 is_front_page → フロントページ is_home → ブログページ is_single → 投稿 is_page → 固定ページ データ参照処理 get_category($category_id) get_tag($tag_id) get_the_title($page_id) $tag->name print_r($widget_options, true) // デバッグモード ※WordPressウィジェット解析ツール – データ構造の理解と条件解析
  1. エクスポートボタンをクリックすると、AJAXリクエストを送信してウィジェット情報を取得
  2. コピーボタンをクリックすると、出力されたテキストをクリップボードにコピー
  3. ダウンロードボタンをクリックすると、Markdown形式のファイルをダウンロード
        <script>
        jQuery(document).ready(function($) {
            // エクスポートボタンのクリックイベント
            $('#export-widgets').on('click', function() {
                $(this).prop('disabled', true).text('処理中...');
                
                $.ajax({
                    url: ajaxurl,
                    type: 'POST',
                    data: {
                        action: 'export_widgets',
                        nonce: '<?php echo wp_create_nonce('widget_export_nonce'); ?>'
                    },
                    success: function(response) {
                        $('#export-widgets').prop('disabled', false).text('ウィジェット構造をエクスポート');
                        
                        if (response.success) {
                            $('#markdown-output').val(response.data);
                            $('#export-result').show();
                        } else {
                            alert('エクスポート中にエラーが発生しました: ' + response.data);
                        }
                    },
                    error: function() {
                        $('#export-widgets').prop('disabled', false).text('ウィジェット構造をエクスポート');
                        alert('エクスポート中にエラーが発生しました。');
                    }
                });
            });
            
            // コピーボタンのクリックイベント
            $('#copy-markdown').on('click', function() {
                var copyText = document.getElementById("markdown-output");
                copyText.select();
                document.execCommand("copy");
                alert("クリップボードにコピーしました");
            });
            
            // ダウンロードボタンのクリックイベント
            $('#download-markdown').on('click', function() {
                var text = $('#markdown-output').val();
                var filename = 'widgets-' + new Date().toISOString().slice(0, 10) + '.md';
                
                var element = document.createElement('a');
                element.setAttribute('href', 'data:text/plain;charset=utf-8,' + encodeURIComponent(text));
                element.setAttribute('download', filename);
                element.style.display = 'none';
                document.body.appendChild(element);
                element.click();
                document.body.removeChild(element);
            });
        });
        </script>
        <?php
    }

AJAXリクエストを処理する関数では、まずセキュリティチェック(nonce検証)と権限チェックを行い、問題がなければウィジェット情報のMarkdownを生成して返します。

    /**
     * ウィジェットデータをエクスポートするAJAXハンドラ
     */
    public function ajax_export_widgets() {
        // nonceの検証
        if (!isset($_POST['nonce']) || !wp_verify_nonce($_POST['nonce'], 'widget_export_nonce')) {
            wp_send_json_error('セキュリティチェックに失敗しました。');
        }
        
        // 管理者権限の確認
        if (!current_user_can('manage_options')) {
            wp_send_json_error('十分な権限がありません。');
        }
        
        $markdown = $this->generate_widgets_markdown();
        wp_send_json_success($markdown);
    }

nonceは、クロスサイトリクエストフォージェリ(CSRF)攻撃を防ぐためのセキュリティ対策です。

JavaScript部分とAJAX処理部分

WordPressのウィジェット管理は、サイトの見た目や機能に大きく影響します。しかし、その設定状態を記録する標準的な方法がなかったため、このプラグインを作成しました。このプラグインを使うことで、ウィジェットの設定変更前に状態を記録したり、問題発生時に設定を確認したりするのが簡単になります。

3. ウィジェットデータの取得と解析

ここでは、WordPressの内部機能を使ってウィジェットデータを取得します。

private function generate_widgets_markdown($debug_mode = false) {
    global $wp_registered_widgets, $wp_registered_sidebars;

    $sidebars_widgets = wp_get_sidebars_widgets();
    // 以下、エクスポート処理...
}

ウィジェットデータを取得する際、まず注目すべきは各ウィジェットがどのように保存されているかを理解することです。WordPressはウィジェット設定をwp_optionsテーブルにシリアライズされた配列として保存しています。

ウィジェットデータの取得と解析 WordPressの内部機能を使ってウィジェットデータを取得します 基本データ取得 function generate_widgets_markdown($debug_mode = false) { global $wp_registered_widgets, $wp_registered_sidebars; $sidebars_widgets = wp_get_sidebars_widgets(); // 以下、エクスポート処理… } ウィジェットオプション取得 ウィジェット設定は wp_options テーブルに シリアライズされた配列として保存 function get_widget_options($widget_id) { // ウィジェットIDからベース名と番号を抽出 if (preg_match(‘/^(.+)-(\d+)$/’, $widget_id, $matches)) { $base_id = $matches[1]; // ウィジェット設定を取得 $widget_options = get_option(‘widget_’ . $base_id); } 表示/非表示条件の解析 デバッグ出力機能で実際のデータ構造を確認 if ($debug_mode) { $output .= ““`php\n”; $output .= “// Widget ID: ” . $widget_id . “\n”; $output .= print_r($widget_options, true); } 表示/非表示条件の保存形式 • widget_action – show/hide • widget_categories – カテゴリーID配列 • widget_pages – ページ条件 • その他(タグ、著者など) 条件関数名の処理 • is_front_page → フロントページ • is_home → ブログページ • is_single → 投稿 • is_page → 固定ページ • その他の条件… タグやその他の条件処理 • タグが配列または単一の数値(ID)として保存 • 単一IDの場合: $tag = get_tag($widget_options[‘widget_tags’]); if ($tag) { $display_info[] = ‘タグ: ‘ . $tag->name; }

各ウィジェットのオプションを取得するには、ウィジェットIDからベース名と番号を抽出し、対応するオプションを取得します。

private function get_widget_options($widget_id) {
    // ウィジェットIDからベース名と番号を抽出
    if (preg_match('/^(.+)-(\d+)$/', $widget_id, $matches)) {
        $base_id = $matches[1];
        $widget_number = $matches[2];

        // ウィジェット設定を取得
        $widget_options = get_option('widget_' . $base_id);

        if (isset($widget_options[$widget_number])) {
            return $widget_options[$widget_number];
        }
    }

    return array();
}

3-1. 表示/非表示条件の解析

この部分が最も難しく、興味深い部分でした。ウィジェットの表示/非表示条件は各テーマやプラグインによって実装方法が異なります。まず、デバッグ出力機能を追加して実際のデータ構造を確認しました。

// デバッグモードの場合、ウィジェットオプションの内容を出力
if ($debug_mode) {
    $output .= "```php\n";
    $output .= "// Widget ID: " . $widget_id . "\n";
    $output .= "// Options:\n";
    $output .= print_r($widget_options, true);
    $output .= "```\n\n";
}

デバッグ出力からわかったのは、表示/非表示条件が以下のような形式で保存されていることです。

  1. widget_action – 表示/非表示を決める値(showまたはhide
  2. widget_categories – カテゴリーID配列
  3. widget_pages – ページ条件(ただしこれが数値IDだけでなく、is_singleis_pageなどの関数名も含む)
  4. その他条件(タグ、著者、カスタム投稿タイプなど)
表示/非表示条件の解析

特にwidget_pagesの処理が複雑でした。この配列には固定ページのIDだけでなく、is_single(投稿ページ)やis_page(固定ページ)のような条件関数名も含まれていました。

3-2. 条件関数名の処理

デバッグ出力から得られた情報を元に、条件関数名を適切な表示名に変換する処理を追加しました。

ウィジェット条件処理フロー デバッグ出力による条件形式の発見 // デバッグモードの場合、ウィジェットオプションの内容を出力 if ($debug_mode) { $output .= print_r($widget_options, true); } 発見された条件保存形式 1. widget_action – show/hide 2. widget_categories – カテゴリーID配列 3. widget_pages – ページID + 条件関数名 (is_single, is_page, is_front_page など) 4. その他 – タグ、著者、カスタム投稿タイプ 条件関数名の処理 // WordPress条件関数の定義マッピング配列 $condition_functions = array( ‘is_front_page’ => ‘フロントページ’, ‘is_home’ => ‘ブログページ’, // その他の条件… ); // widget_pages 配列の各条件を処理 foreach ($widget_options[‘widget_pages’] as $page_condition) { // 条件関数名かチェック if (is_string($page_condition) && isset($condition_functions[$page_condition])) { // 関数名から表示名への変換処理… } } 条件タイプ 文字列 (is_front_page) 数値 (ページID) 条件関数名を表示名に変換 get_the_title($page_id) ※ widget_pages処理の特殊性:IDと条件関数名が混在
// 特殊な条件チェック - WordPress条件関数名
$condition_functions = array(
    'is_front_page' => 'フロントページ',
    'is_home' => 'ブログページ',
    'is_single' => '投稿',
    'is_page' => '固定ページ',
    // その他の条件...
);

foreach ($widget_options['widget_pages'] as $page_condition) {
    // 条件関数名かチェック
    if (is_string($page_condition) && isset($condition_functions[$page_condition])) {
        if ($page_condition === 'is_single') {
            $page_types[] = '投稿';
        } elseif ($page_condition === 'is_page') {
            $page_types[] = '固定ページ';
        } elseif ($page_condition === 'is_front_page') {
            $special_pages[] = 'フロントページ';
        } else {
            $special_pages[] = $condition_functions[$page_condition];
        }
    } else {
        // 数値IDの場合は固定ページのタイトルを取得
        $page_title = get_the_title($page_condition);
        if ($page_title) {
            $display_info[] = 'ページ: ' . $page_title;
        }
    }
}

3-3. タグやその他の条件処理

タグの処理も工夫が必要でした。デバッグ出力から、タグが配列だけでなく単一の数値(ID)として保存されているケースもあることがわかりました。

// タグの表示設定
if (isset($widget_options['widget_tags']) && !empty($widget_options['widget_tags'])) {
    if (is_array($widget_options['widget_tags'])) {
        // 配列の場合の処理
    } else {
        // 単一のタグIDの場合
        $tag = get_tag($widget_options['widget_tags']);
        if ($tag) {
            $display_info[] = 'タグ: ' . $tag->name;
        }
    }
}
こちらもどうぞ。
[WordPress]ウィジェットタイトルを非表示にするCSS
[WordPress]ウィジェットタイトルを非表示にするCSS
WordPressの管理画面で多数のウィジェットを区別しやすくするため、タイトルをつけると便利です。しかし、管理用のタイトルがサイト上で表示されてしまうのは困ります。これは簡単なCSS設定で解決でき、サイト運営の効率が向上しました。ウィジェットタイトルの表示設定についてWordPressサイトでは、多数のウィジェットを配置していると、管理画面での区別が難しくなることがあります。各ウィジェットに管理用のタイトルをつければ楽です。しかし、サイト上でも表示されてしまうため、これまで...

WordPressの編集画面での差し替えた画像が古い状態で表示される?(画像キャッシュ)
WordPressの編集画面での差し替えた画像が古い状態で表示される?(画像キャッシュ)
WordPressの画像キャッシュ問題により、差し替えた画像が古い状態で表示されることがあります。これは、ブラウザのキャッシュと画像URLの仕様が主な原因でした。キャッシュが読み込まれないように、functions.phpに管理者用に JavaScriptのコードを追加して、動的に画像URLにタイムスタンプを付与するようにしました。WordPressの画像キャッシュ問題WordPressでサイトを運営しているのですが、差し替えた画像ファイルをプラグイン(Media Clean...

WordPressの古いリビジョンをまとめるカスタムプラグインを作った
WordPressの古いリビジョンをまとめるカスタムプラグインを作った
WordPressの古いリビジョンを整理するカスタムプラグインを作成しました。このプラグインは一週間以上前のリビジョンから日ごとに最新の一つだけを残し、データベースの肥大化を防ぎます。管理画面からリアルタイムで進行状況を確認でき、毎日自動実行されるため効率的なサイト管理ができます。WordPressの記事保存の処理は、体感ではそこまで速くはなりませんでした。編集履歴を管理するプラグインを作ったWordPressで記事を保存する処理が遅くなってきた気がします。リビジョン(編集履...

Wordはもう古い?文書作成にMarkdown(マークダウン)記法を使うメリット
Wordはもう古い?文書作成にMarkdown(マークダウン)記法を使うメリット
文書をWordで書くケースは多いですが、機能が多すぎたり立ち上がりが遅かったり、逆に使いにくいと感じることもありませんか。 この記事では、文書作成をスムーズに進めるためのMarkdown記法とエディタについて解説します。Wordで文書を作るときに感じる不満あなたは長い文章を書くときに何のソフトを使っていますか。多くの人はビジネス文書の作成に Word を使っているのではないでしょうか。しかし、Wordは長い文章を書くのにあまり効率的でないと感じることはありませんか?起動に時間...
QRコードを読み込むと、関連記事を確認できます。

[WordPress] ウィジェット構造をMarkdown形式で出力するプラグインを作ってみた
タイトルとURLをコピーしました