PIX主题侧边栏添加日历小工具

PIX主题后台小工具中没有日历小工具,虽然可以在functions.php添加一些语句恢复wordpress默认的日历,但是不能满足我的需求。我想要的效果是:如果当天没有发布片刻,则当天方块无颜色;如果当天只发布片刻,则当天方块为绿色;如果当天只发布文章,则当天方块为蓝色;如果当天既发布片刻又发布文章,则当天方块为红色;鼠标移动到颜色方块上,会提示当天发布的片刻或者文章数量,点击颜色方块,会弹出当日发布的片刻或者文章详情。

PIX主题侧边栏添加日历小工具-似水流年
PIX主题侧边栏添加日历小工具-似水流年

后台可以设置日历名称以及建站日期,控制年月切换不得早于建站日期。日历名称设置为空或者发布日历时,前台不显示日历名称。

PIX主题侧边栏添加日历小工具-似水流年

此次只涉及一个文件,即pix/inc/pix-widget.php。

1、增加日历小工具并注册。在function yiyan_api()函数后面添加日历小工具函数。

// ==================== 日历小工具类 ====================
class Pix_Calendar_Widget extends WP_Widget {

    public function __construct() {
        parent::__construct(
            'pix_calendar_widget',
            __('Pix日历小工具', 'text_domain'),
            array('description' => __('显示带有文章和片刻发布记录的日历', 'text_domain'))
        );
    }

    // 前端显示
    public function widget($args, $instance) {
        $title = apply_filters('widget_title', $instance['title']);
        $build_date = !empty($instance['build_date']) ? $instance['build_date'] : '1992-10-12';
        
        echo $args['before_widget'];
        if (!empty($title)) {
            echo $args['before_title'] . $title . $args['after_title'];
        }
        
        // 获取当前年月
        $current_year = date('Y');
        $current_month = date('n');
        
        // 输出日历
        $this->render_calendar($current_year, $current_month, $build_date);
        
        // 添加详情弹窗容器
        echo '<div id="pix-calendar-detail-modal" uk-modal>
            <div class="uk-modal-dialog uk-modal-body">
                <button class="uk-modal-close-default" type="button" uk-close></button>
                <h3 class="uk-modal-title" id="pix-calendar-detail-title"></h3>
                <div id="pix-calendar-detail-content"></div>
            </div>
        </div>';
        
        echo $args['after_widget'];
    }

