0.8
This commit is contained in:
parent
0ed7e7b5e8
commit
33175a8951
|
@ -7,9 +7,15 @@
|
|||
|
||||
## 更新日志 & 预览
|
||||
|
||||
### 0.8
|
||||
|
||||
- 兼容 Typecho 1.3.0
|
||||
- 自动裁切封面并保存在主题目录 `usr/cache/covers` 下,使用前必须开启 `php` 的 `GD拓展` 和`usr`目录的写权限.
|
||||
- 站点统计
|
||||
|
||||
### 0.7.2
|
||||
|
||||
- 优化页面加载速度,自动裁切封面,并压缩为`webp`格式,并保存在主题目录`assets`-`images`-`covers`下,使用前必须开启`php`的`GD拓展`和主题目录的写入权限
|
||||
- ~~优化页面加载速度,自动裁切封面,并压缩为`webp`格式,并保存在主题目录`assets`-`images`-`covers`下,使用前必须开启`php`的`GD拓展`和主题目录的写入权限~~
|
||||
- 修复了置顶文章和翻页的问题
|
||||
|
||||
### 0.7.1
|
||||
|
|
|
@ -17,7 +17,7 @@
|
|||
is_single = false;
|
||||
post_id = 0;
|
||||
is_archive = false;
|
||||
VERSION = "0.7.2";
|
||||
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">老孙博客</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", () => {
|
||||
|
|
|
@ -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"
|
||||
|
|
161
functions.php
161
functions.php
|
@ -119,7 +119,7 @@ define('__TYPECHO_GRAVATAR_PREFIX__', $gravatarPrefix);
|
|||
// 初始化主题
|
||||
function init_theme() {
|
||||
// 检查并创建封面图片目录
|
||||
$coversDir = dirname(__FILE__) . '/assets/images/covers';
|
||||
$coversDir = __TYPECHO_ROOT_DIR__ . '/usr/cache/covers';
|
||||
if (!is_dir($coversDir)) {
|
||||
@mkdir($coversDir, 0755, true);
|
||||
}
|
||||
|
@ -214,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) {
|
||||
|
@ -291,10 +290,9 @@ function process_cover_image($imageUrl) {
|
|||
$filename = md5($imageUrl) . '.webp';
|
||||
|
||||
// 处理后图片的保存路径
|
||||
$themeDir = dirname(__FILE__);
|
||||
$savePath = $themeDir . '/assets/images/covers/' . $filename;
|
||||
$webPath = Helper::options()->themeUrl . '/assets/images/covers/' . $filename;
|
||||
|
||||
$savePath = __TYPECHO_ROOT_DIR__ . '/usr/cache/covers/' . $filename;
|
||||
$webPath = Helper::options()->siteUrl . '/usr/cache/covers/' . $filename;
|
||||
|
||||
// 如果缓存文件已存在,直接返回
|
||||
if (file_exists($savePath)) {
|
||||
return $webPath;
|
||||
|
@ -367,8 +365,8 @@ function process_cover_image($imageUrl) {
|
|||
if (!function_exists('imagewebp')) {
|
||||
// 如果不支持webp,保存为png
|
||||
$filename = md5($imageUrl) . '.png';
|
||||
$savePath = $themeDir . '/assets/images/covers/' . $filename;
|
||||
$webPath = Helper::options()->themeUrl . '/assets/images/covers/' . $filename;
|
||||
$savePath = __TYPECHO_ROOT_DIR__ . '/usr/cache/covers/' . $filename;
|
||||
$webPath = Helper::options()->siteUrl . '/usr/cache/covers/' . $filename;
|
||||
imagepng($targetImage, $savePath, 9); // 9是最高压缩质量
|
||||
} else {
|
||||
// 保存为webp
|
||||
|
@ -388,23 +386,60 @@ function process_cover_image($imageUrl) {
|
|||
*
|
||||
*/
|
||||
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) {
|
||||
|
@ -488,8 +523,6 @@ class ContentFilter
|
|||
return $atts;
|
||||
}
|
||||
}
|
||||
// 注册钩子
|
||||
Typecho_Plugin::factory('Widget_Abstract_Contents')->contentEx = array('ContentFilter', 'filterContent');
|
||||
// 编辑器按钮类
|
||||
class EditorButton {
|
||||
public static function render()
|
||||
|
@ -780,4 +813,90 @@ function time_ago($time, $threshold = 31536000) { // 31536000秒 = 1年
|
|||
|
||||
$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;
|
||||
}
|
59
header.php
59
header.php
|
@ -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()): ?>
|
||||
<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 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">
|
||||
<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>
|
||||
</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,9 +1,12 @@
|
|||
<?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.3
|
||||
* @version 0.8
|
||||
* @link https://www.imsun.org
|
||||
*/
|
||||
if (!defined('__TYPECHO_ROOT_DIR__')) exit; ?>
|
||||
|
|
2
post.php
2
post.php
|
@ -37,7 +37,7 @@
|
|||
<?php endif; ?>
|
||||
</div>
|
||||
<h2 class="post--single__title"><?php $this->title() ?></h2>
|
||||
<div class="post--single__content graph" ><?php $this->content(); ?></div>
|
||||
<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">
|
||||
|
|
Loading…
Reference in New Issue