Wordmoveでrsync: empty remote が出て同期できなくてハマった

macOS で wordmove 実行時の「rsync: empty remote host」エラーの対処法

原因

macOS のアップデート等により、以下のような状況が発生していた:

  • macOS に標準搭載の rsyncopenrsync)は非常に古く、バージョン 2.6.9 相当
  • wordmove はこの古い rsync を利用しようとしてエラーを起こす
  • Homebrew で新しい rsync(3.x系)をインストールしても、パスの優先順位の関係で古い方が呼ばれていた
  • wordmove -dは問題ないがwordmove -tなどでエラー

解決手順

  1. Homebrew で最新の rsync をインストール
    brew install rsync
    • Homebrew 版 rsync をシステムにリンク
      brew link rsync
    • rsync が正しいパスにあるか確認
      which rsync
      # => /usr/local/bin/rsync になっていればOK
    • バージョン確認(3.x 以上が必要)
      rsync --version
      # => rsync version 3.x.x
    • もしバージョンが変わっていない場合の対処 macOS の標準の古い rsync が優先されている可能性があるので、シェルの設定ファイルに以下を追加し、brew 版のパスを優先させる:
      # ~/.zshrc もしくは ~/.bash_profile に追記
      export PATH="/usr/local/bin:$PATH"
      その後、設定を反映させる:
      source ~/.zshrc # or source ~/.bash_profile
      再度 which rsyncrsync --version を確認して、 /usr/local/bin/rsync かつ 3.x 以上になっていることを確認。
    • Wordmove を再実行
      wordmove pull -e production -t

    この対応で rsync: empty remote host 問題は解消するはずです 💪

    text-align: leftの要素を中央揃えを余計なマークアップなしで実現するアイデア

    ひっさびさに投稿するのだけど、基本メモなので最低限のテストしかしてません。

    よく段落は左揃えだけど、全体としてはセンターに揃えたい、ということはありますよね?私だけ?

    これまではラッパー要素で囲って、inline-block使ってたんですが、ちょっと違う方法思いつきました。

    /* これまでこんな感じ */
    <style>
    .wrapper {
      text-align: center;
    }
    .wrapper > p {
      display: inline-block;
    }
    </style>
    <div class="wrapper">
      <p>ダミーテキストです。ダミーテキストです。ダミーテキストです。<br>ダミーテキストです。</p>
    </div>
    
    /* 思いついたのは */
    <style>
    .left-centered {
      display: flex;
      text-align: left;
    }
    .left-centered::before,
    .left-centered::after {
      content: '';
      flex-grow: 1;
    }
    </style>
    <p class="left-centered">ダミーテキストです。ダミーテキストです。ダミーテキストです。<br>ダミーテキストです。</p>
    

    HTML側がシンプルになり、要素を追加せずに修正対応もできるかな。

    メディア一覧にAltテキストを表示させる

    サポートフォーラムで質問あったので、備忘録として。

    add_filter('manage_media_columns', 'posts_columns_attachment_alt', 1);
    add_action('manage_media_custom_column', 'posts_custom_columns_attachment_alt', 1, 2);
    function posts_columns_attachment_alt($defaults){
    $defaults['post_attachment_alt'] = 'Alt';
    return $defaults;
    }
    function posts_custom_columns_attachment_alt($column_name, $id){
    if($column_name === 'post_attachment_alt'){
    echo get_post_meta($id, '_wp_attachment_image_alt', true);
    }
    }

    参考サイト:
    https://daily.glocalism.jp/2013/03/22/wp-media-add-file-url-column/
    https://chaika.hatenablog.com/entry/2016/06/30/084500

    WordmoveでサブディレクトリにインストールしたWPをFTP経由でpush -d/pull -dができなかった原因と対応

    ローカル環境をVCCWで立ち上げるとWordmoveもインストールされていますので、サーバーとローカルのデータの同期がとても楽ですね。

    WordmoveはSSHとFTPのどちらも対応していて、今回はFTPで接続する必要がありました。

    ルート直下へのWordPress設置ではなく、サブディレクトリ(/wordpress/)への設置をしましたので、Movefileの設定は次のようにしていました。

    local:
     vhost: "http://test.local"
     wordpress_path: "/var/www/wordpress/wordpress"
    
    staging:
     vhost: "http://test.com"
     wordpress_path: "/public_html/wordpress" # use an absolute path here

    これでwordmove push -dをするとエラーでリモートのデータベースに反映されません。

    ▬▬ ✓ Pushing Database ▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬
     remote | write /test.com/wordpress/wp-content/dump.php
     local | download http://test.com/wp-content/dump.php?shared_key=73b11018f2b6797ce265b36d8983489bfc4194ea3e5c114be5b4e39314cef4f03e6646edbbf7a092 &gt; /var/www/wordpress/wordpress/wp-content/remote-backup-1450333959.sql
    /usr/local/rbenv/versions/2.1.2/lib/ruby/2.1.0/open-uri.rb:353:in `open_http': 404 Not Found (OpenURI::HTTPError)

    ぐぐると、Wordmoveのバージョンを1.2.0にダウングレードして対応するということがあったのですが、VCCWでインストールされているものは1.2.0でしたので、関係はなさそうです。

    FTP 経由の wordmove pull で、DB が反映されないバグを解決する方法

    エラーをよく見ていると、サブディレクトリが抜けているのがわかります。これですね。ディレクトリがないので404なんですね。

    local | download http://test.com/wp-content/dump.php...

    仕様なのかバグなのか分からないですが、サブディレクトリはうまくいかないようなので、Movefileのvhostにサブディレクトリを追加してみます。

    local:
     vhost: "http://test.local/wordpress"
     wordpress_path: "/var/www/wordpress/wordpress"
    
    staging:
     vhost: "http://test.com/wordpress"
     wordpress_path: "/public_html/wordpress" # use an absolute path here

    localの方は変えなくても大丈夫かもしれませんが、一応両方合わせておきます。

    これでもう一度wordmove push -dでリモートのデータベースも反映されました。
    たぶんwp_optionのhomeとかも変わってしまいますが、wp-config.phpに次の設定をしておけば大丈夫なはずです。

    便利ですWordmove。

    define( 'WP_HOME', 'http://test.com' );
    define( 'WP_SITEURL', 'http://test.com/wordpress' );

    WordPressのPress Thisで403エラーになるのはロリポのWAFが原因でした

    ワードプレスに標準で付いているPress Thisというブックマークレットを使用すると、他のサイトの閲覧中のページについて簡単に自身のWordPressに投稿できます。

    しかし、ポップアップしたウィンドウで403エラーになってしまいました。403_Error_-_Forbidden

    サーバー側のセキュリティ関係の設定が影響してるかなと推察して、PHPの設定などをみていたのですが、WAF設定のログを参照するとロリポップ!ユーザー専用ページ_-_アクセス制限

    まさにpress-this.phpが検出されていました。ロリポップ!ユーザー専用ページ_-_アクセス制限

    それで、press this wafなんかでぐぐってみると、WAFを無効にしたらいいよみたいな記事があったりするんですが、それはないでしょ、と他をあたっていると、ロリポの兄貴分ヘテムルのサポートページ(WAF設定により403エラーが表示される場合に関しまして)がありました。

    ヘテムルでは『.htaccessによる除外記述』というのをしてやるといいらしいのですが、ロリポにはそういう箇所はありませんでした。しかし先ほどのログの下段にあるurl-php-rfiというのが「検出されたシグネチャ」となっていましたので、ヘテムルと同じように下記一行を.htaccessに追加したら、無事Press Thisで投稿ウィンドウが表示されるようになりました。

    SiteGuard_User_ExcludeSig url-php-rfi

    Video.jsのIE8のFlash fallbackが効かなかった

    簡単にページに動画を追加して、IE8とかの古いブラウザでも見れるようにしてくれるVideo.jsを使ったのですが、IE8でのFlash fallbackが効かず何も表示されないという現象がありました。

    Video.jsのバージョンはv4.12.5です。

    原因はvideoタグに設定したwidthとheightがautoになっていたことでした。レスポンシブ対応のためautoにしていたので、そこはさわれないので、IE8用にCSSを追加して対応しました。

    modernizrを入れていましたので、videoタグに非対応のブラウザではno-videoクラスが付きます。それを使って次のルールを追加でOKでした。

    .no-video .video-js {
    width: 640px !important;
    height: 360px !important;
    }
    

    Parallelsで動かしてるWindows7上のIISで動かしてるASPサイトにMacからアクセスした

    クラシックASPで構築されているサイトのコンテンツ制作のお仕事がありまして、ローカルで制作を行うのに、Windows上のIIS(インターネットインフォメーションサービス)でサーバーを設定してやる必要がありました。

    このサイトのお仕事は以前にも一度したことがあったのですが、Windowsで使うので、エディタとかもWindowsのやつを使ってたんですね。でも、私はいつもMacでCoda2使って作業をしているので、サイト管理とか含めCoda2でできたらいいなと思いながらやっていました。

    それが、今回できてしまったので、かなり快適な制作プロセスになっています。
    Coda2でいつもどおりコーディングしつつ、SafariやiOSシミュレーターでWindows上のIISで動いているサイトを表示確認できているので、もう全くストレスがありません!

    作業環境はMacはOS X 10.10.2、WindowsはParallels Desktop 8上にWindows7を入れて動かしています。

    Windowsの設定

    IISの設定

    制作はMacのCoda2なので、データもMac上においています。
    IISでWebサイトの追加をする際に、物理パスにMac上のフォルダも指定できますので、Windows上にデータがなくても問題ありません。

    iis

    ファイアーウォール

    いくつか解説ページがあったのですが、こちらのページの方法でいけました。
    Access IIS on Windows7 VM from the Mac OS (http://markchouanard.com/post/39426320201/access-iis-on-windows7-vm-from-the-mac-os)

    以下、日本語で手順を書いておきます。

    1. コントロールパネルからWindowsファイアーウォールを開きます。
    2. 左メニューより詳細設定をクリック。
    3. 左メニューの受信の規則をクリック。
    4. World Wide Webサービス(HTTPトラフィック)を右クリックでプロパティを開く。
    5. 「有効」をチェックしてOK。

    firewall

    ネットワークを共有ネットワークに

    Parallelsのメニューで、デバイス-ネットワーク1-共有ネットワークになっていることを確認

    network

    コマンドプロンプトでipconfig

    次にMacでhostsファイルに設定をするためにIPアドレスを確認します。
    スタートメニューから「プログラムとファイルの検索」欄にcmd.exeとタイプしてコマンドプロンプトを開きます。
    ipconfigとタイプしてからreturnすると次のような情報が表示されますので、IPv4アドレスをメモっておきます。

    ipconfig

     Macの設定

    このままでもIPアドレスでページを表示できるのですが、hostsファイルに任意のアドレスを登録してわかりやすくしておきます。hostsファイルは/etc/hostsにありますので、先ほど確認したIPv4アドレスとお好みのドメインを設定してやります。
    ターミナルからでもテキストエディタを開いても、あるいはアプリを使ってもなんでもいいです。
    このあたりはいくらでも設定の仕方はみつかると思います。
    例)10.211.55.6  win.mysite.com

    これでParallels上のIISにMac側からアクセスできるようになりました

    Macのブラウザでwin.mysite.comとタイプすればWindows上のページが確認できます!
    Windowsでも同じURLで表示したいときはWindowsのhostsファイルをへんしゅうしてください。

    Macで複数アプリを一括で起動させるのにAutomatorを使えばよかった

    Web制作をしているといろいろなアプリを使うんですが、作業を始める前にいくつも起動させるのが地味に面倒に思っていました。
    ログイン時に常に起動させたいわけじゃないんだけど、頻繁に使うアプリのセットをまとめて起動できたらいいなという感じです。

    そんな便利アプリないかなとかググってたんですがどうも見つからず、代替方法として、「アプリのエイリアスをまとめて一つのフォルダに入れておいて、全選択をして一気に起動させる」なんていうのがありました。けど、なんかもうちょっとスマートにならんかなと。

    と、思っていたらAutomatorがあるじゃないか、と。閃いたというほど大げさなものでもないんですが。。
    複数のPDFをまとめたりするのにワークフローを使ったりはしてるんですが、正直あまり使うことがないので、長いこと思いつきもしなかったです。

    Automatorを立ち上げて、ファイル-新規を選ぶと書類の種類の選択ダイアログが開きますので、「アプリケーション」を選択します。

    スクリーンショット 2015-02-21 20.59.35

    左のユーティリティ内に「アプリケーションを起動」がありますので、これを右側のペインにドラッグします。
    必要なだけ追加したら保存して、Dockに登録するなりしてやると、一発でいくつものアプリを起動させることができます。

    WordPress:ギャラリー挿入時のデフォルトカラム数を変更してみた

    フォーラムでギャラリーのデフォルトカラム値の変更という質問があって、先日の納品時にもちょっと気になったところだったので、対応を調べてみました。

    galleryショートコードをカスタマイズするにはpost_galleryフィルターでショートコードを丸々書き換えて、デフォルトのカラム数を4とかにすればいいのですが、これだと管理画面でギャラリーを追加する際にプルダウンは3のままなんですよね。で、管理画面でのビジュアルエディターでも3列に並んだままです。

    gallery-column管理画面でのデフォルト値はmedia-editor.jsで設定されていて、javascriptだからフックとかもちろんないので、jQueryでページ読み込み後に上書きします。
    スクリプトの挿入はprint_media_templatesアクションフックを使っています。

    WordPress:PDFとかのファイルサイズを取得して表示するショートコードを公式ディレクトリに公開しました

    以前書いたWordPress:PDFのファイルサイズを取得して表示するショートコードとかPHP:PDFのファイルサイズを取得して表示するのにはまったので解決策をが、このサイトでは(少ないながら)わりと見に来られているようでしたので、以前からちょっとやってみたかったプラグイン申請をしてみました。

    WordPress.orgのPlugin Directory:
    Get Filesize Shortcode

    ショートコードの書式は

    ファイルサイズ:[filesize]http:yoursite.com/path/to/file.pdf[/filesize]
    

    とすると、ファイルサイズ:7 MBとかファイルサイズ:613 kBのように適切な単位のついたファイルサイズが返ってきます。
    PDFに限らず、いろんなファイルのサイズが取得できますので、よかったら使ってください。

    たとえばこの画像のファイルサイズは122 KB

    プラグイン申請はこちらの記事にまるまるお世話になりました。
    0からのWordPress公式ディレクトリ登録〜プラグイン編 #wckansai

    CLIP-MAILをロリポで使おうと思ったらいろいろあったので、メモがてら

    アンケートフォームに画像を添付したいとのご要望をいただいて、今回はKENT-WEBさんのCLIP-MAILというフリーソフトを使用しました。
    使用バージョンは4.01 UTF-Versionです。
    今回ロリポップ!でいくらかトラブルがあって、ググってもわりと古いサポート情報しか見当たらないこともあったので、まとめておきます。

    500エラーで表示されない

    これはロリポに関して言えば、改行コードによるもののようでした。
    .cgiのファイルの改行コードがCR+LFになっているのをすべてLFに変換したら表示されました。

    添付ファイルが確認画面で表示されない

    添付画像をアップロードすると確認画面でサムネイルが表示されるはずなのですが、画像が500エラーでロードされない現象がありました。そのまま送信するとメールにはきちんと画像が添付されています。
    これはディレクトリのパーミッションが原因でした。
    ロリポはsuEXECサーバーになりますので、基本CLIP-MAILの説明ページにある通りuplディレクトリには700を指定していたのですが、707にしないと確認画面でサムネイルが表示できませんでした。

    入力エラー画面で項目の順番がバラバラになる

    必須項目が入力されていない場合などに、それらが後ろにいく仕様になっているようです。

    説明ページに下記のとおり書かれているのですが、これでは解決しませんでした。

    ・制御タグ-3
    → name値の並び順を指定する(半角スペースで複数指定)
    → 入力エラー画面及びメール本文の並びを指定します
    (例)

    <input type="hidden" name="sort" value="name email メッセージ" />

    以下はコアプログラム(clipmail.cgi)をカスタマイズしますのでご注意ください。
    サポートの情報だとわりと端折った中上級者向けの書き方をされていてわかりにくかったので、ちょっと長いですが、該当部分を引用します。
    一箇所目は587行目くらいから。

    #-----------------------------------------------------------
    #  フォームデコード
    #-----------------------------------------------------------
    sub parse_form {
    	my ($clip,@key,@need,%in);
    	foreach my $key ( $cgi->param() ) {
    		my $val;
    
    		# 添付
    		if ($key =~ /^clip-\d+$/) {
    			$val = $cgi->param($key);
    			if ($val) { $clip++; }
    
    		# テキスト系
    		} else {
    
    			# 複数値の場合はスペースで区切る
    			$val = join(" ", $cgi->param($key));
    
    			# 無害化/改行変換
    			$key =~ s/[<>&"'\r\n]//g;
    			$val =~ s/&/&amp;/g;
    			$val =~ s/</&lt;/g;
    			$val =~ s/>/&gt;/g;
    			$val =~ s/"/&quot;/g;
    			$val =~ s/'/&#39;/g;
    			$val =~ s/\r\n/\t/g;
    			$val =~ s/\r/\t/g;
    			$val =~ s/\n/\t/g;
    			$val =~ s/-/-/g;
    			$val =~ s/~/~/g;
    
    			# 文字コード変換
    			if ($cf{conv_code}) {
    				$key = $j->set($key)->utf8;
    				$val = $j->set($val)->utf8;
    			}
    
    			# 入力必須
    # ここからコメントアウト
    #			if ($key =~ /^_(.+)/) {
    #				$key = $1;
    #				push(@need,$key);
    #			}
    # ここまでコメントアウト
    
    # ここから追記
    # 必須入力項目
    if ($key =~ /^_(.+)/) {
    $key = $1;
    push(@need,$key);
    if ($val eq "") { $check++; push(@err,$key); }
    }
    $in{$key} .= "\0" if (defined($in{$key}));
    $in{$key} .= $val;
    next if($key eq 'sort'); ## ←追加
    push(@key,$key);
    # ここまで追記
    
    
    		}
    
    		# 受け取るキーの順番を覚えておく
    		push(@key,$key);
    
    		# %inハッシュに代入
    		$in{$key} = $val;
    	}
    
    	# post送信チェック
    	if ($cf{postonly} && $ENV{REQUEST_METHOD} ne 'POST') {
    		&error("不正なアクセスです");
    	}
    	# 添付拒否の場合
    	if (!$cf{attach} && $clip) {
    		&error("不正なアクセスです");
    	}
    
    	# リファレンスで返す
    	return (\@key,\@need,\%in);
    
    
    }
    

    もう一箇所はその続き部分

    #-----------------------------------------------------------
    #  入力エラー表示
    #-----------------------------------------------------------
    sub err_check {
    	my $match2 = shift;
    
    	# テンプレート読み込み
    	my ($err,$flg,$cell,%fname,%err);
    	open(IN,"$cf{tmpldir}/err2.html") or &error("open err: err2.html");
    	my $tmpl = join('', <IN>);
    	close(IN);
    
    	# テンプレート分割
    	my ($head,$loop,$foot) = $tmpl =~ /(.+)<!-- cell_begin -->(.+)<!-- cell_end -->(.+)/s
    			? ($1,$2,$3) : &error("テンプレート不正");
    
    	# 画面展開
    	print "Content-type: text/html; charset=utf-8\n\n";
    	print $head;
    	my $bef;
    # 一行コメントアウトして、その次の行を追加
    # foreach my $key (@$key) {
    foreach my $key (split(/ /,$$in{sort})) { ## ←追加
    		next if ($key eq "need");
    		next if ($key eq "match");
    		next if ($$in{match} && $key eq $match2);
    		next if ($_ eq "match");
    		next if ($bef eq $key);
    		next if ($key eq "x");
    		next if ($key eq "y");
    
    

    これで

    <input type="hidden" name="sort" value="name email メッセージ" />

    をhtmlのform要素に入れれば指定の順に並びます。

    ログデータをCSVでダウンロードできたりもするので、とても使いやすいファイルアップロード機能付きフォームだと思います。

    Emmet:コードの展開時にID名・クラス名のコメントを常に自動追加するようにカスタマイズしてみた

    HTMLを書くときにdivやulなどのブロック要素のあとにコメントを追加することがありますが、それを自動化しよういうことです。
    下が展開後のイメージです。

    <div id="container">
    	<p class="hoge1"></p><!-- /.hoge1 -->
    	<p class="hoge2"></p><!-- /.hoge2 -->
    	<p class="hoge3"></p><!-- /.hoge3 -->
    	<p class="hoge4"></p><!-- /.hoge4 -->
    </div><!-- /#container -->
    

    OZPAの表4でZen-Coding(Emmet)でコード展開時にクラス名・ID名のコメントを自動追加する方法という記事でコメントフィルターを追記する方法が紹介されていますが、もういっそ全部につけてしまいたいと、|cを入力するのが面倒くさいというわけです。|とか端っこすぎて打ちにくいんです。
    |cをつけるのであれば、上記のコードは展開前の状態ですと、
    div#container>p.hoge$*4|c
    とします。これを展開するとデフォルトではおそらく下のようになるかと思います。

    <div id="container">
    	<p class="hoge1"></p>
    	<!-- /.hoge1 -->
    	<p class="hoge2"></p>
    	<!-- /.hoge2 -->
    	<p class="hoge3"></p>
    	<!-- /.hoge3 -->
    	<p class="hoge4"></p>
    	<!-- /.hoge4 -->
    </div>
    <!-- /#container -->
    

    ちょっと最初の展開後イメージと違いますね。
    コメントが次の行に行っちゃうんですよね。これ、なにげに好きじゃないんです。単に好みなんですけど、やたらと行が増えると見にくい気がして。

    というわけで、今回やることは、

    1. id、class属性がある要素は自動でコメントを追加する
    2. コメントは要素の閉じタグと同じ行に続けて追加する

    の2点です。
    あ、私が使ってるエディタはCoda2ですので、それ前提の話になります。他のエディタでどうするのか細かいことは分かりませんが、基本は同じだと思います。本家ドキュメントをご確認ください。

    まずはカスタマイズ用のディレクトリを作ります

    カスタマイズするファイルは本体のファイルを直接いじるのではなく、カスタマイズ用のディレクトリを作って、その中に新たに作ったjsonファイルを放り込むことになります。ディレクトリはあとでパスをEmmetの環境設定で指定するので、どこに作っても構いません。
    私は下記のパスの通り、Emmetプラグインのパッケージの中のContentsディレクトリ内にHackというディレクトリを作成しました。
    ~/Library/Application Support/Coda 2/Plug-ins/Emmet.codaplugin/Contents/Hack
    なお、すでにsnippets.jsonをカスタマイズして、langをjaに変更したり、スニペットをカスタマイズしている場合はこの工程は飛ばしてください。

    snippets.jsonをカスタマイズして、id、class属性がある要素に自動でコメントを追加する

    先ほど作成したHackディレクトリにあるjsonファイルは、自動的にEmmetに読み込まれますので、ファイル名はなんでも構いませんが、ここではsnippets.jsonとします。
    下記内容のファイルを作成し、Hackディレクトリに保存します。

    {
    	"variables": {
    		"lang": "ja",
    		"locale": "ja-JP",
    		"charset": "UTF-8",
    		"indentation": "\t",
    		"newline": "\r\n"
    	},
    	
    	"html": {
    		"filters": "html,c",
    		"profile": "html"
    	}
    }
    

    前半のvariables部分は今回とは関係ないですが、日本語を使用するときはこれも入れておくことでhtmlタグに入れるlang属性がjaになります。
    キモとなるのはfiltersに設定している”html,c”のcです。デフォルトではここは”filters”: “html”となっているのですが、cを加える事でコメントフィルターを通すことができます。

    Emmetの環境設定でパスを通す

    ここまでで基本的なカスタマイズはできたのですが、このままでは展開してもなにも起こりません。
    カスタマイズしたファイルが入っているディレクトリをEmmetに教える必要があります。
    Coda2のメニューより「プラグイン」-「Emmet」-「Emmet Preferences」を開いて「Extensions path」という欄に先ほどのディレクトリのパスを入力して「Reload Extensions」ボタンを押すとHackディレクトリにあるファイルが読み込まれてカスタマイズが有効になります。

    preferences.jsonを作成し、コメントが要素の閉じタグと同じ行に続けて追加されるようにカスタマイズ

    下記内容のpreferences.jsonを作成して、先ほどのHackディレクトリに保存します。
    その後、Coda2のEmmet Preferencesを開いてReload Extensionsボタンを押すと変更が有効になっているはずです。

    {
        "filter.commentAfter": "<!-- /<%= attr('id', '#') %><%= attr('class', '.') %> -->"
    }
    

    idやclassだけじゃなくて、他の属性もコメントに入れたい(そんなことあるかな?)というときは下記のようにすれば入りますよ。たとえばtitle属性を入れたいとか。。。ないか。

    {
        "filter.commentTrigger": "id, class, title",
        "filter.commentAfter": "<!-- /<%= attr('id', '#') %><%= attr('class', '.') %><%= attr('title', ' title:') %> -->"
    }
    

    もっとカスタマイズできることはたくさんあるみたいですので、Emmetのドキュメントを参照してください。

    WordPress:get_template_part()を子テーマで使った時の優先順位

    別件でTheme Checkプラグインで出てきたNoticeを調べていたときに、下記の記事に行き当たり読んでいたら初めて聞く話だったので書いておきます。

    Understanding get_template_part

    日本語ではこちらの記事に優先順位のことが書かれていますが、情報が古いからか仕様が変わったのか分かりませんが、現在の最新版(WP3.7.1)とは順番が違っているようです。

    WordPressのテーマ制作で、テンプレートのパーツを読みこませるときに、

    get_template_part('content', 'single' );

    のように使用すると、まずcontent-single.phpがあればそれを持ってきて、なければcontent.phpを持ってくるというような動作になります。

    1. content-single.php
    2. content.php

    の順序ですね。
    これが、子テーマを使用している場合にはこうなります。

    1. 子テーマのcontent-single.php
    2. 親テーマのcontent-single.php
    3. 子テーマのcontent.php
    4. 親テーマのcontent.php

    get_template_partが裏で何をしてるのか

    実際にテーマを探してるのはlocate_template()という関数で、get_template_partはそれに渡すためのファイルの配列を用意しています。
    [‘content-single.php’,’content.php’]
    という感じですね。この順番が大事です。
    locate_templateは最初のcontent-single.phpについてSTYLESHEETPATH、つまり子テーマのディレクトリを先に探して、次にTEMPLATEPATH、親テーマのディレクトリを探します。
    どちらもなければcontent.phpをSTYLESHEETPATH、TEMPLATEPATHの順に探します。
    ちなみに、header.phpやfooter.phpを読み込むget_header()やget_footer()もこのlocate_template()関数を中で呼んでいるようです。

    locate_template(Codex)

    WordPress:PDFのファイルサイズを取得して表示するショートコード

    以前PHP:PDFのファイルサイズを取得して表示するのにはまったので解決策をというのを書いたのですが、そのコードはテンプレートファイルからPHPコードで呼び出す前提でした。

    今回はショートコードを使用して、投稿エディターから呼び出すようにしました。
    pdfはwp-contentディレクトリの中にpdfディレクトリを作ってそこに入れている想定です。

    [追記]
    少し改訂したものをプラグイン化して公式ディレクトリに公開しましたのでよかったら使ってください。
    WordPress:PDFとかのファイルサイズを取得して表示するショートコードを公式ディレクトリに公開しました
    WordPress.orgのPlugin Directory:
    Get Filesize Shortcode

    引数はファイル名のみですので、

    ファイルサイズ:[filesize file='hoge.pdf']
    

    のように書けば、
    ファイルサイズ:1.2MB
    のようにファイルサイズが返されます。

    今回PDFにしていますが、他のファイル形式でももちろん問題ありません。

    WordPress:投稿内で記事・固定ページ・カテゴリーページのURLをスラッグを指定して出力するショートコード

    投稿内でシングルページや固定ページ・カテゴリーページヘのリンクを貼ることがありますが、直接パスを書いてしまうと、公開URLの変更やディレクトリの移動などがあった場合にリンクが切れてしまいます。
    ショートコードにしておくとその辺りの作業から開放されるので便利です。

    WP MEMO:投稿内で記事・ページへのリンク・URLを出力する
    こちらのページでidを指定してURLを取得する方法を紹介されていたので参考にさせていただきました。
    ただ、個人的にidを使うのが分かりづらくて苦手なので、スラッグから引っ張ってこれるようにしました。

    引数はシンプルに2つだけ用意しています。

    //全部引数を使うとこうなります
    [permalink type='cat' slug='hoge']
    
    //typeがpageのときは省略できますので最小構成はこうなります
    [permalink slug='hoge']
    
    //固定ページで子ページの場合だけ親ページのスラッグも必要になります
    [permalink slug='parent/hoge']
    
    //使うときはhref属性の中身です。
    <a href="&#91;permalink slug='hoge'&#93;">ほげ</a>
    

    ちょこっと足せばカスタム投稿タイプにも対応できるはずです。

    Concrete5:ブロック内のクラス名だけ変えたカスタムテンプレートの書き方

    『Concrete5 Beginner’s Guide』での勉強続行中です。
    なかなか英語読むのしんどいですが、前に挫折した部分は超えて、前より少し分かってきたかも。

    先にConcrete5:ブロックのテンプレートを単純にラップするカスタムテンプレートを作る方法で、コアにアップデートがあっても大丈夫なカスタムテンプレートの書き方を載せましたが、ラップすると余計なdivを書くことになるので、できればクラス名だけ変えたいということもあるかと思います。

    今回はその方法です。
    例として、オートナビブロックにMy Navというカスタムテンプレートを作成してみます。
    まずblocks/autonav/templates/my_nav/というディレクトリを作成して、その中にview.phpというファイルを作成します。
    本の中ではjQueryでゴニョゴニョしたり、このテンプレート専用のcssを設定することを前提にしていたのでカスタムテンプレート名のディレクトリを作成していましたが、ただクラス名を変更するだけのときは、blocks/autonav/templates/my_nav.phpでもいいと思います。
    今回はmy_navディレクトリにこのテンプレート専用のview.cssも配置する想定です。

    <?php
    $bvt = new BlockViewTemplate($b);
    $bvt->setBlockCustomTemplate(false);
    
    functon my_nav_callback($buffer) {
    	return str_replace('<ul class="nag">','<ul class="my_nav">',$buffer);
    }
    
    ob_start("my_nav_callback");
    include($bvt->getTemplate());
    ob_end_flush();
    ?>
    

    前回のラップの時と似てますが、今回はデフォルトテンプレートを内部バッファに保存して、ulのクラス名を置換してから出力しています。
    これでmy_navというクラス名を使用したスタイルをview.cssに設定することができます。

    Concrete5:ブロックのテンプレートを単純にラップするカスタムテンプレートを作る方法

    デザインワークスオンサイドさんのConcrete5の記事「concrete5 でケーキ屋さんのサイトを作ろう! :: テーマのテンプレートとページタイプのおさらい」に触発されて、途中まで読んで挫折した『Concrete5 Beginner’s Guide』を初めから読みなおしています。

    オンサイドさんの記事はいっつもわかりやすくて勉強になります。おすすめです。

    それで本題です。

    Concrete5でデフォルトのブロックにオリジナルなCSSを適用したいときに、デフォルトブロックをたとえばclass付きのdiv要素でラップします。

    ただ、デフォルトのテンプレートをコピーして、カスタムテンプレートでラップするdivを追加するだけだと、コアのアップデートでデフォルトのテンプレートに変更があったときに反映されません。

    それを防ぐ書き方が『Concrete5 Beginner’s Guide』にありましたので、メモを兼ねて。

    デフォルトの記事ブロックをdiv.content-wrapperで囲ったカスタムテンプレートを作成することにします。

    デフォルトのテンプレートをコピーとかする必要はありません。
    /blocks/content/templates/wrapper.php
    というファイルを作成して、下記コードを書きます。

    <div class="content-wrapper">
    <?php
    $bvt = new BlockViewTemplate($b);
    $bvt->setBlockCustomTemplate(false);
    
    include($bvt->getTemplate());
    ?>
    </div>
    

    3-6行目のphpコードでデフォルトのテンプレートを読み込んで書き出しているだけです。
    こうすることで、もしデフォルトテンプレートに更新があった時でも、カスタムテンプレートにも更新が保証されます。

    WordPress:qTranslate使用時にエディタの高さが低くなってしまった時の対処

    先日WordPressを3.6.1に更新したお客さまのサイトで、投稿欄が狭くなって書きにくいと問い合わせがありました。
    3.5か3.6か分からないですが、投稿欄の右下をドラッグしてサイズを変更すると、それを記憶していて次回以降はその高さで表示されるようになっていたみたいですね。

    ですが、多言語プラグインのqTranslateを使っていると本文欄が100ピクセルに強制的に変更されてしまいます。
    ソースを見るとこんな感じでインラインでスタイルを設定されています。

    qTranslateが書き換えたソース

    とはいえ、!importantを使用されてるわけではないので、管理画面にCSSを追加すれば対処できました。

    functions.phpに

    add_action('admin_head', 'content_textarea_height');
    function content_textarea_height() {
      echo'
      <style type="text/css">
        /*heightじゃなくてmin-heightにすると右下のドラッグが有効のままです*/
        #qtrans_textarea_content_ifr { min-height:450px !important; }
      </style>
      ';
    }
    

    実際には、管理画面用のCSSをすでに用意していましたので、そちらにCSSを書いただけなんですけどね。

    qTranslateはTinyMCEまわりをいろいろいじってるみたいなんで、一番WordPressの更新をするのが怖いプラグインです。(個人の感想です)

    WordPress:shortcodeをtinyMCEのボタンに割り当てるやつ

    自分のサイトに入れてたのにどうやったのか忘れてたので、メモ。

    1.ショートコードを作る。

    2,プラグインAddQuicktagをインストール。設定。

    3.カスタム投稿タイプにも使いたいときには以下のコードをfunctions.phpに

    // add custom function to filter hook 'addquicktag_post_types'
    add_filter( 'addquicktag_post_types', 'my_addquicktag_post_types' );
    /**
     * Return array $post_types with custom post types
     * 
     * @param   $post_type Array
     * @return  $post_type Array
     */
    function my_addquicktag_post_types( $post_types ) {
    
        $post_types[] = 'my_custom_post_type';
    
        return $post_types;
    }