Quantcast
Channel: モンキーレンチ
Viewing all 235 articles
Browse latest View live

WordPressで記事公開時と更新時のフックを使い分ける方法

$
0
0

記事公開時のフックはpublish_post?

WordPressで記事公開時に動作するフックが何か調べたところ「publish_post」を使うのがスタンダードのようだったので、publish_postフックを利用するコードを書いてみたのだが、公開したときだけでなく記事の「更新時」も処理が実行されてしまった。

公開時だけ処理をさせたかったので調べてみると、publish_postフックで呼び出す関数内で公開か更新か条件分岐させるような方法をされている方が。

publish_postフックで呼び出した関数内で、グローバル変数や$_POSTの内容をもとに条件分岐させているようだが、少し煩雑…。日本語版のCodexを見ても特にフックが載っていなかったので、半分諦め気味で英語版のCodexを覗いたところ、希望通りのフックを発見した。

Post Status Transitions

WordPressには「下書き」「公開」「レビュー待ち」などいくつかの投稿ステータスがあり、そのステータスの遷移に応じて稼働させることができるフックが用意されている。書式は次の通り。

// 書式
{$old_status}_to_{$new_status}
// 例)下書き状態から公開状態になったとき
add_action( 'draft_to_publish', 'my_function' );

上記のフックで利用できる投稿ステータスは以下のとおり。

ステータス名 内容
new 前のステータスがないとき
publish 公開された投稿やページ
pending レビュー待ちの投稿
draft 下書き状態の投稿
auto-draft 新しく作成された内容がない投稿
future 公開予約された投稿
private ログインしていないユーザーには表示されない投稿
inherit リビジョンまたは添付ファイル
trash ゴミ箱に入っている投稿

従って、例えば「新規公開時に限って処理を実行したい」という場合は、{$old_status}_to_publishの形式で全てのフックを指定すれば良い。

add_action( 'new_to_publish', 'my_function' );
add_action( 'pending_to_publish', 'my_function' );
add_action( 'draft_to_publish', 'my_function' );
add_action( 'auto-draft_to_publish', 'my_function' );
add_action( 'future_to_publish', 'my_function' );
add_action( 'private_to_publish', 'my_function' );

transition_post_statusフック

@jim0912さんから、transition_post_statusフックを使っても実現できるとの情報をいただいた。

以下にサンプルコードを。

add_action( 'transition_post_status', 'myfunction', 10, 3 );
function myfunction( $new_status, $old_status, $post ) {
    // $new_status, $old_status を使って分岐
    // 〜 処理 〜
}

WordPressで管理画面にアクセスできなくなったときの対処法

$
0
0

既存サイトをコピーして新規サイトを構築することになったが、テーブルプレフィックス(接頭辞)がコピー元とコピー先で同じになってしまうのが嫌だったので、コピー先のテーブルプレフィックスを変更することにした。テーブルプレフィックスの変更は wp_config.php の $table_prefix を変更すれば良い。

// wp_config.php
// $table_prefix = 'wp_'; から変更
$table_prefix  = 'hoge_';

これで、テーブルプレフィックスとして「hoge_」が利用されるようになるので、それに合わせてテーブル名を変更する。

