かもメモ

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

Ajaxを使ってWordPressからコンテンツを取得したい。

WordPress製のサイトに独自のコンテンツなどを取得できるAjaxを作成する方法のメモ

  1. 呼び出すアクション名を決める
  2. Ajax送信先をjsから使えるように出力する
  3. Ajaxで呼び出される関数を作成する (PHP)
  4. フロントからAjaxでの呼出しを作成する (javascript)

1. 呼び出すアクション名を決める

アクション名はPHPの関数名やnoce、jsのAjax内などで何度も使うので、どんな仕様にするか決めて仕様に合ったアクション名を先に決めておくのが良いと思います。

今回は my-ajax-action というアクション名にします。

2. Ajax送信先のパスなどの出力

WordPressAjaxのリクエス送信先 /wp-admin/admin-ajax.php のパスやnoneなどの情報をjavascriptグローバル変数として出力する

<?php // function.php
function my_enqueue_scripts() {
  $handle = 'my-script';
  // Ajaxの呼出しが書かれているスクリプトのパス
  $jsFile = 'path/to/myscript.js';
  
  wp_register_script($handle, $jsFile, ['jquery']);
  
  // 1.で決めたアクション名
  $acrion = 'my-ajax-action';
  // 配列をJSのオブジェクトに変換したscriptを出力する
  wp_localize_script($handle, 'MY_AJAX', [
    'api'    => admin_url( 'admin-ajax.php' ),
    'action' => $acrion,
    'nonce'  => wp_create_nonce( $acrion ),
  ]);
  
  wp_enqueue_script($handle);
}
add_action( 'wp_enqueue_scripts', 'my_enqueue_scripts' );

$handleで指定された myscript.js の出力タグの前に次のようなスクリプトが出力されます。

<script type='text/javascript'>
/* <![CDATA[ */
var MY_AJAX = {
  "api": "http:\/\/example.com\/wordpress\/wp-admin\/admin-ajax.php",
  "action": "my-ajax-action",
  "nonce": "生成されたNONCE値"
}
/* ]]> */
</script>

※ 実際には1行で出力されます。グローバル変数になっちゃうので、ちょっとイケてない感あります…

複数のアクションを作成する場合は、アクションとそれに対応したnonceが取得しやすいように配列をネストするなどして工夫してください。

3. 呼び出される関数の作成 (PHP)

3.1 Ajaxから呼び出される関数を定義する

add_action アクションフックで、Ajaxから呼び出される関数を登録する。

<?php // function.php
function my_ajax_event() {
}
add_action( 'wp_ajax_my-ajax-action', 'my_ajax_event' );
add_action( 'wp_ajax_nopriv_my-ajax-action', 'my_ajax_event' );
  • wp_ajax_{action名} … ログインユーザーの時、呼び出される
  • wp_ajax_nopriv_{action名} … 非ログインユーザーの時、呼び出される

フロントから呼び出される場合は、両方のアクションフックを設定する必要がある。
管理画面で使うだけなら、常にログインユーザーなので wp_ajax_{action名} の方だけでOK。

3.2 Ajaxで呼び出される関数の処理を作成する

<?php // function.php
function my_ajax_event() {
  // wp_create_nonce の引数に渡したものと同じ アクション名
  $action = 'my-ajax-action';
  
  // nonceのチェック
  if( check_ajax_referer($action, 'nonce', false) ) {
    $data = [];

    // Ajax(post)のdataから渡される値を使用する場合は $_POST から取得する (適時エスケープ)
    $id = intval( $_POST['post_id'] );
    $name = esc_html( $_POST['name'] );
    
    /* wordpressから色々取得したり、Ajaxで返すデータ作成する */
    
    // 配列をjson形式にエンコード
    $data = json_encode($data);
  } else {
    // エラー
    status_header( '403' );
    $data = 'Forbidden';
  }

  // Ajaxに返す
  header( 'Content-Type: application/json; charset=UTF-8' );
  echo $data;

  die();
}
add_action( 'wp_ajax_my-ajax-action', 'my_ajax_event' );
add_action( 'wp_ajax_nopriv_my-ajax-action', 'my_ajax_event' );

nonceのチェック

