Category
Archives
Cocotiie
Trial And Error!やってみよう!の精神でWeb制作をしています。初心者の方にも伝わるよう、心がけています。少しでも誰かの助けになれれば嬉しいです。宜しくお願い致します。

2006年:Web制作に関する覚書きブログをはじめる。

2018年:Cocotiie(ココッティー)として運営開始。
このサイトは快適なテーマ「SWELL」を使用していますSWELLについて

[WordPress] 代替え 営業日/休業日カレンダー プラグインなし

営業日カレンダー

営業日/休業日カレンダーの需要は意外とあり、開発が終了してしまったXO Event CalendarやBiz Calendarにお世話になっていました。

代替え品を探しましたが、自作する事にしました。代替えとは言い難い程の極シンプルなカレンダーですが、皆さんの助けになれば嬉しいです。チャッピーさんに助けてもらいながら作りました。AIの進歩に驚くばかり、怖いくらいです。一人では何日もかかったはず。

月曜始まりと日曜始まりの2種を作りました。意味不明でもコピペでOKです。

INDEX

仕様

営業日カレンダー
  • 三角の月の送りボタンは、もう前の月/翌月に送れない場合はグレーで表示
  • 日付の余ったセルには、前後の日付をグレーで表示
  • ‘2026-01-01’ 表記で登録
  • ショートコードを張り付けるだけ

JSファイルの作成

子テーマの中に「js」フォルダを作り中にcalendar.jsファイルを作成 js/calendar.js

document.addEventListener('DOMContentLoaded', () => {
  document.querySelectorAll('.holiday-calendar-wrapper').forEach(wrapper => {

    let current = wrapper.dataset.currentMonth;
    const max   = wrapper.dataset.maxMonth;
    const min   = wrapper.dataset.minMonth;
    const body  = wrapper.querySelector('.calendar-body');
    const label = wrapper.querySelector('.current');

    const updateNav = () => {
      wrapper.querySelector('.prev').disabled = (current <= min);
      wrapper.querySelector('.next').disabled = (current >= max);
    };

    const loadMonth = ym => {
      const key = 'cal' + ym.replace('-', '');
      if (!wrapper.dataset[key]) return;

      body.innerHTML = wrapper.dataset[key];

      const [y, m] = ym.split('-');
      label.textContent = `${y}年${m}月`;

      updateNav();
    };

    wrapper.querySelector('.prev').onclick = () => {
      const d = new Date(current + '-01');
      d.setMonth(d.getMonth() - 1);
      const next = d.toISOString().slice(0, 7);
      if (next < min) return;
      current = next;
      loadMonth(current);
    };

    wrapper.querySelector('.next').onclick = () => {
      const d = new Date(current + '-01');
      d.setMonth(d.getMonth() + 1);
      const next = d.toISOString().slice(0, 7);
      if (next > max) return;
      current = next;
      loadMonth(current);
    };

    loadMonth(current);
  });
});

functon.phpにコードを書く

下へ下へとコードを追記してください。

functions.php
├─ファイルのリンク
├─ 日付設定
├─ HTML (日曜始まり、又は月曜始まりのどちらか)
├─ カレンダーの生成
└─ ショートコード

基本部分

先ほどのjsファイルをリンクします。

function enqueue_custom_scripts() {
    wp_enqueue_script(
        'custom-js',
        get_stylesheet_directory_uri() . '/js/calendar.js',
        array(),
        null,
        true
    );
}
add_action('wp_enqueue_scripts', 'enqueue_custom_scripts');

その下に、日付の設定を追記。編集するのはココだけです。

//日付の設定はココ
function my_holiday_dates() {
  return [
    '2026-01-01',
    '2026-01-06',
    '2026-02-11',
    '2026-05-11',
    '2026-06-20',
    '2026-08-31',
    '2026-09-30',
  ];
}

日曜日から始まるカレンダー

日曜始まり、又は月曜始まりのどちらかをコピペしてください。

