2018年 12月 の投稿一覧

[WordPress] WP-Cronを本職のcronに任せる

wp-cron.phpへのリクエスト数が半端ない

WordPressは特定の時間になったら特定の処理を行うというタイマー的な機能を実装するにあたって、WP-CRONという仕組みを用意しています。これは通常WordPress上のいずれかのページへアクセスがあると、それと平行してwp-cron.phpへも同時にアクセスが発生し、その際に実行すべき処理があれば起動するというものです。つまりユーザーが1回アクセスすると必ず最低でも2回のアクセスが走ってしまう。

実際にアクセスログをざっくり集計すると、リクエストの27.5%程度がこのwp-cron.phpでした。

$ cat access_log | wc -l
82336
$ cat access_log | grep wp-cron.php | wc -l
22678

このブログはフロントにCDN(CloudFront)を置いているので、オリジンであるWordPressサーバには最小限のリクエストしか来ないのですが、拡張子に.phpが含まれる物はキャッシュ時間をゼロにして素通りさせている関係上、こいつだけはPV数分やってくるというわけです。そんなに上等なサーバ使ってないのでバズると死ぬw

というわけで、今回はwp-cron.phpへのアクセスを停止し、1分間に1回サーバ内部でWP-CRONを実行する設定をします。

続きを読む

はじめてのReact #11「フォームと連動する」プルダウン編

前回のテキストボックスに続き、今回はプルダウン(<select>)の操作方法になります。
ほぼ同じやり方で<ul>, <ol>などのリストにも適用できます。

メンバーリストComponent

メンバーの一覧をプルダウンとして表示し、名前をクリックすると削除されるComponentです。公式ドキュメントの「Lists and Keys」のサンプルコードを参考にしています。

サンプル

<!DOCTYPE html>
<html>
<head>
  <meta charset="UTF-8" />
  <title>MemberList</title>
  <script src="https://unpkg.com/react@16/umd/react.development.js"></script>
  <script src="https://unpkg.com/react-dom@16/umd/react-dom.development.js"></script>

  <!-- Don't use this in production: -->
  <script src="https://unpkg.com/babel-standalone@6.15.0/babel.min.js"></script>
</head>
<body>
  <div id="root"></div>

  <script type="text/babel">
   class MemberList extends React.Component {
     constructor(props) {
       super(props);
       this.state = {
          guys: props.guys
       };

       this.handleRemove = this.handleRemove.bind(this);
     }

     handleRemove(id){
       const guys = this.state.guys;
       const new_guys = [];

         for( let i=0; i<guys.length; i++ ){
           if(guys[i].id !== id){
             new_guys.push(guys[i]);
           }
       }

       this.setState({guys:new_guys});
     }

     render(){
       const guys = this.state.guys;
       const listItems = guys.map((guy) =>
         <option key={guy.id.toString()} onClick={ ()=>{ this.handleRemove(guy.id) } }>
           {guy.name}
         </option>
       );

       return <select size="3">{listItems}</select>;
     }
   }


    const guys = [
      {id:10, name:"Foo"},
      {id:20, name:"Bar"},
      {id:30, name:"Hoge"}
    ];

    ReactDOM.render(
      <MemberList guys={guys} />,
      document.getElementById('root')
    );
  </script>
</body>
</html>

続きを読む

はじめてのReact #10「フォームと連動する」テキストボックス編

10回目ともなるとだいぶReactで何かを作ることにも慣れてきましたねw 今回はいよいよフォームと関連した処理を書いてみたいと思います。Reactに限らずですがユーザーの入力とリアルタイムに連動して表示が切り替わるのは作っていて楽しいですよね。

入力候補を表示してくれるComponent

ユーザーが入力した文字に応じて、入力候補を自動的に表示してくれるComponentを作成します。今回も公式ドキュメントにあるサンプルコードを、編集して作成した物です。

サンプル

<!DOCTYPE html>
<html>
<head>
  <meta charset="UTF-8" />
  <title>AutoCompletionBox</title>
  <script src="https://unpkg.com/react@16/umd/react.development.js"></script>
  <script src="https://unpkg.com/react-dom@16/umd/react-dom.development.js"></script>

  <!-- Don't use this in production: -->
  <script src="https://unpkg.com/babel-standalone@6.15.0/babel.min.js"></script>
</head>
<body>
  <div id="root"></div>

  <script type="text/babel">
    class AutoCompletionBox extends React.Component {
      constructor(props) {
        super(props);
        this.INITIAL_WORD = '入力してください';

        this.state = {
          value: '',                 //ユーザーが入力した文字列が入る
          word: this.INITIAL_WORD    //自動補完用の文字列が入る
        };

        this.handleChange = this.handleChange.bind(this);
        this.handleSubmit = this.handleSubmit.bind(this);
      }

      handleChange(e) {
        let buff = e.target.value;            //入力された文字列
        let ac   = this.candidateData(buff);  //自動補完された文字列

        this.setState({value: buff, word: ac});
      }
      handleSubmit(e) {
        // 初期文言と自動補完用の文字が異なっていればStateを更新
        if( this.state.word !== this.INITIAL_WORD ){
          this.setState({value: this.state.word});
        }
        e.preventDefault();  //Submitイベントによる画面遷移をキャンセル
      }

      /**
       * 自動補完用の文字列を返却
       */
      candidateData(key){
        let i = key.slice(0,1).toLowerCase();  //先頭の1文字を取り出し小文字に
        let data = {
          a: 'Android',
          b: 'BlackBerryOS',
          f: 'FireFoxOS',
          i: 'iOS',
          t: 'Tizen',
          u: 'Ubuntu Touch',
          w: 'Windows 10 Mobile'
        };

        return( ( i in data )?  data[i]:this.INITIAL_WORD );
      }

      render() {
        return (
          <form onSubmit={this.handleSubmit}>
            <label>
              お使いのスマートフォンのOSは?<br />
              <input type="text" value={this.state.value} onChange={this.handleChange} /><br />
              <input type="submit" value={this.state.word} />
            </label>
          </form>
        );
      }
    }

    ReactDOM.render(
      <AutoCompletionBox />,
      document.getElementById('root')
    );
  </script>
</body>
</html>

続きを読む

はじめてのReact #9「状態に合わせてComponentを切り替える」

Componentの状態をthis.setState()で変化させる度にrender()が自動的に実行され最新の描画がされるのですが、Reactでは単純なHTMLだけではなくComponent自体を別の物に切り替えることができます。

今回はReactの公式ドキュメント「Conditional Rendering」を単純化したサンプルコードでお送りしします。

ログインComponent

よくあるログインとログアウトの管理用のComponentをイメージしたサンプルになっています。最初はログインしていない状態ですが、ボタンをクリックすることでログイン状態になります。再度ボタンをクリックすると最初の状態(ログアウト)に戻るというシンプルなものです。

サンプル

<!DOCTYPE html>
<html>
<head>
  <meta charset="UTF-8" />
  <title>LoginControl</title>
  <script src="https://unpkg.com/react@16/umd/react.development.js"></script>
  <script src="https://unpkg.com/react-dom@16/umd/react-dom.development.js"></script>

  <!-- Don't use this in production: -->
  <script src="https://unpkg.com/babel-standalone@6.15.0/babel.min.js"></script>
</head>
<body>
  <div id="root"></div>

  <script type="text/babel">
    class LoginControl extends React.Component {
      constructor(props) {
        super(props);

        this.handleLoginClick  = this.handleLoginClick.bind(this);
        this.handleLogoutClick = this.handleLogoutClick.bind(this);

        this.state = {
          isLoggedIn: false
        };
      }

      handleLoginClick() {
        this.setState({isLoggedIn: true});
      }
      handleLogoutClick() {
        this.setState({isLoggedIn: false});
      }

      render() {
        const isLoggedIn = this.state.isLoggedIn;
        let message;
        let button;

        if (isLoggedIn) {
          message = "ナイス、ログイン";
          button  = <LogoutButton onClick={this.handleLogoutClick} />;
        }
        else {
          message = "ログインしてください";
          button  = <LoginButton onClick={this.handleLoginClick} />;
        }

        return (
          <div>
            <h1>{message}</h1>
            {button}
          </div>
        );
      }
    }

    function LogoutButton(props) {
      return <button onClick={props.onClick}>ログアウト</button>;
    }

    function LoginButton(props) {
      return <button onClick={props.onClick}>ログイン</button>;
    }

    ReactDOM.render(
      <LoginControl />,
      document.getElementById('root')
    );
  </script>
</body>
</html>

続きを読む

はじめてのReact #8「イベント処理を試してみよう」

イベント処理は、タグ内にonClickなどのイベントハンドラ用の属性を指定することで定義できます。

これだけ聞くと正直気持ち悪いですよねw 結論から言うと最終的には問題ない形でレンダリングされます。実際のサンプルコードを元に話を進めていきましょう。

おみくじComponent

今回はボタンをクリックすると、運勢がアラートされる簡単な「おみくじ」を作成してみたいと思います。

サンプル

<!DOCTYPE html>
<html>
<head>
  <meta charset="UTF-8" />
  <title>おみくじ</title>
  <script src="https://unpkg.com/react@16/umd/react.development.js"></script>
  <script src="https://unpkg.com/react-dom@16/umd/react-dom.development.js"></script>

  <!-- Don't use this in production: -->
  <script src="https://unpkg.com/babel-standalone@6.15.0/babel.min.js"></script>
</head>
<body>
  <div id="root"></div>

  <script type="text/babel">
    class Omikuji extends React.Component {
      dropOmikuji(e){
        let unsei = ["大吉", "吉", "中吉", "小吉", "凶", "大凶"];
        let i = Math.ceil(Math.random() * 100) % unsei.length;

        alert(`あなたの運勢は${unsei[i]}です`);  // ``内に ${} で変数を埋め込めるのはES2015からの追加仕様
      }

      render() {
        return <button onClick={this.dropOmikuji}>おみくじを引く</button>;
      }
    }

    ReactDOM.render(
      <Omikuji />,
      document.getElementById('root')
    );
  </script>
</body>
</html>

続きを読む

はじめてのReact #7「Propsのデフォルト値を設定しよう」

Props未指定の場合のデフォルト値の設定を行う場合に、便利な機能が用意されています。前回行ったデータ型の定義と同様に、連想配列(ハッシュ)を書いてあげるだけで実現できます。

コンストラクタでやれば良くね?というツッコミもありそうですがw Props未指定時に固定値を入れるだけのシンプルなケースの場合はスッキリかけるので便利だったりします。あとは決められた箇所にまとまっているとメンテナンス性も上がりますしね。

指定日までの日数を表示するComponent その3

前回のソースコードに、Propsのデフォルト値を設定するコードを追加しました。今回もこの機能はReact本体には含まれていないためライブラリ「prop-types」を追加している点にも注意してください。

これまでは以下のようにmessage属性を指定していましたが、今回はわざとこれを外しています。

ReactDOM.render(
  <RemainTime date="2112-09-03 00:00:00" message="ドラえもん誕生" />,
  document.getElementById('root')
);

サンプル

<!DOCTYPE html>
<html>
<head>
  <meta charset="UTF-8" />
  <title>RemainTime</title>
  <script src="https://unpkg.com/react@16/umd/react.development.js"></script>
  <script src="https://unpkg.com/react-dom@16/umd/react-dom.development.js"></script>

  <!-- 型定義とデフォルト値設定のためライブラリを追加 -->
  <script src="https://unpkg.com/prop-types@15.6/prop-types.js"></script>

  <!-- Don't use this in production: -->
  <script src="https://unpkg.com/babel-standalone@6.15.0/babel.min.js"></script>
</head>
<body>
  <div id="root"></div>

  <script type="text/babel">
    class RemainTime extends React.Component {
      constructor(props) {
        super(props);
        this.state = {
          now: new Date().getTime(),
          target: new Date(props.date).getTime()
        };
      }

      render() {
        let remain = Math.floor( ( this.state.target - this.state.now ) / (1000 * 60 * 60 * 24) );
        return <h1>{this.props.message}まで約{remain}日</h1>;
      }
    }

    /**
     * Propsの型定義
     */
    RemainTime.propTypes = {
         date: PropTypes.string,
      message: PropTypes.string
    };

    /**
     * Propsのデフォルト値
     */
    RemainTime.defaultProps = {
      message: "Xデー"
    };

    ReactDOM.render(
      <RemainTime date="2112-09-03 00:00:00" />,
      document.getElementById('root')
    );
  </script>