check_ajax_referer( $action, $query_arg, $die )
  • $action (string)
    nonceのアクション名
    nonce作成時の wp_create_nonce() に渡したアクション名と同じ文字列を指定する
  • $query_arg (string)
    $_REQUESTで渡される配列の nonce が格納されているキーを指定
    上の例の場合は data: { nonce: 値 } としてAjaxから送ればOK
  • $die (boolean) default: true
    trueの時 nonce が無効なら die() する
    falseの時 nonce のチェック結果を true / false で返す

Ajax(post)のdataで渡される値は$_POSTで取得することができます。
nonceのチェック関数は内部では$_REQUESTから取得している様なので、$_REQUESTの方がget/postどちらでも取得できるで良いのかもしれません。

Ajaxで呼び出される関数の最後に die() がないと返されるデータの最後に0が追加されてしまうので、忘れないようにdieしておく必要があります。

4. Javascriptの作成 (Ajax呼出し)

後はフロントのjavascriptからAjaxで呼び出すだけです。
URLやアクション名は 2. で作成したグローバル変数から使用します。

// global MY_AJAX
"use strict";
$(function() {
  $.ajax({
    url: MY_AJAX.api,
    type: 'post',
    data: {
      // 呼び出すアクション名
      action: MY_AJAX.action,
      // アクションに対応するnonce
      nonce: MY_AJAX.nonce,
      // ▼ その他 渡したいデータがあれば適時 ▼
      post_id: 12345,
      name: 'name'
    }
  })
  .done(function( res ) {
    console.log( res );
  })
  .fail(function( jqXHR, textStatus, errorThrown ) {
    console.log( jqXHR, textStatus, errorThrown, arguments);
  });
});

 
これで、Ajaxを使ってWordPressから独自のコンテンツとか値を取得することができるようになりました。
Ajaxを使うために出力するjavascriptの変数がglobal変数になってしまうのが、やっぱイケてない感じなので、どうにか出来ないものかと思っています。。。


[参考]

世界一わかりやすいWordPress 導入とサイト制作の教科書 (世界一わかりやすい教科書)

世界一わかりやすいWordPress 導入とサイト制作の教科書 (世界一わかりやすい教科書)

WordPress WP_Query カスタム投稿の特定のtaxonomyを除く(含む)の指定方法

基本的にマニュアルに書いて有ることだけど、すぐ忘れるのでメモ。

タクソノミー(taxonomy)のパラメーター

タクソノミーに関する指定は、tax_queryをキーにした配列内に指定する。

特定の term を除く(含む) WP_Queryの指定方法

operator オプジョンで指定する。

<?php
$args = [
  'post_type' => ['my_post_type'],
  // タクソノミーに関する指定
  'tax_query' => [
    [
      // タクソノミー作成時に指定したタクソノミー名
      'taxonomy' => 'tax_name',
      // terms を slug で指定する
      'field'    => 'slug',
      // fieldで指定した方法で term そ指定する。この場合は slug 名で指定
      'terms'    => [
        'term_slug',
      ],
      // 上記のtermを除く場合は 'NOT IN' ・含む場合は 'IN'
      'operator' => 'NOT IN',
    ],
  ],
];
$the_query = new WP_Query($args);
// 処理
wp_reset_postdata();

 
関係ないけど、はてなブログのマークダウン、リンクをリストにしようとした時URLによっては-だとリストにならない時があってちょっとイライラする…


[参考]

Real World HTTP ―歴史とコードに学ぶインターネットとウェブ技術

Real World HTTP ―歴史とコードに学ぶインターネットとウェブ技術

PHP Bool値を文字列として出力したい。

PHP製の管理画面とかでtruefalse といったBoolean値をそのまま表示させたい時

単純に文字列にキャストしても上手くいかない

<?php
(string) true;  // => "1"
(string) false; // => ""
strval( true );  // => "1"
strval( false ); // => ""

// 空文字を連結してもダメ
echo true . '';  // => "1"
echo false . ''; // => ""

(string), strval で文字列化しても上手く表示することができません。

var_export 関数を使うと true / false の文字列で表示される

<?php
var_export( true );  // => "true"
var_export( false ); // => "false"

変数にして使用したい時は、第二引数をtrue にすればOK

<?php
$boolean = true;
$val = var_export( $boolean, true );
echo $val; // => "true"

三項演算子やif文を使うパターン

簡単ですが、Boolean値以外でもtrueかfalseでされてしまう問題があるのでそれを許容できるのであればOK。

