Beispiel #1
0
// Delete a file OR dir. See NewFile for controversy about filenames and extensions.
func DeleteFile(opt map[string]interface{}, inp map[string][]string, root, host string) error {
	if !CanModifyTemplate(opt) {
		return fmt.Errorf(cant_mod_public)
	}
	rule := map[string]interface{}{
		"filepath": "must",
	}
	dat, e_err := extract.New(rule).Extract(inp)
	if e_err != nil {
		return e_err
	}
	fp := dat["filepath"].(string)
	full_p := filepath.Join(root, scut.GetTPath(opt, host), fp)
	var err error
	if IsDir(fp) {
		err = os.RemoveAll(full_p)
	} else {
		err = os.Remove(full_p)
	}
	if err != nil {
		fmt.Println(err)
		return fmt.Errorf("Can't delete file or directory. Probably it does not exist.")
	}
	return nil
}
Beispiel #2
0
// Since we don't include the template name into the url, only "template", we have to extract the template name from the opt here.
// Example: xyz.com/template/style.css
//			xyz.com/tpl/admin/style.css
func serveTemplateFile(w http.ResponseWriter, req *http.Request, uni *context.Uni) {
	if uni.Paths[1] == "template" {
		p := scut.GetTPath(uni.Opt, uni.Req.Host)
		http.ServeFile(w, req, filepath.Join(uni.Root, p, strings.Join(uni.Paths[2:], "/")))
	} else { // "tpl"
		http.ServeFile(w, req, filepath.Join(uni.Root, "modules", uni.Paths[2], "tpl", strings.Join(uni.Paths[3:], "/")))
	}
}
Beispiel #3
0
// New file OR dir. Filenames without extensions became dirs. RETHINK: This way we lose the ability to create files without extensions.
// Only accessed member of opt will be "TplIsPrivate" in scut.GetTPath. TODO: this is ugly.
func NewFile(opt map[string]interface{}, inp map[string][]string, root, host string) error {
	if !CanModifyTemplate(opt) {
		return fmt.Errorf(cant_mod_public)
	}
	rule := map[string]interface{}{
		"filepath": "must",
		"where":    "must",
	}
	dat, e_err := extract.New(rule).Extract(inp)
	if e_err != nil {
		return e_err
	}
	fp := dat["filepath"].(string)
	where := dat["where"].(string)
	if IsDir(fp) {
		return os.Mkdir(filepath.Join(root, scut.GetTPath(opt, host), where, fp), os.ModePerm)
	}
	return ioutil.WriteFile(filepath.Join(root, scut.GetTPath(opt, host), where, fp), []byte(""), os.ModePerm)
}
Beispiel #4
0
// Displays a display point.
func D(uni *context.Uni) {
	points, points_exist := uni.Dat["_points"]
	var point string
	if points_exist {
		point = points.([]string)[0]
	} else {
		p := uni.Req.URL.Path
		if p == "/" {
			point = "index"
		} else {
			point = p
		}
	}
	queries, queries_exists := jsonp.Get(uni.Opt, "Display-points."+point+".queries")
	if queries_exists {
		qmap, ok := queries.(map[string]interface{})
		if ok {
			runQueries(uni, qmap)
		}
	}
	BeforeDisplay(uni)
	// While it is not the cheapest solution to convert bson.ObjectIds to strings here, where we have to iterate trough all values,
	// it is still better than remembering (and forgetting) to convert it at every specific place.
	scut.IdsToStrings(uni.Dat)
	langs, _ := jsonp.Get(uni.Dat, "_user.languages") // _user always has language member
	langs_s := toStringSlice(langs)
	loc, _ := display_model.LoadLocStrings(uni.Dat, langs_s, uni.Root, scut.GetTPath(uni.Opt, uni.Req.Host), nil) // TODO: think about errors here.
	if loc != nil {
		uni.Dat["loc"] = loc
	}
	if _, isjson := uni.Req.Form["json"]; isjson {
		putJSON(uni)
		return
	} else {
		err := DisplayFile(uni, point)
		if err != nil {
			uni.Dat["missing_file"] = point
			err_404 := DisplayFile(uni, "404")
			if err_404 != nil {
				uni.Put("Cant find file: ", point)
			}
		}
	}
}
Beispiel #5
0
// Forks a public template into a private one: creates a deep recursive copy of the whole directory tree, so the user
// can edit his own template files as he wishes.
func ForkPublic(db *mgo.Database, opt map[string]interface{}, root, host string) error {
	if CanModifyTemplate(opt) {
		return fmt.Errorf("Template is already private.")
	}
	from := filepath.Join(root, scut.GetTPath(opt, host))
	to := filepath.Join(root, "templates", "private", host, scut.TemplateName(opt))
	copy_err := copyrecur.CopyDir(from, to)
	if copy_err != nil { // && copy_err.Error() != "Destination already exists"
		return copy_err
	}
	id := basic.CreateOptCopy(db)
	q := m{"_id": id}
	upd := m{
		"$set": m{
			"TplIsPrivate": true,
		},
	}
	return db.C("options").Update(q, upd)
}
Beispiel #6
0
// Loads localization, template functions and executes the template.
func prepareAndExec(uni *context.Uni, file string) {
	root := uni.Root
	host := uni.Req.Host
	dat := uni.Dat
	opt := uni.Opt
	w := uni.W
	langs, has := jsonp.Get(dat, "_user.languages") // _user should always has languages field
	if !has {
		langs = []string{"en"}
	}
	langs_s := toStringSlice(langs)
	if !has {
		langs = []string{"en"}
	}
	loc, _ := display_model.LoadLocTempl(file, langs_s, root, scut.GetTPath(opt, host), nil) // TODO: think about errors here.
	dat["loc"] = merge(dat["loc"], loc)
	funcMap := template.FuncMap(builtins(uni))
	t, _ := template.New("tpl").Funcs(funcMap).Parse(string(file))
	w.Header().Set("Content-Type", "text/html; charset=utf-8")
	t.Execute(w, dat) // TODO: watch for errors in execution.
}
Beispiel #7
0
// Extracts all requires ( {{require example.t}} ) from a given file.
// Takes into account fallback files too.
// First it checks if the file exists in the current template. If yes, the link will point to that file.
// If not, then the link will point to the fallback module file.
// TODO: Case when the required file does not exists anywhere is not handled.
func ReqLinks(opt map[string]interface{}, file, root, host string) []ReqLink {
	pos := require.RequirePositions(file)
	ret := []ReqLink{}
	for _, v := range pos {
		fi := file[v[0]+10 : v[1]-2] // cut {{require anything/anything.t}} => anything/anything.t
		var typ, path, name string
		exists_in_template, err := Exists(filepath.Join(root, scut.GetTPath(opt, host), fi))
		if err != nil {
			continue
		}
		if exists_in_template {
			typ = scut.TemplateType(opt)
			path = fi
			name = scut.TemplateName(opt)
		} else {
			path = scut.GetModTPath(fi)[1]
			typ = "mod"
			name = strings.Split(fi, "/")[0]
		}
		rl := ReqLink{typ, name, path}
		ret = append(ret, rl)
	}
	return ret
}