トランスビット
トランスビットの開発ノート Webサイト制作に役立つTipsやトラブルシューティングなどの備忘録

Custom Post Type UIとAdvanced Custom Fields

椿さんが終わったのに、なんで春がやってこないんでしょう……毎日寒い。
そう言えば、皆さん縁起物に買う順番があるって知ってました?
熊手で掻き集め、それをザルですくい、扇子で広げ、最後に俵にして積み上げるんだと、露店のおばちゃんが教えてくれました。
去年は知らなかったので、掻き集めた後、いきなり俵にしてましたwwwww

さて、最近使って便利だと思ったWordpressのプラグイン、そして必要に駆られてできたコードを書いてみます。

カスタム投稿タイプをとカスタムフィールドをプラグインで管理してみる

カスタム投稿タイプもカスタムフィールド(以下CF)も、function.phpに直接ゴリゴリ書いた方が使い回しやすくていいんじゃないのかと思っていたのですが、3つ以上カスタム投稿タイプが必要な案件では、流石に管理が面倒なのでCustom Post Type UIというプラグインを使ったりします。
いろんなサイトで紹介されているだけあって、本当に簡便極まりないですね。
ついでにCFもAdvanced Custom Fields(以下ACF)というプラグイン使ったりするようになりました。
これもまた、いろんな(ry

でもACFの場合、カスタムフィールドを含めた絞り込み検索を実装しようとすると、高確率で煮え湯を飲まされます。超危険!
なぜなら、チェックボックスのように複数値を配列で保存するものは、データがシリアライズされて保存されるため、meta_queryでINが使えないのです。LIKEを使ってもいいのですが、複雑な検索要件ならお手上げです。
ACFにこだわらず、配列をシリアライズせずに値をユニークに保存してくれる別のプラグイン(例えばSmart Custom Fields)などもあるので、大人しくそっちを使っとけば万事解決なわけですが、ユーザープロフィールへのCF配置ができるプラグインって、ACFくらいしか見かけません……。

そこで、よーく考えてみました。

要は、ACFでチェックボックスのCFを実現しようとするからいけないんです。
チェックボックスのCFは、function.phpにゴリゴリ書けばいいんです。

ということで、ユーザープロフィールにチェックボックスのCFを設置するコードの中で、個人的に一番悩んだ保存方法を覚書き。

// ユーザー情報追加項目(好物情報)の保存
add_action( 'edit_user_profile_update', 'update_extra_profile_fields' );
function update_extra_profile_fields( $user ) {
  $user_id = $_POST['user_id'];
  $food = $_POST['food'];

  if( !empty( $food ) ) {
    delete_user_meta( $user_id, 'food', '' ); // まずは全消し
    foreach ( $food as $foods )
      if( $foods != '' ){
        add_user_meta( $user_id, 'food', $foods, false );
      }
  } else {
    delete_user_meta( $user_id, 'food', '' );
  }
}

要は、値の個数分add_user_meta()してやればいいんですね。表示する場合も同じように、個数分get_user_meta()すればいいわけです。
今回もwordpressのCodecとフォーラムの過去ログにお世話になりました。
毎回質問してみようかと思うんだけど、答えの近似値って探せばある……ありがたいことです。

Filed under:

PackageResourceViewerでパッケージ内容を書き換える

忙しい時って不思議な行動を取ってしまいます。
役に立ちそうで何の役にも立たない、いわゆる現実逃避の話です。その現実逃避も、年を経る毎に変化してきました。

15年前 → PC重くて作業に支障でる、デフラグしよう!
10年前 → 標準使用だからダメなのかも、Extention探そう!
5年前 → くぁwせdrftgyふじこlp……zzz(育児疲れで寝落ち)
今 → まえやったあれ、ブログに書いとこう!

さて、先日の記事に出てきたSublime Text 3には、たくさんのパッケージがあります。
そのパッケージの中身をごにょごにょしたい時には、PackageResourceViewerを使うと良いらしいです。
私の場合、Japanizeで日本語してあるSublimeTextに、SideBarEnhancements入れてサイドバー拡張したら、サイドバーの表記が英語になっちゃって使いこなせなかったので、そこを日本語化するためだけにインストールしました。
ちなみに、Side Bar.sublime-settingの変更では効かなかったので、PackageResourceViewerからSideBarEnhancementsを開いて、Side Bar.sublime-textを下記に変更。
なんにもないだろうけど、なんかあったら嫌なので、もともとあった分はコメントアウトして下記を追加しました。ついでにドネーション部分も削ってしまいました。
SideBarEnhancementsの作者さん、ごめんなさい。

[
  {"caption":"-", "id":"side-bar-start-separator"},
  { "caption": "新規ファイル作成",        "id": "side-bar-new-file",         "command": "side_bar_new_file",         "args": {"paths": []} },
  { "caption": "新規フォルダ作成",       "id": "side-bar-new-directory",       "command": "side_bar_new_directory",       "args": {"paths": []} },
  { "caption": "-",                 "id": "side-bar-new-separator"},

  { "caption": "編集",              "id": "side-bar-edit",             "command": "side_bar_edit",             "args": {"paths": []} },
  { "caption": "開く / 実行",              "id": "side-bar-open",             "command": "side_bar_open",             "args": {"paths": []} },
  { "caption": "ブラウザで開く",              "id": "side-bar-open-in-browser",             "command": "side_bar_open_in_browser",             "args": {"paths": []} },
  { "caption": "新しいウィンドウで開く",              "id": "side-bar-open-in-new-window",             "command": "side_bar_open_in_new_window",             "args": {"paths": []} },
  { "caption": "Open With Finder",              "id": "side-bar-open-with-finde",             "command": "side_bar_open_with_finder",             "args": {"paths": []} },
  { "caption": "プログラムから開く",        "id": "side-bar-files-open-with",

    "children":
    [

      { "caption": "-",                  "id": "side-bar-files-open-with-edit-application-separator"},
      { "caption": "設定", "id": "side-bar-files-open-with-edit-applications", "command":"side_bar_files_open_with_edit_applications","args": {"paths": []} },
      { "caption": "-",                  "id": "side-bar-files-open-with-edit-applications-separator"}

    ]
  },
  { "caption": "フォルダを開く",            "id": "side-bar-reveal",           "command": "side_bar_reveal",           "args": {"paths": []} },

  { "caption": "-",                 "id": "side-bar-edit-open-separator" },

  { "caption": "ファイル内容の検索・置換", "id": "side-bar-find-selected",    "command": "side_bar_find_in_selected", "args": {"paths": []} },
  { "caption": "プロジェクト内の検索", "id": "side-bar-find-in-project",    "command": "side_bar_find_in_project", "args": {"paths": []} },
  { "caption": "詳細検索", "id": "side-bar-find-advanced",
    "children":
    [
      { "caption": "親フォルダ内",   "id": "side-bar-find-parent",      "command": "side_bar_find_in_parent",   "args": {"paths": []} },
      { "caption": "-",         "id": "side-bar-find-parent-separator"},
      { "caption": "このプロジェクトフォルダ内",  "id": "side-bar-find-project-folder",     "command": "side_bar_find_in_project_folder",   "args": {"paths": []} },
      { "caption": "全てのプロジェクトフォルダ内",  "id": "side-bar-find-project-folders",     "command": "side_bar_find_in_project_folders"},
      { "caption": "-",         "id": "side-bar-find-project-separator"},
      { "id": "side-bar-find-in-files-with-extension",     "command": "side_bar_find_in_files_with_extension",   "args": {"paths": []}},
      { "caption": "In Paths Containing…",   "id": "side-bar-find-files-path-containing",      "command": "side_bar_find_files_path_containing",   "args": {"paths": []} }

    ]
  },
  { "caption": "-",                 "id": "side-bar-find-separator"},
  { "caption": "切り取り",               "id": "side-bar-clip-cut",         "command": "side_bar_cut",              "args": {"paths": []} },
  { "caption": "コピー",              "id": "side-bar-clip-copy",        "command": "side_bar_copy",             "args": {"paths": []} },
  { "caption": "名前のコピー",         "id": "side-bar-clip-copy-name",                     "command": "side_bar_copy_name",                         "args": {"paths": []} },
  { "caption": "ファイルパスのコピー",         "id": "side-bar-clip-copy-path",    "command": "side_bar_copy_path_absolute_from_project_encoded",        "args": {"paths": []} },
  { "caption": "Copy Dir Path",     "id": "side-bar-clip-copy-dir-path",                     "command": "side_bar_copy_dir_path",                         "args": {"paths": []} },
  { "caption": "テキストとしてコピー",      "id": "side-bar-clip-copy-as",
    "children":
    [
      { "caption": "Relative Path From View Encoded",         "id": "side-bar-clip-copy-path-relative-from-view-encoded",    "command": "side_bar_copy_path_relative_from_view_encoded",        "args": {"paths": []} },
      { "caption": "閲覧地点からの相対パス",                 "id": "side-bar-clip-copy-path-relative-from-view",            "command": "side_bar_copy_path_relative_from_view",                "args": {"paths": []} },
      { "caption": "-",                                       "id": "side-bar-clip-copy-path-relative-from-view-separator"},

      { "caption": "Relative Path From Project Encoded",         "id": "side-bar-clip-copy-path-relative-from-project-encoded",    "command": "side_bar_copy_path_relative_from_project_encoded",        "args": {"paths": []} },
      { "caption": "プロジェクトからの相対パス",                 "id": "side-bar-clip-copy-path-relative-from-project",            "command": "side_bar_copy_path_relative_from_project",                "args": {"paths": []} },
      { "caption": "-",                                          "id": "side-bar-clip-copy-path-relative-from-project-separator"},

      { "caption": "Absolute Path From Project Encoded",         "id": "side-bar-clip-copy-path-absolute-from-project-encoded",    "command": "side_bar_copy_path_absolute_from_project_encoded",        "args": {"paths": []} },
      { "caption": "プロジェクトからの絶対パス",                 "id": "side-bar-clip-copy-path-absolute-from-project",            "command": "side_bar_copy_path_absolute_from_project",                "args": {"paths": []} },
      { "caption": "-",                                          "id": "side-bar-clip-copy-path-absolute-from-project-separator"},

      { "caption": "URIとしてのパス",                  "id": "side-bar-clip-copy-path-encoded",             "command": "side_bar_copy_path_encoded",                 "args": {"paths": []} },
      { "caption": "ファイルパス",                          "id": "side-bar-clip-copy-path",                     "command": "side_bar_copy_path",                         "args": {"paths": []} },
      { "caption": "-",                             "id": "side-bar-clip-copy-path-separator"},

      { "caption": "エンコードされた名前",                  "id": "side-bar-clip-copy-name-encoded",             "command": "side_bar_copy_name_encoded",                 "args": {"paths": []} },
      { "caption": "-",                             "id": "side-bar-clip-copy-name-encoded-separator"},

      { "caption": "URL",                           "id": "side-bar-clip-copy-url",             "command": "side_bar_copy_url",                 "args": {"paths": []} },
      { "caption": "-",                             "id": "side-bar-clip-copy-url-separator"},

      { "caption": "aタグを使用してコピー",                         "id": "side-bar-clip-copy-tag-a",                    "command": "side_bar_copy_tag_ahref",                  "args": {"paths": []} },
      { "caption": "imgタグを使用してコピー",                       "id": "side-bar-clip-copy-tag-img",                  "command": "side_bar_copy_tag_img",                    "args": {"paths": []} },
      { "caption": "scriptタグを使用してコピー",                    "id": "side-bar-clip-copy-tag-script",               "command": "side_bar_copy_tag_script",                 "args": {"paths": []} },
      { "caption": "スタイルシートのリンクタグとしてコピー",                     "id": "side-bar-clip-copy-tag-style",                "command": "side_bar_copy_tag_style",                  "args": {"paths": []} },
      { "caption": "-",                             "id": "side-bar-clip-copy-tag-separator"},
      { "caption": "プロジェクト全てのフォルダパスを一括コピー",               "id": "side-bar-clip-copy-project-directories",          "command": "side_bar_copy_project_directories",            "args": {"paths": []} },
      { "caption": "-",                             "id": "side-bar-clip-copy-project-directories-separator"},
      { "caption": "ファイル内テキストをUTF-8でコピー",               "id": "side-bar-clip-copy-content-utf8",             "command": "side_bar_copy_content_utf8",               "args": {"paths": []} },
      { "caption": "ファイル内容をデータURIとしてコピ―",           "id": "side-bar-clip-copy-content-base-64",          "command": "side_bar_copy_content_base64",             "args": {"paths": []} }
    ]
  },

  { "caption": "貼り付け",             "id": "side-bar-clip-paste",       "command": "side_bar_paste",            "args": {"paths": [], "in_parent":"False"} },
  { "caption": "親フォルダに貼り付け",   "id": "side-bar-clip-paste-in-parent",       "command": "side_bar_paste",            "args": {"paths": [], "in_parent":"True"} },
  { "caption": "-",                 "id": "side-bar-clip-separator" },
  { "caption": "名前を付けて複製",         "id": "side-bar-duplicate",        "command": "side_bar_duplicate",        "args": {"paths": []} },
  { "caption": "-",                 "id": "side-bar-duplicate-separator" },

  { "caption": "名前の変更",           "id": "side-bar-rename",           "command": "side_bar_rename",           "args": {"paths": []} },
  { "caption": "ファイルを移動する",             "id": "side-bar-move",             "command": "side_bar_move",             "args": {"paths": []} },
  { "caption": "-",                 "id": "side-bar-rename-move-separator" },

  { "caption": "削除",            "id": "side-bar-delete",           "command": "side_bar_delete",           "args": {"paths": []} },
  { "caption": "Empty",            "id": "side-bar-emptry",           "command": "side_bar_empty",           "args": {"paths": []} },
  { "caption": "-",                 "id": "side-bar-delete-separator" },

  { "caption": "フォルダを再読み込み",           "id": "side-bar-refresh",          "command": "refresh_folder_list" },
  { "caption": "-",                 "id": "side-bar-refresh-separator" },
  { "caption": "プロジェクト",            "id": "side-bar-project",
    "children":
    [
      { "caption": "プロジェクトの編集", "id": "side-bar-project-open-file",      "command": "side_bar_project_open_file",           "args": {"paths": []} },
      { "caption": "Edit Projects Preview URLs", "id": "side-bar-project-preview-url",      "command": "side_bar_project_open_project_preview_urls_file",           "args": {"paths": []} },
      { "caption": "-",                         "id": "side-bar-project-open-file-separator" },
      { "caption": "Promote as Project Folder", "id": "side-bar-project-item-add",     "command": "side_bar_project_item_add",        "args": {"paths": []} },
      { "caption": "Exclude From Project",      "id": "side-bar-project-item-exclude",   "command": "side_bar_project_item_exclude",        "args": {"paths": []} },
      { "caption": "-",                         "id": "side-bar-project-item-separator" },
      { "caption": "プロジェクトからフォルダを取り除く", "id": "side-bar-project-item-remove-folder", "command": "side_bar_project_item_remove_folder", "args": { "paths": []} },
      { "command": "prompt_add_folder", "caption": "Add Folder to Project…", "mnemonic": "d" }

    ]
  },
  { "caption": "-",                 "id": "side-bar-end-separator" }
 ]

これでよし!

Filed under:

Sublime Text 3(Compass+sass)のある暮らし

様々なサイトで絶賛されている高機能エディタ、Sublime Text。
恋に落ちるエディタってすごい二つ名だなと思いますが、嘘じゃありません。

遅ればせながら一年ほど前、疑心暗鬼でRubyをインストールし、初めてSassのSCSS記法を使ったcssを書き始めた一時間後……爆速コーディングとSublime Textの拡張性の高さと安定っぷり(作業中に落ちないってほんと重要!)に衝撃を受け、私も漏れなくSublime Textとの恋に落ちました。

ちなみに、それまでコーディングにはDreamweaverとサクラエディタを使用。
サクラエディタは10年ほど使いました。これ、インストールは圧縮ファイルの展開のみなので、レジストリ汚染しません。
昔、他所に出向いて作業することが多々あったため、インストールフォルダそのものをコピーしてUSBメモリに入れておけば、どこにいっても自分好みにカスタマイズしてある高性能エディタを使えるというのは、非常にありがたかったです。
でも、今はもう他所での作業もないし、Sublime Text 3があるのでアンインストール済み。今までありがとうノシ

Sublime Textの特徴

Sublime Textの良いところ

  1. 動作が軽い
  2. 挙動が安定している
  3. パッケージ(プラグイン)が豊富
  4. コンパイルも簡単
  5. 作業管理(プロジェクト)ができる
  6. 前回開いていたプロジェクトとファイルを覚えてくれてるから、次回作業開始がスムーズ
  7. 使用制限がなく無料で使える

Sublime Textのイマイチなところ

  1. プレビュー機能がなく、プレビューから修正ができない
  2. sassの記述が増えてくると、Compassのコンパイルが遅い

本当は、Sublime TextとChromeにEmmet Live Styleを入れると、デベロッパーツールからcssの修正がDreamweaverライクにできるのですが、私はSassを使ってcss書いているので、直接Sassを修正できないと意味がありません。デベロッパーツールのベータ版使えばSassに対応可能とかそんな感じの記事を見て試したものの、どうにもうまくいかなかったので再挑戦予定です。

後は、Compassのコンパイルが遅いのをどうにかしたい……といっても、三分の一くらいは私のsassの書き方が悪いせいかも。
Sassを使い出してから、ネストでのセレクタ指定にやたら頼るようになり、cssが不細工になってきてます。
IE7やIE8への対応案件が減ってcss3で疑似クラスが使用可能になり、レスポンシブの案件が増え、スマホの時は~とか、タブレットではこうだから~とか考えながら書いてると、classの命名にまで頭が回らず、「あーも-、ここは取りあえずセレクタをネストして書いとくか」と、楽な方楽な方に流れていった結果ですね。
……コーディングのみの案件も出てきたし、今後はBEMっぽい命名規則を意識しようと思います。

ちなみに、BEMについてはこの二つの記事がとっても参考になり、且つしっくりきました。
実践 めんどうくさくない BEM
CSSをキレイに書くを追求すると行き着く「OOCSS」、「BEM」

コンパイルにCompassじゃなくてGruntを使う方法があるらしいので、そっちも試さないと……。

Filed under:

ファイル名を取得して現在地表示

拡張子付、拡張子なし、ファイル名取得用の変数はどっちも便利。
私の場合、現在地表示に使うことがほとんどです。
トランスビットの外の人のデザインにもよりますが、親カテゴリに対して現在地表示をするものの場合、[ 親カテゴリ名_hoge.html ]のように、親の名を子に継承した形でファイル名付けておけば、あとは条件文をちょっと変えてやるだけでOK。

var url = window.location.href;
var filename = url.match(".+/(.+?)([\?#;].*)?$")[1]; // 拡張子付
var filename_only = url.match(".+/(.+?)\.[a-z]+([\?#;].*)?$")[1]; // 拡張子なし

//リスト形式のナビゲーションに現在地表示のためのclassを付与
  $('nav li a').each(function() {
    var $href = $(this).attr('href');
    if ($href.match(filename)) {
      $(this).parent().addClass("current"); // liに付与
    }
  });

なんで最近、現在地表示用のscript書いたり書かなかったりするんやろ……と、よくよく考えてみたら、Wordpress案件の時は、端から付与されているclassを利用したり、phpで処理してしまうからなんですね。得心しました。

Filed under:

WordPressのカスタマイズ時に便利なvar_dump()

はじめまして、トランスビットの中の人です。

トランスビットのサイトリニューアルから、早半年以上・・・。
この開発ノートのページデザインは随分前(多分リニューアル後一週間以内w)に外の人が上げていたようですが、忙しさにかまけて作るのをほったらかしにしてたら、今日の昼食後、トランスビットの外の人に諌められました。

外)「そろそろ、ウチのサイトのブログ仕上げて書き始めて」
中)「なんで?やっぱブログ書いとくと『サイトに箔が付くっ!』とか?」
外)「……『前どうやったっけ?』ってことがなくなるやろ」

……ついに、「忘れた」とか「覚えてない」とかの言い訳が使えなくなるようです。むごい。
とりあえずデザインの再現ができた気がするので、テスト投稿でない一発目の記事を投稿してみます。

PHPの関数 var_dump()

説明:この関数は、指定した式に関してその型や値を含む構造化された情報を 返します。配列の場合、その構造を表示するために各値について再帰的に 探索されます。
PHP 5 では、オブジェクトのすべての public、private および protected なプロパティが出力されます。

WordPressのカスタマイズで、queryで取れているデータの詳細な内容を知りたい時、<pre>タグを使って確認すると、改行が入って便利。
カテゴリ名やら親子関係やら取れたデータの総数やら、色々なことがわかります。
$argsについては省略。

<?php $the_query = new WP_Query($args); ?>
<pre>
<?php var_dump( $the_query ); ?>
</pre>

これで、『……前どうやったっけ?ってことがなくなる』ハズ。

Filed under: