Implement remote embedding of guestbooks #25
| @ -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() { | ||||
|  | ||||
| @ -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) | ||||
| 		}) | ||||
| 	} | ||||
| } | ||||
|  | ||||
| @ -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) | ||||
| } | ||||
|  | ||||
| @ -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 | ||||
| } | ||||
|  | ||||
| @ -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: | ||||
|  | ||||
| @ -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(), | ||||
|  | ||||
| @ -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 { | ||||
|  | ||||
| @ -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) | ||||
| } | ||||
|  | ||||
							
								
								
									
										1
									
								
								migrations/000005_normalize_site_urls.down.sql
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										1
									
								
								migrations/000005_normalize_site_urls.down.sql
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1 @@ | ||||
| UPDATE websites SET SiteUrl = substr(SiteUrl, 8) WHERE substr(SiteUrl, 1, 4) = 'http'; | ||||
							
								
								
									
										1
									
								
								migrations/000005_normalize_site_urls.up.sql
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										1
									
								
								migrations/000005_normalize_site_urls.up.sql
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1 @@ | ||||
| UPDATE websites SET SiteUrl = 'http://' || SiteUrl WHERE substr(SiteUrl, 1, 4) <> 'http'; | ||||
| @ -10,7 +10,7 @@ templ GuestbookDashboardCommentsView(title string, data CommonData, website mode | ||||
| 		<div id="dashboard"> | ||||
| 			@wSidebar(website) | ||||
| 			<div> | ||||
| 				<h1>Comments on { website.SiteUrl }</h1> | ||||
| 				<h1>Comments on { website.Name }</h1> | ||||
| 				<hr/> | ||||
| 				if len(comments) == 0 { | ||||
| 					<p>No comments yet!</p> | ||||
|  | ||||
| @ -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 { | ||||
|  | ||||
| @ -16,7 +16,7 @@ templ wSidebar(website models.Website) { | ||||
| 			<h2>{ website.Name }</h2> | ||||
| 			<ul> | ||||
| 				<li><a href={ templ.URL(dashUrl) }>Dashboard</a></li> | ||||
| 				<li><a href={ templ.URL(externalUrl(website.SiteUrl)) } target="_blank">View Website</a></li> | ||||
| 				<li><a href={ templ.URL(externalUrl(website.Url.String())) } target="_blank">View Website</a></li> | ||||
| 			</ul> | ||||
| 			<h3>Guestbook</h3> | ||||
| 			<ul> | ||||
| @ -70,7 +70,7 @@ templ websiteCreateForm(csrfToken string, form forms.WebsiteCreateForm) { | ||||
| 		if exists { | ||||
| 			<label class="error">{ err }</label> | ||||
| 		} | ||||
| 		<input type="text" name="sitename" id="sitename" required/> | ||||
| 		<input type="text" name="sitename" id="sitename" value={ form.Name } required/> | ||||
| 	</div> | ||||
| 	<div> | ||||
| 		{{ err, exists = form.FieldErrors["siteurl"] }} | ||||
| @ -78,7 +78,7 @@ templ websiteCreateForm(csrfToken string, form forms.WebsiteCreateForm) { | ||||
| 		if exists { | ||||
| 			<label class="error">{ err }</label> | ||||
| 		} | ||||
| 		<input type="text" name="siteurl" id="siteurl" required/> | ||||
| 		<input type="text" name="siteurl" id="siteurl" value={ form.SiteUrl } required/> | ||||
| 	</div> | ||||
| 	<div> | ||||
| 		{{ err, exists = form.FieldErrors["authorname"] }} | ||||
| @ -86,22 +86,18 @@ templ websiteCreateForm(csrfToken string, form forms.WebsiteCreateForm) { | ||||
| 		if exists { | ||||
| 			<label class="error">{ err }</label> | ||||
| 		} | ||||
| 		<input type="text" name="authorname" id="authorname" required/> | ||||
| 		<input type="text" name="authorname" id="authorname" value={ form.AuthorName } required/> | ||||
| 	</div> | ||||
| 	<div> | ||||
| 		<button type="submit">Submit</button> | ||||
| 	</div> | ||||
| } | ||||
| 
 | ||||
| templ WebsiteCreateButton() { | ||||
| 	<button hx-get="/websites/create" hx-target="closest div">Add Website</button> | ||||
| } | ||||
| 
 | ||||
| templ WebsiteList(title string, data CommonData, websites []models.Website) { | ||||
| 	@base(title, data) { | ||||
| 		<h1>My Websites</h1> | ||||
| 		<div> | ||||
| 			@WebsiteCreateButton() | ||||
| 			<a href="/websites/create">Add Website</a> | ||||
| 		</div> | ||||
| 		<div> | ||||
| 			@displayWebsites(websites) | ||||
| @ -171,42 +167,9 @@ templ WebsiteDashboardComingSoon(title string, data CommonData, website models.W | ||||
| } | ||||
| 
 | ||||
| templ WebsiteCreate(title string, data CommonData, form forms.WebsiteCreateForm) { | ||||
| 	<form hx-post="/websites/create" hx-target="closest div"> | ||||
| 		@websiteCreateForm(data.CSRFToken, form) | ||||
| 	</form> | ||||
| } | ||||
| 
 | ||||
| templ embeddableForm(root string, website models.Website) { | ||||
| 	{{ postUrl := fmt.Sprintf("https://%s/websites/%s/guestbook/comments/create/remote", root, shortIdToSlug(website.ShortId)) }} | ||||
| 	{{formStr := | ||||
| 	`<form action="%s" method="post"> | ||||
|         <div> | ||||
|             <label for="authorname">Name</label> | ||||
|             <input type="text" name="authorname" id="authorname"/> | ||||
|         </div> | ||||
|         <div> | ||||
|             <label for="authoremail">Email (Optional) </label> | ||||
|             <input type="text" name="authoremail" id="authoremail"/> | ||||
|         </div> | ||||
|         <div> | ||||
|             <label for="authorsite">Site Url (Optional) </label> | ||||
|             <input type="text" name="authorsite" id="authorsite"/> | ||||
|         </div> | ||||
|         <div> | ||||
|             <label for="content">Comment</label> | ||||
|             <textarea name="content" id="content"></textarea> | ||||
|         </div> | ||||
|         <div> | ||||
|             <input type="submit" value="Submit"/> | ||||
|         </div> | ||||
| </form>` | ||||
| 	}} | ||||
| 	<pre> | ||||
| 		<code> | ||||
| 			{ fmt.Sprintf(formStr, postUrl) } | ||||
| 		</code> | ||||
| 	</pre> | ||||
| } | ||||
| 
 | ||||
| templ embedJavaScriptSnippet(root string, website models.Website) { | ||||
| 	@base(title, data) { | ||||
| 		<form action="/websites/create" method="post"> | ||||
| 			@websiteCreateForm(data.CSRFToken, form) | ||||
| 		</form> | ||||
| 	} | ||||
| } | ||||
|  | ||||
| @ -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, "<input type=\"text\" name=\"sitename\" id=\"sitename\" required></div><div>") | ||||
| 		templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 23, "<input type=\"text\" name=\"sitename\" id=\"sitename\" value=\"") | ||||
| 		if templ_7745c5c3_Err != nil { | ||||
| 			return templ_7745c5c3_Err | ||||
| 		} | ||||
| 		var templ_7745c5c3_Var18 string | ||||
| 		templ_7745c5c3_Var18, templ_7745c5c3_Err = templ.JoinStringErrs(form.Name) | ||||
| 		if templ_7745c5c3_Err != nil { | ||||
| 			return templ.Error{Err: templ_7745c5c3_Err, FileName: `ui/views/websites.templ`, Line: 73, Col: 68} | ||||
| 		} | ||||
| 		_, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var18)) | ||||
| 		if templ_7745c5c3_Err != nil { | ||||
| 			return templ_7745c5c3_Err | ||||
| 		} | ||||
| 		templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 24, "\" required></div><div>") | ||||
| 		if templ_7745c5c3_Err != nil { | ||||
| 			return templ_7745c5c3_Err | ||||
| 		} | ||||
| 		err, exists = form.FieldErrors["siteurl"] | ||||
| 		templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 24, "<label for=\"siteurl\">Site URL: </label> ") | ||||
| 		templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 25, "<label for=\"siteurl\">Site URL: </label> ") | ||||
| 		if templ_7745c5c3_Err != nil { | ||||
| 			return templ_7745c5c3_Err | ||||
| 		} | ||||
| 		if exists { | ||||
| 			templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 25, "<label class=\"error\">") | ||||
| 			if templ_7745c5c3_Err != nil { | ||||
| 				return templ_7745c5c3_Err | ||||
| 			} | ||||
| 			var templ_7745c5c3_Var18 string | ||||
| 			templ_7745c5c3_Var18, templ_7745c5c3_Err = templ.JoinStringErrs(err) | ||||
| 			if templ_7745c5c3_Err != nil { | ||||
| 				return templ.Error{Err: templ_7745c5c3_Err, FileName: `ui/views/websites.templ`, Line: 79, Col: 29} | ||||
| 			} | ||||
| 			_, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var18)) | ||||
| 			if templ_7745c5c3_Err != nil { | ||||
| 				return templ_7745c5c3_Err | ||||
| 			} | ||||
| 			templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 26, "</label> ") | ||||
| 			if templ_7745c5c3_Err != nil { | ||||
| 				return templ_7745c5c3_Err | ||||
| 			} | ||||
| 		} | ||||
| 		templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 27, "<input type=\"text\" name=\"siteurl\" id=\"siteurl\" required></div><div>") | ||||
| 		if templ_7745c5c3_Err != nil { | ||||
| 			return templ_7745c5c3_Err | ||||
| 		} | ||||
| 		err, exists = form.FieldErrors["authorname"] | ||||
| 		templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 28, "<label for=\"authorname\">Site Author: </label> ") | ||||
| 		if templ_7745c5c3_Err != nil { | ||||
| 			return templ_7745c5c3_Err | ||||
| 		} | ||||
| 		if exists { | ||||
| 			templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 29, "<label class=\"error\">") | ||||
| 			templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 26, "<label class=\"error\">") | ||||
| 			if templ_7745c5c3_Err != nil { | ||||
| 				return templ_7745c5c3_Err | ||||
| 			} | ||||
| 			var templ_7745c5c3_Var19 string | ||||
| 			templ_7745c5c3_Var19, templ_7745c5c3_Err = templ.JoinStringErrs(err) | ||||
| 			if templ_7745c5c3_Err != nil { | ||||
| 				return templ.Error{Err: templ_7745c5c3_Err, FileName: `ui/views/websites.templ`, Line: 87, Col: 29} | ||||
| 				return templ.Error{Err: templ_7745c5c3_Err, FileName: `ui/views/websites.templ`, Line: 79, Col: 29} | ||||
| 			} | ||||
| 			_, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var19)) | ||||
| 			if templ_7745c5c3_Err != nil { | ||||
| 				return templ_7745c5c3_Err | ||||
| 			} | ||||
| 			templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 30, "</label> ") | ||||
| 			templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 27, "</label> ") | ||||
| 			if templ_7745c5c3_Err != nil { | ||||
| 				return templ_7745c5c3_Err | ||||
| 			} | ||||
| 		} | ||||
| 		templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 31, "<input type=\"text\" name=\"authorname\" id=\"authorname\" required></div><div><button type=\"submit\">Submit</button></div>") | ||||
| 		templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 28, "<input type=\"text\" name=\"siteurl\" id=\"siteurl\" value=\"") | ||||
| 		if templ_7745c5c3_Err != nil { | ||||
| 			return templ_7745c5c3_Err | ||||
| 		} | ||||
| 		return nil | ||||
| 	}) | ||||
| } | ||||
| 
 | ||||
