ngrokでWordPress製のサイトを公開する

ご存知の通りWordPressドメイン名をデータベースに入れたりデータベースに入れたりしてるので、ngrokで動かせるようにするのはちょっとやっかい。

なのでどうするか。まあ公式ドキュメントに書いてある。

ngrok – documentation

なお既存の記事などのデータがなければ、2のWP_SITEURL, WP_HOMEをアレするだけでもとりあえずなんとかなる。

また、HTTPSでやる場合はこちらも。

<?php
# wp-config.php

# ...

$_SERVER['HTTPS'] = 'on';

# ...

HTTPとHTTPS両方やる場合どうするかについては調べてない。まあリバースプロキシの後ろでやるときみたいになんらかの環境変数見ればいいのでは?

ngrokで"online ngrok process", "tunnels/ngrok process"はなにを指すか

"online ngrok process"は有効なngrokコマンドの数、"tunnels/ngrok process"はngrokによって転送(トンネル)されているポート数、と考えてよさそう。

つまり、無料版

1 online ngrok process

4 tunnels/ngrok process

ngrok - secure introspectable tunnels to localhost

でも、一つのコマンドで複数のトンネルを立てる形であれば、複数のアプリケーションを通せる。

なおngrokは設定ファイルを複数渡すとマージして使ってくれるっぽいので、

# ~/.ngrok2/ngrok.yml
authtoken: XXXXXXXXXXXXXXXX
# tunnels.yml
tunnels:
  app1:
    proto: http
    addr: 8000
  app2:
    proto: http
    addr: 8001
ngrok start --config ~/.ngrok2/ngrok.yml --config tunnels.yml --all

みたいにすると、トークンはデフォルトの設定ファイルに置いといて、リポジトリに突っ込む設定ファイルには入れない、みたいなことができて便利。

Laravelのartisanのzsh補完書いた

サブコマンドの補完はあったんだけど、ちゃんとオプションの補完までしてくれるのがないので自分で書いてみた。zshわからんしcompsysわからんし、そもそもシェルスクリプトさっぱりなので大変苦労したが、まあ使えるものになってきたので公開。

サブコマンド、オプションはもちろん、一部のオプションの値補完できたり、helpの場合には再度サブコマンド補完に出したりと割と頑張ってる。

GitHub - magai/artisan-completion: laravel artisan completion for zsh

使い方

jq使ってるのでそれだけ用意して。opensslも使ってるんだけど多分入ってると思う。で、普通ならzshの補完はオートロードできるんだけど、artisanはphp artisan ...という形で実行されるという特殊な仕様のためできなかった。

なんというか、このartisanの補完はphpコマンドの補完として実装されていて、php artisanと続いたとき以外は元のphpコマンドの補完に投げるというややこしい実装になっている。これもまた苦労した……。

source artisan-completion.zsh
compdef -d php
compdef _artisan php
zstyle ':completion::*:php:*' use-cache true

compinitした上で、上のように書けばおけ。zplug使ってる人はzplugで入れてもいいかと。

重いartisanコマンドを叩きまくってるので、キャッシュはほぼ必須。

Accessの日付処理はWindowsのロケール設定に依存しているが不完全なので問題を回避できない場合があるっぽい?

もう手もとにOffice 365 Soloなくて(仕事終わったんで解約した)、検証できないのでいろいろアレだけど一応書いておく。

AccessGUIから日付を取得しようとすると、Windowsロケールに依存した形式で返ってくるようなのだが、これを適切に取り扱う方法がない。

タスクバーの時計に曜日を表示したいので日付の短い形式のフォーマットを、yyyy/MM/dd '('ddd')'にしていたところ問題が出たのでいろいろ調べてみたのだが、AccessではWindowsに元から用意されていて選択可能ないくつかのフォーマット以外には対応していないようだ。

たとえば上記の場合日付は、2019/03/15 (金)のような形で表示されるが、これをFormat()の第1引数に入れても無視されるし、CDate()では型が違うとエラーになる。

具体的に試したコード、多分だけどこんな感じだったはず。

