riot.jsで作る雑ブログシステム

はじめに

概要

雑なブログシステムを作ろうと思ったので作りました。
なにせ雑なので、下記のような制限付き。

  • DBは利用しない。
  • Server側の処理はなるべくなし

完成品は下記
hasito.com

仕様

機能

  • Markdownをサポート
  • タイトルと編集時期を設定可能

システム概要

  • Markdown処理のパッケージを利用
  • 表示はめんどくさいのでbootstrap
  • ファイルは下記の2つを記事として参照
    • {index}.md 記事の内容
    • {index}.json 更新日とタイトル
  • 参照は記事ファイルのindexを信じて0からループ…404なったら終わり

ファイル構成

-/  
  +blog.tag  
  +index.html  
  -component/markdown-it/dist/markdown-it.min.js  
  -article  
    +0.json  
    +0.md  
    +1.json  
    +1.md  
    +...  

コード

blog.tab

<blog>  
  <div class="list-group">  
    <button each={v,i in articles} onclick={viewart.bind(this,i)} type="button" class="list-group-item">{v.cnf.name}</button>  
  </div>  
  <script>  
    var self=this;  
    self.articles=[];  
    var md = window.markdownit({html:true,breaks:true});  
    viewart(i){  
       $(".view").html(md.render(self.articles[i].md));  
    }  
    self.on("mount",(e)=>{  
      console.log("mount");  
      self.articles=[];  
      var idx=0  
      var cb=(v)=>{  
        if(v){  
          var art={md:v};      
          get_article_cnf(idx,(vv)=>{  
            art.cnf=vv;  
            self.articles.push(art);  
            get_article(++idx,cb)  
          })  
        }else{  
          self.update();  
        }  
      }  
      get_article(idx,cb);  
    });  
  
    var get_article=(i,cb)=>{  
      fetch(`article/${i}.md`)  
        .then(res => {  
          if (!res.ok) {throw Error(false);}  
          return res.text();  
        }).then(body => {  
          cb(body);  
        }).catch(err=>{  
          cb(false);  
        });  
    }  
    var get_article_cnf=(i,cb)=>{  
      fetch(`article/${i}.json`)  
        .then(res => {  
          if (!res.ok) {throw Error(false);}  
          return res.json();  
        }).then(body => {  
          cb(body);  
        }).catch(err=>{  
          cb(false);  
        });  
    }  
  </script>  
</blog>  

index.html

<html>  
  <head>  
    <title>Hello Riot.</title>  
    <meta charset="UTF-8"/>  
  
    <!-- jQuery (necessary for Bootstrap's JavaScript plugins) -->  
    <script src="https://ajax.googleapis.com/ajax/libs/jquery/1.12.4/jquery.min.js"></script>  
    <!-- Latest compiled and minified CSS -->  
    <link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.7/css/bootstrap.min.css" integrity="sha384-BVYiiSIFeK1dGmJRAkycuHAHRg32OmUcww7on3RYdg4Va+PmSTsz/K68vbdEjh4u" crossorigin="anonymous">  
    <!-- Optional theme -->  
    <link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.7/css/bootstrap-theme.min.css" integrity="sha384-rHyoN1iRsVXV4nD0JutlnGaslCJuC7uwjduW9SVrLvRYooPp2bWYgmgJQIXwl/Sp" crossorigin="anonymous">  
    <!-- Latest compiled and minified JavaScript -->  
    <script src="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.7/js/bootstrap.min.js" integrity="sha384-Tc5IQib027qvyjSMfHjOMaLkfuWVxZxUPnCJA7l2mCWNIpG9mGCD8wGNIcPD7Txa" crossorigin="anonymous"></script>  
  </head>  
  <body>  
      <div class="container-fluid">  
        <div class="row">  
            <div class="col-xs-12"><h2>hasito.com</h2></div>  
        </div>  
        <div class="row">  
          <div class="col-xs-2">  
              <blog></blog>  
          </div>  
          <div class="col-xs-10 view">  
          </div>  
        </div>  
    <script type="riot/tag" src="blog.tag"></script>  
   <script src="https://cdn.jsdelivr.net/npm/riot@3.9/riot+compiler.min.js"></script>  
   <script src="component/markdown-it/dist/markdown-it.js"></script>  
   <!-- <script src="riot/riot+compiler.min.js"></script> -->  
    <script>riot.mount('blog')</script>  
  </body>  
</html>  

1.json

  
{  
    "name":"テスト2",  
    "date time":"2018/04/02 02:46"  
}  
  

1.md

  
# テスト記事2  
## sub  
### sub sub  
こんにちわ、これはテスト記事です。  
  
aa**aaaa**aa  
xx__xxxx__xx