コンテンツの読み込みに時間がかかっています

9ページ目

a-blog cms で Tweet の引用をブログにお手軽に実装する方法

https://publish.twitter.com/ を一度ご確認ください。上記のようなサイトがあります。以前は Twitter の Widgets が設定画面にあって、そこでコードをコピペするような感じで提供されていたが、いつの日か無くなってしまっていたと思っていたのですが、いつの間にか復活しておりました。



機能としては、Embedded Tweet / Embedded Timeline / Twitter Buttons の3種類が用意されています。 Buttons はクリックすると 5種類あるみたいですが、今回は全く確認していない。 Timeline も便利に使えそうではあるが、今回は Embedded Tweet のお話です。

a-blog cms の標準的な引用ユニット


blogテーマでは、デフォルトは表示されていないが「引用ユニット」をオンにすると以下のように URL を設定できるようになっている。そこで、https://www.a-blogcms.jp を設定すると、そのページの OGP情報を取得して表示してくれる便利な機能だ。


a-blog cms のテキストユニットでの引用


一般的なテキストの引用については、こんな感じで書くと <blockquote> 〜 </blockquote> のタグで囲まれた文章となる。

さらに脱線気味に cite属性を追加する方法

管理画面 / コンフィグ / エントリー / 編集設定 / テキストタグセレクト の3つ目の入力欄に「引用元URL」と設定します。


上記の設定を行うと以下ような感じで引用元URLを設定できるユニットに進化します。


あとは blog/include/unit.html@section(text-unit) を持ってきて blockquoteブロック をカスタマイズします。3つ目の入力欄の変数は {extend_tag} となっています。

<!-- BEGIN blockquote -->
<div class="entry-container">
<blockquote{class}<!-- BEGIN_IF [{extend_tag}/nem] --> cite="{extend_tag}"<!-- END_IF -->>
{text}[raw|nl2br]</blockquote></div><!-- END blockquote -->

本題の引用ユニットに Embedded Tweet 機能を追加

例えば https://twitter.com/ndrf_kazumich/status/1510118505139798019https://publish.twitter.com/ に設定します。

<blockquote class="twitter-tweet">
<p lang="ja" dir="ltr">今日は朝早起きしたので、a-backup を作り直している。処理を簡単にして短い時間で処理が完了できるようにすることを第一の目標とし、2つ目の目標として設定項目を減らして簡単に使えるようにする。テーマの設定を DB を確認して出来るようになった。 
<a href="https://t.co/5IFYxsPJDq">pic.twitter.com/5IFYxsPJDq</a></p>&mdash; 山本一道@アップルップル (@kazumich) <a href="https://twitter.com/kazumich/status/1601727082824105985?ref_src=twsrc%5Etfw">December 10, 2022</a>
</blockquote> 
<script async src="https://platform.twitter.com/widgets.js" charset="utf-8"></script>

こんな事が書ければ OK な事がわかります。

実は blog テーマは、https://platform.twitter.com/widgets.js が最初から読み込まれているので、<script> タグは消しても動作します。

オリジナルテーマで実装する際には widgets.js が必要になります。必要な時に読み込むようにカスタマイズするには「SetRendered と GET_Rendered を活用した「円グラフのカスタムユニット」を作ってみよう」を参考にしてください。

徐々に情報を減らして動くかを調べてみたところ、class="twitter-tweet" の中の <a> の href 属性に Twitter の URL があるだけで動作する事がわかりました。

テンプレートをカスタマイズしていきます

blog/include/unit.html には最初から @section(quote-unit) がカスタマイズして設置されていました。そこの一部が以下のように書かれています。

(略)
<!-- BEGIN html:veil -->
 {quote_html}[raw]
<!-- END html:veil -->
<!-- BEGIN_IF [{quote_title}/nem/] -->
<blockquote class="quote">
(略)

<-- END html:veil --> の後ある IFブロックを少し修正し、以下のようにします。

(略)
<!-- BEGIN html:veil -->
 {quote_html}[raw]
<!-- END html:veil -->
<!-- BEGIN_IF [{quote_url}/lk/twitter.com] -->
 <blockquote class="twitter-tweet">
  <a href="{quote_url}">Tweet内容をtwitter.comで確認する</a>
 </blockquote>
