chiilog https://chiilog.com/ 愛猫大好きなフロントエンドデベロッパーの備忘録 Tue, 16 Apr 2024 00:47:03 +0000 ja hourly 1 https://wordpress.org/?v=6.8.2 Block Bindings APIもうすこし遊んでみた https://chiilog.com/2024/04/15/2474/ Mon, 15 Apr 2024 06:26:36 +0000 https://chiilog.com/?p=2474 前回、カスタムフィールドと紐づけして表示してみたBlock Bindings APIですが、ヒントをもらったの […]

投稿 Block Bindings APIもうすこし遊んでみたchiilog に最初に表示されました。

]]>
前回、カスタムフィールドと紐づけして表示してみたBlock Bindings APIですが、ヒントをもらったのでもう少し遊んでみました。

なるほど!!!と思ってシェアボタン作ってみました。

https://github.com/chiilog/sns-share-block

今回は既存のボタンブロックをカスタマイズしてボタンブロックを作るので、phpのみで完結。

まずは、ボタンブロックにbindingを入れていきます。

<!-- wp:buttons {"style":{"spacing":{"blockGap":"var:preset|spacing|30"}}} -->
<div class="wp-block-buttons"><!-- wp:button {"metadata":{"bindings":{"url":{"source":"chiilog/share-button","args":{"key":"x"}}}}} -->
<div class="wp-block-button"><a class="wp-block-button__link wp-element-button">X</a></div>
<!-- /wp:button -->

<!-- wp:button {"metadata":{"bindings":{"url":{"source":"chiilog/share-button","args":{"key":"facebook"}}}}} -->
<div class="wp-block-button"><a class="wp-block-button__link wp-element-button">Facebook</a></div>
<!-- /wp:button -->

<!-- wp:button {"metadata":{"bindings":{"url":{"source":"chiilog/share-button","args":{"key":"line"}}}}} -->
<div class="wp-block-button"><a class="wp-block-button__link wp-element-button">LINE</a></div>
<!-- /wp:button -->

<!-- wp:button {"metadata":{"bindings":{"url":{"source":"chiilog/share-button","args":{"key":"hatena"}}}}} -->
<div class="wp-block-button"><a class="wp-block-button__link wp-element-button">はてな</a></div>
<!-- /wp:button -->

<!-- wp:button -->
<div class="wp-block-button"><a class="wp-block-button__link wp-element-button" href="#">ただのボタン</a></div>
<!-- /wp:button --></div>
<!-- /wp:buttons -->

metadata.bindings は固定です。

<!-- wp:button {"bindings":{"url":{"source":"chiilog/share-button","args":{"key":"facebook"}}}} -->

とか書いても動かないので気をつけましょう。(やった)

ちなみに↑の書き方、JSONのエラーですとか返してくれるわけでもなく、背景とかつけたりすると値が消えます。

これだけでブロック側は準備OK。では、PHPを書いていきます。

add_action( 'init', 'chiilog_register_block_bindings' );

function chiilog_register_block_bindings() {
	register_block_bindings_source( 'chiilog/share-button', array(
		'label'              => __( 'SNS', 'chiilog-share-button' ),
		'get_value_callback' => 'chiilog_sns_data_bindings',
		'uses_context'       => [ 'postId' ]
	) );
}

まずは、register_block_bindings_sourceを使ってソースを登録します。

これで、前回使ったカスタムフィールドのようにソースとして扱うことができます。

今回は投稿IDを元にページURLをとりたいので、 uses_contextpostIdを指定しています。

次はコールバック関数を用意します。実際にシェア用のURLをバインディングするやつです。

/**
 * SNSのシェアリンクを返す
 *
 * @param array $source_args
 * @param WP_Block $block_instance
 *
 * @return string|null
 */
function chiilog_sns_data_bindings( $source_args, WP_Block $block_instance ) {
	$current_post_id = $block_instance->context['postId'];

	// キーがない場合はなにもしない
	if ( ! isset( $source_args['key'] ) ) {
		return null;
	}

	switch ( $source_args['key'] ) {
		case 'x':
			return 'https://twitter.com/intent/tweet?url=' . esc_url( get_permalink( $current_post_id ) ) . '&text=' . esc_attr( get_the_title( $current_post_id ) );
		case 'facebook':
			return 'https://www.facebook.com/sharer/sharer.php?u=' . esc_url( get_permalink( $current_post_id ) );
		case 'line':
			return 'https://social-plugins.line.me/lineit/share?url=' . esc_url( get_permalink( $current_post_id ) ) . '&text=' . esc_attr( get_the_title( $current_post_id ) );
		default:
			return null;
	}
}

なんということでしょう。swich文で記述するだけで、ボタンタグ自身のhrefに挿入されることが確認できたと思います。

bindingsを使っていないブロックはリンク先が入力できますが、bindings.url を設定したボタンはリンク先が入力できなくなっています。

リンク先の入力欄がない

さて、リンク先の入力欄がないということはリンクターゲットの設定ができません。同じくbindingsでやってみようかと思いましたが、urlとlinkTargetなど2つ地使うことはできないのか、うまくいきませんでした。私の書き方がまずかったとか色々説はあると思いますが、できるのなら私も見たいのでぜひ書き方教えてほしいです。

追記

浜野さんに書き方教えてもらいました!!!!

<!-- wp:buttons {"style":{"spacing":{"blockGap":"var:preset|spacing|30"}}} -->
<div class="wp-block-buttons"><!-- wp:button {"metadata":{"bindings":{"url":{"source":"chiilog/share-button-link","args":{"key":"x"}},"linkTarget":{"source":"chiilog/share-button-target"}}}} -->
<div class="wp-block-button"><a class="wp-block-button__link wp-element-button">X</a></div>
<!-- /wp:button -->
...
</div>
<!-- /wp:buttons -->

urlに対してはchiilog/share-button-linkを割り当て、linkTargetに対してはchiilog/share-button-targetを割り当てるという感じです。

ひとつの属性に対してひとつのsourceを使う、って覚え方でよさそうかな。

あとはPHPを変更。

add_action( 'init', 'chiilog_register_block_bindings' );

function chiilog_register_block_bindings() {
	register_block_bindings_source( 'chiilog/share-button-link', array(
		'label'              => __( 'SNS URL', 'chiilog/share-button' ),
		'get_value_callback' => 'chiilog_sns_data_bindings',
		'uses_context'       => [ 'postId' ]
	) );

	register_block_bindings_source( 'chiilog/share-button-target', array(
		'label'              => __( 'Link Target', 'chiilog/share-button' ),
		'get_value_callback' => function () {
			return '_blank';
		}
	) );
}

今回は絶対_blankなのでこうなりましたが、argsで変えたいときはget_value_callbackに関数名を指定すればOK。

この方がWP_HTML_Tag_Processor使うよりもスッキリ簡潔に書けますね!!!!

一応下にWP_HTML_Tag_Processor版残しておきますが、書くならregister_block_bindings_sourceを使って書くと思います。


シェアボタンに関しては常にリンクターゲットは_blankにしたいので、ここはWP_HTML_Tag_Processorの出番です。

/**
 * シェアボタンの場合、ボタンのlinkTargetを_blankに変換する
 *
 * @param string $block_content
 * @param WP_Block $block
 *
 * @return string
 */
add_filter( 'render_block_core/button', 'add_link_target_for_binding_button', 10, 2 );

function add_link_target_for_binding_button( $block_content, $block ) {
	$processor = new WP_HTML_Tag_Processor( $block_content );

	if ( isset( $block['attrs']['metadata']['bindings']['url']['source'] ) ) {
		$binding_source = $block['attrs']['metadata']['bindings']['url']['source'];
		if ( $binding_source === 'chiilog/share-button' ) {
			$processor->next_tag( array( 'class_name' => 'wp-block-button__link' ) );
			$processor->set_attribute( 'target', '_blank' );
		}
	}

	return $processor->get_updated_html();
}

Block Bindings APIを使ってるものに限りリンクターゲットを追加しています。

この分岐を入れておけば、bindingsを使っていないボタンは管理画面上でリンクターゲットの設定が可能というわけです。

まとめ

外部ソースってどう使うんだろうな、とピンときてなかったのが、これを作ってみてより身近に感じれるようになりました。シェアボタンがこんな簡単にできるのはえらいこっちゃです。

とはいえ、metadata.bindingsが複雑になるとコードエディターで書きづらそうだなあというのは感じました。改行とか入れても一回ビジュアルエディターにすると1行でギュッとされてしまうので、あとから追記を試すときにちょっと大変でした。

コードエディターで入力する前に一旦見やすいのをローカルに置いといたほうがいいかもしれません。

投稿 Block Bindings APIもうすこし遊んでみたchiilog に最初に表示されました。

]]>
WordPress 6.5 で新登場したBlock Bindings APIを試してみた https://chiilog.com/2024/04/12/2468/ Fri, 12 Apr 2024 07:38:13 +0000 https://chiilog.com/?p=2468 今回も新しいAPIを触ってみました。次はBlock Bindings API! これは動的なデータをブロックに […]

投稿 WordPress 6.5 で新登場したBlock Bindings APIを試してみたchiilog に最初に表示されました。

]]>
https://developer.wordpress.org/news/2024/02/20/introducing-block-bindings-part-1-connecting-custom-fields/

今回も新しいAPIを触ってみました。次はBlock Bindings API!

これは動的なデータをブロックにもたせることができるようになる機能です。

動的なデータって言うとあんまりピンとこないですが、カスタムフィールドがわかりやすいと思います。(現状その他はどうやって使うのかあまりよくわかってない)

WordPress6.5では、以下のブロックで使うことができます。

ブロック属性
画像url, alt, title
段落content
見出しcontent
ボタンurl, text, linkTarget, rel

それぞれのブロックの属性に対して割り当てることができるので、「段落タグを表示する内容は、company_nameというカスタムフィールド」という使い方ができます。

使い方

プラグイン等でカスタムフィールドを用意します。

add_action( 'init', 'chiilog_register_meta_fields' );

function chiilog_register_meta_fields() {
	register_meta(
		'post',
		'company_name',
		array(
			'show_in_rest'      => true,
			'single'            => true,
			'type'              => 'string',
			'sanitize_callback' => 'wp_strip_all_tags'
		)
	);
}

現時点では show_in_rest が true じゃないとだめな模様。

*Note that the show_in_rest property must be set to true for the time being due to security considerations, though there are plans to explore how to remove this requirement in the future.

https://make.wordpress.org/core/2024/03/06/new-feature-the-block-bindings-api/

とあるので、将来的には不要にしたいようですね。

これをどう編集するかは個人の開発の意向によると思いますが、今回は特に作り込む予定ではなかったので、パネルでカスタムフィールドを表示して作業しました。

こんな感じです。

あとはAPIをサポートしているブロックに紐づけるだけ!

ビジュアルエディタではmetadataの追加はまだサポートしていないので、コードエディターに切り替えます。

<!-- wp:paragraph {
	"metadata":{
		"bindings":{
			"content":{
				"source":"core/post-meta",
				"args":{
					"key":"company_name"
				}
			}
		}
	}
} -->
<p></p>
<!-- /wp:paragraph -->

ちなみに本文部分が空っぽのままだと段落ブロックがない状態ので、適当に文字を入力して wp:paragraph を表示させてから metadata を追加しました。

この状態でビジュアルエディターに戻すと、company_name で入力した値が表示されます。

カスタムフィールドを更新してもブロック側で即時反映はされないですが、「更新」を押して記事自体を更新すると値が入り直します。

あくまでカスタムフィールドの値を表示させるだけなので、段落ブロックからカスタムフィールドを編集することはできません。

ですが、ガワは段落ブロックであることに代わりはないので、通常の段落ブロックと同じように背景色をつけたり、フォントサイズを変えたりというスタイルの編集は可能です。

詳細ページで表示できるものは当然アーカイブページでも表示できます。
以下のビデオキャプチャはテーマエディターでインデックスページを触ってみたときのキャプチャです。

使い所は?

基本的に投稿はブロック内で完結できるようになっていますが、アーカイブページに特定の文言(会社名とか人名とか)やアイキャッチ以外の画像を出したいというときに、別途カスタムブロックを作らなくてもよくなったという感じでしょうか。

