Hi K,
Thanks for your response. It looks to me like this would give me both
an HTML template and a text template. In my case, it's an either-or
thing, which is what is so frustrating. If the page is an html page, it
stores an html/template in the map. If it's a csv page, it stores a
text/template in the map (although currently this has to be a different
map). I have to have two sets of functions to interact with those maps
and their templates, where the primary differences are, for example,
whether it calls htmlTemplate.Must() or textTemplate.Must(), or whether
the function accepts as an argument a *htmlTemplate.Template or a
*textTemplate.Template.
I suppose that I could make my own package to wrap the two packages,
let's call it bothTemplates for the purpose of example:
package bothTemplates
import (
text "text/template"
html "html/template"
)
type BothTemplates struct {
isHTML bool
t *text.Template
h *html.Template
}
And then wrap every single one of the functions, or at least the
functions that I use (although that's most of the functions, so for
completeness' sake I really may as well just go ahead and wrap all of
them) to choose whether to use t and text/template or h and
html/template based on the value of isHTML, and to allow me to pass that
bool to the functions which create a new Template. At least then all of
the redundancy would be decently out of sight, and I would only have to
maintain it if the template packages change.
But is that really necessary? Isn't this the purpose of interfaces --
so that you can take two or more types with identical functions and plug
in whichever one you need to use in that case? Are interfaces really,
truly incompatible with chaining? I think that's what this comes down
to -- the text/template and html/template packages are designed for
function chaining, so nearly every function returns a pointer to its own
type.
Thanks,
Renee Jylkka
On 12/31/2018 8:53 PM, K Davidson wrote:
One way to accomplish this may be to use embedding to wrap both
Templates into a new type:
|
packagemain
import(
txt "text/template"
"html/template"
)
// CsvTemplate wraps a html/template.Template and adds a
text/template.Template // field for CSV output.
type CsvTemplatestruct{
template.Template
t txt.Template
}
|
On Monday, December 31, 2018 at 1:51:34 PM UTC-7, Renee Jylkka wrote:
Hello,
The project that I am working on is a web app written on a custom
web server using Go and Go templates. I store all of the
templates in a map[string]Template, where the string is the page
name. When someone visits a page, the server checks whether that
page is in the map, then if so calls a function to fill in a data
structure, then executes the appropriate template, passing it the
data structure. All was rosy until I was asked to create csv
downloads for some of the more complex pages. I cannot use a
html/template.Template for those pages, I have to use a
text/template.Template for those pages, otherwise the character
escaping implemented by html/template creates extra columns in
some of the rows. My immediate thought was that since
text/template.Template and html/template.Template have identical
function lists, I should of course create an interface which would
be implemented by both types. However, I have no idea how to
create an interface to include arguments and return types of that
interface type, such as:
func Must(t *Template, err error) *Template
func (t *Template) Funcs(funcMap FuncMap) *Template
If I try to use *Template, the compiler gives an error that
Template is undefined. If I use my interface name in place of
*Template, the compiler gives the error that neither
text/template.Template nor html/template.Template implements my
interface. Both of these are expected behavior, but of course if
I use text/template.Template or html/template.Template in place of
*Template, only one of the two packages would implement my interface.
Is there a correct way to wrap these two data types (using an
interface or otherwise) so that I can deal with either one in the
same data structures and functions, or am I stuck with a lot of
duplicate code and data structures, with only slight differences
beyond which package I'm using?
Thanks!
Renee Jylkka
--
You received this message because you are subscribed to a topic in the
Google Groups "golang-nuts" group.
To unsubscribe from this topic, visit
https://groups.google.com/d/topic/golang-nuts/4p3-Q4pUJv8/unsubscribe.
To unsubscribe from this group and all its topics, send an email to
golang-nuts+unsubscr...@googlegroups.com
<mailto:golang-nuts+unsubscr...@googlegroups.com>.
For more options, visit https://groups.google.com/d/optout.
--
Renee Jylkka
Ormandy, Inc.
re...@ormandy.com
Please direct all support requests to supp...@ormandysoftware.com
NOTICE: This communication, including attachments, is for the exclusive use of
addressee and may contain proprietary, confidential and/or privileged
information. If the reader of this communication is not the intended
recipient, or an employee or agent responsible for delivering this message to
the intended recipient, you are hereby notified that any dissemination,
distribution or copying of this communication or any attachments is strictly
prohibited. If you are not the intended recipient, please notify the sender
immediately by return e-mail, delete this communication and destroy all copies.
--
You received this message because you are subscribed to the Google Groups
"golang-nuts" group.
To unsubscribe from this group and stop receiving emails from it, send an email
to golang-nuts+unsubscr...@googlegroups.com.
For more options, visit https://groups.google.com/d/optout.