# WordPress講義4回目 ## 環境構築 先週作成したテーマを利用します。 先週の資料は[こちら](https://hackmd.io/@gY8gdngQSbmAZ9WDXUEF6g/B12bMWoT3) **先週時の授業を受けれていない方は[ここから](https://drive.google.com/drive/folders/1KPGe4vudpCcdemfPS1Dr07jlz1EujCfX?usp=sharing)先週作成したWPテーマをダウンロードして続きから作業をしてください。 Local Sites\sample\app\public\wp-content\themes の階層にダウンロードしたmyblogというフォルダを配置してVsCodeで開いてください。** ## オリジナルのプラグインを作ってみよう ### 最小構成のプラグインを作成 #### 1. /wp-content/pluginsフォルダにcustom-post-listフォルダを作成 #### 2. custom-post-listフォルダのなかにcustom-post-list.phpを作成して以下をコピペ ``` <?php //ヘッダー:プラグインであることの宣言。以下を記述することでプラグインとして認識される。 /** * @package WordPress * @subpackage custom-post-list * @author 自分の名前 * * * Plugin Name: 店舗管理用プラグイン * Plugin URI: 自分のサイト * Text Domain: custom-post-list * Description: 店舗管理用オリジナルカスタムフィールド Wp5.5対応版 * Author: 自分の名前 * Author URI: 自分のサイト * Version: 1.0 * License: GPLv3+ */ ``` *これだけでプライグインとしての最小構成は完成しています。 ### 店舗データ管理用のカスタム投稿システムをプラグインとして作る #### 1. まずは以下の内容をコピペ ``` function list_init() { $labels = array( 'name' => _x('店舗データ', 'post type general name'), 'all_items' => __('店舗一覧'), 'singular_name' => __('データ'), 'add_new' => __('データ追加'), 'parent_item_colon' => '' ); $args = array( 'labels' => $labels, 'public' => true,//管理画面・サイトへの表示の有無 'publicly_queryable' => true, 'show_ui' => true, //管理画面のメニューへの表示の有無 'menu_position' => 5,//管理メニューでの表示位置 'query_var' => true, 'rewrite' => true,//パーマリンク設定 'capability_type' => 'post',//権限タイプ 'map_meta_cap' => true,//デフォのメタ情報処理を利用の有無 'hierarchical' => false,//階層(親)の有無 'menu_icon' => 'dashicons-building',//アイコン画像 'supports' => array('title','thumbnail'), // 'taxonomies' => array( '', '' ), //postと共通にする場合 'has_archive' => true, //アーカイブの有無 // 'show_in_rest' => true //Gutenbergを有効化 ); register_post_type('list', $args); } ``` #### 2. list_init関数のなかにさらにタクソノミーの記述も追加 ``` //カテゴリータイプ ポストと別のカテゴリーにする $args = array( 'label' => 'カテゴリー', 'public' => true, 'has_archive' => true, 'show_in_rest' => true, 'hierarchical' => true,// カテゴリーを階層化する方法 ); register_taxonomy('list_cat', 'list', $args); //タグタイプ $args = array( 'label' => 'タグ', 'public' => true, 'has_archive' => true, 'show_in_rest' => true, ); register_taxonomy('list_tag', 'list', $args); ``` #### 3. 最後に関数をadd_actionで登録 ``` function list_init(){ 省略 } add_action('init', 'list_init');//ここを追加 ``` ### 管理画面の編集画面にボックスを追加 ``` // 投稿と固定ページの編集画面メインカラムにボックスを追加 function add_list_field() { // $screens = array( 'post', 'page' ); $screens = array('list'); foreach ($screens as $screen) { add_meta_box('list_data', '店舗データ', 'insert_list_field', $screen); } } add_action('add_meta_boxes', 'add_list_field'); ``` ### 管理画面にフォームボックスを表示する処理 ``` function insert_list_field($post) { // nonceフィールドを追加して後でチェックする wp_nonce_field('save_custom_field_list', 'input_nonce_name'); // 管理画面デザイン Bootstrap echo '<link href="https://cdn.jsdelivr.net/npm/bootstrap@5.0.2/dist/css/bootstrap.min.css" rel="stylesheet" integrity="sha384-EVSTQN3/azprG1Anm3QDgpJLIm9Nao0Yz1ztcQTwFspd3yD65VohhpuuCOmLASjC" crossorigin="anonymous">'; echo '<h3 class="small">店舗・会社 概要</h3> <table class="table table-bordered adminListTable"> <tbody> <tr> <th>会社名・店舗名</th> <td><input class="form-control" type="text" name="cf_company" placeholder="" value="' . esc_attr(get_post_meta($post->ID, 'cf_company', true)) . '" /></td> <th>郵便番号</th> <td><input class="form-control" type="text" name="cf_zip" placeholder="" value="' . esc_attr(get_post_meta($post->ID, 'cf_zip', true)) . '" /></td> </tr> <tr> <th>住所</th> <td><input class="form-control" type="text" name="cf_add" placeholder="" value="' . esc_attr(get_post_meta($post->ID, 'cf_add', true)) . '" /></td> <th>電話番号</th> <td><input class="form-control" type="text" name="cf_tel" placeholder="" value="' . esc_attr(get_post_meta($post->ID, 'cf_tel', true)) . '" /></td> </tr> <tr> <th>営業時間</th> <td><input class="form-control" type="text" name="cf_job_time" placeholder="" value="' . esc_attr(get_post_meta($post->ID, 'cf_job_time', true)) . '" /></td> <th>定休日</th> <td><input class="form-control" type="text" name="cf_holy_day" placeholder="" value="' . esc_attr(get_post_meta($post->ID, 'cf_holy_day', true)) . '" /></td> </tr> <tr> <th>メールアドレス</th> <td><input class="form-control" type="text" name="cf_mail" placeholder="" value="' . esc_attr(get_post_meta($post->ID, 'cf_mail', true)) . '" /></td> <th>ホームページ</th> <td><input class="form-control" type="text" name="cf_url" placeholder="" value="' . esc_attr(get_post_meta($post->ID, 'cf_url', true)) . '" /></td> </tr> </tbody> </table> '; } ``` ### フォームから届いたデータを保存する処理 ``` //データ保存処理 function save_custom_field_list($post_id) { // nonceがセットされているかどうか確認 if (!isset($_POST['input_nonce_name'])) { return $post_id; } // nonceが正しいかどうか検証 if (!wp_verify_nonce($_POST['input_nonce_name'], 'save_custom_field_list')) { return $post_id; } // 自動保存の場合はなにもしない if (defined('DOING_AUTOSAVE') && DOING_AUTOSAVE) { return $post_id; } // ユーザー権限の確認 if (isset($_POST['post_type']) && 'page' == $_POST['post_type']) { if (!current_user_can('edit_page', $post_id)) { return $post_id; } } else { if (!current_user_can('edit_post', $post_id)) { return $post_id; } } // データがセットされているか確認する $param_list = array( 'cf_company', 'cf_zip', 'cf_add', 'cf_tel', 'cf_job_time', 'cf_holy_day', 'cf_mail', 'cf_url' ); foreach ($param_list as $param) { // ユーザーの入力を無害化する // この無効か入れないと クロスサイトスクリプティング(XSS) 攻撃を受ける  // テスト用「"><script>alert(document.cookie);</script>」 $_POST[$param] = sanitize_text_field($_POST[$param]); if (!empty($_POST[$param])) { update_post_meta($post_id, $param, $_POST[$param]); //値を保存 } else { //題名未入力の場合 delete_post_meta($post_id, $param); //値を削除 } } } ``` ### 最後に登録関数をadd_actionで登録 ``` add_action('save_post', 'save_custom_field_list'); ``` ### あとは表示画面作成(省略したいのでコピペベース) archive-list.php ``` <?php get_header(); ?> <!-- Section--> <section class="py-5"> <div class="container px-4 px-lg-5 mt-5"> <div class="row gx-4 gx-lg-5 row-cols-2 row-cols-md-3 row-cols-xl-4 justify-content-center"> <?php if( have_posts()):?> <?php while( have_posts() ): the_post()?> <?php $id = get_post_thumbnail_id(); $img = wp_get_attachment_image_src($id,'large'); ?> <div class="col mb-5"> <div class="card h-100"> <!-- Product image--> <img class="card-img-top" src="<?php echo $img[0]; ?>" alt="..." /> <!-- Product details--> <div class="card-body p-4"> <div class="text-center"> <!-- Product name--> <h5 class="fw-bolder"><?php the_title(); ?></h5> <!-- Product price--> <!-- <?php echo number_format($price);?>円 --> </div> </div> <!-- Product actions--> <div class="card-footer p-4 pt-0 border-top-0 bg-transparent"> <div class="text-center"><a class="btn btn-outline-dark mt-auto" href="<?php the_permalink(); ?>">View options</a></div> </div> </div> </div> <?php endwhile; ?> <?php else:?> 投稿がみつかりませんでした。 <?php endif;?> </div> </div> </section> <?php get_footer(); ?> ``` single-list.php ``` <?php get_header(); ?> <?php if( have_posts() ): ?> <?php while( have_posts() ): the_post()?> <?php $id = get_post_thumbnail_id(); $img = wp_get_attachment_image_src($id,'large'); $cf_company = get_post_meta(get_the_ID(),'cf_company',true); $cf_zip = get_post_meta(get_the_ID(),'cf_zip',true); $cf_add = get_post_meta(get_the_ID(),'cf_add',true); $cf_tel = get_post_meta(get_the_ID(),'cf_tel',true); $cf_job_time = get_post_meta(get_the_ID(),'cf_job_time',true); $cf_holy_day = get_post_meta(get_the_ID(),'cf_holy_day',true); $cf_mail = get_post_meta(get_the_ID(),'cf_mail',true); $cf_url = get_post_meta(get_the_ID(),'cf_url',true); ?> <!-- Product section--> <section class="py-5"> <div class="container px-4 px-lg-5 my-5"> <div class="row gx-4 gx-lg-5 align-items-center"> <div class="col-md-6"><img class="card-img-top mb-5 mb-md-0" src="<?php echo $img[0]; ?>" alt="..." /></div> <div class="col-md-6"> <div class="small mb-1"></div> <h1 class="display-5 fw-bolder"><?php the_title(); ?></h1> <div class="fs-5 mb-5"> <span><?php echo $cf_company;?></span> </div> <div class="fs-5 mb-5"> <p><?php echo $cf_zip;?></p> <p><?php echo $cf_add;?></p> <p><?php echo $cf_tel;?></p> <p><?php echo $cf_job_time;?></p> <p><?php echo $cf_holy_day;?></p> <p><?php echo $cf_mail;?></p> <p><?php echo $cf_url;?></p> </div> </div> </div> </div> </section> <?php endwhile;?> <?php else:?> 記事が見つかりませんでした。 <?php endif?> <?php get_footer(); ?> ```