<!-- ELSE_IF [{quote_title}/nem/] -->
<blockquote class="quote">
(略)

<blockquote>タグclass="twitter-tweet" をつけ、その中の <a>タグ に Tweet の URL を設定するだけOKです。


と設定すれば、以下のような感じになります。


引用機能の隠れた機能?

ローカルでテストしつつ、このブログにも実装しておこう!って作業をしたらこの設定をしないでも、引用ユニットに Twitter の URL を設定するだけで同じものが表示されてしまいました。

コンフィグの設定で Twitter API を設定すると OGP の代わりに、今回の https://publish.twitter.com/ の結果と同じタグを twitter.com から API 経由で持ってきてくれることを忘れておりました。これも、せっかくなのでお伝えしておきます。


a-blog cms の TimePicker をアナログ時計UI にする方法

これは a-blog cms Advent Calendar 2022 4日目の記事です。

a-blog cms の標準の時刻を設定する UI については、以下のような Flatpickr というライブラリを利用しています。 直接 input 要素の入力欄にキーボードから時刻を入れることもできますがマウスクリックで数値の増減をしようとすると随分小さなボタンをクリックする必要が出てきます。


そんな事から Flatpickr 以外の JavaScript ライブラリを探してみる事にし、 Google で timepickerで画像検索 してみるとイロイロな UI を見つける事ができます。


2016年のブログの記事になりますが より直感的な時間入力のUIを考える | UX MILK の中で ClockPicker が紹介されていますが、9年前で更新が止まっていることから似たものを探し、最終的には jquery-clock-timepicker.js にたどり着きました。

Android の時間入力 UI も同様の時計なのを、今回の実装後に知りました。

a-blog cms の管理画面に実装する

利用するライブラリが決まったことから、a-blog cms の中に実装をしていきます。

エントリーの時刻入力フォーム部分になりますので、system/admin/entry/entry.html を複製して利用しているテーマにコピーをします。

このファイル自身は @extends("/admin/_layouts/entry/edit.html") と書かれているファイルなので実体は別のところですね。新規と修正の @section を修正する必要があるのも注意が必要です。

@section("apply-date")
*省略*
<input type="text" name="time" value="%{NOW_TIME}" size="12" id="entryTime" class="acms-admin-form-width-full js-timepicker">
*省略*
@endsection

@section("reapply-date")
*省略*
<input type="text" name="time" value="{time}" size="12" id="entryTime" class="acms-admin-form-width-full js-timepicker">
*省略*
@endsection

class="js-timepicker" となっている部分を、今回 class="js-clockpicker" に修正する事にします。 あとは、jquery-clock-timepicker.js を読み込む必要がありますが、今回は管理画面の中だけで大丈夫なので admin/entry/field.html の中で読み込む事で対応します。

<script src="/js/jquery-clock-timepicker.min.js"></script>
<script type="text/javascript">
  $(document).ready(function() {
  $('.js-clockpicker').clockTimePicker({autosize:true,popupWidthOnDesktop:300});
});
</script>

スタイルを少し調整しないと今の時刻を設定するボタンが離れてしまっているので


admin/entry/field.html に CSS の調整を追加します。

<style>
.entryFormTable .entryFormDateBlock {
    width: 130px;
}
</style>

アナログ時計UI の実装後

9:00 の 9 をクリックすると時間側の UI が表示されます。


その後、分 の UI に切り替わります。また、INPUT 要素の 分 をクリックすると、こちらが表示されるようになっています。


今回の実装で行ったものを以下からダウンロードできるようにしていますので、blog テーマであれば入れるだけ、それ以外は参考にしてもらえば簡単に実装できる事でしょう。


12KB

おまけ1: ブラウザにお任せする

デフォルトの管理画面のコードでは input type="text" name="time" となっておりますが、input type="time" name="time" とし、class の設定から js-timepicker などを消す事でブラウザにお任せする事ができます。


上は Mac の Chrome のキャプチャになります。Edge も同様の UI が出てきます。 残念ながら Mac の Safari は未対応でしたが、iOS の Safari は以下のように対応されているようです。


ブラウザでサポートしているような時には、JavaScript のライブラリを動かさないようにするように今後は検討していく必要がありそうです。

