diff --git a/modules/templates/helper.go b/modules/templates/helper.go
index 1f510bda6..2a45f76a7 100644
--- a/modules/templates/helper.go
+++ b/modules/templates/helper.go
@@ -49,7 +49,7 @@ func NewFuncMap() []template.FuncMap {
 			return setting.AppVer
 		},
 		"AppBuiltWith": func() string {
-				return setting.AppBuiltWith
+			return setting.AppBuiltWith
 		},
 		"AppDomain": func() string {
 			return setting.Domain
diff --git a/modules/templates/static.go b/modules/templates/static.go
index 5c9903cde..65b82053f 100644
--- a/modules/templates/static.go
+++ b/modules/templates/static.go
@@ -7,7 +7,10 @@
 package templates
 
 import (
+	"bytes"
+	"fmt"
 	"html/template"
+	"io"
 	"io/ioutil"
 	"path"
 	"strings"
@@ -15,7 +18,6 @@ import (
 	"code.gitea.io/gitea/modules/log"
 	"code.gitea.io/gitea/modules/setting"
 	"github.com/Unknwon/com"
-	"github.com/go-macaron/bindata"
 	"gopkg.in/macaron.v1"
 )
 
@@ -23,22 +25,94 @@ var (
 	templates = template.New("")
 )
 
+type templateFileSystem struct {
+	files []macaron.TemplateFile
+}
+
+func (templates templateFileSystem) ListFiles() []macaron.TemplateFile {
+	return templates.files
+}
+
+func (templates templateFileSystem) Get(name string) (io.Reader, error) {
+	for i := range templates.files {
+		if templates.files[i].Name()+templates.files[i].Ext() == name {
+			return bytes.NewReader(templates.files[i].Data()), nil
+		}
+	}
+
+	return nil, fmt.Errorf("file '%s' not found", name)
+}
+
 // Renderer implements the macaron handler for serving the templates.
 func Renderer() macaron.Handler {
+	fs := templateFileSystem{}
+	fs.files = make([]macaron.TemplateFile, 0, 10)
+
+	for _, assetPath := range AssetNames() {
+		if strings.HasPrefix(assetPath, "mail/") {
+			continue
+		}
+
+		if !strings.HasSuffix(assetPath, ".tmpl") {
+			continue
+		}
+
+		content, err := Asset(assetPath)
+
+		if err != nil {
+			log.Warn("Failed to read embedded %s template. %v", assetPath, err)
+			continue
+		}
+
+		fs.files = append(fs.files, macaron.NewTplFile(
+			strings.TrimSuffix(
+				assetPath,
+				".tmpl",
+			),
+			content,
+			".tmpl",
+		))
+	}
+
+	customDir := path.Join(setting.CustomPath, "templates")
+
+	if com.IsDir(customDir) {
+		files, err := com.StatDir(customDir)
+
+		if err != nil {
+			log.Warn("Failed to read %s templates dir. %v", customDir, err)
+		} else {
+			for _, filePath := range files {
+				if strings.HasPrefix(filePath, "mail/") {
+					continue
+				}
+
+				if !strings.HasSuffix(filePath, ".tmpl") {
+					continue
+				}
+
+				content, err := ioutil.ReadFile(path.Join(customDir, filePath))
+
+				if err != nil {
+					log.Warn("Failed to read custom %s template. %v", filePath, err)
+					continue
+				}
+
+				fs.files = append(fs.files, macaron.NewTplFile(
+					strings.TrimSuffix(
+						filePath,
+						".tmpl",
+					),
+					content,
+					".tmpl",
+				))
+			}
+		}
+	}
+
 	return macaron.Renderer(macaron.RenderOptions{
-		Funcs: NewFuncMap(),
-		AppendDirectories: []string{
-			path.Join(setting.CustomPath, "templates"),
-		},
-		TemplateFileSystem: bindata.Templates(
-			bindata.Options{
-				Asset:      Asset,
-				AssetDir:   AssetDir,
-				AssetInfo:  AssetInfo,
-				AssetNames: AssetNames,
-				Prefix:     "",
-			},
-		),
+		Funcs:              NewFuncMap(),
+		TemplateFileSystem: fs,
 	})
 }