とは言え、不要なカスタムフィールドを量産するとかえって使いにくい管理画面になってしまうと思うので、設計周りはより慎重に行ったほうが良さそうだと胸に刻んでおきます……。こういうの、不用意にいらないところで使ってしまいがち。

カスタムブロックにBlock Bindings APIを使う方法なんかも紹介されているので、ぜひ紹介記事は一読してみてくださいね!

投稿 WordPress 6.5 で新登場したBlock Bindings APIを試してみたchiilog に最初に表示されました。

]]>
WordPress 6.5 で新登場したInteractivity APIを試してみた https://chiilog.com/2024/04/11/2441/ Thu, 11 Apr 2024 05:31:51 +0000 https://chiilog.com/?p=2441 Interactivity APIとは? ゴリゴリaddEventListenerとかで書いてたJSがサクッと […]

投稿 WordPress 6.5 で新登場したInteractivity APIを試してみたchiilog に最初に表示されました。

]]>
Interactivity APIとは?

ゴリゴリaddEventListenerとかで書いてたJSがサクッと書けるようになるAPIです。(かなりざっくり)

これを使ったらブロック間のやりとりとかもできるようになるので、かなり用途が広いAPIだと思います。

今回はこれを使ってブロックを作ってみました。

ブロックつくってみた

https://github.com/chiilog/iapi-tabs

Interactivity APIを使ったタブブロックです。

実質3〜4日で作りました。Alpine.js とか触ったことある人だともっと理解が早そう。(私は触ったことなかった)

管理画面

表示

使い方

親ブロックとして使うブロックのblock.json のsupports"interactivity": true を入れます。

また、view.js と render.php を使うので、"viewScriptModule": "file:./view.js""render": "file:./render.php" を追加します。

いれるとこんな感じになります。

{
	"$schema": "https://schemas.wp.org/trunk/block.json",
	"apiVersion": 3,
	"name": "chiilog-blocks/iapi-tabs",
	"version": "0.1.0",
	"title": "IAPI Tabs",
	"category": "widgets",
	"icon": "smiley",
	"description": "Example block scaffolded with Create Block tool.",
	"attributes": {
		"contents": {
			"type": "array",
			"default": []
		},
		"tabNavText": {
			"type": "string",
			"source": "text",
			"selector": ".wp-block-chiilog-blocks-iapi-tabs__button span"
		}
	},
	"supports": {
		"interactivity": true,
		"anchor": true
	},
	"textdomain": "chiilog-iapi-tabs",
	"editorScript": "file:./index.js",
	"editorStyle": "file:./index.css",
	"style": "file:./style-index.css",
	"viewScriptModule": "file:./view.js",
	"render": "file:./render.php"
}

これでAPIを使う準備はOK!

次はブロックを用意します。

私は先にrender.php で完成形のHTMLタグを入れただけのファイルを作りました。

<?php
/**
 * @var array    $attributes The block attributes.
 * @var string   $content    The block default content.
 * @var WP_Block $block      The block instance.
 *
 * @see https://github.com/WordPress/gutenberg/blob/trunk/docs/reference-guides/block-api/block-metadata.md#render
 */
?>
<div
	<?php echo get_block_wrapper_attributes(); ?>
>
	<div class="wp-block-chiilog-blocks-iapi-tabs__nav" role="tablist">
		<button
			role="tab"
			class="wp-block-chiilog-blocks-iapi-tabs__button"
			aria-selected="true"
			id="tab-1"
			aria-controls="panel-1"
			tabindex="0"
		>
			<span>ナビ1</span>
		</button>
		<button
			role="tab"
			class="wp-block-chiilog-blocks-iapi-tabs__button"
			aria-selected="false"
			id="tab-2"
			aria-controls="panel-2"
			tabindex="-1"
		>
			<span>ナビ2</span>
		</button>
		<button
			role="tab"
			class="wp-block-chiilog-blocks-iapi-tabs__button"
			aria-selected="false"
			id="tab-3"
			aria-controls="panel-3"
			tabindex="-1"
		>
			<span>ナビ3</span>
		</button>
	</div>
	<div
		id="panel-1"
		role="tabpanel"
		tabindex="0"
		aria-labelledby="tab-1"
		class="wp-block-chiilog-blocks-iapi-tabs__panel"
		aria-expanded="true"
		aria-hidden="false"
	>
		パネル1
	</div>
	<div
		id="panel-2"
		role="tabpanel"
		tabindex="0"
		aria-labelledby="tab-2"
		class="wp-block-chiilog-blocks-iapi-tabs__panel"
		aria-expanded="false"
		aria-hidden="true"
	>
		パネル2
	</div>
	<div
		id="panel-3"
		role="tabpanel"
		tabindex="0"
		aria-labelledby="tab-3"
		class="wp-block-chiilog-blocks-iapi-tabs__panel"
		aria-expanded="false"
		aria-hidden="true"
	>
		パネル3
	</div>
</div>

ただ動かしてみるだけならedit.js もこれベタっと貼っておくだけでもいいですね。私はAPI触るために作ってたのに、なぜかeditの中身も作り込んでいました。(夫に突っ込まれてedit別に作り込まなくてよかったことに気づいた)

ちなみに今回はeditの中身については省きます。

次はこのタグにAPI用のタグを仕込んでいきます。

親のdivにdata-wp-interactive="chiilog-iapi-tabs"を入れます。これの内部でbindなりclickなりいろんなJSが動きます。

<div
	<?php echo get_block_wrapper_attributes(); ?>
	data-wp-interactive="chiilog-iapi-tabs"
>
	...
</div>

こんな感じ。

このdata-wp-interactiveに指定したchiilog-iapi-tabsがストア名になります。

view.jsに以下のように書きます。

/**
 * WordPress dependencies
 */
import { store } from '@wordpress/interactivity';

store( 'chiilog-iapi-tabs', {
	state: {},
	actions: {},
	callbacks: {},
} );

例えば以下のようにactionsの中に書いて、ボタンにclickの動作をつけるとコンソールにclickが出ます。

/**
 * WordPress dependencies
 */
import { store } from '@wordpress/interactivity';

store( 'chiilog-iapi-tabs', {
	state: {},
	actions: {
		selectTab: () => {
			console.log( 'click' );
		},
	},
	callbacks: {},
} );
<button
	role="tab"
	class="tab-nav__button"
	data-wp-on--click="actions.selectTab"
	aria-selected="true"
	id="tab-1"
	aria-controls="panel-1"
	tabindex="0"
>
	<span>ナビ1</span>
</button>

無事clickが動作していることを確認したので、ベタ書きしていた記述をブロックに置き換えます。

<?php
/**
 * @var array $attributes The block attributes.
 * @var string $content The block content.
 * @var WP_Block $block The block object.
 *
 * @see https://github.com/WordPress/gutenberg/blob/trunk/docs/reference-guides/block-api/block-metadata.md#render
 */

$navItems = $attributes['contents'];
?>
<div
	<?php echo get_block_wrapper_attributes(); ?>
	data-wp-interactive="chiilog-iapi-tabs"
>
	<div class="wp-block-chiilog-blocks-iapi-tabs__nav" role="tablist">
		<?php
		if ( $navItems ) :
			foreach ( $navItems as $index => $navItem ) :
				$tabNumber = $index + 1;
				?>
				<button
					role="tab"
					class="wp-block-chiilog-blocks-iapi-tabs__button"
					data-wp-on--click="actions.selectTab"
					aria-selected="<?php echo esc_attr( $index === 0 ? 'true' : 'false' ); ?>"
					id="tab-<?php echo esc_attr( $tabNumber ); ?>"
					aria-controls="panel-<?php echo esc_attr( $tabNumber ); ?>"
					tabindex="<?php echo esc_attr( $index === 0 ? '0' : '-1' ); ?>"
				>
					<?php echo esc_html( $navItem['tabNavText'] ); ?>
				</button>
				<?php
			endforeach;
		endif;
		?>
	</div>
	<div class="wp-block-chiilog-blocks-iapi-tabs__panels">
		<?php echo do_blocks( $content ); ?>
	</div>
</div>

この時点ではaria-selectedとかはまだほぼベタ打ちのままです。

パネル部分はインナーブロックの中にパネルブロック(作成したブロック。インナーブロックはこのパネルブロックしか配置できないように設定)を置く形にしています。

おおよその形にはなったので、タブのJSを書いていきます。

いつものJSならクリックしたナビ以外のaria-selectedを変えたりtabindexを変えたりして実装してるのですが、今回はInteractivity APIを使って実装していくので、

  • state.currentTab でカレントのタブを管理
  • ボタンそれぞれにdata-wp-context='{ "position": (number) }' をつけてタブの番号を付与
  • state.currentTabとcontext.positionが同一であればカレントにする

という処理をしました。

state.currentTabはwp_interactivity_stateで管理するため、render.phpに追加します。

wp_interactivity_state( 'chiilog-iapi-tabs', array (
	'currentTab' => 0
));

ボタンにもAPIのディレクティブをつけていきます。

<button
	role="tab"
	class="wp-block-chiilog-blocks-iapi-tabs__button"
	data-wp-on--click="actions.changeCurrentTab"
	data-wp-bind--aria-selected="state.tabSelected"
	id="tab-<?php echo esc_attr( $tabNumber ); ?>"
	aria-controls="panel-<?php echo esc_attr( $tabNumber ); ?>"
	data-wp-bind--tabindex="state.tabIndex"
	data-wp-context='{ "position": <?php echo esc_attr( $index ); ?> }'
>
	<?php echo esc_html( $navItem['tabNavText'] ); ?>
</button>

さて、次はパネルです。パネルはインナーブロックで管理しているので、ボタンのようにrender.php内で処理することはできません。

なので、パネルブロックにディレクティブをつけるためにrender_blockのフィルターフックを使います。

今回は単一のブロックのみでの動作なので、render_block_{$this->name}のフィルターを使いました。

function add_directives_to_inner_blocks( $block_content, $block ) {
	$panels = new WP_HTML_Tag_Processor( $block_content );
	$panelCount = 0;

	while ( $panels->next_tag() ) {
		foreach ( $panels->class_list() as $class_name ) {
			if ( $class_name === 'wp-block-chiilog-blocks-iapi-tabs-panel' ) {
				$panels->set_attribute( 'data-wp-bind--aria-expanded', 'state.panelExpanded' );
				$panels->set_attribute( 'data-wp-bind--aria-hidden', 'state.panelHidden' );
				$panels->set_attribute( 'data-wp-context', '{ "position": ' . $panelCount . ' }' );
				$panelCount++;
			}
		}
	}

	return $panels->get_updated_html();
}
add_filter( 'render_block_chiilog-blocks/iapi-tabs', 'add_directives_to_inner_blocks', 10, 2 );

ブロック間でデータのやりとりをしたいときはよく使うことになるんだろうなと思います。

WP_HTML_Tag_Processorはブロック作るに限らず色々使い道があるので(aタグをspanに変えたいとか)覚えておくとよさそう。

これで描写側のセットは完了したので、あとはview.jsでJSをゴリゴリしていくだけです。

/**
 * WordPress dependencies
 */
import { getContext, store } from '@wordpress/interactivity';

const { state, actions } = store( 'chiilog-iapi-tabs', {
	state: {
		get panelExpanded() {
			const ctx = getContext();
			return ctx.position === state.currentTab;
		},
		get panelHidden() {
			const ctx = getContext();
			return ctx.position !== state.currentTab;
		},
		get tabSelected() {
			const ctx = getContext();
			return ctx.position === state.currentTab;
		},
		get tabIndex() {
			const ctx = getContext();
			return ctx.position === state.currentTab ? 0 : -1;
		},
	},
	actions: {
		changeCurrentTab: () => {
			const ctx = getContext();
			state.currentTab = ctx.position;
		},
	},
	callbacks: {},
} );

なんということでしょう。書いたのはこれだけ!タブみたいなシンプルなやつだったからというのはあるけど、めちゃくちゃ簡単に動作追加ができました。

ここで終わったと思った?残念!まだ続きます

ふと翌日に複数配置したらどうなるんだ?って配置してみたら、なんとまあ連動して全部動く!