おまけ2:他のエントリー投稿フォームの UI のカスタマイズ

私の個人ブログには、エントリー管理画面のカスタマイズについて a-blog cms 2.10 エントリーのタグ入力画面を元に戻す方法 も紹介していますので、あわせてご覧ください。



動的フォームの途中にメッセージを挟みたい!って実装を無理矢理やってみる(非推奨)

前回も無理矢理な対応で公式ブログに書けない内容だったので、個人のブログに書いてみましたが、今回も非推奨・無理矢理対応です。


コンフィグのエントリー編集設定に、動的フォームの設定があるのでテンプレートをカスタマイズして msg というブロックを追加したらできるんじゃないか?って思ってやってみたところ残念ながらできませんでした。

ここで設定があるのであれば、何らか拡張できて良さそうな気もするんですが...  将来的に、拡張できるようになるといいですね。

表示用のテンプレートのカスタマイズ

/themes/system/include/form/input.html が表示用のテンプレートになります。無理矢理な実装になります。動的フォームの設定では {label} と {caption} が設定できます。

<!-- BEGIN column:loop -->
	
<!-- BEGIN text -->
<!-- BEGIN_IF [{label}/eq/msg]-->
  <tr><td colspan="2"><p>{caption}</p></td></tr>
<!-- ELSE -->
    <tr>
        (略)
    </tr>
<!-- END_IF -->
<!-- END text -->

簡単に紹介すると ラベル に msg とだけ入れた時に、フォームを出さないように設定します。 この msg の文字は決めておけば何でもいいことになります。

同様に /themes/system/include/form/confirm.html も同じように修正すれば、確認画面にも同様の文字列を表示させることができますし、何も出さないようにしてもいいかもしれません。

複数行のテキストを入れられるように

フォーム側のカスタマイズとしては /themes/system/admin/form2/unit.html になります。

<input type="text" name="text_caption_{id}" value="{caption}" id="input-text-caption-{id}" class="acms-admin-form-width-3quarters" />

<textarea name="text_caption_{id}" id="input-text-caption-{id}" class="acms-admin-form-width-3quarters" />{caption}</textarea>

にする事で、複数行書くことができるようになりますので、/themes/system/include/input.html の {caption} を {caption}[nl2br] のようにすれば OK です。場合によっては {caption}[markdown] とかにしておくと見出しや文章をまとめて書くことも可能です。

メール本文の修正も /themes/system/include/body.txt などの

<!-- BEGIN text -->
{label}  : \{form-unit-{utid}\}<!-- END text -->

部分を修正する必要があります。


説明の入力欄について

今回、説明 の入力欄を利用したカスタマイズを行いました。変数としては {caption} になります。こちらはアップルップルで提供しているテーマ内では表示させていませんので管理画面での説明欄になっています。

使い方によってはフォームの項目の下やツールチップなどで表示させて、フォームを入力する人のための説明のために /themes/system/include/input.html でカスタマイズして使うのもオススメです。

最後に

/themes/system のファイルを直接編集するのではなく、自分のテーマの同じ階層にコピーしてからカスタマイズするようにしてください。

今回も、あまりいい実装ではありませんが、無理矢理でも動的フォームの途中に文章などを入れたいというニーズにお答えするカスタマイズでした。


こんな感じの実装となりました。(上記は画像でフォームではありません)


エントリーコードから %{CUSTOM_USER_ID} を作るカスタムグローバル変数の作り方

現在の a-blog cms で、あるユーザーが書いた記事を表示させようと思った時、例えば uid が 10 のエントリーを表示させる際には以下のように書きます。

https://www.domain.com/uid/10

でも、 どちらかと言えば数値で表現するのではなく、以下のような URL で表現したいと思うのではないかと思います。

https://www.domain.com/user/usercode.html 

残念ながら現在の a-blog cms の URLコンテキストには user が用意されておりません。この URLコンテキストの修正は影響範囲が大きいので、なかなか追加することが難しい状況です。追加することで user がブログやカテゴリーで利用できないことになりバージョンアップ動かなくなるサイトが出てしまうからです。

でも、なんとかしたい!という要望をクリアするため「ユーザーコード+".html"」からユーザーの情報や、ユーザーの書いたエントリーの情報などを表示できるような実装を考えてみます。

