WordPressコアのボタンブロックでSNSシェアボタンを作る方法

最近本サイトをブロックテーマに変えました。
SNSシェアボタンを作ろうと思ったので解説します。

↓こんな感じのシェアボタンです!

ボタンを押すとXが開いてポストが出来ます!

attributesと設定のUIを追加

まずはコアのボタンブロックに何のシェアボタンを作るかattributesと設定のUIを追加します

import { __ } from '@wordpress/i18n'; import { InspectorControls } from '@wordpress/block-editor'; import { PanelBody, BaseControl, SelectControl } from '@wordpress/components'; import { addFilter } from '@wordpress/hooks'; import { createHigherOrderComponent } from '@wordpress/compose'; export function addAttribute( settings ) { if ( settings.name !== 'core/button' ) { return settings; } settings.attributes = { ...settings.attributes, namespaceShareProviderNameSlug: { type: 'string', }, }; return settings; } addFilter( 'blocks.registerBlockType', 'namespace/editor/button/add-attribute', addAttribute ); export const withInspectorControls = createHigherOrderComponent( ( BlockEdit ) => ( props ) => { const { name, attributes, setAttributes } = props; if ( name !== 'core/button' ) { return <BlockEdit { ...props } />; } const {namespaceShareProviderNameSlug} = attributes; const ProviderOption = [ { label: 'None', value: '' }, { label: 'Facebook', value: 'facebook' }, { label: 'X', value: 'x' }, { label: 'Hatena', value: 'hatena' }, { label: 'Pocket', value: 'getpocket' }, { label: 'Line', value: 'line' }, ]; return ( <> <BlockEdit { ...props } /> <InspectorControls> <PanelBody title={ __( 'Share Settings', 'namespace' ) } initialOpen={ true } > <BaseControl> <SelectControl __nextHasNoMarginBottom __next40pxDefaultSize label={ __( 'Share Button Provider', 'namespace' ) } options={ ProviderOption } value={ namespaceShareProviderNameSlug || '' } onChange={ ( value ) => { setAttributes( { namespaceShareProviderNameSlug: value ? value : undefined, tagName: value ? 'button' : undefined, } ); } } /> </BaseControl> </PanelBody> </InspectorControls> </> ); } ); addFilter( 'editor.BlockEdit', 'namespace/editor/button/with-toolbar-controls', withInspectorControls );

今回はnamespaceShareProviderNameSlugというattributesを追加しました。
withInspectorControlsで保存する際はnamespaceShareProviderNameSlugとボタンブロックの隠しattributesであるtagNamebuttonにして保存しています。

tagNameをbuttonにするとボタンタグに変換されURLなどのUIがなくなりURLを入れられないように出来ます。

レンダリングする時にシェア用のURLを設定すれば完成

レンダリング側でシェア用のURLを設定すれば完成です

function namespace_render_block_button( $block_content, $parsed_block, $block ) { if ( ! isset( $block->context['postId'] ) ) { return $block_content; } if ( ! isset( $parsed_block['attrs']['namespaceShareProviderNameSlug'] ) ) { return $block_content; } if ( isset( $parsed_block['attrs']['tagName'] ) && 'button' !== $parsed_block['attrs']['tagName'] ) { return $block_content; } $url = get_the_permalink( $block->context['postId'] ); $title = get_the_title(); $p = new WP_HTML_Tag_Processor( $block_content ); if ( $p->next_tag( 'button' ) ) { $facebook_share_url = 'https://www.facebook.com/sharer/sharer.php?u=' . $url; $x_share_url = 'https://x.com/share?text=' . $title . '&url=' . $url; $hatebu_share_url = 'https://b.hatena.ne.jp/add?mode=confirm&url=' . $url; $getpocket_share_url = 'https://getpocket.com/edit?url=' . $url . '&title=' . $title; $line_share_url = 'https://social-plugins.line.me/lineit/share?url=' . $url . ';text=' . $title; if ( 'facebook' === $parsed_block['attrs']['namespaceShareProviderNameSlug'] ) { $p->set_attribute( 'onclick', 'window.open("' . $facebook_share_url . '")' ); } elseif ( 'x' === $parsed_block['attrs']['namespaceShareProviderNameSlug'] ) { $p->set_attribute( 'onclick', 'window.open("' . $x_share_url . '")' ); } elseif ( 'hatena' === $parsed_block['attrs']['namespaceShareProviderNameSlug'] ) { $p->set_attribute( 'onclick', 'window.open("' . $hatebu_share_url . '")' ); } elseif ( 'line' === $parsed_block['attrs']['namespaceShareProviderNameSlug'] ) { $p->set_attribute( 'onclick', 'window.open("' . $line_share_url . '")' ); } elseif ( 'getpocket' === $parsed_block['attrs']['namespaceShareProviderNameSlug'] ) { $p->set_attribute( 'onclick', 'window.open("' . $getpocket_share_url . '")' ); } } $block_content = $p->get_updated_html(); return $block_content; } add_filter( 'render_block_core/button', 'namespace_render_block_button', 10, 3 );

フィルターフックのrender_blockcore/buttonに対して変更を加えています。

このフックの第三引数は$blockそのものが受け取れるのでここでcontextを取得してあげれば投稿IDが取得できます。

こうしておけば、クエリーブロックなどでもcontextに応じたURLが生成されます!

あとは自由にブロックをカスタマイズすれば完成🎉