feat: publish control — missing 'published:' defaults true; published:false hides article from all routes + listings; subjects date-sorted so Topics boxes/dropdowns show newest
This commit is contained in:
@@ -158,6 +158,8 @@ func (c *Content) loadSubject(slug string) (*Subject, error) {
|
|||||||
if err := c.loadFilesUnder(dir, &s.Articles); err != nil {
|
if err := c.loadFilesUnder(dir, &s.Articles); err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
|
// newest first within a subject (drives Topics boxes + ribbon dropdowns)
|
||||||
|
sortArticles(s.Articles)
|
||||||
for _, a := range s.Articles {
|
for _, a := range s.Articles {
|
||||||
a.Subject = slug
|
a.Subject = slug
|
||||||
c.Articles = append(c.Articles, a)
|
c.Articles = append(c.Articles, a)
|
||||||
@@ -177,6 +179,7 @@ func (c *Content) loadFilesUnder(dir string, out *[]*Article) error {
|
|||||||
continue
|
continue
|
||||||
}
|
}
|
||||||
if a, err := c.loadFile(path.Join(dir, name)); err == nil {
|
if a, err := c.loadFile(path.Join(dir, name)); err == nil {
|
||||||
|
// unpublished articles are drafts — load, then hide from all listings
|
||||||
*out = append(*out, a)
|
*out = append(*out, a)
|
||||||
} else {
|
} else {
|
||||||
log.Printf("article %s: %v", name, err)
|
log.Printf("article %s: %v", name, err)
|
||||||
@@ -237,30 +240,36 @@ func (c *Content) findSubject(slug string) *Subject {
|
|||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
// findArticle returns the article with the given slug, or nil.
|
// findArticle returns the article with the given slug, or nil. Drafts are not served.
|
||||||
func (c *Content) findArticle(slug string) *Article {
|
func (c *Content) findArticle(slug string) *Article {
|
||||||
for _, a := range c.Articles {
|
for _, a := range c.Articles {
|
||||||
if a.Slug == slug {
|
if a.Slug == slug && a.FM.Published {
|
||||||
return a
|
return a
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
// findArticlesBySubject returns articles in a subject, newest first.
|
// findArticlesBySubject returns published articles in a subject, newest first.
|
||||||
func (c *Content) findArticlesBySubject(slug string) []*Article {
|
func (c *Content) findArticlesBySubject(slug string) []*Article {
|
||||||
var out []*Article
|
var out []*Article
|
||||||
for _, a := range c.Articles {
|
for _, a := range c.Articles {
|
||||||
if a.Subject == slug {
|
if a.Subject == slug && a.FM.Published {
|
||||||
out = append(out, a)
|
out = append(out, a)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
sortArticles(out)
|
||||||
return out
|
return out
|
||||||
}
|
}
|
||||||
|
|
||||||
// latest returns up to n articles across all subjects, newest first.
|
// latest returns up to n published articles across all subjects, newest first.
|
||||||
func (c *Content) latest(n int) []*Article {
|
func (c *Content) latest(n int) []*Article {
|
||||||
out := c.Articles
|
var out []*Article
|
||||||
|
for _, a := range c.Articles {
|
||||||
|
if a.FM.Published {
|
||||||
|
out = append(out, a)
|
||||||
|
}
|
||||||
|
}
|
||||||
sortArticles(out)
|
sortArticles(out)
|
||||||
if len(out) > n {
|
if len(out) > n {
|
||||||
out = out[:n]
|
out = out[:n]
|
||||||
@@ -268,10 +277,10 @@ func (c *Content) latest(n int) []*Article {
|
|||||||
return out
|
return out
|
||||||
}
|
}
|
||||||
|
|
||||||
// featured returns the first article marked featured.
|
// featured returns the first published article marked featured.
|
||||||
func (c *Content) featured() *Article {
|
func (c *Content) featured() *Article {
|
||||||
for _, a := range c.Articles {
|
for _, a := range c.Articles {
|
||||||
if a.FM.Featured {
|
if a.FM.Featured && a.FM.Published {
|
||||||
return a
|
return a
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -296,6 +305,11 @@ func parseFrontMatter(text string) (FrontMatter, string, bool) {
|
|||||||
if err := yaml.Unmarshal([]byte(yamlText), &fm); err != nil {
|
if err := yaml.Unmarshal([]byte(yamlText), &fm); err != nil {
|
||||||
return FrontMatter{}, text, false
|
return FrontMatter{}, text, false
|
||||||
}
|
}
|
||||||
|
// Missing `published:` key = published (default true). go-yaml sets the
|
||||||
|
// bool to false when the key is absent, so detect absence from the raw text.
|
||||||
|
if !strings.Contains(yamlText, "published") {
|
||||||
|
fm.Published = true
|
||||||
|
}
|
||||||
return fm, body, true
|
return fm, body, true
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user