WordPress のブロックエディタで PDF ファイルを挿入する場合、ファイルブロックを使用しますが、デフォルトで object 要素によるインライン埋め込み表示となり、さらにテキストリンクの横にダウンロードボタンまでもが表示されます。インライン埋め込み表示はピクセルで高さを指定できますが、そのままではスマホ表示で見にくいので別途レスポンシブ対応させる必要がありますし、テキストリンクがあるのでダウンロードボタンも不要です。

一般的にただのテキストリンクにしたい場合が多いと思うのですが、PDF を挿入するたびにいちいちブロックの設定を変更するのも面倒ですし、案件によっては PDF のサムネイル画像を表示して PDF ファイルにリンクさせたい場合もあります。

そこで、ファイルブロックのデフォルト設定の変更と、リンク付きのサムネイルを挿入する独自ブロックを作成してみました。サムネイルは、PDF をメディアファイルにアップロードした際に WordPress で自動で生成される1ページ目のサムネイルを利用します。ついでに、PDF のサムネイルをアイキャッチ画像に設定できるようにしました。

ファイルブロックのインライン埋め込み表示とダウンロードボタン表示をデフォルトでオフにする

functions.php に以下のコードを追加することで、ファイルブロックのデフォルト設定を変更できます。

// ファイルブロックのデフォルト設定を変更
function my_theme_file_block_defaults( $metadata ) {
	if ( isset( $metadata['name'] ) && 'core/file' === $metadata['name'] ) {
		
		// 「インライン埋め込みを表示」→ OFF
		if ( isset( $metadata['attributes']['displayPreview'] ) ) {
			$metadata['attributes']['displayPreview']['default'] = false;
		}
		
		// 「ダウンロードボタンを表示」→ OFF
		if ( isset( $metadata['attributes']['showDownloadButton'] ) ) {
			$metadata['attributes']['showDownloadButton']['default'] = false;
		}
	}
	return $metadata;
}
add_filter( 'block_type_metadata', 'my_theme_file_block_defaults' );

PDF へのリンク付きのサムネイルを挿入する独自ブロックを作る

WordPress で自動で生成される1ページ目のサムネイルを、PDF ファイルへのリンク付きで挿入します。また、PDF のサムネイルを挿入するだけでなく、オプションでサムネイルのサイズと配置が設定できるようにしました。

PDFサムネイルのカスタムブロック

まず、テーマ内に /blocks/pdf-thumbnail/ というフォルダを作り、block.json と index.js、エディタ側の editor.css、公開側の style.css の4つのファイルを作成します。長くなるので、それぞれの内容はここでは割愛します。

そして functions.php に追加します。

// カスタムブロック
/* PDFサムネイルブロックを登録 */
function mytheme_register_pdf_thumbnail_block() {
	register_block_type(
		get_template_directory() . '/blocks/pdf-thumbnail',
		array(
			'render_callback' => 'mytheme_render_pdf_thumbnail_block',
		)
	);
}
add_action( 'init', 'mytheme_register_pdf_thumbnail_block' );

/* PDFサムネイルブロックの出力 */
function mytheme_render_pdf_thumbnail_block( $attributes ) {

	$pdf_id = isset( $attributes['pdfId'] ) ? absint( $attributes['pdfId'] ) : 0;

	if ( ! $pdf_id ) {
		return '';
	}

	/* PDFか確認 */
	if ( 'application/pdf' !== get_post_mime_type( $pdf_id ) ) {
		return '';
	}

	/* PDF URL */
	$pdf_url = wp_get_attachment_url( $pdf_id );

	if ( ! $pdf_url ) {
		return '';
	}

	/* サイズ */
	$size = isset( $attributes['size'] ) ? $attributes['size'] : 'medium';

	$allowed_sizes = array(
		'thumbnail',
		'medium',
		'large',
		'full',
	);

	if ( ! in_array( $size, $allowed_sizes, true ) ) {
		$size = 'medium';
	}

	/* 配置 */
	$align = isset( $attributes['align'] ) ? $attributes['align'] : 'center';

	$allowed_aligns = array(
		'left',
		'center',
		'right',
	);

	if ( ! in_array( $align, $allowed_aligns, true ) ) {
		$align = 'center';
	}

	/* WordPressが生成したPDFプレビュー画像 */
	$thumbnail = wp_get_attachment_image_src( $pdf_id, $size );

	if ( ! $thumbnail ) {
		$thumbnail = wp_get_attachment_image_src( $pdf_id, 'medium' );
	}

	if ( ! $thumbnail ) {
		return '';
	}

	/* alt */
	$alt = get_post_meta( $pdf_id, '_wp_attachment_image_alt', true );

	if ( ! $alt ) {
		$alt = get_the_title( $pdf_id );
	}

	/* ブロック属性 */
	$wrapper_attributes = get_block_wrapper_attributes(
		array(
			'class' => 'pdf-thumbnail-block',
		)
	);

	ob_start();
	?>
	<div <?php echo $wrapper_attributes; ?>>
		<div class="pdf-thumbnail-preview pdf-thumbnail-align-<?php echo esc_attr( $align ); ?>">
			<a href="<?php echo esc_url( $pdf_url ); ?>">
				<img src="<?php echo esc_url( $thumbnail[0] ); ?>" width="<?php echo esc_attr( $thumbnail[1] ); ?>" height="<?php echo esc_attr( $thumbnail[2] ); ?>" alt="<?php echo esc_attr( $alt ); ?>">
			</a>
		</div>
	</div>
	<?php
	return ob_get_clean();
}

