LoginSignup
6
6

More than 5 years have passed since last update.

Movable Type の Data API を使って、画像をアップロードする

Last updated at Posted at 2017-03-23

Movable Type の Data APIを利用してアプリ開発などを行う場合、画像をアップロードしたい、という場面もあると思います。

Data APIから画像をアップロードする方法について、サンプルコードを書いてみました。

やること

  • Movable Type の Data API を使って、画像をアップロード。Movable Type に登録する。
  • JavaScript で実装する
  • jQuery、Movable Type のJavaScript SDK を利用する。

検証環境

  • Movable Type 6.3.3
  • Google Crhome, Microsoft Edge

画像をアップロードする

以下のような流れで考えてみました。

  1. JavaScript SDKで認証を行う
  2. html5のFile API で画像のサムネイル表示
  3. 画像をアップロードしたいパスを入力
  4. アップロードボタンを押すことで、画像をサーバー上にアップロードし、MTのアイテムとして登録する

認証およびMTへの登録は Data API、入力値の反映などはjQueryで行います。

mt-image-upload.html

<!DOCTYPE html>
<html lang="ja">
<head>
  <title>画像をMTに登録するサンプル</title>
  <meta charset="utf-8">
  <meta name="viewport" content="width=device-width, initial-scale=1">
  <script src="https://code.jquery.com/jquery-2.1.4.min.js"></script>
  <script src="<$MTStaticWebPath$>data-api/v3/js/mt-data-api.js"></script>
</head>
<body>

<div class="container" id="container">

  <h2>画像をMTへ登録するサンプル</h2>

        <div id="message"></div>

        <div id="content" style="display: none;">
        <p><input type="file" name="upload" id="fileToUpload"></p>
        <p>アップロードパス</p>
        <p><input type="text" name="path" id="path">

        <p><button id="uploadFile">MTへアップロード</button></p>

        </div>

</div>

<script>

// Movable Type Data API のインスタンス生成

const api = new MT.DataAPI({
  baseUrl: "<$MTCGIPath$><$MTDataAPIScript$>",
  clientId: "image-upload"
});

// MTのブログIDを変数 siteId に格納

const siteId = <$MTBlogID$>;

// メッセージ表示のために使う変数 [html] を定義

let html = '';

$(function() {

  // MTにサインインしているかどうか、トークンを確認する。
  // トークンがない場合、サインインを促す。存在した場合、hiddenで隠されている登録用フォームを表示する

  if (!api.getTokenData()) {
    let html = `
          <p>画像を登録するためにはサインインしてください。</p>
          <p><input type="button" id="signin" class="btn btn-primary btn-lg" value="サインイン"></p>
          `
    $("#message").html(html);
  } else {
    $("#content").show();
  }

  // サインインをクリックしたら、SDKの関数 [getAuthorizationUrl] を実行して、サインインを行う

  $("#signin").on("click", function() {
    location.href = api.getAuthorizationUrl(location.href);
  });

  // アップロードするファイルを選択

$('input[type=file]').after('<p><span id="image"></span></p>');

  $('input[type=file]').change(function() {
    const file = $(this).prop('files')[0];

    // 画像以外は処理を停止

    if (!file.type.match('image.*')) {
      $(this).val('');
      $('span').html('');
      return;
    }

    const reader = new FileReader();
    reader.onload = function() {
      const img_src = $('<img height=\"300\">').attr('src', reader.result);
      $('span').html(img_src);
    }
    reader.readAsDataURL(file);
  });

  // 登録ボタンをクリックしたら、アップロード用の関数[upload]を実行する。

  $("#uploadFile").on("click", function() {
    upload();
  });

  // 画像をアップロードしてMTに登録する。エラーになったら、レスポンスデータからエラーメッセージを表示。それ以外は成功メッセージを表示

  function upload() {
      const data = {
        site_id: siteId,
        path: $("#path").val(),
        file: $("#fileToUpload")[0].files[0],
        autoRenameIfExists: true,
        normalizeOrientation: true,
      };
      api.uploadAsset(data, function(response) {

        if (response.error) {
          alert(response.error.message);
          return;
        }

         alert("画像をアップロードしました。");
         return;
    });
  }

});
</script>

</html>

画像をアップロードするときに、画像の説明やタグも合わせて登録する

画像の情報に説明やタグなどを加えたい場合は、以下のような流れになります。

  1. JavaScript SDKで認証を行う
  2. html5のFile API で画像のサムネイル表示
  3. 画像をアップロードしたいパスを入力
  4. アップロードボタンを押すことで、画像をサーバー上にアップロードし、MTのアイテムとして登録する
  5. アップロード後に取得したレスポンスデータから、登録された画像のアイテムIDを取得する
  6. [PUT]メソッドで、アイテムIDの情報に、説明とタグを加えてupdateする

