データベースに接続できません

TORIYAMAHONPOS WordPressのまめ知識

  • 新規投稿画面にフック

    プラグインより新規投稿画面にだけJavsScriptを追加したい場合には、admin_print_scripts-post-new.php というアクションフックがあると分かった。たとえば、新規投稿画面であらかじめ特定のカテゴリーを選択状態にしておくということができる。こんなことをしなくてもデフォルトのカテゴリーは設定できるが、投稿元によってカテゴリーを変更したかったのだ。

    [PHP]
    function my_scripts_new(){
    $file = WP_PLUGIN_URL . ‘/’ .dirname(plugin_basename( __FILE__ )) .’/example.js’;
    wp_enqueue_script(‘wp-multilingual_new.js’, $file);
    }
    add_action(‘admin_print_scripts-post-new.php’, ‘my_scripts_new’);
    [/PHP]

    似た処理で、新規投稿画面のフッタにだけ処理を加えるということもできる。その場合は、admin_footer-post-new.php というアクションフックが利用できる。
    [PHP]
    function my_footer_new(){
    // 処理
    }
    add_action(‘admin_footer-post-new.php’, ‘my_footer_new’);
    [/PHP]

  • Feedにアイキャッチ画像を追加

    以前フィードに画像を追加する方法として、フィードテンプレートを上書きする方法をメモしていた。画像を追加するだけなら、もっと簡単な方法があった。

    [PHP]
    function my_thumbnail_feeds($content) {
    global $post;
    if(has_post_thumbnail($post->ID)) {
    $content = ‘

    ‘ . get_the_post_thumbnail($post->ID, array(150,150)) . ‘

    ‘ . $content;
    }
    return $content;
    }
    add_filter(‘the_excerpt_rss’, ‘my_thumbnail_feeds’);
    add_filter(‘the_content_feed’, ‘my_thumbnail_feeds’);
    [/PHP]

    なるほど、フィード用にもフィルタがあったんだ!

  • マルチサイトでWPtouch

    WPtouchの無料版では、機能制限としてテーマディレクトリを設定することができない。テーマディレクトリは/plugins/wotouch/themes/default/に固定されているので、スマホ用テーマを自作した際には、このディレクトリ下のファイルを差し替えるのが無難としてきた。
    このほど複数あったブログをひとつのWordPressにまとめ、マルチサイトとして管理するようにしたところ、ここでつまずいた。ブログは複数あるのに、WPTouchのテーマディレクトリが固定(ひとつしかない)ではブログによってスマホ用テーマを分けることはできないではないか。

    おとなしく有料版にグレードアップするしかないのか?
    そもそも有料版ではマルチサイトに対応しているのか?

    と諦めモードになりつつ、ダメモトでWPtouchのコアコードを修正する手段にでた。wptouch.phpの中にreturn ‘default’としている箇所が2つある。まさにテーマディレクトリを固定で返しているところだ。ここでディレクトリ名を操作できそうだ。get_blog_ID()によりマルチサイトのブログIDが分かるので、この値によってテーマ名を分ければよさそうだ。たとえばブログIDが2であればexample-2、3であればexample-3というように分岐してそれぞれのディレクトリにテーマファイルを置けばよい。結果、いまのところうまく動いている!

  • blogというサブディレクトリ名は禁止

    以前はルート直下の”blog”というディレクトリにWordPressをインストールして運営していた当ブログである。WordPressのバージョンアップに伴い、マルチサイトのサブディレクトリとしてブログを構築することにした。

    ルートディレクトリにWordPressをインストールし、ネットワーク管理者の[新規サイトを追加]を行ったところ、エラーで作成できなかった。

    以下の語句は WordPress の機能によって予約されており、ブログ名として使うことはできません: page, comments, blog, files, feed

    とのことで、”blog”というブログ名はダメらしい。
    そういわれても、これまで”blog”だったのだからURLは変えたくない。CMSとして複数サイトを運営できるシステムであるなら、そのなかに”blog”という名前のブログを作成するのは自然な要求ではないのか。そうこうしているうちに、ネットワーク管理者の設定に[登録の設定]-[禁止名]の項目を見つけた。そこに、

    www web root admin main invite administrator files blog

    と設定されているので、おぉここか!?と思って”blog”を削除した。が、新規サイトを作成しようとしても同じエラーである。”blog”はどうしてもダメらしい。設定項目の値と、エラー内容が異なるではないか、この設定はなんなのか?

    仕方なく本ブログは別のサブディレクトリ名で作成し、.htaccessにリダイレクトの設定をした。

  • WordPressを3.1.2にアップデート

    ちょうど連休直前にWordPress3.1.2の日本語版がリリースされたので、よいタイミングだった。もともとはルート直下の複数ディレクトリにそれぞれWordPressをインストールしてサイトを運営していた。今回はルートディレクトリに最新版WordPressをインストールし、サブディレクトリ型マルチサイトを構築すればよいと検討をつけた。インストールしたい階層が以前と異なるため、備え付けのアップデート機能は使わず自力で行う。

    1. 旧サイトのデータベースをバックアップ

      • phpMyAdminでmySQLのテーブルをエクスポートする。
        対象テーブルは、WP_USERS、WP_USERMETA、WP_OPTION以外のすべて
        オプションは、

        • エクスポートでSQL形式
        • オプションの構造で、
          • DROP TABLE / DROP VIEWを追加
          • AUTO_INCREMENT 値を追加する
          • テーブル名やフィールド名を逆クォートで囲む
        • オプションのデータで、
          • 完全な INSERT 文を作成する
          • 長い INSERT 文を作成する
          • 作成するクエリの最大長 50000
          • BLOBに16進数表記を利用する
          • エクスポート形式 INSERT
        • ファイルに保存する
        • エンコーディングnon

        もし投稿履歴があれば事前に削除しておくと、バックアップデータが小さくなる。
        DELETE FROM wp_posts WHERE post_type=’revision’

      • 添付ファイルをダウンロード
        /wp-content/uploads/以下すべてのファイルをFTPでダウンロードする。
    2. 旧サイトを削除
      サブディレクトリ型マルチサイトを作成する場合、同じディレクトリ名が物理的に存在してはならない。削除は怖いのでリネームしておく。

    3. WordPress3.1.2のインストール
      同じデータベース内に旧テーブル(例:WP_)を残しつつ、別の接頭辞(例:WW_)を指定してインストール。マルチサイト化しておく。

    4. データベースの移行
      旧ブログの記事を、新サイトの2つめのブログの記事として流し込む。

      • さきほどエクスポートしたSQLファイル内を書き換える
        • テーブル接頭辞のWP_をWW_2_に置換する。
        • 画像のパスを書き換える。
          /wp-content/uploads/ を、/files/ に置換すればよい。
      • phpMyAdminでSQLファイルをインポート
    5. 添付ファイルをアップロード
      アップロード先は、/wp-content/blogs.dir/2/files/
      例えば、
      http://example.com/example/files/2011/05/01/example.jpg
      というURLの画像ファイルがあった場合、
      ディレクトリ上では以下に配置すればよい。
      ↓↓↓
      /wp-content/blogs.dir/2/files/2011/05/01/example.jpg

    6. テーマやプラグインを設定
      WordPressの関数で変更、非推奨になった箇所があるため、自作のテーマやプラグインでエラーや警告が発生した。修正に半日を費やす。
      以前はできていたことができなくなった仕様もある。例えば、

      • URLにパラメータを持たせて処理していたページ、例えばパーマリンク?param=valueの場合valueに全角文字が使えなくなった。
      • 複数のカテゴリを持つ記事のパーマリンクが一意になった

      このように、以前なんとなくできていたことが明示的にできなくなっている。システム的な矛盾をなくすためと理解するものの、パーマリンクを変更せざるを得ないページも発生した。

  • MySQLを5.1にアップデート

    面倒でほったらかしになっていたサーバまわりのアップデートを、連休中に行った。WordPress3.0がリリースされてからほぼ1年になるので、かなりサボっていたことになる。業務ではもちろん3.0以上を使用していながらも、当ブログは2.8のままだった。というのも、WordPressをバージョンアップするには、さくらインターネットでMySQLのバージョンを4から5に上げねばならなかったからだ。MySQLはMovableTypeと併用していることもあり、手を付けるのに勇気を要した。連休の目標はMySQLとWordPressを最新版にすることと決めた。

    さくらインターネットでのMySQLのバージョンアップは以下のとおりだ。データが少ないためかなんのトラブルもなく、30分もかからずに終わった。

    1. phpMyAdminですべてのテーブルをエクスポートする。複数サイトを運営しているので、サイトごとに分けてエクスポートした。文字コード(UTF-8)に気をつけながら、念のためSQL形式のほかWordPress形式やMT形式でもバックアップを取っておく。
    2. phpMyAdminからいったんログアウトし、さくらのコントロールパネルでデータベースを削除する。やり直しがきかない作業なので、バックアップ内容の確認に念を入れてから行う。
    3. 新しいphpMyAdminにログインし、データベースをMySQL5.1で新規作成する。ここでデータベースのサーバ名とパスワードが変更された。
    4. データベースの照合順序をutf8_generalciに設定し、SQLファイルをインポートする。
    5. wp-config.phpやmt-config.cgiでデータベースのサーバ名とパスワードを修正
    6. ブログの表示を確認して完了
  • この投稿を先頭に固定表示

    公開状態のオプションとして「この投稿を先頭に固定表示」がある。
    テーマのループでは先頭に出現し、投稿ブロックにstickyというクラスが付加される。テーマを作成する際には、このstickyに対応することが要件となっている。つまり通常の投稿と区別するために、背景や文字色を変更しておくとよい。実際には「お知らせ」や「イベント告知」のようなかんじで利用するとよいのか?

    stickyかどうかは、is_sticky()で調べることができる。ついでに、どこに保存されているのかと調べてみるとwp_optionsテーブルのoption_nameが’sticky_posts’の箇所にあった。複数指定した場合でも、ここに配列として格納される。

  • コメントの表示数を制限する

    singleページでのコメントの表示数について、
    ディスカッション設定によりコメントを複数ページに分割表示できるものの、singleページを表示するタイミングで取得するコメントは常にその記事に関するコメントすべてとなる。つまりコメントを5件づつ表示する場合でも、その投稿についてコメントが100件あれば100件を取得している。

    あるサイトのサーバー負荷が異様に重くて調べたところ、特定の記事についてコメントが10000件以上ついているためと分かった。この10000件とは決してスパムではなく、singleページがFLASHゲームで遊ぶ構成になっているため人気ゲームにコメントがたくさんついてしまったのだ。コメントは最新の50件を5件づつ分割表示している。必要なコメントは50件なので、できれば古くなったコメントを削除してしまいたかった。しかしサイト運営者からは過去のコメントを削除しないようにと要求されている。
    そうこうしているうちに、問題となるslow queryが浮かび上がった。
    SELECT wp_comments.* FROM wp_comments WHERE comment_post_ID = '99' AND comment_approved = '1' ORDER BY comment_date_gm

    このSQL文はwp-includes/comment-template.phpのcomments_template()という関数にあった。singleページを表示するさいにグローバル変数の$commentsにコメント配列をセットしている部分である。

    ここにLIMITを追加すればよいのだろうがコアコードは修正できない。フォーラムで質問したところ、query フックでlimit句を追加するアドバイスをいただいた。しかし、コメント取得のSQL文は3とおりがあり並び順が固定の場合もあるため、どうも思ったとおりにいかない。そうこうしているうちに、コメントの取得に件数が制限できないのはコメント階層を考慮してのことだと気付いた。単純にLIMITを付けるだけではダメなのだ。

    今回はコメント階層を使っていないということもあり、comments_template()をfunction.phpにリネームコピーしてカスタマイズすることで対処した。 ここのSQL文のORDERをDESCにして、LIMITを追加。さらにsingle.phpからcomments_template()を呼んでいる部分を、新しい関数名に変更した。

    問題のsingleページはなんとか軽くなったように思う。
    こんな対応でよいのかな?10000件もコメントがつくとは想定外だ。

  • ログイン画面のロゴ

    ログイン画面に表示される「WORDPRESS」というロゴを変更することができる。
    [PHP]
    function my_login_logo() {

    $url = “画像のフルパス”;
    echo ‘

    ‘;
    }
    add_action(‘login_head’, ‘my_login_logo’);
    [/PHP]

    さらに、ダッシュボードの左上の「W」というアイコンを変更することもできる。
    [PHP]
    function my_admin_logo() {

    $url = “画像のフルパス”;
    echo ‘

    ‘;
    }
    add_action(‘admin_head’, ‘my_admin_logo’);
    [/PHP]

    どちらもフックを利用してCSSを上書きしている。属性が強いのか、!importantが必要だった。
    これだけでも、けっこうカスタマイス感が上がる!

  • 表示条件にキーワードを含める

    一覧の表示条件にキーワードを含めるとは、指定のキーワードでの検索結果つまり、
    ブログのURL?s=キーワード
    をやりたいのである。これを検索フォームを使わずに、query_posts()でやってみた。

    [PHP]
    query_posts(array(‘s’=>’キーワード’));
    if (have_posts()){
    while (have_posts()) : the_post();
    // 処理
    endwhile;
    }
    wp_reset_query();
    [/PHP]

    Codexには、query_posts()のパタメータとしてキーワードは記載されていないものの、検索フォームのパラメータであるsを使ってみたらうまくいった。あたりまえといえばあたりまえなのか、こんなことやる必要のある人がいないだけか。