templates: Fix navigation mocks Cleans up the directory structure for templates and fixes the navigation bugs in the applications too. Includes a context! macro which is lifted from upstream, but is currently unreleased. When rocket_dyn_templates is updates, it could be DRY'ed out.
Dependencies
- [2]
RJ75MX6Yroutes: Move user routes to controllers module The last routes to move, the src directory now only has a main.rs file and directories. - [3]
TWIZ7QV4db: Add interface to add a project Right now a project has a name, and an owner which is hardcoded to 1. This is because basically I'm speedrunning to implement push/pull of Pijul and then revisit to add depth to features and tests. Model code is now split into files properly too. - [4]
F5DMFQAOroutes: Move project routes to controllers module Much like other routes, just move the files and clean up the tree. - [5]
KFVJ3KMWfrontend: Introduce navigation bar Minor changes to the front-end mostly, to allow users to register, sign in, and sign out. The sign out route is changed to a GET endpoint, as links in HTML cannot DELETE. - [6]
5UNA2DEAroutes: Register and authenticate users Allow users to sign up, and sign in/sign out. The routes are added, though the design of the pages is very bare bones still, it's hard to go through the full flow to demo. On the server side: Passwords are stored encrypted in the database with salts. This uses the PG encrypt tooling to prevent against bugs and maintainance costs on this project. When a user is signed in, the user ID is set in a private cookie. Rocket has Guards for routes, which has not been implemented yet for this project. - [7]
3E77DEMDroutes: Move root route to controllers module The routes were now in modules in the root, which created a messy situation for the future. For now the routes will be moved to the controllers module and later additional changes will be done to further clean this up. - [*]
W3M3C7CCInitial commit This change includes a very small hello world application server written in Rust using Rocket.rs. Managing dependencies is done with Nix as that works well between Linux and Mac for me. - [*]
K4JNAJOFdatabase: Connect to postgres on Rocket boot As database I've chosen PostgreSQL, as my personal experience has been good with it. This change allows Rocket to connect to the database on booting the server. It depends on the DATABASE_URL being set, and for now circumvents the Rocket config helpers as it seemed faster to be up and running this way.
Change contents
- file deletion: sign_in.html.tera
{% extends "base" %}{% block body %}<div style="width:50%;" class="container-fluid"><form action="./sign_in" method="post"><div class="mb-3 row"><label for="user_name" class="col-sm-2 col-form-label">Username</label><div class="col-sm-10"><input type="text" class="form-control" name="user_name" required></div></div><div class="mb-3 row"><label for="password" class="col-sm-2 col-form-label">Password </label><div class="col-sm-10"><input type="password" class="form-control" name="password" required></div></div><button class="btn btn-primary" type="submit">Sign in</button></form></div>{% endblock body %} - file deletion: new_user.html.tera
{% extends "base" %}{% block body %}<div style="width:30%;" class="container-fluid"><form action="/users" method="post"><div class="mb-3 row"><label for="user_name" class="col-sm-2 col-form-label">Username</label><div class="col-sm-10"><input type="text" class="form-control" name="user_name" required></div></div><div class="mb-3 row"><label for="email" class="col-sm-2 col-form-label">Email</label><div class="col-sm-10"><input type="email" class="form-control" name="email" required></div></div><div class="mb-3 row"><label for="password" class="col-sm-2 col-form-label">Password </label><div class="col-sm-10"><input type="password" class="form-control" name="password" required></div></div><button class="btn btn-primary" type="submit">Sign up</button></form></div>{% endblock body %} - file addition: users[3.21]
- file addition: sign_in.html.tera[0.17]
{% extends "base" %}{% block body %}<div style="width:50%;" class="container-fluid"><form action="./sign_in" method="post"><div class="mb-3 row"><label for="user_name" class="col-sm-2 col-form-label">Username</label><div class="col-sm-10"><input type="text" class="form-control" name="user_name" required></div></div><div class="mb-3 row"><label for="password" class="col-sm-2 col-form-label">Password </label><div class="col-sm-10"><input type="password" class="form-control" name="password" required></div></div><button class="btn btn-primary" type="submit">Sign in</button></form></div>{% endblock body %} - file addition: new.html.tera[0.17]
{% extends "base" %}{% block body %}<div style="width:30%;" class="container-fluid"><form action="/users" method="post"><div class="mb-3 row"><label for="user_name" class="col-sm-2 col-form-label">Username</label><div class="col-sm-10"><input type="text" class="form-control" name="user_name" required></div></div><div class="mb-3 row"><label for="email" class="col-sm-2 col-form-label">Email</label><div class="col-sm-10"><input type="email" class="form-control" name="email" required></div></div><div class="mb-3 row"><label for="password" class="col-sm-2 col-form-label">Password </label><div class="col-sm-10"><input type="password" class="form-control" name="password" required></div></div><button class="btn btn-primary" type="submit">Sign up</button></form></div>{% endblock body %} - edit in templates/nav.html.tera at line 10
</li><li class="nav-item"><a class="nav-link" href="#">Link</a></li><li class="nav-item"><a class="nav-link disabled" href="#" tabindex="-1" aria-disabled="true">Disabled</a> - edit in templates/nav.html.tera at line 11
{% if current_user %} - replacement in templates/nav.html.tera at line 13
<a class="nav-link dropdown-toggle" href="#" id="dropdown08" data-bs-toggle="dropdown" aria-expanded="false">User</a><a class="nav-link dropdown-toggle" href="#" id="dropdown08" data-bs-toggle="dropdown" aria-expanded="false">{{ current_user.name }}</a> - edit in templates/nav.html.tera at line 15
<li><a class="dropdown-item" href="/users/sign_in">Sign in</a></li><li><a class="dropdown-item" href="/users/new">Sign up</a></li> - edit in templates/nav.html.tera at line 18
{% else %}<li class="nav-item"><a class="nav-link" href="/users/new">Sign up</a></li><li class="nav-item"><a class="nav-link" href="/users/sign_in">Sign in</a></li>{% endif %} - replacement in templates/landing.html.tera at line 3
<p>Hello world!</p><div class="px-4 py-5 my-5 text-center"><!--- <img class="d-block mx-auto mb-4" src="/docs/5.1/assets/brand/bootstrap-logo.svg" alt="" width="72" height="57"> ---!><h1 class="display-5 fw-bold">Nidobyte</h1><div class="col-lg-6 mx-auto"><p class="lead mb-4">Open source hosting for Pijul repositories to collaborate on code. </p><div class="d-grid gap-2 d-sm-flex justify-content-sm-center"><a class="btn btn-primary btn-lg ps-4 gap-3" href="/users/sign_up" role="button">Sign up</a><a class="btn btn-outline-secondary btn-lg px-4" href="/projects/explore">Projects</a></div></div></div> - edit in src/main.rs at line 26[10.882][9.388]
}/// this macro is lifted from the upstream unreleased code.#[macro_export]macro_rules! context {($($key:ident $(: $value:expr)?),*$(,)?) => {{use rocket::serde::ser::{Serialize, Serializer, SerializeMap};use ::std::fmt::{Debug, Formatter};#[allow(non_camel_case_types)]struct ContextMacroCtxObject<$($key: Serialize),*> {$($key: $key),*}#[allow(non_camel_case_types)]impl<$($key: Serialize),*> Serialize for ContextMacroCtxObject<$($key),*> {fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>where S: Serializer,{let mut map = serializer.serialize_map(None)?;$(map.serialize_entry(stringify!($key), &self.$key)?;)*map.end()}}#[allow(non_camel_case_types)]impl<$($key: Debug + Serialize),*> Debug for ContextMacroCtxObject<$($key),*> {fn fmt(&self, f: &mut Formatter<'_>) -> ::std::fmt::Result {f.debug_struct("context!")$(.field(stringify!($key), &self.$key))*.finish()}}ContextMacroCtxObject {$($key $(: $value)?),*}}}; - replacement in src/controllers/users.rs at line 40
Template::render("new_user", &Context::default())Template::render("users/new", &Context::default()) - replacement in src/controllers/users.rs at line 96
Template::render("sign_in", &Context::default())Template::render("users/sign_in", &Context::default()) - replacement in src/controllers/root.rs at line 5
#[get("/")]#[get("/", rank = 2)] - edit in src/controllers/projects.rs at line 2
use crate::models::projects; - replacement in src/controllers/projects.rs at line 7
form::{self, Context, Error, Form},form::{self, Error, Form}, - replacement in src/controllers/projects.rs at line 14
fn new(_user: User) -> Template {Template::render("projects/new", &Context::default())fn new(user: User) -> Template {Template::render("projects/new",crate::context! {current_user: user,},) - edit in src/controllers/projects.rs at line 42
use crate::models::projects; - edit in src/controllers/projects.rs at line 58
/*async fn show(db: &State<Database>,repoman: &State<RepoMan>, - edit in src/controllers/projects.rs at line 63
}*/