Search code examples
filetemplatesgoio

Read file as template, execute it and write it back


I'm trying to parse CSS files in which variables can be injected that are defined in a config file. Currently the function does:

  1. Opens the file based on the given path argument
  2. Parses the file's content
  3. Executes the template by injecting the config variable
  4. 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 and template.Execute() an io.Writer as argument. I tried to open the file with os.Open() which returns a file object that implements the io.Writer interface. But how can I get the file's content as a string from such a file object in order to use it with Parse()?


Solution

  • 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.