Ubuntu 18.04のWordPressにReactアプリケーションを埋め込む方法

著者は、Write for DOnationsプログラムの一部として寄付を受け取るためにElectronic Frontier Foundationを選択しました。

前書き

WordPressは、W3Techs(Web Technology Surveys)によると、over 33% of websites on the Internetを強化する人気のあるコンテンツ管理システムです。 人気が高い理由の1つは、明確でわかりやすいドキュメントを簡単にセットアップできることです。 さらに、WordPress開発者をサポートする多くのコミュニティリソースがあります。 WordPressは、安価な、または無料のすぐに使えるソリューションで多くのユースケースを解決できます。 最後に、WordPressには明確に定義されたプラグインシステムが付属しており、開発者はカスタムコードを記述して独自の機能を追加できます。 このプラグインシステムは十分に文書化されており、機能します。このチュートリアルの後半で説明するように、使いやすいです。

最もリッチでインタラクティブなエクスペリエンスを提供したい開発者は、ReactなどのフレームワークでサポートされているJavaScriptを使用できます。 Reactは、開発者が一般的な静的ページまたはフォームを超えて動的でインタラクティブなUIを簡単に作成できるように設計されたJavaScriptライブラリです。 Facebookによって作成され、セキュリティ、安定性、および使いやすさのために十分に維持されているReactは、優れたドキュメントと、ドキュメントとプラグインの確立されたコミュニティ主導のエコシステムを備えているため、人気があります。

このチュートリアルでは、ReactアプリケーションをWordPressサイトに埋め込むためのベストプラクティスを紹介します。 その例では、一般的なユースケースを使用します。複数のページに埋め込まれることを目的としたウィジェットを作成し、時にはページに複数回使用することもあります。 サーバー側では、WordPress shortcodeとして実装されます。 ショートコードはHTMLタグに似ていますが、山かっこ(<...>)の代わりに角かっこ([...])を使用します。 HTML要素を直接レンダリングする代わりに、PHP関数を呼び出します。PHP関数は、データベースからのデータで補間されたHTMLをレンダリングします。

このチュートリアルの終わりまでに、独自のショートコードを作成し、WP Adminのページに挿入して、そのページを公開します。 そのページで、ブラウザーに表示されるReactウィジェットを確認できます。

前提条件

このチュートリアルを実行するには、次のものが必要です。

  • Initial Server Setup with Ubuntu 18.04チュートリアルでセットアップされたUbuntu 18.04サーバーは、root権限を持つ新しいユーザーとともにサーバーのファイアウォールを構成します。

  • 完全に登録されたドメイン名。 このチュートリアルでは、全体を通して例としてyour_domainを使用します。 Namecheapでドメイン名を購入するか、Freenomで無料でドメイン名を取得するか、選択したドメインレジストラを使用できます。

  • 次の両方のDNSレコードがサーバーに設定されています。 それらを追加する方法の詳細については、this introduction to DigitalOcean DNSをたどることができます。

    • サーバーのパブリックIPアドレスを指すyour_domainを含むAレコード。

    • サーバーのパブリックIPアドレスを指すwww.your_domainを含むAレコード。

  • サーバーへのApache、MySQL、およびPHPのインストール。 これは、How To Install Linux, Apache, MySQL, PHP (LAMP) stack on Ubuntu 18.04をたどることで取得できます。

  • How To Secure Apache with Let’s Encrypt on Ubuntu 18.04に従って無料のSSL証明書を生成することにより、Let’s EncryptでApacheを保護しました。

  • How To Install WordPress with LAMP on Ubuntu 18.04とその前提条件に従うことで取得できるWordPressのインストール。

  • How To Install Node.js on Ubuntu 18.04の「PPAを使用したインストール」オプションに従ってNode.jsをインストールします。 このチュートリアルではバージョン11.15.0を使用するため、curlを使用してインストールスクリプトをダウンロードする場合は、10.x11.xに置き換えて、このチュートリアルの手順に従ってください。

[[step-1 -—- updating-and-configuring-filesystem-permissions]] ==ステップ1—ファイルシステムのアクセス許可の更新と構成

Initial Server Setup with Ubuntu 18.04前提条件で作成された非rootユーザーとしてログインすると、WordPressディレクトリ内のファイルを表示または編集するためのアクセス権がなくなります。 後でファイルを追加および変更してWordPressプラグインとReactアプリケーションを作成するため、これは問題です。 この問題を解決するには、このステップでWordPress設定を更新して、WordPressファイルを編集するためのアクセス権を付与します。

次のコマンドを実行し、root以外のユーザーの名前をsammyに、WordPressディレクトリ(前提条件で作成したApacheドキュメントのルートフォルダー)へのパスを/var/www/wordpressに置き換えます。

sudo chown -R sammy:www-data /var/www/wordpress

このコマンドを分解してみましょう。

  • sudo —これにより、sammyがアクセスできないファイルを変更しているため、このコマンドをrootとして実行できます。

  • chown —このコマンドはファイルの所有権を変更します。

  • -R —このフラグは、すべてのサブフォルダーとファイルを含め、所有権を再帰的に変更します。

  • sammy:www-data —これにより、所有者が非rootユーザー(sammy)として設定され、グループがwww-dataとして保持されるため、Apacheはファイルにアクセスしてファイルを提供できます。

  • /var/www/wordpress —これはWordPressディレクトリへのパスを指定します。 これは、所有権が変更されるディレクトリです。

このコマンドが成功したことを確認するには、WordPressディレクトリの内容をリストします。

ls -la /var/www/wordpress

ディレクトリの内容のリストが表示されます。