</body>
</html>

続きを読む

はじめてのReact #6「Propsのデータ型をチェックしよう」

大規模なプロジェクトでは必須?

ComponentがどのようなPropsを欲しがっているか、プロジェクトの規模が大きくなればなるほど管理が大変になってきます。そこでReactではPropsのデータ型を定義できる機能を提供しています。

指定日までの日数を表示するComponent その2

前回のソースコードに、Propsの型を定義するコードを追加しました。また型定義の機能はReact本体には含まれていないため新しくライブラリ「prop-types」を追加している点にも注意してください。

ここではわざと型定義に反するようなPropsの渡し方をして、どのような挙動になるかを確認してみます。

サンプル

<!DOCTYPE html>
<html>
<head>
  <meta charset="UTF-8" />
  <title>RemainTime</title>
  <script src="https://unpkg.com/react@16/umd/react.development.js"></script>
  <script src="https://unpkg.com/react-dom@16/umd/react-dom.development.js"></script>

  <!-- 型定義を行うためのライブラリを追加 -->
  <script src="https://unpkg.com/prop-types@15.6/prop-types.js"></script>

  <!-- Don't use this in production: -->
  <script src="https://unpkg.com/babel-standalone@6.15.0/babel.min.js"></script>
</head>
<body>
  <div id="root"></div>

  <script type="text/babel">
    class RemainTime extends React.Component {
      constructor(props) {
        super(props);
        this.state = {
          now: new Date().getTime(),
          target: new Date(props.date).getTime()
        };
      }

      render() {
        let remain = Math.floor( ( this.state.target - this.state.now ) / (1000 * 60 * 60 * 24) );
        return <h1>{this.props.message}まで約{remain}日</h1>;
      }
    }

    /**
     * Propsの型定義
     */
    RemainTime.propTypes = {
         date: PropTypes.string,
      message: PropTypes.string
    };

    ReactDOM.render(
      //わざとmessageを文字列ではなく、配列として渡してみます
      <RemainTime date="2112-09-03 00:00:00" message={["ドラえもん誕生"]} />,
      document.getElementById('root')
    );
  </script>
</body>
</html>

続きを読む

はじめてのReact #5「Propsを使おう」

Componentに引数を渡せるProps

これまでのサンプルでは以下のように単にタグを書くことでComponentを実行していました。これだけでも十分なパワーを持っているのですが、より汎用的なComponentにすべきPropsと呼ばれる機能を使うと、Component内部に引数を渡すことができます。

ReactDOM.render(
  <Justnow />,
  document.getElementById('root')
);

指定日までの日数を表示するComponent

今回は指定した日付まで、残り何日か表示してくれるComponentを作成してみます。Props部分に集中したかったのでカウントダウン的な処理は端折りましたw

サンプル

<!DOCTYPE html>
<html>
<head>
  <meta charset="UTF-8" />
  <title>RemainTime</title>
  <script src="https://unpkg.com/react@16/umd/react.development.js"></script>
  <script src="https://unpkg.com/react-dom@16/umd/react-dom.development.js"></script>

  <!-- Don't use this in production: -->
  <script src="https://unpkg.com/babel-standalone@6.15.0/babel.min.js"></script>
</head>
<body>
  <div id="root"></div>

  <script type="text/babel">
    class RemainTime extends React.Component {
      constructor(props) {
        super(props);
        this.state = {
          now: new Date().getTime(),
          target: new Date(props.date).getTime()
        };
      }

      render() {
        let remain = Math.floor( ( this.state.target - this.state.now ) / (1000 * 60 * 60 * 24) );
        return <h1>{this.props.message}まで約{remain}日</h1>;
      }
    }

    ReactDOM.render(
      <RemainTime date="2112-09-03 00:00:00" message="ドラえもん誕生"/>,
      document.getElementById('root')
    );
  </script>
</body>
</html>

続きを読む

