0

I'm a beginner in Go and Echo. I am required to store a html template(email template) , which will also have some details passed as context. So that it can be stored into body column (text in MySQL) and will be triggered later.

if user.Email !=""{
            visitingDetails := H{"user_name"      : user.Fname,
                                 "location"       : location.Name,
                                 "visitor_company": visitor.Company,
                                 "visitor_name"   : visitor.Fname +" "+visitor.Lname,
                                 "visitor_phone"  : visitor.Phone,
                                 "visitor_email"  : visitor.Email,
                                 "visitor_fname"  : visitor.Fname,
                                 "visitor_image"  : visitor.ProfilePicture,
                              }
            subject := visitor.Fname +" has come to visit you at the reception"
            body := c.Render(http.StatusOK,"email/user_notify_email.html",visitingDetails)
            emailJob := models.EmailJob{Recipients: visitor.Email , Subject: subject, Body: body}
            db.Create(&emailJob)
            if db.NewRecord(emailJob){
                fmt.Println("Unable to send email")
            }
        }

The EmailJob

type EmailJob struct {
    Id              int       
    Recipients      string    
    Subject         string   
    Body            string          
    Sent            int        
    Error           string 
}

func (t *Template) Render(w io.Writer, name string, data interface{}, c echo.Context) error {
    return t.templates.ExecuteTemplate(w, name, data)
}

body := c.Render(http.StatusOK,"email/user_notify_email.html",visitingDetails)

this line gives error as it returns an error for render. I am not sure how I will I do it? I hope I made it clear. A little help will be much appreciated.

Jonathan Hall
  • 75,165
  • 16
  • 143
  • 189
arundeepak
  • 564
  • 2
  • 12
  • What's the error ? – Charlie Tumahai Feb 18 '18 at 20:31
  • app/controllers/controllers.go:733:91: cannot use body (type error) as type string in field value ... This is the error I am getting. @CeriseLimón – arundeepak Feb 18 '18 at 20:35
  • You are looking at the wrong line. The error is in the emailJob assignment. What is c? Presumably c.Render returns an error, not the rendered template. – Peter Feb 18 '18 at 20:45
  • C is c echo.Context . And Render func has been mentioned in the details. And yes, I think you're correct, @Peter. It perhaps, executes the template. – arundeepak Feb 18 '18 at 20:49

2 Answers2

1

You are using context.Render method incorrectly.

https://github.com/labstack/echo/blob/master/context.go#L111

// Render renders a template with data and sends a text/html response with status
// code. Renderer must be registered using `Echo.Renderer`.
Render(code int, name string, data interface{}) error

The Render methods renders the template and sends it as a response. This method returns an error value, if something unexpected happens, this error value is a description of it. Otherwise, it is equal to nil. See: https://golang.org/pkg/errors/

In order to use Renderer, you must register it and you can use that registered renderer to get rendered template text and save it in DB.

You can see example renderer in unit tests of Echo framework: https://github.com/labstack/echo/blob/master/context_test.go#L23

Hope this helps.

maksadbek
  • 1,508
  • 2
  • 15
  • 28
  • Hi @maksadbek, thanks for having a look into the problem. I want that template to be returned as a string value. instead I am getting an error value. This is the problem. And render is registered with echo. – arundeepak Feb 18 '18 at 21:04
1

After doing a few things and understanding template in golang. I came up with a solution like this.

t, err := template.ParseFiles("templates/email/user_notify_email.html")
        if err != nil {
            fmt.Println("Error happend")
            fmt.Println(err)
            return c.JSON(http.StatusOK, data)
        }
        buf := new(bytes.Buffer)
        if err = t.Execute(buf, visitingDetails); err != nil {
            fmt.Println(err)
        }
        body := buf.String()

And now this body can be stored. Body has rendered template that I required. Much credit goes to this article https://medium.com/@dhanushgopinath/sending-html-emails-using-templates-in-golang-9e953ca32f3d

arundeepak
  • 564
  • 2
  • 12