使用github pages + issues + api建立个人博客

本文介绍如何利用GitHub Pages、Issues及API创建一个免费且高度定制化的个人博客。该方法无需服务器和域名,仅通过HTML、JS和CSS即可实现。文中详细讲解了前端路由配置、文章内容获取与展示、Markdown渲染等关键技术点。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

作者:刘欢

前言

最近写了一个简单的博客并放在github上,在此详述一下细节,以为分享。

方法并不高端,但是:

1.      简单易行不要钱。
不需要数据库,不需要服务器,不需要域名因为github都帮我们做了,壮哉我大github

2.      完全自定义的纯HTML/JS/CSS代码。不需要学各种static sitegenerator的玩法,又能实现独一无二的个人博客。

好了,废话稍止,进入正文

原理就一句话

前端代码hostgithub pages, 利用githubissues做为后台,通过githubAPI完成前后端交互。

基本介绍

·        githubpages

    • Github 提供的托管静态网页的服务,基本使用方法是建立一个名为YOUR_USER_NAME.github.iorepo, 并把代码push到master branch。
    • 注意其只支持静态内容
    • 另外,如果你有自己的域名,也可以将域名指向github pages

·        github issues

每个github repo自带的tracking系统,支持markdown,代码高亮,图片,表格,emoji表情

·        githubAPI

Github提供的API,可以拿到你的issues内容,可以rendermarkdown...更多请看文档

为何不直接使用issues作为博客

事实上,直接使用issues作为博客也是可行的,从这个角度,就是把github issues当成博客平台。
这个方案的缺陷是:
1.   Githubissues并不是为作为博客而设计的,博客平台的很多功能,比如推荐、SEO等都是没有的
2.   你将受限于github的UI和用户(需要注册才能评论),无法自由的定义你想要的UI和交互
而使用github API来构建nobackend app, 即可以合理利用github提供的强大功能,又能随心所欲的定义自己的网站,还能集成任意的第三方服务(评论、分享等),十分潇洒

 

我的玩法

本博客基于m-angular-boilerplate开发,这是我写的一个前端快速开发框架,主要技术为angularJS +bootstrap + grunt + coffeeScript,有兴趣的朋友可以看看。 

这个框架的scope不同于博客系统,在此先不多说。本文会主讲博客涉及到的内容。

上酸菜和代码

首先要在Github上建立repo,名字为YOUR_USER_NAME.github.io,比如我的martin-liu.github.io
拉到本地后开始coding以下为coffee编译出来的js代码,主要使用angularJS,如用其它框架实现,按同样的原理来就是:


1. 注册 routing 。就是把 url 和页面逻辑对应,比如 http://martin-liu.github.io/#!/这个url 就找 partials/home.html 这个 html ,并执行 HomeCtrl 这个 function 。如果找不到,就去 404 页面
angular.forEach(Config.routes, function(route) {
    if (route.params && !route.params.controller) {
      route.params.controller = 'BaseCtrl';
    }
    $routeProvider.when(route.url, route.params);
});
$routeProvider.otherwise({
    templateUrl: 'partials/404.html'
});


Config.routes内容为:

[
{
  "url": "/",
  "params": {
    "name": "home",
    "label": "Home",
    "templateUrl": "partials/home.html",
    "controller": "HomeCtrl"
  }
},
{
  "url": "/article/:id",
  "params": {
    "name": "article",
    "hide": true,
    "templateUrl": "partials/article.html",
    "controller": "ArticleCtrl"
  }
},
{
  "url": "/about",
  "params": {
    "name": "about",
    "label": "About",
    "templateUrl": "partials/about.html"
  }
}
]

