Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -23,3 +23,4 @@ _cgo_export.*
_testmain.go

*.exe
/gor/widgets
4 changes: 2 additions & 2 deletions compile.go
Original file line number Diff line number Diff line change
Expand Up @@ -456,7 +456,7 @@ func PrapareAssets(theme string, layoutName string, topCtx mustache.Context) str
if strings.HasPrefix(stylesheet, "http://") || strings.HasPrefix(stylesheet, "https:") {
assets = append(assets, fmt.Sprintf("<link href=\"%s\" type=\"text/css\" rel=\"stylesheet\" media=\"all\">", stylesheet))
} else {
assets = append(assets, fmt.Sprintf("<link href=\"%s/%s\" type=\"text/css\" rel=\"stylesheet\" media=\"all\">", "/assets/" + theme + "/widgets", stylesheet))
assets = append(assets, fmt.Sprintf("<link href=\"%s/%s\" type=\"text/css\" rel=\"stylesheet\" media=\"all\">", "/assets/"+theme+"/widgets", stylesheet))
}
}
}
Expand Down Expand Up @@ -484,7 +484,7 @@ func PrapareAssets(theme string, layoutName string, topCtx mustache.Context) str
if strings.HasPrefix(javascript, "http://") || strings.HasPrefix(javascript, "https:") {
assets = append(assets, fmt.Sprintf("<script src=\"%s\"></script>", javascript))
} else {
assets = append(assets, fmt.Sprintf("<script src=\"%s/%s\"> </script>", "/assets/" + theme + "/widgets", javascript))
assets = append(assets, fmt.Sprintf("<script src=\"%s/%s\"> </script>", "/assets/"+theme+"/widgets/", javascript))
}
}
}
Expand Down
Binary file modified gor/gor-content.zip
Binary file not shown.
5 changes: 3 additions & 2 deletions gor/gor.go
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,8 @@ import (
"encoding/base64"
"encoding/json"
"flag"
"github.com/wendal/gor"
//"github.com/wendal/gor"
"gor"
"io/ioutil"
"log"
"net/http"
Expand All @@ -13,7 +14,7 @@ import (
)

const (
VER = "3.6.1"
VER = "3.6.2"
)

var (
Expand Down
5 changes: 3 additions & 2 deletions payload.go
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@ import (
"bytes"
"errors"
"fmt"
"github.com/wendal/mustache"
"io"
"io/ioutil"
"log"
Expand All @@ -16,8 +17,6 @@ import (
"strconv"
"strings"
"time"

"github.com/wendal/mustache"
)

// 构建PayLoad
Expand Down Expand Up @@ -529,13 +528,15 @@ func DecodePathInfo(pathinfo string) string {

// 创建permalink的配置生产路径(不限于Post)
func CreatePostURL(db map[string]interface{}, basePath string, post map[string]interface{}) {

var url string
switch post["permalink"].(type) {
case int64:
url = strconv.FormatInt(post["permalink"].(int64), 10)
default:
url = post["permalink"].(string)
}

if strings.Contains(url, ":") {
year, month, day := post["_date"].(time.Time).Date()
url = strings.Replace(url, ":year", fmt.Sprintf("%v", year), -1)
Expand Down
200 changes: 32 additions & 168 deletions widgets.go
Original file line number Diff line number Diff line change
@@ -1,98 +1,24 @@
package gor

import (
"bytes"
"fmt"
"github.com/wendal/errors"
"github.com/wendal/mustache"
"html/template"
"io/ioutil"
"log"
"os"
"path/filepath"
)

var (
// 默认的挂件
WidgetBuilders = make(map[string]WidgetBuilder)
)

const (
Analytics_google = `
<script type="text/javascript">

var _gaq = _gaq || [];
var pluginUrl = '//www.google-analytics.com/plugins/ga/inpage_linkid.js';
_gaq.push(['_require', 'inpage_linkid', pluginUrl]);
_gaq.push(['_setAccount', '%s']);
_gaq.push(['_trackPageview']);

(function() {
var ga = document.createElement('script'); ga.type = 'text/javascript'; ga.async = true;
ga.src = ('https:' == document.location.protocol ? 'https://ssl' : 'http://www') + '.google-analytics.com/ga.js';
var s = document.getElementsByTagName('script')[0]; s.parentNode.insertBefore(ga, s);
})();

</script>`
Comments_disqus = `
<div id="disqus_thread"></div>
<script>
var disqus_developer = 1;
var disqus_shortname = '%s'; // required: replace example with your forum shortname
/* * * DON'T EDIT BELOW THIS LINE * * */
(function() {
var dsq = document.createElement('script'); dsq.type = 'text/javascript'; dsq.async = true;
dsq.src = 'http://' + disqus_shortname + '.disqus.com/embed.js';
(document.getElementsByTagName('head')[0] || document.getElementsByTagName('body')[0]).appendChild(dsq);
})();
</script>
<noscript>Please enable JavaScript to view the <a href="http://disqus.com/?ref_noscript">comments powered by Disqus.</a></noscript>
<a href="http://disqus.com" class="dsq-brlink">blog comments powered by <span class="logo-disqus">Disqus</span></a>
`
tpl_google_prettify = `
<script src="//cdnjscn.b0.upaiyun.com/libs/prettify/r298/prettify.min.js"></script>
<script>
var pres = document.getElementsByTagName("pre");
for (var i=0; i < pres.length; ++i) {
pres[i].className = "prettyprint %s";
}
prettyPrint();
</script>
`
Comments_duoshuo = `
<!-- Duoshuo Comment BEGIN -->
<div class="ds-thread"></div>
<script type="text/javascript">
var duoshuoQuery = {short_name:"%s"};//require,replace your short_name
(function() {
var ds = document.createElement('script');
ds.type = 'text/javascript';ds.async = true;
ds.src = 'http://static.duoshuo.com/embed.js';
ds.charset = 'UTF-8';
(document.getElementsByTagName('head')[0]
|| document.getElementsByTagName('body')[0]).appendChild(ds);
})();
</script>
<!-- Duoshuo Comment END -->
`
tpl_cnzz = `<script src="http://s25.cnzz.com/stat.php?id=%d&web_id=%d" language="JavaScript"></script>`

tpl_uyan = `
<!-- UY BEGIN -->
<div id="uyan_frame"></div>
<script type="text/javascript" src="http://v2.uyan.cc/code/uyan.js?uid=%d"></script>
<!-- UY END -->
`
)

type WidgetBuilder func(Mapper, mustache.Context) (Widget, error)

type Widget interface {
Prepare(mapper Mapper, ctx mustache.Context) Mapper
}

func init() {
WidgetBuilders["analytics"] = BuildAnalyticsWidget //访问统计
WidgetBuilders["comments"] = BuildCommentsWidget //社会化评论
WidgetBuilders["google_prettify"] = BuildGoogle_prettify // 代码高亮
}

// 遍历目录,加载挂件
Expand Down Expand Up @@ -122,8 +48,15 @@ func LoadWidgets(topCtx mustache.Context) ([]Widget, string, error) {
log.Println("Disable >", cnf_path)
}
}
builderFunc := WidgetBuilders[info.Name()]
if builderFunc == nil { // 看看是否符合自定义挂件的格式

log.Println("path>", path)

widget, err := BuildWidget(path, cnf, topCtx)

//log.Println("BuildWidget widget>", widget)
//log.Println("BuildWidget err>", err)

if err != nil {
_widget, _assets, _err := BuildCustomWidget(info.Name(), path, cnf)
if _err != nil {
log.Println("NO WidgetBuilder >>", cnf_path, _err)
Expand All @@ -138,116 +71,47 @@ func LoadWidgets(topCtx mustache.Context) ([]Widget, string, error) {
}
return nil
}
widget, err := builderFunc(cnf, topCtx)
if err != nil {
return err
}
widgets = append(widgets, widget)
log.Println("Load widget from ", cnf_path)
return nil
})

//log.Println("LoadWidgets widgte > ", widgets)
//log.Println("LoadWidgets assets > ", assets)
return widgets, assets, err
}

//-------------------------------------------------------------------------------------
type AnalyticsWidget Mapper
//批量解析处理函数,解析所有包含 config.yml 文件的 widget 子目录
type MyWidget Mapper

func (self AnalyticsWidget) Prepare(mapper Mapper, topCtx mustache.Context) Mapper {
func (self MyWidget) Prepare(mapper Mapper, topCtx mustache.Context) Mapper {
if mapper["analytics"] != nil && !mapper["analytics"].(bool) {
return nil
}
return Mapper(self)
}

func BuildAnalyticsWidget(cnf Mapper, topCtx mustache.Context) (Widget, error) {
switch cnf.Layout() {
case "google": // 鼎鼎大名的免费,但有点拖慢加载速度,原因你懂的
google := cnf[cnf.Layout()].(map[string]interface{})
tracking_id := google["tracking_id"]
if tracking_id == nil {
return nil, errors.New("AnalyticsWidget Of Google need tracking_id")
}
self := make(AnalyticsWidget)
self["analytics"] = fmt.Sprintf(Analytics_google, tracking_id)
return self, nil
case "cnzz": //免费,而且很快,但强制嵌入一个反向链接,靠!
cnzz := cnf[cnf.Layout()].(map[string]interface{})
tracking_id := cnzz["tracking_id"]
if tracking_id == nil {
return nil, errors.New("AnalyticsWidget Of CNZZ need tracking_id")
}
self := make(AnalyticsWidget)
self["analytics"] = fmt.Sprintf(tpl_cnzz, tracking_id, tracking_id)
return self, nil
}
// 其他的尚不支持, 如果需要,请报个issue吧
return nil, errors.New("AnalyticsWidget Only for Goolge/CNZZ yet")

}
func BuildWidget(path string, cnf Mapper, topCtx mustache.Context) (Widget, error) {
layout := cnf.Layout()
tracking := cnf[layout].(map[string]interface{})

//--------------------------------------------------------------------------------
// 社会化屏幕
type CommentsWidget Mapper
log.Println("BuildWidget >>", path, layout, tracking)

func (self CommentsWidget) Prepare(mapper Mapper, topCtx mustache.Context) Mapper {
if mapper["comments"] != nil && !mapper["comments"].(bool) {
log.Println("Disable comments")
return nil
if tracking == nil {
return nil, errors.New(path + "Widget need config")
}
return Mapper(self)
}

func BuildCommentsWidget(cnf Mapper, topCtx mustache.Context) (Widget, error) {
log.Println("Comments >>", cnf.Layout())
switch cnf.Layout() {
case "disqus":
disqus := cnf[cnf.Layout()].(map[string]interface{})
short_name := disqus["short_name"]
if short_name == nil {
return nil, errors.New("CommentsWidget Of disqus need short_name")
}
self := make(CommentsWidget)
self["comments"] = fmt.Sprintf(Comments_disqus, short_name)
return self, nil
case "uyan" :
uyan := cnf[cnf.Layout()].(map[string]interface{})
uid := uyan["uid"]
self := make(CommentsWidget)
self["comments"] = fmt.Sprintf(tpl_uyan, uid)
return self, nil
case "duoshuo":
duoshuo := cnf[cnf.Layout()].(map[string]interface{})
short_name := duoshuo["short_name"]
if short_name == nil {
return nil, errors.New("CommentsWidget Of duoshuo need short_name")
var doc bytes.Buffer
if tmpl, err := template.ParseFiles(path + "/layouts/" + layout + ".tmpl"); err != nil {
return nil, err
} else {
if err := tmpl.Execute(&doc, tracking); err != nil {
return nil, err
}
self := make(CommentsWidget)
self["comments"] = fmt.Sprintf(Comments_duoshuo, short_name)
return self, nil
}
// 其他的,想不到还有啥,哈哈,需要其他的就报个issue吧
return nil, errors.New("CommentsWidget Only for disqus yet")
}

//-----------------------------------------------
// 代码高亮
type google_prettify Mapper

func (self google_prettify) Prepare(mapper Mapper, topCtx mustache.Context) Mapper {
if mapper["google_prettify"] != nil && !mapper["google_prettify"].(bool) {
return nil
}
return Mapper(self)
}

func BuildGoogle_prettify(cnf Mapper, topCtx mustache.Context) (Widget, error) {
if enable, ok := cnf["linenums"].(bool); ok && enable { //是否显示行号
self := make(google_prettify)
self["google_prettify"] = fmt.Sprintf(tpl_google_prettify, "linenums")
return self, nil
}
self := make(google_prettify)
self["google_prettify"] = fmt.Sprintf(tpl_google_prettify, "")
self := make(MyWidget)
self[path] = doc.String()
return self, nil
}

Expand Down Expand Up @@ -282,7 +146,7 @@ func BuildCustomWidget(name string, dir string, cnf Mapper) (Widget, []string, e
return nil, nil, nil
}

layoutFilePath := dir + "/layouts/" + layoutName.(string) + ".html"
layoutFilePath := dir + "/layouts/" + layoutName.(string) + ".tmpl"
f, err := os.Open(layoutFilePath)
if err != nil {
return nil, nil, errors.New("Fail to load Widget Layout" + dir + "\n" + err.Error())
Expand Down