Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
5 changes: 5 additions & 0 deletions locales/en-US/funding.ftl
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
## Works in conjunction with team data from teams.ftl

## funding.html.hbs
funding-page-title = Funding
funding-intro = Rust contributors shown on this page can be funded via GitHub Sponsors. Consider sponsoring them if you want to support the development of Rust.
33 changes: 22 additions & 11 deletions src/assets.rs
Original file line number Diff line number Diff line change
Expand Up @@ -56,36 +56,44 @@ fn concat_files(
files: &[&str],
directory: &str,
extension: &str,
prefix: &str,
) -> anyhow::Result<String> {
let mut concatted = String::new();
for filestem in files {
let vendor_path = root_dir
let file_path = root_dir
.join("static")
.join(directory)
.join(format!("{filestem}.{extension}"));
let contents = fs::read_to_string(vendor_path)
.with_context(|| anyhow::anyhow!("couldn't read vendor {extension}"))?;
let contents = fs::read_to_string(file_path)
.with_context(|| anyhow::anyhow!("couldn't read {prefix} {extension}"))?;
concatted.push_str(&contents);
}

let file_sha = format!("vendor_{}", hash_string(&concatted));
let file_sha = format!("{prefix}_{}", hash_string(&concatted));
let out_file_path = out_dir
.join("static")
.join(directory)
.join(format!("{file_sha}.{extension}"));

write_file(Path::new(&out_file_path), concatted.as_bytes())
.with_context(|| anyhow::anyhow!("couldn't write vendor {extension}"))?;
.with_context(|| anyhow::anyhow!("couldn't write {prefix} {extension}"))?;

relative_url(&out_file_path, out_dir)
}

fn concat_vendor_css(root_dir: &Path, out_dir: &Path, files: Vec<&str>) -> anyhow::Result<String> {
concat_files(root_dir, out_dir, &files, "styles", "css")
concat_files(root_dir, out_dir, &files, "styles", "css", "vendor")
}

