xtzero.me
做一个博客系统
技术学习
2021-02-18

年前做的东西,早就想写个博客记录一下,然后就过年了。电脑充满电带回了家,一条电居然撑到了上班。事实证明mbp的电池是可以在开机状态下合盖待机11天的。

今天的课题是用php做一个静态网站生成器,也叫博客系统。

东西已经做完了,官网是 Hikari 官网,文档里边有,文档本身就是示例,所以这一个地址点进去啥都有。

如果你是在公众号阅读的这篇文章,上边的Hikari官网可能不能点击。你需要点击左下角阅读原文进入原文链接,再点链接进入官网。或者直接复制网址http://hikari.website访问。

文档写得挺详细了,这边就记录一些知识点和坑吧。第一次用php写控制台程序,有很多东西都是之前没用过的。

控制台程序

在php程序中,使用$argc获取控制台参数数量,使用$argv获取控制台参数数组。比较难受的是,就算控制台里按照选项和选项值(command -a 1 -b 2)来输入,$argv也不会给出索引数组,而是将选项也当做一个值。如果要将程序设计成需要分析选项的,就需要特别处理才能获取到选项和选项值的索引数组了。

psr4自动加载

使用composer安装类库的话,项目根目录下就会有vendor目录,我们需要在项目启动的时候引入/vendor/autoload.php,来让composer加载类库。

接口

interface规定程序模板,让实现同一个接口的类都遵循一样的模板。在Hikari中用interface规定了Cmd和Template。

<?php namespace Lib\Base; interface BaseCmd { /** * A command line command must have a `handle` function which is public and static! * @return mixed */ public static function handle($argv); }

一个Cmd类必须有handle方法,这样才能根据控制台输入找到对应的Cmd类,来执行对应类的handle方法。

<?php namespace Lib\Base; interface BaseTemplate { public static function render($data); }

一个Template类必须有一个render方法,这样的设计下,将Template类放在主题的配置数组里,执行构建命令时就可以依次执行每个Template下的render方法来输出静态页了。

markdown解析

直接使用了SegmentFault/HyperDown库,可以输入markdown输出html字符串。然后在模板渲染里写样式。

模板渲染

先写了一个模板渲染方法。

function C($filePath, $replaceData = []) { if (!file_exists($filePath)) { return ""; } $contents = file_get_contents($filePath); if (!empty($replaceData)) { foreach ($replaceData as $k => $v) { $contents = str_replace("{{{$k}}}", $v, $contents); } } return $contents; }

然后准备了一个页面目录pages和组件目录Components,里边存带有模板语法的html片段啥的。比如首页

<body> {{navbar}} <div class="container"> <img class="logo" src="/hikarilogo.png"></img> <h2 id="title"> {{title}} <!-- <span class="version">beta 1</span> --> </h2> <h3 id="subtitle">{{subtitle}}</h3> <div id="menus"> {{menu}} <script> ((function() { var menus = document.getElementsByClassName('menu-action') for (var i = 0; i < menus.length; i ++) { menus[i].addEventListener('click', function() { window.location.href = this.getAttribute('link') }) } })()) </script> </div> </div> {{footer}} </body>

footer组件

<style> .footer { display: flex; flex-direction: column; align-items: center; margin-top: 100px; color: #3E4857; font-size: 13px; } </style> <div class="footer"> <div class="footer-author"> 使用 <a href="https://gitee.com/xtzero/hikari">Hikari</a> 构建 </div> <div class="footer-desc">一个简洁、高效、可定制的博客框架。</div> <div class="footer-statistic"> {{busuanzi}} </div> <div class="footer-police">*ICP备*号-*</div> </div>

和不蒜子组件

<!-- 放在页头 --> <script async src="//busuanzi.ibruce.info/busuanzi/2.3/busuanzi.pure.mini.js"></script> <!-- 显示代码是 --> <span id="busuanzi_container_site_pv">👁 <span id="busuanzi_value_site_pv">加载中...</span></span>

我就可以使用模板渲染方法这样渲染一个主页

$html = C(THEME_BASE_DIR . '/page/index.html', [ 'title' => ENV['title'], 'subtitle' => ENV['subtitle'], 'navbar' => C(THEME_BASE_DIR . '/components/navbar', [ "title" => ENV['title'], "items" => implode("\n", array_map(function($v) { return C(THEME_BASE_DIR . '/components/navbarItem', $v); }, THEME_CONFIG['navbar'])) ]), 'menu' => implode("\n", array_map(function($v) { return C(THEME_BASE_DIR . '/components/indexNav', $v); }, THEME_CONFIG['homepageMenu'])), 'footer' => C(THEME_BASE_DIR . '/components/footer', [ "busuanzi" => C(THEME_BASE_DIR . '/components/busuanzi') ]) ]);

要是模板能支持条件和循环渲染就好了,暂时还没做,只能用implode和array_map来代替了。

xtzero.me
从前从前,有个人爱你很久
友情链接
这里是友情链接
虽然我很菜,但是也希望可以和更多人交换友链。
作品站
这里是我的 作品站
虽然菜,但还没放弃创造。
推广内容
或许你需要买便宜的服务器
你有优惠我有返利,何乐而不为呢。

立即查看 >>
也想使用 Hikari 2 ?
Hikari 2 已经被用来建站啦!点击这里来查看都有哪些案例以及我们的联系方式吧。