dati

A Go library/binary to parse & execute data against template langauges.
git clone git://src.gearsix.net/dati
Log | Files | Refs | Atom | README | LICENSE

commit de35484c3d9e813a4e8107a0971cc693e805b09f
parent 6e7bde7ef5413126cdfda1d14d36bd7a741bb6e6
Author: gearsix <gearsix@tuta.io>
Date:   Sun, 28 Mar 2021 17:48:40 +0100

moved docs/suti.txt -> README; formatting fixes in *.go

Diffstat:
AREADME | 142+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Mdata.go | 34+++++++++++++++++-----------------
Mdata_test.go | 29++++++++++++++---------------
Ddocs/suti.txt | 129-------------------------------------------------------------------------------
Mtemplate.go | 36++++++++++++++++++------------------
Mtemplate_test.go | 26+++++++++++++-------------
6 files changed, 204 insertions(+), 192 deletions(-)

diff --git a/README b/README @@ -0,0 +1,142 @@ +suti +==== + +simple unified templating interface + +USAGE +----- + + suti [OPTIONS] + +DESCRIPTION +----------- + + suti aims to provide a universal interface for executing data files, + written in any data-serialization language, against template files, + written in any templating languages. + Ideally suti will support any language you want to use. + + suti works by using various libraries that do all the hard work to + parse data and template files passed to it. It generates a data + structure of all the passed data files combined (a super-data + structure) and executes that structure against a set of root template + files. + The used libraries are listed below for credit/reference. + + suti can also be imported as a golang package to be used as a library. + +OPTIONS +------- + + - `-r path`, `-root path` = path of template file to execute against. + - `-p path...`, `-partial path...`= path of (multiple) template files that are + called upon by at least one root template. + - If a directory is passed then all files within that directory will + (recursively) be loaded. + - `-gd path...`, `-global-data path...` = path of (multiple) data files to load + as "global data". If a directory is passed then all files within that directory + will (recursively) be loaded. + - `-d path...`, `-data path...` = path of (multiple) data files to load as + "data". If a directory is passed then all files within that directory will + (recursively) be loaded. + - `-dk name`, `-data-key name` = set the name of the key used for the generated + array of data (default: "data") + - `-sd attribute`, `-sort-data attribute` = The file attribute to order data + files by. If no value is provided, the data will be provided in the order it's + loaded. + - Accepted values: "filename", "modified". + - A suffix can be appended to each value to set the sort order: "-asc" (for + ascending), "-desc" (for descending). If not specified, this defaults to + "-asc". + - `-cfg file`, `-config file` = A data file to provide default values for the + above options (see CONFIG). + +CONFIG +------ + + It's possible you'll want to set the same options if you run suti multiple + times for the same project. This can be done by creating a file (written as + a data file) and passing the filepath to the -cfg argument. + + The key names for the options set in the config file must match the name of + the argument option to set (long or short). For example (a config file in + toml): + + root="~/templates/blog.mst" + partial="~/templates/blog/" + gd="./blog.json" + data="./posts/" + dk="posts" + +DATA +---- + + suti generates a single super-structure of all the data files passed to it. + This super-structure is executed against each "root" template. + + The super-structure generated by suti will only have 1 definite key: "data" + (or the value of the "data-key" option). This key will overwrite any "global + data" keys in the root of the super-structure. Its value will be an array, + where each element is the resulting data structure of each parsed "data" + file. + + Parsed "global data" will be written to the root of the super-structure and + into the root of each "data" array object. If a key within one of these + objects conflicts with one of the "global data" keys, then that + "global data" key will not be written to the object. + +TEMPLATES +--------- + + All "root" template files passed to suti that have a file extension matching + one of the supported templating languages will be parsed and executed + against the super-structure generated by suti. + + All "parital" templates will be parsed into any "root" templates that have a + file extension that match the same templating language. + +SUPPORTED LANGUAGES +------------------- + + Below is a list of the supported data-serialisation languages, used for + "data" and "global data" files. + + - JSON (.json), see https://json.org/ + - YAML (.yaml), see https://yamllint.com/ + - TOML (.toml), see https://toml.io/ + + These are the currently supported templating languages, used for files + passed in the "root" and "partial" arguments. + + - mustache (.mu, .mustache), see https://mustache.github.io/ + - golang text/template (.tmpl, .gotmpl), see https://golang.org/pkg/text/template/ + - golang html/template (.hmpl, .gohmpl), see https://golang.org/pkg/html/template/ + - note that this and text/template are almost interchangable, with the + exception that html/template will produce "HTML output safe against code + injection". + - statix (.stx .statix), see https://gist.github.com/plugnburn/c2f7cc3807e8934b179e + +EXAMPLES +-------- + + suti -cfg ./suti.cfg -r templates/textfile.mst + + suti -r homepage.hmpl -p head.hmpl -p body.hmpl -gd meta.json -d posts/* + + see the examples/ directory in the suti repository for a cool example. + +LIBRARIES +--------- + + As stated above, all of these libraries do the hard work, suti just combines + it all together - so thanks to the authors. Also here for reference. + + - The Go standard library is used for parsing JSON, .tmpl/.gotmpl, .hmpl/.gohmpl + - github.com/pelletier/go-toml + - gopkg.in/yaml.v3 + - github.com/cbroglie/mustache + +AUTHORS +------- + + - gearsix <gearsix@tuta.io> diff --git a/data.go b/data.go @@ -1,20 +1,20 @@ package suti /* - Copyright (C) 2021 gearsix <gearsix@tuta.io> +Copyright (C) 2021 gearsix <gearsix@tuta.io> - This program is free software: you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation, either version 3 of the License, or - at your option) any later version. +This program is free software: you can redistribute it and/or modify +it under the terms of the GNU General Public License as published by +the Free Software Foundation, either version 3 of the License, or +at your option) any later version. - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. +This program is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +GNU General Public License for more details. - You should have received a copy of the GNU General Public License - along with this program. If not, see <https://www.gnu.org/licenses/>. +You should have received a copy of the GNU General Public License +along with this program. If not, see <https://www.gnu.org/licenses/>. */ import ( @@ -56,19 +56,19 @@ func loadGlobPaths(paths ...string) ([]string, error) { // LoadData reads all data from `in` and loads it in the format set in `lang`. func LoadData(lang string, in io.Reader) (d Data, e error) { - var fbuf []byte - if fbuf, e = ioutil.ReadAll(in); e != nil { + var inbuf []byte + if inbuf, e = ioutil.ReadAll(in); e != nil { return make(Data), e - } else if len(fbuf) == 0 { + } else if len(inbuf) == 0 { return make(Data), nil } if lang == "json" { - e = json.Unmarshal(fbuf, &d) + e = json.Unmarshal(inbuf, &d) } else if lang == "yaml" { - e = yaml.Unmarshal(fbuf, &d) + e = yaml.Unmarshal(inbuf, &d) } else if lang == "toml" { - e = toml.Unmarshal(fbuf, &d) + e = toml.Unmarshal(inbuf, &d) } else { e = fmt.Errorf("'%s' is not a supported data language", lang) } diff --git a/data_test.go b/data_test.go @@ -1,23 +1,22 @@ package suti /* - Copyright (C) 2021 gearsix <gearsix@tuta.io> +Copyright (C) 2021 gearsix <gearsix@tuta.io> - This program is free software: you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation, either version 3 of the License, or - at your option) any later version. +This program is free software: you can redistribute it and/or modify +it under the terms of the GNU General Public License as published by +the Free Software Foundation, either version 3 of the License, or +at your option) any later version. - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. +This program is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +GNU General Public License for more details. - You should have received a copy of the GNU General Public License - along with this program. If not, see <https://www.gnu.org/licenses/>. +You should have received a copy of the GNU General Public License +along with this program. If not, see <https://www.gnu.org/licenses/>. */ - import ( "encoding/json" "github.com/pelletier/go-toml" @@ -31,9 +30,9 @@ import ( var good = map[string]string{ "json": `{"eg":0}`, "yaml": `eg: 0 -`, + `, "toml": `eg = 0 -`, + `, } const badData = `{"json"!:2:]}}` @@ -178,7 +177,7 @@ func TestGenerateSuperData(t *testing.T) { t.Skip("setup failure:", e) } - sd, e = GenerateSuperData("testdata", gd, d) + sd, e = GenerateSuperData("testdata", gd, d) if e != nil { t.Error(e) } diff --git a/docs/suti.txt b/docs/suti.txt @@ -1,129 +0,0 @@ -NAME - suti - simple unified templating interface - -USAGE - suti [OPTIONS] - -DESCRIPTION - suti aims to provide a universal interface for executing data files, - written in any data-serialization language, against template files, - written in any templating languages. - Ideally suti will support any language you want to use. - - suti works by using various libraries that do all the hard work to - parse data and template files passed to it. It generates a data - structure of all the passed data files combined (a super-data - structure) and executes that structure against a set of root template - files. - The used libraries are listed below for credit/reference. - - suti can also be imported as a golang package to be used as a library. - -OPTIONS - -r path, -root path - path of template file to execute against. - - -p path..., -partial path... - path of (multiple) template files that are called upon by at least one - root template. If a directory is passed then all files within that - directory will (recursively) be loaded. - - -gd path..., -global-data path... - path of (multiple) data files to load as "global data". If a directory is - passed then all files within that directory will (recursively) be loaded. - - -d path..., -data path... - path of (multiple) data files to load as "data". If a directory is passed - then all files within that directory will (recursively) be loaded. - - -dk name, -data-key name - set the name of the key used for the generated array of data (default: - "data") - - -sd attribute, -sort-data attribute - The file attribute to order data files by. If no value is provided, the data - will be provided in the order it's loaded. - Accepted values: "filename", "modified". - A suffix can be appended to each value to set the sort order: "-asc" (for - ascending), "-desc" (for descending). If not specified, this defaults to - "-asc". - - -cfg file, -config file - A data file to provide default values for the above options (see CONFIG). - -CONFIG - It's possible you'll want to set the same options if you run suti multiple - times for the same project. This can be done by creating a file (written as - a data file) and passing the filepath to the -cfg argument. - - The key names for the options set in the config file must match the name of - the argument option to set (long or short). For example (a config file in - toml): - - root="~/templates/blog.mst" - partial="~/templates/blog/" - gd="./blog.json" - data="./posts/" - dk="posts" - -DATA - suti generates a single super-structure of all the data files passed to it. - This super-structure is executed against each "root" template. - - The super-structure generated by suti will only have 1 definite key: "data" - (or the value of the "data-key" option). This key will overwrite any "global - data" keys in the root of the super-structure. Its value will be an array, - where each element is the resulting data structure of each parsed "data" - file. - - Parsed "global data" will be written to the root of the super-structure and - into the root of each "data" array object. If a key within one of these - objects conflicts with one of the "global data" keys, then that - "global data" key will not be written to the object. - -TEMPLATES - All "root" template files passed to suti that have a file extension matching - one of the supported templating languages will be parsed and executed - against the super-structure generated by suti. - - All "parital" templates will be parsed into any "root" templates that have a - file extension that match the same templating language. - -SUPPORTED LANGUAGES - Below is a list of the supported data-serialisation languages, used for - "data" and "global data" files. - - - JSON (.json), see https://json.org/ - - YAML (.yaml), see https://yamllint.com/ - - TOML (.toml), see https://toml.io/ - - These are the currently supported templating languages, used for files - passed in the "root" and "partial" arguments. - - - mustache (.mu, .mustache), see https://mustache.github.io/ - - golang text/template (.tmpl, .gotmpl), see https://golang.org/pkg/text/template/ - - golang html/template (.hmpl, .gohmpl), see https://golang.org/pkg/html/template/ - - note that this and text/template are almost interchangable, with the - exception that html/template will produce "HTML output safe against code - injection". - - statix (.stx .statix), see https://gist.github.com/plugnburn/c2f7cc3807e8934b179e - -EXAMPLES - - suti -cfg ./suti.cfg -r templates/textfile.mst - - suti -r homepage.hmpl -p head.hmpl -p body.hmpl -gd meta.json -d posts/* - - see the examples/ directory in the suti repository for a cool example. - -LIBRARIES - As stated above, all of these libraries do the hard work, suti just combines - it all together - so thanks to the authors. Also here for reference. - - - The Go standard library is used for parsing JSON, .tmpl/.gotmpl, .hmpl/.gohmpl - - github.com/pelletier/go-toml - - gopkg.in/yaml.v3 - - github.com/cbroglie/mustache - -AUTHORS - - gearsix <gearsix@tuta.io> diff --git a/template.go b/template.go @@ -1,26 +1,26 @@ package suti /* - Copyright (C) 2021 gearsix <gearsix@tuta.io> +Copyright (C) 2021 gearsix <gearsix@tuta.io> - This program is free software: you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation, either version 3 of the License, or - at your option) any later version. +This program is free software: you can redistribute it and/or modify +it under the terms of the GNU General Public License as published by +the Free Software Foundation, either version 3 of the License, or +at your option) any later version. - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. +This program is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +GNU General Public License for more details. - You should have received a copy of the GNU General Public License - along with this program. If not, see <https://www.gnu.org/licenses/>. +You should have received a copy of the GNU General Public License +along with this program. If not, see <https://www.gnu.org/licenses/>. */ import ( "bytes" - mst "github.com/cbroglie/mustache" "fmt" + mst "github.com/cbroglie/mustache" hmpl "html/template" "os" "path/filepath" @@ -51,8 +51,8 @@ func loadTemplateFileTmpl(root string, partials ...string) (*tmpl.Template, erro } else if strings.Contains(p, "*") { t, e = t.ParseGlob(p) } else if stat.IsDir() { - t, e = t.ParseGlob(p+"/*.tmpl") - t, e = t.ParseGlob(p+"/*.gotmpl") + t, e = t.ParseGlob(p + "/*.tmpl") + t, e = t.ParseGlob(p + "/*.gotmpl") } else { return nil, fmt.Errorf("non-matching filetype") } @@ -77,8 +77,8 @@ func loadTemplateFileHmpl(root string, partials ...string) (*hmpl.Template, erro } else if strings.Contains(p, "*") { t, e = t.ParseGlob(p) } else if stat.IsDir() { - t, e = t.ParseGlob(p+"/*.hmpl") - t, e = t.ParseGlob(p+"/*.gohmpl") + t, e = t.ParseGlob(p + "/*.hmpl") + t, e = t.ParseGlob(p + "/*.gohmpl") } else { return nil, fmt.Errorf("non-matching filetype") } @@ -141,8 +141,8 @@ func LoadTemplateFile(root string, partials ...string) (t Template, e error) { t, e = loadTemplateFileTmpl(root, partials...) } else if ttype == "hmpl" || ttype == "gohmpl" { t, e = loadTemplateFileHmpl(root, partials...) - } else if ttype == "mst" || ttype == "mustache" { - t, e = loadTemplateFileMst(root, partials...) + } else if ttype == "mst" || ttype == "mustache" { + t, e = loadTemplateFileMst(root, partials...) } else { e = fmt.Errorf("'%s' is not a supported template language", ttype) } diff --git a/template_test.go b/template_test.go @@ -1,20 +1,20 @@ package suti /* - Copyright (C) 2021 gearsix <gearsix@tuta.io> +Copyright (C) 2021 gearsix <gearsix@tuta.io> - This program is free software: you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation, either version 3 of the License, or - at your option) any later version. +This program is free software: you can redistribute it and/or modify +it under the terms of the GNU General Public License as published by +the Free Software Foundation, either version 3 of the License, or +at your option) any later version. - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. +This program is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +GNU General Public License for more details. - You should have received a copy of the GNU General Public License - along with this program. If not, see <https://www.gnu.org/licenses/>. +You should have received a copy of the GNU General Public License +along with this program. If not, see <https://www.gnu.org/licenses/>. */ import ( @@ -52,7 +52,7 @@ func validateTemplateFile(t *testing.T, template Template, root string, partials "mst": "*mustache.Template", "mustache": "*mustache.Template", } - + ttype := getTemplateType(root) if reflect.TypeOf(template).String() != types[ttype] { t.Error("invalid template loaded") @@ -103,7 +103,7 @@ func TestLoadTemplateFile(t *testing.T) { bp = append(bp, tdir+"/badPartial.gohmpl") writeTestFile(t, bp[i], hmplPartialBad) i++ - + gr = append(gr, tdir+"/goodRoot.mustache") writeTestFile(t, gr[i], mstRootGood) gp = append(gp, tdir+"/goodPartial.mst")