Allow articles to be independent of an issue and allow a title for an issue
This commit is contained in:
		| @@ -9,18 +9,20 @@ import ( | |||||||
| ) | ) | ||||||
|  |  | ||||||
| type Article struct { | type Article struct { | ||||||
| 	Title       string | 	Title         string | ||||||
| 	Created     time.Time | 	Created       time.Time | ||||||
| 	Description string | 	Description   string | ||||||
| 	Link        string | 	Link          string | ||||||
| 	EncURL      string | 	EncURL        string | ||||||
| 	EncLength   int | 	EncLength     int | ||||||
| 	EncType     string | 	EncType       string | ||||||
| 	Published   bool | 	Published     bool | ||||||
| 	Rejected    bool | 	Rejected      bool | ||||||
| 	ID          int64 | 	ID            int64 | ||||||
| 	AuthorID    int64 | 	AuthorID      int64 | ||||||
| 	IssueID     int64 | 	IssueID       int64 | ||||||
|  | 	IsInIssue     bool | ||||||
|  | 	AutoGenerated bool | ||||||
| } | } | ||||||
|  |  | ||||||
| func (db *DB) AddArticle(a *Article) (int64, error) { | func (db *DB) AddArticle(a *Article) (int64, error) { | ||||||
| @@ -29,8 +31,8 @@ func (db *DB) AddArticle(a *Article) (int64, error) { | |||||||
| 	selectQuery := "SELECT id FROM issues WHERE published = false" | 	selectQuery := "SELECT id FROM issues WHERE published = false" | ||||||
| 	insertQuery := ` | 	insertQuery := ` | ||||||
|     INSERT INTO articles |     INSERT INTO articles | ||||||
|         (title, description, link, enc_url, enc_length, enc_type, published, rejected, author_id, issue_id) |         (title, description, link, enc_url, enc_length, enc_type, published, rejected, author_id, issue_id, is_in_issue, auto_generated) | ||||||
|     VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?) |     VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?) | ||||||
|     ` |     ` | ||||||
|  |  | ||||||
| 	for i := 0; i < TxMaxRetries; i++ { | 	for i := 0; i < TxMaxRetries; i++ { | ||||||
| @@ -47,8 +49,10 @@ func (db *DB) AddArticle(a *Article) (int64, error) { | |||||||
| 				return 0, fmt.Errorf("error getting issue ID when adding article to DB: %v", err) | 				return 0, fmt.Errorf("error getting issue ID when adding article to DB: %v", err) | ||||||
| 			} | 			} | ||||||
|  |  | ||||||
|  | 			fmt.Println(a) | ||||||
| 			result, err := tx.Exec(insertQuery, a.Title, a.Description, a.Link, | 			result, err := tx.Exec(insertQuery, a.Title, a.Description, a.Link, | ||||||
| 				a.EncURL, a.EncLength, a.EncType, a.Published, a.Rejected, a.AuthorID, id) | 				a.EncURL, a.EncLength, a.EncType, a.Published, a.Rejected, a.AuthorID, id, | ||||||
|  | 				a.IsInIssue, a.AutoGenerated) | ||||||
| 			if err != nil { | 			if err != nil { | ||||||
| 				if rollbackErr := tx.Rollback(); rollbackErr != nil { | 				if rollbackErr := tx.Rollback(); rollbackErr != nil { | ||||||
| 					log.Fatalf("transaction error: %v, rollback error: %v", err, rollbackErr) | 					log.Fatalf("transaction error: %v, rollback error: %v", err, rollbackErr) | ||||||
| @@ -82,7 +86,7 @@ func (db *DB) AddArticle(a *Article) (int64, error) { | |||||||
|  |  | ||||||
| func (db *DB) GetArticle(id int64) (*Article, error) { | func (db *DB) GetArticle(id int64) (*Article, error) { | ||||||
| 	query := ` | 	query := ` | ||||||
|     SELECT title, created, description, link, enc_url, enc_length, enc_type, published, author_id |     SELECT title, created, description, link, enc_url, enc_length, enc_type, published, author_id, issue_id, is_in_issue, auto_generated | ||||||
|     FROM articles |     FROM articles | ||||||
|     WHERE id = ? |     WHERE id = ? | ||||||
|     ` |     ` | ||||||
| @@ -94,7 +98,8 @@ func (db *DB) GetArticle(id int64) (*Article, error) { | |||||||
|  |  | ||||||
| 	if err := row.Scan(&article.Title, &created, &article.Description, | 	if err := row.Scan(&article.Title, &created, &article.Description, | ||||||
| 		&article.Link, &article.EncURL, &article.EncLength, &article.EncType, | 		&article.Link, &article.EncURL, &article.EncLength, &article.EncType, | ||||||
| 		&article.Published, &article.AuthorID); err != nil { | 		&article.Published, &article.AuthorID, &article.IssueID, | ||||||
|  | 		&article.IsInIssue, &article.AutoGenerated); err != nil { | ||||||
| 		return nil, fmt.Errorf("error scanning article row: %v", err) | 		return nil, fmt.Errorf("error scanning article row: %v", err) | ||||||
| 	} | 	} | ||||||
|  |  | ||||||
| @@ -109,7 +114,7 @@ func (db *DB) GetArticle(id int64) (*Article, error) { | |||||||
|  |  | ||||||
| func (db *DB) GetCertainArticles(published, rejected bool) ([]*Article, error) { | func (db *DB) GetCertainArticles(published, rejected bool) ([]*Article, error) { | ||||||
| 	query := ` | 	query := ` | ||||||
|     SELECT id, title, created, description, link, enc_url, enc_length, enc_type, author_id, issue_id |     SELECT id, title, created, description, link, enc_url, enc_length, enc_type, author_id, issue_id, is_in_issue, auto_generated | ||||||
|     FROM articles |     FROM articles | ||||||
|     WHERE published = ? |     WHERE published = ? | ||||||
|     AND rejected = ? |     AND rejected = ? | ||||||
| @@ -126,7 +131,8 @@ func (db *DB) GetCertainArticles(published, rejected bool) ([]*Article, error) { | |||||||
|  |  | ||||||
| 		if err = rows.Scan(&article.ID, &article.Title, &created, | 		if err = rows.Scan(&article.ID, &article.Title, &created, | ||||||
| 			&article.Description, &article.Link, &article.EncURL, &article.EncLength, | 			&article.Description, &article.Link, &article.EncURL, &article.EncLength, | ||||||
| 			&article.EncType, &article.AuthorID, &article.IssueID); err != nil { | 			&article.EncType, &article.AuthorID, &article.IssueID, | ||||||
|  | 			&article.IsInIssue, &article.AutoGenerated); err != nil { | ||||||
| 			return nil, fmt.Errorf("error scanning article row: %v", err) | 			return nil, fmt.Errorf("error scanning article row: %v", err) | ||||||
| 		} | 		} | ||||||
|  |  | ||||||
| @@ -147,9 +153,9 @@ func (db *DB) GetCurrentIssueArticles() ([]*Article, error) { | |||||||
| 	txOptions := &sql.TxOptions{Isolation: sql.LevelSerializable} | 	txOptions := &sql.TxOptions{Isolation: sql.LevelSerializable} | ||||||
| 	issueQuery := "SELECT id FROM issues WHERE published = false" | 	issueQuery := "SELECT id FROM issues WHERE published = false" | ||||||
| 	articlesQuery := ` | 	articlesQuery := ` | ||||||
|     SELECT id, title, created, description, link, enc_url, enc_length, enc_type, author_id |     SELECT id, title, created, description, link, enc_url, enc_length, enc_type, author_id, auto_generated | ||||||
|     FROM articles |     FROM articles | ||||||
|     WHERE issue_id = ? AND published = true |     WHERE issue_id = ? AND published = true AND is_in_issue = true | ||||||
|     ` |     ` | ||||||
|  |  | ||||||
| 	for i := 0; i < TxMaxRetries; i++ { | 	for i := 0; i < TxMaxRetries; i++ { | ||||||
| @@ -182,7 +188,7 @@ func (db *DB) GetCurrentIssueArticles() ([]*Article, error) { | |||||||
|  |  | ||||||
| 				if err = rows.Scan(&article.ID, &article.Title, &created, | 				if err = rows.Scan(&article.ID, &article.Title, &created, | ||||||
| 					&article.Description, &article.Link, &article.EncURL, &article.EncLength, | 					&article.Description, &article.Link, &article.EncURL, &article.EncLength, | ||||||
| 					&article.EncType, &article.AuthorID); err != nil { | 					&article.EncType, &article.AuthorID, &article.AutoGenerated); err != nil { | ||||||
| 					if rollbackErr := tx.Rollback(); rollbackErr != nil { | 					if rollbackErr := tx.Rollback(); rollbackErr != nil { | ||||||
| 						log.Fatalf("transaction error: %v, rollback error: %v", err, rollbackErr) | 						log.Fatalf("transaction error: %v, rollback error: %v", err, rollbackErr) | ||||||
| 					} | 					} | ||||||
|   | |||||||
| @@ -31,7 +31,10 @@ func GenerateRSS(c *Config, db *DB) (*string, error) { | |||||||
| 		for _, tag := range tags { | 		for _, tag := range tags { | ||||||
| 			tagNames = append(tagNames, tag.Name) | 			tagNames = append(tagNames, tag.Name) | ||||||
| 		} | 		} | ||||||
| 		tagNames = append(tagNames, fmt.Sprint("Orient Express ", article.IssueID)) |  | ||||||
|  | 		if article.IsInIssue { | ||||||
|  | 			tagNames = append(tagNames, fmt.Sprint("Orient Express ", article.IssueID)) | ||||||
|  | 		} | ||||||
|  |  | ||||||
| 		user, err := db.GetUser(article.AuthorID) | 		user, err := db.GetUser(article.AuthorID) | ||||||
| 		if err != nil { | 		if err != nil { | ||||||
| @@ -57,9 +60,8 @@ func GenerateRSS(c *Config, db *DB) (*string, error) { | |||||||
| 			PubDate:     article.Created.Format(time.RFC1123Z), | 			PubDate:     article.Created.Format(time.RFC1123Z), | ||||||
| 			Title:       articleTitle, | 			Title:       articleTitle, | ||||||
| 		} | 		} | ||||||
| 		fmt.Println(article.Link, ": ", len(article.Link)) |  | ||||||
|  |  | ||||||
| 		if article.Title == "Autogenerated cpolis Issue Article" { | 		if article.AutoGenerated { | ||||||
| 			item.Enclosure = &rss.Enclosure{ | 			item.Enclosure = &rss.Enclosure{ | ||||||
| 				Url:    article.EncURL, | 				Url:    article.EncURL, | ||||||
| 				Lenght: article.EncLength, | 				Lenght: article.EncLength, | ||||||
|   | |||||||
| @@ -73,11 +73,13 @@ func SubmitArticle(c *b.Config, db *b.DB, s *b.CookieStore) http.HandlerFunc { | |||||||
| 		} | 		} | ||||||
|  |  | ||||||
| 		article := &b.Article{ | 		article := &b.Article{ | ||||||
| 			Title:       r.PostFormValue("article-title"), | 			Title:         r.PostFormValue("article-title"), | ||||||
| 			Description: r.PostFormValue("article-description"), | 			Description:   r.PostFormValue("article-description"), | ||||||
| 			Published:   false, | 			Published:     false, | ||||||
| 			Rejected:    false, | 			Rejected:      false, | ||||||
| 			AuthorID:    session.Values["id"].(int64), | 			AuthorID:      session.Values["id"].(int64), | ||||||
|  | 			IsInIssue:     r.PostFormValue("issue") == "on", | ||||||
|  | 			AutoGenerated: false, | ||||||
| 		} | 		} | ||||||
|  |  | ||||||
| 		article.ID, err = db.AddArticle(article) | 		article.ID, err = db.AddArticle(article) | ||||||
| @@ -153,6 +155,7 @@ func ResubmitArticle(c *b.Config, db *b.DB, s *b.CookieStore) http.HandlerFunc { | |||||||
| 			&b.Attribute{Table: "articles", ID: id, AttName: "title", Value: title}, | 			&b.Attribute{Table: "articles", ID: id, AttName: "title", Value: title}, | ||||||
| 			&b.Attribute{Table: "articles", ID: id, AttName: "description", Value: description}, | 			&b.Attribute{Table: "articles", ID: id, AttName: "description", Value: description}, | ||||||
| 			&b.Attribute{Table: "articles", ID: id, AttName: "rejected", Value: false}, | 			&b.Attribute{Table: "articles", ID: id, AttName: "rejected", Value: false}, | ||||||
|  | 			&b.Attribute{Table: "articles", ID: id, AttName: "is_in_issue", Value: r.PostFormValue("issue") == "on"}, | ||||||
| 		); err != nil { | 		); err != nil { | ||||||
| 			log.Println(err) | 			log.Println(err) | ||||||
| 			http.Error(w, err.Error(), http.StatusInternalServerError) | 			http.Error(w, err.Error(), http.StatusInternalServerError) | ||||||
| @@ -240,46 +243,27 @@ func ReviewUnpublishedArticle(c *b.Config, db *b.DB, s *b.CookieStore) http.Hand | |||||||
| 			return | 			return | ||||||
| 		} | 		} | ||||||
|  |  | ||||||
| 		type htmlData struct { | 		data := new(struct { | ||||||
| 			Title       string | 			Article *b.Article | ||||||
| 			Description string | 			Content template.HTML | ||||||
| 			Content     template.HTML | 			Tags    []*b.Tag | ||||||
| 			Tags        []*b.Tag | 		}) | ||||||
| 			ID          int64 |  | ||||||
| 		} |  | ||||||
|  |  | ||||||
| 		var err error | 		id, err := strconv.ParseInt(r.PathValue("id"), 10, 64) | ||||||
| 		data := new(htmlData) |  | ||||||
|  |  | ||||||
| 		data.ID, err = strconv.ParseInt(r.PathValue("id"), 10, 64) |  | ||||||
| 		if err != nil { | 		if err != nil { | ||||||
| 			log.Println(err) | 			log.Println(err) | ||||||
| 			http.Error(w, err.Error(), http.StatusInternalServerError) | 			http.Error(w, err.Error(), http.StatusInternalServerError) | ||||||
| 			return | 			return | ||||||
| 		} | 		} | ||||||
|  |  | ||||||
| 		article, err := db.GetArticle(data.ID) | 		data.Article, err = db.GetArticle(id) | ||||||
| 		if err != nil { | 		if err != nil { | ||||||
| 			log.Println(err) | 			log.Println(err) | ||||||
| 			http.Error(w, err.Error(), http.StatusInternalServerError) | 			http.Error(w, err.Error(), http.StatusInternalServerError) | ||||||
| 			return | 			return | ||||||
| 		} | 		} | ||||||
|  |  | ||||||
| 		data.Title, err = b.ConvertToPlain(article.Title) | 		articleAbsName := fmt.Sprint(c.ArticleDir, "/", data.Article.ID, ".md") | ||||||
| 		if err != nil { |  | ||||||
| 			log.Println(err) |  | ||||||
| 			http.Error(w, err.Error(), http.StatusInternalServerError) |  | ||||||
| 			return |  | ||||||
| 		} |  | ||||||
|  |  | ||||||
| 		data.Description, err = b.ConvertToPlain(article.Description) |  | ||||||
| 		if err != nil { |  | ||||||
| 			log.Println(err) |  | ||||||
| 			http.Error(w, err.Error(), http.StatusInternalServerError) |  | ||||||
| 			return |  | ||||||
| 		} |  | ||||||
|  |  | ||||||
| 		articleAbsName := fmt.Sprint(c.ArticleDir, "/", article.ID, ".md") |  | ||||||
| 		contentBytes, err := os.ReadFile(articleAbsName) | 		contentBytes, err := os.ReadFile(articleAbsName) | ||||||
| 		if err != nil { | 		if err != nil { | ||||||
| 			log.Println(err) | 			log.Println(err) | ||||||
| @@ -295,7 +279,7 @@ func ReviewUnpublishedArticle(c *b.Config, db *b.DB, s *b.CookieStore) http.Hand | |||||||
| 		} | 		} | ||||||
| 		data.Content = template.HTML(content) | 		data.Content = template.HTML(content) | ||||||
|  |  | ||||||
| 		data.Tags, err = db.GetArticleTags(data.ID) | 		data.Tags, err = db.GetArticleTags(data.Article.ID) | ||||||
| 		if err != nil { | 		if err != nil { | ||||||
| 			log.Println(err) | 			log.Println(err) | ||||||
| 			http.Error(w, err.Error(), http.StatusInternalServerError) | 			http.Error(w, err.Error(), http.StatusInternalServerError) | ||||||
| @@ -314,13 +298,12 @@ func ReviewRejectedArticle(c *b.Config, db *b.DB, s *b.CookieStore) http.Handler | |||||||
| 			return | 			return | ||||||
| 		} | 		} | ||||||
|  |  | ||||||
| 		type htmlData struct { | 		data := new(struct { | ||||||
| 			Selected map[int64]bool | 			Selected map[int64]bool | ||||||
| 			Article  *b.Article | 			Article  *b.Article | ||||||
| 			Content  string | 			Content  string | ||||||
| 			Tags     []*b.Tag | 			Tags     []*b.Tag | ||||||
| 		} | 		}) | ||||||
| 		data := new(htmlData) |  | ||||||
|  |  | ||||||
| 		id, err := strconv.ParseInt(r.PathValue("id"), 10, 64) | 		id, err := strconv.ParseInt(r.PathValue("id"), 10, 64) | ||||||
| 		if err != nil { | 		if err != nil { | ||||||
| @@ -378,13 +361,20 @@ func PublishArticle(c *b.Config, db *b.DB, s *b.CookieStore) http.HandlerFunc { | |||||||
| 		} | 		} | ||||||
|  |  | ||||||
| 		id, err := strconv.ParseInt(r.PathValue("id"), 10, 64) | 		id, err := strconv.ParseInt(r.PathValue("id"), 10, 64) | ||||||
|  | 		if err != nil { | ||||||
|  | 			log.Println(err) | ||||||
|  | 			http.Error(w, err.Error(), http.StatusBadRequest) | ||||||
|  | 			return | ||||||
|  | 		} | ||||||
|  |  | ||||||
|  | 		article, err := db.GetArticle(id) | ||||||
| 		if err != nil { | 		if err != nil { | ||||||
| 			log.Println(err) | 			log.Println(err) | ||||||
| 			http.Error(w, err.Error(), http.StatusInternalServerError) | 			http.Error(w, err.Error(), http.StatusInternalServerError) | ||||||
| 			return | 			return | ||||||
| 		} | 		} | ||||||
|  |  | ||||||
| 		if err = db.AddArticleToCurrentIssue(id); err != nil { | 		if err = db.AddArticleToCurrentIssue(article.ID); err != nil { | ||||||
| 			log.Println(err) | 			log.Println(err) | ||||||
| 			http.Error(w, err.Error(), http.StatusInternalServerError) | 			http.Error(w, err.Error(), http.StatusInternalServerError) | ||||||
| 			return | 			return | ||||||
| @@ -523,7 +513,7 @@ func ShowPublishedArticles(c *b.Config, db *b.DB, s *b.CookieStore) http.Handler | |||||||
|  |  | ||||||
| 		filteredArticles := make([]*b.Article, 0) | 		filteredArticles := make([]*b.Article, 0) | ||||||
| 		for _, article := range publishedArticles { | 		for _, article := range publishedArticles { | ||||||
| 			if article.Title != "Autogenerated cpolis Issue Article" { | 			if !article.AutoGenerated { | ||||||
| 				filteredArticles = append(filteredArticles, article) | 				filteredArticles = append(filteredArticles, article) | ||||||
| 			} | 			} | ||||||
| 		} | 		} | ||||||
|   | |||||||
| @@ -59,14 +59,15 @@ func PublishLatestIssue(c *b.Config, db *b.DB, s *b.CookieStore) http.HandlerFun | |||||||
| 		mimeType := mime.TypeByExtension(filepath.Ext(imgAbsName)) | 		mimeType := mime.TypeByExtension(filepath.Ext(imgAbsName)) | ||||||
|  |  | ||||||
| 		article := &b.Article{ | 		article := &b.Article{ | ||||||
| 			Title:     "Autogenerated cpolis Issue Article", | 			Title:         r.PostFormValue("issue-title"), | ||||||
| 			EncURL:    fmt.Sprint(c.Domain, "/image/serve/", imgFileName), | 			EncURL:        fmt.Sprint(c.Domain, "/image/serve/", imgFileName), | ||||||
| 			EncLength: int(imgSize), | 			EncLength:     int(imgSize), | ||||||
| 			EncType:   mimeType, | 			EncType:       mimeType, | ||||||
| 			Published: true, | 			Published:     true, | ||||||
| 			Rejected:  false, | 			Rejected:      false, | ||||||
| 			Created:   time.Now(), | 			Created:       time.Now(), | ||||||
| 			AuthorID:  session.Values["id"].(int64), | 			AuthorID:      session.Values["id"].(int64), | ||||||
|  | 			AutoGenerated: true, | ||||||
| 		} | 		} | ||||||
| 		fmt.Println(article.Link) | 		fmt.Println(article.Link) | ||||||
|  |  | ||||||
|   | |||||||
| @@ -21,18 +21,20 @@ CREATE TABLE issues ( | |||||||
| ); | ); | ||||||
|  |  | ||||||
| CREATE TABLE articles ( | CREATE TABLE articles ( | ||||||
|     id          INT             AUTO_INCREMENT, |     id              INT             AUTO_INCREMENT, | ||||||
|     title       VARCHAR(255)    NOT NULL, |     title           VARCHAR(255)    NOT NULL, | ||||||
|     created     TIMESTAMP       DEFAULT CURRENT_TIMESTAMP, |     created         TIMESTAMP       DEFAULT CURRENT_TIMESTAMP, | ||||||
|     description TEXT            NOT NULL, |     description     TEXT            NOT NULL, | ||||||
|     link        VARCHAR(255), |     link            VARCHAR(255), | ||||||
|     enc_url     VARCHAR(255), |     enc_url         VARCHAR(255), | ||||||
|     enc_length  INT, |     enc_length      INT, | ||||||
|     enc_type    VARCHAR(255), |     enc_type        VARCHAR(255), | ||||||
|     published   BOOL            NOT NULL, |     published       BOOL            NOT NULL, | ||||||
|     rejected    BOOL            NOT NULL, |     rejected        BOOL            NOT NULL, | ||||||
|     author_id   INT             NOT NULL, |     author_id       INT             NOT NULL, | ||||||
|     issue_id    INT             NOT NULL, |     issue_id        INT             NOT NULL, | ||||||
|  |     is_in_issue     BOOL            NOT NULL, | ||||||
|  |     auto_generated  BOOL            NOT NULL, | ||||||
|     PRIMARY KEY (id), |     PRIMARY KEY (id), | ||||||
|     FOREIGN KEY (author_id) REFERENCES users (id), |     FOREIGN KEY (author_id) REFERENCES users (id), | ||||||
|     FOREIGN KEY (issue_id) REFERENCES issues (id) |     FOREIGN KEY (issue_id) REFERENCES issues (id) | ||||||
|   | |||||||
| @@ -17,7 +17,18 @@ | |||||||
|  |  | ||||||
|         <div> |         <div> | ||||||
|             <h3>Cover</h3> |             <h3>Cover</h3> | ||||||
|             <input id="image-upload" name="issue-image" type="file" required hx-post="/issue/upload-image" /> |             <div class="flex"> | ||||||
|  |                 <label class="btn text-center" for="image-upload">Bild hochladen</label> | ||||||
|  |                 <input class="hidden" id="image-upload" name="issue-image" type="file" required | ||||||
|  |                     hx-post="/issue/upload-image" /> | ||||||
|  |             </div> | ||||||
|  |         </div> | ||||||
|  |  | ||||||
|  |         <div> | ||||||
|  |             <h3>Titel</h3> | ||||||
|  |             <div class="flex flex-col gap-y-1"> | ||||||
|  |                 <input name="issue-title" type="text" /> | ||||||
|  |             </div> | ||||||
|         </div> |         </div> | ||||||
|  |  | ||||||
|         <div> |         <div> | ||||||
|   | |||||||
| @@ -21,6 +21,11 @@ | |||||||
|     <div> |     <div> | ||||||
|         <span>Tags</span> |         <span>Tags</span> | ||||||
|         <div class="flex flex-wrap gap-x-4"> |         <div class="flex flex-wrap gap-x-4"> | ||||||
|  |             <div> | ||||||
|  |                 <input id="issue" name="issue" type="checkbox" /> | ||||||
|  |                 <label for="issue">Orient Express</label> | ||||||
|  |             </div> | ||||||
|  |  | ||||||
|             {{range .Tags}} |             {{range .Tags}} | ||||||
|             <div> |             <div> | ||||||
|                 <input id="{{.Name}}" name="tags" type="checkbox" value="{{.ID}}" /> |                 <input id="{{.Name}}" name="tags" type="checkbox" value="{{.ID}}" /> | ||||||
|   | |||||||
| @@ -21,6 +21,11 @@ | |||||||
|     <div> |     <div> | ||||||
|         <span>Tags</span> |         <span>Tags</span> | ||||||
|         <div class="flex flex-wrap gap-x-4"> |         <div class="flex flex-wrap gap-x-4"> | ||||||
|  |             <div> | ||||||
|  |                 <input id="issue" name="issue" type="checkbox" {{if .Article.IsInIssue}}checked{{end}} /> | ||||||
|  |                 <label for="issue">Orient Express</label> | ||||||
|  |             </div> | ||||||
|  |  | ||||||
|             {{range .Tags}} |             {{range .Tags}} | ||||||
|             <div> |             <div> | ||||||
|                 <input id="tag-{{.Name}}" name="tags" type="checkbox" value="{{.ID}}" {{if index $.Selected |                 <input id="tag-{{.Name}}" name="tags" type="checkbox" value="{{.ID}}" {{if index $.Selected | ||||||
|   | |||||||
| @@ -4,12 +4,12 @@ | |||||||
| <div> | <div> | ||||||
|     <span>Titel</span> |     <span>Titel</span> | ||||||
|     <div class="bg-white border mb-3 px-2 py-2 rounded-md w-full"> |     <div class="bg-white border mb-3 px-2 py-2 rounded-md w-full"> | ||||||
|         {{.Title}} |         {{.Article.Title}} | ||||||
|     </div> |     </div> | ||||||
|  |  | ||||||
|     <span>Beschreibung</span> |     <span>Beschreibung</span> | ||||||
|     <div class="bg-white border mb-3 px-2 py-2 rounded-md w-full"> |     <div class="bg-white border mb-3 px-2 py-2 rounded-md w-full"> | ||||||
|         {{.Description}} |         {{.Article.Description}} | ||||||
|     </div> |     </div> | ||||||
|  |  | ||||||
|     <span>Artikel</span> |     <span>Artikel</span> | ||||||
| @@ -21,16 +21,21 @@ | |||||||
|  |  | ||||||
|     <span>Tags</span> |     <span>Tags</span> | ||||||
|     <div class="bg-white border mb-3 px-2 py-2 rounded-md w-full"> |     <div class="bg-white border mb-3 px-2 py-2 rounded-md w-full"> | ||||||
|  |         {{if .Article.IsInIssue}} | ||||||
|  |         <span>Orient Express</span> | ||||||
|  |         <br> | ||||||
|  |         {{end}} | ||||||
|         {{range .Tags}} |         {{range .Tags}} | ||||||
|         {{.Name}} |         <span>{{.Name}}</span> | ||||||
|         <br> |         <br> | ||||||
|         {{end}} |         {{end}} | ||||||
|     </div> |     </div> | ||||||
|  |  | ||||||
|     <div class="btn-area"> |     <div class="btn-area"> | ||||||
|         <input class="action-btn" type="submit" value="Veröffentlichen" hx-get="/article/publish/{{.ID}}" |         <input class="action-btn" type="submit" value="Veröffentlichen" hx-get="/article/publish/{{.Article.ID}}" | ||||||
|  |             hx-target="#page-content" /> | ||||||
|  |         <input class="btn" type="submit" value="Ablehnen" hx-get="/article/reject/{{.Article.ID}}" | ||||||
|             hx-target="#page-content" /> |             hx-target="#page-content" /> | ||||||
|         <input class="btn" type="submit" value="Ablehnen" hx-get="/article/reject/{{.ID}}" hx-target="#page-content" /> |  | ||||||
|         <button class="btn" hx-get="/hub" hx-target="#page-content">Zurück</button> |         <button class="btn" hx-get="/hub" hx-target="#page-content">Zurück</button> | ||||||
|     </div> |     </div> | ||||||
| </div> | </div> | ||||||
|   | |||||||
		Reference in New Issue
	
	Block a user