4から5にデータを渡すためには、非同期通信の処理を待って次の処理へ渡す必要があります。今回はJavaScriptのPromise メソッドを使って、アップロードに対するレスポンスデータを引き渡しました。

Promise に関しては、こちらの記事 をご参照ください。

タグの情報は、カンマ区切りで入力します。カンマごとに語句を分割して配列[tags]に格納後、Data API に渡しています。

アイテムをアップデートするためのエンドポイント update を、JavaScript SDKで叩きます。

mt-upload-image-1.html


<!DOCTYPE html>
<html lang="ja">
<head>
  <title>タグや説明を付加した画像をMTに登録するサンプル</title>
  <meta charset="utf-8">
  <meta name="viewport" content="width=device-width, initial-scale=1">
  <script src="https://code.jquery.com/jquery-2.1.4.min.js"></script>
  <script src="<$MTStaticWebPath$>data-api/v3/js/mt-data-api.js"></script>
</head>
<body>

<div class="container" id="container">

  <h2>タグや説明を付加した画像をMTへ登録するサンプル</h2>

        <div id="message"></div>

        <div id="content" style="display: none;">
        <p><input type="file" name="upload" id="fileToUpload"></p>
        <p>アップロードパス</p>
        <p><input type="text" name="path" id="path">
        <p>画像の説明</p>
        <p><input type="text" name="desc" id="desc">
        <p>画像のタグ</p>
        <p><input type="text" name="tags" id="tags">

        <p><button id="uploadFile">MTへアップロード</button></p>

        </div>

</div>

<script>

// Movable Type Data API のインスタンス生成

const api = new MT.DataAPI({
  baseUrl: "<$MTCGIPath$><$MTDataAPIScript$>",
  clientId: "image-upload-1"
});

// MTのブログIDを変数 siteId に格納

const siteId = <$MTBlogID$>;

// メッセージ表示のために使う変数 [html] を定義

let html = '';

$(function() {

  // MTにサインインしているかどうか、トークンを確認する。
  // トークンがない場合、サインインを促す。存在した場合、hiddenで隠されている登録用フォームを表示する

  if (!api.getTokenData()) {
    let html = `
          <p>画像を登録するためにはサインインしてください。</p>
          <p><input type="button" id="signin" class="btn btn-primary btn-lg" value="サインイン"></p>
          `
    $("#message").html(html);
  } else {
    $("#content").show();
  }

  // サインインをクリックしたら、SDKの関数 [getAuthorizationUrl] を実行して、サインインを行う

  $("#signin").on("click", function() {
    location.href = api.getAuthorizationUrl(location.href);
  });

  // アップロードするファイルを選択

$('input[type=file]').after('<p><span id="image"></span></p>');

  $('input[type=file]').change(function() {
    const file = $(this).prop('files')[0];

    // 画像以外は処理を停止

    if (!file.type.match('image.*')) {
      $(this).val('');
      $('span').html('');
      return;
    }

    const reader = new FileReader();
    reader.onload = function() {
      const img_src = $('<img height="300">').attr('src', reader.result);
      $('span').html(img_src);
    }
    reader.readAsDataURL(file);
  });

  // 登録ボタンをクリックしたら、関数[upload]を実行。非同期通信のレスポンスが返ってきたら、次の関数[update]に値を引き渡し、タグと説明データを加える。

  $("#uploadFile").on("click", function() {
    upload().then(function(response) {
      update(response);
    });
  });

  // 画像をアップロードしてMTに登録し、レスポンスデータを Promise で渡す

  function upload() {
    return new Promise((resolve, reject) => {
      const data = {
        site_id: siteId,
        path: $("#path").val(),
        file: $("#fileToUpload")[0].files[0],
        autoRenameIfExists: true,
        normalizeOrientation: true,
      };
      api.uploadAsset(data, function(response) {
        if (response.error) {
          alert(response.error.message);
          reject;
        }
        resolve(response);
      });
    });
  }

  // 関数 upload() から返ってきたレスポンスデータを元に、タグと説明のデータを追加してアップデートする

  function update(response) {
    const assetId = response.id;
    const tag = $("#tags").val();
    const tags = tag.split(',');
    const extData = {
      description: $("#desc").val(),
      tags: tags,
    };
    api.updateAsset(siteId, assetId, extData, function(result) {
      if (result.error) {
        alert("アイテムの情報をアップデート中にエラーが発生しました。");
        return;
      }
      alert("画像をアップロードしました。");
      return;
    });
  }
});
</script>

</html>

出力したhtmlで画像を登録する画面。

upload-image-1.png

登録後の画像。タグや説明が付加されています。

upload-image-2.png

6
6
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
6
6