diff --git a/cmd/web/handlers_guestbook.go b/cmd/web/handlers_guestbook.go index 1a6e6b3..5234eb4 100644 --- a/cmd/web/handlers_guestbook.go +++ b/cmd/web/handlers_guestbook.go @@ -5,7 +5,6 @@ import ( "errors" "fmt" "net/http" - "net/url" "strconv" "time" @@ -258,11 +257,10 @@ func (app *application) postGuestbookCommentCreateRemote(w http.ResponseWriter, return } - if normalizeUrl(r.Header.Get("Origin")) != normalizeUrl(website.SiteUrl) { + if !matchOrigin(r.Header.Get("Origin"), website.Url) { app.clientError(w, http.StatusForbidden) return } - if !website.Guestbook.CanComment() { app.clientError(w, http.StatusForbidden) return @@ -285,12 +283,10 @@ func (app *application) postGuestbookCommentCreateRemote(w http.ResponseWriter, // otherwise redirect to the guestbook by default redirectUrl := fmt.Sprintf("/websites/%s/guestbook", shortIdToSlug(website.ShortId)) if form.Redirect != "" { - u := url.URL{ - Scheme: "http", - Host: website.SiteUrl, - Path: form.Redirect, + u, err := website.Url.Parse(form.Redirect) + if err == nil { + redirectUrl = u.String() } - redirectUrl = u.String() } if !form.Valid() { diff --git a/cmd/web/handlers_guestbook_test.go b/cmd/web/handlers_guestbook_test.go index c96693b..182f081 100644 --- a/cmd/web/handlers_guestbook_test.go +++ b/cmd/web/handlers_guestbook_test.go @@ -144,3 +144,88 @@ func TestPostGuestbookCommentCreate(t *testing.T) { }) } } + +func TestPostGuestbookCommentCreateRemote(t *testing.T) { + app := newTestApplication(t) + ts := newTestServer(t, app.routes()) + defer ts.Close() + + _, _, body := ts.get(t, fmt.Sprintf("/websites/%s/guestbook", shortIdToSlug(1))) + validCSRFToken := extractCSRFToken(t, body) + + const ( + validAuthorName = "John Test" + validAuthorEmail = "test@example.com" + validAuthorSite = "example.com" + validContent = "This is a comment" + ) + + tests := []struct { + name string + authorName string + authorEmail string + authorSite string + content string + csrfToken string + wantCode int + }{ + { + name: "Valid input", + authorName: validAuthorName, + authorEmail: validAuthorEmail, + authorSite: validAuthorSite, + content: validContent, + csrfToken: validCSRFToken, + wantCode: http.StatusSeeOther, + }, + { + name: "Blank name", + authorName: "", + authorEmail: validAuthorEmail, + authorSite: validAuthorSite, + content: validContent, + csrfToken: validCSRFToken, + wantCode: http.StatusUnprocessableEntity, + }, + { + name: "Blank email", + authorName: validAuthorName, + authorEmail: "", + authorSite: validAuthorSite, + content: validContent, + csrfToken: validCSRFToken, + wantCode: http.StatusSeeOther, + }, + { + name: "Blank site", + authorName: validAuthorName, + authorEmail: validAuthorEmail, + authorSite: "", + content: validContent, + csrfToken: validCSRFToken, + wantCode: http.StatusSeeOther, + }, + { + name: "Blank content", + authorName: validAuthorName, + authorEmail: validAuthorEmail, + authorSite: validAuthorSite, + content: "", + csrfToken: validCSRFToken, + wantCode: http.StatusUnprocessableEntity, + }, + } + for _, tt := range tests { + t.Run(tt.name, func(t *testing.T) { + form := url.Values{} + form.Add("authorname", tt.authorName) + form.Add("authoremail", tt.authorEmail) + form.Add("authorsite", tt.authorSite) + form.Add("content", tt.content) + form.Add("csrf_token", tt.csrfToken) + code, _, body := ts.postForm(t, fmt.Sprintf("/websites/%s/guestbook/comments/create/remote", shortIdToSlug(1)), form) + assert.Equal(t, code, tt.wantCode) + assert.Equal(t, body, body) + }) + } +} diff --git a/cmd/web/handlers_website.go b/cmd/web/handlers_website.go index 9e6d2d5..a2b8e9e 100644 --- a/cmd/web/handlers_website.go +++ b/cmd/web/handlers_website.go @@ -33,16 +33,20 @@ func (app *application) postWebsiteCreate(w http.ResponseWriter, r *http.Request form.CheckField(validator.MaxChars(form.Name, 256), "sitename", "This field cannot exceed 256 characters") form.CheckField(validator.NotBlank(form.SiteUrl), "siteurl", "This field cannot be blank") form.CheckField(validator.MaxChars(form.SiteUrl, 512), "siteurl", "This field cannot exceed 512 characters") + form.CheckField(validator.Matches(form.SiteUrl, validator.WebRX), "siteurl", "This field must be a valid URL (including http:// or https://)") u, err := url.Parse(form.SiteUrl) - - if !form.Valid() || err != nil { + if err != nil { + form.CheckField(false, "siteurl", "This field must be a valid URL") + } + if !form.Valid() { data := app.newCommonData(r) w.WriteHeader(http.StatusUnprocessableEntity) views.WebsiteCreate("Add a Website", data, form).Render(r.Context(), w) + return } websiteShortID := app.createShortId() - _, err = app.websites.Insert(websiteShortID, userId, form.Name, u.Host, form.AuthorName) + _, err = app.websites.Insert(websiteShortID, userId, form.Name, u.String(), form.AuthorName) if err != nil { app.serverError(w, r, err) return @@ -78,10 +82,6 @@ func (app *application) getWebsiteList(w http.ResponseWriter, r *http.Request) { app.serverError(w, r, err) return } - if r.Header.Get("HX-Request") == "true" { - views.HxWebsiteList(websites) - return - } data := app.newCommonData(r) views.WebsiteList("My Websites", data, websites).Render(r.Context(), w) } diff --git a/cmd/web/helpers.go b/cmd/web/helpers.go index e1321e0..f86b71b 100644 --- a/cmd/web/helpers.go +++ b/cmd/web/helpers.go @@ -5,9 +5,9 @@ import ( "fmt" "math" "net/http" + "net/url" "runtime/debug" "strconv" - "strings" "time" "git.32bit.cafe/32bitcafe/guestbook/internal/models" @@ -130,11 +130,13 @@ func (app *application) durationToTime(duration string) (time.Time, error) { return result, nil } -func normalizeUrl(url string) string { - r, f := strings.CutPrefix(url, "http://") - if f { - return r +func matchOrigin(origin string, u *url.URL) bool { + o, err := url.Parse(origin) + if err != nil { + return false } - r, _ = strings.CutPrefix(url, "https://") - return r + if o.Host != u.Host { + return false + } + return true } diff --git a/internal/models/mocks/guestbookcomment.go b/internal/models/mocks/guestbookcomment.go index 6a0c972..f8520de 100644 --- a/internal/models/mocks/guestbookcomment.go +++ b/internal/models/mocks/guestbookcomment.go @@ -18,6 +18,12 @@ var mockGuestbookComment = models.GuestbookComment{ IsPublished: true, } +var mockSerializedGuestbookComment = models.GuestbookCommentSerialized{ + AuthorName: "John Test", + CommentText: "Hello, world", + Created: time.Now().Format(time.RFC3339), +} + type GuestbookCommentModel struct{} func (m *GuestbookCommentModel) Insert(shortId uint64, guestbookId, parentId int64, authorName, @@ -45,6 +51,17 @@ func (m *GuestbookCommentModel) GetAll(guestbookId int64) ([]models.GuestbookCom } } +func (m *GuestbookCommentModel) GetAllSerialized(guestbookId int64) ([]models.GuestbookCommentSerialized, error) { + switch guestbookId { + case 1: + return []models.GuestbookCommentSerialized{mockSerializedGuestbookComment}, nil + case 2: + return []models.GuestbookCommentSerialized{}, nil + default: + return []models.GuestbookCommentSerialized{}, models.ErrNoRecord + } +} + func (m *GuestbookCommentModel) GetDeleted(guestbookId int64) ([]models.GuestbookComment, error) { switch guestbookId { default: diff --git a/internal/models/mocks/website.go b/internal/models/mocks/website.go index 83cc69e..1e14872 100644 --- a/internal/models/mocks/website.go +++ b/internal/models/mocks/website.go @@ -1,6 +1,7 @@ package mocks import ( + "net/url" "time" "git.32bit.cafe/32bitcafe/guestbook/internal/models" @@ -22,10 +23,14 @@ var mockGuestbook = models.Guestbook{ } var mockWebsite = models.Website{ - ID: 1, - ShortId: 1, - Name: "Example", - SiteUrl: "example.com", + ID: 1, + ShortId: 1, + Name: "Example", + // SiteUrl: "example.com", + Url: &url.URL{ + Scheme: "http", + Host: "example.com", + }, AuthorName: "John Test", UserId: 1, Created: time.Now(), diff --git a/internal/models/website.go b/internal/models/website.go index 53eb35d..811bedf 100644 --- a/internal/models/website.go +++ b/internal/models/website.go @@ -3,15 +3,17 @@ package models import ( "database/sql" "errors" + "net/url" "strconv" "time" ) type Website struct { - ID int64 - ShortId uint64 - Name string - SiteUrl string + ID int64 + ShortId uint64 + Name string + // SiteUrl string + Url *url.URL AuthorName string UserId int64 Created time.Time @@ -179,7 +181,8 @@ func (m *WebsiteModel) Get(shortId uint64) (Website, error) { } row := tx.QueryRow(stmt, shortId) var w Website - err = row.Scan(&w.ID, &w.ShortId, &w.Name, &w.SiteUrl, &w.AuthorName, &w.UserId, &w.Created) + var u string + err = row.Scan(&w.ID, &w.ShortId, &w.Name, &u, &w.AuthorName, &w.UserId, &w.Created) if err != nil { if errors.Is(err, sql.ErrNoRows) { err = ErrNoRecord @@ -189,6 +192,10 @@ func (m *WebsiteModel) Get(shortId uint64) (Website, error) { } return Website{}, err } + w.Url, err = url.Parse(u) + if err != nil { + return Website{}, err + } stmt = `SELECT Id, ShortId, UserId, WebsiteId, Created, IsActive FROM guestbooks WHERE WebsiteId = ? AND Deleted IS NULL` @@ -244,11 +251,16 @@ func (m *WebsiteModel) GetAllUser(userId int64) ([]Website, error) { var websites []Website for rows.Next() { var w Website - err := rows.Scan(&w.ID, &w.ShortId, &w.Name, &w.SiteUrl, &w.AuthorName, &w.UserId, &w.Created, + var u string + err := rows.Scan(&w.ID, &w.ShortId, &w.Name, &u, &w.AuthorName, &w.UserId, &w.Created, &w.Guestbook.ID, &w.Guestbook.ShortId, &w.Guestbook.Created, &w.Guestbook.IsActive) if err != nil { return nil, err } + w.Url, err = url.Parse(u) + if err != nil { + return nil, err + } websites = append(websites, w) } if err = rows.Err(); err != nil { @@ -268,11 +280,16 @@ func (m *WebsiteModel) GetAll() ([]Website, error) { var websites []Website for rows.Next() { var w Website - err := rows.Scan(&w.ID, &w.ShortId, &w.Name, &w.SiteUrl, &w.AuthorName, &w.UserId, &w.Created, + var u string + err := rows.Scan(&w.ID, &w.ShortId, &w.Name, &u, &w.AuthorName, &w.UserId, &w.Created, &w.Guestbook.ID, &w.Guestbook.ShortId, &w.Guestbook.Created, &w.Guestbook.IsActive) if err != nil { return nil, err } + w.Url, err = url.Parse(u) + if err != nil { + return nil, err + } websites = append(websites, w) } if err = rows.Err(); err != nil { diff --git a/internal/validator/validator.go b/internal/validator/validator.go index 0f57692..62037b2 100644 --- a/internal/validator/validator.go +++ b/internal/validator/validator.go @@ -8,51 +8,52 @@ import ( ) var EmailRX = regexp.MustCompile("^[a-zA-Z0-9.!#$%&'*+/=?^_`{|}~-]+@[a-zA-Z0-9](?:[a-zA-Z0-9-]{0,61}[a-zA-Z0-9])?(?:\\.[a-zA-Z0-9](?:[a-zA-Z0-9-]{0,61}[a-zA-Z0-9])?)*$") +var WebRX = regexp.MustCompile("^https?:\\/\\/") type Validator struct { - NonFieldErrors []string - FieldErrors map[string]string + NonFieldErrors []string + FieldErrors map[string]string } func (v *Validator) Valid() bool { - return len(v.FieldErrors) == 0 && len(v.NonFieldErrors) == 0 + return len(v.FieldErrors) == 0 && len(v.NonFieldErrors) == 0 } func (v *Validator) AddFieldError(key, message string) { - if v.FieldErrors == nil { - v.FieldErrors = make(map[string]string) - } - if _, exists := v.FieldErrors[key]; !exists { - v.FieldErrors[key] = message - } + if v.FieldErrors == nil { + v.FieldErrors = make(map[string]string) + } + if _, exists := v.FieldErrors[key]; !exists { + v.FieldErrors[key] = message + } } func (v *Validator) AddNonFieldError(message string) { - v.NonFieldErrors = append(v.NonFieldErrors, message) + v.NonFieldErrors = append(v.NonFieldErrors, message) } func (v *Validator) CheckField(ok bool, key, message string) { - if !ok { - v.AddFieldError(key, message) - } + if !ok { + v.AddFieldError(key, message) + } } func NotBlank(value string) bool { - return strings.TrimSpace(value) != "" + return strings.TrimSpace(value) != "" } func MaxChars(value string, n int) bool { - return utf8.RuneCountInString(value) <= n + return utf8.RuneCountInString(value) <= n } func PermittedValue[T comparable](value T, permittedValues ...T) bool { - return slices.Contains(permittedValues, value) + return slices.Contains(permittedValues, value) } func MinChars(value string, n int) bool { - return utf8.RuneCountInString(value) >= n + return utf8.RuneCountInString(value) >= n } func Matches(value string, rx *regexp.Regexp) bool { - return rx.MatchString(value) + return rx.MatchString(value) } diff --git a/migrations/000005_normalize_site_urls.down.sql b/migrations/000005_normalize_site_urls.down.sql new file mode 100644 index 0000000..1d42f9e --- /dev/null +++ b/migrations/000005_normalize_site_urls.down.sql @@ -0,0 +1 @@ +UPDATE websites SET SiteUrl = substr(SiteUrl, 8) WHERE substr(SiteUrl, 1, 4) = 'http'; diff --git a/migrations/000005_normalize_site_urls.up.sql b/migrations/000005_normalize_site_urls.up.sql new file mode 100644 index 0000000..a9ea2b3 --- /dev/null +++ b/migrations/000005_normalize_site_urls.up.sql @@ -0,0 +1 @@ +UPDATE websites SET SiteUrl = 'http://' || SiteUrl WHERE substr(SiteUrl, 1, 4) <> 'http'; diff --git a/ui/views/guestbooks.templ b/ui/views/guestbooks.templ index 8004437..080d947 100644 --- a/ui/views/guestbooks.templ +++ b/ui/views/guestbooks.templ @@ -10,7 +10,7 @@ templ GuestbookDashboardCommentsView(title string, data CommonData, website mode
No comments yet!
diff --git a/ui/views/guestbooks_templ.go b/ui/views/guestbooks_templ.go index 5b12c21..7d167f9 100644 --- a/ui/views/guestbooks_templ.go +++ b/ui/views/guestbooks_templ.go @@ -59,9 +59,9 @@ func GuestbookDashboardCommentsView(title string, data CommonData, website model return templ_7745c5c3_Err } var templ_7745c5c3_Var3 string - templ_7745c5c3_Var3, templ_7745c5c3_Err = templ.JoinStringErrs(website.SiteUrl) + templ_7745c5c3_Var3, templ_7745c5c3_Err = templ.JoinStringErrs(website.Name) if templ_7745c5c3_Err != nil { - return templ.Error{Err: templ_7745c5c3_Err, FileName: `ui/views/guestbooks.templ`, Line: 13, Col: 37} + return templ.Error{Err: templ_7745c5c3_Err, FileName: `ui/views/guestbooks.templ`, Line: 13, Col: 34} } _, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var3)) if templ_7745c5c3_Err != nil { diff --git a/ui/views/websites.templ b/ui/views/websites.templ index db383dd..e8c29d6 100644 --- a/ui/views/websites.templ +++ b/ui/views/websites.templ @@ -16,7 +16,7 @@ templ wSidebar(website models.Website) {
-
- { fmt.Sprintf(formStr, postUrl) }
-
-
-}
-
-templ embedJavaScriptSnippet(root string, website models.Website) {
+ @base(title, data) {
+
+ }
}
diff --git a/ui/views/websites_templ.go b/ui/views/websites_templ.go
index e8aee69..83e490a 100644
--- a/ui/views/websites_templ.go
+++ b/ui/views/websites_templ.go
@@ -65,7 +65,7 @@ func wSidebar(website models.Website) templ.Component {
if templ_7745c5c3_Err != nil {
return templ_7745c5c3_Err
}
- var templ_7745c5c3_Var4 templ.SafeURL = templ.URL(externalUrl(website.SiteUrl))
+ var templ_7745c5c3_Var4 templ.SafeURL = templ.URL(externalUrl(website.Url.String()))
_, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(string(templ_7745c5c3_Var4)))
if templ_7745c5c3_Err != nil {
return templ_7745c5c3_Err
@@ -271,92 +271,102 @@ func websiteCreateForm(csrfToken string, form forms.WebsiteCreateForm) templ.Com
return templ_7745c5c3_Err
}
}
- templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 23, "Upload this JavaScript WebComponent to your site and include it in your ")
- if templ_7745c5c3_Err != nil {
- return templ_7745c5c3_Err
- }
- var templ_7745c5c3_Var26 string
- templ_7745c5c3_Var26, templ_7745c5c3_Err = templ.JoinStringErrs(``)
- if templ_7745c5c3_Err != nil {
- return templ.Error{Err: templ_7745c5c3_Err, FileName: `ui/views/websites.templ`, Line: 120, Col: 140}
- }
- _, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var26))
- if templ_7745c5c3_Err != nil {
- return templ_7745c5c3_Err
- }
- templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 39, "
tag.
")
+ templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 38, "")
if templ_7745c5c3_Err != nil {
return templ_7745c5c3_Err
}
var templ_7745c5c3_Var27 string
- templ_7745c5c3_Var27, templ_7745c5c3_Err = templ.JoinStringErrs(
- `
-
-`)
+ templ_7745c5c3_Var27, templ_7745c5c3_Err = templ.JoinStringErrs(website.Name)
if templ_7745c5c3_Err != nil {
- return templ.Error{Err: templ_7745c5c3_Err, FileName: `ui/views/websites.templ`, Line: 129, Col: 8}
+ return templ.Error{Err: templ_7745c5c3_Err, FileName: `ui/views/websites.templ`, Line: 113, Col: 22}
}
_, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var27))
if templ_7745c5c3_Err != nil {
return templ_7745c5c3_Err
}
- templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 40, "
Then add the custom elements where you want your form and comments to show up
")
- if templ_7745c5c3_Err != nil {
- return templ_7745c5c3_Err
- }
- gbUrl := fmt.Sprintf("https://%s/websites/%s/guestbook", data.RootUrl, shortIdToSlug(website.ShortId))
- templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 41, "")
+ templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 39, "Embed your Guestbook
Upload this JavaScript WebComponent to your site and include it in your ")
if templ_7745c5c3_Err != nil {
return templ_7745c5c3_Err
}
var templ_7745c5c3_Var28 string
- templ_7745c5c3_Var28, templ_7745c5c3_Err = templ.JoinStringErrs(fmt.Sprintf(`
- `, gbUrl, gbUrl))
+ templ_7745c5c3_Var28, templ_7745c5c3_Err = templ.JoinStringErrs(``)
if templ_7745c5c3_Err != nil {
- return templ.Error{Err: templ_7745c5c3_Err, FileName: `ui/views/websites.templ`, Line: 140, Col: 72}
+ return templ.Error{Err: templ_7745c5c3_Err, FileName: `ui/views/websites.templ`, Line: 116, Col: 140}
}
_, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var28))
if templ_7745c5c3_Err != nil {
return templ_7745c5c3_Err
}
- templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 42, "
If your web host does not allow CORS requests, use an iframe instead
")
+ templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 40, "
tag.")
if templ_7745c5c3_Err != nil {
return templ_7745c5c3_Err
}
var templ_7745c5c3_Var29 string
- templ_7745c5c3_Var29, templ_7745c5c3_Err = templ.JoinStringErrs(fmt.Sprintf(``, gbUrl))
+ templ_7745c5c3_Var29, templ_7745c5c3_Err = templ.JoinStringErrs(
+ `
+
+`)
if templ_7745c5c3_Err != nil {
- return templ.Error{Err: templ_7745c5c3_Err, FileName: `ui/views/websites.templ`, Line: 150, Col: 75}
+ return templ.Error{Err: templ_7745c5c3_Err, FileName: `ui/views/websites.templ`, Line: 125, Col: 8}
}
_, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var29))
if templ_7745c5c3_Err != nil {
return templ_7745c5c3_Err
}
- templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 43, "
Then add the custom elements where you want your form and comments to show up
") + if templ_7745c5c3_Err != nil { + return templ_7745c5c3_Err + } + gbUrl := fmt.Sprintf("https://%s/websites/%s/guestbook", data.RootUrl, shortIdToSlug(website.ShortId)) + templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 42, "")
+ if templ_7745c5c3_Err != nil {
+ return templ_7745c5c3_Err
+ }
+ var templ_7745c5c3_Var30 string
+ templ_7745c5c3_Var30, templ_7745c5c3_Err = templ.JoinStringErrs(fmt.Sprintf(`
+ `, gbUrl, gbUrl))
+ if templ_7745c5c3_Err != nil {
+ return templ.Error{Err: templ_7745c5c3_Err, FileName: `ui/views/websites.templ`, Line: 136, Col: 72}
+ }
+ _, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var30))
+ if templ_7745c5c3_Err != nil {
+ return templ_7745c5c3_Err
+ }
+ templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 43, "
If your web host does not allow CORS requests, use an iframe instead
")
+ if templ_7745c5c3_Err != nil {
+ return templ_7745c5c3_Err
+ }
+ var templ_7745c5c3_Var31 string
+ templ_7745c5c3_Var31, templ_7745c5c3_Err = templ.JoinStringErrs(fmt.Sprintf(``, gbUrl))
+ if templ_7745c5c3_Err != nil {
+ return templ.Error{Err: templ_7745c5c3_Err, FileName: `ui/views/websites.templ`, Line: 146, Col: 75}
+ }
+ _, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var31))
+ if templ_7745c5c3_Err != nil {
+ return templ_7745c5c3_Err
+ }
+ templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 44, "
Coming Soon
Coming Soon
")
- if templ_7745c5c3_Err != nil {
- return templ_7745c5c3_Err
- }
- var templ_7745c5c3_Var35 string
- templ_7745c5c3_Var35, templ_7745c5c3_Err = templ.JoinStringErrs(fmt.Sprintf(formStr, postUrl))
- if templ_7745c5c3_Err != nil {
- return templ.Error{Err: templ_7745c5c3_Err, FileName: `ui/views/websites.templ`, Line: 206, Col: 34}
- }
- _, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var35))
- if templ_7745c5c3_Err != nil {
- return templ_7745c5c3_Err
- }
- templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 50, "
")
- if templ_7745c5c3_Err != nil {
- return templ_7745c5c3_Err
- }
- return nil
- })
-}
-
-func embedJavaScriptSnippet(root string, website models.Website) templ.Component {
- return templruntime.GeneratedTemplate(func(templ_7745c5c3_Input templruntime.GeneratedComponentInput) (templ_7745c5c3_Err error) {
- templ_7745c5c3_W, ctx := templ_7745c5c3_Input.Writer, templ_7745c5c3_Input.Context
- if templ_7745c5c3_CtxErr := ctx.Err(); templ_7745c5c3_CtxErr != nil {
- return templ_7745c5c3_CtxErr
- }
- templ_7745c5c3_Buffer, templ_7745c5c3_IsBuffer := templruntime.GetBuffer(templ_7745c5c3_W)
- if !templ_7745c5c3_IsBuffer {
- defer func() {
- templ_7745c5c3_BufErr := templruntime.ReleaseBuffer(templ_7745c5c3_Buffer)
- if templ_7745c5c3_Err == nil {
- templ_7745c5c3_Err = templ_7745c5c3_BufErr
- }
- }()
- }
- ctx = templ.InitializeContext(ctx)
- templ_7745c5c3_Var36 := templ.GetChildren(ctx)
- if templ_7745c5c3_Var36 == nil {
- templ_7745c5c3_Var36 = templ.NopComponent
- }
- ctx = templ.ClearChildren(ctx)
return nil
})
}