WordPressで記事一覧を表示する(WP_Query編)

よくあるネタで申し訳ないですが、
WordPressで記事一覧を表示する方法です。

一言で、記事一覧と言っても、
月別やカテゴリー別など、何かの分類で表示したい場合は、アーカイブを使いましょう。
今回は、記事一覧の中でも投稿の一覧を表示する為のコードに成ります。

投稿の一覧を表示する為には、WP_Query()という関数か、
get_posts()というテンプレートタグを使います。
乱暴な言い方をすると、ページネーションが必要な場合は、WP_Query()を使います。

トップページに最新の5件を表示する
などであれば、get_posts()でも良いですし、今回、ご紹介するWP_Query()でも良いですね。

ここでご紹介するコードを使う場所(ファイル)ですが、
固定ページで使用しても良いですし、トップページでも使用しても大丈夫です。
どのPHPファイルに書くかは、テンプレート階層に準じてください。

早速ですが、いつものように、プログラムの全文から・・・

<?php
// 取得する記事の条件を設定
$args = array(
    'post_type' => 'post', // カスタム投稿の場合は、カスタム投稿のpost_typeを指定
    'paged' => $paged,
    'posts_per_page' => 3
);

// 条件($args)を元に記事の一覧を取得
$query = new WP_Query( $args );
?>

<?php
// 記事が取得できている場合
if ( $query->have_posts() ) :
?>

<div class="table-responsive">
	<table class="emp_table text-nowrap">

<?php
	// 記事を1件ずつ表示する為のループの開始
	while ( $query->have_posts() ) : $query->the_post();

/* ここに記事をどう表示するかを記述する */

<?php
	// 記事を1件ずつ表示する為のループの終了
	endwhile;
?>

	</table>
</div>

<?php
// 記事が取得できている場合の条件最後
endif;

// WP_Queryをリセットする
wp_reset_postdata();
?>

それぞれの説明です。

// 取得する記事の条件を設定
$args = array(
    'post_type' => 'post', // カスタム投稿の場合は、カスタム投稿のpost_typeを指定
    'paged' => $paged,
    'posts_per_page' => 3
);

3行目から7行目は、どんな条件の記事一覧が必要か指定しています。
ここで指定できる条件(パラメータ)についても公式ドキュメントのWP_Query()の説明を参照すると良いと思います。

// 条件($args)を元に記事の一覧を取得
$query = new WP_Query( $args );

10行目で記事の一覧を取得します。

// 記事が取得できている場合
if ( $query->have_posts() ) :

15行目は記事の一覧が取得できているか確認し、取得出来ている場合はこのまま下の処理を進めます。
取得出来ていない場合は、37行目までスキップします。

	// 記事を1件ずつ表示する為のループの開始
	while ( $query->have_posts() ) : $query->the_post();

23行目で取得した記事一覧を1件づつ表示する為のループを開始します。

25行目付近に記事をどう表示したいかを書きます。
ここは、それぞれで色々な表示があると思いますので、今回の説明からは省きますが、
タイトルを表示したければ、
the_title();
などに成りますね。

	// 記事を1件ずつ表示する為のループの終了
	endwhile;

29行目は23行目で始まる記事一覧のループの範囲を示す為のループの最後です。

// 記事が取得できている場合の条件最後
endif;

37行目は、15行目で確認した記事の一覧が取得できているか確認している条件式の終わりを明示しています。

// WP_Queryをリセットする
wp_reset_postdata();

最後に40行目で、WP_Query()という関数を使ったので、リセットしておきます。

以上で、投稿の一覧を表示できるように成ります。

なお、固定ページで記事一覧を作成し、トップページ等からリンクを設定する場合は、
固定ページに設定したslugを元に以下のようなコードでリンクを設定します。

<a href="<?php echo esc_url( get_permalink( get_page_by_path('固定ページのslug名')->ID ) );?>">リンク先の名称</a>

WordPressでログインユーザにだけ固定ページを見せる

WordPressでユーザの名前やメールアドレスなどを画面表示などに使用したい場合、
そのページをログインユーザだけに見せる。
という方法をとりたくなりまよね。

