进行主题修改前必看
博客魔改有风险,请务必备份 你的原代码
因为.pug和.styl以及.yml等对缩进要求较为严格,请尽量不要使用记事本等无法提供语法高亮的文本编辑器 进行修改。
本文涉及修改内容会以diff代码块 进行标识,复制时请不要忘记删除 前面的+,-符号
本帖基于Anzhiyu主题进行修改方案编写,因此请读者优先掌握Anzhiyu主题官方文档 的内容后再来进行魔改。
前言 上个月看到柳神 的一篇关于类似朋友圈的迁移魔改文,同时自己也关注这类良久,毕竟托静态博客的福,你是无论如何都挺难像动态博客那样好处理即时的内容,不过可以参考类似部分大佬的教程,将页面修改为通过API获取内容的方式,使其展示在前端.
我最早关注过Memos和Moments这两项项目,其中Memos的设计是有比较大的缺陷(于我而言),单挑一处不稳定API就可以从这篇文章筛选出去了,不过好就好在占用极少,对在意占用资源的朋友们比较友好.
所以这一篇的目的就是修改即刻短文的获取方式由原essay.yml变更为网络API
参考文献以及鸣谢 本文来源项目:
本文修改基于以下项目:
📍特别提醒 请进行完以上部署的步骤后再进行以下的操作
本文代码来源:
本文另类思路来源:
(提供了添加配置项的思路,避免后续维护直接修改代码带来的不可逆操作)
参考步骤 优势对比 接下来的表格来源于柳神 的从Moments迁移到Ech0 | LiuShen’s Blog ,基本我的评价也与此差不多.
特性 MemosMomentsMemosPWA适配✅ 支持 ❌ 不支持 ✅ 支持 标签系统 ✅ 完善 ✅ 完善 ✅ 支持 S3 图床✅ 支持 ✅ 支持 ✅ 支持 Meting音乐❌ 不支持 ✅ 支持 ✅ 支持 视频分享 ✅ 支持 ✅ 支持 ✅ 支持 设计风格 功能导向,略显臃肿 功能全面,类似后台 简约美观,轻量 开发活跃度 非常活跃,API易变 相对稳定 活跃,快速迭代 个人评价 功能强大,但更新太折腾,生态不稳定。 功能完美,但没PWA对我是减分项 界面戳我,功能追上来了,PWA是加分项,目前的最爱
硬性要求 一台服务器
自主域名
已部署anzhiyu的Hexo博客
Ech0部署 有服务器部署 如果你拥有个人服务器的就继续参考柳神的步骤走下去从Moments迁移到Ech0 | LiuShen’s Blog
在此我主要推无服务器的部署方法
无服务器部署 看到上面的硬性要求 要求有服务器,有人就懵逼了起来,”都穷玩博客了,我哪里会有多余资金购置服务器”
说的对!对于我个人而言我是有一台服务器的,不过考虑到稳定性和续费的高昂价格,我不禁踌躇
所以我们走一些比较偏门的方法,令我们拥有一台服务器
在此我介绍云部署平台Zeabur(非广),类似的有Hugging Face
注册完毕后来到控制台-创建项目(随便一个地区)-Docker 容器镜像(填入以下内容)
镜像: sn0wl1n/ech0:latest
环境变量: JWT_SECRET(变量名) ; Hello Echos(变量值)
端口: 6277 ; HTTP
卷(创建两项): /data , /opt/ech0/data ; /backup, /opt/ech0/backup
具体解释源自:
不过我发现这种部署方案更新比较麻烦
创建完毕在项目里切换到网络,添加个人域名,比如我这里用的是ech0.gbfun.cc
后面就可以进入域名,注册ech0的管理员账号了
关于管理员的账号说明可以查阅上方的Ech0安装部署指南
📍 首次使用注册的账号会被设置为管理员(目前仅管理员支持发布内容)
魔改方案 接下来是高危步骤,请务必备份好源代码.
📍特别提醒 以下涉及修改内容较多,请务必备份源代码以方便回滚
涉及的相关文件 文件路径 操作 目的 _config.anzhiyu.yml修改 添加 ech0 配置项 themes/anzhiyu/layout/includes/page/essay.pug修改 动态加载容器 themes/anzhiyu/layout/includes/bbTimeList.pug修改 首页轮播条动态加载 source/js/essay.js创建 API 获取与渲染逻辑 themes/anzhiyu/layout/includes/additional-js.pug修改 脚本配置注入 themes/anzhiyu/source/js/utils.js修改 更新 initIndexEssay themes/anzhiyu/source/css/_extra/essay_page/essay_page.css修改 样式适配 themes/anzhiyu/layout/includes/head.pug修改 轮播 CSS 条件 themes/anzhiyu/layout/includes/top/top.pug修改 轮播 JS 条件
具体修改代码 _config.anzhiyu.yml - 添加 Ech0 配置此处思路来源梦爱吃鱼 的友链朋友圈项目
添加集中整体的 API 配置,便于维护
1 2 3 4 5 6 7 8 9 10 11 12 ech0: enable: true api_url: https://ech0.gbfun.cc/api/echo/page page_limit: 30 index_limit: 10 cache_ttl: 1800000 name: LixdHappy desc: 羊了个羊 avatar: /img/博客头像.gif avatar_link: /about/ top_background: https://img.gbfun.cc/file/project/MWjwM6eh.jpg
代码源于柳神 的从Moments迁移到Ech0-说说页面
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 (function ( ) { 'use strict' ; const defaultConfig = { api_url : 'https://ech0.gbfun.cc/api/echo/page' , page_limit : 30 , index_limit : 10 , cache_ttl : 1800000 , name : 'Ech0' , avatar : '/img/avatar.png' }; function getConfig ( ) { return typeof Ech0Config !== 'undefined' ? { ...defaultConfig, ...Ech0Config } : defaultConfig; } async function fetchEch0Data (limit ) { const config = getConfig (); const cacheKey = `ech0_cache_${limit} ` ; const cacheTimeKey = `ech0_cache_time_${limit} ` ; const now = Date .now (); const cachedData = localStorage .getItem (cacheKey); const cachedTime = localStorage .getItem (cacheTimeKey); if (cachedData && cachedTime && (now - parseInt (cachedTime)) < config.cache_ttl ) { return JSON .parse (cachedData); } try { const response = await fetch (config.api_url , { method : 'POST' , headers : { 'Content-Type' : 'application/json' }, body : JSON .stringify ({ page : 1 , pageSize : limit }) }); const data = await response.json (); if (data.code === 1 && data.data && Array .isArray (data.data .items )) { localStorage .setItem (cacheKey, JSON .stringify (data.data .items )); localStorage .setItem (cacheTimeKey, now.toString ()); return data.data .items ; } } catch (error) { console .error ('Ech0 API Error:' , error); } return []; } function generateEssayItemHTML (item, config ) { const content = item.content || '' ; const date = item.created_at || new Date ().toISOString (); const images = Array .isArray (item.images ) ? item.images : []; const extensionType = item.extension_type || '' ; const extension = item.extension || '' ; const location = item.location || '' ; const tags = Array .isArray (item.tags ) && item.tags .length ? item.tags .map (t => t.name || t) : []; let html = ` <li class="bber-item"> <div class="user-avatar" style="background: url(${config.avatar} ) left 28% / cover no-repeat #ffffffad;"></div> <div class="bber-content"> <div class="right"> <div class="bber-name">${config.name} </div> <p class="datacont">${escapeHtml(content)} ` ; if (images.length > 0 ) { html += `<div class="bber-container-img">` ; images.forEach (img => { const imgUrl = img.image_url || img; html += `<a class="bber-content-img" href="${imgUrl} " target="_blank" data-fancybox="gallery"><img src="${imgUrl} " loading="lazy"></a>` ; }); html += `<div class="bber-content-noimg"></div><div class="bber-content-noimg"></div><div class="bber-content-noimg"></div></div>` ; } if (extensionType === 'VIDEO' && extension) { html += `<div class="bber-video-container">` ; if (extension.startsWith ('BV' ) || extension.includes ('bilibili' )) { const bvid = extension.startsWith ('BV' ) ? extension : extension.match (/BV[\w]+/ )?.[0 ] || extension; html += `<div class="bilibiliPlayer"><iframe src="https://www.bilibili.com/blackboard/html5mobileplayer.html?bvid=${bvid} &as_wide=1&high_quality=1&danmaku=0" scrolling="no" border="0" frameborder="no" framespacing="0" allowfullscreen="true" loading="lazy"></iframe></div>` ; } else if (extension.includes ('youtube' ) || extension.match (/^[\w-]{11}$/ )) { const videoId = extension.match (/^[\w-]{11}$/ ) ? extension : extension.match (/(?:v=|\/)[\w-]{11}/ )?.[1 ] || extension; html += `<div class="youtubePlayer"><iframe src="https://www.youtube.com/embed/${videoId} " frameborder="0" allowfullscreen loading="lazy"></iframe></div>` ; } html += `</div>` ; } if (extensionType === 'MUSIC' && extension) { const music = parseMusicLink (extension); if (music) { html += `<div class="bber-music"><meting-js id="${music.id} " server="${music.server} " type="song" mutex="true" preload="none" theme="var(--anzhiyu-main)" data-lrctype="0" order="list"></meting-js></div>` ; } } if ((extensionType === 'WEBSITE' || extensionType === 'GITHUBPROJ' ) && extension) { let siteUrl = '' , title = '' ; try { const extObj = typeof extension === 'string' ? JSON .parse (extension) : extension; siteUrl = extObj.site || extObj.url || extension; title = extObj.title || siteUrl; } catch { siteUrl = extension; title = extension; } html += `<div class="bber-external-link"><a href="${siteUrl} " target="_blank" rel="nofollow noopener" class="external-link"><i class="anzhiyufont anzhiyu-icon-link"></i><span>${escapeHtml(title)} </span></a></div>` ; } html += `</p><hr class="essay-hr">` ; html += `<div class="bber-bottom"><div class="bber-info"> <div class="bber-info-time"><i class="anzhiyufont anzhiyu-icon-clock"></i><time class="datatime" datetime="${date} " style="display: inline;">${getRelativeTime(date)} </time></div>` ; if (tags.length > 0 ) { html += `<div class="essay-tag"><i class="anzhiyufont anzhiyu-icon-tags faa-tada"></i><span>${escapeHtml(tags.join(', ' ))} </span></div>` ; } if ((extensionType === 'WEBSITE' || extensionType === 'GITHUBPROJ' ) && extension) { let linkUrl = '' ; try { linkUrl = JSON .parse (extension).site || extension; } catch { linkUrl = extension; } html += `<a class="bber-content-link" title="跳转到短文指引的链接" href="${linkUrl} " rel="external nofollow" target="_blank"><i class="anzhiyufont anzhiyu-icon-link"></i>链接</a>` ; } html += `</div><div class="bber-reply" onclick="rm && rm.rightMenuCommentText('${escapeHtml(content)} ')"><i class="anzhiyufont anzhiyu-icon-message"></i></div></div></div></div></li>` ; return html; } async function renderEssayPage ( ) { } async function renderIndexEssayBar ( ) { } function initEssaySwiper ( ) { } function initEch0 ( ) { } if (document .readyState === 'loading' ) { document .addEventListener ('DOMContentLoaded' , initEch0); } else { initEch0 (); } document .addEventListener ('pjax:complete' , initEch0); window .Ech0Essay = { init : initEch0 }; })();
主要有几项特性:
Ech0 API获取内容数据
30分钟 localStorage 缓存
支持图片,视频(B站/YouTube),音乐,外链
兼容Pjax
以下内容没有diff代码块标注修改位置,请自行斟辨.
datacont与bber-content去除圆角(此处内容可能并不需要,因为我的修改内容过多,可能有破坏了该处的原有样式,所以我在此进行了修改,可能原有anzhiyu代码并没有此处内容)1 2 3 4 #bber .bber-content .datacont { border-radius : 0 ; }
1 2 3 #bber div .bber-content { border-radius : 0 ; }
没有此处的修改,可能会造成datacont容器左上方变为圆角
essay-tag胶囊样式这里是我新加入的变量,用于获取Ech0的内容tag标签,该处是绝对定位布置在时间的右边,链接的左边
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 #bber .essay-tag { display : flex; align-items : center; font-size : 0.7rem ; color : var (--anzhiyu-fontcolor); background-color : var (--anzhiyu-gray-op); padding : 0 8px ; border-radius : 20px ; height : 24px ; cursor : default; } #bber .essay-tag i { margin-right : 4px ; font-size : 0.7rem ; color : var (--anzhiyu-main); } #bber .essay-tag span { max-width : 120px ; overflow : hidden; text-overflow : ellipsis; white-space : nowrap; }
视频容器样式 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 #bber .bber-video-container { width : 100% ; margin : 10px 0 ; } #bber .bilibiliPlayer ,#bber .youtubePlayer { position : relative; width : 100% ; padding-bottom : 56.25% ; height : 0 ; overflow : hidden; border-radius : 12px ; } #bber .bilibiliPlayer iframe ,#bber .youtubePlayer iframe { position : absolute; top : 0 ; left : 0 ; width : 100% ; height : 100% ; border-radius : 12px ; border : var (--style-border); }
移动端朋友圈样式 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 @media screen and (max-width : 900px ), (max-height : 580px ) { div #essay_page { border : var (--style-border); box-shadow : var (--anzhiyu-shadow-border); border-radius : 10px ; background : rgba (255 , 255 , 255 , 0.75 ); backdrop-filter : saturate (180% ) blur (20px ); -webkit-backdrop-filter : saturate (180% ) blur (20px ); } [data-theme="dark" ] div #essay_page { background : rgba (30 , 30 , 30 , 0.78 ); } body [data-type=essay] .right { margin-left : 55px ; } #bber .timeline ul li .bber-item { width : 95% ; border : none; border-radius : 0 ; padding : 0 ; background : transparent; box-shadow : none; } .bber-name { font-size : 16px ; font-weight : 800 ; display : block; } .user-avatar { width : 45px ; height : 45px ; border-radius : 10px ; overflow : hidden; position : absolute; display : block; left : 0 ; top : 0 ; } #bber .bber-item .right { max-width : calc (100% - 55px ); overflow : hidden; } #bber .bber-info-time , #bber .bber-content-link , #bber .bber-info-address , #bber .essay-tag { font-size : 0.65rem ; padding : 0 6px ; height : 22px ; } #bber .essay-tag span { max-width : 80px ; } }
整体上来说,这部分最明显的是处理了移动端的背景,在夜间模式增加了高斯模糊的背景,提高可视度.
此处用于处理首页轮播条的获取数据方式由essay.yml变更为Ech0 API,经过此步骤后essay.yml可以自行删除或留念
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 //- bbTimeList.pug - Ech0 API动态加载版本 if theme.ech0 && theme.ech0.enable - let onclick_value = theme.pjax.enable ? `pjax.loadUrl("/essay/");` : ''; - let href_value = theme.pjax.enable ? 'javascript:void(0);' : `/essay/`; #bbTimeList.bbTimeList.container i.anzhiyufont.anzhiyu-icon-jike.bber-logo.fontbold(onclick=onclick_value, title="即刻短文" gbtip="即刻短文", href=href_value, aria-hidden="true") #bbtalk.swiper-container.swiper-no-swiping.essay_bar_swiper_container(tabindex="-1") #bber-talk.swiper-wrapper(onclick=onclick_value) //- 动态内容由JS渲染 a.li-style.swiper-slide(href=href_value) 加载中... a.bber-gotobb.anzhiyufont.anzhiyu-icon-circle-arrow-right(onclick=onclick_value, href=href_value, title="查看全文" gbtip="查看全文") script(src=url_for(theme.home_top.swiper.swiper_js)) script. if (typeof Ech0Config === 'undefined') { var Ech0Config = { api_url: '#{theme.ech0.api_url}', page_limit: #{theme.ech0.page_limit}, index_limit: #{theme.ech0.index_limit}, cache_ttl: #{theme.ech0.cache_ttl}, name: '#{theme.ech0.name}', avatar: '#{theme.ech0.avatar}' } } else if site.data.essay each i in site.data.essay if i.home_essay - let onclick_value = theme.pjax.enable ? `pjax.loadUrl("/essay/");` : ''; - let href_value = theme.pjax.enable ? 'javascript:void(0);' : `/essay/`; #bbTimeList.bbTimeList.container i.anzhiyufont.anzhiyu-icon-jike.bber-logo.fontbold(onclick=onclick_value, title="即刻短文" gbtip="即刻短文", href=href_value, aria-hidden="true") #bbtalk.swiper-container.swiper-no-swiping.essay_bar_swiper_container(tabindex="-1") #bber-talk.swiper-wrapper(onclick=onclick_value) each i in site.data.essay each item, index in i.essay_list if index < 10 - var contentText = item.image ? item.content + ' [图片]' : (item.video ? item.content + ' [视频]' : item.content) a.li-style.swiper-slide(href=href_value)= contentText a.bber-gotobb.anzhiyufont.anzhiyu-icon-circle-arrow-right( onclick=onclick_value, href=href_value, title="查看全文" gbtip="查看全文") script(src=url_for(theme.home_top.swiper.swiper_js))
整体替换文件
整体替换文件
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 //- essay.pug - Ech0 API动态加载版本 if theme.ech0 && theme.ech0.enable #essay_page .author-content.author-content-item.essayPage.single(style=`background: url(${theme.ech0.top_background}) left 28% / cover no-repeat;`) .author-info .msg .avatar a.essay-avatar(href=theme.ech0.avatar_link) img(src=theme.ech0.avatar) .eassy-name= theme.ech0.name .desc= theme.ech0.desc #bber section.timeline.page-1.content ul#waterfall.list //- 动态内容由JS渲染 #bber-tips(style='color: var(--anzhiyu-secondtext);') | - 加载中... - script. if (typeof Ech0Config === 'undefined') { var Ech0Config = { api_url: '#{theme.ech0.api_url}', page_limit: #{theme.ech0.page_limit}, index_limit: #{theme.ech0.index_limit}, cache_ttl: #{theme.ech0.cache_ttl}, name: '#{theme.ech0.name}', avatar: '#{theme.ech0.avatar}' } } script(defer data-pjax src=url_for('/js/essay.js')) else if site.data.essay //- 回退到原有的静态数据模式 each i in site.data.essay #essay_page .author-content.author-content-item.essayPage.single(style = i.top_background ? `background: url(${i.top_background}) left 28% / cover no-repeat;` : "") .author-info .msg .avatar a.essay-avatar(href=i.avatarLink) img(src=i.avatar) .eassy-name=i.name .desc=i.desc #bber section.timeline.page-1.content ul#waterfall.list each item, index in i.essay_list if index < i.limit li.bber-item .user-avatar(style = i.top_background ? `background: url(${i.avatar}) left 28% / cover no-repeat #ffffffad;` : "") .bber-content .right .bber-name=i.name p.datacont= item.content if item.image .bber-container-img each iten, indey in item.image a.bber-content-img(href=url_for(item.image[indey]), target="_blank", data-fancybox="gallery", data-caption="") img(src=url_for(item.image[indey])) .bber-content-noimg .bber-content-noimg .bber-content-noimg if item.video .bber-container-img each iten, indey in item.video if (item.video[indey].includes('player.bilibili.com')) div(style="position: relative; padding: 30% 45%;margin-top: 10px;margin-bottom: 10px;") iframe(style="position: absolute; width: 100%; height: 100%; left: 0; top: 0;margin: 0;border-radius: 12px;border: var(--style-border);" src=url_for(item.video[indey]) scrolling="no" border="0" frameborder="no" framespacing="0" allowfullscreen="true") else a.bber-content-video(href=url_for(item.video[indey]) data-fancybox="gallery", data-caption="") video(src=url_for(item.video[indey])) .bber-content-noimg .bber-content-noimg .bber-content-noimg if item.aplayer .bber-music meting-js(id=item.aplayer.id, server=item.aplayer.server, type="song", mutex="true",preload="none", theme="var(--anzhiyu-main)", data-lrctype="0", order="list") .bber-bottom .bber-info-address if item.address span=item.address .bber-info-time - var datedata = new Date(item.date).toISOString() time.datatime(datetime= item.date)= datedata .bber-info-link if item.link a.bber-content-link(title="跳转到短文指引的链接", href=url_for(item.link), rel="external nofollow") i.anzhiyufont.anzhiyu-icon-link | 链接 .bber-reply(onclick="rm.rightMenuCommentText(" + `'${item.content}'` + ")") i.anzhiyufont.anzhiyu-icon-message hr.essay-hr #bber-tips(style='color: var(--anzhiyu-secondtext);') ="- 只展示最近" + i.limit + "条短文 -"
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 //- 即刻依赖waterfall script(async data-pjax src=url_for(theme.asset.waterfall)) + //- Ech0 即刻短文 API + if theme.ech0 && theme.ech0.enable + script. + if (typeof Ech0Config === 'undefined') { + var Ech0Config = { + api_url: '#{theme.ech0.api_url}', + page_limit: #{theme.ech0.page_limit}, + index_limit: #{theme.ech0.index_limit}, + cache_ttl: #{theme.ech0.cache_ttl}, + name: '#{theme.ech0.name}', + avatar: '#{theme.ech0.avatar}' + } + } + script(defer data-pjax src=url_for('/js/essay.js'))
自行删除附带的+,还是没忍住标注
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 initIndexEssay : function ( ) { const bbTimeList = document .getElementById ("bbTimeList" ); if (!bbTimeList) return ; const swiperWrapper = document .querySelector ('#bber-talk' ); if (!swiperWrapper) return ; const slides = swiperWrapper.querySelectorAll ('.swiper-slide' ); if (slides.length === 0 || (slides.length === 1 && slides[0 ].textContent .includes ('加载中' ))) { return ; } setTimeout (() => { const swiperContainer = document .querySelector ('.essay_bar_swiper_container' ); if (!swiperContainer) return ; if (swiperContainer.swiper ) { swiperContainer.swiper .destroy (true , true ); }
1 2 if site.data.essay || theme.home_top.swiper.enable || (theme.ech0 && theme.ech0.enable) link(rel='stylesheet' href=url_for(theme.home_top.swiper.swiper_css) media="print" onload="this.media='all'")
确保在配置项的enable: true可以生效
1 2 3 if theme.home_top.swiper.enable if !site.data.essay && !(theme.ech0 && theme.ech0.enable) script(src=url_for(theme.home_top.swiper.swiper_js))
同理
至此,关于魔改即刻短文兼容Ech0 到此完毕
剩下内容你可以查阅柳神的后续步骤
从Moments迁移到Ech0-注意事项 | LiuShen’s Blog
总结 如果你仔细查阅过本站的大部分内容,你会发现基本上是对于anzhiyu主题的魔改,算是一些对于优秀设计的简陋复刻,个人水平十分有限,也是个穷学生才会折腾静态博客,不过有一说一,Hexo博客的构建着实令人着急,也难怪主题作者安知鱼会重构主题,不过个人认为这是潜力巨大才有开发的可能性
在此已接近每月一篇文章的速度更新,后续或许还会更加懒散,希望大家多多担待,往后主题定性后或许就开始搬运自己的文章上来了,更新速度或许还会更快?
如果你看到这里了,哪一天没有更新就可以看看即刻短文 了解一下情况,算对鄙人莫大的慰籍了
在此,感谢你的耐心阅读,祝你有所感悟!