    // 渲染日历
    private function render_calendar($year, $month, $build_date) {
        // 获取当月天数
        $days_in_month = date('t', mktime(0, 0, 0, $month, 1, $year));
        
        // 获取当月第一天是星期几 (0=周日, 6=周六)
        $first_day_of_week = date('w', mktime(0, 0, 0, $month, 1, $year));
        
        // 获取当月所有文章和片刻的发布日期
        $posts = get_posts(array(
            'post_type' => 'post',
            'posts_per_page' => -1,
            'date_query' => array(
                array(
                    'year' => $year,
                    'month' => $month,
                ),
            ),
        ));
        
        $moments = get_posts(array(
            'post_type' => 'moment',
            'posts_per_page' => -1,
            'date_query' => array(
                array(
                    'year' => $year,
                    'month' => $month,
                ),
            ),
        ));
        
        // 创建日期统计数组
        $date_stats = array();
        
        // 统计文章
        foreach ($posts as $post) {
            $post_day = date('j', strtotime($post->post_date));
            if (!isset($date_stats[$post_day])) {
                $date_stats[$post_day] = array('posts' => array(), 'moments' => array());
            }
            $date_stats[$post_day]['posts'][] = $post;
        }
        
        // 统计片刻
        foreach ($moments as $moment) {
            $moment_day = date('j', strtotime($moment->post_date));
            if (!isset($date_stats[$moment_day])) {
                $date_stats[$moment_day] = array('posts' => array(), 'moments' => array());
            }
            $date_stats[$moment_day]['moments'][] = $moment;
        }
        
        // 中文月份名称数组
        $month_names = array('一月', '二月', '三月', '四月', '五月', '六月', '七月', '八月', '九月', '十月', '十一月', '十二月');
        
        // 开始输出日历
        echo '<div class="pix-calendar-widget" data-build-date="'.esc_attr($build_date).'">';
        
        // 日历头部 - 月份和年份导航
        echo '<div class="pix-calendar-header">';
        echo '<div class="pix-calendar-nav">';
        
        // 上一年按钮
        $prev_year = $year - 1;
        $prev_year_disabled = $prev_year < date('Y', strtotime($build_date)) ? 'disabled' : '';
        echo '<a class="pix-calendar-prev-year" data-year="'.$prev_year.'" '.$prev_year_disabled.'>&lt;&lt;</a>';
        
        // 上一月按钮
        $prev_month = $month - 1;
        $prev_month_year = $year;
        if ($prev_month < 1) {
            $prev_month = 12;
            $prev_month_year--;
        }
        $prev_month_disabled = ($prev_month_year < date('Y', strtotime($build_date)) || 
                               ($prev_month_year == date('Y', strtotime($build_date)) && $prev_month < date('n', strtotime($build_date)))) ? 'disabled' : '';
        echo '<a class="pix-calendar-prev-month" data-year="'.$prev_month_year.'" data-month="'.$prev_month.'" '.$prev_month_disabled.'>&lt;</a>';
        
        // 月份和年份显示 - 使用中文月份
        echo '<div class="pix-calendar-title">';
        echo $month_names[$month - 1] . ' ' . $year;
        echo '</div>';
        
        // 下一月按钮
        $next_month = $month + 1;
        $next_month_year = $year;
        if ($next_month > 12) {
            $next_month = 1;
            $next_month_year++;
        }
        $next_month_disabled = ($next_month_year > date('Y') || 
                               ($next_month_year == date('Y') && $next_month > date('n'))) ? 'disabled' : '';
        echo '<a class="pix-calendar-next-month" data-year="'.$next_month_year.'" data-month="'.$next_month.'" '.$next_month_disabled.'>&gt;</a>';
        
        // 下一年按钮
        $next_year = $year + 1;
        $next_year_disabled = $next_year > date('Y') ? 'disabled' : '';
        echo '<a class="pix-calendar-next-year" data-year="'.$next_year.'" '.$next_year_disabled.'>&gt;&gt;</a>';
        
        echo '</div>';
        
        // 星期标题
        $weekdays = array('日', '一', '二', '三', '四', '五', '六');
        echo '<div class="pix-calendar-weekdays">';
        foreach ($weekdays as $day) {
            echo '<div>'.$day.'</div>';
        }
        echo '</div>';
        echo '</div>';
        
        // 日历主体
        echo '<div class="pix-calendar-days">';
        
        // 填充上个月的空白
        for ($i = 0; $i < $first_day_of_week; $i++) {
            echo '<div class="pix-calendar-day other-month"></div>';
        }
        
        // 填充当月的日期
        for ($day = 1; $day <= $days_in_month; $day++) {
            $day_class = 'pix-calendar-day';
            $tooltip = '';
            $has_content = false;
            
            if (isset($date_stats[$day])) {
                $stats = $date_stats[$day];
                $posts_count = count($stats['posts']);
                $moments_count = count($stats['moments']);
                
                if ($posts_count > 0 && $moments_count > 0) {
                    $day_class .= ' has-both';
                    $tooltip = '文章: '.$posts_count.' 篇, 片刻: '.$moments_count.' 条';
                    $has_content = true;
                } elseif ($posts_count > 0) {
                    $day_class .= ' has-post';
                    $tooltip = '文章: '.$posts_count.' 篇';
                    $has_content = true;
                } elseif ($moments_count > 0) {
                    $day_class .= ' has-moment';
                    $tooltip = '片刻: '.$moments_count.' 条';
                    $has_content = true;
                }
            }
            
            // 如果是今天,添加特殊类
            if ($year == date('Y') && $month == date('n') && $day == date('j')) {
                $day_class .= ' today';
            }
            
            echo '<div class="'.$day_class.'"';
            if ($tooltip) {
                echo ' uk-tooltip="title: '.$tooltip.'"';
            }
            if ($has_content) {
                echo ' data-year="'.$year.'" data-month="'.$month.'" data-day="'.$day.'"';
            }
            echo '>'.$day.'</div>';
        }
        
        // 计算需要填充的下个月的空白
        $days_shown = $first_day_of_week + $days_in_month;
        $weeks_shown = ceil($days_shown / 7);
        $days_to_fill = $weeks_shown * 7 - $days_shown;
        
        for ($i = 0; $i < $days_to_fill; $i++) {
            echo '<div class="pix-calendar-day other-month"></div>';
        }
        
        echo '</div>';
        echo '</div>';
    }

