2年前に作った草野球チームのホームページをWordPress化した話

2年前に作った草野球チームのホームページをWordPress化した話

はじめに

本記事では、以前作成したホームページを私以外の人でも運用できるように WordPress 化した過程を書いています。

最初に公開したのが 2020 年の 8 月ごろだったので、正確には 2 年と半年ほど前に作成したものになります。

なぜ WordPress 化したのか?

以前は素の PHP で構築しており、試合結果の更新などはコードを直接更新して GitHub Actions を使ってロリポップで契約したレンタルサーバーにデプロイして運用していました。その後、家庭の事情もあり現在は休部状態となってしまいました。

しかし現在も新メンバーの募集やチーム公式 Twitter の更新など、チーム運用には携わっているので、今後の運用のことも考えて Web サイトを誰でも更新できるように作り直そうと決めました。

WordPress を選択した理由は以下になります。

  • Laravel などを使用して、自分で CMS の仕組みを作成するのは時間がかかりすぎる
  • WordPress のテーマ開発は少し勉強したこともあり、仕事でも使う可能性がある(割りと突然振られることがあるので、復習の意味も込めて)
  • この技術ブログのように Gatsby で作成することも考えたが、現在のサイトも PHP で構築していることから WordPress の方が速く作り直すことができそうだった
  • 自動インストールなど、WordPress の方がレンタルサーバとの相性が良い

ロリップで使用しているサーバーと PHP のバージョンは下記の通りです。

  • Web サーバ: LiteSpeed
  • PHP: 8.1

開発期間

2023 年 2 月頃から進めましたが、途中仕事で扱う技術のキャッチアップ(WPF や SQLServer 関連)などこの開発から離れていた期間もあり実質 2 週間程度だと思います。

3 月には公開しました。(その後、細かな修正はありましたが…。)

開発環境全体のディレクトリ構成

開発環境は Dokcer を使用しています。

  • Windows11: 22H2(22621.1413)
  • WSL: Ubuntu-20.04 Version 2
  • Ubuntu: 20.04.5 LTS
  • Docker: 20.10.23(build 7155243)
  • Docker Compose: 2.15.1
プロジェクトディレクトリ
├── .devcontainer
│   ├── apache
│   │     └── 000-default.conf
│   ├── devcontainer.json
│   ├── docker-compose.yml
│   ├── php
│   │     └── php.ini
│   └── wordpress
│          └── Dockerfile
├── .github
│   └── workflows
│       ├── production-wordpress-deploy.yml
├── .vscode
│      └── launch.json
├── public # コンテナ起動時に作成されるWordPressファイル群
│     │   ├── index.php
│     │   ├── plugins # 開発で使用したプラグインもGitで管理
│     │   │     ├── contact-form-7
│     │   │     ├── contact-form-cfdb7
│     │   │     ├── index.php
│     │   │     ├── moving-media-library
│     │   │     ├── show-current-template
│     │   │     ├── widget-importer-exporter
│     │   │     ├── wordpress-importer
│     │   │     └── wp-mail-smtp
│     │   ├── themes
│     │   │     ├── LINEUP_BASEBALLCLUB
│     │   │     │   ├── 404.php
│     │   │     │   ├── assets
│     │   │     │   ├── contact.php
│     │   │     │   ├── content-menu.php
│     │   │     │   ├── customize_functions
│     │   │     │   ├── footer.php
│     │   │     │   ├── functions.php
│     │   │     │   ├── header.php
│     │   │     │   ├── home.php
│     │   │     │   ├── index.php
│     │   │     │   ├── introduction.php
│     │   │     │   ├── member.php
│     │   │     │   ├── privacy-policy.php
│     │   │     │   ├── rule.php
│     │   │     │   ├── score.php
│     │   │     │   ├── screenshot.png
│     │   │     │   ├── style.css
│     │   │     │   └── team.php
│     │   │     └── index.php
│     │   ├── upgrade
│     │   └── uploads
│      # WordPressの細かいファイル群は省略
└── src
      ├── babel.config.js
      ├── images
      ├── js
      │     ├── index.js
      ├── package-lock.json
      ├── package.json
      ├── postcss.config.js
      ├── scss
      │     ├── foundation
      │     ├── layout
      │     ├── object
      │     │   ├── component
      │     │   ├── project
      │     │   └── utility
      │     │
      │     └── style.scss
      ├── webpack.config.common.js
      ├── webpack.config.dev.js
      └── webpack.config.prod.js