最終的には、ユーザー情報だけでは無理っぽく、カテゴリーやエントリーを作ったりする必要があるので、スマートではありません。ゴメンナサイ。

カスタムグローバル変数

まずはオリジナルのグローバル変数を作ります。オリジナルグローバル変数の作成についてはサポート対象外ではありますが、 extension/acms/Hook.php function extendsGlobalVars を以下のような感じで書いてください。

public function extendsGlobalVars(&$globalVars)
{
    if (EID) {
        $ecd = \ACMS_RAM::entryCode(EID);
        list($ucd) = explode('.', $ecd);

        if ($ucd) {
            $sql = \SQL::newSelect('user');
            $sql->addSelect('user_id');
            $sql->addWhereOpr('user_code', $ucd);
            $sql->addWhereOpr('user_pass', '', '<>');
            $sql->addWhereOpr('user_blog_id', BID);
            $sql->addWhereOpr('user_status', 'open');
            if ($uid = \DB::query($sql->get(dsn()), 'one')) {
                $globalVars->set('CUSTOM_USER_ID', $uid);
            }
        }
    }
}

これにより %{CUSTOM_USER_ID} で UID が扱えるようになります。

config.server.php を設定

extension/acms/Hook.php をカスタマイズしている場合には、config.server.php の HOOK_ENABLE1 に設定します。

define('HOOK_ENABLE', 1);

モジュールID の設定で %{CUSTOM_USER_ID} を利用する

モジュールとしては、Entry_Summary とか User_Search など uid で情報を取得するようなモジュールを選択します。

モジュールID の条件設定の引数の鉛筆マークをクリックすると入力フォームが表示されます。ここにはユーザーIDを数値で設定したり、グローバル変数を設定ができます。そこに今回の %{CUSTOM_USER_ID} を入力します。



最後に /user/usercode.html を表示できるようにするには

ちょっと、最初にも書きましたが、無理矢理でゴメンナサイ。

/user/ はカテゴリー で、usercode.html はエントリー を作ります。こうすることで、/利用しているテーマ/user/_entry.html のテンプレートが表示できるようになります。

こうすることで、/利用しているテーマ/user/index.html で表示したいユーザーの一覧ページもできます。

ユーザーが管理画面上で usercode を書き換えると、エントリーコードと紐付かないことになりますので注意が必要です。

不特定多数のユーザーがいるようなサイトではなく、ユーザーを作った時点で手動でエントリーも作れるような規模の案件であれば使えるのではないかと思います。いかがでしょうか。


SmartBlock に地図を挿入する方法を考えてみる

先日、SmartBlock に、地図ブロックが欲しいという要望があったので、その方法を少し考えてみたいと思います。

a-blog cms の地図ユニットでは


地図ユニットでは、実際の地図に自由に動かせるピンとズームレベルの調整を実際の地図上でできるようになっており、細かい緯度経度の数値については手で触る必要はない状況ではあります。しかし、このユニットのようなものを新しく UI を用意するのは大変なので、他の方法を考えてみます。

SmartBlock の YouTube 対応について

YouTubeの場合には、URLを入力することで YouTube である事と 動画ID が分かって、動画を表示させるための iframe を組み立てる事ができます。


iframe をそのまま入力できるようにする

Google Maps を貼れるようにするというより汎用的に、色々な iframe タグをそのまま受け入れる事ができるようにするというプランです。


iframe 側にサイズの指定などがあり、キレイにコンテンツを埋め込めないこともあるかもしれませんが、どんなものでも対応にできるのはアリかと思います。ボタンのデザインはこんなでいいだろうか?

Embedブロックを拡張する

SmartBlock の YouTube対応を行なっているブロックの名前は Embedブロック というらしい。今のところ YouTube にしか対応していないようなので、これを拡張するのが2つ目のプランになります。

例えば、ベースキャンプ名古屋 を表示させるためのリンクを用意してみます。

https://www.google.co.jp/maps/search/%E3%83%99%E3%83%BC%E3%82%B9%E3%82%AD%E3%83%A3%E3%83%B3%E3%83%97%E5%90%8D%E5%8F%A4%E5%B1%8B/@35.176842,136.8931377,15z