fn concat_app_js(root_dir: &Path, out_dir: &Path, files: Vec<&str>) -> anyhow::Result<String> {
concat_files(root_dir, out_dir, &files, "scripts", "js")
fn build_js_file(root_dir: &Path, out_dir: &Path, file: &str) -> anyhow::Result<String> {
concat_files(
root_dir,
out_dir,
&[file],
"scripts",
"js",
Path::new(file).file_stem().unwrap().to_str().unwrap(),
)
}

#[derive(Serialize, Debug)]
Expand All @@ -97,7 +105,8 @@ pub struct CSSFiles {

#[derive(Serialize, Debug)]
pub struct JSFiles {
app: String,
tools_install: String,
funding_shuffle: String,
}

#[derive(Serialize, Debug)]
Expand All @@ -116,7 +125,8 @@ pub fn compile_assets(
let app_css_file = compile_sass(root_dir, out_dir, "app", base_url)?;
let fonts_css_file = compile_sass(root_dir, out_dir, "fonts", base_url)?;
let vendor_css_file = concat_vendor_css(root_dir, out_dir, vec!["tachyons"])?;
let app_js_file = concat_app_js(root_dir, out_dir, vec!["tools-install"])?;
let tools_install_js = build_js_file(root_dir, out_dir, "tools-install")?;
let funding_shuffle_js = build_js_file(root_dir, out_dir, "funding-shuffle")?;

Ok(AssetFiles {
css: CSSFiles {
Expand All @@ -125,7 +135,8 @@ pub fn compile_assets(
vendor: format!("{base_url}/{vendor_css_file}"),
},
js: JSFiles {
app: format!("{base_url}/{app_js_file}"),
tools_install: format!("{base_url}/{tools_install_js}"),
funding_shuffle: format!("{base_url}/{funding_shuffle_js}"),
},
})
}
7 changes: 5 additions & 2 deletions src/main.rs
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
use crate::assets::compile_assets;
use crate::i18n::{TeamHelper, create_loader};
use crate::redirect::create_redirects;
use crate::render::{RenderCtx, render_directory, render_governance, render_index};
use crate::render::{RenderCtx, render_directory, render_funding, render_governance, render_index};
use crate::rust_version::fetch_rust_version;
use crate::teams::{encode_zulip_stream, load_rust_teams};
use anyhow::Context;
Expand Down Expand Up @@ -110,8 +110,11 @@ fn main() -> anyhow::Result<()> {
".well-known/security.txt",
)?;

let all_team_members = ctx.teams.all_team_members();

render_index(&ctx)?;
render_governance(&ctx)?;
render_governance(&ctx, &all_team_members)?;
render_funding(&ctx, &all_team_members)?;
render_directory(&ctx, "community")?;
render_directory(&ctx, "learn")?;
render_directory(&ctx, "policies")?;
Expand Down
26 changes: 22 additions & 4 deletions src/render.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@ use crate::assets::AssetFiles;
use crate::fs::{copy_dir_all, ensure_directory};
use crate::i18n::{EXPLICIT_LOCALE_INFO, LocaleInfo, SUPPORTED_LOCALES};
use crate::rust_version::RustVersion;
use crate::teams::{PageData, RustTeamData};
use crate::teams::{AllTeamMembers, PageData, RustTeamData};
use crate::{BaseUrl, ENGLISH, LAYOUT};
use anyhow::Context;
use handlebars::Handlebars;
Expand Down Expand Up @@ -179,7 +179,10 @@ pub fn render_index(render_ctx: &RenderCtx) -> anyhow::Result<()> {
})
}

pub fn render_governance(render_ctx: &RenderCtx) -> anyhow::Result<()> {
pub fn render_governance(
render_ctx: &RenderCtx,
all_team_members: &AllTeamMembers,
) -> anyhow::Result<()> {
let data = render_ctx.teams.index_data();

// Index page
Expand Down Expand Up @@ -226,13 +229,12 @@ pub fn render_governance(render_ctx: &RenderCtx) -> anyhow::Result<()> {
})?;

// Page with all team members
let all_team_members_data = render_ctx.teams.all_team_members();
for_all_langs("governance/people/index.html", |dst_path, lang| {
render_ctx
.page(
"governance/all-team-members",
"governance-all-team-members-title",
&all_team_members_data,
all_team_members,
lang,
)
.render(dst_path)
Expand Down Expand Up @@ -263,6 +265,22 @@ pub fn render_governance(render_ctx: &RenderCtx) -> anyhow::Result<()> {
Ok(())
}

pub fn render_funding(
render_ctx: &RenderCtx,
all_team_members: &AllTeamMembers,
) -> anyhow::Result<()> {
let data = render_ctx.teams.funding_data(all_team_members);

// Index page
for_all_langs("funding/index.html", |dst_path, lang| {
render_ctx
.page("funding", "funding-page-title", &data, lang)
.render(dst_path)
})?;

Ok(())
}

/// Render all templates found in the given directory.
pub fn render_directory(render_ctx: &RenderCtx, category: &str) -> anyhow::Result<()> {
for dir in std::fs::read_dir(render_ctx.template_dir.join(category))? {
Expand Down
32 changes: 32 additions & 0 deletions src/teams.rs
Original file line number Diff line number Diff line change
Expand Up @@ -346,6 +346,27 @@ impl RustTeamData {
people
}

pub fn funding_data(&self, all_team_members: &AllTeamMembers) -> FundingData {
let people_with_sponsors = all_team_members
.active
.iter()
.filter_map(|member| {
let person = self.people.get(&member.github)?;
if person.github_sponsors {
Some(FundablePerson {
name: member.name.clone(),
github: member.github.to_string(),
})
} else {
None
}
})
.collect();
FundingData {
people: people_with_sponsors,
}
}

fn get_toplevel_team_url<'a>(&'a self, mut team: &'a Team) -> Option<String> {
while !is_toplevel_team(team) {
let Some(parent) = &team.subteam_of else {
Expand Down Expand Up @@ -476,6 +497,17 @@ pub struct PersonData {
alumni_teams: Vec<PersonTeam>,
}

#[derive(Serialize)]
pub struct FundablePerson {
name: String,
github: String,
}

#[derive(Serialize)]
pub struct FundingData {
people: Vec<FundablePerson>,
}

pub fn load_rust_teams() -> anyhow::Result<RustTeamData> {
println!("Downloading Team API data");

Expand Down
23 changes: 23 additions & 0 deletions static/scripts/funding-shuffle.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
// From https://stackoverflow.com/a/2450976/1107768
function shuffle(array) {
let currentIndex = array.length;

// While there remain elements to shuffle...
while (currentIndex !== 0) {
// Pick a remaining element...
let randomIndex = Math.floor(Math.random() * currentIndex);
currentIndex--;

// And swap it with the current element.
[array[currentIndex], array[randomIndex]] = [
array[randomIndex], array[currentIndex]];
}
}

document.addEventListener("DOMContentLoaded", () => {
// Shuffle people to reduce ordering bias
const wrapper = document.querySelector("#people");
const children = Array(...wrapper.children);
shuffle(children);
wrapper.replaceChildren(...children);
});
2 changes: 1 addition & 1 deletion templates/components/tools/rustup.html.hbs
Original file line number Diff line number Diff line change
Expand Up @@ -38,4 +38,4 @@
</div>
</div>

<script type="text/javascript" src="{{assets.js.app}}"></script>
<script type="text/javascript" src="{{assets.js.tools_install}}"></script>
32 changes: 32 additions & 0 deletions templates/funding.html.hbs
Original file line number Diff line number Diff line change
@@ -0,0 +1,32 @@
{{#*inline "member"}}
<div class="person w-100 w-25-l mb3 flex flex-row items-center">
<a class="mr4 w4 h4 flex-shrink-0" href="{{baseurl}}/governance/people/{{member.github}}">
<img class="w-100 h-100 bg-white br2"
src="https://avatars.githubusercontent.com/{{member.github}}"
alt="{{member.name}}">
</a>
<div class="flex flex-column">
<a href="{{baseurl}}/governance/people/{{member.github}}">{{member.name}}</a>
<a href="https://github.com/sponsors/{{member.github}}" class="button button-secondary mt2">Sponsor</a>
</div>
</div>
{{/inline}}

{{#*inline "page"}}
<section class="green" style="padding-bottom: 10px;">
<div class="w-100 mw-none mw-8-m mw9-l center f2 ph3">
<p>{{fluent "funding-intro"}}</p>
</div>
</section>

<section class="green" style="padding-bottom: 15px;">
<div id="people" class="w-100 mw-none mw-8-m mw9-l flex flex-column flex-row-l flex-wrap-l center ph3">
{{#each data.people as |member|}}
{{> member member=member baseurl=../baseurl }}
{{/each}}
</div>
<script type="text/javascript" src="{{assets.js.funding_shuffle}}"></script>
</section>
{{/inline}}

{{~> (lookup this "parent")~}}
3 changes: 3 additions & 0 deletions templates/governance/all-team-members.html.hbs
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,9 @@
<p>{{#fluent "governance-all-team-members-intro"}}{{#fluentparam
"count"}}{{len data.active}}{{/fluentparam}}{{/fluent}}</p>
</div>
<div class="w-100 mw-none mw9-l center">
<a href="{{baseurl}}/funding" class="button button-secondary mw6">Sponsor Rust contributors</a>
</div>
</section>

<section class="green" style="padding-bottom: 15px;">
Expand Down