画像のカスタムフィールドグループで「ブラウザ側のリサイズ機能」が動作しない問題


最近はメディア機能を利用される人も多いかもしれませんが、カスタムフィールドグループで画像を利用すると「ブラウザ側のリサイズ機能を使用する」が機能していない事が分かりました。将来的なアップデートで修正される予定ですが、正常に動作するサンプルコード を紹介しておきます。

グループ名: album / 画像 : photo で設定しています。

正常に動作するサンプルコード

<table class="js-fieldgroup-sortable adminTable acms-admin-table-admin-edit">
  <tbody>
  <!-- BEGIN album:loop -->
  <tr class="sortable-item">
    <td class="item-handle acms-admin-table-nowrap">
      <i class="acms-admin-icon-sort"></i>
    </td>
    <td>
      <table>
        <tr>
          <td class="js-img_resize_cf">
            <!-- BEGIN_IF [{photo@path}/nem] -->
            <img src="%{ARCHIVES_DIR}{photo@path}" class="js-img_resize_preview" style="max-width:300px" alt="{photo@alt}" />
            <input type="hidden" name="photo@old[]" value="{photo@path}" />
            <label for="input-checkbox-photo@edit[]" class="acms-admin-form-checkbox">
              <input type="checkbox" name="photo@edit[]" value="delete" id="input-checkbox-photo@edit[]" />
              <i class="acms-admin-ico-checkbox"></i>削除</label>
            <!-- ELSE -->
            <img src="%{ARCHIVES_DIR}{photo@path}" class="js-img_resize_preview" style="max-width:300px;display:none" />
            <!-- END_IF -->
            <input type="file" name="photo[]" class="js-img_resize_input" />
            <br/>
            <input type="hidden" name="photo@width[]" value="800" />
          </td>
        </tr>
      </table>
    </td>
    <td class="acms-admin-table-nowrap">
      <input type="button" class="item-delete acms-admin-btn-admin acms-admin-btn-admin-danger" value="削除" />
    </td>
  </tr>
  <!-- END album:loop -->
  <tr class="sortable-item item-template">
    <td class="item-handle acms-admin-table-nowrap">
      <i class="acms-admin-icon-sort"></i>
    </td>
    <td>
      <table>
        <tr class="js-custom-img_resize_cf">
          <td class="js-img_resize">
            <img src="" style="max-width:300px;display:none" class="js-img_resize_preview" />
            <input type="file" name="photo[]" class="js-img_resize_input" style="max-width:300px" />
            <br/>
            <input type="hidden" name="photo@width[]" value="800" />
          </td>
        </tr>
      </table>
    </td>
    <td class="acms-admin-table-nowrap">
      <input type="button" class="item-delete acms-admin-btn-admin acms-admin-btn-admin-danger" value="削除" />
    </td>
  </tr>
  </tbody>
  <tfoot>
  <tr>
    <td colSpan="3">
      <input type="button" class="item-insert acms-admin-btn-admin" value="追加" />
      <input type="hidden" class="item-max" value="20" />
    </td>
  </tr>
  </tfoot>
</table>
<input type="hidden" name="@album[]" value="photo@path" />
<input type="hidden" name="@album[]" value="photo@alt" />
<input type="hidden" name="@album[]" value="photo@x" />
<input type="hidden" name="@album[]" value="photo@y" />
<input type="hidden" name="@album[]" value="photo@edit" />
<input type="hidden" name="@album[]" value="photo@old" />
<input type="hidden" name="photo:extension" value="image" />
<input type="hidden" name="@album[]" value="photo" />
<input type="hidden" name="field[]" value="photo" />
<input type="hidden" name="field[]" value="@album" />

<script>
ACMS.Ready(function () {
  ACMS.addListener("acmsAddCustomFieldGroup", function(e) {
    $('.js-custom-img_resize_cf', e.target).each(function () {
      ACMS.Library.ResizeImage(this);
    });
  });
});
</script>

TinyPNG API を使って、画像を最適化してみよう

この記事は Advent Calendar 2019 の25日目の記事となります。さまざまな a-blog cms に関する記事が公開されていますので是非ごらんください。



