<?xml version="1.0" encoding="utf-8" standalone="yes"?><rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom"><channel><title>Hugo on Time Friend</title><link>https://time-friend.com/zh/tags/hugo/</link><description>Recent content in Hugo on Time Friend</description><generator>Hugo</generator><language>zh-CN</language><lastBuildDate>Thu, 14 Aug 2025 17:00:00 +0000</lastBuildDate><atom:link href="https://time-friend.com/zh/tags/hugo/index.xml" rel="self" type="application/rss+xml"/><item><title>博客 Logo 动画是怎么做的</title><link>https://time-friend.com/zh/archive/blog-architecture-animated-logo/</link><pubDate>Thu, 14 Aug 2025 17:00:00 +0000</pubDate><guid>https://time-friend.com/zh/archive/blog-architecture-animated-logo/</guid><description>&lt;p&gt;网站左上角那个小方框, 是视频.&lt;/p&gt;
&lt;p&gt;默认灰度, hover 才亮起来, 颜色每次还不一样, 播放速度也会先快后缓. 像被惊醒了一下.&lt;/p&gt;
&lt;h1 id="为什么做这个"&gt;为什么做这个&lt;/h1&gt;
&lt;p&gt;之前 logo 是张静态 PNG. 总觉得缺了点呼吸感. 正好手头有一段素材, 就把 logo 从静态图换成了视频.&lt;/p&gt;
&lt;h1 id="mp4-没有-alpha-通道"&gt;mp4 没有 Alpha 通道&lt;/h1&gt;
&lt;p&gt;剪映导出时明明去掉了背景, 但 mp4 不支持透明通道, 透明部分被压成了黑色.&lt;/p&gt;
&lt;p&gt;桌面端用 &lt;code&gt;mix-blend-mode: screen&lt;/code&gt; 解决 — 黑色变完全透明, 只保留亮色部分:&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"&gt;&lt;code class="language-css" data-lang="css"&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;@&lt;span style="color:#66d9ef"&gt;media&lt;/span&gt; &lt;span style="color:#f92672"&gt;(&lt;/span&gt;&lt;span style="color:#f92672"&gt;hover&lt;/span&gt;&lt;span style="color:#f92672"&gt;:&lt;/span&gt; &lt;span style="color:#f92672"&gt;hover&lt;/span&gt;&lt;span style="color:#f92672"&gt;)&lt;/span&gt; &lt;span style="color:#f92672"&gt;and&lt;/span&gt; &lt;span style="color:#f92672"&gt;(&lt;/span&gt;&lt;span style="color:#f92672"&gt;pointer&lt;/span&gt;&lt;span style="color:#f92672"&gt;:&lt;/span&gt; &lt;span style="color:#f92672"&gt;fine&lt;/span&gt;&lt;span style="color:#f92672"&gt;)&lt;/span&gt; {
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; #header #logo { &lt;span style="color:#66d9ef"&gt;mix-blend-mode&lt;/span&gt;: &lt;span style="color:#66d9ef"&gt;screen&lt;/span&gt;; }
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;}
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;限定 &lt;code&gt;(hover: hover)&lt;/code&gt; 是因为移动端浏览器对 &lt;code&gt;&amp;lt;video&amp;gt;&lt;/code&gt; 的 blend mode 支持普遍不好.&lt;/p&gt;
&lt;p&gt;移动端改用 &lt;code&gt;&amp;lt;canvas&amp;gt;&lt;/code&gt; 做逐像素抠图: video 隐藏继续播放, canvas 每帧取画面, RGB 都低于 30 的像素 alpha 置 0:&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"&gt;&lt;code class="language-js" data-lang="js"&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#66d9ef"&gt;function&lt;/span&gt; &lt;span style="color:#a6e22e"&gt;render&lt;/span&gt;() {
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#a6e22e"&gt;canvasCtx&lt;/span&gt;.&lt;span style="color:#a6e22e"&gt;drawImage&lt;/span&gt;(&lt;span style="color:#a6e22e"&gt;videoEl&lt;/span&gt;, &lt;span style="color:#ae81ff"&gt;0&lt;/span&gt;, &lt;span style="color:#ae81ff"&gt;0&lt;/span&gt;, &lt;span style="color:#a6e22e"&gt;w&lt;/span&gt;, &lt;span style="color:#a6e22e"&gt;h&lt;/span&gt;);
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#66d9ef"&gt;var&lt;/span&gt; &lt;span style="color:#a6e22e"&gt;src&lt;/span&gt; &lt;span style="color:#f92672"&gt;=&lt;/span&gt; &lt;span style="color:#a6e22e"&gt;canvasCtx&lt;/span&gt;.&lt;span style="color:#a6e22e"&gt;getImageData&lt;/span&gt;(&lt;span style="color:#ae81ff"&gt;0&lt;/span&gt;, &lt;span style="color:#ae81ff"&gt;0&lt;/span&gt;, &lt;span style="color:#a6e22e"&gt;w&lt;/span&gt;, &lt;span style="color:#a6e22e"&gt;h&lt;/span&gt;).&lt;span style="color:#a6e22e"&gt;data&lt;/span&gt;;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#66d9ef"&gt;var&lt;/span&gt; &lt;span style="color:#a6e22e"&gt;id&lt;/span&gt; &lt;span style="color:#f92672"&gt;=&lt;/span&gt; &lt;span style="color:#a6e22e"&gt;canvasCtx&lt;/span&gt;.&lt;span style="color:#a6e22e"&gt;createImageData&lt;/span&gt;(&lt;span style="color:#a6e22e"&gt;w&lt;/span&gt;, &lt;span style="color:#a6e22e"&gt;h&lt;/span&gt;);
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#66d9ef"&gt;for&lt;/span&gt; (&lt;span style="color:#66d9ef"&gt;var&lt;/span&gt; &lt;span style="color:#a6e22e"&gt;i&lt;/span&gt; &lt;span style="color:#f92672"&gt;=&lt;/span&gt; &lt;span style="color:#ae81ff"&gt;0&lt;/span&gt;; &lt;span style="color:#a6e22e"&gt;i&lt;/span&gt; &lt;span style="color:#f92672"&gt;&amp;lt;&lt;/span&gt; &lt;span style="color:#a6e22e"&gt;src&lt;/span&gt;.&lt;span style="color:#a6e22e"&gt;length&lt;/span&gt;; &lt;span style="color:#a6e22e"&gt;i&lt;/span&gt; &lt;span style="color:#f92672"&gt;+=&lt;/span&gt; &lt;span style="color:#ae81ff"&gt;4&lt;/span&gt;) {
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#a6e22e"&gt;id&lt;/span&gt;.&lt;span style="color:#a6e22e"&gt;data&lt;/span&gt;[&lt;span style="color:#a6e22e"&gt;i&lt;/span&gt;] &lt;span style="color:#f92672"&gt;=&lt;/span&gt; &lt;span style="color:#a6e22e"&gt;src&lt;/span&gt;[&lt;span style="color:#a6e22e"&gt;i&lt;/span&gt;];
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#a6e22e"&gt;id&lt;/span&gt;.&lt;span style="color:#a6e22e"&gt;data&lt;/span&gt;[&lt;span style="color:#a6e22e"&gt;i&lt;/span&gt;&lt;span style="color:#f92672"&gt;+&lt;/span&gt;&lt;span style="color:#ae81ff"&gt;1&lt;/span&gt;] &lt;span style="color:#f92672"&gt;=&lt;/span&gt; &lt;span style="color:#a6e22e"&gt;src&lt;/span&gt;[&lt;span style="color:#a6e22e"&gt;i&lt;/span&gt;&lt;span style="color:#f92672"&gt;+&lt;/span&gt;&lt;span style="color:#ae81ff"&gt;1&lt;/span&gt;];
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#a6e22e"&gt;id&lt;/span&gt;.&lt;span style="color:#a6e22e"&gt;data&lt;/span&gt;[&lt;span style="color:#a6e22e"&gt;i&lt;/span&gt;&lt;span style="color:#f92672"&gt;+&lt;/span&gt;&lt;span style="color:#ae81ff"&gt;2&lt;/span&gt;] &lt;span style="color:#f92672"&gt;=&lt;/span&gt; &lt;span style="color:#a6e22e"&gt;src&lt;/span&gt;[&lt;span style="color:#a6e22e"&gt;i&lt;/span&gt;&lt;span style="color:#f92672"&gt;+&lt;/span&gt;&lt;span style="color:#ae81ff"&gt;2&lt;/span&gt;];
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#a6e22e"&gt;id&lt;/span&gt;.&lt;span style="color:#a6e22e"&gt;data&lt;/span&gt;[&lt;span style="color:#a6e22e"&gt;i&lt;/span&gt;&lt;span style="color:#f92672"&gt;+&lt;/span&gt;&lt;span style="color:#ae81ff"&gt;3&lt;/span&gt;] &lt;span style="color:#f92672"&gt;=&lt;/span&gt; (&lt;span style="color:#a6e22e"&gt;src&lt;/span&gt;[&lt;span style="color:#a6e22e"&gt;i&lt;/span&gt;] &lt;span style="color:#f92672"&gt;&amp;lt;&lt;/span&gt; &lt;span style="color:#ae81ff"&gt;30&lt;/span&gt; &lt;span style="color:#f92672"&gt;&amp;amp;&amp;amp;&lt;/span&gt; &lt;span style="color:#a6e22e"&gt;src&lt;/span&gt;[&lt;span style="color:#a6e22e"&gt;i&lt;/span&gt;&lt;span style="color:#f92672"&gt;+&lt;/span&gt;&lt;span style="color:#ae81ff"&gt;1&lt;/span&gt;] &lt;span style="color:#f92672"&gt;&amp;lt;&lt;/span&gt; &lt;span style="color:#ae81ff"&gt;30&lt;/span&gt; &lt;span style="color:#f92672"&gt;&amp;amp;&amp;amp;&lt;/span&gt; &lt;span style="color:#a6e22e"&gt;src&lt;/span&gt;[&lt;span style="color:#a6e22e"&gt;i&lt;/span&gt;&lt;span style="color:#f92672"&gt;+&lt;/span&gt;&lt;span style="color:#ae81ff"&gt;2&lt;/span&gt;] &lt;span style="color:#f92672"&gt;&amp;lt;&lt;/span&gt; &lt;span style="color:#ae81ff"&gt;30&lt;/span&gt;) &lt;span style="color:#f92672"&gt;?&lt;/span&gt; &lt;span style="color:#ae81ff"&gt;0&lt;/span&gt; &lt;span style="color:#f92672"&gt;:&lt;/span&gt; &lt;span style="color:#ae81ff"&gt;255&lt;/span&gt;;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; }
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#a6e22e"&gt;canvasCtx&lt;/span&gt;.&lt;span style="color:#a6e22e"&gt;putImageData&lt;/span&gt;(&lt;span style="color:#a6e22e"&gt;id&lt;/span&gt;, &lt;span style="color:#ae81ff"&gt;0&lt;/span&gt;, &lt;span style="color:#ae81ff"&gt;0&lt;/span&gt;);
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#a6e22e"&gt;requestAnimationFrame&lt;/span&gt;(&lt;span style="color:#a6e22e"&gt;render&lt;/span&gt;);
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;}
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;这个性能取决于视频分辨率, logo 尺寸很小, 所以开销可以接受.&lt;/p&gt;</description></item><item><title>首页打字效果是如何实现的</title><link>https://time-friend.com/zh/archive/blog-architecture-typing-effect/</link><pubDate>Tue, 12 Aug 2025 11:50:00 +0000</pubDate><guid>https://time-friend.com/zh/archive/blog-architecture-typing-effect/</guid><description>&lt;p&gt;打开首页会看到一行文字在逐字打字, 过几秒又换一句. 这个效果不复杂, 但很多人问怎么做的.&lt;/p&gt;
&lt;p&gt;这篇说一下实现方式.&lt;/p&gt;
&lt;h1 id="整体原理"&gt;整体原理&lt;/h1&gt;
&lt;p&gt;首页加载时, 从一个 JSON 文件里随机选一句台词, 用 Typed.js 这个库模拟打字效果.&lt;/p&gt;
&lt;pre tabindex="0"&gt;&lt;code&gt;首页加载
 ↓
main.js 检测到当前是首页
 ↓
根据语言 (中文/英文) 确定取哪个字段
 ↓
从 /data/quotes.json 随机取一条
 ↓