これを iframe で表示させようとしても残念ながら表示させる事ができません。

<iframe src="https://www.google.co.jp/maps/search/%E3%83%99%E3%83%BC%E3%82%B9%E3%82%AD%E3%83%A3%E3%83%B3%E3%83%97%E5%90%8D%E5%8F%A4%E5%B1%8B/@35.176842,136.8931377,15z" 
width="100%" height="450"></iframe>

どうするべきかを色々調べてみたところ Maps Embed API というものを利用するといい事が分かりました。 Google Maps を iframe で利用するための API という事で、これを使えばいけそうです。

https://www.google.com/maps/embed/v1/{MODE}?{PARAMETER}

MODE には



place 場所や住所を表示
search 検索したお店などを表示
directions 2点間のルートを表示
view マーカーやルートを表示しない地図を表示
streetview ストリートビューを表示

PARAMETER には



q 住所、名称、緯度経度など
key API キー
center 経度,緯度
zoom ズームレベル

上記を設定することで、そのままの URL を iframe で利用できなかった Google Maps も iframe で利用が可能になります。APIキーの設定が少しハードルになりますが、今のところ Maps JavaScript API のように利用によっては費用がかかることはないとのことです。

Google Maps の URL を調べる

例えば「ベースキャンプ名古屋」で検索すると URL は

https://www.google.co.jp/maps/place/%E3%83%99%E3%83%BC%E3%82%B9%E3%82%AD%E3%83%A3%E3%83%B3%E3%83%97%E5%90%8D%E5%8F%A4%E5%B1%8B/@35.172764,136.885233,17z/data=!3m2!4b1!5s0x600376dc919f1feb:0xee5e0ae169e6ccf3!4m5!3m4!1s0x600376dc919b8655:0x5bbf0168ec8292bb!8m2!3d35.172764!4d136.887427

のようになり、読みやすく書くと place/ベースキャンプ名古屋/@緯度,経度,ズームレベルz ..... のようになります。 これらから必要な情報を取得して URL を組み立て直すと

https://www.google.com/maps/embed/v1/place?q=ベースキャンプ名古屋&center=緯度,経度&zoom=ズームレベル&key=APIキー

のようになります。

次に「ラーメン屋」で検索すると

https://www.google.com/maps/search/%E3%83%A9%E3%83%BC%E3%83%A1%E3%83%B3%E5%B1%8B/@35.1727749,136.8852676,17z/data=!3m1!4b1

のようになりました。この場合では MODE が search になります。

https://www.google.com/maps/embed/v1/search?q=ラーメン屋&center=緯度,経度&zoom=ズームレベル&key=APIキー

MODE が place と search に対応するくらいで大丈夫な気もしますが、directions や view なども頑張ってみてもいいかもしれません。

短縮URLの対応をどうするんだろ?

ブラウザの Google Maps で共有リンクを取得すると短縮URLになります。これだと、URLを解析するだけで対応ができません。また、スマホのアプリからの共有機能で情報をコピーしてもURLは短縮されてしまいます。


いろいろ調べていたところで、以下のような記事を見つけました。

ここにあるようなコードで短縮URLを戻してURLを組み立てるといいかもしれません。

「名古屋駅」の短縮URL は、以下のような感じになります。

https://goo.gl/maps/F4kxDQmPukVvF5ye8

これを、上記の外部サイトで紹介されていた関数 expand_url を利用して展開すると、

https://www.google.co.jp/maps/place/%E5%90%8D%E5%8F%A4%E5%B1%8B%E9%A7%85/@35.170915,136.8815369,17z/data=!3m1!4b1!4m5!3m4!1s0x600376e794d78b89:0x81f7204bf8261663!8m2!3d35.170915!4d136.8815369

のようになります。しかし、「ベースキャンプ名古屋」の短縮URLは

https://g.page/basecamp758?share

という感じになっており、Googleマイビジネス【プロフィールの略称】というものでした。この機能は、今調べてみると昨年夏に終了しており辞めることはできても、新しく作ることができないようです。

「名古屋駅」と同様の expand_url では、うまく展開できませんでした。

最後に

