Library
Basic Usage
If you look through the Core library, you’ll see packages that provide different functionality. These packages are designed to be shared and used through the application. Since Blueprint is a web application, some of the packages must be thread-safe to ensure they won’t throw any errors if they are accessed at the same time by two separate threads.
As you create your own packages, you can store them in the blueprint/lib folder to keep them organized and separate.
It’s a good idea to keep them light on dependencies so you can reuse them again in later projects. Packages that are too tightly-coupled require time to rework so you might as well do it right from the start.
Let’s take a look at the email package in sections. The first of the three sections is the package declaration and import section. Notice how the only packages the email package uses are part of the standard library. This is a good indicator that the package could be moved to a different project without rewriting.
// Package email provides email sending via SMTP.
package email
import (
"encoding/base64"
"fmt"
"net/smtp"
)
The Info struct holds the details for the SMTP server and it should be added to the Info struct of the lib/env package and then parsed from the env.json file. See the Configuration section for more information about adding to env.json.
// Info holds the details for the SMTP server.
type Info struct {
Username string
Password string
Hostname string
Port int
From string
}
The final section of the email package sends an email using the configuration settings. You’ll notice the function is a struct method which makes it really easy to use from the flight package.
// Send an email.
func (c Info) Send(to, subject, body string) error {
auth := smtp.PlainAuth("", c.Username, c.Password, c.Hostname)
// Create the header
header := make(map[string]string)
header["From"] = c.From
header["To"] = to
header["Subject"] = subject
header["MIME-Version"] = "1.0"
header["Content-Type"] = `text/plain; charset="utf-8"`
header["Content-Transfer-Encoding"] = "base64"
// Set the message
message := ""
for k, v := range header {
message += fmt.Sprintf("%s: %s\r\n", k, v)
}
message += "\r\n" + base64.StdEncoding.EncodeToString([]byte(body))
// Send the email
err := smtp.SendMail(
fmt.Sprintf("%s:%d", c.Hostname, c.Port),
auth,
c.From,
[]string{to},
[]byte(message),
)
return err
}
To use in a controller, you would get the context from the flight package
and then from the Config variable, you could access the email struct and then
the Send()
function.
// Index sends an email.
func Index(w http.ResponseWriter, r *http.Request) {
c := flight.Context(w, r)
err := c.Config.Email.Send("This is the subject", "This is the body!")
if err != nil {
c.FlashError(err)
return
}
}
Code Generation
A new lib package can be generated using this command: jay generate lib/default package:value