Data APIを利用して記事投稿ページを作ってみよう

前回の記事では、Movable Type のData APIを利用して、認証=>記事データの表示を行いました。今回は、認証の仕組みを利用して、「Movable Type へ記事を投稿する仕組み」を作成します。

Data APIを利用したアプリケーションいろいろ

Movable Type には、iPhoneから簡単に記事投稿できるiOSアプリ「Movable Type for iOS」があります。実はこのアプリは、一覧取得・画像のアップロード・記事作成など、すべてMovable Type のData APIを利用しています。

Google Chrome から簡単に記事を投稿できる、Movable Type 用の投稿アプリ「Movable Type Writer」も、実はData APIを利用しています。

Movable Type for iOS

(画像は [Movbale Type for iOS] の画面)

このように、Data APIを利用すると、Movable Type 自身の管理画面を使わずに、記事の投稿や編集ができるようになります。作りこめば、オリジナルの管理画面もできてしまいます。

今回は、Data APIを利用したオリジナルの記事投稿ページを作って、管理画面を使わずに記事を投稿してみましょう。

仕様

仕様は以下とします。

  • ブログに投稿する権限を持つユーザーがMovable Type にサインインすると、メールフォームのような記事投稿画面が表示される
  • 投稿画面からは「記事タイトル」「本文」「続き」の3つが入力できる
  • 入力後「投稿」ボタンを押すと、Movable Type に記事が投稿されて、ブログのトップページが更新される

実際の画面イメージを紹介します。今回のデザインも、前回同様、Movable Type の標準テーマ「Rainier」を利用して実装します。

投稿ページにアクセスすると、サインインを促すメッセージが表示されます。

サインイン画面

サインインのリンクをクリックすると、Movable Type の投稿画面が表示されます。

サインイン画面

投稿画面には、「タイトル」「本文」「続き」の3種類の入力フォームが表示されます

入力フォームが表示される

入力後、「投稿」ボタンを押すと、「投稿が完了しました」というメッセージが表示されます

投稿完了メッセージ

ブログのトップページを見ると、投稿した内容が反映されています

トップページの更新

投稿画面のテンプレート

それでは、実際のコードを見てみましょう。今回はjQueryを使ってコードを記述します。

まず最初に、<head>-</head>内で

  • Data API SDK
  • jQuery

の2つを読み込むようにします。[Rainier]の[HTMLヘッダー]というテンプレートモジュールに以下の2行を記述します。

    <script type="text/javascript" src="<$MTStaticWebPath$>data-api/v2/js/mt-data-api.min.js"></script>
    <script type="text/javascript" src="<$MTStaticWebPath$>jquery/jquery.min.js"></script>

次に、投稿画面のコードを記述します。投稿画面用のhtmlは、インデックステンプレートなどで作成すると良いでしょう。投稿フォームを表示したい部分に、以下のコードを記述します。

<script type="text/javascript">
  var api = new MT.DataAPI({
    baseUrl: '<$MTCGIPath$>mt-data-api.cgi',
    clientId: 'post-entry',
    sessionPath: '/',
  });

  var siteId = <$MTBlogID$>;

    function SignIn() {
        api.getToken(function(response) {
            if(response.error) {
                if(response.error.code === 401) {
                 location.href = api.getAuthorizationUrl(location.href);
                }
            }
        });
    }

    function SignOut() {
        api.revokeAuthentication(function(response) {
          if (response.error) {
            alert ('サインアウトに失敗しました。');
            return;
          } else {
          location.reload();
          }
        });
    }

    function PostEntry() {

      var entry = {};
      entry['title']  = $('#title').val();
      entry['body']   = $('#text_body').val();
      entry['more']   = $('#text_more').val();
      entry['status'] = 'Publish';

      api.createEntry(<$MTBlogID$>, entry, function(response) {
        if (response.error) {
          alert(response.error.code + ':' + response.error.message);
          return;
        } 
          var message = "投稿が完了しました。\nタイトル:" + response.title;
          alert(message);
          location.reload();
      });
    
    }

  $(function() {
        if (!api.getTokenData()) {
           $('#entry-post').hide();
           $('#sign-in').show();
        }
        else {
           $('#entry-post').show();
           $('#sign-in').hide();
        }
    });
