Improve OpenGraph / favicons
Before Width: | Height: | Size: 17 KiB |
Before Width: | Height: | Size: 23 KiB |
Before Width: | Height: | Size: 3.1 KiB |
Before Width: | Height: | Size: 4.2 KiB |
Before Width: | Height: | Size: 6.8 KiB |
Before Width: | Height: | Size: 9.8 KiB |
Before Width: | Height: | Size: 12 KiB |
Before Width: | Height: | Size: 13 KiB |
Before Width: | Height: | Size: 17 KiB |
Before Width: | Height: | Size: 18 KiB |
Before Width: | Height: | Size: 22 KiB |
Before Width: | Height: | Size: 5.2 KiB |
Before Width: | Height: | Size: 5.5 KiB |
Before Width: | Height: | Size: 6.8 KiB |
Before Width: | Height: | Size: 7.1 KiB |
Before Width: | Height: | Size: 24 KiB |
Before Width: | Height: | Size: 24 KiB |
Before Width: | Height: | Size: 15 KiB After Width: | Height: | Size: 1.7 KiB |
Before Width: | Height: | Size: 16 KiB After Width: | Height: | Size: 2.4 KiB |
Before Width: | Height: | Size: 9.8 KiB |
After Width: | Height: | Size: 94 KiB |
14
src/db/db.go
|
@ -338,6 +338,20 @@ func QueryScalar(ctx context.Context, conn ConnOrTx, query string, args ...inter
|
|||
return nil, ErrNoMatchingRows
|
||||
}
|
||||
|
||||
func QueryString(ctx context.Context, conn ConnOrTx, query string, args ...interface{}) (string, error) {
|
||||
result, err := QueryScalar(ctx, conn, query, args...)
|
||||
if err != nil {
|
||||
return "", err
|
||||
}
|
||||
|
||||
switch r := result.(type) {
|
||||
case string:
|
||||
return r, nil
|
||||
default:
|
||||
return "", oops.New(nil, "QueryString got a non-string result: %v", result)
|
||||
}
|
||||
}
|
||||
|
||||
func QueryInt(ctx context.Context, conn ConnOrTx, query string, args ...interface{}) (int, error) {
|
||||
result, err := QueryScalar(ctx, conn, query, args...)
|
||||
if err != nil {
|
||||
|
|
|
@ -1,8 +1,7 @@
|
|||
{{ template "base.html" . }}
|
||||
|
||||
{{ define "content" }}
|
||||
<div class="content-block">
|
||||
<div class="description mw7 ph3 ph0-ns">
|
||||
<div class="center-layout mw7 mv3 ph3 ph0-ns post-content">
|
||||
<h1>Handmade Code of Conduct v1.0</h1>
|
||||
<p>The Handmade community is an international community of programmers, designers, artists, musicians, mathematicians, and other creatives dedicated to building and improving high quality software.</p>
|
||||
<p>Outlined herein are the guidelines we pledge to uphold to maintain a healthy community, stay true to the ideas first explored in our <a href="/manifesto">Manifesto</a> and refined by valuable feedback, and ensure we mature into a functional, inclusive, and innovative network.</p>
|
||||
|
@ -44,9 +43,7 @@
|
|||
<p>They will uphold the ideas explored in the <a href="/manifesto">Manifesto</a>, setting the prime example of Handmade values in their development, behavior, and character.</p>
|
||||
<p>They agree to enforce the code of conduct as written and accepted by the community, understanding that there are times when enforcement involves consequences for those shown to be in repeated and flagrant violation thereof.</p>
|
||||
<p>They also agree to ensure all future revisions to such are accepted by and in the best interest of the community.</p>
|
||||
<a class="external" href="https://creativecommons.org/licenses/by-sa/4.0" rel="nofollow" target="_blank"><img src="/static/creative-commons-by-sa.png"></a>
|
||||
<p>This code of conduct is released under a <a class="external" href="https://creativecommons.org/licenses/by-sa/4.0">Creative Commons Attribution-ShareAlike 4.0 International License</a>.</p>
|
||||
<p class="mt4 edited">Written by Jeroen van Rijn</p>
|
||||
</div>
|
||||
<p class="c--dim i">Written by Jeroen van Rijn</p>
|
||||
</div>
|
||||
{{ end }}
|
||||
|
|
|
@ -1,8 +1,7 @@
|
|||
{{ template "base.html" . }}
|
||||
|
||||
{{ define "content" }}
|
||||
<div class="content-block">
|
||||
<div class="description mw7 ph3 ph0-ns">
|
||||
<div class="center-layout mw7 mv3 ph3 ph0-ns post-content">
|
||||
<h1>Handmade Guide to Community Interaction v1.0</h1>
|
||||
<h2>Our Philosophy</h2>
|
||||
<p>The Handmade community strives to create an environment conducive to innovation, education, and constructive discussion. To that end, we expect members of the site to respect the following set of principles to maintain civil discourse and create an inclusive environment.</p>
|
||||
|
@ -38,10 +37,8 @@
|
|||
<li>Advertise projects for what they are and what their authors have reasonable hope and expectations their project will become.</li>
|
||||
</ul>
|
||||
<p>It is up to the discretion of the moderators to determine when these guidelines are being met, and they are permitted to act accordingly.</p>
|
||||
<p>If you feel an action has been made against you unreasonably, please contact the <a href="/contact">Handmade Dev Team</a> privately with your grievance and we will review the decision.</p>
|
||||
<a class="external" href="https://creativecommons.org/licenses/by-sa/4.0" rel="nofollow" target="_blank"><img src="/static/creative-commons-by-sa.png"></a>
|
||||
<p>If you feel an action has been made against you unreasonably, please contact the <a href="/contact">Handmade Network Team</a> privately with your grievance and we will review the decision.</p>
|
||||
<p>This code of conduct is released under a <a class="external" href="https://creativecommons.org/licenses/by-sa/4.0">Creative Commons Attribution-ShareAlike 4.0 International License</a>.</p>
|
||||
<p class="mt4 edited">Written by Jeroen van Rijn</p>
|
||||
</div>
|
||||
<p class="c--dim i">Written by Jeroen van Rijn</p>
|
||||
</div>
|
||||
{{ end }}
|
||||
|
|
|
@ -3,7 +3,7 @@
|
|||
{{ define "content" }}
|
||||
<div class="content-block">
|
||||
{{ range .Subforums }}
|
||||
<div class="pv3">
|
||||
<div class="mv3">
|
||||
<h2 class="ma0 ph3 pb2">
|
||||
<a href="{{ .Url }}">
|
||||
{{ .Name }} »<br/>
|
||||
|
|
|
@ -44,20 +44,10 @@
|
|||
|
||||
<link rel="stylesheet" href="{{ statictheme .Theme "theme.css" }}" />
|
||||
<link rel="stylesheet" href="{{ .ProjectCSSUrl }}" />
|
||||
<link rel="apple-touch-icon" sizes="57x57" href="{{ static "apple-icon-57x57.png" }}">
|
||||
<link rel="apple-touch-icon" sizes="60x60" href="{{ static "apple-icon-60x60.png" }}">
|
||||
<link rel="apple-touch-icon" sizes="72x72" href="{{ static "apple-icon-72x72.png" }}">
|
||||
<link rel="apple-touch-icon" sizes="76x76" href="{{ static "apple-icon-76x76.png" }}">
|
||||
<link rel="apple-touch-icon" sizes="114x114" href="{{ static "apple-icon-114x114.png" }}">
|
||||
<link rel="apple-touch-icon" sizes="120x120" href="{{ static "apple-icon-120x120.png" }}">
|
||||
<link rel="apple-touch-icon" sizes="144x144" href="{{ static "apple-icon-144x144.png" }}">
|
||||
<link rel="apple-touch-icon" sizes="152x152" href="{{ static "apple-icon-152x152.png" }}">
|
||||
<link rel="apple-touch-icon" sizes="180x180" href="{{ static "apple-icon-180x180.png" }}">
|
||||
<link rel="icon" type="image/png" sizes="192x192" href="{{ static "android-icon-192x192.png" }}">
|
||||
<link rel="apple-touch-icon" href="{{ static "logo.png" }}">
|
||||
<link rel="icon" type="image/png" sizes="16x16" href="{{ static "favicon-16x16.png" }}">
|
||||
<link rel="icon" type="image/png" sizes="32x32" href="{{ static "favicon-32x32.png" }}">
|
||||
<link rel="icon" type="image/png" sizes="96x96" href="{{ static "favicon-96x96.png" }}">
|
||||
<link rel="manifest" href="{{ static "manifest.json" }}">
|
||||
<link rel="icon" type="image/png" sizes="400x400" href="{{ static "logo.png" }}">
|
||||
<meta name="msapplication-TileColor" content="#ffffff">
|
||||
<meta name="msapplication-TileImage" content="{{ static "ms-icon-144x144.png" }}">
|
||||
<meta name="theme-color" content="#ffffff">
|
||||
|
@ -83,7 +73,7 @@
|
|||
{{ template "header.html" . }}
|
||||
{{ template "notices.html" .Notices }}
|
||||
{{ with .Breadcrumbs }}
|
||||
<div class="tc tl-ns ph2 ph0-ns pb2 pb0-ns">
|
||||
<div class="tc tl-ns ph2 ph0-ns mb2">
|
||||
{{ range $i, $e := . -}}
|
||||
{{- if gt $i 0 -}}
|
||||
<span class="ph2">»</span>
|
||||
|
|
|
@ -1,8 +1,7 @@
|
|||
{{ template "base.html" . }}
|
||||
|
||||
{{ define "content" }}
|
||||
<div class="content-block">
|
||||
<div class="description mw7 ph3 ph0-ns">
|
||||
<div class="center-layout mw7 mv3 ph3 ph0-ns post-content">
|
||||
<p>Modern computer hardware is amazing. Manufacturers have orchestrated billions of pieces of silicon into terrifyingly complex and efficient structures that sweep electrons through innumerable tangled paths, branchings, and reunions with the sole purpose of performing computations at more than a billion times per second. This awe-inspiring piece of computational wizardry has at its disposal multiple billions of uniquely addressible silicon plates where it can store the results of millions of computations in an array of several vanishingly small chips. All of this hardware, though each component often sits no further than 7 or 8 centimeters away from the others, cycles so fast that the speed of light, a physical law of the universe, limits the rate at which they communicate with each other.</p>
|
||||
<h2>So why is software still slow?</h2>
|
||||
<p>Why does it take your operating system 10 seconds, 30 seconds, a minute to boot up? Why does your word processor freeze when you save a document on the cloud? Why does your web browser take 3, 4, 10 seconds to load a web page? Why does your phone struggle to keep more than a few apps open at a time? And why does each update somehow make the problem worse?</p>
|
||||
|
@ -19,7 +18,6 @@
|
|||
<p>It doesn't require a degree, or a dissertation, or a decade of experience. You don't need an expensive computer or a certificate or even prior knowledge. All you need is an open mind and a sense of curiosity. We'll help you with the rest.</p>
|
||||
<h2>Will you join us?</h2>
|
||||
<p>Will you build your software by hand?</p>
|
||||
<p class="edited mt4">Written by Andrew Chronister</p>
|
||||
</div>
|
||||
<p class="c--dim i">Written by Andrew Chronister</p>
|
||||
</div>
|
||||
{{ end }}
|
||||
|
|
|
@ -158,7 +158,7 @@ func BlogThread(c *RequestContext) ResponseData {
|
|||
return FourOhFour(c)
|
||||
}
|
||||
|
||||
thread, posts := FetchThreadPostsAndStuff(
|
||||
thread, posts, preview := FetchThreadPostsAndStuff(
|
||||
c.Context(),
|
||||
c.Conn,
|
||||
cd.ThreadID,
|
||||
|
@ -200,6 +200,10 @@ func BlogThread(c *RequestContext) ResponseData {
|
|||
}
|
||||
|
||||
baseData := getBaseData(c, thread.Title, []templates.Breadcrumb{BlogBreadcrumb(c.CurrentProject.Slug)})
|
||||
baseData.OpenGraphItems = append(baseData.OpenGraphItems, templates.OpenGraphItem{
|
||||
Property: "og:description",
|
||||
Value: preview,
|
||||
})
|
||||
|
||||
var res ResponseData
|
||||
res.MustWriteTemplate("blog_post.html", blogPostData{
|
||||
|
|
|
@ -449,7 +449,7 @@ func ForumThread(c *RequestContext) ResponseData {
|
|||
}
|
||||
|
||||
c.Perf.StartBlock("SQL", "Fetch posts")
|
||||
_, postsAndStuff := FetchThreadPostsAndStuff(
|
||||
_, postsAndStuff, preview := FetchThreadPostsAndStuff(
|
||||
c.Context(),
|
||||
c.Conn,
|
||||
cd.ThreadID,
|
||||
|
@ -497,6 +497,10 @@ func ForumThread(c *RequestContext) ResponseData {
|
|||
}
|
||||
|
||||
baseData := getBaseData(c, thread.Title, SubforumBreadcrumbs(cd.LineageBuilder, c.CurrentProject, cd.SubforumID))
|
||||
baseData.OpenGraphItems = append(baseData.OpenGraphItems, templates.OpenGraphItem{
|
||||
Property: "og:description",
|
||||
Value: preview,
|
||||
})
|
||||
|
||||
var res ResponseData
|
||||
res.MustWriteTemplate("forum_thread.html", forumThreadData{
|
||||
|
|
|
@ -318,6 +318,10 @@ func Index(c *RequestContext) ResponseData {
|
|||
|
||||
baseData := getBaseData(c, "", nil)
|
||||
baseData.BodyClasses = append(baseData.BodyClasses, "hmdev", "landing") // TODO: Is "hmdev" necessary any more?
|
||||
baseData.OpenGraphItems = append(baseData.OpenGraphItems, templates.OpenGraphItem{
|
||||
Property: "og:description",
|
||||
Value: "A community of programmers committed to producing quality software through deeper understanding",
|
||||
})
|
||||
|
||||
var res ResponseData
|
||||
err = res.WriteTemplate("landing.html", LandingTemplateData{
|
||||
|
|
|
@ -178,7 +178,7 @@ func ProjectIndex(c *RequestContext) ResponseData {
|
|||
}
|
||||
c.Perf.EndBlock()
|
||||
|
||||
baseData := getBaseDataAutocrumb(c, "Project List")
|
||||
baseData := getBaseDataAutocrumb(c, "Projects")
|
||||
var res ResponseData
|
||||
res.MustWriteTemplate("project_index.html", ProjectTemplateData{
|
||||
BaseData: baseData,
|
||||
|
@ -366,6 +366,11 @@ func ProjectHomepage(c *RequestContext) ResponseData {
|
|||
if canEdit {
|
||||
projectHomepageData.BaseData.Header.EditUrl = hmnurl.BuildProjectEdit(project.Slug, "")
|
||||
}
|
||||
projectHomepageData.BaseData.OpenGraphItems = append(projectHomepageData.BaseData.OpenGraphItems, templates.OpenGraphItem{
|
||||
Property: "og:description",
|
||||
Value: project.Blurb,
|
||||
})
|
||||
|
||||
projectHomepageData.Project = templates.ProjectToTemplate(project, c.Theme)
|
||||
for _, owner := range owners {
|
||||
projectHomepageData.Owners = append(projectHomepageData.Owners, templates.UserToTemplate(owner, c.Theme))
|
||||
|
|
|
@ -304,7 +304,7 @@ func getBaseData(c *RequestContext, title string, breadcrumbs []templates.Breadc
|
|||
|
||||
ReportIssueMailto: "team@handmade.network",
|
||||
|
||||
OpenGraphItems: buildDefaultOpenGraphItems(c.CurrentProject),
|
||||
OpenGraphItems: buildDefaultOpenGraphItems(c.CurrentProject, title),
|
||||
|
||||
IsProjectPage: !c.CurrentProject.IsHMN(),
|
||||
Header: templates.Header{
|
||||
|
@ -344,12 +344,21 @@ func getBaseData(c *RequestContext, title string, breadcrumbs []templates.Breadc
|
|||
return baseData
|
||||
}
|
||||
|
||||
func buildDefaultOpenGraphItems(project *models.Project) []templates.OpenGraphItem {
|
||||
func buildDefaultOpenGraphItems(project *models.Project, title string) []templates.OpenGraphItem {
|
||||
if title == "" {
|
||||
title = "Handmade Network"
|
||||
}
|
||||
|
||||
image := hmnurl.BuildPublic("logo.png", false)
|
||||
if !project.IsHMN() {
|
||||
image = hmnurl.BuildUserFile(project.LogoLight)
|
||||
}
|
||||
|
||||
return []templates.OpenGraphItem{
|
||||
{Property: "og:site_name", Value: "Handmade.Network"},
|
||||
{Property: "og:title", Value: title},
|
||||
{Property: "og:site_name", Value: "Handmade Network"},
|
||||
{Property: "og:type", Value: "website"},
|
||||
{Property: "og:image", Value: hmnurl.BuildUserFile(project.LogoLight)},
|
||||
{Property: "og:image:secure_url", Value: hmnurl.BuildUserFile(project.LogoLight)},
|
||||
{Property: "og:image", Value: image},
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -1,8 +1,16 @@
|
|||
package website
|
||||
|
||||
import "git.handmade.network/hmn/hmn/src/templates"
|
||||
|
||||
func Manifesto(c *RequestContext) ResponseData {
|
||||
baseData := getBaseDataAutocrumb(c, "Handmade Manifesto")
|
||||
baseData.OpenGraphItems = append(baseData.OpenGraphItems, templates.OpenGraphItem{
|
||||
Property: "og:description",
|
||||
Value: "Modern computer hardware is amazing. Manufacturers have orchestrated billions of pieces of silicon into terrifyingly complex and efficient structures…",
|
||||
})
|
||||
|
||||
var res ResponseData
|
||||
res.MustWriteTemplate("manifesto.html", getBaseDataAutocrumb(c, "Manifesto"), c.Perf)
|
||||
res.MustWriteTemplate("manifesto.html", baseData, c.Perf)
|
||||
return res
|
||||
}
|
||||
|
||||
|
@ -13,14 +21,26 @@ func About(c *RequestContext) ResponseData {
|
|||
}
|
||||
|
||||
func CodeOfConduct(c *RequestContext) ResponseData {
|
||||
baseData := getBaseDataAutocrumb(c, "Code of Conduct")
|
||||
baseData.OpenGraphItems = append(baseData.OpenGraphItems, templates.OpenGraphItem{
|
||||
Property: "og:description",
|
||||
Value: "The Handmade community is an international community of creatives dedicated to building and improving high quality software. These are the guidelines we pledge to uphold to maintain a healthy community.",
|
||||
})
|
||||
|
||||
var res ResponseData
|
||||
res.MustWriteTemplate("code_of_conduct.html", getBaseDataAutocrumb(c, "Code of Conduct"), c.Perf)
|
||||
res.MustWriteTemplate("code_of_conduct.html", baseData, c.Perf)
|
||||
return res
|
||||
}
|
||||
|
||||
func CommunicationGuidelines(c *RequestContext) ResponseData {
|
||||
baseData := getBaseDataAutocrumb(c, "Communication Guidelines")
|
||||
baseData.OpenGraphItems = append(baseData.OpenGraphItems, templates.OpenGraphItem{
|
||||
Property: "og:description",
|
||||
Value: "The Handmade community strives to create an environment conducive to innovation, education, and constructive discussion. These are the principles we expect members to respect.",
|
||||
})
|
||||
|
||||
var res ResponseData
|
||||
res.MustWriteTemplate("communication_guidelines.html", getBaseDataAutocrumb(c, "Communication Guidelines"), c.Perf)
|
||||
res.MustWriteTemplate("communication_guidelines.html", baseData, c.Perf)
|
||||
return res
|
||||
}
|
||||
|
||||
|
|
|
@ -126,7 +126,7 @@ func FetchThreadPostsAndStuff(
|
|||
connOrTx db.ConnOrTx,
|
||||
threadId int,
|
||||
page, postsPerPage int,
|
||||
) (models.Thread, []postAndRelatedModels) {
|
||||
) (models.Thread, []postAndRelatedModels, string) {
|
||||
limit := postsPerPage
|
||||
offset := (page - 1) * postsPerPage
|
||||
if postsPerPage == 0 {
|
||||
|
@ -188,7 +188,24 @@ func FetchThreadPostsAndStuff(
|
|||
})
|
||||
}
|
||||
|
||||
return thread, posts
|
||||
preview, err := db.QueryString(ctx, connOrTx,
|
||||
`
|
||||
SELECT post.preview
|
||||
FROM
|
||||
handmade_post AS post
|
||||
JOIN handmade_thread AS thread ON post.thread_id = thread.id
|
||||
JOIN handmade_postversion AS ver ON post.current_id = ver.id
|
||||
WHERE
|
||||
post.thread_id = $1
|
||||
AND thread.first_id = post.id
|
||||
`,
|
||||
thread.ID,
|
||||
)
|
||||
if err != nil && !errors.Is(err, db.ErrNoMatchingRows) {
|
||||
panic(oops.New(err, "failed to fetch posts for thread"))
|
||||
}
|
||||
|
||||
return thread, posts, preview
|
||||
}
|
||||
|
||||
func UserCanEditPost(ctx context.Context, connOrTx db.ConnOrTx, user models.User, postId int) bool {
|
||||
|
|