Skip to content

Commit

Permalink
Merge pull request #2 from gochore/dev
Browse files Browse the repository at this point in the history
support theme
  • Loading branch information
wolfogre authored Apr 7, 2020
2 parents 5455592 + fb7c685 commit 86d077e
Show file tree
Hide file tree
Showing 11 changed files with 487 additions and 115 deletions.
40 changes: 0 additions & 40 deletions attribute.go

This file was deleted.

17 changes: 11 additions & 6 deletions element.go
Original file line number Diff line number Diff line change
@@ -1,31 +1,36 @@
package emailt

import (
"bytes"
"fmt"
"html/template"
"io"
"strings"
)

type Element interface {
Render(writer io.Writer) error
Render(writer io.Writer, themes ...Theme) error
}

type StringElement string

func (e StringElement) Render(writer io.Writer) error {
_, err := writer.Write([]byte(e))
return err
func (e StringElement) Render(writer io.Writer, themes ...Theme) error {
return htmlRender(strings.NewReader(string(e)), writer, mergeThemes(themes))
}

type TemplateElement struct {
Data interface{}
Template string
}

func (e TemplateElement) Render(writer io.Writer) error {
func (e TemplateElement) Render(writer io.Writer, themes ...Theme) error {
t, err := template.New("").Parse(e.Template)
if err != nil {
return fmt.Errorf("parse template: %w", err)
}
return t.Execute(writer, e.Data)
buffer := &bytes.Buffer{}
if err := t.Execute(buffer, e.Data); err != nil {
return fmt.Errorf("template execute: %w", err)
}
return htmlRender(buffer, writer, mergeThemes(themes))
}
41 changes: 40 additions & 1 deletion element_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@ func TestStringElement_Render(t *testing.T) {
tests := []struct {
name string
e StringElement
style Theme
wantWriter string
wantErr bool
}{
Expand All @@ -18,11 +19,25 @@ func TestStringElement_Render(t *testing.T) {
wantWriter: "<p>test</p>",
wantErr: false,
},
{
name: "with_style",
e: "<p>test</p>",
style: MapTheme{
"p": Attributes{
{
Name: "style",
Value: "background-color:#dedede;",
},
},
},
wantWriter: `<p style="background-color:#dedede;">test</p>`,
wantErr: false,
},
}
for _, tt := range tests {
t.Run(tt.name, func(t *testing.T) {
writer := &bytes.Buffer{}
err := tt.e.Render(writer)
err := tt.e.Render(writer, tt.style)
if (err != nil) != tt.wantErr {
t.Errorf("Render() error = %v, wantErr %v", err, tt.wantErr)
return
Expand Down Expand Up @@ -60,6 +75,30 @@ func TestTemplateElement_Render(t *testing.T) {
wantWriter: "A:a, B:1",
wantErr: false,
},
{
name: "invalid_template",
fields: fields{
Data: struct {
A string
B int
}{
A: "a",
B: 1,
},
Template: "A:{{.A}}, B:{{.B}",
},
wantWriter: "",
wantErr: true,
},
{
name: "invalid_data",
fields: fields{
Data: "test",
Template: "A:{{.A}}, B:{{.B}}",
},
wantWriter: "",
wantErr: true,
},
}
for _, tt := range tests {
t.Run(tt.name, func(t *testing.T) {
Expand Down
27 changes: 24 additions & 3 deletions email.go
Original file line number Diff line number Diff line change
@@ -1,15 +1,36 @@
package emailt

import (
"fmt"
"io"
)

type Email struct {
elements []Element
theme Theme
}

func (e *Email) AddElements(element ...Element) {
type Option func(email *Email)

func WithTheme(theme Theme) Option {
return func(email *Email) {
email.theme = theme
}
}

func NewEmail(options ...Option) *Email {
ret := &Email{
theme: DefaultTheme,
}
for _, option := range options {
option(ret)
}
return ret
}

func (e *Email) AddElements(element ...Element) *Email {
e.elements = append(e.elements, element...)
return e
}

func (e *Email) Render(writer io.Writer) error {
Expand All @@ -26,8 +47,8 @@ func (e *Email) Render(writer io.Writer) error {
`)

for _, element := range e.elements {
if err := element.Render(writer); err != nil {
return err
if err := element.Render(writer, e.theme); err != nil {
return fmt.Errorf("render: %w", err)
}
}

Expand Down
7 changes: 1 addition & 6 deletions email_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -54,9 +54,6 @@ func TestEmail_Render(t *testing.T) {
Template: "{{.A}}({{.B}})",
},
},
Attr: DefaultTableAttr,
HeaderAttr: DefaultTableHeaderAttr,
DataAttr: DefaultTableDataAttr,
},
},
},
Expand All @@ -65,9 +62,7 @@ func TestEmail_Render(t *testing.T) {
}
for _, tt := range tests {
t.Run(tt.name, func(t *testing.T) {
e := &Email{
elements: tt.fields.elements,
}
e := NewEmail().AddElements(tt.fields.elements...)
got := bytes.NewBuffer(nil)
err := e.Render(got)
if (err != nil) != tt.wantErr {
Expand Down
6 changes: 0 additions & 6 deletions main_test.go

This file was deleted.

78 changes: 26 additions & 52 deletions table.go
Original file line number Diff line number Diff line change
Expand Up @@ -2,40 +2,36 @@ package emailt

import (
"fmt"
"html/template"
"io"
"reflect"
"sort"
"strings"
)

type Table struct {
Dataset interface{}
Columns []Column
Attr Attributes
HeaderAttr Attributes
DataAttr Attributes
type Column struct {
Name string
Template string
}

func NewTable() Table {
return Table{
Attr: DefaultTableAttr,
HeaderAttr: DefaultTableHeaderAttr,
DataAttr: DefaultTableDataAttr,
}
type Columns []Column

type Table struct {
Dataset interface{}
Columns Columns
}

func (t Table) WithDataset(dataset interface{}) Table {
t.Dataset = dataset
return t
}

func (t Table) WithColumns(columns []Column) Table {
func (t Table) WithColumns(columns Columns) Table {
t.Columns = columns
return t
}

func (t Table) Render(writer io.Writer) error {
func (t Table) Render(writer io.Writer, themes ...Theme) error {
theme := mergeThemes(themes)

dataset := reflect.ValueOf(t.Dataset)
if dataset.Kind() != reflect.Slice {
return fmt.Errorf("%v is not a slice", dataset.Type())
Expand Down Expand Up @@ -90,57 +86,35 @@ func (t Table) Render(writer io.Writer) error {
}
}
}
var rowTemplate *template.Template
{
rowBuilder := strings.Builder{}
rowBuilder.WriteString("<tr>\n")
for _, column := range columns {
rowBuilder.WriteString(fmt.Sprintf("<td %s>%s</td>\n", t.DataAttr, column.Template))
}
rowBuilder.WriteString("</tr>")
var err error
rowTemplate, err = template.New("").Parse(rowBuilder.String())
if err != nil {
return fmt.Errorf("Parse: %w", err)
}
}

render := newFmtWriter(writer)

render.Printlnf("<table %s>", t.Attr.String())
render.Printlnf("<table %s>", theme.Attributes("table"))

render.Println("<tr>")

for _, column := range columns {
render.Printlnf("<th %s>%s</th>", t.HeaderAttr, column.Name)
render.Printlnf("<th %s>%s</th>", theme.Attributes("th"), column.Name)
}
render.Println("</tr>")

for i := 0; i < dataset.Len(); i++ {
if err := rowTemplate.Execute(render, dataset.Index(i)); err != nil {
return fmt.Errorf("Execute: %w", err)
render.Println("<tr>")
for _, column := range columns {
render.Printlnf("<td %s>", theme.Attributes("td"))
e := TemplateElement{
Data: dataset.Index(i),
Template: column.Template,
}
if err := e.Render(writer, theme); err != nil {
return fmt.Errorf("render: %w", err)
}
render.Println("\n</td>")
}
render.Println()
render.Println("</tr>")
}

render.Println("</table>")

return render.Err()
}

type Column struct {
Name string
Template string
}

var (
DefaultTableAttr = Attributes{
{Name: "style", Value: "border:1px black solid; padding:3px 3px 3px 3px; border-collapse:collapse;"},
}
DefaultTableHeaderAttr = Attributes{
{Name: "style", Value: "border:1px black solid; padding:3px 3px 3px 3px; border-collapse:collapse; background-color:#dedede;"},
}
DefaultTableDataAttr = Attributes{
{Name: "style", Value: "border:1px black solid; padding:3px 3px 3px 3px; border-collapse:collapse;"},
}
)
7 changes: 6 additions & 1 deletion table_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,11 @@ import (
"golang.org/x/net/html"
)

type TestStruct1 struct {
A string
B int
}

func TestTable_Render(t1 *testing.T) {
type fields struct {
Dataset interface{}
Expand Down Expand Up @@ -100,7 +105,7 @@ func TestTable_Render(t1 *testing.T) {
}
for _, tt := range tests {
t1.Run(tt.name, func(t1 *testing.T) {
t := NewTable().WithColumns(tt.fields.Columns).WithDataset(tt.fields.Dataset)
t := Table{}.WithColumns(tt.fields.Columns).WithDataset(tt.fields.Dataset)
got := bytes.NewBuffer(nil)
err := t.Render(got)
if (err != nil) != tt.wantErr {
Expand Down
Loading

0 comments on commit 86d077e

Please sign in to comment.