2. Home页面的实现

    code如下,BlogRemoteService.getBlogs()就是ajax call刚刚那个url,拿issues数据。

    BlogRemoteService.getBlogs().then((function(_this) {
          return function(blogs) {
            return _this.data.blogs = _this.processBlogs(blogs);
          };
        })(this));
    
    processBlogs = function(blogs) {
        return _.map(blogs, BlogService.decorateBlog);
      };
    

    BlogService.decorateBlog就是下面的取summary

    •  文章summary 

           

    可以看到,文章内容有一段注释,里面是json代码。注释不会显示,但可被获取,做为metadata。

    <!--
    {
    "summary":"渺小如我们,是风吹动水面,是蝴蝶一次振翅。在正确的位置,也能掀起远方的风暴;找到那个支点,也能撬动地球。"
    }
    -->
    BlogService.decorateBlog的内容如下,用来解析注释内容,赋值给blog.meta
        decorateBlog: function(blog) {
          var e, meta, metaStr;
          if (!blog.body) {
            return blog;
          }
          metaStr = blog.body.substring(0, blog.body.indexOf('-->'));
          metaStr = metaStr.replace(/\n|\r|<!-{2,}/gm, ' ');
          try {
            meta = JSON.parse(metaStr);
          } catch (_error) {
            e = _error;
            console.log(e);
          }
          blog.meta = meta;
          if (blog.meta.summary) {
            BlogRemoteService.renderMarkdown(blog.meta.summary).then(function(data) {
              return blog.meta.summary = data;
            });
          }
          return blog;
        }
    

    • html页面, 展示blog list, 带summary。如果不用angularJS, 用handlebarsmustache也可轻松实现
      <m-loading ng-if="!vm.data.blogs"></m-loading>
      <div ng-if="vm.data.blogs" ng-repeat="blog in vm.data.blogs">
      <div style="cursor:pointer"
           ng-click="Util.redirect('/article/' + blog.number)">
        <h3 ng-bind="blog.title"></h3>
        <p class="summary" ng-bind-html="blog.meta.summary"></p>
        <span ng-bind="blog.created_at | date:'yyyy-MM-dd'"</span>>
      </div>
      <hr/>
      </div>
      

      3.    文章页面的实现

      BlogRemoteService.getBlog(id).then((function(_this) { return function(blog) { if (blog.body) { _this.data.blog = BlogService.decorateBlog(blog); BlogRemoteService.renderMarkdown(blog.body).then(function(ret) { return _this.data.content = ret; }); return $rootScope.blog = _this.data.blog; } }; })(this));

      post   blog.content https://api.github.com/markdown

      • html

      <m-loading ng-if="!vm.data.content"></m-loading>
      <div ng-if="vm.data.content">
      <h2 class="align-center" ng-bind="vm.data.blog.title"></h2>
      <p ng-bind="vm.data.blog.created_at | date:'yyyy-MM-dd hh:mm:ss'" class="created-at"></p>
      <br/>
      <div ng-bind-html="vm.data.content"></div>
      </div>
      
      <br/>
      <br/>
      <hr/>
      <p>欢迎扫码订阅公众号:</p>
      <img width="120" src="/image/qrcode_wechat.jpg"/>
      <div ng-if="vm.data.blog.number"
       duoshuo data-thread-key="{{vm.data.blog.number}}"></div>
      

      4.      关于css
      css
      主要是用的bootstrap,但是代码高亮是copyfrom github,代码在这里

      5.      使用多说评论百度统计jiathis社会化分享
      需要到各自的网站上注册,得到相应代码

      以下为异步加载多说和百度统计的代码

       function addScript(src){
           var el = document.createElement("script");
           el.src = src;
           var s = document.getElementsByTagName("script")[0];
           s.parentNode.insertBefore(el, s);
         }
      
         // duoshuo
         var duoshuoQuery = {
           short_name: 'martin-liu'
         }
      
         // baidu statistics
         var _hmt = _hmt || [];
         _hmt.push(['_setAutoPageview', false]);
      
         var scriptSrcs = [
           'http://static.duoshuo.com/embed.unstable.js', // duoshuo
           '//hm.baidu.com/hm.js?a67e974dea316e70836c07c3e3576a29' // baidu statistics
         ]
      
         for(var i = 0; i < scriptSrcs.length; i++){
           addScript(scriptSrcs[i]);
         }
      

      另外,对于多说使用angular-duoshuo来支持angularJS

      <div ng-if="vm.data.blog.number"
       duoshuo data-thread-key="{{vm.data.blog.number}}"></div>
      

      百度统计,url变化时触发

      $rootScope.$on('$routeChangeSuccess', function($event, current) {
        if (_hmt) {
          return _hmt.push(['_trackPageview', $location.url()]);
        }
      });
      

      6.      fork me on github
      https://github.com/blog/273-github-ribbons

      7.      使用locache做本地cache,减少request数量,提高用户体验。我设置为5分钟失效

      this.getWithCache = function(key, isSession, getFunc, timeout) {
        var cache, data, defer, promise;
        cache = Cache;
        if (isSession) {
          cache = Cache.session;
        }
        defer = $q.defer();
        data = cache.get(key);
        if (data) {
          defer.resolve(data);
          return defer.promise;
        } else {
          promise = getFunc();
          promise.then(function(data) {
            return cache.set(key, data, timeout);
          });
          return promise;
        }
      };
      

      8.     pushgithub,等几分钟,一个新鲜的热乎乎的博客就出现了!
      以下是我的部署script,因为有build过程(concat,uglify之类)

      #!/bin/bash
      grunt build
      ( cd dist
      git init
      git add .
      git commit -m "Deployed to Github Pages"
      git push --force --quiet "https://github.com/martin-liu/martin-liu.github.io.git" master
      )
      

      Next

      还有一些问题没有解决,如

      •  RSS
      •  SEO

      最后

      可以看到,这是个非常简单的blog,并不完善,但是workable,可以在此基础上迭代开发。这一点相当重要,因为

      Done is better than perfect.

      -- facebook
      标语

       

       





      评论
      添加红包

      请填写红包祝福语或标题

      红包个数最小为10个

      红包金额最低5元

      当前余额3.43前往充值 >
      需支付:10.00
      成就一亿技术人!
      领取后你会自动成为博主和红包主的粉丝 规则
      hope_wisdom
      发出的红包
      实付
      使用余额支付
      点击重新获取
      扫码支付
      钱包余额 0

      抵扣说明:

      1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
      2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

      余额充值