カテゴリー
WordPress

固定ページの親子判定

親ページのスラッグ「parent」、子ページのスラッグ「parent/child」両方に何らかの処理をしたい場合。

global $wp_query;

if (strpos($wp_query->query['pagename'], 'parent') !== false) {
     // 処理
}

WP_Query – Class | Developer.WordPress.org

カテゴリー
JavaScript VS Code

JS Minify & Obfuscator

VS Code で JavaScript の圧縮・軽量化する機能拡張「JS & CSS Minifier」(非推奨だけど使える)の変わりは、「JS Minify & Obfuscator」がよさげ。

https://marketplace.visualstudio.com/items?itemName=themebetter.jsminifyobfuscator

「JS & CSS Minifier」から他の機能拡張に乗り換えられない大きな理由だった「保存場所」の指定ができる。

"jsMinifyObfuscator.watchFolders": {
    // "src": "dist"
    // "src/js": "../dist"
    // "src/js": "../../dist"
},
カテゴリー
Misc

SVG 三角形

パーツとして使いたい時ように、最小限のコードで SVG の三角形。

<svg xmlns="http://www.w3.org/2000/svg" width="100" height="100">
  <polygon points="100 0, 0 100, 100 100" fill="red" />
</svg>
カテゴリー
CSS SASS

Flex 左揃え 5列以上も対応

フレックスボックスを使った以下のレイアウト。

  1. フレックスアイテムの幅は可変。
  2. フレックスアイテムの間隔が(ほぼ)一定
  3. フレックスアイテムは左揃え

例としてフレックスアイテムが 3列で間隔(ギャップ)を 10px として、HTML は以下とすると。

<div class="flex">
  <div></div>
  <div></div>
  <div></div>
  <div></div>
</div>

まずは、フレックスコンテナーの設定。

.flex {
  display: flex;
  flex-wrap: wrap;
}

次にフレックスアイテムの幅は 100% / 3 – 20px / 3 なので、個々のアイテムの幅を設定。

.flex > div {
   width: calc(100% / 3 - 20px / 3);
   padding-top: calc(100% / 3 - 20px / 3); /* 仮の高さ */
   background-color: #000; /* 仮の背景色 */
}

4個目~のフレックスアイテム用に margin-top を設定。

.flex > div:nth-child(n+4) {
  margin-top: 10px;
}

各行の先頭のフレックスアイテム以外に margin-left を設定。

.flex > div:not(:nth-child(3n+1)) {
  margin-left: 0;
  background-color: #ccc; /* 仮の背景色 */
}

上記で大体 OK のはずだけど、割り切れない時の小数点の扱いによって、想定する列数でなくなるので、各行の最後のフレックスアイテムは margin-left を auto に設定。

.flex > div:nth-child(3n) {
  margin-left: auto;
}

インターネット上の記事でよく space-between + 疑似要素で左寄せにする方法を見るけど、それだと5列以上には対応できないし、疑似要素を追加する必要もないので、一案として。

Sass のミックスインにしておけば4列以上も簡単に書き出せる。

