<?php
/*
Plugin Name: News Tabs PRO – Premium Tabs + Most News (Final Stable)
Description: Moneycontrol-style Most News slider with Premium Tabs (Latest, Popular, IPO, Tools)
Version: 6.4
Author: Pawan Meghwal
*/
if (!defined('ABSPATH')) exit;
/* =====================================================
ADMIN SETTINGS
===================================================== */
add_action('admin_menu', function () {
add_menu_page(
'News Tabs PRO',
'News Tabs PRO',
'manage_options',
'news-tabs-pro',
'news_tabs_pro_settings',
'dashicons-screenoptions',
30
);
});
add_action('admin_init', function () {
register_setting('news_tabs_pro', 'ntp_latest_count');
register_setting('news_tabs_pro', 'ntp_popular_days');
register_setting('news_tabs_pro', 'ntp_ipo_page');
register_setting('news_tabs_pro', 'ntp_tools_page');
});
function news_tabs_pro_settings(){ ?>
<div class="wrap">
<h1>News Tabs PRO – Settings</h1>
<form method="post" action="options.php">
<?php settings_fields('news_tabs_pro'); ?>
<table class="form-table">
<tr>
<th>Latest Posts Per Load</th>
<td><input type="number" name="ntp_latest_count" value="<?php echo esc_attr(get_option('ntp_latest_count',10)); ?>"></td>
</tr>
<tr>
<th>Popular (Last X Days)</th>
<td><input type="number" name="ntp_popular_days" value="<?php echo esc_attr(get_option('ntp_popular_days',2)); ?>"></td>
</tr>
<tr>
<th>IPO Page</th>
<td><?php wp_dropdown_pages(['name'=>'ntp_ipo_page','selected'=>get_option('ntp_ipo_page'),'show_option_none'=>'-- Select --']); ?></td>
</tr>
<tr>
<th>Tools Page</th>
<td><?php wp_dropdown_pages(['name'=>'ntp_tools_page','selected'=>get_option('ntp_tools_page'),'show_option_none'=>'-- Select --']); ?></td>
</tr>
</table>
<?php submit_button(); ?>
</form>
</div>
<?php }
/* =====================================================
MOST NEWS META
===================================================== */
add_action('add_meta_boxes', function () {
add_meta_box('ntp_most_news','Most News','ntp_most_box','post','side','high');
});
function ntp_most_box($post){
$m = get_post_meta($post->ID,'_ntp_most_news',true);
$o = get_post_meta($post->ID,'_ntp_most_order',true); ?>
<p>
<label>
<input type="checkbox" name="ntp_most_news" value="1" <?php checked($m,'1'); ?>>
<strong>Most News</strong>
</label>
</p>
<p>
<label>Priority (1–4)</label>
<input type="number" name="ntp_most_order" min="1" max="4"
value="<?php echo esc_attr($o ?: 1); ?>" style="width:100%">
<small>Same priority = latest first</small>
</p>
<?php }
add_action('save_post_post', function ($id) {
if (defined('DOING_AUTOSAVE') && DOING_AUTOSAVE) return;
if (!current_user_can('edit_post',$id)) return;
isset($_POST['ntp_most_news'])
? update_post_meta($id,'_ntp_most_news','1')
: delete_post_meta($id,'_ntp_most_news');
if (isset($_POST['ntp_most_order']))
update_post_meta($id,'_ntp_most_order',max(1,min(4,(int)$_POST['ntp_most_order'])));
});
/* =====================================================
HELPERS
===================================================== */
function ntp_thumb($id){
return has_post_thumbnail($id)
? get_the_post_thumbnail_url($id,'large')
: 'https://via.placeholder.com/400x400';
}
/* =====================================================
AJAX LOAD MORE – LATEST
===================================================== */
add_action('wp_ajax_ntp_load_more_latest','ntp_load_more_latest');
add_action('wp_ajax_nopriv_ntp_load_more_latest','ntp_load_more_latest');
function ntp_load_more_latest(){
$page = max(1,(int)$_POST['page']);
$limit = (int)get_option('ntp_latest_count',10);
$exclude = isset($_POST['exclude']) ? array_map('intval',$_POST['exclude']) : [];
$q = new WP_Query([
'post_type'=>'post',
'posts_per_page'=>$limit,
'paged'=>$page,
'post__not_in'=>$exclude
]);
if($q->have_posts()):
while($q->have_posts()): $q->the_post(); ?>
<a class="ntp-item" href="<?php the_permalink(); ?>">
<img src="<?php echo ntp_thumb(get_the_ID()); ?>">
<span><?php the_title(); ?></span>
</a>
<?php endwhile;
endif;
wp_reset_postdata();
wp_die();
}
/* =====================================================
AJAX PAGE LOAD (IPO / TOOLS)
===================================================== */
add_action('wp_ajax_ntp_load_page','ntp_load_page');
add_action('wp_ajax_nopriv_ntp_load_page','ntp_load_page');
function ntp_load_page(){
$p = get_post((int)$_POST['page_id']);
if($p) echo apply_filters('the_content',$p->post_content);
wp_die();
}
/* =====================================================
SHORTCODE
===================================================== */
add_shortcode('news_tabs_pro', function(){
$limit = (int)get_option('ntp_latest_count',10);
$days = (int)get_option('ntp_popular_days',2);
$ipo = (int)get_option('ntp_ipo_page');
$tools = (int)get_option('ntp_tools_page');
/* MOST NEWS */
$q = new WP_Query([
'posts_per_page'=>4,
'meta_query'=>[['key'=>'_ntp_most_news','value'=>'1']],
'meta_key'=>'_ntp_most_order',
'orderby'=>['meta_value_num'=>'ASC','date'=>'DESC']
]);
$most = $q->posts;
$most_ids = wp_list_pluck($most,'ID');
/* LATEST */
$latest = get_posts([
'posts_per_page'=>$limit,
'post__not_in'=>$most_ids
]);
/* POPULAR */
$popular = get_posts([
'posts_per_page'=>$limit,
'orderby'=>'comment_count',
'date_query'=>[['after'=>"$days days ago"]]
]);
ob_start(); ?>
<style>
/* ORIGINAL CSS – UNCHANGED */
.ntp-box{background:#fff;border-radius:20px;box-shadow:0 14px 40px rgba(0,0,0,.10);font-family:Inter,system-ui}
.ntp-tabs{display:flex;background:#f3f6fb;border-radius:20px;padding:6px;margin-bottom:16px}
.ntp-tabs button{flex:1;padding:14px 0;font-size:16px;font-weight:600;border:none;background:transparent;color:#111;border-radius:14px;cursor:pointer}
.ntp-tabs button.active{background:#1f3fae;color:#fff;border-radius:14px 0 0 14px}
.ntp-content{display:none;padding:18px}
.ntp-content.active{display:block}
.ntp-most-head{font-size:18px;font-weight:800;margin-bottom:12px}
.ntp-most-track{display:flex;gap:14px;overflow-x:auto}
.ntp-most-card{min-width:260px;border-radius:16px;overflow:hidden;position:relative;color:#fff;text-decoration:none}
.ntp-most-card img{width:100%;height:170px;object-fit:cover}
.ntp-most-title{position:absolute;bottom:0;padding:12px;font-size:15px;font-weight:700;background:linear-gradient(transparent,rgba(0,0,0,.85))}
.ntp-item{display:flex;gap:14px;padding:14px 0;border-bottom:1px solid #eee;text-decoration:none;color:#111}
.ntp-item img{width:90px;height:90px;object-fit:cover;border-radius:12px}
.ntp-item span{font-size:15px;font-weight:500;line-height:1.45}
.ntp-see-more{display:block;margin:18px auto 0;padding:12px 22px;background:#1f3fae;color:#fff;font-size:15px;font-weight:600;border:none;border-radius:14px;cursor:pointer}
</style>
<div class="ntp-box">
<div class="ntp-tabs">
<button class="active" onclick="ntpTab(event,'latest')">Latest</button>
<button onclick="ntpTab(event,'popular')">Popular</button>
<button onclick="ntpLoadPage(event,<?php echo $ipo; ?>)">IPO</button>
<button onclick="ntpLoadPage(event,<?php echo $tools; ?>)">Tools</button>
</div>
<div id="latest" class="ntp-content active">
<?php if($most): ?>
<div class="ntp-most-head">MOST NEWS</div>
<div class="ntp-most-track">
<?php foreach($most as $p): ?>
<a class="ntp-most-card" href="<?php echo get_permalink($p->ID); ?>">
<img src="<?php echo ntp_thumb($p->ID); ?>">
<div class="ntp-most-title"><?php echo esc_html($p->post_title); ?></div>
</a>
<?php endforeach; ?>
</div>
<?php endif; ?>
<?php foreach($latest as $p): ?>
<a class="ntp-item" href="<?php echo get_permalink($p->ID); ?>">
<img src="<?php echo ntp_thumb($p->ID); ?>">
<span><?php echo esc_html($p->post_title); ?></span>
</a>
<?php endforeach; ?>
<button class="ntp-see-more" onclick="ntpLoadMore()">See More</button>
</div>
<div id="popular" class="ntp-content">
<?php foreach($popular as $p): ?>
<a class="ntp-item" href="<?php echo get_permalink($p->ID); ?>">
<img src="<?php echo ntp_thumb($p->ID); ?>">
<span><?php echo esc_html($p->post_title); ?></span>
</a>
<?php endforeach; ?>
</div>
<div id="ajax" class="ntp-content"></div>
</div>
<script>
let ntpPage = 2;
let ntpExclude = <?php echo json_encode($most_ids); ?>;
function ntpTab(e,id){
document.querySelectorAll('.ntp-tabs button').forEach(b=>b.classList.remove('active'));
document.querySelectorAll('.ntp-content').forEach(c=>c.classList.remove('active'));
e.target.classList.add('active');
document.getElementById(id).classList.add('active');
}
function ntpLoadMore(){
let btn=document.querySelector('.ntp-see-more');
btn.innerText='Loading...';
fetch('<?php echo admin_url("admin-ajax.php"); ?>',{
method:'POST',
headers:{'Content-Type':'application/x-www-form-urlencoded'},
body:'action=ntp_load_more_latest&page='+ntpPage+'&exclude[]='+ntpExclude.join('&exclude[]=')
}).then(r=>r.text()).then(h=>{
if(h.trim()===''){btn.innerText='No More';btn.disabled=true;}
else{btn.insertAdjacentHTML('beforebegin',h);btn.innerText='See More';ntpPage++;}
});
}
function ntpLoadPage(e,id){
let box=document.getElementById('ajax');
document.querySelectorAll('.ntp-tabs button').forEach(b=>b.classList.remove('active'));
e.target.classList.add('active');
document.querySelectorAll('.ntp-content').forEach(c=>c.classList.remove('active'));
box.classList.add('active');
box.innerHTML='Loading...';
fetch('<?php echo admin_url("admin-ajax.php"); ?>',{
method:'POST',
headers:{'Content-Type':'application/x-www-form-urlencoded'},
body:'action=ntp_load_page&page_id='+id
}).then(r=>r.text()).then(t=>box.innerHTML=t);
}
</script>
<?php return ob_get_clean();
});
Leave a Reply