Skip to content

Commit

Permalink
change New constructor receiver to html string or path string
Browse files Browse the repository at this point in the history
  • Loading branch information
Roman Sarvarov committed Jun 15, 2024
1 parent f776c42 commit 2dafea1
Show file tree
Hide file tree
Showing 9 changed files with 70 additions and 102 deletions.
20 changes: 2 additions & 18 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -38,13 +38,12 @@ package main
import (
"log"
"net/http"
"time"


inertia "github.com/romsar/gonertia"
)

func main() {
i, err := inertia.New("./resources/views/root.html")
i, err := inertia.New("resources/views/root.html") // put here HTML or path to the root template file
if err != nil {
log.Fatal(err)
}
Expand Down Expand Up @@ -95,21 +94,6 @@ You can also find more examples and starter kits in [examples folder](./examples

### More examples

#### Load root template using embed
```go
import "embed"

//go:embed templates
var templateFS embed.FS

// ...

i, err := inertia.New(
/* ... */
inertia.WithTemplateFS(templateFS),
)
```

#### Set asset version ([learn more](https://inertiajs.com/asset-versioning))

```go
Expand Down
3 changes: 2 additions & 1 deletion examples/vue3_tailwind/main.go
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
package main

import (
_ "embed"
"encoding/json"
"fmt"
inertia "github.com/romsar/gonertia"
Expand All @@ -26,7 +27,7 @@ func initInertia() *inertia.Inertia {
manifestPath := "./public/build/manifest.json"

i, err := inertia.New(
"./resources/views/root.html",
"resources/views/root.html",
inertia.WithVersionFromFile(manifestPath),
inertia.WithSSR(),
)
Expand Down
8 changes: 4 additions & 4 deletions helpers_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -159,24 +159,24 @@ func tmpFile(t *testing.T, content string) *os.File {

closed := false

if _, err := f.WriteString(content); err != nil {
if _, err = f.WriteString(content); err != nil {
t.Fatalf("unexpected error: %s", err)
}

if err := f.Close(); err != nil {
if err = f.Close(); err != nil {
t.Fatalf("unexpected error: %s", err)
}

closed = true

t.Cleanup(func() {
if !closed {
if err := f.Close(); err != nil {
if err = f.Close(); err != nil {
t.Fatalf("unexpected error: %s", err)
}
}

if err := os.Remove(f.Name()); err != nil {
if err = os.Remove(f.Name()); err != nil {
t.Fatalf("unexpected error: %s", err)
}
})
Expand Down
21 changes: 16 additions & 5 deletions inertia.go
Original file line number Diff line number Diff line change
Expand Up @@ -5,16 +5,15 @@ import (
"fmt"
"html/template"
"io"
"io/fs"
"log"
"net/http"
"os"
)

// Inertia is a main Gonertia structure, which contains all the logic for being an Inertia adapter.
type Inertia struct {
templateFS fs.FS
rootTemplate *template.Template
rootTemplatePath string
rootTemplateHTML string

sharedProps Props
sharedTemplateData TemplateData
Expand All @@ -30,9 +29,21 @@ type Inertia struct {
}

// New initializes and returns Inertia.
func New(rootTemplatePath string, opts ...Option) (*Inertia, error) {
func New(rootTemplate string, opts ...Option) (*Inertia, error) {
if f, err := os.Open(rootTemplate); err == nil {
defer f.Close()

var bs []byte
bs, err = io.ReadAll(f)
if err != nil {
return nil, fmt.Errorf("cannot read root template file %q: %w", rootTemplate, err)
}

rootTemplate = string(bs)
}

i := &Inertia{
rootTemplatePath: rootTemplatePath,
rootTemplateHTML: rootTemplate,
marshallJSON: json.Marshal,
containerID: "app",
logger: log.New(io.Discard, "", 0),
Expand Down
37 changes: 37 additions & 0 deletions inertia_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,43 @@ import (
"testing"
)

var rootTemplate = `<html>
<head>{{ .inertiaHead }}</head>
<body>{{ .inertia }}</body>
</html>`

func TestNew(t *testing.T) {
t.Parallel()

t.Run("root template init", func(t *testing.T) {
t.Parallel()

t.Run("by html", func(t *testing.T) {
i, err := New(rootTemplate)
if err != nil {
t.Fatalf("unexpected error: %s", err)
}

if i.rootTemplateHTML != rootTemplate {
t.Fatalf("root template html=%s, want=%s", i.rootTemplateHTML, rootTemplate)
}
})

t.Run("by path", func(t *testing.T) {
f := tmpFile(t, rootTemplate)

i, err := New(f.Name())
if err != nil {
t.Fatalf("unexpected error: %s", err)
}

if i.rootTemplateHTML != rootTemplate {
t.Fatalf("root template html=%s, want=%s", i.rootTemplateHTML, rootTemplate)
}
})
})
}

func TestInertia_ShareProp(t *testing.T) {
t.Parallel()

Expand Down
9 changes: 0 additions & 9 deletions option.go
Original file line number Diff line number Diff line change
Expand Up @@ -3,22 +3,13 @@ package gonertia
import (
"fmt"
"io"
"io/fs"
"log"
"net/http"
)

// Option is an option parameter that modifies Inertia.
type Option func(i *Inertia) error

// WithTemplateFS returns Option that will set Inertia's templateFS.
func WithTemplateFS(templateFS fs.FS) Option {
return func(i *Inertia) error {
i.templateFS = templateFS
return nil
}
}

// WithVersion returns Option that will set Inertia's version.
func WithVersion(version string) Option {
return func(i *Inertia) error {
Expand Down
18 changes: 0 additions & 18 deletions option_test.go
Original file line number Diff line number Diff line change
@@ -1,30 +1,12 @@
package gonertia

import (
"embed"
"io"
"log"
"reflect"
"testing"
)

func TestWithTemplateFS(t *testing.T) {
t.Parallel()

i := I()
fs := embed.FS{}

option := WithTemplateFS(fs)

if err := option(i); err != nil {
t.Fatalf("unexpected error: %s", err)
}

if !reflect.DeepEqual(i.templateFS, fs) {
t.Fatalf("templateFS=%#v, want=%#v", i.templateFS, fs)
}
}

func TestWithVersion(t *testing.T) {
t.Parallel()

Expand Down
12 changes: 3 additions & 9 deletions response.go
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,6 @@ import (
"fmt"
"html/template"
"net/http"
"path/filepath"
"strings"
)

Expand Down Expand Up @@ -97,21 +96,16 @@ func (i *Inertia) doHTMLResponse(w http.ResponseWriter, r *http.Request, page *p

setHTMLResponse(w)

if err := i.rootTemplate.Execute(w, templateData); err != nil {
if err = i.rootTemplate.Execute(w, templateData); err != nil {
return fmt.Errorf("execute root template: %w", err)
}

return nil
}

func (i *Inertia) buildRootTemplate() (*template.Template, error) {
tmpl := template.New(filepath.Base(i.rootTemplatePath)).Funcs(template.FuncMap(i.sharedTemplateFuncs))

if i.templateFS != nil {
return tmpl.ParseFS(i.templateFS, i.rootTemplatePath)
}

return tmpl.ParseFiles(i.rootTemplatePath)
tmpl := template.New("").Funcs(template.FuncMap(i.sharedTemplateFuncs))
return tmpl.Parse(i.rootTemplateHTML)
}

func (i *Inertia) buildTemplateData(r *http.Request, page *page) (TemplateData, error) {
Expand Down
44 changes: 6 additions & 38 deletions response_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -10,47 +10,21 @@ import (
"regexp"
"strings"
"testing"
"testing/fstest"
)

var rootTemplate = `<html>
<head>{{ .inertiaHead }}</head>
<body>{{ .inertia }}</body>
</html>`

//nolint:gocognit
func TestInertia_Render(t *testing.T) {
t.Parallel()

t.Run("plain request", func(t *testing.T) {
t.Parallel()

t.Run("file template", func(t *testing.T) {
t.Parallel()

f := tmpFile(t, rootTemplate)

i := I(func(i *Inertia) {
i.rootTemplatePath = f.Name()
i.version = "f8v01xv4h4"
})

assertRootTemplateSuccess(t, i)
})

t.Run("embed fs template", func(t *testing.T) {
t.Run("success", func(t *testing.T) {
t.Parallel()

fs := fstest.MapFS{
"app.html": {
Data: []byte(rootTemplate),
},
}

i := I(func(i *Inertia) {
i.rootTemplatePath = "app.html"
i.rootTemplateHTML = rootTemplate
i.version = "f8v01xv4h4"
i.templateFS = fs
})

assertRootTemplateSuccess(t, i)
Expand All @@ -62,8 +36,6 @@ func TestInertia_Render(t *testing.T) {
t.Run("success", func(t *testing.T) {
t.Parallel()

f := tmpFile(t, rootTemplate)

ts := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
reqContentType := r.Header.Get("Content-Type")
wantContentType := "application/json"
Expand Down Expand Up @@ -102,7 +74,7 @@ func TestInertia_Render(t *testing.T) {
defer ts.Close()

i := I(func(i *Inertia) {
i.rootTemplatePath = f.Name()
i.rootTemplateHTML = rootTemplate
i.version = "f8v01xv4h4"
i.ssrURL = ts.URL
i.ssrHTTPClient = ts.Client()
Expand Down Expand Up @@ -135,15 +107,13 @@ func TestInertia_Render(t *testing.T) {
t.Run("error with fallback", func(t *testing.T) {
t.Parallel()

f := tmpFile(t, rootTemplate)

ts := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
w.WriteHeader(http.StatusInternalServerError)
}))
defer ts.Close()

i := I(func(i *Inertia) {
i.rootTemplatePath = f.Name()
i.rootTemplateHTML = rootTemplate
i.version = "f8v01xv4h4"
i.ssrURL = ts.URL
i.ssrHTTPClient = ts.Client()
Expand All @@ -169,11 +139,10 @@ func TestInertia_Render(t *testing.T) {
t.Run("shared funcs", func(t *testing.T) {
t.Parallel()

f := tmpFile(t, `{{ trim " foo bar " }}`)
w, r := requestMock(http.MethodGet, "/")

i := I(func(i *Inertia) {
i.rootTemplatePath = f.Name()
i.rootTemplateHTML = `{{ trim " foo bar " }}`
i.sharedTemplateFuncs = TemplateFuncs{
"trim": strings.TrimSpace,
}
Expand All @@ -195,11 +164,10 @@ func TestInertia_Render(t *testing.T) {
t.Run("shared template data", func(t *testing.T) {
t.Parallel()

f := tmpFile(t, `Hello, {{ .text }}!`)
w, r := requestMock(http.MethodGet, "/")

i := I(func(i *Inertia) {
i.rootTemplatePath = f.Name()
i.rootTemplateHTML = `Hello, {{ .text }}!`
i.sharedTemplateData = TemplateData{
"text": "world",
}
Expand Down

0 comments on commit 2dafea1

Please sign in to comment.