カテゴリー: WordPress/php

  • WordPress開発が捗る!ブックマークしておくべきCodexまとめ

    WordPress開発が捗る!ブックマークしておくべきCodexまとめ

    WordPressには関数やフック機能など、便利なものが一通り揃えられていますが、我々はそのほんの一部しか知りません。多すぎて覚えられるわけないし。なので、毎回「どうすんだっけなー」と探しちゃいますよね。

    WordPressには、WordPressの全てが記されているであろう「WordPress Codex」というWikiが存在するんですが、初心者のうちはあんまり見ないですよね。なんか、ググって出てきたコードをコピペする感じ。

    初心者のうちはそれでいいと思いますが、ある程度関数とかわかって自分でコードを書けるようになったらこれほどありがたいサイトはないので、ぜひ見てみてくださいね。今回は、その中でも開発に便利なページを紹介しますので、ブックマークしておきましょう。




    関数リファレンス

    リンク

    WordPressの関数が全部あります。ここだけでもブックマークしておけばとりあえずOK。

    条件分岐タグ

    リンク

    よく使う条件分岐タグ。ほぼどんなものでも条件分岐できちゃう。ログインしてるときだけとか、便利ですよね。

    テンプレートタグ

    リンク

    これ一つでいろんなテンプレートが呼び出せちゃうタグたち。

    管理メニューの追加

    リンク

    管理画面のメニューに項目を追加するための関数たち。テーマ開発やプラグイン開発には必須ですね。

    プラグイン API/フック

    リンク

    涙が出るほど便利だけど、鼻血が出るほどややこしい、フックについての基本が書かれています。特に「いつ関数を実行するのか」を指定するためのフックは開発でよく使いますね。

    ただ、使い方についてはCodexの説明は正直よくわからないので、ググったほうがいいです。僕もそのうち書く…かも。

    コーディング規約

    リンク

    WordPress開発するときのコーディング規約について書かれています。

    「コーディング規約?何それ?」となってる方はぜひ見てみてください。あなたのコード、たぶん相当汚いです。

    WordPressのコーディング規約は別に守らなくても誰からも怒られませんが、規約をなるべく守るよう心掛けるだけでも、綺麗で統一されたコードが書けるようになりますよ。なんか、WordPressしてるわーって気分になります。

    おわり

    以上、ブックマークしておくと捗りそうなページを紹介しました。最初はたぶん、見ても何書いてるかわからないと思うんですが、わかるようになればすごく楽しいです。特に、PHPの基礎がわかったら読めるようになると思いますよ。

    PHP初心者にまず読んでほしい一冊の本

    とりあえずざっと見て「こんなんあるんかー」くらいに認識しておいて、いざ開発で詰まったとき、「そういえば…」って思い出せたらいい感じ。

    ではでは、良いWordPressライフを!

  • WordPress 管理画面「ツール」に項目を追加する方法

    WordPress 管理画面「ツール」に項目を追加する方法

    管理画面のメニューとか「設定」内に項目を追加する方法はググればすぐ見つかったんだけど、「ツール」内に項目を追加する方法がすぐには見つからなかったのでメモ。

    使うのはadd_management_page()という関数でした。




    使い方

    使い方は以下の通り

    add_management_page( 'Custom Permalinks', 'Custom Permalinks', 'manage_options', 'my-unique-identifier', 'custom_permalinks_options_page' );

    使用例:

    function all_update() {
      add_management_page('一括更新', '一括更新', 8, 'all_update', 'all_update_page');
    }
    add_action('admin_menu', 'all_update');
    
    function all_update_page() {
      // HTML を表示させるコード
      ?>
      <div class="wrap">
        <h2>一括更新</h2>
        <p>ここにHTMLを書いていくよ</p>
      </div>
    <?php
    }

     

    プラグインをインストールするとなんでもかんでも「設定」に入りがちだけど、ツールっぽい機能はやっぱりツールにいれたいよね。ということで探してみました。

    add_management_page()でツール内に項目を追加する以外にも、「ユーザー」とか「ダッシュボード」とかにも追加できる関数をまとめて紹介しているCodexがありました。これをブックマークしておくと、プラグイン開発が捗りそうですね!

    現場からは以上です。

  • WordPress カスタム投稿ごとにfeedの内容を出し分ける

    WordPress カスタム投稿ごとにfeedの内容を出し分ける

    クラ「WordPressのfeedをカスタマイズしてほしいです。しかもカスタム投稿ごとに内容を変えて。」

    ぼく「できらぁ!!」

    というわけでやってみました。案外簡単でした。




    デフォルトのfeedを無効にする

    まず、ややこしいのでWordPressデフォルトのfeedを無効にしておきましょう。functions.phpに以下記述

    remove_filter('do_feed_rdf', 'do_feed_rdf', 10);
    remove_filter('do_feed_rss', 'do_feed_rss', 10);
    remove_filter('do_feed_rss2', 'do_feed_rss2', 10);
    remove_filter('do_feed_atom', 'do_feed_atom', 10);

    feedのテンプレートをコピー

    自分でfeedのphpを書くのは非常にめんどうなので、WordPress本体のものをコピーして使っちゃいましょう。ちなみに、今回コメントのfeedは無視することにします。

    “wp-includes”の中に以下4つのfeed用テンプレートがあるので、コピーしてテーマの中に持ってきます。

    • feed-atom.php
    • feed-rdf.php
    • feed-rss
    • feed-rss2.php

    僕は、テーマの中に”feed”というディレクトリを作り格納しました。

    新テンプレートを読み込むようにする

    上でテーマ内に持ってきたfeedテンプレートを、WordPressのfeedとして使うようにします。functions.phpに以下記述

    function custom_feed_rdf() {
      $template_file = '/feed/feed-rdf.php';
      $template_file = ( file_exists( get_stylesheet_directory() . $template_file )
          ? get_stylesheet_directory()
          : ABSPATH . WPINC
          ) . $template_file;
      load_template( $template_file );
    }
    add_action('do_feed_rdf', 'custom_feed_rdf', 10, 1);
    
    function custom_feed_rss() {
      $template_file = '/feed/feed-rss.php';
      $template_file = ( file_exists( get_stylesheet_directory() . $template_file )
          ? get_stylesheet_directory()
          : ABSPATH . WPINC
          ) . $template_file;
      load_template( $template_file );
    }
    add_action('do_feed_rss', 'custom_feed_rss', 10, 1);
    
    function custom_feed_rss2( $for_comments ) {
      $template_file = '/feed/feed-rss2' . ( $for_comments ? '-comments' : '' ) . '.php';
      $template_file = ( file_exists( get_stylesheet_directory() . $template_file )
          ? get_stylesheet_directory()
          : ABSPATH . WPINC
          ) . $template_file;
      load_template( $template_file );
    }
    add_action('do_feed_rss2', 'custom_feed_rss2', 10, 1);
    
    function custom_feed_atom( $for_comments ) {
      $template_file = '/feed/feed-atom' . ( $for_comments ? '-comments' : '' ) . '.php';
      $template_file = ( file_exists( get_stylesheet_directory() . $template_file )
          ? get_stylesheet_directory()
          : ABSPATH . WPINC
          ) . $template_file;
      load_template( $template_file );
    }
    add_action('do_feed_atom', 'custom_feed_atom', 10, 1);

    do_feed_atom()あたりをWordPress Codexでさらっと見ておくとわかりやすいです。



    feedテンプレートをカスタマイズ

    これでようやくカスタマイズの準備が整いました。さっそくカスタマイズ…する前に、もうちょっと事前知識を入れておきましょう。

    投稿タイプごとにfeedを表示させるには?

    例えば、通常の投稿のfeedであれば、”http://hogehoge.com/feed/”というように、ホームURLの末尾に”/feed/”をつければ表示されます。

    では、カスタム投稿”shop”の場合はどうかというと、

    “http://hogehoge.com/feed?post_type=shop”

    というように、”?post_type=[カスタム投稿名]”をパラメータとしてつけることで表示できます。

    ということはすなわち、テンプレートに”post_type”というパラメータが渡っていて、それが変数として使われていると推測されます。

    そしてWordPressさんのことだから、変数名はきっと”$post_type”だろうと思ってやってみたところ、ドンピシャでした。よかったー、ここわかんなかったらけっこう苦労してたかも。

    というわけでカスタマイズ開始

    一番簡単な”feed-rss.php”を例にします。デフォルトまんまで開くとこんな感じ

    <?php
    /**
     * RSS 0.92 Feed Template for displaying RSS 0.92 Posts feed.
     *
     * @package WordPress
     */
    
    header('Content-Type: ' . feed_content_type('rss') . '; charset=' . get_option('blog_charset'), true);
    $more = 1;
    
    echo '<?xml version="1.0" encoding="'.get_option('blog_charset').'"?'.'>'; ?>
    <rss version="0.92">
    <channel>
    	<title><?php wp_title_rss(); ?></title>
    	<link><?php bloginfo_rss('url') ?></link>
    	<description><?php bloginfo_rss('description') ?></description>
    	<lastBuildDate><?php
    		$date = get_lastpostmodified( 'GMT' );
    		echo $date ? mysql2date( 'D, d M Y H:i:s +0000', $date ) : date( 'D, d M Y H:i:s +0000' );
    	?></lastBuildDate>
    	<docs>http://backend.userland.com/rss092</docs>
    	<language><?php bloginfo_rss( 'language' ); ?></language>
    
    	<?php
    	/**
    	 * Fires at the end of the RSS Feed Header.
    	 *
    	 * @since 2.0.0
    	 */
    	do_action( 'rss_head' );
    	?>
    
    <?php while (have_posts()) : the_post(); ?>
    	<item>
    		<title><?php the_title_rss() ?></title>
    		<description><![CDATA[<?php the_excerpt_rss() ?>]]></description>
    		<link><?php the_permalink_rss() ?></link>
    		<?php
    		/**
    		 * Fires at the end of each RSS feed item.
    		 *
    		 * @since 2.0.0
    		 */
    		do_action( 'rss_item' );
    		?>
    	</item>
    <?php endwhile; ?>
    </channel>
    </rss>
    

    なんのことはない、普段よく触るテンプレートとだいたい一緒です。

    実際にfeedをブラウザを表示させ、どの関数が何を出力しているのか見ながらやればけっこう簡単に理解できます。

    そして、33行目を見てください。そう、これ…あれですよね!普通に記事をループさせてるだけです!

    記事をループしているので、いつも通り$postとかも使えちゃいます。

    なので、カスタムフィールドもあっさり取得できます。以下は例えばAdvanced Custom Fieldsで取得できる値。

    $link = get_field(‘acf_link’, $post->ID );

    “$post”さえあればいろんな値が取得できます。

    で、カスタム投稿タイプは?

    肝心のそこですが、例えば

    “http://hogehoge.com/feed?post_type=shop”

    で開かれたfeedには、$post_type という変数に”shop”が格納されています。ありがたいですね。

    じゃああとは、$post_typeに入っている値によって場合分けしてやればOKです。

    <?php
    /**
     * RSS 0.92 Feed Template for displaying RSS 0.92 Posts feed.
     *
     * @package WordPress
     */
    
    header('Content-Type: ' . feed_content_type('rss') . '; charset=' . get_option('blog_charset'), true);
    $more = 1;
    
    echo '<?xml version="1.0" encoding="'.get_option('blog_charset').'"?'.'>'; ?>
    <rss version="0.92">
    <channel>
    	<title><?php wp_title_rss(); ?></title>
    	<link><?php bloginfo_rss('url') ?></link>
    	<description><?php bloginfo_rss('description') ?></description>
    	<lastBuildDate><?php
    		$date = get_lastpostmodified( 'GMT' );
    		echo $date ? mysql2date( 'D, d M Y H:i:s +0000', $date ) : date( 'D, d M Y H:i:s +0000' );
    	?></lastBuildDate>
    	<docs>http://backend.userland.com/rss092</docs>
    	<language><?php bloginfo_rss( 'language' ); ?></language>
    
    	<?php
    	/**
    	 * Fires at the end of the RSS Feed Header.
    	 *
    	 * @since 2.0.0
    	 */
    	do_action( 'rss_head' );
    	?>
    <?php if( $post_type == 'shop' ): ?>
    <?php while (have_posts()) : the_post(); ?>
    <?php $thumb = get_field('acf_thumb', $post->ID ); ?>
    	<item>
    		<title><?php the_title_rss() ?></title>
    		<?php if( $post->post_content ): ?>
    		<description><![CDATA[<?php the_excerpt_rss() ?>]]></description>
    <?php endif; ?>
    <?php if($thumb): ?>
    		<link><?php the_permalink_rss() ?></link>
    <?php else: ?>
    <link><?php echo home_url('/'); ?></link>
    <?php endif; ?>
    		<?php
    		/**
    		 * Fires at the end of each RSS feed item.
    		 *
    		 * @since 2.0.0
    		 */
    		do_action( 'rss_item' );
    		?>
    	</item>
    <?php endwhile; ?>
    <?php else: ?>
    <?php while (have_posts()) : the_post(); ?>
    <?php $link = get_field('acf_link', $post->ID ); ?>
    	<item>
    		<title><?php the_title_rss() ?></title>
    		<?php if( $link ): ?>
    		<link><?php $link; ?></link>
    <?php else: ?>
    <link><?php echo home_url('/') ?></link>
    <?php endif; ?>
    		<?php
    		/**
    		 * Fires at the end of each RSS feed item.
    		 *
    		 * @since 2.0.0
    		 */
    		do_action( 'rss_item' );
    		?>
    	</item>
    <?php endwhile; ?>
    <?php endif; ?>
    </channel>
    </rss>
    

    これでよし。

     

    以上、現場からでした。

  • WordPress 特定のカスタムフィールドに値がある記事だけで「前へ」「次へ」を実装

    WordPress 特定のカスタムフィールドに値がある記事だけで「前へ」「次へ」を実装

    「このカスタムフィールドに値がある記事だけで『前の記事へ』『次の記事へ』のページ送りを実装してください」と言われたけど、思ったより大変だったのでメモ。

    通常、詳細記事のページネーションは”previous_post_link()”と”next_post_link()”を使えば簡単に実装できるんだけど、この関数は残念ながらカスタムフィールドの有無の判定とかはできないので、がんばってphpを書いたのであった。




    functions.phpに以下を記述

    function get_custom_pagenation() {
      global $post;
      $html = '';
      $current_id = $post->ID; //現在の記事のID
      $array_has_thumb = array();
    
      // カスタムフィールドに値がある記事を全部出して、"$array_has_thumb"にIDを格納
      $wp_query = new WP_Query();
      $param = array(
        'posts_per_page' => '-1',
        'post_type' => 'post',
        'meta_key' => 'hoge',
        'meta_value' => false,
        'meta_compare' => '!='
      );
      $wp_query -> query( $param );
    
      if( $wp_query -> have_posts() ){
        while( $wp_query -> have_posts() ) {
          $wp_query -> the_post();
          $array_has_thumb[] = $post->ID;
        }
      }
      wp_reset_query();
    
      // "$array_has_thumb"から現在の記事IDのキーを取り出しておく
      $current_key = array_keys( $array_has_thumb, $current_id );
    
      // 前の記事のID
      foreach( $array_has_thumb as $data ) {
        if( $data == $current_id ) {
          break;
        }
        $prev_id = $data;
      }
      // 次の記事のID
      foreach( $array_has_thumb as $key => $value ) {
        $next_id = $value;
    
        if( $key > $current_key[0] ) {
          break;
        }
      }
      if( $next_id == $data ) {
        $next_id = NULL;
      }
    
      // IDが取得出来たらその記事のパーマリンクを取得
      if ( $prev_id ) {
        $prev_link = get_permalink( $prev_id );
      }
      if ( $next_id ) {
        $next_link = get_permalink( $next_id );
      }
    
      // 出力部分
      if( $prev_link ) {
        $html .= '<p class="prev"><a href="' .$prev_link. '">前の記事へ</a></p>';
      }
      $html .= '<p class="list"><a href="' .home_url('/'). '">トップへ</a></p>';
      if ( $next_link ) {
        $html .= '<p class="next"><a href="' .$next_link. '">次の記事へ</a></p>';
      }
      return $html;
    }

    だいたいコメントに書いてある通りの処理です。

    要は、

    • まず’hoge’というカスタムフィールドに値がある記事のみループさせ、
    • 配列’$array_has_thumb’に記事IDを格納。
    • その配列から、今の記事IDの前後の記事IDを取得して、
    • 記事IDが取得できていたらページネーションを表示

    という流れです。前後の記事IDを取得する部分はもうちょい綺麗に書けそう…あとは、meta_keyやpost_typeの値を引数で渡してやると汎用性高まりますね。まぁそれは気が向いたら挑戦してみてください。🤗

     

    使うときはテンプレートに

    <?php echo get_custom_pagenation(); ?>

    と書くと表示されます。

     

    現場からは以上です。

  • WordPress 親カテゴリーを選択できないようにする2018

    WordPress 親カテゴリーを選択できないようにする2018

    WordPressの投稿画面でカテゴリーを選択するとき、子カテゴリーを持つ親カテゴリーは選択できないようにする。

    調べたら何件か情報があったけど、どれも若干古くて動かなかったりしたのでWP最新版+php7でも動くように修正しました。




    functions.phpに以下を記述(コピペでOK)

    <?php
    require_once(ABSPATH . '/wp-admin/includes/template.php');
    class Nocheck_Category_Checklist extends Walker_Category_Checklist {
    
      function start_el( &$output, $category, $depth = 0, $args = array(), $id = 0 ) {
        extract($args);
        if ( empty( $taxonomy ) )
          $taxonomy = 'category';
    
        if ( $taxonomy == 'category' )
          $name = 'post_category';
        else
          $name = 'tax_input['.$taxonomy.']';
    
        $class = in_array( $category->term_id, $popular_cats ) ? ' class="popular-category"' : '';
        $cat_child = get_term_children( $category->term_id, $taxonomy );
    
        if( !empty( $cat_child ) ) {
          $output .= "\n<li id='{$taxonomy}-{$category->term_id}'$class>" . '<label class="selectit"><input value="' . $category->term_id . '" type="checkbox" name="'.$name.'[]" id="in-'.$taxonomy.'-' . $category->term_id . '"' . checked( in_array( $category->term_id, $selected_cats ), true, false ) . disabled( empty( $args['disabled'] ), true, false ) . ' /> ' . esc_html( apply_filters('the_category', $category->name )) . '</label>';
        } else {
          $output .= "\n<li id='{$taxonomy}-{$category->term_id}'$class>" . '<label class="selectit"><input value="' . $category->term_id . '" type="checkbox" name="'.$name.'[]" id="in-'.$taxonomy.'-' . $category->term_id . '"' . checked( in_array( $category->term_id, $selected_cats ), true, false ) . disabled( empty( $args['disabled'] ), false, false ) . ' /> ' . esc_html( apply_filters('the_category', $category->name )) . '</label>';
        }
      }
    
    }
    
    function wp_category_terms_checklist_no_top( $args, $post_id = null ) {
      $args['checked_ontop'] = false;
      $args['walker'] = new Nocheck_Category_Checklist();
      return $args;
    }
    add_action( 'wp_terms_checklist_args', 'wp_category_terms_checklist_no_top' );

     

    これでよし。

    古いコードで動かなかった原因は、phpのバージョンによる”extends”の仕様変更(引数のデフォルト値が同じじゃないとだめ)と、WPのバージョンに伴い”get_category_children()”という関数が使えなくなっていたからでした。

    このコードも今は動いていますが、そのうち動かなくなる日が来るかもですね!

     

    現場からは以上です。

  • WordPress 投稿内やウィジェットでphpファイルを読み込めるようにする方法

    WordPress 投稿内やウィジェットでphpファイルを読み込めるようにする方法

    WordPressでは、テンプレートファイルに以下のように書くことで、他のphpファイルを読み込むことができる。

    例えばテーマ内の”hoge.php”というファイルを読み込みたかったら、

    get_template_part('hoge');

    と書けばOK。しかしこれはphpなので、投稿とかでは使えません。固定ページの途中でループを使いたいんじゃ…といったことがたまにあると思います。




    そこで今回はこれを、投稿内やウィジェットでも読み込めるようにします。

    基本的に、投稿やテキストウィジェット内でphpを使えるようになるプラグイン”PHP Execution”はセキュリティ上使わないほうがいいので、ショートコードを使って読み込むことにする。

     

    functions.phpに以下を記述。

    <?php
    // テンプレート呼び出し用ショートコード
    function my_php_Include( $params = array() ) {
      extract( shortcode_atts(array('file' => 'default'), $params ) );
      ob_start();
      get_template_part( $file );
      return ob_get_clean();
     }
     add_shortcode('myphp','my_php_Include');

    これで、投稿内で”hoge.php”を読み込みたい場合は

    [myphp file='hoge']

    とショートコードを書けばOK。

    “hoge”の部分を変えれば他のファイルも読み込めます。

     

    ウィジェットの「テキスト」でも使いたい場合は、ウィジェットでショートコードを使えるようになる以下のコードをfunctions.phpに追加する。

    add_filter('widget_text', 'do_shortcode' ); //ウィジェットでショートコードを使う

    これでテキストウィジェットでもショートコードが使えます。

     

    現場からは以上です。

  • フォームに全角や日本語を入力すると消えてしまうときに疑うこと

    フォームに全角や日本語を入力すると消えてしまうときに疑うこと

    お問い合わせフォームとかで、フォームに日本語や全角テキストを入力すると、うまくPOSTできずに消えてしまう事案が発生。

    原因は、phpの文字コード設定にありました。




    php.iniの設定を見る

    既にphp.iniがサーバーによって用意されている場合は、php.iniを確認してみましょう。

    php.iniの場所がわからないときは

    現在読み込まれているphp.iniは、phpinfo()によって確認できます。

    info.php等適当なphpファイルを作り、以下のようにコードを書きます

    <?php phpinfo(); ?>

     

    書いたらファイルをFTPでサーバーにアップし、ファイルにアクセス。

    すると、現在利用されているphpの情報が表示されます。これは使う機会が多いので覚えておきましょう

    上の画像が、現在読み込まれているphp.iniです。

    php.iniの場所がわかったら、FTPでphp.iniをダウンロードし、ファイルを開きます。

    下記のような部分があったら修正しましょう

    mbstring.internal_encoding = EUC-JP

    mbstring.internal_encoding = UTF-8

    修正したらアップし、フォームの動作を確認してください。



    別のphp.iniがある場合

    あれれ?サーバーが用意したphp.ini以外にも、ルートディレクトリなんかにもphp.iniがあるぞ?

    という場合が稀にあります。たぶん、WordPressを使うにあたってサーバーのデフォルトのphp.iniじゃ話にならないので、誰かが新たに自前のphp.iniを追加したんでしょうね。また、サーバーによってはもとからここに置いてある場合もあります。いろいろ大人の事情があるんでしょう。

     

    まずはその別php.iniを開いて中身を読んでみて、’mbstring.internal_encoding = UTF-8‘という内容が書かれているにも関わらずエラーが出る場合、なんらかの理由でこのphp.iniが読み込まれていない可能性が高いです。

    前章で説明したphp.iniの場所探しで、この別php.iniが読み込まれていない場合、.htaccessを見てみてください。

    下記のような表記があるでしょうか?あるかもしれませんし、ないかもしれません

    setenv PHPRC /home/xxx.com/html/

    このコードは、別php.iniを読み込むためのコードです。

     

    ない場合は追加しましょう。php.iniが置いてある場所を絶対パスで指定します。

    ある場合は、内容が間違っていないか確認します。

    絶対パスがわからないときは

    適当なphpファイルに下記コードを書き、アップしてアクセス。

    <?php echo __FILE__; ?>

     

    WordPressを使っている場合は要注意

    で、今回なんでこんなエラーが出たかというと、WordPressでパーマリンクを変更した際に.htaccessが上書きされ、php.ini読み込み部分のコードが消えてしまったのが原因です。

    なかなかホラーですよね…

    何かサイト全体、もしくはフォームに影響がありそうな変更があった場合はフォームの動作確認を必ずしましょう。特にコンバージョンに関わる部分にエラーが出るとやばいですからね。。

     

    がんばれWordPressマン!

  • WordPress functions.phpを関数ごとに分割して管理しやすくする話

    WordPress functions.phpを関数ごとに分割して管理しやすくする話

    現在はWordPressを使用してのWebサイト制作の需要が高く、小~中規模のコーポレートサイトをWordPressのオリジナルテーマでCMS化するといった案件が多くあります。

    僕が得意なのはこの分野で、何十件ものサイトのWordPressオリジナルテーマを作ってきました。

     

    その中で、やはりだいたいどのサイトでも使うコードというものが存在していて、これを毎回「あれ、どうすんだっけ…」と調べて書くのは非常に効率が悪いしめんどくさいです。

    そんなときは、テンプレート内やfunctions.phpに全てのコードを書くのではなく、関数を作って関数ごとにphpファイルを作って管理することで、以降同じような処理を書くときにぐっと時間が短くなります。

     

    今回は、僕が普段行っているファイルの管理方法を紹介します。




    テーマの雛形を作る

    プログラミングの時短のコツは、なんといっても「最低限必要なソースがあらかじめ用意されている」ということが基本になります。

    bootstrapやLaravelなどのフレームワークと呼ばれるものも原理は同じです。ただ、これらは「人様が用意してくれたフレームワーク」なので、学習に時間がかかる、拡張しづらい、自由が利かないなどのデメリットがあります。

    ただ、チームでの開発のときに、マニュアルが用意されているため自分以外の人が全く何を書いてあるかわからないといった状況にならないため、主に大規模な開発を行ったり、デザインの段階からフレームワークを用いることを前提としているのであれば非常に便利ですが、逆に小規模だけどデザイン性を重視していて、小回りが利いたほうがいいという状態のときは使いづらいです。

     

    そこで、「人様が作ったフレームワーク」ではなく、「自分のために、自分で作る、自分のためのフレームワーク」を作っていこうぜというわけです。

    拡張性に優れている雛形ができれば、サイトを作れば作るほどどんどん使い勝手がよくなっていきます。最初は数時間かかっていた作業も、雛形があれば数分で終わります

     

    WordPressテーマの雛形の例

    ここで僕の雛形をざっと紹介します。

    こんな感じ。

    themeというフォルダ内にテーマファイルを保管していて、WordPressサイトを作るときはこのthemeフォルダごとコピペしてフォルダ名を変更、あとはstyle.cssの中のテーマ名を変更すればテーマの基本は完成。あっというまですね。

    custumizerフォルダはテーマカスタマイザーという機能を使うのに必要なソース、
    tplフォルダは、各ページ共通で読み込まれるテンプレート(ナビとか)
    functionsフォルダはfunctions.phpに書くところの関数を、関数ごとにファイルにして分けてます。

    functions



    なんでfunctions.phpを分ける必要があるの?

    ひとえに、管理、拡張のしやすさが理由です。

    例えば、title.phpとcategory_list.phpの中身を見てみましょう。

    <?php
    /**
    * タイトル文字数制限
    *
    * @param integer $limit 表示させる文字数。引数を指定しない場合は20
    */
    function show_limit_title($limit = 20) {
      global $post;
      $title = $post->post_title;
      
      if( mb_strlen( $title ) > $limit) {
        $title= mb_substr( $title , 0 , $limit ) ;
        $show_title = $title. ・・・ ;
      } else {
        $show_title = $title;
      }
    
      echo $show_title;
    }
    <?php
    /**
    * 一覧とか詳細にその記事のカテゴリーを表示させるやつ
    *
    * @param string $delimiter 区切り文字を指定できる。引数を指定しない場合は区切り文字なし。
    */
    function show_category( $delimiter = null ) {
      $cats = get_the_category();
      $tmp = $cats;
    
      if( !$cats ) {
        return false;
      }
      
      foreach( $cats as $cat) {
        $cat_id = $cat->term_id;
        $cat_link = get_category_link( $cat_id );
        
        // 出力部分
        echo '<a href="' .$cat_link. '">' .$cat->name. '</a>';
        if( $delimiter && next($tmp) ) {
          echo $delimiter;
        }
      }
    }

    各関数については以下の記事で紹介しています。

    WordPress – タイトルの文字数制限を、関数を作っていい感じにやる

    WordPress – その記事が属するカテゴリーの一覧を表示させる関数

    関数ごとにファイルを分け、それぞれの関数にドキュメントで説明を加えています。ドキュメントはWordPressの規約にのっとっているつもりですが、もしできてなかったらごめんなさい。

     

    今のとこ紹介したのは2つですが、これが10個とか20個になったらfunctions.phpどうなると思いますか?どこに何が書いてあるか探すのも時間かかるし、拡張するのも大変になってきます。

    関数ごとにファイルを分けてやることで、拡張したいときは各ファイルを触ればいいし、関数を追加したいときはファイルを追加すればいいだけです。シンプルでわかりやすいですね。

     

    ちなみにこのブログ書いてて思ったんですが、関数の名前とファイル名を一緒にしたほうがもっとわかりやすいですよね。まだまだ修行が足りてませんでした

     

    functions.phpの書き方

    functions.phpの中身は非常にシンプル。

    <?php
    /**
    * Add Theme Supports
    * WordPressのテーマ拡張機能の有効化
    */
    // add_theme_support('menus'); // メニュー機能
    // add_theme_support('post-thumbnails'); // サムネイル機能
    
    
    /** 
    * Include Functions
    * いろんな関数を個々に読み込む
    * いらないものはできればコメントアウトしておきたい
    * 使わないのに入れておくと邪魔なものは最初からコメントアウトしてある
    */
    get_template_part('functions/editor'); // エディターに関するカスタマイズ
    // get_template_part('functions/menu'); //メニュー機能のカスタマイズ用
    get_template_part('functions/mobile'); // スマホ分岐
    get_template_part('functions/short_code'); // ショートコード集
    // get_template_part('functions/widgets'); // ウィジェットの設定
    get_template_part('functions/category_list'); // カテゴリー表示させたりする
    get_template_part('functions/new'); // Newマーク
    get_template_part('functions/pagenation'); // ページネーション
    // get_template_part('functions/thumbnails'); // サムネイルのあれこれ
    get_template_part('functions/title'); // タイトルの文字数制限
    get_template_part('functions/body_class'); // bodyのclassの表示
    
    
    /** 
    * Theme Customizer
    * テーマカスタマイザーを使うときに。
    */
    // get_template_part('customizer/customize'); // カスタマイザーの記述はここ
    // get_template_part('customizer/style'); // 色を変えたりするときのstyleの記述
    // get_template_part('customizer/customizer-repeater/functions'); // repeaterのプラグイン
    // get_template_part('customizer/repeater'); // repeaterのカスタマイズ
    

     

    こんな感じで、各phpファイルをget_template_part();という関数を使って呼び出し、使わない関数はコメントアウトしているだけ。

    get_template_part();については公式Codexをどうぞ。

     

    おわり

    今回は、WordPressテーマ開発の効率化のため、テーマの雛形作りとfunctions.phpの分け方について紹介しました。

    雛形を作るときは苦労するんですが、慣れれば拡張もさくさくいけるようになるし、自分で自分のためになるツールを育てるというのはすごく楽しいです。

     

    同じような作業を繰り返し行う場合は、その作業をいかに短縮するかというのは我々エンジニアの重要なテーマです。

    それでは、良いエンジニアライフを。

  • wp_head();とwp_footer();とはいったい何なのか

    wp_head();とwp_footer();とはいったい何なのか

    WordPressテーマ開発をやり始めたころ、「header.phpにはwp_head();を、footer.phpにはwp_footer();を必ず書いてください」と言われ、意味もよくわからず「とりあえずこれ書いとかんと動かんのやな」くらいのイメージでいましたが、書かなければ動かないということは当然これらは重要な役割を持っているからなのです。

     

    よく「なんで動かんのやろ…」と原因不明の不具合に悩まされているとき、wp_head();かwp_footer();のどっちかがないということがたまにありますが、この方々はとんでもなく重要な役割を持っていることを知れば、書き忘れることも少なくなるでしょう。

    むしろ愛着すら持つようになるかもしれません。

     

    というわけで、今回はwp_head();とwp_footer();がいったい何なのかを徹底解説したいと思います。




    wp_head();とは

    WordPress Codexでは、wp_head();について以下のように説明されています。

    ‘wp_head’ アクションをスタートさせる。テーマテンプレートファイル内の</head>タグ直前で使う(例: header.php や index.php の中)。

    全然意味がわかりません。とりあえず</head>の直前に入れたほうがいいということだけは伝わります。

    これでは結局なんやねんってなってしまうので、実際にテンプレートにwp_head();を入れて、サイト上でどのようになっているのか確認してみましょう。

    <!DOCTYPE html>
    <html lang="ja">
    <head>
    <meta charset="utf-8">
    <meta http-equiv="X-UA-Compatible" content="IE=edge">
    <title><?php wp_title( '|', true, 'right' ); bloginfo('name');?></title>
    <link rel="stylesheet" href="<?php bloginfo( 'stylesheet_url' ); ?>" type="text/css" />
    <?php wp_head(); ?>
    </head>

    ↓ブラウザ上で見てみると…

    <!DOCTYPE html>
    <html lang="ja">
    <head>
    <meta charset="utf-8">
    <meta http-equiv="X-UA-Compatible" content="IE=edge">
    <title>テスト</title>
    <link rel="stylesheet" href="http://localhost/nomou/htdocs/wp-content/themes/sample/style.css" type="text/css" />
    <meta name='robots' content='noindex,follow' />
    <link rel='dns-prefetch' href='//s.w.org' />
    		<script type="text/javascript">
    			window._wpemojiSettings = {"baseUrl":"https:\/\/s.w.org\/images\/core\/emoji\/2.4\/72x72\/","ext":".png","svgUrl":"https:\/\/s.w.org\/images\/core\/emoji\/2.4\/svg\/","svgExt":".svg","source":{"concatemoji":"http:\/\/localhost\/nomou\/htdocs\/wp-includes\/js\/wp-emoji-release.min.js?ver=4.9.6"}};
    			!function(a,b,c){function d(a,b){var c=String.fromCharCode;l.clearRect(0,0,k.width,k.height),l.fillText(c.apply(this,a),0,0);var d=k.toDataURL();l.clearRect(0,0,k.width,k.height),l.fillText(c.apply(this,b),0,0);var e=k.toDataURL();return d===e}function e(a){var b;if(!l||!l.fillText)return!1;switch(l.textBaseline="top",l.font="600 32px Arial",a){case"flag":return!(b=d([55356,56826,55356,56819],[55356,56826,8203,55356,56819]))&&(b=d([55356,57332,56128,56423,56128,56418,56128,56421,56128,56430,56128,56423,56128,56447],[55356,57332,8203,56128,56423,8203,56128,56418,8203,56128,56421,8203,56128,56430,8203,56128,56423,8203,56128,56447]),!b);case"emoji":return b=d([55357,56692,8205,9792,65039],[55357,56692,8203,9792,65039]),!b}return!1}function f(a){var c=b.createElement("script");c.src=a,c.defer=c.type="text/javascript",b.getElementsByTagName("head")[0].appendChild(c)}var g,h,i,j,k=b.createElement("canvas"),l=k.getContext&&k.getContext("2d");for(j=Array("flag","emoji"),c.supports={everything:!0,everythingExceptFlag:!0},i=0;i<j.length;i++)c.supports[j[i]]=e(j[i]),c.supports.everything=c.supports.everything&&c.supports[j[i]],"flag"!==j[i]&&(c.supports.everythingExceptFlag=c.supports.everythingExceptFlag&&c.supports[j[i]]);c.supports.everythingExceptFlag=c.supports.everythingExceptFlag&&!c.supports.flag,c.DOMReady=!1,c.readyCallback=function(){c.DOMReady=!0},c.supports.everything||(h=function(){c.readyCallback()},b.addEventListener?(b.addEventListener("DOMContentLoaded",h,!1),a.addEventListener("load",h,!1)):(a.attachEvent("onload",h),b.attachEvent("onreadystatechange",function(){"complete"===b.readyState&&c.readyCallback()})),g=c.source||{},g.concatemoji?f(g.concatemoji):g.wpemoji&&g.twemoji&&(f(g.twemoji),f(g.wpemoji)))}(window,document,window._wpemojiSettings);
    		</script>
    		<style type="text/css">
    img.wp-smiley,
    img.emoji {
    	display: inline !important;
    	border: none !important;
    	box-shadow: none !important;
    	height: 1em !important;
    	width: 1em !important;
    	margin: 0 .07em !important;
    	vertical-align: -0.1em !important;
    	background: none !important;
    	padding: 0 !important;
    }
    </style>
    <link rel='stylesheet' id='dashicons-css'  href='http://localhost/nomou/htdocs/wp-includes/css/dashicons.min.css?ver=4.9.6' type='text/css' media='all' />
    <link rel='stylesheet' id='admin-bar-css'  href='http://localhost/nomou/htdocs/wp-includes/css/admin-bar.min.css?ver=4.9.6' type='text/css' media='all' />
    <link rel='https://api.w.org/' href='http://localhost/nomou/htdocs/wp-json/' />
    <link rel="EditURI" type="application/rsd+xml" title="RSD" href="http://localhost/nomou/htdocs/xmlrpc.php?rsd" />
    <link rel="wlwmanifest" type="application/wlwmanifest+xml" href="http://localhost/nomou/htdocs/wp-includes/wlwmanifest.xml" /> 
    <meta name="generator" content="WordPress 4.9.6" />
    <link rel="canonical" href="http://localhost/nomou/htdocs/" />
    <link rel='shortlink' href='http://localhost/nomou/htdocs/' />
    <link rel="alternate" type="application/json+oembed" href="http://localhost/nomou/htdocs/wp-json/oembed/1.0/embed?url=http%3A%2F%2Flocalhost%2Fnomou%2Fhtdocs%2F" />
    <link rel="alternate" type="text/xml+oembed" href="http://localhost/nomou/htdocs/wp-json/oembed/1.0/embed?url=http%3A%2F%2Flocalhost%2Fnomou%2Fhtdocs%2F&#038;format=xml" />
    <style type="text/css" media="print">#wpadminbar { display:none; }</style>
    <style type="text/css" media="screen">
    	html { margin-top: 32px !important; }
    	* html body { margin-top: 32px !important; }
    	@media screen and ( max-width: 782px ) {
    		html { margin-top: 46px !important; }
    		* html body { margin-top: 46px !important; }
    	}
    </style>
    </head>
    

    うわーっ!なんかいっぱい増えてる!

    <meta name=’robots’ content=’noindex,follow’ />

    以降は全部wp_head();によって出力されているんですね。

     

    そう、wp_head();とは、WordPressさんサイドで用意してくれるhtmlをhead内に出力してくれる関数なんです。

    例えばそこには、All in one SEO Pack等のプラグインで設定したmeta情報や、プラグイン固有のスタイルシート、javascriptファイルなんかも出力されることになります。

     

    逆に言えばwp_head();がないと、head内に必要な情報が出力されないということです。

    wp_footer();とは

    これも例によりCodexを見てみましょう。もしかするとわかりやすい説明が…

    ‘wp_footer’ アクションフックをスタートさせる。テーマテンプレートファイル内の </body> タグ直前で使う(例: footer.php や index.php の中)。

    うん、そうだと思った。

     

    wp_footer();も、働きとしてはwp_head();と同じです。</body>直前に、ページの最後に読み込まれるべきスクリプトなんかが出力されるわけですね。見てみましょう

    <?php wp_footer(); ?>
    </body>
    </html>

    ↓ブラウザ上で見ると…

    <script type='text/javascript' src='http://localhost/nomou/htdocs/wp-includes/js/admin-bar.min.js?ver=4.9.6'></script>
    <script type='text/javascript' src='http://localhost/nomou/htdocs/wp-includes/js/wp-embed.min.js?ver=4.9.6'></script>
    	<!--[if lte IE 8]>
    		<script type="text/javascript">
    			document.body.className = document.body.className.replace( /(^|\s)(no-)?customize-support(?=\s|$)/, '' ) + ' no-customize-support';
    		</script>
    	<![endif]-->
    	<!--[if gte IE 9]><!-->
    		<script type="text/javascript">
    			(function() {
    				var request, b = document.body, c = 'className', cs = 'customize-support', rcs = new RegExp('(^|\\s+)(no-)?'+cs+'(\\s+|$)');
    
    						request = true;
    		
    				b[c] = b[c].replace( rcs, ' ' );
    				// The customizer requires postMessage and CORS (if the site is cross domain)
    				b[c] += ( window.postMessage && request ? ' ' : ' no-' ) + cs;
    			}());
    		</script>
    	<!--<![endif]-->
    			<div id="wpadminbar" class="nojq nojs">
    							<a class="screen-reader-shortcut" href="#wp-toolbar" tabindex="1">ツールバーへスキップ</a>
    						<div class="quicklinks" id="wp-toolbar" role="navigation" aria-label="ツールバー" tabindex="0">
    				<ul id="wp-admin-bar-root-default" class="ab-top-menu">
    		<li id="wp-admin-bar-wp-logo" class="menupop"><a class="ab-item" aria-haspopup="true" href="http://localhost/nomou/htdocs/wp-admin/about.php"><span class="ab-icon"></span><span class="screen-reader-text">WordPress について</span></a><div class="ab-sub-wrapper"><ul id="wp-admin-bar-wp-logo-default" class="ab-submenu">
    		<li id="wp-admin-bar-about"><a class="ab-item" href="http://localhost/nomou/htdocs/wp-admin/about.php">WordPress について</a>		</li></ul><ul id="wp-admin-bar-wp-logo-external" class="ab-sub-secondary ab-submenu">
    		<li id="wp-admin-bar-wporg"><a class="ab-item" href="https://ja.wordpress.org/">WordPress.org</a>		</li>
    		<li id="wp-admin-bar-documentation"><a class="ab-item" href="http://wpdocs.osdn.jp/">ドキュメンテーション</a>		</li>
    		<li id="wp-admin-bar-support-forums"><a class="ab-item" href="https://ja.wordpress.org/support/">サポートフォーラム</a>		</li>
    		<li id="wp-admin-bar-feedback"><a class="ab-item" href="https://ja.wordpress.org/support/forum/feedback/">フィードバック</a>		</li></ul></div>		</li>
    		<li id="wp-admin-bar-site-name" class="menupop"><a class="ab-item" aria-haspopup="true" href="http://localhost/nomou/htdocs/wp-admin/">テスト</a><div class="ab-sub-wrapper"><ul id="wp-admin-bar-site-name-default" class="ab-submenu">
    		<li id="wp-admin-bar-dashboard"><a class="ab-item" href="http://localhost/nomou/htdocs/wp-admin/">ダッシュボード</a>		</li></ul><ul id="wp-admin-bar-appearance" class="ab-submenu">
    		<li id="wp-admin-bar-themes"><a class="ab-item" href="http://localhost/nomou/htdocs/wp-admin/themes.php">テーマ</a>		</li></ul></div>		</li>
    		<li id="wp-admin-bar-customize" class="hide-if-no-customize"><a class="ab-item" href="http://localhost/nomou/htdocs/wp-admin/customize.php?url=http%3A%2F%2Flocalhost%2Fnomou%2Fhtdocs%2F">カスタマイズ</a>		</li>
    		<li id="wp-admin-bar-updates"><a class="ab-item" href="http://localhost/nomou/htdocs/wp-admin/update-core.php" title="2件のプラグイン更新, 翻訳の更新"><span class="ab-icon"></span><span class="ab-label">3</span><span class="screen-reader-text">2件のプラグイン更新, 翻訳の更新</span></a>		</li>
    		<li id="wp-admin-bar-comments"><a class="ab-item" href="http://localhost/nomou/htdocs/wp-admin/edit-comments.php"><span class="ab-icon"></span><span class="ab-label awaiting-mod pending-count count-0" aria-hidden="true">0</span><span class="screen-reader-text">0件のコメントが承認待ちです。</span></a>		</li>
    		<li id="wp-admin-bar-new-content" class="menupop"><a class="ab-item" aria-haspopup="true" href="http://localhost/nomou/htdocs/wp-admin/post-new.php"><span class="ab-icon"></span><span class="ab-label">新規</span></a><div class="ab-sub-wrapper"><ul id="wp-admin-bar-new-content-default" class="ab-submenu">
    		<li id="wp-admin-bar-new-post"><a class="ab-item" href="http://localhost/nomou/htdocs/wp-admin/post-new.php">投稿</a>		</li>
    		<li id="wp-admin-bar-new-media"><a class="ab-item" href="http://localhost/nomou/htdocs/wp-admin/media-new.php">メディア</a>		</li>
    		<li id="wp-admin-bar-new-page"><a class="ab-item" href="http://localhost/nomou/htdocs/wp-admin/post-new.php?post_type=page">固定ページ</a>		</li>
    		<li id="wp-admin-bar-new-shop"><a class="ab-item" href="http://localhost/nomou/htdocs/wp-admin/post-new.php?post_type=shop">店舗情報</a>		</li>
    		<li id="wp-admin-bar-new-user"><a class="ab-item" href="http://localhost/nomou/htdocs/wp-admin/user-new.php">ユーザー</a>		</li></ul></div>		</li>
    		<li id="wp-admin-bar-edit"><a class="ab-item" href="http://localhost/nomou/htdocs/wp-admin/post.php?post=11&#038;action=edit">固定ページを編集</a>		</li></ul><ul id="wp-admin-bar-top-secondary" class="ab-top-secondary ab-top-menu">
    		<li id="wp-admin-bar-search" class="admin-bar-search"><div class="ab-item ab-empty-item" tabindex="-1"><form action="http://localhost/nomou/htdocs/" method="get" id="adminbarsearch"><input class="adminbar-input" name="s" id="adminbar-search" type="text" value="" maxlength="150" /><label for="adminbar-search" class="screen-reader-text">検索</label><input type="submit" class="adminbar-button" value="検索"/></form></div>		</li>
    		<li id="wp-admin-bar-my-account" class="menupop with-avatar"><a class="ab-item" aria-haspopup="true" href="http://localhost/nomou/htdocs/wp-admin/profile.php">こんにちは、<span class="display-name">root</span> さん<img alt='' src='http://1.gravatar.com/avatar/d01ced56814ff772907fb3f10654240e?s=26&#038;d=mm&#038;r=g' srcset='http://1.gravatar.com/avatar/d01ced56814ff772907fb3f10654240e?s=52&#038;d=mm&#038;r=g 2x' class='avatar avatar-26 photo' height='26' width='26' /></a><div class="ab-sub-wrapper"><ul id="wp-admin-bar-user-actions" class="ab-submenu">
    		<li id="wp-admin-bar-user-info"><a class="ab-item" tabindex="-1" href="http://localhost/nomou/htdocs/wp-admin/profile.php"><img alt='' src='http://1.gravatar.com/avatar/d01ced56814ff772907fb3f10654240e?s=64&#038;d=mm&#038;r=g' srcset='http://1.gravatar.com/avatar/d01ced56814ff772907fb3f10654240e?s=128&#038;d=mm&#038;r=g 2x' class='avatar avatar-64 photo' height='64' width='64' /><span class='display-name'>root</span></a>		</li>
    		<li id="wp-admin-bar-edit-profile"><a class="ab-item" href="http://localhost/nomou/htdocs/wp-admin/profile.php">プロフィールを編集</a>		</li>
    		<li id="wp-admin-bar-logout"><a class="ab-item" href="http://localhost/nomou/htdocs/wp-login.php?action=logout&#038;_wpnonce=775107e931">ログアウト</a>		</li></ul></div>		</li></ul>			</div>
    						<a class="screen-reader-shortcut" href="http://localhost/nomou/htdocs/wp-login.php?action=logout&#038;_wpnonce=775107e931">ログアウト</a>
    					</div>
    
    		</body>
    </html>
    

    これまたすごい量のコードが出力されています。

    ここにはページの最後に読み込むスクリプトに加え、ログインしているときにサイト上部に表示される管理バーのコードも出力されます

    なので、wp_footer();がないと一部のスクリプトが読み込まれずエラーになったり。管理バーが表示されません。

     

    おわり

    wp_head();とwp_footer();の重要さがご理解いただけたかと思います。この方々がいないと、ページはまともに機能しません。

    以後、書き忘れのないよう注意しましょう。

    本記事の基礎的なことを含め、マッハでWordPressについてプロ並みのスキルを身につけたいなら、TechAcademyのWordPressコース等、プログラミングスクールで学ぶのが手っ取り早いです。

    最短4週間でオリジナルテーマを作れるようになりますので、ホームページを作りたいけど外注に出すと高いから自社で作りたい方や、WordPress構築の仕事を請けたい方はぜひ検討してみてください。

    WordPressでWebサイトを構築するのに便利なプラグインを以下の記事で紹介しているので、ついでにどうぞ。

    WordPress構築で使える、カスタマイズに便利なプラグイン11個

    それじゃ、バイバイ~

     

  • BackWPupのエラーをようやく解決した話

    BackWPupのエラーをようやく解決した話

    WordPressのバックアップ用プラグインBackWPupをよく使っているんですが、クライアントから自動バックアップでエラーが出るとの連絡が。

     

    ログを見てみるとこんな感じ

    エラー:シグナル”SIGXCPU”(CPUの時間制限を超えました)がスクリプトへ送信されます!とのこと。

     

    だいたいはサーバーのスペック不足が原因だと思うのですが、いろいろ試してみて解決したのでメモ。




    ファイルとデータベースのジョブは分ける

    まず、サーバーへの負担を減らすためにも、ファイルとデータベースのバックアップは分け、それぞれ別のタイミングで自動バックアップをとるよう設定。

    これにより、重要なデータベースのバックアップだけでもとりあえず正常に行えるし、そもそもファイルはそんな頻繁にバックアップとらなくていいと思うので(WordPressはあんまりファイルいじらないため。ローカルに手動で保存もできるし。)、データベースは毎日、ファイルは週一でバックアップをとるようにしました。

     

    しかし、これではエラーは解決できませんでした。次いってみましょう。

     

    最大スクリプト実行時間を設定

    ググると最初に出てきたのがこれ。

    最大スクリプト実行時間を60秒にしてみたらなおったよ~という報告がありましたが、僕の場合はだめでした。



    サーバーの負荷を軽減で解決

    最終的にこれで解決しました。

    サーバーの負荷を軽減が、デフォルトでは無効になっているので、最小にしたところ無事自動バックアップが正常に行われていました。

     

    最大スクリプト実行時間はあまり関係ないかもしれませんが、念のため。

     

    よくわからないサーバーを使っていると、よくわからないエラーに悩まされることが多々あります。サーバーはいいサーバーを使おうね!

    おすすめサーバーは以下で紹介していますので、よかったら見てってくださいね。

    https://meshikui.com/2018/12/03/1396/

    ではでは、良いバックアップライフを。

  • 【WordPress】記事内にテンプレートを挿入するプラグイン”TinyMCE Templates”

    【WordPress】記事内にテンプレートを挿入するプラグイン”TinyMCE Templates”

    複数の記事内に同じ内容、例えば広告だったり、他の記事のリストだったりを挿入したいときに便利なプラグイン”TinyMCE Templates“。




    使い方は簡単で、プラグインをインストールすると管理メニューに「テンプレート」という項目が追加されるため、そこからテンプレートを作成するだけ。

    複数のテンプレートを登録でき、記事内に挿入する際にテンプレートを選択できる。

     

    ショートコードとして挿入

    テンプレートを作成する際、更新ボタンの下に「ショートコードとして挿入」という項目があり、デフォルトは「いいえ」になっている。

    これを「はい」にすると、登録した内容をショートコードで挿入することができるようになる。

    ショートコードとして挿入できると、例えば

    「あ、テンプレート修正せんと。でも全記事やるのめんどくせー」

    ってときに、ショートコードで挿入している場合は、テンプレート編集画面でテンプレートを修正するだけで済む。

    ただし、記事側でテンプレートを編集できないというデメリットがある。

     

    逆に、「いいえ」にするとショートコードではなくテンプレートに書いたhtmlコードをそのまま挿入することになる。

    こちらは記事側でhtmlを編集できるが、修正が必要な場合は全記事なおす必要がある。

     

    ショートコードとして挿入を、

    • 「はい」…全記事に同じテンプレートをいれる必要があり、たびたび修正が発生する可能性がある場合(広告を貼りかえる場合等)
    • 「いいえ」…テンプレートの一部を記事ごとに書き換える必要がある場合。(管理者からのコメントや、URL等)

    このように使い分けるといいだろう。

  • PHP初心者にまず読んでほしい一冊の本

    PHP初心者にまず読んでほしい一冊の本

    駆け出しペチパー(PHPer)のみなさま、こんにちは。

    検索でこの記事を発見して読みに来ていただいたということは、おそらくこれからPHPを勉強してプログラミングができるようになりたい、もしくはなんとなくPHPわかるけど、ちゃんと基礎を学ぼうと思う、そういった意思を心に秘めていることだと思います。

     

    それでは、PHP初心者がまず何をすればいいのか。答えは1つです。

     

    この本を読んでください。

    当記事では、この本(タイトルが長いけど「この本」で通すのもなんなので、以降マスターブックと呼びます)を読んでほしい理由を綴っていますので、どうぞお付き合いください。だいたい5分くらいで読めると思います。

    ちなみに、私もマスターブック持ってます。PHPを使う方であれば、大半は持ってるんじゃないかと思うくらいメジャーで素敵な本なので、知っておいて損はないですよ!




    PHPの本を読むという行為のメリット

    マスターブックを読んでほしいという話の前に、そもそもプログラミング初心者はまず本を読むべきだという話をします。

     

    「PHPの情報を検索して調べる」vs「PHPの本を読む」

    だいたい、プログラミング関係の情報はググれば山ほど記事がありますよね。無料で調べられるし、ネットさえつながっていれば現場でもどこでもその場で調べることができます。

    これに関しては、ネット社会のすばらしさを実感します。とても良いです。

    それでは、いったい何が悪いのか。それは、検索するのは自分であり、基本的に自分の知っている範囲でのワードでしか調べることができないという点です。

    作業中にわからない部分があり、検索して解決するという点に関しては圧倒的メリットがありますが、そもそも自分が知らないことを調べるというのはなかなか難しい傾向にあります。

     

    実は恥ずかしいことに私がそういった経験がありまして、PHPを初めて触ったときからずっと検索だけで2年ほどやってきたんですが、それでもマスターブックに書いてある大半が知らないことでした。「これそういう意味だったの!?そんな便利な関数あったの!?最初に知っときたかったーー」のオンパレードです。

    ネット検索だけで数年がかりで蓄えた知識は、一冊の本を買って数日間で得られる知識に敵わないんですね。

     

    また、ネット上の記事はほとんどが個人が書いたブログです。もちろん法人とか、しっかりした手順で書かれた記事もあるのですが、「いやこれ間違っとるけどちゃんと自分で書いたコードか?」「この記事さっき別のサイトで見たのとほぼ同じやししかも解決せんかったやつや!」ってなることが多々あるのが現実です。

    私のサイトのコードは自分で書いたものだし動作確認も行っているので、たぶんコピペで動くとは思うんですが、それでも確実かと言われると自信がありません。。

    一方、本は違います。いろんな方面のプロが何回もチェックしてますので、間違っているということはほぼほぼないです。信用が違いますね。



    マスターブックを読むメリット

    本を読むという行為自体のメリットを伝えた次は、どうしてこの本を勧めるかを書いていきますね。

     

    マスターブックの内容

    マスターブックは全部でChapter13まであり、下記のような構成になっています。

    1. PHPの開発環境
    2. PHPの基礎
    3. PHPの組み込み関数
    4. WebでのPHP
    5. クラスとオブジェクト
    6. データベースの準備
    7. データ操作の基本
    8. PHPからデータベースを操作する
    9. PHPとMariaDB/MySQLで作る会員管理システム-基本機能
    10. PHPとMariaDB/MySQLで作る会員管理システム-管理機能
    11. データベースの運用
    12. PHPの応用
    13. これからプログラミンぐをしていくにあたって

    どうですか?やばみが伝わりますか?

     

    この本一冊で、PHPの基礎~応用はもちろん、開発環境の構築の話やMySQL(MariaDB)の作成・操作方法、更に会員管理システムを実際に作りながら学べ、挙句の果てにChapter13では自分で設計から考えプログラミングをするためのレクチャーをしてくれます。最後に練習問題もあります。

    もう全部ですよね。まさにPHPマスターブックです。



    マスターブックを読んだあとは

    マスターブックを一通り読み終え、会員管理システムも作ってみたあなたは、もうPHPの基礎はマスターしています。本を読み終えたら、文系美女と観光地にデートでもいきましょう。

    美女なんかより、もっともっとPHPを学びたいストイックなあなたに、基礎の次のステップへの指針をさらっと紹介しておきます。

     

    PHP公式サイトに訪れる

    PHP公式サイトには、言語リファレンスというPHPの辞書があります。

    リンク → 言語リファレンス

    基礎を学ぶ前にこのサイトを見てもいったい何を書いてるのかわからない、わからない部分がわからないという事態に陥ると思いますが、基礎を学んだあとはこのサイトの呪文が読めるようになっているはずです。

    わからないことは公式サイトで調べるようにしましょう。

     

    PHPフレームワークを学ぶ

    フレームワークという言葉を聞きなれない方もいらっしゃるかもしれませんが、簡単にいうと土台です。PHPでシステム開発をするために必要な機能や枠組みがあらかじめ用意されているソフトウェアで、大規模なシステム開発や、ECサイト開発によく使われます。

    WordPressも、フレームワークと捉えることが可能です。いろんなタグや関数、リダイレクト機能、データベース管理機能が備わってますからね。

    数あるPHPフレームワークの中でも私がおすすめするのは、今熱いと言われているLaravel、EC-CUBEで使われているSymfonyの2つです。

     

    オブジェクト指向について学ぶ

    マスターブックでも少し触れられてはいますが、オブジェクト指向は難しいです。たぶんすぐには理解できないと思います。

    ただ、私は無理してオブジェクト指向をマスターする必要はないと思っています。上記のフレームワークがオブジェクト指向で組まれているので、構造を理解できて編集できる程度の知識があればいいんじゃないでしょうか。自分で1からオブジェクト指向で組むのは現実的とは思えないです。

    たぶん、オブジェクト指向で組む必要があるのは、フレームワークを作るレベルのエキスパートたちですよね。。

     

    まとめ

    わからないことや疑問に思ったことを調べるにはネットが便利ですが、しっかりと基礎を身に着けたければ本を読むほかありません。

    たった一冊の本を読まなかったばっかりに、数年間苦労した私のようにならないためにも。。

     

  • WordPressの記事から括弧”[]”で囲まれた文字列を取り除いて表示する方法

    WordPressの記事から括弧”[]”で囲まれた文字列を取り除いて表示する方法




    FC2とかからWordPressに記事データを移管した際、”[emoji:v-412]”みたいな文字列がたくさんあって邪魔です。

    そんなときは、functions.phpに以下のように記述。

    function content_replace($content) {
    	$content = preg_replace("/\[emoji.+?\]/", "", $content);
    	return $content;
    }
    add_filter('the_content', 'content_replace');

    ちなみに、”[]”で囲まれている文字列全てを削除したい場合は、2行目を

    $content = preg_replace("/\[.+?\]/", "", $content);

    こう変更。

     

    あとは記事を表示させたい場所にいつも通りthe_content();と書けばOK

     

  • WordPress – 特定のタームの記事だけ処理を変えたいときの条件分岐

    WordPress – 特定のタームの記事だけ処理を変えたいときの条件分岐

    「このタームの記事だけ項目を非表示にできますか?」と言われたとき、すぐにはわからなくてちょっと調べたので、以後すぐ思い出せるようにメモ。




    実装

    has_term( ‘slug’, $taxonomy );を使えば簡単。
    第一引数は対象となるターム、第二引数はそのタームが属するタクソノミーを指定します。

    <?php
    if( has_term('service','cat_blog') ) {
      // ここに「service」というタームに属する場合の処理を書く
    } else {
      // それ以外の場合の処理。
    }
    ?>

     

    ただ項目を非表示にするだけでよかったら、

    <?php
    if( !has_term('service','cat_blog') ) { //"service"に属さない場合
      // 処理を行う
    }
    ?>

    これだけでOK。

     

    複数のタームを指定したい場合はarray()を使う。

    <?php
    if( has_term( array('service','shop') ,'cat_blog') ) {
      // ここに「service」もしくは「shop」というタームに属する場合の処理を書く
    } else {
      // それ以外の場合の処理。
    }
    ?>

     

    タクソノミー関係の分岐ってけっこうややこしいので、「どうやってググったらええかすらわからん!!」ってときは、WordPress Codexを見てみるのが一番早いです。

    以下の記事も参考にどうぞ!

    WordPress開発が捗る!ブックマークしておくべきCodexまとめ

     

    以上、現場からでした。

  • WordPress 条件分岐 “is_archive()” が効かないときに確認すること

    WordPress 条件分岐 “is_archive()” が効かないときに確認すること

    is_archive()とは、アーカイブページであるということを示す条件タグです。




    使うときは以下のように使います

    <?php
    if( is_archive() ) {
    	// 投稿一覧ページでのみ行いたい処理
    } else {
    	// その他で行う処理
    }
    ?>

     

    ところが、設定 > 表示設定 で、一覧ページ用の固定ページを指定している(例:infoとか)場合、一覧ページと判別してくれません

    そんなときはis_home()を使いましょう。

    <?php
    if( is_home() || is_archive() ) {
    	// 投稿一覧ページ及びアーカイブページでのみ行いたい処理
    } else {
    	// その他で行う処理
    }
    ?>

    is_home()だけだと全記事一覧ページしか判別してくれない可能性があるので、is_archive()も加えてやることで、カテゴリーページや年別アーカイブページも判別してくれるようになります。

     

    もしかするとトップページでis_home()を使用している方もいるかもしれませんが、
    トップページはis_front_page()で分岐してやるのが正しいです。

  • WordPress – その記事が属するカテゴリーの一覧を表示させる関数

    WordPress – その記事が属するカテゴリーの一覧を表示させる関数

    WordPressの記事を書いて、例えばカテゴリーを複数選択したとき(ニュース、日常)、記事の詳細ページとかに、選択したカテゴリーの一覧がいい感じに表示される関数を紹介する。




    functions.phpに以下のように記述

    function show_category( $delimiter = null ) {
      $cats = get_the_category();
      $tmp = $cats;
    
      if( !$cats ) {
        return false;
      }
      
      foreach( $cats as $cat) {
        // 出力部分
        echo $cat->name;
        if( $delimiter && next($tmp) ) {
          echo $delimiter;
        }
      }
    }

     

    使うときは、テンプレートに以下のように書く

    <?php show_category(','); ?>

    出力はこんな感じでされる

    ニュース,日常

    引数には区切り文字(’,’とか’/’)を指定できる。何も指定しない場合は、区切り文字なしで続けて表示される。

     

    カテゴリーをspanとかaタグで囲みたいときは、foreachの中をちょっといじる。

    function show_category( $delimiter = null ) {
      $cats = get_the_category();
      $tmp = $cats;
    
      if( !$cats ) {
        return false;
      }
      
      foreach( $cats as $cat) {
        $cat_id = $cat->term_id;
        $cat_link = get_category_link( $cat_id );
        
        // 出力部分
        echo '<a href="' .$cat_link. '">' .$cat->name. '</a>';
        if( $delimiter && next($tmp) ) {
          echo $delimiter;
        }
      }
    }

    上記のような関数を作り、引数なしで出力すると、そのカテゴリーページへのリンクがついたaタグで囲まれたカテゴリー一覧が出力される。

     

  • WordPress – タイトルの文字数制限を、関数を作っていい感じにやる

    WordPress – タイトルの文字数制限を、関数を作っていい感じにやる

    WordPressのテーマ制作のとき、レイアウトが崩れるのを防ぐためにタイトルの文字数を制限してやる必要がある、という場合。

    タイトルの文字数制限でググればやり方が書いてあるが、毎回書くのはめんどうだしソースもちょっとぐちゃっとなりがちなので、関数を作って、そして簡単に実装できるようにする。




    functions.phpに以下を記述

    function show_limit_title($limit = 20) {
      global $post;
      $title = $post->post_title;
      
      if( mb_strlen( $title ) > $limit) {
        $title= mb_substr( $title , 0 , $limit ) ;
        $show_title = $title. '・・・' ;
      } else {
        $show_title = $title;
      }
    
      echo $show_title;
    }

     

    あとは、タイトルを表示させたい部分に、”the_title();”の代わりに以下のように書くだけ。

    <p><?php show_limit_title(); ?></p>

    デフォルトでは20文字制限となっているので、文字数を変えたい場合は括弧の中に数値を入れてやる。

    // 40文字まで
    <p><?php show_limit_title(40); ?></p>

    場所やカスタム投稿によって表示文字数を変えたい場合は引数の値を変えるだけでいいので、使いやすいです。

    あなたのfunctions.phpのおともに是非!

    functions.phpのちょっとした小技を書いたこちらの記事もどうぞ🤗

    WordPress functions.phpを関数ごとに分割して管理しやすくする話

  • WordPressテーマ作成時に、いろんなサイズのサムネイルのダミー画像をサクッと生成する方法

    WordPressテーマ作成時に、いろんなサイズのサムネイルのダミー画像をサクッと生成する方法

    WordPressのテーマを制作するとき、サムネイル機能をつけることはよくあると思うが、「サムネイル画像が登録されていない場合に表示させるダミー画像」を作るのが意外とめんどくさい。

    今回は、その作業をなるべくぱぱっと終わらせる小技を紹介しよう。




    準備するもの

    何はともあれ、元となる画像を用意しよう。

    上の画像はAdobe Stockのサンプルなので勝手に使わないように。

    大きさは、1920px x 1920pxのものがいいんじゃないだろうか。できるだけいろんな形に切り取られてもおかしくない画像を用意しよう。

    サムネイルサイズの設定

    サムネイルのサイズを複数登録する必要がある際、functions.phpにいつも書くであろうこういうやつ。

    add_image_size( 'arhive-thumbnail', 438, 289, true );
    add_image_size( 'single-topics-thumbnail', 916, 600, true );
    add_image_size( 'single-shop-thumbnail', 458, 300, true );
    add_image_size( 'top-topics-thumbnail', 373, 250, true );
    add_image_size( 'single-shop-thumbnail', 285,200, true );

    …書くよね?

    いつも通りでOK。

    アップロード

    作った画像を管理画面からアップロードしてしまう。

    するとなんということでしょう

    uploadsフォルダ内に、あらゆるサイズで切り取られたダミー画像が勝手にできあがっているじゃありませんか。

    これなら開発の流れでついでにできちゃうし、汎用的な画像をあらかじめ用意しておけば、どのサイトでも使いまわせる。デザイナー様のお手を煩わせるまでもないのである。

  • WordPress 国産で無料のブログ用テーマ「Simplicity」の紹介

    WordPress 国産で無料のブログ用テーマ「Simplicity」の紹介

    突然だが、テーマが変わったのにお気づきだろうか。

    当ブログの読者はほとんどいないため、おそらく気付いているとかいう以前の問題だとは思うが、テーマを変更したのには理由がある。

    私は、当ブログを「テーマのカスタマイズをまったく行わない」という縛りプレイのもと運営している。具体的には、テンプレートを直接いじらない(functions.phpも含め)ということだ。

    フロントエンドエンジニアなのに何しとんねんと思われるかもしれないが、一種の遊びのようなものである。気にしないでほしい。テーマを自作する程度のスキルはちゃんとある。

    そして、今までは「Kale」という海外製のシンプルなテーマを使用していたのだが、カスタマイズをしないのにシンプルなテーマを選ぶという愚かさにとうとう気付いてしまい、しかもフォントも日本向けではないので読みづらいという理由もあったため、カスタマイズに優れていて、日本製で、無料であるという条件のもと、新しいテーマを探した。

    そんなとき出会ったのが、この「Simplicity」である。

    「Simplicity」のダウンロードはこちら




    Simplictyのすごいところ

    インストールして30分くらいしか経っていないが、それだけの時間でもこのテーマのすばらしさを実感できたため、軽く紹介させていただく。

    カスタマイザーが豊富

    明らかに無料ではないレベルのカスタマイズの数々。

    レイアウトの設定も数多く、SEOやアクセス解析の設定、SNSの設定などもできる。

    特にすごいのがこのスキン機能

    ワンクリックでサイトの雰囲気をガラリと変えることができる。しかも種類が多い。

     

    記事ページがすごい

    非常に読みやすい。

    見出しのスタイルもオシャレだし、可読性が良い。日本人には日本人の読みやすさがあるんだと痛感した。

    前のテーマのときもなんとか頑張って読みやすいようにスタイルを調整していたのだが、Simplicityは最初から圧倒的に読みやすいのだ。

     

    記事の下には、よくあるシェアボタンや関連記事が最初からついてる。プラグインとかいらない。

     

    ウィジェットがすごい

    途方もない数のウィジェットが設定できる。広告用のウィジェットまである。

     

    とりあえずざっと見た感じでもこんなにすごい。おそらくもっといろいろな機能があるのだろう。無料というのが信じられない。あとで請求とかされないよね?(されない)

    とにかく今すぐWordPressでブログ書きたいんじゃ!という人には本当にオススメ。

  • WordPress 特定のページを404にリダイレクトさせる方法

    WordPress 特定のページを404にリダイレクトさせる方法

    例えば、WordPressの仕様上絶対に生成されてしまうんだけど、アクセスされたくないので404にしたい場合。
    あんまないとは思うんですけどね…




    functions.phpに以下のように記述

    add_action( 'template_redirect', 'status404' );
    
    function status404() {
      if ( is_tax(array('hoge','moge')) ) {
        global $wp_query;
        $wp_query->set_404();
        status_header(404);
      }
    }

    上記の場合は、”hoge”もしくは”moge”というスラッグのついたタクソノミーページを404にするというものです。

    条件分岐タグを使えば、404にするページを複数指定できます。
    条件分岐タグ一覧

    この分岐の条件を間違えると、全然違うページが404になったりして大変なことになるので、実装する場合はよくチェックしましょう。