实践自托管 Google Fonts

稍微有那么一点麻烦。

缘起

本站一直使用的是 WordPress 官方出品的 Twenty Fifteen 主题,并以子主题的形式做了一些小的修改。这一主题的一大特点就是西文部分使用了 Google 的 Noto Serif 开放源代码字体。这一字体的效果配合中文的衬线字体还是相当不错的。这一主题的官方设定是直接调用 Google Fonts API。自从 Google 推出 Fonts API 之后,很多的网站都会使用这个 API。这个 API 当然有其优点。首先是兼容性,Google Fonts API 会根据浏览器自动选择加载不同 Web Font 格式的 CSS 文件;其次是可以方便地组合不同的字体、字重、字符集。然而,虽然 Google 的服务可用性还是有相当的保证的,这种服务也许不至于因为没人用就砍掉,但是基于一些方面的考虑,还是决定尝试放到自己服务器上。

过程

开始之前,请确认你对 WordPress 的架构有基本的了解。

首先自然是从 Twenty Fifteen 主题里面找具体用了哪些字体。一般来说,不同的主题定义字体的地方不尽相同。对于 Twenty Fifteen,最终可以定位到 functions.php 文件中的 twentyfifteen_fonts_url() 函数1。这里摘取其中一段(L291-L297)

/*
* Translators: If there are characters in your language that are not supported
* by Noto Sans, translate this to 'off'. Do not translate into your own language.
*/
if ( 'off' !== _x( 'on', 'Noto Sans font: on or off', 'twentyfifteen' ) ) {
	$fonts[] = 'Noto Sans:400italic,700italic,400,700';
}

可以看到官方的主题巧妙地使用了 _x() 函数2通过主题的本地化机制实现是否加载某一字体的功能。接着的部分就是根据本地化信息判断是否要加载扩展字符集。最后用 add_query_arg() 函数3构建 Google Font API 的请求 URL 字符串,就算是完成了。可以看到 Google Font API 的使用确实是很方便,开发者不需要再费力去考虑字体对浏览器的兼容性。

根据这个函数的代码,也就获得了各种不同字体所要加载的字重和字形信息,整理如下

Noto Sans:400italic,700italic,400,700
Noto Serif:400italic,700italic,400,700
Inconsolata:400,700

至于其他扩展字符,对于这里来说应该用不太到。

然后就要用利用 google-webfonts-helper 项目4来完成获取所需要的字体的工作。打开项目的 实例站点,找到我们需要的几种字体,选择好对应的字重字形就可以很方便地生成所需要的 CSS 以及获取字体的下载链接。

可以看到,如果需要支持一些老的浏览器的话,就需要多个不同格式的字体。如果是西文字体可能占用空间并不大,但如果是中文字体,多个字体格式所占用的空间以及加载时长就会是一个很大的问题,如果是自己托管字体这个问题就很麻烦。

处理好字体资源和 CSS 资源的位置,并确认路径正确以后,接着就是要修改 twentyfifteen_fonts_url() 函数。WordPress 提供了子主题的机制,可以方便地用子主题中定义的同名函数覆盖原主题中的函数。这里修改如下

function twentyfifteen_fonts_url() {
	$fonts_url = get_stylesheet_directory_uri().'/css/fonts.css';
	return $fonts_url;
}

这个函数只需要直接返回我们预先设置好的本地字体 CSS 的 URL 即可。

最后应用子主题就完成了。


  1. functions.php in twentyfifteen_2.5 – WordPress Themes 
  2. _x() | Function | WordPress Developer Resources 
  3. add_query_arg() | Function | WordPress Developer Resources 
  4. majodev/google-webfonts-helper 

《实践自托管 Google Fonts》上有7条评论

    1. 粗略看了一下你提到的插件(如果我没找错的话应该是 Host Google Fonts Locally https://wordpress.org/plugins/host-google-fonts-locally/

      首先,这个插件的作用是将用户到 Google Font API 的请求改为从服务器进行下载 CSS 以及字体。( https://plugins.trac.wordpress.org/browser/host-google-fonts-locally/trunk/host-google-fonts-locally.php#L143

      其次,如果我没理解错这个插件的说明的话,这个插件只是将作者的另外一个插件( Google Fonts Typography https://wordpress.org/plugins/olympus-google-fonts/ )的中的字体链接给替换掉。

      我的需求也就仅仅是用针对现在这个主题,这就安装一个插件个人感觉有点太重了。

      1. 这个插件可以把引用的谷歌字体下载到本地,再替换掉本地的css请求中的链接。
        这个插件可以用作国内商业站的搭建,很适合技术水平很差的用户。

  1. Noto 系列的中文字体好像每个都有6、7MB?这样是不是意味着用户每次访问都要下载一次这个完整的 .woff. 文件?

    1. 之前我也做过针对中文字体的测试,Regular字重的Noto Serif SC的woff文件大小是2.4M。

      关于加载的问题,情况可能比较复杂,现代的浏览器可能会有针对字体的缓存,所以并不一定每次都会下载。但是我并不太记得之前试验时候的情况了。

发表回复

您的邮箱地址不会被公开。 必填项已用 * 标注