无插件实现 typecho 独立友链页面

友链功能

  • 后台添加友链
  • 好看的CSS样式
  • 自动检测友链状态

友链模板效果

2024-10-20T12:19:40.png

如何实现上图效果?

修改主题 functions.php
  在主题文件 functions.php 文件的 themeConfig 函数中添加以下代码:

    $friendLink = new Typecho_Widget_Helper_Form_Element_Textarea('friendLink', NULL, NULL, _t('友链'), _t('名称|简介|链接|图标'));
    $form->addInput($friendLink);

然后在 functions.php 文件末尾加上以下代码:

###友链状态检测###
define('CACHE_DIR', __DIR__ . '/cache/'); // 确保这个路径是可写的
if (!is_dir(CACHE_DIR)) {
    mkdir(CACHE_DIR, 0777, true);
}
// 检查链接状态并使用文件缓存
function checkLink($url) {
    // 生成缓存文件名
    $cacheFile = CACHE_DIR . 'link_status_' . md5($url) . '.cache';
    
    // 检查缓存文件是否存在且未过期
    if (file_exists($cacheFile) && (time() - filemtime($cacheFile) < 86400)) {
        // 从缓存文件中读取状态
        return file_get_contents($cacheFile);
    }

    // 如果缓存文件不存在或已过期,检查链接
    $ch = curl_init($url);
    curl_setopt($ch, CURLOPT_NOBODY, true);
    curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
    curl_setopt($ch, CURLOPT_TIMEOUT, 60);
    curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, false);
    curl_setopt($ch, CURLOPT_SSL_VERIFYHOST, false);

    curl_exec($ch);
    $httpCode = curl_getinfo($ch, CURLINFO_HTTP_CODE);
    curl_close($ch);
    
    // 根据状态码设置状态
    $status = ($httpCode == 200) ? '正常' : '异常';

    // 将状态存入缓存文件
    file_put_contents($cacheFile, $status);

    return $status;
}
###友链状态检测###   

随后我们创建一个新的友链模板 (代码仅供参考且只适用于Ying主题,需根据自己的主题去进行适配)

<?php
$prePattern = "/<pre(.*?)>/i";
$preReplacement = '<pre class="notranslate" \\\\\\$1>';
$content = preg_replace($prePattern, $preReplacement, $this->content);

$blockquotePattern = "/<blockquote(.*?)>/i";
$blockquoteReplacement = '<blockquote class="trm-color-quote trm-mb-40" \\\\\\$1>';
$content = preg_replace($blockquotePattern, $blockquoteReplacement, $content);

$ulPattern = "/<ul(.*?)>/i";
$ulReplacement = '<ul class="trm-list trm-mb-40" \\\\\\$1>';
$content = preg_replace($ulPattern, $ulReplacement, $content);
?>
<h1>友链</h1>
<div class="links">
    <div class="links-container">
        <?php if (!empty(trim($this->options->friendLink))): ?>  
            <?php
            $friendLinks = explode("\n", $this->options->friendLink);
            shuffle($friendLinks);
            foreach ($friendLinks as $link):
                $parts = explode("|", $link);
                if (count($parts) >= 4):
                    $title = htmlspecialchars($parts[0]);
                    $description = htmlspecialchars($parts[1]);
                    $url = htmlspecialchars($parts[2]);
                    $avatar = htmlspecialchars($parts[3]);
                    $status = checkLink($url); 
                    if ($status == "正常"): 
            ?>  
            <div class="link-item">
                <a href="<?php echo $url; ?>" title="<?php echo $description; ?>" style="display: flex; align-items: center; text-decoration: none; color: inherit;">
                    <span class="link-avatar">
                        <img class="avatar" src="<?php echo $avatar; ?>" alt="<?php echo $title; ?>">
                    </span>
                    <div class="link-info">
                        <div class="link-title-container">
                            <span class="link-title"><?php echo $title; ?></span>
                        </div>
                        <div class="link-desc-status">
                            <div class="link-desc"><?php echo $description; ?></div>
                            <div class="link-status normal"><?php echo $status; ?></div>
                        </div>
                    </div>
                </a>
            </div>
            <?php
                    endif;
                endif;
            endforeach;
            ?>  
        <?php endif; ?>
    </div>
</div>

然后我们要修改CSS样式 (我的代码很丑, 仅供参考)

.links {
    width: 600px;
    height: auto;
    overflow: hidden;
    display: flex;
    flex-wrap: wrap;
}

.links-container {
    display: flex;
    flex-wrap: wrap;
    width: 100%;
}

.link-item {
    width: calc(30% - 8px);
    height: auto;
    box-sizing: border-box;
    display: flex;
    align-items: center;
    background-color: #ffffff;
    border: 1px solid #e0e0e0;
    border-radius: 8px;
    padding: 4px;
    margin: 4px;
}

.link-avatar {
    flex-shrink: 0;
}

.avatar {
    width: 35px;
    height: 35px;
    border-radius: 10%;
    object-fit: cover;
    margin-right: 8px;
}

.link-info {
    flex: 1;
    display: flex;
    flex-direction: column;
    margin-top: -10%;
}

.link-title-container {
    display: flex;
    align-items: center;
}

.link-title {
    font-size: 14px;
    color: #333;
    text-decoration: none;
    font-weight: bold;
    margin-bottom: -3px;
    overflow: hidden;
    text-overflow: ellipsis;
    white-space: nowrap;
}

.link-desc-status {
    display: flex;
    justify-content: space-between;
    align-items: center;
    margin-top: 2px;
}

.link-desc {
    font-size: 11px;
    color: #777;
    overflow: hidden;
    text-overflow: ellipsis;
    white-space: nowrap;
    max-width: 87px;
}

.link-status {
    font-size: 12px;
    color: #666;
    text-align: right;
    white-space: nowrap;
    overflow: hidden;
    text-overflow: ellipsis;
    line-height: 1.2;
}

.link-status.normal {
    color: #4caf50;
}

.link-status.abnormal {
    color: #f44336;
}

.link-item:hover {
    box-shadow: 0 4px 10px rgba(0, 0, 0, 0.1);
}

@media (max-width: 768px) {
    .link-item {
        width: calc(50% - 8px);
    }
}

@media (max-width: 480px) {
    .link-item {
        width: calc(100% - 8px);
    }
}

显示效果不佳

按照自己的需求,修改代码中的 style 部分即可,思路还是一样的

如何在后台添加友链?

2024-10-20T12:30:38.png

评论区

暂无评论,快来抢沙发