これが例えば決済ボタンだとか、ページで1つしか配置できないようにしているものならsupportsでmultiple: false にしておけばいいけど、これはタブブロック。複数配置することも考えられるもの。あと、ついでにボタンとかパネルについてるidもユニークにしておかねばならぬ。

というわけで、ブロックのclientIdをattributes: tabClientIdに保存して使うことにしました。(save.js でやってたらこんな回りくどいことしなくてももっと簡単だったはず)

<button
	role="tab"
	class="wp-block-chiilog-blocks-iapi-tabs__button"
	data-wp-on--click="actions.changeCurrentTab"
	data-wp-bind--aria-selected="state.tabSelected"
	id="tab-<?php echo esc_attr( $tabClientId ) . '-' . esc_attr( $tabNumber ); ?>"
	aria-controls="panel-<?php echo esc_attr( $tabClientId ) . '-' . esc_attr( $tabNumber ); ?>"
	data-wp-bind--tabindex="state.tabIndex"
	data-wp-context='{ "position": <?php echo esc_attr( $index ); ?> }'
>
	<?php echo esc_html( $navItem['tabNavText'] ); ?>
</button>

肝心のブロックが全部一緒に動いちゃう部分ですが、これは

wp_interactivity_state( 'chiilog-iapi-tabs', array (
	'currentTab' => 0
));

で最初にステートを定義しているのが問題でした。なので、このカレントの管理をブロック自身のコンテキストに持たせるようにしました。

<?php
/**
 * @var array $attributes The block attributes.
 * @var string $content The block content.
 * @var WP_Block $block The block object.
 *
 * @see https://github.com/WordPress/gutenberg/blob/trunk/docs/reference-guides/block-api/block-metadata.md#render
 */

$navItems    = $attributes['contents'];
$tabClientId = $attributes['tabClientId'];

$context = array(
	'currentTab'  => 0,
);

?>
<div
	<?php echo get_block_wrapper_attributes(); ?>
	data-wp-interactive="chiilog-iapi-tabs"
	data-tab-client-id="<?php echo esc_attr( $tabClientId ); ?>"
	<?php echo wp_interactivity_data_wp_context( $context ); ?>
>
	...
</div>

view.js でもステートを参照していたので、changeCurrentTab をstate.currentTabから context.currentTabに差し替えます。

/**
 * WordPress dependencies
 */
import { getContext, store } from '@wordpress/interactivity';

const { state, actions } = store( `chiilog-iapi-tabs`, {
	state: {
		get panelExpanded() {
			const ctx = getContext();
			return ctx.position === ctx.currentTab;
		},
		get panelHidden() {
			const ctx = getContext();
			return ctx.position !== ctx.currentTab;
		},
		get tabSelected() {
			const ctx = getContext();
			return ctx.position === ctx.currentTab;
		},
		get tabIndex() {
			const ctx = getContext();
			return ctx.position === ctx.currentTab ? 0 : -1;
		},
	},
	actions: {
		changeCurrentTab: () => {
			const ctx = getContext();
			ctx.currentTab = ctx.position;
		},
	},
	callbacks: {},
} );

これでどれだけタブを置いても一緒にカレントが動いてしまうことはなくなりました!

作ってみての感想

最初は難しそうだなーできるかなーと思ってたんですが、案外サクッとできてしまいました。組み合わせてswiperと連動させたりとかもできるのかな…どきどき。

とは言え、書くのにはJSの知識が必要なので、しっかりJS勉強しておかないといけないなあという感じです。まだまだ知識不足感は否めません。

あと、実装するうえで結構ChatGPTに助けてもらいました。

エラー文の解説もそうですが、コードをベタっと貼り付けて「ここがこうなってるんだけどどうして?」って聞くとわりといい返事を返してくれたので、問題の解消のヒント(ときには答え)にかなり役立ちました。頼れる相棒です。答えに「それはホントか?」って思ったら根拠を調べたりするので勉強にもなります。

ちなみに、ChatGPT自体にInteractivity API自体の知識はまだないのでこの辺は聞いてません。

実装中のメモはzennでまとめています。

https://zenn.dev/chiilog/scraps/1129dfe7a551d7

参考にしたサイト、GitHub等

Interactivity APIとはなんぞや?でまずは触ったCookbookのレシピ

上記をもとに作られたより強力なスライダーのリポジトリ。WP_HTML_Tag_Processorまわり等はこちらを参考にしました。

https://github.com/ryanwelcher/iapi-gallery-slider

タブのeditを実装するにあたり、キタジマさんのSnow Monkey Blocksのタブブロックをめちゃくちゃ参考にさせてもらいました。

https://github.com/inc2734/snow-monkey-blocks/tree/master/src/blocks/tabs

ありがとうございました!

投稿 WordPress 6.5 で新登場したInteractivity APIを試してみたchiilog に最初に表示されました。

]]>
The Block Developers Cookbook をやってみた https://chiilog.com/2024/04/05/2432/ Fri, 05 Apr 2024 02:57:05 +0000 https://chiilog.com/?p=2432 The Block Developers Cookbookとは? https://blockdeveloper […]

投稿 The Block Developers Cookbook をやってみたchiilog に最初に表示されました。

]]>
The Block Developers Cookbookとは?

https://blockdevelopercookbook.com/recipes/

ブロックの練習できるレシピ集です。WordCamp Asia 2024のワークショップ枠であったらしいです。

同僚のtoro_unitにおすすめしてもらい上から順番にやってみました。これ全部理解して書けたらカスタムブロック作れると言っても過言ではないらしいですよ。

レシピは9つで難易度は様々

私が挑戦したときはレシピは合計9つありました。

ブロックスタイルをつけたりするような簡単なやつから、最新のIntaractivity APIを使ったスライダーまでレベルは様々。

時々掲載順が変わるので「あれ…これやってないのに前にある……」がちょくちょくあります。

スキルレベルで難易度が表示されていますが、実際動かすコードなんかはすでに入っていることが多かったです。(例:Simple Fade-in EffectのフェードインするJSの実装など)

だからって提示されてるコードをコピペして「わー動いたー」じゃやったことにならないので、ファイル開いてこれなにしてるんだろうなーとかここがこの動作を担ってるんだな、とか調べながら進めました。

なので、大体の目安時間が書いてありますが全然その時間では終わらなかったです。

調べながら書いていたメモはzennにおいています。

https://zenn.dev/chiilog/scraps/345b7e5324f1b1

セットアップとかは悩まなくてOK

レシピそれぞれスタンドアローンで動かす用の npx のコードがあります。環境用意するの面倒だし…という言い訳は通用しません。

なお、リポジトリ単位で落としてくる方法もあるので、この辺は好きな方を選択したらいいと思います。

それぞれのレシピの感想

せっかくなのでそれぞれのレシピを軽く振り返ってみようと思います。

Custom Image block style

これはお馴染みのやつです。ブロックにカスタムスタイルを追加する方法。

こちらはプラグインで追加されてますが、私はブロックスタイルはテーマの領域だと思っているので、いつもテーマのfunctions.phpに書いて作業してます。

Block Transforms

ブロックの変換をつくるレシピ。普段全然使わないので実際の作り方に触れられてよかったです。

特定の言葉を入れてエンター押したらブロックに変わるとかいうマジックもやりました。これ使い所どこなんだろう?と思いながらも面白かったです。

Editorial Notes

ブロックにメモを残す機能です。表示側には出ないですが、管理画面でブロック選択すると表示されます。

複数人で更新するメディアとか校正する必要がある記事とかだと嬉しい機能なのかなあと思いつつ、既存ブロックにこういう機能を生やす方法があるんだなあと思うなどしました。

Customize the build process

これはブロックというよりビルドまわりのレシピ。

getWebpackEntryPoints を使うと複数のブロックのエントリーポイント書かなくてよさそうというまなび。このビルドは既存のブロックどうこうというよりカスタムブロックたくさん作るとかのときに特に有効な気がします。

Simple Fade-in Effect

カバーブロックにフェードインのCSSを追加できるようにするレシピ。

WP_HTML_Tag_Processor 使ってすべてのカバーブロックがスクロールに応じて下からふわっとフェードインしてくるようなアニメーションがつきます。

ブロックにクラスつける自体のコードは大したことないけど、フェードインのコードの方が気になってしばらくJSファイルの方を調べてました。

Creating a custom format

書式APIのレシピ。選択範囲にabbr タグがつけられるようになります。

この書式APIのは汎用性が高い(inline-blockを使えるようにしたいとかでよく使う)ので、カスタムブロック作るよりこっちのほうが実は重要なんではないかなーと思ったりしています。

現状、スライダーとかタブとかそういう機能面で拡張しないといけないようなものを除いてパターンでかなり解決できるものが増えているなというのが体感としてあるので、書くならこっちの方が増えそう……かな…?

Word Counter

全ブロックで使ってる文字数のカウントをするレシピ。

やってるとなんかカウントが合わないな…?って思ってたんですが、これは英文が前提となっているので、オプションつけて日本語対応する必要がありました。

以外といろんなドキュメント見たのこのブロックかもしれません。

Post Meta Testimonial Block

カスタムフィールドと連携するブロックのレシピ。

多分仕様通りなんだろうとは思いますが、パネルからカスタムフィールドを表示しているとうまく更新できない罠がありました。

まだあまり調べられてませんが、カスタムフィールドもBlock Bindings APIでブロック作らなくても使いやすくなるのかな…?

Interactive API Gallery Slider

今回一番目玉なレシピ。その分時間かけました。

package.jsonに start: 'wp-scripts start --experimental-modules', 追加し忘れて(正確にはformatコマンドに足してた)ずーっと動かない動かないってブチギレて困ってました。動かないときはpackage.json から見直してみましょう。(自戒)

そしてこのレシピ地味に誤字あったり途中でJS側だけ関数名変わったりしてる罠があるので単にコピペしてると詰みます。これはこれでいい練習になるかな。
見てたら気づくけど、ぱぱっとコピペして進めてると気付かないかも。(これには気づくのにpackage.jsonには気付かないのかとか言わないで)

Interactivity APIは6.5で新搭載になったAPIなので、公式のドキュメントもじっくり見ながら進めました。

難しそうだなとドキドキしてたんですが、ドキュメントしっかりしてるし思ったよりとっつきやすそうだなと思いました。食わず嫌いよくない。

API使ってどうこうっていうより、そもそも動作のロジック考える方が時間使いそう。

ブロック作りたいならこれをやればOK!

一通りやってみて、カスタムブロックに挑戦してみたいならこれを一通りやるといいと思います。Interactivity APIまで網羅してるのがつよい。

もくもく会とかで同士を募って一緒にわいわいやるのも楽しそう。

最初にレシピ通りに進める→ここをこうしたかったらどうする?とかアレンジしてみる、とかですごく力がつくと思います。繰り返しやるのもよさそう。

私は次はInteractivity APIを使ってタブを作ってみようと思ってます。またzennでメモしながら進めます!

投稿 The Block Developers Cookbook をやってみたchiilog に最初に表示されました。

]]>
子連れ目線から振り返るWordCamp Kansai 2024 #wckansai https://chiilog.com/2024/02/28/2398/ Wed, 28 Feb 2024 13:52:28 +0000 https://chiilog.com/?p=2398 2024年2月24日に開催されたWordCamp Kansai 2024に参加してきました!リアル参加はなんと […]

投稿 子連れ目線から振り返るWordCamp Kansai 2024 #wckansaichiilog に最初に表示されました。

]]>
2024年2月24日に開催されたWordCamp Kansai 2024に参加してきました!リアル参加はなんと5年ぶり。びびった。

やっぱりWordCampはいいな〜って思いました。みなさまお久しぶりな方ばっかりで同窓会感がありつつも新しい出会いがあったり。(前日からカバン入れとかなきゃと思ってたのに名刺忘れたのは私です)

今回は託児付きキッズスペースがあったので、娘も一緒に参加しました!

5年ぶりに参加してみて

WordCampは(確か)初参加が2012年の東京開催のやつで、そこから関西方面中心に毎回参加していました。2014年あたりから実行委員やったりしつつ、2018年で燃え尽きて2019年は一般参加者してた記憶があります。(2019年は当日行ってやっぱ実行委員or当日スタッフやればよかった〜って思ったような)

