この記事ではWordpressで
記事情報をCSV出力するボタンを投稿一覧画面に設置する方法
をご紹介します。
作成するボタン(イメージ)

- WordPress管理画面にボタンを設置する方法
- WordPress管理画面でPOST送信を実行する方法
- 記事一覧情報をCSVで出力する方法
- WordPress管理画面で「フォーム送信」を動かすための仕組み

今回ご紹介するソースコードを利用することで、記事ごとの記事IDやURLを一覧で出力することができます!
ぜひ最後までご覧いただければ幸いです!


【結論】ソースコード
以下のソースコードをfunctions.phpに記述するだけで「記事の一覧情報をCSV出力するボタン」を投稿一覧画面に表示できます。
ソースコード(functions.php)
/**
* CSVファイルを生成して出力する。
*/
function createCsvPostList()
{
if (isset($_POST['csv-output']) && $_POST['csv-output'] === 'true') {
// セキュリティチェック
if (!isset($_POST['nonce']) || !wp_verify_nonce($_POST['nonce'], 'csv-output-action')) {
wp_die('セキュリティチェックに失敗しました。');
}
// CSVファイル名
$file_name = '記事PV出力_' . date('Ymd_His') . '.csv';
// CSVダウンロード用のヘッダーを設定
header('Content-Type: text/csv; charset=utf-8');
header('Content-Disposition: attachment; filename="' . $file_name . '"');
// 出力ストリームに接続されたファイルポインタを作成
$output = fopen('php://output', 'w');
// Excel互換のためにUTF-8 BOM(バイトオーダーマーク)を追加
fwrite($output, "\xEF\xBB\xBF");
// CSVヘッダー行
fputcsv($output, ['記事ID', '記事タイトル', '記事URL']);
// 公開済みの記事を全て取得
$args = [
'post_type' => 'post',
'post_status' => 'publish',
'posts_per_page' => -1, // 全ての記事を取得
];
$posts = new WP_Query($args);
// 記事が見つからなかった場合の処理
if (!$posts->have_posts()) {
fputcsv($output, ['記事が見つかりませんでした。']);
fclose($output);
exit;
}
// 記事の処理件数をカウント
$post_count = 0;
if ($posts->have_posts()) {
while ($posts->have_posts()) {
$posts->the_post();
// 記事の処理件数をカウントアップ
$post_count++;
// 記事IDとタイトルを取得
$post_id = get_the_ID();
$post_title = get_the_title();
$post_url = get_permalink();
// CSVにデータを追加
fputcsv($output, [$post_id, $post_title, $post_url]);
}
wp_reset_postdata();
}
// 処理件数をCSVに出力
fputcsv($output, ['処理件数:' . $post_count . '件']);
// ファイルポインタを閉じる
fclose($output);
// これ以上の出力を防ぐために終了
exit;
}
}
/**
* 管理画面の投稿一覧画面にCSV出力ボタンを追加する
*/
function addCsvExportButtonToPostList()
{
global $pagenow;
// 投稿一覧画面でのみ実行
if ('edit.php' === $pagenow) {
?>
<form method="post" action="<?php echo admin_url('admin-post.php'); ?>" style="display: inline-block; position: fixed; right: 30px; bottom: 30px;">
<input type="hidden" name="action" value="csv_export">
<?php wp_nonce_field('csv-output-action', 'nonce'); ?>
<input type="hidden" name="csv-output" value="true">
<button type="submit" class="csv-output-btn">記事情報をCSV出力</button>
</form>
<?php
}
}
add_action('admin_footer', 'addCsvExportButtonToPostList');
/**
* CSV出力処理を実行
*/
add_action('admin_post_csv_export', 'createCsvPostList');
add_action('admin_post_nopriv_csv_export', 'createCsvPostList');
functions.phpの編集方法については以下の記事で詳しく解説しています。


