/-O-

Just a simple static blog Generator with single static pages and Github API / 通过GithubAPI交互实现在浏览器中发布文章的静态博客生成器

Primary LanguageJavaScriptMIT LicenseMIT

-O-

head
Just a simple static blog Generator with single static pages.
现在开始就在GithubPages上撰写吧


example


想法🤔

之前逛v2社区的时候看到有人写了一个利用github api的博客,顿时非常心动,但项目已经久未更新,我便有了自己写一个的想法..

特点💊

  • 原生JavaScript
  • PJAX
  • 支持模板
  • 支持标签页,归档页
  • 自带简单搜索功能,支持介入搜索
  • 甚至只需要Github Pages #)3 )
  • 硬核图片Lazyload
  • 平滑回滚至头部 2ax=V²(完全可以用原生的scroll啊喂!)
  • 封面图支持~

可用主题🧻

  1. -O-程序自带
  2. Anatole
  3. Simple
  4. 期待各位的移植和创造~

部署📖

具体看wiki

编辑器使用提示📎

  • 在内容编辑栏按下Alt + V可以根据视频URL快捷添加<video>标签

  • 在内容编辑栏按下Tab时会插入四个空格

  • 当日期一栏填的是非日期时会自动切换创建页面模式,日期一栏中填的内容将作为页面链接。 例如:当你填写的是20200407,创建的是post-<文章ID>.html一类的文章页面;而当你填写的是aboutme,创建的页面是aboutme.html

  • 页面不可转为文章,反之亦然.

  • 发布文章时页面中的内联 js 会自动被注释,但是访问对应页面时还是会执行的

  • 其他使用提示请见 wiki - 管理|后台的使用

一定要注意💡

  • 不要不要不要修改模板的index.html,本身这个模板也只是一个媒介,并不会被直接上传到博客仓库,在前台并不展现外观,另外若修改index.html需要修改后台部分的(所以还是不要瞎折腾啦=A=)

  • 不要向cloth.otp.html<clothhead>里面添加<script>标签,不然并不会执行/引入,反之你可以在<clothhead>以外部分引入<script>.

关于搜索🔍

  • 在文章列表页通过hash访问 #!搜索内容 可以进行搜索,需要注意的是,由于索引文件的限制,只支持根据文章部分内容和标题,标签,日期这类的搜索.

  • 你也可以接入Github的搜索API,详见search.js

文章封面📋

2019.8.10,老瓶闲着蛋疼加了个文章封面的支持.

bilityPic

编辑文章时在无论哪个位置以注释的形式插入一条

<!--[cover:<link>]-->  

发布文章时会自动识别,一同上载.接下来,最重要的是模板部分了.
postitempost模板中会有这样一个标签:

<ifcover><img src='{[postcover]}'></img></ifcover>  
  • ifcover标签在这两个模板中可以出现在很多个地方,有头有尾.如果指定的文章或页面没有封面,渲染完成后所有的ifcover标签都会被自动剔除.

  • 如果有封面,ifcover标签会保留,而{[postcover]}会被替换为封面图片url.由此,你可以尽可能地去自定义您的封面以使其样式融入主题😃

  • 我怎么删除封面呢?
    只需要编辑文章的时候,把之前的那一条改成:

    <!--[cover:none]-->  

    然后编辑发布文章,即可删除封面.(由于pages缓存问题,可能要稍等一下才能看到效果)
    Have fun~