Outputtotal 216
drwxr-x---  5 sammy www-data  4096 Apr 13 15:42 .
drwxr-xr-x  4 root  root      4096 Apr 13 15:39 ..
-rw-r-----  1 sammy www-data   235 Apr 13 15:54 .htaccess
-rw-r-----  1 sammy www-data   420 Nov 30  2017 index.php
-rw-r-----  1 sammy www-data 19935 Jan  1 20:37 license.txt
-rw-r-----  1 sammy www-data  7425 Jan  9 02:56 readme.html
-rw-r-----  1 sammy www-data  6919 Jan 12 06:41 wp-activate.php
drwxr-x---  9 sammy www-data  4096 Mar 13 00:18 wp-admin
-rw-r-----  1 sammy www-data   369 Nov 30  2017 wp-blog-header.php
-rw-r-----  1 sammy www-data  2283 Jan 21 01:34 wp-comments-post.php
-rw-r-----  1 sammy www-data  2898 Jan  8 04:30 wp-config-sample.php
-rw-r-----  1 sammy www-data  3214 Apr 13 15:42 wp-config.php
drwxr-x---  6 sammy www-data  4096 Apr 13 15:54 wp-content
-rw-r-----  1 sammy www-data  3847 Jan  9 08:37 wp-cron.php
drwxr-x--- 19 sammy www-data 12288 Mar 13 00:18 wp-includes
-rw-r-----  1 sammy www-data  2502 Jan 16 05:29 wp-links-opml.php
-rw-r-----  1 sammy www-data  3306 Nov 30  2017 wp-load.php
-rw-r-----  1 sammy www-data 38883 Jan 12 06:41 wp-login.php
-rw-r-----  1 sammy www-data  8403 Nov 30  2017 wp-mail.php
-rw-r-----  1 sammy www-data 17947 Jan 30 11:01 wp-settings.php
-rw-r-----  1 sammy www-data 31085 Jan 16 16:51 wp-signup.php
-rw-r-----  1 sammy www-data  4764 Nov 30  2017 wp-trackback.php
-rw-r-----  1 sammy www-data  3068 Aug 17  2018 xmlrpc.php

これらのファイルは、前提条件のHow To Install WordPress with LAMP on Ubuntu 18.04wordpress.orgからダウンロードしたlatest.tar.gzという名前のファイルのWordPressコアに含まれているファイルです。 上記の出力のように権限が表示される場合、これはファイルとディレクトリが正しく更新されていることを意味します。

このステップでは、WordPressのインストールを更新して、自分でファイルを編集できるようにしました。 次のステップでは、そのアクセスを使用して、WordPressプラグインを構成するファイルを作成します。

[[step-2 -—- creating-a-basic-wordpress-plugin]] ==ステップ2—基本的なWordPressプラグインの作成

WordPressディレクトリ内のファイルを変更するためのアクセス権があるので、基本的なWordPressプラグインを作成し、インストールに追加します。 これにより、Reactはチュートリアルの後半でWordPressと対話できるようになります。

WordPressプラグインは次のように簡単にできます:

  1. wp-content/plugins内のディレクトリ。

  2. そのディレクトリ内にある同じ名前で.phpのファイル拡張子を持つファイル。

  3. WordPressに重要なプラグインメタデータを提供する、そのファイルの上部にある特別なコメント。

後で記述するReactコードのプラグインを作成するには、まずWordPressプラグインのディレクトリを作成します。 簡単にするために、このチュートリアルではプラグインにreact-wordpressという名前を付けます。 次のコマンドを実行し、wordpressをApacheドキュメントルートに置き換えます。

mkdir /var/www/wordpress/wp-content/plugins/react-wordpress

次に、新しく作成したディレクトリに移動します。 後続のコマンドはここから実行されます。

cd /var/www/wordpress/wp-content/plugins/react-wordpress

今すぐプラグインファイルを作成しましょう。 このチュートリアルでは、コマンドnanoで呼び出されるnanoを、すべてのファイルのコマンドラインテキストエディターとして使用します。 PicoVimEmacsなど、他の任意のテキストエディタを自由に使用することもできます。

編集のためにreact-wordpress.phpを開きます。

nano react-wordpress.php

ファイルに次の行を追加して、プラグインの開始を作成します。

/var/www/wordpress/wp-content/plugins/react-wordpress/react-wordpress.php

上部のコメント付きセクションはプラグインのメタデータを提供し、ABSPATH定数をチェックする行は、悪意のあるアクターがURLによってこのスクリプトに直接アクセスするのを防ぎます。 ABSPATHはWordPressルートディレクトリへの絶対パスであるため、ABSPATHが定義されている場合は、ファイルがWordPress環境を介してロードされたことを確認できます。

[.note]#Note:プラグインのメタデータコメントには多くのフィールドを使用できますが、必要なのはPlugin Nameのみです。 詳細については、WordPressドキュメントのHeader Requirementsページを参照してください。

次に、Webブラウザーを開き、ドメインのPluginsページ(https://your_domain/wp-admin/plugins.php)に移動します。 WordPressのデフォルトプラグインとともにプラグインがリストされます:

WP Admin Plugins Page

プラグインを有効にするには、Activateをクリックします。

プラグインをアクティブ化すると、プラグインを含む行が青色で強調表示され、左側に青い境界線が表示されます。その下にあるActivateというリンクの代わりに、Deactivateというリンクが表示されます。 )s:

WP Admin Plugins Page After Plugin Activation

次に、プラグインの構造を確立します。

ターミナルに戻ってreact-wordpress.phpを開きます。

nano react-wordpress.php

次に、これを更新して、有用な定数を定義する次の強調表示された行を追加します。

/var/www/wordpress/wp-content/plugins/react-wordpress/react-wordpress.php

新しく追加された行で、3つの定数を定義しました。

  1. ERW_WIDGET_PATH —これはReactアプリケーションへのパスになります。

  2. ERW_ASSET_MANIFEST —これはReactアセットマニフェストへのパスです。これは、アプリケーションが機能するためにページに含める必要のあるJavaScriptファイルとCSSファイルのリストを含むファイルです。

  3. ERW_INCLUDES —このサブディレクトリには、すべてのPHPファイルが含まれます。

define()plugin_dir_path( __FILE__ )を参照することに注意してください。 これは、そのファイルへのディレクトリパスを表します。

定数定義を追加したら、ファイルを保存してエディターを終了します。

[.note]#Note:定数をnamespaceにすることが重要です。 この場合、Embedding React in WordPressを表す名前空間ERW_を使用しています。 この名前空間の前に変数を付けると、他のプラグインで定義されている定数と競合しないように、変数が一意になります。

他のPHPファイルを含むincludes/フォルダーを作成するには、プラグインディレクトリのトップレベルである/var/www/your_domain/wp-content/plugins/react-wordpressから始めます。 次に、フォルダーを作成します。

mkdir includes

WordPressプラグインを作成するために必要なPHP関連のファイルとフォルダーを作成したので、Reactの初期ファイルとフォルダーを作成します。

[[step-3 -—- initializing-the-react-application]] ==ステップ3—Reactアプリケーションを初期化する

このステップでは、Create React Appを使用してReactアプリケーションを初期化します。

このチュートリアルは、Create React Appバージョン3.0.1を使用してテストされました。 バージョン3.0.0は、asset-manifest.jsonの構造に重大な変更を加えたため、この以前のバージョンは、変更を加えないとこのチュートリアルと互換性がありません。 ここで想定されているバージョンを使用していることを確認するには、次のコマンドを実行してCreate React Appをインストールします。

sudo npm install --global [email protected]

このコマンドは、Create React Appのバージョン3.0.1をインストールします。 --globalフラグは、システム全体にインストールします。 システム全体にインストールすると、パスを指定せずにcreate-react-app(またはnpx create-react-app)を実行すると、インストールしたばかりのバージョンが使用されます。

Create React Appをインストールしたら、それを使用してReactアプリケーションを作成します。 このチュートリアルでは、アプリにwidgetという名前を付けます。

sudo create-react-app widget

このコマンドは、NPMに付属するバイナリであるnpxを使用します。 NPMでホストされているCLIツールおよびその他の実行可能ファイルを簡単に使用できるように設計されています。 ローカルに見つからない場合、これらのツールがインストールされます。

create-react-appコマンドは、プロジェクトフォルダーと基本的なReactアプリに必要なすべてのファイルを生成します。 これには、index.htmlファイル、JavaScript、CSS、およびテストファイルの開始、およびプロジェクトと依存関係を定義するためのpackage.jsonが含まれます。 追加のビルドツールをインストールして構成する必要なく、実稼働用にアプリケーションをビルドできる依存関係とスクリプトが事前に含まれています。

widgetアプリを設定すると、ターミナルの出力は次のようになります。

Output...
Success! Created widget at /var/www/wordpress/wp-content/plugins/react-wordpress/widget
Inside that directory, you can run several commands:

  npm start
    Starts the development server.

  npm run build
    Bundles the app into static files for production.

  npm test
    Starts the test runner.

  npm run eject
    Removes this tool and copies build dependencies, configuration files
    and scripts into the app directory. If you do this, you can’t go back!

We suggest that you begin by typing:

  cd widget
  npm start

Happy hacking!

次に、新しく作成されたディレクトリに移動します。

cd widget

これで、default build commandnpm run buildを使用してアプリケーションを構築できるようになります。 このbuildコマンドは、buildという名前のスクリプトのキーscriptsの下にあるファイルpackage.jsonを調べます。

/var/www/wordpress/wp-content/plugins/react-wordpress/widget/package.json

{
  "name": "widget",
  "version": "0.1.0",
  "private": true,
  "dependencies": {
    "react": "^16.9.0",
    "react-dom": "^16.9.0",
    "react-scripts": "3.1.1"
  },
  "scripts": {
    "start": "react-scripts start",
    "build": "react-scripts build",
    "test": "react-scripts test",
    "eject": "react-scripts eject"
  },
  "eslintConfig": {
    "extends": "react-app"
  },
  "browserslist": {
    "production": [
      ">0.2%",
      "not dead",
      "not op_mini all"
    ],
    "development": [
      "last 1 chrome version",
      "last 1 firefox version",
      "last 1 safari version"
    ]
  }
}

これにより、create-react-appによって提供されるコアコンポーネントの1つであるreact-scriptsノードモジュールによって提供されるreact-scripts.js実行可能ファイルが呼び出されます。 これにより、ビルドスクリプトが呼び出され、webpackを使用して、プロジェクトファイルがブラウザが理解できる静的アセットファイルにコンパイルされます。 これを行うには:

  • 依存関係の解決。

  • SASSファイルをCSSおよびJSXにコンパイルするか、TypeScriptをJavaScriptにコンパイルします。

  • ES6構文をES5構文に変換し、ブラウザー間の互換性を向上させます。

buildについて少し知ったので、ターミナルで次のコマンドを実行します。

sudo npm run build

コマンドが完了すると、次のような出力が表示されます。

Output> [email protected] build /var/www/wordpress/wp-content/plugins/react-wordpress/widget
> react-scripts build

Creating an optimized production build...
Compiled successfully.

File sizes after gzip:

  36.83 KB (+43 B)  build/static/js/2.6efc73d3.chunk.js
  762 B (+44 B)     build/static/js/runtime~main.a8a9905a.js
  710 B (+38 B)     build/static/js/main.2d1d08c1.chunk.js
  539 B (+44 B)     build/static/css/main.30ddb8d4.chunk.css

The project was built assuming it is hosted at the server root.
You can control this with the homepage field in your package.json.
For example, add this to build it for GitHub Pages:

  "homepage" : "http://myname.github.io/myapp",

The build folder is ready to be deployed.
You may serve it with a static server:

  npm install -g serve
  serve -s build

Find out more about deployment here:

  https://bit.ly/CRA-deploy

これでプロジェクトがビルドされましたが、次のステップに進む前に、アプリケーションが存在する場合にのみロードするようにすることをお勧めします。

Reactは、アプリケーションをレンダリングするDOM内のHTML要素を使用します。 これはtarget要素と呼ばれます。 デフォルトでは、この要素のIDはrootです。 このrootノードが作成中のアプリであることを確認するには、src/index.jsを変更して、名前空間付きerw-roottargetのIDを確認します。 これを行うには、最初にsrc/index.jsを開きます。

sudo nano src/index.js

強調表示された行を変更して追加します。

/var/www/wordpress/wp-content/plugins/react-wordpress/widget/src/index.js

import React from 'react';
import ReactDOM from 'react-dom';
import './index.css';
import App from './App';
import * as serviceWorker from './serviceWorker';

const target = document.getElementById('erw-root');
if (target) { ReactDOM.render(, target); }

serviceWorker.unregister();

最後に、編集が完了したらファイルを保存して終了します。

このファイルでは、デフォルトのindex.jsファイルに2つの重要な変更を加えました。

  1. ターゲット要素を<div id="root"></div>から<div id="erw-root"></div>に変更したため、アプリケーションの名前空間になります。

  2. ReactDOM.render()への呼び出しをif (...)ステートメントで囲み、アプリが存在する場合にのみロードされるようにしました。

[.note]#Note:ウィジェットがすべてのページに存在することを期待する場合は、エラー処理の行を追加することもできます。これにより、IDerw-rootの要素があればコンソールにメッセージが出力されます。 sが見つかりません。 ただし、このチュートリアルではこの手順を省略します。 このような行は、要素を含める予定のないページを含め、要素がないすべてのページでコンソールエラーを生成します。 これらの複数のJavaScriptコンソールエラーは、サイトの検索エンジンのランキングを下げるリスクを負う可能性があります。

src/ディレクトリ内のJavaScriptまたはCSSファイルを変更した後、変更が組み込まれるようにアプリを再コンパイルすることが重要です。 アプリを再構築するには、次を実行します。

sudo npm run build

これで、build/ディレクトリにJavaScriptファイルとCSSファイルの形式で動作するReactアプリケーションが含まれます。 次のステップでは、ページのJavaScriptとCSSをキューに入れるPHPファイルを設定します。

[[step-4 -—- enqueueing-the-javascript-and-css-files]] ==ステップ4—JavaScriptファイルとCSSファイルをエンキューする

このステップでは、WordPressのアクションとフィルターを使用して次のことを行います。

  1. WordPressページのロードサイクルの適切な時点で、スクリプトエンキューコードを出力します。

  2. Enqueue your JavaScript and CSS filesは、ページの読み込み速度への影響が最も少ない方法です。

WordPressはプライマリフックとしてactions and filtersを使用します。 アクションを使用すると、ページの読み込みサイクルの指定された時間にコードを実行でき、フィルターは、他の方法では所有していない関数の戻り値を変更することで特定の動作を変更します。

これらのフックを使用するには、アセットマニフェストを解析するコードを含むPHPファイルを作成します。 これは、後ですべてのアセットをキューに入れるために使用するのと同じファイルであるため、スクリプトは<head>タグに書き込まれます。

ファイルを作成する前に、次のコマンドを使用して、Reactアプリを含むディレクトリから、最上位のreact-wordpressプラグインディレクトリに移動します。

cd /var/www/wordpress/wp-content/plugins/react-wordpress

includes/フォルダー内にenqueue.phpファイルを作成します。

nano includes/enqueue.php

ファイルの先頭に開始<?phpタグを配置することから始めます。 また、ABSPATHをチェックする行を追加します。これは、前に説明したように、すべてのPHPファイルのベストプラクティスです。

/var/www/wordpress/wp-content/plugins/react-wordpress/includes/enqueue.php

このファイルを保存して終了します。

次に、react-wordpress.phpを更新して、プロジェクトからenqueue.phpを要求します。 まず、編集用にファイルを開きます。

nano react-wordpress.php

次の強調表示された行を追加します。

/var/www/wordpress/wp-content/plugins/react-wordpress/react-wordpress.php

重要なタスクをチャンクに分割するために、includes/ディレクトリから他のPHPファイルを要求することはWordPressプラグインの一般的なパターンです。 require_once()関数は、引数として渡されたファイルの内容を、そのファイルのPHPコードがインラインで記述されているかのように解析します。 同様のコマンドincludeとは異なり、requireは、要求しようとしているファイルが見つからない場合に例外を発生させます。 (require()だけではなく)require_once()を使用すると、ディレクティブrequire_once( ERW_INCLUDES . '/enqueue.php' );が複数回指定された場合に、enqueue.phpが複数回解析されないことが保証されます。

ファイルを保存して終了します。

ここで、includes/enqueue.phpを再度開きます。

nano includes/enqueue.php

次に、強調表示された次のコードを追加します。

/var/www/wordpress/wp-content/plugins/react-wordpress/includes/enqueue.php

initアクションに関数を追加すると、このコードは、テーマや他のプラグインがロードされた後の、ロードプロセスのinitフェーズで実行されます。

script_loader_tagフィルターを使用して<script>タグにasyncおよびdefer属性を設定すると、DOMの構築とページのレンダリングをブロックする代わりに、スクリプトを非同期でロードするようにブラウザーに指示します。

次に、wp_enqueue_scriptsアクションはフロントエンドアイテムをキューに入れます。 詳細については、this pageを参照してください。

必ずファイルを書き込んで終了してください。

これで、WordPressにスクリプトおよびスタイルシートタグをページに書き込むように指示しました。 この次のステップでは、アセットマニフェストと呼ばれるファイルを解析します。 これにより、キューに入れる必要があるすべてのファイルへのパスが得られます。

[[step-5 --- parsing-the-asset-manifest]] ==ステップ5—アセットマニフェストの解析

このステップでは、Reactビルドによって生成されたアセットマニフェストを解析して、JavaScriptファイルとCSSファイルのリストを作成します。

アプリケーションをビルドすると、Reactビルドスクリプトはプロジェクトを複数のJavaScriptおよびCSSファイルにビルドします。 各ファイルにはファイルのコンテンツのハッシュが含まれるため、ファイルの量と名前はビルドごとに異なります。 アセットマニフェストは、最後のビルドで生成された各ファイルの名前とそのファイルへのパスを提供します。 プログラムで解析することにより、ページに書き込むスクリプトとスタイルシートのタグは、名前が変わっても常に正しいファイルを指すことが保証されます。

まず、catコマンドを使用してasset-manifest.jsonを調べます。

cat widget/build/asset-manifest.json

これは次のようになります。

Output{
  "files": {
    "main.css": "/static/css/main.2cce8147.chunk.css",
    "main.js": "/static/js/main.a284ff71.chunk.js",
    "main.js.map": "/static/js/main.a284ff71.chunk.js.map",
    "runtime~main.js": "/static/js/runtime~main.fa565546.js",
    "runtime~main.js.map": "/static/js/runtime~main.fa565546.js.map",
    "static/js/2.9ca06fd6.chunk.js": "/static/js/2.9ca06fd6.chunk.js",
    "static/js/2.9ca06fd6.chunk.js.map": "/static/js/2.9ca06fd6.chunk.js.map",
    "index.html": "/index.html",
    "precache-manifest.e40c3c7a647ca45e36eb20f8e1a654ee.js": "/precache-manifest.e40c3c7a647ca45e36eb20f8e1a654ee.js",
    "service-worker.js": "/service-worker.js",
    "static/css/main.2cce8147.chunk.css.map": "/static/css/main.2cce8147.chunk.css.map",
    "static/media/logo.svg": "/static/media/logo.5d5d9eef.svg"
  }
}

それを解析するために、コードは.js.cssで終わるオブジェクトキーを探します。

enqueue.phpファイルを開きます。

nano includes/enqueue.php

ハイライトされたスニペットを追加します。

/var/www/wordpress/wp-content/plugins/react-wordpress/includes/enqueue.php

 $value ) {
      if ( preg_match( '@static/js/(.*)\.chunk\.js@', $key, $matches ) ) {
        if ( $matches && is_array( $matches ) && count( $matches ) === 2 ) {
          $name = "erw-" . preg_replace( '/[^A-Za-z0-9_]/', '-', $matches[1] );
          wp_enqueue_script( $name, get_site_url() . $value, array( 'erw-main' ), null, true );
        }
      }

      if ( preg_match( '@static/css/(.*)\.chunk\.css@', $key, $matches ) ) {
        if ( $matches && is_array( $matches ) && count( $matches ) == 2 ) {
          $name = "erw-" . preg_replace( '/[^A-Za-z0-9_]/', '-', $matches[1] );
          wp_enqueue_style( $name, get_site_url() . $value, array( 'erw' ), null );
        }
      }
    }

  });
});

完了したら、ファイルを作成して終了します。

強調表示されたコードは次のことを行います。

  1. 資産マニフェストファイルを読み取り、JSONファイルとして解析します。 キー'files'に格納されているコンテンツにアクセスし、それを$asset_manifest変数に格納します。

  2. メインCSSファイルが存在する場合、キューに入れます。

  3. 最初にReactランタイムをエンキューし、次にメインJavaScriptファイルをエンキューし、ランタイムを依存関係として設定して、最初にページにロードされるようにします。

  4. static/js/<hash>.chunk.jsという名前のJavaScriptファイルのアセットマニフェストファイルリストを解析し、メインファイルの後のページにエンキューします。

  5. static/css/<hash>.chunk.cssという名前のCSSファイルのアセットマニフェストファイルリストを解析し、メインのCSSファイルの後にページにエンキューします。

[.note]#Note:wp_enqueue_script()およびwp_enqueue_styleを使用すると、エンキューされたファイルの<script>および<link>タグがすべてのページに表示されます。 最後の引数trueは、ファイルを<head>要素の下部ではなく、ページコンテンツフッターの下に配置するようにWordPressに指示します。 これは、JavaScriptファイルの読み込みによってページの残りの部分が遅くならないようにするために重要です。

このステップでは、アプリで使用されるスクリプトとスタイルのファイルパスを分離しました。 次のステップでは、これらのファイルパスがReactアプリのbuildディレクトリを指していること、およびブラウザからソースファイルにアクセスできないことを確認します。

[[step-6 -—- serving-and-securing-static-files]] ==ステップ6—静的ファイルの提供と保護

この時点で、WordPressにロードするJavaScriptファイルとCSSファイルとそれらの場所を指定しました。 ただし、ブラウザでhttps://your_domainにアクセスしてJavaScriptコンソールを見ると、HTTP404エラーが表示されます。 (JavaScriptコンソールの使用方法の詳細については、this articleを確認してください。)

404 Errors in the JavaScript Console

これは、ファイルへのURLルート(例:/static/js/main.2d1d08c1.chunk.js)がファイルへの実際のパス(例:/wp-content/plugins/react-wordpress/widget/build/static/js/main.2d1d08c1.chunk.js)と一致しないためです。

このステップでは、Reactにビルドディレクトリの場所を伝えることにより、この問題を修正します。 また、.htaccessファイルにApache書き換えルールを追加して、ソースファイルがブラウザーに表示されないように保護します。

Reactにアプリへの正しいパスを与えるには、Reactアプリケーションのディレクトリ内でpackage.jsonを開きます。

sudo nano widget/package.json

次に、強調表示されたhomepage行を追加します。

/var/www/wordpress/wp-content/plugins/react-wordpress/widget/package.json