<?php
function print_boolean($val) {
  echo ($val)? 'true':'false';
}
print_boolean( true );  // => "true"
print_boolean( false ); // => "false"

// Boolean値以外でも true か false で出力される
print_boolean(  );  // => "false"
print_boolean( 0 ); // => "false"
print_boolean("false"); // => "true"

Boolean を var_dump、prent_r した時の違い

<?php
var_dump( true );  // => bool(true)
var_dump( false ); // =>  bool(false)

print_r( true );  // => "1"
print_r( false ); // => ""

 
Bool値を文字列にキャストした際にfalse""になってしまうのは、文字列の"false"をBoolean値にキャストするとtrueになる仕様のためなんじゃないかなと思いました。👇

<?php
$bool = (bool) "false";
var_dump( $bool ); // => bool(true)
$bool = (bool) 0
var_dump( $bool ); // => bool(false)

[参考]

いきなりはじめるPHP~ワクワク・ドキドキの入門教室~

いきなりはじめるPHP~ワクワク・ドキドキの入門教室~

SublimeText マークダウンの時だけ行末スペースの自動削除をOFFにしたい。

Atomに乗り遅れてSublimeTextを使い続けてるマンです。
SublimeTextの設定で"trim_trailing_white_space_on_save": trueにしていると不要な行末のスペースを自動削除できて超便利です。

しかしREADME.mdとかマークダウンを書くことが増えているので、同じプロジェクト内のプロフラムのファイルは行末の無駄なスペースを削除したいけど、マークダウンで削除されるのは改行の時にチョット困る…
と、暫くマークダウンだけ別のエディタで開いたりしていましたが、いい加減面倒くささがMAX限界値に達したので重すぎる腰を上げてマークダウンの時だけ行末スペースの自動削除をOFFにしたのでメモしておきます。

インストールしてるテーマやパッケージなど

  • MarkdownLight - マークダウンのシンタックスハイライト
  • Markdown Extended - マークダウンのコード内のシンタックスハイライト
  • OmniMarkupPreviewer - ブラウザでリアルタイムでマークダウンのプレビューがみれるパッケージ
    ⌘+alt+Oでプレビューを起動
  • Table Editor - テーブルをフォーマットしてくれるパッケージ
    テーブルの記述位置でtabキーを押すとキレイにフォーマットしてくれる

Markdownの時だけ有効な設定ファイルを作成する

  1. テキトーな.mdなマークダウンファイルを作成し、シンタックスMarkdown Extendedにする
  2. メニューからView > Syntax > Open all with current extension as... > Markdown Extended を選択
  3. 設定ファイル Markdown Extended.sublime-settingsMacの場合~/Library/Application Support/Sublime Text 3/Packages/User/内に作成される

シンタックスMarkdownにする時は、2ではMarkdownを選択。設定ファイルはMarkdown.sublime-settingsになります

シンタックスMarkdown(Markdown Extended)の時、保存時の行末スペースの自動削除をOFFにする

先の手順で作成された設定ファイル(Markdown Extended.sublime-settings)を開き下記のように記述して保存すればOK

{
  // シンタックスハイライトに使用するカラースキームファイルのパス (適時変更してください)
  "color_scheme": "Packages/User/SublimeLinter/MarkdownLight (SL).tmTheme",
  // Table Editor パッケージを使用する
  "enable_table_editor": true,
  // Markdown Extended で使用する拡張子
  "extensions":
  [
    "md",
    "markdown"
  ],
  // タブサイズ
  "tab_size": 2,
  // タブをスペースに変換する
  "translate_tabs_to_spaces": true,
  // 保存時の行末スペース自動削除 OFF
  "trim_trailing_white_space_on_save": false
}

設定は適時変更してください。

color_scheme に使用したいファイルが見つからない時

パッケージコントロールcolor_schemeで使用したいスキームをインストールしてもファイルが見つからない時は、 一度メニューSublime Text > Preferences > Color Scheme から使用したいスキームを選択するとSublime Text 3/Packages/User/内にファイルが作成されます。
この時、全体のカラースキームが変更されるので、ファイルが作成されたら同様にメニューから元のスキームを再選択してもとに戻して上げる必要があります。
 
これで、ようやく面倒くささから開放されました!
pug(旧jade)でも行末スペースが欲しいときもあるので、同じような設定にしても良いかもしれません。
Atomとかならもっと簡単に設定できるのかしら?

