读取文件作为模板,执行它并将结果写回文件。

huangapple go评论92阅读模式
英文:

Read file as template, execute it and write it back

问题

我正在尝试解析CSS文件,其中可以注入在配置文件中定义的变量。目前该函数执行以下操作:

  1. 根据给定的路径参数打开文件。
  2. 解析文件的内容。
  3. 通过注入配置变量来执行模板。
  4. 将渲染后的内容写入控制台,而不是原始文件。
func parse(path string) {
    f, err := ioutil.ReadFile(path)

    if err != nil {
        log.Print(err)
        return
    }

    // Parse需要一个字符串作为参数
    t, err := template.New("css").Parse(string(f))

    if err != nil {
        log.Print(err)
        return
    }

    // 一个示例配置
    config := map[string]string {
        "textColor": "#abcdef",
        "linkColorHover": "#ffaacc",
    }   

    // Execute需要一个io.Writer作为参数
    err = t.Execute(os.Stdout, config)   

    if err != nil {
        log.Print("无法执行 ", path)
    }
}

我的问题是template.Parse()需要字符串作为内容,而template.Execute()需要一个io.Writer作为参数。我尝试使用os.Open()打开文件,它返回一个实现了io.Writer接口的文件对象。但是,我如何从这样的文件对象中获取文件的内容作为字符串,以便与Parse()一起使用呢?

英文:

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

<!-- lang: go -->

func parse(path string) {
	f, err := ioutil.ReadFile(path)

	if err != nil {
		log.Print(err)
		return
	}

	// Parse requires a string
	t, err := template.New(&quot;css&quot;).Parse(string(f))

	if err != nil {
		log.Print(err)
		return
	}

    // A sample config
	config := map[string]string {
		&quot;textColor&quot;: &quot;#abcdef&quot;,
		&quot;linkColorHover&quot;: &quot;#ffaacc&quot;,
	}	

	// Execute needs some sort of io.Writer
	err = t.Execute(os.Stdout, config)	

	if err != nil {
		log.Print(&quot;Can&#39;t execute &quot;, 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()?

答案1

得分: 58

使用ParseFiles来解析模板。这段代码基本上与问题中调用ReadFile、template.New和Parse的方式相同,但更简短。

t, err := template.ParseFiles(path)
if err != nil {
    log.Print(err)
    return
}

使用os.Create来打开输出文件。

f, err := os.Create(path)
if err != nil {
    log.Println("create file: ", err)
    return
}

文件是一个io.Writer。你可以直接将模板执行到打开的文件中:

err = t.Execute(f, config)
if err != nil {
    log.Print("execute: ", err)
    return
}

完成后关闭文件。

f.Close()

在playground上查看完整的工作示例

英文:

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(&quot;create file: &quot;, 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(&quot;execute: &quot;, err)
	return
}

Close the file when done.

f.Close()

Complete working example on the playground.

答案2

得分: 3

这是我根据Cerise Limón的答案编写的一个函数:

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
}
英文:

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
}

huangapple
  • 本文由 发表于 2015年9月14日 00:21:49
  • 转载请务必保留本文链接:https://go.coder-hub.com/32551811.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定