    // 后台表单
    public function form($instance) {
        $title = !empty($instance['title']) ? $instance['title'] : __('发布日历', 'text_domain');
        $build_date = !empty($instance['build_date']) ? $instance['build_date'] : '1992-10-12';
        ?>
        <p>
            <label for="<?php echo $this->get_field_id('title'); ?>"><?php _e('标题:'); ?></label>
            <input class="widefat" id="<?php echo $this->get_field_id('title'); ?>" name="<?php echo $this->get_field_name('title'); ?>" type="text" value="<?php echo esc_attr($title); ?>">
        </p>
        <p>
            <label for="<?php echo $this->get_field_id('build_date'); ?>"><?php _e('建站日期:'); ?></label>
            <input class="widefat" id="<?php echo $this->get_field_id('build_date'); ?>" name="<?php echo $this->get_field_name('build_date'); ?>" type="date" value="<?php echo esc_attr($build_date); ?>">
            <small>格式: YYYY-MM-DD</small>
        </p>
        <?php
    }

    // 保存设置
    public function update($new_instance, $old_instance) {
        $instance = array();
        $instance['title'] = (!empty($new_instance['title'])) ? strip_tags($new_instance['title']) : '';
        $instance['build_date'] = (!empty($new_instance['build_date'])) ? $new_instance['build_date'] : '1992-10-12';
        return $instance;
    }
}

// 注册小工具
function register_pix_calendar_widget() {
    register_widget('Pix_Calendar_Widget');
}
add_action('widgets_init', 'register_pix_calendar_widget');

2、在function pix_widgets_styles()小工具式样中添加日历样式:

    /* 日历小工具样式 */
    .pix-calendar-widget {
        font-size: 14px;
        margin-bottom: 20px;
    }
    
    .pix-calendar-header {
        margin-bottom: 10px;
        color: #333 !important;
    }
    
    .pix-calendar-nav {
        display: flex;
        justify-content: space-between;
        align-items: center;
        margin-bottom: 10px;
    }
    
    .pix-calendar-nav a {
        color: #333;
        text-decoration: none;
        padding: 0 5px;
    }
    
    .pix-calendar-nav a:hover {
        color: #1e87f0;
    }
    
    .pix-calendar-disabled {
        color: #ccc;
        padding: 0 5px;
    }
    
    .pix-calendar-title {
        font-weight: bold;
        text-align: center;
    }
    
    .pix-calendar-month-selector,
    .pix-calendar-year-selector {
        cursor: pointer;
    }
    
    .pix-calendar-month-selector:hover,
    .pix-calendar-year-selector:hover {
        color: #1e87f0;
        text-decoration: underline;
    }
    
    .pix-calendar-weekdays {
        display: grid;
        grid-template-columns: repeat(7, 1fr);
        text-align: center;
        font-weight: bold;
        margin-bottom: 5px;
    }
    
    .pix-calendar-days {
        display: grid;
        grid-template-columns: repeat(7, 1fr);
        gap: 2px;
    }
    
    .pix-calendar-day {
        aspect-ratio: 1;
        display: flex;
        align-items: center;
        justify-content: center;
        border-radius: 3px;
        cursor: default;
        position: relative;
        color: #333 !important;
    }
    
    .pix-calendar-day.other-month {
        opacity: 0.3;
    }
    
    .pix-calendar-day.has-post {
        background-color: #1e87f0 !important;
        color: white;
        cursor: pointer;
    }
    
    .pix-calendar-day.has-moment {
        background-color: #32d296 !important;
        color: white;
        cursor: pointer;
    }
    
    .pix-calendar-day.has-both {
        background-color: #f0506e !important;
        color: white;
        cursor: pointer;
    }
    
    .pix-calendar-day.today {
        font-weight: bold;
        box-shadow: 0 0 0 1px #1e87f0;
    }
    
    /* 详情弹窗样式 */
/* 内容项卡片样式 */
.pix-calendar-detail-item {
    display: flex;
    margin-bottom: 1.25rem;
    padding: 1rem;
    background-color: white;
    border-radius: 8px;
    box-shadow: 0 2px 4px rgba(0, 0, 0, 0.05);
    transition: all 0.2s ease;
    border-left: 4px solid transparent;
}

.pix-calendar-detail-item:hover {
    transform: translateY(-2px);
    box-shadow: 0 4px 8px rgba(0, 0, 0, 0.1);
}