Docker の開発環境では、Xdebug を使ったデバッグ環境の構築やメール送信のテストとしてmailhogなどをコンテナとして用意しました。

テーマのディレクトリ構成

LIENUP-Wordpress-Theme
├── 404.php
├── assets
│     ├── adminCss
│     │     └── admin.css # 管理画面用css
│     ├── css
│     │     └── style.min.css # webpackで出力する
│     ├── favicon.ico
│     ├── images
│     │     ├── footer-visual.jpg
│     │     ├── logo.png
│     │     ├── no-image.png
│     │     ├── ogp.png
│     │     ├── pagetop.png
│     │     └── youtube-icon.svg
│     └── js
│          └── bundle.min.js # webpackで出力する
├── contact.php
├── content-menu.php
├── customize_functions
│      ├── contact_form_functions.php # Contact Form7に関する設定
│      ├── page_functions.php # 固定ページに関する設定
│      ├── remove_default__menu.php # 不要なメニューを管理画面に表示させない設定
│      └── widgets_functions.php # ウィジェットに関する設定
├── functions.php
├── footer.php
├── header.php
├── home.php
├── index.php
├── introduction.php
├── member.php
├── privacy-policy.php
├── rule.php
├── score.php
├── screenshot.png
├── style.css
└── team.php

customize_functionsディレクトリ配下のファイルは、functions.phpで読み込むようにしています。

"functions.php"

// ~ ファイルの末尾 ~

// 固定ページに関する処理をまとめたファイル
require(get_template_directory() . '/customize_functions/page_functions.php');
// Contact Form7に関する設定をまとめたファイル
require(get_template_directory() . '/customize_functions/contact_form_functions.php');
// カスタムウィジェット関係の処理をまとめたファイル
require(get_template_directory() . '/customize_functions/widgets_functions.php');
// 管理画面の不要なメニューを非表示にする処理をまとめたファイル
require(get_template_directory() . '/customize_functions/remove_default__menu.php');

サイト一覧

トップページ

まずはトップページとなる画面です。

top-page

基本的に各ページを固定ページとして作成して、部分的に変更したい箇所をカスタムフィールドの入力欄で作成しているシンプルなものになっています。

ブログなど動的に追加されるコンテンツを投稿していく予定は今のところありません。

admin-menu-01

page-01

ほぼトップページのみカスタムフィールドで入力項目を作成しています。入力項目としてはメインビジュアルで表示されるテキストや、背景の動画の URL などを指定しています。

"page_functions.php"
/**
 * 固定ページにカスタムフィールドを表示させる
 *
 * @return void
 */
function add_custom_inputbox(): void
{
    // 第一引数:編集画面のhtmlに挿入されるid属性
    // 第二引数:管理画面に表示されるカスタムフィールド名
    // 第三引数:編集画面にhtmlを出力するための関数を指定
    // 第四引数:管理画面に表示するカスタムフィールドの場所(post: 投稿ページ、page: 固定ページ、その他 'dashboard','link',などが指定できる)
    // 第五引数:メタボックスの配置場所('normal': 通常のメタボックスエリア、'side': サイドバーのメタボックスエリア、'advanced': 通常のメタボックスエリアの下部)
    add_meta_box('main_visual_movie_id', 'メインビジュアルムービー登録欄', 'main_visual_movie', 'page', 'normal');

    add_meta_box('sns_link_id', 'SNSリンク', 'sns_link', 'page', 'normal');

    add_meta_box('main_visual_text_id', 'メインビジュアルテキスト登録欄', 'main_visual_text', 'page', 'normal');

    add_meta_box('top_page_panel_image_id', 'パネル画像エリア', 'top_page_panel_image', 'page', 'normal');

    add_meta_box('team_theme_id', 'チームテーマ', 'team_theme_text', 'page', 'normal');

    add_meta_box('is_member_recruiting_id', 'メンバー募集ステータス', 'is_member_recruiting', 'page', 'normal');
}
/**
 * フックに登録
 */
add_action('admin_menu', 'add_custom_inputbox');

以下は、add_meta_boxで指定しているトップページのメインビジュアルの背景用動画を指定するカスタムフィールドを表示させる関数です。

このカスタムフィールドはフロントページに指定した固定ページのみに表示させるように指定しています。

"page_functions.php"
/**
 * トップページ用の固定ページにメインビジュアル用の動画を登録するテキストボックスを表示させる
 * ※素材は別のURLからでも、管理画面のメディアからでも良いこととする
 *
 * @return void
 */
function main_visual_movie(): void
{
    // カスタムフィールドを作る関数の中では必ずグローバル関数を使う
    global $post;

    // フロントページに指定している固定ページIDを取得
    $page_obj = (int)get_option('page_on_front');

    $main_visual_movie = get_post_meta($post->ID, 'main_visual_movie', true);

    if ($post->ID === $page_obj) {
        echo '<p>メインビジュアルムービーURL :</p><input type="text" name="main_visual_movie" value="' . esc_attr($main_visual_movie) . '"> ';
    }
}

チーム内に試合の動画を撮影してくれているメンバーがいるので、限定公開でチーム用の Youtube アカウントに動画を投稿しています。

その投稿した動画をホームページ内に表示させているのですが、動的にコンテンツが追加されるのでカスタムウィジェットで登録して表示させるようにしました。

スライダーのプラグインはSwiperを使用しています。

widget-youtube-01

"home.php"
<?php

// ~ 中略 ~

    <section class="c-homeContainer p-homeCategory p-homeCategory__movie--wrapp u-hidden u-padding__top--xxl js-youtube-container">
        <h2 class="p-homeCategory__movie__title">MOVIE</h2>
        <div class="flex-wrapp">
            <div class="p-homeCategory__movie p-slider__wrapp p-youtube__container">
                <div class="p-homeCategory__movie__item p-slider__item">
                    <!-- Swiper -->
                    <div class="swiper mySwiper p-swiper__container">
                        <div class="swiper-wrapper">
                            <?php dynamic_sidebar('widget_youtube'); ?>
                        </div>
                        <div class="swiper-button-next"></div>
                        <div class="swiper-button-prev"></div>
                        <div class="swiper-pagination"></div>
                    </div>
                </div>
            </div>
        </div>
    </section>
</main>

<?php get_footer(); ?>

登録したウィジェットを表示させる部分は以下の用に記述しています。

"customize_functions/widgets_functions.php"
<?php

/**
 * Youtuhbe動画登録用のウィジェットを作成
 */
class youtube_widgets extends WP_Widget // ウィジェットAPIを継承
{

    /**
     * コンストラクター
     */
    function __construct()
    {
        parent::__construct(
            'youtube_widgets', // Base ID
            'Youtube動画ウィジェット' // 管理画面に表示されるウィジェットの名前
        );
    }

    // ~ 中略 ~

    /**
     * ウィジェットのフロントエンドを表示させる処理
     * ※dynamic_sidebarメソッドで呼び出した際に表示されるhtml
     *
     * @param [type] $args: ウィジェットの引数
     * @param [type] $instance: 現在登録されている値
     * @return void
     */
    function widget($args, $instance): void
    {
        // 配列のキー名を変数名として使える用に展開
        extract($args);

        // ウィジェットに入力された情報を取得
        $title        = apply_filters('widget_title', $instance['title']);
        $youtube_url = apply_filters('widget_youtube_url', $instance['youtube_url']);
        $img_path     = apply_filters('widget_img_path', $instance['img_path']);

        // ウィジェットから入力された情報がある場合はhtmlを表示する
        if (!empty($title)) {
?>
            <!-- ここからHTMLタグ -->
            <a class="swiper-slide" href="<?php echo esc_url($youtube_url); ?> " target="_blank" rel="noopener noreferrer">
                <div class="p-youtube__container">
                    <img class="p-youtube" src="<?php echo esc_url($img_path); ?>" />
                    <img class="p-youtube--icon" src='<?php echo get_template_directory_uri(); ?>/assets/images/youtube-icon.svg' />
                </div>
            </a>
            <!-- ここまで -->
        <?php
        }
    }

