diff --git a/public/roles/network_brainstorming.png b/public/roles/network_brainstorming.png new file mode 100644 index 0000000..896acea Binary files /dev/null and b/public/roles/network_brainstorming.png differ diff --git a/public/style.css b/public/style.css index d8949a9..4d37c95 100644 --- a/public/style.css +++ b/public/style.css @@ -7369,6 +7369,10 @@ article code { flex-grow: 1; flex-shrink: 1; } } +.c--normal { + color: black; + color: var(--fg-font-color); } + .c--inherit { color: inherit; } .c--inherit:hover, .c--inherit:active { diff --git a/src/hmnurl/urls.go b/src/hmnurl/urls.go index 8ee16af..416053d 100644 --- a/src/hmnurl/urls.go +++ b/src/hmnurl/urls.go @@ -172,6 +172,13 @@ func BuildAbout() string { return Url("/about", nil) } +var RegexFoundation = regexp.MustCompile("^/foundation$") + +func BuildFoundation() string { + defer CatchPanic() + return Url("/foundation", nil) +} + var RegexCommunicationGuidelines = regexp.MustCompile("^/communication-guidelines$") func BuildCommunicationGuidelines() string { @@ -207,6 +214,24 @@ func BuildConferences() string { return Url("/conferences", nil) } +/* +* Volunteer/Staff Roles + */ + +var RegexStaffRolesIndex = regexp.MustCompile(`^/roles$`) + +func BuildStaffRolesIndex() string { + defer CatchPanic() + return Url("/roles", nil) +} + +var RegexStaffRole = regexp.MustCompile(`^/roles/(?P[^/]+)$`) + +func BuildStaffRole(slug string) string { + defer CatchPanic() + return Url(fmt.Sprintf("/roles/%s", slug), nil) +} + /* * User */ diff --git a/src/rawdata/scss/_core.scss b/src/rawdata/scss/_core.scss index 594fa37..b66c5ac 100644 --- a/src/rawdata/scss/_core.scss +++ b/src/rawdata/scss/_core.scss @@ -197,6 +197,10 @@ article code { } } +.c--normal { + @include usevar('color', 'fg-font-color'); +} + .c--inherit { color: inherit; diff --git a/src/templates/src/about.html b/src/templates/src/about.html index d66e199..c1499fb 100644 --- a/src/templates/src/about.html +++ b/src/templates/src/about.html @@ -1,24 +1,102 @@ {{ template "base.html" . }} {{ define "content" }} -
-
-

We're a small group of programmers and idealists who are trying to make programming better for everyone. And we think the best way to do that is by collecting the best, down-to-earth programming projects in one place and building a community of the most talented programmers and most eager learners we can find.

-

Abner Coimbre

-

Abner Coimbre started Handmade Network when rallying the Handmade Hero community around a common goal. He leads the policies, initiatives, and public facing of the network. Abner became NASA's Kennedy Intern of the Year in 2015 and was named to Kennedy’s 2016 Top 10 Innovators. In 2017 Abner moved to Seattle, WA to work for Jonathan Blow's studio Thekla Inc.

-

Twitter: @AbnerCoimbre

-

Jeroen van Rijn

-

Jeroen is just this guy, you know. He's a veteran programmer who at one time found himself chin deep in webdev and decided the best thing for his sanity was to retire from it. Then Abner proposed what would become Handmade Network and he decided to dust off his keyboard and join the fray, only to find the keyboard wasn't particularly dusty yet. Some keys were getting stuck or unresponsive, sure, but a replacement keyboard soon fixed that. When not wrangling RSI, he develops the backend software that makes the website tick.

-

Apart from this he has a keen interest in low-level programming, optimisation, compiler writing and games development, among other subjects. When the site software is sufficiently mature, he plans to do an educational series on the Handmade Network, passing on some of the 30 years of collected knowledge he's gathered.

-

Twitter: @J_vanRijn

-

Matt Mascarenhas

-

Matt is a lifelong computer user, music player and book reader. In contrast to everyone else on the Handmade Network team, his education only touched on computer programming, having culminated with a degree in English language and literature. Or, rather, it would have culminated there had Casey not begun his educational programming project Handmade Hero.

-

Within the Handmade Network, Matt has become the person to ask if you want to know if / when Casey covered a particular topic on Handmade Hero – at least until the annotation system receives its long-expected overhaul, at which point he'll become partially redundant – and will be the first port of call should you have any issues with the Handmade Network website.

-

While not annotating or grepping the annotations for answers to people's questions, Matt practises programming in C with a view to developing a bunch of software – to play, to run your console-based applications, for doing linguistic research and for staging theatrical productions – writes audio and story for games, and evangelises his Arch Linux system, taking full credit for Abner's discovery of the beautiful distribution.

-

Twitter: @miblo_

-

Andrew Chronister

-

Andrew is co-developer of Handmade Network and a student of computer engineering at the University of Washington. When he's not coding away at his project of the month, he can be found doing pointless math and cracking bad jokes on niche experimental decentralized social networks.

-

Mastodon: @chr@cybre.space

+
+
+

+ We're trying to put programming back on the right track. +

+

+ Software is bad and getting worse. Despite amazing advances in hardware, today's software has made computers slower and buggier than they were decades ago. People's computers are more powerful than they know. They deserve better. +

+

+ Inspired by Casey Muratori's Handmade Hero, Abner Coimbre founded Handmade Network as a hub for fans of the show. Since then, the community has grown massively, launched many careers, and spawned amazing projects that thousands of people use every day. +

+ +

+ We can teach programmers how things actually work. We can teach users to expect better. We can build the best software you've ever seen. Join us. +

+
+ +
+

Leadership

+
+
+

Ben Visness

+

Lead

+

+ Ben is the leader of the Handmade Network. He has been a community admin since 2018, and became the official community lead in 2022. Frustrated by what he was being taught in college, Ben joined the Handmade community in 2016 and started learning what actually matters in programming. (He did graduate, though.) +

+

+ As community lead and foundation president, Ben sets the vision and direction for the Handmade community and writes a lot of web pages like this one. +

+

+ On the professional side, after many years in web development, Ben now works at Mozilla as a WebAssembly engineer. He also coaches a FIRST Robotics Competition team. +

+ +
+ +
+

Asaf Gartner

+

Admin

+

+ Asaf is an experienced member of the Handmade community, having been a part of it since its inception. He was drawn to the community while growing increasingly dissatisfied with the prevalent culture in web development, and in 2018 he joined the admin team to help build the HMN website and move the network forward. +

+

+ With a severe allergy to unnecessary complexity, he is constantly looking for ways to create software that doesn't frustrate the user. +

+
+ +
+

Colin Davidson

+

Admin

+

+ Colin is a generalist systems engineer who likes to tinker with strange hardware, and works up and down the tech stack for fun. He started the ball rolling on the education side of Handmade Network, looking to ease the learning process for new Handmade adventurers. He cares deeply about spreading mechanical sympathy, helping others write code that makes the computer happy, so that users running upstack can experience the same fast-computer joy that a lucky few embedded engineers on terrible hardware enjoy every day. +

+

+ Professionally, Colin has worked with embedded user and kernelspace networking, front and backend webdev, and hypervisor infrastructure. He also spends a fair amount of time plonking around on the guitar, working with the Odin team, and writing code instrospection tools to debug his hobby kernel projects. +

+
+
+
+ +
+

Key Contributors

+
+
+

Martin Fouilleul

+

[Secret Project] Lead

+

Martin is a PhD student at Ircam, researching programming languages and models for distributed temporal interactions in music and performing arts software. He is also a former sound engineer and computer music designer.

+

Right now he is working behind the scenes on a secret Handmade Network project, to be revealed at a later date.

+
+
+

???

+

Education Lead

+

+ This could be you! Education is one of our flagship initiatives, and we are looking for someone to lead it. If you are excited about programming education and want to help out, please learn more and get in touch! +

+
+
+
+
+

???

+

Advocacy Lead

+

+ This could be you! We want to go out into the world and advocate for better software and better programming practices. We need a strong communicator who can lead this for us. If this excites you, please learn more and get in touch! +

+
+
+

???

+

Design Lead

+

+ This could be you! Building software for people means designing software for people. We are looking for someone with visual and UX design skills to design website features, event art, livestreaming assets, educational graphics, and more. If any of this sounds interesting to you, learn more and get in touch! +

+
+
{{ end }} diff --git a/src/templates/src/contact.html b/src/templates/src/contact.html index efc8a50..13600a8 100644 --- a/src/templates/src/contact.html +++ b/src/templates/src/contact.html @@ -3,14 +3,12 @@ {{ define "content" }}
-

If you are experiencing technical issues with the site, please send a detailed email to team@handmade.network with a description of the problem, and we'll do our best to address it in a timely manner.

-

For administrative issues, such as moderation disputes or content revisions, contact any of the staff by email:

- +

+ If you are experiencing technical issues with the site, please send a detailed email to team@handmade.network with a description of the problem, and we'll do our best to address it in a timely manner. +

+

+ For administrative issues, such as moderation disputes or content revisions, contact any of the staff on Discord, or by email at team@handmade.network. +

{{ end }} diff --git a/src/templates/src/foundation.html b/src/templates/src/foundation.html new file mode 100644 index 0000000..e0b0c84 --- /dev/null +++ b/src/templates/src/foundation.html @@ -0,0 +1,8 @@ +{{ template "base.html" . }} + +{{ define "content" }} +
+

Handmade Software Foundation

+ +
+{{ end }} diff --git a/src/templates/src/include/footer.html b/src/templates/src/include/footer.html index 5f6d0f3..72b87b4 100644 --- a/src/templates/src/include/footer.html +++ b/src/templates/src/include/footer.html @@ -7,14 +7,14 @@
  • Main Page
  • +
  • + Manifesto +
  • About
  • - Handmade Manifesto -
  • -
  • - Forums + Roles
  • Projects diff --git a/src/templates/src/include/role_card.html b/src/templates/src/include/role_card.html new file mode 100644 index 0000000..6cdd37c --- /dev/null +++ b/src/templates/src/include/role_card.html @@ -0,0 +1,8 @@ + +
    +

    {{ .Name }}

    +
    + {{ .Description }} +
    +
    +
    diff --git a/src/templates/src/layouts/role_base.html b/src/templates/src/layouts/role_base.html new file mode 100644 index 0000000..5a0748c --- /dev/null +++ b/src/templates/src/layouts/role_base.html @@ -0,0 +1,19 @@ +{{ template "base.html" . }} + +{{ define "content" }} +
    +

    {{ .Role.Name }}

    + {{ block "role content" . }}{{ end }} + +
    +

    Other roles

    +
    + {{ range .OtherRoles }} +
    + {{ template "role_card.html" . }} +
    + {{ end }} +
    +
    +
    +{{ end }} diff --git a/src/templates/src/manifesto.html b/src/templates/src/manifesto.html index 95b5faa..17795a1 100644 --- a/src/templates/src/manifesto.html +++ b/src/templates/src/manifesto.html @@ -15,7 +15,7 @@

    Some of us aren't satisfied with the current state of software. We think that wheels need to be reinvented. We like looking under the hood, understanding what others take for granted. We remember how software used to be, and know how much potential there is to make it better. We fight against the status quo, because we know how things could be.

    This is what Handmade means. It's not a technique or a language or a management strategy. It's not a library or a framework or a paradigm. It's an idea. The idea that we can build software that works with the computer, not against it. The idea that the user matters more than the programmer. The idea that sometimes a small group can do more than an army of software engineers, and do it better.

    You don't need a degree, a dissertation, or a decade of experience. You don't need an expensive computer or a certificate. All you need is an open mind and a sense of curiosity. We'll help you with the rest.

    -

    Will you join us?

    +

    Will you join us?

    Will you build your software by hand?

    Written by Ben Visness and the Handmade community. Original by Andrew Chronister.

  • diff --git a/src/templates/src/role_advocacy.html b/src/templates/src/role_advocacy.html new file mode 100644 index 0000000..96484fa --- /dev/null +++ b/src/templates/src/role_advocacy.html @@ -0,0 +1,43 @@ +{{ template "role_base.html" . }} + +{{ define "role content" }} +

    + We need to tell the outside world what we're all about. We want to convince programmers and users alike that software is bad and needs to be better. We want to do more than just complain - we want to advocate for better software development practices and better software, period. +

    +

    + To do this, we want someone with great communication skills who can communicate our vision to the outside world. As Advocacy Lead, you can shape the public face of the Handmade Network and Handmade Software Foundation and push for real change in the world of software. +

    +

    + To give you an idea of what we're looking for, here are some of our advocacy ideas: +

    + +

    + With your help, we can show people that there is a better way to build software. If this excites you, please get in touch! See the How to apply section below. +

    + +

    Commitment

    +

    + We would like to produce a few key reports per year - big pieces that can make a splash on Hacker News or other tech media. In addition, we'd like to maintain a consistent public presence through e.g. social media. +

    +

    + How you achieve this is up to you - this position is flexible and many details are up in the air. Overall, we would expect ongoing communication with the leadership team and commitment to publishing the major pieces described above. +

    + +

    How to apply

    +

    + Send us an email at team@handmade.network or contact @bvisness on Discord. Please share with us: +

    +

    + Like all Handmade Network positions, this is a volunteer role. Thank you for your interest! +

    +{{ end }} diff --git a/src/templates/src/role_design.html b/src/templates/src/role_design.html new file mode 100644 index 0000000..2e0c5d9 --- /dev/null +++ b/src/templates/src/role_design.html @@ -0,0 +1,46 @@ +{{ template "role_base.html" . }} + +{{ define "role content" }} +

    + We are looking for someone with visual design and UX skills to set the visual direction for everything the Network and Foundation does. Whether that's making promotional art for events or making infographics for education, we need a consistent visual voice and appealing presentation. +

    +

    + Here are some examples of what you might do: +

    +

    +

    + If any of this excites you, please get in touch! See the How to apply section below. +

    + +

    Commitment

    +

    + Our design needs fluctuate over time, but we always have a long list of things to improve. +

    +

    + At a minimum, we would expect you to be on call for design needs and to produce mockups or assets within a week of the request. (Timing may vary depending on the scope of work requested.) However, we would be thrilled with any other design work you choose to contribute - we want our stuff to look and feel good! +

    + +

    How to apply

    +

    + Send us an email at team@handmade.network or contact @bvisness on Discord. Please share a portfolio or other examples of your work. +

    +

    + Like all Handmade Network positions, this is a volunteer role. Thank you for your interest! +

    +{{ end }} diff --git a/src/templates/src/role_education.html b/src/templates/src/role_education.html new file mode 100644 index 0000000..5c732a7 --- /dev/null +++ b/src/templates/src/role_education.html @@ -0,0 +1,45 @@ +{{ template "role_base.html" . }} + +{{ define "role content" }} +

    + Education is one of the Foundation's flagship initiatives. We want to provide serious educational material for programmers that goes deeper than anything else on the internet, and equips programmers to learn directly from real sources. +

    +

    + We are looking for someone to head up our educational activities. This includes: +

    +

    +

    + If this sounds interesting to you, please get in touch! See the How to apply section below. +

    + +

    Commitment

    +

    + As one of our flagship initiatives, our educational content needs ongoing attention. You would be expected to spend at least a few hours a week on Handmade education and to stay in frequent communication with external contributors. You would also be expected to lead any education-related meetings and to be the point of contact for any education-related inquiries. +

    +

    + In general, we want new and updated educational material to be released on a regular basis, and it would be your job to make that happen! +

    + +

    How to apply

    +

    + Send us an email at team@handmade.network or contact @bvisness on Discord. Please share with us: +

    +

    +

    + Like all Handmade Network positions, this is a volunteer role. Thank you for your interest! +

    +{{ end }} diff --git a/src/templates/src/roles.html b/src/templates/src/roles.html new file mode 100644 index 0000000..a092e65 --- /dev/null +++ b/src/templates/src/roles.html @@ -0,0 +1,17 @@ +{{ template "base.html" . }} + +{{ define "content" }} +
    +

    Get involved!

    +

    + Excited about our mission? We want your help with the following positions: +

    +
    + {{ range .Roles }} +
    + {{ template "role_card.html" . }} +
    + {{ end }} +
    +
    +{{ end }} diff --git a/src/templates/types.go b/src/templates/types.go index 8810e10..1cc6851 100644 --- a/src/templates/types.go +++ b/src/templates/types.go @@ -75,7 +75,7 @@ type Footer struct { CodeOfConductUrl string CommunicationGuidelinesUrl string ProjectIndexUrl string - ForumsUrl string + RolesUrl string ContactUrl string SearchActionUrl string } diff --git a/src/website/base_data.go b/src/website/base_data.go index 1c0e607..0141038 100644 --- a/src/website/base_data.go +++ b/src/website/base_data.go @@ -84,7 +84,7 @@ func getBaseData(c *RequestContext, title string, breadcrumbs []templates.Breadc ManifestoUrl: hmnurl.BuildManifesto(), CommunicationGuidelinesUrl: hmnurl.BuildCommunicationGuidelines(), ProjectIndexUrl: hmnurl.BuildProjectIndex(1), - ForumsUrl: hmnurl.HMNProjectContext.BuildForum(nil, 1), + RolesUrl: hmnurl.BuildStaffRolesIndex(), ContactUrl: hmnurl.BuildContactPage(), SearchActionUrl: "https://duckduckgo.com", }, diff --git a/src/website/roles.go b/src/website/roles.go new file mode 100644 index 0000000..93b03c4 --- /dev/null +++ b/src/website/roles.go @@ -0,0 +1,107 @@ +package website + +import ( + "net/http" + + "git.handmade.network/hmn/hmn/src/hmnurl" + "git.handmade.network/hmn/hmn/src/templates" +) + +type Role struct { + Slug string + Name string + Description string + Template string + Url string // weird and redundant + + RedirectSlug string +} + +var roles = []Role{ + { + Slug: "education", + Name: "Education Lead", + Description: "Lead our flagship education initiative and make sure we're putting out a steady stream of content.", + Template: "role_education.html", + Url: hmnurl.BuildStaffRole("education"), + }, + { + Slug: "advocacy", + Name: "Advocacy Lead", + Description: "Put the Handmade ethos into the world by advocating for better software and better programming practices.", + Template: "role_advocacy.html", + Url: hmnurl.BuildStaffRole("advocacy"), + }, + { + Slug: "design", + Name: "Design Lead", + Description: "Set the visual direction for everything we do. Make key art, design website features, and more.", + Template: "role_design.html", + Url: hmnurl.BuildStaffRole("design"), + }, +} + +const StaffRolesIndexName = "Roles" + +func StaffRolesIndex(c *RequestContext) ResponseData { + type TemplateData struct { + templates.BaseData + Roles []Role + } + + var res ResponseData + res.MustWriteTemplate("roles.html", TemplateData{ + BaseData: getBaseDataAutocrumb(c, StaffRolesIndexName), + Roles: roles, + }, c.Perf) + return res +} + +func StaffRole(c *RequestContext) ResponseData { + type TemplateData struct { + templates.BaseData + Role Role + OtherRoles []Role + } + + slug := c.PathParams["slug"] + role, ok := getRole(slug) + if !ok { + return FourOhFour(c) // TODO: Volunteering-specific 404 + } + + if role.RedirectSlug != "" { + return c.Redirect(hmnurl.BuildStaffRole(role.RedirectSlug), http.StatusSeeOther) + } + + var otherRoles []Role + for _, otherRole := range roles { + if otherRole.Slug == role.Slug { + continue + } + otherRoles = append(otherRoles, otherRole) + if len(otherRoles) >= 3 { + break + } + } + + var res ResponseData + res.MustWriteTemplate(role.Template, TemplateData{ + BaseData: getBaseData(c, role.Name, []templates.Breadcrumb{ + {Name: StaffRolesIndexName, Url: hmnurl.BuildStaffRolesIndex()}, + {Name: role.Name, Url: ""}, + }), + Role: role, + OtherRoles: otherRoles, + }, c.Perf) + return res +} + +func getRole(slug string) (Role, bool) { + for _, role := range roles { + if role.Slug == slug { + return role, true + } + } + return Role{}, false +} diff --git a/src/website/routes.go b/src/website/routes.go index 0154d4b..7231013 100644 --- a/src/website/routes.go +++ b/src/website/routes.go @@ -48,6 +48,7 @@ func NewWebsiteRoutes(conn *pgxpool.Pool) http.Handler { // NOTE(asaf): HMN-only routes: hmnOnly.GET(hmnurl.RegexManifesto, Manifesto) hmnOnly.GET(hmnurl.RegexAbout, About) + // hmnOnly.GET(hmnurl.RegexFoundation, Foundation) hmnOnly.GET(hmnurl.RegexCommunicationGuidelines, CommunicationGuidelines) hmnOnly.GET(hmnurl.RegexContactPage, ContactPage) hmnOnly.GET(hmnurl.RegexMonthlyUpdatePolicy, MonthlyUpdatePolicy) @@ -59,6 +60,9 @@ func NewWebsiteRoutes(conn *pgxpool.Pool) http.Handler { hmnOnly.GET(hmnurl.RegexJamIndex2022, JamIndex2022) hmnOnly.GET(hmnurl.RegexJamFeed2022, JamFeed2022) + hmnOnly.GET(hmnurl.RegexStaffRolesIndex, StaffRolesIndex) + hmnOnly.GET(hmnurl.RegexStaffRole, StaffRole) + hmnOnly.GET(hmnurl.RegexOldHome, Index) hmnOnly.POST(hmnurl.RegexLoginAction, securityTimerMiddleware(time.Millisecond*100, Login)) diff --git a/src/website/staticpages.go b/src/website/staticpages.go index f54fea6..8262547 100644 --- a/src/website/staticpages.go +++ b/src/website/staticpages.go @@ -1,8 +1,15 @@ package website -import "git.handmade.network/hmn/hmn/src/templates" +import ( + "git.handmade.network/hmn/hmn/src/hmnurl" + "git.handmade.network/hmn/hmn/src/templates" +) func Manifesto(c *RequestContext) ResponseData { + type TemplateData struct { + templates.BaseData + AboutUrl string + } baseData := getBaseDataAutocrumb(c, "Handmade Manifesto") baseData.OpenGraphItems = append(baseData.OpenGraphItems, templates.OpenGraphItem{ Property: "og:description", @@ -10,13 +17,38 @@ func Manifesto(c *RequestContext) ResponseData { }) var res ResponseData - res.MustWriteTemplate("manifesto.html", baseData, c.Perf) + res.MustWriteTemplate("manifesto.html", TemplateData{ + BaseData: baseData, + AboutUrl: hmnurl.BuildAbout(), + }, c.Perf) return res } func About(c *RequestContext) ResponseData { + type TemplateData struct { + templates.BaseData + FoundationUrl string + RolesUrl string + EducationLeadUrl string + AdvocacyLeadUrl string + DesignLeadUrl string + } + var res ResponseData - res.MustWriteTemplate("about.html", getBaseDataAutocrumb(c, "About"), c.Perf) + res.MustWriteTemplate("about.html", TemplateData{ + BaseData: getBaseDataAutocrumb(c, "About"), + FoundationUrl: hmnurl.BuildFoundation(), + RolesUrl: hmnurl.BuildStaffRolesIndex(), + EducationLeadUrl: hmnurl.BuildStaffRole("education"), + AdvocacyLeadUrl: hmnurl.BuildStaffRole("advocacy"), + DesignLeadUrl: hmnurl.BuildStaffRole("design"), + }, c.Perf) + return res +} + +func Foundation(c *RequestContext) ResponseData { + var res ResponseData + res.MustWriteTemplate("foundation.html", getBaseDataAutocrumb(c, "Foundation"), c.Perf) return res }