From 1352908c1362e34f23e28fa3a8a229bd02611442 Mon Sep 17 00:00:00 2001 From: Sean Linsley Date: Tue, 14 Nov 2017 11:00:18 -0600 Subject: [PATCH 1/5] =?UTF-8?q?oops=20I=20should've=20started=20committing?= =?UTF-8?q?=20earlier=20=F0=9F=91=BC?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- Cargo.lock | 28 +++++ Cargo.toml | 2 + app/styles/app.scss | 22 ++-- src/bin/server.rs | 2 +- src/dist.rs | 71 ++++--------- src/html/_categories.hbs | 12 +++ src/html/_crates.hbs | 12 +++ src/html/_keywords.hbs | 12 +++ src/html/index.hbs | 222 +++++++++++++++++++++++++++++++++++++++ src/html/mod.rs | 51 +++++++++ src/krate/metadata.rs | 32 +++--- src/lib.rs | 5 +- src/util/mod.rs | 15 +++ 13 files changed, 407 insertions(+), 79 deletions(-) create mode 100644 src/html/_categories.hbs create mode 100644 src/html/_crates.hbs create mode 100644 src/html/_keywords.hbs create mode 100644 src/html/index.hbs create mode 100644 src/html/mod.rs diff --git a/Cargo.lock b/Cargo.lock index 78a1c33b0ab..d316d578272 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -133,6 +133,7 @@ dependencies = [ "flate2 0.2.20 (registry+https://github.com/rust-lang/crates.io-index)", "futures 0.1.17 (registry+https://github.com/rust-lang/crates.io-index)", "git2 0.6.8 (registry+https://github.com/rust-lang/crates.io-index)", + "handlebars 0.29.1 (registry+https://github.com/rust-lang/crates.io-index)", "hex 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)", "htmlescape 0.3.1 (registry+https://github.com/rust-lang/crates.io-index)", "hyper 0.11.6 (registry+https://github.com/rust-lang/crates.io-index)", @@ -732,6 +733,20 @@ dependencies = [ "url 1.6.0 (registry+https://github.com/rust-lang/crates.io-index)", ] +[[package]] +name = "handlebars" +version = "0.29.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +dependencies = [ + "lazy_static 0.2.9 (registry+https://github.com/rust-lang/crates.io-index)", + "log 0.3.8 (registry+https://github.com/rust-lang/crates.io-index)", + "pest 0.3.3 (registry+https://github.com/rust-lang/crates.io-index)", + "quick-error 1.2.1 (registry+https://github.com/rust-lang/crates.io-index)", + "regex 0.2.2 (registry+https://github.com/rust-lang/crates.io-index)", + "serde 1.0.19 (registry+https://github.com/rust-lang/crates.io-index)", + "serde_json 1.0.5 (registry+https://github.com/rust-lang/crates.io-index)", +] + [[package]] name = "hex" version = "0.2.0" @@ -1139,6 +1154,11 @@ name = "percent-encoding" version = "1.0.0" source = "registry+https://github.com/rust-lang/crates.io-index" +[[package]] +name = "pest" +version = "0.3.3" +source = "registry+https://github.com/rust-lang/crates.io-index" + [[package]] name = "phf" version = "0.7.21" @@ -1200,6 +1220,11 @@ dependencies = [ "getopts 0.2.15 (registry+https://github.com/rust-lang/crates.io-index)", ] +[[package]] +name = "quick-error" +version = "1.2.1" +source = "registry+https://github.com/rust-lang/crates.io-index" + [[package]] name = "quine-mc_cluskey" version = "0.2.4" @@ -1928,6 +1953,7 @@ dependencies = [ "checksum gcc 0.3.54 (registry+https://github.com/rust-lang/crates.io-index)" = "5e33ec290da0d127825013597dbdfc28bee4964690c7ce1166cbc2a7bd08b1bb" "checksum getopts 0.2.15 (registry+https://github.com/rust-lang/crates.io-index)" = "65922871abd2f101a2eb0eaebadc66668e54a87ad9c3dd82520b5f86ede5eff9" "checksum git2 0.6.8 (registry+https://github.com/rust-lang/crates.io-index)" = "0c1c0203d653f4140241da0c1375a404f0a397249ec818cd2076c6280c50f6fa" +"checksum handlebars 0.29.1 (registry+https://github.com/rust-lang/crates.io-index)" = "fb04af2006ea09d985fef82b81e0eb25337e51b691c76403332378a53d521edc" "checksum hex 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)" = "d6a22814455d41612f41161581c2883c0c6a1c41852729b17d5ed88f01e153aa" "checksum html5ever 0.21.0 (registry+https://github.com/rust-lang/crates.io-index)" = "ba3a1fd1857a714d410c191364c5d7bf8a6487c0ab5575146d37dd7eb17ef523" "checksum htmlescape 0.3.1 (registry+https://github.com/rust-lang/crates.io-index)" = "e9025058dae765dee5070ec375f591e2ba14638c63feff74f13805a72e523163" @@ -1974,6 +2000,7 @@ dependencies = [ "checksum openssl-probe 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)" = "d98df0270d404ccd3c050a41d579c52d1db15375168bb3471e04ec0f5f378daf" "checksum openssl-sys 0.9.20 (registry+https://github.com/rust-lang/crates.io-index)" = "0ad395f1cee51b64a8d07cc8063498dc7554db62d5f3ca87a67f4eed2791d0c8" "checksum percent-encoding 1.0.0 (registry+https://github.com/rust-lang/crates.io-index)" = "de154f638187706bde41d9b4738748933d64e6b37bdbffc0b47a97d16a6ae356" +"checksum pest 0.3.3 (registry+https://github.com/rust-lang/crates.io-index)" = "0a6dda33d67c26f0aac90d324ab2eb7239c819fc7b2552fe9faa4fe88441edc8" "checksum phf 0.7.21 (registry+https://github.com/rust-lang/crates.io-index)" = "cb325642290f28ee14d8c6201159949a872f220c62af6e110a56ea914fbe42fc" "checksum phf_codegen 0.7.21 (registry+https://github.com/rust-lang/crates.io-index)" = "d62594c0bb54c464f633175d502038177e90309daf2e0158be42ed5f023ce88f" "checksum phf_generator 0.7.21 (registry+https://github.com/rust-lang/crates.io-index)" = "6b07ffcc532ccc85e3afc45865469bf5d9e4ef5bfcf9622e3cfe80c2d275ec03" @@ -1982,6 +2009,7 @@ dependencies = [ "checksum pq-sys 0.4.4 (registry+https://github.com/rust-lang/crates.io-index)" = "4dfb5e575ef93a1b7b2a381d47ba7c5d4e4f73bff37cee932195de769aad9a54" "checksum precomputed-hash 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)" = "925383efa346730478fb4838dbe9137d2a47675ad789c546d150a6e1dd4ab31c" "checksum pulldown-cmark 0.0.15 (registry+https://github.com/rust-lang/crates.io-index)" = "378e941dbd392c101f2cb88097fa4d7167bc421d4b88de3ff7dbee503bc3233b" +"checksum quick-error 1.2.1 (registry+https://github.com/rust-lang/crates.io-index)" = "eda5fe9b71976e62bc81b781206aaa076401769b2143379d3eb2118388babac4" "checksum quine-mc_cluskey 0.2.4 (registry+https://github.com/rust-lang/crates.io-index)" = "07589615d719a60c8dd8a4622e7946465dfef20d1a428f969e3443e7386d5f45" "checksum quote 0.3.15 (registry+https://github.com/rust-lang/crates.io-index)" = "7a6e920b65c65f10b2ae65c831a81a073a89edd28c7cce89475bff467ab4167a" "checksum r2d2 0.7.4 (registry+https://github.com/rust-lang/crates.io-index)" = "2c8284508b38df440f8f3527395e23c4780b22f74226b270daf58fee38e4bcce" diff --git a/Cargo.toml b/Cargo.toml index 014b17c24af..a2e258409e5 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -73,6 +73,8 @@ conduit-static = "0.8" conduit-git-http-backend = "0.8" civet = "0.9" +handlebars = "0.29.1" + [dev-dependencies] conduit-test = "0.8" hyper = "0.11" diff --git a/app/styles/app.scss b/app/styles/app.scss index d21c08f0ae3..63a7855714b 100644 --- a/app/styles/app.scss +++ b/app/styles/app.scss @@ -33,7 +33,7 @@ body { @include align-items(center); } -.ember-application > div { +body > div { width: 960px; @media only screen and (max-width: 960px) { width: 100%; @@ -99,19 +99,13 @@ body { } .current-user-links { - display: none; left: auto; right: 0; min-width: 200px; - - &.open { display: block; } } #doc-links { - display: none; left: auto; min-width: 150px; - - &.open { display: block; } } form.search { @include display-flex; @@ -266,9 +260,13 @@ pre { button.dropdown, a.dropdown { color: inherit; cursor: pointer; - .arrow { font-size: 50%; display: inline-block; vertical-align: middle; } + .arrow { + font-size: 50%; + display: inline-block; + vertical-align: middle; + } .arrow::after { content: "▼"; } - &.active .arrow::after { content: "▲"; } + .dropdown-container:hover & .arrow::after { content: "▲"; } } ul.dropdown { @@ -300,12 +298,16 @@ ul.dropdown { } } li.last { border-top: 1px solid $gray-border; } - &.open { + + display: none; + + .dropdown-container:hover & { display: block; visibility: visible; opacity: 1; } } + .dropdown-container { display: inline-block; position: relative; diff --git a/src/bin/server.rs b/src/bin/server.rs index 99eccba50a4..563bd9a3433 100644 --- a/src/bin/server.rs +++ b/src/bin/server.rs @@ -63,7 +63,7 @@ fn main() { .unwrap_or(8888) }; let threads = if config.env == Env::Development { - 1 + 4 } else { 50 }; diff --git a/src/dist.rs b/src/dist.rs index 7526b8c0bbd..9adb5fe81e0 100644 --- a/src/dist.rs +++ b/src/dist.rs @@ -1,61 +1,26 @@ -//! This module implements middleware to serve the compiled emberjs -//! frontend +//! This module implements middleware to serve the compiled, static assets. use std::error::Error; use conduit::{Handler, Request, Response}; -use conduit_static::Static; -use conduit_middleware::AroundMiddleware; +use conduit_static; +use conduit_middleware::Middleware; -use util::RequestProxy; +#[allow(missing_debug_implementations, missing_copy_implementations)] +pub struct Static; -// Can't derive debug because of Handler and Static. -#[allow(missing_debug_implementations)] -pub struct Middleware { - handler: Option>, - dist: Static, -} - -impl Default for Middleware { - fn default() -> Middleware { - Middleware { - handler: None, - dist: Static::new("dist"), - } - } -} - -impl AroundMiddleware for Middleware { - fn with_handler(&mut self, handler: Box) { - self.handler = Some(handler); - } -} - -impl Handler for Middleware { - fn call(&self, req: &mut Request) -> Result> { - // First, attempt to serve a static file. If we're missing a static - // file, then keep going. - match self.dist.call(req) { - Ok(ref resp) if resp.status.0 == 404 => {} - ret => return ret, - } - - // Second, if we're requesting html, then we've only got one page so - // serve up that page. Otherwise proxy on to the rest of the app. - let wants_html = req.headers() - .find("Accept") - .map(|accept| accept.iter().any(|s| s.contains("html"))) - .unwrap_or(false); - // If the route starts with /api, just assume they want the API - // response. Someone is either debugging or trying to download a crate. - let is_api_path = req.path().starts_with("/api"); - if wants_html && !is_api_path { - self.dist.call(&mut RequestProxy { - other: req, - path: Some("/index.html"), - method: None, - }) - } else { - self.handler.as_ref().unwrap().call(req) +impl Middleware for Static { + fn after(&self, req: &mut Request, resp: Result>) + -> Result> + { + match resp { + Ok(resp) => { + if resp.status.0 == 404 { + conduit_static::Static::new("dist").call(req) + } else { + Ok(resp) + } + } + Err(resp) => Err(resp) } } } diff --git a/src/html/_categories.hbs b/src/html/_categories.hbs new file mode 100644 index 00000000000..4fecbeca6bb --- /dev/null +++ b/src/html/_categories.hbs @@ -0,0 +1,12 @@ + diff --git a/src/html/_crates.hbs b/src/html/_crates.hbs new file mode 100644 index 00000000000..2c4b5ea0105 --- /dev/null +++ b/src/html/_crates.hbs @@ -0,0 +1,12 @@ + diff --git a/src/html/_keywords.hbs b/src/html/_keywords.hbs new file mode 100644 index 00000000000..ebd9dc1b3e9 --- /dev/null +++ b/src/html/_keywords.hbs @@ -0,0 +1,12 @@ + diff --git a/src/html/index.hbs b/src/html/index.hbs new file mode 100644 index 00000000000..245c851abb3 --- /dev/null +++ b/src/html/index.hbs @@ -0,0 +1,222 @@ + + + + + + + + {{!content-for "head"}} + + + + + Cargo: packages for Rust + + {{!content-for "head-footer"}} + + + + + + {{!content-for "body"}} + + {{!google-jsapi}} + +
+ + + + + + + + +
+ {{!flash-message}} + + + +
+
+ Instantly publish your crates and install them. Use the API to + interact and find out more information about available crates. Become + a contributor and enhance the site with your work. +
+ +
+
+ {{!svg-jar "download"}} + {{format_num num_downloads}} + Downloads +
+
+ {{!svg-jar "crate"}} + {{format_num num_crates}} + Crates in stock +
+
+
+ +
+
+

