A blog with the web framework Rocket - part 2
- 344 words
- 2 min
A home page for our blog
Tera installation
We will use the template engine tera.
In the Cargo file
First, we register it in the Cargo file:
[package]
name = "blog-rs"
version = "0.1.0"
authors = [" my_user_name <my_mail>"]
edition = "2018"
[dependencies]
rocket = "0.4.0"
[dependencies.rocket_contrib]
version = "*"
default-features = false
features = ["tera_templates"]
Preparation of the rocket
Then in our src/main.rs, we import rocket_contrib::templates::Template;:
#![feature(proc_macro_hygiene, decl_macro)]
#[macro_use]
extern crate rocket;
extern crate rocket_contrib;
use rocket_contrib::templates::Template;
// ...
Preparation of our rocket
Then we create our route to the home page:
// ...
use rocket_contrib::templates::Template;
// We use HashMap to pass a context to our templates use
std::collections::HashMap;
#[get("/")]
fn home() -> Template {
// We create our context, passing in it a title variable
// containing the string slice "Welcome"
let mut context = HashMap::new();
context.insert("title", "Welcome");
// Then we render our template.
Template::render("home", &context)
}
Then we mount our route and attach the method Template::fairing() to the rocket:
fn main() {
rocket::ignite()
.mount("/", routes![home])
.attach(Template::fairing())
.launch();
}
Alright, our rocket is almost ready to be launched!
Creation of our templates
A base template
We create a base template that we extends for every template we will render. We place all our templates in the templates/ directory.
Here is our base template:
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Our blog app - {% block title %}{% endblock %}</title>
</head>
<body>
<ul>
<li><a href="/">Home</a></li>
<li><a href="">A link to log in, not ready yet</a></li>
</ul>
{% block content %}
{% endblock %}
</body>
</html>
And our home template:
{% extends "base" %}
{% block title %}{{ title }}{% endblock %}
{% block content %}
<h1>Welcome on our blog application!!!</h1>
{% endblock %}
Now you can launch the rocket:
cargo run
Add some style
To style our application, we will use materializecss (any other solution, is OK, it is up to you). We won't use CDN to use materialize. So let's create a static directory at the root of our application and 3 subdirectories: static/js, static/css and static/fonts. In the directory static/fonts, place the Roboto fonts that you can download at https://fonts.google.com/
Then our project is organized like this:
Custom the rocket
We use a static_path variable as rocket mount point will change the relative path of the css files downloaded. We must pass this variable to the template in our home function:
#[get("/")]
fn home() -> Template {
let mut context = HashMap::new();
context.insert("title", "Welcome");
context.insert("static_path", "");
Template::render("home", &context)
}
Then we must also mount our static files, then we use the StaticFiles custom handler from rocket_contrib:
First, we register it into Cargo.toml:
# ..
[dependencies.rocket_contrib]
version = "*"
default-features = false
features = ["tera_templates", "serve"]
We mount our static files on /public, as they are accessible to everyone. Static files must be mount first, otherwise it is not working, yet I don't know why.
// ...
use rocket_contrib::serve::StaticFiles;
// ..
fn main() {
rocket::ignite()
.mount("/public", StaticFiles::from("/static"))
.mount("/", routes![home])
.attach(Template::fairing())
.launch();
}
Now in our base template we import css and js files:
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0, user-scalable=yes">
<title>Our blog app - {% block title %}{% endblock %}</title>
<link rel="stylesheet" href="{{ static_path }}/public/css/materialize.css">
</head>
<body>
// ..
<div class="container">
{% block content %}
{% endblock %}
</div>
<script type="text/javascript" src="{{ static_path }}/public/js/materialize.js"></script>
</body>
</html>
And to finish this part we add a simple navigation bar to our app. This navbar will be usefull for a user to log into the application and once she is logged in, she could see her articles she wrote. So we just modify the base template.
<!-- .. -->
<body>
<nav class="navbar navbar-default teal">
<div class="container">
<div class="nav-wrapper">
<a href="/">Our blog</a>
<ul class="right hide-on-med-and-down">
<li><a href="">Login</a></li>
</ul>
</div>
</div>
</nav>
<!-- .. -->