以下は、固定ページでの実装方法になります。
最初に全てのコードを掲載します。

<?php
/**
  Template Name: page-work
**/
while ( have_posts() ) : the_post();
  $url_path = get_permalink();
  $args = array(
    'redirect' => $url_path,
    'label_username' => __( 'Username' ),
    'label_password' => __( 'Password' ),
    'remember' => false
  );
  if ( !is_user_logged_in() )
  {
    wp_login_form( $args );
  } else {
    /* ここにログインしているユーザ用の処理を記述 */
  }
endwhile; // End of the loop.

まずは、以下で、専用の固定ページ用のテンプレートとして宣言します。

/**
Template Name: page-work
**/

page-work 部分は、任意ですが、テンプレートのファイル名はpage-xxxx.phpとしましょう。

ログインしたら、今いるページに戻って来る為に、今いるページのパーマリンクを取得します。

$url_path = get_permalink();

ログインしていなかったら、ログインフォームを表示させる為のコード

$args = array(
  'redirect' => $url_path,
  'label_username' => __( 'Username' ),
  'label_password' => __( 'Password' ),
  'remember' => false
);
if ( !is_user_logged_in() )
{
  wp_in_form( $args );
}

ログインしていなかったら、ログインフォームではなく、トップページにリダイレクトなどしたい場合は、

wp-redirect()

を使用すると良いかと。

LB配下で安全にconcrete5を使う

この記事はconcrete5 Japan Advent Calendar 2017の8日目の記事です。
7日目はpictron2009さんの記事”プライマリで仕事を受注した案件でconcrete5が採用に至ったポイント“でした。

concrete5でも、LB越しのアクセスでは、
ユーザーのアクセス元の IP アドレスが変わるとログアウトするように設計
されているんだとか・・・

と、いう事で、AWSのALBやELB越しにアクセスした場合、何の対処もしないとnginxに到達するアクセス元IPはALBやELBのIPアドレスになってしまうのは、LB経由の場合は普通の事。

最近すっかりAWS仕事が多い事もあって、その回避策・・・

まずは、EC2インスタンスにKUSANAGIをインストールして、プロビジョニングとconcrete5のインストールまで実施
現時点(2017年12月10日)では、KUSANAGIでインストールされるconcrete5は5.7という事で、
ドキュメントルートに展開されたconcrete5のファイルをごっそり削除して、8.2の各ファイルを展開します。
データベースが作られてしまっている場合は、250テーブル弱ほどあると思いますが、一気にdrop table テーブル名
として、テーブルも削除し、8.2をインストールしましょう。

8.2のインストールができたら、concrete5のダッシュボードにアクセスして、nginx上のログを確認してみましょう。
KUSANAGIでnginxのログファイルは

/home/kusanagi/プロファイル名/log/nginx/access.log

に出力されます。

また、KUSANAGIのアクセスログフォーマットは

    log_format main '$request_time $sent_http_x_f_cache $sent_http_x_b_cache '
                    '$remote_addr - $remote_user [$time_local] "$request" '
                    '$status $body_bytes_sent "$http_referer" '
                    '"$http_user_agent" "$http_x_forwarded_for"';

として記録されます。
この”$remote_addr”が、LBのIPアドレスに成ってしまうのが問題ですよね。
#LBのIPを信頼済みIPアドレスとして認識させる方法もあるようですが...

そこで、/etc/nginx/nginx.conf
に以下の行を追記します。
#自分は、httpディレクティブの一番最後に以下を記載

        set_real_ip_from        ALBやELBに設定しているサブネットマスク値
        real_ip_header          X-Forwarded-For;
        real_ip_recursive       on;

これで、”$remote_addr”は、アクセス元クライアントのIPが正しく記録され、concrete5にログイン後もログアウトされる事なく利用できるようになります。
(自分の環境ではログアウトされる事なく動いていますが、これが正しい対応かは判っていませんが・・・)

みなさんにハッピーなconcrete5ライフを!!