Skip to content

Commit

Permalink
templates: Add readFile action that does not evaluate templates (#5553
Browse files Browse the repository at this point in the history
)

* Create an includeRaw template function to include a file without parsing it as a template.

Some formatting fixes

* Rename to readFile, various docs adjustments

---------

Co-authored-by: Francis Lavoie <lavofr@gmail.com>
  • Loading branch information
asyncmeow and francislavoie committed May 26, 2023
1 parent 9cde715 commit 31d75ac
Show file tree
Hide file tree
Showing 2 changed files with 49 additions and 8 deletions.
35 changes: 29 additions & 6 deletions modules/caddyhttp/templates/templates.go
Expand Up @@ -88,15 +88,25 @@ func init() {
//
// ##### `httpInclude`
//
// Includes the contents of another file by making a virtual HTTP request (also known as a sub-request). The URI path must exist on the same virtual server because the request does not use sockets; instead, the request is crafted in memory and the handler is invoked directly for increased efficiency.
// Includes the contents of another file, and renders it in-place,
// by making a virtual HTTP request (also known as a sub-request).
// The URI path must exist on the same virtual server because the
// request does not use sockets; instead, the request is crafted in
// memory and the handler is invoked directly for increased efficiency.
//
// ```
// {{httpInclude "/foo/bar?q=val"}}
// ```
//
// ##### `import`
//
// Imports the contents of another file and adds any template definitions to the template stack. If there are no defitions, the filepath will be the defition name. Any {{ define }} blocks will be accessible by {{ template }} or {{ block }}. Imports must happen before the template or block action is called
// Reads and returns the contents of another file, and parses it
// as a template, adding any template definitions to the template
// stack. If there are no definitions, the filepath will be the
// definition name. Any {{ define }} blocks will be accessible by
// {{ template }} or {{ block }}. Imports must happen before the
// template or block action is called. Note that the contents are
// NOT escaped, so you should only import trusted template files.
//
// **filename.html**
// ```
Expand All @@ -113,13 +123,26 @@ func init() {
//
// ##### `include`
//
// Includes the contents of another file and renders in-place. Optionally can pass key-value pairs as arguments to be accessed by the included file.
// Includes the contents of another file, rendering it in-place.
// Optionally can pass key-value pairs as arguments to be accessed
// by the included file. Note that the contents are NOT escaped,
// so you should only include trusted template files.
//
// ```
// {{include "path/to/file.html"}} // no arguments
// {{include "path/to/file.html" "arg1" 2 "value 3"}} // with arguments
// ```
//
// ##### `readFile`
//
// Reads and returns the contents of another file, as-is.
// Note that the contents are NOT escaped, so you should
// only read trusted files.
//
// ```
// {{readFile "path/to/file.html"}}
// ```
//
// ##### `listFiles`
//
// Returns a list of the files in the given directory, which is relative to the template context's file root.
Expand All @@ -130,10 +153,10 @@ func init() {
//
// ##### `markdown`
//
// Renders the given Markdown text as HTML. This uses the
// Renders the given Markdown text as HTML and returns it. This uses the
// [Goldmark](https://github.com/yuin/goldmark) library,
// which is CommonMark compliant. It also has these plugins
// enabled: Github Flavored Markdown, Footnote and syntax
// which is CommonMark compliant. It also has these extensions
// enabled: Github Flavored Markdown, Footnote, and syntax
// highlighting provided by [Chroma](https://github.com/alecthomas/chroma).
//
// ```
Expand Down
22 changes: 20 additions & 2 deletions modules/caddyhttp/templates/tplcontext.go
Expand Up @@ -30,7 +30,7 @@ import (
"time"

"github.com/Masterminds/sprig/v3"
"github.com/alecthomas/chroma/v2/formatters/html"
chromahtml "github.com/alecthomas/chroma/v2/formatters/html"
"github.com/caddyserver/caddy/v2"
"github.com/caddyserver/caddy/v2/modules/caddyhttp"
"github.com/dustin/go-humanize"
Expand Down Expand Up @@ -74,6 +74,7 @@ func (c *TemplateContext) NewTemplate(tplName string) *template.Template {
// add our own library
c.tpl.Funcs(template.FuncMap{
"include": c.funcInclude,
"readFile": c.funcReadFile,
"import": c.funcImport,
"httpInclude": c.funcHTTPInclude,
"stripHTML": c.funcStripHTML,
Expand Down Expand Up @@ -123,6 +124,23 @@ func (c TemplateContext) funcInclude(filename string, args ...any) (string, erro
return bodyBuf.String(), nil
}

// funcReadFile returns the contents of a filename relative to the site root.
// Note that included files are NOT escaped, so you should only include
// trusted files. If it is not trusted, be sure to use escaping functions
// in your template.
func (c TemplateContext) funcReadFile(filename string) (string, error) {
bodyBuf := bufPool.Get().(*bytes.Buffer)
bodyBuf.Reset()
defer bufPool.Put(bodyBuf)

err := c.readFileToBuffer(filename, bodyBuf)
if err != nil {
return "", err
}

return bodyBuf.String(), nil
}

// readFileToBuffer reads a file into a buffer
func (c TemplateContext) readFileToBuffer(filename string, bodyBuf *bytes.Buffer) error {
if c.Root == nil {
Expand Down Expand Up @@ -315,7 +333,7 @@ func (TemplateContext) funcMarkdown(input any) (string, error) {
extension.Footnote,
highlighting.NewHighlighting(
highlighting.WithFormatOptions(
html.WithClasses(true),
chromahtml.WithClasses(true),
),
),
),
Expand Down

0 comments on commit 31d75ac

Please sign in to comment.