| func WebsiteCreateButton() 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 | ||||
| 		var templ_7745c5c3_Var20 string | ||||
| 		templ_7745c5c3_Var20, templ_7745c5c3_Err = templ.JoinStringErrs(form.SiteUrl) | ||||
| 		if templ_7745c5c3_Err != nil { | ||||
| 			return templ.Error{Err: templ_7745c5c3_Err, FileName: `ui/views/websites.templ`, Line: 81, Col: 69} | ||||
| 		} | ||||
| 		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 | ||||
| 				} | ||||
| 			}() | ||||
| 		_, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var20)) | ||||
| 		if templ_7745c5c3_Err != nil { | ||||
| 			return templ_7745c5c3_Err | ||||
| 		} | ||||
| 		ctx = templ.InitializeContext(ctx) | ||||
| 		templ_7745c5c3_Var20 := templ.GetChildren(ctx) | ||||
| 		if templ_7745c5c3_Var20 == nil { | ||||
| 			templ_7745c5c3_Var20 = templ.NopComponent | ||||
| 		templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 29, "\" required></div><div>") | ||||
| 		if templ_7745c5c3_Err != nil { | ||||
| 			return templ_7745c5c3_Err | ||||
| 		} | ||||
| 		ctx = templ.ClearChildren(ctx) | ||||
| 		templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 32, "<button hx-get=\"/websites/create\" hx-target=\"closest div\">Add Website</button>") | ||||
| 		err, exists = form.FieldErrors["authorname"] | ||||
| 		templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 30, "<label for=\"authorname\">Site Author: </label> ") | ||||
| 		if templ_7745c5c3_Err != nil { | ||||
| 			return templ_7745c5c3_Err | ||||
| 		} | ||||
| 		if exists { | ||||
| 			templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 31, "<label class=\"error\">") | ||||
| 			if templ_7745c5c3_Err != nil { | ||||
| 				return templ_7745c5c3_Err | ||||
| 			} | ||||
| 			var templ_7745c5c3_Var21 string | ||||
| 			templ_7745c5c3_Var21, templ_7745c5c3_Err = templ.JoinStringErrs(err) | ||||
| 			if templ_7745c5c3_Err != nil { | ||||
| 				return templ.Error{Err: templ_7745c5c3_Err, FileName: `ui/views/websites.templ`, Line: 87, Col: 29} | ||||
| 			} | ||||
| 			_, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var21)) | ||||
| 			if templ_7745c5c3_Err != nil { | ||||
| 				return templ_7745c5c3_Err | ||||
| 			} | ||||
| 			templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 32, "</label> ") | ||||
| 			if templ_7745c5c3_Err != nil { | ||||
| 				return templ_7745c5c3_Err | ||||
| 			} | ||||
| 		} | ||||
| 		templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 33, "<input type=\"text\" name=\"authorname\" id=\"authorname\" value=\"") | ||||
| 		if templ_7745c5c3_Err != nil { | ||||
| 			return templ_7745c5c3_Err | ||||
| 		} | ||||
| 		var templ_7745c5c3_Var22 string | ||||
| 		templ_7745c5c3_Var22, templ_7745c5c3_Err = templ.JoinStringErrs(form.AuthorName) | ||||
| 		if templ_7745c5c3_Err != nil { | ||||
| 			return templ.Error{Err: templ_7745c5c3_Err, FileName: `ui/views/websites.templ`, Line: 89, Col: 78} | ||||
| 		} | ||||
| 		_, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var22)) | ||||
| 		if templ_7745c5c3_Err != nil { | ||||
| 			return templ_7745c5c3_Err | ||||
| 		} | ||||
| 		templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 34, "\" required></div><div><button type=\"submit\">Submit</button></div>") | ||||
| 		if templ_7745c5c3_Err != nil { | ||||
| 			return templ_7745c5c3_Err | ||||
| 		} | ||||
| @ -365,69 +375,6 @@ func WebsiteCreateButton() templ.Component { | ||||
| } | ||||
| 
 | ||||