それからコロナ禍があったり、子供が産まれたりでイベント類から遠ざかり、去年の後半からちょこちょこWordPress Meetupに参加しはじめてます。

オンラインかオフラインか

普段私はフルリモートなので、オンラインイベントが主になってくるとまじで全然人と会う機会がなくなりました。話し相手は夫か猫か娘。さみし!

ちょこちょこオンラインのイベント参加はしてましたが、自分から話振るのが苦手なので、どうしても聞き専になりがちというか、見て終わるみたいな感じが多かったように思います。

まあ、オンラインにはどんな格好でも参加できるって利点はありますけどね!!(すっぴんパジャマ常習犯)

オフラインは

  1. 化粧しないといけない
  2. 着替えないといけない
  3. 髪まかないといけない
  4. 娘の着替えやお出かけセットの準備がいる
  5. 移動しないといけない

などなど、ドひきこもりにとっては色々と乗り越えるハードルがありますが、こうもオンラインばっかりで家族だけとしか喋らないと、なんとなく閉塞感がある感じがして逆に外に出たくなりました。

娘も卒乳して長く出かけられるようになったのもあって、夫が(いつの間にか)オーガナイザーになってたWordPress Meetupに久しぶりに行くか〜って思い立ち、娘と一緒にひっそり参加したところ、(イベントで)夫が次のWordCamp Kansaiの実行委員長することを知り、これは参加せねば!と心待ちにしていました。

子連れ参加って実際どうなの?

今回託児付きキッズスペースがあったので娘も一緒に連れていきましたが、正直子連れで勉強会って結構大変だよなーって思います。

娘が騒ぐとかそういう意味ではなく(ありがたいことに今のところ外でギャン泣きとかあまりない✌)、純粋に荷物量がエグいのと、移動経路をしっかり調べる(私は方向音痴です✌)必要があります。

自分の荷物+子供の荷物が多い

娘のおむつセット、ご飯やおやつ、予備の着替えや母子手帳なり保険証なり。
これに加えて、自分のPCやら充電器やら………そして娘は絶賛ベビーカーイヤイヤ期。乗ったな、と思っても10分後には「あーく(歩く)」で、片手は手をつなぎ、片手はベビーカー。どこの地獄?

ベビーカーなかったらなかったで大荷物持って娘抱えて移動しないといけないから、それはそれで会場着くまでに体力使い切っちゃうけど……。あと娘の寝る場所が確保できないので、こういうイベントごとにはベビーカー自体はまだ必要…。

娘の荷物は減らせないので、減らすのは自分の荷物!

いつも勉強会はMacBookを持っていってますが、登壇でもなければXでポストしたりメモアプリでメモするくらいなのでiPadで十分だろうとiPad+Magic Keyboard(MacBookで使ってたやつ)で行ってみました。

結果的にメモならiPadで十分だなと思ったので、今後は基本iPadで行こうと思います!しかしiPad用Magic Keyboardはほしい……キーボード持っていくなら若干かさばりました。

移動経路はベビーカーでも通れる道を探す

ベビーカーがあるということは、基本的にエレベーター移動。エレベーター探したり、乗るのに結構待ったりで移動時間は倍くらい見ておいたほうがいいし、道探しが甘いとエスカレーター&階段しかなかったりします。

今回、私は道中のパン屋さんに行きたくて寄り道したのですが、エレベーターを探すのに苦労して余計にウロウロしたりしてました。

帰り道も、三宮のスロープが工事中なの知らなくてうっかり上がってしまい、阪急三宮に入ってまた駅までの道を探してウロウロ……。自分の記憶に頼ると痛い目を見るなと反省しました。

キッズスペースは実際どうだった?

さて本題。キッズスペースは過去のWordCamp Kansaiでもありましたが、当時は私は結婚もしてなかったしあったら来やすいのかな、くらいの気持ちでした。

実際使う側になってみると、自分がウロウロしてる間子供を見ててもらえるのはすごくありがたかった!会場はやっぱり人が多いし、まだふらふらよちよち歩く娘を連れての移動はちょっと無理がありました。(まあハッピーアワーとか懇親会はしっかり一緒にウロウロしてましたが)

ちょくちょく様子を見に行きましたが、なんと娘、預けてわりとすぐから爆睡
脅威の約4時間睡眠!ちょっと寝すぎてびっくり。

年始にもゲームのイベント参加のためにホテルに保育士さん派遣して見ててもらうみたいなこともしましたが、そのときも爆睡してたの見る限り、行ってる保育園に預ける以外では寝てやり過ごそうとしているような気配をちょっぴり感じます。

起きてからは保育士さん2人を独占して(他の子は帰宅済みで1人だった)たくさん遊んでもらっていました。アンパンマンの救急車のおもちゃだったり、おままごと、シール貼りなどなど……お迎え時にはどんな様子だったか、おむつ交換はいつしたか、おやつは何を食べたか(※持参したもの)、どれくらい寝ていたのかなどなどしっかり紙で報告をいただきました。

お迎え後は……

ハッピーアワーと懇親会少しだけ参加して、いろんな方から「かわいいねえ」「そっくりだねえ」とたくさん話しかけてもらいました!

○✗ゲームのために使うガムテープで作られた○中でしかウロウロしない娘にワロタ。おねえにゃんx2の影響でしょうか。

行ってよかったしまた参加したい!

娘も楽しかったのか、「帰ろうか?」って聞いてもずっと首を振って帰りたがらなかったWordCamp。皆さん暖かく接してくれて本当にありがたかったです🙏

スタッフ参加はなかなかむずかしい立場ですが、やっぱりWordPressコミュニティはあったけえし楽しいので、またMeetup含めばしばし参加していきたいなと思います!

投稿 子連れ目線から振り返るWordCamp Kansai 2024 #wckansaichiilog に最初に表示されました。

]]>
Kansai WordPress Meetupで登壇してきました+軽くフォローアップ https://chiilog.com/2023/12/10/2362/ Sun, 10 Dec 2023 01:27:03 +0000 https://chiilog.com/?p=2362 めちゃめちゃ久しぶり…前回アップしたスライドから察するに実に4年ぶり!?に登壇しました!緊張した! スライドは […]

投稿 Kansai WordPress Meetupで登壇してきました+軽くフォローアップchiilog に最初に表示されました。

]]>
めちゃめちゃ久しぶり…前回アップしたスライドから察するに実に4年ぶり!?に登壇しました!緊張した!

スライドはこちらです。

ブロックエディター推してきました。

好きなものは惜しみなく推していくぞ!!!!!という気持ちで仕上げました。

このスライドをつくるにあたって気をつけたことは

♥かわいいスライドにする♥

ことです。

登壇の機会があったのは初心者向けのもくもく会の前のセッションだったので、親しみを感じてほしいなあ…という思いもあって「スライドはかわいくしよう」と思いました。特に実際のコードを書いたりするわけでもなかったので、余計に。

ということで、今回はCanvaを使ってスライドを作りました。いろんなスライドのデザインあって、見てるだけでめちゃ楽しかったです。

……と、これだけだとふざけてんのか?と思われちゃうかもなので真面目な(?)気をつけたことも。

  • 具体的なコードじゃなくて経験談をメインにする
  • 「ちょっと触ってみるか……」って思ってもらえるところをゴールにする

これでも5年ほどブロックに触れているので、最初の頃はこうだったんじゃよ………みたいな話はめちゃくちゃ持ってます。ただ、それを全部話すと20分じゃ足りないし、なにより苦労話は全然楽しくない。

なので、リリース当時はどういうフローでブロック触っていたかとかを思い出しながら書きました。

思い返せば思い返すほど、今のブロックエディターってめちゃくちゃ触りやすくなったな…と思います。

デモは2つやりました

どれくらいブロックが触りやすくなったかはデモを交えておはなししました。デフォルトブロックで何ができるのか?は、実際にブロックを配置して設定を触ってお見せしました。(有効化したテーマはTwenty Twenty-Fourです)

margin・padding・gapが管理画面から触れるだけで個人的にめちゃめちゃありがたいです。

もうひとつのデモはパターン化のデモをしました。

ブロックを組み合わせることで以下のようなスタイルが作れます。↓↓


About


News

お知らせ

こういうデザインを使い回すために「パターン化」という手法があるよ〜という話をしました。

こういうタイトルのデザインをスタイル追加したりカスタムブロック作ったりせずに表現できるのよすぎじゃないですか???(ちなみに前はパターン化も横並びもなかったです)

正直これだけでブロック触る価値めちゃあると思います。

デフォルトブロックいっぱいさわろう

とにかくカスタムブロックだとかそういう難しそうなところは一旦置いておいて、とにかくブロックを使ってみよう!ということをお伝えしました。

ブロックを知ることで実現できるデザインの引き出しは確実に増えます。(私はここで結構痛い目を見たりしているので、ブロックの振る舞いは再確認しておこうと思っています……)

もくもく会での質問大会

ありがたいことに、何人かの方が質問に来てくれました!
そこで、どんな質問があったのかをこちらにも載せておきます。

テーマを変えてもスタイルは適用される?子テーマの場合は?

これはテーマの話にもなるのですが、以下はTwenty Twenty-Fourを有効化した状態で配置した段落ブロックの設定パネルです。

カラーパレットの上に「テーマ」というのがありますね。つまり、ここで表示されているカラーパレットはTwenty Twenty-Four固有のカラーということです。

テーマのカラーをつけた状態でどういうHTMLが生成されるのかというと、こんな感じのHTMLです。

<p class="has-accent-3-color has-text-color has-link-color">テキスト</p>

オレンジ色のカラーを適用したのですが、実際そのオレンジ色はstyle属性で入るわけではなくて、has-accent-3-colorというクラスに対して適用されています。

つまり、テーマを変えるとこのクラスがない、もしくは別のカラーが指定されていればカラーが適用されなくる、という具合です。

これが子テーマだったら子テーマ側で変更を加えない限りは同じ色が適用されます。

これはカラーだけではなく、余白(margin、padding、gap)も同様です。

ただ、カスタムで値を独自に入れた場合はこのようにstyle属性で値が入るので、頻繁にテーマを変えたい場合なんかはカスタムで値を入れて、更にいろんなところで使うときにはパターンを作っておくのもありかもしれませんね。

<p class="has-text-color has-link-color" style="color:#3d54d9">テキスト</p>

画像を回り込ませたい

画像をフロートにさせたいんだけど、どうしたらいいでしょう?ということでした。
その場で集まっていた方々と一緒に検証してみたんですが、無事できました!

それがこちら。

テキストが回り込みます。テキストが回り込みます。テキストが回り込みます。テキストが回り込みます。テキストが回り込みます。テキストが回り込みます。テキストが回り込みます。テキストが回り込みます。テキストが回り込みます。テキストが回り込みます。テキストが回り込みます。テキストが回り込みます。テキストが回り込みます。テキストが回り込みます。テキストが回り込みます。テキストが回り込みます。テキストが回り込みます。テキストが回り込みます。テキストが回り込みます。テキストが回り込みます。テキストが回り込みます。テキストが回り込みます。テキストが回り込みます。テキストが回り込みます。テキストが回り込みます。テキストが回り込みます。テキストが回り込みます。テキストが回り込みます。テキストが回り込みます。テキストが回り込みます。テキストが回り込みます。テキストが回り込みます。テキストが回り込みます。テキストが回り込みます。テキストが回り込みます。テキストが回り込みます。

グループブロックの中で右寄せ・左寄せを設定した画像+テキスト、という構成です。グループに囲っていないと画像がメインエリアからぽーんとはみ出していました。

この方法はスマホでも回り込みが発生するので、スマホのときは回り込ませないようにしたい…とかは、画像にスタイルをつけてそういうCSSをつけるか、回り込みは諦めてメディアと文章を使うかになるのかなあ?とかそういう意見交換をしました。

テーブルのプラグインを紹介

個人的に大好きなプラグインです。セルの結合だとかthに変えるだとかをめちゃくちゃ簡単にできます。テーブルよく触ってるんですけどーって話題が出たときにこれ使ったらどうでしょう?と推してきました。

久々の登壇あったけえ

