<?php
/**
* Plugin Name: Xd News List 二次元美化完整版
* Plugin URI:
* Description: WordPress资源列表插件,二次元动漫风后台、分栏卡片布局不拥挤、自定义HTML/CSS模板、支持文章/子比社区帖子、自定义模板变量、广告管理
* Version: 2.06
* Author: Dev
* License: GPL2
*/
if (!defined('ABSPATH')) exit;
// ===================== 全局默认配置 =====================
$default_base_options = [
'active_template' => 'template1',
'media_type' => 'image',
'banner_img' => 'https://g.gtimg.cn/music/photo_new/T057XD001003CoPL62IyR9q.png',
'banner_video' => '',
'banner_url' => '',
'show_privilege' => '1',
'posts_per_page' => 38,
'cat_ids' => '',
'exclude_pids' => '',
'only_sticky' => '0',
'stat_hours' => 24,
'data_source' => 'post',
'forum_ids' => '',
'forum_status' => 'publish',
'forum_exclude' => '',
'site_tip_text' => '本站资源仅供学习,禁止商用',
'copyright_text' => '©2026 二次元资源站 版权所有'
];
$default_link_options = [
'link1_text' => '商务合作',
'link1_url' => '',
'link2_text' => '二次元交流群',
'link2_url' => '',
'link3_text' => '资源求稿通道',
'link3_url' => ''
];
$default_ad_options = [
'ad_switch' => '1',
'ad_mode' => 'top',
'ad_interval' => 3
];
$default_ad_list = [];
// ===================== 内置系统模板 =====================
function xd_news_get_system_templates(){
return [
'template1' => [
'name' => '模板1:原版小刀左右分栏',
'css' => '',
'html' => '
<div class="xd-news-wrap template1">
<div class="index-news">
<div class="index-news-tool left">
{{banner_html}}
<div class="index-news-tool-container">
{{link_bar}}
{{privilege_html}}
</div>
</div>
<div class="index-news-article right">
<div class="title">最近更新<font>+{{today_count}}</font></div>
<div class="news-article_container" id="newslist">
{{item_list}}
</div>
{{pagination}}
</div>
</div>
</div>
'
],
'template2' => [
'name' => '模板2:简约单列表',
'css' => '
.template2 {
padding: 12px;
border: 1px solid #eee;
border-radius: 8px;
background: #fff;
}
.template2 .title {
font-size: 16px;
font-weight: bold;
margin-bottom: 12px;
padding-bottom: 8px;
border-bottom: 1px solid #eee;
}
.template2 .page {
margin-top: 15px;
display: flex;
gap: 10px;
justify-content: center;
}
.template2 .page div {
padding: 5px 16px;
border: 1px solid #ddd;
border-radius: 4px;
cursor: pointer;
}
.template2 ul.page-item {
list-style: none;
padding: 0;
margin: 0;
}
.template2 .item-post {
padding: 8px 10px;
margin: 4px 0;
border-bottom: 1px solid #f5f5f5;
display: flex;
justify-content: space-between;
align-items: center;
}
.template2 .item-ad {
padding: 8px 10px;
margin: 6px 0;
background: #f8f8f8;
border-radius: 6px;
}
.template2 .link-footer {
margin-top: 16px;
padding-top: 10px;
border-top: 1px solid #eee;
font-size: 13px;
}
',
'html' => '
<div class="xd-news-wrap template2">
<div class="title">最近更新 <span style="color:#f30;">+{{today_count}}</span></div>
<div class="news-article_container" id="newslist">
{{item_list}}
</div>
{{pagination}}
<div class="link-footer">{{link_bar}}</div>
</div>
'
]
];
}
// ===================== 配置读取函数 =====================
function xd_news_get_all_templates(){
$system = xd_news_get_system_templates();
$user_tpl = get_option('xd_news_user_templates', []);
return array_merge($system, $user_tpl);
}
function xd_get_base_options(){
global $default_base_options;
$opts = get_option('xd_news_base_options');
return is_array($opts) ? array_merge($default_base_options, $opts) : $default_base_options;
}
function xd_get_link_options(){
global $default_link_options;
$opts = get_option('xd_news_link_options');
return is_array($opts) ? array_merge($default_link_options, $opts) : $default_link_options;
}
function xd_get_ad_options(){
global $default_ad_options;
$opts = get_option('xd_news_ad_options');
return is_array($opts) ? array_merge($default_ad_options, $opts) : $default_ad_options;
}
function xd_get_ad_list(){
global $default_ad_list;
$ads = get_option('xd_news_ad_list');
return is_array($ads) ? $ads : $default_ad_list;
}
// ===================== 注册配置项 =====================
function xd_news_register_setting(){
global $default_base_options, $default_link_options, $default_ad_options, $default_ad_list;
register_setting('xd_base_group', 'xd_news_base_options', [
'sanitize_callback' => 'xd_news_sanitize_base',
'default' => $default_base_options
]);
register_setting('xd_link_group', 'xd_news_link_options', [
'sanitize_callback' => 'xd_news_sanitize_link',
'default' => $default_link_options
]);
register_setting('xd_ad_set_group', 'xd_news_ad_options', [
'sanitize_callback' => 'xd_news_sanitize_ad_set',
'default' => $default_ad_options
]);
register_setting('xd_news_ad_group', 'xd_news_ad_list', [
'sanitize_callback' => 'xd_news_sanitize_ad_list',
'default' => $default_ad_list
]);
register_setting('xd_tpl_group', 'xd_news_user_templates');
}
add_action('admin_init', 'xd_news_register_setting');
// ===================== 数据清洗过滤 =====================
function xd_news_sanitize_base($input){
global $default_base_options;
$out = [];
$tpl_list = array_keys(xd_news_get_all_templates());
$out['active_template'] = in_array($input['active_template'], $tpl_list) ? $input['active_template'] : 'template1';
$out['media_type'] = $input['media_type'] === 'video' ? 'video' : 'image';
$out['banner_img'] = esc_url_raw($input['banner_img']);
$out['banner_video'] = esc_url_raw($input['banner_video']);
$out['banner_url'] = esc_url_raw($input['banner_url']);
$out['show_privilege'] = $input['show_privilege'] === '1' ? '1' : '0';
$out['posts_per_page'] = max(1, absint($input['posts_per_page']));
$out['cat_ids'] = sanitize_text_field($input['cat_ids']);
$out['exclude_pids'] = sanitize_text_field($input['exclude_pids']);
$out['only_sticky'] = $input['only_sticky'] === '1' ? '1' : '0';
$out['stat_hours'] = max(1, absint($input['stat_hours']));
$out['data_source'] = $input['data_source'] === 'forum' ? 'forum' : 'post';
$out['forum_ids'] = sanitize_text_field($input['forum_ids']);
$out['forum_status'] = sanitize_text_field($input['forum_status']);
$out['forum_exclude'] = sanitize_text_field($input['forum_exclude']);
$out['site_tip_text'] = sanitize_text_field($input['site_tip_text']);
$out['copyright_text'] = sanitize_text_field($input['copyright_text']);
return $out;
}
function xd_news_sanitize_link($input){
global $default_link_options;
$out = [];
$out['link1_text'] = sanitize_text_field($input['link1_text']);
$out['link1_url'] = esc_url_raw($input['link1_url']);
$out['link2_text'] = sanitize_text_field($input['link2_text']);
$out['link2_url'] = esc_url_raw($input['link2_url']);
$out['link3_text'] = sanitize_text_field($input['link3_text']);
$out['link3_url'] = esc_url_raw($input['link3_url']);
return $out;
}
function xd_news_sanitize_ad_set($input){
global $default_ad_options;
$out = [];
$out['ad_switch'] = $input['ad_switch'] === '1' ? '1' : '0';
$out['ad_mode'] = $input['ad_mode'] === 'split' ? 'split' : 'top';
$out['ad_interval'] = max(1, absint($input['ad_interval']));
return $out;
}
function xd_news_sanitize_ad_list($input){
if (!is_array($input)) return [];
$clean = [];
foreach ($input as $ad) {
if (empty($ad['text'])) continue;
$clean[] = [
'link' => esc_url_raw($ad['link']),
'text' => sanitize_text_field($ad['text']),
'color' => sanitize_hex_color($ad['color']) ?: '#32cd99'
];
}
return $clean;
}
// ===================== 后台菜单与资源 =====================
function xd_news_add_menu(){
add_options_page(
'Xd‑News 二次元配置面板',
'Xd‑二次元列表配置',
'manage_options',
'xd‑news‑config',
'xd_news_admin_page'
);
}
add_action('admin_menu', 'xd_news_add_menu');
function xd_enqueue_admin_media(){
wp_enqueue_media();
}
add_action('admin_enqueue_scripts', 'xd_enqueue_admin_media');
// ===================== 二次元美化后台页面完整代码 =====================
function xd_news_admin_page(){
$base_opts = xd_get_base_options();
$link_opts = xd_get_link_options();
$ad_set = xd_get_ad_options();
$ad_list = xd_get_ad_list();
$has_forum = post_type_exists('forum_post');
$all_tpl = xd_news_get_all_templates();
$system_tpl = xd_news_get_system_templates();
$user_tpl = get_option('xd_news_user_templates', []);
// 保存自定义模板
if(isset($_POST['save_custom_tpl']) && wp_verify_nonce($_POST['xd_tpl_nonce'], 'xd_tpl_action')){
$tpl_id = sanitize_text_field($_POST['tpl_id']);
$tpl_name = sanitize_text_field($_POST['tpl_name']);
$tpl_css = stripslashes($_POST['tpl_css']);
$tpl_html = stripslashes($_POST['tpl_html']);
$user_tpl[$tpl_id] = ['name' => $tpl_name, 'css' => $tpl_css, 'html' => $tpl_html];
update_option('xd_news_user_templates', $user_tpl);
echo '<div class="notice notice-success anime-notice-success"><p>🌸 自定义模板保存成功!</p></div>';
}
// 删除模板
if(isset($_GET['del_tpl'])){
$del_id = sanitize_text_field($_GET['del_tpl']);
if(!isset($system_tpl[$del_id]) && isset($user_tpl[$del_id])){
unset($user_tpl[$del_id]);
update_option('xd_news_user_templates', $user_tpl);
echo '<div class="notice notice-success anime-notice-success"><p>🌸 模板已删除</p></div>';
}
}
$edit_id = isset($_GET['edit_tpl']) ? sanitize_text_field($_GET['edit_tpl']) : '';
$edit_data = $edit_id && isset($all_tpl[$edit_id]) ? $all_tpl[$edit_id] : ['name'=>'','css'=>'','html'=>''];
?>
<style>
.wrap {background: linear-gradient(135deg, #fff5fb 0%, #f0f8ff 100%);padding:20px;border-radius:16px;}
.wrap h2 {color:#9340b7;font-size:26px;font-weight:bold;text-shadow:0 0 6px #ffc0e8;display:flex;align-items:center;gap:10px;}
.wrap h2::before {content:"🌸";font-size:30px;}
.anime-notice-success {border-left:5px solid #ff88bb;background:#fff0f8;border-radius:10px;box-shadow:0 2px 12px #ffd8ec;}
.notice-warning {border-left:5px solid #9168d8;background:#f8f0ff;border-radius:10px;box-shadow:0 2px 12px #e8d8ff;}
.xd-tab-nav {display:flex;gap:8px;margin:20px 0;border-bottom:none;flex-wrap:wrap;}
.xd-tab-btn {padding:10px 22px;border:none;border-radius:999px;background:linear-gradient(135deg,#e8c8ff,#ffd8ef);color:#622080;font-weight:500;cursor:pointer;transition:all 0.3s ease;box-shadow:0 2px 8px #e0c0f0;}
.xd-tab-btn.active {background:linear-gradient(135deg,#b878e8,#ff88bb);color:#fff;box-shadow:0 3px 14px #d090e8;transform:translateY(-2px);}
.xd-tab-btn:hover {transform:translateY(-2px);}
.xd-tab-content {display:none;}
.anime-card {background:#fff;border-radius:18px;padding:24px;margin-bottom:24px;box-shadow:0 4px 18px rgba(180,120,230,0.12);border:1px solid #f0e0ff;}
.anime-card-title {font-size:18px;font-weight:bold;color:#9340b7;margin:0 0 18px 0;padding-bottom:10px;border-bottom:2px dashed #e8ccff;display:flex;align-items:center;gap:8px;}
.anime-card-title::before {content:"✨";}
.form-table {margin:0;}
.form-table th {width:240px;color:#703090;font-weight:500;padding:14px 10px;}
.form-table td {padding:14px 10px;}
.regular-text,input[type="url"],input[type="number"] {border:1px solid #e0c8f0;border-radius:12px;padding:10px 14px;width:100%;max-width:600px;background:#fcfaff;transition:0.2s;}
.regular-text:focus,input[type="url"]:focus,input[type="number"]:focus {outline:none;border-color:#b878e8;box-shadow:0 0 0 3px rgba(184,120,232,0.18);}
textarea {border:1px solid #e0c8f0;border-radius:12px;padding:12px 16px;background:#fcfaff;width:100%;}
.tpl-code-box {background:#2a2438 !important;color:#e8e0ff !important;font-family:Consolas,monospace;}
select {border:1px solid #e0c8f0;border-radius:12px;padding:10px 14px;background:#fcfaff;min-width:320px;}
.button,.button-primary {border-radius:999px !important;padding:8px 20px !important;border:none !important;box-shadow:0 2px 10px rgba(184,120,232,0.2);}
.button-primary {background:linear-gradient(135deg,#b878e8,#ff88bb) !important;color:#fff !important;}
.button {background:#f0e8ff !important;color:#703090 !important;}
.tpl-wrap {display:grid;grid-template-columns:300px 1fr;gap:24px;}
.tpl-list-box {background:#fcfaff;border-radius:16px;padding:18px;border:1px dashed #e0c8f0;}
.tpl-list-box h4 {color:#9340b7;margin-top:0;}
.tpl-list-box li {padding:6px 0;}
.tpl-list-box a {color:#b858c8;}
.tpl-list-box a[href*="del_tpl"] {color:#e05088;}
.ad-item {background:#fcfaff;border-radius:14px;padding:16px;margin:12px 0;border:1px dashed #f0d8f8;}
.description {color:#9060b0;font-size:13px;margin-top:6px;}
@media (max-width:1200px){.tpl-wrap {grid-template-columns:1fr;}}
</style>
<div class="wrap">
<h2>Xd二次元资源列表|可视化模板配置面板</h2>
<?php if ($base_opts['data_source'] === 'forum' && !$has_forum): ?>
<div class="notice notice-warning"><p>⚠️ 未检测到子比社区 forum_post 帖子类型,请开启社区圈子功能,否则前台无板块数据。</p></div>
<?php endif; ?>
<div class="xd-tab-nav">
<button class="xd-tab-btn active" data-tab="tab-base">基础全局设置</button>
<button class="xd-tab-btn" data-tab="tab-tpl">🎨 自定义模板管理</button>
<button class="xd-tab-btn" data-tab="tab-link">底部链接配置</button>
<button class="xd-tab-btn" data-tab="tab-ad">广告系统管理</button>
</div>
<!-- 基础设置标签页 -->
<div class="xd-tab-content" id="tab-base">
<form method="post" action="options.php">
<?php settings_fields('xd_base_group'); ?>
<div class="anime-card">
<h3 class="anime-card-title">启用模板选择</h3>
<table class="form-table">
<tr>
<th>当前前端展示模板</th>
<td>
<select name="xd_news_base_options[active_template]">
<?php foreach ($all_tpl as $tid => $tpl): ?>
<option value="<?php echo esc_attr($tid); ?>" <?php selected($base_opts['active_template'], $tid); ?>>
<?php echo esc_html($tpl['name']); ?>
</option>
<?php endforeach; ?>
</select>
<p class="description">新增/修改模板请切换到「自定义模板管理」标签页。</p>
</td>
</tr>
</table>
</div>
<div class="anime-card">
<h3 class="anime-card-title">内容数据源设置</h3>
<table class="form-table">
<tr>
<th>读取内容来源</th>
<td>
<label><input type="radio" name="xd_news_base_options[data_source]" value="post" <?php checked($base_opts['data_source'], 'post'); ?>> WordPress普通文章</label>
<label><input type="radio" name="xd_news_base_options[data_source]" value="forum" <?php checked($base_opts['data_source'], 'forum'); ?>> 子比社区帖子 forum_post</label>
</td>
</tr>
</table>
</div>
<div class="anime-card">
<h3 class="anime-card-title">轮播图 & 特权模块</h3>
<table class="form-table">
<tr>
<th>轮播媒体类型</th>
<td>
<label><input type="radio" name="xd_news_base_options[media_type]" value="image" <?php checked($base_opts['media_type'], 'image'); ?>> 图片轮播</label>
<label><input type="radio" name="xd_news_base_options[media_type]" value="video" <?php checked($base_opts['media_type'], 'video'); ?>> MP4视频轮播</label>
</td>
</tr>
<tr class="row-image">
<th>轮播图地址</th>
<td>
<input type="text" id="banner_img" name="xd_news_base_options[banner_img]" value="<?php echo esc_attr($base_opts['banner_img']); ?>" class="regular-text">
<input type="button" class="button xd-upload-img" value="选择图片">
<p><img id="preview_img" src="<?php echo esc_attr($base_opts['banner_img']); ?>" style="max-width:300px;margin-top:10px;border-radius:12px;"></p>
</td>
</tr>
<tr class="row-video" style="display:none;">
<th>轮播视频地址</th>
<td>
<input type="text" id="banner_video" name="xd_news_base_options[banner_video]" value="<?php echo esc_attr($base_opts['banner_video']); ?>" class="regular-text">
<input type="button" class="button xd-upload-video" value="上传视频">
<?php if (!empty($base_opts['banner_video'])): ?>
<p style="margin-top:10px;"><video style="max-width:300px;border-radius:12px;" controls src="<?php echo esc_attr($base_opts['banner_video']); ?>"></video></p>
<?php endif; ?>
</td>
</tr>
<tr>
<th>轮播跳转链接</th>
<td><input type="url" name="xd_news_base_options[banner_url]" value="<?php echo esc_attr($base_opts['banner_url']); ?>" class="regular-text"></td>
</tr>
<tr>
<th>右侧特权模块开关</th>
<td>
<label><input type="radio" name="xd_news_base_options[show_privilege]" value="1" <?php checked($base_opts['show_privilege'], '1'); ?>> 开启</label>
<label><input type="radio" name="xd_news_base_options[show_privilege]" value="0" <?php checked($base_opts['show_privilege'], '0'); ?>> 关闭</label>
</td>
</tr>
</table>
</div>
<div class="anime-card">
<h3 class="anime-card-title">内容筛选过滤</h3>
<table class="form-table">
<tr><th colspan="2" style="color:#b858c8;font-weight:bold;">WordPress文章筛选</th></tr>
<tr><th>读取分类ID(逗号分隔)</th><td><input type="text" name="xd_news_base_options[cat_ids]" value="<?php echo esc_attr($base_opts['cat_ids']); ?>" class="regular-text" placeholder="1,2,10"></td></tr>
<tr><th>排除文章ID</th><td><input type="text" name="xd_news_base_options[exclude_pids]" value="<?php echo esc_attr($base_opts['exclude_pids']); ?>" class="regular-text" placeholder="5,12"></td></tr>
<tr>
<th>仅展示置顶文章</th>
<td>
<label><input type="radio" name="xd_news_base_options[only_sticky]" value="1" <?php checked($base_opts['only_sticky'], '1'); ?>> 开启</label>
<label><input type="radio" name="xd_news_base_options[only_sticky]" value="0" <?php checked($base_opts['only_sticky'], '0'); ?>> 关闭</label>
</td>
</tr>
<tr><th colspan="2" style="color:#b858c8;font-weight:bold;margin-top:10px;">子比社区帖子筛选 plate_id</th></tr>
<tr><th>指定板块 plate_id</th><td><input type="text" name="xd_news_base_options[forum_ids]" value="<?php echo esc_attr($base_opts['forum_ids']); ?>" class="regular-text" placeholder="3,7,9"></td></tr>
<tr>
<th>帖子读取状态</th>
<td>
<select name="xd_news_base_options[forum_status]">
<option value="publish" <?php selected($base_opts['forum_status'], 'publish'); ?>>正常发布帖子</option>
<option value="pending" <?php selected($base_opts['forum_status'], 'pending'); ?>>待审核帖子</option>
<option value="trash" <?php selected($base_opts['forum_status'], 'trash'); ?>>回收站</option>
</select>
</td>
</tr>
<tr><th>排除帖子ID</th><td><input type="text" name="xd_news_base_options[forum_exclude]" value="<?php echo esc_attr($base_opts['forum_exclude']); ?>" class="regular-text" placeholder="18,22"></td></tr>
</table>
</div>
<div class="anime-card">
<h3 class="anime-card-title">分页、统计与自定义变量</h3>
<table class="form-table">
<tr><th>统计更新小时数</th><td><input type="number" min="1" name="xd_news_base_options[stat_hours]" value="<?php echo esc_attr($base_opts['stat_hours']); ?>"> 小时内更新内容标记为红色日期</td></tr>
<tr><th>单页展示条数(广告+内容)</th><td><input type="number" min="1" name="xd_news_base_options[posts_per_page]" value="<?php echo esc_attr($base_opts['posts_per_page']); ?>"> 超出自动分到下一页</td></tr>
<tr><th colspan="2" style="color:#b858c8;font-weight:bold;margin-top:10px;">模板自定义变量</th></tr>
<tr><th>站点提示文字 {{site_tip}}</th><td><input type="text" name="xd_news_base_options[site_tip_text]" value="<?php echo esc_attr($base_opts['site_tip_text']); ?>" class="regular-text"></td></tr>
<tr><th>底部版权文字 {{copyright}}</th><td><input type="text" name="xd_news_base_options[copyright_text]" value="<?php echo esc_attr($base_opts['copyright_text']); ?>" class="regular-text"></td></tr>
</table>
</div>
<?php submit_button('🌸 保存全部基础设置'); ?>
</form>
</div>
<!-- 模板管理标签页 -->
<div class="xd-tab-content" id="tab-tpl" style="display:none;">
<div class="anime-card">
<h3 class="anime-card-title">自定义模板编辑器|粘贴HTML+CSS即可生成新样式</h3>
<div class="tpl-wrap">
<div class="tpl-list-box">
<h4>全部模板列表</h4>
<ul style="padding-left:15px;">
<?php foreach ($all_tpl as $tid => $tpl): ?>
<li>
<?php echo esc_html($tpl['name']); ?>
<a href="?page=xd-news-config&edit_tpl=<?php echo esc_attr($tid); ?>">编辑</a>
<?php if (!isset($system_tpl[$tid])): ?>
<a href="?page=xd-news-config&del_tpl=<?php echo esc_attr($tid); ?>" onclick="return confirm('确定删除该自定义模板?')">删除</a>
<?php endif; ?>
</li>
<?php endforeach; ?>
</ul>
<hr style="border-color:#e0d8f8;">
<a href="?page=xd-news-config&edit_tpl=new" class="button button-primary" style="margin-top:10px;">➕ 新增自定义模板</a>
</div>
<div>
<?php $form_tid = $edit_id ?: uniqid('user_tpl_'); ?>
<form method="post">
<?php wp_nonce_field('xd_tpl_action', 'xd_tpl_nonce'); ?>
<input type="hidden" name="save_custom_tpl" value="1">
<input type="hidden" name="tpl_id" value="<?php echo esc_attr($form_tid); ?>">
<table class="form-table">
<tr><th>模板展示名称</th><td><input type="text" name="tpl_name" value="<?php echo esc_attr($edit_data['name']); ?>" class="regular-text" required placeholder="例如:二次元卡片资源模板"></td></tr>
<tr>
<th>独立自定义CSS样式</th>
<td>
<textarea name="tpl_css" rows="8" class="tpl-code-box"><?php echo esc_textarea($edit_data['css']); ?></textarea>
<p class="description">仅作用于当前模板,无需添加 <style> 标签。</p>
</td>
</tr>
<tr>
<th>HTML结构代码(支持变量)</th>
<td>
<textarea name="tpl_html" rows="14" class="tpl-code-box" required><?php echo esc_textarea($edit_data['html']); ?></textarea>
<p class="description">可用变量:{{today_count}} {{banner_html}} {{privilege_html}} {{link_bar}} {{item_list}} {{pagination}} {{site_tip}} {{copyright}}</p>
</td>
</tr>
</table>
<?php submit_button('💜 保存模板代码'); ?>
</form>
</div>
</div>
</div>
</div>
<!-- 底部链接标签页 -->
<div class="xd-tab-content" id="tab-link" style="display:none;">
<div class="anime-card">
<h3 class="anime-card-title">底部文字链接配置</h3>
<form method="post" action="options.php">
<?php settings_fields('xd_link_group'); ?>
<table class="form-table">
<tr><th>链接1显示文字</th><td><input type="text" name="xd_news_link_options[link1_text]" value="<?php echo esc_attr($link_opts['link1_text']); ?>" class="regular-text"></td></tr>
<tr><th>链接1跳转地址(可留空)</th><td><input type="text" name="xd_news_link_options[link1_url]" value="<?php echo esc_attr($link_opts['link1_url']); ?>" class="regular-text"></td></tr>
<tr><th>链接2显示文字</th><td><input type="text" name="xd_news_link_options[link2_text]" value="<?php echo esc_attr($link_opts['link2_text']); ?>" class="regular-text"></td></tr>
<tr><th>链接2跳转地址(可留空)</th><td><input type="text" name="xd_news_link_options[link2_url]" value="<?php echo esc_attr($link_opts['link2_url']); ?>" class="regular-text"></td></tr>
<tr><th>链接3显示文字</th><td><input type="text" name="xd_news_link_options[link3_text]" value="<?php echo esc_attr($link_opts['link3_text']); ?>" class="regular-text"></td></tr>
<tr><th>链接3跳转地址(可留空)</th><td><input type="text" name="xd_news_link_options[link3_url]" value="<?php echo esc_attr($link_opts['link3_url']); ?>" class="regular-text"></td></tr>
</table>
<?php submit_button('🌸 保存链接设置'); ?>
</form>
</div>
</div>
<!-- 广告管理标签页 -->
<div class="xd-tab-content" id="tab-ad" style="display:none;">
<div class="anime-card">
<h3 class="anime-card-title">广告全局控制</h3>
<form method="post" action="options.php">
<?php settings_fields('xd_ad_set_group'); ?>
<table class="form-table">
<tr>
<th>广告总开关</th>
<td>
<label><input type="radio" name="xd_news_ad_options[ad_switch]" value="1" <?php checked($ad_set['ad_switch'], '1'); ?>> 开启广告展示</label>
<label><input type="radio" name="xd_news_ad_options[ad_switch]" value="0" <?php checked($ad_set['ad_switch'], '0'); ?>> 完全关闭广告</label>
</td>
</tr>
<tr>
<th>广告展示模式</th>
<td>
<label><input type="radio" name="xd_news_ad_options[ad_mode]" value="top" <?php checked($ad_set['ad_mode'], 'top'); ?>> 全部置顶顶部</label>
<label><input type="radio" name="xd_news_ad_options[ad_mode]" value="split" <?php checked($ad_set['ad_mode'], 'split'); ?>> 间隔穿插内容中间</label>
</td>
</tr>
<tr><th>每多少条内容插入广告</th><td><input type="number" min="1" name="xd_news_ad_options[ad_interval]" value="<?php echo esc_attr($ad_set['ad_interval']); ?>"></td></tr>
</table>
<?php submit_button('🌸 保存广告全局设置'); ?>
</form>
</div>
<div class="anime-card">
<h3 class="anime-card-title">自定义广告条目</h3>
<form method="post" action="options.php" id="ad-form">
<?php settings_fields('xd_news_ad_group'); ?>
<table class="form-table" id="ad-table">
<?php if (!empty($ad_list)): foreach ($ad_list as $idx => $ad): ?>
<tr class="ad-item">
<th>广告 #<?php echo $idx + 1; ?></th>
<td>
<div style="margin:8px 0;">
<label>跳转链接(可空):</label>
<input type="url" name="xd_news_ad_list[<?php echo $idx; ?>][link]" value="<?php echo esc_attr($ad['link']); ?>" class="regular-text">
</div>
<div style="margin:8px 0;">
<label>广告文字:</label>
<input type="text" name="xd_news_ad_list[<?php echo $idx; ?>][text]" value="<?php echo esc_attr($ad['text']); ?>" class="regular-text" required>
</div>
<div style="margin:8px 0;display:flex;align-items:center;gap:10px;">
<label>文字颜色:</label>
<input type="color" name="xd_news_ad_list[<?php echo $idx; ?>][color]" value="<?php echo esc_attr($ad['color']); ?>">
<button type="button" class="button del-ad">删除本条广告</button>
</div>
</td>
</tr>
<?php endforeach; endif; ?>
</table>
<div style="margin-top:10px;display:flex;gap:12px;align-items:center;">
<button type="button" class="button button-primary" id="add-ad">➕ 新增一条广告</button>
<?php submit_button('💜 保存全部广告条目', 'primary', 'submit', false); ?>
</div>
</form>
</div>
</div>
</div>
<script>
jQuery(function($){
$('.xd-tab-btn').click(function(){
const tabId = $(this).data('tab');
$('.xd-tab-btn').removeClass('active');
$(this).addClass('active');
$('.xd-tab-content').hide();
$('#' + tabId).show();
});
function toggleMediaRow(){
const type = $('input[name="xd_news_base_options[media_type]"]:checked').val();
$('.row-image').toggle(type === 'image');
$('.row-video').toggle(type === 'video');
}
toggleMediaRow();
$('input[name="xd_news_base_options[media_type]"]').change(toggleMediaRow);
let frameImg;
$('.xd-upload-img').click(function(){
if (frameImg) return frameImg.open();
frameImg = wp.media({title: '选择轮播图片', multiple: false, library: {type: 'image'}});
frameImg.on('select', function(){
const a = frameImg.state().get('selection').first().toJSON();
$('#banner_img').val(a.url);
$('#preview_img').attr('src', a.url);
});
frameImg.open();
});
let frameVideo;
$('.xd-upload-video').click(function(){
if (frameVideo) return frameVideo.open();
frameVideo = wp.media({title: '上传MP4视频', multiple: false, library: {type: 'video'}});
frameVideo.on('select', function(){
const a = frameVideo.state().get('selection').first().toJSON();
$('#banner_video').val(a.url);
location.reload();
});
frameVideo.open();
});
let adIdx = <?php echo count($ad_list); ?>;
$('#add-ad').click(function(){
const html = `<tr class="ad-item"><th>广告#${adIdx+1}</th><td><div style="margin:8px 0;"><label>跳转链接(可空):</label><input type="url" name="xd_news_ad_list[${adIdx}][link]" class="regular-text"></div><div style="margin:8px 0;"><label>广告文字:</label><input type="text" name="xd_news_ad_list[${adIdx}][text]" class="regular-text" required></div><div style="margin:8px 0;display:flex;align-items:center;gap:10px;"><label>文字颜色:</label><input type="color" name="xd_news_ad_list[${adIdx}][color]" value="#ff88bb"><button type="button" class="button del-ad">删除本条广告</button></div></td></tr>`;
$('#ad-table').append(html);
adIdx++;
});
$(document).on('click', '.del-ad', function(){
$(this).closest('.ad-item').remove();
});
});
</script>
<?php
}
// ===================== 前端静态资源加载 =====================
function xd_news_load_assets(){
$plugin_url = plugin_dir_url(__FILE__);
wp_enqueue_style('layui-css', $plugin_url . 'assets/layui.css');
wp_enqueue_style('xd-common', $plugin_url . 'assets/common.css', ['layui-css']);
wp_enqueue_style('xd-shuangyi', $plugin_url . 'assets/shuangyi.css', ['xd-common']);
wp_enqueue_style('xd-index', $plugin_url . 'assets/index.css', ['xd-shuangyi']);
wp_enqueue_script('layui-js', $plugin_url . 'assets/layui.js', ['jquery'], '', true);
wp_enqueue_script('xd-news-js', $plugin_url . 'assets/script.js', ['jquery','layui-js'], '', true);
}
// ===================== 核心渲染函数(完整无截断) =====================
function xd_news_render_html(){
$base_opts = xd_get_base_options();
$link_opts = xd_get_link_options();
$ad_set = xd_get_ad_options();
$ads_raw = xd_get_ad_list();
$posts_per_page = $base_opts['posts_per_page'];
$data_source = $base_opts['data_source'];
$active_tpl_id = $base_opts['active_template'];
$all_tpl = xd_news_get_all_templates();
$tpl_info = isset($all_tpl[$active_tpl_id]) ? $all_tpl[$active_tpl_id] : xd_news_get_system_templates()['template1'];
$content_raw = [];
$stat_seconds = $base_opts['stat_hours'] * 3600;
$time_limit = current_time('timestamp') - $stat_seconds;
$today_count = 0;
$site_tip = $base_opts['site_tip_text'];
$copyright = $base_opts['copyright_text'];
// 查询普通文章
if ($data_source === 'post') {
$query_args = [
'post_type' => 'post',
'posts_per_page' => 999,
'orderby' => 'modified',
'order' => 'DESC',
'post_status' => 'publish',
'no_found_rows' => true,
'update_post_meta_cache' => false,
'update_post_term_cache' => false,
];
if (!empty($base_opts['cat_ids'])) $query_args['category__in'] = array_map('intval', explode(',', $base_opts['cat_ids']));
if (!empty($base_opts['exclude_pids'])) $query_args['post__not_in'] = array_map('intval', explode(',', $base_opts['exclude_pids']));
if ($base_opts['only_sticky'] === '1') {
$sticky = get_option('sticky_posts');
if (!empty($sticky)) $query_args['post__in'] = $sticky;
}
$wp_query = new WP_Query($query_args);
if ($wp_query->have_posts()) {
while ($wp_query->have_posts()) {
$wp_query->the_post();
$p = $wp_query->post;
$mod_t = strtotime($p->post_modified);
$content_raw[] = $p;
if ($mod_t >= $time_limit) $today_count++;
}
}
wp_reset_postdata();
} else {
// 查询子比社区帖子
$forum_args = [
'post_type' => 'forum_post',
'posts_per_page' => 999,
'orderby' => 'modified',
'order' => 'DESC',
'post_status' => $base_opts['forum_status'],
'ignore_sticky_posts' => true,
'no_found_rows' => true,
'update_post_meta_cache' => false,
'update_post_term_cache' => false,
];
if (!empty($base_opts['forum_ids'])) {
$f_ids = array_map('intval', explode(',', $base_opts['forum_ids']));
$forum_args['meta_query'][] = ['key'=>'plate_id','value'=>$f_ids,'compare'=>'IN','type'=>'NUMERIC'];
}
if (!empty($base_opts['forum_exclude'])) $forum_args['post__not_in'] = array_map('intval', explode(',', $base_opts['forum_exclude']));
$forum_query = new WP_Query($forum_args);
if ($forum_query->have_posts()) {
while ($forum_query->have_posts()) {
$forum_query->the_post();
$p = $forum_query->post;
$mod_t = strtotime($p->post_modified);
$content_raw[] = $p;
if ($mod_t >= $time_limit) $today_count++;
}
}
wp_reset_postdata();
}
// 按修改时间倒序排序
usort($content_raw, function ($a, $b) {
$ta = strtotime($a->post_modified);
$tb = strtotime($b->post_modified);
return $tb - $ta;
});
// 广告拼接逻辑
$ads = [];
if ($ad_set['ad_switch'] === '1') $ads = $ads_raw;
$full_list = [];
if ($ad_set['ad_mode'] === 'top') {
foreach ($ads as $ad) $full_list[] = ['type' => 'ad', 'data' => $ad];
foreach ($content_raw as $item) $full_list[] = ['type' => 'post', 'data' => $item];
} else {
$line = 0; $ad_idx = 0;
foreach ($content_raw as $item) {
$full_list[] = ['type' => 'post', 'data' => $item];
$line++;
if ($line >= $ad_set['ad_interval'] && $ad_idx < count($ads)) {
$full_list[] = ['type' => 'ad', 'data' => $ads[$ad_idx]];
$ad_idx++; $line = 0;
}
}
for ($i = $ad_idx; $i < count($ads); $i++) $full_list[] = ['type' => 'ad', 'data' => $ads[$i]];
}
$chunks_all = array_chunk($full_list, $posts_per_page);
$chunks = array_slice($chunks_all, 0, 4);
$totalPage = count($chunks);
// 轮播HTML生成
ob_start();
if ($base_opts['media_type'] === 'image'):
?>
<div class="dad addd layui-carousel" id="test1" lay-anim="fade" style="width: 390px; height: 300px;">
<a href="<?php echo esc_url($base_opts['banner_url']); ?>" rel="nofollow" target="_blank">
<img src="<?php echo esc_attr($base_opts['banner_img']); ?>" width="100%" height="100%" >
</a>
</div>
<?php else: ?>
<div style="width:390px;height:300px;overflow:hidden;border-radius:4px;">
<video width="390" height="300" muted autoplay loop playsinline style="object-fit:cover;display:block;">
<source src="<?php echo esc_attr($base_opts['banner_video']); ?>" type="video/mp4">
</video>
</div>
<?php endif;
$banner_html = ob_get_clean();
// 特权模块HTML
ob_start();
if ($base_opts['show_privilege'] === '1'):
?>
<fieldset>
<legend>本站特权</legend>
</fieldset>
<ul class="tequan">
<li class="clearfix">
<div><i style="background-position: center -389px;"></i><span>简洁好看</span></div>
<div class="liright"><i style="background-position: center -360px;"></i><span>按时更新</span></div>
</li>
<li class="clearfix">
<div><i style="background-position: center -101px;"></i><span>少量广告</span></div>
<div class="liright"><i style="background-position: center -263px;"></i><span>资源丰富</span></div>
</li>
</ul>
<?php endif;
$privilege_html = ob_get_clean();
// 底部链接栏
ob_start();
$link_arr = [];
if (!empty($link_opts['link1_text'])) $link_arr[] = ['t' => $link_opts['link1_text'], 'u' => $link_opts['link1_url']];
if (!empty($link_opts['link2_text'])) $link_arr[] = ['t' => $link_opts['link2_text'], 'u' => $link_opts['link2_url']];
if (!empty($link_opts['link3_text'])) $link_arr[] = ['t' => $link_opts['link3_text'], 'u' => $link_opts['link3_url']];
foreach ($link_arr as $l):
if (!empty($l['u'])) echo '<a href="' . esc_attr($l['u']) . '" class="noad" target="_blank">' . esc_html($l['t']) . '</a>';
else echo '<span class="noad">' . esc_html($l['t']) . '</span>';
endforeach;
$link_bar = ob_get_clean();
// 列表循环HTML
ob_start();
foreach ($chunks as $pageIndex => $items):
?>
<ul class="page-item" style="<?php echo $pageIndex === 0 ? 'display:block' : 'display:none' ?>">
<?php foreach ($items as $item): ?>
<?php if ($item['type'] === 'ad'):
$ad = $item['data'];
?>
<li class="item-ad addd">
<a href="<?php echo esc_url($ad['link']) ?>" rel="nofollow" target="_blank">
<font style="color:<?php echo esc_attr($ad['color']) ?>"><?php echo esc_html($ad['text']) ?></font>
</a>
<span class="myad">广告</span>
</li>
<?php else:
$p = $item['data'];
$mod_t = strtotime($p->post_modified);
$is_new = $mod_t >= $time_limit;
$color = $is_new ? '#ff0000' : '#999999';
$date_show = date('m-d', $mod_t);
?>
<li class="item-post new">
<a href="<?php echo get_permalink($p->ID); ?>" title="<?php echo esc_attr($p->post_title); ?>">
<?php echo esc_html($p->post_title); ?>
</a>
<span style="color:<?php echo $color; ?>"><?php echo $date_show; ?></span>
</li>
<?php endif; ?>
<?php endforeach; ?>
</ul>
<?php endforeach;
$item_list = ob_get_clean();
// 分页HTML
ob_start();
if ($totalPage > 1):
?>
<div class="page layui-clear" data-nowpage="1" data-totalpage="<?php echo $totalPage ?>">
<div class="top" id="last">上一页</div>
<b class="cfx"></b>
<div class="bottom" id="next">下一页</div>
</div>
<?php endif;
$pagination = ob_get_clean();
// 变量替换映射
$replace_map = [
'{{today_count}}' => $today_count,
'{{banner_html}}' => $banner_html,
'{{privilege_html}}' => $privilege_html,
'{{link_bar}}' => $link_bar,
'{{item_list}}' => $item_list,
'{{pagination}}' => $pagination,
'{{site_tip}}' => $site_tip,
'{{copyright}}' => $copyright
];
$tpl_html = $tpl_info['html'];
$tpl_css = trim($tpl_info['css']);
foreach ($replace_map as $k => $v) {
$tpl_html = str_replace($k, $v, $tpl_html);
}
ob_start();
if (!empty($tpl_css)) echo '<style>' . $tpl_css . '</style>';
echo $tpl_html;
return ob_get_clean();
}
// ===================== 短代码调用 =====================
function xd_news_shortcode($atts){
xd_news_load_assets();
return xd_news_render_html();
}
add_shortcode('xd_news_list', 'xd_news_shortcode');
// ===================== 侧边栏小工具完整类 =====================
class Xd_News_Widget extends WP_Widget
{
public function __construct(){
parent::__construct(
'xd_news_widget',
'Xd-News二次元资源列表',
[
'description' => '自定义HTML/CSS模板资源列表,支持子比社区板块筛选、广告分页'
]
);
}
// 后台小工具表单
public function form($instance){
echo '<p>所有配置请到 【设置 > Xd‑二次元列表配置】 面板统一修改</p>';
}
// 前台输出小工具
public function widget($args, $instance){
xd_news_load_assets();
echo $args['before_widget'];
echo xd_news_render_html();
echo $args['after_widget'];
}
}
// 注册侧边栏小工具
function xd_news_register_widget(){
register_widget('Xd_News_Widget');
}
add_action('widgets_init', 'xd_news_register_widget');
使用说明
- 新建文件,粘贴全部代码,保存为 xd-news-list.php;
- 上传到网站插件目录 /wp-content/plugins/xd-news-list/;
- WP 后台插件页面启用;
- 后台「设置」菜单出现【Xd‑二次元列表配置】,分 4 大独立卡片分区,二次元粉紫渐变风格;
- 支持自定义 HTML/CSS 模板、后台新增变量、广告管理、文章 / 子比帖子双数据源;
- 调用方式:页面插入短代码 / 外观 – 小工具拖拽挂件。最近更新+1
- 淘宝闪购悦享会员领奶茶免单 广告
- CorelDRAWCDRX4-2024破除限制永久解锁 07-27
- 随机小姐姐美女热舞源码 v6.0版本 07-24
- Html网页本地图片拼接工具 v1.0 07-24
- 抖音聊天 v1.1.30 官方版 07-23
- 多窗口电脑文件管理器 Q-Dir 07-22
- 手机摄影达人新手小白必修课 07-22
- 豆包Ai实战营从小白到高手速成 07-21
- 婚恋攻略让你得到靠谱的婚姻 07-21
- 精【原创修改】驾考宝典会员解锁,看个特殊说明吧 07-19
- 2024能落地的销售实战课程 07-18
- 撞上心理学,提升恋商的必修课 07-17
- 【有声书】【仙逆】著:耳根演播:边江, 丸子, 朱宇, 梦生文化 多版本合集 07-14
- 小红书实操陪跑营教你引流获客 07-08
- 新手入门到精通成为短视频高手 07-06
- 7大新媒体写作实操技巧又快又稳 07-05
- 2025春季拍剪效全能集训营 06-30
- AI电影制作实操课个人就能做电影 06-30
- 豆包AI 1.74.5.0 (生图无水印下载) 06-30
- 爆火健身小姐姐瘦身燃脂教学精选合集 06-29
- 网文写作训练营普通人也能玩 06-29
- 剪辑高手训练营思维+调色+拍摄 06-29
- 用手机拍摄有品质的短视频 06-28
- Web前端全栈工程师2023视频课程 06-26
- AIGC人工智能必修提示工程入门 06-24
- 图片无损放大变清晰工具:AI-Lossless-Zoomer 06-23
- 360安全浏览器16.1.2270.0绿色版 06-22
- 常盛春觉察型伴侣21节课 06-22
- 结婚婚前婚礼流程准备筹备必备物品采购清单日程安排表格资料 06-21
- 零基础手机拍摄剪辑高级感短片 06-20
- 知心雅思全系 06-18
- 摄影摄像后期零基础思维课 06-17
- 浪迹升华聊天技巧速成视频课程 06-16
- 人工智能图片图像AI磨皮降噪工具 Topaz DeNoise AI v3.7.0 汉化破解版下载 06-16
- 轻量级鼠标录制器 v1.6(仅71KB) 06-10
- 视频音频处理工具箱:Aiseesoft Video Converter v10.8.62 06-10
上一页下一页
© 版权声明
文章版权归作者所有,未经允许请勿转载。
THE END








暂无评论内容