    // ~ 中略 ~
}

チーム紹介

チーム紹介のページです。

team

ここでは、固定ページ内に投稿した内容を出力しているだけの簡単なものになっています。

team-01

固定ページ内のコードもシンプルです

"introduction.php"
<?php
/*
    Template Name: Introduction ~チーム紹介ページ~
*/
?>

<?php get_header(); ?>

<?php get_template_part('content', 'menu'); ?>

<main class="l-main__rule u-inner">

    <section class="c-table">
        <h2 class="c-title">チーム紹介<span class="c-title__sub">- Team -</span></h2>

        <?php
        // 固定ページの投稿内容を表示する
        if (have_posts()) {
            while (have_posts()) {
                the_post();
                the_content();
            }
        }
        ?>

    </section>
</main>

<?php get_footer(); ?>

チーム規則

チーム規則のページです。

このページもチーム紹介ページとほぼ同じ内容となっています。

rule

メンバー募集

メンバー募集のページです。

フォームの部分はプラグインの ContactForm7 で作成しています。スパム対策として、reCAPTCHA (v3)を設定してます。

member

メンバー募集のページでは募集中のステータスを変更できる用にしています。

member-01

固定ページからのチェックボックスを非表示にすると表示が切り替わりフォームも非表示になります。

member-02

お問い合わせ

お問い合わせのページです。

こちらもフォームの部分は ContactForm7 で作成しています。

contact

改善点

WordPress 化するに当たり、今後改善すべき点をいくつか振り返りました。

問い合わせフォームの処理を自作する

WordPress で構築されているサイトを色々参考にしていたのですが、とあるサイトでは ContactForm7 が使用されておらずreCAPTCHA (v3)のトークンを Ajax で api のエンドポイントに送信する方法が使用されており、こういう仕組みを一つ作っておけば色々使いまわせそうだなと思いました。

自分でメンテナンスする必要がありますが、プラグインの仕様変更にも左右されないので作成してみたいと思います。

今回は期限を決めて開発していたためプラグインを使用することにしました。

レスポンシブ表示の改善

しばらくメンテナンスしていなかったのですが、メディアクエリでmax-widthを基準に記述していて、ブレークポイントの記述がごちゃごちゃしているなと感じました。

また、タブレット画面での表示が崩れているので問い合わせフォームの件より優先的に修正していこうと思います。

参考にした書籍

WordPress に関する書籍は初学者向けが多く、取り敢えず作ってみよう(プラグインもりもりで)という物が多いです。

取り敢えず作り上げることも大事なのですが、こちらの書籍は WordPress がどういったアーキテクチャなのか分かりやすく解説されていて、カスタマイズ手法や開発のポイントなども記載されているのである程度開発に関わって来た人は一度目を通して損はないと思います。

最後に

草野球チームはそもそも活動しているのか分かりづらいチームが多いです。ホームページを持ったり SNS 運用したりすることでチームの雰囲気やしっかり活動していることが伝わるので今後も継続していくとともに、ゆくゆくは自分の手を離れるようにしてきたいと思います(笑

ホームページから問い合わせて、体験参加を経て入部してくれた人もいるので作って良かったと実感しています。

LINEUP では「楽しみながら勝つ!」というテーマを掲げて活動しています。野球の経歴問わずメンバーを募集していますので、興味のある方は一度体験で参加してみてはいかがでしょうか?(宣伝

メンバー募集ページでは年齢制限を設けていますが、そこは柔軟に対応させて頂きます。