| func WebsiteList(title string, data CommonData, websites []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_Var21 := templ.GetChildren(ctx) | ||||
| 		if templ_7745c5c3_Var21 == nil { | ||||
| 			templ_7745c5c3_Var21 = templ.NopComponent | ||||
| 		} | ||||
| 		ctx = templ.ClearChildren(ctx) | ||||
| 		templ_7745c5c3_Var22 := templruntime.GeneratedTemplate(func(templ_7745c5c3_Input templruntime.GeneratedComponentInput) (templ_7745c5c3_Err error) { | ||||
| 			templ_7745c5c3_W, ctx := templ_7745c5c3_Input.Writer, templ_7745c5c3_Input.Context | ||||
| 			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_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 33, "<h1>My Websites</h1><div>") | ||||
| 			if templ_7745c5c3_Err != nil { | ||||
| 				return templ_7745c5c3_Err | ||||
| 			} | ||||
| 			templ_7745c5c3_Err = WebsiteCreateButton().Render(ctx, templ_7745c5c3_Buffer) | ||||
| 			if templ_7745c5c3_Err != nil { | ||||
| 				return templ_7745c5c3_Err | ||||
| 			} | ||||
| 			templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 34, "</div><div>") | ||||
| 			if templ_7745c5c3_Err != nil { | ||||
| 				return templ_7745c5c3_Err | ||||
| 			} | ||||
| 			templ_7745c5c3_Err = displayWebsites(websites).Render(ctx, templ_7745c5c3_Buffer) | ||||
| 			if templ_7745c5c3_Err != nil { | ||||
| 				return templ_7745c5c3_Err | ||||
| 			} | ||||
| 			templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 35, "</div>") | ||||
| 			if templ_7745c5c3_Err != nil { | ||||
| 				return templ_7745c5c3_Err | ||||
| 			} | ||||
| 			return nil | ||||
| 		}) | ||||
| 		templ_7745c5c3_Err = base(title, data).Render(templ.WithChildren(ctx, templ_7745c5c3_Var22), templ_7745c5c3_Buffer) | ||||
| 		if templ_7745c5c3_Err != nil { | ||||
| 			return templ_7745c5c3_Err | ||||
| 		} | ||||
| 		return nil | ||||
| 	}) | ||||
| } | ||||
| 
 | ||||
