Edited at

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

More than 1 year has passed since last update.

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で画像を登録する画面。

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