模板说明🔨

  • template.json

    项目
    alltp 所有要部署到仓库的模板文件,不建议修改(博客初始化时会被部署到./barn/目录下)
    necessary 加载页面时一定要加载的几个模板,无论你访问博客的哪个页面这几个模板都会载入浏览器缓存
    usemain 使用main.json的几个模板,当你访问使用这几个模板的页面时加载过程会等待main.json载入完毕
    templatehtmls 指定各类模板对应的文件,如果部署后修改了这里,上面几个项目中的模板文件名也要进行修改
    generatehtmls 主要是tags和archives模板对应的页面文件

    模板文件名在部署到仓库后可以进行相应的修改,同时对于博客所在仓库中template.json也要有所修改.
    PS:loading.otp.htmltemplate.json中是无法配置的,请不要修改文件名.

  • 模板渲染简单gif.

    render

  • 模板特殊占位

    1. index.html模板都能使用{[barndir]}占位符,这个占位符会被替换为博客核心文件所在的相对目录。
      默认核心文件存在./barn/下,{[barndir]}也就会被替换为barn/

    2. index.html 媒介页面 ( ⚠ 不要修改,不影响外观 )

      <!--description-->
      <meta name="description" content="{[description]}" />   Description 
      <!--Keywords-->
      <meta name="keywords" content="{[keywords]}" />   Keywords
      <loadingarea></loadingarea>  用于放置Loading页面,不要删除!   
      {(MainTitle)}<title>{[title]}{[titlemiddle]}{[sitename]}</title>{(MainTitleEnd)}  注释用于识别标题所在位置,{[title]}为当前标题,{[sitename]}为站点名(在main.json配置),{[titlemiddle]}是一个小短横```-```,访问首页的时候不会显示    
      {(PostTitle)}{[title]}{(PostTitleEnd)}  文章标题,一般和上面的{[title]}一致  
      {(PostDate)}{[date]}{(PostDateEnd)}  文章日期  
      {(PostContent)}
      {[content]}   文章内容
      {(PostContentEnd)}
      {(PostTag)}{[tags]}{(PostTagEnd)}  文章tags
      {(PostID)}{[pid]}{(PostIDEnd)}  文章pid  
      {(PostCover)}{[cover]}{(PostCoverEnd)}  (此处可能为none)文章封面,具体看上方封面设置
      {(PubTime)}{[pubtime]}{(PubTimeEnd)} 初次发布时间戳(毫秒级)
      {(EditTime)}{[edittime]}{(EditTimeEnd)}  最近一次编辑时间戳(毫秒级)
      {(PageType)}{[type]}{(PageTypeEnd)}  用于指定页面类型  
      <script src="./main.js?233"></script>
    3. postitem.otp.html 文章列表单项

      {(PostItem)}  主要postitem模板
      {[postitemlink]}  文章列表每一项的链接
      {[postitemtitle]}  文章列表每一项的标题  
      {[postitemintro]}  文章列表每一项的简介
      {[postitemdate]}  文章列表每一项的日期  
      {[postitemtags]}  文章列表每一项的标签  
      <ifcover><img src='{[postcover]}'></img></ifcover>  封面标签,以及封面占位符  
      {(PostItemEnd)}
      {(NoItem)}   加载more时没有更多文章的模板
      <h3 style='color:#AAA;'>没有更多了呢</h3>   
      {(NoItemEnd)}
    4. postlist.otp.html 文章列表

      {(PostListTemplate)}  用于划定PostList模板的范围
      {[postitems]}  用于载入文章列表  
      {[morebtn]}  加载更多按钮的替换符
      {[backbtn]}  返回上一页按钮的替换符(可以不写)
      {(PageType)}{[pagetype]}{(PageTypeEnd)}  用于指定pagetype   
      {(PostListTemplateEnd)}
      
      {(MoreBtn)}
      加载更多按钮的模板
      {(MoreBtnEnd)}
      {(BackBtn)}
      返回上一页按钮的模板
      {(BackBtnEnd)}
    5. post.otp.html 文章/页面单页

      {(PostTemplate)}  模板开头
      {[posttitle]}  文章标题  
      {[postdate]}  文章日期  
      {[postcontent]}  文章内容  
      {[posttags]}  文章标签(html)  
      {(:PostEnd)}  (需要保留) 指定文章结束的地方.  
      {[comments]}  用于渲染评论(接comment.otp.html)  
      {(PostTemplateEnd)} 模板结尾  
      {(PostTagsTemplate)}  文章底部单个标签的模板
      {[tagurl]} 这个标签的url  
      {[tagname]}  这个标签的名字  
      {(PostTagsTemplateEnd)}   文章底部单个标签模板结束
      {(PostTagsDelimiter)},{(PostTagsDelimiterEnd)}  标签与标签之间的分隔,这里默认是一个逗号  
      {(IfPage)}<span>这里是页面</span>{(IfPageEnd)}  如果是页面,标签这里显示的内容
      
      
      <ifcover><img src='{[postcover]}'></img></ifcover>  封面标签,以及封面占位符  

      {(:PostEnd)}{(Footer:)} 的说明具体看wiki

    6. main.otp.html 酥脆外皮

      {[contents]}  用于渲染页面内容  
      {(Footer:)}  (需要保留) 指定页脚开始的地方  

      {(:PostEnd)}{(Footer:)} 的说明具体看wiki

    7. cloth.otp.html 外衣

      <clothhead>
      模板头部内容,用于替代页面中的<head>  
      </clothhead>
      {[main]}  用于渲染main.otp.html
    8. archives.otp.html 归档页

      具体介绍看wiki

    9. tags.otp.html 标签页

      具体介绍看wiki

    10. comment.otp.html 评论框页

    {[pid]}  文章唯一id  
    1. loading.otp.html

      加载浮页具体配置看wiki

    2. search.js

      借助search.js我们可以引用外部搜索,默认模板中的search.js引用了github的搜索api,可以编辑以进行配置。

