大约2年前,我就立下 Flag 说今后有能力一定要自己动手,创建一个属于自己的 Typecho 主题。最近总算是有时间和能力来完成这一目标,实现这个拖了太久的 Flag。

了解概念

正式开发之前,我们必须要讨论一些基本概念。

前端 vs. 后端

通常在Web领域,与用户交互的页面一般泛指为前端,而后端则为处理并提供数据的服务。可以简单理解为,你的电脑是前端,而你博客的服务器是后端。无论数据是如何到达前端的,最终都要能被浏览器渲染为用户能看到的 Web 页面。

浏览器其实仅需要 HTML 就可以展示数据,但是纯 HTML 的网页样式一般都比较单一。为了让网页更有个性,开发人员通常会提供样式表 CSS,告诉浏览器应该如何渲染数据(例如:所有的标题需要加粗,日期必须要为红色等等)。最后 JavaScript 可以操作的内容就多了,我简单列几点:

  • 更改 HTML 元素原本的行为(例如:一个链接原本应该跳转到另一个网页,JavaScript 可以阻止原本的行为,让链接不再能跳转)
  • 修改网页内容(例如:将文章的更新日期从2024年08月13日更改为2025年01月01日。)
  • 获取网页内容(例如:网页内所有的标题,网页内所有的按钮,网页内所有的超链接)
  • 等等...

前后端一体 vs. 前后端分离

由于 JavaScript 的强大功能,网站开发通常被分为了2种形态:

  • 前后端一体
  • 前后端分离

前后端一体是 Typecho、WordPress 等博客框架采用的途径,它的意思是后端(你博客的服务器)将处理好的 HTML、CSS 直接发送给前端(发送请求用户的浏览器),浏览器通过 HTML 和 CSS 数据渲染出网页。一个简单的网站甚至不需要任何 JavaScript。

前后端分离是指后端先仅返回一些 HTML、CSS 模板,让用户的浏览器执行 JavaScript 命令,再请求后端拿到真实的数据。

这样描述可能有些抽象,让我们来举一个例子。假如我需要写一个展示天气气温的网页,若网页是前后端一体的,服务器会直接返回北京的气温 30 摄氏度;若网页是前后端分离的,服务器可能只会返回一个占位符 --,由定义好的 JavaScript 再请求一次服务器,拿到数据 30,最后将网页中的占位符 -- 替换为30

这两种形态各有优劣,我们这里不具体讨论。

开始开发

由于是开发 Typecho 主题,不是开发整个博客框架。首先我们应该阅读 Typecho 主题开发官方文档,了解应该如何获取到我们想要的数据,最后拼接为一个完整的 HTML 页面。

更简单的方法是直接用官方的 Hello World 主题修改。想让一个网页符合自己的审美,需要修改 CSS 样式表;想让页面展示更多内容,需要修改 php 文件,让它输出更多内容。

选择样式表

我认为,让一个网页好看是美工领域的事情,不如挑一个自己看着舒服的直接使用。因此,现在的主题是基于 Bulma CSS 框架所开发。这个框架提供了完整的按钮、表单等样式,非常漂亮。

bulma-css

添加 JavaScript 代码辅助

由于我本质上是基于 Typecho 框架而改造,很多现成的方法不利于改造,这时候我们就可以加一些 JavaScript 在前端渲染,最后也能得到相同的效果。例如,给非本域名的标签加上 _blank,实现页面跳转到新窗口。

document.querySelectorAll('a').forEach(function(link) {
    const currentDomain = window.location.hostname;
    const href = link.getAttribute('href');
    if (href && (href.startsWith('http://') || href.startsWith('https://'))) {
        const linkDomain = (new URL(href)).hostname;
        if (linkDomain !== currentDomain && !linkDomain.endsWith(`.${currentDomain}`)) {
            link.setAttribute('target', '_blank');
        }
    }
});

成品展示

亮色模式:

typecho-theme-bulma-light

黑暗模式:

typecho-theme-bulma-dark