かもメモ

自分の落ちた落とし穴に何度も落ちる人のメモ帳

WordPress ContactForm7 動的なオリジナルのフォームタグを作りたい。

WordPressでサイトを作る時のフォームの定番Contact Form 7はすごく便利なのですが、カスタム投稿から動的にselectタグを作るなどカスタマイズしたタグが欲しいことがあります。

ゴール (作りたいフォームタグ)

f:id:kikiki-kiki:20170730234424p:plain
例えばこんな感じに、タレント(talent)というカスタム投稿タイプを作成して所属するアイドルを登録して
フォームでは、お仕事を依頼するタレントを選べるようにしたいような場合。

タレントを登録・削除するたびに、フォームのセレクトタグのvalueの値を変更するのはメンドーだし、ジョニー先生に任せた時に上手く運用できるか怪しいので、タレントの登録情報を動的に取得してセレクトタグを出力できると運用の手間も減ってハッピーになれそうです。

※ カスタム投稿タイプの登録は割愛します

Contact Form 7 のカスタムフォームタグ・フォーム登録画面で使えるショートコードを作成する

Contact Form 7 は管理画面からショートコードを使ってフォームを作成できるので、同じようにショートコードのフォーマットでカスタムフォームタグを生成出来るようにしたいと思います。

どうやら wpcf7_add_form_tag と言う関数でショートコードと実際のフォームでどのように出力するかを決めているようでした。

contact-form-7/includes/form-tags-manager.php
function wpcf7_add_form_tag( $tag, $func, $features = '' ) {
  $manager = WPCF7_FormTagsManager::get_instance();
  return $manager->add( $tag, $func, $features );
}
note. Contact Form 7 バージョン 4.8.1
  • 第1引数が ショートコード
  • 第2引数が 実際のフォームに出力する際に呼ばれる関数
  • 第3引数が 使用できるオプション?

な感じっぽいです。

各フォームタグがどのように作られているかはcontact-form-7/modules/の中にあるtext.phpなどフォームパーツごとのファイル参考にしてカスタムフォームタグを作成していきます。今回はselectタグを作成するので contact-form-7/modules/select.php を参考に、 下の画像の感じで select_talent_list という名前のショートコードでタグが出力できるようにしたいと思います。👇

f:id:kikiki-kiki:20170731011733p:plain

functions.php にコードを記述します。

<?php // functions.php
// Contact Form 7 が導入されていて wpcf7_add_form_tag が有効な場合のみ
if( function_exists('wpcf7_add_form_tag') ) {
  // ※タグを出力するfunctionを先に記述していないと上手く動作しない
  function make_talent_select_tag($tag) {
    // 基本的な設定は参考にするタグの出力の仕方を参考に
    $t = new WPCF7_Shortcode($tag);
    $atts = [];
    $class = wpcf7_form_controls_class( $tag->type );
    $atts['class'] = $tag->get_class_option( $class );
    $atts['id'] = $tag->get_id_option();
    $atts['name'] = $tag->name;
    $name = sanitize_html_class( $atts['name'] );

    if ( $tag->is_required() ) {
      $atts['aria-required'] = 'true';
    }

    $atts['aria-invalid'] = $validation_error ? 'true' : 'false';
    
    // デフォルト選択 selected:値 というオプションがあれば該当するoptionタグを selected にする    
    $default = $tag->get_option( 'selected', '', true );

    // first_as_label オプションで先頭を未選択状態の文字を表示できるようにする
    $first_as_label = $tag->has_option( 'first_as_label' );
    $values = $tag->values;
    
    $options = '';
    if( $first_as_label && count($values)) {
      $options = '<option value>' . esc_html($values[0]) . '</option>';
    }

    // タレント名一覧を取得してセレクトタグのオプションにする
    $talents = get_talent_name_list();
    foreach($talents as $val) {
      $value = esc_attr($val);
      $selected = "";
      // デフォルト選択に該当している場合 selected 属性を出力する
      if( $default == $value) {
        $selected = ' selected="selected"';
      }
      $options .= '<option value="' . $value . '"' . $selected . '>' . esc_html($val) . '</option>';
    }

    $atts = wpcf7_format_atts( $atts );
    $html = sprintf(
      '<span class="wpcf7-form-control-wrap %1$s"><select %2$s>%3$s</select></span>',
      $name, $atts, $options
    );

    // 出力するタグのHTMLを返す
    return $html;
  }

  // ショートコードなどを登録
  wpcf7_add_form_tag(['select_talent_list', 'select_talent_list*'],
    'make_talent_select_tag',
    [
      'name-attr' => true,
      'selectable-values' => true,
    ]
  );

  // バリデーションは 元の select のものを利用
  add_filter( 'wpcf7_validate_select_talent_list', 'wpcf7_select_validation_filter', 10, 2 );
  add_filter( 'wpcf7_validate_select_talent_list*', 'wpcf7_select_validation_filter', 10, 2 );
}