ほんと、世の中 W◯rdとか辞めてMarkdownが主流になって欲しい。(TinyMCEゴリゴリカスタマイズって苦いお仕事の体験もあってビジュアルエディアあまり好きじゃない)


[参考]

最速の仕事術はプログラマーが知っている

最速の仕事術はプログラマーが知っている

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 の力技しなくていいから幸せになれそう。


IE11バグ display table, table-cell 内で max-width が効かない

IE11… またお前か!
max-widthのバグが多いですねw

display: table, display: table-cell の中にある img タグのmax-width: 100% が無視されて、要素からはみ出したりしてしまう問題。

<div class="table">
  <div class="table-cell">
    <img class="max-width-100per">
  </div>
</div>

table-layout: fixed を使うと max-width が効く

display: table を持っている要素に table-layout: fixed を設定すると、table-cell 中にある画像の max-width が有効になる。

‘table-cell’ 内に inner のdiv 要素などを置いても画像の max-width は無視されてしました…

サンプル

See the Pen IE11 max-width un available in display: table, table-cell by KIKIKI (@chaika-design) on CodePen.

IE 滅ぶべし!


[参考]

IEバグ inline-block 内の要素に max-width が効かないにハマる

コーディングをしていて IE で崩れていると連絡を受けてしまいました。
IE11のサポートしてたのですが、まぁ流石にもうIEでも大丈夫だろうと思ってたら、まさかIE6時代のようにバグに遭遇してしまいました。
マイクロソフトを信じたのが間違いだった…

発生していたバグ: inline-blockが親要素を突き破ってしまう例

inline-blockで横並びにした要素内の画像が親要素の幅を無視して表示されてしまっていた。
f:id:kikiki-kiki:20170707021555p:plain

HTML

div(class="inline-block width200px")
  div(class="inline-block")
    img(src="width 300px の画像")

div(class="block width200px")
  div(class="inline-block")
    img(src="width 300px の画像")

CSS

.block
  display: block
.inline-block
  display: inline-block
.width200px
  width: 200px
img
  max-width: 100% // width: 100% か max-width: 100% が無いと要素を突き破る
  height: auto

このようにwidthが200pxに指定された要素の中に、inline-block要素が入り、その中に200pxより大きな300px幅の画像が入るような構成の場合、Chrome, Safari, Firefoxではmax-widthが効き囲っている要素のwidthに画像が縮小されますがが、IE11はボックスは200pxのまま、inline-blockは画像幅の300pxになり親要素を突き破ってしまいます。

これは、画像のwidthmax-widthを指定してない時の表示と同じ感じでした。

IE 11 inline-block が中の要素の max-width: 100% が効かず親要素のwidth指定を無視してしまうっぽい

どうやらIE11ではmax-widthが指定された要素がinline-block要素中にある時、inline-block要素にwidthの指定がないと、例えinline-block要素の親要素にwidthが指定されていてもmax-widthが効かずこの幅を無視して突き破ってしまう問題があるようです。

解決方法 1. 画像の max-width:100% を辞めて、width: 100% にする

例えばレスポンシブなものとかで画像が拡大されてしまってもOKなら画像の max-width:100%width:100% に変更するのが簡単です。

div(class="inline-block width200px")
  div(class="inline-block")
    img(src="width 300px の画像") ← width: 100% にする

div(class="block width200px")
  div(class="inline-block")
    img(src="width 300px の画像") ← width: 100% にする

解決方法 2. inline-block に width の指定をする

表示幅が決まっているなら画像の親のinline-block要素にwidthの指定をするのが簡単です。

div(class="inline-block")  ← width 指定無くてもOK
  div(class="inline-block") ← この要素にwidthを指定
    img(src="width 300px の画像")

div(class="block")   ← width 指定無くてもOK
  div(class="inline-block") ← この要素にwidthを指定
    img(src="width 300px の画像")

※ widthの指定は 100% でもOKでした。

解決方法 2. 親要素を display: inline-block でないものにする

画像を囲っている要素の display: inline-blockdisplay: blockdisplay: inline にした場合も画像のmax-widthは親の親要素の指定に準拠して表示されました

div(class="inline-block width200px") 
  div(class="block") ← この要素のdisplayを block か inline に変更
    img(src="width 300px の画像")

div(class="block width200px")
  div(class="block")  ← この要素のdisplayを block か inline に変更
    img(src="width 300px の画像")
サンプル

ちょっと横幅があるので、CODEPNのサイトで見たほうが見やすいかも。
👇

See the Pen IE11 inline-block bug test by KIKIKI (@chaika-design) on CodePen.

 
最初 max-width が効かなくなってるって事に気づかなくて時間がかかってしまった。。。
未だにIE使ってる人なんているのかなぁ…? マイクロソフトのブラウザを使うのは今すぐやめるんだ!!


バグズ・ライフ [Blu-ray]

バグズ・ライフ [Blu-ray]

Git log 指定日からの作業内容をテキストファイルに出力したい

日報とか週報とかの提出を求められる時、いちいちテキストを書くのがメンドーなのでgit logをテキストファイルとして出力したいと思いました。

1. 今日とか1週間とかの git log をいい感じにして表示する

1週間分の自分のコミットを [YYYY-MM-DD] ハッシュ: コミット時のコメント で表示するコマンドは次のような感じでできました。

git log 
  --oneline --branches --reverse
  --author="$(git config user.name)"
  --date=iso --since="1week" 
  --pretty=format:"[%ad] %h: %s"

※ 長いから改行しているけど、コマンドラインなら1行で

使用しているオプションの説明

  • --branches
    全てのブランチを対象にする。
    オプションがないと今いるブランチのみが対象になる
  • --author
    author="name" で指定したAuthorのlogだけを取得
    "$(git config user.name)" とすれば .gitconfig にある user.name が対象になる
  • --date
    date="sio" - “YYYY-MM-DD HH mm ss フォーマット date="short" - YYYY-MM-DD フォーマット iso だと時刻が表示されてしまうので、作業時間がバレるのは ちょっとなー って場合は short を指定したほうが良さそう
  • --since
    いつのコミットから表示するか
    日報のように今日の分だけなら --since="today"
    --since="2017-06-25" のように日付を指定することもできる
  • --pretty=format:
    log を表示するフォーマット
    • %ad - コミットした時間 (-date= オプションに従った形式)
    • %h - コミットのハッシュ (短縮版)
    • %s - コミットコメント その他、詳しいオプションについては「git logのフォーマットを指定する - Qiita」に詳しく載っています

2. git log をファイルに出力する

いい感じの git log の表示オプションが作れたら、次はlogをファイルに出力します。
ファイルへの出力はコマンドの最後に > ファイル名 をつけるだけ。
log.txt というファイルを作って出力する場合は次のような感じ

git log 
  --oneline --branches --reverse
  --author="$(git config user.name)"
  --date=short --since="1week" 
  --pretty=format:"[%ad] %h: %s"
  > log.txt

※ 長いから改行しているけど、コマンドラインなら1行で

コマンドを実行すると、コマンドを実行した場所に log.txt が作成されます。

3. 作成したgit logのコマンドをエイリアス化して、日付を引数で渡せるようにする

毎回この長いコマンドを実行するのもメンドーなので、コマンドをエイリアス化して、開始日(since)の指定をオプションで渡せるようにしたいと思います。
git コマンドの エイリアスはglobalなら.~/.gitconfigに、現在の作業リポジトリなら .git/config ファイルに記入されるので、ここに直接コマンドを書いてエイリアスを作成します。

今回は、あるプロジェクトでだけ使いたかったので、リポジトリ内の .git/config に下記のエイリアスコマンドを追記しました。

[alias]
  logfile = "!f () {\
    git log --oneline --branches --reverse --date=short\
    --author=\"$(git config user.name)\"\
    --pretty=format:\"[%ad] %h: %s\"\
    --since=\"$1\"\
    > ../log.txt;\
  };f"

コマンドのエイリアス名は logfile としました。
で、この作業リポジトリ内で 次のようなコマンドを実行すると、、、

$ git logfile today

本日のコミットログをリポジトリのあるディレクトリの1つ上の階層に log.txt ファイルとして書き出せるようになりました!
₍₍ ᕕ(´ ω` )ᕗ⁾⁾ ヤッタゼ

global のエイリアスにする場合は ログファイルの書き出し先のパスをデスクトップにするとか適時工夫する必要があるかと思います。


[参考]

入門git

入門git