/* 不同类型的内容项边框色 */
.pix-calendar-detail-item.post {
    border-left-color: #4299e1;
}

.pix-calendar-detail-item.moment {
    border-left-color: #48bb78;
}

/* 缩略图样式 */
.pix-calendar-detail-thumbnail {
    width: 80px;
    height: 80px;
    margin-right: 1rem;
    flex-shrink: 0;
    border-radius: 6px;
    overflow: hidden;
    background-color: #f8fafc;
    display: flex;
    align-items: center;
    justify-content: center;
}

.pix-calendar-detail-thumbnail img {
    width: 100%;
    height: 100%;
    object-fit: cover;
}

/* 无缩略图时的占位图标 */
.pix-calendar-detail-thumbnail:empty::before {
    content: "";
    display: block;
    width: 40px;
    height: 40px;
    background-color: #e2e8f0;
    mask-repeat: no-repeat;
    mask-position: center;
}

/* 内容区域样式 */
.pix-calendar-detail-content-inner {
    flex: 1;
}

/* 标题样式 */
.pix-calendar-detail-title {
    margin: 0 0 0.5rem 0;
    font-size: 1.1rem;
    font-weight: 600;
    color: #2d3748;
}

.pix-calendar-detail-title a {
    color: inherit;
    text-decoration: none;
    transition: color 0.2s ease;
}

.pix-calendar-detail-title a:hover {
    color: #4299e1;
}

/* 摘要样式 */
.pix-calendar-detail-excerpt {
    font-size: 0.9rem;
    color: #4a5568;
    margin-bottom: 0.5rem;
    line-height: 1.5;
}

/* 元信息样式 */
.pix-calendar-detail-meta {
    display: flex;
    align-items: center;
    font-size: 0.8rem;
    color: #718096;
}

.pix-calendar-detail-meta span {
    display: flex;
    align-items: center;
    margin-right: 1rem;
}

.pix-calendar-detail-meta svg {
    width: 14px;
    height: 14px;
    margin-right: 0.3rem;
    fill: currentColor;
}
    
    /* 月份和年份选择下拉菜单 */
    .pix-calendar-selector {
        position: absolute;
        background: white;
        border: 1px solid #ddd;
        border-radius: 4px;
        padding: 5px;
        z-index: 1000;
        box-shadow: 0 5px 15px rgba(0,0,0,0.1);
        max-height: 200px;
        overflow-y: auto;
    }
    
    .pix-calendar-selector-item {
        padding: 5px 10px;
        cursor: pointer;
    }
    
    .pix-calendar-selector-item:hover {
        background-color: #f8f8f8;
    }
    
    /* 移动端适配 */
    @media (max-width: 768px) {
    .pix-calendar-day {
        font-size: 12px; /* 调整字体大小 */
        min-height: 30px; /* 确保触摸友好 */
    }
    }

