Better edu home page
This commit is contained in:
parent
4e44ba0b45
commit
48af5e650d
Binary file not shown.
After Width: | Height: | Size: 103 KiB |
Binary file not shown.
After Width: | Height: | Size: 91 KiB |
Binary file not shown.
After Width: | Height: | Size: 106 KiB |
|
@ -7394,7 +7394,7 @@ article code {
|
||||||
border-color: #aaa;
|
border-color: #aaa;
|
||||||
border-color: var(--theme-color-dim); }
|
border-color: var(--theme-color-dim); }
|
||||||
|
|
||||||
.c--dimmer, footer .list li:not(:last-child)::after {
|
.c--dimmer, footer .list li:not(:last-child)::after, .edu-course .edu-article.coming-soon {
|
||||||
color: #999;
|
color: #999;
|
||||||
color: var(--dimmer-color); }
|
color: var(--dimmer-color); }
|
||||||
|
|
||||||
|
@ -8306,6 +8306,27 @@ nav.timecodes {
|
||||||
text-align: center;
|
text-align: center;
|
||||||
margin: 10px 0; }
|
margin: 10px 0; }
|
||||||
|
|
||||||
|
.edu-course .edu-article.coming-soon {
|
||||||
|
font-style: italic; }
|
||||||
|
|
||||||
|
.edu-course .edu-article::after {
|
||||||
|
content: '';
|
||||||
|
position: absolute;
|
||||||
|
width: 1rem;
|
||||||
|
height: 10rem;
|
||||||
|
border-width: 0 0 1px 1px;
|
||||||
|
border-style: solid;
|
||||||
|
border-color: #bbb;
|
||||||
|
border-color: var(--dimmest-color);
|
||||||
|
left: -1.5rem;
|
||||||
|
top: -9rem;
|
||||||
|
border-bottom-left-radius: 0.5rem; }
|
||||||
|
|
||||||
|
.edu-topic img {
|
||||||
|
width: 100%;
|
||||||
|
height: 14rem;
|
||||||
|
object-fit: cover; }
|
||||||
|
|
||||||
.edu-article .note {
|
.edu-article .note {
|
||||||
color: red; }
|
color: red; }
|
||||||
|
|
||||||
|
|
|
@ -1,3 +1,32 @@
|
||||||
|
.edu-course {
|
||||||
|
.edu-article.coming-soon {
|
||||||
|
@extend .c--dimmer;
|
||||||
|
font-style: italic;
|
||||||
|
}
|
||||||
|
|
||||||
|
.edu-article::after {
|
||||||
|
$height: 10rem;
|
||||||
|
content: '';
|
||||||
|
position: absolute;
|
||||||
|
width: 1rem;
|
||||||
|
height: $height;
|
||||||
|
border-width: 0 0 1px 1px;
|
||||||
|
border-style: solid;
|
||||||
|
@include usevar(border-color, dimmest-color);
|
||||||
|
left: -1.5rem;
|
||||||
|
top: 1rem - $height;
|
||||||
|
border-bottom-left-radius: 0.5rem;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
.edu-topic {
|
||||||
|
img {
|
||||||
|
width: 100%;
|
||||||
|
height: 14rem;
|
||||||
|
object-fit: cover;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
.edu-article {
|
.edu-article {
|
||||||
.note {
|
.note {
|
||||||
color: red;
|
color: red;
|
||||||
|
|
|
@ -41,7 +41,7 @@
|
||||||
{{ end }}
|
{{ end }}
|
||||||
|
|
||||||
{{ define "content" }}
|
{{ define "content" }}
|
||||||
<div class="ph2 ph0-ns">
|
<div class="ph3 ph0-ns">
|
||||||
<h1>{{ .Title }}</h1>
|
<h1>{{ .Title }}</h1>
|
||||||
{{ if and .User .User.IsEduAuthor }}
|
{{ if and .User .User.IsEduAuthor }}
|
||||||
<div class="mb3">
|
<div class="mb3">
|
||||||
|
|
|
@ -1,28 +1,44 @@
|
||||||
{{ template "base.html" . }}
|
{{ template "base.html" . }}
|
||||||
|
|
||||||
{{ define "content" }}
|
{{ define "content" }}
|
||||||
|
<div class="ph3 ph0-ns">
|
||||||
<h1>Learn the Handmade way.</h1>
|
<h1>Learn the Handmade way.</h1>
|
||||||
|
|
||||||
<h2>Guides</h2>
|
<p>Dive into one of these topics and start learning.</p>
|
||||||
|
|
||||||
{{ if and .User .User.IsEduAuthor }}
|
<div class="flex flex-column flex-row-ns g3 mt3 mb4">
|
||||||
<div class="mb2">
|
<a href="#compilers" class="edu-topic db flex-fair-ns bg--dim br3 overflow-hidden c--inherit flex flex-column">
|
||||||
<a href="{{ .NewArticleUrl }}"><span class="big pr1">+</span> New Article</a>
|
<img src="{{ static "education/compilers.jpg" }}">
|
||||||
|
<div class="pa3">
|
||||||
|
<h2>Compilers</h2>
|
||||||
|
<div>
|
||||||
|
Learn how programming languages are made.
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</a>
|
||||||
|
<a href="#networking" class="edu-topic db flex-fair-ns bg--dim br3 overflow-hidden c--inherit flex flex-column">
|
||||||
|
<img src="{{ static "education/networking.jpg" }}">
|
||||||
|
<div class="pa3">
|
||||||
|
<h2>Networking</h2>
|
||||||
|
<div>
|
||||||
|
Learn how computers communicate, and how the internet actually works.
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</a>
|
||||||
|
<a href="#time" class="edu-topic db flex-fair-ns bg--dim br3 overflow-hidden c--inherit flex flex-column">
|
||||||
|
<img src="{{ static "education/time.jpg" }}">
|
||||||
|
<div class="pa3">
|
||||||
|
<h2>Time</h2>
|
||||||
|
<div>
|
||||||
|
Get better at handling time, from calendars to timezones to clock sync.
|
||||||
|
</div>
|
||||||
</div>
|
</div>
|
||||||
{{ end }}
|
|
||||||
|
|
||||||
<div class="flex flex-column g3 mb3">
|
|
||||||
{{ range .Articles }}
|
|
||||||
<a class="c--inherit flex flex-column pa3 bg--dim br2" href="{{ .Url }}" >
|
|
||||||
<h3 class="mb1 link">{{ .Title }}</h3>
|
|
||||||
<div>{{ .Description }}</div>
|
|
||||||
</a>
|
</a>
|
||||||
{{ end }}
|
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<h2>What makes us different?</h2>
|
<h2>What makes us different?</h2>
|
||||||
|
|
||||||
<div class="flex flex-column flex-row-ns g3">
|
<div class="flex flex-column flex-row-ns g3 mb4">
|
||||||
<div class="flex-fair bg--dim pa3 br2">
|
<div class="flex-fair bg--dim pa3 br2">
|
||||||
<h3>Real material.</h3>
|
<h3>Real material.</h3>
|
||||||
|
|
||||||
|
@ -40,10 +56,34 @@
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
{{ if and .User .User.IsEduAuthor }}
|
<h2>All Topics</h2>
|
||||||
<div class="mt3">
|
|
||||||
<b>SECRET AUTHOR MAINTENANCE COMMANDS:</b>
|
{{ range .Courses }}
|
||||||
<a href="{{ .RerenderUrl }}">Rerender all content</a>
|
<div id="{{ .Slug }}" class="edu-course mv3 bg--dim pa3 br3">
|
||||||
|
<h3>{{ .Name }}</h3>
|
||||||
|
<div class="overflow-hidden">
|
||||||
|
<div class="edu-articles ml3 pl3">
|
||||||
|
{{ range .Articles }}
|
||||||
|
<div class="edu-article mt3 relative {{ if not .Published }}coming-soon{{ end }}">
|
||||||
|
{{ if or (and $.User $.User.IsEduTester) .Published }}
|
||||||
|
<a href="{{ .Url }}"><h4>{{ .Title }}</h4></a>
|
||||||
|
{{ else }}
|
||||||
|
<h4>{{ .Title }} (coming soon)</h4>
|
||||||
|
{{ end }}
|
||||||
|
<div>{{ .Description }}</div>
|
||||||
</div>
|
</div>
|
||||||
{{ end }}
|
{{ end }}
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
{{ end }}
|
||||||
|
|
||||||
|
{{ if and .User .User.IsEduAuthor }}
|
||||||
|
<div class="mt3">
|
||||||
|
<b>SECRET AUTHOR COMMANDS:</b>
|
||||||
|
<div><a href="{{ .RerenderUrl }}">Rerender all content</a></div>
|
||||||
|
<div><a href="{{ .NewArticleUrl }}"><span class="big pr1">+</span> New Article</a></div>
|
||||||
|
</div>
|
||||||
|
{{ end }}
|
||||||
|
</div>
|
||||||
{{ end }}
|
{{ end }}
|
||||||
|
|
|
@ -395,6 +395,12 @@ type TextEditor struct {
|
||||||
UploadUrl string
|
UploadUrl string
|
||||||
}
|
}
|
||||||
|
|
||||||
|
type EduCourse struct {
|
||||||
|
Name string
|
||||||
|
Slug string
|
||||||
|
Articles []EduArticle
|
||||||
|
}
|
||||||
|
|
||||||
type EduArticle struct {
|
type EduArticle struct {
|
||||||
Title string
|
Title string
|
||||||
Slug string
|
Slug string
|
||||||
|
|
|
@ -23,24 +23,68 @@ import (
|
||||||
func EducationIndex(c *RequestContext) ResponseData {
|
func EducationIndex(c *RequestContext) ResponseData {
|
||||||
type indexData struct {
|
type indexData struct {
|
||||||
templates.BaseData
|
templates.BaseData
|
||||||
Articles []templates.EduArticle
|
Courses []templates.EduCourse
|
||||||
NewArticleUrl string
|
NewArticleUrl string
|
||||||
RerenderUrl string
|
RerenderUrl string
|
||||||
}
|
}
|
||||||
|
|
||||||
articles, err := fetchEduArticles(c, c.Conn, models.EduArticleTypeArticle, c.CurrentUser)
|
// TODO: Someday this can be dynamic again? Maybe? Or not? Who knows??
|
||||||
if err != nil {
|
// articles, err := fetchEduArticles(c, c.Conn, models.EduArticleTypeArticle, c.CurrentUser)
|
||||||
|
// if err != nil {
|
||||||
|
// panic(err)
|
||||||
|
// }
|
||||||
|
|
||||||
|
// var tmplArticles []templates.EduArticle
|
||||||
|
// for _, article := range articles {
|
||||||
|
// tmplArticles = append(tmplArticles, templates.EducationArticleToTemplate(&article))
|
||||||
|
// }
|
||||||
|
|
||||||
|
article := func(slug string) templates.EduArticle {
|
||||||
|
if article, err := fetchEduArticle(c, c.Conn, slug, models.EduArticleTypeArticle, c.CurrentUser); err == nil {
|
||||||
|
return templates.EducationArticleToTemplate(article)
|
||||||
|
} else if errors.Is(err, db.NotFound) {
|
||||||
|
return templates.EduArticle{
|
||||||
|
Title: "<UNKNOWN ARTICLE>",
|
||||||
|
}
|
||||||
|
} else {
|
||||||
panic(err)
|
panic(err)
|
||||||
}
|
}
|
||||||
|
|
||||||
var tmplArticles []templates.EduArticle
|
|
||||||
for _, article := range articles {
|
|
||||||
tmplArticles = append(tmplArticles, templates.EducationArticleToTemplate(&article))
|
|
||||||
}
|
}
|
||||||
|
|
||||||
tmpl := indexData{
|
tmpl := indexData{
|
||||||
BaseData: getBaseData(c, "Handmade Education", nil),
|
BaseData: getBaseData(c, "Handmade Education", nil),
|
||||||
Articles: tmplArticles,
|
Courses: []templates.EduCourse{
|
||||||
|
{
|
||||||
|
Name: "Compilers",
|
||||||
|
Slug: "compilers",
|
||||||
|
Articles: []templates.EduArticle{
|
||||||
|
article("compilers"),
|
||||||
|
{
|
||||||
|
Title: "Baby's first language theory",
|
||||||
|
Description: "State machines, abstract datatypes, type theory...",
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
{
|
||||||
|
Name: "Networking",
|
||||||
|
Slug: "networking",
|
||||||
|
Articles: []templates.EduArticle{
|
||||||
|
article("networking"),
|
||||||
|
{
|
||||||
|
Title: "Internet infrastructure",
|
||||||
|
Description: "How does the internet actually work? How does your ISP know where to send your data? What happens to the internet if physical communication breaks down?",
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
{
|
||||||
|
Name: "Time",
|
||||||
|
Slug: "time",
|
||||||
|
Articles: []templates.EduArticle{
|
||||||
|
article("time"),
|
||||||
|
article("ntp"),
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
NewArticleUrl: hmnurl.BuildEducationArticleNew(),
|
NewArticleUrl: hmnurl.BuildEducationArticleNew(),
|
||||||
RerenderUrl: hmnurl.BuildEducationRerender(),
|
RerenderUrl: hmnurl.BuildEducationRerender(),
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue