Skip to content

Commit

Permalink
Add a Gotham example.
Browse files Browse the repository at this point in the history
  • Loading branch information
kaj committed Jul 2, 2018
1 parent 85bc237 commit fe68936
Show file tree
Hide file tree
Showing 13 changed files with 272 additions and 0 deletions.
4 changes: 4 additions & 0 deletions .travis.yml
Original file line number Diff line number Diff line change
Expand Up @@ -24,12 +24,16 @@ matrix:
- cd ../mime03 && cargo fmt -- --check
- cd ../iron && cargo fmt -- --check
- cd ../nickel && cargo fmt -- --check
- cd ../gotham && cargo fmt -- --check
- rust: stable
env: TASK=iron
script: cd examples/iron && cargo test
- rust: stable
env: TASK=nickel
script: cd examples/nickel && cargo test
- rust: stable
env: TASK=gotham
script: cd examples/gotham && cargo test
allow_failures:
- rust: nightly
env:
Expand Down
17 changes: 17 additions & 0 deletions examples/gotham/Cargo.toml
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
[package]
name = "gotham-ructe"
version = "0.1.0"
authors = ["Rasmus Kaj <kaj@kth.se>"]

build = "src/build.rs"

[build-dependencies]
ructe = { path = "../..", features = ["sass", "mime03"] }

[dependencies]
gotham = "~0.2.0"
gotham_derive = "~0.2.0"
hyper = "~0.11.27" # Must match gotham dependency
serde = "~1.0.66" # Must match gotham dependency
serde_derive = "~1.0.66" # Must match gotham dependency
mime = "~0.3.8"
8 changes: 8 additions & 0 deletions examples/gotham/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
This is an example of using ructe with the gotham framework.