はじめてのReact #4「Lifecycleを活用してみる」

ComponentのLifecycle

ReactのComponentは生まれてから死ぬ(破棄される)までの間にたくさんのイベントが用意されており、それらのタイミングで特定のメソッドを実行してくれる機能を自由に使用することができます。

現在時間を表示するComponent その3

今回はReactの公式ドキュメントのソースを参考にしながら、前回まで作成してきたJustnowComponentを時間が経過するごとに表示も変更するようにしてみたいと思います。

サンプル

<!DOCTYPE html>
<html>
<head>
  <meta charset="UTF-8" />
  <title>Justnow3</title>
  <script src="https://unpkg.com/react@16/umd/react.development.js"></script>
  <script src="https://unpkg.com/react-dom@16/umd/react-dom.development.js"></script>

  <!-- Don't use this in production: -->
  <script src="https://unpkg.com/babel-standalone@6.15.0/babel.min.js"></script>
</head>
<body>
  <div id="root"></div>

  <script type="text/babel">
    class Justnow extends React.Component {
      constructor(props) {
        super(props);
        this.state = {
          now: new Date()
        };
      }

     /**
      * Lifecycle: ComponentがDOMツリーに加わった際の処理
      */
      componentDidMount() {
        this.timerID = setInterval(
          () => this.tick(),
          1000
        );
      }

     /**
      * Lifecycle: ComponentがDOMツリーから削除される際の処理
      */
      componentWillUnmount() {
        clearInterval(this.timerID);
      }

      tick() {
        this.setState({
          now: new Date()
        });
      }

      render() {
        let now = this.state.now;
        let now_date = [now.getFullYear(), now.getMonth()+1, now.getDate()].join('-');
        let now_time = [now.getHours(), now.getMinutes(), now.getSeconds()].join(':');

        return <h1>{now_date} {now_time}</h1>;
      }
    }

    ReactDOM.render(
      <Justnow />,
      document.getElementById('root')
    );
  </script>
</body>
</html>

以下のページにあるサンプルコードを参考にしています。

続きを読む

はじめてのReact #3「Stateを試してみる」

Component内部のデータ管理をどうするか

Reactの売りはデータに変更が発生すると、それに連動しrender()メソッドが実行されるところでもあります。勝手にデータが書き換わってくれる、しかも高速に! ところが前回作成したJustnow Componentではそういった動きになってくれません。

今回はまずはComponent内部でどのようにデータを持つべきかを試してみたいと思います。

現在時間を表示するComponent その2

Reactでは内部でデータを保持するためにstateというプロパティに値を格納します。
前回はrender()メソッド内に持っていたデータを、今回はstateに移し替えてみます。

サンプル

<!DOCTYPE html>
<html>
<head>
  <meta charset="UTF-8" />
  <title>Justnow2</title>
  <script src="https://unpkg.com/react@16/umd/react.development.js"></script>
  <script src="https://unpkg.com/react-dom@16/umd/react-dom.development.js"></script>

  <!-- Don't use this in production: -->
  <script src="https://unpkg.com/babel-standalone@6.15.0/babel.min.js"></script>
</head>
<body>
  <div id="root"></div>

  <script type="text/babel">
    class Justnow extends React.Component {
      constructor(props) {
        super(props);
        this.state = {
          now: new Date()
        };
      }

      render() {
        let now = this.state.now;
        let now_date = [now.getFullYear(), now.getMonth()+1, now.getDate()].join('-');
        let now_time = [now.getHours(), now.getMinutes(), now.getSeconds()].join(':');

        return <h1>{now_date} {now_time}</h1>;
      }
    }

    ReactDOM.render(
      <Justnow />,
      document.getElementById('root')
    );
  </script>
</body>
</html>

続きを読む

はじめてのReact #2「Componentを試してみる」

ReactはComponentを作るための仕組み?

Reactを触っていて感じるのは、React自体はコンポーネントを作るための仕組みなんだなということです。

例えば現在時間を表示する機能がほしいと思ったら <Justnow>というオリジナルのタグをReactで作成し、必要なWebページに埋め込むだけ。もちろん要素名(タグ名)は自由に命名できます。あとはこの応用で機能毎に必要な要素を用意して組み合わせるようなイメージでしょうか。Reactというと色々できて難しそうなイメージがありましたが、スタート地点は非常にシンプルな気がします。