函数/自带变量供应💬

  • 外部 JavaScript 文件载入

    (常用于模板中加载外部脚本,比如可以用在 library.js 中)

    // 这里以载入 Markdown-It 库为示例
    $.script("https://cdn.jsdelivr.net/npm/markdown-it@latest/dist/markdown-it.min.js");

    $.script 对应脚本的引入在页面渲染时进行,保证内联脚本(直接写在页面中 <script>...</script> 之间的脚本)执行之前全部载入。

    • 注意 1: 模板和页面中通过 src 属性(即以 <script src="..."></script> 的形式)引入的脚本会通过 $.script 进行载入。
    • 注意 2: 用 $.script 重复引入多次相同 URL 的外部脚本时,只有首次引入时会载入此脚本一次。
    • 注意 3: 博客前端 library.jssearch.js 脚本都是通过 $.script 载入的。
  • 当前文章信息

    每次文章或页面载入完毕后,程序会把文章信息储存在一个对象中:

    B.currentPostInfo
    1. 当访问的是文章时,其内容为:

      {  
         cover: "none", // 封面图片URL
         date: "20220206", // 文章日期
         editTime: 1644416432224, // 文章上一次被编辑的时间戳(毫秒级)
         pid: "6", // 文章/页面唯一id
         pubTime: 1644415998546, // 文章发布时间戳(毫秒级,一旦发布就不会变)
         tags: "日常", // 文章的标签们
         title: "Hello7" // 文章标题
      }
    2. 当访问的是用户创建的页面时,其内容为:

      {
         cover: "https://ae01.alicdn.com/kf/He6234e196550496abff612ee2f209cd9n.jpg", // 封面图片URL
         editTime: 1644417418735, // 页面上一次被编辑的时间戳(毫秒级)
         link: "testpage", // 页面链接
         pid: "7", // 文章/页面唯一id
         pubTime: 1644415284074, // 页面发布时间戳(毫秒级,一旦发布就不会变)
         tags: "", // 页面的标签们,暂时一直为空
         title: "New Page" // 页面标题
      }
    3. 访问其他页面时:返回 false

  • 页面渲染后回调

    B.callAfterRender(callBackFunction1);
    B.callAfterRender(callBackFunction2);

    通过这个方法,你可以注册一个或多个回调函数callBackFunction。每当页面渲染完毕(以及所有JavaScript脚本执行完毕),程序会调用所有的回调函数。

    • 传入回调函数的第一个参数为当前页面的模板名

    • 使用例 1

      B.callAfterRender((pageType)=>{
         console.log(pageType);
      })

      当我访问文章列表页(博客首页)时,等页面渲染完,控制台会输出:postlist.otp.html

    • 使用例 2:可以结合 MathJax 来进行文章页面的数学公式渲染,详情见 template/library.js

    ⚠ 请不要把此方法写入到内联脚本中,否则可能导致相同回调函数的重复注册。但是你可以写到通过 $.script 引入的外部脚本中,因为 $.script 保证这些脚本只会被载入一次。

  • 导航栏相关

    B.nav*

    具体看wiki

  • 平滑滚动至顶部,直接滚到底部

    B.scrolltop(maxspeed,minspeed); //(最大速度,最小速度)单位:px/10ms
    B.scrollbottom();  //直接滚到底部,用于快速看到底部的内容
  • 暂停当前会话中的lazyload(懒加载)

    B.lazy(bool);  //true则开启懒加载,false则关闭。当懒加载关闭后往下滚动页面图片不会再载入,流量用户狂喜。
    /*注意:在未刷新页面的情况下这一选项是持续有效的,刷新页面重建会话后会恢复到默认值,也就是false*/
  • 改变head中的<title>标签

    $.title(yourtitle);
  • 抓取元素(id)

    SC(id); //return element
  • 控制Loading的显示和隐藏

    B.loadshow(); //show
    B.loadhide(); //hide
  • 加载更多按钮和返回上一页按钮

    B.more(); //在文章列表加载更多
    B.turnback(); //在文章列表返回上一面  
    B.back(); //返回历史上一页  
  • CSS3Animation动画检查器

    anichecker(e, func); //e为元素id , func为animation结束后回调的函数.  
  • PJAX自动操作

    PJAX.sel(id); //选择PJAX操作的容器  
    PJAX.autoprevent(); //自动排查当前页是否有外站地址并放入忽略名单  
    PJAX.start(); //开始监听所有a标签和popstate,开启PJAX  
    PJAX.pause(); //暂停PJAX对于popstate的监听,可以用start来重激活  
    PJAX.jump(url); //动态载入页面,但不会改变地址栏  
  • 利用PJAX做搜索跳转的小技巧

    //比如你要搜索的内容是searchtxt  
    var searchtxt='233';
    window.history.pushState(null,null,'/#!'+searchtxt); //在文章列表访问 /#!搜索内容 可调用自带的搜索功能  
    PJAX.jump('/#!'+searchtxt); //因为PJAX.jump不会改变地址栏,所以要用pushState先加工一道  
  • 获得当前时间戳

    timestamp(); // 毫秒级

main.json可配置项🔧

  • name 站点名,请务必在部署完毕后第一时间配置,后期修改不容易
  • posts_per_page 每页默认显示多少文章
  • more_per_page More按钮在同一页面能按多少次

引用项目⚙️

感谢❤

  • Ghosin 提了非常多很不错的意见!
  • Ohmyga 帮助改进了LoadingPage...
  • 匿名小伙伴们的资助~

MIT LICENSE.