{
  "name": "widget",
  "version": "0.1.0",
  "private": true,
  "homepage": "/wp-content/plugins/react-wordpress/widget/build",
  "dependencies": {
    "react": "^16.9.0",
    "react-dom": "^16.9.0",
    "react-scripts": "3.1.1"
  },
  "scripts": {
    "start": "react-scripts start",
    "build": "react-scripts build",
    "test": "react-scripts test",
    "eject": "react-scripts eject"
  },
  "eslintConfig": {
    "extends": "react-app"
  },
  "browserslist": {
    "production": [
      ">0.2%",
      "not dead",
      "not op_mini all"
    ],
    "development": [
      "last 1 chrome version",
      "last 1 firefox version",
      "last 1 safari version"
    ]
  }
}

ファイルを書き込んで終了します。 次に、Reactアプリケーションを再構築します。 widget/のトップレベルに移動します。

cd widget

次に、buildコマンドを実行します。

sudo npm run build

ビルドコマンドが完了したら、コンテンツをターミナルに出力してアセットマニフェストを検査します。

cat build/asset-manifest.json

ファイルパスがすべて変更されていることがわかります。

/var/www/wordpress/wp-content/plugins/react-wordpress/widget/build/asset-manifest.json

{
  "files": {
    "main.css": "/wp-content/plugins/react-wordpress/widget/build/static/css/main.2cce8147.chunk.css",
    "main.js": "/wp-content/plugins/react-wordpress/widget/build/static/js/main.a28d856a.chunk.js",
    "main.js.map": "/wp-content/plugins/react-wordpress/widget/build/static/js/main.a28d856a.chunk.js.map",
    "runtime~main.js": "/wp-content/plugins/react-wordpress/widget/build/static/js/runtime~main.2df87c4b.js",
    "runtime~main.js.map": "/wp-content/plugins/react-wordpress/widget/build/static/js/runtime~main.2df87c4b.js.map",
    "static/js/2.9ca06fd6.chunk.js": "/wp-content/plugins/react-wordpress/widget/build/static/js/2.9ca06fd6.chunk.js",
    "static/js/2.9ca06fd6.chunk.js.map": "/wp-content/plugins/react-wordpress/widget/build/static/js/2.9ca06fd6.chunk.js.map",
    "index.html": "/wp-content/plugins/react-wordpress/widget/build/index.html",
    "precache-manifest.233e0a9875cf4d2df27d6280d12b780d.js": "/wp-content/plugins/react-wordpress/widget/build/precache-manifest.233e0a9875cf4d2df27d6280d12b780d.js",
    "service-worker.js": "/wp-content/plugins/react-wordpress/widget/build/service-worker.js",
    "static/css/main.2cce8147.chunk.css.map": "/wp-content/plugins/react-wordpress/widget/build/static/css/main.2cce8147.chunk.css.map",
    "static/media/logo.svg": "/wp-content/plugins/react-wordpress/widget/build/static/media/logo.5d5d9eef.svg"
  }
}

これにより、正しいファイルの場所がアプリに通知されますが、問題も発生します。アプリのsrcディレクトリへのパスが公開され、create-react-appに精通している人がhttps://your_domain/wp-content/plugins/react-wordpress/widget/src/index.jsにアクセスしてアプリのソースファイルの調査を開始します。 自分で試してみてください!

ユーザーにアクセスさせたくないパスを保護するには、WordPressの.htaccessファイルにApache書き換えルールを追加します。

nano /var/www/wordpress/.htaccess

4つの強調表示された行を追加します。

/var/www/wordpress/.htaccess


