最近本サイトをブロックテーマに変えました。
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であるtagNameをbuttonにして保存しています。
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_blockでcore/buttonに対して変更を加えています。
このフックの第三引数は$blockそのものが受け取れるのでここでcontextを取得してあげれば投稿IDが取得できます。
こうしておけば、クエリーブロックなどでもcontextに応じたURLが生成されます!
あとは自由にブロックをカスタマイズすれば完成🎉