New Crates

+ {{>crates crates=new_crates}} +
+
+

Most Downloaded

+ {{>crates crates=most_downloaded}} +
+
+

Just Updated

+ {{>crates crates=just_updated}} +
+
+

Most Recent Downloads

+ {{>crates crates=most_recently_downloaded}} +
+
+

Popular Keywords (see all)

+ {{>keywords keywords=popular_keywords}} +
+
+

Popular Categories (see all)

+ {{>categories categories=popular_categories}} +
+
+
+ + +
+ + + + {{!content-for "body-footer"}} + + diff --git a/src/html/mod.rs b/src/html/mod.rs new file mode 100644 index 00000000000..8ad10b2a6ea --- /dev/null +++ b/src/html/mod.rs @@ -0,0 +1,51 @@ +#![allow(unused_imports)] + +use std::fs::File; +use std::io::Read; + +use conduit::{Request, Response}; + +use util::{human, internal, CargoResult, ChainError, RequestUtils}; + +extern crate handlebars; +use self::handlebars::*; + +use krate; + +use serde_json; +use serde::Serialize; +use serde_json::Map; +use serde_json::Value; + +use conduit::WriteBody; + +use diesel::*; +use db::RequestTransaction; + +pub fn index(req: &mut Request) -> CargoResult { + let html = include_str!("index.hbs"); + + let mut handlebars = Handlebars::new(); + handlebars.register_helper("format_num", Box::new(format_num)); + handlebars.register_template_string("categories", include_str!("_categories.hbs"))?; + handlebars.register_template_string("crates", include_str!("_crates.hbs"))?; + handlebars.register_template_string("keywords", include_str!("_keywords.hbs"))?; + + let mut json = json!(&krate::metadata::summary_json(&*req.db_conn()?).unwrap()); + json["current_user"] = json!({"id": 1, "name": "Sean Linsley"}); + // TODO: flash message + // TODO: SVG embed + // TODO: global layout, that other pages can render into + // TODO: user image in header + + let rendered = handlebars.template_render(html, &json).expect("failed to render"); + + Ok(req.html(&String::from(rendered))) +} + +fn format_num(h: &Helper, _: &Handlebars, rc: &mut RenderContext) -> Result<(), RenderError> { + let param = h.param(0).expect("no argument passed").value(); + let rendered = format!("{}", param); + try!(rc.writer.write(rendered.into_bytes().as_ref())); + Ok(()) +} diff --git a/src/krate/metadata.rs b/src/krate/metadata.rs index b9692eeb90d..cb5b03cac78 100644 --- a/src/krate/metadata.rs +++ b/src/krate/metadata.rs @@ -22,11 +22,14 @@ use super::{Crate, CrateDownload, EncodableCrate, ALL_COLUMNS}; /// Handles the `GET /summary` route. pub fn summary(req: &mut Request) -> CargoResult { + Ok(req.json(&summary_json(&*req.db_conn()?).unwrap())) +} + +pub fn summary_json(conn: &PgConnection) -> CargoResult { use diesel::dsl::*; use diesel::types::{BigInt, Nullable}; use schema::crates::dsl::*; - let conn = req.db_conn()?; let num_crates = crates.count().get_result(&*conn)?; let num_downloads = metadata::table .select(metadata::total_downloads) @@ -90,18 +93,7 @@ pub fn summary(req: &mut Request) -> CargoResult { .map(Category::encodable) .collect(); - #[derive(Serialize)] - struct R { - num_downloads: i64, - num_crates: i64, - new_crates: Vec, - most_downloaded: Vec, - most_recently_downloaded: Vec, - just_updated: Vec, - popular_keywords: Vec, - popular_categories: Vec, - } - Ok(req.json(&R { + Ok(SummaryResponse { num_downloads: num_downloads, num_crates: num_crates, new_crates: encode_crates(new_crates)?, @@ -110,7 +102,19 @@ pub fn summary(req: &mut Request) -> CargoResult { just_updated: encode_crates(just_updated)?, popular_keywords: popular_keywords, popular_categories: popular_categories, - })) + }) +} + +#[derive(Serialize, Debug)] +pub struct SummaryResponse { + num_downloads: i64, + num_crates: i64, + new_crates: Vec, + most_downloaded: Vec, + most_recently_downloaded: Vec, + just_updated: Vec, + popular_keywords: Vec, + popular_categories: Vec, } /// Handles the `GET /crates/:crate_id` route. diff --git a/src/lib.rs b/src/lib.rs index 80c4e7a51e8..d7f99cd25f2 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -86,6 +86,7 @@ pub mod download; pub mod git; pub mod github; pub mod http; +pub mod html; pub mod keyword; pub mod krate; pub mod owner; @@ -224,6 +225,8 @@ pub fn middleware(app: Arc) -> MiddlewareBuilder { let mut router = RouteBuilder::new(); + router.get("/", C(html::index)); + // Mount the router under the /api/v1 path so we're at least somewhat at the // liberty to change things in the future! router.get("/api/v1/*path", R(Arc::clone(&api_router))); @@ -278,7 +281,7 @@ pub fn middleware(app: Arc) -> MiddlewareBuilder { // Serve the static files in the *dist* directory, which are the frontend assets. // Not needed for the backend tests. if env != Env::Test { - m.around(dist::Middleware::default()); + m.add(dist::Static); } return m; diff --git a/src/util/mod.rs b/src/util/mod.rs index 6086088fe9a..98008b19b08 100644 --- a/src/util/mod.rs +++ b/src/util/mod.rs @@ -29,6 +29,7 @@ pub trait RequestUtils { fn redirect(&self, url: String) -> Response; fn json(&self, t: &T) -> Response; + fn html(&self, &str) -> Response; fn query(&self) -> HashMap; fn wants_json(&self) -> bool; fn pagination(&self, default: usize, max: usize) -> CargoResult<(i64, i64)>; @@ -49,6 +50,16 @@ pub fn json_response(t: &T) -> Response { } } +pub fn html_response(html: &str) -> Response { + let mut headers = HashMap::new(); + headers.insert("Content-Type".to_string(), vec!["text/html; charset=utf-8".to_string()]); + headers.insert("Content-Length".to_string(), vec![html.len().to_string()]); + Response { + status: (200, "OK"), + headers: headers, + body: Box::new(Cursor::new(html.to_string())), + } +} impl<'a> RequestUtils for Request + 'a { fn json(&self, t: &T) -> Response { @@ -98,6 +109,10 @@ impl<'a> RequestUtils for Request + 'a { } Ok((((page - 1) * limit) as i64, limit as i64)) } + + fn html(&self, html: &str) -> Response { + html_response(html) + } } // Can't Copy or Debug the fn. From 992bfa16a98445ff9f3b00f2622419e6e5816d00 Mon Sep 17 00:00:00 2001 From: Sean Linsley Date: Tue, 14 Nov 2017 19:16:24 -0600 Subject: [PATCH 2/5] embed SVGs --- src/html/_categories.hbs | 4 ++-- src/html/_crates.hbs | 4 ++-- src/html/_keywords.hbs | 4 ++-- src/html/index.hbs | 10 +++++----- src/html/mod.rs | 21 ++++++++++++++++++++- src/html/svgs/button-download.svg | 7 +++++++ src/html/svgs/crate.svg | 5 +++++ src/html/svgs/download.svg | 6 ++++++ src/html/svgs/flag.svg | 16 ++++++++++++++++ src/html/svgs/lock.svg | 4 ++++ src/html/svgs/right-arrow.svg | 4 ++++ 11 files changed, 73 insertions(+), 12 deletions(-) create mode 100644 src/html/svgs/button-download.svg create mode 100644 src/html/svgs/crate.svg create mode 100644 src/html/svgs/download.svg create mode 100644 src/html/svgs/flag.svg create mode 100644 src/html/svgs/lock.svg create mode 100644 src/html/svgs/right-arrow.svg diff --git a/src/html/_categories.hbs b/src/html/_categories.hbs index 4fecbeca6bb..2e6aca9d82e 100644 --- a/src/html/_categories.hbs +++ b/src/html/_categories.hbs @@ -1,10 +1,10 @@
    {{#each categories as |category|}}
  • - + {{category.category}} ({{format_num category.crates_cnt}})
    - {{!svg-jar "right-arrow"}} + {{embed_svg "right-arrow"}}
  • diff --git a/src/html/_crates.hbs b/src/html/_crates.hbs index 2c4b5ea0105..91630c02bf4 100644 --- a/src/html/_crates.hbs +++ b/src/html/_crates.hbs @@ -1,10 +1,10 @@
      {{#each crates as |crate|}}
    • - + {{crate.name}} ({{crate.max_version}})
      - {{!svg-jar "right-arrow"}} + {{embed_svg "right-arrow"}}
    • diff --git a/src/html/_keywords.hbs b/src/html/_keywords.hbs index ebd9dc1b3e9..48680842591 100644 --- a/src/html/_keywords.hbs +++ b/src/html/_keywords.hbs @@ -1,10 +1,10 @@
        {{#each keywords as |keyword|}}
      • - + {{keyword.id}} ({{format_num keyword.crates_cnt}})
        - {{!svg-jar "right-arrow"}} + {{embed_svg "right-arrow"}}
      • diff --git a/src/html/index.hbs b/src/html/index.hbs index 245c851abb3..70a868aea55 100644 --- a/src/html/index.hbs +++ b/src/html/index.hbs @@ -95,7 +95,7 @@ {{else}} - {{!svg-jar "lock"}} + {{embed_svg "lock"}} Log in with GitHub {{/if}} @@ -141,12 +141,12 @@ @@ -161,12 +161,12 @@
        - {{!svg-jar "download"}} + {{embed_svg "download"}} {{format_num num_downloads}} Downloads
        - {{!svg-jar "crate"}} + {{embed_svg "crate"}} {{format_num num_crates}} Crates in stock
        diff --git a/src/html/mod.rs b/src/html/mod.rs index 8ad10b2a6ea..2004dc28f55 100644 --- a/src/html/mod.rs +++ b/src/html/mod.rs @@ -2,6 +2,7 @@ use std::fs::File; use std::io::Read; +use std::collections::HashMap; use conduit::{Request, Response}; @@ -27,6 +28,7 @@ pub fn index(req: &mut Request) -> CargoResult { let mut handlebars = Handlebars::new(); handlebars.register_helper("format_num", Box::new(format_num)); + handlebars.register_helper("embed_svg", Box::new(embed_svg)); handlebars.register_template_string("categories", include_str!("_categories.hbs"))?; handlebars.register_template_string("crates", include_str!("_crates.hbs"))?; handlebars.register_template_string("keywords", include_str!("_keywords.hbs"))?; @@ -34,7 +36,6 @@ pub fn index(req: &mut Request) -> CargoResult { let mut json = json!(&krate::metadata::summary_json(&*req.db_conn()?).unwrap()); json["current_user"] = json!({"id": 1, "name": "Sean Linsley"}); // TODO: flash message - // TODO: SVG embed // TODO: global layout, that other pages can render into // TODO: user image in header @@ -49,3 +50,21 @@ fn format_num(h: &Helper, _: &Handlebars, rc: &mut RenderContext) -> Result<(), try!(rc.writer.write(rendered.into_bytes().as_ref())); Ok(()) } + +fn embed_svg(h: &Helper, _: &Handlebars, rc: &mut RenderContext) -> Result<(), RenderError> { + let param = h.param(0).expect("no argument passed").value().to_string().replace("\"", ""); + + let mut svgs = HashMap::new(); + svgs.insert("crate".to_string(), include_str!("svgs/crate.svg").to_string()); + svgs.insert("button-download".to_string(), include_str!("svgs/button-download.svg").to_string()); + svgs.insert("download".to_string(), include_str!("svgs/download.svg").to_string()); + svgs.insert("flag".to_string(), include_str!("svgs/flag.svg").to_string()); + svgs.insert("lock".to_string(), include_str!("svgs/lock.svg").to_string()); + svgs.insert("right-arrow".to_string(), include_str!("svgs/right-arrow.svg").to_string()); + + let svg = &svgs[¶m]; + + try!(rc.writer.write(svg.as_ref())); + + Ok(()) +} diff --git a/src/html/svgs/button-download.svg b/src/html/svgs/button-download.svg new file mode 100644 index 00000000000..5afae471fd3 --- /dev/null +++ b/src/html/svgs/button-download.svg @@ -0,0 +1,7 @@ + + + + + + + diff --git a/src/html/svgs/crate.svg b/src/html/svgs/crate.svg new file mode 100644 index 00000000000..9032b255795 --- /dev/null +++ b/src/html/svgs/crate.svg @@ -0,0 +1,5 @@ + + + + + diff --git a/src/html/svgs/download.svg b/src/html/svgs/download.svg new file mode 100644 index 00000000000..a754591d5ea --- /dev/null +++ b/src/html/svgs/download.svg @@ -0,0 +1,6 @@ + + + + + + diff --git a/src/html/svgs/flag.svg b/src/html/svgs/flag.svg new file mode 100644 index 00000000000..ae3735d3c6b --- /dev/null +++ b/src/html/svgs/flag.svg @@ -0,0 +1,16 @@ + + + + + + + + + + + + + + + + diff --git a/src/html/svgs/lock.svg b/src/html/svgs/lock.svg new file mode 100644 index 00000000000..969c618c916 --- /dev/null +++ b/src/html/svgs/lock.svg @@ -0,0 +1,4 @@ + + + + diff --git a/src/html/svgs/right-arrow.svg b/src/html/svgs/right-arrow.svg new file mode 100644 index 00000000000..f44739eb1ff --- /dev/null +++ b/src/html/svgs/right-arrow.svg @@ -0,0 +1,4 @@ + + + + From 236e68861d163200414451e84db700dfa52b8d37 Mon Sep 17 00:00:00 2001 From: Sean Linsley Date: Wed, 15 Nov 2017 09:02:47 -0600 Subject: [PATCH 3/5] import cleanup --- src/html/mod.rs | 14 +------------- 1 file changed, 1 insertion(+), 13 deletions(-) diff --git a/src/html/mod.rs b/src/html/mod.rs index 2004dc28f55..962f489b59a 100644 --- a/src/html/mod.rs +++ b/src/html/mod.rs @@ -1,26 +1,14 @@ -#![allow(unused_imports)] - -use std::fs::File; -use std::io::Read; use std::collections::HashMap; use conduit::{Request, Response}; -use util::{human, internal, CargoResult, ChainError, RequestUtils}; +use util::{CargoResult, RequestUtils}; extern crate handlebars; use self::handlebars::*; use krate; -use serde_json; -use serde::Serialize; -use serde_json::Map; -use serde_json::Value; - -use conduit::WriteBody; - -use diesel::*; use db::RequestTransaction; pub fn index(req: &mut Request) -> CargoResult { From 03d28da8c46d5993ba15ae2a619f624d591ba640 Mon Sep 17 00:00:00 2001 From: Sean Linsley Date: Wed, 15 Nov 2017 10:13:51 -0600 Subject: [PATCH 4/5] add global layout --- src/html/index.hbs | 263 ++++++++++---------------------------------- src/html/layout.hbs | 153 ++++++++++++++++++++++++++ src/html/mod.rs | 19 ++-- 3 files changed, 219 insertions(+), 216 deletions(-) create mode 100644 src/html/layout.hbs diff --git a/src/html/index.hbs b/src/html/index.hbs index 70a868aea55..5a44d97bd68 100644 --- a/src/html/index.hbs +++ b/src/html/index.hbs @@ -1,222 +1,71 @@ - - - - - - +{{#>layout}} + {{#*inline "head"}} + Cargo: packages for Rust + {{/inline}} - {{!content-for "head"}} + {{#*inline "main"}} +
        +

        The Rust community’s crate registry

        - - - - Cargo: packages for Rust - - {{!content-for "head-footer"}} - - - - - - {{!content-for "body"}} - - {{!google-jsapi}} +