画像を最適化してファイルサイズを小さくすることでパフォーマンスをよくすることができます。
これを実現するために「ロスレス圧縮」機能が a-blog cms にはありますが、サーバー側で必要なライブラリが入っていないと動作しません。

必要なライブラリ例

  • pngquant
  • optipng
  • pngcrush
  • pngout
  • advpng
  • jpegtran
  • jpegoptim
  • gifsicle
  • svgo

共用のレンタルサーバーなどだと、これらのライブラリが入っている可能性が少なく、対応に困ります。
そこで、画像最適をするサービスで有名な「TinyPNG」のAPIを使い、ライブラリが入っていないサーバーでも画像のロスレス圧縮に対応させる拡張アプリを作ってみたので紹介いたします。

この拡張アプリで実現できること

TinyPNGのAPIを利用して、画像のロスレス圧縮を実現できます。Hook機能を使って画像生成時にすべてロスレス圧縮します。 また校正オプションを用意していて、ロスレス圧縮された状態で画像のリサイズをすることができます。

インストール方法

設置方法

https://github.com/appleple/acms-tiny-png/raw/master/build/TinyPNG.zip のリンクからzipファイルをダウンロードします。zipを解凍すると TinyPNG というディレクトリが出てくるので extension/plugins/ に設置します。

アプリのインストール

設置できたら、管理画面にログインし、拡張アプリ から TinyPNG 拡張アプリをインストールします。

config.server.php

拡張アプリのインストールができたら、config.server.php の HOOK_ENABLE の値を「1」に設定します。

APIキーの設定

https://tinypng.com/ でアカウントを作成し、API Key を発行ください。発行した API Key を以下の様に private/config.system.yaml に追記します。

tiny_png_api_key: xxxxxxxxxxxxxxxxxxxxxxxxxxx

以上でインストール・設定は完了です。

参照: https://github.com/appleple/acms-tiny-png

使い方

特にロスレス圧縮するだけなら、なにも意識せず通常通りの作業で、自動的にTinyPNGのAPIを通して、圧縮されるようになります。

画像のリサイズを TinyPNG APIで実行する

TinyPNGで画像を好きなサイズにリサイズできる校正オプションも用意しました。もちろんロスレス圧縮された状態でリサイズされます。

scale

アスペクト比を維持したまま、幅または高さを指定してリサイズします。幅、高さの両方の指定はできません。

<img src="%{MEDIA_ARCHIVES_DIR}{hoge@path}[resizeTinyPng('scale', 300)]" /> <!-- 幅指定 -->
<img src="%{MEDIA_ARCHIVES_DIR}{hoge@path}[resizeTinyPng('scale', 0, 300)]" /> <!-- 高さ指定 -->

fit

アスペクト比を維持したまま、指定された寸法に収まるように縮小します。幅と高さ両方の指定が必要です。

<img src="%{MEDIA_ARCHIVES_DIR}{hoge@path}[resizeTinyPng('fit', 300, 300)]" />

cover

指定された寸法になるように縮小し、はみ出した部分はトリミングします。幅と高さ両方の指定が必要です。

<img src="%{MEDIA_ARCHIVES_DIR}{hoge@path}[resizeTinyPng('cover', 200, 200)]" />

改善したいところ

さくっと作ったままですので、まだまだ改善しないといけないところがあります。

  • 同期的にAPIをたたいているので、画像のアップロード処理がすごく遅くなってしまう。-> バックグラウンドで実行する様に修正する。
  • 余分なAPIコールがあるので、節約するようにしたい。
  • 残りAPI回数が、管理画面から確認できるようにしたい。

まだまだ改善点はありますが、この拡張アプリを入れることで、共用のレンタルサーバーなどでも簡単にロスレス圧縮に対応できるようになります。 よかったらぜひ試してみてください。

Unit_List の使用ケースその1:ギャラリー

Unit_Listとは、ビルトインモジュールの1つで、現段階では Entry_Body 以外で唯一ユニットを表示できるモジュールです。Entry_Body と違うところは、Entry_Body はエントリーのユニットを表示するのに対し、 Unit_List はエントリーをまたぎ、ユニットのみを表示して一覧にすることができます。

Unit_List は特殊なモジュールのため、どう応用していいのか想像がつきづらいかと思いますが、その1例として、ギャラリーページに使われます。


(スクリーンショット:写真が並んだギャラリーページ)

ユニットリストをギャラリーとして利用した例


実装方法

まずは、ギャラリーを表示したい場所に、ユニットリストを実装したファイルをインクルード機能を使って読み込みます。

インクルードファイルが /include/unit_list.html の場合、ソースコードは以下のようになります(※ファイルのパス、ファイル名が違う場合は30行目を修正してください)。

ソースコード(/include/unit_list.html)

<script>
  ACMS.Ready(function(){
    ACMS.Config.ppMark = 'a[data-rel^="prettyPhoto"]';
  });
</script>
<!-- BEGIN_MODULE Unit_List id="gallery" -->
<div class="acms-container">
  <!--#include file="/admin/module/setting.html"-->
  <div class="acms-grid">
    <!-- BEGIN unit:loop -->
    <div class="acms-col-md-4 acms-col-sm-6 text-center" style="position: relative;"> 
      <a href="<!-- BEGIN_IF [{large}/nem/] -->%{ARCHIVES_DIR}{large}<!-- ELSE -->%{ARCHIVES_DIR}{normal}<!-- END_IF -->" data-rel="prettyPhoto[gallery{entry_id}]" title="{entry_title}" >
          <p class="acms-text-center"><!-- #BEGIN image:veil -->
            <img src="%{ARCHIVES_DIR}{normal}[resizeImg(200,200)]" alt="{alt}"  class="acms-img-rounded"><!-- #END image:veil -->
          </p>
      </a>
      <!-- BEGIN_MODULE Touch_SessionWithAdministration -->
      <!-- 編集ボタン -->
      <form action="" method="post" style="position: absolute; bottom: 20px; right: 15px;">
        <input type="hidden" name="eid" value="{entry_id}" />
        <input type="hidden" name="admin" value="entry-edit" />
        <input type="submit" name="ACMS_POST_2GET" value="変更する" class ="acms-admin-btn" />
      </form>
      <!-- END_MODULE Touch_SessionWithAdministration -->
    </div>
    <!-- END unit:loop -->
  </div>
 
  <!-- 続きを読むボタン -->
  <!-- BEGIN pager:veil --><!-- BEGIN forwardLink -->
  <form action="" method="post" class="js-post_include">
    <input type="hidden" name="bid" value="%{BID}" />
    <input type="hidden" name="cid" value="%{CID}" />
    <input type="hidden" name="tpl" value="/include/unit_list.html" />
    <input type="submit" name="ACMS_POST_2GET" value="もっと見る" class="acms-btn acms-btn-block acms-btn-large" />
    <input type="hidden" name="page" value="{forwardPage}" />
  </form>
  <!-- END forwardLink --><!-- END pager:veil -->
</div>
<!-- END_MODULE Unit_List -->

注意点

  • モジュールID名を修正するときは6行目を変更してください(現在のモジュールID名は「gallery」になっています)
  • 1~5行目では、prettyPhotoはHTML5対応するため、12行目のrel属性をdata-rel属性に変更しています
  • ファイルのパス、ファイル名が違う場合は34行目を修正してください

モジュールの設定



ユニットタイプの「画像」がチェックされていることを確認してください。

他の設定については、必要に応じて有効にしてください。


Unit_List を使うことで変わるギャラリーページの運用方法


Unit_Listをギャラリーページで使うことになると、基本的にはエントリーのページでは文字を挿入することがなくなります。運用時に運営者が迷わないように、管理画面>コンフィグ>編集設定の順にページを移動し、「画像」以外のユニット追加ボタンを削除しましょう。


編集設定のページにある、ユニット追加ボタンを「画像」以外削除しておく


エントリー編集画面のユニット追加ボタン


このように画像投稿専用のUIが運営者に提供できます。