// カスタム投稿タイプ `talent` のタイトル(名前)を返す
function get_talent_name_list() {
  $data = [];
  $args = array(
    'post_type'      => 'talent',
    'post_status'    => 'publish',
    'posts_per_page' => -1,
    'orderby'        => [
      'menu_order' => 'ASC',
      'date' => 'ASC',
    ],
  );
  $the_query = new WP_Query($args);
  if ( $the_query->have_posts() ) {
    while ( $the_query->have_posts() ) {
      $the_query->the_post();
      $talentName = get_the_title();
      $data[] = $talentName;
    }
  }
  // reset query
  wp_reset_postdata();
  return $data;
}

ざっくり作ってあるので、ショートコードにvalueを追加しても無視したり、他にあるオプションが使えなかったりしますが、

[select_talent_list <name> id:<id属性> class:<追加するclass> first_as_label "未選択状態に表示される文字"]

というショートコードでカスタム投稿タイプ talent 一覧を選択できるselectタグを作成することができました!

カスタム投稿タイプを変更すると、フォームタグが動的に変わる!

タレントに ジョニー別府 を追加・保存して、フォームをリロードすると…
f:id:kikiki-kiki:20170731010516p:plain

_人人人人人人人人人人人人人人人人人人人人人_
> 自動的に「ジョニー別府」が追加されます <
 ̄YYYYYYYYYYYYYYYYYYYY

元のselectタグのバリデーションを利用しているので、
[select_talent_list* first_as_label "---"] の様に入力必須にすれば未選択時にはちゃんとエラーが表示されました!
わーい! 

まとめ

プラグインの仕様が変わるとコードを更新しなければならなかったりしてくると思いますが、簡単に独自のフォームタグを作成することができるし、フォームパーツの出力はコードでどんなふうにもできるので、カスタム投稿だけでなく、タクソノミーを取得するとか色々と動的に更新されるフォームパーツを作ることができそうです!


[参考]

アイカツ! フォトonステージ! ! イラストコレクション

アイカツ! フォトonステージ! ! イラストコレクション

MVNO DMM モバイルにしてて助かった話。

いま気胸で入院をしている病室からこの記事を書いています。さっきまでCT撮ってましたw
病室に21世紀にもなって基本的人権であるネット環境・wifiが無いのでモバイル端末のデザリングをしている状態です。(Japaniはビジネスホテルでも未だにネット無いところも多いのでインターネッツ権の後進国でありましょう!)

そのモバイル端末ですが、長らく ぷららLTEモバイル を使っていました。

しかし、ぷららからLTEモバイルサービス終了が発表され、同グループでのオススメの移転先プランの通知を貰ったのですが容量無制限プランは無ありませんでした。電話は自分からは殆どかけないし外出時以外は自宅のwifiなので、これを期にランニングコストを下げようと思い最近格安プランに惹かれてiPadに試験導入したDMMのSIMが思ったより快適だったのでメインのモバイル端末もDMMに変更していました。

今回DMMに変更しておいて良かった。と実感たのでこの記事を書くことにしました。

それでは、DMMの回し者のようなDMMモバイルにして良かった点の話。
行ってみましょー!

回線速度が速い!

新幹線の中でも快適に繋がります。
今までは新幹線だけでなく、ローカルの電車内でもTwitterの画像が全然表示されませんでした。早くえっちなイラスト(予想)みたいのに!!!! となる事もあったのですが、DMMに変えてからは移動中でも快適ついったライフが送れています!
今思えばぷららLTEが遅すぎたのかもしれません…w

ど田舎ちほーだから恐らくDMMモバイルを使っている人も少ない事もあり速度的な不満を感じたことはありません。
東京に行った時お昼帯は少しもっさりするなーと思いましたが、ぷららの時はもっと遅かったのであまりストレスには感じませんでしたw
(幸せの沸点を下げておくと不幸が減るのです!)

余った容量が翌月に持ち越せる!

DMMにした一番の決め手がこれでした。
初めての容量制限ありだったので自分の使用料をあまり把握しておらず若干の不安があったのですが、余った分の容量を貯金のように持ち越せるので仕事柄 自宅での作業が多く容量が余ることが結構あるので、遠征や出張の予定が入っている時も容量の貯金があると精神衛生にも良いです!

また、残りの容量はWEBサイトから簡単に確認できるので毎月請求の際に貯金はどれだけあるかなぁ〜と確認しています。

ネットから簡単に容量を追加できる

WEBだけで完結できて楽ちん。
今入院していて身動きがとれないのにモバイルの容量をガンガン使っている状態でどうしよう…と思っていたのですが、DMMにログインしてモバイルの管理画面を見に行くと容量を追加するボタンが有り、そこから追加したい容量を選んで確認ボタンをクリックするだけでクレジットカードの入力も必要なく容量を追加することが出来ました!
f:id:kikiki-kiki:20170721152019p:plain

それも翌月への繰越なしなら1000MB 480円ワンコイン以下なのでとても助かっています。
これでアマプラやabemaTVでもアニメが見れるぞ!

結構繋がる

先日下の画像のようなグンマーちほーの奥地に行ってきたのですが、軒並み a◯ 回線が圏外な中 そこそこの電波拾いっぷりを発揮しました!
f:id:kikiki-kiki:20170724130413p:plain あれ?結構繋がるんやん!!!!  

請求書が発行できる

クレジットカードの明細がDMMって付くのでアレって意見もありますが、
ちょっと遷移方法が解り難いのですがWEBサイトの「お客様情報」の下の方にある「購入履歴」から領収書を発行できます。
DMM mobile 名義なので経費に積むにも領収書発行しちゃえば«いかがわしく»ないと思いますw

まとめ

インターネッツに依存しまくってる生活に慣れてしまうと、ネットに繋げなくなるって恐怖心がマジっぱない。
そして、最近覚えたギガ減るって感覚を身をもって体験することが出来ました。
願わくばDMMさんが二重認証を導入してくれんことを!

あーはやく治ってほしい。お体…


Git 過去の特定のコミット位置からブランチを切りたい

今のブランチの途中に戻って先に別の開発をしないといけないとか、特定のコミット位置から別のブランチを作成したい時のアレ。

例えば

$ git log --all --decorate --graph --oneline
* ab7b929 (HEAD -> develop) 図書館にレシピの本を置いたよ。たーのしー
* 7cb8ef3 図書館をつくったよ。わーい
* 9f0e540 服がぬげたよ。
* 85767d5 カレーはからい。たーのしー
* 175658e 温泉がみつかったよ。
* a9b3d53 ボスがふえたよ。たーのしー
* e0e054e じゃぱりまんを作ったよ。わーい
* 94b8397 でんち
* 6fe1920 バスてきなもの。たーのしー
* 98f5f9b ジャパリパークの敷地をつくったよ。わーい。

94b8397 でんち から別のブランチを切ってジャパリバスを作りたいような場合、
今のリポジトリをリモートにpushしているならgit reset --hard HEAD^ で必要なところまで戻してブランチを切った後、git pull origin でもとに戻しても良いのだけれどチョットめんどーです。

結論

$ git checkout -b <new_branch> <commit_hash>

で、特定のコミット位置からブランチを切ることができる。 (∩´∀`)∩わーい

起点となる位置を指定してブランチを切っている

リモートのブランチをローカルにチェックアウトして持ってくるような時、次のようなコマンドを使います。

$ git checkout -b <ローカルに作成するブランチ名> origin/<リモートのブランチ名>

これは origin/<リモートのブランチ名> の部分が「どこを基点にするか」という意味なようでコミットハッシュを指定すれば、そのコミット位置を基点にブランチを作成することができます。

先の例の 94b8397 でんち から create-bus ブランチを切る場合は下記のような感じ。

$ git checkout -b create-bus 94b8397

これで新しいcreate-busブランチが作成されそこにチェックアウトされます

$ git log --all --decorate --graph --oneline
* ab7b929 (develop) 図書館にレシピの本を置いたよ。たーのしー
* 7cb8ef3 図書館をつくったよ。わーい
* 9f0e540 服がぬげたよ。
* 85767d5 カレーはからい。たーのしー
* 175658e 温泉がみつかったよ。
* a9b3d53 ボスがふえたよ。たーのしー
* e0e054e じゃぱりまんを作ったよ。わーい
* 94b8397 でんち (HEAD -> create-bus)
* 6fe1920 バスてきなもの。たーのしー
* 98f5f9b ジャパリパークの敷地をつくったよ。わーい。

わーい

基点の指定は checkout の直後でもOK

$ git checkout <基点となる場所> -b <作成するブランチ名>

基点となる場所をcheckout-b の間に書いてもOKみたいです。
 

ちょっとした事だけれど、覚えてると必要になった時 reset の力技しなくていいから幸せになれそう。