トラブルシューティング

よくある問題とその解決方法をまとめます。症状 → 原因 → 対処の順で記載しています。最後に FAQ も用意しています。

md ホストにアクセスしても 404 / 503 が返る

もっとも頻発する症状です。原因は複数あり得るため、上から順に切り分けます。

原因 1: kill switch が ON になっている

一般タブの kill switch が ON のとき、core-functions.phpksmd_handle_subdomain_request() が以下のように動作し、503 を返します。

// (3) kill switch (md ホスト確認後にのみ評価)
if ( ! empty( $opts['kill_switch'] ) ) {
    ksmd_send_503( __( 'md サブドメインは一時停止中です。', 'kashiwazaki-llmo-md-subdomain' ) );
}

一般タブで「kill switch を OFF にする (md 配信を再開)」ボタンを押してください。

原因 2: master switch が OFF になっている

master switch (enabled) が default で OFF になっているのはインストール直後の事故防止のためです。一般タブで「プラグインを有効化」をチェックして保存してください。

// (4) 有効/無効 (default OFF)
if ( empty( $opts['enabled'] ) ) {
    ksmd_send_503( __( 'プラグインがまだ有効化されていません。設定画面で有効化してください。', 'kashiwazaki-llmo-md-subdomain' ) );
}

原因 3: md_host が間違っている

$_SERVER['HTTP_HOST']md_host と一致しないとプラグインは即 return します (メイン側 no-op の原則を守るため)。一般タブで md_host が実際にアクセスしているサブドメインと一致していることを確認してください。

if ( $host !== strtolower( (string) $md_host ) ) {
    return; // メイン側は完全に no-op
}

原因 4: DNS 反映前 / DNS 設定漏れ

DNS が反映されていないと、そもそも md ホストへ到達できません。dig md.example.com @8.8.8.8 で外部 DNS 経由で確認してください。詳しくは DNS と Bootstrap ページを参照。

⚠️ Warning

503 と 404 では原因が異なります。503 はプラグインが意図的に停止している (kill switch / master switch OFF) ケース。404 はプラグインは動作しているが該当 URL が存在しない (post 削除済 / route 無効) ケース。レスポンスヘッダの X-Ksmd-Cache が出ていれば、少なくともプラグインは応答しています。

md.example.com にアクセスすると www サイトが表示される

md ホスト用の index.php が無いか、Web サーバの設定が誤っているケースです。

原因 1: Bootstrap installer 未実行

診断タブの「md ホスト ブートストラップ」セクションで「index.php を生成」を実行していないと、md ホストへのリクエストが Web サーバのデフォルト DocumentRoot (= メインサイト) にフォールバックしている可能性があります。

原因 2: Web サーバの VirtualHost で DocumentRoot が分離されていない

Apache / Nginx / コントロールパネルで md サブドメイン用の DocumentRoot が登録されていない場合、メインサイトの DocumentRoot にリクエストが流れてしまいます。サーバの管理画面で md サブドメインを「サブドメインとして追加」してください。

原因 3: Cloudflare 等の Page Rule 干渉

