19 Commits

Author SHA1 Message Date
浪子 a106080633 1.2.3 2025-08-05 10:04:56 +08:00
浪子 57aeb81c62 1.2.3
fix 随机文章跳转
fix 无说说时无评论框的bug
2025-08-04 19:46:24 +08:00
浪子 4dcaefb291 1.2.3
使用评论实现说说的功能
2025-08-04 17:00:37 +08:00
浪子 0017693c81 1.2.2
增加一个随机阅读的独立页面
2025-08-02 14:29:25 +08:00
浪子 d268bd10bb 1.2.2
fix 标签
2025-08-02 14:01:18 +08:00
浪子 b416e58596 1.2.2
增加全局侧边栏的显示开关
2025-08-02 10:50:39 +08:00
浪子 5d67235be0 1.2.2
先解析短代码再解析markdown
2025-08-01 10:58:21 +08:00
浪子 134bb0d66c 1.2.1
增加了多条公告的功能 并修改了相关描述
2025-07-27 13:39:53 +08:00
浪子 8afb1934dd 1.2.1 2025-07-19 11:11:55 +08:00
浪子 b73e465a79 1.2.0 2025-07-19 10:09:34 +08:00
浪子 ae990a722b 1.2.1 2025-07-12 08:24:51 +08:00
浪子 35806ea2fb 1.2.0 2025-07-11 19:16:34 +08:00
浪子 3bb53afcea 1.2.0 2025-07-10 19:48:37 +08:00
浪子 9f389fbb34 1.2.0 2025-07-10 18:58:47 +08:00
浪子 4c1c795dc2 1.1.9 2025-07-10 13:34:00 +08:00
浪子 b3b1407647 1.1.8 2025-07-09 16:56:11 +08:00
浪子 6b9cc81754 1.1.7 2025-07-08 11:30:32 +08:00
浪子 c313e29d99 1.1.6 2025-07-07 19:39:19 +08:00
浪子 33bc5d53f5 1.1.5 2025-07-07 17:30:50 +08:00
20 changed files with 1265 additions and 529 deletions
+2
View File
@@ -1 +1,3 @@
*.html
/.vercel
page-talks copy.php
+48 -1
View File
@@ -32,4 +32,51 @@
- 增加系统显示设置
- 增加浏览器信息显示设置
- 修复pjax模式下的404跳转
- 2025.07.07 表情短代码解析集成
- 1.1.5
- 将表情短代码(如 :smile:)自动解析为图片表情,集成到主题评论内容输出中。
- 2025.07.08
- 1.1.6
- 修复头像区域背景的bug
- 优化php8.3兼容性
- 1.1.8
- 优化github链接的正则表达式,只解析主仓库链接(如 https://github.com/用户名/仓库名),不再解析子路径(如 /tree/、/blob/ 等)为卡片。
- 实现文章内容图片懒加载,自动将常见图片格式(jpg、jpeg、png、webp)的<img>标签替换为带懒加载属性的格式。
- 修正getPostCover函数,确保只从原始内容中提取第一张真实图片地址,不受懒加载替换影响,避免首页首图变成load.svg。
- 新增支持[success]、[primary]、[danger]、[warning]、[info]、[dark]等alert类短代码,自动渲染为对应的Bootstrap风格提示框。
- 新增支持[collapse title='xxx']内容[/collapse]折叠面板短代码,自动渲染为带唯一ID的Bootstrap折叠结构。
- 新增支持[download file='xxx.zip' size='12MB']文件地址[/download]下载短代码,自动渲染为带文件名、大小、声明和下载地址的下载信息块。
- 新增支持[reply]隐藏内容[/reply]回复可见短代码,未满足条件时前端显示提示,已评论且审核通过后显示隐藏内容。
- 1.2.0
- 新增支持首页登录
- 2025.08.02
- 1.2.2
- 增加侧边栏显示的全局开关
- 修复代码块中的短代码解析问题
- 新增一个随机文章阅读的独立页面
- 2025.08.03
- 1.2.3
- 修复随机页面在 PJAX 模式下的缓存问题
- 在随机页面添加缓存控制头,防止 PJAX 缓存
- 在 JavaScript 中添加随机页面检测,强制刷新确保获取新文章
- 修复后端登录验证问题,确保密码错误时返回正确的错误信息
- 重新设计随机页面模板,添加完整的页面结构和加载动画
- 修复随机页面重定向问题,使用 JavaScript 跳转避免缓存
- 修复随机页面 JavaScript 错误,移除不存在的 InstantClick.preload 方法调用
- 优化随机页面跳转逻辑,确保在 PJAX 模式下也能正常自动跳转
+15 -5
View File
@@ -3,10 +3,16 @@ if (!defined('__TYPECHO_ROOT_DIR__')) exit;
$this->need('header.php');
?>
<div class="row row-cols-1">
<?php if ($this->options->showsidebar): ?>
<div class="col-lg-8 col-md-12 animated fadeInLeft ">
<div class="animated fadeInLeft ">
<?php else: ?>
<div class="col-lg-12 col-md-12">
<div class="row box-plr15">
<?php endif; ?>
<div> <!--文章列表-->
<div id="posts">
<?php if ($this->options->listmodel): ?>
<div class=" mr-0 ml-0">
<?php while ($this->next()): ?>
<?php
@@ -61,21 +67,25 @@ $coverImage = getPostCover($this->content, $this->cid);
</article>
<?php endwhile; ?>
</div>
<div class="mt20 p-flex-s-right" data-no-instant>
<?php $this->pageNav('&laquo;', '&raquo;', 1, '...', array(
<div class="mt20 p-flex-s-right" data-no-instant>
<?php $this->pageNav('&laquo;', '&raquo;', 1, '...', array(
'wrapTag' => 'ul',
'wrapClass' => 'pagination comment-ajax-load',
'itemTag' => 'li',
'textTag' => 'span',
'currentClass' => 'active',
'currentClass' => 'cur',
'prevClass' => 'prev',
'nextClass' => 'next'
)); ?>
</div>
</div>
<?php else: ?>
<?php $this->need('card.php'); ?>
<?php endif; ?>
</div>
</div>
</div>
</div>
<?php if ($this->options->showsidebar): ?>
<?php $this->need('sidebar.php'); ?>
<?php endif; ?>
<?php $this->need('footer.php'); ?>
+1 -1
View File
File diff suppressed because one or more lines are too long
+87 -43
View File
@@ -74,9 +74,6 @@ class Puock {
this.registerModeChangeEvent()
this.eventCommentPageChangeEvent()
this.eventCommentPreSubmit()
this.eventSmiley()
this.eventOpenCommentBox()
this.eventCloseCommentBox()
this.eventSendPostLike()
this.eventPostMainBoxResize()
this.swiperOnceEvent()
@@ -84,6 +81,8 @@ class Puock {
this.detectDevice()
window.addEventListener('resize', ()=>this.detectDevice());
layer.config({shade: 0.5})
// 新增:首次加载时初始化评论相关事件
this.initCommentEvents();
}
pageInit() {
@@ -144,6 +143,10 @@ class Puock {
});
// form ajax submit
$(document).on("submit", ".ajax-form", (e) => {
// 如果是登录弹窗表单,允许原生提交
if ($(e.target).attr('id') === 'front-login-form') {
return true;
}
e.preventDefault();
const form = $(this.ct(e));
const formEls = form.find(":input")
@@ -209,6 +212,32 @@ class Puock {
}
return false;
})
// 登录弹窗表单AJAX提交(集成Puock插件接口)
$(document).off('submit', '#front-login-form');
$(document).on('submit', '#front-login-form', function(e) {
e.preventDefault();
var $form = $(this);
var data = $form.serialize();
$.ajax({
url: '/index.php/ajaxlogin/',
type: 'POST',
data: data,
dataType: 'json',
success: function(res) {
if (res.success) {
window.Puock.toast(res.msg || '登录成功', TYPE_SUCCESS);
setTimeout(function() {
window.location.reload();
}, 800);
} else {
window.Puock.toast(res.msg || '登录失败', TYPE_DANGER);
}
},
error: function() {
window.Puock.toast('请求失败', TYPE_DANGER);
}
});
});
}
pageLinkBlankOpenInit() {
@@ -416,7 +445,7 @@ class Puock {
this.pageLinkBlankOpenInit()
this.initGithubCard();
this.keyUpHandle();
this.loadHitokoto();
// this.loadHitokoto();
// this.asyncCacheViews();
this.swiperInit();
// this.validateInit();
@@ -465,6 +494,8 @@ class Puock {
// $('#post-main, #sidebar').theiaStickySidebar({
// additionalMarginTop: 20
// });
// 新增:pjax切换后重新初始化评论相关事件
this.initCommentEvents();
}
@@ -770,12 +801,14 @@ class Puock {
}
parseFormData(formEl, args = {}) {
// 先获取表单所有字段
const dataArr = formEl.serializeArray();
const data = {...args};
const data = {};
for (let i = 0; i < dataArr.length; i++) {
data[dataArr[i].name] = dataArr[i].value;
}
return jQuery.param(data);
// 合并额外参数
return jQuery.param(Object.assign(data, args));
}
eventCommentPreSubmit() {
@@ -879,33 +912,49 @@ class Puock {
}
eventOpenCommentBox() {
$(document).on("click", "[id^=comment-reply-]", (e) => {
this.data.comment.replyId = $(this.ct(e)).attr("data-id");
if ($.trim(this.data.comment.replyId) === '') {
this.toast('结构有误', TYPE_DANGER);
$(document).off("click", ".comment-reply");
$(document).on("click", ".comment-reply", function(e) {
e.preventDefault();
const replyBtn = $(e.currentTarget);
const replyId = replyBtn.attr("data-coid");
if ($.trim(replyId) === '') {
window.Puock.toast('结构有误', TYPE_DANGER);
return;
}
const cf = $("#comment-form"),
cb = $("#comment-box-" + this.data.comment.replyId);
cf.addClass("box-sw");
cb.removeClass("d-none").append(cf);
const cf = $("#comment-form");
const commentLi = replyBtn.closest('.post-comment');
// 只在表单在原位时插入占位符
if (!$("#comment-form-place-holder").length && cf.parent().attr("id") === "comment-form-box") {
cf.before('<div id="comment-form-place-holder"></div>');
}
// 每次都append到目标评论下方
commentLi.append(cf);
$("#comment-cancel").removeClass("d-none");
$("#comment").val("");
$("#comment_parent").val(this.data.comment.replyId);
})
$("#comment_parent").val(replyId);
window.Puock.data.comment.replyId = replyId;
// 滚动至表单
if (cf.length && cf[0].scrollIntoView) {
cf[0].scrollIntoView({behavior: "smooth", block: "center"});
}
});
}
eventCloseCommentBox() {
$(document).off("click", "#comment-cancel");
$(document).on("click", "#comment-cancel", () => {
const cf = $("#comment-form"),
cb = $("#comment-box-" + this.data.comment.replyId);
cf.removeClass("box-sw");
cb.addClass("d-none");
$("#comment-form-box").append(cf);
const cf = $("#comment-form");
const holder = $("#comment-form-place-holder");
if (holder.length) {
holder.before(cf);
holder.remove();
} else {
$("#comment-form-box").append(cf);
}
$("#comment-cancel").addClass("d-none");
this.data.comment.replyId = null;
})
$("#comment_parent").val('');
});
}
eventSendPostLike() {
@@ -949,11 +998,12 @@ class Puock {
}
eventSmiley() {
$(document).off('click', '.smiley-img');
$(document).on('click', '.smiley-img', (e) => {
const comment = $("#comment");
comment.val(comment.val() + ' ' + $(this.ct(e)).attr("data-id") + ' ');
layer.closeAll();
})
});
}
startLoading() {
@@ -991,6 +1041,13 @@ class Puock {
const title = el.attr("title") || el.data("title") || '提示';
const url = el.data("url");
const onceLoad = el.data("once-load")
// 检查 url 是否存在,避免 SparkMD5 错误
if (!url) {
console.warn('Modal toggle: url is undefined');
return;
}
const id = SparkMD5.hash(url)
if (onceLoad && this.data.modalStorage[id]) {
this.modalLoadRender(id, this.data.modalStorage[id], title, noTitle, noPadding)
@@ -1135,25 +1192,6 @@ class Puock {
});
}
loadHitokoto() {
setTimeout(() => {
$(".widget-puock-hitokoto").each((_, v) => {
const el = $(v);
const api = el.attr("data-api") || "https://v1.hitokoto.cn/"
$.get(api, (res) => {
el.find(".t").text(res.hitokoto ?? res.content ?? "无内容");
el.find('.f').text(res.from);
el.find('.fb').removeClass("d-none");
}, 'json').fail((err) => {
console.error(err)
el.find(".t").text("加载失败:" + err.responseText || err);
el.remove(".fb");
})
})
}, 300)
}
toast(msg, type = TYPE_PRIMARY, options = {}) {
options = Object.assign({
duration: 2600,
@@ -1171,6 +1209,12 @@ class Puock {
return t;
}
// 新增:统一初始化评论相关事件
initCommentEvents() {
this.eventOpenCommentBox();
this.eventCloseCommentBox();
this.eventSmiley();
}
}
jQuery(() => {
+1 -1
View File
@@ -73,7 +73,7 @@ if ($pageprev == '1' && $this->have()):
'wrapClass' => 'pagination comment-ajax-load',
'itemTag' => 'li',
'textTag' => 'span',
'currentClass' => 'active',
'currentClass' => 'cur',
'prevClass' => 'prev',
'nextClass' => 'next'
)); ?>
+7 -62
View File
@@ -43,9 +43,9 @@
<div>
<?php if(!$this->user->hasLogin()): ?>
<div class="d-inline-block">
<a class="btn btn-primary btn-ssm" href="<?php $this->options->loginUrl(); ?>" title="登录" target="_blank">
<i class="fa fa-right-to-bracket"></i>&nbsp;登录
</a>
<button class="btn btn-primary btn-ssm pk-modal-toggle" type="button" data-once-load="true" data-id="front-login" title="快捷登录" data-url="<?php echo get_correct_url('/login/'); ?>">
<i class="fa fa-right-to-bracket"></i>&nbsp;快捷登录
</button>
</div>
<?php endif; ?>
</div>
@@ -59,7 +59,7 @@
<i class="fa-regular fa-face-smile t-md"></i>
</button>
<?php endif; ?>
<input type="hidden" name="parent" id="comment-parent" value="">
<input type="hidden" name="parent" id="comment_parent" value="">
<button type="submit" id="comment-submit" class="btn btn-primary btn-ssm">
<i class="fa-regular fa-paper-plane"></i>&nbsp;发布评论
</button>
@@ -171,14 +171,14 @@
<?php endif; ?>
</div>
<div class="t-sm c-sub">
<span><?php $comments->date('Y-m-d H:i:s'); ?></span>
<span><?php echo friendly_date($comments->created); ?></span>
<a rel="nofollow" class="hide-info animated bounceIn c-sub-a t-sm ml-1 comment-reply" href="javascript:void(0);" data-coid="<?php echo $comments->coid; ?>"><span class="comment-reply-text"><i class="fa fa-share-from-square"></i>回复</span></a>
</div>
</div>
</div>
<div class="content">
<div class="content-text t-md mt10 puock-text">
<?php if ($comments->parent) {echo getPermalinkFromCoid($comments->parent);} $comments->content();?>
<?php if ($comments->parent) {echo getPermalinkFromCoid($comments->parent);} echo parse_smiley_shortcode($comments->content);?>
<div class="comment-os c-sub">
<?php
$deviceInfo = getBrowsersInfo($comments->agent);
@@ -217,59 +217,4 @@
</div>
<?php endif; ?>
</li>
<?php } ?>
<script>
// 评论局部回复,表单移动到评论下方
document.addEventListener('DOMContentLoaded', function() {
// 监听评论区的回复按钮
document.body.addEventListener('click', function(e) {
var target = e.target;
if (
target.classList.contains('comment-reply') ||
(target.parentNode && target.parentNode.classList && target.parentNode.classList.contains('comment-reply'))
) {
e.preventDefault();
// 兼容span嵌套与a标签直接点击
var replyBtn = target.classList.contains('comment-reply') ? target : target.parentNode;
var commentId = replyBtn.getAttribute('data-coid');
var commentLi = replyBtn.closest('.post-comment');
var respondBox = document.getElementById('comment-form-box');
var commentForm = document.getElementById('comment-form');
var cancelBtn = document.getElementById('comment-cancel');
var parentInput = document.getElementById('comment-parent');
// 记录原位置
if (!document.getElementById('comment-form-place-holder')) {
var holder = document.createElement('div');
holder.id = 'comment-form-place-holder';
respondBox.parentNode.insertBefore(holder, respondBox);
}
// 移动表单
commentLi.appendChild(respondBox);
// 设置parent
if (parentInput) parentInput.value = commentId;
// 展示取消按钮
if(cancelBtn) cancelBtn.classList.remove('d-none');
// 聚焦文本域
var textarea = commentForm.querySelector('textarea');
if (textarea) textarea.focus();
// 滚动至表单
respondBox.scrollIntoView({behavior: "smooth", block: "center"});
return false;
}
// 取消回复
if (target.id === 'comment-cancel') {
e.preventDefault();
var respondBox = document.getElementById('comment-form-box');
var holder = document.getElementById('comment-form-place-holder');
var parentInput = document.getElementById('comment-parent');
if (holder) {
holder.parentNode.insertBefore(respondBox, holder);
holder.parentNode.removeChild(holder);
}
if (parentInput) parentInput.value = '';
target.classList.add('d-none');
return false;
}
});
});
</script>
<?php } ?>
+1 -1
View File
@@ -68,7 +68,7 @@
&copy; <?php echo date('Y'); ?> <a href="<?php $this->options->siteUrl(); ?>"><?php $this->options->title(); ?></a>
<div class="fs12 mt10 c-sub">
<span> &nbsp;Theme by
<a target="_blank" class="c-sub" title="Puock v2.8.14" href="https://github.com/jkjoy/typecho-theme-puock">Puock</a>
<a target="_blank" class="c-sub" title="Puock v1.2.3" href="https://github.com/jkjoy/typecho-theme-puock">Puock</a>
</span>
<span> &nbsp;Powered by
<a target="_blank" class="c-sub" title="Typecho" href="https://typecho.org">Typecho</a> <p><a target="_blank" class="c-sub" title="老孙博客" href="https://imsun.org">老孙博客</a>制作</p>
+733 -183
View File
File diff suppressed because it is too large Load Diff
+54 -10
View File
@@ -10,7 +10,11 @@
'search' => _t('包含关键字 %s 的文章'),
'tag' => _t('标签 %s 下的文章'),
'author' => _t('%s 发布的文章')
], '', ' - '); ?><?php $this->options->title(); ?></title>
], '', ' - '); ?>
<?php $this->options->title(); ?>
<?php if ($this->is('index')) echo ' - '; ?>
<?php if ($this->is('index')) $this->options->description() ?>
</title>
<link rel="canonical" href="<?php $this->options->siteUrl(); ?>">
<meta name='robots' content='max-image-preview:large' />
<?php $this->options->addhead(); ?>
@@ -71,7 +75,7 @@
</li>
<?php \Widget\Contents\Page\Rows::alloc()->to($pages); ?>
<?php while ($pages->next()): ?>
<li <?php if ($this->is('page', $pages->slug)): ?> class='current-menu-item current_page_item menu-current<?php endif; ?> menu-item menu-item-type-post_type menu-item-object-page '>
<li class="menu-item menu-item-type-post_type menu-item-object-page<?php if ($this->is('page', $pages->slug)) echo ' current-menu-item current_page_item menu-current'; ?>">
<a class='ww'
href="<?php $pages->permalink(); ?>"
title="<?php $pages->title(); ?>">
@@ -79,6 +83,15 @@
</a>
</li>
<?php endwhile; ?>
<?php if($this->user->hasLogin()): ?>
<li>
<a data-bs-toggle="tooltip" title="用户中心" href="/admin" target="_blank">
<img alt="用户中心" src="<?php $stats = get_site_statistics();echo $stats['avatar']; ?>" class="min-avatar">
</a>
</li>
<?php else: ?>
<li><a data-no-instant data-bs-toggle="tooltip" title="登入" data-title="登入" href="javascript:void(0)" class="pk-modal-toggle" data-once-load="true" data-url="<?php echo get_correct_url('/login/'); ?>"><i class="fa fa-right-to-bracket"></i></a></li>
<?php endif; ?>
<li><a class="colorMode" data-bs-toggle="tooltip" title="模式切换" href="javascript:void(0)"><i class="fa fa-circle-half-stroke"></i></a></li>
<li><a class="search-modal-btn" data-bs-toggle="tooltip" title="搜索" href="javascript:void(0)"><i class="fa fa-search"></i></a></li>
</ul>
@@ -126,8 +139,8 @@
<?php endwhile; ?>
<li class='menu-item menu-item-type-post_type menu-item-object-page'>
<span><a href="#">分类</a>
<a href="#menu-sub-689" data-bs-toggle="collapse"><i class="fa fa-chevron-down t-sm ml-1 menu-sub-icon"></i></a></span>
<ul id="menu-sub-689" class="sub-menu collapse">
<a href="#menu" data-bs-toggle="collapse"><i class="fa fa-chevron-down t-sm ml-1 menu-sub-icon"></i></a></span>
<ul id="menu" class="sub-menu collapse">
<?php $categories = Typecho_Widget::widget('Widget_Metas_Category_List'); ?>
<?php while($categories->next()): ?>
<li class="menu-item menu-item-type-post_type menu-item-object-page menu-item-child">
@@ -139,6 +152,15 @@
</li>
<?php endwhile; ?>
</ul>
<?php if($this->user->hasLogin()): ?>
<li>
<a data-bs-toggle="tooltip" title="用户中心" href="/admin" target="_blank">
<img alt="用户中心" src="<?php $stats = get_site_statistics();echo $stats['avatar']; ?>" class="min-avatar">
</a>
</li>
<?php else: ?>
<li><a data-no-instant data-bs-toggle="tooltip" title="登入" data-title="登入" href="javascript:void(0)" class="pk-modal-toggle" data-once-load="true" data-url="<?php echo get_correct_url('/login/'); ?>"><i class="fa fa-right-to-bracket"></i></a></li>
<?php endif; ?>
</ul>
</nav>
</div>
@@ -155,12 +177,34 @@
<div data-swiper="init" data-swiper-class="global-top-notice-swiper" data-swiper-args='{"direction":"vertical","autoplay":{"delay":3000,"disableOnInteraction":false},"loop":true}'>
<div class="swiper global-top-notice-swiper">
<div class="swiper-wrapper">
<div class="swiper-slide t-line-1">
<a class="ta3" data-no-instant href="javascript:void(0)">
<span class="notice-icon"><i class="fa-regular fa-bell"></i></span>
<span><?php $this->options->gonggao(); ?></span>
</a>
</div>
<?php
// 获取公告内容
$gonggao = $this->options->gonggao;
if ($gonggao) {
// 按行分割
$lines = explode("\n", $gonggao);
foreach ($lines as $line) {
$parts = explode('|', $line);
// 只处理格式正确的行
if (count($parts) >= 3) {
$title = trim($parts[0]);
$url = trim($parts[1]);
$icon = trim($parts[2]);
// 链接为空时使用 javascript:void(0)
$href = $url !== '' ? htmlspecialchars($url) : 'javascript:void(0)';
// 图标为空时使用默认
$icon_class = $icon !== '' ? $icon : 'fa-regular fa-bell';
// 输出 HTML
echo '<div class="swiper-slide t-line-1">';
echo '<a class="ta3" data-no-instant href="' . $href . '">';
echo '<span class="notice-icon"><i class="' . $icon_class . '"></i></span>';
echo '<span>' . htmlspecialchars($title) . '</span>';
echo '</a>';
echo '</div>';
}
}
}
?>
</div>
</div>
</div>
+11 -3
View File
@@ -1,10 +1,11 @@
<?php
/**
* Pouck theme for Typecho
*
* 老孙移植
*
* @package Typecho Pouck Theme
* @author 老孙博客
* @version 1.1.4
* @version 1.2.3
* @link http://www.imsun.org
*/
@@ -13,8 +14,13 @@ $this->need('header.php');
$this->need('sticky.php');
?>
<div class="row row-cols-1">
<?php if ($this->options->showsidebar): ?>
<div class="col-lg-8 col-md-12 animated fadeInLeft ">
<div class="animated fadeInLeft ">
<?php else: ?>
<div class="col-lg-12 col-md-12">
<div class="row box-plr15">
<?php endif; ?>
<div> <!--文章列表-->
<div id="posts">
<?php if ($this->options->listmodel): ?>
@@ -82,7 +88,7 @@ if ($pageprev == '1' && $this->have()):
'wrapClass' => 'pagination comment-ajax-load',
'itemTag' => 'li',
'textTag' => 'span',
'currentClass' => 'active',
'currentClass' => 'cur',
'prevClass' => 'prev',
'nextClass' => 'next'
)); ?>
@@ -96,5 +102,7 @@ if ($pageprev == '1' && $this->have()):
</div>
</div>
</div>
<?php if ($this->options->showsidebar): ?>
<?php $this->need('sidebar.php'); ?>
<?php endif; ?>
<?php $this->need('footer.php'); ?>
+1 -1
View File
@@ -16,7 +16,7 @@ if (!defined('__TYPECHO_ROOT_DIR__')) exit; ?>
</div>
<div id="page">
<div class="row row-cols-1">
<div id="posts" class="col-12 animated fadeInLeft ">
<div id="posts" class="col-12">
<div class="puock-text no-style">
<p><?php $this->content(); ?></p>
</div>
+65
View File
@@ -0,0 +1,65 @@
<?php
/**
* 随机阅读
*
* @package custom
*/
if (!defined('__TYPECHO_ROOT_DIR__')) exit;
// 防止 PJAX 缓存,确保每次都是随机文章
header('Cache-Control: no-cache, no-store, must-revalidate');
header('Pragma: no-cache');
header('Expires: 0');
header('X-InstantClick: no-cache');
// 获取随机文章
function getRandomPost() {
$db = Typecho_Db::get();
// 统计符合条件的文章总数
$countSql = $db->select('COUNT(*) AS count')
->from('table.contents')
->where('status = ?', 'publish')
->where('type = ?', 'post')
->where('created <= ?', time());
$countResult = $db->fetchRow($countSql);
$total = $countResult['count'];
if ($total > 0) {
// 随机选择一个偏移量
$offset = mt_rand(0, $total - 1);
// 根据偏移量获取一篇文章
$sql = $db->select()
->from('table.contents')
->where('status = ?', 'publish')
->where('type = ?', 'post')
->where('created <= ?', time())
->limit(1)
->offset($offset);
$result = $db->fetchRow($sql);
if (!empty($result)) {
$target = Typecho_Widget::widget('Widget_Abstract_Contents')->filter($result);
return $target['permalink'];
}
}
return false;
}
// 获取随机文章链接
$randomPostUrl = getRandomPost();
// 直接重定向,实现无感跳转
if ($randomPostUrl) {
// 使用 302 临时重定向,避免缓存
header('Location: ' . $randomPostUrl, true, 302);
exit;
} else {
// 如果没有文章,重定向到首页
header('Location: ' . $this->options->siteUrl, true, 302);
exit;
}
?>
+8 -2
View File
@@ -17,7 +17,11 @@ if (!defined('__TYPECHO_ROOT_DIR__')) exit; ?>
<?php $commenters = getAllCommenters(); ?>
<div id="page-reads">
<div id="page" class="row row-cols-1">
<?php if ($this->options->showsidebar): ?>
<div id="posts" class="col-lg-8 col-md-12 animated fadeInLeft ">
<?php else: ?>
<div id="posts" class="col-lg-12 col-md-12">
<?php endif; ?>
<div class="p-block puock-text">
<h2 class="t-lg"><?php $this->title() ?></h2>
<div class="mt20 row pd-links">
@@ -44,5 +48,7 @@ if (!defined('__TYPECHO_ROOT_DIR__')) exit; ?>
</div>
</div>
</div>
<?php $this->need('sidebar.php'); ?>
<?php $this->need('footer.php'); ?>
<?php if ($this->options->showsidebar): ?>
<?php $this->need('sidebar.php'); ?>
<?php endif; ?>
<?php $this->need('footer.php'); ?>
+199
View File
@@ -0,0 +1,199 @@
<?php
/**
* 说说页面
* @package custom
* @author 老孙
* @version 1.0
*/
if (!defined('__TYPECHO_ROOT_DIR__')) exit;
$this->need('header.php');
?>
<div id="breadcrumb" class="animated fadeInUp">
<nav aria-label="breadcrumb">
<ol class="breadcrumb">
<li class="breadcrumb-item"><a class="a-link" href="<?php $this->options->siteUrl(); ?>">首页</a></li>
<li class="breadcrumb-item active" aria-current="page"><?php $this->title() ?></li>
</ol>
</nav>
</div>
<div id="page-moments">
<div class="row">
<?php if ($this->options->showsidebar): ?>
<div id="comments" class="col-lg-8 col-md-12 animated fadeInLeft">
<?php else: ?>
<div id="comments" class="col-lg-12 col-md-12">
<?php endif; ?>
<?php
// 登录状态检测
if ($this->user->hasLogin()) {
$GLOBALS['isLogin'] = true;
} else {
$GLOBALS['isLogin'] = false;
}
// 评论回调函数
function threadedComments($comments, $options) {
$mail = $comments->mail;
$mailHash = md5(strtolower(trim($mail)));
$purl = $comments->url;
$nickname = $comments->author;
$cnavatar = Helper::options()->cnavatar ? Helper::options()->cnavatar : 'https://cravatar.cn/avatar/';
$avatarurl = rtrim($cnavatar, '/') . '/' . $mailHash . '?s=80&d=identicon';
$loadingImg = Helper::options()->themeUrl . '/assets/img/load.svg';
?>
<div class="mb20 puock-text moments-item">
<div class="row">
<div class="col-12 col-md-1">
<a class="meta ta3" href="<?php echo $purl; ?>" target="_blank">
<div class="avatar mb10">
<img src='<?php echo $loadingImg; ?>'
class='lazy md-avatar mt-1'
data-src='<?php echo $avatarurl; ?>'
>
</div>
<div class="t-line-1 info fs12"><?php echo $nickname; ?></div>
</a>
</div>
<div class="col-12 col-md-11">
<div class="p-block moment-content-box"> <span class="al"></span>
<div class="mt10 moment-content entry-content show-link-icon">
<?php if ($comments->parent) {echo getPermalinkFromCoid($comments->parent);} echo parse_smiley_shortcode($comments->content);?>
</div>
<div class="mt10 moment-footer p-flex-s-right">
<span class="t-sm c-sub">
<span class="mr-2"><i class="fa-regular fa-clock mr-1"></i><?php echo friendly_date($comments->created); ?></span>
</span>
</div>
</div>
</div>
</div>
</div>
<?php } ?>
<?php $this->comments()->to($comments); ?>
<?php if ($this->user->hasLogin() && $this->user->group == 'administrator') : ?>
<div class="p-block">
<input type="hidden" value="<?php $this->commentUrl() ?>">
<div>
<span class="t-lg border-bottom border-primary puock-text pb-2">
<i class="fa-regular fa-comments mr-1"></i>有什么新鲜事
</span>
</div>
<div class="mt20 clearfix" id="comment-form-box">
<form method="post" action="<?php $this->commentUrl() ?>" id="comment-form" class="mt10" role="form">
<div class="form-group">
<textarea rows="4" name="text" id="comment" class="form-control form-control-sm t-sm" placeholder="发表您的新鲜事儿..." required><?php $this->remember('text'); ?></textarea>
</div>
<input type="hidden" value="<?php $this->user->screenName(); ?>" name="author" />
<input type="hidden" value="<?php $this->user->mail(); ?>" name="mail" />
<input type="hidden" value="<?php $this->options->siteUrl(); ?>" name="url" />
<input type="hidden" name="_" value="<?php Typecho_Widget::widget('Widget_Security')->to($security);
echo $security->getToken($this->request->getRequestUrl()); ?>">
<div class="p-flex-sbc mt10">
<div class="form-foot">
<?php if($this->options->social): ?>
<button id="comment-insert-image" class="btn btn-outline-secondary btn-ssm" type="button" title="插入图片">
<i class="fa-solid fa-image"></i>
</button>
<button id="comment-smiley" class="btn btn-outline-secondary btn-ssm pk-modal-toggle" type="button" title="表情" data-once-load="true"
data-url="<?php echo get_correct_url('/emoji/'); ?>">
<i class="fa-regular fa-face-smile t-md"></i>
</button>
<?php endif; ?>
<button type="submit" class="btn btn-primary btn-ssm"><i class="fa-regular fa-paper-plane"></i> 立即发表</button>
</div>
</div>
</form>
</div>
</div>
<?php endif; ?>
<?php if ($comments->have()): ?>
<!-- 评论列表 -->
<?php while ($comments->next()): ?>
<?php threadedComments($comments, $this->options); ?>
<?php endwhile; ?>
<!-- 分页导航 -->
<div class="mt20 p-flex-s-right" data-no-instant>
<?php $comments->pageNav('&laquo;', '&raquo;', 1, '...', array(
'wrapTag' => 'ul',
'wrapClass' => 'pagination comment-ajax-load',
'itemTag' => 'li',
'textTag' => 'span',
'currentClass' => 'active',
'prevClass' => 'prev',
'nextClass' => 'next'
)); ?>
</div>
</div>
<?php endif; ?>
<?php if ($this->options->showsidebar): ?>
<?php $this->need('sidebar.php'); ?>
<?php endif; ?>
</div>
</div>
<?php $this->need('footer.php'); ?>
<script>
document.addEventListener('DOMContentLoaded', function() {
var btn = document.getElementById('comment-insert-image');
if (!btn) return;
btn.addEventListener('click', function() {
let modal = document.createElement('div');
modal.innerHTML = `
<style>
.insert-image {
position: fixed;
z-index: 9999;
left: 0;
top: 0;
width: 100vw;
height: 100vh;
background: rgba(211, 134, 202, 0.9);
display: flex;
align-items: center;
justify-content: center;
}
</style>
<div id="img-insert-modal" class="insert-image">
<div class="min-width-modal" style="max-width: 290px">
<form>
<div class="form-label">插入图片</div>
<div class="mb15">
<label for="img-insert-title" class="form-label">标题(可选)</label>
<input id="img-insert-title" type="text" class="form-control form-control-sm">
</div>
<div class="mb15">
<label for="img-insert-url" class="form-label">图片地址 <span style="color:red">*</span></label>
<input id="img-insert-url" type="text" class="form-control form-control-sm" required>
</div>
<div class="mb15 d-flex justify-content-center wh100">
<button id="img-insert-cancel" class="btn btn-ssm btn-primary mr5">取消</button>
<button id="img-insert-confirm" class="btn btn-ssm btn-primary mr5">插入</button>
</div>
</form>
</div>
</div>
`;
document.body.appendChild(modal);
document.getElementById('img-insert-cancel').onclick = function() {
document.body.removeChild(modal);
};
document.getElementById('img-insert-confirm').onclick = function() {
let url = document.getElementById('img-insert-url').value.trim();
let title = document.getElementById('img-insert-title').value.trim();
if (!url) {
alert('图片地址不能为空!');
return;
}
let tag = `<img src=\"${url}\"` + (title ? ` alt=\"${title}\" title=\"${title}\"` : '') + ` />`;
let textarea = document.getElementById('comment');
if (textarea) {
let start = textarea.selectionStart, end = textarea.selectionEnd;
let val = textarea.value;
textarea.value = val.substring(0, start) + tag + val.substring(end);
textarea.focus();
textarea.selectionStart = textarea.selectionEnd = start + tag.length;
}
document.body.removeChild(modal);
};
});
});
</script>
+9 -14
View File
@@ -16,20 +16,21 @@ if (!defined('__TYPECHO_ROOT_DIR__')) exit; ?>
</div>
<div id="page-tags">
<div id="page" class="row row-cols-1">
<?php if ($this->options->showsidebar): ?>
<div id="posts" class="col-lg-8 col-md-12 animated fadeInLeft">
<?php else: ?>
<div id="posts" class="col-lg-12 col-md-12">
<?php endif; ?>
<div class="puock-text p-block no-style pb-2">
<?php
// 获取所有标签
$tags = Typecho_Widget::widget('Widget_Metas_Tag_Cloud');
// 准备字母数组
$letters = range('A', 'Z');
$letters[] = '0';
$letters[] = '0';
// 获取所有存在的首字母
$existingLetters = array();
$tagsArray = array();
$tagsArray = array();
while ($tags->next()) {
$firstChar = getFirstChar($tags->name);
if (!in_array($firstChar, $existingLetters)) {
@@ -41,7 +42,6 @@ if (!defined('__TYPECHO_ROOT_DIR__')) exit; ?>
'count' => $tags->count
);
}
// 对每个字母下的标签按名称排序
foreach ($tagsArray as &$letterTags) {
usort($letterTags, function($a, $b) {
@@ -49,7 +49,6 @@ if (!defined('__TYPECHO_ROOT_DIR__')) exit; ?>
});
}
?>
<!-- 字母导航 -->
<ul class='pl-0' id='tags-main-index'>
<?php foreach ($letters as $letter): ?>
@@ -63,13 +62,11 @@ if (!defined('__TYPECHO_ROOT_DIR__')) exit; ?>
<li class='t'><?php echo $i; ?></li>
<?php endfor; ?>
</ul>
<!-- 标签列表 -->
<ul id='tags-main-box' class='pl-0'>
<?php
// 按字母顺序排序
ksort($tagsArray);
foreach ($tagsArray as $letter => $tags): ?>
<li class='n' id='<?php echo $letter; ?>'>
<h4 class='tag-name'><span class='t-lg c-sub'>#</span><?php echo $letter; ?></h4>
@@ -81,9 +78,7 @@ if (!defined('__TYPECHO_ROOT_DIR__')) exit; ?>
</ul>
</div>
</div>
<?php
?>
<?php if ($this->options->showsidebar): ?>
<?php $this->need('sidebar.php'); ?>
<?php $this->need('footer.php'); ?>
<?php endif; ?>
<?php $this->need('footer.php'); ?>
-168
View File
@@ -1,168 +0,0 @@
<?php
/**
* 说说页面
*
* @package custom
*/
if (!defined('__TYPECHO_ROOT_DIR__')) exit; ?>
<?php $this->need('header.php'); ?>
<div id="breadcrumb" class="animated fadeInUp">
<nav aria-label="breadcrumb">
<ol class="breadcrumb">
<li class="breadcrumb-item"><a class="a-link" href="<?php $this->options->siteUrl(); ?>">首页</a></li>
<li class="breadcrumb-item active " aria-current="page"><?php $this->title() ?></li>
</ol>
</nav>
<div id="page-moments">
<div class="row">
<div id="posts" class="col-lg-8 col-md-12 animated fadeInLeft ">
<?php $tooot = $this->fields->tooot ? $this->fields->tooot : 'https://www.imsun.org/toot.json'; ?>
<script src="https://cdnjs.cloudflare.com/ajax/libs/marked/15.0.12/marked.min.js" integrity="sha512-rCQgmUulW6f6QegOvTntKKb5IAoxTpGVCdWqYjkXEpzAns6XUFs8NKVqWe+KQpctp/EoRSFSuykVputqknLYMg==" crossorigin="anonymous" referrerpolicy="no-referrer"></script>
<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/lightbox2/2.11.5/css/lightbox.min.css" integrity="sha512-xtV3HfYNbQXS/1R1jP53KbFcU9WXiSA1RFKzl5hRlJgdOJm4OxHCWYpskm6lN0xp0XtKGpAfVShpbvlFH3MDAA==" crossorigin="anonymous" referrerpolicy="no-referrer" />
<script src="https://cdnjs.cloudflare.com/ajax/libs/lightbox2/2.11.5/js/lightbox.min.js" integrity="sha512-KbRFbjA5bwNan6DvPl1ODUolvTTZ/vckssnFhka5cG80JVa5zSlRPCr055xSgU/q6oMIGhZWLhcbgIC0fyw3RQ==" crossorigin="anonymous" referrerpolicy="no-referrer"></script>
<div id="tooot"></div>
</div>
<script>
function fetchAndDisplayToots() {
let offset = 0;
const limit = 20;
function formatHTML(toots) {
let htmlString = '';
toots.forEach(toot => {
const isReblog = toot.reblog && toot.reblog.content;
const content = isReblog ? toot.reblog.content : toot.content;
const url = isReblog ? toot.reblog.url : toot.url;
const account = isReblog ? toot.reblog.account : toot.account;
const created_at = isReblog ? toot.reblog.created_at : toot.created_at;
const media_attachments = isReblog ? toot.reblog.media_attachments : toot.media_attachments;
let mediaHTML = '';
if (media_attachments && media_attachments.length > 0) {
media_attachments.forEach(attachment => {
if (attachment.type === 'image') {
mediaHTML += `<a href="${attachment.url}" target="_blank" data-lightbox="image-set"><img src="${attachment.preview_url}" class="thumbnail-image img" ></a>`;
}
});
}
const htmlContent = marked.parse(content || '');
htmlString += `
<div class="mb20 puock-text moments-item">
<div class="row">
<div class="col-12 col-md-1">
<a class="meta ta3" href="${account.url}" target="_blank" rel="nofollow">
<div class="avatar mb10">
<img src='${account.avatar}'
class='lazy md-avatar mt-1'
data-src='${account.avatar}'
alt="${account.display_name}" title="${account.display_name}">
</div>
<div class="t-line-1 info fs12">${account.display_name}</div>
</a>
</div>
<div class="col-12 col-md-11">
<div class="p-block moment-content-box"> <span class="al"></span>
<div class="mt10 moment-content entry-content show-link-icon">
<p>${htmlContent}</p>
<div class="resimg">${mediaHTML}</div>
</div>
<div class="mt10 moment-footer p-flex-s-right"> <span class="t-sm c-sub">
<a class="c-sub-a" href="${url}">
<span class="mr-2"><i class="fa-regular fa-clock mr-1"></i>${new Date(created_at).toLocaleString()}</span>
</a>
</span>
</div>
</div>
</div>
</div>
</div>
`;
});
return htmlString;
}
function fetchToots() {
return fetch('<?php echo $tooot; ?>')
.then(response => response.json())
.catch(error => {
console.error('Error fetching toots:', error);
return [];
});
}
const memosContainer = document.getElementById('tooot');
if (memosContainer) memosContainer.innerHTML = '';
fetchToots().then(data => {
if (!Array.isArray(data)) {
console.error('toot.json is not an array:', data);
return;
}
const tootsToShow = data.slice(offset, offset + limit);
if (memosContainer) memosContainer.innerHTML += formatHTML(tootsToShow);
});
}
// 保证首次和 pjax 都能调用
if (document.readyState === "loading") {
document.addEventListener("DOMContentLoaded", fetchAndDisplayToots);
} else {
fetchAndDisplayToots();
}
document.addEventListener('pjax:end', fetchAndDisplayToots);
</script>
<style>
div pre code {
white-space: pre-wrap;
word-wrap: break-word;
overflow-wrap: break-word;
word-break: break-all;
word-break: break-word;
}
div p a {
word-break: break-all;
word-break: break-word;
}
.resimg {
display: grid;
grid-template-columns: repeat(3, 1fr);
column-gap: 10px;
row-gap: 10px;
}
/* 单个缩略图的样式 */
.thumbnail-image {
width: 100%; /* 确保其宽度填满父容器 */
height: 200px; /* 固定高度 */
display: flex; /* 使用 flexbox 居中 */
align-items: center; /* 垂直居中 */
justify-content: center; /* 水平居中 */
overflow: hidden; /* 确保容器内的多余内容不会显示出来 */
border-radius: 4px; /* 圆角 */
transition: transform .3s ease; /* 鼠标悬停时的过渡效果 */
cursor: zoom-in; /* 鼠标指针变为放大镜 */
}
img {
object-fit: cover; /* 保持图片的纵横比,但会将图片裁剪以填充容器 */
object-position: center; /* 保证中央部分 */
}
/* 缩略图内的图片样式 */
.thumbnail-image img {
width: 100%;
min-height: 200px;
}
/* 当屏幕宽度小于732px时 */
@media (max-width: 732px) {
.resimg {
grid-template-columns: repeat(2, 1fr); /* 修改为两列 */
}
}
/* 当屏幕宽度小于400px时 */
@media (max-width: 400px) {
.resimg {
grid-template-columns: 1fr; /* 修改为一列 */
}
.thumbnail-image img {
width: 100%;
height: 480px;
}
}
</style>
<?php $this->need('sidebar.php'); ?>
</div>
</div>
<?php $this->need('footer.php'); ?>
+6
View File
@@ -10,7 +10,11 @@
</div>
<div id="page-empty">
<div id="page" class="row row-cols-1">
<?php if ($this->options->showsidebar): ?>
<div id="post-main" class="col-lg-8 col-md-12 animated fadeInLeft ">
<?php else: ?>
<div id="post-main" class="col-lg-12 col-md-12">
<?php endif; ?>
<div class="p-block"><div>
<h1 id="post-title" class="mb-0 puock-text t-xxl"><?php $this->title() ?></h1>
</div>
@@ -60,5 +64,7 @@ if($days > 180){
<?php $this->need('comments.php'); ?>
<?php endif; ?>
</div>
<?php if ($this->options->showsidebar): ?>
<?php $this->need('sidebar.php'); ?>
<?php endif; ?>
<?php $this->need('footer.php'); ?>
+7 -1
View File
@@ -15,7 +15,11 @@
<div class="puock-text p-block t-md ad-page-top"><?php $this->options->articletop(); ?></div>
<?php endif; ?>
<div class="row row-cols-1 post-row">
<?php if ($this->options->showsidebar): ?>
<div id="post-main" class="col-lg-8 col-md-12 animated fadeInLeft ">
<?php else: ?>
<div id="post-main" class="col-lg-12 col-md-12">
<?php endif; ?>
<div class="p-block"><div>
<h1 id="post-title" class="mb-0 puock-text t-xxl"><?php $this->title() ?></h1>
</div>
@@ -52,7 +56,7 @@ $wordCount = mb_strlen($content, 'UTF-8');
?>
<div class="mt20 entry-content-box">
<div class="entry-content show-link-icon content-main puock-text ">
<p class="fs12 c-sub no-indent"> <i class="fa-regular fa-clock"></i> 共计<?php echo $wordCount; ?>个字符,预计需要花费 <?php echo ceil($wordCount / 800); ?>分钟才能阅读完成。 </p>
<p class="fs12 c-sub no-indent"> <i class="fa-regular fa-clock"></i> &nbsp;本文共计<?php echo $wordCount; ?>,预计需要花费 <?php echo ceil($wordCount / 800); ?>分钟才能阅读完成。 </p>
<p class="fs12 c-sub">
<?php
$modified = $this->modified;
@@ -216,5 +220,7 @@ if($days > 180){
<div class="puock-text p-block t-md ad-comment-top"><?php $this->options->articlefoot(); ?></div>
<?php endif; ?>
</div>
<?php if ($this->options->showsidebar): ?>
<?php $this->need('sidebar.php'); ?>
<?php endif; ?>
<?php $this->need('footer.php'); ?>
+10 -33
View File
@@ -18,57 +18,34 @@
</div>
<?php endif; ?>
<!-- 个人信息 -->
<?php
// 获取数据库连接
$db = Typecho_Db::get();
$prefix = $db->getPrefix();
// 1. 获取uid=1的用户信息
$user = $db->fetchRow($db->select()->from('table.users')->where('uid = ?', 1));
$email = $user['mail'];
$nickname = $user['screenName'];
// 获取用户设置的 Gravatar 镜像
$cnavatar = Helper::options()->cnavatar ? Helper::options()->cnavatar : 'https://cravatar.cn/avatar/';
$hash = md5($email);
$avatar = rtrim($cnavatar, '/') . '/' . $hash . '?s=80&d=identicon';
// 2. 获取用户总数
$userCount = $db->fetchObject($db->select(array('COUNT(*)' => 'num'))->from('table.users'))->num;
// 3. 获取文章总数(只统计 type='post' 且 status='publish'
$postCount = $db->fetchObject($db->select(array('COUNT(*)' => 'num'))->from('table.contents')->where('type = ?', 'post')->where('status = ?', 'publish'))->num;
// 4. 获取评论总数
$commentCount = $db->fetchObject($db->select(array('COUNT(*)' => 'num'))->from('table.comments'))->num;
// 5. 获取文章浏览总量(累加所有文章的 views 字段)
$totalViews = $db->fetchObject(
$db->select(array('SUM(views)' => 'viewsum'))->from('table.contents')->where('type = ?', 'post')
)->viewsum;
if ($totalViews === null) $totalViews = 0;
?>
<!-- 个人信息 -->
<?php $stats = get_site_statistics(); ?>
<?php if (!empty($this->options->sidebarBlock) && in_array('ShowAdmin', $this->options->sidebarBlock)): ?>
<div class="widget-puock-author widget">
<div class="header" style="background-image: url('<?php echo $this->options->bgUrl() ?: $this->options->themeUrl('assets/img/cover.png'); ?>')">
<img src='<?php $this->options->themeUrl('assets/img/load.svg'); ?>' class='lazy avatar' data-src='<?php echo $avatar; ?>' >
<div class="header" style="background-image: url('<?php echo !empty($this->options->bgUrl) ? $this->options->bgUrl : $this->options->themeUrl('assets/img/cover.png'); ?>')">
<img src='<?php $this->options->themeUrl('assets/img/load.svg'); ?>' class='lazy avatar' data-src='<?php echo $stats['avatar']; ?>' >
</div>
<div class="content t-md puock-text">
<div class="text-center p-2">
<div class="t-lg"><?php echo $nickname; ?></div>
<div class="t-lg"><?php echo $stats['nickname']; ?></div>
<div class="mt10 t-sm"><?php $this->options->description(); ?></div>
</div>
<div class="row mt10">
<div class="col-3 text-center">
<div class="c-sub t-sm">用户数</div>
<div><?php echo $userCount; ?></div>
<div><?php echo $stats['userCount']; ?></div>
</div>
<div class="col-3 text-center">
<div class="c-sub t-sm">文章数</div>
<div><?php echo $postCount; ?></div>
<div><?php echo $stats['postCount']; ?></div>
</div>
<div class="col-3 text-center">
<div class="c-sub t-sm">评论数</div>
<div><?php echo $commentCount; ?></div>
<div><?php echo $stats['commentCount']; ?></div>
</div>
<div class="col-3 text-center">
<div class="c-sub t-sm">阅读量</div>
<div><?php echo $totalViews; ?></div>
<div><?php echo $stats['totalViews']; ?></div>
</div>
</div>
</div>
@@ -132,7 +109,7 @@ if ($totalViews === null) $totalViews = 0;
<div class="pk-widget p-block">
<div>
<span class="t-lg border-bottom border-primary puock-text pb-2">
<i class="fa fa-chart-simple mr-1"></i>热门文章
<i class="fa-solid fa-fire"></i> 热门文章
</span>
</div>
<div class="mt20">