今回は SmartBlock のブロックの改良をするための方法を少し調べ、こんな感じの実装をやってみて欲しいを伝えるために書いてみました。いつ、誰にお願いするか分かりませんが、そのうち改良されて便利に使えるようになるといいなって思っています。



USB-C接続非対応のディスプレイを快適に利用する方法

アップルップルでは、現在 50% 出社という月の半分は社外での勤務が OK になっています。そのため MacBook Pro を持って帰り、また出社時にはディスプレイと電源を接続する必要が出てきています。外部ディスプレイが1枚であれば USB-C のケーブルを2つ接続することになり、外部ディスプレイが2枚の人は USB-C のケーブルを3つ抜き差しが必要なことになります。打ち合わせが多い人になると、この抜き差しの回数も随分な回数になる事が予想されます。

Apple Studio Display は高い!


アップルが最近出した Studio Display という高価なディスプレイがありますが、なかなか買えそうにありません。(199,800円から) でも、昔 Apple Thunderbolt Display を買ったりもしているので買える日が来たらいいな〜って思っていたりもします。

ケーブルの抜き差しを減らすには 1本にまとめる事が大事

では、その方法を考えてみましょう!

一番簡単な方法は、USB給電対応の USB-C ハブを導入する事です。USB給電 については PD と表記されることも多いので、USB-C ハブを探す際には、PD の表記がある USB-C のポートが付いているものを選択しましょう。

USB PD (給電) の W数には注意が必要

MacBook Pro の充電には USB-C から給電することになります。表にまとめると、以下の W数の ACアダプタが同梱されています。



MacBook Air 30W
MacBook Pro 13 61W
MacBook Pro 14 67W - 96W
MacBook Pro 16 140W
MacBook Pro 16( 旧 intel ) 96W

基本は、この W数のものを使う事をオススメします。そんな中で、今回は USB-C ハブの PD (給電) の W数を注目してみると 100W に対応しているものが少なく 60W のものが多い事が分かります。

さらに 140W というのは、まだ無いのではないかと思います。見つけられていません。あったら教えてください。とりあえず、現段階では社内に 140W が必要な MacBook Pro 16 が無い(近いうちにあることになる)ので、100W のものを探すことにします。

Apple Studio Display の説明に「ホスト用アップストリームThunderbolt 3(USB-C)ポート x 1(96Wのホスト充電)」と書かれていました。140W には対応していないが、16インチで使ってはダメと書かれていないので 100W でいいのかもしれません。

ディスプレイが1枚の 27インチ 4K (3840x2160)の場合

この場合には、普通に PD の W数だけ気にしたら大丈夫なので、以下のような製品を使えば OK です。100W対応と書かれているPD と HDMI ポートがあるものを選択ください。


ディスプレイが2枚の 24インチ WQHD (2560x1440) 場合

電源1つのディスプレイ2つで、3本の USB-C の抜き差しが出てくるタイプなので、この人たちを楽にするのが大事ですね。2台のディスプレイをさせる USB-Cハブは多くありません。

Windows なら大丈夫だけど MacOS の場合には USB-C 1本でディスプレイは1つしか繋がらないという OS 側の制限があったりもします。過去 HDMI が2つあるものを買って MacOS ではダメだったこともあります。注意ください。

分かりやすいところでは、USB-C が2つ同時に接続するようなコネクターになっているものを選びましょう。


UWQHD(3440x1440) 場合

HDMI で4K の場合には 3840x2160 か 1920x1080 の 16:9 の解像度であれば大丈夫なのですが、変形の 21:9 のディスプレイの性能を発揮しようとすると実は HDMI では NG で、Displayport 接続になります。 なので、USB-Cハブのディスプレイポートに Displayport が付いているモデルを選択するようにしましょう。

Displayport付き USB-Cハブは数が少ないっぽいです。さらに W数が100W になると選択肢がさらに減ります。


60W でいい場合には、こちらも選択肢に。

社内の外部ディスプレイ&電源環境について

上記を実施し、アップルップルの社内では USB-C接続 1本でディスプレイと電源を皆さんが利用できるような環境となりました。


さらに1席、スタンディングデスクを1席追加し、そこに UWQHD(3440x1440) の大型ディスプレイを置いて立って作業しようかなって思った時にもケーブル1本で対応できるような準備も完了です。