3、添加JS小工具脚本。在document.addEventListener('DOMContentLoaded', function() {下方添加:

        // 初始化日历小工具
        function initCalendarWidgets() {
            // 月份和年份导航
            document.querySelectorAll('.pix-calendar-prev-year, .pix-calendar-next-year, .pix-calendar-prev-month, .pix-calendar-next-month').forEach(button => {
                button.addEventListener('click', function(e) {
                    e.preventDefault();
                    if (this.hasAttribute('disabled')) return;
                    
                    const calendarWidget = this.closest('.pix-calendar-widget');
                    const buildDate = calendarWidget.getAttribute('data-build-date');
                    const siteYear = new Date(buildDate).getFullYear();
                    const siteMonth = new Date(buildDate).getMonth() + 1;
                    
                    let year, month;
                    
                    if (this.classList.contains('pix-calendar-prev-year')) {
                        year = parseInt(this.getAttribute('data-year'));
                        month = parseInt(calendarWidget.querySelector('.pix-calendar-prev-month').getAttribute('data-month'));
                    } 
                    else if (this.classList.contains('pix-calendar-next-year')) {
                        year = parseInt(this.getAttribute('data-year'));
                        month = parseInt(calendarWidget.querySelector('.pix-calendar-next-month').getAttribute('data-month'));
                    }
                    else if (this.classList.contains('pix-calendar-prev-month')) {
                        year = parseInt(this.getAttribute('data-year'));
                        month = parseInt(this.getAttribute('data-month'));
                    }
                    else if (this.classList.contains('pix-calendar-next-month')) {
                        year = parseInt(this.getAttribute('data-year'));
                        month = parseInt(this.getAttribute('data-month'));
                    }
                    
                    // 确保年份不小于建站年份
                    if (year < siteYear || (year == siteYear && month < siteMonth)) {
                        year = siteYear;
                        month = siteMonth;
                    }
                    
                    // 确保年份不大于当前年份
                    const currentYear = new Date().getFullYear();
                    const currentMonth = new Date().getMonth() + 1;
                    if (year > currentYear || (year == currentYear && month > currentMonth)) {
                        year = currentYear;
                        month = currentMonth;
                    }
                    
                    // 使用AJAX更新日历内容
                    updateCalendarWidget(calendarWidget, year, month, buildDate);
                });
            });
            
            // 日期点击事件 - 显示详情
            document.querySelectorAll('.pix-calendar-day.has-post, .pix-calendar-day.has-moment, .pix-calendar-day.has-both').forEach(day => {
                day.addEventListener('click', function() {
                    const year = this.getAttribute('data-year');
                    const month = this.getAttribute('data-month');
                    const day = this.getAttribute('data-day');
                    
                    // 获取日期详情
                    getCalendarDayDetails(year, month, day);
                });
            });
        }
        
        // 更新日历小工具
        function updateCalendarWidget(calendarWidget, year, month, buildDate) {
            const formData = new FormData();
            formData.append('action', 'pix_calendar_widget_ajax');
            formData.append('year', year);
            formData.append('month', month);
            formData.append('build_date', buildDate);
            
            fetch('<?php echo admin_url("admin-ajax.php"); ?>', {
                method: 'POST',
                body: formData,
                credentials: 'same-origin'
            })
            .then(response => response.text())
            .then(html => {
                // 更新日历内容
                calendarWidget.querySelector('.pix-calendar-days').innerHTML = html;
                
                // 更新标题
                const monthNames = ['一月', '二月', '三月', '四月', '五月', '六月', '七月', '八月', '九月', '十月', '十一月', '十二月'];
                calendarWidget.querySelector('.pix-calendar-title').textContent = monthNames[month - 1] + ' ' + year;
                
                // 更新导航按钮状态
                updateCalendarNavButtons(calendarWidget, year, month, buildDate);
                
                // 重新绑定日期点击事件
                initCalendarWidgets();
            })
            .catch(error => {
                console.error('Error updating calendar:', error);
            });
        }
        
        // 获取日期详情
        function getCalendarDayDetails(year, month, day) {
            const formData = new FormData();
            formData.append('action', 'pix_calendar_day_details');
            formData.append('year', year);
            formData.append('month', month);
            formData.append('day', day);
            
            fetch('<?php echo admin_url("admin-ajax.php"); ?>', {
                method: 'POST',
                body: formData,
                credentials: 'same-origin'
            })
            .then(response => response.json())
            .then(data => {
                if (data.success) {
                    showCalendarDayModal(data.date, data.posts, data.moments);
                } else {
                    console.error('Error fetching day details:', data.message);
                }
            })
            .catch(error => {
                console.error('Error fetching day details:', error);
            });
        }
        
        // 显示日期详情弹窗
        function showCalendarDayModal(date, posts, moments) {
            const modal = document.getElementById('pix-calendar-detail-modal');
            const title = document.getElementById('pix-calendar-detail-title');
            const content = document.getElementById('pix-calendar-detail-content');
            
            // 设置标题
            title.textContent = date;
            
            // 清空内容
            content.innerHTML = '';
            
            // 添加文章
            if (posts.length > 0) {
                posts.forEach(post => {
                    const item = document.createElement('div');
                    item.className = 'pix-calendar-detail-item';
                    
                    let thumbnail = '';
                    if (post.thumbnail) {
                        thumbnail = `<div class="pix-calendar-detail-thumbnail">
                            <img src="${post.thumbnail}" alt="${post.title}">
                        </div>`;
                    }
                    
                    item.innerHTML = `
                        ${thumbnail}
                        <div class="pix-calendar-detail-content">
                            <h3 class="pix-calendar-detail-title">
                                <a href="${post.link}" target="_blank">${post.title}</a>
                            </h3>
                            <div class="pix-calendar-detail-excerpt">${post.excerpt}</div>
                            <div class="pix-calendar-detail-meta">
                                ${post.date} · ${post.comments} 评论 · ${post.views} 浏览
                            </div>
                        </div>
                    `;
                    
                    content.appendChild(item);
                });
            }
            
            // 添加片刻
            if (moments.length > 0) {
                moments.forEach(moment => {
                    const item = document.createElement('div');
                    item.className = 'pix-calendar-detail-item';
                    
                    let thumbnail = '';
                    if (moment.thumbnail) {
                        thumbnail = `<div class="pix-calendar-detail-thumbnail">
                            <img src="${moment.thumbnail}" alt="${moment.title}">
                        </div>`;
                    }
                    
                    item.innerHTML = `
                        ${thumbnail}
                        <div class="pix-calendar-detail-content">
                            <h3 class="pix-calendar-detail-title">
                                <a href="${moment.link}" target="_blank">${moment.title}</a>
                            </h3>
                            <div class="pix-calendar-detail-excerpt">${moment.excerpt}</div>
                            <div class="pix-calendar-detail-meta">
                                ${moment.date} · ${moment.comments} 评论 · ${moment.views} 浏览
                            </div>
                        </div>
                    `;
                    
                    content.appendChild(item);
                });
            }
            
            // 如果没有内容
            if (posts.length === 0 && moments.length === 0) {
                content.innerHTML = '<p>这一天没有发布内容</p>';
            }
            
            // 显示弹窗
            if (typeof UIkit !== 'undefined') {
                UIkit.modal(modal).show();
            } else {
                modal.style.display = 'block';
            }
        }
        
        // 更新日历导航按钮状态
        function updateCalendarNavButtons(calendarWidget, year, month, buildDate) {
            const siteYear = new Date(buildDate).getFullYear();
            const siteMonth = new Date(buildDate).getMonth() + 1;
            const currentYear = new Date().getFullYear();
            const currentMonth = new Date().getMonth() + 1;
            
            // 更新上一年按钮
            const prevYearBtn = calendarWidget.querySelector('.pix-calendar-prev-year');
            const prevYear = year - 1;
            prevYearBtn.setAttribute('data-year', prevYear);
            if (prevYear < siteYear || (prevYear == siteYear && month < siteMonth)) {
                prevYearBtn.setAttribute('disabled', 'disabled');
            } else {
                prevYearBtn.removeAttribute('disabled');
            }
            
            // 更新下一年按钮
            const nextYearBtn = calendarWidget.querySelector('.pix-calendar-next-year');
            const nextYear = year + 1;
            nextYearBtn.setAttribute('data-year', nextYear);
            if (nextYear > currentYear || (nextYear == currentYear && month > currentMonth)) {
                nextYearBtn.setAttribute('disabled', 'disabled');
            } else {
                nextYearBtn.removeAttribute('disabled');
            }
            
            // 更新上一月按钮
            const prevMonthBtn = calendarWidget.querySelector('.pix-calendar-prev-month');
            let prevMonth = month - 1;
            let prevMonthYear = year;
            if (prevMonth < 1) {
                prevMonth = 12;
                prevMonthYear--;
            }
            prevMonthBtn.setAttribute('data-year', prevMonthYear);
            prevMonthBtn.setAttribute('data-month', prevMonth);
            if (prevMonthYear < siteYear || (prevMonthYear == siteYear && prevMonth < siteMonth)) {
                prevMonthBtn.setAttribute('disabled', 'disabled');
            } else {
                prevMonthBtn.removeAttribute('disabled');
            }
            
            // 更新下一月按钮
            const nextMonthBtn = calendarWidget.querySelector('.pix-calendar-next-month');
            let nextMonth = month + 1;
            let nextMonthYear = year;
            if (nextMonth > 12) {
                nextMonth = 1;
                nextMonthYear++;
            }
            nextMonthBtn.setAttribute('data-year', nextMonthYear);
            nextMonthBtn.setAttribute('data-month', nextMonth);
            if (nextMonthYear > currentYear || (nextMonthYear == currentYear && nextMonth > currentMonth)) {
                nextMonthBtn.setAttribute('disabled', 'disabled');
            } else {
                nextMonthBtn.removeAttribute('disabled');
            }
        }
        
        // 初始化日历小工具
        initCalendarWidgets();
        
        // 为PJAX重新加载时初始化日历
        document.addEventListener('pjax:complete', function() {
            initCalendarWidgets();
        });

4、找到</script>在下面的<?php }后继续添加以下代码,一直到add_action('wp_footer', 'pix_widgets_styles');前结束:

// 日历小工具AJAX处理
add_action('wp_ajax_pix_calendar_widget_ajax', 'pix_calendar_widget_ajax');
add_action('wp_ajax_nopriv_pix_calendar_widget_ajax', 'pix_calendar_widget_ajax');

function pix_calendar_widget_ajax() {
    $year = isset($_POST['year']) ? intval($_POST['year']) : date('Y');
    $month = isset($_POST['month']) ? intval($_POST['month']) : date('n');
    $build_date = isset($_POST['build_date']) ? $_POST['build_date'] : '1992-10-12';
    
    // 获取当月天数
    $days_in_month = date('t', mktime(0, 0, 0, $month, 1, $year));
    
    // 获取当月第一天是星期几 (0=周日, 6=周六)
    $first_day_of_week = date('w', mktime(0, 0, 0, $month, 1, $year));
    
    // 获取当月所有文章和片刻的发布日期
    $posts = get_posts(array(
        'post_type' => 'post',
        'posts_per_page' => -1,
        'date_query' => array(
            array(
                'year' => $year,
                'month' => $month,
            ),
        ),
    ));
    
    $moments = get_posts(array(
        'post_type' => 'moment',
        'posts_per_page' => -1,
        'date_query' => array(
            array(
                'year' => $year,
                'month' => $month,
            ),
        ),
    ));
    
    // 创建日期统计数组
    $date_stats = array();
    
    // 统计文章
    foreach ($posts as $post) {
        $post_day = date('j', strtotime($post->post_date));
        if (!isset($date_stats[$post_day])) {
            $date_stats[$post_day] = array('posts' => array(), 'moments' => array());
        }
        $date_stats[$post_day]['posts'][] = $post;
    }
    
    // 统计片刻
    foreach ($moments as $moment) {
        $moment_day = date('j', strtotime($moment->post_date));
        if (!isset($date_stats[$moment_day])) {
            $date_stats[$moment_day] = array('posts' => array(), 'moments' => array());
        }
        $date_stats[$moment_day]['moments'][] = $moment;
    }
    
    // 输出日历主体部分
    $output = '';
    
    // 填充上个月的空白
    for ($i = 0; $i < $first_day_of_week; $i++) {
        $output .= '<div class="pix-calendar-day other-month"></div>';
    }
    
    // 填充当月的日期
    for ($day = 1; $day <= $days_in_month; $day++) {
        $day_class = 'pix-calendar-day';
        $tooltip = '';
        $has_content = false;
        
        if (isset($date_stats[$day])) {
            $stats = $date_stats[$day];
            $posts_count = count($stats['posts']);
            $moments_count = count($stats['moments']);
            
            if ($posts_count > 0 && $moments_count > 0) {
                $day_class .= ' has-both';
                $tooltip = '文章: '.$posts_count.' 篇, 片刻: '.$moments_count.' 条';
                $has_content = true;
            } elseif ($posts_count > 0) {
                $day_class .= ' has-post';
                $tooltip = '文章: '.$posts_count.' 篇';
                $has_content = true;
            } elseif ($moments_count > 0) {
                $day_class .= ' has-moment';
                $tooltip = '片刻: '.$moments_count.' 条';
                $has_content = true;
            }
        }
        
        // 如果是今天,添加特殊类
        if ($year == date('Y') && $month == date('n') && $day == date('j')) {
            $day_class .= ' today';
        }
        
        $output .= '<div class="'.$day_class.'"';
        if ($tooltip) {
            $output .= ' uk-tooltip="title: '.$tooltip.'"';
        }
        if ($has_content) {
            $output .= ' data-year="'.$year.'" data-month="'.$month.'" data-day="'.$day.'"';
        }
        $output .= '>'.$day.'</div>';
    }
    
    // 计算需要填充的下个月的空白
    $days_shown = $first_day_of_week + $days_in_month;
    $weeks_shown = ceil($days_shown / 7);
    $days_to_fill = $weeks_shown * 7 - $days_shown;
    
    for ($i = 0; $i < $days_to_fill; $i++) {
        $output .= '<div class="pix-calendar-day other-month"></div>';
    }
    
    echo $output;
    wp_die();
}

// 日期详情AJAX处理
add_action('wp_ajax_pix_calendar_day_details', 'pix_calendar_day_details');
add_action('wp_ajax_nopriv_pix_calendar_day_details', 'pix_calendar_day_details');

function pix_calendar_day_details() {
    $year = isset($_POST['year']) ? intval($_POST['year']) : date('Y');
    $month = isset($_POST['month']) ? intval($_POST['month']) : date('n');
    $day = isset($_POST['day']) ? intval($_POST['day']) : date('j');
    
    // 获取指定日期的文章
    $posts = get_posts(array(
        'post_type' => 'post',
        'posts_per_page' => -1,
        'date_query' => array(
            array(
                'year' => $year,
                'month' => $month,
                'day' => $day,
            ),
        ),
    ));
    
    // 获取指定日期的片刻
    $moments = get_posts(array(
        'post_type' => 'moment',
        'posts_per_page' => -1,
        'date_query' => array(
            array(
                'year' => $year,
                'month' => $month,
                'day' => $day,
            ),
        ),
    ));
    
    // 处理文章数据
    $processed_posts = array();
    foreach ($posts as $post) {
        setup_postdata($post);
        
        // 获取缩略图
        $thumbnail = '';
        if (has_post_thumbnail($post->ID)) {
            $thumbnail = get_the_post_thumbnail_url($post->ID, 'thumbnail');
        }
        
        // 获取浏览数
        $views = get_post_meta($post->ID, 'views', true) ?: 0;
        
        $processed_posts[] = array(
            'title' => get_the_title($post),
            'link' => get_permalink($post),
            'excerpt' => wp_trim_words(get_the_excerpt($post), 20),
            'date' => get_the_date('', $post),
            'comments' => get_comments_number($post->ID),
            'views' => $views,
            'thumbnail' => $thumbnail
        );
    }
    wp_reset_postdata();
    
    // 处理片刻数据
    $processed_moments = array();
    foreach ($moments as $moment) {
        setup_postdata($moment);
        
        // 获取缩略图
        $thumbnail = '';
        $moment_ga = get_post_meta($moment->ID, 'moment_ga', true);
        if (!empty($moment_ga) && isset($moment_ga[0]['src'])) {
            $thumbnail = $moment_ga[0]['src'];
        } elseif (has_post_thumbnail($moment->ID)) {
            $thumbnail = get_the_post_thumbnail_url($moment->ID, 'thumbnail');
        }
        
        // 获取浏览数
        $views = get_post_meta($moment->ID, 'views', true) ?: 0;
        
        $processed_moments[] = array(
            'title' => get_the_title($moment),
            'link' => get_permalink($moment),
            'excerpt' => wp_trim_words(get_the_excerpt($moment), 20),
            'date' => get_the_date('', $moment),
            'comments' => get_comments_number($moment->ID),
            'views' => $views,
            'thumbnail' => $thumbnail
        );
    }
    wp_reset_postdata();
    
    // 格式化日期
    $date = sprintf('%d年%d月%d日', $year, $month, $day);
    
    wp_send_json(array(
        'success' => true,
        'date' => $date,
        'posts' => $processed_posts,
        'moments' => $processed_moments
    ));
}
Comments | 6 条评论
  • D.K

    Firefox 141 Firefox 141 Windows 10 Windows 10 cn中国–广东–惠州 电信 ip address 113.83.*.*

    还不够完整,要有农历、节气、节假日和放假安排的日历小工具才完整😁

    • 似水流年

      IBrowse r IBrowse r Android 12 Android 12 cn中国–河南–漯河 电信 ip address 222.89.*.*

      那就太专业了,可以直接安装插件了。😹

  • 刘郎

    Google Chrome 127 Google Chrome 127 GNU/Linux GNU/Linux cn中国 中国联通 ip address 2408:826a:9867:8ab1:*:*

    可惜不适用我的主题😂

    • 似水流年

      IBrowse r IBrowse r Android 12 Android 12 cn中国–河南–漯河 电信 ip address 222.89.*.*

      让AI分析这几个代码,然后把你的侧边栏小工具文件分析下函数和变量,就说按照侧边栏小工具文件,把这几段代码修改成适配代码。

      • 奶爸

        Google Chrome 136 Google Chrome 136 Windows 10 Windows 10 cn中国–上海–上海 电信/电信CN2 ip address 58.32.*.*

        很不错啊!

        • 似水流年

          Google Chrome 127 Google Chrome 127 GNU/Linux GNU/Linux cn中国 中国联通 ip address 2408:8220:5f12:91a0:*:*

          没事鼓捣一下。😀

消息盒子
# 您需要首次评论以获取消息 #
# 您需要首次评论以获取消息 #

只显示最新10条未读和已读信息