@mixin flex(
  $row: 3,
  $gap: 10px,
) {
  display: flex;
  flex-wrap: wrap;

  $column-gap: ($row - 1) * $gap;
  $second-row: $row + 1;

  & > div {
    width: calc(100% / #{$row} - #{$column-gap} / #{$row});
    padding-top: calc(100% / #{$row} - #{$column-gap} / #{$row}); // 仮の高さ
    background-color: #000; // 仮の背景色
  }

  & > div:nth-child(n+#{$second-row}) {
    margin-top: $gap;
  }

  & > div:not(:nth-child(#{$row}n+1)) {
    margin-left: $gap;
    background-color: #ccc; // 仮の背景色
  }

  & > div:nth-child(#{$row}n) {
    margin-left: auto;
  }
}

5列を書き出す。

.flex {
  @include flex(5);
}

6列で間隔を 15px で書き出す。

.flex {
  @include flex(6, 15px);
}

IE11 にも対応。

カテゴリー
JavaScript

JavaScript と JQuery 対応メモ

ブラウザのスクロール位置

// JavaScript
document.documentElement.scrollTop || document.body.scrollTop;
// JQuery
$(window).scrollTop();

高さ(padding, border 含む)

// Javascript
element.offsetHeight;
// Jquery
element.outerHeight();
カテゴリー
VS Code

VS Code 機能拡張 設定メモ

デフォルトを上書きする個人設定メモ。

JS & CSS Minifier

// ミニファイ自動実行
"es6-css-minify.minifyOnSave": "yes",
// ターゲットディレクトリ
"es6-css-minify.jsMinPath": "/js",

Live Sass Compiler

// ソースマップ
"liveSassCompile.settings.generateMap": false,
// ベンダープレフィックス
"liveSassCompile.settings.autoprefix": null,
// 書き出し形式とディレクトリ
"liveSassCompile.settings.formats": [
    {
        "format": "compressed",
        "extensionName": ".min.css",
        "savePath": "/css",
    },
],
// 書き出し形式とディレクトリ
// デフォルト(上)とミニファイ書き出し
"liveSassCompile.settings.formats": [
    {
        "format": "expanded",
        "extensionName": ".css",
        "savePath": "/css",
    },
    {
        "format": "compressed",
        "extensionName": ".min.css",
        "savePath": "/css",
    },
],

Easy Sass

// オートコンパイルを実行しない
"easysass.compileAfterSave": false,
// パーシャルファイルは出力しない
"easysass.excludeRegex": "^_+",
// ターゲットディレクトリ
"easysass.targetDir": "css",
カテゴリー
Node.js

Node.js で EJS

Sass のコンパイルや JavaScript の minify などは、VS Code(私的メインエディタ) の機能拡張に任せて、EJS だけ npm-scripts に監視しさせる開発環境構築メモ。Node.js はインストール済み。

必要パッケージのインストール

  • rimraf: 書き出しディレクトリのクリーン
  • watch: .ejs の変更を監視
  • chokidar-cli: .ejs の変更を監視
  • ejs-cli: .ejs を .html に変換
// npm i -D rimraf watch ejs-cli
npm i -D rimraf chokidar-cli ejs-cli

※読み方が分からないが chokidar-cli の方が watch より 反応が良い気がしたので変更@200406

ディレクトリ構造

数ページの会社案内のようなサイトを作るとして、dist ディレクトリに何から何まで書き出すと想定。

dist
├ assets // css や js が書き出される
├ summary
│ └ index.html
└ index.hmlt
node_modules
src
├ assets // sass や js を保存(ここは VS Code に任せる)
├ summary
│ └ index.ejs
├ _footer.ejs
├ _header.ejs
└ index.ejs
package.json

npm-scripts

「dist」ディレクトリの .html は必ず .ejs から変換。

// "ejs": "rimraf dist/**/*.html && ejs-cli -b src **/!(_)*.ejs -o dist",
"ejs": "rimraf \"dist/**/*.html\" && ejs-cli -b src \"**/!(_)*.ejs\" -o dist",
// "watch/ejs": "watch \"npm run ejs\" src -p /assets/"
"watch/ejs": "chokidar \"src/**/*.ejs\" -c \"npm run ejs\""

※watch が実行するコマンドは、Windows の場合、ダブルクォーテーションで囲まないとエラーになった。
※watch は、「-p」の後に正規表現で除外を設定するけど、chokidar は監視を絞り込む感じ。
※Mac で rimraf, ejs-cli の対象をダブルクォーテーションで囲まないとエラーになった@200407

リンク

カテゴリー
WordPress

カスタム投稿タイプ

WordPress のカスタム投稿タイプ。頻繁に設定するものでもなく、機会があるたび、自分で書いた古いコードやネットで再検索するのでメモ。

基本形

例えば、「ニュース」ようのカスタム投稿タイプを作るとする。「my_post_type」としている関数名は、既存の関数名と被らなければ好きな名前で。

add_action('init', 'my_post_type');

function my_post_type()
{
    register_post_type(
        'news',
        array(
            'label' => 'ニュース',
            'labels' => array(
                'all_items' => 'ニュース一覧',
            ),
            'public' => true,
            'menu_position' => 5,
            'has_archive' => true,
        )
    );
}

余計なコードは書きたくないので、デフォルト値や自動的に継承される値をわざわざ書かなければ、私的にはこれが基本かな。

基本形+階層化カテゴリ

先の「my_post_type」関数内に、階層化カテゴリの設定も追加。「’hierarchical’ => true」がないとタグになる。

add_action('init', 'my_post_type');

function my_post_type()
{
    register_post_type(
        'news',
        array(
            'label' => 'ニュース',
            'labels' => array(
                'all_items' => 'ニュース一覧',
            ),
            'public' => true,
            'menu_position' => 5,
            'has_archive' => true,
        )
    );

    register_taxonomy(
        'news_cat',
        'news',
        array(
            'hierarchical' => true,
        )
    );
}

複数追加

たとえば、「ニュース」と「メニュー」の二つを追加するなら、関数内に二つ「register_post_type」を設定すれば OK。

add_action('init', 'my_post_type');

function my_post_type()
{
    register_post_type(
        'news',
        array(
            'label' => 'ニュース',
            'labels' => array(
                'all_items' => 'ニュース一覧',
            ),
            'public' => true,
            'menu_position' => 5,
            'has_archive' => true,
        )
    );

    register_post_type(
        'menu',
        array(
            'label' => 'メニュー',
            'labels' => array(
                'all_items' => 'メニュー一覧',
            ),
            'public' => true,
            'menu_position' => 5,
            'has_archive' => true,
        )
    );
}

リンク

カテゴリー
Rulish

私的略語メモ

A

  • arr: array

B

  • btn: button

C

  • cat: category
  • cls: class
  • cnt: count
  • cur: current

E

  • elm: element
  • err: error

M

  • msg: message

O

  • obj: object

P

  • pos: position

R

  • req: request
  • res: response
  • ret: return / result

S

  • str: string

T

  • tmp: temporary

V

  • val: value

X

  • xhr: XMLHttpRequest
カテゴリー
JavaScript

郵便番号 ハイフン補完

input 要素にハイフン無しの郵便番号の入力があった場合、ハイフンを補完する JavaScript 。

input 要素がひとつの場合

HTML

<input type="text" name="zip">

JavaScript

document.querySelector('input[name=zip]').addEventListener('keyup', function() {
  this.value = this.value.replace(/(\d{3})(\d{4})/, '$1-$2');
});

上記でキーボードがタイプされる都度、input 要素の value 属性が7桁の数字だったらハイフンを補完する。

しかし、このままだと input 要素に 7 桁の数字をコピペした時に反応しないので、以下のように input 要素にもう一つイベントを登録する。

JavaScript

document.querySelector('input[name=zip]').addEventListener('keyup', function() {
  this.value = this.value.replace(/(\d{3})(\d{4})/, '$1-$2');
});

document.querySelector('input[name=zip]').addEventListener('change', function() {
  this.value = this.value.replace(/(\d{3})(\d{4})/, '$1-$2');
});

同じことを二回書いてるだけだけど、まとめたかったら関数にしてしまう。

JavaScript

document.querySelector('input[name=zip]').addEventListener('keyup', setZip);
document.querySelector('input[name=zip]').addEventListener('change', setZip);

function setZip()
{
  this.value = this.value.replace(/(\d{3})(\d{4})/, '$1-$2');
}

input 要素が複数の場合

HTML

<input type="text" name="zip1">
<input type="text" name="zip2">

JavaScript

var zip = document.querySelectorAll('input[name^=zip');

for (var i = 0; i < zip.length; i++) {
  zip[i].addEventListener('keyup', setZip);
  zip[i].addEventListener('change', setZip);
}

function setZip()
{
  this.value = this.value.replace(/(\d{3})(\d{4})/, '$1-$2');
}

input 要素に同一のクラス名、例えば「class=”zip”」を付与していれば、「querySelectorAll(‘input[name^=zip’)」は「querySelectorAll(‘.zip’)」としてもよい。

JQuery

JQuery を読み込んでいたら、以下で終了。

// input 要素がひとつ
$('input[name=zip]').on('keyup change', function() {
  $(this).val($(this).val().replace(/(\d{3})(\d{4})/, '$1-$2'));
});

// input 要素が複数
$('input[name^=zip').on('keyup change', function() {
  $(this).val($(this).val().replace(/(\d{3})(\d{4})/, '$1-$2'));
});

// input 要素に共通のクラス名
$('.zip').on('keyup change', function() {
  $(this).val($(this).val().replace(/(\d{3})(\d{4})/, '$1-$2'));
});

JQuery や他のライブラリ等を使うか、素のJavaScript のみで書くかは、臨機応変で。

リンク

this – JavaScript | MDN#DOM イベントハンドラとして