| func WebsiteDashboard(title string, data CommonData, 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 { | ||||
| @ -460,7 +407,62 @@ func WebsiteDashboard(title string, data CommonData, website models.Website) tem | ||||
| 				}() | ||||
| 			} | ||||
| 			ctx = templ.InitializeContext(ctx) | ||||
| 			templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 36, "<div id=\"dashboard\">") | ||||
| 			templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 35, "<h1>My Websites</h1><div><a href=\"/websites/create\">Add Website</a></div><div>") | ||||
| 			if templ_7745c5c3_Err != nil { | ||||
| 				return templ_7745c5c3_Err | ||||
| 			} | ||||
| 			templ_7745c5c3_Err = displayWebsites(websites).Render(ctx, templ_7745c5c3_Buffer) | ||||
| 			if templ_7745c5c3_Err != nil { | ||||
| 				return templ_7745c5c3_Err | ||||
| 			} | ||||
| 			templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 36, "</div>") | ||||
| 			if templ_7745c5c3_Err != nil { | ||||
| 				return templ_7745c5c3_Err | ||||
| 			} | ||||
| 			return nil | ||||
| 		}) | ||||
| 		templ_7745c5c3_Err = base(title, data).Render(templ.WithChildren(ctx, templ_7745c5c3_Var24), templ_7745c5c3_Buffer) | ||||
| 		if templ_7745c5c3_Err != nil { | ||||
| 			return templ_7745c5c3_Err | ||||
| 		} | ||||
| 		return nil | ||||
| 	}) | ||||
| } | ||||
| 
 | ||||