今回は先ほど例に出した現在時間を表示するためのJustnow Componentを作ってみたいと思います。

現在時間を表示するComponent

サンプル

前回のサンプルにちょろっと書き足しました。このままコピペしてブラウザで開けば実行されます。

<!DOCTYPE html>
<html>
<head>
  <meta charset="UTF-8" />
  <title>Justnow</title>
  <script src="https://unpkg.com/react@16/umd/react.development.js"></script>
  <script src="https://unpkg.com/react-dom@16/umd/react-dom.development.js"></script>

  <!-- Don't use this in production: -->
  <script src="https://unpkg.com/babel-standalone@6.15.0/babel.min.js"></script>
</head>
<body>
  <div id="root"></div>

  <script type="text/babel">
    class Justnow extends React.Component {
      render() {
        let now = new Date();
        let now_date = [now.getFullYear(), now.getMonth()+1, now.getDate()].join('-');
        let now_time = [now.getHours(), now.getMinutes(), now.getSeconds()].join(':');

        return <h1>{now_date} {now_time}</h1>;
      }
    }

    ReactDOM.render(
      <Justnow />,
      document.getElementById('root')
    );
  </script>
</body>
</html>

続きを読む

はじめてのReact #1「HelloWorld」

JavaScript界のモダンな3大フレームワーク「React」「AngularJS」「Vue.js」、いずれも一長一短あるクセのあるソフトウェアで常に宗教戦争にさらされているわけですが、結論から言えばプロジェクトや個人の趣向にあった物を使えば良いし、正直なところES2015(ES6)以降を使うなら個人的にはVanillaJSで十分な場合が多いと思っています。

ところがしばらく前からReacは単なるWebアプリの世界を抜け出し、スマホ用のネイティブアプリやVRなど様々な分野に広がりを見せています。Googleトレンドで過去5年間のデータを見ると、調べ方によりますがこれを書いている2018年末はReactが優位な模様。

乗るしか無い、このビッグウェーブに!というわけで、しばらくReactについてお勉強をしてみたいと思います。

続きを読む

AWSからのメール: Your certificate is renewed

Amazon(AWS)から以下のようなメールが届きました。
このブログはCloudFrontを通しつつ、AWSのCertificate Manager(ACM)で無料のSSL証明書を利用しているのですが、どうもSSL証明書が自動的に更新されたっぽい!?

Greetings from Amazon Web Services,

This notification is to notify you that AWS Certificate Manager (ACM) has completed the renewal of an SSL/TLS certificate that certificate includes the primary domain blog.katsubemakito.net and a total of 1 domains.

AWS account ID: xxxxxxxxxxxx
AWS Region name: us-east-1
Certificate identifier: arn:aws:acm:us-east-1:xxxxxxxxxxxx:certificate/xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx

Your new certificate expires on Jan 22, 2020 at 12:00:00 UTC.
If you have questions about this process, please use the Support Center at https://console.aws.amazon.com/support to contact AWS Support. If you don’t have an AWS support plan, post a new thread in the AWS Certificate Manager discussion forum at https://forums.aws.amazon.com/forum.jspa?forumID=206

This notification is intended solely for authorized individuals for blog.katsubemakito.net. To express any concerns about this notification or if it has reached you in error, forward it along with a brief explanation of your concern to validation-questions@amazon.com.

Sincerely,
Amazon Web Services

続きを読む

映画「シュガー・ラッシュ:オンライン」ラルフ、YouTuberになる ★★★☆☆

2012年に公開された「シュガー・ラッシュ」の続編、「シュガー・ラッシュ:オンライン」を封切り日に見てきました。

結論から言うと……なにこれ切ない。
クリスマスや年末年始シーズンに公開される映画だよね?しかもディズニー映画で!?ってくらい意表を突かれたテーマとラストでした。原題のRalph Breaks the Internetの名の通り、主人公ラルフが最終的にインターネットの世界を壊して回るのですが、壊れたのは果たしてインターネットだけだったのか…。


続きを読む