gocart 0.0.1 → 0.0.2
Sign up to get free protection for your applications and to get access to all the features.
- data/LICENSE +0 -0
- data/README.md +0 -0
- data/assets/Gemfile +24 -0
- data/assets/Guardfile +37 -0
- data/assets/Rakefile +5 -0
- data/assets/config.rb +24 -0
- data/assets/spec/javascripts/support/jasmine.yml +86 -0
- data/assets/spec/javascripts/support/jasmine_config.rb +23 -0
- data/assets/spec/javascripts/support/jasmine_runner.rb +32 -0
- data/assets/src/server/http_handler.go +136 -0
- data/assets/src/server/main.go +31 -0
- data/assets/src/server/templates.go +42 -0
- data/assets/src/www/app/coffee/adapters/dummy_data.js.coffee +6 -0
- data/assets/src/www/app/coffee/adapters/reddit.js.coffee +294 -0
- data/assets/src/www/app/coffee/application.js.coffee +23 -0
- data/assets/src/www/app/coffee/controllers/app.js.coffee +69 -0
- data/assets/src/www/app/coffee/controllers/nav.js.coffee +55 -0
- data/assets/src/www/app/coffee/controllers/subreddit_posts.js.coffee +57 -0
- data/assets/src/www/app/coffee/helpers/event_manager.js.coffee +3 -0
- data/assets/src/www/app/coffee/helpers/properties.js.coffee +19 -0
- data/assets/src/www/app/coffee/helpers/storage.js.coffee +14 -0
- data/assets/src/www/app/coffee/libs/3rdparty.js.coffee +7 -0
- data/assets/src/www/app/coffee/libs/deferred.js.coffee +92 -0
- data/assets/src/www/app/coffee/libs/logger.js.coffee +40 -0
- data/assets/src/www/app/coffee/libs/mod_loader.js.coffee +44 -0
- data/assets/src/www/app/coffee/main.js.coffee +42 -0
- data/assets/src/www/app/coffee/models/comment.js.coffee +26 -0
- data/assets/src/www/app/coffee/models/post.js.coffee +27 -0
- data/assets/src/www/app/coffee/models/sub_reddit.js.coffee +18 -0
- data/assets/src/www/app/coffee/widgets/post_detail.js.coffee +2 -0
- data/assets/src/www/app/coffee/widgets/posts.js.coffee +45 -0
- data/assets/src/www/app/coffee/widgets/subreddit_detail.js.coffee +2 -0
- data/assets/src/www/app/coffee/widgets/subreddits.js.coffee +44 -0
- data/assets/src/www/app/images/test.png +0 -0
- data/assets/src/www/app/partials/index.html +92 -0
- data/assets/src/www/app/sass/application.css.scss +136 -0
- data/assets/src/www/app/templates/application.gotmpl +2 -0
- data/assets/src/www/app/templates/base.gotmpl.erb +27 -0
- data/assets/src/www/app/templates/home.gotmpl +9 -0
- data/assets/src/www/spec/coffee/deferred-spec.coffee +202 -0
- data/assets/src/www/spec/coffee/mocks.coffee +137 -0
- data/assets/src/www/spec/coffee/mod_loader-spec.coffee +45 -0
- data/assets/src/www/spec/coffee/properties-spec.coffee +21 -0
- data/assets/src/www/spec/coffee/reddit_adapter-spec.coffee +143 -0
- data/assets/src/www/vendor/css/jq.ui.css +630 -0
- data/assets/src/www/vendor/images/ajax-loader.png +0 -0
- data/assets/src/www/vendor/images/icons-18-black.png +0 -0
- data/assets/src/www/vendor/images/icons-18-white.png +0 -0
- data/assets/src/www/vendor/images/icons-36-black.png +0 -0
- data/assets/src/www/vendor/images/icons-36-white.png +0 -0
- data/assets/src/www/vendor/js/ICanHaz.min.js +10 -0
- data/assets/src/www/vendor/js/jq.mobi.min.js +20 -0
- data/assets/src/www/vendor/js/jq.ui.min.js +90 -0
- data/assets/src/www/vendor/js/jq.web.min.js +58 -0
- data/assets/src/www/vendor/js/phonegap-1.1.0.js +4577 -0
- data/assets/src/www/vendor/js/touch.js +103 -0
- data/assets/tasks/app.rake +34 -0
- data/assets/tasks/jasmine.rake +8 -0
- data/assets/tasks/server.rake +58 -0
- data/assets/tasks/www.rake +163 -0
- data/bin/gocart +25 -0
- data/lib/gocart.rb +5 -6
- data/lib/gocart/base.rb +28 -0
- data/lib/gocart/environment.rb +18 -0
- data/lib/gocart/version.rb +1 -1
- metadata +113 -41
- data/.gitignore +0 -4
- data/Gemfile +0 -4
- data/Rakefile +0 -1
- data/gocarg.go +0 -29
- data/gocart.gemspec +0 -38
data/LICENSE
ADDED
File without changes
|
data/README.md
ADDED
File without changes
|
data/assets/Gemfile
ADDED
@@ -0,0 +1,24 @@
|
|
1
|
+
source 'http://rubygems.org'
|
2
|
+
|
3
|
+
gem 'rack'
|
4
|
+
|
5
|
+
group :development do
|
6
|
+
gem 'sass'
|
7
|
+
gem 'coffee-script'
|
8
|
+
gem 'therubyracer'
|
9
|
+
gem 'sprockets'
|
10
|
+
gem 'guard'
|
11
|
+
gem 'guard-coffeescript'
|
12
|
+
gem 'guard-jasmine'
|
13
|
+
gem 'guard-sass'
|
14
|
+
gem 'guard-rake'
|
15
|
+
gem 'guard-livereload'
|
16
|
+
gem 'guard-shell'
|
17
|
+
gem 'jasmine'
|
18
|
+
gem 'yui-compressor'
|
19
|
+
gem 'uglifier'
|
20
|
+
|
21
|
+
gem 'rb-inotify', :require => false
|
22
|
+
gem 'rb-fsevent', :require => false
|
23
|
+
gem 'rb-fchange', :require => false
|
24
|
+
end
|
data/assets/Guardfile
ADDED
@@ -0,0 +1,37 @@
|
|
1
|
+
# More info at https://github.com/guard/guard#readme
|
2
|
+
|
3
|
+
load File.dirname(__FILE__) + '/config.rb'
|
4
|
+
|
5
|
+
guard 'coffeescript', :input => 'src/www/spec/coffee', :output => 'spec/javascripts', :hide_success => true
|
6
|
+
|
7
|
+
guard 'shell' do
|
8
|
+
watch(%r{^src/server/.+\.go$}) do
|
9
|
+
`GOPATH="#{ROOT}" go install #{GO_APP_NAME} 1>&2`
|
10
|
+
end
|
11
|
+
end
|
12
|
+
|
13
|
+
guard 'rake', :task => 'app:www:compile' do
|
14
|
+
watch(%r{^src/www/app/coffee/.+$})
|
15
|
+
watch(%r{^src/www/app/sass/.+$})
|
16
|
+
end
|
17
|
+
|
18
|
+
guard 'rake', :task => 'app:www:compile_templates' do
|
19
|
+
watch(%r{^src/www/app/templates/.+$})
|
20
|
+
end
|
21
|
+
|
22
|
+
guard 'rake', :task => 'app:www:vendor' do
|
23
|
+
watch(%r{^src/www/vendor/.+$})
|
24
|
+
end
|
25
|
+
|
26
|
+
guard 'rake', :task => 'app:www:images' do
|
27
|
+
watch(%r{^src/www/app/images/.+$})
|
28
|
+
end
|
29
|
+
|
30
|
+
guard 'rake', :task => 'app:www:partials' do
|
31
|
+
watch(%r{^src/www/app/partials/.+$})
|
32
|
+
end
|
33
|
+
|
34
|
+
guard 'livereload', :apply_js_live => false do
|
35
|
+
watch(%r{bin/assets/www/javascripts/.+$})
|
36
|
+
watch(%r{spec/javascripts/.+$})
|
37
|
+
end
|
data/assets/Rakefile
ADDED
data/assets/config.rb
ADDED
@@ -0,0 +1,24 @@
|
|
1
|
+
require 'rubygems'
|
2
|
+
require 'bundler'
|
3
|
+
|
4
|
+
Bundler.require
|
5
|
+
|
6
|
+
if !defined? ROOT
|
7
|
+
ROOT = Pathname(File.dirname(__FILE__))
|
8
|
+
|
9
|
+
ASSET_BUNDLES = %w( application.css application.js )
|
10
|
+
GO_APP_NAME = 'server'
|
11
|
+
GO_BUILD_PATH = ROOT.join('bin')
|
12
|
+
|
13
|
+
ASSETS_PATH = ROOT.join('bin', 'assets')
|
14
|
+
TMPL_BUILD_PATH = ASSETS_PATH.join('templates')
|
15
|
+
MIN_WWW_PATH = ASSETS_PATH.join('www-min')
|
16
|
+
DEBUG_WWW_PATH = ASSETS_PATH.join('www-debug')
|
17
|
+
|
18
|
+
WWW_SPEC_PATH = ROOT.join('spec', 'javascripts')
|
19
|
+
|
20
|
+
WWW_SRC_ROOT_PATH = ROOT.join('src', 'www')
|
21
|
+
WWW_SRC_APP_PATH = WWW_SRC_ROOT_PATH.join('app')
|
22
|
+
WWW_SRC_VENDOR_PATH = WWW_SRC_ROOT_PATH.join('vendor')
|
23
|
+
WWW_SRC_SPEC_PATH = WWW_SRC_ROOT_PATH.join('spec')
|
24
|
+
end
|
@@ -0,0 +1,86 @@
|
|
1
|
+
# src_files
|
2
|
+
#
|
3
|
+
# Return an array of filepaths relative to src_dir to include before jasmine specs.
|
4
|
+
# Default: []
|
5
|
+
#
|
6
|
+
# EXAMPLE:
|
7
|
+
#
|
8
|
+
# src_files:
|
9
|
+
# - lib/source1.js
|
10
|
+
# - lib/source2.js
|
11
|
+
# - dist/**/*.js
|
12
|
+
#
|
13
|
+
src_files:
|
14
|
+
- js/vendor/jquery-1.6.4.min
|
15
|
+
- js/vendor/ICanHaz.min.js
|
16
|
+
- js/vendor/phonegap-1.1.0.js
|
17
|
+
- js/vendor/iscroll-min.js
|
18
|
+
- js/libs/mod_loader.js
|
19
|
+
- js/libs/deferred.js
|
20
|
+
- js/libs/3rdparty.js
|
21
|
+
- js/libs/logger.js
|
22
|
+
- js/helpers/**/*.js
|
23
|
+
- js/models/**/*.js
|
24
|
+
- js/adapters/**/*.js
|
25
|
+
- js/services/**/*.js
|
26
|
+
- js/controllers/**/*.js
|
27
|
+
|
28
|
+
# stylesheets
|
29
|
+
#
|
30
|
+
# Return an array of stylesheet filepaths relative to src_dir to include before jasmine specs.
|
31
|
+
# Default: []
|
32
|
+
#
|
33
|
+
# EXAMPLE:
|
34
|
+
#
|
35
|
+
# stylesheets:
|
36
|
+
# - css/style.css
|
37
|
+
# - stylesheets/*.css
|
38
|
+
#
|
39
|
+
stylesheets:
|
40
|
+
|
41
|
+
# helpers
|
42
|
+
#
|
43
|
+
# Return an array of filepaths relative to spec_dir to include before jasmine specs.
|
44
|
+
# Default: ["helpers/**/*.js"]
|
45
|
+
#
|
46
|
+
# EXAMPLE:
|
47
|
+
#
|
48
|
+
# helpers:
|
49
|
+
# - helpers/**/*.js
|
50
|
+
#
|
51
|
+
helpers:
|
52
|
+
- mocks.js
|
53
|
+
|
54
|
+
# spec_files
|
55
|
+
#
|
56
|
+
# Return an array of filepaths relative to spec_dir to include.
|
57
|
+
# Default: ["**/*[sS]pec.js"]
|
58
|
+
#
|
59
|
+
# EXAMPLE:
|
60
|
+
#
|
61
|
+
# spec_files:
|
62
|
+
# - **/*[sS]pec.js
|
63
|
+
#
|
64
|
+
spec_files:
|
65
|
+
|
66
|
+
# src_dir
|
67
|
+
#
|
68
|
+
# Source directory path. Your src_files must be returned relative to this path. Will use root if left blank.
|
69
|
+
# Default: project root
|
70
|
+
#
|
71
|
+
# EXAMPLE:
|
72
|
+
#
|
73
|
+
# src_dir: public
|
74
|
+
#
|
75
|
+
src_dir: bin/assets/www-debug
|
76
|
+
|
77
|
+
# spec_dir
|
78
|
+
#
|
79
|
+
# Spec directory path. Your spec_files must be returned relative to this path.
|
80
|
+
# Default: spec/javascripts
|
81
|
+
#
|
82
|
+
# EXAMPLE:
|
83
|
+
#
|
84
|
+
# spec_dir: spec/javascripts
|
85
|
+
#
|
86
|
+
spec_dir: spec/javascripts
|
@@ -0,0 +1,23 @@
|
|
1
|
+
module Jasmine
|
2
|
+
class Config
|
3
|
+
|
4
|
+
# Add your overrides or custom config code here
|
5
|
+
|
6
|
+
end
|
7
|
+
end
|
8
|
+
|
9
|
+
|
10
|
+
# Note - this is necessary for rspec2, which has removed the backtrace
|
11
|
+
module Jasmine
|
12
|
+
class SpecBuilder
|
13
|
+
def declare_spec(parent, spec)
|
14
|
+
me = self
|
15
|
+
example_name = spec["name"]
|
16
|
+
@spec_ids << spec["id"]
|
17
|
+
backtrace = @example_locations[parent.description + " " + example_name]
|
18
|
+
parent.it example_name, {} do
|
19
|
+
me.report_spec(spec["id"])
|
20
|
+
end
|
21
|
+
end
|
22
|
+
end
|
23
|
+
end
|
@@ -0,0 +1,32 @@
|
|
1
|
+
$:.unshift(ENV['JASMINE_GEM_PATH']) if ENV['JASMINE_GEM_PATH'] # for gem testing purposes
|
2
|
+
|
3
|
+
require 'rubygems'
|
4
|
+
require 'jasmine'
|
5
|
+
jasmine_config_overrides = File.expand_path(File.join(File.dirname(__FILE__), 'jasmine_config.rb'))
|
6
|
+
require jasmine_config_overrides if File.exist?(jasmine_config_overrides)
|
7
|
+
if Jasmine::Dependencies.rspec2?
|
8
|
+
require 'rspec'
|
9
|
+
else
|
10
|
+
require 'spec'
|
11
|
+
end
|
12
|
+
|
13
|
+
jasmine_config = Jasmine::Config.new
|
14
|
+
spec_builder = Jasmine::SpecBuilder.new(jasmine_config)
|
15
|
+
|
16
|
+
should_stop = false
|
17
|
+
|
18
|
+
if Jasmine::Dependencies.rspec2?
|
19
|
+
RSpec.configuration.after(:suite) do
|
20
|
+
spec_builder.stop if should_stop
|
21
|
+
end
|
22
|
+
else
|
23
|
+
Spec::Runner.configure do |config|
|
24
|
+
config.after(:suite) do
|
25
|
+
spec_builder.stop if should_stop
|
26
|
+
end
|
27
|
+
end
|
28
|
+
end
|
29
|
+
|
30
|
+
spec_builder.start
|
31
|
+
should_stop = true
|
32
|
+
spec_builder.declare_suites
|
@@ -0,0 +1,136 @@
|
|
1
|
+
package main
|
2
|
+
|
3
|
+
import (
|
4
|
+
"fmt"
|
5
|
+
"log"
|
6
|
+
"net/http"
|
7
|
+
"os"
|
8
|
+
"regexp"
|
9
|
+
"strings"
|
10
|
+
)
|
11
|
+
|
12
|
+
// HTTP Error Enumerables
|
13
|
+
type HttpError struct {
|
14
|
+
ErrorString string
|
15
|
+
CodeNum int
|
16
|
+
}
|
17
|
+
|
18
|
+
func (h HttpError) Error() string { return h.ErrorString }
|
19
|
+
func (h HttpError) Code() int { return h.CodeNum }
|
20
|
+
func (h HttpError) Report(w http.ResponseWriter) { http.Error(w, h.ErrorString, h.CodeNum) }
|
21
|
+
|
22
|
+
var (
|
23
|
+
ErrHttpResourceNotFound = &HttpError{ErrorString: "Not found", CodeNum: 404}
|
24
|
+
ErrHttpMethodNotAllowed = &HttpError{ErrorString: "Method not allowed", CodeNum: 405}
|
25
|
+
ErrHttpBadRequeset = &HttpError{ErrorString: "Bad request", CodeNum: 400}
|
26
|
+
ErrHttpInternalError = &HttpError{ErrorString: "Internal failure", CodeNum: 500}
|
27
|
+
)
|
28
|
+
|
29
|
+
type HttpHandler struct {
|
30
|
+
RootURLPath string
|
31
|
+
TmplPath string
|
32
|
+
WwwPath string
|
33
|
+
Addr string
|
34
|
+
Port uint
|
35
|
+
Debug bool
|
36
|
+
ServStatic bool
|
37
|
+
templates *Templates
|
38
|
+
rootURLPathLen int
|
39
|
+
wwwURLPathLen int
|
40
|
+
}
|
41
|
+
|
42
|
+
// Load all the temmplates into memeory
|
43
|
+
func (h *HttpHandler) loadTemplates() {
|
44
|
+
h.templates = &Templates{}
|
45
|
+
h.templates.LoadTemplates(h.TmplPath)
|
46
|
+
}
|
47
|
+
|
48
|
+
// Configures the http connection and starts the listender
|
49
|
+
func (h *HttpHandler) HandleHttpConnection() {
|
50
|
+
h.rootURLPathLen = len(h.RootURLPath + "/")
|
51
|
+
h.wwwURLPathLen = len(h.RootURLPath + "/assets/")
|
52
|
+
|
53
|
+
h.loadTemplates()
|
54
|
+
|
55
|
+
h.initServeHomeHndlr(h.RootURLPath + "/")
|
56
|
+
if h.Debug || h.ServStatic {
|
57
|
+
h.initServeStaticHndlr(h.RootURLPath + "/assets/")
|
58
|
+
}
|
59
|
+
|
60
|
+
// Build the address with port if it's provided
|
61
|
+
address := h.Addr
|
62
|
+
if h.Port != 0 {
|
63
|
+
address = fmt.Sprintf("%s:%d", h.Addr, h.Port)
|
64
|
+
}
|
65
|
+
|
66
|
+
err := http.ListenAndServe(address, nil)
|
67
|
+
if err != nil {
|
68
|
+
log.Fatal("ListenAndServe: ", err)
|
69
|
+
}
|
70
|
+
}
|
71
|
+
|
72
|
+
// Network event handler for HTTP trafic. Serves up the
|
73
|
+
// home.html file which will allow connection to the websocket
|
74
|
+
func (h *HttpHandler) initServeHomeHndlr(path string) {
|
75
|
+
regProps := &CommonProps{
|
76
|
+
Title: "Go + WWW + Rake test app",
|
77
|
+
Debug: h.Debug,
|
78
|
+
RootURL: h.RootURLPath,
|
79
|
+
Host: "",
|
80
|
+
}
|
81
|
+
|
82
|
+
hostPortRep := regexp.MustCompile(":\\d+$")
|
83
|
+
|
84
|
+
http.HandleFunc(path, func(w http.ResponseWriter, r *http.Request) {
|
85
|
+
if r.URL.Path != h.RootURLPath+"/" {
|
86
|
+
ErrHttpResourceNotFound.Report(w)
|
87
|
+
return
|
88
|
+
}
|
89
|
+
if r.Method != "GET" {
|
90
|
+
ErrHttpMethodNotAllowed.Report(w)
|
91
|
+
return
|
92
|
+
}
|
93
|
+
w.Header().Set("Content-Type", "text/html; charset=utf-8")
|
94
|
+
|
95
|
+
// Normalalize http host
|
96
|
+
if len(regProps.Host) == 0 {
|
97
|
+
regProps.Host = r.Host
|
98
|
+
if (h.Debug || h.ServStatic) && h.Port != 0 {
|
99
|
+
if strings.Contains(r.Host, ":") {
|
100
|
+
regProps.Host = hostPortRep.ReplaceAllString(r.Host, fmt.Sprintf(":%d", h.Port))
|
101
|
+
} else {
|
102
|
+
regProps.Host = fmt.Sprintf("%s:%d", r.Host, h.Port)
|
103
|
+
}
|
104
|
+
}
|
105
|
+
}
|
106
|
+
|
107
|
+
b, err := h.templates.Render("home", regProps, nil)
|
108
|
+
if err != nil {
|
109
|
+
log.Println("Failed to render template, home")
|
110
|
+
return
|
111
|
+
}
|
112
|
+
|
113
|
+
w.Write(b)
|
114
|
+
})
|
115
|
+
}
|
116
|
+
|
117
|
+
// Simple handler for serving static files
|
118
|
+
func (h *HttpHandler) initServeStaticHndlr(path string) {
|
119
|
+
http.HandleFunc(path, func(w http.ResponseWriter, r *http.Request) {
|
120
|
+
asset := r.URL.Path[h.wwwURLPathLen:]
|
121
|
+
fullAssetPath := h.WwwPath + "/" + asset
|
122
|
+
log.Println(fullAssetPath)
|
123
|
+
|
124
|
+
file, err := os.Open(fullAssetPath)
|
125
|
+
if err != nil {
|
126
|
+
ErrHttpResourceNotFound.Report(w)
|
127
|
+
return
|
128
|
+
}
|
129
|
+
stat, err := file.Stat()
|
130
|
+
if err != nil {
|
131
|
+
ErrHttpInternalError.Report(w)
|
132
|
+
return
|
133
|
+
}
|
134
|
+
http.ServeContent(w, r, asset, stat.ModTime(), file)
|
135
|
+
})
|
136
|
+
}
|
@@ -0,0 +1,31 @@
|
|
1
|
+
package main
|
2
|
+
|
3
|
+
import (
|
4
|
+
"flag"
|
5
|
+
"log"
|
6
|
+
)
|
7
|
+
|
8
|
+
var addr = flag.String("addr", "", "IP address the server is to run on")
|
9
|
+
var port = flag.Uint("port", 0, "Port address to run the server on")
|
10
|
+
var rootURLPath = flag.String("root", "", "URL Path root of the webapp")
|
11
|
+
var tmplPath = flag.String("tmpl", "assets/templates", "Specifies the directory to use for template assets.")
|
12
|
+
var wwwPath = flag.String("www", "assets/www-debug", "Specifies the directory to use for web assest.")
|
13
|
+
var debug = flag.Bool("debug", false, "Enable debug mode where extra loging is produce, each request will reload templates, and all assets are served from non-concaticated files.")
|
14
|
+
var static = flag.Bool("static", false, "Enables serving up static content from disk")
|
15
|
+
|
16
|
+
func main() {
|
17
|
+
flag.Parse()
|
18
|
+
|
19
|
+
httpHndlr := &HttpHandler{
|
20
|
+
Addr: *addr,
|
21
|
+
Port: *port,
|
22
|
+
RootURLPath: *rootURLPath,
|
23
|
+
TmplPath: *tmplPath,
|
24
|
+
WwwPath: *wwwPath,
|
25
|
+
Debug: *debug,
|
26
|
+
ServStatic: *static,
|
27
|
+
}
|
28
|
+
|
29
|
+
httpHndlr.HandleHttpConnection()
|
30
|
+
log.Println("")
|
31
|
+
}
|
@@ -0,0 +1,42 @@
|
|
1
|
+
package main
|
2
|
+
|
3
|
+
import (
|
4
|
+
"bytes"
|
5
|
+
"html/template"
|
6
|
+
"log"
|
7
|
+
)
|
8
|
+
|
9
|
+
type Templates struct {
|
10
|
+
tmpls *template.Template
|
11
|
+
}
|
12
|
+
|
13
|
+
// Object defining what all template data will use
|
14
|
+
type TmplProps struct {
|
15
|
+
Common *CommonProps
|
16
|
+
Contents interface{}
|
17
|
+
}
|
18
|
+
|
19
|
+
// Generic properties shared by all templates
|
20
|
+
type CommonProps struct {
|
21
|
+
Title string
|
22
|
+
Debug bool
|
23
|
+
RootURL string
|
24
|
+
Host string
|
25
|
+
}
|
26
|
+
|
27
|
+
// Loads the templates from disk and returns them loaded
|
28
|
+
// into memory.
|
29
|
+
func (t *Templates) LoadTemplates(path string) {
|
30
|
+
t.tmpls = template.Must(template.ParseGlob(path + "/*.gotmpl"))
|
31
|
+
}
|
32
|
+
|
33
|
+
// Renders a template and returns the byte array for it
|
34
|
+
func (t *Templates) Render(tmplName string, common *CommonProps, contents interface{}) ([]byte, error) {
|
35
|
+
buf := bytes.NewBuffer(nil)
|
36
|
+
err := t.tmpls.ExecuteTemplate(buf, tmplName, &TmplProps{Common: common, Contents: contents})
|
37
|
+
if err != nil {
|
38
|
+
log.Println("Error: failed to execute template", tmplName, ", because", err)
|
39
|
+
}
|
40
|
+
|
41
|
+
return buf.Bytes(), err
|
42
|
+
}
|