</script>

    <div id="entry-post">
      <form name="CreateEntry" id="CreateEntry" method="post">
        <p><input type="text" name="title" id="title" placeholder="タイトル" style="width:80%"></p>
        <p><textarea name="text_body" id="text_body" placeholder="本文" rows="8" style="width:80%"></textarea></p>
        <p><textarea name="text_more" id="text_more" placeholder="続き" rows="8" style="width:80%"></textarea></p>
        <p><input type="submit" OnClick="PostEntry(); return false;" value="投稿する"></p>
      </form>
        <p><input type="button" onClick="SignOut()" value="サインアウト"></p>
    </div>

    <div id="sign-in">
      <p>記事を投稿するためにはサインインしてください。</p>
      <p><input type="button" onClick="SignIn()" value="サインイン"></p>
    </div>

まず最初に、Data APIのインスタンスを生成します。clientIdは適当な語句を設定しましょう。今回は「post-entry」としてみました。

  var api = new MT.DataAPI({
    baseUrl: '<$MTCGIPath$>mt-data-api.cgi',
    clientId: 'post-entry',
    sessionPath: '/',
  });

関数[SignIn]を定義します。この関数は、サインインボタンをクリックしたときに、エンドポイント[getToken]して、すでにサインインが行われているかどうかをチェックします。サインインがおこなれていない場合、Movable Type の認証画面を呼び出します。

    function SignIn() {
        api.getToken(function(response) {
            if(response.error) {
                if(response.error.code === 401) {
                 location.href = api.getAuthorizationUrl(location.href);
                }
            }
        });
    }

関数[SingOut]を定義します。この関数は「サインアウト」ボタンをクリックした時、認証用トークンを廃棄してサインアウトを行います。エンドポイント[revokeAuthentication]を利用しています。

function SignOut() {
        api.revokeAuthentication(function(response) {
          if (response.error) {
            alert ('サインアウトに失敗しました。');
            return;
          } else {
          location.reload();
          }
        });
    }

関数[PostEntry]を定義します。この関数は、「投稿」ボタンをクリックした時、投稿画面に入力された「タイトル」「本文」「続き」のデータを、jQueryを利用して取得します。投稿時の状態は「Pulish」、すなわち公開にして、投稿後すぐに記事を公開するようにしています。

取得したデータを、Data API経由でMovable Type に投稿します。投稿時には、エンドポイント「createEntry」を利用しています。もしエラーが発生したら、エラーコードとエラーメッセージをアラート表示します。投稿が済んだら「投稿が完了しました。」というメッセージとともに、記事のタイトルをアラートで表示して、投稿画面をリロードし直します。記事のタイトルデータは、「response.title」で取得して、変数messageに出力しています。

   function PostEntry() {

      var entry = {};
      entry['title']  = $('#title').val();
      entry['body']   = $('#text_body').val();
      entry['more']   = $('#text_more').val();
      entry['status'] = 'Publish';

      api.createEntry(<$MTBlogID$>, entry, function(response) {
        if (response.error) {
          alert(response.error.code + ':' + response.error.message);
          return;
        } 
          var message = "投稿が完了しました。\nタイトル:" + response.title;
          alert(message);
          location.reload();
      });
    
    }

最後に、投稿画面読み込み時の処理を定義します。Movable Type でサインインを行っていない場合、すなわち認証トークンが存在しない場合、サインインを促すメッセージを記述している<div id ="entry-post">...</div>を非表示、<div id="sing-in">...</div>を表示します。サインインが済んでいた場合は、表示・非表示を切り替えます。

  $(function() {
        if (!api.getTokenData()) {
           $('#entry-post').hide();
           $('#sign-in').show();
        }
        else {
           $('#entry-post').show();
           $('#sign-in').hide();
        }
    });


</script>

    <div id="entry-post">
      <form name="CreateEntry" id="CreateEntry" method="post">
        <p><input type="text" name="title" id="title" placeholder="タイトル" style="width:80%"></p>
        <p><textarea name="text_body" id="text_body" placeholder="本文" rows="8" style="width:80%"></textarea></p>
        <p><textarea name="text_more" id="text_more" placeholder="続き" rows="8" style="width:80%"></textarea></p>
        <p><input type="submit" OnClick="PostEntry(); return false;" value="投稿する"></p>
      </form>
        <p><input type="button" onClick="SignOut()" value="サインアウト"></p>
    </div>

    <div id="sign-in">
      <p>記事を投稿するためにはサインインしてください。</p>
      <p><input type="button" onClick="SignIn()" value="サインイン"></p>
    </div>

いかがでしょうか?JavaScriptとjQueryだけで、オリジナルの記事投稿ページができました。

みなさんも、ぜひ自分だけの投稿ページ作成にチャレンジしてみてください!