お問い合わせ

SWELL 不具合 | 目次が表示されなくなった原因と回避策

SWELLを使っていてあるタイミングから目次が表示されていないことに気が付きました。

カスタマイズの影響だったのですが、SWELL特有の原因でなかなか気が付かなかったのでメモしておきます。

SWELLの目次はJavascriptで生成している

SWELLの目次は、サイトを表示した後にjavascriptで見出し構造を解析して目次を生成する仕組みです。

サイトを表示する時にPHPで目次を生成しているわけではありません。

javascriptが正常に動かない場合は目次が表示されません。

もし、SWELLの目次が表示されない場合は、javascriptのエラーを疑うのが第一です。

SWELLの目次が表示されない場合は?
  • javascriptの最適化プラグインを導入していないか?
    • AutoptimizeのJS圧縮
    • キャッシュプラグインのJS最適化
  • レンタルサーバーでjavascriptの最適化を行う機能が有効化されていないか?

Javascriptのエラーが疑われる場合は、Javascriptの最適化機能をOFFしてみます。

検証ツールなどでjavascriptの実行にエラーが無い場合は、PHP側の問題を疑います。

なぜカスタマイズすると目次が表示されなくなるのか?

カスタマイズのコードにあるthe_contentフィルターが原因

カスタマイズコードで、apply_filters('the_content',....)を追加して、the_contentの内容を参照していました。

このコードを追加した時は目次が表示されず、追加しなければ目次が表示されます。

目次が表示されなくなる仕組み

SWELLの目次表示のコードは以下のようになっていました。

the_contentフィルターフックで、目次の処理を行うとSWELL::$added_tocがセットされて、2回目以降は表示されないようになっています。

プラグイン等のコードにapply_filters('the_content',....)があると、そのタイミングで目次が追加され、それ以降は追加されなくなります。

一方で、プラグイン等のコードにあるapply_filters('the_content',....)の出力はSWELLには渡らないので、目次は表示されないというカラクリになります。

/**
 * 目次 + 目次広告のセット
 */
function add_toc( $content, $is_content_hook = true ) {

	// ウィジェットですでにswell_tocで生成されている時に本文エリアでの2重生成を防ぐ
	// if ( SWELL::$added_toc ) return $content;

	$SETTING = SWELL::get_setting();
	$toc_ad  = '';
	$toc     = '';

	// ショートコードで目次が挿入されているかどうか
	if ( false !== strpos( $content, 'class="swell-toc-placeholder"' ) ) {

		// 目次本体
		$toc = '<div class="p-toc -called-from-sc -' . $SETTING['index_style'] . '">' .
			'<span class="p-toc__ttl">' . $SETTING['toc_title'] . '</span></div>';

		// 目次広告コード
		if ( SWELL::is_show_toc_ad() ) {
			$toc_ad = \SWELL_PARTS::toc_ad();
		}

		// 広告を目次の前に設置するか、後ろに設置するか
		$toc_content = 'after' === $SETTING['toc_ad_position'] ? $toc . $toc_ad : $toc_ad . $toc;

		$content = str_replace(
			'<div class="swell-toc-placeholder"></div>',
			$toc_content,
			$content
		);

		SWELL::$added_toc = true;

	} elseif ( $is_content_hook ) {

		if ( SWELL::$added_toc ) return $content;

		// 目次本体
		if ( SWELL::is_show_index() ) {
			$toc = '<div class="p-toc -' . $SETTING['index_style'] . '">' .
				'<span class="p-toc__ttl">' . $SETTING['toc_title'] . '</span></div>';
		}

		// 目次広告コード
		if ( SWELL::is_show_toc_ad() ) {
			$toc_ad = \SWELL_PARTS::toc_ad();
		}

		// 広告を目次の前に設置するか、後ろに設置するか
		$toc_content = 'after' === $SETTING['toc_ad_position'] ? $toc . $toc_ad : $toc_ad . $toc;

		// 1つ目の見出しの前へ設置
		$tag = '/^<h2.*?>/im';
		if ( $toc_content && preg_match( $tag, $content, $tags ) ) {

			// $h_count = substr_count( $content, '</h2' );
			// if ( 1 ) $h_count += substr_count( $content, '</h3' );

			if ( (int) get_query_var( 'page' ) > 1 ) {
				// 2ページ目以降の時はコンテンツ上部に目次を追加
				$content = $toc_content . $content;
			} else {
				$content = preg_replace( $tag, $toc_content . $tags[0], $content, 1 );
			}

			SWELL::$added_toc = true;
		}
	}

	return $content;
}

目次が表示されない時の回避策は?

プラグインが原因の場合

プラグイン等にapply_filters('the_content',....)の記述がある場合は、避けようがありません。

自動で目次を追加するのをやめて、ショートコードで目次を追加してもいいでしょう。

自前のコードが原因の場合

自前でコードを書いている場合は、apply_filters('the_content',....)を以下のように置き換えることで対応できるでしょう。

変更前
$html = apply_filters( 'the_content', get_the_content());
変更後
$html = do_shortcode(do_blocks(get_the_content()));

まとめ

SWELLのテーマを使っていると、不思議な不具合に出会うことがあり、複雑な気持ちになります。

SWELLフォーラムに目次が2重に表示されるというような投稿が散見されるので、その対策で目次を出力したフラグを保持して、対策しているのかもしれません。

今回の件は、プラグインなどで普通に使われる記述が原因なので、SWELLとプラグインの相性問題のような感じに見える可能性もあります。

役に立ったら他の人にもシェア!
  • URLをコピーしました!
  • URLをコピーしました!
コメントを閉じる

コメント

コメントする

コメントは日本語で入力してください。(スパム対策)

クリックできる目次