Typecho 博客主题 Facile 个性化修改日志

博客上一个主题是 Initial 用了2-3年,后来更换到 Facile,目前是2.5版本,为方便以后跟随主题作者更新,根据自己的需求做了一些修改。

1、自定义CSS样式

header .navbar{border-width:0 0 1px 0;}
.post-list .post .post-title{font-size:26px;}
.sidebar section h2{font-size:14px;}
.sidebar section ul li{font-size:14px;}
.sidebar section ul li a{font-size:14px;}
.sidebar .latest-comment .media-body p{font-size:14px;}
.text-color{font-size:14px;word-wrap:break-word;word-break:break-all;}
.post-page article .post-content p{line-height:1.8;}
.post-page article .post-content img:not(.logo){display:inline;}
.post-page article .post-content blockquote{font-size:14px;padding:10px 10px 10px 20px;border-radius:0.5rem;}
.light-color .post-page article .post-content blockquote{border-left:4px solid #ca896d;background:#f3f3f3;color:#444;}
.dark-color .post-page article .post-content blockquote{border-left:4px solid #d69d85;background:#1e1e1e;color:#bbb;}
.archive-title{border-radius:4px;padding:18px 20px 10px;text-align:center;}
.archive-page .archives .archives-item ul li .day{text-align:right;}
.light-color .archive-title{background:#f3f3f3;}
.dark-color .archive-title{background:#16161a;}
.nav-item{font-size:14px;}
.nitxt .form-control{height:calc(2.25em + .75rem + 3px);}
.nitxt .required{color:#f00;}
.text-truncate{font-size:16px;}
.table-responsive{font-size:16px;}
code{font-size:100%;padding:0 4px;}
#comments .comment-input .row div{margin-bottom:0;}
#comments .comment-input .row div.nitxt{margin-bottom:16px;}
#comments .comments-lists .comment-author .comment-reply a, #comments .comments-lists .comment-author .comment-reply i{font-size:12px;color:#888;}
#copyright-info p{font-size:.8125rem;line-height:120%;}
#copyright-info p a{font-size:.8125rem;}
footer .text-center {font-size:12px;}
@media screen and (max-width:575px) {
  .post-list .post .post-title{font-size:22px;}
  .post-page .post-title{font-size:24px;}
}
@media (prefers-color-scheme: dark) {
  .archive-title{background:#16161a;}
  .post-page article .post-content blockquote{border-left:4px solid #d69d85;background:#1e1e1e;color:#bbb;}
}
@media (prefers-color-scheme: light) {
  .archive-title{background:#f3f3f3;}
  .post-page article .post-content blockquote{border-left:4px solid #ca896d;background:#f3f3f3;color:#444;}
}
注:comment-input.php文件input和textarea上层div的class加上:nitxt,目的为了统一输入框与验证码Captcha的高度。

2、自定义JS,实现内容里的内链自动取消target="_blank"

<script>
document.addEventListener('DOMContentLoaded',function(){
const h=window.location.hostname,l=document.querySelectorAll('.post-content a');
l.forEach(i=>{const r=i.getAttribute('href');r&&(!r.startsWith('http')||r.includes(h))&&(i.target='_self',i.removeAttribute('target'))});
});
</script>

注:作者模板全局 JS 已经加了target="_blank"

3、标题和模板副标题中间加上“-”分隔

查找header.php的代码<?php if ($this->is('index')) echo $this->options->tagline; ?>,修改为:<?php if ($this->is('index')) echo ' - ' . $this->options->tagline; ?>

4、新增导航显示文章分类

查找header.php的代码<?php $this->widget('Widget_Contents_Page_List')->to($pages); ?>,在其上方加入:

<?php $this->widget('Widget_Metas_Category_List@nav')->to($category); ?>
<?php while($category->next()): ?>
<li class="nav-item<?php if ($this->is('category', $category->slug)) echo ' active'; ?>">
  <a class="nav-link" href="<?php $category->permalink(); ?>"<?php if ($this->is('category', $category->slug)) echo ' aria-current="category"'; ?>><?php $category->name(); ?></a>
</li>
<?php endwhile; ?>

5、新增分享内容页给好友或朋友圈时,显示缩微图和简介

查找header.php的代码<link rel="icon" href="<?php echo $this->options->logoUrl?$this->options->logoUrl:$this->options->siteUrl . 'favicon.ico'; ?>" type="image/x-icon">,在其上方加入:

<?php if ($this->is('post') || $this->is('page')): ?>
<?php
// 获取缩略图
$thumb = '';
// 先尝试自定义字段
if ($this->fields->thumb) {
    $thumb = $this->fields->thumb;
} 
// 再尝试自动获取第一张图片
else {
    preg_match('/<img[^>]+src=[\'"]([^\'"]+)[\'"][^>]*>/i', $this->content, $matches);
    if (!empty($matches[1])) {
        $thumb = $matches[1];
    }
}
// 处理图片路径,确保是完整URL
if (!empty($thumb)) {
    // 如果已经是完整URL(http/https或//开头),不做处理
    if (!preg_match('/^(https?:)?\/\//i', $thumb)) {
        // 不是完整URL,需要加上网站根URL
        if (strpos($thumb, '/') = 0) {
            // 以斜杠开头,是网站根目录下的绝对路径
            $thumb = rtrim($this-&gt;options-&gt;siteUrl, &#039;/&#039;) . $thumb;
        } else {
            // 相对路径,使用网站根URL作为基础
            $thumb = rtrim($this-&gt;options-&gt;siteUrl, &#039;/&#039;) . &#039;/&#039; . ltrim($thumb, &#039;/&#039;);
        }
    }
} 
// 没有图片,使用默认
else {
    $thumb = rtrim($this-&gt;options-&gt;siteUrl, &#039;/&#039;) . &#039;/usr/themes/&#039; . $this-&gt;options-&gt;theme . &#039;/images/default.png&#039;;
}
// 获取描述
if ($this-&gt;fields-&gt;excerpt) {
    $description = $this-&gt;fields-&gt;excerpt;
} elseif ($this-&gt;description) {
    $description = $this-&gt;description;
} else {
    $description = Typecho_Common::subStr(strip_tags($this-&gt;excerpt), 0, 150, &#039;...&#039;);
}
?&gt;
    &lt;meta property=&quot;og:title&quot; content=&quot;&lt;?php $this-&gt;title() ?&gt;&quot; /&gt;
    &lt;meta property=&quot;og:type&quot; content=&quot;article&quot; /&gt;
    &lt;meta property=&quot;og:url&quot; content=&quot;&lt;?php $this-&gt;permalink() ?&gt;&quot; /&gt;
    &lt;meta property=&quot;og:image&quot; content=&quot;&lt;?php echo $thumb ?&gt;&quot; /&gt;
    &lt;meta property=&quot;og:image:width&quot; content=&quot;800&quot; /&gt;
    &lt;meta property=&quot;og:image:height&quot; content=&quot;800&quot; /&gt;
    &lt;meta property=&quot;og:description&quot; content=&quot;&lt;?php echo htmlspecialchars($description) ?&gt;&quot; /&gt;
    &lt;meta property=&quot;og:site_name&quot; content=&quot;&lt;?php $this-&gt;options-&gt;title() ?&gt;&quot; /&gt;
    &lt;!-- Twitter --&gt;
    &lt;meta name=&quot;twitter:card&quot; content=&quot;summary_large_image&quot; /&gt;
    &lt;meta name=&quot;twitter:title&quot; content=&quot;&lt;?php $this-&gt;title() ?&gt;&quot; /&gt;
    &lt;meta name=&quot;twitter:description&quot; content=&quot;&lt;?php echo htmlspecialchars($description) ?&gt;&quot; /&gt;
    &lt;meta name=&quot;twitter:image&quot; content=&quot;&lt;?php echo $thumb ?&gt;&quot; /&gt;
    &lt;!-- Wechat --&gt;
    &lt;meta property=&quot;wechat:article:title&quot; content=&quot;&lt;?php $this-&gt;title() ?&gt;&quot; /&gt;
    &lt;meta property=&quot;wechat:article:description&quot; content=&quot;&lt;?php echo htmlspecialchars(Typecho_Common::subStr(strip_tags($description), 0, 120, &#039;...&#039;)) ?&gt;&quot; /&gt;
    &lt;meta property=&quot;wechat:article:image&quot; content=&quot;&lt;?php echo $thumb ?&gt;&quot; /&gt;
&lt;?php endif; ?&gt;</code></pre><h2>6、屏蔽<code>&lt;head&gt;</code>部分相关的meta内容输出</h2><p>查找header.php的代码<code>&lt;?php $this-&gt;header(); ?&gt;</code>,修改为:<code>&lt;?php $this-&gt;header(&#039;generator=&amp;template=&amp;pingback=&amp;xmlrpc=&amp;wlw=&amp;rss1=&amp;rss2=&amp;atom=&amp;social=&#039;); ?&gt;</code></p><blockquote>注:<code>social</code>是Typecho 1.3.0新增的。</blockquote><h2>7、右侧sidebar新增随机文章显示</h2><p>helpers.php最底部新增代码如下:</p><pre><code class="lang-PHP">function getRandomPosts($random = 5) {
    $db = Typecho_Db::get();
    $adapterName = $db-&gt;getAdapterName(); // 兼容非MySQL数据库
    if ($adapterName 'pgsql' || $adapterName &#039;Pdo_Pgsql&#039; || $adapterName 'Pdo_SQLite' || $adapterName &#039;SQLite&#039;) {
        $order_by = &#039;RANDOM()&#039;;
    } else {
        $order_by = &#039;RAND()&#039;;
    }
    
    $sql = $db-&gt;select()-&gt;from(&#039;table.contents&#039;)
        -&gt;where(&#039;status = ?&#039;, &#039;publish&#039;)
        -&gt;where(&#039;table.contents.created &lt;= ?&#039;, time())
        -&gt;where(&#039;type = ?&#039;, &#039;post&#039;)
        -&gt;limit($random)
        -&gt;order($order_by);

    $result = $db-&gt;fetchAll($sql);
    if ($result) {
        foreach ($result as $val) {
            // 实例化内容组件并推入数据行
            $obj = Typecho_Widget::widget(&#039;Widget_Abstract_Contents&#039;);
            $obj-&gt;push($val);
            
            // 通过对象属性获取数据,避免数组键缺失
            $post_title = htmlspecialchars($obj-&gt;title);
            $permalink = $obj-&gt;permalink;
            
            echo &#039;
                &lt;li&gt;
                    &lt;a href=&quot;&#039; . $permalink . &#039;&quot; title=&quot;&#039; . $post_title . &#039;&quot;&gt;&#039; . $post_title . &#039;&lt;/a&gt;
                &lt;/li&gt;&#039;;
        }
    }
}</code></pre><p>sidebar.php对应位置新增代码:</p><pre><code class="lang-PHP">        &lt;?php if ($component '推荐阅读'): ?>
            <!--最新文章-->
            <section class="ml-xl-4 ml-lg-3 mb-5">
                <h2 class="mb-4"><?php echo $GLOBALS['t']['sidebar']['recommendPosts']; ?></h2>
                <ul aria-label="<?php echo $GLOBALS['t']['sidebar']['recommendPosts']; ?>">
<?php getRandomPosts(10);?>
                </ul>
            </section>
        <?php endif; ?>

在语言包,'sidebar' => array(,下面新增:'recommendPosts' => '推荐阅读',。对应的英文语言包也需要加上。最后配置:外观-设置外观的“侧边栏组件”处,加上推荐阅读。

8、实现文章内容里非本站链接加上rel="nofollow"

查找post.php的这段代码:

$GLOBALS['post']['content'] = addBootstrapTableClasses($GLOBALS['post']['content']);

在其下面的新增下面代码:

// == 核心功能:外链自动添加 rel="nofollow"(适配泛域名) ==
function autoAddNofollowToExternalLinks($content, $siteUrl) {
    // 1. 解析并标准化本站根域名(提取 yourname.site,兼容所有二级域名)
    $siteParsed = parse_url(rtrim($siteUrl, '/'));
    $siteHost = isset($siteParsed['host']) ? strtolower($siteParsed['host']) : '';
    if (empty($siteHost)) return $content;

    // 提取根域名
    $siteHostParts = explode('.', $siteHost);
    $rootDomain = count($siteHostParts) >= 2 
        ? $siteHostParts[count($siteHostParts)-2] . '.' . $siteHostParts[count($siteHostParts)-1] 
        : $siteHost; // 兜底:防止域名格式异常

    // 2. 正则匹配所有<a>标签,捕获href和所有属性
    $pattern = '/<a\s+([^>]*?)href=["\']([^"\']+)["\']([^>]*?)>/i';
    $content = preg_replace_callback($pattern, function($matches) use ($rootDomain) {
        $fullTag = $matches[0];
        $preHrefAttr = trim($matches[1]); // href前的属性
        $href = $matches[2];               // 链接地址
        $postHrefAttr = trim($matches[3]); // href后的属性
        $allAttrs = $preHrefAttr . ' ' . $postHrefAttr; // 拼接所有属性(去重空格)
        $allAttrs = preg_replace('/\s+/', ' ', $allAttrs);

        // 3. 判断是否为站内链接(核心:泛域名匹配 *.yourname.site)
        $isInternal = false;
        $hrefTrim = rtrim($href, '/');
        
        // 情况1:相对路径(无域名,如 /post/123、about.html)
        if (strpos($href, '://') = false &amp;&amp; !preg_match(&#039;/^\/\/[^\/]+/&#039;, $href)) {
            $isInternal = true;
        }
        // 情况2:绝对路径(含 *.yourname.site 域名)
        else {
            $hrefParsed = parse_url($hrefTrim);
            $hrefHost = isset($hrefParsed[&#039;host&#039;]) ? strtolower($hrefParsed[&#039;host&#039;]) : &#039;&#039;;
            if (!empty($hrefHost)) {
                // 匹配规则:
                // 1. 精准匹配根域名(yourname.site)
                // 2. 匹配所有二级域名(*.yourname.site)
                if ($hrefHost= $rootDomain || substr($hrefHost, -strlen($rootDomain) - 1) = &#039;.&#039; . $rootDomain) {
                    $isInternal = true;
                }
            }
        }

        // 4. 站内链接直接返回原标签,不做任何修改
        if ($isInternal) {
            return $fullTag;
        }

        // 5. 外链:检查是否已有rel=&quot;nofollow&quot;(避免重复添加)
        if (preg_match(&#039;/rel\s*=\s*[&quot;\&#039;](.*?)nofollow(.*?)[&quot;\&#039;]/i&#039;, $allAttrs)) {
            return $fullTag;
        }

        // 6. 外链且无nofollow:添加/追加rel=&quot;nofollow&quot;
        if (preg_match(&#039;/rel\s*=\s*[&quot;\&#039;][^&quot;\&#039;]+[&quot;\&#039;]/i&#039;, $allAttrs)) {
            // 已有rel属性,追加nofollow(如 rel=&quot;noopener&quot; → rel=&quot;noopener nofollow&quot;)
            $allAttrs = preg_replace(&#039;/rel\s*=\s*[&quot;\&#039;]([^&quot;\&#039;]+)[&quot;\&#039;]/i&#039;, &#039;rel=&quot;$1 nofollow&quot;&#039;, $allAttrs);
        } else {
            // 无rel属性,新增rel=&quot;nofollow&quot;
            $allAttrs .= &#039; rel=&quot;nofollow&quot;&#039;;
        }

        // 7. 重新拼接&lt;a&gt;标签(保持属性顺序,仅修改rel)
        return &#039;&lt;a &#039; . trim($allAttrs) . &#039; href=&quot;&#039; . $href . &#039;&quot;&gt;&#039;;
    }, $content);

    return $content;
}

// 执行外链处理(传入本站域名)
$GLOBALS[&#039;post&#039;][&#039;content&#039;] = autoAddNofollowToExternalLinks(
    $GLOBALS[&#039;post&#039;][&#039;content&#039;],
    $this-&gt;options-&gt;siteUrl
);
//== 外链处理结束====

发表评论

行为验证™ 安全组件加载中...

评论 暂无评论

文章目录