mirror of
https://github.com/jkjoy/typecho-theme-farallon.git
synced 2026-06-28 02:34:26 +00:00
Compare commits
16 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
| 33175a8951 | |||
| 0ed7e7b5e8 | |||
| 6f37575943 | |||
| 6b8f758dcf | |||
| 1f535bb9d6 | |||
| a42f5f41ca | |||
| 16e91b835e | |||
| 9671712412 | |||
| 4df85ae062 | |||
| a6883c5ce7 | |||
| 4dce3365b6 | |||
| 26e2c5b40c | |||
| c5eb0aa112 | |||
| cd3933ea53 | |||
| 482e9a1e93 | |||
| 13c3587762 |
@@ -1,3 +1,4 @@
|
||||
|
||||
tooot.php
|
||||
Parsedown.php
|
||||
/assets/images/covers
|
||||
|
||||
@@ -7,6 +7,23 @@
|
||||
|
||||
## 更新日志 & 预览
|
||||
|
||||
### 0.8
|
||||
|
||||
- 兼容 Typecho 1.3.0
|
||||
- 自动裁切封面并保存在主题目录 `usr/cache/covers` 下,使用前必须开启 `php` 的 `GD拓展` 和`usr`目录的写权限.
|
||||
- 站点统计
|
||||
|
||||
### 0.7.2
|
||||
|
||||
- ~~优化页面加载速度,自动裁切封面,并压缩为`webp`格式,并保存在主题目录`assets`-`images`-`covers`下,使用前必须开启`php`的`GD拓展`和主题目录的写入权限~~
|
||||
- 修复了置顶文章和翻页的问题
|
||||
|
||||
### 0.7.1
|
||||
|
||||
- 调整了赞赏的样式,同时填写支付宝和微信收款码的图片地址即可显示
|
||||
- 调整文章列表的加载方式
|
||||
- 调整了文件的结构
|
||||
|
||||
### 0.7.0
|
||||
|
||||
根据原版更新,修复了一些问题,并添加了一些功能
|
||||
@@ -32,7 +49,7 @@
|
||||
|
||||
|
||||
|
||||
[预览](https://www.imsun.org/)
|
||||
[预览](https://blog.imsun.org/)
|
||||
|
||||
https://www.imsun.org/archives/1640.html
|
||||
|
||||
|
||||
+3
-18
@@ -1,5 +1,5 @@
|
||||
<?php if (!defined('__TYPECHO_ROOT_DIR__')) exit; ?>
|
||||
<?php $this->need('module/header.php'); ?>
|
||||
<?php $this->need('header.php'); ?>
|
||||
<header class="archive--header">
|
||||
<h2 class="post--single__title">
|
||||
<?php $this->archiveTitle(array(
|
||||
@@ -37,25 +37,10 @@ $memosId = is_numeric($memosId) ? intval($memosId) : null;
|
||||
<?php $this->need('module/postlist.php'); ?>
|
||||
<?php endif; ?>
|
||||
<!-- 分页导航 -->
|
||||
<?php $this->pageNav(
|
||||
' ',
|
||||
' ',
|
||||
1,
|
||||
'...',
|
||||
array(
|
||||
'wrapTag' => 'nav',
|
||||
'wrapClass' => 'nav-links nav-links__comment',
|
||||
'itemTag' => '',
|
||||
'textTag' => 'span',
|
||||
'itemClass' => 'page-numbers',
|
||||
'currentClass' => 'page-numbers current',
|
||||
'prevClass' => 'hidden',
|
||||
'nextClass' => 'hidden'
|
||||
)
|
||||
); ?>
|
||||
<?php $this->need('module/paging.php'); ?>
|
||||
<?php else: ?>
|
||||
<!-- 无结果 -->
|
||||
<?php $this->need('module/notfound.php'); ?>
|
||||
<?php endif; ?>
|
||||
</div>
|
||||
<?php $this->need('module/footer.php'); ?>
|
||||
<?php $this->need('footer.php'); ?>
|
||||
@@ -1,146 +0,0 @@
|
||||
.donate-panel {
|
||||
position: relative;
|
||||
display: inline-block;
|
||||
}
|
||||
|
||||
.button--like {
|
||||
background: none;
|
||||
border: none;
|
||||
padding: 0;
|
||||
cursor: pointer;
|
||||
transition: transform 0.3s ease;
|
||||
}
|
||||
|
||||
.button--like:hover {
|
||||
transform: scale(1.1);
|
||||
}
|
||||
|
||||
.icon--default {
|
||||
fill: #666;
|
||||
transition: fill 0.3s ease;
|
||||
}
|
||||
|
||||
.button--like:hover .icon--default {
|
||||
fill: #ff4081;
|
||||
}
|
||||
|
||||
#qrcode-panel {
|
||||
position: absolute;
|
||||
bottom: 100%;
|
||||
left: 50%;
|
||||
transform: translateX(-50%);
|
||||
background: white;
|
||||
border-radius: 8px;
|
||||
box-shadow: 0 2px 10px rgba(0, 0, 0, 0.1);
|
||||
padding: 15px;
|
||||
margin-bottom: 10px;
|
||||
display: none;
|
||||
animation: fadeIn 0.3s ease;
|
||||
min-width: 240px;
|
||||
}
|
||||
|
||||
@keyframes fadeIn {
|
||||
from {
|
||||
opacity: 0;
|
||||
transform: translate(-50%, 10px);
|
||||
}
|
||||
to {
|
||||
opacity: 1;
|
||||
transform: translate(-50%, 0);
|
||||
}
|
||||
}
|
||||
|
||||
.qrcode-body {
|
||||
text-align: center;
|
||||
}
|
||||
|
||||
.donate-memo {
|
||||
margin-bottom: 10px;
|
||||
position: relative;
|
||||
}
|
||||
|
||||
#donate-close {
|
||||
position: absolute;
|
||||
right: -5px;
|
||||
top: -5px;
|
||||
cursor: pointer;
|
||||
font-size: 12px;
|
||||
color: #666;
|
||||
padding: 2px 5px;
|
||||
border-radius: 3px;
|
||||
}
|
||||
|
||||
#donate-close:hover {
|
||||
color: #ff4081;
|
||||
}
|
||||
|
||||
.donate-qrpay img {
|
||||
max-width: 240px;
|
||||
height: auto;
|
||||
display: block;
|
||||
margin: 0 auto;
|
||||
transition: opacity 0.3s ease;
|
||||
}
|
||||
|
||||
/* 支付方式切换按钮样式 */
|
||||
.donate-methods {
|
||||
display: flex;
|
||||
justify-content: center;
|
||||
margin-bottom: 15px;
|
||||
gap: 10px;
|
||||
}
|
||||
|
||||
.donate-method-btn {
|
||||
padding: 5px 15px;
|
||||
border: none;
|
||||
border-radius: 15px;
|
||||
cursor: pointer;
|
||||
background: #f5f5f5;
|
||||
color: #666;
|
||||
font-size: 14px;
|
||||
transition: all 0.3s ease;
|
||||
}
|
||||
|
||||
.donate-method-btn.active {
|
||||
background: #ff4081;
|
||||
color: white;
|
||||
}
|
||||
|
||||
.donate-method-btn:hover {
|
||||
background: #ff4081;
|
||||
color: white;
|
||||
}
|
||||
|
||||
/* QR码容器样式 */
|
||||
.qr-container {
|
||||
position: relative;
|
||||
height: 100%;
|
||||
width: 100%;
|
||||
margin: 0 auto;
|
||||
}
|
||||
|
||||
.qr-image {
|
||||
position: absolute;
|
||||
top: 0;
|
||||
left: 0;
|
||||
opacity: 0;
|
||||
visibility: hidden;
|
||||
transition: opacity 0.3s ease, visibility 0.3s ease;
|
||||
}
|
||||
|
||||
.qr-image.active {
|
||||
opacity: 1;
|
||||
visibility: visible;
|
||||
}
|
||||
|
||||
/* 小三角形 */
|
||||
#qrcode-panel:after {
|
||||
content: '';
|
||||
position: absolute;
|
||||
bottom: -8px;
|
||||
left: 50%;
|
||||
transform: translateX(-50%);
|
||||
border-left: 8px solid transparent;
|
||||
border-right: 8px solid transparent;
|
||||
border-top: 8px solid white;
|
||||
}
|
||||
+4
-3
@@ -17,7 +17,7 @@
|
||||
is_single = false;
|
||||
post_id = 0;
|
||||
is_archive = false;
|
||||
VERSION = "0.7.0";
|
||||
VERSION = "0.8";
|
||||
constructor() {
|
||||
super();
|
||||
this.initCopyright();
|
||||
@@ -45,8 +45,9 @@
|
||||
}
|
||||
}
|
||||
initCopyright() {
|
||||
const copyright = `<div class="site--footer__info">由<a href="https://www.typecho.org" target="_blank">Typecho</a> 驱动 <br>
|
||||
Theme <a href="https://fatesinger.com/101971" target="_blank">farallon</a> by bigfa <br>Made with<a href="https://www.imsun.org" target="_blank"> Sun</a> / version ${this.VERSION}
|
||||
const copyright = `<div class="site--footer__info">
|
||||
Theme <a href="https://github.com/jkjoy/typecho-theme-farallon" target="_blank">farallon</a> Designed by <a href="https://fatesinger.com/" target="_blank">bigfa</a>
|
||||
<p><a href="https://www.imsun.org" target="_blank"> 老孙博客</a> 移植 / version ${this.VERSION}</p>
|
||||
</div>`;
|
||||
document.querySelector(".site--footer__content").insertAdjacentHTML("afterend", copyright);
|
||||
document.querySelector(".icon--copryrights").addEventListener("click", () => {
|
||||
|
||||
@@ -1,65 +0,0 @@
|
||||
document.addEventListener('DOMContentLoaded', function() {
|
||||
const donateBtn = document.getElementById('donate-btn');
|
||||
const qrcodePanel = document.getElementById('qrcode-panel');
|
||||
const donateClose = document.getElementById('donate-close');
|
||||
const methodBtns = document.querySelectorAll('.donate-method-btn');
|
||||
const qrImages = document.querySelectorAll('.qr-image');
|
||||
let isVisible = false;
|
||||
|
||||
// 切换支付方式
|
||||
function switchPayMethod(method) {
|
||||
// 更新按钮状态
|
||||
methodBtns.forEach(btn => {
|
||||
btn.classList.remove('active');
|
||||
if (btn.dataset.method === method) {
|
||||
btn.classList.add('active');
|
||||
}
|
||||
});
|
||||
|
||||
// 更新二维码显示
|
||||
qrImages.forEach(img => {
|
||||
img.classList.remove('active');
|
||||
if (img.dataset.method === method) {
|
||||
img.classList.add('active');
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
// 点击打赏按钮切换二维码显示状态
|
||||
function toggleQRCode(event) {
|
||||
event.stopPropagation();
|
||||
isVisible = !isVisible;
|
||||
qrcodePanel.style.display = isVisible ? 'block' : 'none';
|
||||
}
|
||||
|
||||
// 点击关闭按钮隐藏二维码
|
||||
function hideQRCode(event) {
|
||||
event.stopPropagation();
|
||||
isVisible = false;
|
||||
qrcodePanel.style.display = 'none';
|
||||
}
|
||||
|
||||
// 点击二维码面板之外的地方隐藏二维码
|
||||
function handleDocumentClick(event) {
|
||||
if (isVisible && !qrcodePanel.contains(event.target) && !donateBtn.contains(event.target)) {
|
||||
isVisible = false;
|
||||
qrcodePanel.style.display = 'none';
|
||||
}
|
||||
}
|
||||
|
||||
// 绑定事件监听器
|
||||
donateBtn.addEventListener('click', toggleQRCode);
|
||||
donateClose.addEventListener('click', hideQRCode);
|
||||
document.addEventListener('click', handleDocumentClick);
|
||||
|
||||
// 绑定支付方式切换按钮事件
|
||||
methodBtns.forEach(btn => {
|
||||
btn.addEventListener('click', (e) => {
|
||||
const method = e.target.dataset.method;
|
||||
switchPayMethod(method);
|
||||
});
|
||||
});
|
||||
|
||||
// 初始化显示第一个支付方式
|
||||
switchPayMethod('wechat');
|
||||
});
|
||||
+19
-14
@@ -1,13 +1,13 @@
|
||||
document.addEventListener('click', function (e) {
|
||||
// 检查点击的元素是否是 .post-read-more a
|
||||
// 检查点击的元素是否是 .loadmore a
|
||||
if (e.target.closest('.loadmore a')) {
|
||||
e.preventDefault();
|
||||
var btn = e.target.closest('.loadmore a');
|
||||
var nextPage = btn.getAttribute('href');
|
||||
var nextPage = btn.getAttribute('href');
|
||||
// 防止重复点击
|
||||
if (btn.classList.contains('loading')) return false;
|
||||
btn.classList.add('loading');
|
||||
btn.textContent = '加载中...';
|
||||
btn.textContent = '加载中...';
|
||||
// 发起 AJAX 请求
|
||||
fetch(nextPage)
|
||||
.then(response => {
|
||||
@@ -19,18 +19,23 @@ document.addEventListener('click', function (e) {
|
||||
.then(data => {
|
||||
// 创建一个临时的 DOM 元素来解析返回的 HTML
|
||||
var parser = new DOMParser();
|
||||
var htmlDoc = parser.parseFromString(data, 'text/html');
|
||||
// 找到新的文章
|
||||
var newPosts = htmlDoc.querySelectorAll('.post--item');
|
||||
// 找到新的"加载更多"按钮
|
||||
var newBtn = htmlDoc.querySelector('.nav-links a');
|
||||
// 获取文章列表容器和加载更多按钮
|
||||
var postReadMore = document.querySelector('.nav-links');
|
||||
var articleList = document.querySelector('.articleList');
|
||||
var htmlDoc = parser.parseFromString(data, 'text/html');
|
||||
// 调试代码:检查选择器
|
||||
console.log('Searching for #loadpost:', htmlDoc.querySelectorAll('#loadpost'));
|
||||
console.log('Searching for .nav-links:', htmlDoc.querySelector('.nav-links'));
|
||||
// 找到新的文章和按钮
|
||||
var newPosts = htmlDoc.querySelectorAll('#loadpost');
|
||||
var newBtn = htmlDoc.querySelector('.nav-links a');
|
||||
// 更健壮的元素选择
|
||||
var articleList = document.querySelector('#loadposts') ||
|
||||
document.querySelector('.posts-container') ||
|
||||
document.body;
|
||||
var postReadMore = document.querySelector('.nav-links');
|
||||
if (newPosts.length > 0) {
|
||||
newPosts.forEach(post => {
|
||||
articleList.insertBefore(post, postReadMore);
|
||||
});
|
||||
// 使用 appendChild 替代 insertBefore
|
||||
articleList.appendChild(post);
|
||||
});
|
||||
// 新文章淡入效果
|
||||
Array.from(newPosts).forEach(post => {
|
||||
post.style.opacity = 0;
|
||||
@@ -39,7 +44,7 @@ document.addEventListener('click', function (e) {
|
||||
post.style.opacity = 1;
|
||||
}, 10);
|
||||
});
|
||||
}
|
||||
}
|
||||
// 更新"加载更多"按钮或移除它
|
||||
if (newBtn) {
|
||||
btn.setAttribute('href', newBtn.getAttribute('href'));
|
||||
|
||||
+1
-1
@@ -35,7 +35,7 @@ document.addEventListener('DOMContentLoaded', function() {
|
||||
});
|
||||
}
|
||||
// 给所有复制链接添加点击事件
|
||||
document.querySelectorAll('.text').forEach(link => {
|
||||
document.querySelectorAll('.copy').forEach(link => {
|
||||
link.addEventListener('click', function(e) {
|
||||
e.preventDefault();
|
||||
const textToCopy = this.getAttribute('data-copy') || this.textContent;
|
||||
|
||||
@@ -5,16 +5,17 @@
|
||||
<?php $this->need('./module/sns.php'); ?>
|
||||
<?php //sitemap填入
|
||||
if($this->options->sitemapurl): ?>
|
||||
<a href="<?php $this->options->sitemapurl() ?>" target="_blank" aria-label="网站地图">💗</a>
|
||||
<a href="<?php $this->options->sitemapurl() ?>" target="_blank" aria-label="网站地图"></a>
|
||||
<?php endif; ?>
|
||||
</div>
|
||||
<?php //添加加载时间控制
|
||||
if ($this->options->showtime): ?>
|
||||
页面加载耗时<?php echo timer_stop();?>
|
||||
<?php endif; ?>
|
||||
<?php $this->options->tongji(); ?>
|
||||
<div class="copyright"> © <?php echo date('Y'); ?>
|
||||
<?php $this->options->title(); ?>
|
||||
<?php $this->options->tongji(); ?>
|
||||
<?php $stats = getSiteStatsWithCache(); ?>
|
||||
<div class="copyright"> © <?php echo $stats['siteCreateYear']; ?>-<?php echo date('Y'); ?>
|
||||
<?php $this->options->title(); ?> 💗 由 <a href="https://www.typecho.org" target="_blank"> Typecho </a> 驱动
|
||||
<svg class="icon icon--copryrights" viewBox="0 0 1040 1024" width="16" height="16">
|
||||
<path
|
||||
d="M717.056236 383.936299l-51.226708 0c-28.2893 0-51.226708 22.936385-51.226708 51.225685l0 128.062678c0 28.2893 22.937408 51.225685 51.226708 51.225685l51.226708 0c28.2893 0 51.225685-22.936385 51.225685-51.225685L768.281921 435.161984C768.281921 406.872684 745.345536 383.936299 717.056236 383.936299zM717.056236 537.611308c0 14.158465-11.480472 25.612331-25.613354 25.612331-14.132882 0-25.612331-11.453866-25.612331-25.612331l0-76.835969c0-14.158465 11.480472-25.613354 25.612331-25.613354 14.133905 0 25.613354 11.453866 25.613354 25.613354L717.056236 537.611308zM1013.977739 426.580538 859.776751 165.30079c-8.888438-15.063067-22.294772-25.975605-37.57171-32.080649-32.708959-34.856879-79.187527-56.638975-130.762159-56.638975L332.862064 76.581166c-51.575656 0-98.0532 21.782096-130.761136 56.639998-15.276938 6.105045-28.683273 17.017582-37.572734 32.079626L10.327206 426.580538c-21.26021 36.069497-8.655124 82.217537 28.239158 103.028515l115.00836 64.967664 0 199.163015c0 99.024318 80.264045 153.678078 179.287339 153.678078l358.580818 0c99.024318 0 179.290409-80.266092 179.290409-179.290409L870.733291 594.575694l115.00836-64.966641C1022.63184 508.798075 1035.238972 462.650035 1013.977739 426.580538zM153.574724 536.518417l-67.058278-37.875632c-24.589025-13.907755-33.019021-44.647873-18.809391-68.684312l85.86767-145.555074L153.574724 536.518417zM646.620024 127.807874c0 56.5786-60.205197 102.45137-134.467551 102.45137-74.261331 0-134.466528-45.873794-134.466528-102.45137L646.620024 127.807874zM819.507606 742.515071c0 84.893482-68.810179 153.677055-153.678078 153.677055L358.475418 896.192126c-84.8679 0-153.675008-68.783573-153.675008-153.677055l0-461.030142c0-76.150354 55.402821-139.361001 128.093377-151.545508 1.332345 83.883479 81.06734 151.545508 179.258687 151.545508 98.19237 0 177.926342-67.662029 179.25971-151.545508 72.690556 12.183484 128.096447 75.394131 128.096447 151.545508L819.508629 742.515071zM937.791569 498.642784l-67.058278 37.875632 0-252.111948 85.86767 145.552004C970.807521 453.995935 962.377524 484.736053 937.791569 498.642784z"
|
||||
+485
-45
@@ -22,25 +22,30 @@ function themeConfig($form) {
|
||||
$form->addInput($twitterurl);
|
||||
$mastodonurl = new Typecho_Widget_Helper_Form_Element_Text('mastodonurl', NULL, NULL, _t('mastodon'), _t('会在个人信息显示'));
|
||||
$form->addInput($mastodonurl);
|
||||
$friendlyTime = new Typecho_Widget_Helper_Form_Element_Radio('friendlyTime',
|
||||
array('0' => _t('否'),
|
||||
'1' => _t('是')),
|
||||
'0', _t('是否显示友好时间'), _t('默认不显示友好时间,显示标准时间格式'));
|
||||
$form->addInput($friendlyTime);
|
||||
$showProfile = new Typecho_Widget_Helper_Form_Element_Radio('showProfile',
|
||||
array('0'=> _t('否'), '1'=> _t('是')),
|
||||
'0', _t('是否在文章页面显示作者信息'), _t('选择“是”将在文章页面包含显示作者信息。'));
|
||||
'0', _t('是否在文章页面显示作者信息'), _t('选择"是"将在文章页面包含显示作者信息。'));
|
||||
$form->addInput($showProfile);
|
||||
$showcate = new Typecho_Widget_Helper_Form_Element_Radio('showcate',
|
||||
array('0'=> _t('否'), '1'=> _t('是')),
|
||||
'0', _t('是否在文章页面显示文章分类'), _t('选择“是”将在文章页面显示文章的分类信息。'));
|
||||
'0', _t('是否在文章页面显示文章分类'), _t('选择"是"将在文章页面显示文章的分类信息。'));
|
||||
$form->addInput($showcate);
|
||||
$showrelated = new Typecho_Widget_Helper_Form_Element_Radio('showrelated',
|
||||
array('0'=> _t('否'), '1'=> _t('是')),
|
||||
'0', _t('是否显示相关文章'), _t('选择“是”将在文章页面显示相关文章。'));
|
||||
'0', _t('是否显示相关文章'), _t('选择"是"将在文章页面显示相关文章。'));
|
||||
$form->addInput($showrelated);
|
||||
$showshare = new Typecho_Widget_Helper_Form_Element_Radio('showshare',
|
||||
array('0'=> _t('否'), '1'=> _t('是')),
|
||||
'0', _t('是否显示复制链接'), _t('选择“是”将在文章页面显示复制链接。'));
|
||||
'0', _t('是否显示复制链接'), _t('选择"是"将在文章页面显示复制链接。'));
|
||||
$form->addInput($showshare);
|
||||
$showtime = new Typecho_Widget_Helper_Form_Element_Radio('showtime',
|
||||
array('0'=> _t('否'), '1'=> _t('是')),
|
||||
'0', _t('是否显示页面加载时间'), _t('选择“是”将在页脚显示加载时间。'));
|
||||
'0', _t('是否显示页面加载时间'), _t('选择"是"将在页脚显示加载时间。'));
|
||||
$form->addInput($showtime);
|
||||
$loadmore = new Typecho_Widget_Helper_Form_Element_Radio('loadmore',
|
||||
array('0'=> _t('加载更多'), '1'=> _t('页码模式')),
|
||||
@@ -52,8 +57,10 @@ function themeConfig($form) {
|
||||
$form->addInput($cnavatar);
|
||||
$midimg = new Typecho_Widget_Helper_Form_Element_Text('midimg', NULL, '/img/', _t('填写分类图片路径,以"/"结尾'), _t('默认使用网站根目录下的img文件夹,也可以填写绝对或者CDN地址,自动匹配目录下以分类ID为文件名的mid.jpg格式的图片'));
|
||||
$form->addInput($midimg);
|
||||
$donate = new Typecho_Widget_Helper_Form_Element_Text('donate', NULL, NULL, _t('赞赏二维码'), _t('不填写则不显示'));
|
||||
$form->addInput($donate);
|
||||
$wxpay = new Typecho_Widget_Helper_Form_Element_Text('wxpay', NULL, 'https://blog.loliko.cn/images/wechatpay.png', _t('微信收款码'), _t('赞赏二维码'));
|
||||
$form->addInput($wxpay);
|
||||
$alipay= new Typecho_Widget_Helper_Form_Element_Text('alipay', NULL, 'https://blog.loliko.cn/images/alipay.png', _t('支付宝收款码'), _t('赞赏二维码'));
|
||||
$form->addInput($alipay);
|
||||
$addhead = new Typecho_Widget_Helper_Form_Element_Textarea('addhead', NULL, NULL, _t('Head内代码用于网站验证等'), _t('支持HTML'));
|
||||
$form->addInput($addhead);
|
||||
$tongji = new Typecho_Widget_Helper_Form_Element_Textarea('tongji', NULL, NULL, _t('统计代码'), _t('支持HTML'));
|
||||
@@ -71,18 +78,6 @@ function themeFields($layout) {
|
||||
$layout->addItem($summary);
|
||||
$cover= new Typecho_Widget_Helper_Form_Element_Text('cover', NULL, NULL, _t('文章封面'), _t('自定义文章封面'));
|
||||
$layout->addItem($cover);
|
||||
// $douban= new Typecho_Widget_Helper_Form_Element_Text('douban', NULL, NULL, _t('豆瓣API'), _t('自定义页面豆瓣API'));
|
||||
// $layout->addItem($douban);
|
||||
//$neodb= new Typecho_Widget_Helper_Form_Element_Text('neodb', NULL, NULL, _t('NeoDB API'), _t('自定义页面NeoDB API'));
|
||||
//$layout->addItem($neodb);
|
||||
// $tooot= new Typecho_Widget_Helper_Form_Element_Text('tooot', NULL, NULL, _t('Mastodon API'), _t('自定义页面Mastodon API'));
|
||||
// $layout->addItem($tooot);
|
||||
// $memos= new Typecho_Widget_Helper_Form_Element_Text('memos', NULL, NULL, _t('Memos地址'), _t(' 自定义页面Memos地址'));
|
||||
// $layout->addItem($memos);
|
||||
// $memosID= new Typecho_Widget_Helper_Form_Element_Text('memosID', NULL, NULL, _t('Memos ID'), _t('自定义页面Memos ID'));
|
||||
// $layout->addItem($memosID);
|
||||
// $memosnum= new Typecho_Widget_Helper_Form_Element_Text('memosnum', NULL, NULL, _t('Memos数量'), _t('自定义页面Memos数量'));
|
||||
// $layout->addItem($memosnum);
|
||||
}
|
||||
|
||||
/*
|
||||
@@ -121,6 +116,17 @@ $options = Typecho_Widget::widget('Widget_Options');
|
||||
$gravatarPrefix = empty($options->cnavatar) ? 'https://cravatar.cn/avatar/' : $options->cnavatar;
|
||||
define('__TYPECHO_GRAVATAR_PREFIX__', $gravatarPrefix);
|
||||
|
||||
// 初始化主题
|
||||
function init_theme() {
|
||||
// 检查并创建封面图片目录
|
||||
$coversDir = __TYPECHO_ROOT_DIR__ . '/usr/cache/covers';
|
||||
if (!is_dir($coversDir)) {
|
||||
@mkdir($coversDir, 0755, true);
|
||||
}
|
||||
}
|
||||
// 在主题加载时执行初始化
|
||||
init_theme();
|
||||
|
||||
/**
|
||||
* 页面加载时间
|
||||
*/
|
||||
@@ -148,6 +154,19 @@ function timer_start() {
|
||||
*/
|
||||
function img_postthumb($cid) {
|
||||
$db = Typecho_Db::get();
|
||||
|
||||
// 首先检查是否设置了自定义封面
|
||||
$cover = $db->fetchRow($db->select('str_value')
|
||||
->from('table.fields')
|
||||
->where('cid = ?', $cid)
|
||||
->where('name = ?', 'cover'));
|
||||
|
||||
// 如果找到自定义封面,直接返回
|
||||
if ($cover && !empty($cover['str_value'])) {
|
||||
return $cover['str_value'];
|
||||
}
|
||||
|
||||
// 否则尝试从文章内容中获取第一张图片
|
||||
$rs = $db->fetchRow($db->select('table.contents.text')
|
||||
->from('table.contents')
|
||||
->where('table.contents.cid=?', $cid)
|
||||
@@ -178,20 +197,16 @@ function getPermalinkFromCoid($coid) {
|
||||
* 图片灯箱
|
||||
*/
|
||||
class ImageStructureProcessor {
|
||||
public static function processContent($content, $widget) {
|
||||
// 首先检查内容是否为空
|
||||
public static function processContent($content, $widget, $lastResult = null) {
|
||||
$content = empty($lastResult) ? $content : $lastResult;
|
||||
if (empty($content) || !is_string($content)) {
|
||||
return $content;
|
||||
}
|
||||
if ($widget instanceof Widget_Archive) {
|
||||
try {
|
||||
// 使用 DOM 操作确保结构完整性
|
||||
$dom = new DOMDocument('1.0', 'UTF-8');
|
||||
// 添加错误处理
|
||||
libxml_use_internal_errors(true);
|
||||
// 添加基础 HTML 结构以确保正确解析
|
||||
$content = '<!DOCTYPE html><html><head><meta charset="UTF-8"></head><body><div>' . $content . '</div></body></html>';
|
||||
// 直接加载内容到 DOM
|
||||
$dom->loadHTML($content,
|
||||
LIBXML_HTML_NOIMPLIED |
|
||||
LIBXML_HTML_NODEFDTD |
|
||||
@@ -199,7 +214,6 @@ class ImageStructureProcessor {
|
||||
LIBXML_NOWARNING
|
||||
);
|
||||
$xpath = new DOMXPath($dom);
|
||||
// 查找所有没有父 figure 的图片,排除 SVG
|
||||
$images = $xpath->query("//img[not(ancestor::figure) and not(contains(@src, '.svg'))]");
|
||||
if ($images->length > 0) {
|
||||
foreach ($images as $img) {
|
||||
@@ -246,15 +260,125 @@ class ImageStructureProcessor {
|
||||
} catch (Exception $e) {
|
||||
// 记录错误但返回原始内容
|
||||
error_log('Image processing error: ' . $e->getMessage());
|
||||
return $content;
|
||||
// 如果发生错误,返回上一个过滤器结果或原始内容
|
||||
return empty($lastResult) ? $content : $lastResult;
|
||||
}
|
||||
}
|
||||
return $content;
|
||||
}
|
||||
}
|
||||
Typecho_Plugin::factory('Widget_Abstract_Contents')->contentEx = function($content, $widget) {
|
||||
return ImageStructureProcessor::processContent($content, $widget);
|
||||
};
|
||||
|
||||
/**
|
||||
* 处理图片为封面图(裁剪为5:3,最大宽度500px,转换为webp)
|
||||
*
|
||||
* @param string $imageUrl 原始图片URL
|
||||
* @return string 处理后的图片URL
|
||||
*/
|
||||
function process_cover_image($imageUrl) {
|
||||
// 检查GD库是否可用
|
||||
if (!function_exists('imagecreatetruecolor')) {
|
||||
return $imageUrl; // 如果GD库不可用,返回原图
|
||||
}
|
||||
|
||||
// 分析URL
|
||||
$parsed = parse_url($imageUrl);
|
||||
|
||||
// 如果图片是外部链接,需要下载
|
||||
$isExternalUrl = !empty($parsed['host']) && $parsed['host'] !== $_SERVER['HTTP_HOST'];
|
||||
|
||||
// 生成唯一的文件名(使用MD5哈希)
|
||||
$filename = md5($imageUrl) . '.webp';
|
||||
|
||||
// 处理后图片的保存路径
|
||||
$savePath = __TYPECHO_ROOT_DIR__ . '/usr/cache/covers/' . $filename;
|
||||
$webPath = Helper::options()->siteUrl . '/usr/cache/covers/' . $filename;
|
||||
|
||||
// 如果缓存文件已存在,直接返回
|
||||
if (file_exists($savePath)) {
|
||||
return $webPath;
|
||||
}
|
||||
|
||||
// 获取原始图片内容
|
||||
if ($isExternalUrl) {
|
||||
// 外部图片,需要下载
|
||||
$imageContent = @file_get_contents($imageUrl);
|
||||
if (!$imageContent) {
|
||||
return $imageUrl; // 无法下载,返回原图
|
||||
}
|
||||
} else {
|
||||
// 本地图片
|
||||
$localPath = $_SERVER['DOCUMENT_ROOT'] . $parsed['path'];
|
||||
if (!file_exists($localPath)) {
|
||||
return $imageUrl; // 无法找到本地文件,返回原图
|
||||
}
|
||||
$imageContent = @file_get_contents($localPath);
|
||||
}
|
||||
|
||||
// 创建图像资源
|
||||
$originalImage = @imagecreatefromstring($imageContent);
|
||||
if (!$originalImage) {
|
||||
return $imageUrl; // 无法创建图像资源,返回原图
|
||||
}
|
||||
|
||||
// 获取原始图片尺寸
|
||||
$originalWidth = imagesx($originalImage);
|
||||
$originalHeight = imagesy($originalImage);
|
||||
|
||||
// 计算目标尺寸(5:3比例,最大宽度500px)
|
||||
$targetWidth = min(500, $originalWidth);
|
||||
$targetHeight = intval($targetWidth * 3 / 5);
|
||||
|
||||
// 计算裁剪坐标(居中裁剪)
|
||||
$cropX = 0;
|
||||
$cropY = 0;
|
||||
$cropWidth = $originalWidth;
|
||||
$cropHeight = $originalHeight;
|
||||
|
||||
// 计算比例
|
||||
$originalRatio = $originalWidth / $originalHeight;
|
||||
$targetRatio = 5 / 3;
|
||||
|
||||
if ($originalRatio > $targetRatio) {
|
||||
// 原图过宽,需要裁剪宽度
|
||||
$cropWidth = intval($originalHeight * $targetRatio);
|
||||
$cropX = intval(($originalWidth - $cropWidth) / 2);
|
||||
} else {
|
||||
// 原图过高,需要裁剪高度
|
||||
$cropHeight = intval($originalWidth / $targetRatio);
|
||||
$cropY = intval(($originalHeight - $cropHeight) / 2);
|
||||
}
|
||||
|
||||
// 创建目标图像
|
||||
$targetImage = imagecreatetruecolor($targetWidth, $targetHeight);
|
||||
|
||||
// 裁剪并调整大小
|
||||
imagecopyresampled(
|
||||
$targetImage,
|
||||
$originalImage,
|
||||
0, 0,
|
||||
$cropX, $cropY,
|
||||
$targetWidth, $targetHeight,
|
||||
$cropWidth, $cropHeight
|
||||
);
|
||||
|
||||
// 保存为webp格式
|
||||
if (!function_exists('imagewebp')) {
|
||||
// 如果不支持webp,保存为png
|
||||
$filename = md5($imageUrl) . '.png';
|
||||
$savePath = __TYPECHO_ROOT_DIR__ . '/usr/cache/covers/' . $filename;
|
||||
$webPath = Helper::options()->siteUrl . '/usr/cache/covers/' . $filename;
|
||||
imagepng($targetImage, $savePath, 9); // 9是最高压缩质量
|
||||
} else {
|
||||
// 保存为webp
|
||||
imagewebp($targetImage, $savePath, 80); // 80是质量参数
|
||||
}
|
||||
|
||||
// 释放资源
|
||||
imagedestroy($originalImage);
|
||||
imagedestroy($targetImage);
|
||||
|
||||
return $webPath;
|
||||
}
|
||||
|
||||
/**
|
||||
* *获取文章卡片
|
||||
@@ -262,23 +386,60 @@ Typecho_Plugin::factory('Widget_Abstract_Contents')->contentEx = function($conte
|
||||
*
|
||||
*/
|
||||
function get_article_summary($post) {
|
||||
// 首先尝试从自定义字段获取摘要
|
||||
// 优先从自定义字段获取摘要
|
||||
$db = Typecho_Db::get();
|
||||
// 查询自定义字段表
|
||||
$row = $db->fetchRow($db->select()
|
||||
$row = $db->fetchRow($db->select('str_value')
|
||||
->from('table.fields')
|
||||
->where('cid = ?', $post['cid'])
|
||||
->where('name = ?', 'summary'));
|
||||
// 如果找到自定义摘要字段
|
||||
|
||||
if ($row && !empty($row['str_value'])) {
|
||||
return $row['str_value'];
|
||||
}
|
||||
// 如果没有自定义摘要,截取文章内容
|
||||
// 去除HTML标签
|
||||
// 确保自定义摘要不超过 100 字节
|
||||
$text = $row['str_value'];
|
||||
$byte_limit = 280;
|
||||
$summary = '';
|
||||
$byte_count = 0;
|
||||
$length = mb_strlen($text, 'UTF-8');
|
||||
|
||||
for ($i = 0; $i < $length; $i++) {
|
||||
$char = mb_substr($text, $i, 1, 'UTF-8');
|
||||
$char_bytes = strlen($char);
|
||||
if ($byte_count + $char_bytes > $byte_limit) {
|
||||
break;
|
||||
}
|
||||
$summary .= $char;
|
||||
$byte_count += $char_bytes;
|
||||
}
|
||||
return $summary;
|
||||
}
|
||||
|
||||
// 没有自定义摘要,处理文章内容
|
||||
if (empty($post['text']) || !is_string($post['text'])) {
|
||||
return '';
|
||||
}
|
||||
|
||||
$text = strip_tags($post['text']);
|
||||
|
||||
// 截取指定长度的摘要
|
||||
return Typecho_Common::subStr($text, 0, 100, '...');
|
||||
$byte_limit = 277; // 预留 3 字节给省略号
|
||||
$summary = '';
|
||||
$byte_count = 0;
|
||||
$length = mb_strlen($text, 'UTF-8');
|
||||
|
||||
for ($i = 0; $i < $length; $i++) {
|
||||
$char = mb_substr($text, $i, 1, 'UTF-8');
|
||||
$char_bytes = strlen($char);
|
||||
if ($byte_count + $char_bytes > $byte_limit) {
|
||||
break;
|
||||
}
|
||||
$summary .= $char;
|
||||
$byte_count += $char_bytes;
|
||||
}
|
||||
|
||||
// 如果截断了,添加省略号
|
||||
if ($byte_count < strlen($text)) {
|
||||
$summary .= '...';
|
||||
}
|
||||
|
||||
return $summary;
|
||||
}
|
||||
// 在原函数中使用
|
||||
function get_article_info($atts) {
|
||||
@@ -307,6 +468,9 @@ function get_article_info($atts) {
|
||||
$imageToDisplay = img_postthumb($post['cid']);
|
||||
if (empty($imageToDisplay)) {
|
||||
$imageToDisplay = $default_thumbnail;
|
||||
} else {
|
||||
// 处理封面图片
|
||||
$imageToDisplay = process_cover_image($imageToDisplay);
|
||||
}
|
||||
// 构建输出
|
||||
$output = '<div class="graph--mixtapeEmbed">';
|
||||
@@ -325,11 +489,16 @@ class ContentFilter
|
||||
{
|
||||
// 首先运行之前的过滤器结果
|
||||
$content = empty($lastResult) ? $content : $lastResult;
|
||||
|
||||
// 处理图片灯箱
|
||||
$content = ImageStructureProcessor::processContent($content, $widget, $content);
|
||||
|
||||
// 然后处理我们的文章短代码
|
||||
$content = preg_replace_callback('/\[article\s+([^\]]+)\]/', function($matches) {
|
||||
$atts = self::parse_atts($matches[1]);
|
||||
return get_article_info($atts);
|
||||
}, $content);
|
||||
|
||||
return $content;
|
||||
}
|
||||
// 解析短代码属性
|
||||
@@ -354,8 +523,6 @@ class ContentFilter
|
||||
return $atts;
|
||||
}
|
||||
}
|
||||
// 注册钩子
|
||||
Typecho_Plugin::factory('Widget_Abstract_Contents')->contentEx = array('ContentFilter', 'filterContent');
|
||||
// 编辑器按钮类
|
||||
class EditorButton {
|
||||
public static function render()
|
||||
@@ -387,8 +554,11 @@ EOF;
|
||||
}
|
||||
}
|
||||
// 注册编辑器按钮钩子
|
||||
Typecho_Plugin::factory('admin/write-post.php')->bottom = array('EditorButton', 'render');
|
||||
Typecho_Plugin::factory('admin/write-page.php')->bottom = array('EditorButton', 'render');
|
||||
// 避免重复注册,在最后执行
|
||||
if (!Typecho_Plugin::exists('Widget_Abstract_Contents', 'editor')) {
|
||||
Typecho_Plugin::factory('admin/write-post.php')->bottom = array('EditorButton', 'render');
|
||||
Typecho_Plugin::factory('admin/write-page.php')->bottom = array('EditorButton', 'render');
|
||||
}
|
||||
|
||||
/**
|
||||
* 评论者认证等级 + 身份
|
||||
@@ -459,4 +629,274 @@ function commentApprove($widget, $email = NULL)
|
||||
$result['commentNum'] = $commentNum;
|
||||
}
|
||||
return $result;
|
||||
}
|
||||
|
||||
/**
|
||||
* Typecho后台附件增强:图片预览、批量插入、保留官方删除按钮与逻辑
|
||||
* @author 老孙博客
|
||||
* @date 2025-04-25
|
||||
*/
|
||||
Typecho_Plugin::factory('admin/write-post.php')->bottom = array('AttachmentHelper', 'addEnhancedFeatures');
|
||||
Typecho_Plugin::factory('admin/write-page.php')->bottom = array('AttachmentHelper', 'addEnhancedFeatures');
|
||||
|
||||
class AttachmentHelper {
|
||||
public static function addEnhancedFeatures() {
|
||||
?>
|
||||
<style>
|
||||
#file-list{display:grid;grid-template-columns:repeat(auto-fill,minmax(200px,1fr));gap:15px;padding:15px;list-style:none;margin:0;}
|
||||
#file-list li{position:relative;border:1px solid #e0e0e0;border-radius:4px;padding:10px;background:#fff;transition:all 0.3s ease;list-style:none;margin:0;}
|
||||
#file-list li:hover{box-shadow:0 2px 8px rgba(0,0,0,0.1);}
|
||||
#file-list li.loading{opacity:0.7;pointer-events:none;}
|
||||
.att-enhanced-thumb{position:relative;width:100%;height:150px;margin-bottom:8px;background:#f5f5f5;overflow:hidden;border-radius:3px;display:flex;align-items:center;justify-content:center;}
|
||||
.att-enhanced-thumb img{width:100%;height:100%;object-fit:contain;display:block;}
|
||||
.att-enhanced-thumb .file-icon{display:flex;align-items:center;justify-content:center;width:100%;height:100%;font-size:40px;color:#999;}
|
||||
.att-enhanced-finfo{padding:5px 0;}
|
||||
.att-enhanced-fname{font-size:13px;margin-bottom:5px;word-break:break-all;color:#333;}
|
||||
.att-enhanced-fsize{font-size:12px;color:#999;}
|
||||
.att-enhanced-factions{display:flex;justify-content:space-between;align-items:center;margin-top:8px;gap:8px;}
|
||||
.att-enhanced-factions button{flex:1;padding:4px 8px;border:none;border-radius:3px;background:#e0e0e0;color:#333;cursor:pointer;font-size:12px;transition:all 0.2s ease;}
|
||||
.att-enhanced-factions button:hover{background:#d0d0d0;}
|
||||
.att-enhanced-factions .btn-insert{background:#467B96;color:white;}
|
||||
.att-enhanced-factions .btn-insert:hover{background:#3c6a81;}
|
||||
.att-enhanced-checkbox{position:absolute;top:5px;right:5px;z-index:2;width:18px;height:18px;cursor:pointer;}
|
||||
.batch-actions{margin:15px;display:flex;gap:10px;align-items:center;}
|
||||
.btn-batch{padding:8px 15px;border-radius:4px;border:none;cursor:pointer;transition:all 0.3s ease;font-size:10px;display:inline-flex;align-items:center;justify-content:center;}
|
||||
.btn-batch.primary{background:#467B96;color:white;}
|
||||
.btn-batch.primary:hover{background:#3c6a81;}
|
||||
.btn-batch.secondary{background:#e0e0e0;color:#333;}
|
||||
.btn-batch.secondary:hover{background:#d0d0d0;}
|
||||
.upload-progress{position:absolute;bottom:0;left:0;width:100%;height:2px;background:#467B96;transition:width 0.3s ease;}
|
||||
</style>
|
||||
<script>
|
||||
$(document).ready(function() {
|
||||
// 批量操作UI按钮
|
||||
var $batchActions = $('<div class="batch-actions"></div>')
|
||||
.append('<button type="button" class="btn-batch primary" id="batch-insert">批量插入</button>')
|
||||
.append('<button type="button" class="btn-batch secondary" id="select-all">全选</button>')
|
||||
.append('<button type="button" class="btn-batch secondary" id="unselect-all">取消全选</button>');
|
||||
$('#file-list').before($batchActions);
|
||||
|
||||
// 插入格式
|
||||
Typecho.insertFileToEditor = function(title, url, isImage) {
|
||||
var textarea = $('#text'),
|
||||
sel = textarea.getSelection(),
|
||||
insertContent = isImage ? '' :
|
||||
'[' + title + '](' + url + ')';
|
||||
textarea.replaceSelection(insertContent + '\n');
|
||||
textarea.focus();
|
||||
};
|
||||
|
||||
// 批量插入
|
||||
$('#batch-insert').on('click', function(e) {
|
||||
e.preventDefault();
|
||||
e.stopPropagation();
|
||||
var content = '';
|
||||
$('#file-list li').each(function() {
|
||||
if ($(this).find('.att-enhanced-checkbox').is(':checked')) {
|
||||
var $li = $(this);
|
||||
var title = $li.find('.att-enhanced-fname').text();
|
||||
var url = $li.data('url');
|
||||
var isImage = $li.data('image') == 1;
|
||||
content += isImage ? '\n' : '[' + title + '](' + url + ')\n';
|
||||
}
|
||||
});
|
||||
if (content) {
|
||||
var textarea = $('#text');
|
||||
var pos = textarea.getSelection();
|
||||
var newContent = textarea.val();
|
||||
newContent = newContent.substring(0, pos.start) + content + newContent.substring(pos.end);
|
||||
textarea.val(newContent);
|
||||
textarea.focus();
|
||||
}
|
||||
});
|
||||
|
||||
$('#select-all').on('click', function(e) {
|
||||
e.preventDefault();
|
||||
e.stopPropagation();
|
||||
$('#file-list .att-enhanced-checkbox').prop('checked', true);
|
||||
return false;
|
||||
});
|
||||
$('#unselect-all').on('click', function(e) {
|
||||
e.preventDefault();
|
||||
e.stopPropagation();
|
||||
$('#file-list .att-enhanced-checkbox').prop('checked', false);
|
||||
return false;
|
||||
});
|
||||
|
||||
// 防止复选框冒泡
|
||||
$(document).on('click', '.att-enhanced-checkbox', function(e) {e.stopPropagation();});
|
||||
|
||||
// 增强文件列表样式,但不破坏li原结构和官方按钮
|
||||
function enhanceFileList() {
|
||||
$('#file-list li').each(function() {
|
||||
var $li = $(this);
|
||||
if ($li.hasClass('att-enhanced')) return;
|
||||
$li.addClass('att-enhanced');
|
||||
// 只增强,不清空li
|
||||
// 增加批量选择框
|
||||
if ($li.find('.att-enhanced-checkbox').length === 0) {
|
||||
$li.prepend('<input type="checkbox" class="att-enhanced-checkbox" />');
|
||||
}
|
||||
// 增加图片预览(如已有则不重复加)
|
||||
if ($li.find('.att-enhanced-thumb').length === 0) {
|
||||
var url = $li.data('url');
|
||||
var isImage = $li.data('image') == 1;
|
||||
var fileName = $li.find('.insert').text();
|
||||
var $thumbContainer = $('<div class="att-enhanced-thumb"></div>');
|
||||
if (isImage) {
|
||||
var $img = $('<img src="' + url + '" alt="' + fileName + '" />');
|
||||
$img.on('error', function() {
|
||||
$(this).replaceWith('<div class="file-icon">🖼️</div>');
|
||||
});
|
||||
$thumbContainer.append($img);
|
||||
} else {
|
||||
$thumbContainer.append('<div class="file-icon">📄</div>');
|
||||
}
|
||||
// 插到插入按钮之前
|
||||
$li.find('.insert').before($thumbContainer);
|
||||
}
|
||||
|
||||
});
|
||||
}
|
||||
|
||||
// 插入按钮事件
|
||||
$(document).on('click', '.btn-insert', function(e) {
|
||||
e.preventDefault();
|
||||
e.stopPropagation();
|
||||
var $li = $(this).closest('li');
|
||||
var title = $li.find('.att-enhanced-fname').text();
|
||||
Typecho.insertFileToEditor(title, $li.data('url'), $li.data('image') == 1);
|
||||
});
|
||||
|
||||
// 上传完成后增强新项
|
||||
var originalUploadComplete = Typecho.uploadComplete;
|
||||
Typecho.uploadComplete = function(attachment) {
|
||||
setTimeout(function() {
|
||||
enhanceFileList();
|
||||
}, 200);
|
||||
if (typeof originalUploadComplete === 'function') {
|
||||
originalUploadComplete(attachment);
|
||||
}
|
||||
};
|
||||
|
||||
// 首次增强
|
||||
enhanceFileList();
|
||||
});
|
||||
</script>
|
||||
<?php
|
||||
}
|
||||
}
|
||||
?>
|
||||
<?php
|
||||
/**
|
||||
* 友好时间显示函数
|
||||
* @param int $time 时间戳
|
||||
* @param int $threshold 阈值(秒),超过此值则显示标准日期格式(Y-m-d)
|
||||
* @return string
|
||||
*/
|
||||
function time_ago($time, $threshold = 31536000) { // 31536000秒 = 1年
|
||||
$now = time();
|
||||
$difference = $now - $time;
|
||||
|
||||
// 如果时间差超过阈值(默认1年),则返回标准日期格式(不带时间)
|
||||
if ($difference >= $threshold) {
|
||||
return date('Y-m-d', $time);
|
||||
}
|
||||
|
||||
// 1年以内的时间,返回友好格式(如 "3天前")
|
||||
$periods = array("秒", "分钟", "小时", "天", "周", "个月", "年");
|
||||
$lengths = array("60", "60", "24", "7", "4.35", "12");
|
||||
|
||||
for ($j = 0; $difference >= $lengths[$j] && $j < count($lengths); $j++) {
|
||||
$difference /= $lengths[$j];
|
||||
}
|
||||
|
||||
$difference = round($difference);
|
||||
return $difference . $periods[$j] . "前";
|
||||
}
|
||||
|
||||
/***
|
||||
* 获取站点统计信息(带缓存)
|
||||
*/
|
||||
function getSiteStatsWithCache() {
|
||||
$cacheFile = __TYPECHO_ROOT_DIR__ . '/usr/cache/site_stats.cache';
|
||||
$cacheTime = 3600; // 1小时缓存
|
||||
$currentVersion = '1.1'; // 当前版本号
|
||||
|
||||
// 检查缓存
|
||||
if (file_exists($cacheFile)) {
|
||||
$cacheData = json_decode(file_get_contents($cacheFile), true);
|
||||
if ($cacheData &&
|
||||
isset($cacheData['cache_time']) &&
|
||||
time() - $cacheData['cache_time'] < $cacheTime &&
|
||||
isset($cacheData['cache_version']) &&
|
||||
$cacheData['cache_version'] === $currentVersion) {
|
||||
return $cacheData;
|
||||
}
|
||||
}
|
||||
|
||||
$db = Typecho_Db::get();
|
||||
$stats = [];
|
||||
|
||||
// 1. 总分类数
|
||||
$stats['totalCategories'] = $db->fetchObject($db->select('COUNT(*) AS cnt')
|
||||
->from('table.metas')
|
||||
->where('type = ?', 'category'))->cnt;
|
||||
|
||||
// 2. 总标签数
|
||||
$stats['totalTags'] = $db->fetchObject($db->select('COUNT(*) AS cnt')
|
||||
->from('table.metas')
|
||||
->where('type = ?', 'tag'))->cnt;
|
||||
|
||||
// 3. 总文章数
|
||||
$stats['totalPosts'] = $db->fetchObject($db->select('COUNT(*) AS cnt')
|
||||
->from('table.contents')
|
||||
->where('type = ?', 'post')
|
||||
->where('status = ?', 'publish'))->cnt;
|
||||
|
||||
// 4. 总文章字数
|
||||
$stats['totalWords'] = $db->fetchObject($db->select('SUM(LENGTH(text)) AS total')
|
||||
->from('table.contents')
|
||||
->where('type = ?', 'post')
|
||||
->where('status = ?', 'publish'))->total ?: 0;
|
||||
|
||||
// 5. 建站时间
|
||||
$oldestPost = $db->fetchObject($db->select('MIN(created) AS created')
|
||||
->from('table.contents')
|
||||
->where('type = ?', 'post')
|
||||
->where('status = ?', 'publish'));
|
||||
|
||||
if ($oldestPost && !empty($oldestPost->created)) {
|
||||
$stats['siteCreationDate'] = date('Y-m-d', $oldestPost->created);
|
||||
$stats['siteCreateYear'] = date('Y', $oldestPost->created);
|
||||
$stats['siteDays'] = ceil((time() - $oldestPost->created) / 86400);
|
||||
} else {
|
||||
$stats['siteCreationDate'] = 'N/A';
|
||||
$stats['siteCreateYear'] = 'N/A';
|
||||
$stats['siteDays'] = 0;
|
||||
}
|
||||
|
||||
// 6. 友情链接数量
|
||||
$stats['totalLinks'] = 0;
|
||||
if (class_exists('Links_Plugin')) {
|
||||
$stats['totalLinks'] = $db->fetchObject($db->select('COUNT(*) AS cnt')
|
||||
->from('table.links'))->cnt ?: 0;
|
||||
}
|
||||
|
||||
// 7. 总留言数量
|
||||
$stats['totalComments'] = $db->fetchObject($db->select('COUNT(*) AS cnt')
|
||||
->from('table.comments')
|
||||
->where('status != ?', 'spam'))->cnt;
|
||||
|
||||
// 保存缓存
|
||||
$stats['cache_time'] = time();
|
||||
$stats['cache_version'] = $currentVersion; // 设置版本号
|
||||
if (!is_dir(dirname($cacheFile))) {
|
||||
mkdir(dirname($cacheFile), 0755, true);
|
||||
}
|
||||
if (!file_put_contents($cacheFile, json_encode($stats))) {
|
||||
error_log('Failed to write site stats cache to ' . $cacheFile);
|
||||
}
|
||||
|
||||
return $stats;
|
||||
}
|
||||
@@ -39,42 +39,37 @@ if (!defined('__TYPECHO_ROOT_DIR__')) exit; ?>
|
||||
</script>
|
||||
<div class="main">
|
||||
<header class="site--header">
|
||||
<?php if ($this->options->logoUrl): ?>
|
||||
<a href="<?php $this->options->siteUrl(); ?>" class="site--url">
|
||||
<img src="<?php $this->options->logoUrl() ?>" class="avatar" alt="<?php $this->options->title() ?>" />
|
||||
</a>
|
||||
<span class="u-xs-show">
|
||||
<a href="<?php $this->options->siteUrl(); ?>"><?php $this->options->title() ?></a>
|
||||
</span>
|
||||
<?php else: ?>
|
||||
<span class="u-xs-show">
|
||||
<a href="<?php $this->options->siteUrl(); ?>"><?php $this->options->title() ?></a>
|
||||
</span>
|
||||
<?php endif; ?>
|
||||
<div class="site--header__center">
|
||||
<div class="inner">
|
||||
<nav>
|
||||
<ul>
|
||||
<?php $this->widget('Widget_Contents_Page_List')->to($pages); ?>
|
||||
<?php while($pages->next()): ?>
|
||||
<?php if ($this->options->logoUrl): ?>
|
||||
<a href="<?php $this->options->siteUrl(); ?>" class="site--url">
|
||||
<img src="<?php $this->options->logoUrl() ?>" class="avatar" alt="<?php $this->options->title() ?>" />
|
||||
</a>
|
||||
<span class="u-xs-show">
|
||||
<a href="<?php $this->options->siteUrl(); ?>"><?php $this->options->title() ?></a>
|
||||
</span>
|
||||
<?php else: ?>
|
||||
<span class="u-xs-show">
|
||||
<a href="<?php $this->options->siteUrl(); ?>"><?php $this->options->title() ?></a>
|
||||
</span>
|
||||
<?php endif; ?>
|
||||
<div class="site--header__center">
|
||||
<div class="inner">
|
||||
<nav>
|
||||
<ul>
|
||||
<?php $this->widget('Widget_Contents_Page_List')->to($pages); ?>
|
||||
<?php while($pages->next()): ?>
|
||||
<li><a <?php if($this->is('page', $pages->slug)): ?> class="current"<?php endif; ?> href="<?php $pages->permalink(); ?>" title="<?php $pages->title(); ?>"><?php $pages->title(); ?></a></li>
|
||||
<?php endwhile; ?>
|
||||
</ul>
|
||||
</nav>
|
||||
<!-- 这年头谁会用站内的搜索啊 -->
|
||||
<div class="search--area">
|
||||
<?php endwhile; ?>
|
||||
</ul>
|
||||
</nav>
|
||||
<div class="search--area">
|
||||
<form id="search" method="post" action="./" role="search" class="search-form">
|
||||
<label>
|
||||
<input type="text" name="s" class="search-field text" placeholder="Search" required/>
|
||||
</label>
|
||||
<button type="submit" class="search-submit submit">搜索</button>
|
||||
</form>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<svg class="svgIcon" width="25" height="25" data-action="show-search">
|
||||
<path
|
||||
d="M20.067 18.933l-4.157-4.157a6 6 0 1 0-.884.884l4.157 4.157a.624.624 0 1 0 .884-.884zM6.5 11c0-2.62 2.13-4.75 4.75-4.75S16 8.38 16 11s-2.13 4.75-4.75 4.75S6.5 13.62 6.5 11z">
|
||||
</path>
|
||||
</svg>
|
||||
</header>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<svg class="svgIcon" width="25" height="25" data-action="show-search"><path d="M20.067 18.933l-4.157-4.157a6 6 0 1 0-.884.884l4.157 4.157a.624.624 0 1 0 .884-.884zM6.5 11c0-2.62 2.13-4.75 4.75-4.75S16 8.38 16 11s-2.13 4.75-4.75 4.75S6.5 13.62 6.5 11z"></path></svg>
|
||||
</header>
|
||||
@@ -1,130 +1,21 @@
|
||||
<?php
|
||||
/**
|
||||
* 一款单栏主题. 移植自HUGO主题 Farallon 原作者 bigfa
|
||||
* 一款单栏主题.
|
||||
* 移植自HUGO主题 <a href="https://github.com/bigfa/Farallon">Farallon</a>
|
||||
* 原作者 bigfa
|
||||
* * 适配Typecho 1.3.0
|
||||
* @package Farallon
|
||||
* @author 老孙
|
||||
* @version 0.7.0
|
||||
* @version 0.8
|
||||
* @link https://www.imsun.org
|
||||
*/
|
||||
// 确保退出安全
|
||||
if (!defined('__TYPECHO_ROOT_DIR__')) exit;
|
||||
/** 文章置顶 */
|
||||
$sticky = $this->options->sticky; // 置顶的文章id,多个用|隔开
|
||||
$db = Typecho_Db::get();
|
||||
$pageSize = $this->options->pageSize;
|
||||
if ($sticky && !empty(trim($sticky))) {
|
||||
$sticky_cids = array_filter(explode('|', $sticky)); // 分割文本并过滤空值
|
||||
if (!empty($sticky_cids)) {
|
||||
$sticky_html = " <span class='sticky--post'> 置顶 </span> "; // 置顶标题的 html
|
||||
// 清空原有文章的队列
|
||||
$this->row = [];
|
||||
$this->stack = [];
|
||||
$this->length = 0;
|
||||
// 获取总数,并排除置顶文章数量
|
||||
if (isset($this->currentPage) && $this->currentPage == 1) {
|
||||
$totalOriginal = $this->getTotal();
|
||||
$stickyCount = count($sticky_cids);
|
||||
$this->setTotal(max($totalOriginal - $stickyCount, 0));
|
||||
// 构建置顶文章的查询
|
||||
$selectSticky = $this->select()->where('type = ?', 'post');
|
||||
foreach ($sticky_cids as $i => $cid) {
|
||||
if ($i == 0)
|
||||
$selectSticky->where('cid = ?', $cid);
|
||||
else
|
||||
$selectSticky->orWhere('cid = ?', $cid);
|
||||
}
|
||||
// 获取置顶文章
|
||||
$stickyPosts = $db->fetchAll($selectSticky);
|
||||
// 压入置顶文章到文章队列
|
||||
foreach ($stickyPosts as &$stickyPost) {
|
||||
$stickyPost['title'] .= $sticky_html;
|
||||
$this->push($stickyPost);
|
||||
}
|
||||
$standardPageSize = $pageSize - count($stickyPosts);
|
||||
} else {
|
||||
$standardPageSize = $pageSize;
|
||||
}
|
||||
// 构建正常文章查询,排除置顶文章
|
||||
$selectNormal = $this->select()
|
||||
->where('type = ?', 'post')
|
||||
->where('status = ?', 'publish')
|
||||
->where('created < ?', time())
|
||||
->order('created', Typecho_Db::SORT_DESC)
|
||||
->page(isset($this->currentPage) ? $this->currentPage : 1, $standardPageSize);
|
||||
foreach ($sticky_cids as $cid) {
|
||||
$selectNormal->where('table.contents.cid != ?', $cid);
|
||||
}
|
||||
} else {
|
||||
// 如果sticky_cids为空,使用默认查询
|
||||
$selectNormal = $this->select()
|
||||
->where('type = ?', 'post')
|
||||
->where('status = ?', 'publish')
|
||||
->where('created < ?', time())
|
||||
->order('created', Typecho_Db::SORT_DESC)
|
||||
->page(isset($this->currentPage) ? $this->currentPage : 1, $pageSize);
|
||||
}
|
||||
} else {
|
||||
// 如果没有置顶文章,使用默认查询
|
||||
$selectNormal = $this->select()
|
||||
->where('type = ?', 'post')
|
||||
->where('status = ?', 'publish')
|
||||
->where('created < ?', time())
|
||||
->order('created', Typecho_Db::SORT_DESC)
|
||||
->page(isset($this->currentPage) ? $this->currentPage : 1, $pageSize);
|
||||
}
|
||||
// 登录用户显示私密文章
|
||||
if ($this->user->hasLogin()) {
|
||||
$uid = $this->user->uid;
|
||||
if ($uid) {
|
||||
$selectNormal->orWhere('authorId = ? AND status = ?', $uid, 'private');
|
||||
}
|
||||
}
|
||||
$normalPosts = $db->fetchAll($selectNormal);
|
||||
// 如果之前没有清空队列(没有置顶文章的情况),现在清空
|
||||
if (empty($sticky) || empty(trim($sticky)) || empty($sticky_cids)) {
|
||||
$this->row = [];
|
||||
$this->stack = [];
|
||||
$this->length = 0;
|
||||
}
|
||||
// 压入正常文章到文章队列
|
||||
foreach ($normalPosts as $normalPost) {
|
||||
$this->push($normalPost);
|
||||
}
|
||||
?>
|
||||
<?php $this->need('module/header.php');?>
|
||||
if (!defined('__TYPECHO_ROOT_DIR__')) exit; ?>
|
||||
<?php $this->need('module/sticky.php'); ?>
|
||||
<?php $this->need('header.php');?>
|
||||
<main class="site--main">
|
||||
<div class="articleList">
|
||||
<?php $this->need('module/postlist.php'); ?>
|
||||
<?php if ($this->options->loadmore): ?>
|
||||
<?php
|
||||
$this->pageNav(
|
||||
' ',
|
||||
' ',
|
||||
1,
|
||||
'...',
|
||||
array(
|
||||
'wrapTag' => 'nav',
|
||||
'wrapClass' => 'nav-links nav-links__comment',
|
||||
'itemTag' => '',
|
||||
'textTag' => 'span',
|
||||
'itemClass' => 'page-numbers',
|
||||
'currentClass' => 'page-numbers current',
|
||||
'prevClass' => 'hidden',
|
||||
'nextClass' => 'hidden'
|
||||
)
|
||||
);
|
||||
?>
|
||||
<?php else:?>
|
||||
<?php
|
||||
$nextPage = $this->_currentPage + 1;
|
||||
$totalPages = ceil($this->getTotal() / $this->parameter->pageSize);
|
||||
if ($this->_currentPage < $totalPages): ?>
|
||||
<div class="nav-links">
|
||||
<span class="loadmore"><?php $this->pageLink('加载更多', 'next'); ?></span>
|
||||
<div class="articleList">
|
||||
<?php $this->need('module/postlist.php'); ?>
|
||||
<?php $this->need('module/paging.php'); ?>
|
||||
</div>
|
||||
<?php endif; ?>
|
||||
<script src="<?php $this->options->themeUrl('assets/js/loadmore.js'); ?>"></script>
|
||||
<?php endif; ?>
|
||||
</div>
|
||||
</main>
|
||||
<?php $this->need('module/footer.php'); ?>
|
||||
<?php $this->need('footer.php'); ?>
|
||||
+5
-3
@@ -1,12 +1,13 @@
|
||||
<?php if (!defined('__TYPECHO_ROOT_DIR__')) exit; ?>
|
||||
<div id="loadposts">
|
||||
<?php while($this->next()): ?>
|
||||
<article class="post--item post--item__status" itemtype="http://schema.org/Article" itemscope="itemscope">
|
||||
<article id="loadpost" class="post--item post--item__status" itemtype="http://schema.org/Article" itemscope="itemscope">
|
||||
<div class="content">
|
||||
<header>
|
||||
<img src="<?php $this->options->logoUrl() ?>" class="avatar" width="48" height="48" />
|
||||
<a datetime='<?php $this->date('Y-m-d'); ?>' class="humane--time" href="<?php $this->permalink() ?>"
|
||||
itemprop="datePublished">
|
||||
<?php $this->date('Y-m-d'); ?>
|
||||
<?php $options = Helper::options();if ($options->friendlyTime == '1') {echo time_ago($this->created);} else {$this->date('Y-m-d H:i'); }?>
|
||||
</a>
|
||||
</header>
|
||||
<div class="description" itemprop="about">
|
||||
@@ -14,4 +15,5 @@
|
||||
</div>
|
||||
</div>
|
||||
</article>
|
||||
<?php endwhile; ?>
|
||||
<?php endwhile; ?>
|
||||
</div>
|
||||
@@ -0,0 +1,31 @@
|
||||
<?php if ($this->options->loadmore): ?>
|
||||
<?php
|
||||
$this->pageNav(
|
||||
' ',
|
||||
' ',
|
||||
1,
|
||||
'...',
|
||||
array(
|
||||
'wrapTag' => 'nav',
|
||||
'wrapClass' => 'nav-links',
|
||||
'itemTag' => '',
|
||||
'textTag' => 'span',
|
||||
'itemClass' => 'page-numbers',
|
||||
'currentClass' => 'page-numbers current',
|
||||
'prevClass' => 'hidden',
|
||||
'nextClass' => 'hidden'
|
||||
)
|
||||
);
|
||||
?>
|
||||
<?php else:?>
|
||||
<?php
|
||||
$nextPage = $this->_currentPage + 1;
|
||||
$totalPages = ceil($this->getTotal() / $this->parameter->pageSize);
|
||||
if ($this->_currentPage < $totalPages):
|
||||
?>
|
||||
<div class="nav-links">
|
||||
<span class="loadmore"><?php $this->pageLink('加载更多', 'next'); ?></span>
|
||||
</div>
|
||||
<script src="<?php $this->options->themeUrl('assets/js/loadmore.js'); ?>"></script>
|
||||
<?php endif; ?>
|
||||
<?php endif; ?>
|
||||
+13
-8
@@ -1,10 +1,10 @@
|
||||
<div id="loadposts">
|
||||
<?php while($this->next()): ?>
|
||||
<?php
|
||||
// 获取当前文章的分类
|
||||
$categories = $this->categories;
|
||||
$memosMid = $this->options->memos; // 获取主题设置中的说说分类 mid
|
||||
$isMemos = false;
|
||||
|
||||
// 检查当前文章是否属于说说分类
|
||||
foreach ($categories as $category) {
|
||||
if ($category['mid'] == $memosMid) {
|
||||
@@ -12,30 +12,32 @@
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
// 根据是否为说说分类使用不同的显示模板
|
||||
if ($isMemos):
|
||||
?>
|
||||
<div id="loadpost">
|
||||
<article class="post--item post--item__status" itemtype="http://schema.org/Article" itemscope="itemscope">
|
||||
<div class="content">
|
||||
<header>
|
||||
<img src="<?php $this->options->logoUrl() ?>" class="avatar" width="48" height="48" />
|
||||
<a datetime='<?php $this->date('Y-m-d'); ?>' class="humane--time" href="<?php $this->permalink() ?>"
|
||||
itemprop="datePublished">
|
||||
<?php $this->date('Y-m-d'); ?>
|
||||
<?php $options = Helper::options();if ($options->friendlyTime == '1') {echo time_ago($this->created);} else {$this->date('Y-m-d H:i'); }?>
|
||||
</a>
|
||||
</header>
|
||||
<div class="description" itemprop="about">
|
||||
<?php $this->excerpt(200, '...'); ?>
|
||||
</div>
|
||||
</div>
|
||||
</article>
|
||||
</article>
|
||||
</div>
|
||||
<?php else: ?>
|
||||
<article class="post--item">
|
||||
<div id="loadpost">
|
||||
<article class="post--item" id="loadpost">
|
||||
<div class="content">
|
||||
<h2 class="post--title">
|
||||
<a href="<?php $this->permalink() ?>">
|
||||
<?php $this->title() ?>
|
||||
<?php $this->title() ?><?php if (isset($this->isSticky) && $this->isSticky): ?><?php echo $this->stickyHtml; ?><?php endif; ?>
|
||||
<?php if((time() - $this->created) < 60*60*24*3): ?>
|
||||
<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24" fill="none"
|
||||
class="icon--sticky" stroke="currentColor" stroke-width="2" stroke-linecap="round"
|
||||
@@ -56,7 +58,7 @@
|
||||
<div class="meta">
|
||||
<svg class="icon" viewBox="0 0 1024 1024" width="16" height="16"><path d="M512 97.52381c228.912762 0 414.47619 185.563429 414.47619 414.47619s-185.563429 414.47619-414.47619 414.47619S97.52381 740.912762 97.52381 512 283.087238 97.52381 512 97.52381z m0 73.142857C323.486476 170.666667 170.666667 323.486476 170.666667 512s152.81981 341.333333 341.333333 341.333333 341.333333-152.81981 341.333333-341.333333S700.513524 170.666667 512 170.666667z m36.571429 89.697523v229.86362h160.865523v73.142857H512a36.571429 36.571429 0 0 1-36.571429-36.571429V260.388571h73.142858z"></path></svg>
|
||||
<time>
|
||||
<?php $this->date('Y-m-d'); ?>
|
||||
<?php $options = Helper::options();if ($options->friendlyTime == '1') {echo time_ago($this->created);} else {$this->date('Y-m-d H:i'); }?>
|
||||
</time>
|
||||
<svg class="icon" viewBox="0 0 1024 1024" width="16" height="16"><path d="M408.551619 97.52381a73.142857 73.142857 0 0 1 51.736381 21.430857L539.306667 197.973333A73.142857 73.142857 0 0 0 591.067429 219.428571H804.571429a73.142857 73.142857 0 0 1 73.142857 73.142858v560.761904a73.142857 73.142857 0 0 1-73.142857 73.142857H219.428571a73.142857 73.142857 0 0 1-73.142857-73.142857V170.666667a73.142857 73.142857 0 0 1 73.142857-73.142857h189.123048z m0 73.142857H219.428571v682.666666h585.142858V292.571429h-213.504a146.285714 146.285714 0 0 1-98.499048-38.13181L487.619048 249.734095 408.551619 170.666667zM365.714286 633.904762v73.142857h-73.142857v-73.142857h73.142857z m365.714285 0v73.142857H414.47619v-73.142857h316.952381z m-365.714285-195.047619v73.142857h-73.142857v-73.142857h73.142857z m365.714285 0v73.142857H414.47619v-73.142857h316.952381z"></path></svg>
|
||||
<?php $this->category(','); ?>
|
||||
@@ -73,11 +75,14 @@
|
||||
$cover = $this->fields->cover;
|
||||
$imageToDisplay = !empty($cover) ? $cover : $firstImage;
|
||||
if($imageToDisplay):
|
||||
$imageToDisplay = process_cover_image($imageToDisplay);
|
||||
?>
|
||||
<a href="<?php $this->permalink() ?>" class="cover--link">
|
||||
<img src="<?php echo $imageToDisplay; ?>" alt="<?php $this->title() ?>" class="cover" itemprop="image"/>
|
||||
</a>
|
||||
<?php endif; ?>
|
||||
</article>
|
||||
</div>
|
||||
<?php endif; ?>
|
||||
<?php endwhile; ?>
|
||||
<?php endwhile; ?>
|
||||
</div>
|
||||
+3
-1
@@ -1,8 +1,9 @@
|
||||
<?php if (!defined('__TYPECHO_ROOT_DIR__')) exit; ?>
|
||||
<div class="related--content">
|
||||
<?php $this->related(6)->to($relatedPosts); ?>
|
||||
<?php if ($relatedPosts->have()): ?>
|
||||
<h3 class="related--posts__title">相关文章</h3>
|
||||
<div class="post--single__related">
|
||||
<?php $this->related(6)->to($relatedPosts); ?>
|
||||
<?php while ($relatedPosts->next()): ?>
|
||||
<div class="post--single__related__item">
|
||||
<a href="<?php $relatedPosts->permalink(); ?>">
|
||||
@@ -18,4 +19,5 @@
|
||||
</div>
|
||||
<?php endwhile; ?>
|
||||
</div>
|
||||
<?php endif; ?>
|
||||
</div>
|
||||
@@ -0,0 +1,124 @@
|
||||
<?php if (!defined('__TYPECHO_ROOT_DIR__')) exit;
|
||||
$sticky = $this->options->sticky;
|
||||
$db = Typecho_Db::get();
|
||||
$pageSize = $this->options->pageSize;
|
||||
if ($sticky && !empty(trim($sticky))) {
|
||||
$sticky_cids = array_filter(explode('|', $sticky));
|
||||
if (!empty($sticky_cids)) {
|
||||
$sticky_html = " <span class='sticky--post'> 置顶 </span>";
|
||||
// 保存原始对象状态
|
||||
$originalRows = $this->row;
|
||||
$originalStack = $this->stack;
|
||||
$originalLength = $this->length;
|
||||
$totalOriginal = $this->getTotal();
|
||||
// 重置当前对象状态
|
||||
$this->row = [];
|
||||
$this->stack = [];
|
||||
$this->length = 0;
|
||||
// 关键修改:不再减少总文章数
|
||||
// 保持原始总数,这样分页逻辑不会受影响
|
||||
// $this->setTotal(max($totalOriginal - $stickyCount, 0));
|
||||
if (isset($this->currentPage) && $this->currentPage == 1) {
|
||||
// 查询置顶文章
|
||||
$selectSticky = $this->select()->where('type = ?', 'post');
|
||||
foreach ($sticky_cids as $i => $cid) {
|
||||
if ($i == 0)
|
||||
$selectSticky->where('cid = ?', $cid);
|
||||
else
|
||||
$selectSticky->orWhere('cid = ?', $cid);
|
||||
}
|
||||
$stickyPosts = $db->fetchAll($selectSticky);
|
||||
|
||||
// 添加置顶文章到结果集
|
||||
foreach ($stickyPosts as &$stickyPost) {
|
||||
$stickyPost['isSticky'] = true;
|
||||
$stickyPost['stickyHtml'] = $sticky_html;
|
||||
$this->push($stickyPost);
|
||||
}
|
||||
|
||||
// 计算当前页应显示的普通文章数量
|
||||
$standardPageSize = $pageSize - count($stickyPosts);
|
||||
|
||||
// 确保第一页不会显示太多文章
|
||||
if ($standardPageSize <= 0) {
|
||||
$standardPageSize = 0; // 如果置顶文章已经填满或超过一页,则不显示普通文章
|
||||
}
|
||||
} else {
|
||||
// 非第一页显示正常数量的文章
|
||||
$standardPageSize = $pageSize;
|
||||
}
|
||||
// 查询普通文章
|
||||
if ($this->currentPage == 1) {
|
||||
// 第一页需要排除置顶文章并限制数量
|
||||
$selectNormal = $this->select()
|
||||
->where('type = ?', 'post')
|
||||
->where('status = ?', 'publish')
|
||||
->where('created < ?', time());
|
||||
|
||||
// 排除所有置顶文章
|
||||
foreach ($sticky_cids as $cid) {
|
||||
$selectNormal->where('table.contents.cid != ?', $cid);
|
||||
}
|
||||
|
||||
$selectNormal->order('created', Typecho_Db::SORT_DESC)
|
||||
->limit($standardPageSize)
|
||||
->offset(0);
|
||||
} else {
|
||||
// 非第一页的查询
|
||||
// 计算正确的偏移量:(当前页码-1) * 每页数量 - 置顶文章数
|
||||
// 这样可以确保不会漏掉文章
|
||||
$offset = ($this->currentPage - 1) * $pageSize - count($sticky_cids);
|
||||
$offset = max($offset, 0); // 确保偏移量不为负
|
||||
|
||||
$selectNormal = $this->select()
|
||||
->where('type = ?', 'post')
|
||||
->where('status = ?', 'publish')
|
||||
->where('created < ?', time());
|
||||
|
||||
// 排除所有置顶文章
|
||||
foreach ($sticky_cids as $cid) {
|
||||
$selectNormal->where('table.contents.cid != ?', $cid);
|
||||
}
|
||||
|
||||
$selectNormal->order('created', Typecho_Db::SORT_DESC)
|
||||
->limit($pageSize)
|
||||
->offset($offset);
|
||||
}
|
||||
} else {
|
||||
// 没有有效的置顶文章ID,正常查询
|
||||
$selectNormal = $this->select()
|
||||
->where('type = ?', 'post')
|
||||
->where('status = ?', 'publish')
|
||||
->where('created < ?', time())
|
||||
->order('created', Typecho_Db::SORT_DESC)
|
||||
->page(isset($this->currentPage) ? $this->currentPage : 1, $pageSize);
|
||||
}
|
||||
} else {
|
||||
// 没有设置置顶文章,正常查询
|
||||
$selectNormal = $this->select()
|
||||
->where('type = ?', 'post')
|
||||
->where('status = ?', 'publish')
|
||||
->where('created < ?', time())
|
||||
->order('created', Typecho_Db::SORT_DESC)
|
||||
->page(isset($this->currentPage) ? $this->currentPage : 1, $pageSize);
|
||||
}
|
||||
// 添加私有文章查询条件
|
||||
if ($this->user->hasLogin()) {
|
||||
$uid = $this->user->uid;
|
||||
if ($uid) {
|
||||
$selectNormal->orWhere('authorId = ? AND status = ?', $uid, 'private');
|
||||
}
|
||||
}
|
||||
// 获取普通文章
|
||||
$normalPosts = $db->fetchAll($selectNormal);
|
||||
// 如果没有置顶文章或在前面的代码中没有重置对象状态,则在这里重置
|
||||
if (empty($sticky) || empty(trim($sticky)) || empty($sticky_cids)) {
|
||||
$this->row = [];
|
||||
$this->stack = [];
|
||||
$this->length = 0;
|
||||
}
|
||||
// 将普通文章添加到结果集
|
||||
foreach ($normalPosts as $normalPost) {
|
||||
$this->push($normalPost);
|
||||
}
|
||||
?>
|
||||
+8
-4
@@ -1,5 +1,5 @@
|
||||
<?php if (!defined('__TYPECHO_ROOT_DIR__')) exit; ?>
|
||||
<div class="post--cards">
|
||||
<div class="post--cards" id="loadposts">
|
||||
<?php while($this->next()): ?>
|
||||
<?php // 获取文章图片
|
||||
$default_thumbnail = Helper::options()->themeUrl . '/assets/images/nopic.svg';
|
||||
@@ -12,8 +12,11 @@
|
||||
if (empty($imageToDisplay)) {
|
||||
$imageToDisplay = $firstImage;
|
||||
}
|
||||
if (!empty($imageToDisplay) && $imageToDisplay != $default_thumbnail) {
|
||||
$imageToDisplay = process_cover_image($imageToDisplay);
|
||||
}
|
||||
?>
|
||||
<article class="post--card">
|
||||
<article class="post--card" id="loadpost">
|
||||
<img src="<?php echo $imageToDisplay; ?>" alt="<?php $this->title() ?>" class="cover" itemprop="image"/>
|
||||
<div class="content">
|
||||
<h2 class="post--title">
|
||||
@@ -29,9 +32,10 @@
|
||||
<path d="M512 97.52381c228.912762 0 414.47619 185.563429 414.47619 414.47619s-185.563429 414.47619-414.47619 414.47619S97.52381 740.912762 97.52381 512 283.087238 97.52381 512 97.52381z m0 73.142857C323.486476 170.666667 170.666667 323.486476 170.666667 512s152.81981 341.333333 341.333333 341.333333 341.333333-152.81981 341.333333-341.333333S700.513524 170.666667 512 170.666667z m36.571429 89.697523v229.86362h160.865523v73.142857H512a36.571429 36.571429 0 0 1-36.571429-36.571429V260.388571h73.142858z"></path>
|
||||
</svg>
|
||||
<time datetime='<?php $this->date('Y-m-d'); ?>' class="humane--time">
|
||||
<?php $this->date('Y-m-d'); ?>
|
||||
<?php $options = Helper::options();if ($options->friendlyTime == '1') {echo time_ago($this->created);} else {$this->date('Y-m-d H:i'); }?>
|
||||
</time>
|
||||
</div>
|
||||
</div>
|
||||
</article>
|
||||
<?php endwhile; ?>
|
||||
<?php endwhile; ?>
|
||||
</div>
|
||||
+2
-2
@@ -5,7 +5,7 @@
|
||||
* @package custom
|
||||
*/
|
||||
if (!defined('__TYPECHO_ROOT_DIR__')) exit; ?>
|
||||
<?php $this->need('./module/header.php'); ?>
|
||||
<?php $this->need('header.php'); ?>
|
||||
<section class="site--main">
|
||||
<header class="archive--header">
|
||||
<h1 class="post--single__title"><?php $this->title() ?></h1>
|
||||
@@ -57,4 +57,4 @@ if (!defined('__TYPECHO_ROOT_DIR__')) exit; ?>
|
||||
?>
|
||||
</div>
|
||||
</section>
|
||||
<?php $this->need('./module/footer.php'); ?>
|
||||
<?php $this->need('footer.php'); ?>
|
||||
+2
-2
@@ -5,7 +5,7 @@
|
||||
* @package custom
|
||||
*/
|
||||
if (!defined('__TYPECHO_ROOT_DIR__')) exit; ?>
|
||||
<?php $this->need('./module/header.php'); ?>
|
||||
<?php $this->need('header.php'); ?>
|
||||
<div class="site--main">
|
||||
<header class="archive--header">
|
||||
<h1 class="post--single__title"><?php $this->title() ?></h1>
|
||||
@@ -33,4 +33,4 @@ if (!defined('__TYPECHO_ROOT_DIR__')) exit; ?>
|
||||
<?php endwhile; ?>
|
||||
</section>
|
||||
</div>
|
||||
<?php $this->need('./module/footer.php'); ?>
|
||||
<?php $this->need('footer.php'); ?>
|
||||
+2
-2
@@ -5,7 +5,7 @@
|
||||
* @package custom
|
||||
*/
|
||||
if (!defined('__TYPECHO_ROOT_DIR__')) exit; ?>
|
||||
<?php $this->need('./module/header.php'); ?>
|
||||
<?php $this->need('header.php'); ?>
|
||||
<script src="<?php $this->options->themeUrl('assets/js/db.js'); ?>"></script>
|
||||
<section class="site--main">
|
||||
<header class="archive--header">
|
||||
@@ -28,4 +28,4 @@ new Douban({
|
||||
</script>
|
||||
</div>
|
||||
</section>
|
||||
<?php $this->need('./module/footer.php'); ?>
|
||||
<?php $this->need('footer.php'); ?>
|
||||
+5
-39
@@ -5,20 +5,17 @@
|
||||
* @package custom
|
||||
*/
|
||||
if (!defined('__TYPECHO_ROOT_DIR__')) exit;
|
||||
$this->need('./module/header.php');
|
||||
$this->need('header.php');
|
||||
?>
|
||||
|
||||
<div class="site--main site--main__gears">
|
||||
<header class="archive--header">
|
||||
<h1 class="post--single__title"><?php $this->title() ?></h1>
|
||||
</header>
|
||||
|
||||
<div id="goods" class="good--list">
|
||||
<?php
|
||||
// 获取内容并解析
|
||||
$content = $this->content;
|
||||
$goods = parseGoodsTable($content);
|
||||
|
||||
if (!empty($goods)) {
|
||||
foreach ($goods as $item): ?>
|
||||
<div class="good--item">
|
||||
@@ -44,31 +41,7 @@ $this->need('./module/header.php');
|
||||
<?php $this->need('./module/comments.php'); ?>
|
||||
<?php endif; ?>
|
||||
</div>
|
||||
|
||||
<style>
|
||||
.img40 {
|
||||
height: 137px;
|
||||
width: auto;
|
||||
object-fit: cover;
|
||||
}
|
||||
.img-spacer {
|
||||
width: 100%;
|
||||
aspect-ratio: 1;
|
||||
overflow: hidden;
|
||||
}
|
||||
.brand {
|
||||
font-weight: 500;
|
||||
margin-bottom: 5px;
|
||||
}
|
||||
.no-goods {
|
||||
grid-column: 1 / -1;
|
||||
text-align: center;
|
||||
padding: 20px;
|
||||
background: #f5f5f5;
|
||||
border-radius: 8px;
|
||||
}
|
||||
</style>
|
||||
|
||||
<style>.img40{height:137px;width:auto;object-fit:cover;}.img-spacer{width:100%;aspect-ratio:1;overflow:hidden;}.brand{font-weight:500;margin-bottom:5px;}.no-goods{grid-column:1 / -1;text-align:center;padding:20px;background:#f5f5f5;border-radius:8px;}</style>
|
||||
<?php
|
||||
/**
|
||||
* 解析商品表格数据
|
||||
@@ -77,25 +50,20 @@ $this->need('./module/header.php');
|
||||
*/
|
||||
function parseGoodsTable($content) {
|
||||
$goods = array();
|
||||
|
||||
// 创建DOM对象
|
||||
$dom = new DOMDocument();
|
||||
libxml_use_internal_errors(true); // 禁用libxml错误
|
||||
$dom->loadHTML(mb_convert_encoding($content, 'HTML-ENTITIES', 'UTF-8'), LIBXML_HTML_NOIMPLIED | LIBXML_HTML_NODEFDTD);
|
||||
libxml_clear_errors();
|
||||
|
||||
// 查找表格
|
||||
$tables = $dom->getElementsByTagName('table');
|
||||
|
||||
if ($tables->length > 0) {
|
||||
$table = $tables->item(0); // 获取第一个表格
|
||||
$rows = $table->getElementsByTagName('tr');
|
||||
|
||||
$rows = $table->getElementsByTagName('tr');
|
||||
// 跳过表头行
|
||||
for ($i = 1; $i < $rows->length; $i++) {
|
||||
$row = $rows->item($i);
|
||||
$cells = $row->getElementsByTagName('td');
|
||||
|
||||
$cells = $row->getElementsByTagName('td');
|
||||
// 确保有足够的单元格
|
||||
if ($cells->length >= 5) {
|
||||
$item = array(
|
||||
@@ -113,9 +81,7 @@ function parseGoodsTable($content) {
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return $goods;
|
||||
}
|
||||
|
||||
$this->need('./module/footer.php');
|
||||
$this->need('footer.php');
|
||||
?>
|
||||
+4
-8
@@ -5,7 +5,7 @@
|
||||
* @package custom
|
||||
*/
|
||||
if (!defined('__TYPECHO_ROOT_DIR__')) exit; ?>
|
||||
<?php $this->need('./module/header.php'); ?>
|
||||
<?php $this->need('header.php'); ?>
|
||||
<section class="site--main">
|
||||
<header class="archive--header">
|
||||
<h1 class="post--single__title"><?php $this->title() ?></h1>
|
||||
@@ -13,17 +13,13 @@ if (!defined('__TYPECHO_ROOT_DIR__')) exit; ?>
|
||||
</header>
|
||||
<div class="template--linksWrap">
|
||||
<ul class="link-items">
|
||||
<?php
|
||||
Links_Plugin::output('<li class="link-item"><a class="link-item-inner effect-apollo" href="{url}" target="_blank">
|
||||
<span class="sitename"><strong>{name}</strong>{title}</span>
|
||||
</a></li>');
|
||||
?>
|
||||
<?php Links_Plugin::output('<li class="link-item"><a class="link-item-inner effect-apollo" href="{url}" target="_blank"><span class="sitename"><strong>{name}</strong>{title}</span></a></li>'); ?>
|
||||
</ul>
|
||||
</div>
|
||||
<article class="post--single">
|
||||
<?php if ($this->allow('comment')): ?>
|
||||
<?php $this->need('./module/comments.php'); ?>
|
||||
<?php $this->need('module/comments.php'); ?>
|
||||
<?php endif; ?>
|
||||
</article>
|
||||
</section>
|
||||
<?php $this->need('./module/footer.php'); ?>
|
||||
<?php $this->need('footer.php'); ?>
|
||||
+2
-2
@@ -5,7 +5,7 @@
|
||||
* @package custom
|
||||
*/
|
||||
if (!defined('__TYPECHO_ROOT_DIR__')) exit; ?>
|
||||
<?php $this->need('./module/header.php'); ?>
|
||||
<?php $this->need('header.php'); ?>
|
||||
<div class="site--main">
|
||||
<header class="archive--header">
|
||||
<h1 class="post--single__title"><?php $this->title() ?></h1>
|
||||
@@ -148,4 +148,4 @@ img {
|
||||
}
|
||||
</style>
|
||||
</div>
|
||||
<?php $this->need('./module/footer.php'); ?>
|
||||
<?php $this->need('footer.php'); ?>
|
||||
|
||||
+3
-9
@@ -5,7 +5,7 @@
|
||||
* @package custom
|
||||
*/
|
||||
if (!defined('__TYPECHO_ROOT_DIR__')) exit; ?>
|
||||
<?php $this->need('./module/header.php'); ?>
|
||||
<?php $this->need('header.php'); ?>
|
||||
<div class="site--main">
|
||||
<header class="archive--header">
|
||||
<h1 class="post--single__title"><?php $this->title() ?></h1>
|
||||
@@ -16,7 +16,7 @@ if (!defined('__TYPECHO_ROOT_DIR__')) exit; ?>
|
||||
$memos = $this->fields->memos ? $this->fields->memos : 'https://memos.imsun.org';
|
||||
$memosID = $this->fields->memosID ? $this->fields->memosID : '1';
|
||||
$memosnum = $this->fields->memosnum ? $this->fields->memosnum : '20';
|
||||
?>
|
||||
?>
|
||||
<article class="post--single">
|
||||
<script src="<?php $this->options->themeUrl('assets/js/marked.min.js'); ?>"></script>
|
||||
<link rel="stylesheet" href="<?php $this->options->themeUrl('assets/css/lightbox.min.css'); ?>">
|
||||
@@ -32,7 +32,6 @@ const limit = 10; // 每页条数
|
||||
let url = '<?php echo $memos; ?>';
|
||||
let memosID = '<?php echo $memosID; ?>';
|
||||
let memosnum = '<?php echo $memosnum; ?>';
|
||||
|
||||
function loadMemos(page) {
|
||||
fetch(`${url}/api/v1/memo?creatorId=${memosID}&rowStatus=NORMAL&limit=${limit}&offset=${(page - 1) * limit}`)
|
||||
.then(res => res.json())
|
||||
@@ -64,7 +63,6 @@ function loadMemos(page) {
|
||||
// 这里可以添加一些用户提示错误发生的 HTML 更新
|
||||
});
|
||||
}
|
||||
|
||||
function Format(item) {
|
||||
let date = getTime(new Date(item.createdTs * 1000).toString()),
|
||||
content = item.content,
|
||||
@@ -94,7 +92,6 @@ function Format(item) {
|
||||
text: text.replace(/\[(.*?)\]\((.*?)\)/g, '[链接]' + `${imgs?'[图片]':''}`)
|
||||
}
|
||||
}
|
||||
|
||||
// 页面时间格式化
|
||||
function getTime(time) {
|
||||
let d = new Date(time),
|
||||
@@ -105,16 +102,13 @@ function getTime(time) {
|
||||
if (new Date().getFullYear() == ls[0]) return ls[1] + '月' + ls[2] + '日 ' + ls[3] +':'+ ls[4]
|
||||
else return ls[0] + '年' + ls[1] + '月' + ls[2] + '日 ' + ls[3] +':'+ ls[4]
|
||||
}
|
||||
|
||||
// 初始加载第一页
|
||||
loadMemos(currentPage);
|
||||
|
||||
// 点击“加载更多”按钮时加载下一页
|
||||
document.getElementById('loadmore').addEventListener('click', function() {
|
||||
currentPage++;
|
||||
loadMemos(currentPage);
|
||||
});
|
||||
|
||||
</script>
|
||||
<style>
|
||||
div pre code {
|
||||
@@ -169,4 +163,4 @@ img {
|
||||
}
|
||||
</style>
|
||||
</div>
|
||||
<?php $this->need('./module/footer.php'); ?>
|
||||
<?php $this->need('footer.php'); ?>
|
||||
|
||||
+11
-11
@@ -5,7 +5,7 @@
|
||||
* @package custom
|
||||
*/
|
||||
if (!defined('__TYPECHO_ROOT_DIR__')) exit; ?>
|
||||
<?php $this->need('./module/header.php'); ?>
|
||||
<?php $this->need('header.php'); ?>
|
||||
<link rel="stylesheet" href="<?php $this->options->themeUrl('assets/css/neodb.css'); ?>">
|
||||
<script src="<?php $this->options->themeUrl('assets/js/neodb.js'); ?>"></script>
|
||||
<section class="site--main">
|
||||
@@ -15,14 +15,14 @@ if (!defined('__TYPECHO_ROOT_DIR__')) exit; ?>
|
||||
</header>
|
||||
<div class="site--main">
|
||||
<div class="neodb-container"></div>
|
||||
<?php $neodb = $this->fields->neodb ? $this->fields->neodb : 'https://neodb.imsun.org'; ?>
|
||||
<script>
|
||||
const neodb = new NeoDB({
|
||||
container: ".neodb-container",
|
||||
baseAPI: "<?php echo $neodb; ?>/api",
|
||||
types: ["book", "movie", "tv", "music", "game"],
|
||||
});
|
||||
</script>
|
||||
</div>
|
||||
<?php $neodb = $this->fields->neodb ? $this->fields->neodb : 'https://neodb.imsun.org'; ?>
|
||||
<script>
|
||||
const neodb = new NeoDB({
|
||||
container: ".neodb-container",
|
||||
baseAPI: "<?php echo $neodb; ?>/api",
|
||||
types: ["book", "movie", "tv", "music", "game"],
|
||||
});
|
||||
</script>
|
||||
</div>
|
||||
</section>
|
||||
<?php $this->need('./module/footer.php'); ?>
|
||||
<?php $this->need('footer.php'); ?>
|
||||
+2
-2
@@ -5,7 +5,7 @@
|
||||
* @package custom
|
||||
*/
|
||||
if (!defined('__TYPECHO_ROOT_DIR__')) exit; ?>
|
||||
<?php $this->need('./module/header.php'); ?>
|
||||
<?php $this->need('header.php'); ?>
|
||||
<section class="site--main">
|
||||
<header class="archive--header">
|
||||
<h1 class="post--single__title"><?php $this->title() ?></h1>
|
||||
@@ -30,4 +30,4 @@ if (!defined('__TYPECHO_ROOT_DIR__')) exit; ?>
|
||||
<?php endif; ?>
|
||||
</div>
|
||||
</section>
|
||||
<?php $this->need('./module/footer.php'); ?>
|
||||
<?php $this->need('footer.php'); ?>
|
||||
@@ -1,5 +1,5 @@
|
||||
<?php if (!defined('__TYPECHO_ROOT_DIR__')) exit; ?>
|
||||
<?php $this->need('./module/header.php'); ?>
|
||||
<?php $this->need('header.php'); ?>
|
||||
<section class="site--main">
|
||||
<header class="archive--header">
|
||||
<h1 class="post--single__title"><?php $this->title() ?></h1>
|
||||
@@ -14,5 +14,5 @@
|
||||
<?php endif; ?>
|
||||
</article>
|
||||
</section>
|
||||
<?php $this->need('module/footer.php'); ?>
|
||||
<?php $this->need('footer.php'); ?>
|
||||
|
||||
@@ -1,13 +1,6 @@
|
||||
<?php if (!defined('__TYPECHO_ROOT_DIR__')) exit; ?>
|
||||
<?php $this->need('module/header.php'); ?>
|
||||
<style>
|
||||
#toc {font-size:14px;padding:10px 15px;background-color:var(--farallon-background-gray);border-radius:10px;margin-bottom:20px}
|
||||
#toc summary{cursor:pointer}
|
||||
#toc toc-title{font-weight:600}
|
||||
#toc ul{padding-left:10px;margin-bottom:10px}
|
||||
#toc ul li::before{content:"·";margin-right:5px}
|
||||
#toc ul li>ul{margin-left:10px;font-size:12px}
|
||||
</style>
|
||||
<?php $this->need('header.php'); ?>
|
||||
<style>#toc{font-size:14px;padding:10px 15px;background-color:var(--farallon-background-gray);border-radius:10px;margin-bottom:20px}#toc summary{cursor:pointer}#toc toc-title{font-weight:600}#toc ul{padding-left:10px;margin-bottom:10px}#toc ul li::before{content:"·";margin-right:5px}#toc ul li>ul{margin-left:10px;font-size:12px}</style>
|
||||
<main class="site--main">
|
||||
<article class="post--single">
|
||||
<ul class="meta">
|
||||
@@ -16,7 +9,7 @@
|
||||
<path
|
||||
d="M512 97.52381c228.912762 0 414.47619 185.563429 414.47619 414.47619s-185.563429 414.47619-414.47619 414.47619S97.52381 740.912762 97.52381 512 283.087238 97.52381 512 97.52381z m0 73.142857C323.486476 170.666667 170.666667 323.486476 170.666667 512s152.81981 341.333333 341.333333 341.333333 341.333333-152.81981 341.333333-341.333333S700.513524 170.666667 512 170.666667z m36.571429 89.697523v229.86362h160.865523v73.142857H512a36.571429 36.571429 0 0 1-36.571429-36.571429V260.388571h73.142858z">
|
||||
</path>
|
||||
</svg><time class="humane--time"><?php $this->date('Y-m-d'); ?></time>
|
||||
</svg><time class="humane--time"><?php $options = Helper::options();if ($options->friendlyTime == '1') {echo time_ago($this->created);} else {$this->date('Y-m-d H:i'); }?></time>
|
||||
<svg class="icon" viewBox="0 0 1024 1024" width="16" height="16">
|
||||
<path
|
||||
d="M408.551619 97.52381a73.142857 73.142857 0 0 1 51.736381 21.430857L539.306667 197.973333A73.142857 73.142857 0 0 0 591.067429 219.428571H804.571429a73.142857 73.142857 0 0 1 73.142857 73.142858v560.761904a73.142857 73.142857 0 0 1-73.142857 73.142857H219.428571a73.142857 73.142857 0 0 1-73.142857-73.142857V170.666667a73.142857 73.142857 0 0 1 73.142857-73.142857h189.123048z m0 73.142857H219.428571v682.666666h585.142858V292.571429h-213.504a146.285714 146.285714 0 0 1-98.499048-38.13181L487.619048 249.734095 408.551619 170.666667zM365.714286 633.904762v73.142857h-73.142857v-73.142857h73.142857z m365.714285 0v73.142857H414.47619v-73.142857h316.952381z m-365.714285-195.047619v73.142857h-73.142857v-73.142857h73.142857z m365.714285 0v73.142857H414.47619v-73.142857h316.952381z">
|
||||
@@ -44,40 +37,33 @@
|
||||
<?php endif; ?>
|
||||
</div>
|
||||
<h2 class="post--single__title"><?php $this->title() ?></h2>
|
||||
<div class="post--single__content graph" ><?php $this->content(); ?></div>
|
||||
<?php if($this->options->donate): ?>
|
||||
<div class="post--single__content graph" ><?php //$this->content(); ?><?php echo ContentFilter::filterContent($this->content, $this, null); ?></div>
|
||||
<?php if($this->options->wxpay): ?>
|
||||
<!--打赏 -->
|
||||
<div class="post--single__action">
|
||||
<link rel="stylesheet" href="<?php $this->options->themeUrl('assets/css/donate.css'); ?>">
|
||||
<script type="text/javascript" src="<?php $this->options->themeUrl('assets/js/donate.js'); ?>"></script>
|
||||
<div class="donate-panel">
|
||||
<div id="donate-btn">
|
||||
<button class="button--like">
|
||||
<svg class="icon--default" viewBox="0 0 1024 1024" width="32" height="32">
|
||||
<path
|
||||
d="M332.8 249.6c38.4 0 83.2 19.2 108.8 44.8L467.2 320 512 364.8 556.8 320l25.6-25.6c32-32 70.4-44.8 108.8-44.8 19.2 0 38.4 6.4 57.6 12.8 44.8 25.6 70.4 57.6 76.8 108.8 6.4 44.8-6.4 89.6-38.4 121.6L512 774.4 236.8 492.8C204.8 460.8 185.6 416 192 371.2c6.4-44.8 38.4-83.2 76.8-108.8C288 256 313.6 249.6 332.8 249.6L332.8 249.6M332.8 185.6C300.8 185.6 268.8 192 243.2 204.8 108.8 275.2 89.6 441.6 185.6 537.6l281.6 281.6C480 832 499.2 838.4 512 838.4s32-6.4 38.4-19.2l281.6-281.6c96-96 76.8-262.4-57.6-332.8-25.6-12.8-57.6-19.2-89.6-19.2-57.6 0-115.2 25.6-153.6 64L512 275.2 486.4 249.6C448 211.2 390.4 185.6 332.8 185.6L332.8 185.6z">
|
||||
</path>
|
||||
</svg>
|
||||
</button>
|
||||
</div>
|
||||
<div id="qrcode-panel" style="display: none;">
|
||||
<div class="qrcode-body">
|
||||
<div class="hidden">
|
||||
<span id="donate-close">关闭</span>
|
||||
</div>
|
||||
<div class="donate-qrpay">
|
||||
<img id="wxqr" src="<?php $this->options->donate() ?>" />
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<button class="button--like" onclick="openModal()">
|
||||
<svg class="icon--default" viewBox="0 0 1024 1024" width="32" height="32"><path d="M332.8 249.6c38.4 0 83.2 19.2 108.8 44.8L467.2 320 512 364.8 556.8 320l25.6-25.6c32-32 70.4-44.8 108.8-44.8 19.2 0 38.4 6.4 57.6 12.8 44.8 25.6 70.4 57.6 76.8 108.8 6.4 44.8-6.4 89.6-38.4 121.6L512 774.4 236.8 492.8C204.8 460.8 185.6 416 192 371.2c6.4-44.8 38.4-83.2 76.8-108.8C288 256 313.6 249.6 332.8 249.6L332.8 249.6M332.8 185.6C300.8 185.6 268.8 192 243.2 204.8 108.8 275.2 89.6 441.6 185.6 537.6l281.6 281.6C480 832 499.2 838.4 512 838.4s32-6.4 38.4-19.2l281.6-281.6c96-96 76.8-262.4-57.6-332.8-25.6-12.8-57.6-19.2-89.6-19.2-57.6 0-115.2 25.6-153.6 64L512 275.2 486.4 249.6C448 211.2 390.4 185.6 332.8 185.6L332.8 185.6z"></path></svg>
|
||||
</button>
|
||||
</div>
|
||||
<!-- 弹窗 -->
|
||||
<div class="modal" id="modal" onclick="closeModal()">
|
||||
<div class="modal-content" onclick="event.stopPropagation()">
|
||||
<span class="close-btn" onclick="closeModal()">×</span>
|
||||
<p>如果觉得文章对你有帮助,可以请作者喝杯咖啡 ☕️</p>
|
||||
<img src="<?php $this->options->wxpay() ?>" alt="微信二维码">
|
||||
<img src="<?php $this->options->alipay() ?>" alt="支付宝二维码">
|
||||
</div>
|
||||
</div>
|
||||
<script>function openModal(){document.getElementById('modal').style.display='flex'}function closeModal(){document.getElementById('modal').style.display='none'}</script>
|
||||
<style>.button--like{background:none;border:none;padding:0;cursor:pointer;transition:transform 0.3s ease;}.button--like:hover{transform:scale(1.1);}.icon--default{fill:#666;transition:fill 0.3s ease;}.button--like:hover .icon--default{fill:#ff4081;}.modal{display:none;position:fixed;top:0;left:0;width:100%;height:100%;background-color:rgba(0,0,0,0.1);justify-content:center;align-items:center;z-index:1000;}.modal-content{background-color:white;padding:20px;border-radius:10px;text-align:center;position:relative;}.modal-content img{width:200px;height:200px;margin-top:10px;}.close-btn{position:absolute;top:10px;right:10px;cursor:pointer;font-size:20px;color:#888;}</style>
|
||||
<?php endif; ?>
|
||||
<!-- 复制链接 -->
|
||||
<?php if($this->options->showshare): ?>
|
||||
<div class="post--share">
|
||||
<svg viewBox="0 0 24 24" aria-hidden="true"><g><path d="M18.36 5.64c-1.95-1.96-5.11-1.96-7.07 0L9.88 7.05 8.46 5.64l1.42-1.42c2.73-2.73 7.16-2.73 9.9 0 2.73 2.74 2.73 7.17 0 9.9l-1.42 1.42-1.41-1.42 1.41-1.41c1.96-1.96 1.96-5.12 0-7.07zm-2.12 3.53l-7.07 7.07-1.41-1.41 7.07-7.07 1.41 1.41zm-12.02.71l1.42-1.42 1.41 1.42-1.41 1.41c-1.96 1.96-1.96 5.12 0 7.07 1.95 1.96 5.11 1.96 7.07 0l1.41-1.41 1.42 1.41-1.42 1.42c-2.73 2.73-7.16 2.73-9.9 0-2.73-2.74-2.73-7.17 0-9.9z"></path></g></svg>
|
||||
<span class="text" data-copy="<?php $this->permalink(); ?>">复制链接</span><span class="link text"><?php $this->permalink(); ?></span><div class="notice--wrapper" id="copyTooltip" style="display: none;">复制成功!</div>
|
||||
<span class="cpoy" data-copy="<?php $this->permalink(); ?>">复制链接</span>
|
||||
<span class="link copy"><?php $this->permalink(); ?></span>
|
||||
<div class="notice--wrapper" id="copyTooltip" style="display: none;">复制成功!</div>
|
||||
</div>
|
||||
<?php endif; ?>
|
||||
<!-- TAG -->
|
||||
@@ -126,7 +112,7 @@
|
||||
<?php $this->need('module/related.php'); ?>
|
||||
<?php endif; ?>
|
||||
<?php if ($this->allow('comment')): ?>
|
||||
<?php $this->need('./module/comments.php'); ?>
|
||||
<?php $this->need('module/comments.php'); ?>
|
||||
<?php endif; ?>
|
||||
<!--翻页-->
|
||||
<nav class="navigation post-navigation is-active">
|
||||
@@ -145,4 +131,4 @@
|
||||
<script src="<?php $this->options->themeUrl('assets/js/post.js'); ?>"></script>
|
||||
<link rel="stylesheet" href="<?php $this->options->themeUrl('assets/css/lightbox.min.css'); ?>">
|
||||
<script src="<?php $this->options->themeUrl('assets/js/lightbox-plus-jquery.min.js'); ?>"></script>
|
||||
<?php $this->need('module/footer.php'); ?>
|
||||
<?php $this->need('footer.php'); ?>
|
||||
Reference in New Issue
Block a user