Cloudflare で「md.example.com/* → www.example.com/$1 にリダイレクト」のような Page Rule が残っていると、md へのリクエストが www に強制リダイレクトされます。Cloudflare ダッシュボード → Rules → Page Rules / Configuration Rules を確認してください。

md ホストの favicon が表示されない

md ホストは Markdown 配信が主目的のため HTML <head> がなく、ブラウザの favicon discovery 経路が制限されます。本プラグインは「favicon プロキシ」機能で 5 URI への 302 redirect を提供しますが、ブラウザの挙動依存で表示されない場合があります。

原因 1: 「favicon プロキシ」設定が OFF

「一般」タブの「favicon プロキシ」チェックボックス (enable_favicon_proxy) が OFF だと、md ホストの /favicon.ico 等は通常のルート解決を経由して 404 になります。デフォルトは ON です。curl -I https://md.example.com/favicon.ico で 302 が返るか確認してください。

原因 2: WordPress の Site Icon が未設定

302 リダイレクト先は get_site_icon_url() から取得します。「設定 → 一般 → サイトアイコン」が未設定の場合は home_url('/favicon.ico') にフォールバック。テーマやサーバーが /favicon.ico を返さなければ最終的にブラウザは 404 を受け取ります。

原因 3: ブラウザが text/markdown をダウンロード扱い

md ホームは Content-Type: text/markdown; charset=utf-8 で配信されるため、Chrome / Firefox 等の主要ブラウザは「ダウンロード対象」として処理し、タブを開きません。タブが開かないため favicon リクエスト自体が発生しません。これは仕様上の制約で、AI クローラ・curl・iOS Safari の自動推測経路 (/apple-touch-icon.png) は引き続き機能します。

メイン側 HTML に md 並行版へのリンクヘッダが出ない

「出力」タブの「メイン側 md 並行版リンク (alt-link)」機能は、メインサイトの HTML レスポンスに HTTP Link: ヘッダ + HTML <head><link> タグで md URL を AI クローラに告知します。出力されない場合は以下を順に確認してください。

原因 1: master switch (enabled) が OFF

一般タブのプラグイン有効化チェックが OFF だと alt-link 機能も無効です。

原因 2: enable_md_alternate_link 設定が OFF

「出力」タブの「メイン側 md 並行版リンク」が OFF だと alt-link は出力されません。デフォルトは ON。curl -sI https://example.com/posts/foo | grep -i ^link で確認できます。

原因 3: 「対象範囲」タブで該当 post_type / route が OFF

alt-link は md 側 resolver と整合し、enabled_post_types / enabled_routes で OFF にされた対象には出力しません (AI クローラへの誤誘導防止)。「対象範囲」タブで該当 post_type / route が ON か確認してください。

原因 4: 出力対象外のリクエスト

alt-link は admin / AJAX / REST / cron / feed / robots / trackback / 404 では出力しません。また is_singular() / is_archive() / is_home() / is_search() 等のコンテンツページのみ対象です。空検索 (?s= で s が空) も除外されます。

Markdown が古いままで更新が反映されない

キャッシュ問題です。本プラグインは backend を 3 種類サポートしており、それぞれの flush 経路を理解しておくと解決が早くなります。

原因 1: post 保存時の自動 invalidation がスキップされた

admin/admin-loader.phpsave_post および transition_post_status hook が ksmd_invalidate_post_cache / ksmd_on_transition を呼び、対象 post の cache を削除します。これらのフックはコア経由の保存ではほぼ確実に発火しますが、REST API や WP-CLI 経由の更新では順序差で残ることがあります。

原因 2: 別 backend の cache が残っている

backend を切り替えた直後 (例: transient → object_cache) は旧 backend のデータが残ることがあります。一般タブで kill switch を ON → OFF とトグルすると ksmd_cache_flush_all() が呼ばれ、すべての backend を flush します。

原因 3: cache backend の挙動を理解する

// includes/cache.php
function ksmd_cache_get( $key ) {
    $backend = ksmd_cache_backend();
    switch ( $backend ) {
        case 'object_cache':
            $found = false;
            $val   = wp_cache_get( $key, 'ksmd', false, $found );
            return $found ? $val : false;
        case 'custom_table':
            return ksmd_cache_get_custom_table( $key );
        case 'transient':
        default:
            return get_transient( $key );
    }
}

💡 Tip

強制リフレッシュは ?md_refresh=1 をクエリに付けて (admin ログイン状態で) アクセスする方法もあります。core-functions.php:110current_user_can( 'manage_options' ) を確認した上で $force_miss = true となります。

Test renderer で「HTTP リクエストブロック」エラー

WP_HTTP_BLOCK_EXTERNAL 定数が true の場合、wp_remote_get() がエラーを返すため、Test renderer や Bootstrap verify が動作しません。

対処

wp-config.phpWP_HTTP_BLOCK_EXTERNALtrue になっていないか確認します。true でも WP_ACCESSIBLE_HOSTS に md ホストを追加すれば動作します。

// wp-config.php 例
define( 'WP_HTTP_BLOCK_EXTERNAL', true );
define( 'WP_ACCESSIBLE_HOSTS', 'md.example.com,*.example.com' );

アクセスログが記録されない

診断タブのアクセスログ機能で何も記録されない場合、いくつかの原因が考えられます。

原因 1: 「アクセスログを有効化」がチェックされていない

診断タブの「アクセスログを有効化」チェックボックスを ON にして「診断設定を保存」してください。access_log_enabled オプションが true になります。

// includes/security.php
function ksmd_access_log( $uri, $status, $start_ts ) {
    $opts = get_option( KSMD_OPTION_KEY, array() );
    if ( empty( $opts['access_log_enabled'] ) ) {
        return;
    }
    // ...
}

原因 2: 専用テーブル {prefix}ksmd_access_logs が作成されていない

本プラグインはアクセスログを {prefix}ksmd_access_logs テーブルに INSERT で記録します (旧版の update_option ベースは廃止)。テーブルは初回ログ記録時に ksmd_access_log_maybe_create_table()dbDelta で自動作成しますが、DB 権限不足で作成失敗するとログが残らなくなります。

原因 3: ksmd_access_log_table_ready オプションの不整合

テーブル作成済みフラグ ksmd_access_log_table_ready が KSMD_VERSION と一致するが実テーブルが無いケース (uninstall + 同一バージョン再インストール時等) では、ksmd_access_log_maybe_create_table() がフラグを削除して再作成します。手動でも phpMyAdmin で delete_option('ksmd_access_log_table_ready') 相当のクエリを実行すれば再作成されます。

function ksmd_access_log_maybe_create_table() {
    global $wpdb;
    $table = $wpdb->prefix . 'ksmd_access_logs';
    if ( get_option( 'ksmd_access_log_table_ready' ) === KSMD_VERSION ) {
        // 再インストール時の保険: テーブル実体を確認、無ければ flag を消して再作成へ
        $exists = (bool) $wpdb->get_var( $wpdb->prepare( 'SHOW TABLES LIKE %s', $table ) );
        if ( $exists ) {
            return;
        }
        delete_option( 'ksmd_access_log_table_ready' );
    }
    // dbDelta で CREATE TABLE
    // ...
}

Schema.org の type が反映されない

「post なのに Article でなく WebPage が出る」「特定の CPT を ProfilePage にしたいのに反映されない」といったケースです。

原因 1: Schema.org タブの schema_type_map 設定漏れ

Schema.org タブで post_type 別 / route 別の @type マッピングを設定します (ksmd_settings.schema_type_map)。デフォルトは以下の通りです (ksmd_get_default_settings())。

'schema_type_map' => array(
    'post'             => 'Article',
    'page'             => 'WebPage',
    'archive'          => 'CollectionPage',
    'term'             => 'CollectionPage',
    'category'         => 'CollectionPage',
    'tag'              => 'CollectionPage',
    'author'           => 'ProfilePage',
    'date'             => 'CollectionPage',
    'home'             => 'WebSite',
    'front_page'       => 'WebSite',
    'search'           => 'SearchResultsPage',
    '404'              => 'Thing',
),

原因 2: ksmd_schema_type filter で上書きされている

テーマや別プラグインが ksmd_schema_type filter を使って @type を強制上書きしている可能性があります。functions.php 等で add_filter( 'ksmd_schema_type', ... ) していないか確認してください。実装は以下です。

// includes/md-schema-mapper.php
$type = apply_filters( 'ksmd_schema_type', $type, $post->post_type, array( 'post' => $post ) );

// includes/md-route-renderers.php (route 系)
$type = apply_filters( 'ksmd_schema_type', $type, 'archive', $context );
$type = apply_filters( 'ksmd_schema_type', $type, 'term', $context );
$type = apply_filters( 'ksmd_schema_type', $type, 'author', $context );
// ...

対処

意図して上書きしているのでなければ、remove_filter() で外すか、Schema.org タブで再度マッピングを設定して保存してください。

Bootstrap installer が「権限なし」エラー

「ディレクトリへの書き込み権限がありません」または「probe ファイルの書き込みに失敗しました」と表示される場合、サーバ側の権限問題です。

原因 1: ディレクトリの ownership / permission

md ホストの DocumentRoot が PHP 実行ユーザ (www-data / nginx / apache) と異なるユーザの ownership になっていると書き込めません。

ls -la /home/user/public_html/md.example.com
# drwxr-xr-x 2 user user 4096 Apr 30 12:00 .
# 所有者が user なのに PHP が www-data で動いていると書き込み不可

# 対処: PHP 実行ユーザを ownership に追加 or 親ディレクトリに合わせる
sudo chown -R www-data:www-data /home/user/public_html/md.example.com
# または: グループに www-data を入れて 775 にする

原因 2: open_basedir 制限

php.iniphp-fpm プールで open_basedir が設定されている場合、その範囲外のディレクトリは realpath()file_put_contents() がすべて失敗します。Bootstrap installer の gate #1 (realpath) や gate #8 (probe write) で失敗します。

# php-fpm pool config 例
# /etc/php/8.x/fpm/pool.d/example.conf
php_admin_value[open_basedir] = /home/user/:/tmp/:/var/lib/php/

# md DocumentRoot が /home/user/ 配下なら OK
# /var/www/md.example.com/ 等は基準外で書き込み不可

原因 3: SELinux

RHEL / CentOS で SELinux が enforcing の場合、httpd_sys_rw_content_t ラベルが必要なディレクトリに対する書き込みがブロックされます。

sudo chcon -R -t httpd_sys_rw_content_t /home/user/public_html/md.example.com

複数言語サイトでの inLanguage が反映されない

多言語環境で inLanguage の値が想定と違うケースです。

原因 1: i18n タブの上書き値

言語タブで inLanguage の上書き値を設定している場合、それが優先されます。多言語プラグインに任せるなら空欄に戻してください。

原因 2: WPML / Polylang / MultilingualPress 連携 (次バージョン対応予定)

v1.0.0 時点では WPML / Polylang の自動連携は未実装です。診断タブの互換性チェック表に「次バージョンで自動連携対応予定」と記載されています (admin/sections/diagnostics.php)。現状はテーマ側の get_locale()ksmd_route_schema_header_lines filter で上書きすると確実です。

原因 3: route 別 schema header lines

archive / term / author 等の route ごとに inLanguage を変えたい場合、ksmd_route_schema_header_lines filter を使います。

add_filter( 'ksmd_route_schema_header_lines', function( $lines, $type, $headline, $url, $context ) {
    // term route だけ inLanguage を tt の言語に切り替え
    if ( $type === 'term' && ! empty( $context['term'] ) ) {
        // pll_get_term_language( $context['term']->term_id ) 等で取得
        $lang = pll_get_term_language( $context['term']->term_id );
        $lines[] = '> inLanguage: ' . $lang;
    }
    return $lines;
}, 10, 5 );

Custom table キャッシュの肥大化

cache_backend = custom_table を選択すると {prefix}ksmd_cache テーブルにキャッシュが蓄積します。サイト規模が大きくなるとテーブルが肥大化することがあります。

原因 1: TTL が長すぎる

キャッシュタブで TTL (cache_duration) を default の 1 時間 (HOUR_IN_SECONDS) より長くしている場合、エントリが残り続けます。post 数 × route 数 × TTL の積でテーブルサイズが決まります。

原因 2: 自動 GC が働いていない

本プラグインは ksmd_cache_get_custom_table() 内で「読み込み時に expires_at < now なら DELETE」する lazy GC を実装しています。読まれない古いエントリは残り続けるため、定期的な手動 flush が望ましいです。

function ksmd_cache_get_custom_table( $key ) {
    // ...
    if ( (int) $row['expires_at'] < $now ) {
        $wpdb->delete( $table, array( 'cache_key' => $key ), array( '%s' ) );
        return false;
    }
    return maybe_unserialize( $row['cache_value'] );
}

対処: 手動 flush

一般タブの kill switch を ON → OFF とトグルすると ksmd_cache_flush_all() が呼ばれ、ksmd_cache_truncate_custom_table() でテーブルが TRUNCATE されます。

object_cache backend に切り替えたら他プラグインが影響を受けた

backend を object_cache にした際に、save_post 等の hook 経由で wp_cache_flush() が呼ばれ、他プラグインの cache まで道連れになる現象です。

原因と対処

v1.0.0 では「backend が object_cache の場合のみ」 group flush 非対応 drop-in で wp_cache_flush() を呼ぶ仕様に修正済みです。cache_backendtransientcustom_table の場合は wp_cache_flush() を呼ばないため、他プラグインへの影響はありません。

// includes/cache.php
function ksmd_cache_flush_all() {
    // transient (常に削除)
    if ( function_exists( 'ksmd_clear_all_transients' ) ) {
        ksmd_clear_all_transients();
    }
    // group flush に対応している drop-in なら group 単位で flush
    if ( function_exists( 'wp_cache_supports' ) && wp_cache_supports( 'flush_group' )
         && function_exists( 'wp_cache_flush_group' ) ) {
        wp_cache_flush_group( 'ksmd' );
    } elseif ( ksmd_cache_backend() === 'object_cache' && function_exists( 'wp_cache_flush' ) ) {
        // backend が object_cache でかつ group flush 非対応 → 全 object cache を flush せざるを得ない
        wp_cache_flush();
    }
    // custom table
    ksmd_cache_truncate_custom_table();
}

恒久的に他プラグインへの影響を避けるには、wp_cache_supports('flush_group') をサポートする drop-in (Redis Object Cache pro / W3 Total Cache 等) を使ってください。wp_cache_flush_group('ksmd') が使えれば本プラグインの cache だけを flush できます。

kill switch が ON のまま戻せない

kill switch が ON のまま OFF にできない、というレアケースです。

原因 1: 一般タブのトグルボタンが機能しない

一般タブの ksmd_toggle_kill_switch アクションは admin_post_ksmd_toggle_kill_switch hook で処理されます。check_admin_referer() + current_user_can('manage_options') のチェックがあるため、権限不足やセッション切れだと動作しません。一度ログアウト → ログインしてから再度トグルしてください。

原因 2: option を直接編集する最終手段

どうしてもトグルできない場合は phpMyAdmin / WP-CLI で直接 option を書き換えます。

# WP-CLI 経由で kill_switch を OFF に
wp option get ksmd_settings --format=json > /tmp/ksmd.json
# ksmd.json を編集して kill_switch:false に
wp option update ksmd_settings --format=json < /tmp/ksmd.json
-- phpMyAdmin の SQL タブで実行 (上級者向け)
SELECT option_value FROM wp_options WHERE option_name = 'ksmd_settings';
-- 値をコピーして PHP unserialize / json で kill_switch を false に書き換え
-- UPDATE で書き戻し

md → www にリダイレクトされてしまう

md.example.com にアクセスしたのに www.example.com に強制リダイレクトされる現象です。

原因 1: Yoast SEO 等のメインサイト canonical redirect

Yoast SEO の「Force canonical URL redirects」を有効にすると、canonical (= www) と異なるホスト (= md) からのアクセスを www に強制リダイレクトします。

対処: template_redirect priority -1 が先勝ちする確認

本プラグインは template_redirect priority -1 でフックしているため、Yoast 等の canonical redirect (priority 1 グループ) より先に発火し、md ホストでの応答を返してそのまま exit します。理屈上は競合しないはずですが、別プラグインが priority -1 以下 (つまり -10 等) で動作している場合は本プラグインの動作が阻害される可能性があります。

// includes/core-functions.php
add_action( 'template_redirect', 'ksmd_handle_subdomain_request', -1 );

原因 2: Cloudflare の Always Use HTTPS / 強制リダイレクト

Cloudflare の「Always Use HTTPS」や「Page Rules → Forwarding URL」が md.example.com を別ホストにリダイレクトしている可能性があります。Cloudflare ダッシュボードで設定を見直してください。

全 11+ filter が効かない

カスタマイズしたつもりの filter (ksmd_md_scheme / ksmd_host / ksmd_home_intro_markdown 等) が反映されないケースです。

原因 1: filter 名のスペル誤り

本プラグインの filter 名は厳密です。よくある誤りパターン: ksmd_md_host (誤) / ksmd_host (正)、ksmd_archive_links (誤) / ksmd_home_archive_links (正) など。extending.html リファレンスで正確な filter 名を確認してください。

原因 2: 登録タイミング (init 以前 / 以後)

本プラグインは plugins_loaded priority 0 で core-functions.php を require_once しています。filter 自体は apply_filters() 呼び出し時に評価されるため、add_filter()template_redirect 発火前であれば間に合います。一般的には init hook 内で add_filter() するのが安全です。

// 推奨パターン: init で add_filter
add_action( 'init', function() {
    add_filter( 'ksmd_host', function( $host ) {
        return 'ai.example.com';
    } );
} );

原因 3: priority の競合

同じ filter に複数の add_filter() が掛かっている場合、priority の数値が小さい方が先に動作します。期待通りの値を返すには priority を 9999 等にして最後に動作させると確実です。

主要 filter のリファレンス

filter 名呼び出し場所用途
ksmd_md_schememd-renderer.php:154md リンク生成時の scheme (http/https) を上書き
ksmd_hostcore-functions.php:48 / md-renderer.php:143md ホスト名を動的上書き
ksmd_home_intro_markdownmd-route-renderers.php:359md ホームのイントロ Markdown を上書き
ksmd_home_archive_linksmd-route-renderers.php:577md ホームのアーカイブリンク一覧を上書き
ksmd_home_recent_post_typemd-route-renderers.php:402md ホーム最新記事一覧の post_type を上書き
ksmd_archive_default_post_typesmd-route-renderers.php:491archive route のデフォルト post_types を上書き
ksmd_term_archive_post_typesmd-route-renderers.php:159term archive の対象 post_types を上書き
ksmd_archive_query_argsmd-route-renderers.php:113, 185, 243, 312, 426, 711, 764WP_Query 引数を上書き (route 別)
ksmd_schema_typemd-schema-mapper.php:39 / md-route-renderers.php 多数Schema.org の @type を上書き
ksmd_schema_header_linesmd-schema-mapper.php:129singular post の Schema header 行を上書き
ksmd_schema_footer_linesmd-schema-mapper.php:168singular post の Schema footer 行を上書き
ksmd_route_schema_header_linesmd-route-renderers.php:860route 系の Schema header 行を上書き
ksmd_route_schema_footer_linesmd-route-renderers.php:895route 系の Schema footer 行を上書き
ksmd_robots_txt_linesmd-resolver.php:360md ホストの robots.txt 行を上書き
ksmd_bootstrap_sslverifymd-bootstrap-installer.php:649verify 時の SSL 検証を上書き (default true)

公式バグ報告先

解決しない問題は GitHub Issues で報告してください。最低限以下の情報を添えると診断が早くなります。

報告先

必須情報

診断タブの互換性チェック表
互換性チェック表のスクリーンショットを Issue に添付すると、サポート側で環境問題の切り分けが格段に早くなります。

💡 Tip

診断タブの「設定の export / import」セクションで JSON を出力できます (ksmd_export_settings アクション)。設定のスクリーンショットを並べるよりも、JSON ファイルを Issue に添付した方が再現性が高いです。

FAQ

細かいよくある質問を 10 個に絞ってまとめます。

Q1. メインサイトの SEO に影響しますか?

A. しません。本プラグインは「メインサイト出力に副作用ゼロ」を設計原則とし、$_SERVER['HTTP_HOST'] が md ホストでない限り即 return します。さらに md レスポンスは X-Robots-Tag: noindex, follow を付けて自身の検索インデックス化を抑止し、Link: rel="canonical" でメインサイトを正規 URL として明示します。

Q2. AI クローラ向けと言いますが Googlebot はどうなりますか?

A. Googlebot に対しても md ホストは noindex, follow です。Google は md ホストを通常検索結果には載せませんが、リンクは辿ります。狙いは ChatGPT / Claude / Perplexity / Gemini 等の AI クローラの token 消費を減らすことです。

Q3. md ホストへのアクセスログをサーバ側 (Apache/Nginx) でも取れますか?

A. はい。サーバ側のアクセスログは通常通り記録されます。本プラグインのアクセスログは「プラグインが応答した URI / 処理時間 / status / IP / UA」を記録するもので、サーバログとは独立しています。

Q4. CDN / Cloudflare 配下でキャッシュは動きますか?

A. md レスポンスは Cache-Control: no-store, no-cache, must-revalidate, max-age=0 を返すため、CDN エッジキャッシュは効きません。これは「kill switch を瞬時に効かせる」「post 更新を即時反映する」ための設計です。エッジキャッシュを効かせたい場合は CDN 側で Page Rule で Cache-Control を上書きすれば可能ですが、推奨しません。

Q5. md ホストでログインや購読等の動作はできますか?

A. できません。本プラグインは AJAX / REST / cron リクエストでは介入しません (core-functions.php の防御ガード)。ログイン UI やプラグイン UI が必要な場合はメインサイト (www) で行ってください。

Q6. md ホストの URL 構造はどう決まりますか?

A. メインサイトと同じパス構造です。https://www.example.com/2024/01/foo/ に対応する md は https://md.example.com/2024/01/foo/ です。リダイレクトはせず、md ホストの URL 内で完結する内部巡回 (md → md) を実装しています。

Q7. CPT (カスタム投稿タイプ) は対応していますか?

A. はい。デフォルトでは get_post_types( array( 'public' => true ) ) から attachment を除いた全 public post_type が ON になっています (有効化時に保存)。後から CPT を追加した場合は対象範囲タブで個別に ON にしてください。

Q8. パスワード保護記事や下書き記事は md で出ますか?

A. 出ません。ksmd_is_post_publicly_serviceable()post_status === 'publish' / post_password === '' / is_post_publicly_viewable() を厳密にチェックし、いずれか NG なら 404 を返します (includes/security.php)。

Q9. アクセスログの IP は anonymize されますか?

A. 「IP 匿名化」チェックボックスを ON にすると、IPv4 は末尾オクテットを 0 マスク、IPv6 は inet_pton で 16 バイトに正規化した上で下位 8 バイト (= 64 bit suffix) を 0 マスクします (RFC 7239 / GDPR 推奨の "IPv6 anonymization to /64" 準拠)。実装は ksmd_anonymize_ip()

Q10. プラグイン更新時に既存の設定は保持されますか?

A. はい。ksmd_settings オプションは更新時に削除されません。ksmd_migrate_legacy_option() がアップグレード時に旧キー kashiwazaki_llmo_md_settings から新キー ksmd_settings へ 1 回限りのコピーを行い、新フィールドの default を array_merge() で補完します。設定が消えるのは「プラグインを停止 → 削除」した場合のみです (uninstall.php が動作)。

まとめ

本ページではよくある問題と対処を網羅しました。それでも解決しない場合は GitHub Issues に互換性チェック表のスクリーンショットと設定の JSON エクスポートを添えて報告してください。