ちょこちょこコールアンドレスポンスを交えながら話しましたが、いっぱい反応もらってめちゃうれしかったです。「ブロック触ってみます!」とかも感想としてもらっては〜〜〜〜〜〜推して良かった〜〜〜!!!って思いました。

Kansai WordPress Meetupのオーガナイザーのみなさま、登壇機会をいただけてありがとうございました!

投稿 Kansai WordPress Meetupで登壇してきました+軽くフォローアップchiilog に最初に表示されました。

]]>
TypeScriptのジェネリクスってなあに https://chiilog.com/2021/10/09/2348/ Sat, 09 Oct 2021 08:24:42 +0000 https://chiilog.com/?p=2348 こんな感じでコンポーネントを書いていたところ、PropsWithChildren を使えばいいじゃん、と教えて […]

投稿 TypeScriptのジェネリクスってなあにchiilog に最初に表示されました。

]]>
type Props = { title: string; children: ReactNode | undefined; } const Heading = ( { title, children }:Props ) => { return ( <> <h1>{ title }</h1> <div>{ children }</div> </> ); }

こんな感じでコンポーネントを書いていたところ、PropsWithChildren を使えばいいじゃん、と教えてもらうなどしました。で、ジェネリクスについて掘り下げて教えてもらったので備忘録。

type Props = PropsWithChildren<{ title: string }>
// type Props = { title: string } & { children?: ReactNode | undefined } と同義
const Heading = ( { title, children }:Props ) => {
  return (
    <>
      <h1>{ title }</h1>
      <div>{ children }</div>
    </>
  );
}

https://typescript-jp.gitbook.io/deep-dive/type-system/generics

https://js.studio-kingdom.com/typescript/handbook/generics

https://qiita.com/k-penguin-sato/items/9baa959e8919157afcd4

ジェネリクスは一言で言うと外から設定できる型定義のこと。

@types/react にはいろいろな便利な型が用意されてるので、自前で時間かけて書くよりもともとあるものを使ったほうが時短になってよい。(そういう型があるってのはコード見ないとわからないけども………)

PropsWithChildrenだけじゃなく、大体の関数にジェネリクスは定義されている。

おなじみ useStateもジェネリクスがあるので、こういうことができる。

// Todoリストの状態管理
const [state, setState] = useState<'ready' | 'inprogress' | 'completed' | ''>('');

//  レビューの星管理
const [reviewStar, setReviewStar] = useState<1 | 2 | 3 | 4 | 5>(1);

useState自体、特に型定義しなくても引数の中身を見て推察してくれるけど、中身を絞りたいときにはとても有用。

もしくは、初期値をnullにした場合、nullしか受け付けてくれなくなるので、ジェネリクスに ReactNode をいれるなど。

// これだと setName で nullしか入らなくなる
const [name, setName] = useState(null);

// ジェネリクスにReactNodeを入れておくと、型がReactNodeになるのでnull以外も設定できる
const [name, setName] = useState<ReactNode>(null);

ジェネリクスは沼らしいので細かく設定しすぎたり時間かけ過ぎたりするのは本末転倒だから気をつける!

投稿 TypeScriptのジェネリクスってなあにchiilog に最初に表示されました。

]]>
jQueryをやめてJavaScriptのクラスデビューした https://chiilog.com/2021/03/17/2343/ Wed, 17 Mar 2021 10:02:28 +0000 https://chiilog.com/?p=2343 以前ブログにまとめたコード、クラス化しました。(めちゃくちゃペアプロしてもらった。ありがたい限り) https […]

投稿 jQueryをやめてJavaScriptのクラスデビューしたchiilog に最初に表示されました。

]]>
以前ブログにまとめたコード、クラス化しました。(めちゃくちゃペアプロしてもらった。ありがたい限り)

https://chiilog.com/2021/02/12/2306/

今度はGitHubにあげました。

https://github.com/chiilog/multiple-swippers

PHPのクラス化はちょっと前からやってたのですが、JavaScriptのクラス化は今回が初めて。ちょこちょこ記述が似てるから前ほど「ヒッ!無理!」とはならなかったあたり無条件反射でワタシニハ無理デスを抜けられたかな。

読み方がわかってくると、クラス化せず整理せず思うがまま書いてるコードより全然読めるじゃないですか?メソッド単位でやってることを追いかければよい。(多分膨大な量のコードをはいって渡されたら泣くと思うけど)

Swiperから追加で対応してるもの

  • 再生ボタン/一時停止ボタン
  • 次へ/前へボタン(Swiper本体実装とは別
  • ウィンドウ幅でSwiperの有効化・無効化(必要ないときはmediaQueryをnullに設定)
  • 同一クラスをページ中に複数設置

セレクタの指定にquerySelectorAllとかquerySelectorを使ってます。クラス指定するとバグったり(複数に対応できない)しました(´・ω・`)

メソッドのコツ

コツと言うか気をつけておくこと。

  • 複数の機能をひとつのメソッドに持たせない
  • まず正確にどういう機能をつくるか日本語で書く(←JSに限らずこれがイマイチできてない)
  • メソッド名をわかりやすくする(ぱっとメソッド名見て何してるかわかるとよい)

投稿 jQueryをやめてJavaScriptのクラスデビューしたchiilog に最初に表示されました。

]]>
JSの関数の書き方 https://chiilog.com/2021/02/24/2340/ Wed, 24 Feb 2021 04:12:17 +0000 https://chiilog.com/?p=2340 基本。 https://developer.mozilla.org/ja/docs/Web/JavaScrip […]

投稿 JSの関数の書き方chiilog に最初に表示されました。

]]>
基本。

https://developer.mozilla.org/ja/docs/Web/JavaScript/Guide/Functions

// 引数なし
function example() {
    ....
}

// 引数をいれるとき
function example2( hoge ) {
    return hoge * 2;
}

実行するときは example(); とか example2( 2 ); とかで書く。

throttleとかdebounceやらをかませるときも同じ。(これでこんがらがった)関数は実行されないとなにもしない。

関数は実行されないとなにもしない。(大事なことなので2回)

最近はアロー関数を使ったりもしている。

https://developer.mozilla.org/ja/docs/Web/JavaScript/Reference/Functions/Arrow_functions

const hoge = () => {
    ....
}

こちらも実行はおなじく hoge(); 。Internet Explorerでは使えないみたいですが、そんなブラウザはもうない。(ポリフィルとかを探せばいいらしい。)

投稿 JSの関数の書き方chiilog に最初に表示されました。

]]>
ドモルガンの法則を使って返り値をシンプルにする https://chiilog.com/2021/02/18/2330/ Thu, 18 Feb 2021 09:46:11 +0000 https://chiilog.com/?p=2330 算数の頃から数字とか式とかを扱うのが苦手だったけどそんなこといってられねえ。 https://mathtrai […]

投稿 ドモルガンの法則を使って返り値をシンプルにするchiilog に最初に表示されました。

]]>
算数の頃から数字とか式とかを扱うのが苦手だったけどそんなこといってられねえ。

https://mathtrain.jp/de

ドモルガンの法則!

1:「A または B」でない,という状況は 「A でない」かつ「B でない」という状況と同じ

2:「A かつ B」でない,という状況は 「A でない」または「B でない」という状況と同じ

つまりどういうこと?

さっきの抜粋を式に起こしてみる。

1: A || B ←はんたい→ ! A && ! B

2: ! A && ! B ←はんたい→ A || B

これをJSで使うとこうなる。

function isSliderActive() {
    /**
      * trueになるとき: スライダーが存在し、かつ中身がこわれていないとき
      * falseになるとき: スライダーが存在しないか、中身がこわれているとき
      **/
    return slider && ! slider.destroyed;
}

スライダーがアクティブなら true、そうじゃなければfalseが返ってくる。

毎回if文でウンタラカンタラかつほにゃらら……なんてするより全然わかりやすい。

文字で考えるよりベン図のほうがもっとわかりやすいかも。

まだイマイチ対偶が上手に考えられないから訓練必要。

投稿 ドモルガンの法則を使って返り値をシンプルにするchiilog に最初に表示されました。

]]>
グローバルプロパティはglobalThisがよき https://chiilog.com/2021/02/17/2327/ Wed, 17 Feb 2021 10:30:16 +0000 https://chiilog.com/?p=2327 ロードだったりリサイズだったりのときのイベントリスナーのターゲット、今まではwindowだったりdocumen […]

投稿 グローバルプロパティはglobalThisがよきchiilog に最初に表示されました。

]]>
ロードだったりリサイズだったりのときのイベントリスナーのターゲット、今まではwindowだったりdocument.defaultViewだったりを書いていたけど、絶対にこの処理はブラウザ上でだけ動かす!(特定の指定じゃないと動かないなども含め)とかいうとき以外はglobalThisを使う。

globalThis.addEventListener( 'load', () => { ... } );

https://developer.mozilla.org/ja/docs/Web/JavaScript/Reference/Global_Objects/globalThis

globalThis プロパティは、環境を越えてグローバルな this 値 (すなわちグローバルオブジェクト自身) にアクセスするための標準的な方法を提供します。window や self などの同様のプロパティとは異なり、これはウィンドウのコンテキストでも非ウィンドウのコンテキストでも動作することが保証されています。この方法では、コードがどの環境で実行されているのかを知らなくても、一貫した方法でグローバルオブジェクトにアクセスすることができます。名前を覚えやすくするために、グローバルスコープでは this の値は globalThis であることを忘れないでください。

ESLintとかで怒られるときは、.eslintrcにて

{
	"globals": {
		"globalThis": true
	}
}

を指定する。

投稿 グローバルプロパティはglobalThisがよきchiilog に最初に表示されました。

]]>
オプショナルチェイニングを使って存在チェックをする https://chiilog.com/2021/02/16/2325/ Tue, 16 Feb 2021 02:42:25 +0000 https://chiilog.com/?p=2325 こんな定数を用意して navigation.nextElの存在チェックをしようと思ったら、いままでif文はこん […]

投稿 オプショナルチェイニングを使って存在チェックをするchiilog に最初に表示されました。

]]>
const option = {     navigation: {         nextEl: '.next-btn',         prevEl: '.prev-btn', } .... }

こんな定数を用意して navigation.nextElの存在チェックをしようと思ったら、いままでif文はこんなふうに書いてたけど

// optionが存在する、かつnavigation.nextElがある
if ( option && option.navigation.nextEl ) : ...

オプショナルチェイニングを使うともっと簡単に書ける!

if ( option?.navigation?.nextEl ) :

https://developer.mozilla.org/ja/docs/Web/JavaScript/Reference/Operators/Optional_chaining

上記の例だと、optionがなければその時点でundefinedが返されるので、option自体の存在チェックが不要。べんり。

投稿 オプショナルチェイニングを使って存在チェックをするchiilog に最初に表示されました。

]]>
文字列と変数を結合するときはテンプレートリテラルで書く https://chiilog.com/2021/02/15/2321/ Mon, 15 Feb 2021 01:49:01 +0000 https://chiilog.com/?p=2321 いつも結合時は みたいなプラスとシングル(もしくはダブル)クオートで囲ってたのですが、テンプレートリテラルを使 […]

投稿 文字列と変数を結合するときはテンプレートリテラルで書くchiilog に最初に表示されました。

]]>
いつも結合時は

const hoge = animal + 'はかわいい';

みたいなプラスとシングル(もしくはダブル)クオートで囲ってたのですが、テンプレートリテラルを使えばドシンプルに書ける。

const hoge = `${ animal }はかわいい`;

これをテンプレートリテラルと言うらしい。なるほど。

https://developer.mozilla.org/ja/docs/Web/JavaScript/Reference/Template_literals

`←これバッククオートと読んでたけど、正しくはグレーブアクセント(Google変換ではグラーブで出てくる)。altでもcmdでもなく、Shift+@で出ます。(いつもわからなくなる)

投稿 文字列と変数を結合するときはテンプレートリテラルで書くchiilog に最初に表示されました。

]]>
特定のブレークポイント以下でSwiperを動作させないコード https://chiilog.com/2021/02/12/2306/ Fri, 12 Feb 2021 03:45:24 +0000 https://chiilog.com/?p=2306 カルーセル系の実装はSwiperを使用しているのですが、「768px以下ではカルーセルさせて、それ以上のときは […]