SELECT Format(#2019/03/15 (金)#, 'yyyy/MM/dd')

'2019/03/15 (金)'がそのまま返る。Format()関数はどうも、認識できないデータを渡すとそのまま返す?

SELECT CDate(#2019/03/15 (金)#)

これはエラーになる。

Windowsの設定を変更すればもちろん回避できるが。

VirtualBoxで、仮想アプライアンスのエクスポートをCLIでやる

半分くらいまで手動で(GUIで)やってからふと思い付いて調べたら、やっぱりできた。

VBoxManage list vms で名前取って、VBoxManage export <NAME> -o <NAME>.ova みたいな。

拡張子でエクスポートするファイルタイプを指定する形っぽい。.ovfで指定したら.vmdkもいっしょに出てきた。

多分GUI同様--ovf10がデフォルトだろうけど、不安な人は明示的に指定してもいいかも。

2018年に買ってよかったもの5つ

コーヒーメーカーとコーヒーミルと、水出しアイスコーヒー用のボトル

コーヒーメーカーは象印のEC-GB40ていう安いやつ。ドリップでそこまで味変わらんだろうと思ったので、ちゃんとしたドリッパーではなくコーヒーメーカー。じっさいそれで特に問題なくおいしい。

コーヒーミルはHARIOのMSCS-2Bていう手動のやつ。自動のはよさそうなのは高いのしかないし、手動でも困らんだろうと。アイスコーヒーの水出し用に大量に豆挽くときはけっこう困るので、早くも自動の買いたくなってきているが、手入れもしやすいしこれ自体はいい感じ。

水出しアイスコーヒー用のボトルはHARIOのフィルターインコーヒーボトルというやつ。水出しアイスコーヒーはとにかくうまいのでおすすめ。豆の量がそこそこ必要になるのだけ大変だが、その分の価値はある。60gの豆を手で挽いて、3杯分にしかならないのはつらいが。

コーヒーを豆で買うようになって、いろいろ飲み比べたりもして、なかなか充実したコーヒーライフになった。最近は決まったのしか飲まなくなってきているので、もうちょっといろいろ試したい気もするが。

除湿機

雨の日でも洗濯したいが、乾燥機までは厳しいので除湿機。三菱のMJ-120MX-Wってやつ。だいぶ安くなってたとはいえ3万もするし、今まで除湿機使ったことなかったのでどうかなと思ったが、かなり便利だった。雨が続くようなときに困らないのはもちろん、今まで洗濯する前に天気見てするか決めたりしていたのが、ほぼ気にする必要がなくなったことでかなりストレス減った。

地味に部屋の除湿もいい感じ。湿度高い夏場の雨の日とかに床がべたべたしていやな気分になるのを回避できるんだよね。

サブウーファー PM-SUB8

ブックシェルフタイプのスピーカーだけだと低音厳しいのでずっと欲しかった。さすがに低音すごいけど、集合住宅だとちょっと躊躇してしまうくらい出る。ボリュームをスピーカーの半分に、また夜間は使わないなどしてる。早く周りを気にせず音出せる環境にしたい……。

メタルみたいに元々音圧が強いようなのより、3ピースロックバンド的な音の方がサブウーファーのあるなしで違う。

コードレス掃除機

マキタのCL107FDSHWって安いやつ。紙パックで使ってる。うちはだいぶ狭いから一回の掃除機でコード付け替えるのってせいぜい2、3回で済んでたんだけど、それでもそれが0になると快適。ヘッドの性能はいまいちだが、個人的にはそこまで困らない。

Kindle Paperwhite

この辺にいろいろ書いたので割愛。とにかく読書が捗る。

Kindle Paperwhite マンガモデルを一ヶ月くらい使ってみての追加の感想 - 遠い叫び

Laravelでinput:checkboxのデフォルトでのチェックを実装する

ご存知の通りHTMLの仕様バグによりinput:checkboxは未チェック時、nameも送ってくれない。通常なら以下のようにして、フォームエラー時の再チェックを実装する。

<input type="checkbox" name="example" value="1" {!! old('example') == 1 ? 'checked="checked" : '' !!}>

デフォルトが未チェックであればこれで問題ないが、デフォルトでチェック状態にしたい場合はこれでは駄目だ。以下のように、引数なしのold()で、通常のフォーム表示なのか、フォームエラー時にリダイレクトされたのかを判断する。

<input type="checkbox" name="example" value="1" {!! empty(old()) || old('example') == 1 ? 'checked="checked"' : '' !!}>

もちろんこのチェックボックス以外のデータがない場合もempty(old())が真になるが、最低でもCSRFチェック用のフィールドは存在するため問題にはならないはず。

引数なしのold()がなにを返すかについてはドキュメントにはないので、以下のようにソースコードを辿る。

  1. old()Illuminate/Foundation/helpers.php::old().
  2. そこから、Illuminate\Http\Request::old()が呼び出されていて、その実体はIlluminate\Http\Concerns\InteractsWithFlashData::old()
  3. InteractsWithFlashData::old()からIlluminate\Session\Store::getOldInput()が呼び出されている。
  4. getOldInput()ではArr::get()されている。
  5. Arr::get()$keyが空の場合は$arrayをそのまま返している。

意外と道のりが長くてびっくりした。