// HTML
function my_render_calendar_single_month($year, $month) {
  $holidays = my_holiday_dates();

  ob_start();

  echo '<table class="holiday-calendar">';
  echo '<tr class="week">';
  echo '<th class="sun">日</th><th>月</th><th>火</th><th>水</th><th>木</th><th>金</th><th class="sat">土</th>';
  echo '</tr><tr>';

  $first_w = (int) date('w', strtotime("$year-$month-01"));

  $prev = new DateTime("$year-$month-01");
  $prev->modify('-1 month');
  $prev_last = (int) $prev->format('t');

  for ($i = $first_w - 1; $i >= 0; $i--) {
    $day  = $prev_last - $i;
    $date = $prev->format('Y-m-') . sprintf('%02d', $day);

    $class = ['other-month'];
    if (in_array($date, $holidays, true)) {
      $class[] = 'holiday';
    }

    echo '<td class="'.implode(' ', $class).'">'.$day.'</td>';
  }

  $days = (int) date('t', strtotime("$year-$month-01"));

  for ($d = 1; $d <= $days; $d++) {
    $date = sprintf('%04d-%02d-%02d', $year, $month, $d);
    $class = [];

    if (in_array($date, $holidays, true)) {
      $class[] = 'holiday';
    }

    $w = (int) date('w', strtotime($date));
    if ($w === 0) $class[] = 'sun';
    if ($w === 6) $class[] = 'sat';

    echo '<td class="'.implode(' ', $class).'">'.$d.'</td>';

    if ((($d + $first_w) % 7) === 0) {
      echo '</tr><tr>';
    }
  }

  $last_w = (int) date('w', strtotime("$year-$month-$days"));

  $next = new DateTime("$year-$month-01");
  $next->modify('+1 month');
  $next_day = 1;

  for ($i = $last_w + 1; $i < 7; $i++) {
    $date = $next->format('Y-m-') . sprintf('%02d', $next_day);

    $class = ['other-month'];
    if (in_array($date, $holidays, true)) {
      $class[] = 'holiday';
    }

    echo '<td class="'.implode(' ', $class).'">'.$next_day.'</td>';
    $next_day++;
  }

 echo '</tr></table>';

/* カレンダーの下の部分 */
echo '<div class="calendar-legend">';
echo '<span class="legend-item holiday">';
echo '<span class="legend-box"></span> 休業日';
echo '</span>';
echo '</div>';

return ob_get_clean();
}

カレンダーの下の部分の「休業日」の部分は用途に応じて書き換えて下さい。

月曜から始まるカレンダー

// HTML
function my_render_calendar_single_month($year, $month) {
  $holidays = my_holiday_dates();

  ob_start();

  echo '<table class="holiday-calendar">';
  echo '<tr class="week">';
  echo '<th>月</th><th>火</th><th>水</th><th>木</th><th>金</th><th class="sat">土</th><th class="sun">日</th>';
  echo '</tr><tr>';

  $first_w = (int) date('N', strtotime("$year-$month-01")) - 1;

  $prev = new DateTime("$year-$month-01");
  $prev->modify('-1 month');
  $prev_last = (int) $prev->format('t');

  for ($i = $first_w - 1; $i >= 0; $i--) {
    $day  = $prev_last - $i;
    $date = $prev->format('Y-m-') . sprintf('%02d', $day);

    $class = ['other-month'];
    if (in_array($date, $holidays, true)) {
      $class[] = 'holiday';
    }

    echo '<td class="'.implode(' ', $class).'">'.$day.'</td>';
  }

  $days = (int) date('t', strtotime("$year-$month-01"));

  for ($d = 1; $d <= $days; $d++) {
    $date = sprintf('%04d-%02d-%02d', $year, $month, $d);
    $class = [];

    if (in_array($date, $holidays, true)) {
      $class[] = 'holiday';
    }

    $w = (int) date('N', strtotime($date)) - 1;
    if ($w === 6) $class[] = 'sun';
    if ($w === 5) $class[] = 'sat';

    echo '<td class="'.implode(' ', $class).'">'.$d.'</td>';

    if ((($d + $first_w) % 7) === 0) {
      echo '</tr><tr>';
    }
  }

  $last_w = (int) date('N', strtotime("$year-$month-$days")) - 1;

  $next = new DateTime("$year-$month-01");
  $next->modify('+1 month');
  $next_day = 1;

  for ($i = $last_w + 1; $i < 7; $i++) {
    $date = $next->format('Y-m-') . sprintf('%02d', $next_day);

    $class = ['other-month'];
    if (in_array($date, $holidays, true)) {
      $class[] = 'holiday';
    }

    echo '<td class="'.implode(' ', $class).'">'.$next_day.'</td>';
    $next_day++;
  }

 echo '</tr></table>';

/* カレンダーの下の部分 */
echo '<div class="calendar-legend">';
echo '<span class="legend-item holiday">';
echo '<span class="legend-box"></span> 休業日';
echo '</span>';
echo '</div>';

return ob_get_clean();
}