投稿 特定のブレークポイント以下でSwiperを動作させないコードchiilog に最初に表示されました。

]]>
カルーセル系の実装はSwiperを使用しているのですが、「768px以下ではカルーセルさせて、それ以上のときはカルーセルさせない。しかもそれがページ内に同じクラスで複数ある」というような場合にかなりコードを工夫しないといけなかったので、供養がてらコードを残します。

ちなみに、上記のような複雑なことをしない場合(ただ単に複数同じクラスのSwiperを設置する)はこんなごちゃごちゃと書かずに公式サイトのサンプルコードを書けば普通に動作します。

Swiperってなによ?はこちらで紹介しています。https://chiilog.com/2018/04/16/965/

公式サイトはこちら。https://swiperjs.com/

主に自分用の備忘録だしJS雑魚だし苦労して書いた(信頼してはいけない、の意)なのでへーこんなことしたんだー程度に見てください。
一応動いてる(と思う)けどきれいなコードではないしもっとシンプルに書けるかも。

やったこと

まず、最初はloadとかresizeをjQueryにまかせていました。私の苦労のはじまりはここでページ中に複数設置してテストしなかったこと。(ブラウザチェック中に気付いて死んだ)

リサイズしたらdestroy部分が何故かエラーを吐く。ナンデ??あっ、複数設置してるときはそれぞれdestroyしないとダメ?という理解で早々に$('.swiper-container').each()で書き換えたものの、Firefoxでバグるバグる。(あとで見直すとChromeとかでももちろんバグってた)

console.logで carouselBool の真偽値をresizeごとに取ってみると、意図しないところで変な動きをしているのを発見。(trueのはずなのにtrueになったあとfalseになるとかそういう意味不明な動作)そもそもなんでそんな動きになってるんだ????でマジでわからなくて撃沈。

それからSwiperにresizeイベントがあるな、って気付いて書き直したけど、そもそもdestroyしたあとにまたカルーセルを動かすことができなくてこれも撃沈。(destroyしたら新しくSwiperを作り直さなければいけないようだ)

ブチ切れた結果、「そうだjQueryをやめよう」

jQueryはJSわからなくてもある程度手軽に書けるけど、やっぱJSわかってないとこういうときに詰む。

で、割と初めてレベルで(コピペとかで使ったことはあるけど)自前でaddEventListenerを書きました。書いてみて思ったけどJS別にめちゃくちゃハードル高いわけじゃないな?(※私が案件で書かないといけないレベルに限る)

リサイズやらロードやらってもっともっと複雑に書かないといけないと思ってたわけですよ。でもイベントリスナーにタイプ指定するだけ。これは勝った。で、完成したのがGistのコード。console.logで真偽値が正確に取れるかどうかのチェックから始めて、classListとかforEachの書き方を調べ、createCarouselって名前で関数化………。正直泣いたけどちゃんとできたのでヨシ!

JSできねー!!!って言ってる場合じゃなくなってきたので、楽するためにちゃんとTypeScript(とJest?)覚えようと決意しました。(何度もそれTypeScriptのほうが楽だよと洗脳された結果)

投稿 特定のブレークポイント以下でSwiperを動作させないコードchiilog に最初に表示されました。

]]>
#Catlog を購入したので、セットアップをしてみた https://chiilog.com/2020/03/17/1260/ Tue, 17 Mar 2020 05:34:44 +0000 https://chiilog.com/?p=1260 買うぞー買うぞーと言っていたCatlog(キャトログ)をついに購入したので、自慢さわってみた感じを。まだ購入し […]

投稿 #Catlog を購入したので、セットアップをしてみたchiilog に最初に表示されました。

]]>
買うぞー買うぞーと言っていたCatlog(キャトログ)をついに購入したので、自慢さわってみた感じを。
まだ購入したばっかりなので、使用感などはしばらく使ってからまた改めて。

Catlogとは?

株式会社RABOが販売している、「猫の生活をテクノロジーで見守る」というコンセプトの首輪型ウェアラブルデバイスです。キャットログじゃなくてキャトログだそうです。サイトがとてもおしゃれ。

https://rabo.cat/catlog
ブログカードが出ると思ったらWordPressだった

なお、今回は私の予算の関係上ジルの分(Home+Pendantのセット)のみ購入です。だいぶちょっと遅くなったお誕生日プレゼントです。レーナの分もおいおい購入予定!

クロネコの箱がかわいい

Catlogの特別仕様!かわいい。

何が届いたかひと目でわかる、Catlogデザインの箱!もうここでわくわくしちゃいます。
ジルとレーナも興味津々。

箱をあけるとFor Youカード!イラストがたいへんかわいい

当たり前ですが中身は首輪サイズ

なんとなく考えてたサイズより小さい

Homeはもうちょっと大きいのかなと思ってましたが手のひらサイズでコンパクトです。Mサイズの首輪がわりとぴったりめくらい。

なお、充電はUSB給電です。はUSBが挿せる電源タワーやコンセントを用意する必要があります。

コードはそんなに長くないので、オススメは机の上に置いておける電源タワーです!今は一時的に仕事部屋にHomeを置いていますが、電源タワーにつないで丁度いい長さでした。

アプリのセットアップ

アプリは普通にAppStoreやGoogle Playから検索してインストールすることもできますし、付属のカードの裏にQRコードが載っているので読み取りでインストールページに飛ぶこともできます。

まずは新規会員登録から行います。別途、メールアドレスの確認でメールが飛んでいるので承認しておきましょう。
電源を入れます。
Bluetooth接続します。
Homeを検索。このあと、近くにあるHomeの型番(?)が表示されるので、ぽちっとタップします。
首輪をつける猫を設定します。今回はジル用なのでジルの情報。
アプリで出すための写真を撮ります。なかなかポーズが決まらず5回か6回くらい撮りました。

セットアップ自体は画面の誘導に従ってやるだけなので簡単です。こういうスマホアプリと連動するアプリ系って独特なデザインが多い印象があるのですが、UIもとてもシンプルでわかりやすいし、イラストがかわいい!アプリのアイコンもキュンとくるかわいさです。季節で変わるのかな。たのしみです。

Home自体が割と軽いので、イタズラされないようにする必要があるかも?

届いたばかりのときは当然、Pendantの充電ができていないので、先にHomeに置いて充電しましょう。届いたときから大体2〜3時間でフル充電できた気がします。正確に測ってないのでもっとかかってる or 短いかもですが・・・。

1回の充電で1週間もつそうです。素晴らしい充電のもち具合。

充電が終わったらスマホに通知が来ます。(・∀・)イイネ!!

実際につけたあとのアプリ

今何しているかが表示されます。
時間帯別行動表

部屋の温度が右上に表示されているので、部屋が寒すぎたり暑すぎたりしたら遠隔でエアコンをつけたりできますね。なんと我が家にはNature Remoがあります(ドヤッ

時間帯別に歩きました、寝ていました、走りましたが表示されますが、ここはその時間帯のトータル表示なので、リアルタイムにこの時間になにをしていた、という表示ではないみたいです。タイムライン形式になっているのかと思い込んでバグかな?と問い合わせ出したのは私です(返信来る前に気づいて恥ずかしかった)

肝心のPendantの具合は?

https://rabo.cat/catlog/pendant

かわいいです。(そういうことではない)

というのは置いておいて、重さ的にはかなり軽いです。さすがに何もついてないベルトだけの首輪と同じ!とはいきませんが、へたにネームプレートとか飾りがついてる首輪よりは軽いんじゃないかと思います。

他にもPendantはかなりこだわって作られているので、ぜひ上のリンクから製品設計を見てみてください。

ジルはゴールド×ホワイトベルト。かわいい。

ベルトはMにしましたが、もしかしたらSでもよかったのか・・・?っていうくらい余裕があります。一番短くしているけど、指4本くらい入りました。ちゃんと測ったんだけどなぁ。ジルがスリムなせいもあると思いますが、レーナのベルトをSで注文して付け替えようかな?と考え中。普通に単品のグレーベルトもかわいいから買ってもよさそうではあるけども。なやましい!

今後の進化に超期待!

我が家は私も夫もフルリモートなので家にいることが多いのですが、猫たちが別の部屋でくつろいでいることもあるので、アプリをちょっと立ち上げて何してるのか見たりします。近くにいても見ます。何度も見るのが苦にならないというか、見たくなるUIはすばらしいと思います。(寝ています、とかかわいい)

Catlogは行動データを集めてどんどん進化していくデバイスです。少し前にアニコムとの共同開発のプレスリリースも出ていたので、疾病予測・予防医療にはとても期待しています!

https://prtimes.jp/main/html/rd/p/000000010.000037478.html

投稿 #Catlog を購入したので、セットアップをしてみたchiilog に最初に表示されました。

]]>
ピュリナワンの定期便の利用をはじめました https://chiilog.com/2020/02/16/1243/ Sun, 16 Feb 2020 14:05:15 +0000 https://chiilog.com/?p=1243 以前、猫ズのご飯をピュリナワンに統一したという記事を書きましたが、ようやっとあげるご飯が落ち着いたので、定期便 […]

投稿 ピュリナワンの定期便の利用をはじめましたchiilog に最初に表示されました。

]]>
以前、猫ズのご飯をピュリナワンに統一したという記事を書きましたが、ようやっとあげるご飯が落ち着いたので、定期便に申し込みました。

https://remoneko.life/catfood-2019summer/

避妊手術以来、そのときの絶食がよほどショックだったのかあればあるだけ食べる1時間前から催促するジルのご飯を横取りするという3コンボ(効果:掃除機のように吸い込まれていく)がデフォルトになったレーナですが、あれから避妊猫用のものを与えていました。

ジルもグレインフリーチキンの食いつきがちょっとずつ落ちていってたので、ものは試しと白身魚を与えてみるともりもり食べ始めたので、もうピュリナワンでいくことに決定。(ニュートロと混ぜたりしてたけど、コスパ+味変の意味で白身魚に)

ピュリナワン定期お届け便
https://shop.nestle.jp/front/contents/petfood/cat/purina_one_teiki/

定期便に変更した理由

ホームセンターが近くにあるので減ったら買いに行く、もしくは楽天やAmazonを利用していましたが、まあそこそこ重いし、どこが最安値か見るのも面倒になってきた(本音)ためです。あと、定期便であれば20%オフが毎回うけられるのもイイ!

定期便と聞くと一ヶ月に一回届くのか?と思いがちですが、1ヶ月ごと、2ヶ月ごと、3ヶ月ごとが選べます。我が家は3ヶ月ごとにピュリナワングレインフリーの白身魚・チキンの両方が届くようにしました!

フードの他におやつも注文できる

我が家の鉄板おやつはちゅーるですが、定期購入でデンタライフという猫用のデンタルケアができるおやつや、クリスピーキッス、ピューレキッスといったもおやつも定期購入に含めることができます。

今までデンタル用はグリニーズの歯磨き用おやつを与えていましたが、定期購入できるなら一気にやっちゃえーということで次回お届け分から定期購入に含めてみました。レーナも晴れて1歳になったのでおやつデビュー!(今までは1歳未満ということでちゅーるも子猫用、おやつはジルのみでした)

デンタライフが届いたらまたレビューしたいと思います。

投稿 ピュリナワンの定期便の利用をはじめましたchiilog に最初に表示されました。

]]>
無印の猫草はコスパよし、育てるのも楽でオススメ! https://chiilog.com/2020/01/31/1221/ Thu, 30 Jan 2020 15:26:42 +0000 https://chiilog.com/?p=1221 今までは猫草は近所のホームセンターで購入していたのですが、たまたま生協で無印の猫草栽培セットを見つけたので購入 […]

投稿 無印の猫草はコスパよし、育てるのも楽でオススメ!chiilog に最初に表示されました。

]]>
今までは猫草は近所のホームセンターで購入していたのですが、たまたま生協で無印の猫草栽培セットを見つけたので購入してみました。

ジルは猫草だいすき

実店舗は限られた店舗しか販売してないようですが、ネットストアでの販売がありました。

https://www.muji.com/jp/ja/store/cmdty/detail/4945247879612
ネットストアの商品ページ

または、LOHACOでも発売されているようです!

https://lohaco.jp/product/3267695/
LOHACOの商品ページ