| func WebsiteDashboard(title string, data CommonData, 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_Var25 := templ.GetChildren(ctx) | ||||
| 		if templ_7745c5c3_Var25 == nil { | ||||
| 			templ_7745c5c3_Var25 = templ.NopComponent | ||||
| 		} | ||||
| 		ctx = templ.ClearChildren(ctx) | ||||
| 		templ_7745c5c3_Var26 := templruntime.GeneratedTemplate(func(templ_7745c5c3_Input templruntime.GeneratedComponentInput) (templ_7745c5c3_Err error) { | ||||
| 			templ_7745c5c3_W, ctx := templ_7745c5c3_Input.Writer, templ_7745c5c3_Input.Context | ||||
| 			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_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 37, "<div id=\"dashboard\">") | ||||
| 			if templ_7745c5c3_Err != nil { | ||||
| 				return templ_7745c5c3_Err | ||||
| 			} | ||||
| @ -468,87 +470,87 @@ func WebsiteDashboard(title string, data CommonData, website models.Website) tem | ||||
| 			if templ_7745c5c3_Err != nil { | ||||
| 				return templ_7745c5c3_Err | ||||
| 			} | ||||
| 			templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 37, "<div><h1>") | ||||
| 			if templ_7745c5c3_Err != nil { | ||||
| 				return templ_7745c5c3_Err | ||||
| 			} | ||||
| 			var templ_7745c5c3_Var25 string | ||||
| 			templ_7745c5c3_Var25, 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: 117, Col: 22} | ||||
| 			} | ||||
| 			_, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var25)) | ||||
| 			if templ_7745c5c3_Err != nil { | ||||
| 				return templ_7745c5c3_Err | ||||
| 			} | ||||
| 			templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 38, "</h1><h2>Embed your Guestbook</h2><p>Upload <a href=\"/static/js/guestbook.js\" download>this JavaScript WebComponent</a> to your site and include it in your <code>") | ||||
| 			if templ_7745c5c3_Err != nil { | ||||
| 				return templ_7745c5c3_Err | ||||
| 			} | ||||
| 			var templ_7745c5c3_Var26 string | ||||
| 			templ_7745c5c3_Var26, templ_7745c5c3_Err = templ.JoinStringErrs(`<head>`) | ||||
| 			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, "</code> tag.</p><div><pre><code id=\"guestbookSnippet\">") | ||||
| 			templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 38, "<div><h1>") | ||||
| 			if templ_7745c5c3_Err != nil { | ||||
| 				return templ_7745c5c3_Err | ||||
| 			} | ||||
| 			var templ_7745c5c3_Var27 string | ||||
| 			templ_7745c5c3_Var27, templ_7745c5c3_Err = templ.JoinStringErrs( | ||||
| 				`<head> | ||||
|     <script type="module" src="js/guestbook.js"></script> | ||||
| </head>`) | ||||
| 			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, "</code></pre><p>Then add the custom elements where you want your form and comments to show up</p>") | ||||
| 			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, "<pre><code>") | ||||
| 			templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 39, "</h1><h2>Embed your Guestbook</h2><p>Upload <a href=\"/static/js/guestbook.js\" download>this JavaScript WebComponent</a> to your site and include it in your <code>") | ||||
| 			if templ_7745c5c3_Err != nil { | ||||
| 				return templ_7745c5c3_Err | ||||
| 			} | ||||
| 			var templ_7745c5c3_Var28 string | ||||
| 			templ_7745c5c3_Var28, templ_7745c5c3_Err = templ.JoinStringErrs(fmt.Sprintf(`<guestbook-form guestbook="%s"></guestbook-form> | ||||
| <guestbook-comments guestbook="%s"></guestbook-comments>`, gbUrl, gbUrl)) | ||||
| 			templ_7745c5c3_Var28, templ_7745c5c3_Err = templ.JoinStringErrs(`<head>`) | ||||
| 			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, "</code></pre></div><p>If your web host does not allow CORS requests, use an iframe instead</p><div><pre><code>") | ||||
| 			templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 40, "</code> tag.</p><div><pre><code id=\"guestbookSnippet\">") | ||||
| 			if templ_7745c5c3_Err != nil { | ||||
| 				return templ_7745c5c3_Err | ||||
| 			} | ||||
| 			var templ_7745c5c3_Var29 string | ||||
| 			templ_7745c5c3_Var29, templ_7745c5c3_Err = templ.JoinStringErrs(fmt.Sprintf(`<iframe src="%s" title="Guestbook"></iframe>`, gbUrl)) | ||||
| 			templ_7745c5c3_Var29, templ_7745c5c3_Err = templ.JoinStringErrs( | ||||
| 				`<head> | ||||
|     <script type="module" src="js/guestbook.js"></script> | ||||
| </head>`) | ||||
| 			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, "</code></pre></div></div></div>") | ||||
| 			templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 41, "</code></pre><p>Then add the custom elements where you want your form and comments to show up</p>") | ||||
| 			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, "<pre><code>") | ||||
| 			if templ_7745c5c3_Err != nil { | ||||
| 				return templ_7745c5c3_Err | ||||
| 			} | ||||
| 			var templ_7745c5c3_Var30 string | ||||
| 			templ_7745c5c3_Var30, templ_7745c5c3_Err = templ.JoinStringErrs(fmt.Sprintf(`<guestbook-form guestbook="%s"></guestbook-form> | ||||
| <guestbook-comments guestbook="%s"></guestbook-comments>`, 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, "</code></pre></div><p>If your web host does not allow CORS requests, use an iframe instead</p><div><pre><code>") | ||||
| 			if templ_7745c5c3_Err != nil { | ||||
| 				return templ_7745c5c3_Err | ||||
| 			} | ||||
| 			var templ_7745c5c3_Var31 string | ||||
| 			templ_7745c5c3_Var31, templ_7745c5c3_Err = templ.JoinStringErrs(fmt.Sprintf(`<iframe src="%s" title="Guestbook"></iframe>`, 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, "</code></pre></div></div></div>") | ||||
| 			if templ_7745c5c3_Err != nil { | ||||
| 				return templ_7745c5c3_Err | ||||
| 			} | ||||
| 			return nil | ||||
| 		}) | ||||
| 		templ_7745c5c3_Err = base(title, data).Render(templ.WithChildren(ctx, templ_7745c5c3_Var24), templ_7745c5c3_Buffer) | ||||
| 		templ_7745c5c3_Err = base(title, data).Render(templ.WithChildren(ctx, templ_7745c5c3_Var26), templ_7745c5c3_Buffer) | ||||
| 		if templ_7745c5c3_Err != nil { | ||||
| 			return templ_7745c5c3_Err | ||||
| 		} | ||||
| @ -572,12 +574,12 @@ func WebsiteDashboardComingSoon(title string, data CommonData, website models.We | ||||
| 			}() | ||||
| 		} | ||||
| 		ctx = templ.InitializeContext(ctx) | ||||
| 		templ_7745c5c3_Var30 := templ.GetChildren(ctx) | ||||
| 		if templ_7745c5c3_Var30 == nil { | ||||
| 			templ_7745c5c3_Var30 = templ.NopComponent | ||||
| 		templ_7745c5c3_Var32 := templ.GetChildren(ctx) | ||||
| 		if templ_7745c5c3_Var32 == nil { | ||||
| 			templ_7745c5c3_Var32 = templ.NopComponent | ||||
| 		} | ||||
| 		ctx = templ.ClearChildren(ctx) | ||||
| 		templ_7745c5c3_Var31 := templruntime.GeneratedTemplate(func(templ_7745c5c3_Input templruntime.GeneratedComponentInput) (templ_7745c5c3_Err error) { | ||||
| 		templ_7745c5c3_Var33 := templruntime.GeneratedTemplate(func(templ_7745c5c3_Input templruntime.GeneratedComponentInput) (templ_7745c5c3_Err error) { | ||||
| 			templ_7745c5c3_W, ctx := templ_7745c5c3_Input.Writer, templ_7745c5c3_Input.Context | ||||
| 			templ_7745c5c3_Buffer, templ_7745c5c3_IsBuffer := templruntime.GetBuffer(templ_7745c5c3_W) | ||||
| 			if !templ_7745c5c3_IsBuffer { | ||||
| @ -589,7 +591,7 @@ func WebsiteDashboardComingSoon(title string, data CommonData, website models.We | ||||
| 				}() | ||||
| 			} | ||||
| 			ctx = templ.InitializeContext(ctx) | ||||
| 			templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 44, "<div id=\"dashboard\">") | ||||
| 			templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 45, "<div id=\"dashboard\">") | ||||
| 			if templ_7745c5c3_Err != nil { | ||||
| 				return templ_7745c5c3_Err | ||||
| 			} | ||||
| @ -597,26 +599,26 @@ func WebsiteDashboardComingSoon(title string, data CommonData, website models.We | ||||
| 			if templ_7745c5c3_Err != nil { | ||||
| 				return templ_7745c5c3_Err | ||||
| 			} | ||||
| 			templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 45, "<div><h1>") | ||||
| 			templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 46, "<div><h1>") | ||||
| 			if templ_7745c5c3_Err != nil { | ||||
| 				return templ_7745c5c3_Err | ||||
| 			} | ||||
| 			var templ_7745c5c3_Var32 string | ||||
| 			templ_7745c5c3_Var32, templ_7745c5c3_Err = templ.JoinStringErrs(website.Name) | ||||
| 			var templ_7745c5c3_Var34 string | ||||
| 			templ_7745c5c3_Var34, 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: 164, Col: 22} | ||||
| 				return templ.Error{Err: templ_7745c5c3_Err, FileName: `ui/views/websites.templ`, Line: 160, Col: 22} | ||||
| 			} | ||||
| 			_, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var32)) | ||||
| 			_, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var34)) | ||||
| 			if templ_7745c5c3_Err != nil { | ||||
| 				return templ_7745c5c3_Err | ||||
| 			} | ||||
| 			templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 46, "</h1><p>Coming Soon</p></div></div>") | ||||
| 			templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 47, "</h1><p>Coming Soon</p></div></div>") | ||||
| 			if templ_7745c5c3_Err != nil { | ||||
| 				return templ_7745c5c3_Err | ||||
| 			} | ||||
| 			return nil | ||||
| 		}) | ||||
| 		templ_7745c5c3_Err = base(title, data).Render(templ.WithChildren(ctx, templ_7745c5c3_Var31), templ_7745c5c3_Buffer) | ||||
| 		templ_7745c5c3_Err = base(title, data).Render(templ.WithChildren(ctx, templ_7745c5c3_Var33), templ_7745c5c3_Buffer) | ||||
| 		if templ_7745c5c3_Err != nil { | ||||
| 			return templ_7745c5c3_Err | ||||
| 		} | ||||
| @ -640,113 +642,41 @@ func WebsiteCreate(title string, data CommonData, form forms.WebsiteCreateForm) | ||||
| 			}() | ||||
| 		} | ||||
| 		ctx = templ.InitializeContext(ctx) | ||||
| 		templ_7745c5c3_Var33 := templ.GetChildren(ctx) | ||||
| 		if templ_7745c5c3_Var33 == nil { | ||||
| 			templ_7745c5c3_Var33 = templ.NopComponent | ||||
| 		templ_7745c5c3_Var35 := templ.GetChildren(ctx) | ||||
| 		if templ_7745c5c3_Var35 == nil { | ||||
| 			templ_7745c5c3_Var35 = templ.NopComponent | ||||
| 		} | ||||
| 		ctx = templ.ClearChildren(ctx) | ||||
| 		templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 47, "<form hx-post=\"/websites/create\" hx-target=\"closest div\">") | ||||
| 		templ_7745c5c3_Var36 := templruntime.GeneratedTemplate(func(templ_7745c5c3_Input templruntime.GeneratedComponentInput) (templ_7745c5c3_Err error) { | ||||
| 			templ_7745c5c3_W, ctx := templ_7745c5c3_Input.Writer, templ_7745c5c3_Input.Context | ||||
| 			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_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 48, "<form action=\"/websites/create\" method=\"post\">") | ||||
| 			if templ_7745c5c3_Err != nil { | ||||
| 				return templ_7745c5c3_Err | ||||
| 			} | ||||
| 			templ_7745c5c3_Err = websiteCreateForm(data.CSRFToken, form).Render(ctx, templ_7745c5c3_Buffer) | ||||
| 			if templ_7745c5c3_Err != nil { | ||||
| 				return templ_7745c5c3_Err | ||||
| 			} | ||||
| 			templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 49, "</form>") | ||||
| 			if templ_7745c5c3_Err != nil { | ||||
| 				return templ_7745c5c3_Err | ||||
| 			} | ||||
| 			return nil | ||||
| 		}) | ||||
| 		templ_7745c5c3_Err = base(title, data).Render(templ.WithChildren(ctx, templ_7745c5c3_Var36), templ_7745c5c3_Buffer) | ||||
| 		if templ_7745c5c3_Err != nil { | ||||
| 			return templ_7745c5c3_Err | ||||
| 		} | ||||
| 		templ_7745c5c3_Err = websiteCreateForm(data.CSRFToken, form).Render(ctx, templ_7745c5c3_Buffer) | ||||
| 		if templ_7745c5c3_Err != nil { | ||||
| 			return templ_7745c5c3_Err | ||||
| 		} | ||||
| 		templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 48, "</form>") | ||||
| 		if templ_7745c5c3_Err != nil { | ||||
| 			return templ_7745c5c3_Err | ||||
| 		} | ||||
| 		return nil | ||||
| 	}) | ||||
| } | ||||
| 
 | ||||