The files in static is based on open clipart, modified by me and
optimized by [svgomg](https://jakearchibald.github.io/svgomg/).

* grass.svg is https://openclipart.org/detail/122113/grass
* cloud.svg is based on https://openclipart.org/detail/193560/cloud
* btfl.svg is based on https://openclipart.org/detail/149131/butterfly
14 changes: 14 additions & 0 deletions examples/gotham/src/build.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
extern crate ructe;

use ructe::{compile_templates, StaticFiles};
use std::env;
use std::path::PathBuf;

fn main() {
let out_dir = PathBuf::from(env::var("OUT_DIR").unwrap());
let base_dir = PathBuf::from(env::var("CARGO_MANIFEST_DIR").unwrap());
let mut statics = StaticFiles::new(&out_dir).unwrap();
statics.add_files(&base_dir.join("statics")).unwrap();
statics.add_sass_file(&base_dir.join("style.scss")).unwrap();
compile_templates(&base_dir.join("templates"), &out_dir).unwrap();
}
85 changes: 85 additions & 0 deletions examples/gotham/src/main.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,85 @@
extern crate gotham;
#[macro_use]
extern crate gotham_derive;
extern crate hyper;
extern crate mime;
#[macro_use]
extern crate serde_derive;

mod ructe_response;

use gotham::http::response::create_response;
use gotham::router::builder::{
build_simple_router, DefineSingleRoute, DrawRoutes,
};
use gotham::router::Router;
use gotham::state::{FromState, State};
use hyper::header::Expires;
use hyper::{Response, StatusCode};
use ructe_response::RucteResponse;
use std::io::{self, Write};
use std::time::{Duration, SystemTime};
use templates::*;

fn main() {
let addr = "127.0.0.1:3000";
println!("Starting server on http://{}/", addr);
gotham::start(addr, router())
}

pub fn router() -> Router {
build_simple_router(|route| {
route.get("/").to(homepage);
route.get("/robots.txt").to(robots);
route
.get("/static/:name")
.with_path_extractor::<FilePath>()
.to(static_file);
})
}

fn homepage(state: State) -> (State, Response) {
state.html(|o| page(o, &[("first", 3), ("second", 7), ("third", 2)]))
}

fn footer(out: &mut Write) -> io::Result<()> {
templates::footer(out, &[
("ructe", "https://crates.io/crates/ructe"),
("gotham", "https://gotham.rs/"),
])
}

fn robots(state: State) -> (State, Response) {
let res = create_response(
&state,
StatusCode::Ok,
Some((b"".to_vec(), mime::TEXT_PLAIN)),
);
(state, res)
}

#[derive(Deserialize, StateData, StaticResponseExtender)]
pub struct FilePath {
pub name: String,
}

static FAR: Duration = Duration::from_secs(180 * 24 * 60 * 60);

fn static_file(state: State) -> (State, Response) {
let res = {
let FilePath { ref name } = FilePath::borrow_from(&state);
if let Some(data) = statics::StaticFile::get(&name) {
create_response(
&state,
StatusCode::Ok,
Some((data.content.to_vec(), data.mime.clone())),
).with_header(Expires((SystemTime::now() + FAR).into()))
} else {
println!("Static file {} not found", name);
create_response(&state, StatusCode::NotFound, None)
}
};
(state, res)
}

include!(concat!(env!("OUT_DIR"), "/templates.rs"));
32 changes: 32 additions & 0 deletions examples/gotham/src/ructe_response.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,32 @@
use gotham::http::response::create_response;
use gotham::state::State;
use hyper::{Response, StatusCode};
use mime::TEXT_HTML_UTF_8;
use std::io::{self, Write};

pub trait RucteResponse: Sized {
fn html<F>(self, do_render: F) -> (Self, Response)
where
F: FnOnce(&mut Write) -> io::Result<()>;
}

impl RucteResponse for State {
fn html<F>(self, do_render: F) -> (Self, Response)
where
F: FnOnce(&mut Write) -> io::Result<()>,
{
let mut buf = Vec::new();
let res = match do_render(&mut buf) {
Ok(()) => create_response(
&self,
StatusCode::Ok,
Some((buf, TEXT_HTML_UTF_8)),
),
Err(e) => {
println!("Rendering failed: {}", e);
create_response(&self, StatusCode::InternalServerError, None)
}
};
(self, res)
}
}
1 change: 1 addition & 0 deletions examples/gotham/statics/btfl.svg
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
1 change: 1 addition & 0 deletions examples/gotham/statics/cloud.svg
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
1 change: 1 addition & 0 deletions examples/gotham/statics/grass.svg
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added examples/gotham/statics/squirrel.jpg
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
59 changes: 59 additions & 0 deletions examples/gotham/style.scss
Original file line number Diff line number Diff line change
@@ -0,0 +1,59 @@
html, body {
margin: 0;
padding: 0;
}

body {
background: left bottom / auto 9% repeat-x url(static-name(grass.svg)) fixed,
82% 96% / 5vh auto no-repeat url(static-name(btfl.svg)) fixed,
center bottom / auto 10% repeat-x url(static-name(grass.svg)) fixed,
right bottom / auto 11% repeat-x url(static-name(grass.svg)) fixed,
10% 90% / 8vh auto no-repeat url(static-name(btfl.svg)) fixed,
linear-gradient(#519dd2, #7ec0ec) fixed;
}

main {
padding: 2ex 3ex;
margin: 8vh auto 1em;
max-width: 37em;
background: white;
border-radius: 1em;
position: relative;

&:before, &:after {
content: url(static-name(cloud.svg));
display: block;
position: absolute;
z-index: -1;
}
&:before {
width: 52%;
top: -7vh;
left: -7%;
}
&:after {
width: 30%;
top: -6vh;
right: -4%;
}
}

footer {
background: #84ff5e;
border-radius: 1em 0 0;
bottom: 0;
padding: 0 1em;
position: fixed;
right: 0;
}

h1 {
margin: 0 0 1ex;
}
figure {
float: right;
margin: 0 0 1ex 1em;
}
p {
margin: 0 0 1em;
}
14 changes: 14 additions & 0 deletions examples/gotham/templates/footer.rs.html
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
@(frameworks: &[(&str, &str)])

<footer>
@if let Some(((last_name, last_href), prev)) = frameworks.split_last() {
Made with
@if let Some(((last_name, last_href), prev)) = prev.split_last() {
@for (name, href) in prev {
<a href="@href">@name</a>,
}
<a href="@last_href">@last_name</a> and
}
<a href="@last_href">@last_name</a>.
}
</footer>
36 changes: 36 additions & 0 deletions examples/gotham/templates/page.rs.html
Original file line number Diff line number Diff line change
@@ -0,0 +1,36 @@
@use templates::statics::*;
@use footer;

@(paras: &[(&str, usize)])

<!doctype html>
<html lang="sv">
<head>
<title>Example</title>
<meta name="viewport" content="width=device-width, initial-scale=1"/>
<link rel="stylesheet" type="text/css" href="/static/@style_css.name"/>
</head>
<body>
<main>
<h1>Example</h1>

<p>This is a simple sample page,
to be served with gotham.
It contains an image of a squirrel and not much more.</p>

<figure>
<img src="/static/@squirrel_jpg.name" alt="Squirrel!"
width="240" height="160"/>
<figcaption>A squirrel</figcaption>
</figure>

@for (order, n) in paras {
<p>This is a @order paragraph, with @n repeats.
@for _ in 1..=*n {
This is a @order paragraph.
}
}
</main>
@:footer()
</body>
</html>

0 comments on commit fe68936

Please sign in to comment.