育つまでどれくらい?

説明書には1週間とありましたが、1月の寒い時期だったせいか、草らしくなってきたなあと思うまで2週間ほどかかりました。しっかり「猫草!」って感じになるまでにはプラス1週間です。

ずぼっと顔をつっこんでみるジル
猫草の先をはみはみしてみたりと堪能するジル
レーナはまだ猫草がよくわかっていない

育てる手間は?

土ではなく、再生粉砕パルプを使った栽培になるので、もし栽培中に倒しても中がぶちまけられることはなし!

栽培セットの栽培方法にある通りに250ccの水をそそいで、日当たりの良いところに放置。
あとはパルプがかぴかぴに乾燥してるかな〜?というときにだけちょっと湿る程度に水を注ぎました。

あとは、ネットでカビが生えることがあると見たので朝起きたときにカビのチェックくらいです。(幸いにもカビは生えませんでした!)

お値段もホームセンターの約半分でお財布にやさしい

無印の猫草栽培セットは、税込み190円でした!いつものホームセンターではおおよそ300円くらいで買っていた(気がする)ので、約半分の値段で、しかも2つ購入できていることになるので、かなりお財布にやさしい!

ジルは猫草大好きなのでたまに購入していたのですが、頻度からしても今後はこの猫草を購入しようかなと思います。

投稿 無印の猫草はコスパよし、育てるのも楽でオススメ!chiilog に最初に表示されました。

]]>
猫と中・小型犬用自動給餌器、カリカリマシーン3種類使ったので、それぞれのレビューとおすすめ機種の紹介 https://chiilog.com/2020/01/17/1171/ Thu, 16 Jan 2020 16:39:08 +0000 https://chiilog.com/?p=1171 おそらく自動給餌器で一番有名なうちのこエレクトリックさんの「カリカリマシーン」を、現在発売されているものすべて […]

投稿 猫と中・小型犬用自動給餌器、カリカリマシーン3種類使ったので、それぞれのレビューとおすすめ機種の紹介chiilog に最初に表示されました。

]]>
おそらく自動給餌器で一番有名なうちのこエレクトリックさんの「カリカリマシーン」を、現在発売されているものすべて使ってみたので、それぞれのメリット・デメリットとおすすめの機種をレビューします。

※ どの機種もタンク・トレー部分を丸洗いできるので、その点はおすすめポイントから省略しています。

僅差でおすすめなのは「カリカリマシーンSP」

一番お高いカリカリマシーン

カリカリマシーンSPを導入して一週間ほどですが、カリカリマシーンとカリカリマシーンSPはそこまで大差ないなぁと思いました。なお、カリカリマシーンECOを買うならカリカリマシーンがいいです

ただし、オフラインから復帰しようとしてログアウトしたあと、本体のWi-Fiに接続できずいまだ復帰できていません……。(2020/08/27追記)

カリカリマシーンSPとカリカリマシーン、両者の違いは

  • メインの操作場所(スマホからか本体からか)
  • カメラで様子を見れたり話しかけたりができるか(みまもりカメラの有無)
  • 出先から設定していないご飯を出せるか(リモート給餌ができるかどうか)

出先で急遽ご飯を出す必要がある!タイマーセット忘れた!というときなんかは、SPしかその機能がないので一択になってしまいますが…。言い換えれば、カメラが不要タイマー通りの給餌しかしないのなら、通常のカリカリマシーンで十分!だと思います。

我が家の場合はレーナがジルのご飯を盗み食いするという困った現状があり、出先で急遽出せる機種の方がよいという判断でカリカリマシーンSPに切り替えました。(今までジルが使っていたカリカリマシーンはおさがりでレーナ用になりました)

https://remoneko.life/stay-at-home/
困った現状が浮き彫りになったときの記事

カリカリマシーンSPってどうなの?

カリカリマシーンSPについて掘り下げていきます!

まず、カリカリマシーンSPは現状発売されている同シリーズで一番高い機種です。
我が家で購入したときは、Amazonで¥17,800でした。カリカリマシーンの倍くらいですね!(倍は言い過ぎかも)

お値段が高いだけあって、機能も豊富です。SPにしかない機能は以下の通り。

  • メインの操作はスマホアプリ
  • カメラでご飯を食べてるかチェックできる(※リアルタイムのみ)
  • マイクがあるので話しかけられる
  • 出先からでも設定した時間外にご飯を出せる
  • ご飯を出すときの音声パターンをいくつか登録できる

イマドキな感じの機能ですね。

本体の大きさは?

本体の大きさはカリカリマシーンと同じくらいです。H380 x W245 x D300mmなので、そこそこ大きい。

組み立て中。二匹とも興味津々

電源アダプターはカリカリマシーンより小ぶりになっています。

左がカリカリマシーン、右がカリカリマシーンSPの電源

電池でもうごくのはカリカリマシーンと同様です。ただし、電池稼働だとカメラで見たり設定外の給餌はできず、タイマーで設定した給餌のみが動作する仕様です。

電池は単一電池です。家に2つしかなくて、現状電池稼働していません。

設定パネルはかなり単純です。時間を設定するボタンなどもありません。

「セット」をぽちっと押すと、1ポーション(約10g)のご飯が出ます。

タンクにはたくさんのご飯が入りますが、がっちりと密閉されているわけではないので、そのへんが気になる人はこまめにいれるくらいの量にするといいと思います。もしくは密閉用にテープを貼ったり…?

アプリの画面は?

アプリはAppStoreやGoogle Playからダウンロードできます。

操作に迷うことはあまりないと思いますが、設定はちょっと苦労しました。

アプリ初回起動時の画面
Wi-Fi接続中
登録完了画面

新規の登録も、手順自体は大変簡単です。

ですが、Wi-Fi接続時に本体のWi-Fiに接続するためにiPhoneの[設定]→[Wi-Fi]をひらくのですが、アプリに戻ったときに初回起動時の画面に戻ってしまうことが2〜3度あり、なかなか先に進めませんでした…。

本体Wi-Fiから家のWi-Fiにもどすときもなんと初回画面に戻ってしまったり…。
Wi-Fiをつなぎ直せと言うならつなぎ直すまで保持してほしいですね。

手間取ったのはいちいち初期画面に戻るときだけで、それ以外はスムーズでした。

設定画面
タイマーの設定画面

設定はわりと直感でなんとかなります。この手のアプリに慣れていれば説明書も不要ではないかと思います。

タイマーは最大4件まで設定できます。我が家は朝と長時間のお出かけ時の給餌だけできればいいので、フルで4回は使っていませんが、多いと見るか少ないと見るかはおうちの給餌事情によります。(タイマーを使ってないだけで、我が家は実質4回給餌してます)

ちょっと不満なポイント

ペットの登録ができるのですが、猫の種類が少ない!!!!!ベンガルはいませんでした。
なので、その他で設定してベンガルと手入力しています。

トレーを使っていると、たまに手動給餌ができないことが…?

トレーには別売りのトレーアタッチメントを使っているのですが、それのせいか、一度だけ手動での給餌が失敗しました。タンクにフードは十分入っていた+トレーを取ると給餌できたので、トレーのはまりがよくなかったのかもしれませんが、トレーを使う場合には、事前にきちんと給餌できるかテストしたほうがよさそうです。

手動給餌できなかったときのエラー画面

カリカリマシーンSPを使う上での注意点

カメラ機能を期待している場合は改めたほうがいいです。

この給餌器についているカメラに暗視機能はありません。また、Amazonのレビューにもありますが、カメラ位置が高いので、実際食べているところは見ることができません。そして、時間設定で録画することもできません

なんらかの事情で家の電気が死んでしまったらカメラ機能も死んでしまいますので、カメラは実際あってないようなものと思います。実際、私も全くチェックしていません。

カメラで猫たちの様子が見たい場合は、素直にWebカメラを購入したほうがよさそうです。

https://remoneko.life/network-camera-for-cat-arlo-vs-planex/

カリカリマシーンSPをおすすめする人・しない人

私が思う「おすすめできる人」と「他の機種にしたほうがいい人」はこんな感じでしょうか。

おすすめできる人

  • 出先でも急遽の給餌をしたい人
  • 設定は全部スマホでしたい人

他の機種にしたほうがいい人

  • スマホのアプリの設定が苦手、そもそもスマホが苦手な人
  • カメラ機能を最も重視している人
  • コンパクトな給餌器がいい人

カリカリマシーンってどうなの?

カリカリマシーンSPとほぼ同機種、カリカリマシーンはどうでしょう。
こちらはAmazonでお値段¥9,200です。

以前ブログに書いていますが、基本的なタイマー給餌はばっちりです。

https://remoneko.life/automatic-feeder/
カリカリマシーンSPでは不要だった時計の設定があります

SPでメインだったスマホでの操作はすべて本体からの操作になります。
現時刻はもちろん、給餌する時間の設定もこのパネル部分から設定します。

フード排出口に手を突っ込む

https://twitter.com/Jill_and_Reena/status/1206975575010631680

どうやったらこんなことを覚えられるのか謎ですが、ジルはこんな感じでご飯をほじくり出します。
これができるのはよくもありわるくもあり…。(ご飯を横取りされたら自分で出すしかなかったから)

本体が同一なので、SPでもできるのかもしれませんが、今の所SPではほじくり出せていません。

カリカリマシーンをおすすめする人・しない人

私が思う「おすすめできる人」と「他の機種にしたほうがいい人」はこんな感じでしょうか。

おすすめできる人

  • タイマー通りの給餌ができればOKの人
  • スマホでなんやかんやするのが苦手な人
  • 本体だけで設定やら何やら完結したい人

他の機種にしたほうがいい人

  • 給餌タイミングがバラバラで、猫がほしがるときに出したい人
  • 猫にほじくり出されるのが我慢ならない人
  • コンパクトな給餌器がいい人

カリカリマシーンECOってどうなの?

それでは最後にカリカリマシーンECOです。Amazonでのお値段は¥9,280です。値下げ後の値段はカリカリマシーンより高くて、定価はカリカリマシーンと同じですね。

正直言ってあまりおすすめはしない

最終的にご家庭によりけりなので、ハマるおうちはハマると思います。
以下のおすすめできない点を気にしないのであれば、十分に購入検討できる機種です。

おすすめできない点

  • リモコン操作は本体にUSB接続しないとできない上に、はずしておかないといけない
    → マメに出したり出さなかったりの設定を変える場合にかなり面倒。残量0になったときも、エラー解消のため接続する必要アリ
  • ポーションを0に設定しても、時間になったら録音した音声が再生される
    → カリカリマシーンはポーション0のときは再生されません。給餌なしなのに音声だけが再生されて、猫たちが勘違いしました
  • フード切れお知らせは本当にフードが切れないとわからない
    → 残量が減ったらお知らせに光るタイプではなく、給餌するものがなくなって初めて点滅する
  • 電源でのみ稼働するので、停電時などは使えない

我が家は基本朝のみ、昼・夜は長時間のお出かけのときだけなので、ちょこちょこ給餌設定を変えていました。なので、リモコンを繋がないと何もできない、ポーション0でも音声が再生される(一旦設定をリセットしないといけない)という点で合いませんでした。

また、寝室に置いているので、光り続けるお知らせランプが地味に眩しかったというのもあります。

残量が0になったら点滅するランプ

カリカリマシーンECOのおすすめできる点

散々おすすめできないと書きましたが、ECOにしかないおすすめポイントはもちろんあります。

何よりも省スペースであること!

ほか2つより圧倒的にコンパクト(H280 x W220 x D220mm)です!また、白一色のシンプルなデザインなのもいいですね。

ポーションが約5gから設定できる

他のカリカリマシーンはすべて1ポーション約10gですが、ECOだと1ポーション約5gという小回りのきく給餌ができます。最大8ポーション(約40g)なので、高齢猫さんや少食な猫さんにピッタリかもしれません。

また、カリカリマシーンSP・カリカリマシーンともに最大4回の給餌でしたが、ECOは最大6回まで給餌できます。

コードがメタルコートなので噛みちぎり防止

メタルコートになっているのはカリカリマシーンECOのみです。コードでいたずらする子がいても、カリカリマシーンよりは安心して置けそうです。

メタルコートされたコード

