diff --git a/public/android-icon-144x144.png b/public/android-icon-144x144.png deleted file mode 100644 index 101f25a2..00000000 Binary files a/public/android-icon-144x144.png and /dev/null differ diff --git a/public/android-icon-192x192.png b/public/android-icon-192x192.png deleted file mode 100644 index 65981642..00000000 Binary files a/public/android-icon-192x192.png and /dev/null differ diff --git a/public/android-icon-36x36.png b/public/android-icon-36x36.png deleted file mode 100644 index 2c73870f..00000000 Binary files a/public/android-icon-36x36.png and /dev/null differ diff --git a/public/android-icon-48x48.png b/public/android-icon-48x48.png deleted file mode 100644 index e3e167d6..00000000 Binary files a/public/android-icon-48x48.png and /dev/null differ diff --git a/public/android-icon-72x72.png b/public/android-icon-72x72.png deleted file mode 100644 index 363ae897..00000000 Binary files a/public/android-icon-72x72.png and /dev/null differ diff --git a/public/android-icon-96x96.png b/public/android-icon-96x96.png deleted file mode 100644 index f18359d1..00000000 Binary files a/public/android-icon-96x96.png and /dev/null differ diff --git a/public/apple-icon-114x114.png b/public/apple-icon-114x114.png deleted file mode 100644 index d928a1d5..00000000 Binary files a/public/apple-icon-114x114.png and /dev/null differ diff --git a/public/apple-icon-120x120.png b/public/apple-icon-120x120.png deleted file mode 100644 index cbb2631d..00000000 Binary files a/public/apple-icon-120x120.png and /dev/null differ diff --git a/public/apple-icon-144x144.png b/public/apple-icon-144x144.png deleted file mode 100644 index 101f25a2..00000000 Binary files a/public/apple-icon-144x144.png and /dev/null differ diff --git a/public/apple-icon-152x152.png b/public/apple-icon-152x152.png deleted file mode 100644 index 395c7bfe..00000000 Binary files a/public/apple-icon-152x152.png and /dev/null differ diff --git a/public/apple-icon-180x180.png b/public/apple-icon-180x180.png deleted file mode 100644 index 68f9070b..00000000 Binary files a/public/apple-icon-180x180.png and /dev/null differ diff --git a/public/apple-icon-57x57.png b/public/apple-icon-57x57.png deleted file mode 100644 index ef69c3d1..00000000 Binary files a/public/apple-icon-57x57.png and /dev/null differ diff --git a/public/apple-icon-60x60.png b/public/apple-icon-60x60.png deleted file mode 100644 index a833697e..00000000 Binary files a/public/apple-icon-60x60.png and /dev/null differ diff --git a/public/apple-icon-72x72.png b/public/apple-icon-72x72.png deleted file mode 100644 index 363ae897..00000000 Binary files a/public/apple-icon-72x72.png and /dev/null differ diff --git a/public/apple-icon-76x76.png b/public/apple-icon-76x76.png deleted file mode 100644 index fe344c2f..00000000 Binary files a/public/apple-icon-76x76.png and /dev/null differ diff --git a/public/apple-icon-precomposed.png b/public/apple-icon-precomposed.png deleted file mode 100644 index 52ec936e..00000000 Binary files a/public/apple-icon-precomposed.png and /dev/null differ diff --git a/public/apple-icon.png b/public/apple-icon.png deleted file mode 100644 index 52ec936e..00000000 Binary files a/public/apple-icon.png and /dev/null differ diff --git a/public/favicon-16x16.png b/public/favicon-16x16.png index e1ea7b48..efef8927 100644 Binary files a/public/favicon-16x16.png and b/public/favicon-16x16.png differ diff --git a/public/favicon-32x32.png b/public/favicon-32x32.png index b769ca15..59330b40 100644 Binary files a/public/favicon-32x32.png and b/public/favicon-32x32.png differ diff --git a/public/favicon-96x96.png b/public/favicon-96x96.png deleted file mode 100644 index f18359d1..00000000 Binary files a/public/favicon-96x96.png and /dev/null differ diff --git a/public/logo.png b/public/logo.png new file mode 100644 index 00000000..e1236b4e Binary files /dev/null and b/public/logo.png differ diff --git a/src/db/db.go b/src/db/db.go index e6713b25..cf76995b 100644 --- a/src/db/db.go +++ b/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 { diff --git a/src/templates/src/code_of_conduct.html b/src/templates/src/code_of_conduct.html index c6db30ce..aab09804 100644 --- a/src/templates/src/code_of_conduct.html +++ b/src/templates/src/code_of_conduct.html @@ -1,52 +1,49 @@ {{ template "base.html" . }} {{ define "content" }} -
-
-

Handmade Code of Conduct v1.0

-

The Handmade community is an international community of programmers, designers, artists, musicians, mathematicians, and other creatives dedicated to building and improving high quality software.

-

Outlined herein are the guidelines we pledge to uphold to maintain a healthy community, stay true to the ideas first explored in our Manifesto and refined by valuable feedback, and ensure we mature into a functional, inclusive, and innovative network.

-

COMMUNITY

-

OPEN-MINDED

-

The Handmade community strives to be unprejudiced—we welcome unusual ideas, encourage different points of view, and consider their effectiveness in reality.

-

The Handmade community does not waste time and alienate others by engaging in flame-wars, drawing out pointless arguments, singling out developers, or making attacks on the hard work of others; instead, we learn from exercising the methods that we believe to be reasonable, and offer suggestions on how to improve ourselves and others.

-

DOWN-TO-EARTH

-

Handmade favors the languages and tools that first serve the users of our software by not wasting their time and resources, and second those who develop it by making meaningful abstractions oriented to the task at hand.

-

We try to minimize the emergent complexity of tightly coupled systems, avoid the over-complication by refusing to blindly apply accepted strategies without clear understanding of their costs, and we prefer that which is simple to that which is easy. When uncertain, we make measurements and follow the data.

-

DIVERSE

-

Handmade encourages participation by everyone. We will do everything in our power to ensure everyone feels accepted and respected in their interactions with our community.

-

If someone has been harmed or offended, it is our responsibility to listen carefully and respectfully, and do our best to right the wrong. We accept that jokes and trolling can be taken too far and are not valid excuses for the alienation of any person.

-

Although this list cannot be exhaustive, we explicitly honour diversity in age, culture, ethnicity, family background, gender identity or expression, language, national origin, neurotype, phenotype, political beliefs, profession, race, religion, sexual orientation, socio-economic status, membership in other communities, and technical ability.

-

Some of the ideas and wording for this statement were based on diversity statements from Ubuntu Diversity Page, which is in turn based on the Python community and Dreamwidth Studios (CC-BY-SA 3.0).

-

To see how we encourage participation by everyone, see our Handmade Guide to Community Interaction.

-

INDIVIDUAL

-

INQUISITIVE

-

The Handmade developer strives to understand their creations on a technical level. They will take the time on their personal software projects to meet their goals to the best of their abilities, without taking shortcuts that diminish the value of their work.

-

They include technical understanding and user experience as important metrics for the quality of their creations, and minimize trade-offs which impact these negatively.

-

They will ask questions exhaustively, and always re-evaluate what they consider to be a “good solution” in light of new evidence. Their curiosity is one of the primary driving forces in their work.

-

CONSIDERATE

-

The developer practices empathy; they try to understand how those they interact with and those they create for see the world in order to better understand each other.

-

They realize that their actions in both professional and community contexts can have consequences for other people that they may not immediately understand, and will do their best to correct themselves when they make a mistake.

-

They will, to the best of their abilities, keep those who enjoy their ongoing personal software projects up to date on the state of development and be honest about their progress and achievement of their stated goals.

-

WILLING TO SHARE

-

Handmade community members share their knowledge and expertise unflinchingly. They will not hesitate to lend a hand if the opportunity to improve the software development space arises.

-

They realize that their fellow community member not knowing something is an opportunity rather than a character flaw. They also realize that their knowledge and experience, however deep and long-collected, is not absolute, and accept that the experiences of others may differ.

-

LEADERS

-

TIGHT-KNIT

-

The Handmade Dev Team acts as one unit.

-

The staff are open with each other, make decisions unanimously, and perform their roles admirably for the benefit of the community.

-

RECEPTIVE

-

The leaders are receptive to the state of the community.

-

They will listen to everyone's concerns and make careful, considered judgment calls to move forward or solve a problem.

-

They will never place personal benefit over the well-being of the community, and only act against the community's immediate short-term interests if it’s for the long-term benefit of everyone involved.

-

SERIOUS

-

The leaders are serious about their roles.

-

They will uphold the ideas explored in the Manifesto, setting the prime example of Handmade values in their development, behavior, and character.

-

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.

-

They also agree to ensure all future revisions to such are accepted by and in the best interest of the community.

- -

This code of conduct is released under a Creative Commons Attribution-ShareAlike 4.0 International License.

-

Written by Jeroen van Rijn

-
+
+

Handmade Code of Conduct v1.0

+

The Handmade community is an international community of programmers, designers, artists, musicians, mathematicians, and other creatives dedicated to building and improving high quality software.

+

Outlined herein are the guidelines we pledge to uphold to maintain a healthy community, stay true to the ideas first explored in our Manifesto and refined by valuable feedback, and ensure we mature into a functional, inclusive, and innovative network.

+

COMMUNITY

+

OPEN-MINDED

+

The Handmade community strives to be unprejudiced—we welcome unusual ideas, encourage different points of view, and consider their effectiveness in reality.

+

The Handmade community does not waste time and alienate others by engaging in flame-wars, drawing out pointless arguments, singling out developers, or making attacks on the hard work of others; instead, we learn from exercising the methods that we believe to be reasonable, and offer suggestions on how to improve ourselves and others.

+

DOWN-TO-EARTH

+

Handmade favors the languages and tools that first serve the users of our software by not wasting their time and resources, and second those who develop it by making meaningful abstractions oriented to the task at hand.

+

We try to minimize the emergent complexity of tightly coupled systems, avoid the over-complication by refusing to blindly apply accepted strategies without clear understanding of their costs, and we prefer that which is simple to that which is easy. When uncertain, we make measurements and follow the data.

+

DIVERSE

+

Handmade encourages participation by everyone. We will do everything in our power to ensure everyone feels accepted and respected in their interactions with our community.

+

If someone has been harmed or offended, it is our responsibility to listen carefully and respectfully, and do our best to right the wrong. We accept that jokes and trolling can be taken too far and are not valid excuses for the alienation of any person.

+

Although this list cannot be exhaustive, we explicitly honour diversity in age, culture, ethnicity, family background, gender identity or expression, language, national origin, neurotype, phenotype, political beliefs, profession, race, religion, sexual orientation, socio-economic status, membership in other communities, and technical ability.

+

Some of the ideas and wording for this statement were based on diversity statements from Ubuntu Diversity Page, which is in turn based on the Python community and Dreamwidth Studios (CC-BY-SA 3.0).

+

To see how we encourage participation by everyone, see our Handmade Guide to Community Interaction.

+

INDIVIDUAL

+

INQUISITIVE

+

The Handmade developer strives to understand their creations on a technical level. They will take the time on their personal software projects to meet their goals to the best of their abilities, without taking shortcuts that diminish the value of their work.

+

They include technical understanding and user experience as important metrics for the quality of their creations, and minimize trade-offs which impact these negatively.

+

They will ask questions exhaustively, and always re-evaluate what they consider to be a “good solution” in light of new evidence. Their curiosity is one of the primary driving forces in their work.

+

CONSIDERATE

+

The developer practices empathy; they try to understand how those they interact with and those they create for see the world in order to better understand each other.

+

They realize that their actions in both professional and community contexts can have consequences for other people that they may not immediately understand, and will do their best to correct themselves when they make a mistake.

+

They will, to the best of their abilities, keep those who enjoy their ongoing personal software projects up to date on the state of development and be honest about their progress and achievement of their stated goals.

+

WILLING TO SHARE

+

Handmade community members share their knowledge and expertise unflinchingly. They will not hesitate to lend a hand if the opportunity to improve the software development space arises.

+

They realize that their fellow community member not knowing something is an opportunity rather than a character flaw. They also realize that their knowledge and experience, however deep and long-collected, is not absolute, and accept that the experiences of others may differ.

+

LEADERS

+

TIGHT-KNIT

+

The Handmade Dev Team acts as one unit.

+

The staff are open with each other, make decisions unanimously, and perform their roles admirably for the benefit of the community.

+

RECEPTIVE

+

The leaders are receptive to the state of the community.

+

They will listen to everyone's concerns and make careful, considered judgment calls to move forward or solve a problem.

+

They will never place personal benefit over the well-being of the community, and only act against the community's immediate short-term interests if it’s for the long-term benefit of everyone involved.

+

SERIOUS

+

The leaders are serious about their roles.

+

They will uphold the ideas explored in the Manifesto, setting the prime example of Handmade values in their development, behavior, and character.

+

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.

+

They also agree to ensure all future revisions to such are accepted by and in the best interest of the community.

+

This code of conduct is released under a Creative Commons Attribution-ShareAlike 4.0 International License.

+

Written by Jeroen van Rijn

{{ end }} diff --git a/src/templates/src/communication_guidelines.html b/src/templates/src/communication_guidelines.html index 82e10ee0..f8fdf388 100644 --- a/src/templates/src/communication_guidelines.html +++ b/src/templates/src/communication_guidelines.html @@ -1,47 +1,44 @@ {{ template "base.html" . }} {{ define "content" }} -
-
-

Handmade Guide to Community Interaction v1.0

-

Our Philosophy

-

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.

-

Discourse

-
    -
  • The community is mostly business, with a bit of fun. Discussion should primarily be about software development, and in particular about the relevant project or topic at hand.
  • -
  • Support arguments with evidence and rational discussion. Don't resort to ad hominem attacks or personality judgments.
  • -
  • Differing opinions are valuable and should be respected. Not everyone sees eye-to-eye on every matter, but we're all trying to write useful software.
  • -
  • Language has meaning, and can be used in destructive ways. Be aware that what you say may not seem injurious to you, but might make someone else's experience on the site tangibly worse. If you are asked to reconsider your conduct, please exercise some introspection. We want everyone to feel welcome here. This includes people both inside and outside the Handmade community.
  • -
  • Be aware of differences in English comprehension and culture. What you say may be misinterpreted by a more fluent or less fluent speaker, or someone from a different culture. Misunderstandings should be resolved with the help of a third party, preferably a staff member.
  • -
-

Inclusiveness

-

The Handmade community will encourage participation of underrepresented groups. In order to promote diversity among the community, a Handmade community member shall not:

-
    -
  • Sexualize or objectify other members, even if you think it’s a compliment.
  • -
  • Use pejoratives or excessively rely on foul language, especially if used to attack an individual.
  • -
  • Denigrate, belittle, defame, or speak ill of any individual.
  • -
  • Leave unsubstantiated or unjust criticism on someone's work, or disparage a person while critiquing their work.
  • -
  • Dismiss other people’s contributions, opinions, or concerns based on their personal attributes, especially those described in the Diversity section of the code of conduct.
  • -
  • Be rude. Disagreement is not an excuse to be flippant or inconsiderate.
  • -
  • Antagonize others, particularly if a disagreement has occurred. Instead, a peaceful resolution should be sought, with an impartial third party if necessary.
  • -
  • Assume a motive for uncharacteristic behavior. Everyone has a bad day.
  • -
  • Dwell excessively on a topic or argument when the other parties involved have made it clear they are no longer interested or comfortable discussing it.
  • -
  • Continue to ask a person to disclose information, particularly about their personal lives, when that person has declined to do so.
  • -
-

Integrity

-

The Handmade community values integrity, the honest pursuit of knowledge, and working hard to build effective, uncomplicated software.

-

In particular, we strive to:

-
    -
  • Be honest to others about the state of our work.
  • -
  • Foster an environment where dedicated learners of any skill level may ask questions and receive detailed, useful answers.
  • -
  • Ensure all members of a project are kept up to date on the status of that project.
  • -
  • Advertise projects for what they are and what their authors have reasonable hope and expectations their project will become.
  • -
-

It is up to the discretion of the moderators to determine when these guidelines are being met, and they are permitted to act accordingly.

-

If you feel an action has been made against you unreasonably, please contact the Handmade Dev Team privately with your grievance and we will review the decision.

- -

This code of conduct is released under a Creative Commons Attribution-ShareAlike 4.0 International License.

-

Written by Jeroen van Rijn

-
+
+

Handmade Guide to Community Interaction v1.0

+

Our Philosophy

+

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.

+

Discourse

+
    +
  • The community is mostly business, with a bit of fun. Discussion should primarily be about software development, and in particular about the relevant project or topic at hand.
  • +
  • Support arguments with evidence and rational discussion. Don't resort to ad hominem attacks or personality judgments.
  • +
  • Differing opinions are valuable and should be respected. Not everyone sees eye-to-eye on every matter, but we're all trying to write useful software.
  • +
  • Language has meaning, and can be used in destructive ways. Be aware that what you say may not seem injurious to you, but might make someone else's experience on the site tangibly worse. If you are asked to reconsider your conduct, please exercise some introspection. We want everyone to feel welcome here. This includes people both inside and outside the Handmade community.
  • +
  • Be aware of differences in English comprehension and culture. What you say may be misinterpreted by a more fluent or less fluent speaker, or someone from a different culture. Misunderstandings should be resolved with the help of a third party, preferably a staff member.
  • +
+

Inclusiveness

+

The Handmade community will encourage participation of underrepresented groups. In order to promote diversity among the community, a Handmade community member shall not:

+
    +
  • Sexualize or objectify other members, even if you think it’s a compliment.
  • +
  • Use pejoratives or excessively rely on foul language, especially if used to attack an individual.
  • +
  • Denigrate, belittle, defame, or speak ill of any individual.
  • +
  • Leave unsubstantiated or unjust criticism on someone's work, or disparage a person while critiquing their work.
  • +
  • Dismiss other people’s contributions, opinions, or concerns based on their personal attributes, especially those described in the Diversity section of the code of conduct.
  • +
  • Be rude. Disagreement is not an excuse to be flippant or inconsiderate.
  • +
  • Antagonize others, particularly if a disagreement has occurred. Instead, a peaceful resolution should be sought, with an impartial third party if necessary.
  • +
  • Assume a motive for uncharacteristic behavior. Everyone has a bad day.
  • +
  • Dwell excessively on a topic or argument when the other parties involved have made it clear they are no longer interested or comfortable discussing it.
  • +
  • Continue to ask a person to disclose information, particularly about their personal lives, when that person has declined to do so.
  • +
+

Integrity

+

The Handmade community values integrity, the honest pursuit of knowledge, and working hard to build effective, uncomplicated software.

+

In particular, we strive to:

+
    +
  • Be honest to others about the state of our work.
  • +
  • Foster an environment where dedicated learners of any skill level may ask questions and receive detailed, useful answers.
  • +
  • Ensure all members of a project are kept up to date on the status of that project.
  • +
  • Advertise projects for what they are and what their authors have reasonable hope and expectations their project will become.
  • +
+

It is up to the discretion of the moderators to determine when these guidelines are being met, and they are permitted to act accordingly.

+

If you feel an action has been made against you unreasonably, please contact the Handmade Network Team privately with your grievance and we will review the decision.

+

This code of conduct is released under a Creative Commons Attribution-ShareAlike 4.0 International License.

+

Written by Jeroen van Rijn

{{ end }} diff --git a/src/templates/src/forum.html b/src/templates/src/forum.html index dc0fe6af..99f35632 100644 --- a/src/templates/src/forum.html +++ b/src/templates/src/forum.html @@ -3,7 +3,7 @@ {{ define "content" }}
{{ range .Subforums }} -
+

{{ .Name }} »
diff --git a/src/templates/src/layouts/base.html b/src/templates/src/layouts/base.html index 5bf931e5..4d38c046 100644 --- a/src/templates/src/layouts/base.html +++ b/src/templates/src/layouts/base.html @@ -44,20 +44,10 @@ - - - - - - - - - - + - - + @@ -83,7 +73,7 @@ {{ template "header.html" . }} {{ template "notices.html" .Notices }} {{ with .Breadcrumbs }} -
+
{{ range $i, $e := . -}} {{- if gt $i 0 -}} » diff --git a/src/templates/src/manifesto.html b/src/templates/src/manifesto.html index 6d008abb..a205cf3a 100644 --- a/src/templates/src/manifesto.html +++ b/src/templates/src/manifesto.html @@ -1,25 +1,23 @@ {{ template "base.html" . }} {{ define "content" }} -
-
-

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.

-

So why is software still slow?

-

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?

-

We made it slow.

-

Not necessarily you, not necessarily me, not necessarily any single person in particular. But we, the software development community, made it slow by ignoring the fundamental reality of our occupation. We write code, code that runs on computers. Real computers, with central processing units and random access memory and hard disk drives and display buffers. Real computers, with integer and bitwise math and floating point units and L2 caches, with threads and cores and a tenuous little network connection to a million billion other computers. Real computers not built for ease of human understanding but for blindingly, incomprehensibly fast speed.

-

A lot of us have forgotten that.

-

In our haste to get our products, our projects, the works of our hands and minds, to as many people as possible, we take shortcuts. We make assumptions. We generalize, and abstract, and assume that just because these problems have been solved before that they never need to be solved again. We build abstraction layers, then forget we built them and build more on top.

-

And it's true that many of us think we do not have the time, the money, the mental bandwidth to always consider these things in detail. The deadline is approaching or the rent is due or we have taxes to fill out and a manager on our back and someone asking us why we always spend so much time at the office, and we just have to stick the library or virtual machine or garbage collector in there to cover up the places we can't think through right now.

-

Others of us were never taught to think about the computer itself. We learned about objects and classes and templates and how to make our code clean and pretty. We learned how to write code to make the client or the manager or the teacher happy, but made the processor churn. And because we did, that amazing speed we'd been granted was wasted, by us, in a death by a thousand abstraction layers.

-

But some of us aren't satisfied with that.

-

Some of us take a few extra steps into the covered territory, the wheels sitting, motionless, in a pile behind us, examine their designs and decide there is a better way. The more experienced among us remember how software used to be, the potential that we know exists for computer programs to be useful, general, and efficient. Others of us got fed up with the tools we were expected to use without complaint, but which failed us time and time again. Some of us are just curious and don't know what's good for us. Don't trust what we've been told is good for us.

-

We sat down and looked at our hardware, and examined our data, and thought about how to use the one to transform the other. We tinkered, and measured, and read, and compared, and wrote, and refined, and modified, and measured again, over and over, until we found we had built the same thing, but 10 times faster and incomparably more useful to the people we designed it for. And we had built it by hand.

-

That is what Handmade means. It's not a technique or a language or a management strategy, it isn't a formula or a library or an abstraction. It's an idea. The idea that we can build software that works with the computer, not against it. The idea that sometimes an individual programmer can be more productive than a large team, that a small group can do more than an army of software engineers and *do it better*. The idea that programming is about transforming data and we wield the code, the tool we use to bend that data to our will.

-

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.

-

Will you join us?

-

Will you build your software by hand?

-

Written by Andrew Chronister

-
+
+

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.

+

So why is software still slow?

+

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?

+

We made it slow.

+

Not necessarily you, not necessarily me, not necessarily any single person in particular. But we, the software development community, made it slow by ignoring the fundamental reality of our occupation. We write code, code that runs on computers. Real computers, with central processing units and random access memory and hard disk drives and display buffers. Real computers, with integer and bitwise math and floating point units and L2 caches, with threads and cores and a tenuous little network connection to a million billion other computers. Real computers not built for ease of human understanding but for blindingly, incomprehensibly fast speed.

+

A lot of us have forgotten that.

+

In our haste to get our products, our projects, the works of our hands and minds, to as many people as possible, we take shortcuts. We make assumptions. We generalize, and abstract, and assume that just because these problems have been solved before that they never need to be solved again. We build abstraction layers, then forget we built them and build more on top.

+

And it's true that many of us think we do not have the time, the money, the mental bandwidth to always consider these things in detail. The deadline is approaching or the rent is due or we have taxes to fill out and a manager on our back and someone asking us why we always spend so much time at the office, and we just have to stick the library or virtual machine or garbage collector in there to cover up the places we can't think through right now.

+

Others of us were never taught to think about the computer itself. We learned about objects and classes and templates and how to make our code clean and pretty. We learned how to write code to make the client or the manager or the teacher happy, but made the processor churn. And because we did, that amazing speed we'd been granted was wasted, by us, in a death by a thousand abstraction layers.

+

But some of us aren't satisfied with that.

+

Some of us take a few extra steps into the covered territory, the wheels sitting, motionless, in a pile behind us, examine their designs and decide there is a better way. The more experienced among us remember how software used to be, the potential that we know exists for computer programs to be useful, general, and efficient. Others of us got fed up with the tools we were expected to use without complaint, but which failed us time and time again. Some of us are just curious and don't know what's good for us. Don't trust what we've been told is good for us.

+

We sat down and looked at our hardware, and examined our data, and thought about how to use the one to transform the other. We tinkered, and measured, and read, and compared, and wrote, and refined, and modified, and measured again, over and over, until we found we had built the same thing, but 10 times faster and incomparably more useful to the people we designed it for. And we had built it by hand.

+

That is what Handmade means. It's not a technique or a language or a management strategy, it isn't a formula or a library or an abstraction. It's an idea. The idea that we can build software that works with the computer, not against it. The idea that sometimes an individual programmer can be more productive than a large team, that a small group can do more than an army of software engineers and *do it better*. The idea that programming is about transforming data and we wield the code, the tool we use to bend that data to our will.

+

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.

+

Will you join us?

+

Will you build your software by hand?

+

Written by Andrew Chronister

{{ end }} diff --git a/src/website/blogs.go b/src/website/blogs.go index 1b54e64f..036c6915 100644 --- a/src/website/blogs.go +++ b/src/website/blogs.go @@ -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{ diff --git a/src/website/forums.go b/src/website/forums.go index 9751ff57..03a106fa 100644 --- a/src/website/forums.go +++ b/src/website/forums.go @@ -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{ diff --git a/src/website/landing.go b/src/website/landing.go index ff82df32..911e2476 100644 --- a/src/website/landing.go +++ b/src/website/landing.go @@ -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{ diff --git a/src/website/projects.go b/src/website/projects.go index 8be835e0..9eeeb5a7 100644 --- a/src/website/projects.go +++ b/src/website/projects.go @@ -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)) diff --git a/src/website/routes.go b/src/website/routes.go index 0aeef1f4..96ca3124 100644 --- a/src/website/routes.go +++ b/src/website/routes.go @@ -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}, } } diff --git a/src/website/staticpages.go b/src/website/staticpages.go index 16ee2168..63446a9e 100644 --- a/src/website/staticpages.go +++ b/src/website/staticpages.go @@ -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 } diff --git a/src/website/threads_and_posts_helper.go b/src/website/threads_and_posts_helper.go index 16c802bb..35120c5d 100644 --- a/src/website/threads_and_posts_helper.go +++ b/src/website/threads_and_posts_helper.go @@ -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 {