This commit is contained in:
浪子 2025-06-26 19:35:46 +08:00
parent a0c6ea57fc
commit 05a83e5879
10 changed files with 318 additions and 11 deletions

1
.gitignore vendored Normal file
View File

@ -0,0 +1 @@
*.html

View File

@ -18,6 +18,7 @@
2. 在后台管理界面启用该主题。
3. 根据需要自定义主题设置。
4. 主题部分功能需要安装插件`Puock`。项目地址: [Puock Plugin](https://github.com/jkjoy/typecho-plugin-puock)
5. 友情链接功能需要使用插件`Links`。项目地址: [Links Plugin](https://file.imsun.org/upload/2025-06/Links-1.2.7.zip),首页友情链接需要在`友链分类`中添加分类`home`。
### 主题配置

View File

@ -0,0 +1,65 @@
<?php if (!defined('__TYPECHO_ROOT_DIR__')) exit; ?>
<div class="row mr-0 ml-0">
<?php while ($this->next()): ?>
<?php
$coverImage = getPostCover($this->content, $this->cid);
?>
<article class="block card-plain post-item col-md-6 col-12 post-item-card">
<div class="p-block post-item-block">
<div class="thumbnail position-relative">
<a class="t-sm ww" href="<?php $this->permalink() ?>">
<img title="<?php $this->title() ?>" alt="<?php $this->title() ?>" src='<?php $this->options->themeUrl('assets/img/load.svg'); ?>'
data-src='<?php echo $coverImage; ?>' class='lazy' />
</a>
<div class="post-tags">
<span class="badge bg-danger"></span>
<?php if (isset($this->isSticky) && $this->isSticky): ?><?php echo $this->stickyHtml; ?><?php endif; ?>
</div>
</div>
<div class="post-info">
<h2 class="info-title">
<?php foreach($this->categories as $category): ?>
<a class="badge d-none d-md-inline-block bg-primary ahfff"
href="<?php echo $category['permalink']; ?>">
<i class="fa-regular fa-folder-open"></i> <?php echo $category['name']; ?>
</a>
<?php endforeach; ?>
<a class="a-link puock-text" title="<?php $this->title() ?>"
href="<?php $this->permalink() ?>"><?php $this->title() ?>
</a>
</h2>
<div class="info-meta c-sub">
<div class="text-2line"> <?php $this->excerpt(200, '...'); ?></div>
</div>
<div class="info-footer w-100">
<div>
<span class="t-sm c-sub">
<span class="mr-2">
<i class="fa-regular fa-eye mr-1"></i>
<span class="view">浏览:<?php get_post_view($this) ?></span>
<span class="t-sm d-none d-sm-inline-block">次阅读</span>
</span>
<a class="c-sub-a" href="<?php $this->permalink() ?>#comments">
<i class="fa-regular fa-comment mr-1"></i>
<?php $this->commentsNum('0', '1', '%d'); ?>
<span class="t-sm d-none d-sm-inline-block">个评论</span>
</a>
</span>
</div>
<div>
<?php foreach($this->categories as $category): ?>
<a class="c-sub-a t-sm ml-md-2 line-h-20 d-inline-block d-md-none"
href="<?php echo $category['permalink']; ?>">
<i class="fa-regular fa-folder-open"></i> <?php echo $category['name']; ?>
</a>
<?php endforeach; ?>
<span class="t-sm ml-md-2 c-sub line-h-20 d-none d-md-inline-block">
<i class="fa-regular fa-clock"></i> <?php $this->date(); ?>
</span>
</div>
</div>
</div>
</div>
</article>
<?php endwhile; ?>
</div>

View File

@ -224,4 +224,73 @@
</div>
<?php endif; ?>
</li>
<?php } ?>
<?php } ?>
<script>
var TypechoComment = {
dom : function (id) {
return document.getElementById(id);
},
create : function (tag, attr) {
var el = document.createElement(tag);
for (var key in attr) {
el.setAttribute(key, attr[key]);
}
return el;
},
reply : function (cid, coid) {
var comment = this.dom(cid), parent = comment.parentNode,
response = this.dom('comment-form-box'), holder = response.parentNode,
form = this.dom('comment-form'), textarea = this.dom('comment'),
submit = this.dom('comment-submit'),
cancel = this.dom('comment-cancel');
if (null != this.dom('comment-form-place-holder')) {
var holder = this.dom('comment-form-place-holder');
}
// 移动评论表单
if (null == this.dom('comment-form-place-holder')) {
var holder = this.create('div', {
'id': 'comment-form-place-holder'
});
response.parentNode.insertBefore(holder, response);
}
// 修改表单中的内容
comment.appendChild(response);
// 显示取消回复按钮
cancel.style.display = '';
// 记录回复的评论ID
this.dom('comment-parent').value = coid;
// 移动光标到评论框
textarea.focus();
return false;
},
cancelReply : function () {
var response = this.dom('comment-form-box'), holder = this.dom('comment-form-place-holder'),
comment = this.dom('comment-parent');
if (null != holder) {
holder.parentNode.insertBefore(response, holder);
holder.parentNode.removeChild(holder);
}
// 隐藏取消回复按钮
this.dom('comment-cancel').style.display = 'none';
// 清除回复评论ID
comment.value = '';
return false;
}
};
</script>

View File

@ -13,7 +13,7 @@
<div class="mt20 t-md index-links-box">
<?php Links_Plugin::output('
<a class="badge links-item" href="{url}" target="_blank" title="{title}" rel="nofollow">{name}</a>
'); ?>
',0,'home'); ?>
</div>
</div>
<?php endif; ?>

View File

@ -297,7 +297,7 @@ function get_permalink($cid) {
$post['type'] = 'post'; // 确保类型为文章
$post = Typecho_Widget::widget('Widget_Abstract_Contents')->filter($post);
// 使用文章对象的 permalink 方法生成链接
return $post['permalink'];
return $post['permalink'] ?? '';
} catch (Exception $e) {
// 出现异常时使用最简单的方式
$options = Helper::options();
@ -678,7 +678,10 @@ function getBrowsersInfo ($userAgent) {
* @return mixed|void
*/
function pregMatch($reg, $sourceData) {
if (preg_match($reg, $sourceData, $mat)) return $mat[1];
if (preg_match($reg, $sourceData, $mat)) {
return $mat[1] ?? '';
}
return '';
}
/**

View File

@ -4,7 +4,7 @@
*
* @package Typecho Pouck Theme
* @author 老孙博客
* @version 1.0
* @version 1.0.1
* @link http://www.imsun.org
*/
@ -17,6 +17,7 @@ $this->need('sticky.php');
<div class="animated fadeInLeft ">
<div> <!--文章列表-->
<div id="posts">
<?php if ($this->options->listmodel): ?>
<div class=" mr-0 ml-0">
<?php while ($this->next()): ?>
<?php
@ -87,6 +88,9 @@ if ($pageprev == '1' && $this->have()):
</div>
<?php endif; ?>
</div>
<?php else: ?>
<?php $this->need('card.php'); ?>
<?php endif; ?>
</div>
</div>
</div>

166
page-talks.php Normal file
View File

@ -0,0 +1,166 @@
<?php
/**
* 说说页面
*
* @package custom
*/
if (!defined('__TYPECHO_ROOT_DIR__')) exit; ?>
<?php $this->need('header.php'); ?>
<div id="breadcrumb" class="animated fadeInUp">
<nav aria-label="breadcrumb">
<ol class="breadcrumb">
<li class="breadcrumb-item"><a class="a-link" href="<?php $this->options->siteUrl(); ?>">首页</a></li>
<li class="breadcrumb-item active " aria-current="page"><?php $this->title() ?></li>
</ol>
</nav>
<div id="page-moments">
<div class="row">
<div id="posts" class="col-lg-8 col-md-12 animated fadeInLeft ">
<?php $tooot = $this->fields->tooot ? $this->fields->tooot : 'https://www.imsun.org/toot.json'; ?>
<script src="https://cdnjs.cloudflare.com/ajax/libs/marked/15.0.12/marked.min.js" integrity="sha512-rCQgmUulW6f6QegOvTntKKb5IAoxTpGVCdWqYjkXEpzAns6XUFs8NKVqWe+KQpctp/EoRSFSuykVputqknLYMg==" crossorigin="anonymous" referrerpolicy="no-referrer"></script>
<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/lightbox2/2.11.5/css/lightbox.min.css" integrity="sha512-xtV3HfYNbQXS/1R1jP53KbFcU9WXiSA1RFKzl5hRlJgdOJm4OxHCWYpskm6lN0xp0XtKGpAfVShpbvlFH3MDAA==" crossorigin="anonymous" referrerpolicy="no-referrer" />
<script src="https://cdnjs.cloudflare.com/ajax/libs/lightbox2/2.11.5/js/lightbox.min.js" integrity="sha512-KbRFbjA5bwNan6DvPl1ODUolvTTZ/vckssnFhka5cG80JVa5zSlRPCr055xSgU/q6oMIGhZWLhcbgIC0fyw3RQ==" crossorigin="anonymous" referrerpolicy="no-referrer"></script>
<div id="tooot"></div>
</div>
<script>
window.onload = function() {
let offset = 0; // 初始偏移量
const limit = 20; // 每次加载的数量
function formatHTML(toots) {
let htmlString = '';
toots.forEach(toot => {
// 判断是否存在 reblog
const isReblog = toot.reblog && toot.reblog.content;
const content = isReblog ? toot.reblog.content : toot.content;
const url = isReblog ? toot.reblog.url : toot.url;
const account = isReblog ? toot.reblog.account : toot.account;
const created_at = isReblog ? toot.reblog.created_at : toot.created_at;
const media_attachments = isReblog ? toot.reblog.media_attachments : toot.media_attachments;
let mediaHTML = ''; // 初始化资源相关HTML为空字符串
// 处理媒体附件
if (media_attachments.length > 0) {
media_attachments.forEach(attachment => {
if (attachment.type === 'image') {
mediaHTML += `<a href="${attachment.url}" target="_blank" data-lightbox="image-set"><img src="${attachment.preview_url}" class="thumbnail-image img" ></a>`;
}
});
}
// 使用 marked 转换 markdown 内容为 HTML
const htmlContent = marked.parse(content);
// 创建 HTML 字符串
htmlString += `
<div class="mb20 puock-text moments-item">
<div class="row">
<div class="col-12 col-md-1">
<a class="meta ta3" href="${account.url}" target="_blank" rel="nofollow">
<div class="avatar mb10">
<img src='${account.avatar}'
class='lazy md-avatar mt-1'
data-src='${account.avatar}'
alt="${account.display_name}" title="${account.display_name}">
</div>
<div class="t-line-1 info fs12">${account.display_name}</div>
</a>
</div>
<div class="col-12 col-md-11">
<div class="p-block moment-content-box"> <span class="al"></span>
<div class="mt10 moment-content entry-content show-link-icon">
<p>${htmlContent}
</p>
<div class="resimg">${mediaHTML}</div>
</div>
<div class="mt10 moment-footer p-flex-s-right"> <span class="t-sm c-sub">
<a class="c-sub-a" href="${url}">
<span class="mr-2"><i class="fa-regular fa-clock mr-1"></i>${new Date(created_at).toLocaleString()}</span>
</a>
</span>
</div>
</div>
</div>
</div>
</div>
`;
});
return htmlString;
}
function fetchToots() {
return fetch('<?php echo $tooot; ?>')
.then(response => response.json())
.catch(error => {
console.error('Error fetching toots:', error);
return [];
});
}
function fetchAndDisplayToots() {
fetchToots().then(data => {
const memosContainer = document.getElementById('tooot');
const tootsToShow = data.slice(offset, offset + limit); // 选择要显示的toots
memosContainer.innerHTML += formatHTML(tootsToShow);
});
}
// 在页面加载完成后获取并展示 toots
fetchAndDisplayToots();
};
</script>
<style>
div pre code {
white-space: pre-wrap;
word-wrap: break-word;
overflow-wrap: break-word;
word-break: break-all;
word-break: break-word;
}
div p a {
word-break: break-all;
word-break: break-word;
}
.resimg {
display: grid;
grid-template-columns: repeat(3, 1fr);
column-gap: 10px;
row-gap: 10px;
}
/* 单个缩略图的样式 */
.thumbnail-image {
width: 100%; /* 确保其宽度填满父容器 */
height: 200px; /* 固定高度 */
display: flex; /* 使用 flexbox 居中 */
align-items: center; /* 垂直居中 */
justify-content: center; /* 水平居中 */
overflow: hidden; /* 确保容器内的多余内容不会显示出来 */
border-radius: 4px; /* 圆角 */
transition: transform .3s ease; /* 鼠标悬停时的过渡效果 */
cursor: zoom-in; /* 鼠标指针变为放大镜 */
}
img {
object-fit: cover; /* 保持图片的纵横比,但会将图片裁剪以填充容器 */
object-position: center; /* 保证中央部分 */
}
/* 缩略图内的图片样式 */
.thumbnail-image img {
width: 100%;
min-height: 200px;
}
/* 当屏幕宽度小于732px时 */
@media (max-width: 732px) {
.resimg {
grid-template-columns: repeat(2, 1fr); /* 修改为两列 */
}
}
/* 当屏幕宽度小于400px时 */
@media (max-width: 400px) {
.resimg {
grid-template-columns: 1fr; /* 修改为一列 */
}
.thumbnail-image img {
width: 100%;
height: 480px;
}
}
</style>
<?php $this->need('sidebar.php'); ?>
</div>
</div>
<?php $this->need('footer.php'); ?>

View File

@ -183,10 +183,10 @@ if($days > 180){
</div>
</div>
</div> <!--评论上方-->
<?php $this->need('comments.php'); ?>
</div>
<?php $this->need('comments.php'); ?>
<?php if ($this->options->articlefoot): ?>
<div class="puock-text p-block t-md ad-comment-top"><?php $this->options->articlefoot(); ?></div>
<?php endif; ?>
</div>
<?php $this->need('sidebar.php'); ?>
<?php $this->need('footer.php'); ?>

View File

@ -167,7 +167,6 @@ if ($totalViews === null) $totalViews = 0;
</div>
<?php endif; ?>
<?php endif; ?>
<!-- 最近评论 -->
<?php if (!empty($this->options->sidebarBlock) && in_array('ShowRecentComments', $this->options->sidebarBlock)): ?>
<?php
@ -201,10 +200,10 @@ if ($totalViews === null) $totalViews = 0;
<!-- 热门标签 -->
<?php if (!empty($this->options->sidebarBlock) && in_array('ShowTags', $this->options->sidebarBlock)): ?>
<?php
$tags = \Widget\Metas\Tag\Cloud::alloc('sort=count&desc=1&limit=20');
$tags = \Widget\Metas\Tag\Cloud::alloc('sort=count&desc=1');
if ($tags->have()):
// 定义可用的颜色类数组
$colors = ['bg-primary', 'bg-secondary', 'bg-success', 'bg-danger', 'bg-warning', 'bg-info'];
$colors = ['bg-primary', 'bg-secondary', 'bg-success', 'bg-danger', 'bg-warning', 'bg-info', 'bg-transparent', 'bg-gradient'];
?>
<div class="pk-widget p-block ">
<div>
@ -226,6 +225,5 @@ if ($tags->have()):
</div>
<?php endif; ?>
<?php endif; ?>
</div>
</div>