• WordPress の REST API の _links に 投稿を追加する

    WordPress の REST API には、関連するオブジェクトをリンクする機能があります。

    例えば以下のようなコードを足すと、固定ページの API に親のページへのリンクを追加できます。( デフォルトで up という親ページへのリンクがついています。)

    $post_type = 'page';
    add_filter( 'rest_prepare_' . $post_type, 'rest_prepare', 10, 3 );
    function rest_prepare( \WP_REST_Response $response, \WP_Post $post, \WP_REST_Request $request ) {
       $response->add_link(
          'parent',
          rest_url("/wp/v2/pages/{$post->post_parent}"),
          array(
             'embeddable' => true,
          )
       );
       return $response;
    }

    embeddable => true を設定すると、_embed クエリーをつけてリクエストしたときに、リンクされた投稿のデータも一緒に取得されます。

    関連記事の機能とか作るときに便利に使えそうです。

  • カスタムブロック開発を TypeScript で行う。

    TypeScript で書いたコードをいろいろいじってたら、カスタムブロックもTypeScirpt で書きたくなってきました。そんなわけでいろいろ試行錯誤してみてます。

    レポジトリ:https://github.com/torounit/gutenberg-examples-with-typescript

    一からwebpack の設定とかを扱うのは面倒だし、@wordpress/scirpts の wp-scirpts はそのまま使いたいなーと言うことで、webpack の設定を一部上書きする格好で設定しています。

    wp-scripts になるべく乗っかりたいので、ts-loader ではなく、babel でコンパイルするようにしてます。なので、tsc での型チェックをビルド時に走らせてます。

    Babel 7でTypeScriptをトランスパイルしつつ型チェックをする 〜webpack 4 + Babel 7 + TypeScript + TypeScript EsLint + Prettierの開発環境を構築する〜 の記事を参考にいろいろしてます。

    ブロックエディター周りのパッケージの型定義もDefinitelyTyped に入っていたりするので、以外に簡単に TypeScirpt での開発できそうです。

  • WordCamp Tokyo 2019 で 「本当にだれにでもできる、WordPress をよりよいものにする方法。」という話をしました。#wctokyo

    WordCamp Tokyo 2019 で 「本当にだれにでもできる、WordPress をよりよいものにする方法。」という話をしました。#wctokyo

    Photo by sugawara shinnosuke

    ブログを書くまでが WordCamp です。

    というわけで、11/1 – 2 に開催された WordCamp Tokyo 2019 に参加してきました。初日はコントリビューターデイ、翌日はセッションデイという内容でした。

    コントリビューターデイ

    コントリビューターデイでは、ヘルプデスク担当と言うことでしたが、まぁ他のチームのメンターとか、参加者の皆さんがヘルプしていたようで、得に忙しいと言うことも無かったです。なぜか落とし物の連絡が来たり、これがほんとのヘルプデスク感ありました。ひさびさに落ち着いて Gutenberg の issue とかを読む時間に出来たのはよかったです。

    セッションデイ

    久々に、WordCamp Tokyo でセッションをさせて頂きました。去年の今頃、WordPress 5.0 beta 4 / Gutenberg 4.3 で日本語入力における不具合があったのですが、そのときに、僕がどう関わったのかという話を中心に、「本当にだれにでもできる、WordPress をよりよいものにする方法。」というテーマでお話しさせて頂きました。

    当日紹介した、Github や、Slack でのやりとりです。

    WordPress の本体や、Gutenberg へのコントリビューション・改善提案は、達人プログラマーじゃ無いと出来ないと思われているようですが、そうでなくてもやることいっぱいあるよ!という話ができればいいなと思いながら話しました。

    Slack 上でのやりとりや Github 上でのコメントなど、まず最初にやらないといけないのは、コミュニケーションを取るということなんだなと感じる次第です。

    Slack での Meeting のスケジュールは https://make.wordpress.org/meetings/ こちらにて公開されています。

    セッションでは、アジア太平洋でも参加しやすい時間帯のミーティングの話もしました。11/14 の 14:00 から、APAC Editor Triage Session が #core-editor のチャンネルで行われます。ぜひどんな感じなのか覗いてみてください。

    感想とか

    久々に WordCamp Tokyo で登壇させて頂きました。とても有意義な時間でした。セッションを聞いた方から「やってみようと思いました!」ってコメントを頂けてとても嬉しかったです。

    信州 WordPress Meetup vol.18 を、11/23 に開催します。またそちらでも WordCamp Tokyo 2019 の振り返りをやるので、是非お越しくださいー。

  • Gutenberg 6.1 から 「文書」サイドバーに設定パネルを追加できるようになるようです

    「ステータスと公開状態」パネルの下に、プラグインから新たなパネルを挿入できるようになるようです。今までの meta box 風味に使いたい場合はこちらの方が重宝しそうです。

    import { registerPlugin } from '@wordpress/plugins';
    import { PluginDocumentSettingPanel } from '@wordpress/edit-post';
    
    const MyDocumentSetting = () => (
    	<PluginDocumentSettingPanel
    		className="my-document-setting-plugin"
    		title="My Panel Title">
    		<p>My Document Setting Panel</p>
    	</PluginDocumentSettingPanel>
    );
    
    registerPlugin( 'my-document-setting', { render: MyDocumentSetting } );
    

    色んなプラグインがこれを使うと、サイドバーがカオスになる未来が待っていそうなので、使いどころは吟味した方が良さげですね。

    SlotFill という仕組みを用いて、この機能は実装されています。似たようなモノもいろいろ用意されているので、ドキュメントを見てみるといろいろ詳しく書いてあります。

    https://developer.wordpress.org/block-editor/developers/slotfills/

    公開後に変更してもそんなに問題無いようなモノ(description など)や、デフォルトの設定で良い感じになっているヤツは今まで通りの PluginSidebar で良いのかなとは思います。逆に、公開時に何かアクションを起こすようなモノはこれで UI を作った方がよいのかなと。

    なんにせよ便利なので、使いどころを考えたいです。

  • WordPress Meetup Map 1.0.0 を公開しました。

    WordPress Meetup Map 1.0.0 を公開しました。

    WordPress Meetup Map 1.0.0 をリリースしました。

    結構前から公開はしていたんですが、やりたいこと一通り実装したので正式リリースと言うことです。

    これは何?

    WordPress Meetup は、WordPress の地域ごとのコミュニティで定期的にイベントとかを開催してたりします。WordPress のダッシュボードに「WordPress イベントとニュース」がありますが、そこに表示されるヤツを国ごとに一覧で見れたり、地図にピンが立ったりするヤツです。

    額賀さんが欲しいって言ってたので、作りかけて放置してたのをうりゃって完成させたヤツです。

    PWA になってるのでアプリっぽく動きます。

    仕組み

    イベントの取得は、ダッシュボードのヤツと全く同じAPIを使っています。 Codex にも載ってます。WordPress.org API « WordPress Codex

    https://api.wordpress.org/events/1.0/?country=JP みたいなリクエストを投げると、日本国内の登録されているイベントの一覧が返ってきます。

    API のソースコードは、 https://meta.trac.wordpress.org/browser/sites/trunk/api.wordpress.org/public_html/events/1.0/index.php にあります。細かい仕様が Codex には載ってないので結構ソースを読むハメになりました。

    この API は国や都市、もしくは現在地などが指定されないとデータが取得出来ないようになってます。なので初回アクセス時はブラウザの Geolocation API を使って緯度経度を取得し、OpenStreetMap の Nominatim というサービスを使って緯度経度から国名を取得しています。2回目以降は最後に選択された国をlocalStrage に保存してそれを使うようにしてます。

    また、https://wp-meetup-map.netlify.com/?country=us のように指定することもできます。

    国名コードの一覧は、lukes/ISO-3166-Countries-with-Regional-Codes の json を使ってます。

    フロントエンドは、Create React App / react-app-rewired / TypeScriptです。TypeScript 使うと補完も便利だし気分良くコード書けるので良いですね。Create React App は最小限のものが過不足無く入っていてシンプルで良いなと改めて思いました。

    バックエンドは、Netlify 使ってます。難しいこと一切考えなくて良いので楽。

    react-app-rewired は、workbox のキャッシュの設定をいじりたかったので使ってます。ランタイムキャッシュは他に良い方法無いのかなと思っているので誰か教えて下さい。

    余談

    色んな国のヤツ取れるようにして良かったなーっておもいました。こんなことあるんだなー。

    Repository

    Github: torounit/wp-meetup-map

  • 『WordPressのやさしい教科書。手を動かしながら学ぶ実用サイト作りと正しい運用 5.x対応版』の執筆に参加しました #wpネコ本

    『WordPressのやさしい教科書。手を動かしながら学ぶ実用サイト作りと正しい運用 5.x対応版』の執筆に参加しました #wpネコ本

    WordPressのやさしい教科書。手を動かしながら学ぶ実用サイト作りと正しい運用 5.x対応版』通称ネコ本が、5/21に発売されましたがその執筆に参加させて頂きました。もとはちさん額賀さんシマさんとの共著となっております。

    「カフェとか小さなお店向けサイトを作ろうという方向け」というテーマで執筆すると言うことで、PHPやJavaScriptなど全く書かない、可能な限りHTMLやCSSも書かないでサイトを作る・運用するという本になっております。

    そんなわけで、「WordPress をカスタマイズしてサイトを作ろう」みたいな本ではなく、ある意味ではWordPressの説明書に近い本になったのではないかなと思います。可能な限りプラグインなども最小限にして、WordPress の本体の機能を上手く使ってサイトを作る方法を紹介しています。

    僕は主に、ブロックエディターの解説などを中心に執筆させて頂きました。文章よりコードを読み書きする方が得意なのでなかなか難産でした。これをきっかけに「ブロックエディターを使ってみよう」という人が増えたら嬉しいなと思う次第です。

    また、6/10 に、WordPress のオンライン勉強会 WP ZoomUP にて、内容の紹介や、書籍の内容に沿って実際にサイト作ってみるライブデモみたいなモノを行いますので、ご興味ある方はぜひそちらもどうぞ。

    #20 WP ZoomUP 「WordPressのやさしい教科書」実際にサイトを作ってみよう! – connpass

    執筆陣のブログ

    『WordPressのやさしい教科書。 手を動かしながら学ぶ実用サイト作りと正しい運用 5.x対応版』という書籍の執筆に参加させて頂きました。 | mt8

    「WordPressのやさしい教科書。 」を書きました ‹ nuuno

    https://shimakyohsuke.com/2019/05/24/wp5-8341/

    謝辞

    出版・編集の担当者さん、ご紹介いただいた、デジタルキューブ岡本さん、レビューを手伝って頂いた、村上さん (@ud_fibonacci)みうらさん (@NOCE_WEB_DESIGN)こうのさん (@chiaki_kouno)齋木さん (@lunaluna_dev)なおさん (@naokomc) 、執筆チームのみなさん、本当にありがとうございます。

  • Advanced Posts Blocks 0.2.2 をりりーすしました。

    一月にリリースしたプラグインですが、今更ブログを書きます。Advanced Posts Blocks というプラグインをリリースしました。

    機能

    WordPress のビルトインのブロックに、「最新の記事」ブロックがありますが、あれを大幅に強化したプラグインです。より細かい検索条件で記事を取得できたり、テーマ側でテンプレートを用意することで表示をカスタマイズ出来ます。

    • 複数の投稿の一覧を表示する Multiple Posts Block
    • 特定の記事の子ページ一覧を表示する Children Posts Block
    • 特定の個別投稿を表示する Single Post Block

    の3つのブロックを提供します。

    テンプレート

    テーマのなかに、template-parts/blocks/advanced-posts-blocks/posts.php といったファイルを用意することで、表示をカスタマイズすることができます。WordPress のテンプレート階層のように、template-parts/blocks/advanced-posts-blocks/posts/page.php と行ったファイルを用意すると、個別ページの一覧の場合は、こちらが読み込まれます。ブロックのスタイルなどを利用すると更に細かいテンプレートのカスタマイズができます。

    開発

    開発は Github で行っています。https://github.com/torounit/advanced-posts-blocks プルリクエストなどください!

  • Custom Post Type Permalinks 3.3.1 をリリースしました。

    Custom Post Type Permalinks 3.3.1 をリリースしました。

    Custom Post Type Permalinks を久々にアップデートしました。

    ちゃんとリリースノートとか書かねばとは思うのですが、取り急ぎ、ざっくりとした変更点の解説。

    日付・著者での投稿タイプアーカイブの無効化

    デフォルトで有効になっていますが、register_post_type の設定でこれらを無効化できるようにしました。

    register_post_type( 'foo',
        array(
            'public' => true,
            'has_archive' => true,
            'cptp' => array(
                'author_archive' => false,
                'date_archive' => false,
            )
        )
    );

    PHP でのパーマリンク設定

    以前にも似たような機能はありましたが、以下のようにしてパーマリンクの設定を出来るようにしています。

    register_post_type( 'foo',
        array(
            'public' => true,
            'has_archive' => true,
            'cptp' => array(
                'permalink_structure' => '%post_id%',
            )
        )
    );

    その他

    • 階層無しのタクソノミーでも階層ありのパーマリンクと同様にパースしていたのを修正
    • WordPress 5.0 でのテスト

    抜本的な変更はなかなか難しいのですが、細かいリファクタリングなどは続けていきたいなーとは思います。

  • WordPress 5.0 への更新について

    WordPress 5.0 への更新を控えるように等の情報があるので、ちょっとそれはどうなんだろうとおもってつらつらと。

    Supported Versions « WordPress Codex

    WordPress の Codex によれば、サポートポリシーとしては、最新版のみです。可能であれば古いバージョンにもセキュリティアップデートは適用するとのことですが、基本的には最新版を使うことが推奨されてます。

    バージョン番号について

    WordPress のバージョン番号は、上位2桁が10進数的な扱いです。3.9 の次は 4.0 でしたし、4.9 -> 5.0 です。なので 4系から5系みたいな感じではないです。3桁目は、パッチのバージョンなので上位2桁とはまた別にナンバリングされます。4.7.11 みたいな。バージョン番号の付け方としては違和感がありますが、最初の小数点は無視してバージョン 49 から 50 に上がったんだなーくらいのノリで理解するのが良いのかなと。

    なので、5.0 はメジャーアップデートではありますが、普段のメジャーアップデートと基本的には同じです。まぁ内容次第というところはありますが。個人的には、REST APIがマージされた 4.7 や、管理画面がリニューアルされた 3.8 辺りの方が印象は強かったりします。

    ブロックエディタを使いたくない場合

    Classic Editor プラグインを入れましょう。2022 年まではとりあえずサポートするようです。そのあとはサポート終了というわけでは無く、2022 年になったときにまた検討すると言うことのようです。

    また、利用しているテーマ・プラグインが 5.0 対応しているのか等は確認する必要があるのかなと思います。

    不具合などが心配な場合

    5.0 に限った話では無いですし、プラグイン・テーマなどもそうですが、不安な場合は事前に検証するのが良いかと思います。サーバー内に、test.example.com みたいな感じで、同じプラグイン・テーマ・本体を入れた環境を用意して、それで試すのが良いかと思います。All-in-One WP Migration 等を利用すると手軽に同一の環境を再現できるかと思います。

    まとめ

    WordPress のアップデートと一口に言っても本体やプラグインなど様々なものが関わってきますので、とりあえず検証できる環境を用意して、安心して WordPress と付き合っていけるようにしましょう。

    WordPress に限った話ではないですが、アップデートのときは、事前検証・バックアップをちゃんととりましょう。

  • unregisterBlockType で ブロックを削除する。

    HandBook のほうには、

    wp.blocks.unregisterBlockType( 'core/verse' );

    をするとブロックの登録を解除できるという話だったのですが、このまま書いても解除されないんですよね。

    何故かというと、core/verse が 登録される前に unregisterBlockType が実行されてしまうからです。なので、Gutenberg / ブロックエディタの初期化処理が終了してから、こいつを実行してあげる必要があります。

    const { _wpLoadBlockEditor } = window;
    const { unregisterBlockType } = wp.blocks;
    _wpLoadBlockEditor.then( () => {
        unregisterBlockType( 'core/verse' );
    } );

    こんな感じで、_wpLoadBlockEditor の完了を待ってから実行すれば良いみたいです。

    _wpLoadBlockEditor はこんな感じです。

    
    window._wpLoadBlockEditor = new Promise( function( resolve ) {
    	wp.domReady( function() {
    		resolve( wp.editPost.initializeEditor( 'editor', "%s", %d, %s, %s ) );
    	} );
    } );

    覚えておくと何かの役に立つかもしれません。

  • Gutenberg のカスタムブロックでも、ES Modules import を使う。

    要は、どうしたいかというと、

    const { registerBlockType } = wp.blocks;

    これを、Gutenberg のコアのソースコードのように、

    import { registerBlockType } form '@wordpress/blocks'

    としたいと言うことです。

    やりかた

    webpack.config.js を の externals を良い感じに設定すればできます。Gunteberg 本体も似たようなコトをやっています。

    const entryPointNames = [
    	'blocks',
    	'components',
    	'editor',
    	'utils',
    	'viewport',
    	'edit-post',
    	'core-blocks',
    	'nux',
    ];
    
    const gutenbergPackages = [
    	'api-request',
    	'blob',
    	'core-data',
    	'data',
    	'date',
    	'deprecated',
    	'dom',
    	'element',
    	'keycodes',
    	'plugins',
    	'shortcode',
    ];
    
    const wordPressPackages = [
    	'a11y',
    	'dom-ready',
    	'hooks',
    	'i18n',
    	'is-shallow-equal',
    ];
    
    const externals = {
    	react: 'React',
    	'react-dom': 'ReactDOM',
    	tinymce: 'tinymce',
    	moment: 'moment',
    	jquery: 'jQuery',
    	lodash: 'lodash',
    	'lodash-es': 'lodash'
    };
    
    [
    	...entryPointNames,
    	...gutenbergPackages,
    	...wordPressPackages,
    ].forEach( ( name ) => {
    	externals[`@wordpress/${ name }`] = {
    		window: ['wp', name],
    	};
    } );
    
    module.exports = {
    	output: {
    		library: ['wp', '[name]'],
    		libraryTarget: 'window',
    	},
    	mode: 'production',
    	module: {
    		rules: [
    			{
    				test: /\.js$/,
    				exclude: /node_modules/,
    				use: {
    					loader: 'babel-loader',
    					options: {
    						presets: ['@babel/preset-env']
    					}
    				}
    			}
    		]
    	},
    	devtool: 'source-map',
    	externals,
    	resolve: {
    		extensions: ['.js', '.jsx']
    	}
    };

    こんな感じの config を書いてます。externals の 設定を行えば、@wordpress/{packageName} みたいなので、import の解決が出来ます。output の設定も書かないとうまいこと動きません。ここでちょっとつまづきました。

    メリット

    • コアのソースをコピペするときに、import とかを書き換えなくて済む。
    • npm で、@wordpress/editor 等を devDependencies で入れておけば、PHPStorm 等でコードジャンプが容易に出来る。
    • ちょっとカッコいい。

    addFilter 等もあるため、コアのソースを読みたいという瞬間はかなり多いです。ですので、コードジャンプが行えるのは大きな利点なのかなとおもいます。

  • registerBlockType の styles プロパティ

    wp.blocks.registerBlockType に styles というプロパティがあります。これにちょっとした設定をするだけで、「追加 CSS クラス」がグラフィカルに適用できるようになります。「ブロックタイプを変更」というボタンが出現し、GUIで適用するスタイルを選択出来ます。

    「ブロックタイプを変更」を押したときの様子

    実装

    'use strict';
    const { registerBlockType } = 'wp.blocks';
    
    registerBlockType( 'block-example/basic', {
    	title: 'Example',
    	icon: 'universal-access-alt',
    	category: 'example',
    	styles: [
    		{ name: 'default', label: 'default', isDefault: true },
    		{ name: 'style1', label: 'スタイル1' },
    		{ name: 'style2', label: 'スタイル2' },
    	],
    	edit ( { className } ) {
    		return <div className={ className }>Basic example with JSX! (editor)</div>;
    	},
    	save ( { className } ) {
    		return <div className={ className }>Basic example with JSX! (front)</div>;
    	},
    } );
    

    実装はこんな感じでとにかくシンプルです。styles プロパティを指定するだけです。適用される class は is-style-style1 だとか、is-style-[name] という格好になります。

    GUI でゴリゴリ出来ていろいろ楽そうですねこれ。