Read file as template, execute it and write it back
Solution 1
Use ParseFiles to parse the template. This code basically does the same thing as calling ReadFile, template.New and Parse as in the question, but it's shorter.
t, err := template.ParseFiles(path)
if err != nil {
log.Print(err)
return
}
Use os.Create to open the output file.
f, err := os.Create(path)
if err != nil {
log.Println("create file: ", err)
return
}
A file is an io.Writer. You can execute the template directly to the open file:
err = t.Execute(f, config)
if err != nil {
log.Print("execute: ", err)
return
}
Close the file when done.
f.Close()
Complete working example on the playground.
Solution 2
Here is a function I made with Cerise Limón's answer
func createFileUsingTemplate(t *template.Template, filename string, data interface{}) error {
f, err := os.Create(filename)
if err != nil {
return err
}
defer f.Close()
err = t.Execute(f, data)
if err != nil {
return err
}
return nil
}
Related videos on Youtube
user3147268
Updated on September 15, 2021Comments
-
user3147268 over 2 years
I'm trying to parse CSS files in which variables can be injected that are defined in a config file. Currently the function does:
- Opens the file based on the given path argument
- Parses the file's content
- Executes the template by injecting the config variable
- Writes the rendered content to the console instead of the original file
func parse(path string) { f, err := ioutil.ReadFile(path) if err != nil { log.Print(err) return } // Parse requires a string t, err := template.New("css").Parse(string(f)) if err != nil { log.Print(err) return } // A sample config config := map[string]string { "textColor": "#abcdef", "linkColorHover": "#ffaacc", } // Execute needs some sort of io.Writer err = t.Execute(os.Stdout, config) if err != nil { log.Print("Can't execute ", path) } }
My problem is that
template.Parse()
requires the content as string andtemplate.Execute()
anio.Writer
as argument. I tried to open the file withos.Open()
which returns a file object that implements theio.Writer
interface. But how can I get the file's content as a string from such a file object in order to use it withParse()
?-
user3147268 over 8 yearsI try to extend a static side generator. Therefore I need to do this only once.
-
user3147268 over 8 yearsI use
os.Walk("root", filterFunc)
and a filter to find all css files. if the script found one it callsparse()
with the path. So, does it makes sense to callParseFiles()
if I need only to parse a single file? And lastly:os.Create(path)
will overwrite the original file, right? -
Cerise Limón over 8 yearsFor this scenario, you should call ParseFiles with a single file at a time. Caling ParseFiles with a single file saves code as noted in the answer. Yes, this overwrites the original file. If that's not what you are asking in the question, then please clarify.
-
user3147268 over 8 yearsNo, that's exactly what I needed. Thank you very much.
-
Admin about 6 yearsGreat, thanks @CeriseLimón I needed this too. Could you please explain what this is? Never seen this before
map[string]string
-
Cerise Limón about 6 years@Sbe88 It's a map with string keys and string values.