最近本サイトをブロックテーマに変えました。
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が生成されます!
あとは自由にブロックをカスタマイズすれば完成🎉