| func embeddableForm(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_Var34 := templ.GetChildren(ctx) | ||||
| 		if templ_7745c5c3_Var34 == nil { | ||||
| 			templ_7745c5c3_Var34 = templ.NopComponent | ||||
| 		} | ||||
| 		ctx = templ.ClearChildren(ctx) | ||||
| 		postUrl := fmt.Sprintf("https://%s/websites/%s/guestbook/comments/create/remote", root, shortIdToSlug(website.ShortId)) | ||||
| 		formStr := | ||||
| 			`<form action="%s" method="post"> | ||||
|         <div> | ||||
|             <label for="authorname">Name</label> | ||||
|             <input type="text" name="authorname" id="authorname"/> | ||||
|         </div> | ||||
|         <div> | ||||
|             <label for="authoremail">Email (Optional) </label> | ||||
|             <input type="text" name="authoremail" id="authoremail"/> | ||||
|         </div> | ||||
|         <div> | ||||
|             <label for="authorsite">Site Url (Optional) </label> | ||||
|             <input type="text" name="authorsite" id="authorsite"/> | ||||
|         </div> | ||||
|         <div> | ||||
|             <label for="content">Comment</label> | ||||
|             <textarea name="content" id="content"></textarea> | ||||
|         </div> | ||||
|         <div> | ||||
|             <input type="submit" value="Submit"/> | ||||
|         </div> | ||||
| </form>` | ||||
| 		templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 49, "<pre><code>") | ||||
| 		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, "</code></pre>") | ||||
| 		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 | ||||
| 	}) | ||||
| } | ||||
|  | ||||
		Loading…
	
	
			
			x
			
			
		
	
		Reference in New Issue
	
	Block a user