-1

I want to use gorazor a written in that uses -Syntax. They provide an example which i tried to understand and adapt.

What is working

I want to iterate over a slices of movies and currently this works:

list movies

I ran

# to generate the code
gorazor tpl tpl 
# to start the webapp
go run main.go

Based on this movie.gohtml

@{
  import (
    "razor_tut/models"
  )
  
  var movie *models.Movie
  var movieSlice *[]models.Movie
}

@{
  title := movie.Title
  releaseYear := movie.ReleaseYear
  numberOfMovies := len(*movieSlice)
  movies := *movieSlice
}
<div>
    <h2>My favorite movie out of @numberOfMovies</h2>
    <ul>
      <li> @title (@releaseYear)</li>
    </ul>
    <h2>My other favorite movies</h2>
    <ul data-comment="How to render the slice below">
        @movies
    </ul>
</div>

What fails?

But my attempt to render the content of @movies fails

@if (@movies != null)
{
  foreach (var mov in  @movies)
  {
     <li>@mov.Title </li>
  }
}

or this

    <ul data-comment="this below fails">
      @foreach(var mov in @movies){
          <li>@mov.Title</li>     
      }
    </ul>

both fail with this Error: failed to format template

 gorazor tpl tpl
gorazor processing dir: tpl -> tpl
panic: failed to format template

          40 _buffer.WriteString(gorazor.HTMLEscape(releaseYear))
          41 // Line: 19
          42 _buffer.WriteString(")</li>\n    </ul>\n    <h2>My other favorite movies</h2>\n    <ul data-comment=\"this below fails\">\n      ")
          43 if (
          44 // Line: 23
        >>>> _buffer.WriteString(gorazor.HTMLEscape(movies))
          46 != null)
          47 {
          48 foreach (var mov in
          49 // Line: 25
          50 _buffer.WriteString(gorazor.HTMLEscape(movies))


goroutine 7 [running]:
github.com/sipin/gorazor/pkg/razorcore.FormatBuffer({0xc0002f9500?, 0x10?})
        C:/Users/my/go/pkg/mod/github.com/sipin/[email protected]/pkg/razorcore/utils.go:50 +0x2d4
github.com/sipin/gorazor/pkg/razorcore.generate({0xc00000aa00?, 0x26?}, {0xc00000e780, 0x26}, {0x80?, 0xe7?, 0x0?})
        C:/Users/my/go/pkg/mod/github.com/sipin/[email protected]/pkg/razorcore/compiler.go:656 +0x5e
github.com/sipin/gorazor/pkg/razorcore.GenFile({0xc00000aa00, 0x10}, {0xc00000e780, 0x26}, {0xd4?, 0x6d?, 0xb3?})
        C:/Users/my/go/pkg/mod/github.com/sipin/[email protected]/pkg/razorcore/api.go:26 +0x96
github.com/sipin/gorazor/pkg/razorcore.GenFolder.func2({0xc00000aa00, 0x10}, 0xc000149b20)
        C:/Users/my/go/pkg/mod/github.com/sipin/[email protected]/pkg/razorcore/api.go:66 +0x107
created by github.com/sipin/gorazor/pkg/razorcore.GenFolder in goroutine 1
        C:/Users/my/go/pkg/mod/github.com/sipin/[email protected]/pkg/razorcore/api.go:79 +0x245

Project structure

Project razor_zwei has these files and folders:

razor_zwei
├─── main.go
├─── models
|    └─── movie.go
└───tpl
     └─── movie.gohtml

Code

For main.go

package main

import (
    "fmt"
    "net/http"
    "razor_zwei/models"
    "razor_zwei/tpl"  // gorazor will generate the go code
)

func main() {
    // tpl.Movie(...) is generated from gorazor
    http.HandleFunc("/movie", 
        func(w http.ResponseWriter, r *http.Request) {
            fmt.Fprintf(w, "%s", 
                     tpl.Movie(GetMovie(), GetMovies()))
    })

    fmt.Print("Server running on http://localhost:8080")
    http.ListenAndServe(":8080", nil)
}

func GetMovie() *models.Movie {
    return &models.Movie{
        ID: 1, Title: "Foo", ReleaseYear: 2010, Genre: nil, Price: 6.99}
}
func GetMovies() *[]models.Movie {
    return &[]models.Movie{
        {ID: 1, Title: "Foo", ReleaseYear: 2010, Genre: nil, Price: 6.99},
        {ID: 2, Title: "Bar", ReleaseYear: 2011, Genre: nil, Price: 17.99},
        {ID: 1, Title: "Baz", ReleaseYear: 2012, Genre: nil, Price: 28.99},
    }
}

For models/movie.go

package models

// Movie represents a movie with its details.
type Movie struct {
    ID          int     `json:"id"`
    Title       string  `json:"title"`
    ReleaseYear int     `json:"releaseYear"`
    Genre       *string `json:"genre,omitempty"` // pointer to allow nil
    Price       float64 `json:"price"`
}

2 Answers 2

2

I think I found the problem. you are importing razor_zwei/tpl/layout in tpl/home.gohtml and then changing layout variable. because layout has been defined previously this error happens. use = instead of := and the problem might go away.

Sign up to request clarification or add additional context in comments.

4 Comments

This already helped. Now i get: panic: runtime error: slice bounds out of range [:1] with length 0
can you provide the full error ?
I overhauled the question and added the error details
I couldn't actually find the problem. but it seems like that gorazor is detecting first block empty
0

My assumption was that razor (/ c#) syntax can be used inside a code block @.... But this seems to not be the case. The below works

@{
  // file tpl/movie.gohtml 
  import (
    "razor_tut/models"
  )
  
  var movie *models.Movie
  var movieSlice *[]models.Movie
}

@{
  title := movie.Title
  releaseYear := movie.ReleaseYear
  numberOfMovies := len(*movieSlice)
  movies := *movieSlice
}
<div>
    <h2>My favorite movie out of @numberOfMovies</h2>
    <ul>
      <li> @title (@releaseYear)</li>
    </ul>
    <h2>My other favorite movies</h2>
    <ul data-comment="this below fails">
      @for _, mov := range movies {
        <li>@mov.Title</li>  
      }
    </ul>
</div>

Comments

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.