github.com/goplus/yap@v0.8.1/internal/htmltempl/template.go (about)

     1  /*
     2   * Copyright (c) 2023 The GoPlus Authors (goplus.org). All rights reserved.
     3   *
     4   * Licensed under the Apache License, Version 2.0 (the "License");
     5   * you may not use this file except in compliance with the License.
     6   * You may obtain a copy of the License at
     7   *
     8   *     http://www.apache.org/licenses/LICENSE-2.0
     9   *
    10   * Unless required by applicable law or agreed to in writing, software
    11   * distributed under the License is distributed on an "AS IS" BASIS,
    12   * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
    13   * See the License for the specific language governing permissions and
    14   * limitations under the License.
    15   */
    16  
    17  package htmltempl
    18  
    19  import (
    20  	"bytes"
    21  	"fmt"
    22  	"html/template"
    23  	"io/fs"
    24  	"log"
    25  	"path"
    26  	"strings"
    27  	_ "unsafe"
    28  
    29  	"github.com/goplus/yap/internal/templ"
    30  )
    31  
    32  // Template is the representation of a parsed template. The *parse.Tree
    33  // field is exported only for use by html/template and should be treated
    34  // as unexported by all other clients.
    35  type Template struct {
    36  	*template.Template
    37  }
    38  
    39  func (p *Template) InitTemplates(fsys fs.FS, delimLeft, delimRight, suffix string) {
    40  	tpl, err := parseFS(fsys, delimLeft, delimRight, suffix)
    41  	if err != nil {
    42  		log.Panicln(err)
    43  	}
    44  	p.Template = tpl
    45  }
    46  
    47  //go:linkname parseFiles html/template.parseFiles
    48  func parseFiles(t *template.Template, readFile func(string) (string, []byte, error), filenames ...string) (*template.Template, error)
    49  
    50  func parseFS(fsys fs.FS, delimLeft, delimRight, suffix string) (*template.Template, error) {
    51  	pattern := "*" + suffix
    52  	filenames, err := fs.Glob(fsys, pattern)
    53  	if err != nil {
    54  		return nil, err
    55  	}
    56  	if len(filenames) == 0 {
    57  		return nil, fmt.Errorf("template: pattern matches no files: %#q", pattern)
    58  	}
    59  	if delimLeft == "" {
    60  		delimLeft = "{{"
    61  	}
    62  	if delimRight == "" {
    63  		delimRight = "}}"
    64  	}
    65  	t := template.New("").Delims(delimLeft, delimRight)
    66  	return parseFiles(t, readFileFS(fsys, delimLeft, delimRight, suffix), filenames...)
    67  }
    68  
    69  func readFileFS(fsys fs.FS, delimLeft, delimRight, suffix string) func(string) (string, []byte, error) {
    70  	return func(file string) (name string, b []byte, err error) {
    71  		name = strings.TrimSuffix(path.Base(file), suffix)
    72  		if b, err = fs.ReadFile(fsys, file); err != nil {
    73  			return
    74  		}
    75  		var buf bytes.Buffer
    76  		if templ.TranslateEx(&buf, string(b), delimLeft, delimRight) {
    77  			b = buf.Bytes()
    78  		}
    79  		return
    80  	}
    81  }