解説
簡単にソースコードの解説をします。
ポイント(3つ)
- ① createCsvPostList()
-
CSVファイルの出力を行う関数
- ② addCsvExportButtonToPostList()
-
投稿一覧画面にCSV出力処理を実行するためのボタンを設置する関数
(=createCsvPostList()を実行するためのボタン) - ③ add_action(‘admin_post_〇〇〇’, ‘●●●●●’);
-
WordPress管理画面内でPOST送信を実行するために必要なアクションフック
① createCsvPostList()
createCsvPostList()はCSVファイルの出力を行う関数です。この関数が実行されることで、ローカルPC上に記事一覧情報がCSVファイルでダウンロードされます。
/**
* CSVファイルを生成して出力する。
*/
function createCsvPostList()
{
if (isset($_POST['csv-output']) && $_POST['csv-output'] === 'true') {
// セキュリティチェック
if (!isset($_POST['nonce']) || !wp_verify_nonce($_POST['nonce'], 'csv-output-action')) {
wp_die('セキュリティチェックに失敗しました。');
}
// CSVファイル名
$file_name = '記事PV出力_' . date('Ymd_His') . '.csv';
// CSVダウンロード用のヘッダーを設定
header('Content-Type: text/csv; charset=utf-8');
header('Content-Disposition: attachment; filename="' . $file_name . '"');
// 出力ストリームに接続されたファイルポインタを作成
$output = fopen('php://output', 'w');
// Excel互換のためにUTF-8 BOM(バイトオーダーマーク)を追加
fwrite($output, "\xEF\xBB\xBF");
// CSVヘッダー行
fputcsv($output, ['記事ID', '記事タイトル', '記事URL']);
// 公開済みの記事を全て取得
$args = [
'post_type' => 'post',
'post_status' => 'publish',
'posts_per_page' => -1, // 全ての記事を取得
];
$posts = new WP_Query($args);
// 記事が見つからなかった場合の処理
if (!$posts->have_posts()) {
fputcsv($output, ['記事が見つかりませんでした。']);
fclose($output);
exit;
}
// 記事の処理件数をカウント
$post_count = 0;
if ($posts->have_posts()) {
while ($posts->have_posts()) {
$posts->the_post();
// 記事の処理件数をカウントアップ
$post_count++;
// 記事IDとタイトルを取得
$post_id = get_the_ID();
$post_title = get_the_title();
$post_url = get_permalink();
// CSVにデータを追加
fputcsv($output, [$post_id, $post_title, $post_url]);
}
wp_reset_postdata();
}
// 処理件数をCSVに出力
fputcsv($output, ['処理件数:' . $post_count . '件']);
// ファイルポインタを閉じる
fclose($output);
// これ以上の出力を防ぐために終了
exit;
}
}
上から順番に、主要なソースコードの解説をします。
if (isset($_POST['csv-output']) && $_POST['csv-output'] === 'true'){
~省略~
}
name属性がcsv-output
でvalue属性がtrue
となっているボタンからPOST送信があった場合にのみ、CSV出力処理が実行されるよう制御しています。
// セキュリティチェック
if (!isset($_POST['nonce']) || !wp_verify_nonce($_POST['nonce'], 'csv-output-action')) {
wp_die('セキュリティチェックに失敗しました。');
}
WordPressにはnonceという仕組みが用意されています。いわゆるCSRF攻撃対策のために、上記のセキュリティチェック処理が必須です。
CSRF対策については以下の記事で詳しく解説しています。


具体的には、ボタンをクリックしたときにトークン(ランダムな文字列)も一緒にPOST送信し、上記のソースコードで「このPOST送信は受け取って問題のないものか?(攻撃者によるリクエストではないか?)」を判定しています。
POST送信を行うようなWebアプリでは、必ずこのようにトークンを用いて正規のリクエストかどうかを判定する必要があります。



CSRF対策をしておかないと、例えば、「アクセス情報を改ざん → 不正にアクセスされる」といった被害が発生する可能性があります!
// CSVファイル名
$file_name = '記事PV出力_' . date('Ymd_His') . '.csv';
コメントにもあるように、ここでCSVファイルの名前を設定しています。ファイルの上書きを防ぐためにも、基本的には日時情報を含めることで、ファイル名が必ず一意となるようにすることをオススメします。
// CSVダウンロード用のヘッダーを設定
header('Content-Type: text/csv; charset=utf-8');
header('Content-Disposition: attachment; filename="' . $fileName . '"');
ここではヘッダー情報を設定しています。
- Content-Type: text/csv; …… ファイル形式をCSVに設定
- Content-Disposition: attachment; ……
attachment
を指定することで、「このファイルがダウンロードするべきもの」ということをブラウザへ伝えています。
// CSVヘッダー行
fputcsv($output, ['記事ID', '記事タイトル', '記事URL']);
CSVファイルに出力する各列の項目名を設定しています。出力する情報や出力する順番などに応じてご調整ください。
// 公開済みの記事を全て取得
$args = [
'post_type' => 'post',
'post_status' => 'publish',
'posts_per_page' => -1, // 全ての記事を取得
];
$posts = new WP_Query($args);
ここではすべての記事情報を取得しています。行っていることは、サブループの生成とまったく同じです。
上記のソースコードでは「公開済み」の記事を対象としていますが、別のオプションや複数のオプションを同時に指定することも可能です。
サブループ(WP_Query)については以下の記事で詳しく解説しています。
※「投稿状態のオプション」については下記記事の投稿の状態(公開・下書きなど)の章をご覧ください。


if ($posts->have_posts()) {
while ($posts->have_posts()) {
$posts->the_post();
// 記事の処理件数をカウントアップ
$post_count++;
// 記事IDとタイトルを取得
$post_id = get_the_ID();
$post_title = get_the_title();
$post_url = get_permalink();
// CSVにデータを追加
fputcsv($output, [$post_id, $post_title, $post_url]);
}
wp_reset_postdata();
}
サブループを利用したことがある方ならお馴染みのループ処理です。ページ制作のときはここでHTMLタグを使用して記事情報を出力しますが、今回はCSVファイルへ出力するデータとして、記事情報をピックアップしています。
もしカテゴリーやタグ情報も必要な場合は、この処理内でget_the_category()などのテンプレートタグを使用してご自由にカスタマイズ可能です。
② addCsvExportButtonToPostList()
続いて、投稿一覧画面にCSV出力処理を実行するためのボタンを表示するソースコードの解説です。
/**
* 管理画面の投稿一覧画面にCSV出力ボタンを追加する
*/
function addCsvExportButtonToPostList()
{
global $pagenow;
// 投稿一覧画面でのみ実行
if ('edit.php' === $pagenow) {
?>
<form method="post" action="<?php echo admin_url('admin-post.php'); ?>" style="display: inline-block; position: fixed; right: 30px; bottom: 30px;">
<input type="hidden" name="action" value="csv_export">
<?php wp_nonce_field('csv-output-action', 'nonce'); ?>
<input type="hidden" name="csv-output" value="true">
<button type="submit" class="csv-output-btn">記事情報をCSV出力</button>
</form>
<?php
}
}
add_action('admin_footer', 'addCsvExportButtonToPostList');
global $pagenow;
// 投稿一覧画面でのみ実行
if ('edit.php' === $pagenow) {
~省略~
}
global $pagenow;
により、「現在表示中のページ情報」を取得することができます。また、「投稿一覧画面=edit.php」のため、if分でいまいるページが投稿一覧画面かどうかを判定しています。
<!-- ボタンは画面右下に固定表示する -->
<form method="post" action="<?php echo admin_url('admin-post.php'); ?>" style="display: inline-block; position: fixed; bottom: 30px; right: 30px;">
<input type="hidden" name="action" value="csv_export">
<?php wp_nonce_field('csv-output-action', 'nonce'); ?>
<input type="hidden" name="csv-output" value="true">
<button type="submit" class="csv-output-btn">PV数をCSV出力</button>
</form>
ここで投稿一覧画面に表示するボタンのHTMLを記述しています。
- action=”<?php echo admin_url(‘admin-post.php’); ?>”でPOST送信先URLを自動生成
- ハイライト行でWordpressの
wp_nonce_field
関数を利用し、トークンを生成 - formタグに直接style属性を持たせ、position: fixed;で固定表示
WordPressでは管理画面内でフォーム送信を処理するためのファイルとしてadmin-post.php
が準備されています。action属性では、admin_url()
関数を使用することで、admin-post.php
へPOST送信するためのURLを生成しています。
また、wp_nonce_field
関数によって、自動的にトークンを持つinputタグが生成されます。
wp_nonce_field
関数によって自動生成されるinputタグ


add_action('admin_footer', 'addCsvExportButtonToPostList');
最後に、アクションフックadmin_footer
にaddCsvExportButtonToPostList()
関数をフックすることで、投稿一覧画面のフッター部分(</body>タグの直前)でボタンのHTMLが出力されるよう設定しています。
③ add_action(‘admin_post_〇〇〇’, ‘●●●●●’);
3つ目のポイントとなるソースコードは、以下の2行です。
/**
* CSV出力処理を実行
*/
add_action('admin_post_csv_export', 'createCsvPostList');
add_action('admin_post_nopriv_csv_export', 'createCsvPostList');
先ほどadmin-post.php
について触れました。
上記2行のソースコードは、admin-post.php
で実行するための関数を登録するためのものです。admin-post.php
は、フォーム送信されたデータに含まれる「action属性の値」にもとづき、登録されているアクション(関数)を実行します。
具体的にはadmin_post_{action}
というアクションフックに登録された関数が実行されるという仕組みになっています。
例えば今回のソースコードを見ると、formタグ内にあるinputタグのひとつにvalue="csv_export"
が設定されています。(つまりフォームデータにcsv_export
が含まれる)
一方、アクションフックではadd_action('admin_post_csv_export', 'createCsvPostList');
のように、createCsvPostList()関数をフックしています。
なお、admin_post_nopriv_csv_export
アクションフックについては、本来は非ログインユーザー向けのものです。一見すると不要にも思えますが、セキュリティの互換性から、admin_post_{action}とadmin_post_nopriv_{action}は併記することが推奨されています。
まとめ
以上が記事情報をCSV出力するボタンを投稿一覧画面に設置する方法でした。
今回は「記事一覧情報をCSV出力する」という具体的な目的にそった内容でした。しかし、当記事の内容を理解すれば、管理画面上でフォーム送信する処理を安全に書くことができるようになります。
特にnonceによるセキュリティチェックやadmin_post_{action}のようなアクションフックの理解は、Wordpressカスタマイズの柔軟性を高めてくれるはずです。



この記事が皆さまのWordpress開発のお役に立てたなら何よりです!
それでは、最後までご覧いただきありがとうございました!
当ブログではWordpressやWeb制作、PHPやLaravelなどのWebアプリに関する情報を発信しています。ご興味のある方はほかの記事もご覧いただけるとうれしいです!
コメント