サムネイルをアイキャッチ画像として設定できるようにする

そもそもアイキャッチ画像を設定する際のメディアライブラリに表示されるのは画像ファイルだけですので、ここに PDF も表示させます。そして、PDF をアイキャッチ画像として選択した際に、PDF の1枚目のサムネイルを表示するようにします。

// PDFの1ページ目サムネイルをアイキャッチ画像として設定できるようにする
/* アイキャッチ画像設定のメディアライブラリにPDFを含める */
function sic_featured_image_include_pdf( $query ) {

	if ( ! is_admin() ) {
		return $query;
	}

	// メディアライブラリのAJAXリクエストのみ
	if ( ! isset( $_POST['action'] ) || 'query-attachments' !== $_POST['action'] ) {
		return $query;
	}

	/* アイキャッチ画像では WordPress が post_mime_type = image を指定して検索する。そこにPDFを追加する。 */
	if ( isset( $query['post_mime_type'] ) && 'image' === $query['post_mime_type'] ) {
		$query['post_mime_type'] = array(
			'image',
			'application/pdf',
		);
	}

	return $query;
}
add_filter( 'ajax_query_attachments_args', 'sic_featured_image_include_pdf' );


/* PDFをアイキャッチに指定した場合、PDFの1ページ目サムネイルをアイキャッチ画像として表示する */
function sic_pdf_featured_image_html( $html, $post_id, $post_thumbnail_id, $size, $attr ) {

	if ( ! $post_thumbnail_id ) {
		return $html;
	}

	// アイキャッチがPDFか確認
	if ( 'application/pdf' !== get_post_mime_type( $post_thumbnail_id ) ) {
		return $html;
	}

	/* PDFの1ページ目サムネイルを取得 */
	$image = wp_get_attachment_image_src( $post_thumbnail_id, $size );

	if ( ! $image ) {
		return $html;
	}

	$src    = $image[0];
	$width  = $image[1];
	$height = $image[2];

	/* alt属性 */
	$alt = get_post_meta( $post_thumbnail_id, '_wp_attachment_image_alt', true );

	if ( '' === $alt ) {
		$alt = get_the_title( $post_thumbnail_id );
	}

	/* 属性 */
	$attributes = '';

	if ( is_array( $attr ) ) {
		foreach ( $attr as $name => $value ) {
			$attributes .= sprintf(
				' %s="%s"',
				esc_attr( $name ),
				esc_attr( $value )
			);
		}
	}

	/* img要素 */
	$html = sprintf(
		'<img src="%1$s" width="%2$d" height="%3$d" alt="%4$s"%5$s />',
		esc_url( $src ),
		(int) $width,
		(int) $height,
		esc_attr( $alt ),
		$attributes
	);

	return $html;
}
add_filter( 'post_thumbnail_html', 'sic_pdf_featured_image_html', 10, 5 );

以前はこういうカスタマイズは非常に多くの時間がかかり、実現できないこともあったのですが、今は ChatGPT の存在によりとても助かっています。“こうしたい” を何度かやりとりすることで理想のカスタマイズが可能になります。