ALTER TABLE `wp_comments` RENAME `hoge_comments`;
ALTER TABLE `wp_links` RENAME `hoge_links`;
ALTER TABLE `wp_options` RENAME `hoge_options
ALTER TABLE `wp_postmeta` RENAME `hoge_postmeta`;
ALTER TABLE `wp_posts` RENAME `hoge_posts`;
ALTER TABLE `wp_term_relationships` RENAME `hoge_term_relationships`;
ALTER TABLE `wp_term_taxonomy` RENAME `hoge_term_taxonomy`;
ALTER TABLE `wp_terms` RENAME `hoge_terms`;
ALTER TABLE `wp_usermeta` RENAME `hoge_usermeta`;
ALTER TABLE `wp_users` RENAME `hoge_users`;

表示確認したところ特に問題無し。次に管理画面にアクセスしようとログイン画面を表示。ここも問題無し。ユーザー名とパスワードを入力しログインをクリック。すると下記の画面がでて管理画面にアクセスできなくなってしまった。

このページにアクセスするための十分なアクセス権がありません。

このページにアクセスするための十分なアクセス権がありません。

調べたところ、optionsテーブルとuser_metaテーブル内にプレフィックス付きのデータがあるのを発見。プレフィックス直でデータに使用してるのってどうなん…というのは置いといて、下記のような感じでデータを更新。

UPDATE hoge_options SET option_name = 'hoge_user_roles' WHERE option_name = 'wp_user_roles';
UPDATE hoge_usermeta SET meta_key = 'hoge_capabilities' WHERE meta_key = 'wp_capabilities';
UPDATE hoge_usermeta SET meta_key = 'hoge_user_level' WHERE meta_key = 'wp_user_level';

これで問題なく管理画面にもログインすることができた。

SIGMA DP1x買った。

$
0
0

購入に至る経緯

現在主に使用しているデジタル一眼レフカメラSIGMA SD15が大きくて重いので、気軽に持ち歩けるサブカメラを探そうと思い「最高のサブカメラを探す!」を書いた。

記事を買いているうちに、やはりSIGMAの一眼レフカメラに手を出してしまった以上、コンデジもSIGMAでなければ、と変な使命感にかられてしまう。DPは画角とF値の違うDP1x(28mm・F4)とDP2x(40mm・F2.8)があり、どちらにするかかなり迷ったが広角な写真が好きな事と金額が1万円ほど安いという理由からDP1xを購入することにした。

どこで買おう?

はじめに有名どころのネットショップ(カメラのキタムラ、マップカメラ、フジヤカメラetc)をチェックし、カメラのキタムラで中古品が2万円弱であるのを発見。だが、ヤフオクならもっと安く手に入るかも…と思い、出勤前、昼休み、帰宅してから深夜までヤフオクに張り付くこと1週間。僕の手元には今、カメラのキタムラから届いたDP1xがいらっしゃいます。

商品ランクがAB品(良品)で多少のスレ傷ありとの記載だっがが、現物を見てみると全く問題なし。最初からこれにすれば良かった…。ちなみに、カメラのキタムラのネット中古は商品を希望の店舗まで届けてもらいチェックできるというもの。チェックして気に入らなければ購入しないでも構わない。もし中古品は見てみないと買えないという方は一度利用されてみては。

で、DP1x

SIGMA DP1x

SIGMA DP1x

平日はなかなか外で撮る時間がないので、軽く室内を撮影してみたが、思った以上にオートフォーカスが遅い!SD15も速い方ではないし、DP1xも普通のカメラと比べれば遅いという話は聞いていたが、DP1やDP1sから比べると改善しているとの記事を見たので、まぁSD15くらいには動くでしょうと思っていたから、1枚目撮ったときは愕然とした。オートフォーカスが遅いというと焦点が定まるまでに時間がかかるとの認識だったが、DP1xはレベルが違う。半押しすると画面がフリーズするんだ…。

まぁ、SIGAMAのカメラはそんな不器用なところも好きだったりするのでこれぐらいは許容範囲。うん。一眼に比べると直感的に設定が変更できない感じはあるけど、慣れればコンデジの中では操作しやすい部類だと思うし、特にマニュアルフォーカスは便利。オートフォーカスが遅いため、対象までの距離が書いてあるダイヤルを回すだけでフォーカスを合わせることができるマニュアルフォーカスは常用する価値があると思う。

背面

背面

DP1xは電源を入れるとレンズが飛び出してくる沈胴型。レンズキャップをはめているとレンズが飛び出せないのでカメラが起動しない。しかもキャップは外しにくいのでパッと使いたいときには不便だ。せっかくのコンパクトさが失われてしまうが、レンズフードフィルターを付けてしまおうかと検討中。

起動したところ。

起動したところ。

そこまですると外付けファインダーも欲しくなってくるが、カメラが小さくて使いにくそうだし、そもそも純正は高い。LUMIX用のファインダーが幾分買いやすい価格ではあるのだが…。

今日から始めるMacのローカル開発環境構築(MAMP導入編)

$
0
0

今までMacのローカル環境で開発するときはVirtualBoxでバーチャル環境を作り、そこを使って開発していたのだが、重くなったりファイルのやり取りが面倒だったりして、結局外部にテストサーバーを立ててローカルでは開発しないということが多かった。しかし、先日の勉強会で参加者のみなさんがMAMPやXAMPPのローカル開発環境を持っていたのを見て、僕もちゃんと構築しておこうと思い直しローカル開発環境を構築してみることにした。

やりたいこと

Macでローカル開発環境を構築するにはMAMPを使うのが一般的のようだ。普通にインストールしてMAMPを起動すると、http://localhost:8080 というURLでローカルの環境にアクセスできるようになる。しかし、これだと本番環境とURLが異なりいろいろと面倒が増えるし、複数サイトを管理するときに不便である。そこで、MAMPのApacheの設定を変更してバーチャルホストを使用し、本番環境と同じURLでアクセスできる環境を構築する。

MAMPのインストール

まず下記のサイトからMAMPをインストールする。無料版(MAMP)と有料版(MAMP Pro)があるので無料版をダウンロードする(ただし、MAMPをダウンロードしても何故かMAMP Proが付いてくる…)。

ダウンロードしたらインストーラーを起動し、画面の指示に沿ってインストールする。

MAMPのインストーラー

MAMPのインストーラー

MAMPでバーチャルホスト設定

MAMPの設定

MAMPをインストールしたらアプリケーションフォルダに「MAMP」「MAMP PRO」の2つのフォルダが作られているので「MAMP > MAMP」からMAMPを起動する。初回起動時、下記のような画面が表示される。今回はMAMP PROは不要なので下記のようにチェックを外して「MAMPを起動」から起動する。

しつこくMAMP PROの利用を薦めてくるのでシャットアウトする。

しつこくMAMP PROの利用を薦めてくるのでシャットアウトする。

MAMPが起動する。ここで「サーバを起動」をクリックすれば http://localhost:8080 でアクセスできるようになるが、今回はバーチャルホストの設定を行いたいので「環境設定」をクリックする。

MAMP起動画面

MAMP起動画面

環境設定を開いたら「ポート」タブをクリックする。デフォルトではApacheのポートが 8080 となっているため、開発環境をブラウザで開くためにURLの後ろに「:8080」を付ける必要がある。本番環境と同じURLにしたいので、Apacheの標準ポート 80 に変更する(MySQLはデフォルトのままにしているが、未テストなので状況によってはこちらも標準の 3306 にしたほうが良いかも)。

ポートの設定

ポートの設定

Apacheの設定

上記でMAMPの設定は完了。次にApacheの設定ファイルでバーチャルホストの設定を行う。Apacheの設定ファイルは「/Applications/MAMP/config/apache/httpd.conf」にある。ファイルを開いたらバーチャルホストの設定ファイルを読みこませるために、下記の通りコメントアウトを外す。

#Include /Applications/MAMP/conf/apache/extra/httpd-vhosts.conf
Include /Applications/MAMP/conf/apache/extra/httpd-vhosts.conf

コメントアウトしたら /Applications/MAMP/conf/apache/extra/httpd-vhosts.conf ファイルを編集する。サンプルで2件の設定が入っていたのでそれはコメントアウトして、設定を追加した。サンプルとして僕の書いた設定など。

# 基本サイト
<VirtualHost *:80>
    ServerName localhost
    DocumentRoot /Applications/MAMP/htdocs/localhost/www
    <Directory "/Applications/MAMP/htdocs/2inc.org/www">
        Order Deny,Allow
        Deny from all
        Allow from 127.0.0.1
        Allow from localhost
    </Directory>
    ErrorLog logs/localhost
</VirtualHost>

# 2inc.org
<VirtualHost *:80>
    ServerName 2inc.org
    DocumentRoot /Applications/MAMP/htdocs/2inc.org/www
    <Directory "/Applications/MAMP/htdocs/2inc.org/www">
        Options Includes ExecCGI FollowSymLinks
        AllowOverride All
        Order Deny,Allow
        Deny from all
        Allow from 127.0.0.1
        Allow from localhost
    </Directory>
    ErrorLog logs/2inc.org/error_log
    CustomLog logs/2inc.org/access_log combined env=!no_log
</VirtualHost>

httpd-vhosts.conf を保存したら、DocumentRootで指定したディレクトリと、ErrorLogで指定したファイルを作成する。エラーログのパスは「/Applications/MAMP/Library/logs/」以下となる。もし作成しなかったらApacheのエラーが出てMAMPが起動しないので注意。

Hostsを編集する

ここまで設定できたらMAMPを起動する。ただし、バーチャルホストの設定ファイルで本番サイトと同じURLを指定したので、いまブラウザでそのURLを開いても本番サイトが表示されてしまう。このような場合はHostsと呼ばれるファイルを編集して「このドメインはlocalhost(このMac)を表示する」という設定をすれば良い。GUIで設定できたほうが便利なので、Hosts というアプリを利用する。

インストール、設定方法は下記が詳しい。インストールが完了するとMacの環境設定パネルにHostsが表示されるようになる。

あとは下記のようにipに「127.0.0.1」、hostnameにドメイン名を入力して、ローカル開発時にはuseにチェックすれば良い。

hosts設定画面

hosts設定画面

CSSの不便さを解消する!Sass(SCSS)のMacへの導入方法と基本的な使い方

$
0
0

Sass(SCSS)とは

SassとはCSSを拡張するメタ言語のこと。HAMLという言語でスタイルを記述する。SassをコンパイルすることでCSSファイルが生成される。Sassで、変数の使用、セレクタのネスト・継承などが使用できるようになる。

SassはHAMLという言語で記述すると前述したが、Sass 3.0からはSassy CSS(SCSS)というCSSの記述に近い新しい文法がサポートされた。

Sassのインストール

Sassを利用するにはRuby、HAML、SASSのインストールが必要となる。MacにはRubyがインストールされてるため、Rubyのインストールについては割愛する。

// HAMLのインストール
$ sudo gem install haml
// SASSのインストール
$ sudo gem install sass

Sassの使用方法

Sassは.scssファイルをファイルを作成して記述する。

構文

基本的な構文は以下のとおり。他にもSassには便利な関数も用意されている。

#container {
    @include clearfix; // ミックスインを利用
    width: 960px;
    /* 子要素をネストで定義 */
    #main {
        float: left;
        width: 650px;
    }
    #sub {
        float: right;
        width: 300px;
    }
    #footer {
        /* プロパティのネスト */
        font: {
            family: Arial;
            size: 85%;
            style: italic;
        }
    }
}
/* ミックスインを定義 */
@mixin clearfix {
    #zoom: 1;
    /* 擬似要素をネストで指定 */
    &:after {
        content: ".";
        display: block;
        clear: both;
        height: 0;
        visibility: hidden;
    }
}
/* 継承元となる基本ボタンスタイルを定義 */
.basicButton {
    border: #ccc solid 1px;
    background-color: #eee;
    padding: 5px 10px;
    text-align: center;
}
/* .basicbuttonを継承した.blueButtonを定義 */
.blueButton {
    @extends .basicButton;
    background-color: #00f;
    color: #fff;
}

.scssファイルのコンパイル

下記のコマンドでCSSファイルの生成(コンパイル)を行う。

$ sass hoge.scss hoge.css

また、次のコマンドでscssファイルを監視するようになり、scssファイルに変更があるたびに自動でコンパイルしてくれるようになる。

$ sass --watch hoge.scss:hoge.css
// ディレクトリ単位での監視(ディレクトリ内の.scssを.cssにコンパイル)
$ sass --watch /PATH/TO/css
// .scssと.cssを別ディレクトリで管理
$sass --watch /PATH/TO/sass:/PATH/TO/css

Compass

CompassはSassを拡張したCSSフレームワーク。mixinでCSS3のborder-radiusやbox-shadowが定義してあり、ベンダープレフィックスを補完したスタイルが簡単に利用できる。また、clearfixやリセットCSSなども含まれる。

ツールを利用して自動コンパイルする

下記は起動しておくだけで.scssファイルを自動コンパイルしてくれる便利なアプリ。ターミナルを利用しなくても良いのでコマンドが苦手でも簡単にSassを利用できる。

開発ツールにもSassを導入する

主要な開発ツールにもSassのシンタックスハイライトやコンパイルを行うためのプラグインが公開されている。

DP1xのフードアダプターHA-11とMCプロテクターを買った。

$
0
0

SIGMA DP1x用のレンズフード「HA-11」と、ケンコーのMCプロテクターを購入した(純正のプロテクターは高い…)。レンズキャップをはめたり外したりするのが以外に面倒だったからだ。HA-11はフードアダプターとフードのセットとなっており、レンズを保護するためのMCプロテクターを取り付けるためにはこのフードアダプターが必要となる。

フードアダプターを取り付けたDP1x、MCプロテクター、レンズフード

フードアダプターを取り付けたDP1x、MCプロテクター、レンズフード

MCプロテクターを取り付けたことで写りに影響があるのかが心配だったが、ちょっと撮ってみた感じだと特に変わったようには感じなかった。カメラ本体が小さいのでSD15の時と違ってカメラが持ちにくく思っていたが、レンズアダプターがそこそこ長く左手を添えるのに調度良いので両手で固定して取りやすくなった。

それにレンズのことをそれほど気にせずに取り扱いができるようになったの安心感は大きい。

DP1x + HA-11

DP1x + HA-11

購入前はフードが四角形なのがちょっとダサイのではと思っていたが、取り付けてみると良い具合にカメラっぽさが出て意外に良い。調べてみると純正では無いがフードもいろいろ売ってあるみたい。丸型が良いかなーと思っていたので、四角に飽きたら買ってみようと思う。

試し撮りした写真など。

ガラス板を載せられた我が家のカエル。

ガラス板を載せられた我が家のカエル。

ベランダから。光ファイバーのケーブルが邪魔…

ベランダから。光ファイバーのケーブルが邪魔…

各ディレクトリごと、各データベースごとにバックアップをとるシェルスクリプト

$
0
0

以前、「MySQLとWebディレクトリのバックアップをとるシェルスクリプト」という記事でMySQLとWebディレクトリのバックアップをとるシェルスクリプトを紹介したが、これは全てのデータベース、Webディレクトリをそれぞれまるっと一つの圧縮ファイルにまとめるものだった。

複数のサイトを一つのサーバーで運営しているが、容量が増えるに連れ、単一ファイルに圧縮してしまうと特定のサイトだけリストアしたいときや、バックアップの一部を別ホストに移動したいときなどに不都合がでてくるようになった。

そこで、MySQLサーバーのデータベース一覧を取得して各データベースごとに圧縮、指定したディレクトリ以下のディレクトリ(もしくはファイル)ごとに圧縮するようにシェルスクリプトを改良してみた。

#!/bin/sh

# 何日分保存するか
period=3
# バックアップしたいディレクトリ
wwwdir=/var/www
# バックアップ保存先ディレクトリ
dirpath=/home/backup
# 今日のバックアップを保存するディレクトリ
todaydir=`date '+%Y%m%d'`
# DBユーザー
dbuser=hoge
# DBパスワード
dbpassword=xxxxx

# 今日のバックアップを保存するディレクトリを作成
mkdir $dirpath/$todaydir

# MySQLバックアップ
for i in `mysql -u$dbuser -p$dbpassword -e "show databases"`
do
    if [ $i == "Database" ]; then
        continue
    fi;
    mysqldump $i -u$dbuser -p$dbpassword --opt | gzip > $dirpath/$todaydir/mysql.$i.sql.tar.gz
done;

# ディレクトリバックアップ
for i in `ls $wwwdir`
do
   tar cvfz $dirpath/$todaydir/www.$i.tar.gz $wwwdir/$i
done
chown -R all:all $dirpath/$todaydir

olddir=`date -d "$period days ago" '+%Y%m%d'`
rm -rf $dirpath/$olddir

実行すると、下記のようなファイルが生成される。あとはこれを別ファイルに転送するようにcronに設定すれば良い。その際は「さくらのレンタルサーバーで、WebディレクトリとMySQLを圧縮し、自動的に外部にバックアップする方法」を参考にされると良いかも…。

/home/backup
 ┗ /20130129/
  ┣ mysql.site-a.sql.tar.gz
  ┣ www.site-a.tar.gz
  ┣ mysql.site-b.sql.tar.gz
  ┗ www.site-b.tar.gz

Linuxで各ディレクトリごとの容量を表示するコマンド

$
0
0

Linuxで、各ディレクトリごとの容量を見たかったのだが、コマンドを知らなかったのでメモ。

# オプション付けなかったら一つ一つのファイルまで容量が表示されてしまう
du ~/Dropbox/github/*

# ~/Dropbox/github/ 直下のディレクトリ・ファイルをMB単位で表示
# -m はMB単位。-h に変えればファイルごとに適切な単位で表示
du -ms ~/Dropbox/github/*
1	Dropbox/github/MW-Theme-Switcher-on-Multi-Device-Switcher
1	Dropbox/github/MW-Theme-Switcher-on-WPtap
1	Dropbox/github/MW-WP-Form
1	Dropbox/github/MW-WP-Most-Popular
1	Dropbox/github/jquery.SimpleSlideShow.js
1	Dropbox/github/jquery.naviRollover

Ktai Entryを利用してメール投稿をしたとき「投稿者」権限でも即公開する方法

$
0
0

Ktai Entryは、設定したメールアドレス宛にメールを送信することで記事投稿ができるようになるプラグイン。基本的な使い方などは下記をご参照ください。

Ktai Entryは、設定したメールアドレスに送られてきたメールの送り主をもとに、誰の投稿かを判断する。そして、その送り主の権限を参照され記事のステータスが決まる。権限が管理者・編集者であれば記事はすぐに公開されるが、投稿者の場合は下書き状態で保存される。

今回、複数のユーザーが存在するサイトでKtai Entryを利用することになり、「作成者」権限のユーザーからメール投稿された記事も即公開状態にしたかったので、方法を調べてみた。

記事のステータスを決める部分に「ktai_post_status」フックが用意されていたのでそれを利用すれば良い。

public function ktai_post_status( $status, $flg, $author, $from) {
	// ユーザー情報を取得
	$user = wp_set_current_user( $author );
	// 投稿者でも公開状態で投稿
	if ( current_user_can( 'edit_published_posts' ) ) {
		$status = 'publish';
	}
	return $status;
}
add_filter( 'ktai_post_status', 'ktai_post_status', 10, 4 );

バックアップはクラウドへ…。Amazon S3でクラウドバックアップ

$
0
0

Amazon S3はAmazon Web Servicesによって提供されるクラウドストレージ。容量や通信量に応じて課金される重量課金制のウェブサービス。そこそこの容量でも通信量が多くなければ低価格で利用できるためバックアップ用途にとても相性が良い。

これまでVPSをバックアップ用途に利用していたが、Amazon S3でも簡単にバックアップの仕組みが構築できたので、これからWebサイト等のバックアップを行いたいと考えている方にAmazon S3へバックアップする方法をご紹介したい。

AWS(Amazon Web Services)に登録する

Amazon S3を利用するには、まずAWSにアカウント登録する必要がある。登録画面が英語で迷ってしまったが、本記事を書く際、オフィシャルにわかりやすく登録手順がまとめてあるのを見つけてしまった。まだ登録されていない方は下記を参考に登録されると良いだろう。

バケットの作成

Amazon S3は一般的なレンタルサーバーと違い、FTPでファイルやディレクトリをアップロードするのではなく、専用のコマンドで「バケット」と呼ばれる場所にファイルやディレクトリをアップロードし「オブジェクト」として保存する。バケットはAWSの管理画面から作成する。

AWS管理画面で「アカウント/コンソール > AWS Management Console」と進むとサービスの一覧が表示されるので「S3」をクリックする。

AWS Management Console

AWS Management Console

S3の管理画面が開くので、ここで「Create Backet」をクリックし任意のバケット名を入力、リージョン(どこのサーバーを使うか)を選択してバケットを作成する。

バケットの作成

バケットの作成

アクセスキーの取得

Amazon S3の操作には独自のコマンドを使用する。その際、正しい利用者かの識別のために「アクセスキー」が必要となる。AWS管理画面で「アカウント/コンソール > セキュリティ証明書」と進み、アクセスキーを取得する。

セキュリティ証明書

セキュリティ証明書

アクセスキーを作成すると「アクセスキーID」と「シークレットアクセスキー」が表示されるので控えておこう。

アクセスキーIDとセキュリティアクセスキー

アクセスキーIDとセキュリティアクセスキー

s3syncのインストール

Amazon S3でデータの転送や同期を行うには、s3syncというrsyncのようなコマンドを使用する。s3syncを使うにはrubyが必要なので、rubyのインストールも行う。

# rubyのインストール
$ sudo yum install ruby
# s3syncをダウンロード・解凍
$ wget http://s3.amazonaws.com/ServEdge_pub/s3sync/s3sync.tar.gz
$ tar zvfx s3sync.tar.gz
# configファイルを作成
# s3config.ymlの場所は、環境変数・$S3CONF/・$HOME/.s3conf/・/etc/s3conf/ のいずれか
$ sudo mkdir /etc/s3conf/
$ sudo cp s3sync/s3config.yml.example /etc/s3conf/s3config.yml
$ sudo vi /etc/s3conf/s3config.yml
##############################
aws_access_key_id: xxxxx       # アクセスキーIDを記述
aws_secret_access_key: xxxxx   # シークレットアクセスキーを記述
S3SYNC_NATIVE_CHARSET: UTF-8
AWS_CALLING_FORMAT: SUBDOMAIN  # リージョンが米国以外の場合は必要
##############################

s3cmdのインストール

s3cmdはAmazon S3を操作するためのコマンド群。今回はs3syncでバックアップデータのアップロードを行うが、容量が増大するのを防ぐために古いアップロードデータをs3cmdで削除することにする。

s3cmdはyumでもインストールできるし、公開されているzipファイルを解凍してそのまま利用することもできる。簡単なyumでのインストールがオススメだが、レンタルサーバーなどyumが使えない環境ではzipファイルをダウンロードしてインストールすることになる。ここではレンタルサーバーの例として「さくらのレンタルサーバー」の場合の設定を記しておく。

# yumでインストールの場合
$ cd /etc/yum.repos.d/
$ wget http://s3tools.org/repo/RHEL_6/s3tools.repo
$ sed -i -e s/enabled=1/enabled=0/ s3tools.repo
$ yum install s3cmd --enablerepo=s3tools

# zipファイルをダウンロードしてインストールの場合(pythonが必要)
$ mkdir -p $HOME/local/python
$ wget http://peak.telecommunity.com/dist/virtual-python.py
$ python virtual-python.py --prefix=$HOME/local/python -v
$ vi .cshrc
##############################
# 以下を追記
set path = ($HOME/local/python/bin $path)
set PYTHONPATH =($HOME/local/python)
##############################
# .cshrc再読み込みのため、一旦ログアウトしてログイン
$ wget http://peak.telecommunity.com/dist/ez_setup.py
$ python ez_setup.py
$ wget http://downloads.sourceforge.net/project/s3tools/s3cmd/1.1.0-beta3/s3cmd-1.1.0-beta3.zip
$ unzip s3cmd-1.1.0-beta3.zip
$ cd s3cmd-1.1.0-beta3
$ python setup.py install

# s3cmdの設定(「Access Key」でアクセスキーIDを指定、「Secret Key」でシークレットアクセスキーを指定)
$ s3cmd --configure

バックアップを実行するシェルスクリプト

Amazon S3にバックアップを行うために、次の内容でシェルファイルを作成し実行する。下記の例ではAmazon S3に3日分のバックアップデータを保存し、ローカルにはバックアップデータは残さないようにしている。

$ vi backup.sh
###########################
#!/bin/sh

# 何日分保存するか
period=3
# ローカルのバックアップ保存ディレクトリ
backupdir=/usr/local/backup
# バックアップの名前
today=`date '+%Y%m%d'`
# webディレクトリ
webdir=/var/www
# MySQLホスト名
dbhost=localhost
# MySQLユーザ名
dbuser=hoge
# MySQLパスワード
dbpasswd=xxxxx
# Amazon S3バケット名
backet=example
# Amazon S3バックアップ保存ディレクトリ
s3backupdir=backup

# ローカルにバックアップデータを保存
mkdir $backupdir/$today
tar cvfz $backupdir/$today/www.tar.gz $webdir

# mysqlデータを保存
/usr/local/bin/mysqldump -A -h$dbhost -u$dbuser -p$dbpasswd --opt | gzip > $backupdir/$today/mysql.sql.gz

# Amazon S3に転送
# /usr/local/bin/ruby /home/アカウント名/s3sync/s3sync.rb(さくらのレンタルサーバーの場合)
ruby /usr/local/s3sync/s3sync.rb -r --delete $backupdir/$today $backet:$s3backupdir

# ローカルのバックアップデータを削除
rm -rf $backupdir/*

# Amazon S3から古いファイルを削除
# yesterday=`date -v-${period}d +%Y%m%d`(さくらのレンタルサーバーの場合)
yesterday=`date -d "$period days ago" '+%Y%m%d'`
# /home/アカウント名/local/python/bin/s3cmd(さくらのレンタルサーバーの場合)
/usr/bin/s3cmd del -r s3://$backet/$s3backupdir/$yesterday/
###########################
$ chmod 700 backup.sh

public => falseなカスタム投稿タイプのとき、更新時に出る記事へのリンクを消す

$
0
0

register_post_type でカスタム投稿タイプを定義するとき、public => false とすることで「この投稿タイプでユーザーインターフェースを表示しない(show_ui=false)、post_type クエリがフロントエンドで実行できない(publicly_queryable=false)、検索結果からこの投稿タイプを除外する(exclude_from_search=true)、ナビゲーションメニューで post_type を選択候補から外す(show_in_nav_menus=false)」が設定される。このとき、さらに show_ui => true とすることで「フロントエンドで実行はできないが、ユーザーインターフェース(管理画面)は表示する」という状態にすることができる。

register_post_type( 'contacts',array(
    'public' => false,
    'show_ui' => true,
    'supports' => array( 'title' )
);

上記のような設定にすることで、表に出す必要はないが内部的に管理したいデータの管理画面を作成することができる。例えば「お問い合せ管理」や「顧客管理」などの用途が考えられる。

public => false, show_ui => ture で作成したカスタム投稿タイプの管理画面は以下。

一覧画面

一覧画面

一覧画面ではクイック編集部分の「表示」リンクが表示されなくなり、投稿画面では「投稿のプレビュー」、更新後の「投稿を表示ボタン」が表示されなくなる。ただ、なぜか更新後メッセージ表示部分の「投稿を表示する」だけは表示が残っている。

投稿画面(公開後)

投稿画面(公開後)

そこで、下記のコードを用いて更新後メッセージ表示部分の「投稿を表示する」を非表示にしてみた。コードは functions.php へ追記すればOK。

function cpt_public_false() {
	// カスタム投稿タイプのときだけ実行
	$cpts = get_post_types( array(
		'_builtin' => false,
	) );
	$pt = get_post_type();
	if ( ! in_array( $pt, $cpts ) )
		return;
	// カスタム投稿タイプオブジェクトを取得
	$pto = get_post_type_object( get_post_type() );
	// public => false のとき
	if ( isset( $pto->public ) && $pto->public == false ) {
		?>
		<style type="text/css">
		.post-php #message a {
			display: none;
		}
		</style>
		<?php
	}
}
add_action( 'admin_head', 'cpt_public_false' );

カスタム投稿タイプに独自の権限を設定して操作できるユーザーを制限する方法

$
0
0

WordPressの投稿タイプ(post や page 等)には、それぞれ閲覧・編集・削除等の権限が設定されている。独自のカスタム投稿タイプを設定した場合、その投稿タイプの権限の初期値は「post」となる。もし「問い合わせ管理」というカスタム投稿タイプを作成し、管理者だけが閲覧できるようにしたい場合を想定する。

// カスタム投稿タイプを作成
register_post_type( 'contacts', array(
	'public'  => false,
	'show_ui' => true,
) );

上記のように普通に作成すると権限が「post」となるため、「投稿」を操作できるユーザーは「問い合わせ管理」も操作できる状態となってしまう。そこで、register_post_type するとき、capability_type と capabilities を設定してオリジナルの権限を作成することでアクセス制御を行うことができる。

// 付与する権限を用意
$contact_capabilities = array(
	'read_contact',	  // 閲覧のメタ権限
	'edit_contact',   // 編集のメタ権限
	'delete_contact', // 削除のメタ権限
	'edit_contacts',   // 自分の投稿を編集する権限
	'edit_others_contacts', // 他のユーザーの投稿を編集する権限
	'publish_contacts',     // 投稿を公開する権限
	'read_private_contacts', // プライベート投稿を閲覧する権限
	'delete_contacts',       // 自分の投稿を削除する権限
	'delete_private_contacts',   // プライベート投稿を削除する権限
	'delete_published_contacts', // 公開済み投稿を削除する権限
	'delete_others_contacts',    // 他のユーザーの投稿を削除する権限
	'edit_private_contacts',  // プライベート投稿を編集する権限
	'edit_published_contacts' // 公開済みの投稿を編集する権限
);

// カスタム投稿作成時に権限グループとその権限を設定
register_post_type( 'contacts', array(
	'public'  => false,
	'show_ui' => true,
	'capability_type' => 'contact',
	'capabilities'    => $contact_capabilities,
) );

// 管理者に独自権限を付与
$role = get_role( 'administrator' );
foreach ( $contact_capabilities as $cap ) {
	$role->add_cap( $cap );
}

管理者以外のユーザー権限にもオリジナル権限を付与したい場合は「User Role Editor」を使用すれば良い。管理者に付与されているオリジナル権限から、どの権限を付与させるか選択することができる。

ちなみに、「メタ権限」を付与しないと権限不足となってしまい正しく管理画面を表示することができなかった。もし編集に関する権限を持たせたいとしたら edit_contacts、edit_others_contacts、edit_private_contacts、edit_published_contacts だけではなく edit_contact 権限も付与しなければならないようだ。

記事ごとにIP制限ができるWordPressプラグイン「MW IP Denied」

$
0
0

「MW IP Denied」は記事ごとにIP制限をすることができるWordPressプラグイン。このページは社内からのみ閲覧、学内からのみ閲覧など、企業サイトや学校サイトで需要がありそうなのだがプラグインが見つからなかったので自作した。

ダウンロード

使い方

WordPressのプラグインディレクトリにアップロードし有効化すると、投稿画面のサイドバーに「許可するIP」というメタボックスが表示されるようになる。何も記入しない場合は誰でもアクセスできるが、ここにIPアドレスを入力するとそのIPアドレスからのアクセスのみ許可されるようになる。

IPアドレスはカンマ区切りで複数指定でき、サブネットマスクも使用できる。

MW IP Deniedをインストールすると「許可するIP」メタボックスが追加される。

MW IP Deniedをインストールすると「許可するIP」メタボックスが追加される。

表示画面について

IP制限がかけられたページにアクセスすると「HTTP/1.1 401 Access Denied」のステータスコードを返し、画面には「Access Denied」とだけ表示する。

テンプレートディレクトリに「template-access-denied.php」というファイルを設置すればアクセス制限次の表示内容を変更することができる。

ショートコードの利用

MW IP Denied では2つのショートコードを利用できる。

mw-ip-allow

ショートコード「shortcode_ip_allow」を利用すれば、任意の範囲を任意のIPアドレスからのアクセス時のみ表示させることができる。

[ mw-ip-allow allow="192.168.1.1,192.168.1.10/24"]
ここの内容は 192.168.1.1、192.168.1.10/24 からのアクセスのみ許可される。
[ /mw-ip-allow]

mw-ip-ip-deny

ショートコード「mw-ip-ip-deny」を利用すれば、任意の範囲を任意のIPアドレスからのアクセス時のみ非表示にさせることができる。

[ mw-ip-deny deny="192.168.1.1,192.168.1.10/24"]
ここの内容は 192.168.1.1、192.168.1.10/24 からのアクセスのみ拒否される。
[ /mw-ip-deny]

ダウンロード

GitHubを使う上での超基本的なコマンド6つ

$
0
0

GitHubを使用したバージョン管理は以下の流れで行う。「ワークツリー」が実際の作業ファイルが保存されている作業ディレクトリ、「リポジトリ」がコミット(変更履歴)を記録する場所、「インデックス」が「ワークツリー」と「リポジトリ」の中間層となる。複数人でリポジトリを共有したい場合はリモートにリポジトリを作成し共有する。

GitHubでのバージョン管理の流れ

GitHubでのバージョン管理の流れ

ローカルリポジトリの作成 – git init

ローカルリポジトリの作成は「git init」で行う。git init コマンドで、カレントディレクトリがリポジトリとなる。

# ホームディレクトリに /git/test を作成
$ mkdir ~/git/test
# testディレクトリに移動
$ cd ~/git/test
# ローカルリポジトリ作成
$ git init
Initialized empty Git repository in /Users/hoge/git/test/.git/

インデックスに登録 – git add

「git add ファイル名」でファイルを登録することができる。スペース区切りで複数ファイルを指定することで、複数のファイルを一度にインデックスに登録できる。

# test.txt をインデックスに登録
$ git add test.txt

ブランチとインデックスの確認 – git status

「git status」でローカルリポジトリでどのブランチを使用しているか、また、インデックスの状況を確認することができる。

$ git status
# On branch master
#
# Initial commit
#
# Changes to be committed:
#   (use "git rm --cached <file>..." to unstage)
#
#	new file:   test.txt
#

変更をリポジトリに記録する – git commit

インデックスに登録した変更をリポジトリに記録するために「コミット」と呼ばれる操作を行う。コミットは「git commit」で行う。-m オプションを付けることでそのコミットに対するメッセージを指定することができる。

# First commit. というメッセージとともにコミット
# test.txt の追加を test リポジトリに記録する
$ git commit -m "First commit."

リモートリポジトリの登録 – git remote add

複数人でリポジトリを共有する場合、リモートにリポジトリを作成し、そこにプッシュ(アップロード)、プル(ダウンロード)することでリポジトリを共有することができる。
「git remote add 名前 URL」でリモートリポジトリを登録する。「名前」の部分は一般的に「orgin」が指定される。これで次回からプッシュ、プルを行う場合は自動的にこのリモートリポジトリが利用される。

# GitHub上でリポジトリを作成するとどのURLを指定すれば良いか指定されるのでそれを指定する。
# ここではGitHub上に test というリポジトリを作成した場合を想定する。
$ git remote add origin https://github.com/inc2734/test.git

リモートリポジトリに変更をプッシュする – git push

「git push リポジトリ ブランチ名」でリモートリポジトリに変更を記録できる。「-uオプション」でブランチ名を指定すれば、次回以降、そのブランチが自動的に指定される。

# git remote add で指定したリポジトリのmasterブランチに変更を記録する
$ git push -u origin master

WordPressの仮想robots.txtはWordPressがルートにインストールされているときしか生成されない。

$
0
0

検索エンジンのクローラーにクロールの範囲を指定できるrobots.txt。WordPressはこのrobots.txtを自動的に生成してくれる。

が、とあるサイトでこのWordPressが生成するrobots.txtにアクセスしようとすると404となってしまった。原因を調べると、WordPressのコアコードの中にその答えが。

// robots.txt -only if installed at the root
$home_path = parse_url( home_url() );
$robots_rewrite = ( empty( $home_path['path'] ) || '/' == $home_path['path'] ) ? array( 'robots\.txt$' => $this->index . '?robots=1' ) : array();

/wp-includes/rewrite.php を見ると「robots.txt -only if installed at the root」つまり、「robots.txtはルートにインストールしたときだけ」。http://example.jp/ にWordPressをインストールした場合 http://example.jp/robots.txt にアクセスすることはできるが、http://example.jp/hoge/ にWordPressをインストールした場合は http://example.jp/hoge/robots.txt にはアクセスできないということだ。


フォーム生成WordPressプラグイン「MW WP Form」に管理画面がつきました。

$
0
0

柔軟なフォームデザイン、確認画面が表示可能、同一URL・個別URLでの画面変遷が可能、豊富なバリデーションルールが特徴のWordPress用フォーム生成プラグイン「MW WP Form」をバージョンアップしました(0.5.5 ⇒ 0.6)。主な変更内容は以下のとおりです。

  • フォームを作成する管理画面が利用可能に。
  • アクションフック mwform_mail_{$key} を廃止。
  • フィルターフック mwform_mail_{$key} を追加。
  • 各バリデーション項目(必須以外)で入力がないときでも反応してしまっていたバグを修正。

ダウンロード

WordPressプラグインディレクトリ、もしくはWordPressの管理画面からダウンロードしてください。

デモ

次のパターンのデモを用意しました。ぜひご確認ください。

フォーム生成

フォームを使用する方法は、フォーム管理画面で作成する方法とfunctions.phpに設定を書く方法の2種類があります。

functions.phpを利用する場合のフォーム設置方法は「柔軟なカスタマイズ性が魅力のフォーム生成WordPressプラグイン「MW WP Form」」をご覧ください。

フォーム管理画面でのフォーム作成方法

ダッシュボード > MW WP Form から「新規作成」をクリックします。

MW WP Form フォーム管理画面

MW WP Form フォーム管理画面

本文

新規作成画面が開きますので、本文入力欄にHTMLを入力してフォームを生成します。各フォーム項目のボタンがありますので、適当なものをクリックしてフォーム項目を追加できます(書くフォーム項目にはname属性の指定が必要です。詳しくは「柔軟なカスタマイズ性が魅力のフォーム生成WordPressプラグイン「MW WP Form」」をご覧ください)。

MW WP Form が入力画面、確認画面、完了画面のどのフォームを表示するかはクリックしたボタンで決定されます。確認画面が必要なフォームの場合は「戻る」「確認・送信」の2つのボタンを設置してください。確認画面が不要なフォームの場合は「送信」ボタンのみを設置してください。

完了画面メッセージ

完了画面に表示したい内容を入力します。

URL設定

入力画面、確認画面、完了画面のURLをそれぞれ異なるものにしたい場合に入力します(同一のURLで変遷させる場合は未入力で構いません)。フォームを表示するための「フォーム識別子」は、ここで入力したページの本文に貼り付けてください。

URL設定例

入力画面、完了画面が同一URLの場合

入力画面URL  
確認画面URL  
完了画面URL  

入力画面、確認画面、完了画面を個別URLで利用する場合

入力画面URL http://example.jp/form_input/
確認画面URL http://example.jp/form_confirm/
完了画面URL http://example.jp/form_complete/

バリデーションルール

各フォーム項目のバリデーションルールを設定できます。バリデーションルールを追加する場合は「バリデーションルールを追加」をクリックします。バリデーションボックスが追加されるので、バリデーションをかけたいフォーム要素のname属性を「バリデーションを適用する項目」に入力します。

バリデーションルールを削除する場合は、各バリデーションボックスの左上の表示される「☓」をクリックします。

フォーム識別子

表示されているフォーム識別子をフォームを設置したいページに貼り付けます。もし個別URLのフォームの場合は、URL設定で入力したページに貼り付けてください。

メール設定

送信されるメールの内容を設定します。本文欄で{表示したいフォーム項目のname属性}と入力するとそのフォーム項目に変換されてメールが送信されます。

ダウンロード

WordPressプラグインディレクトリ、もしくはWordPressの管理画面からダウンロードしてください。

バグ・不具合があった場合や、セキュリティ的な面でお気づきなことなど、何かございましたらコメントやメールにてお知らせいただければと思います。

WordPressのHTMLエディタにクイックタグを追加するコード

$
0
0

WordPress投稿画面のHTMLエディタには「クイックタグ」と呼ばれるオリジナルのボタンを追加することができる。プラグインで追加する方法もあるが、functions.php にコードを書くことでも簡単に追加することができるので、その方法を。

Quicktags API

/**
 * Quicktags API
 * @param    id           ボタンのid属性値
 * @param    display      ボタンのvalue属性値
 * @param    arg1         HTMLの開始タグもしくはボタンクリック時に実行するコールバック関数
 * @param    arg2         HTMLの閉じタグ
 * @param    access_key   ボタンのアクセスキー
 * @param    title        ボタンのtitle属性値
 * @param    priority     優先度
 * @param    instance     Limit the button to a specifric instance of Quicktags, add to all instances if not present.(不明…)
 */
// QTags.addButton( id, display, arg1, arg2, access_key, title, priority, instance );

// アクションフック「admin_print_footer_scripts」にフックして追加
add_action( 'admin_print_footer_scripts', 'add_my_quicktag' );
function add_my_quicktag() {
    <script type="text/javascript">
    // <hr />を表示
    QTags.addButton(
        'my_hr',
        'hr',
        '<hr />',
        ''
    );
    // <b></b>で囲む
    QTags.addButton(
        'my_b',
        'b',
        '<b>',
        '</b>'
    );
    </script>
}

WordPressに簡単にGoogleMapsを設置できるプラグイン「MW Google Maps」を作りました。

$
0
0

WordPressに簡単にGoogleMapsを設置できるプラグイン「MW Google Maps」を作りました。投稿画面でマップを設定し、ショートコードを埋め込むことでマップを表示できます。一覧画面用に、複数のピンが表示されるショートコードもあります。

ダウンロード

使い方

WordPressのプラグインディレクトリにアップロードし有効化すると、投稿画面のサイドバー「設定」メニュー内に「MW Google Maps」というメニューが表示されるようになります。まずここでどの投稿タイプにマップを表示させるかを設定します。

設定メニューにMW Google Maps設定画面へのリンクが表維持されます。

設定メニューにMW Google Maps設定画面へのリンクが表維持されます。

Google Mapsを表示させたい投稿タイプを選択します。

Google Mapsを表示させたい投稿タイプを選択します。

MW Google Mapsの設定画面で選択した投稿タイプの投稿画面にGoogle Mapsを設定するためのメタボックスが表示されます。住所や名称を入力して「検索」を押してピンをたてる位置を決めます。ピンをドラッグすることも可能です。

Google Mapsメタボックス

Google Mapsメタボックス

Google Mapsを表示させるショートコード

[ mw-google-maps]

投稿内にマップを表示させるショートコードです。引数として「id」を渡すことで任意の投稿に設定されたマップを表示させることもできます。

// 投稿画面で使用
[ mw-google-maps]

// 任意の投稿に設定されたマップを表示(投稿IDを渡す)
[ mw-google-maps id="352"]

// テンプレートで任意の位置に表示
<?php echo do_shortcode( '[ mw-google-maps]' ); ?>

[ mw-google-maps-multi]

投稿一覧ページで使用するショートコードです。一覧ページに表示されている投稿に設定されたピンを一つのマップ内に表示します。拡大率はピンの位置に応じて自動的に調整されます。引数「key」に任意の文字列を渡すことでマップに設定される id を変更できます(デフォルトは mw-google-maps-map-multi)。また、引数「ids」にカンマ区切りで複数の投稿IDを渡すことで任意の投稿に設定されたマップを表示させることができます。

// テンプレート内で任意の位置にマップを表示
<?php echo do_shortcode( '[ mw-google-maps-multi]' ); ?>

// 任意の投稿に設定されたマップを表示(投稿IDを渡す)
<?php echo do_shortcode( '[ mw-google-maps-multi ids="19,85,330"]' ); ?>

ダウンロード

query_posts、have_posts でハマったこと

$
0
0

query_posts で $posts は上書きされない

$posts にはそのページで表示する投稿情報の一覧が格納される。query_posts を発行することで取得する投稿を変更することができるが、このとき $posts は変更されないようだ。

ただ、表示される情報は確かに変更されるので、どこの情報が変更されるのか調べたところ、$wp_query->posts の情報が変更されるようだ。

// index.php
var_dump( count( $posts ) ); // = 10
var_dump( count( $wp_query->posts ) ); // = 10
query_posts( array( 'posts_per_page' => 5 ) );
var_dump( count( $posts ) );  // = 10
var_dump( count( $wp_query->posts ) ); // = 5

WordPressループ内で have_posts を使うと無限ループになる。

ページに表示される投稿の一覧を取得してゴニョゴニョするショートコードを作成した。その際、WordPressループを使用して投稿の一覧を取得・処理をするコードを書いた。そのショートコードを記事内に記述しページを表示したところ、無限ループが発生し、投稿内容が無限に繰り返し表示するようになってしまった。

調べてみると、英語版のCodexに次のような記述が。

Calling this function within the loop will cause an infinite loop. (訳:ループ内で、この関数を呼び出すと、無限ループが発生します。)

解決策

WordPressループは使用せず、$wp_query->posts を foreach で回すようにコードを変更することで解決できた。

add_shortcode( 'hogeshortcode', 'hogeshortcode' );
function hogeshortcode( $atts ) {
    /* このコードは無限ループ!
    if ( have_posts() ) {
        while ( have_posts() ) {
            the_post();
            〜処理〜
        }
    }
    */

    // 下記のように変更すればOK
    global $wp_query, $post;
    foreach ( $wp_query->posts as $post ) {
        setup_postdata( $post );
        〜処理〜
    }
    wp_reset_postdata( $post );
}

query_postsで条件変更しても「MW Google Maps」に表示されるピンが変更されないので調べてみた。旧バージョンをお使いの方はバージョンアップしてください。

jQueryで特定の要素を包み込む方法まとめ

$
0
0

基礎編

wrap

マッチする要素を1つずつ囲む場合は wrap を使います。

<div class="hoge">
    <span>span</span>
    <span>span2</span>
    <b>b</b>
</div>
$( '.hoge span' ).wrap( '<p></p>' );
<div class="hoge">
    <p><span>span</span></p>
    <p><span>span2</span></p>
    <b>b</b>
</div>

wrapInner

マッチする要素の子要素を囲む場合は wrapInner を使います。

<div class="hoge">
    <span>span</span>
    <span>span2</span>
    <b>b</b>
</div>
$( '.hoge' ).wrapInner( '<p></p>' );
<div class="hoge">
    <p>
        <span>span</span>
        <span>span2</span>
        <b>b</b>
    </p>
</div>
$( '.hoge span' ).wrapInner( '<i></i>' );
<div class="hoge">
    <p>
        <span><i>span</i></span>
        <span><i>span2</i></span>
        <b>b</b>
    </p>
</div>

wrapAll

マッチする要素を1つにまとめて囲む場合は wrapAll を使います。

<div class="hoge">
    <span>span</span>
    <span>span2</span>
    <b>b</b>
</div>
$( '.hoge span' ).wrapAll( '<p></p>' );
<div class="hoge">
    <p>
        <span>span</span>
        <span>span2</span>
    </p>
    <b>b</b>
</div>

応用編

特定の子要素を除く子要素全てを1つの要素で囲みたい

全体を1つにまとめたいけど、特定の要素だけは含めたくないという場合の方法を紹介します。
下記は「i要素以外を1つのpで囲みたい場合」の例です。

<div class="hoge">
    <span>span</span>
    <i>span2</i>
    <b>b</b>
</div>
var hoge = $( '.hoge' );
var hoge.children(  '*:not( i )'  ).wrapAll( '<p></p>' );
<div class="hoge">
    <i>span2</i>
    <p>
        <span>span</span>
        <b>b</b>
    </p>
</div>
Viewing all 235 articles
Browse latest View live