ソフトウェア/pukiwiki/QRコードの表示 の変更点
更新- 追加された行はこの色です。
- 削除された行はこの色です。
- ソフトウェア/pukiwiki/QRコードの表示 へ行く。
- ソフトウェア/pukiwiki/QRコードの表示 の差分を削除
[[公開メモ]] * 目的 [#vf82d490] pukiwiki 内の重要なリンクについて、 ページを印刷したときにQRコードが表示されるようにしたかったので、 [[Google Chart>https://developers.google.com/chart/]] と [[Bitly>http://bitly.com]] を使って make_pagelink を拡張しました。 * QR コードを表示するには [#yc150815] Google Chart へリンクを張ればOK 例えば、 http://chart.apis.google.com/chart?cht=qr&chld=L%7c1&chs=120x120&chl=http://dora.bk.tsukuba.ac.jp/~takeuchi/ の url へアクセスすれば http://dora.bk.tsukuba.ac.jp/~takeuchi/ を表わすQRコードを画像として得られます。 &ref(http://chart.apis.google.com/chart?cht=qr&chld=L%7c1&chs=80x80&chl=http://dora.bk.tsukuba.ac.jp/~takeuchi/&.png); 詳しい使い方は他のページでいろいろ解説されています→ [[Google:qrコード google]] 本家の解説はこちら: https://developers.google.com/chart/infographics/docs/qr_codes ** 基本的には [#t9149dec] LANG:php $qr_img = '<img src="' . 'http://chart.apis.google.com/chart?cht=qr' . '&chs=80x80&chld=L|1&chl=' . urlencode($url) . '" class="visible-print-inline">'; のようにして画像を html に埋め込めます。 class="visible-print-inline" は bootstrap の css クラスで、印刷時のみ表示するように指定するためのものです。 * pukiwiki ページへのリンク [#j9584b0c] アドレスが長いのでQRコード画像が大きくなってしまいます。 例えばこのページの URL は http://dora.bk.tsukuba.ac.jp/~takeuchi/?%E3%82%BD%E3%83%95%E3%83%88%E3%82%A6%E3%82%A7%E3%82%A2%2Fpukiwiki%2FQR%E3%82%B3%E3%83%BC%E3%83%89%E3%81%AE%E8%A1%A8%E7%A4%BA なので、QRコードは &ref(http://chart.apis.google.com/chart?cht=qr&chld=L%7c1&chs=120x120&chl=http%3A%2F%2Fdora.bk.tsukuba.ac.jp%2F%7Etakeuchi%2F%3F%25E3%2582%25BD%25E3%2583%2595%25E3%2583%2588%25E3%2582%25A6%25E3%2582%25A7%25E3%2582%25A2%252Fpukiwiki%252FQR%25E3%2582%25B3%25E3%2583%25BC%25E3%2583%2589%25E3%2581%25AE%25E8%25A1%25A8%25E7%25A4%25BA&.png); となり、かなり大きく印刷しないと認識されません。 * bitly で url を短くする [#o05fa0c3] url 短縮サービスを使うことでシンプルなQRコードを作成できます。 &ref(http://chart.apis.google.com/chart?cht=qr&chld=Q%7c1&chs=60x60&chl=http%3A%2F%2Fj.mp/1epCc4p&.png); これなら小さめに印刷しても認識できます。 ** bitly の api [#obc2c6ec] こちらを参考に、bitly にアクセスして短縮urlを得るコードを書きました。 http://qiita.com/maruyam-a/items/96c8ad733c770a44117e LANG:php function shorten_url($url) { // to create your own access token, // see http://qiita.com/maruyam-a/items/96c8ad733c770a44117e $access_token = 'xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx'; $api_url = 'https://api-ssl.bitly.com/v3/shorten?' . 'access_token=' . $access_token . '&longUrl=' . urlencode($url); $curl = curl_init(); curl_setopt($curl, CURLOPT_URL, $api_url); curl_setopt ($curl, CURLOPT_RETURNTRANSFER, TRUE); $result = json_decode( curl_exec( $curl ), true ); return $result['data']['url']; } * データベースへ格納する [#sa510877] ページを表示する度に短縮アドレスを bitly に問い合せるのは無駄なので、 一度得た短縮アドレスをデータベースに格納しておくことにしました。 LANG:php function fetch_short_url($url) { $db = new SQLite3('cache/short_urls.sqlite3'); $db->query('CREATE TABLE IF NOT EXISTS short_urls ' . '(url VARCHAR(1024) PRIMARY KEY, short VARCHAR(32));'); $short = $db->querySingle('SELECT short FROM short_urls ' . 'WHERE url=\'' . SQLite3::escapeString($url) . '\';'); if ($short == NULL) { $short = shorten_url($url); $db->query('INSERT INTO short_urls VALUES(\'' . SQLite3::escapeString($url) . '\',\'' . SQLite3::escapeString($short) . '\');'); } $db->close(); return $short; } pukiwiki では cache/ 以下にデータを保持できるので、 cache/short_urls.sqlite3 というデータベースを作成し、 短縮アドレスを格納しています。 こうすることで、一回目の表示では bitly にアクセスするため時間がかかりますが、 二回目以降は高速に表示が可能です。 * qr プラグイン [#w26e2d88] ということで、QRコード表示用のプラグインを作成しました。 plugin/qr.inc.php LANG:php <?php // // pukiwiki用 QRコード プラグイン (qr.inc.php) // Copywrite 2015 Osamu Takeuchi <osamu@big.jp> // // [履歴] // 2015.06.18 初期リリース // // [インストール] // ソースファイルを (pukiwiki)/plugin/qr.inc.php として保存 // // [使い方] // &qr(http://www.example.com/); や &qr([[PageName]]); により、 // 印刷時のみ表示される QRコードを埋め込む // オプションを含めたフルセットの使い方は、 // &qr(AnyString_or_PageName[,chs=L|1][,chld=80x80][,visible]); // function shorten_url($url) { // to create your own access token, // see http://qiita.com/maruyam-a/items/96c8ad733c770a44117e $access_token = 'xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx'; $api_url = 'https://api-ssl.bitly.com/v3/shorten?' . 'access_token=' . $access_token . '&longUrl=' . urlencode($url); $curl = curl_init(); curl_setopt($curl, CURLOPT_URL, $api_url); curl_setopt ($curl, CURLOPT_RETURNTRANSFER, TRUE); $result = json_decode( curl_exec( $curl ), true ); return $result['data']['url']; } function fetch_short_url($url) { $db = new SQLite3('cache/short_urls.sqlite3'); $db->query('CREATE TABLE IF NOT EXISTS short_urls ' . '(url VARCHAR(1024) PRIMARY KEY, short VARCHAR(32));'); $short = $db->querySingle('SELECT short FROM short_urls ' . 'WHERE url=\'' . SQLite3::escapeString($url) . '\';'); if ($short == NULL) { $short = shorten_url($url); $db->query('INSERT INTO short_urls VALUES(\'' . SQLite3::escapeString($url) . '\',\'' . SQLite3::escapeString($short) . '\');'); } $db->close(); return $short; } function plugin_qr_inline() { global $script; $args = func_get_args(); $str_or_bracket = trim(array_shift($args)); $chs = '80x80'; $chld = 'L|1'; $class = ' class="visible-print-inline"'; if (preg_match('/^\\[\\[(.*?)(#[A-Za-z0-9]+)?\\]\\]$/', $str_or_bracket, $match)) { $str = $script . '?' . urlencode($match[1]) . $match[2]; } else { $str = $str_or_bracket; } if (preg_match('/^https?\:\/\//', $str)) { $str = fetch_short_url($str); $chs = '33x33'; $chld = 'Q|1'; } foreach ($args as $arg) { $arg = trim($arg); if (mb_substr($arg,0,4) == 'chs=') $chs = mb_substr($arg,4); if (mb_substr($arg,0,5) == 'chld=') $chld = mb_substr($arg,5); if ($arg == 'visible') $class = ''; } return '<img src="' . 'http://chart.apis.google.com/chart?cht=qr' . '&chs=' . urlencode($chs) . '&chld=' . urlencode($chld) . '&chl=' . urlencode($str) . '"' . $class . '>'; } ?> ** 使用例 [#q78569eb] &qr(任意の文字列,chs=60x60,visible); &qr(任意の文字列,chs=60x60,visible); &qr([[ソフトウェア/pukiwiki/QRコードの表示]],visible); &qr([[ソフトウェア/pukiwiki/QRコードの表示]],visible); &qr([[ソフトウェア/pukiwiki/QRコードの表示]]); &qr([[ソフトウェア/pukiwiki/QRコードの表示]]); ← 印刷時しか表示されません。 正しく表示されるかは印刷プレビューで確かめてください。 * make_pagelink を書き換える [#ja924d7a] pukiwiki では [[目的Page名]] という形で文中に目的ページへのリンクを埋め込みますが、 [[@目的Page名]] のようにページ名の前に @ を付けることにより、 印刷時にQRコードを表示するように改造しました。 LANG:php // Make hyperlink for the page function make_pagelink($page, $alias = '', $anchor = '', $refer = '', $isautolink = FALSE) { $add_qr_code = false; if (substr($page, 0, 1)=='@') { $add_qr_code = true; $page = substr($page, 1); } $link = make_pagelink_without_qrcode($page, $alias, $anchor, $refer, $isautolink); if ($add_qr_code && preg_match('/href="([^"]*)"/', $link, $match)) { require_once(PLUGIN_DIR . 'qr.inc.php'); return $link . plugin_qr_inline($match[1]); } return $link; } function make_pagelink_without_qrcode($page, $alias = '', $anchor = '', $refer = '', $isautolink = FALSE) { ... - 元々の make_pagelink を make_pagelink_without_qrcode と改名して、 新しく作った make_pagelink の中から呼び出します - ページ名の先頭に @ があれば、それを除いて make_pagelink_without_qrcode を呼びます - 作成された html 内の href の値を読み取って qr プラグインを呼び出す という動作です。 * 使い方 [#oe59e086] 例えば、 [[このページへのリンク>@ソフトウェア/pukiwiki/QRコードの表示]] のようにページ名の前に @ を付けて書くと、一見 [[このページへのリンク>@ソフトウェア/pukiwiki/QRコードの表示]] のように普通のリンクができるように見えますが、 印刷しようとすると、上記リンクにQRコードが付きます。 めでたしめでたし。 * Bitly API v4 への対応 [#q8c834f7] - Bitly にログインして Settings から API を選択 - Access Token の項目で Enter Password のフィールドにパスワードを入れて Generate token する - 生成された token をコピーしておく https://www.meganii.com/blog/2020/04/17/bitly-api-migrating-from-v3/ や https://qiita.com/re-24/items/bfdd533e5dacecd21a7a#post%E3%83%A1%E3%82%BD%E3%83%83%E3%83%89%E3%81%AE%E5%AE%9F%E8%A1%8C などを参考に、 LANG: php function shorten_url($url) { $access_token = 'xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx'; $api_url = 'https://api-ssl.bitly.com/v4/shorten'; $header = [ 'Authorization: Bearer ' . $access_token, 'Content-Type: application/json', ]; $data = [ 'long_url'=> $url, ]; $curl = curl_init($api_url); curl_setopt($curl, CURLOPT_POST, TRUE); //POSTで送信 curl_setopt($curl, CURLOPT_HTTPHEADER, $header); // リクエストにヘッダーを含める curl_setopt($curl, CURLOPT_POSTFIELDS, http_build_query($data)); //データをセット curl_setopt($curl, CURLOPT_RETURNTRANSFER, TRUE); //受け取ったデータを変数に $result = json_decode( curl_exec( $curl ), true ); return $result['data']['url']; } * Google Chart API が廃止になったことへの対応 [#u5b9aba1] https://intercord.jp/blog/2024415google-chart-api/ によれば、 http://chart.apis.google.com/chart?chs=500x500&cht=qr&chl=(URL) の代わりに https://api.qrserver.com/v1/create-qr-code/?data=(URL) とすれば良いそうなのですが・・・ - 生成に時間がかかる - QR コードのバージョンを指定できない という問題があるので、現在代替手段を探し中です。 という問題があるのでちょっと使いづらいです。。。 * qrcode.js を使ってブラウザ上で生成する [#m38e0049] https://github.com/davidshimjs/qrcodejs こちらを利用すると javascript を使ってブラウザ上で QR コードを生成可能になります。 ただこのコード 2024/04 次点で9年前から更新されておらず、pull request がたんまり溜まっていました。 - Android 端末でのバージョンチェックに関するバグ - ユニコード対応部分のバグ - SVG をダークカラーで使う際のエッジ処理 - 同じ要素に繰り返し生成する際の初期化処理 - Drawing.clear() で画像を非表示 - QRCodeLimitLength の数え間違い あたりに対応するため - https://github.com/davidshimjs/qrcodejs/pull/273/files - https://github.com/davidshimjs/qrcodejs/pull/170/files - https://github.com/davidshimjs/qrcodejs/pull/137/files - https://github.com/davidshimjs/qrcodejs/pull/82/files - https://github.com/davidshimjs/qrcodejs/pull/248/files - https://github.com/davidshimjs/qrcodejs/pull/258/files - https://github.com/davidshimjs/qrcodejs/pull/31/files - https://github.com/davidshimjs/qrcodejs/pull/74/files を取り込み、また、生成する画像サイズをコンテナとなる div 要素に合わせるため LANG: js this._elImage.style.width = "100%"; // added by osamu@big.jp this._elImage.style.height = "100%"; // added by osamu@big.jp を追加したのが https://dora.bk.tsukuba.ac.jp/~takeuchi/qrcode.js になります。 LANG: php $id = uniqid(); list($width, $height)=explode("x", $chs); list($level, $typeNumber)=explode("|", $chld); return '<span id="'.$id.'" style="display: inline-block; width: '.$width.'px; height: '.$height.'px; border: 8px solid white;"'.$class.'></span><script lang="javascript">{ new QRCode("'.$id.'", {text: "'.$str.'", width: '.($width*10).', height: '.($height*10).', typeNumber: '.$typeNumber.', correctLevel: QRCode.CorrectLevel.'.$level.'}); }</script>'; とすることで QR コードを表示できるようになりました。 * コメント・質問 [#icbe13bd] #article_kcaptcha
Counter: 5194 (from 2010/06/03),
today: 1,
yesterday: 4