RewriteRule ^wp-content/plugins/react-wordpress/widget/(build|public)/(.*) - [L]
RewriteRule ^wp-content/plugins/react-wordpress/widget/* totally-bogus-erw.php [L]


# BEGIN WordPress

RewriteEngine On
RewriteBase /
RewriteRule ^index\.php$ - [L]
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteRule . /index.php [L]


# END WordPress

これは、wp-content/plugins/react-wordpress/widget/build/またはwp-content/react-wordpress/widget/public/のすべてへのブラウザー要求を許可するようにApacheに指示します。 それ以外はtotally-bogus-erw.phpにリダイレクトされます。 トップレベルにtotally-bogus-erw.phpという名前のファイルがない限り、このリクエストはWordPressによって処理され、404エラーが発生します。

リクエストアクティビティを監視し、404をログに記録するStreamなどのWordPressプラグインがあります。 ログには、ユーザーが404を受け取ったときにリクエストされたIPアドレスとページがリクエストに表示されます。 totally-bogus-erw.phpを監視すると、特定のIPアドレスがReactアプリのsrcディレクトリをクロールしようとしているかどうかがわかります。

必ずファイルを書き込んで終了してください。

JavaScriptファイルとCSSファイルをページに読み込むために必要なルーティングを確立したので、JavaScriptが対話してアプリをレンダリングするHTML要素をページに追加するショートコードを使用します。

[[ステップ-7 ---ショートコードの作成]] ==ステップ7—ショートコードの作成

ショートコードを使用すると、非常にシンプルなページ内構文で、サーバー側のデータで補間された複雑なHTMLブロックを挿入できます。 このステップでは、WordPressショートコードを作成して登録し、それを使用してアプリケーションをページに埋め込みます。

プラグインのトップレベルに移動します。

cd /var/www/wordpress/wp-content/plugins/react-wordpress/

ショートコードを含む新しいPHPファイルを作成します。

touch includes/shortcode.php

次に、プラグインのロード時にincludes/shortcode.phpが必要になるように、メインのPHPファイルを編集します。 最初に開くreact-wordpress.php

nano react-wordpress.php

次に、強調表示された次の行を追加します。

/var/www/wordpress/wp-content/plugins/react-wordpress/react-wordpress.php

ファイルを書き込んで終了します。

次に、新しく作成したショートコードファイルを開きます。

nano includes/shortcode.php

次のコードを追加してください。

/var/www/wordpress/wp-content/plugins/react-wordpress/includes/shortcode.php

"; });

このコードには大部分が定型文が含まれています。 erw_widgetという名前のショートコードを登録します。このショートコードは、呼び出されると、Reactアプリのルート要素である<div id="erw-root"></div>をページに出力します。

shortcode.phpを保存して終了します。

Reactアプリの動作を確認するには、新しいWordPressページを作成し、ショートコードを追加する必要があります。

Webブラウザでhttps://your_domain/wp-adminに移動します。 ページの最上部に、左側にWordPressのロゴが付いた黒いバーが表示され、その後に家のアイコン、サイトの名前、コメントのバブルアイコンと番号、および+ New+ Newボタンにカーソルを合わせると、メニューがドロップダウンします。 Pageというメニュー項目をクリックします。

Create a Page

画面が読み込まれると、カーソルはAdd titleというテキストボックスにフォーカスされます。 そこをクリックして入力を開始すると、新しいページに関連するタイトルが付けられます。 このチュートリアルでは、My React Appを使用します。

Giving the Page a Title

WordPress Gutenberg editorを使用しているとすると、ページ上部のタイトルの下に、Start writing or type / to choose a blockというテキスト行が表示されます。 そのテキストにカーソルを合わせると、右側に3つのシンボルが表示されます。 [/]に似ている最も近いものを選択して、ショートコードブロックを追加します。

Adding a Shortcode Block

新しく追加されたテキスト領域にショートコード[erw_widget]を入力します。 次に、ウィンドウの右上隅にある青いPublish…ボタンをクリックし、Publishを押して確認します。

Type in Your Shortcode and Publish

ページが公開されたことを確認する緑色のバーが表示されます。 View Pageリンクをクリックします。

Click Link to View Page

画面にアプリが表示されます:

Working React App

ページに基本的なReactアプリのレンダリングができたので、管理者がサーバー側で提供するオプションでそのアプリをカスタマイズできます。

[[step-8 -—- injecting-server-generated-settings]] ==ステップ8—サーバーで生成された設定の挿入

このステップでは、サーバー生成データとユーザー提供データの両方を使用して、アプリケーションに設定を注入します。 これにより、アプリケーションで動的データを表示し、ページ内でウィジェットを複数回使用できるようになります。

まず、index.jsファイルを開きます。

sudo nano widget/src/index.js

次に、import App from './App';行を削除し、次の強調表示された行でindex.jsの内容を更新します。

/var/www/wordpress/wp-content/plugins/react-wordpress/widget/src/index.js

import React from 'react';
import ReactDOM from 'react-dom';
import './index.css';
import * as serviceWorker from './serviceWorker';

const App = () => (
  
Hello,
World!
); const target = document.getElementById('erw-root'); if (target) { ReactDOM.render(, target); } serviceWorker.unregister();

これにより、Reactアプリケーションが変更され、デフォルトのCreate React App画面が返される代わりに、Hello, World!を読み取る要素が返されます。

ファイルを保存して終了します。 次に、編集のためにindex.cssを開きます。

nano widget/src/index.css

index.cssの内容を次のコードに置き換えます。

/var/www/wordpress/wp-content/plugins/react-wordpress/widget/src/index.css

.App {
  width: 100px;
  height: 100px;
  border: 1px solid;
  display: inline-block;
  margin-right: 20px;
  position: relative;
}

.App .App__Message {
  font-size: 15px;
  line-height: 15px;
  position: absolute;
  top: 50%;
  transform: translateY(-50%);
  text-align: center;
  width: 100%;
}

.Appのスタイルは、実線の境界線を持つ100ピクセルの正方形をレンダリングし、.App__Messageのスタイルは、垂直方向と水平方向の両方で、正方形の中央にあるテキストをレンダリングします。

ファイルを書き込んで終了し、アプリケーションを再構築します。

cd widget
sudo npm run build

ビルドが成功したら、ブラウザでhttps://your_domain/index.php/my-react-app/を更新します。 これで、CSSでスタイルを設定したボックスとテキストHello, World!が表示されます。

Simplified React Application

次に、ユーザーが指定した境界線の色とサイズで構成されるカスタム設定を追加します。 また、サーバーから現在のユーザーの表示名を渡します。

引数を受け入れるためのショートコードの更新

ユーザーが指定した引数を渡すには、まずユーザーに引数を渡す方法を提供する必要があります。 ターミナルに戻り、プラグインのトップレベルに戻ります。

cd ..

次に、編集のためにshortcode.phpファイルを開きます。

nano includes/shortcode.php

以下の強調表示された行を含むようにショートコードファイルを更新します。

/var/www/wordpress/wp-content/plugins/react-wordpress/includes/shortcode.php

 'black' );
  $args = shortcode_atts( $default_atts, $atts );

  return "
"; });

ファイルを書き込んで終了します。 コードが'color' => 'black'$default_atts配列に追加する方法に注目してください。 配列キーcolorは、color属性が[erw_widget]ショートコードに渡される可能性があることを期待するようにWordPressに指示します。 配列値blackは、デフォルト値を設定します。 すべてのショートコード属性は文字列としてショートコード関数に渡されるため、デフォルト値を設定したくない場合は、代わりに空の文字列('')を使用できます。 ページ内に複数の要素があることが予想されるため、最後の行はIDではなくクラスを使用するように変更されます。

次に、ブラウザに戻り、Hello, World!ボックスの下にあるEditボタンをクリックします。 ブラウザのWordPressページを更新して、ショートコードの2番目のインスタンスを追加し、両方のインスタンスに色属性を追加します。 このチュートリアルでは、[erw_widget color="#cf6f1a"][erw_widget color="#11757e"]を使用します。

Add a Second Widget

青いUpdateボタンをクリックして保存します。

[.note]#Note:2番目のウィジェットはまだ表示されません。 IDで識別される単一のインスタンスではなく、クラスで識別される複数のインスタンスを期待するようにReactアプリを更新する必要があります。

次に、編集のためにindex.jsを開きます。

sudo nano widget/src/index.js

以下で更新します。

/var/www/wordpress/wp-content/plugins/react-wordpress/widget/src/index.js

import React from 'react';
import ReactDOM from 'react-dom';
import './index.css';
import * as serviceWorker from './serviceWorker';

const App = () => (
  
Hello,
World!
); const targets = document.querySelectorAll('.erw-root'); Array.prototype.forEach.call(targets, target => ReactDOM.render(, target)); serviceWorker.unregister();

ファイルを書き込んで終了します。 更新された行は、クラスerw-rootの各インスタンスでReactアプリを呼び出します。 そのため、ショートコードを2回使用すると、ページに2つの正方形が表示されます。

最後に、編集のためにindex.cssを開きます。

sudo nano widget/src/index.css

次の強調表示された行を含むようにファイルを更新します。

/var/www/wordpress/wp-content/plugins/react-wordpress/widget/src/index.css

.erw-root { display: inline-block; }

.App {
  width: 100px;
  height: 100px;
  border: 1px solid;
  display: inline-block;
  margin-right: 20px;
  position: relative;
}

.App .App__Message {
  font-size: 15px;
  line-height: 15px;
  position: absolute;
  top: 50%;
  transform: translateY(-50%);
  text-align: center;
  width: 100%;
}

この追加された行により、隣接する複数のウィジェットが上下に並んで表示されます。

ファイルを保存して終了します。

次に、Reactアプリを再コンパイルします。

cd widget
sudo npm run build

ブラウザでページを更新すると、両方のウィジェットが表示されます:

Two Widgets

ウィジェットにはまだ境界線の色が表示されないことに注意してください。 これについては、今後のセクションで説明します。

各ウィジェットインスタンスを一意に識別する

各ウィジェットを一意に識別するために、サーバーからIDを渡す必要があります。 これは、ルート要素のdata-id属性を介して実行できます。 これは重要です。ページ上の各ウィジェットには異なる設定がある可能性があるためです。

これを行うには、最上位のプラグインディレクトリに戻り、shortcode.phpを開いて編集します。

cd ..
nano includes/shortcode.php

次の強調表示された行を持つように更新します。

/var/www/wordpress/wp-content/plugins/react-wordpress/includes/shortcode.php

 'black' );
  $args = shortcode_atts( $default_atts, $atts );
  $uniqid = uniqid('id');

  return "
"; });

最初の新しい行は、プレフィックスidを持つ一意のIDを生成します。 更新された行は、data-id属性を使用してIDをReactルートに添付します。 これにより、ReactでIDにアクセスできるようになります。

ファイルを保存しますが、まだ終了しないでください。

JavaScriptwindowオブジェクトに設定を書き込む

ショートコードファイルでは、ウィンドウグローバルJavaScriptオブジェクトのページに設定を書き込みます。 windowオブジェクトを使用すると、React内からアクセスできるようになります。

shortcode.phpを開いたまま、次のように更新します。

/var/www/wordpress/wp-content/plugins/react-wordpress/includes/shortcode.php

 'black' );
  $args = shortcode_atts( $default_atts, $atts );
  $uniqid = uniqid('id');

  global $current_user;
  $display_name = $current_user ? $current_user->display_name : 'World';

  ob_start(); ?>
  
  

これらの更新は、window-global settingsオブジェクトを初期化し、WP Adminで提供されるデータを入力する各要素の前に、<script>ブロックを書き込みます。

[.note]#Note:構文<?=<?php echo
の省略形です#

ファイルを保存して終了します。

これで、inspectはWebブラウザのWordPressページになります。 これにより、ページのHTMLが表示されます。 CTRL+Fを検索してwindow.erwSettingsを検索すると、ページのHTMLに次のように設定が書き込まれていることがわかります。

...
  window.erwSettings = window.erwSettings || {};
  window.erwSettings["id5d5f1958aa5ae"] = {
    'color': '#cf6f1a',
    'name': 'sammy',
  }
...

Reactから設定を取得する

Reactアプリでは、IDに基づいて設定を取得し、境界線の色の値をプロパティ(prop)としてAppコンポーネントに渡します。 これにより、Appコンポーネントは、値がどこから来たのかを知る必要なしに値を使用できます。

編集のためにindex.jsを開きます。

sudo nano widget/src/index.js

以下の強調表示された行が含まれるように更新します。

/var/www/wordpress/wp-content/plugins/react-wordpress/widget/src/index.js

import React from 'react';
import ReactDOM from 'react-dom';
import './index.css';
import * as serviceWorker from './serviceWorker';

const App = ({ settings }) => (
  
Hello,
{settings.name}!
); const targets = document.querySelectorAll('.erw-root'); Array.prototype.forEach.call(targets, target => { const id = target.dataset.id; const settings = window.erwSettings[id]; ReactDOM.render(, target) }); serviceWorker.unregister();

ファイルを保存して、テキストエディターを終了します。

これで、Reactアプリはwindow-globalwindow.erwSettingsオブジェクトからの一意のIDを使用して設定を取得し、それらをAppコンポーネントに渡します。 これを有効にするには、アプリケーションを再コンパイルします。

cd widget
sudo npm run build

この最後の手順を完了した後、ブラウザーでWordPressページを更新します。 ユーザーが提供する境界線の色とサーバーが提供する表示名がウィジェットに表示されます。

Widgets with Settings Applied

結論

このチュートリアルでは、内部にReactアプリケーションを含む独自のWordPressプラグインを作成しました。 次に、WP Adminページビルダー内にアプリケーションを埋め込み可能にするブリッジとしてショートコードを構築し、最終的にページ上のウィジェットをカスタマイズしました。

これで、配信メカニズムがすでに整っているという自信を持って、Reactアプリケーションを拡張できます。 WordPressのこの基盤により、クライアント側のエクスペリエンスに集中できるようになり、アプリケーションが拡大および成長するにつれて、WordPressのインストールで機能する本番指向のツールやテクニックを簡単に追加できます。

Reactの強固な基盤で何ができるかについてさらに読むには、次のチュートリアルのいずれかを試してください。

Related