フードタンクはがっちり密閉

先述した2機種と違い、がっちりと上蓋が閉まるタイプなので、多めに入れていても酸化はそこまで気にならなそうです。(蓋が透明ではないので上から残量確認できないですが…)

カリカリマシーンECOをおすすめする人・しない人

以上をふまえて、私が思う「おすすめできる人」と「他の機種にしたほうがいい人」はこんな感じです。

おすすめできる人

  • 少量(5g)から給餌したい+時間設定をそんなに変更しない人
  • リモコン操作がいるときに毎回USB接続が苦にならない人
  • リモコンをなくさない自信がある人
  • コンパクトであることを重視する人

他の機種にしたほうがいい人

  • そもそもどれを買うか悩んでいる人
  • 給餌スペースにゆとりがある人
  • 約10gからの給餌で問題ない人
  • リモコンをなくす人(なくしたら何もできなくなって詰みます)

多頭飼いのおうちは機種をまとめた方がいいかも

我が家は今はジルがSP、レーナがカリカリマシーンを使っていますが、時間のズレが発生してしまいます。

SPの方は現時刻は自動設定っぽいのでずれようがないのですが、カリカリマシーンの方は本体の設定をちょっと触ったりしている間に時間がずれてしまうことがあるので、その点は注意が必要ですね。特に、同居猫さんのご飯を取ってしまう子がいるおうち…。(我が家です)

ちなみに我が家は未だに有用な対策がありません。レーナの方を数秒早く出しても、ブルドーザーのように吸い込んでいってジルのご飯を奪いに行くので、毎朝戦争です…。(よい対策があったら教えてほしい!)

また、こっちはスマホから、こっちは本体からというのも後々を考えるとちょっと面倒かもしれません。

まとめ

かなり長い記事になりましたが、我が家の場合の最適機種はカリカリマシーンSP!

正直、カリカリマシーンにリモート給餌機能だけが備わったタイプがあればそちらを選びます。それくらい、カリカリマシーンSPとカリカリマシーンは僅差です。

少量から給餌したいおうちはぜひECOも検討してくださいね。

投稿 猫と中・小型犬用自動給餌器、カリカリマシーン3種類使ったので、それぞれのレビューとおすすめ機種の紹介chiilog に最初に表示されました。

]]>
2019年買ってよかった猫のためのグッズまとめ! https://chiilog.com/2019/12/29/2488/ Sun, 29 Dec 2019 08:57:42 +0000 https://chiilog.com/?p=1115 一年経つのはあっという間ですね!ということで、今年買ってよかったものをまとめました。 Webカメラ Arlo […]

投稿 2019年買ってよかった猫のためのグッズまとめ!chiilog に最初に表示されました。

]]>
一年経つのはあっという間ですね!ということで、今年買ってよかったものをまとめました。

Webカメラ Arlo Q

詳しくは以下の記事に夫がまとめていますが、出先で今猫たちが何をしてるか確認できるのはとてもよい!

https://remoneko.life/network-camera-for-cat-arlo-vs-planex/

出張中に猫たちが恋しくなっても、マイクで「ジル」と呼びかけるとすっ飛んできてくれてすごくかわいい。ジルはかしこい!(ちなみにレーナは呼んでも来ない。ジルがすっ飛んでくるのに釣られてやってくるタイプ)

呼ぶと飛んでくるかわいいやつ

LEDにゃんだろー光線

こちらは正式には買ったものじゃなく、登壇のお礼としてほしいものリストからいただいたおもちゃです。
詳細はこちらの記事で!

https://remoneko.life/cattyman-nyandaro-kousen/

大体おもちゃのブームは短くてすぐ遊んでくれなくなりますが、このおもちゃは未だに現役で遊んでいます。寝室に誘導するためにも相変わらず便利なアイテム!ただ、ときどき手元を見て次どこに出すのかチェックされるようになりました。

自動給餌器カリカリマシーン

こちらも詳細は前に別記事にまとめました。

https://remoneko.life/automatic-feeder/

今年はレーナも増えたので、レーナの分も買いました。こちらは同じものではなく、「カリカリマシーンECO」というちょっと見た目がおしゃれな省スペースバージョンです。

カリカリマシーンかカリカリマシーンECOか

近々カリカリマシーンSPも購入予定なので、そのときに詳しく比較記事を書こうと思っていますが、ECOは正直に言ってあまり有用ではありません。リモコンで操作できると書いていますが、本体と繋がないと操作ができません。

その点に目を瞑れるのであれば、

  • 約5g段階でフードが出せる
  • 時間があまりずれない(ただし、多頭飼いのおうちはシリーズをまとめたほうが良いです!)
  • カリカリマシーンに比べておしゃれ

といったメリットもあります。ただ、私が今の時点でオススメするのはカリカリマシーンの方ですね。

じわじわ時間がずれていくので、たまに時間合わせが必要ですが、これは多頭飼いでなければそこまで気にしなくていいと思います。我が家はレーナがすぐジルのご飯を奪いに行くので、時間設定はこまめに見ています。

ポールタイプの爪とぎ

今まで置くダンボールタイプの爪とぎを使っていましたが、レーナが隅を噛みちぎったりちぎったカスを食べようとしたりするので、家の爪とぎはすべて麻のポールに置き換えました。

ジルは置くタイプがお気に入りだったので研ぐかなあと心配でしたが杞憂でした。上のタイプは寝室に置いているのですが、寝室に入るたびにとぎとぎしています。

くっついているネズミのおもちゃは絶対にレーナが噛みちぎるので設置段階で切り取って処分しました。

リビングの方にはこのちょっと背丈が高いタイプを置いていますが、寝室に置いているタイプのほうが人気です。
高いほうが伸びながら研げていいのかなと思っていましたが、あまり関係なさそう。

また、麻も置いているとボロボロになるので、もけもけが目立ってきたら買い替え時です。

柱部分が爪とぎになってるキャットタワーもおすすめ

レーナは最近このキャットタワーの爪とぎでも研ぐようになりました。

こちらは天井に突っ張るタイプですが、よくジルが一番上でくつろいだりばたばた暴れたりしています。

締めすぎると天井の壁紙に穴があいてしまうので、タオル等を挟むのをおすすめします…。(経験者は語る)

てっぺんからレーナをしばきまくるかと思いきやぺろぺろも混ぜるジル

2020年も4人で楽しく暮らします

今年はリモネコを始めた年ですが、来年はよりいっそうジルとレーナの写真をあげたりグッズのレビューなどをやっていきたいと思います。

みなさま、良いお年を!

投稿 2019年買ってよかった猫のためのグッズまとめ!chiilog に最初に表示されました。

]]>
初めての外泊!そのときジルとレーナは・・・? https://chiilog.com/2019/11/26/1013/ Tue, 26 Nov 2019 10:11:56 +0000 https://chiilog.com/?p=1013 つい先日、夫とふたりでプチ新婚旅行(私が海外興味なし&長く家を空けたくない)で、二泊三日の外泊をしてきました。 […]

投稿 初めての外泊!そのときジルとレーナは・・・?chiilog に最初に表示されました。

]]>
つい先日、夫とふたりでプチ新婚旅行(私が海外興味なし&長く家を空けたくない)で、二泊三日の外泊をしてきました。

猫は放っておいたらずっと寝てるというのは頭ではわかっていたものの、二人揃って外泊は実は初めて。色々と不安でした。

前準備

まず、ペットホテルに預けるという選択肢はありませんでした。ジルが神経質なので、知らないところにあずけてストレスを溜めるよりは家でのんびり過ごしてもらうことを優先しました。

※ 主にレーナの対策ばっかり

いつも夜は寝室に放しているので、旅行中も特にケージには入れずに寝室を開放することは決めていました。
ただ、レーナが避妊直後ということで、抜糸を少し早めたり(走り回ってたので問題なしとお墨付き。10日で抜糸しました)、寝室のレーナ用ケージを買い替えたりしました。

もともと使っていたケージが子猫用だったのでさすがにもう今のサイズ感には耐えられないのか、たまに寝返りで落ちてたので、これを機に買い替えました。

上がったり下がったりのときの音がだいぶ静かで、寝室に置くにはぴったりです!
※ 登ったり降りたりがジルの使っている以下のケージより抑えめというだけで、音自体はします。

あと、少し前から自動給餌器を追加購入しました。
ジル用の自動給餌器と同じ、カリカリマシーンのECOです。

これのレビューは後日改めて。

避妊手術前までダラ食い気まぐれ食いだったレーナですが、食べれないときがある!と危機感を覚えたのか、出た分はすぐ食べる、足りないと催促する、ジルのご飯を盗み食いすると腹ペコマンになってしまったので、お皿に出しておくこともできず。避妊前から導入はしていましたが、改めて買っておいてよかったなーと思いました。

自動給水器も前回購入から結構経っていたのでこちらも購入。
結構重いけど、水がたくさんはいって数日の留守でも使えそうでよいです。

買ったものはこんな感じ。

あとは、寝室に置いてるカメラの位置調整をしたり、AlexaのEcho Showを置いていろんな角度から寝室をチェックできるようにしました。

ちなみに、カメラは以前はPLANEXのカメラを使っていたんですが、あまりのアプリの使い勝手の悪さ、接続不良でついに撤去になり、現在はArloを使っています。Arloについては夫が随分前から下書きに置いてるのでそのうち書いてくれるでしょう。

Alexaは暗視機能はないものの、着信でカメラが表示できるのでPLANEXを改めて出すより設定が簡単というのもあり採用しました。Alexa経由で部屋の電気もつけられるし!

掃除機やら携帯の充電コードやらを撤去して、噛めるものを極力減らしてお留守番用寝室は完成しました。

旅行中のジルとレーナ

ガチ寝室なのでかなり一部抜き出し

家を出発してから、さっそく二人は爆睡。(動作検知の精度があまりよくなかったので、途中からタイムラインを見られるプランに課金してます)

寝てる寝てるーとしばらくは見ずに旅行を楽しんでいたのですが、事件はお昼に起きました。

レーナがジルのご飯を全部横取り

ジルはのんきに爆睡。というか、あえて譲ってるようにも見える・・・。
きみ、そりゃあ「留守中レーナをよろしくね」とは言ったけど!

お昼だけだったらまあ・・・夜もでるし、と不憫に思いながら(寝てるけど)ついに夜ご飯の時間。

またレーナがジルのご飯を全部横取り

さすがに朝だけしか食べれてないことに危機感!(寝てるけど)

このあたりから私が「もう帰ろう」と連呼しだしてるのですが、ふと起きたジル、自分の給餌器の前に行って、餌の出口に手を突っ込んだ!!!

そうだった・・・この子、自分でほじくり出せるんだった・・・。(出ずに引っかかってる分だから無限に出せるわけではないけど)

部屋が暗いからご飯の時間がわからないのか?と、ご飯前に自動で電気がつくようにとかの調整もしたものの、結局この旅行中ほとんどレーナがジルのご飯を食べてしまう、という結果に終わりました。

それ以外は激しい取っ組み合い(遊び)がちょっとあったくらいで、いたずららしいいたずらもなく、一泊くらいだったら泊まりでも大丈夫そうだなあとわかったのは収穫でした。走り回るときのためにもうちょっと広い部屋があったらいいなあ・・・。

お留守番から見えた課題

レーナの盗み食い問題がかなり深刻!今のジルの自動給餌器だと、タイマーの設定はできるものの、外出先から追加で出すことはできないので、ジルの給餌器はそのうちスマホで遠隔操作できるタイプに変更しようと思いました。盗み食いを防止することはできないけど、ジルが前に陣取って食べてるときに追加で出してあげることはできる・・・。

ジルの方はあまり水を飲まない・・・。全く飲まないことはないものの、家にいるときはのどがかわいたら「シャワーで水出して」って催促しに来るので(無視し続ける or 気が向いたら給水器を使う)、自分で水を飲むようにさせるようにしないといけなさそう。

シャワー出せを要求するジル

私の心配性も結構課題ですね!気になってちょくちょくカメラを覗いてしまう・・・。(私のほうが分離不安だ)

お土産に首を傾げるふたり。かわいい。

投稿 初めての外泊!そのときジルとレーナは・・・?chiilog に最初に表示されました。

]]>