カレンダーの下の部分の「休業日」の部分は用途に応じて書き換えて下さい。

共通部分

//カレンダー生成
function my_holiday_calendar_with_nav() {
  $holidays = my_holiday_dates();
  $latest   = max($holidays);

  $max_month = date('Y-m', strtotime($latest));
  $now_month = date('Y-m');
  $min_month = date('Y-m'); // 今月

  ob_start();
  ?>
  <div class="holiday-calendar-wrapper"
     data-min-month="<?php echo esc_attr($min_month); ?>"
     data-max-month="<?php echo esc_attr($max_month); ?>"
     data-current-month="<?php echo esc_attr($now_month); ?>">

    <div class="calendar-nav">
      <button class="prev">◀</button>
      <span class="current"></span>
      <button class="next">▶</button>
    </div>

    <div class="calendar-body"></div>
  </div>
  <?php
  return ob_get_clean();
}


//JS用
add_action('wp_footer', function () {

  $holidays = my_holiday_dates();
  $latest   = max($holidays);

  $start = new DateTime('first day of this month');
  $start->setTime(0, 0, 0);

  $end = new DateTime(date('Y-m-01', strtotime($latest)));
  $end->setTime(0, 0, 0);

  echo '<script>';

  while ($start <= $end) {
    $key = 'cal' . $start->format('Ym');

    echo "document.querySelectorAll('.holiday-calendar-wrapper')
      .forEach(w => w.dataset.$key = `" .
        my_render_calendar_single_month(
          $start->format('Y'),
          $start->format('m')
        ) .
      "`);";

    $start->modify('+1 month');
  }

  echo '</script>';
});

ショートコードの設定

add_shortcode('holiday_calendar', 'my_holiday_calendar_with_nav');

上記までをfunction.phpに追記

CSS

休業日の色を#2271b1とした例

.holiday-calendar {
  width: 100%;
  border-collapse: collapse;
  font-size: 14px;
}

.holiday-calendar th,
.holiday-calendar td {
  border: 1px solid #ddd;
  padding: 6px 0;
  text-align: center;
}

.holiday-calendar td.other-month {
  color: #bbb;
}


.holiday-calendar .sun {
  color: #d63638;
}

.holiday-calendar .sat {
  color: #2271b1;
}

.holiday-calendar .holiday {
  background: #2271b1;
  color: #fff;
}

.calendar-legend {
  margin-top: 8px;
  font-size: 13px;
}

.legend-item {
  display: inline-flex;
  align-items: center;
}

.legend-box {
  width: 14px;
  height: 14px;
  background: #2271b1;
  display: inline-block;
  margin-right: 6px;
}

.calendar-nav {
  display: flex;
  justify-content: center;
  align-items: center;
  gap: 12px;
  margin-bottom: 6px;
}

.calendar-nav button {
  background: none;
  border: none;
  cursor: pointer;
  font-size: 16px;
}

.calendar-nav button:disabled {
  opacity: 0.3;
  cursor: default;
}

表示方法

先ほど、ショートコードの設定をしたので、ウィジェットや固定ページにショートコードを貼ります。

[holiday_calendar]
よかったらシェアお願いします
  • URLをコピーしました!
  • URLをコピーしました!

コメント ※ハンドルネームでお願いします

コメントする

INDEX