New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
proposal: html/template: building pages dynamically with one function call #65924
Comments
Can you outline what API changes you are suggesting in the html/template package? Thanks. |
please also show examples of before/after code |
Thanks for suggesting improvements! 🙂 |
So why not something like: var f []string
fs.WalkDir(os.DirFS("template"), func(p string, d fs.DirEntry, err error) error {
if strings.HasSuffix(p, ".html") {
f = append(f, p)
}
return nil
})
template.ParseFiles(f...) or using template.Glob (and less directories everywhere). |
@seankhliao |
CC @robpike |
Not sure it's worth adding, but if it is, it would go into text/template first. |
@robpike I agree, after more study, that it should first go into text/template. |
BTW, example tmpl, err := template.ParseFiles(
"template/base.html",
"template/common/footer.html",
"template/common/nav/index.html",
"template/common/nav/search.html",
"template/page/index.html",
"template/page/content/thing/index.html",
...list of files grows without an end in sight
) does not work as expected as ParseFiles uses file basename as template name: log.Printf("Template: %v", t.DefinedTemplates()) prints
(note single index.html) |
@AlexanderYastrebov <!-- file path: "template/page/index.html" -->
{{define "template/page/index.html"}}
<div><h1>Page!</h1></div>
{{end}} Regardless, the main idea still stands. The heart of what I'm getting at is, though it is straightforward to parse and execute files even when one has many to deal with, adding a quality-of-life function for handling many templates within nested directories will increase consistency between code bases, thereby increasing the reliability of the community's code. |
helm offers a similar capability using their custom functions
As helm has a well defined root directory for execution, this works, but the feature in this proposal doesn't make it clear why the paths are named relative to some arbitrary root not corresponding to the template location. I think adding this feature makes template development more confusing. |
Great, I would like to have this feature. |
Enhancing
html/template
for Dynamic Template CompositionProposal Details:
The Go programming language has become a favored choice for building robust web services, thanks in part to its efficiency and simplicity. However, when it comes to rendering web pages with the
html/template
package, developers often face the challenge of managing multiple template files. The current process requires parsing each template file individually before execution, leading to redundant code and decreased maintainability, especially in projects with extensive use of templates.Objective:
To address this, I propose the introduction of a new feature within the
html/template
package to enable dynamic and automated parsing of sub-templates directly from a base template. This feature aims to reduce boilerplate code, enhance code cleanliness, and streamline the development process.Feature Description:
Automated Sub-Template Parsing: Allow a base template to automatically include and parse all associated sub-templates without explicitly listing each file. This mechanism would dynamically identify and load sub-templates referenced within the base template, simplifying the template rendering process.
New Functionality, No Breaking Changes: This feature would be introduced as an additional function within the
html/template
package, ensuring backward compatibility and no disruption to existing codebases. It would offer developers the choice between the traditional method and this new, more streamlined approach.Benefits for RESTful Web Services: As Go continues to gain popularity for developing RESTful web services that adhere to the principles of Roy Fielding and HATEOS, standardizing template management could significantly benefit developers. A common, efficient method for handling template parsing would encourage cleaner code, reduce the likelihood of custom, error-prone solutions, and promote best practices within the Go community.
Proposed API Changes
Introduction of a New Function for Dynamic Template Loading
Function Name:
ParseBaseTemplate
Signature:
func ParseBaseTemplate(filePath string) (*Template, error)
This function initializes and returns a new template based on the base template file specified by
filePath
. It scans the base template for references to sub-templates and automatically loads these sub-templates into the template object. The function is designed to streamline the process of working with complex templates by eliminating the need to manually parse each file.Enhancement to Template Delimiters for Sub-Template Inclusion
The function will parse the base template to identify references to sub-templates. This could leverage existing template actions (e.g., {{template "name"}}) or a predefined pattern to denote template inclusion, ensuring the function can accurately discover and load all necessary sub-templates.
Dynamic Sub-Template Loading:
Upon identifying a sub-template reference, the function will resolve the file path (relative to the base template or a predefined template directory) and parse the sub-template. This process repeats recursively for any sub-templates referenced within other sub-templates, ensuring a comprehensive template hierarchy is constructed.
Error Handling and Reporting Enhancements
With the introduction of dynamic sub-template loading, enhanced error handling and reporting mechanisms are necessary to ensure developers can easily debug issues related to template parsing. This includes clear error messages for missing sub-templates, circular references, or parsing errors within dynamically included templates.
Example Usage
Here's a hypothetical example demonstrating how a developer might use the new
ParseBaseTemplate
function:In this example, the developer only needs to call
ParseBaseTemplate
once to load the base template along with all its sub-templates, based on the references within the base template. This significantly reduces boilerplate code and simplifies the template management process.Before & After
Before:
After:
Rationale:
The motivation behind this proposal is to address a growing need within the Go ecosystem for more efficient template management. As web applications become more complex and the use of templates increases, the ability to dynamically manage these templates becomes crucial. By providing a standard solution within the standard library, we can enhance developer productivity, ensure code quality, and foster innovation in Go-based web services.
Conclusion:
Introducing dynamic template composition into the
html/template
package represents a significant step forward in improving the developer experience and code quality for Go-based web applications. By reducing redundancy and streamlining the template handling process, we can unlock new possibilities for web development in Go, aligning with the language's philosophy of simplicity and efficiency.The text was updated successfully, but these errors were encountered: