Remove resources from the table of contents

This commit is contained in:
Ben Visness 2022-09-19 20:26:43 -05:00
parent 4b9fe628e6
commit 8121830561
8 changed files with 49 additions and 5 deletions

View File

@ -6353,7 +6353,7 @@ input[type=submit]:not(.button-small), .notice {
.f3 { .f3 {
font-size: 1.5rem; } font-size: 1.5rem; }
.f4 { .f4, .edu-article .resource-title {
font-size: 1.25rem; } font-size: 1.25rem; }
.f5 { .f5 {
@ -8301,6 +8301,9 @@ nav.timecodes {
text-align: center; text-align: center;
margin: 10px 0; } margin: 10px 0; }
.edu-article .resource-title {
font-weight: bold; }
.edu-article .note { .edu-article .note {
color: red; } color: red; }

View File

@ -211,6 +211,10 @@ func TestEducationArticleDelete(t *testing.T) {
AssertRegexMatch(t, BuildEducationArticleDelete("foo"), RegexEducationArticleDelete, map[string]string{"slug": "foo"}) AssertRegexMatch(t, BuildEducationArticleDelete("foo"), RegexEducationArticleDelete, map[string]string{"slug": "foo"})
} }
func TestEducationRerender(t *testing.T) {
AssertRegexMatch(t, BuildEducationRerender(), RegexEducationRerender, nil)
}
func TestForum(t *testing.T) { func TestForum(t *testing.T) {
AssertRegexMatch(t, hmn.BuildForum(nil, 1), RegexForum, nil) AssertRegexMatch(t, hmn.BuildForum(nil, 1), RegexForum, nil)
AssertRegexMatch(t, hmn.BuildForum([]string{"wip"}, 2), RegexForum, map[string]string{"subforums": "wip", "page": "2"}) AssertRegexMatch(t, hmn.BuildForum([]string{"wip"}, 2), RegexForum, map[string]string{"subforums": "wip", "page": "2"})

View File

@ -481,6 +481,12 @@ func BuildEducationArticleDelete(slug string) string {
return Url(fmt.Sprintf("/education/%s/delete", slug), nil) return Url(fmt.Sprintf("/education/%s/delete", slug), nil)
} }
var RegexEducationRerender = regexp.MustCompile(`^/education/rerender$`)
func BuildEducationRerender() string {
return Url("/education/rerender", nil)
}
/* /*
* Forums * Forums
*/ */

View File

@ -60,7 +60,7 @@ var ggcodeTags = map[string]ggcodeTag{
Renderer: func(c ggcodeRendererContext, n *ggcodeNode, entering bool) error { Renderer: func(c ggcodeRendererContext, n *ggcodeNode, entering bool) error {
if entering { if entering {
c.W.WriteString(`<div class="edu-resource">`) c.W.WriteString(`<div class="edu-resource">`)
c.W.WriteString(fmt.Sprintf(` <a href="%s" target="_blank"><h2>%s</h2></a>`, n.Args["url"], utils.OrDefault(n.Args["name"], "[missing `name`]"))) c.W.WriteString(fmt.Sprintf(` <a class="resource-title" href="%s" target="_blank">%s</a>`, n.Args["url"], utils.OrDefault(n.Args["name"], "[missing `name`]")))
} else { } else {
c.W.WriteString("</div>") c.W.WriteString("</div>")
} }
@ -212,17 +212,14 @@ type ggcodeDelimiterParser struct {
} }
func (p ggcodeDelimiterParser) IsDelimiter(b byte) bool { func (p ggcodeDelimiterParser) IsDelimiter(b byte) bool {
fmt.Println("delmit", string(b))
return b == '(' || b == ')' return b == '(' || b == ')'
} }
func (p ggcodeDelimiterParser) CanOpenCloser(opener, closer *parser.Delimiter) bool { func (p ggcodeDelimiterParser) CanOpenCloser(opener, closer *parser.Delimiter) bool {
fmt.Println("oopen")
return opener.Char == '(' && closer.Char == ')' return opener.Char == '(' && closer.Char == ')'
} }
func (p ggcodeDelimiterParser) OnMatch(consumes int) gast.Node { func (p ggcodeDelimiterParser) OnMatch(consumes int) gast.Node {
fmt.Println("out!")
return p.Node return p.Node
} }

View File

@ -3,6 +3,11 @@
@extend .pa3, .bg--dim, .br3; @extend .pa3, .bg--dim, .br3;
} }
.resource-title {
@extend .f4;
font-weight: bold;
}
.note { .note {
color: red; color: red;
} }

View File

@ -40,4 +40,10 @@
</div> </div>
</div> </div>
{{ if and .User .User.IsEduAuthor }}
<div class="mt3">
<b>SECRET AUTHOR MAINTENANCE COMMANDS:</b>
<a href="{{ .RerenderUrl }}">Rerender all content</a>
</div>
{{ end }}
{{ end }} {{ end }}

View File

@ -25,6 +25,7 @@ func EducationIndex(c *RequestContext) ResponseData {
templates.BaseData templates.BaseData
Articles []templates.EduArticle Articles []templates.EduArticle
NewArticleUrl string NewArticleUrl string
RerenderUrl string
} }
articles, err := fetchEduArticles(c, c.Conn, models.EduArticleTypeArticle, c.CurrentUser) articles, err := fetchEduArticles(c, c.Conn, models.EduArticleTypeArticle, c.CurrentUser)
@ -41,6 +42,7 @@ func EducationIndex(c *RequestContext) ResponseData {
BaseData: getBaseData(c, "Handmade Education", nil), BaseData: getBaseData(c, "Handmade Education", nil),
Articles: tmplArticles, Articles: tmplArticles,
NewArticleUrl: hmnurl.BuildEducationArticleNew(), NewArticleUrl: hmnurl.BuildEducationArticleNew(),
RerenderUrl: hmnurl.BuildEducationRerender(),
} }
var res ResponseData var res ResponseData
@ -232,6 +234,26 @@ func EducationArticleDeleteSubmit(c *RequestContext) ResponseData {
return res return res
} }
func EducationRerender(c *RequestContext) ResponseData {
everything := utils.Must1(fetchEduArticles(c, c.Conn, 0, c.CurrentUser))
for _, thing := range everything {
newHTML := parsing.ParseMarkdown(thing.CurrentVersion.ContentRaw, parsing.EducationRealMarkdown)
utils.Must1(c.Conn.Exec(c,
`
UPDATE education_article_version
SET content_html = $2
WHERE id = $1
`,
thing.CurrentVersionID,
newHTML,
))
}
res := c.Redirect(hmnurl.BuildEducationIndex(), http.StatusSeeOther)
res.AddFutureNotice("success", "Rerendered all education content.")
return res
}
func fetchEduArticles( func fetchEduArticles(
ctx context.Context, ctx context.Context,
dbConn db.ConnOrTx, dbConn db.ConnOrTx,

View File

@ -123,6 +123,7 @@ func NewWebsiteRoutes(conn *pgxpool.Pool) http.Handler {
educationPrerelease.GET(hmnurl.RegexEducationGlossary, EducationGlossary) educationPrerelease.GET(hmnurl.RegexEducationGlossary, EducationGlossary)
educationPrerelease.GET(hmnurl.RegexEducationArticleNew, educationAuthorsOnly(EducationArticleNew)) educationPrerelease.GET(hmnurl.RegexEducationArticleNew, educationAuthorsOnly(EducationArticleNew))
educationPrerelease.POST(hmnurl.RegexEducationArticleNew, educationAuthorsOnly(EducationArticleNewSubmit)) educationPrerelease.POST(hmnurl.RegexEducationArticleNew, educationAuthorsOnly(EducationArticleNewSubmit))
educationPrerelease.GET(hmnurl.RegexEducationRerender, educationAuthorsOnly(EducationRerender))
educationPrerelease.GET(hmnurl.RegexEducationArticle, EducationArticle) // Article stuff must be last so `/glossary` and others do not match as an article slug educationPrerelease.GET(hmnurl.RegexEducationArticle, EducationArticle) // Article stuff must be last so `/glossary` and others do not match as an article slug
educationPrerelease.GET(hmnurl.RegexEducationArticleEdit, educationAuthorsOnly(EducationArticleEdit)) educationPrerelease.GET(hmnurl.RegexEducationArticleEdit, educationAuthorsOnly(EducationArticleEdit))
educationPrerelease.POST(hmnurl.RegexEducationArticleEdit, educationAuthorsOnly(EducationArticleEditSubmit)) educationPrerelease.POST(hmnurl.RegexEducationArticleEdit, educationAuthorsOnly(EducationArticleEditSubmit))