传给 Typed.js, 开始打字动画
&lt;/code&gt;&lt;/pre&gt;&lt;h1 id="数据来源-quotesjson"&gt;数据来源: quotes.json&lt;/h1&gt;
&lt;p&gt;台词存在 &lt;code&gt;static/data/quotes.json&lt;/code&gt; 里.&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"&gt;&lt;code class="language-json" data-lang="json"&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;[
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; {
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#f92672"&gt;&amp;#34;en&amp;#34;&lt;/span&gt;: &lt;span style="color:#e6db74"&gt;&amp;#34;Hope is a good thing, maybe the best of things, and no good thing ever dies.&amp;#34;&lt;/span&gt;,
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#f92672"&gt;&amp;#34;zh&amp;#34;&lt;/span&gt;: &lt;span style="color:#e6db74"&gt;&amp;#34;希望是美好的，也许是世间最美好的事物，而美好的事物永不消逝。&amp;#34;&lt;/span&gt;,
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#f92672"&gt;&amp;#34;author&amp;#34;&lt;/span&gt;: &lt;span style="color:#e6db74"&gt;&amp;#34;The Shawshank Redemption&amp;#34;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; },
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; {
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#f92672"&gt;&amp;#34;en&amp;#34;&lt;/span&gt;: &lt;span style="color:#e6db74"&gt;&amp;#34;Get busy living or get busy dying.&amp;#34;&lt;/span&gt;,
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#f92672"&gt;&amp;#34;zh&amp;#34;&lt;/span&gt;: &lt;span style="color:#e6db74"&gt;&amp;#34;忙着活，或忙着死。&amp;#34;&lt;/span&gt;,
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#f92672"&gt;&amp;#34;author&amp;#34;&lt;/span&gt;: &lt;span style="color:#e6db74"&gt;&amp;#34;The Shawshank Redemption&amp;#34;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; }
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;]
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;每条数据包含三个字段:&lt;/p&gt;</description></item><item><title>如何让博客支持离线访问</title><link>https://time-friend.com/zh/archive/blog-architecture-service-worker/</link><pubDate>Tue, 08 Jul 2025 15:30:00 +0000</pubDate><guid>https://time-friend.com/zh/archive/blog-architecture-service-worker/</guid><description>&lt;p&gt;PWA 是个 buzzword, 说白了这个博客用到的 PWA 功能就两个: manifest.json 和 Service Worker. manifest.json 让浏览器知道&amp;quot;这是个应用&amp;quot;, Service Worker 让它在离线时也能工作.&lt;/p&gt;
&lt;p&gt;这篇重点说 Service Worker, 因为它比较复杂. manifest.json 很简单, 放在最后说.&lt;/p&gt;
&lt;h1 id="service-worker-是什么"&gt;Service Worker 是什么&lt;/h1&gt;
&lt;p&gt;简单说, Service Worker 是一个运行在浏览器背后的脚本. 它独立于网页, 在后台默默干活.&lt;/p&gt;
&lt;p&gt;你可以把它理解为&lt;strong&gt;浏览器和网络之间的中间人&lt;/strong&gt;. 正常情况下, 浏览器请求一个资源 (HTML, JS, 图片), 直接去服务器拿. 有了 Service Worker, 请求会先经过它:&lt;/p&gt;
&lt;pre tabindex="0"&gt;&lt;code&gt;浏览器 → Service Worker → 网络 (或缓存)
&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;Service Worker 可以决定: 这个请求是去网络拿, 还是直接从本地缓存返回, 还是两者都做.&lt;/p&gt;
&lt;p&gt;这个博客的 Service Worker 就是用 Workbox 生成的, 大约 5KB.&lt;/p&gt;
&lt;h1 id="有什么用"&gt;有什么用&lt;/h1&gt;
&lt;h2 id="离线访问"&gt;离线访问&lt;/h2&gt;
&lt;p&gt;这是最核心的功能. 如果用户访问过一次博客, Service Worker 会把静态资源缓存下来. 下次即使没有网络, 也能打开之前看过的文章.&lt;/p&gt;</description></item><item><title>我是怎么给博客加页面统计的</title><link>https://time-friend.com/zh/archive/blog-architecture-analytics/</link><pubDate>Sun, 15 Jun 2025 13:20:00 +0000</pubDate><guid>https://time-friend.com/zh/archive/blog-architecture-analytics/</guid><description>&lt;p&gt;写博客不知道有没有人看, 会很空虚. 统计不是为了 KPI, 就是图一乐.&lt;/p&gt;
&lt;p&gt;这个博客的页面统计有两套系统, 各管各的.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Busuanzi&lt;/strong&gt; 显示在文章页面上, 读者能看到每篇文章被看了多少次. 它是开源的, 不需要注册, 脚本一引就行.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Google Analytics&lt;/strong&gt; 在后台跑, 只有我自己能看到. 用来分析流量来源, 用户分布, 热门内容等.&lt;/p&gt;
&lt;p&gt;两套互不干扰.&lt;/p&gt;
&lt;h1 id="busuanzi-前端展示"&gt;Busuanzi (前端展示)&lt;/h1&gt;
&lt;p&gt;Busuanzi 是不蒜子的英文名, 一个极简的阅读统计工具. 没有后台, 没有 Dashboard, 只有一个计数器和一段 JS 脚本.&lt;/p&gt;
&lt;h2 id="引入脚本"&gt;引入脚本&lt;/h2&gt;
&lt;p&gt;在 &lt;code&gt;layouts/partials/js.html&lt;/code&gt; 里加载:&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"&gt;&lt;code class="language-html" data-lang="html"&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;{{ if .IsPage }}
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&amp;lt;&lt;span style="color:#f92672"&gt;script&lt;/span&gt; &lt;span style="color:#a6e22e"&gt;async&lt;/span&gt; &lt;span style="color:#a6e22e"&gt;src&lt;/span&gt;&lt;span style="color:#f92672"&gt;=&lt;/span&gt;&lt;span style="color:#e6db74"&gt;&amp;#34;//busuanzi.ibruce.info/busuanzi/2.3/busuanzi.pure.mini.js&amp;#34;&lt;/span&gt;&amp;gt;&amp;lt;/&lt;span style="color:#f92672"&gt;script&lt;/span&gt;&amp;gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;{{ end }}
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;只在文章页加载, 首页和列表页不用.&lt;/p&gt;
&lt;h2 id="显示阅读量"&gt;显示阅读量&lt;/h2&gt;
&lt;p&gt;在文章页模板 &lt;code&gt;layouts/_default/single.html&lt;/code&gt; 里:&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"&gt;&lt;code class="language-html" data-lang="html"&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&amp;lt;&lt;span style="color:#f92672"&gt;div&lt;/span&gt; &lt;span style="color:#a6e22e"&gt;class&lt;/span&gt;&lt;span style="color:#f92672"&gt;=&lt;/span&gt;&lt;span style="color:#e6db74"&gt;&amp;#34;article-tag&amp;#34;&lt;/span&gt;&amp;gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &amp;lt;&lt;span style="color:#f92672"&gt;i&lt;/span&gt; &lt;span style="color:#a6e22e"&gt;class&lt;/span&gt;&lt;span style="color:#f92672"&gt;=&lt;/span&gt;&lt;span style="color:#e6db74"&gt;&amp;#34;fa fa-eye&amp;#34;&lt;/span&gt;&amp;gt;&amp;lt;/&lt;span style="color:#f92672"&gt;i&lt;/span&gt;&amp;gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &amp;lt;&lt;span style="color:#f92672"&gt;span&lt;/span&gt; &lt;span style="color:#a6e22e"&gt;id&lt;/span&gt;&lt;span style="color:#f92672"&gt;=&lt;/span&gt;&lt;span style="color:#e6db74"&gt;&amp;#34;busuanzi_container_page_pv&amp;#34;&lt;/span&gt;&amp;gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &amp;lt;&lt;span style="color:#f92672"&gt;span&lt;/span&gt; &lt;span style="color:#a6e22e"&gt;id&lt;/span&gt;&lt;span style="color:#f92672"&gt;=&lt;/span&gt;&lt;span style="color:#e6db74"&gt;&amp;#34;busuanzi_value_page_pv&amp;#34;&lt;/span&gt;&amp;gt;0&amp;lt;/&lt;span style="color:#f92672"&gt;span&lt;/span&gt;&amp;gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &amp;lt;/&lt;span style="color:#f92672"&gt;span&lt;/span&gt;&amp;gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&amp;lt;/&lt;span style="color:#f92672"&gt;div&lt;/span&gt;&amp;gt;
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;Busuanzi 的脚本加载后会自动查找 &lt;code&gt;id=&amp;quot;busuanzi_value_page_pv&amp;quot;&lt;/code&gt; 的元素, 把阅读量填进去. 数据存在 Busuanzi 的服务端, 不需要自己维护.&lt;/p&gt;</description></item><item><title>评论系统怎么接入博客的</title><link>https://time-friend.com/zh/archive/blog-architecture-giscus/</link><pubDate>Tue, 06 May 2025 10:30:00 +0000</pubDate><guid>https://time-friend.com/zh/archive/blog-architecture-giscus/</guid><description>&lt;p&gt;博客不能没有评论. 但又不想为了一个评论功能去搞数据库和 moderation. Giscus 是一个折中方案.&lt;/p&gt;
&lt;p&gt;这个博客的评论系统用的是 Giscus. 它基于 GitHub Discussions. 所有评论都直接存在 GitHub 仓库里, 不需要自建数据库, 不需要第三方服务.&lt;/p&gt;
&lt;h1 id="整体流程"&gt;整体流程&lt;/h1&gt;
&lt;pre tabindex="0"&gt;&lt;code&gt;用户打开文章页
 ↓
加载 giscus.app/client.js
 ↓
Giscus 脚本读取 data- 属性配置
 ↓
根据 mapping=&amp;#34;pathname&amp;#34; 取当前 URL 路径
 ↓
用 GitHub Discussions API 查询匹配的 Discussion
 ↓
找到 → 渲染评论框和已有评论
未找到 → 显示&amp;#34;留个评论吧&amp;#34;输入框
 ↓
用户写评论 → 点击发布
 ↓
跳转 GitHub OAuth 授权 (首次需要)
 ↓
评论通过 API 写入仓库的 Discussions
 ↓
Giscus WebSocket 监听变更 → 实时更新评论区
&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;整个过程用户无感知, 不需要离开页面.&lt;/p&gt;
&lt;h1 id="哪里对接"&gt;哪里对接&lt;/h1&gt;
&lt;p&gt;评论系统以 script 标签嵌入页面. 在 &lt;code&gt;layouts/partials/comments.html&lt;/code&gt; 里:&lt;/p&gt;</description></item><item><title>我是怎么部署这个博客的</title><link>https://time-friend.com/zh/archive/blog-architecture-deployment/</link><pubDate>Thu, 10 Apr 2025 15:44:00 +0000</pubDate><guid>https://time-friend.com/zh/archive/blog-architecture-deployment/</guid><description>&lt;p&gt;静态文件总得找个地方放, 还得让全世界都能访问.&lt;/p&gt;
&lt;h1 id="部署平台-cloudflare-pages"&gt;部署平台: Cloudflare Pages&lt;/h1&gt;
&lt;p&gt;选 Cloudflare Pages 而不是其他平台, 原因有三:&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;&lt;strong&gt;全球 CDN&lt;/strong&gt;: Cloudflare 有遍布全球的边缘节点, 无论访客在哪, 都能从最近的节点加载页面&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;零配置 HTTPS&lt;/strong&gt;: 自动签发和续期 SSL 证书, 不需要手动处理&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;免费额度够用&lt;/strong&gt;: 对于个人博客来说, 带宽和构建次数完全够用&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;配置很简单, 在 Cloudflare Pages 控制台创建一个项目, 关联 GitHub 仓库. 构建命令和输出目录在 GitHub Actions 里控制, 不需要在控制台配.&lt;/p&gt;
&lt;p&gt;有个坑: Cloudflare Pages 默认分配的域名是 &lt;code&gt;&amp;lt;project&amp;gt;.pages.dev&lt;/code&gt;, 项目名一旦确定就不能改. 想换只能删掉重建. 我那会儿随便打了个名字, 后来想改发现不行, 只能留着.&lt;/p&gt;
&lt;h1 id="cicd-流程"&gt;CI/CD 流程&lt;/h1&gt;
&lt;p&gt;完整的部署流程由 GitHub Actions 管理:&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"&gt;&lt;code class="language-yaml" data-lang="yaml"&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#f92672"&gt;name&lt;/span&gt;: &lt;span style="color:#ae81ff"&gt;Deploy to Cloudflare Pages&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#f92672"&gt;on&lt;/span&gt;:
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#f92672"&gt;push&lt;/span&gt;:
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#f92672"&gt;branches&lt;/span&gt;: [&lt;span style="color:#ae81ff"&gt;master]&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#f92672"&gt;workflow_dispatch&lt;/span&gt;:
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#f92672"&gt;jobs&lt;/span&gt;:
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#f92672"&gt;build&lt;/span&gt;:
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#f92672"&gt;runs-on&lt;/span&gt;: &lt;span style="color:#ae81ff"&gt;ubuntu-latest&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#f92672"&gt;steps&lt;/span&gt;:
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; - &lt;span style="color:#f92672"&gt;uses&lt;/span&gt;: &lt;span style="color:#ae81ff"&gt;actions/checkout@v4&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; - &lt;span style="color:#f92672"&gt;uses&lt;/span&gt;: &lt;span style="color:#ae81ff"&gt;peaceiris/actions-hugo@v3&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#f92672"&gt;with&lt;/span&gt;:
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#f92672"&gt;hugo-version&lt;/span&gt;: &lt;span style="color:#e6db74"&gt;&amp;#34;0.164.0&amp;#34;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#f92672"&gt;extended&lt;/span&gt;: &lt;span style="color:#66d9ef"&gt;true&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; - &lt;span style="color:#f92672"&gt;uses&lt;/span&gt;: &lt;span style="color:#ae81ff"&gt;actions/setup-node@v4&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#f92672"&gt;with&lt;/span&gt;:
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#f92672"&gt;node-version&lt;/span&gt;: &lt;span style="color:#ae81ff"&gt;24&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#f92672"&gt;cache&lt;/span&gt;: &lt;span style="color:#ae81ff"&gt;npm&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; - &lt;span style="color:#f92672"&gt;name&lt;/span&gt;: &lt;span style="color:#ae81ff"&gt;Install dependencies&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#f92672"&gt;run&lt;/span&gt;: &lt;span style="color:#ae81ff"&gt;npm ci&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; - &lt;span style="color:#f92672"&gt;name&lt;/span&gt;: &lt;span style="color:#ae81ff"&gt;Patch theme for Hugo compatibility&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#f92672"&gt;run&lt;/span&gt;: &lt;span style="color:#ae81ff"&gt;bash scripts/patch-theme.sh&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; - &lt;span style="color:#f92672"&gt;name&lt;/span&gt;: &lt;span style="color:#ae81ff"&gt;Build&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#f92672"&gt;run&lt;/span&gt;: &lt;span style="color:#ae81ff"&gt;npm run build&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; - &lt;span style="color:#f92672"&gt;name&lt;/span&gt;: &lt;span style="color:#ae81ff"&gt;Deploy to Cloudflare Pages&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#f92672"&gt;run&lt;/span&gt;: &lt;span style="color:#ae81ff"&gt;npx wrangler pages deploy public --project-name=time-friend&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#f92672"&gt;env&lt;/span&gt;:
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#f92672"&gt;CLOUDFLARE_API_TOKEN&lt;/span&gt;: &lt;span style="color:#ae81ff"&gt;${{ secrets.CLOUDFLARE_API_TOKEN }}&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#f92672"&gt;CLOUDFLARE_ACCOUNT_ID&lt;/span&gt;: &lt;span style="color:#ae81ff"&gt;${{ secrets.CLOUDFLARE_ACCOUNT_ID }}&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;触发条件是 push 到 master 分支. 也支持手动触发 (&lt;code&gt;workflow_dispatch&lt;/code&gt;), 方便在不改代码的情况下重新部署.&lt;/p&gt;</description></item><item><title>博客的 Google SEO 是怎么做的</title><link>https://time-friend.com/zh/archive/blog-architecture-google-seo/</link><pubDate>Tue, 25 Mar 2025 11:08:00 +0000</pubDate><guid>https://time-friend.com/zh/archive/blog-architecture-google-seo/</guid><description>&lt;p&gt;这篇文章只讲 Google SEO. 其他搜索引擎不搞, 原因很简单: 流量大头在 Google, 把 Google 做好就够了.&lt;/p&gt;
&lt;h1 id="结构化数据"&gt;结构化数据&lt;/h1&gt;
&lt;p&gt;这是最重要的部分. 结构化数据让 Google 在搜索结果里展示 rich result, 包括发布时间, 作者, 摘要等信息.&lt;/p&gt;
&lt;p&gt;每篇文章在构建时自动注入 JSON-LD:&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"&gt;&lt;code class="language-html" data-lang="html"&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;{{ if .IsPage }}
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&amp;lt;&lt;span style="color:#f92672"&gt;script&lt;/span&gt; &lt;span style="color:#a6e22e"&gt;type&lt;/span&gt;&lt;span style="color:#f92672"&gt;=&lt;/span&gt;&lt;span style="color:#e6db74"&gt;&amp;#34;application/ld+json&amp;#34;&lt;/span&gt;&amp;gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;{
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#e6db74"&gt;&amp;#34;@context&amp;#34;&lt;/span&gt;&lt;span style="color:#f92672"&gt;:&lt;/span&gt; &lt;span style="color:#e6db74"&gt;&amp;#34;https://schema.org&amp;#34;&lt;/span&gt;,
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#e6db74"&gt;&amp;#34;@type&amp;#34;&lt;/span&gt;&lt;span style="color:#f92672"&gt;:&lt;/span&gt; &lt;span style="color:#e6db74"&gt;&amp;#34;Article&amp;#34;&lt;/span&gt;,
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#e6db74"&gt;&amp;#34;headline&amp;#34;&lt;/span&gt;&lt;span style="color:#f92672"&gt;:&lt;/span&gt; &lt;span style="color:#e6db74"&gt;&amp;#34;{{ .Title }}&amp;#34;&lt;/span&gt;,
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#e6db74"&gt;&amp;#34;datePublished&amp;#34;&lt;/span&gt;&lt;span style="color:#f92672"&gt;:&lt;/span&gt; &lt;span style="color:#e6db74"&gt;&amp;#34;{{ .Date.Format &amp;#34;&lt;/span&gt;&lt;span style="color:#ae81ff"&gt;2006&lt;/span&gt;&lt;span style="color:#f92672"&gt;-&lt;/span&gt;&lt;span style="color:#ae81ff"&gt;01&lt;/span&gt;&lt;span style="color:#f92672"&gt;-&lt;/span&gt;&lt;span style="color:#ae81ff"&gt;02&lt;/span&gt;&lt;span style="color:#a6e22e"&gt;T15&lt;/span&gt;&lt;span style="color:#f92672"&gt;:&lt;/span&gt;&lt;span style="color:#ae81ff"&gt;04&lt;/span&gt;&lt;span style="color:#f92672"&gt;:&lt;/span&gt;&lt;span style="color:#ae81ff"&gt;05&lt;/span&gt;&lt;span style="color:#a6e22e"&gt;Z07&lt;/span&gt;&lt;span style="color:#f92672"&gt;:&lt;/span&gt;&lt;span style="color:#ae81ff"&gt;00&lt;/span&gt;&lt;span style="color:#e6db74"&gt;&amp;#34; }}&amp;#34;&lt;/span&gt;,
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#e6db74"&gt;&amp;#34;dateModified&amp;#34;&lt;/span&gt;&lt;span style="color:#f92672"&gt;:&lt;/span&gt; &lt;span style="color:#e6db74"&gt;&amp;#34;{{ .Lastmod.Format &amp;#34;&lt;/span&gt;&lt;span style="color:#ae81ff"&gt;2006&lt;/span&gt;&lt;span style="color:#f92672"&gt;-&lt;/span&gt;&lt;span style="color:#ae81ff"&gt;01&lt;/span&gt;&lt;span style="color:#f92672"&gt;-&lt;/span&gt;&lt;span style="color:#ae81ff"&gt;02&lt;/span&gt;&lt;span style="color:#a6e22e"&gt;T15&lt;/span&gt;&lt;span style="color:#f92672"&gt;:&lt;/span&gt;&lt;span style="color:#ae81ff"&gt;04&lt;/span&gt;&lt;span style="color:#f92672"&gt;:&lt;/span&gt;&lt;span style="color:#ae81ff"&gt;05&lt;/span&gt;&lt;span style="color:#a6e22e"&gt;Z07&lt;/span&gt;&lt;span style="color:#f92672"&gt;:&lt;/span&gt;&lt;span style="color:#ae81ff"&gt;00&lt;/span&gt;&lt;span style="color:#e6db74"&gt;&amp;#34; }}&amp;#34;&lt;/span&gt;,
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#e6db74"&gt;&amp;#34;author&amp;#34;&lt;/span&gt;&lt;span style="color:#f92672"&gt;:&lt;/span&gt; {
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#e6db74"&gt;&amp;#34;@type&amp;#34;&lt;/span&gt;&lt;span style="color:#f92672"&gt;:&lt;/span&gt; &lt;span style="color:#e6db74"&gt;&amp;#34;Person&amp;#34;&lt;/span&gt;,
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#e6db74"&gt;&amp;#34;name&amp;#34;&lt;/span&gt;&lt;span style="color:#f92672"&gt;:&lt;/span&gt; &lt;span style="color:#e6db74"&gt;&amp;#34;{{ .Site.Params.author }}&amp;#34;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; },
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#e6db74"&gt;&amp;#34;description&amp;#34;&lt;/span&gt;&lt;span style="color:#f92672"&gt;:&lt;/span&gt; &lt;span style="color:#e6db74"&gt;&amp;#34;{{ if .Description }}{{ .Description }}{{ else }}{{ .Summary | plainify }}{{ end }}&amp;#34;&lt;/span&gt;,
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#e6db74"&gt;&amp;#34;url&amp;#34;&lt;/span&gt;&lt;span style="color:#f92672"&gt;:&lt;/span&gt; &lt;span style="color:#e6db74"&gt;&amp;#34;{{ .Permalink }}&amp;#34;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; {{ &lt;span style="color:#66d9ef"&gt;with&lt;/span&gt; .&lt;span style="color:#a6e22e"&gt;Params&lt;/span&gt;.&lt;span style="color:#a6e22e"&gt;tags&lt;/span&gt; }}
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; ,&lt;span style="color:#e6db74"&gt;&amp;#34;keywords&amp;#34;&lt;/span&gt;&lt;span style="color:#f92672"&gt;:&lt;/span&gt; &lt;span style="color:#e6db74"&gt;&amp;#34;{{ delimit . &amp;#34;&lt;/span&gt;, &lt;span style="color:#e6db74"&gt;&amp;#34; }}&amp;#34;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; {{ &lt;span style="color:#a6e22e"&gt;end&lt;/span&gt; }}
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;}
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&amp;lt;/&lt;span style="color:#f92672"&gt;script&lt;/span&gt;&amp;gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;{{ end }}
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;关键字段:&lt;/p&gt;</description></item><item><title>博客的构建流水线是怎么跑的</title><link>https://time-friend.com/zh/archive/blog-architecture-build-pipeline-pwa/</link><pubDate>Wed, 05 Mar 2025 16:30:00 +0000</pubDate><guid>https://time-friend.com/zh/archive/blog-architecture-build-pipeline-pwa/</guid><description>&lt;p&gt;文章写完之后, 总不能手动一条条部署. 自动化的目的很简单: push 完代码就什么都不用管了.&lt;/p&gt;
&lt;p&gt;本质上就两件事: 把 Markdown 变成静态文件扔到网上去, 顺便把构建流程自动化.&lt;/p&gt;
&lt;h1 id="gulp-任务"&gt;Gulp 任务&lt;/h1&gt;
&lt;p&gt;整个构建就两个 Gulp 任务, 串行跑:&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"&gt;&lt;code class="language-js" data-lang="js"&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#a6e22e"&gt;gulp&lt;/span&gt;.&lt;span style="color:#a6e22e"&gt;task&lt;/span&gt;(&lt;span style="color:#e6db74"&gt;&amp;#34;default&amp;#34;&lt;/span&gt;, &lt;span style="color:#a6e22e"&gt;gulp&lt;/span&gt;.&lt;span style="color:#a6e22e"&gt;series&lt;/span&gt;(&lt;span style="color:#e6db74"&gt;&amp;#39;build&amp;#39;&lt;/span&gt;, &lt;span style="color:#e6db74"&gt;&amp;#39;generate-service-worker&amp;#39;&lt;/span&gt;));
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;h2 id="build"&gt;build&lt;/h2&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"&gt;&lt;code class="language-js" data-lang="js"&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#a6e22e"&gt;gulp&lt;/span&gt;.&lt;span style="color:#a6e22e"&gt;task&lt;/span&gt;(&lt;span style="color:#e6db74"&gt;&amp;#39;build&amp;#39;&lt;/span&gt;, () =&amp;gt; &lt;span style="color:#a6e22e"&gt;gulp&lt;/span&gt;.&lt;span style="color:#a6e22e"&gt;src&lt;/span&gt;(&lt;span style="color:#e6db74"&gt;&amp;#39;./&amp;#39;&lt;/span&gt;).&lt;span style="color:#a6e22e"&gt;pipe&lt;/span&gt;(&lt;span style="color:#a6e22e"&gt;shell&lt;/span&gt;([&lt;span style="color:#e6db74"&gt;&amp;#39;hugo --buildFuture --minify&amp;#39;&lt;/span&gt;])));
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;一行代码. 调用 Hugo 构建, &lt;code&gt;--buildFuture&lt;/code&gt; 允许发布未来日期的内容, &lt;code&gt;--minify&lt;/code&gt; 在构建时做 HTML/CSS/JS 压缩.&lt;/p&gt;
&lt;p&gt;为什么用 gulp-shell 而不是直接调用 Hugo? 因为后续需要在构建完成后做一些处理, Gulp 作为编排工具把任务串起来比较方便. 如果用 npm script 串命令也可以, 但 Gulp 的 task 定义更清晰, 错误处理也更直接.&lt;/p&gt;
&lt;h2 id="generate-service-worker"&gt;generate-service-worker&lt;/h2&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"&gt;&lt;code class="language-js" data-lang="js"&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#a6e22e"&gt;gulp&lt;/span&gt;.&lt;span style="color:#a6e22e"&gt;task&lt;/span&gt;(&lt;span style="color:#e6db74"&gt;&amp;#39;generate-service-worker&amp;#39;&lt;/span&gt;, () =&amp;gt; {
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#66d9ef"&gt;return&lt;/span&gt; &lt;span style="color:#a6e22e"&gt;workbox&lt;/span&gt;.&lt;span style="color:#a6e22e"&gt;generateSW&lt;/span&gt;({
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#a6e22e"&gt;globDirectory&lt;/span&gt;&lt;span style="color:#f92672"&gt;:&lt;/span&gt; &lt;span style="color:#e6db74"&gt;&amp;#39;./public&amp;#39;&lt;/span&gt;,
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#a6e22e"&gt;globPatterns&lt;/span&gt;&lt;span style="color:#f92672"&gt;:&lt;/span&gt; [&lt;span style="color:#e6db74"&gt;&amp;#39;**/*.{woff2,woff,js,css,png.jpg}&amp;#39;&lt;/span&gt;],
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#a6e22e"&gt;globIgnores&lt;/span&gt;&lt;span style="color:#f92672"&gt;:&lt;/span&gt; [&lt;span style="color:#e6db74"&gt;&amp;#39;sw.js&amp;#39;&lt;/span&gt;],
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#a6e22e"&gt;swDest&lt;/span&gt;&lt;span style="color:#f92672"&gt;:&lt;/span&gt; &lt;span style="color:#e6db74"&gt;`./public/sw.js`&lt;/span&gt;,
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#a6e22e"&gt;clientsClaim&lt;/span&gt;&lt;span style="color:#f92672"&gt;:&lt;/span&gt; &lt;span style="color:#66d9ef"&gt;true&lt;/span&gt;,
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#a6e22e"&gt;skipWaiting&lt;/span&gt;&lt;span style="color:#f92672"&gt;:&lt;/span&gt; &lt;span style="color:#66d9ef"&gt;true&lt;/span&gt;,
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#a6e22e"&gt;runtimeCaching&lt;/span&gt;&lt;span style="color:#f92672"&gt;:&lt;/span&gt; [
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; { &lt;span style="color:#a6e22e"&gt;urlPattern&lt;/span&gt;&lt;span style="color:#f92672"&gt;:&lt;/span&gt; &lt;span style="color:#e6db74"&gt;/.*\.js/&lt;/span&gt;, &lt;span style="color:#a6e22e"&gt;handler&lt;/span&gt;&lt;span style="color:#f92672"&gt;:&lt;/span&gt; &lt;span style="color:#e6db74"&gt;&amp;#39;NetworkFirst&amp;#39;&lt;/span&gt; },
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; { &lt;span style="color:#a6e22e"&gt;urlPattern&lt;/span&gt;&lt;span style="color:#f92672"&gt;:&lt;/span&gt; &lt;span style="color:#e6db74"&gt;/.*\.css/&lt;/span&gt;, &lt;span style="color:#a6e22e"&gt;handler&lt;/span&gt;&lt;span style="color:#f92672"&gt;:&lt;/span&gt; &lt;span style="color:#e6db74"&gt;&amp;#39;StaleWhileRevalidate&amp;#39;&lt;/span&gt; },
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; { &lt;span style="color:#a6e22e"&gt;urlPattern&lt;/span&gt;&lt;span style="color:#f92672"&gt;:&lt;/span&gt; &lt;span style="color:#e6db74"&gt;/.*\.(?:png|jpg|jpeg|svg|gif)/&lt;/span&gt;,
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#a6e22e"&gt;handler&lt;/span&gt;&lt;span style="color:#f92672"&gt;:&lt;/span&gt; &lt;span style="color:#e6db74"&gt;&amp;#39;CacheFirst&amp;#39;&lt;/span&gt;,
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#a6e22e"&gt;options&lt;/span&gt;&lt;span style="color:#f92672"&gt;:&lt;/span&gt; { &lt;span style="color:#a6e22e"&gt;cacheName&lt;/span&gt;&lt;span style="color:#f92672"&gt;:&lt;/span&gt; &lt;span style="color:#e6db74"&gt;&amp;#39;images&amp;#39;&lt;/span&gt;, &lt;span style="color:#a6e22e"&gt;expiration&lt;/span&gt;&lt;span style="color:#f92672"&gt;:&lt;/span&gt; { &lt;span style="color:#a6e22e"&gt;maxEntries&lt;/span&gt;&lt;span style="color:#f92672"&gt;:&lt;/span&gt; &lt;span style="color:#ae81ff"&gt;50&lt;/span&gt; } } },
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; { &lt;span style="color:#a6e22e"&gt;urlPattern&lt;/span&gt;&lt;span style="color:#f92672"&gt;:&lt;/span&gt; &lt;span style="color:#e6db74"&gt;/.*\.html/&lt;/span&gt;, &lt;span style="color:#a6e22e"&gt;handler&lt;/span&gt;&lt;span style="color:#f92672"&gt;:&lt;/span&gt; &lt;span style="color:#e6db74"&gt;&amp;#39;NetworkFirst&amp;#39;&lt;/span&gt; }
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; ]
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; })
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; .&lt;span style="color:#a6e22e"&gt;then&lt;/span&gt;(() =&amp;gt; &lt;span style="color:#a6e22e"&gt;console&lt;/span&gt;.&lt;span style="color:#a6e22e"&gt;info&lt;/span&gt;(&lt;span style="color:#e6db74"&gt;&amp;#39;Service Worker 生成完成&amp;#39;&lt;/span&gt;))
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; .&lt;span style="color:#66d9ef"&gt;catch&lt;/span&gt;(&lt;span style="color:#a6e22e"&gt;error&lt;/span&gt; =&amp;gt; &lt;span style="color:#a6e22e"&gt;console&lt;/span&gt;.&lt;span style="color:#a6e22e"&gt;warn&lt;/span&gt;(&lt;span style="color:#e6db74"&gt;&amp;#39;Service Worker 生成失败: &amp;#39;&lt;/span&gt; &lt;span style="color:#f92672"&gt;+&lt;/span&gt; &lt;span style="color:#a6e22e"&gt;error&lt;/span&gt;));
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;});
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;这个任务用 Workbox 自动生成 SW, 具体原理和缓存策略在 &lt;a href="https://time-friend.com/zh/archive/blog-architecture-service-worker/"&gt;PWA 与 Service Worker&lt;/a&gt; 那篇里讲了.&lt;/p&gt;</description></item><item><title>我的博客主题是如何定制的</title><link>https://time-friend.com/zh/archive/blog-architecture-theme-customization/</link><pubDate>Sat, 15 Feb 2025 09:15:00 +0000</pubDate><guid>https://time-friend.com/zh/archive/blog-architecture-theme-customization/</guid><description>&lt;p&gt;主题用的 &lt;code&gt;hugo-cactus-dark&lt;/code&gt;, 一个暗色主题, 干净, 没什么花哨的东西. 完全够用.&lt;/p&gt;
&lt;p&gt;但原版主题只覆盖了基础功能. 我需要双语切换, Giscus 评论, 页面统计, 结构化数据, 这些原版都没有. 所以直接 fork 了一份, 在 &lt;code&gt;layouts/&lt;/code&gt; 里覆盖掉需要改的模板.&lt;/p&gt;
&lt;h1 id="覆盖了哪些"&gt;覆盖了哪些&lt;/h1&gt;
&lt;p&gt;&lt;code&gt;layouts/&lt;/code&gt; 目录下的模板优先级高于主题里的同名文件. 我只覆盖需要改的部分, 不需要动的就留给主题.&lt;/p&gt;
&lt;p&gt;这个东西开发的时候有个烦人的点: Hugo 对模板有缓存. 你改了 &lt;code&gt;layouts/&lt;/code&gt; 下的文件, 有时候浏览器还是用旧版本. 不是 Hugo 的锅, 是浏览器缓存了 HTML. 清一下或者开无痕模式就好.&lt;/p&gt;
&lt;h2 id="headhtml"&gt;head.html&lt;/h2&gt;
&lt;p&gt;改动最大的一个. 原版只输出了基本的 meta 和样式引用. 这里加了一堆东西:&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"&gt;&lt;code class="language-html" data-lang="html"&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#75715e"&gt;&amp;lt;!-- 搜索引擎验证 --&amp;gt;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&amp;lt;&lt;span style="color:#f92672"&gt;meta&lt;/span&gt; &lt;span style="color:#a6e22e"&gt;name&lt;/span&gt;&lt;span style="color:#f92672"&gt;=&lt;/span&gt;&lt;span style="color:#e6db74"&gt;&amp;#34;360-site-verification&amp;#34;&lt;/span&gt; &lt;span style="color:#a6e22e"&gt;content&lt;/span&gt;&lt;span style="color:#f92672"&gt;=&lt;/span&gt;&lt;span style="color:#e6db74"&gt;&amp;#34;xxx&amp;#34;&lt;/span&gt; /&amp;gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&amp;lt;&lt;span style="color:#f92672"&gt;meta&lt;/span&gt; &lt;span style="color:#a6e22e"&gt;name&lt;/span&gt;&lt;span style="color:#f92672"&gt;=&lt;/span&gt;&lt;span style="color:#e6db74"&gt;&amp;#34;sogou_site_verification&amp;#34;&lt;/span&gt; &lt;span style="color:#a6e22e"&gt;content&lt;/span&gt;&lt;span style="color:#f92672"&gt;=&lt;/span&gt;&lt;span style="color:#e6db74"&gt;&amp;#34;xxx&amp;#34;&lt;/span&gt; /&amp;gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#75715e"&gt;&amp;lt;!-- 双语 hreflang --&amp;gt;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;{{ if .IsTranslated }}
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;{{ range .Translations }}
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&amp;lt;&lt;span style="color:#f92672"&gt;link&lt;/span&gt; &lt;span style="color:#a6e22e"&gt;rel&lt;/span&gt;&lt;span style="color:#f92672"&gt;=&lt;/span&gt;&lt;span style="color:#e6db74"&gt;&amp;#34;alternate&amp;#34;&lt;/span&gt; &lt;span style="color:#a6e22e"&gt;hreflang&lt;/span&gt;&lt;span style="color:#f92672"&gt;=&lt;/span&gt;&lt;span style="color:#e6db74"&gt;&amp;#34;{{ .Lang }}&amp;#34;&lt;/span&gt; &lt;span style="color:#a6e22e"&gt;href&lt;/span&gt;&lt;span style="color:#f92672"&gt;=&lt;/span&gt;&lt;span style="color:#e6db74"&gt;&amp;#34;{{ .Permalink }}&amp;#34;&lt;/span&gt;&amp;gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;{{ end }}
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&amp;lt;&lt;span style="color:#f92672"&gt;link&lt;/span&gt; &lt;span style="color:#a6e22e"&gt;rel&lt;/span&gt;&lt;span style="color:#f92672"&gt;=&lt;/span&gt;&lt;span style="color:#e6db74"&gt;&amp;#34;alternate&amp;#34;&lt;/span&gt; &lt;span style="color:#a6e22e"&gt;hreflang&lt;/span&gt;&lt;span style="color:#f92672"&gt;=&lt;/span&gt;&lt;span style="color:#e6db74"&gt;&amp;#34;{{ .Lang }}&amp;#34;&lt;/span&gt; &lt;span style="color:#a6e22e"&gt;href&lt;/span&gt;&lt;span style="color:#f92672"&gt;=&lt;/span&gt;&lt;span style="color:#e6db74"&gt;&amp;#34;{{ .Permalink }}&amp;#34;&lt;/span&gt;&amp;gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;{{ end }}
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#75715e"&gt;&amp;lt;!-- Open Graph --&amp;gt;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&amp;lt;&lt;span style="color:#f92672"&gt;meta&lt;/span&gt; &lt;span style="color:#a6e22e"&gt;property&lt;/span&gt;&lt;span style="color:#f92672"&gt;=&lt;/span&gt;&lt;span style="color:#e6db74"&gt;&amp;#34;og:locale&amp;#34;&lt;/span&gt; &lt;span style="color:#a6e22e"&gt;content&lt;/span&gt;&lt;span style="color:#f92672"&gt;=&lt;/span&gt;&lt;span style="color:#e6db74"&gt;&amp;#34;{{ if eq .Lang &amp;#34;&lt;/span&gt;&lt;span style="color:#a6e22e"&gt;zh&lt;/span&gt;&lt;span style="color:#960050;background-color:#1e0010"&gt;&amp;#34;&lt;/span&gt; &lt;span style="color:#960050;background-color:#1e0010"&gt;}}&lt;/span&gt;&lt;span style="color:#a6e22e"&gt;zh_CN&lt;/span&gt;&lt;span style="color:#960050;background-color:#1e0010"&gt;{{&lt;/span&gt; &lt;span style="color:#a6e22e"&gt;else&lt;/span&gt; &lt;span style="color:#960050;background-color:#1e0010"&gt;}}&lt;/span&gt;&lt;span style="color:#a6e22e"&gt;en_US&lt;/span&gt;&lt;span style="color:#960050;background-color:#1e0010"&gt;{{&lt;/span&gt; &lt;span style="color:#a6e22e"&gt;end&lt;/span&gt; &lt;span style="color:#960050;background-color:#1e0010"&gt;}}&amp;#34;&lt;/span&gt;&amp;gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&amp;lt;&lt;span style="color:#f92672"&gt;meta&lt;/span&gt; &lt;span style="color:#a6e22e"&gt;property&lt;/span&gt;&lt;span style="color:#f92672"&gt;=&lt;/span&gt;&lt;span style="color:#e6db74"&gt;&amp;#34;og:title&amp;#34;&lt;/span&gt; &lt;span style="color:#a6e22e"&gt;content&lt;/span&gt;&lt;span style="color:#f92672"&gt;=&lt;/span&gt;&lt;span style="color:#e6db74"&gt;&amp;#34;{{ .Title }}&amp;#34;&lt;/span&gt;&amp;gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&amp;lt;&lt;span style="color:#f92672"&gt;meta&lt;/span&gt; &lt;span style="color:#a6e22e"&gt;property&lt;/span&gt;&lt;span style="color:#f92672"&gt;=&lt;/span&gt;&lt;span style="color:#e6db74"&gt;&amp;#34;og:image&amp;#34;&lt;/span&gt; &lt;span style="color:#a6e22e"&gt;content&lt;/span&gt;&lt;span style="color:#f92672"&gt;=&lt;/span&gt;&lt;span style="color:#e6db74"&gt;&amp;#34;{{ .Params.image | absURL }}&amp;#34;&lt;/span&gt;&amp;gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&amp;lt;&lt;span style="color:#f92672"&gt;meta&lt;/span&gt; &lt;span style="color:#a6e22e"&gt;property&lt;/span&gt;&lt;span style="color:#f92672"&gt;=&lt;/span&gt;&lt;span style="color:#e6db74"&gt;&amp;#34;og:description&amp;#34;&lt;/span&gt; &lt;span style="color:#a6e22e"&gt;content&lt;/span&gt;&lt;span style="color:#f92672"&gt;=&lt;/span&gt;&lt;span style="color:#e6db74"&gt;&amp;#34;{{ .Summary | truncate 200 }}&amp;#34;&lt;/span&gt;&amp;gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#75715e"&gt;&amp;lt;!-- Canonical --&amp;gt;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&amp;lt;&lt;span style="color:#f92672"&gt;link&lt;/span&gt; &lt;span style="color:#a6e22e"&gt;rel&lt;/span&gt;&lt;span style="color:#f92672"&gt;=&lt;/span&gt;&lt;span style="color:#e6db74"&gt;&amp;#34;canonical&amp;#34;&lt;/span&gt; &lt;span style="color:#a6e22e"&gt;href&lt;/span&gt;&lt;span style="color:#f92672"&gt;=&lt;/span&gt;&lt;span style="color:#e6db74"&gt;&amp;#34;{{ .Permalink }}&amp;#34;&lt;/span&gt;&amp;gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#75715e"&gt;&amp;lt;!-- 结构化数据 --&amp;gt;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;{{ if .IsPage }}
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&amp;lt;&lt;span style="color:#f92672"&gt;script&lt;/span&gt; &lt;span style="color:#a6e22e"&gt;type&lt;/span&gt;&lt;span style="color:#f92672"&gt;=&lt;/span&gt;&lt;span style="color:#e6db74"&gt;&amp;#34;application/ld+json&amp;#34;&lt;/span&gt;&amp;gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;{
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#e6db74"&gt;&amp;#34;@context&amp;#34;&lt;/span&gt;&lt;span style="color:#f92672"&gt;:&lt;/span&gt; &lt;span style="color:#e6db74"&gt;&amp;#34;https://schema.org&amp;#34;&lt;/span&gt;,
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#e6db74"&gt;&amp;#34;@type&amp;#34;&lt;/span&gt;&lt;span style="color:#f92672"&gt;:&lt;/span&gt; &lt;span style="color:#e6db74"&gt;&amp;#34;Article&amp;#34;&lt;/span&gt;,
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#e6db74"&gt;&amp;#34;headline&amp;#34;&lt;/span&gt;&lt;span style="color:#f92672"&gt;:&lt;/span&gt; &lt;span style="color:#e6db74"&gt;&amp;#34;{{ .Title }}&amp;#34;&lt;/span&gt;,
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#e6db74"&gt;&amp;#34;datePublished&amp;#34;&lt;/span&gt;&lt;span style="color:#f92672"&gt;:&lt;/span&gt; &lt;span style="color:#e6db74"&gt;&amp;#34;{{ .Date.Format &amp;#34;&lt;/span&gt;&lt;span style="color:#ae81ff"&gt;2006&lt;/span&gt;&lt;span style="color:#f92672"&gt;-&lt;/span&gt;&lt;span style="color:#ae81ff"&gt;01&lt;/span&gt;&lt;span style="color:#f92672"&gt;-&lt;/span&gt;&lt;span style="color:#ae81ff"&gt;02&lt;/span&gt;&lt;span style="color:#a6e22e"&gt;T15&lt;/span&gt;&lt;span style="color:#f92672"&gt;:&lt;/span&gt;&lt;span style="color:#ae81ff"&gt;04&lt;/span&gt;&lt;span style="color:#f92672"&gt;:&lt;/span&gt;&lt;span style="color:#ae81ff"&gt;05&lt;/span&gt;&lt;span style="color:#a6e22e"&gt;Z07&lt;/span&gt;&lt;span style="color:#f92672"&gt;:&lt;/span&gt;&lt;span style="color:#ae81ff"&gt;00&lt;/span&gt;&lt;span style="color:#e6db74"&gt;&amp;#34; }}&amp;#34;&lt;/span&gt;,
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#e6db74"&gt;&amp;#34;dateModified&amp;#34;&lt;/span&gt;&lt;span style="color:#f92672"&gt;:&lt;/span&gt; &lt;span style="color:#e6db74"&gt;&amp;#34;{{ .Lastmod.Format &amp;#34;&lt;/span&gt;&lt;span style="color:#ae81ff"&gt;2006&lt;/span&gt;&lt;span style="color:#f92672"&gt;-&lt;/span&gt;&lt;span style="color:#ae81ff"&gt;01&lt;/span&gt;&lt;span style="color:#f92672"&gt;-&lt;/span&gt;&lt;span style="color:#ae81ff"&gt;02&lt;/span&gt;&lt;span style="color:#a6e22e"&gt;T15&lt;/span&gt;&lt;span style="color:#f92672"&gt;:&lt;/span&gt;&lt;span style="color:#ae81ff"&gt;04&lt;/span&gt;&lt;span style="color:#f92672"&gt;:&lt;/span&gt;&lt;span style="color:#ae81ff"&gt;05&lt;/span&gt;&lt;span style="color:#a6e22e"&gt;Z07&lt;/span&gt;&lt;span style="color:#f92672"&gt;:&lt;/span&gt;&lt;span style="color:#ae81ff"&gt;00&lt;/span&gt;&lt;span style="color:#e6db74"&gt;&amp;#34; }}&amp;#34;&lt;/span&gt;,
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#e6db74"&gt;&amp;#34;author&amp;#34;&lt;/span&gt;&lt;span style="color:#f92672"&gt;:&lt;/span&gt; { &lt;span style="color:#e6db74"&gt;&amp;#34;@type&amp;#34;&lt;/span&gt;&lt;span style="color:#f92672"&gt;:&lt;/span&gt; &lt;span style="color:#e6db74"&gt;&amp;#34;Person&amp;#34;&lt;/span&gt;, &lt;span style="color:#e6db74"&gt;&amp;#34;name&amp;#34;&lt;/span&gt;&lt;span style="color:#f92672"&gt;:&lt;/span&gt; &lt;span style="color:#e6db74"&gt;&amp;#34;{{ .Site.Params.author }}&amp;#34;&lt;/span&gt; }
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;}
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&amp;lt;/&lt;span style="color:#f92672"&gt;script&lt;/span&gt;&amp;gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;{{ end }}
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;为什么要加 Open Graph? 因为文章分享到社交媒体时, 预览卡片需要这些 meta. 没有的话就只显示一个光秃秃的链接.&lt;/p&gt;</description></item><item><title>博客多语言是怎么实现的</title><link>https://time-friend.com/zh/archive/blog-architecture-i18n/</link><pubDate>Mon, 20 Jan 2025 14:21:00 +0000</pubDate><guid>https://time-friend.com/zh/archive/blog-architecture-i18n/</guid><description>&lt;p&gt;写技术博客有个尴尬: 中文内容国内读者看, 但海外流量也不少. 干脆中英文都上.&lt;/p&gt;
&lt;p&gt;这个博客是中英双语的. 同一篇文章有中文版和英文版, 各自有独立的 URL, 互不影响.&lt;/p&gt;
&lt;p&gt;i18n 分两层: 一是&lt;strong&gt;内容&lt;/strong&gt;的国际化 (文章本身有中英文版本), 二是&lt;strong&gt;界面&lt;/strong&gt;的国际化 (按钮, 菜单, 提示文字跟着语言切换).&lt;/p&gt;
&lt;h1 id="内容国际化"&gt;内容国际化&lt;/h1&gt;
&lt;h2 id="目录结构"&gt;目录结构&lt;/h2&gt;
&lt;p&gt;Hugo 的 &lt;code&gt;module.mounts&lt;/code&gt; 来做语言映射:&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"&gt;&lt;code class="language-yaml" data-lang="yaml"&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#f92672"&gt;module&lt;/span&gt;:
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#f92672"&gt;mounts&lt;/span&gt;:
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; - &lt;span style="color:#f92672"&gt;source&lt;/span&gt;: &lt;span style="color:#ae81ff"&gt;content/en&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#f92672"&gt;target&lt;/span&gt;: &lt;span style="color:#ae81ff"&gt;content&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#f92672"&gt;lang&lt;/span&gt;: &lt;span style="color:#ae81ff"&gt;en&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; - &lt;span style="color:#f92672"&gt;source&lt;/span&gt;: &lt;span style="color:#ae81ff"&gt;content&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#f92672"&gt;target&lt;/span&gt;: &lt;span style="color:#ae81ff"&gt;content&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#f92672"&gt;lang&lt;/span&gt;: &lt;span style="color:#ae81ff"&gt;zh&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#f92672"&gt;excludeFiles&lt;/span&gt;: &lt;span style="color:#e6db74"&gt;&amp;#39;en/**&amp;#39;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;英文内容从 &lt;code&gt;content/en&lt;/code&gt; 取, 中文内容从 &lt;code&gt;content&lt;/code&gt; 取, 排除掉 &lt;code&gt;en/&lt;/code&gt; 目录. 这样中文和英文文件互不干扰, 各自在独立的目录下.&lt;/p&gt;
&lt;p&gt;中文文章在 &lt;code&gt;content/archive/&lt;/code&gt; 下, 英文文章在 &lt;code&gt;content/en/archive/&lt;/code&gt; 下.&lt;/p&gt;
&lt;h2 id="translationkey-配对"&gt;translationKey 配对&lt;/h2&gt;
&lt;p&gt;用 Hugo 的 &lt;code&gt;translationKey&lt;/code&gt; 来配对文章. 同一篇文章的中英文版本用同一个 key:&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"&gt;&lt;code class="language-yaml" data-lang="yaml"&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#75715e"&gt;# 中文文章&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#f92672"&gt;translationKey&lt;/span&gt;: &lt;span style="color:#ae81ff"&gt;zh0189&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#f92672"&gt;title&lt;/span&gt;: &lt;span style="color:#ae81ff"&gt;Git系列之关于add命令的一些事&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#f92672"&gt;slug&lt;/span&gt;: &lt;span style="color:#ae81ff"&gt;git-series-about-add-command&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#75715e"&gt;# 英文文章&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#f92672"&gt;translationKey&lt;/span&gt;: &lt;span style="color:#ae81ff"&gt;zh0189&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#f92672"&gt;title&lt;/span&gt;: &lt;span style="color:#f92672"&gt;Git Series&lt;/span&gt;: &lt;span style="color:#ae81ff"&gt;About the Add Command&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#f92672"&gt;slug&lt;/span&gt;: &lt;span style="color:#ae81ff"&gt;git-series-about-add-command&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;Hugo 会自动把这两个页面识别为翻译对. 模板里用 &lt;code&gt;.Translations&lt;/code&gt; 拿到对应语言的版本, 用来做语言切换.&lt;/p&gt;</description></item><item><title>我的博客架构长什么样</title><link>https://time-friend.com/zh/archive/blog-architecture-overview/</link><pubDate>Fri, 10 Jan 2025 10:00:00 +0000</pubDate><guid>https://time-friend.com/zh/archive/blog-architecture-overview/</guid><description>&lt;p&gt;很多人好奇这个博客是怎么搭的.&lt;/p&gt;
&lt;p&gt;看起来很简单,但背后东西不少.算不上大工程,但从工程角度确实折腾了不少东西.双语架构,自动化构建, PWA, Google SEO 等等.&lt;/p&gt;
&lt;p&gt;所以打算写个系列,把现在的这套东西记录下来.用什么,为什么这么选,代码怎么写的,性能上怎么考虑的.&lt;/p&gt;
&lt;h1 id="整体架构"&gt;整体架构&lt;/h1&gt;
&lt;pre tabindex="0"&gt;&lt;code&gt;Markdown 内容 (中英双语)
 ↓
 Hugo SSG (extended, v0.164)
 ↓
 自定义主题 (fork cactus-dark, 大改)
 ↓
 Gulp Pipeline
 ├── hugo --minify
 └── Workbox generateSW
 ↓
 Cloudflare Pages (GitHub Actions CI)
&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;三层: 内容层, 构建层, 部署层. 没有数据库, 没有后端, 全是静态文件.&lt;/p&gt;
&lt;h2 id="为什么用-hugo"&gt;为什么用 Hugo&lt;/h2&gt;
&lt;p&gt;我是前端, 喜欢用前端圈的东西. Hugo 是用 Go 写的, 文章多了以后构建速度就是快. 两百多篇文章, 几秒就构建完了. 这就是核心原因.&lt;/p&gt;
&lt;p&gt;构建快了, 更新博客的心理负担就小. 这是一个正反馈.&lt;/p&gt;
&lt;p&gt;Go 模板用起来也挺顺手, 变量作用域, 管道语法, partial 系统, 该有的都有. 不过刚开始接触的时候, &lt;code&gt;{{ range }}&lt;/code&gt; 和 &lt;code&gt;{{ with }}&lt;/code&gt; 的区别可能会绕一下.&lt;/p&gt;</description></item><item><title>使用Travis CI自动化部署你的Hugo,Hexo博客</title><link>https://time-friend.com/zh/archive/automated-deployment-hugo-hexo-blog-with-travis-ci/</link><pubDate>Tue, 20 Nov 2018 16:14:25 +0000</pubDate><guid>https://time-friend.com/zh/archive/automated-deployment-hugo-hexo-blog-with-travis-ci/</guid><description>&lt;h1 id="travis-ci-是什么"&gt;Travis CI 是什么?&lt;/h1&gt;
&lt;p&gt;Travis CI 是在线托管的 CI 服务，用 Travis 来进行持续集成，不需要自己搭服务器。最重要的是，它对开源项目是免费的。
如果公司是用的是 gitlab,也有提供相应的持续集成服务.这里就过多赘述.&lt;/p&gt;
&lt;h1 id="travis-ci-配置文件"&gt;Travis CI 配置文件&lt;/h1&gt;
&lt;p&gt;Travis 要求项目的根目录下面，必须有一个&lt;code&gt;.travis.yml&lt;/code&gt;文件。&lt;/p&gt;
&lt;p&gt;当你的仓库有提交的时候,travis 会自动执行你下面配置的行为.&lt;/p&gt;
&lt;h1 id="travis-ci-的钩子与生命周期"&gt;Travis CI 的钩子与生命周期&lt;/h1&gt;
&lt;h2 id="travis-的钩子"&gt;Travis 的钩子&lt;/h2&gt;
&lt;p&gt;Travis 有不同的阶段,他提供了 7 个钩子。&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;before_install：install 阶段之前执行&lt;/li&gt;
&lt;li&gt;before_script：script 阶段之前执行&lt;/li&gt;
&lt;li&gt;after_failure：script 阶段失败时执行&lt;/li&gt;
&lt;li&gt;after_success：script 阶段成功时执行&lt;/li&gt;
&lt;li&gt;before_deploy：deploy 步骤之前执行&lt;/li&gt;
&lt;li&gt;after_deploy：deploy 步骤之后执行&lt;/li&gt;
&lt;li&gt;after_script：script 阶段之后执行&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 id="生命周期"&gt;生命周期&lt;/h2&gt;
&lt;ol&gt;
&lt;li&gt;before_install&lt;/li&gt;
&lt;li&gt;install&lt;/li&gt;
&lt;li&gt;before_script&lt;/li&gt;
&lt;li&gt;script&lt;/li&gt;
&lt;li&gt;aftersuccess or afterfailure&lt;/li&gt;
&lt;li&gt;[OPTIONAL] before_deploy&lt;/li&gt;
&lt;li&gt;[OPTIONAL] deploy&lt;/li&gt;
&lt;li&gt;[OPTIONAL] after_deploy&lt;/li&gt;
&lt;li&gt;after_script&lt;/li&gt;
&lt;/ol&gt;
&lt;h1 id="travisyml"&gt;.travis.yml&lt;/h1&gt;
&lt;p&gt;下面是我的博客部署配置,也是我项目&lt;code&gt;.travis.yml&lt;/code&gt;文件的内容.&lt;/p&gt;
&lt;h2 id="hugo"&gt;hugo&lt;/h2&gt;
&lt;p&gt;这是我的 hugo 部署配置,仅供参考&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"&gt;&lt;code class="language-yaml" data-lang="yaml"&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#f92672"&gt;language&lt;/span&gt;: &lt;span style="color:#ae81ff"&gt;node_js&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#f92672"&gt;node_js&lt;/span&gt;: &lt;span style="color:#ae81ff"&gt;10.13.0&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#f92672"&gt;install&lt;/span&gt;:
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; - &lt;span style="color:#ae81ff"&gt;wget https://github.com/gohugoio/hugo/releases/download/v0.51/hugo_0.51_Linux-64bit.deb&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; - &lt;span style="color:#ae81ff"&gt;sudo dpkg -i hugo*.deb&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; - &lt;span style="color:#ae81ff"&gt;hugo version&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; - &lt;span style="color:#ae81ff"&gt;rm -rf public&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; - &lt;span style="color:#ae81ff"&gt;npm install&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#f92672"&gt;script&lt;/span&gt;:
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; - &lt;span style="color:#ae81ff"&gt;hugo --buildFuture&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; - &lt;span style="color:#ae81ff"&gt;gulp&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; - &lt;span style="color:#ae81ff"&gt;echo &amp;#39;Build done!&amp;#39;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#f92672"&gt;after_success&lt;/span&gt;:
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; - &lt;span style="color:#ae81ff"&gt;git config --global user.name &amp;#34;Fan&amp;#34;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; - &lt;span style="color:#ae81ff"&gt;git config --global user.email &amp;#34;你的邮箱&amp;#34;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; - &lt;span style="color:#ae81ff"&gt;git clone https://${ACCESS_TOKEN}@github.com/Num142857/alili.tech.git container&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; - &lt;span style="color:#ae81ff"&gt;rm -rf container/*&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; - &lt;span style="color:#ae81ff"&gt;cp -r public/* container&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; - &lt;span style="color:#ae81ff"&gt;cd container&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; - &lt;span style="color:#ae81ff"&gt;git add .&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; - &lt;span style="color:#ae81ff"&gt;git commit -m &amp;#39;Travis upate blog&amp;#39;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; - &lt;span style="color:#ae81ff"&gt;git push -u origin gh-pages -f&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;h2 id="hexo"&gt;Hexo&lt;/h2&gt;
&lt;p&gt;这是我的 hexo 部署配置,仅供参考.&lt;/p&gt;</description></item><item><title>让你的Hugo博客支持echarts图表</title><link>https://time-friend.com/zh/archive/make-your-hugo-blog-support-echarts-charts/</link><pubDate>Mon, 19 Nov 2018 16:14:25 +0000</pubDate><guid>https://time-friend.com/zh/archive/make-your-hugo-blog-support-echarts-charts/</guid><description>&lt;p&gt;在之前hexo构建的博客里,有使用到图表,但是现在迁移到hugo之后,就没有相关的插件支持了.&lt;/p&gt;
&lt;p&gt;所以自己动手丰衣足食.&lt;/p&gt;
&lt;p&gt;在hugo中有支持一种特性叫做 &lt;code&gt;Shortcodes&lt;/code&gt;.简单的来说就是一个可以传参的小模板.&lt;/p&gt;
&lt;h1 id="创建shortcodes"&gt;创建Shortcodes&lt;/h1&gt;
&lt;p&gt;创建 &lt;code&gt;./layouts/Shortcodes/echarts.html&lt;/code&gt;文件&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"&gt;&lt;code class="language-html" data-lang="html"&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&amp;lt;&lt;span style="color:#f92672"&gt;div&lt;/span&gt; &lt;span style="color:#a6e22e"&gt;id&lt;/span&gt;&lt;span style="color:#f92672"&gt;=&lt;/span&gt;&lt;span style="color:#e6db74"&gt;&amp;#34;echarts{{ .Get `height` }}&amp;#34;&lt;/span&gt; &lt;span style="color:#a6e22e"&gt;style&lt;/span&gt;&lt;span style="color:#f92672"&gt;=&lt;/span&gt;&lt;span style="color:#e6db74"&gt;&amp;#34;width: 100%;height: {{.Get `height`}}px;margin: 0 auto&amp;#34;&lt;/span&gt;&amp;gt;&amp;lt;/&lt;span style="color:#f92672"&gt;div&lt;/span&gt;&amp;gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&amp;lt;&lt;span style="color:#f92672"&gt;script&lt;/span&gt; &lt;span style="color:#a6e22e"&gt;src&lt;/span&gt;&lt;span style="color:#f92672"&gt;=&lt;/span&gt;&lt;span style="color:#e6db74"&gt;&amp;#34;https://cdn.bootcss.com/echarts/3.8.0/echarts.common.min.js&amp;#34;&lt;/span&gt;&amp;gt;&amp;lt;/&lt;span style="color:#f92672"&gt;script&lt;/span&gt;&amp;gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&amp;lt;&lt;span style="color:#f92672"&gt;script&lt;/span&gt; &lt;span style="color:#a6e22e"&gt;type&lt;/span&gt;&lt;span style="color:#f92672"&gt;=&lt;/span&gt;&lt;span style="color:#e6db74"&gt;&amp;#34;text/javascript&amp;#34;&lt;/span&gt;&amp;gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#75715e"&gt;// 基于准备好的dom，初始化echarts实例
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#66d9ef"&gt;var&lt;/span&gt; &lt;span style="color:#a6e22e"&gt;myChart&lt;/span&gt; &lt;span style="color:#f92672"&gt;=&lt;/span&gt; &lt;span style="color:#a6e22e"&gt;echarts&lt;/span&gt;.&lt;span style="color:#a6e22e"&gt;init&lt;/span&gt;(document.&lt;span style="color:#a6e22e"&gt;getElementById&lt;/span&gt;(&lt;span style="color:#e6db74"&gt;&amp;#39;echarts{{ .Get `height` }}&amp;#39;&lt;/span&gt;));
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#75715e"&gt;// 指定图表的配置项和数据
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#66d9ef"&gt;var&lt;/span&gt; &lt;span style="color:#a6e22e"&gt;option&lt;/span&gt; &lt;span style="color:#f92672"&gt;=&lt;/span&gt; &lt;span style="color:#a6e22e"&gt;JSON&lt;/span&gt;.&lt;span style="color:#a6e22e"&gt;parse&lt;/span&gt;({{ .&lt;span style="color:#a6e22e"&gt;Inner&lt;/span&gt; }})
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#75715e"&gt;// 使用刚指定的配置项和数据显示图表。
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#a6e22e"&gt;myChart&lt;/span&gt;.&lt;span style="color:#a6e22e"&gt;setOption&lt;/span&gt;(&lt;span style="color:#a6e22e"&gt;option&lt;/span&gt;);
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&amp;lt;/&lt;span style="color:#f92672"&gt;script&lt;/span&gt;&amp;gt;
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;h1 id="使用"&gt;使用&lt;/h1&gt;
&lt;p&gt;在 Shortcodes 插入echarts的配置数据,这样你就可以再页面中看到一个完整的图表了&lt;/p&gt;
&lt;div id='raw'&gt;
&lt;p style="opacity: 0;"&gt;
Time Friend - Be a friend of time, long-term thinking, documenting growth
本文资源来源互联网，仅供学习研究使用，版权归该资源的合法拥有者所有，
&lt;/p&gt;

 &lt;script&gt;
 $(function () {
 var html = "\n\u003cpre\u003e\n\u003ccode class=\u0022language-json hljs\u0022\u003e\n\u003cspan class=\u0022hljs-string\u0022\u003e\u0022{{\u0022\u003c\/span\u003e \u0026lt; echarts height=\u003cspan class=\u0022hljs-string\u0022\u003e\u0022400\u0022\u003c\/span\u003e \u0026gt; \u003cspan class=\u0022hljs-string\u0022\u003e\u0022}}\u0022\u003c\/span\u003e\n\u003cbr\u003e\n{\u003cspan class=\u0022hljs-attr\u0022\u003e\u0022textStyle\u0022\u003c\/span\u003e:{\u003cspan class=\u0022hljs-attr\u0022\u003e\u0022color\u0022\u003c\/span\u003e:\u003cspan class=\u0022hljs-string\u0022\u003e\u0022#fff\u0022\u003c\/span\u003e},\u003cspan class=\u0022hljs-attr\u0022\u003e\u0022title\u0022\u003c\/span\u003e:{\u003cspan class=\u0022hljs-attr\u0022\u003e\u0022text\u0022\u003c\/span\u003e:\u003cspan class=\u0022hljs-string\u0022\u003e\u00222018年11月国内浏览器数据统计\u0022\u003c\/span\u003e,\u003cspan class=\u0022hljs-attr\u0022\u003e\u0022subtext\u0022\u003c\/span\u003e:\u003cspan class=\u0022hljs-string\u0022\u003e\u0022浏览器数据分析\u0022\u003c\/span\u003e,\u003cspan class=\u0022hljs-attr\u0022\u003e\u0022x\u0022\u003c\/span\u003e:\u003cspan class=\u0022hljs-string\u0022\u003e\u0022center\u0022\u003c\/span\u003e,\u003cspan class=\u0022hljs-attr\u0022\u003e\u0022textStyle\u0022\u003c\/span\u003e:{\u003cspan class=\u0022hljs-attr\u0022\u003e\u0022color\u0022\u003c\/span\u003e:\u003cspan class=\u0022hljs-string\u0022\u003e\u0022#fff\u0022\u003c\/span\u003e}},\u003cspan class=\u0022hljs-attr\u0022\u003e\u0022tooltip\u0022\u003c\/span\u003e:{\u003cspan class=\u0022hljs-attr\u0022\u003e\u0022trigger\u0022\u003c\/span\u003e:\u003cspan class=\u0022hljs-string\u0022\u003e\u0022item\u0022\u003c\/span\u003e,\u003cspan class=\u0022hljs-attr\u0022\u003e\u0022formatter\u0022\u003c\/span\u003e:\u003cspan class=\u0022hljs-string\u0022\u003e\u0022{a} \u0026lt;br\/\u0026gt;{b} : {c} ({d}%)\u0022\u003c\/span\u003e},\u003cspan class=\u0022hljs-attr\u0022\u003e\u0022legend\u0022\u003c\/span\u003e:{\u003cspan class=\u0022hljs-attr\u0022\u003e\u0022type\u0022\u003c\/span\u003e:\u003cspan class=\u0022hljs-string\u0022\u003e\u0022scroll\u0022\u003c\/span\u003e,\u003cspan class=\u0022hljs-attr\u0022\u003e\u0022orient\u0022\u003c\/span\u003e:\u003cspan class=\u0022hljs-string\u0022\u003e\u0022vertical\u0022\u003c\/span\u003e,\u003cspan class=\u0022hljs-attr\u0022\u003e\u0022right\u0022\u003c\/span\u003e:\u003cspan class=\u0022hljs-number\u0022\u003e10\u003c\/span\u003e,\u003cspan class=\u0022hljs-attr\u0022\u003e\u0022top\u0022\u003c\/span\u003e:\u003cspan class=\u0022hljs-number\u0022\u003e120\u003c\/span\u003e,\u003cspan class=\u0022hljs-attr\u0022\u003e\u0022bottom\u0022\u003c\/span\u003e:\u003cspan class=\u0022hljs-number\u0022\u003e20\u003c\/span\u003e,\u003cspan class=\u0022hljs-attr\u0022\u003e\u0022data\u0022\u003c\/span\u003e:[\u003cspan class=\u0022hljs-string\u0022\u003e\u0022Chrome\u0022\u003c\/span\u003e,\u003cspan class=\u0022hljs-string\u0022\u003e\u0022IE 9.0\u0022\u003c\/span\u003e,\u003cspan class=\u0022hljs-string\u0022\u003e\u0022IE 11.0\u0022\u003c\/span\u003e,\u003cspan class=\u0022hljs-string\u0022\u003e\u0022QQ\u0022\u003c\/span\u003e,\u003cspan class=\u0022hljs-string\u0022\u003e\u0022IE 8.0\u0022\u003c\/span\u003e,\u003cspan class=\u0022hljs-string\u0022\u003e\u00222345\u0022\u003c\/span\u003e,\u003cspan class=\u0022hljs-string\u0022\u003e\u0022搜狗高速\u0022\u003c\/span\u003e,\u003cspan class=\u0022hljs-string\u0022\u003e\u0022Firefox\u0022\u003c\/span\u003e,\u003cspan class=\u0022hljs-string\u0022\u003e\u0022Safari\u0022\u003c\/span\u003e,\u003cspan class=\u0022hljs-string\u0022\u003e\u0022其他\u0022\u003c\/span\u003e],\u003cspan class=\u0022hljs-attr\u0022\u003e\u0022textStyle\u0022\u003c\/span\u003e:{\u003cspan class=\u0022hljs-attr\u0022\u003e\u0022color\u0022\u003c\/span\u003e:\u003cspan class=\u0022hljs-string\u0022\u003e\u0022#fff\u0022\u003c\/span\u003e}},\u003cspan class=\u0022hljs-attr\u0022\u003e\u0022series\u0022\u003c\/span\u003e:[{\u003cspan class=\u0022hljs-attr\u0022\u003e\u0022name\u0022\u003c\/span\u003e:\u003cspan class=\u0022hljs-string\u0022\u003e\u0022浏览器用户比例\u0022\u003c\/span\u003e,\u003cspan class=\u0022hljs-attr\u0022\u003e\u0022type\u0022\u003c\/span\u003e:\u003cspan class=\u0022hljs-string\u0022\u003e\u0022pie\u0022\u003c\/span\u003e,\u003cspan class=\u0022hljs-attr\u0022\u003e\u0022radius\u0022\u003c\/span\u003e:\u003cspan class=\u0022hljs-string\u0022\u003e\u002255%\u0022\u003c\/span\u003e,\u003cspan class=\u0022hljs-attr\u0022\u003e\u0022center\u0022\u003c\/span\u003e:[\u003cspan class=\u0022hljs-string\u0022\u003e\u002250%\u0022\u003c\/span\u003e,\u003cspan class=\u0022hljs-string\u0022\u003e\u002260%\u0022\u003c\/span\u003e],\u003cspan class=\u0022hljs-attr\u0022\u003e\u0022data\u0022\u003c\/span\u003e:[{\u003cspan class=\u0022hljs-attr\u0022\u003e\u0022name\u0022\u003c\/span\u003e:\u003cspan class=\u0022hljs-string\u0022\u003e\u0022Chrome\u0022\u003c\/span\u003e,\u003cspan class=\u0022hljs-attr\u0022\u003e\u0022value\u0022\u003c\/span\u003e:\u003cspan class=\u0022hljs-number\u0022\u003e46.88\u003c\/span\u003e},{\u003cspan class=\u0022hljs-attr\u0022\u003e\u0022name\u0022\u003c\/span\u003e:\u003cspan class=\u0022hljs-string\u0022\u003e\u0022IE 9.0\u0022\u003c\/span\u003e,\u003cspan class=\u0022hljs-attr\u0022\u003e\u0022value\u0022\u003c\/span\u003e:\u003cspan class=\u0022hljs-number\u0022\u003e7.4\u003c\/span\u003e},{\u003cspan class=\u0022hljs-attr\u0022\u003e\u0022name\u0022\u003c\/span\u003e:\u003cspan class=\u0022hljs-string\u0022\u003e\u0022IE 11.0\u0022\u003c\/span\u003e,\u003cspan class=\u0022hljs-attr\u0022\u003e\u0022value\u0022\u003c\/span\u003e:\u003cspan class=\u0022hljs-number\u0022\u003e6.21\u003c\/span\u003e},{\u003cspan class=\u0022hljs-attr\u0022\u003e\u0022name\u0022\u003c\/span\u003e:\u003cspan class=\u0022hljs-string\u0022\u003e\u0022QQ\u0022\u003c\/span\u003e,\u003cspan class=\u0022hljs-attr\u0022\u003e\u0022value\u0022\u003c\/span\u003e:\u003cspan class=\u0022hljs-number\u0022\u003e5.75\u003c\/span\u003e},{\u003cspan class=\u0022hljs-attr\u0022\u003e\u0022name\u0022\u003c\/span\u003e:\u003cspan class=\u0022hljs-string\u0022\u003e\u0022IE 8.0\u0022\u003c\/span\u003e,\u003cspan class=\u0022hljs-attr\u0022\u003e\u0022value\u0022\u003c\/span\u003e:\u003cspan class=\u0022hljs-number\u0022\u003e5.74\u003c\/span\u003e},{\u003cspan class=\u0022hljs-attr\u0022\u003e\u0022name\u0022\u003c\/span\u003e:\u003cspan class=\u0022hljs-string\u0022\u003e\u00222345\u0022\u003c\/span\u003e,\u003cspan class=\u0022hljs-attr\u0022\u003e\u0022value\u0022\u003c\/span\u003e:\u003cspan class=\u0022hljs-number\u0022\u003e5.68\u003c\/span\u003e},{\u003cspan class=\u0022hljs-attr\u0022\u003e\u0022name\u0022\u003c\/span\u003e:\u003cspan class=\u0022hljs-string\u0022\u003e\u0022搜狗高速\u0022\u003c\/span\u003e,\u003cspan class=\u0022hljs-attr\u0022\u003e\u0022value\u0022\u003c\/span\u003e:\u003cspan class=\u0022hljs-number\u0022\u003e4.74\u003c\/span\u003e},{\u003cspan class=\u0022hljs-attr\u0022\u003e\u0022name\u0022\u003c\/span\u003e:\u003cspan class=\u0022hljs-string\u0022\u003e\u0022Firefox\u0022\u003c\/span\u003e,\u003cspan class=\u0022hljs-attr\u0022\u003e\u0022value\u0022\u003c\/span\u003e:\u003cspan class=\u0022hljs-number\u0022\u003e2.54\u003c\/span\u003e},{\u003cspan class=\u0022hljs-attr\u0022\u003e\u0022name\u0022\u003c\/span\u003e:\u003cspan class=\u0022hljs-string\u0022\u003e\u0022Safari\u0022\u003c\/span\u003e,\u003cspan class=\u0022hljs-attr\u0022\u003e\u0022value\u0022\u003c\/span\u003e:\u003cspan class=\u0022hljs-number\u0022\u003e2.48\u003c\/span\u003e},{\u003cspan class=\u0022hljs-attr\u0022\u003e\u0022name\u0022\u003c\/span\u003e:\u003cspan class=\u0022hljs-string\u0022\u003e\u0022其他\u0022\u003c\/span\u003e,\u003cspan class=\u0022hljs-attr\u0022\u003e\u0022value\u0022\u003c\/span\u003e:\u003cspan class=\u0022hljs-number\u0022\u003e12.59\u003c\/span\u003e}],\u003cspan class=\u0022hljs-attr\u0022\u003e\u0022itemStyle\u0022\u003c\/span\u003e:{\u003cspan class=\u0022hljs-attr\u0022\u003e\u0022emphasis\u0022\u003c\/span\u003e:{\u003cspan class=\u0022hljs-attr\u0022\u003e\u0022shadowBlur\u0022\u003c\/span\u003e:\u003cspan class=\u0022hljs-number\u0022\u003e10\u003c\/span\u003e,\u003cspan class=\u0022hljs-attr\u0022\u003e\u0022shadowOffsetX\u0022\u003c\/span\u003e:\u003cspan class=\u0022hljs-number\u0022\u003e0\u003c\/span\u003e,\u003cspan class=\u0022hljs-attr\u0022\u003e\u0022shadowColor\u0022\u003c\/span\u003e:\u003cspan class=\u0022hljs-string\u0022\u003e\u0022rgba(0, 0, 0, 0.5)\u0022\u003c\/span\u003e}}}]}\n\u003cbr\u003e\n\u003cspan class=\u0022hljs-string\u0022\u003e\u0022{{\u0022\u003c\/span\u003e \u0026lt; \/echarts \u0026gt; \u003cspan class=\u0022hljs-string\u0022\u003e\u0022}}\u0022\u003c\/span\u003e\n\u003c\/code\u003e\n\u003c\/pre\u003e\n"
 html = html.replace(/"{/g, "{")
 html = html.replace(/{"/g, "{")
 html = html.replace(/"}/g, "}")
 html = html.replace(/}"/g, "}")
 $('#raw').html(html);

 let postTitle = $('.posttitle').text()
 let postContentTitle = $('#raw &gt; h1').text()
 if(postTitle === postContentTitle){
 $('#raw &gt; h1').hide()
 }
 $('button.preview').hide()
 })

 &lt;/script&gt;
&lt;/div&gt;

&lt;h1 id="效果"&gt;效果&lt;/h1&gt;
&lt;div id="echarts400" style="width: 100%;height: 400px;margin: 0 auto"&gt;&lt;/div&gt;
&lt;script src="https://cdn.bootcss.com/echarts/3.8.0/echarts.common.min.js"&gt;&lt;/script&gt;
&lt;script type="text/javascript"&gt;
 
 var myChart = echarts.init(document.getElementById('echarts400'));
 
 var option = JSON.parse("\n {\"textStyle\":{\"color\":\"#fff\"},\"title\":{\"text\":\"2018年11月国内浏览器数据统计\",\"subtext\":\"浏览器数据分析\",\"x\":\"center\",\"textStyle\":{\"color\":\"#fff\"}},\"tooltip\":{\"trigger\":\"item\",\"formatter\":\"{a} \u003cbr/\u003e{b} : {c} ({d}%)\"},\"legend\":{\"type\":\"scroll\",\"orient\":\"vertical\",\"right\":10,\"top\":120,\"bottom\":20,\"data\":[\"Chrome\",\"IE 9.0\",\"IE 11.0\",\"QQ\",\"IE 8.0\",\"2345\",\"搜狗高速\",\"Firefox\",\"Safari\",\"其他\"],\"textStyle\":{\"color\":\"#fff\"}},\"series\":[{\"name\":\"浏览器用户比例\",\"type\":\"pie\",\"radius\":\"55%\",\"center\":[\"50%\",\"60%\"],\"data\":[{\"name\":\"Chrome\",\"value\":46.88},{\"name\":\"IE 9.0\",\"value\":7.4},{\"name\":\"IE 11.0\",\"value\":6.21},{\"name\":\"QQ\",\"value\":5.75},{\"name\":\"IE 8.0\",\"value\":5.74},{\"name\":\"2345\",\"value\":5.68},{\"name\":\"搜狗高速\",\"value\":4.74},{\"name\":\"Firefox\",\"value\":2.54},{\"name\":\"Safari\",\"value\":2.48},{\"name\":\"其他\",\"value\":12.59}],\"itemStyle\":{\"emphasis\":{\"shadowBlur\":10,\"shadowOffsetX\":0,\"shadowColor\":\"rgba(0, 0, 0, 0.5)\"}}}]}\n")
 
 myChart.setOption(option);
&lt;/script&gt;</description></item><item><title>Hugo平台博文指定时间之后不显示?</title><link>https://time-friend.com/zh/archive/hugo-articles-not-displaying-after-specified-time/</link><pubDate>Sun, 18 Nov 2018 16:14:25 +0000</pubDate><guid>https://time-friend.com/zh/archive/hugo-articles-not-displaying-after-specified-time/</guid><description>&lt;p&gt;自从博客切换到Hugo之后,是遇到了一些坑.&lt;/p&gt;
&lt;p&gt;明明正确添加到文章,页面时间调整到今天,或者是今天之后缺不能显示在文章列表里.&lt;/p&gt;
&lt;p&gt;原因是Hugo模板在循环遍历文件的时候,只要超过当前时间的文章都不会出现.&lt;/p&gt;
&lt;h2 id="时区问题"&gt;时区问题&lt;/h2&gt;
&lt;p&gt;如果你的文章时间没有指定时区的话.&lt;/p&gt;
&lt;p&gt;像这样&lt;code&gt;2018-11-19 16:14:25&lt;/code&gt;,很有可能文章不会显示.&lt;/p&gt;
&lt;p&gt;Hugo时间统一为格林威治时间,因为中国的时间比格林威治时间早8个小时.
格林威治时间没有到你配置的时间的时候,文章是不会出现在文章列表里的.&lt;/p&gt;
&lt;h2 id="解决方案"&gt;解决方案&lt;/h2&gt;
&lt;p&gt;本地服务&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;hugo server --buildFuture
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;页面生成&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;hugo --buildFuture
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;</description></item><item><title>Hugo博客百度SEO终极优化,熊掌号自动推送</title><link>https://time-friend.com/zh/archive/hugo-template-seo-optimization/</link><pubDate>Sat, 17 Nov 2018 16:14:25 +0000</pubDate><guid>https://time-friend.com/zh/archive/hugo-template-seo-optimization/</guid><description>&lt;p&gt;在切换到Hugo平台之后,比较头疼的是之前hexo很多seo的插件不能使用了.
下面跟大家说一下我的seo优化方案.&lt;/p&gt;
&lt;h1 id="meta标签优化"&gt;Meta标签优化&lt;/h1&gt;
&lt;h2 id="description"&gt;Description&lt;/h2&gt;
&lt;p&gt;meta description，被认为是最有用的meta标签，是网站的简介信息。
content控制在100个字符以内比较好。&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"&gt;&lt;code class="language-html" data-lang="html"&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&amp;lt;&lt;span style="color:#f92672"&gt;meta&lt;/span&gt; &lt;span style="color:#a6e22e"&gt;name&lt;/span&gt;&lt;span style="color:#f92672"&gt;=&lt;/span&gt;&lt;span style="color:#e6db74"&gt;&amp;#39;description&amp;#39;&lt;/span&gt; &lt;span style="color:#a6e22e"&gt;itemprop&lt;/span&gt;&lt;span style="color:#f92672"&gt;=&lt;/span&gt;&lt;span style="color:#e6db74"&gt;&amp;#34;description&amp;#34;&lt;/span&gt; &lt;span style="color:#a6e22e"&gt;content&lt;/span&gt;&lt;span style="color:#f92672"&gt;=&lt;/span&gt;&lt;span style="color:#e6db74"&gt;&amp;#34;{{ if .Description }}{{ .Description }}{{ else }}{{if .IsPage}}{{substr .Summary 0 100}}{{ end }}{{ end }}&amp;#34;&lt;/span&gt;&amp;gt;
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;h2 id="keywords"&gt;Keywords&lt;/h2&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"&gt;&lt;code class="language-html" data-lang="html"&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;{{ if .Keywords }} 
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&amp;lt;&lt;span style="color:#f92672"&gt;meta&lt;/span&gt; &lt;span style="color:#a6e22e"&gt;name&lt;/span&gt;&lt;span style="color:#f92672"&gt;=&lt;/span&gt;&lt;span style="color:#e6db74"&gt;&amp;#34;keywords&amp;#34;&lt;/span&gt; &lt;span style="color:#a6e22e"&gt;content&lt;/span&gt;&lt;span style="color:#f92672"&gt;=&lt;/span&gt;&lt;span style="color:#e6db74"&gt;&amp;#34;{{ delimit .Keywords &amp;#34;&lt;/span&gt;&lt;span style="color:#960050;background-color:#1e0010"&gt;,&lt;/span&gt; &lt;span style="color:#960050;background-color:#1e0010"&gt;&amp;#34;&lt;/span&gt; &lt;span style="color:#960050;background-color:#1e0010"&gt;}}&amp;#34;&lt;/span&gt; &amp;gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;{{else}}
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&amp;lt;&lt;span style="color:#f92672"&gt;meta&lt;/span&gt; &lt;span style="color:#a6e22e"&gt;name&lt;/span&gt;&lt;span style="color:#f92672"&gt;=&lt;/span&gt;&lt;span style="color:#e6db74"&gt;&amp;#34;keywords&amp;#34;&lt;/span&gt; &lt;span style="color:#a6e22e"&gt;content&lt;/span&gt;&lt;span style="color:#f92672"&gt;=&lt;/span&gt;&lt;span style="color:#e6db74"&gt;&amp;#34;{{ delimit .Site.Params.Keywords &amp;#34;&lt;/span&gt;&lt;span style="color:#960050;background-color:#1e0010"&gt;,&lt;/span&gt; &lt;span style="color:#960050;background-color:#1e0010"&gt;&amp;#34;&lt;/span&gt; &lt;span style="color:#960050;background-color:#1e0010"&gt;}}&amp;#34;&lt;/span&gt; &amp;gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;{{ end }}
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;h1 id="百度熊掌号推送"&gt;百度熊掌号推送&lt;/h1&gt;
&lt;p&gt;说到seo熊掌号是必不可少的了,他可以做到24小时之内收录.所以这个必须不能放过.&lt;/p&gt;
&lt;h2 id="gulp"&gt;gulp&lt;/h2&gt;
&lt;p&gt;在这里我要使用gulp来做我的自动化任务管理工具&lt;/p&gt;
&lt;h3 id="安装gulp需要的模块"&gt;安装gulp需要的模块&lt;/h3&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;npm init
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;npm install gulp --save
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;npm install xml2js --save
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;npm install xmlhttprequest --save
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;h3 id="在项目根目录创建一个gulpfilejs文件"&gt;在项目根目录创建一个&lt;code&gt;gulpfile.js&lt;/code&gt;文件&lt;/h3&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"&gt;&lt;code class="language-js" data-lang="js"&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#75715e"&gt;// 导入相关依赖
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#66d9ef"&gt;const&lt;/span&gt; &lt;span style="color:#a6e22e"&gt;gulp&lt;/span&gt; &lt;span style="color:#f92672"&gt;=&lt;/span&gt; &lt;span style="color:#a6e22e"&gt;require&lt;/span&gt;(&lt;span style="color:#e6db74"&gt;&amp;#34;gulp&amp;#34;&lt;/span&gt;);
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#66d9ef"&gt;const&lt;/span&gt; &lt;span style="color:#a6e22e"&gt;fs&lt;/span&gt; &lt;span style="color:#f92672"&gt;=&lt;/span&gt; &lt;span style="color:#a6e22e"&gt;require&lt;/span&gt;(&lt;span style="color:#e6db74"&gt;&amp;#39;fs&amp;#39;&lt;/span&gt;);
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#66d9ef"&gt;const&lt;/span&gt; &lt;span style="color:#a6e22e"&gt;xml2js&lt;/span&gt; &lt;span style="color:#f92672"&gt;=&lt;/span&gt; &lt;span style="color:#a6e22e"&gt;require&lt;/span&gt;(&lt;span style="color:#e6db74"&gt;&amp;#39;xml2js&amp;#39;&lt;/span&gt;)
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#66d9ef"&gt;const&lt;/span&gt; &lt;span style="color:#a6e22e"&gt;parser&lt;/span&gt; &lt;span style="color:#f92672"&gt;=&lt;/span&gt; &lt;span style="color:#66d9ef"&gt;new&lt;/span&gt; &lt;span style="color:#a6e22e"&gt;xml2js&lt;/span&gt;.&lt;span style="color:#a6e22e"&gt;Parser&lt;/span&gt;();
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#66d9ef"&gt;const&lt;/span&gt; &lt;span style="color:#a6e22e"&gt;XMLHttpRequest&lt;/span&gt; &lt;span style="color:#f92672"&gt;=&lt;/span&gt; &lt;span style="color:#a6e22e"&gt;require&lt;/span&gt;(&lt;span style="color:#e6db74"&gt;&amp;#34;xmlhttprequest&amp;#34;&lt;/span&gt;).&lt;span style="color:#a6e22e"&gt;XMLHttp&lt;/span&gt;;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#75715e"&gt;// 注册百度站长与熊掌号,百度会提供下面的数据给你
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#66d9ef"&gt;var&lt;/span&gt; &lt;span style="color:#a6e22e"&gt;xz_appid&lt;/span&gt; &lt;span style="color:#f92672"&gt;=&lt;/span&gt; &lt;span style="color:#e6db74"&gt;&amp;#39;xxxxx&amp;#39;&lt;/span&gt;;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#66d9ef"&gt;var&lt;/span&gt; &lt;span style="color:#a6e22e"&gt;xz_token&lt;/span&gt; &lt;span style="color:#f92672"&gt;=&lt;/span&gt; &lt;span style="color:#e6db74"&gt;&amp;#39;xxxxx&amp;#39;&lt;/span&gt;;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#66d9ef"&gt;var&lt;/span&gt; &lt;span style="color:#a6e22e"&gt;baidu_token&lt;/span&gt;&lt;span style="color:#f92672"&gt;=&lt;/span&gt; &lt;span style="color:#e6db74"&gt;&amp;#39;xxxxx&amp;#39;&lt;/span&gt; 
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#75715e"&gt;//熊掌号每天需要提交的url数量
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#75715e"&gt;// 注意这个数字必须要跟百度允许提交的url数量一致,如果多了会提交失败.
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#66d9ef"&gt;const&lt;/span&gt; &lt;span style="color:#a6e22e"&gt;xzCount&lt;/span&gt; &lt;span style="color:#f92672"&gt;=&lt;/span&gt; &lt;span style="color:#ae81ff"&gt;20&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#75715e"&gt;// 创建一个任务
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#a6e22e"&gt;gulp&lt;/span&gt;.&lt;span style="color:#a6e22e"&gt;task&lt;/span&gt;(&lt;span style="color:#e6db74"&gt;&amp;#39;baiduSeo&amp;#39;&lt;/span&gt;, () =&amp;gt; {
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#75715e"&gt;// 读取sitemap.xml文件并且转换成json
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#a6e22e"&gt;fs&lt;/span&gt;.&lt;span style="color:#a6e22e"&gt;readFile&lt;/span&gt;(&lt;span style="color:#a6e22e"&gt;__dirname&lt;/span&gt; &lt;span style="color:#f92672"&gt;+&lt;/span&gt; &lt;span style="color:#e6db74"&gt;&amp;#39;/public/sitemap.xml&amp;#39;&lt;/span&gt;, &lt;span style="color:#66d9ef"&gt;function&lt;/span&gt;(&lt;span style="color:#a6e22e"&gt;err&lt;/span&gt;, &lt;span style="color:#a6e22e"&gt;data&lt;/span&gt;) {
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#a6e22e"&gt;parser&lt;/span&gt;.&lt;span style="color:#a6e22e"&gt;parseString&lt;/span&gt;(&lt;span style="color:#a6e22e"&gt;data&lt;/span&gt;, &lt;span style="color:#66d9ef"&gt;function&lt;/span&gt; (&lt;span style="color:#a6e22e"&gt;err&lt;/span&gt;, &lt;span style="color:#a6e22e"&gt;result&lt;/span&gt;) {
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#75715e"&gt;// 把读取的数据传入这个函数
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#a6e22e"&gt;urlSubmit&lt;/span&gt;(&lt;span style="color:#a6e22e"&gt;result&lt;/span&gt;.&lt;span style="color:#a6e22e"&gt;urlset&lt;/span&gt;.&lt;span style="color:#a6e22e"&gt;url&lt;/span&gt;)
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#a6e22e"&gt;console&lt;/span&gt;.&lt;span style="color:#a6e22e"&gt;log&lt;/span&gt;(&lt;span style="color:#e6db74"&gt;&amp;#39;Done&amp;#39;&lt;/span&gt;);
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; });
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; });
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; });
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#75715e"&gt;// 提交url的方法
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#66d9ef"&gt;function&lt;/span&gt; &lt;span style="color:#a6e22e"&gt;urlSubmit&lt;/span&gt;(&lt;span style="color:#a6e22e"&gt;urls&lt;/span&gt;) {
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#75715e"&gt;// 最新内容提交
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#66d9ef"&gt;var&lt;/span&gt; &lt;span style="color:#a6e22e"&gt;new_target&lt;/span&gt; &lt;span style="color:#f92672"&gt;=&lt;/span&gt; &lt;span style="color:#e6db74"&gt;&amp;#34;http://data.zz.baidu.com/urls?appid=&amp;#34;&lt;/span&gt;&lt;span style="color:#f92672"&gt;+&lt;/span&gt;&lt;span style="color:#a6e22e"&gt;xz_appid&lt;/span&gt;&lt;span style="color:#f92672"&gt;+&lt;/span&gt;&lt;span style="color:#e6db74"&gt;&amp;#34;&amp;amp;token=&amp;#34;&lt;/span&gt;&lt;span style="color:#f92672"&gt;+&lt;/span&gt;&lt;span style="color:#a6e22e"&gt;xz_token&lt;/span&gt;&lt;span style="color:#f92672"&gt;+&lt;/span&gt;&lt;span style="color:#e6db74"&gt;&amp;#34;&amp;amp;type=realtime&amp;#34;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; 
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#75715e"&gt;// 历史提交
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#66d9ef"&gt;var&lt;/span&gt; &lt;span style="color:#a6e22e"&gt;history_target&lt;/span&gt; &lt;span style="color:#f92672"&gt;=&lt;/span&gt; &lt;span style="color:#e6db74"&gt;&amp;#34;http://data.zz.baidu.com/urls?appid=&amp;#34;&lt;/span&gt;&lt;span style="color:#f92672"&gt;+&lt;/span&gt;&lt;span style="color:#a6e22e"&gt;xz_appid&lt;/span&gt;&lt;span style="color:#f92672"&gt;+&lt;/span&gt;&lt;span style="color:#e6db74"&gt;&amp;#34;&amp;amp;token=&amp;#34;&lt;/span&gt;&lt;span style="color:#f92672"&gt;+&lt;/span&gt;&lt;span style="color:#a6e22e"&gt;xz_token&lt;/span&gt;&lt;span style="color:#f92672"&gt;+&lt;/span&gt;&lt;span style="color:#e6db74"&gt;&amp;#34;&amp;amp;type=batch&amp;#34;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#75715e"&gt;// 百度站长
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#66d9ef"&gt;var&lt;/span&gt; &lt;span style="color:#a6e22e"&gt;baidu_target&lt;/span&gt; &lt;span style="color:#f92672"&gt;=&lt;/span&gt; &lt;span style="color:#e6db74"&gt;&amp;#34;http://data.zz.baidu.com/urls?site=https://你的域名&amp;amp;token=&amp;#34;&lt;/span&gt;&lt;span style="color:#f92672"&gt;+&lt;/span&gt;&lt;span style="color:#a6e22e"&gt;baidu_token&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#75715e"&gt;// MIP
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#66d9ef"&gt;var&lt;/span&gt; &lt;span style="color:#a6e22e"&gt;MIP_target&lt;/span&gt; &lt;span style="color:#f92672"&gt;=&lt;/span&gt; &lt;span style="color:#e6db74"&gt;&amp;#34;http://data.zz.baidu.com/urls?site=https://你的域名&amp;amp;token=&amp;#34;&lt;/span&gt;&lt;span style="color:#f92672"&gt;+&lt;/span&gt;&lt;span style="color:#a6e22e"&gt;baidu_token&lt;/span&gt;&lt;span style="color:#f92672"&gt;+&lt;/span&gt;&lt;span style="color:#e6db74"&gt;&amp;#34;&amp;amp;type=mip&amp;#34;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#75715e"&gt;// AMP
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#66d9ef"&gt;var&lt;/span&gt; &lt;span style="color:#a6e22e"&gt;AMP_target&lt;/span&gt; &lt;span style="color:#f92672"&gt;=&lt;/span&gt; &lt;span style="color:#e6db74"&gt;&amp;#34;http://data.zz.baidu.com/urls?site=https://你的域名&amp;amp;token=&amp;#34;&lt;/span&gt;&lt;span style="color:#f92672"&gt;+&lt;/span&gt;&lt;span style="color:#a6e22e"&gt;baidu_token&lt;/span&gt;&lt;span style="color:#f92672"&gt;+&lt;/span&gt;&lt;span style="color:#e6db74"&gt;&amp;#34;&amp;amp;type=amp&amp;#34;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#75715e"&gt;// 最新url,看熊掌号情况而定
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#a6e22e"&gt;urls&lt;/span&gt; &lt;span style="color:#f92672"&gt;=&lt;/span&gt; &lt;span style="color:#a6e22e"&gt;urls&lt;/span&gt;.&lt;span style="color:#a6e22e"&gt;map&lt;/span&gt;(&lt;span style="color:#a6e22e"&gt;item&lt;/span&gt;=&amp;gt;&lt;span style="color:#a6e22e"&gt;item&lt;/span&gt;.&lt;span style="color:#a6e22e"&gt;loc&lt;/span&gt;[&lt;span style="color:#ae81ff"&gt;0&lt;/span&gt;])
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#a6e22e"&gt;allUrls&lt;/span&gt; &lt;span style="color:#f92672"&gt;=&lt;/span&gt; &lt;span style="color:#a6e22e"&gt;urls&lt;/span&gt;.&lt;span style="color:#a6e22e"&gt;join&lt;/span&gt;(&lt;span style="color:#e6db74"&gt;&amp;#39;\n&amp;#39;&lt;/span&gt;)
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#66d9ef"&gt;var&lt;/span&gt; &lt;span style="color:#a6e22e"&gt;new_urls_Arr&lt;/span&gt; &lt;span style="color:#f92672"&gt;=&lt;/span&gt; &lt;span style="color:#a6e22e"&gt;urls&lt;/span&gt;.&lt;span style="color:#a6e22e"&gt;slice&lt;/span&gt;(&lt;span style="color:#ae81ff"&gt;0&lt;/span&gt;,&lt;span style="color:#a6e22e"&gt;xzCount&lt;/span&gt;)
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#a6e22e"&gt;new_urls&lt;/span&gt;&lt;span style="color:#f92672"&gt;=&lt;/span&gt; &lt;span style="color:#a6e22e"&gt;new_urls_Arr&lt;/span&gt;.&lt;span style="color:#a6e22e"&gt;join&lt;/span&gt;(&lt;span style="color:#e6db74"&gt;&amp;#39;\n&amp;#39;&lt;/span&gt;);
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#a6e22e"&gt;console&lt;/span&gt;.&lt;span style="color:#a6e22e"&gt;info&lt;/span&gt;(&lt;span style="color:#e6db74"&gt;&amp;#39;百度站长开始提交&amp;#39;&lt;/span&gt;,&lt;span style="color:#a6e22e"&gt;new_urls&lt;/span&gt;)
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#a6e22e"&gt;sendData&lt;/span&gt;(&lt;span style="color:#a6e22e"&gt;baidu_target&lt;/span&gt;,&lt;span style="color:#a6e22e"&gt;new_urls&lt;/span&gt;,&lt;span style="color:#e6db74"&gt;&amp;#39;百度站长提交成功&amp;#39;&lt;/span&gt;)
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#a6e22e"&gt;console&lt;/span&gt;.&lt;span style="color:#a6e22e"&gt;info&lt;/span&gt;(&lt;span style="color:#e6db74"&gt;&amp;#39;熊掌号开始提交&amp;#39;&lt;/span&gt;)
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#a6e22e"&gt;sendData&lt;/span&gt;(&lt;span style="color:#a6e22e"&gt;new_target&lt;/span&gt;,&lt;span style="color:#a6e22e"&gt;new_urls&lt;/span&gt;,&lt;span style="color:#e6db74"&gt;&amp;#39;熊掌号提交完成&amp;#39;&lt;/span&gt;)
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#75715e"&gt;// 提交历史url 每天最多500w条
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#a6e22e"&gt;console&lt;/span&gt;.&lt;span style="color:#a6e22e"&gt;info&lt;/span&gt;(&lt;span style="color:#e6db74"&gt;&amp;#34;历史数据开始提交&amp;#34;&lt;/span&gt;)
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#a6e22e"&gt;sendData&lt;/span&gt;(&lt;span style="color:#a6e22e"&gt;history_target&lt;/span&gt;,&lt;span style="color:#a6e22e"&gt;allUrls&lt;/span&gt;,&lt;span style="color:#e6db74"&gt;&amp;#34;历史数据提交完成&amp;#34;&lt;/span&gt;)
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#a6e22e"&gt;console&lt;/span&gt;.&lt;span style="color:#a6e22e"&gt;info&lt;/span&gt;(&lt;span style="color:#e6db74"&gt;&amp;#34;MIP 开始提交&amp;#34;&lt;/span&gt;)
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#a6e22e"&gt;sendData&lt;/span&gt;(&lt;span style="color:#a6e22e"&gt;MIP_target&lt;/span&gt;,&lt;span style="color:#a6e22e"&gt;allUrls&lt;/span&gt;,&lt;span style="color:#e6db74"&gt;&amp;#34;MIP提交成功&amp;#34;&lt;/span&gt;)
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#a6e22e"&gt;console&lt;/span&gt;.&lt;span style="color:#a6e22e"&gt;info&lt;/span&gt;(&lt;span style="color:#e6db74"&gt;&amp;#34;AMP 开始提交&amp;#34;&lt;/span&gt;)
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#a6e22e"&gt;sendData&lt;/span&gt;(&lt;span style="color:#a6e22e"&gt;AMP_target&lt;/span&gt;,&lt;span style="color:#a6e22e"&gt;allUrls&lt;/span&gt;,&lt;span style="color:#e6db74"&gt;&amp;#34;AMP提交成功&amp;#34;&lt;/span&gt;)
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#75715e"&gt;// 提交数据
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#66d9ef"&gt;function&lt;/span&gt; &lt;span style="color:#a6e22e"&gt;sendData&lt;/span&gt;(&lt;span style="color:#a6e22e"&gt;target&lt;/span&gt;,&lt;span style="color:#a6e22e"&gt;urls&lt;/span&gt;,&lt;span style="color:#a6e22e"&gt;message&lt;/span&gt;){
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#66d9ef"&gt;var&lt;/span&gt; &lt;span style="color:#a6e22e"&gt;xhr&lt;/span&gt; &lt;span style="color:#f92672"&gt;=&lt;/span&gt; &lt;span style="color:#66d9ef"&gt;new&lt;/span&gt; &lt;span style="color:#a6e22e"&gt;XMLHttpRequest&lt;/span&gt;();
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#a6e22e"&gt;xhr&lt;/span&gt;.&lt;span style="color:#a6e22e"&gt;open&lt;/span&gt;(&lt;span style="color:#e6db74"&gt;&amp;#39;POST&amp;#39;&lt;/span&gt;, &lt;span style="color:#a6e22e"&gt;target&lt;/span&gt;, &lt;span style="color:#66d9ef"&gt;false&lt;/span&gt;);
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#a6e22e"&gt;xhr&lt;/span&gt;.&lt;span style="color:#a6e22e"&gt;setRequestHeader&lt;/span&gt;(&lt;span style="color:#e6db74"&gt;&amp;#39;Content-type&amp;#39;&lt;/span&gt;, &lt;span style="color:#e6db74"&gt;&amp;#39;text/plain&amp;#39;&lt;/span&gt;);
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#a6e22e"&gt;xhr&lt;/span&gt;.&lt;span style="color:#a6e22e"&gt;onload&lt;/span&gt; &lt;span style="color:#f92672"&gt;=&lt;/span&gt; &lt;span style="color:#66d9ef"&gt;function&lt;/span&gt; () {
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#a6e22e"&gt;console&lt;/span&gt;.&lt;span style="color:#a6e22e"&gt;log&lt;/span&gt;(&lt;span style="color:#66d9ef"&gt;this&lt;/span&gt;.&lt;span style="color:#a6e22e"&gt;responseText&lt;/span&gt;);
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#66d9ef"&gt;if&lt;/span&gt;(&lt;span style="color:#a6e22e"&gt;message&lt;/span&gt;){&lt;span style="color:#a6e22e"&gt;console&lt;/span&gt;.&lt;span style="color:#a6e22e"&gt;info&lt;/span&gt;(&lt;span style="color:#a6e22e"&gt;message&lt;/span&gt;)}
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; };
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#a6e22e"&gt;xhr&lt;/span&gt;.&lt;span style="color:#a6e22e"&gt;send&lt;/span&gt;(&lt;span style="color:#a6e22e"&gt;urls&lt;/span&gt;);
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; }
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;};
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#a6e22e"&gt;gulp&lt;/span&gt;.&lt;span style="color:#a6e22e"&gt;task&lt;/span&gt;(&lt;span style="color:#e6db74"&gt;&amp;#34;default&amp;#34;&lt;/span&gt;,[
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#e6db74"&gt;&amp;#39;baiduSeo&amp;#39;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;])
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;配置好以上都文件之后&lt;/p&gt;</description></item><item><title>博客构建工具Hugo的基本使用</title><link>https://time-friend.com/zh/archive/basic-usage-of-hugo-blog-building-tool/</link><pubDate>Thu, 15 Nov 2018 16:14:25 +0000</pubDate><guid>https://time-friend.com/zh/archive/basic-usage-of-hugo-blog-building-tool/</guid><description>&lt;p&gt;最终还是把博客迁移到了&lt;code&gt;Hugo&lt;/code&gt;,当初最纠结的是这套主题在&lt;code&gt;Hugo&lt;/code&gt;平台上没有.
但是脑子一热，花了两三天时间。这套主题。全部迁移到了&lt;code&gt;Hugo&lt;/code&gt;平台。
接下来就给大家介绍一下&lt;code&gt;Hugo&lt;/code&gt;的使用以及踩到的坑,以及解决方案.&lt;/p&gt;
&lt;h1 id="hugo的性能"&gt;Hugo的性能&lt;/h1&gt;
&lt;p&gt;正是因为hexo的性能不能满足,在生成静态文件的时候极其不稳定.而且时间也相对比较长一些.
在相同页面数量的情况下,处理速度hugo是hexo20倍及以上.这才是我换Hugo的原因.&lt;/p&gt;
&lt;h1 id="配置文件"&gt;配置文件&lt;/h1&gt;
&lt;p&gt;两个平台有很多共通的地方,迁移起来有很多工作是非常顺其自然的.
在配置文件上hugo也是可以使用yaml的,所以从hexo迁移过来会相对好很多.
其次hugo还可以使用json作为配置文件,为用户提供了很多选择.&lt;/p&gt;
&lt;h1 id="hugo的基本使用"&gt;Hugo的基本使用&lt;/h1&gt;
&lt;h2 id="mac平台下"&gt;Mac平台下&lt;/h2&gt;
&lt;p&gt;Mac下Hugo提供了homebrew安装的方式，非常简便。&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;brew install hugo
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;Debian and Ubuntu平台下&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;sudo apt-get install hugo
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;h2 id="windows平台下"&gt;Windows平台下&lt;/h2&gt;
&lt;p&gt;Windows下Hugo提供了Chocolatey方式的安装，通过如下命令即可。&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;choco install hugo -confirm
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;验证安装&lt;/p&gt;
&lt;p&gt;安转完成后，我们打开终端，输入如下命令进行验证是否安装成功&lt;/p&gt;
&lt;pre tabindex="0"&gt;&lt;code&gt;hugo version
&lt;/code&gt;&lt;/pre&gt;&lt;h2 id="创建一个站点"&gt;创建一个站点&lt;/h2&gt;
&lt;pre tabindex="0"&gt;&lt;code&gt;hugo new site quickstart
&lt;/code&gt;&lt;/pre&gt;&lt;h2 id="添加一个主题"&gt;添加一个主题&lt;/h2&gt;
&lt;pre tabindex="0"&gt;&lt;code&gt;cd quickstart;\
git init;\
git submodule add https://github.com/budparr/gohugo-theme-ananke.git themes/ananke;\

# 编辑你的 config.toml 配置文件
# 添加一个叫 Ananke 的主题
echo &amp;#39;theme = &amp;#34;ananke&amp;#34;&amp;#39; &amp;gt;&amp;gt; config.toml
&lt;/code&gt;&lt;/pre&gt;&lt;h2 id="新建一篇文章"&gt;新建一篇文章&lt;/h2&gt;
&lt;pre tabindex="0"&gt;&lt;code&gt;hugo new posts/my-first-post.md
&lt;/code&gt;&lt;/pre&gt;&lt;h2 id="本地开启hugo服务"&gt;本地开启Hugo服务&lt;/h2&gt;
&lt;pre tabindex="0"&gt;&lt;code&gt;hugo server -D
&lt;/code&gt;&lt;/pre&gt;&lt;h2 id="构建静态站点"&gt;构建静态站点&lt;/h2&gt;
&lt;pre tabindex="0"&gt;&lt;code&gt;hugo
&lt;/code&gt;&lt;/pre&gt;</description></item></channel></rss>