diff options
16 files changed, 220 insertions, 233 deletions
diff --git a/clams-server/src/main/java/no/eliashaugsbakk/clams/server/Main.java b/clams-server/src/main/java/no/eliashaugsbakk/clams/server/Main.java index 93a42cb..e456e7b 100644 --- a/clams-server/src/main/java/no/eliashaugsbakk/clams/server/Main.java +++ b/clams-server/src/main/java/no/eliashaugsbakk/clams/server/Main.java @@ -2,6 +2,7 @@ package no.eliashaugsbakk.clams.server; import io.javalin.Javalin; import io.javalin.rendering.template.JavalinPebble; +import java.util.Map; import no.eliashaugsbakk.clams.server.controller.BlogController; import no.eliashaugsbakk.clams.server.repository.SqliteManager; @@ -11,17 +12,20 @@ public class Main { SqliteManager dbManager = new SqliteManager("testDb.db"); dbManager.init(); - BlogController blogController = new BlogController(); + BlogController blogController = new BlogController(dbManager); var app = Javalin.create(config -> { config.staticFiles.add("/public"); config.fileRenderer(new JavalinPebble()); - config.routes.error(404, ctx -> ctx.render("templates/404.html")); + config.routes.error(404, ctx -> ctx.render("templates/404.html", + Map.of("page_title", "404 - Page Not Found", "page_css", "404"))); config.routes.get("/", ctx -> ctx.redirect("/home")); - config.routes.get("/home", ctx -> ctx.render("templates/home.html")); - config.routes.get("/projects", ctx -> ctx.render("templates/projects.html")); + config.routes.get("/home", ctx -> ctx.render("templates/home.html", + Map.of("page_title", "Elias Haugsbakk", "page_css", "home"))); + config.routes.get("/projects", ctx -> ctx.render("templates/projects.html", + Map.of("page_title", "Projects - Elias Haugsbakk", "page_css", "projects"))); config.routes.get("/blog/{slug}", blogController::handleGetPost); config.routes.get("/blog", blogController::handleGetOverview); diff --git a/clams-server/src/main/java/no/eliashaugsbakk/clams/server/controller/BlogController.java b/clams-server/src/main/java/no/eliashaugsbakk/clams/server/controller/BlogController.java index d4fc9d3..076e0e3 100644 --- a/clams-server/src/main/java/no/eliashaugsbakk/clams/server/controller/BlogController.java +++ b/clams-server/src/main/java/no/eliashaugsbakk/clams/server/controller/BlogController.java @@ -1,21 +1,80 @@ package no.eliashaugsbakk.clams.server.controller; import io.javalin.http.Context; +import java.time.ZoneId; +import java.util.List; import java.util.Map; +import no.eliashaugsbakk.clams.server.repository.BlogPostRepo; +import no.eliashaugsbakk.clams.server.repository.BlogPostRepoSqlite; +import no.eliashaugsbakk.clams.server.repository.SqliteManager; public class BlogController { + private final BlogPostRepo blogPostRepo; + + public BlogController(SqliteManager sqliteManager) { + this.blogPostRepo = new BlogPostRepoSqlite(sqliteManager); + } + public void handleGetPost(Context ctx) { ctx.render("templates/post.html", - Map.of("title", "place holder Title", - "published_date", "place holder Release Date", - "author", "place holder Author", - "content", "place holder Content")); + Map.of("page_title", "place holder Title - Elias Haugsbakk", "page_css", "post", + "title", "place holder Title", "published_date", "place holder Release Date", + "author", "place holder Author", "content", "place holder Content")); } public void handleGetOverview(Context ctx) { - ctx.render("templates/blog.html", Map.of( - "all_posts_by_year", "place holder for all posts", - "recent_posts", " place holder for recent posts" - )); + StringBuilder allPosts = new StringBuilder(); + + int prevYear = blogPostRepo.listPostsByPublishedDesc().getFirst().published() + .atZone(ZoneId.of("Europe/Oslo")).getYear(); + + allPosts.append(String.format(""" + <details class="year-accordion" open> + <summary class="year-toggle">%d</summary> + <ul class="post-list"> + """, prevYear)); + + for (var post : blogPostRepo.listPostsByPublishedDesc()) { + int year = post.published().atZone(ZoneId.of("Europe/Oslo")).getYear(); + if (year == prevYear) { + allPosts.append(String.format(""" + <li><a href="/blog/%s">%s</a></li> + """, post.slug(), post.title())); + } else { + allPosts.append(String.format(""" + </ul> + </details> + <details class="year-accordion"> + <summary class="year-toggle">%d</summary> + <ul class="post-list"> + <li><a href="/blog/%s">%s</a></li> + """, year, post.slug(), post.title())); + prevYear = year; + } + } + allPosts.append(""" + </ul> + </details> + """); + + + var featuredSlugs = List.of("test-page", "another-one"); + + StringBuilder featuredPosts = new StringBuilder(); + featuredPosts.append("<ul class=\"recent-list\">"); + + for (String slug : featuredSlugs) { + blogPostRepo.getPost(slug).ifPresent(post -> featuredPosts.append( + String.format(""" + <li> + <a href="/blog/%s">%s</a> <span class="featured-desc">-- %s</span> + </li> + """, post.slug(), post.title(), post.summary()))); + } + featuredPosts.append("</ul>"); + + ctx.render("templates/blog.html", + Map.of("page_title", "Elias Haugsbakk's Blog", "page_css", "blog", + "all_posts", allPosts.toString(), "recent_posts", featuredPosts.toString())); } } diff --git a/clams-server/src/main/java/no/eliashaugsbakk/clams/server/model/Post.java b/clams-server/src/main/java/no/eliashaugsbakk/clams/server/model/Post.java index e4136d0..833c524 100644 --- a/clams-server/src/main/java/no/eliashaugsbakk/clams/server/model/Post.java +++ b/clams-server/src/main/java/no/eliashaugsbakk/clams/server/model/Post.java @@ -2,5 +2,5 @@ package no.eliashaugsbakk.clams.server.model; import java.time.Instant; -public record Post(String title, String slug, Instant timePublished, String content) { +public record Post(String title, String slug, String summary, Instant timePublished, String content) { } diff --git a/clams-server/src/main/java/no/eliashaugsbakk/clams/server/repository/BlogPostRepoSqlite.java b/clams-server/src/main/java/no/eliashaugsbakk/clams/server/repository/BlogPostRepoSqlite.java index 50daf39..2979589 100644 --- a/clams-server/src/main/java/no/eliashaugsbakk/clams/server/repository/BlogPostRepoSqlite.java +++ b/clams-server/src/main/java/no/eliashaugsbakk/clams/server/repository/BlogPostRepoSqlite.java @@ -54,7 +54,7 @@ public class BlogPostRepoSqlite implements BlogPostRepo { @Override public Optional<Post> getPost(String slug) { String sql = """ - SELECT title, slug, content, published + SELECT title, slug, summary, content, published FROM posts WHERE slug = ? """; @@ -68,12 +68,13 @@ public class BlogPostRepoSqlite implements BlogPostRepo { if (resultSet.next()) { String title = resultSet.getString("title"); String postSlug = resultSet.getString("slug"); + String summary = resultSet.getString("summary"); String content = resultSet.getString("content"); String publishedRaw = resultSet.getString("published"); Instant timePublished = Instant.parse(publishedRaw); - return Optional.of(new Post(title, postSlug, timePublished, content)); + return Optional.of(new Post(title, postSlug, summary, timePublished, content)); } return Optional.empty(); } diff --git a/clams-server/src/main/resources/public/css/404.css b/clams-server/src/main/resources/public/css/404.css new file mode 100644 index 0000000..6ddf009 --- /dev/null +++ b/clams-server/src/main/resources/public/css/404.css @@ -0,0 +1,14 @@ +.error-container { + text-align: center; + margin-top: 100px; +} + +.error-code { + font-size: 5rem; + margin-bottom: 10px; + opacity: 0.3; +} + +.error-home-link { + margin-top: 40px; +} diff --git a/clams-server/src/main/resources/public/css/blog.css b/clams-server/src/main/resources/public/css/blog.css index 86eb0ed..c0fd080 100644 --- a/clams-server/src/main/resources/public/css/blog.css +++ b/clams-server/src/main/resources/public/css/blog.css @@ -1,10 +1,10 @@ -/* blog.css - page specific styles */ - .intro-text { - margin-bottom: 60px; + text-align: center; + max-width: 600px; + margin: 0 auto 60px auto; } -section { +.blog-section { margin-bottom: 60px; } @@ -52,7 +52,43 @@ section { } } -/* Specific spacing for blog lists */ -.content-grid li { - margin-bottom: 0.8rem; +.year-accordion { + margin-bottom: 1.5rem; + cursor: pointer; +} + +.year-toggle { + font-size: 1.25rem; + font-weight: bold; + list-style: none; + margin-bottom: 0.5rem; +} + +.year-toggle::-webkit-details-marker { + display: none; +} + +.year-toggle:hover { + opacity: 0.7; +} + +.post-list { + margin-top: 10px; + padding-left: 20px; + border-left: 2px solid var(--border-color); +} + +.post-list li { + margin-bottom: 0.65rem; +} + +.post-list a { + font-size: 0.9rem; + font-weight: normal; +} + +.featured-desc { + font-weight: normal; + color: var(--text-color); + opacity: 0.85; } diff --git a/clams-server/src/main/resources/public/css/common.css b/clams-server/src/main/resources/public/css/common.css index 3c8d927..ffed73f 100644 --- a/clams-server/src/main/resources/public/css/common.css +++ b/clams-server/src/main/resources/public/css/common.css @@ -57,50 +57,13 @@ h2 { .left-column { text-align: right; } .right-column { text-align: left; } -ul { +.main-container ul { list-style-type: none; padding: 0; margin: 0; } -li { margin-bottom: 1rem; } - -details { - margin-bottom: 1rem; - cursor: pointer; -} - -summary { - font-weight: bold; - list-style: none; /* Removes the default arrow in some browsers */ -} - -summary::-webkit-details-marker { - display: none; /* Removes the default arrow in Safari/Chrome */ -} - -summary:hover { - opacity: 0.7; -} - -.tag { - display: inline-block; - background-color: rgba(0,0,0,0.05); - padding: 2px 8px; - border-radius: 4px; - font-size: 0.75rem; - font-weight: bold; - text-transform: uppercase; - letter-spacing: 1px; - margin-right: 5px; - border: 1px solid var(--border-color); -} - -details ul { - margin-top: 10px; - padding-left: 20px; - border-left: 2px solid var(--border-color); -} +.main-container li { margin-bottom: 1rem; } a { color: var(--text-color); @@ -143,12 +106,6 @@ footer p { opacity: 0.5; } -.intro-text { - text-align: center; - max-width: 600px; - margin: 0 auto 60px auto; -} - @media (max-width: 600px) { .content-grid { grid-template-columns: 1fr; @@ -169,7 +126,6 @@ footer p { } } -/* Subtle Scrollbar Styling */ ::-webkit-scrollbar { width: 10px; } @@ -188,7 +144,6 @@ footer p { background-color: #bbb; } -/* Firefox Support */ * { scrollbar-width: thin; scrollbar-color: #d1d1cd var(--bg-color); diff --git a/clams-server/src/main/resources/public/css/home.css b/clams-server/src/main/resources/public/css/home.css index c3679b4..2cf0bd8 100644 --- a/clams-server/src/main/resources/public/css/home.css +++ b/clams-server/src/main/resources/public/css/home.css @@ -7,10 +7,6 @@ margin-bottom: 20px; } -.right-column a { - font-size: 1.2rem; -} - .description { display: block; font-size: 0.9rem; diff --git a/clams-server/src/main/resources/public/css/post.css b/clams-server/src/main/resources/public/css/post.css index 0c8391c..e905cbc 100644 --- a/clams-server/src/main/resources/public/css/post.css +++ b/clams-server/src/main/resources/public/css/post.css @@ -1,5 +1,3 @@ -/* post.css - specific styles for blog posts */ - .post-header { display: flex; justify-content: space-between; @@ -45,15 +43,6 @@ border-top: 1px dashed var(--border-color); } -.prev-post, .next-post { - font-size: 1rem; - text-decoration: none; -} - -.prev-post:hover, .next-post:hover { - text-decoration: underline; -} - @media (max-width: 600px) { .post-header { flex-direction: column; diff --git a/clams-server/src/main/resources/public/css/projects.css b/clams-server/src/main/resources/public/css/projects.css index 8453a01..4886a6d 100644 --- a/clams-server/src/main/resources/public/css/projects.css +++ b/clams-server/src/main/resources/public/css/projects.css @@ -1,5 +1,3 @@ -/* projects.css - specific styles for the projects page */ - .projects-category { margin-bottom: 80px; } @@ -17,6 +15,19 @@ margin: 10px 0 20px 0; } +.tag { + display: inline-block; + background-color: rgba(0,0,0,0.05); + padding: 2px 8px; + border-radius: 4px; + font-size: 0.75rem; + font-weight: bold; + text-transform: uppercase; + letter-spacing: 1px; + margin-right: 5px; + border: 1px solid var(--border-color); +} + .project-links { margin-top: 20px; font-size: 0.9rem; @@ -39,7 +50,6 @@ font-size: 0.9rem; } -/* Simple list for smaller projects */ .simple-project-list { margin-top: 30px; } @@ -53,8 +63,3 @@ opacity: 0.6; margin: 0 10px; } - -.small-link { - font-size: 0.8rem; - margin-left: 5px; -} diff --git a/clams-server/src/main/resources/templates/404.html b/clams-server/src/main/resources/templates/404.html index 6bbcecd..bb4c4d5 100644 --- a/clams-server/src/main/resources/templates/404.html +++ b/clams-server/src/main/resources/templates/404.html @@ -1,41 +1,14 @@ -<!DOCTYPE html> -<html> -<head> - <meta charset="UTF-8"> - <title>404 - Page Not Found</title> - <link rel="stylesheet" href="/css/common.css"> - <style> - .error-container { - text-align: center; - margin-top: 100px; - } - .error-code { - font-size: 5rem; - margin-bottom: 10px; - opacity: 0.3; - } - </style> -</head> -<body> +{% extends "templates/layout.html" %} - <main class="main-container"> - <div class="error-container"> - <div class="error-code">404</div> - <h1>Page Not Found</h1> - <p>The page you are looking for does not exist.</p> - <p style="margin-top: 40px;"> - <a href="/">Return to Home Page</a> - </p> - </div> - </main> - - <footer> - <p> - <span class="footer-left"><a href="/">eliashaugsbakk.xyz</a></span> - <span class="footer-separator">|</span> - <span class="footer-right"><a href="mailto:[email protected]">[email protected]</a></span> +{% block content %} +<main class="main-container"> + <div class="error-container"> + <div class="error-code">404</div> + <h1>Page Not Found</h1> + <p>The page you are looking for does not exist.</p> + <p class="error-home-link"> + <a href="/">Return to Home Page</a> </p> - </footer> - -</body> -</html> + </div> +</main> +{% endblock %} diff --git a/clams-server/src/main/resources/templates/blog.html b/clams-server/src/main/resources/templates/blog.html index 168cfe1..200a144 100644 --- a/clams-server/src/main/resources/templates/blog.html +++ b/clams-server/src/main/resources/templates/blog.html @@ -1,13 +1,6 @@ -<!DOCTYPE html> -<html> -<head> - <meta charset="UTF-8"> - <title>Elias Haugsbakk's Blog</title> - <link rel="stylesheet" href="/css/common.css"> - <link rel="stylesheet" href="/css/blog.css"> -</head> -<body> +{% extends "templates/layout.html" %} +{% block content %} <main class="main-container"> <header> <h1>Elias Haugsbakk's Blog</h1> @@ -21,28 +14,18 @@ <div class="content-grid"> <div class="left-column"> - <section id="all"> - <h2>{{ all_posts_title }}</h2> - <!-- Tells Pebble to trust your pre-grouped HTML links --> - {{ all_posts_by_year | raw }} + <section id="all" class="blog-section"> + <h2>All Posts</h2> + {{ all_posts| raw }} </section> </div> <div class="right-column"> - <section id="recent"> - <h2>Recent</h2> + <section id="recent" class="blog-section"> + <h2>Featured</h2> {{ recent_posts | raw }} </section> </div> </div> </main> - -<footer> - <p> - <span class="footer-left"><a href="/">eliashaugsbakk.xyz</a></span> - <span class="footer-separator">|</span> - <span class="footer-right"><a href="mailto:[email protected]">[email protected]</a></span> - </p> -</footer> -</body> -</html> +{% endblock %} diff --git a/clams-server/src/main/resources/templates/home.html b/clams-server/src/main/resources/templates/home.html index 199ae29..b5ff1d6 100644 --- a/clams-server/src/main/resources/templates/home.html +++ b/clams-server/src/main/resources/templates/home.html @@ -1,39 +1,22 @@ -<!DOCTYPE html> -<html> -<head> - <meta charset="UTF-8"> - <title>Elias Haugsbakk</title> - <link rel="stylesheet" href="/css/common.css"> - <link rel="stylesheet" href="/css/home.css"> -</head> -<body> +{% extends "templates/layout.html" %} - <main class="main-container"> - <h1>Elias Haugsbakk's Webpage</h1> - - <div class="content-grid"> - <div class="left-column"> - <img src="/images/elias_haugsbakk.JPEG" alt="Image of Elias Haugsbakk" class="profile-img"> - <p>Hello! I am Elias and this is my webpage.</p> - </div> +{% block content %} +<main class="main-container"> + <h1>Elias Haugsbakk's Webpage</h1> - <div class="right-column"> - <ul> - <li><a href="/blog">Blog</a> <span class="description">-- personal projects and thoughts</span></li> - <li><a href="https://github.com/eliashaugsbakk">GitHub</a> <span class="description">-- home for my code</span></li> - <li><a href="/projects">Projects</a> <span class="description">-- the projects I have worked on</span></li> - </ul> - </div> + <div class="content-grid"> + <div class="left-column"> + <img src="/images/elias_haugsbakk.JPEG" alt="Image of Elias Haugsbakk" class="profile-img"> + <p>Hello! I am Elias and this is my webpage.</p> </div> - </main> - <footer> - <p> - <span class="footer-left"><a href="/">eliashaugsbakk.xyz</a></span> - <span class="footer-separator">|</span> - <span class="footer-right"><a href="mailto:[email protected]">[email protected]</a></span> - </p> - </footer> - -</body> -</html> + <div class="right-column"> + <ul> + <li><a href="/blog">Blog</a> <span class="description">-- personal projects and thoughts</span></li> + <li><a href="https://github.com/eliashaugsbakk">GitHub</a> <span class="description">-- home for my code</span></li> + <li><a href="/projects">Projects</a> <span class="description">-- the projects I have worked on</span></li> + </ul> + </div> + </div> +</main> +{% endblock %} diff --git a/clams-server/src/main/resources/templates/layout.html b/clams-server/src/main/resources/templates/layout.html new file mode 100644 index 0000000..4c8b8dc --- /dev/null +++ b/clams-server/src/main/resources/templates/layout.html @@ -0,0 +1,23 @@ +<!DOCTYPE html> +<html lang="en"> +<head> + <meta charset="UTF-8"> + <meta name="viewport" content="width=device-width, initial-scale=1"> + <title>{{ page_title }}</title> + <link rel="stylesheet" href="/css/common.css"> + <link rel="stylesheet" href="/css/{{ page_css }}.css"> +</head> +<body> + +{% block content %}{% endblock %} + +<footer> + <p> + <span class="footer-left"><a href="/">eliashaugsbakk.xyz</a></span> + <span class="footer-separator">|</span> + <span class="footer-right"><a href="mailto:[email protected]">[email protected]</a></span> + </p> +</footer> + +</body> +</html> diff --git a/clams-server/src/main/resources/templates/post.html b/clams-server/src/main/resources/templates/post.html index 85f8977..40444b2 100644 --- a/clams-server/src/main/resources/templates/post.html +++ b/clams-server/src/main/resources/templates/post.html @@ -1,13 +1,6 @@ -<!DOCTYPE html> -<html> -<head> - <meta charset="UTF-8"> - <title>{{ title }} - Elias Haugsbakk</title> - <link rel="stylesheet" href="/css/common.css"> - <link rel="stylesheet" href="/css/post.css"> -</head> -<body> +{% extends "templates/layout.html" %} +{% block content %} <main class="main-container"> <header class="post-header"> <span class="post-date">{{ published_date }}</span> @@ -25,14 +18,4 @@ {{ next_post_link | raw }} </nav> </main> - -<footer> - <p> - <span class="footer-left"><a href="/">eliashaugsbakk.xyz</a></span> - <span class="footer-separator">|</span> - <span class="footer-right"><a href="mailto:[email protected]">[email protected]</a></span> - </p> -</footer> - -</body> -</html> +{% endblock %} diff --git a/clams-server/src/main/resources/templates/projects.html b/clams-server/src/main/resources/templates/projects.html index 8af0538..bab2a05 100644 --- a/clams-server/src/main/resources/templates/projects.html +++ b/clams-server/src/main/resources/templates/projects.html @@ -1,13 +1,6 @@ -<!DOCTYPE html> -<html> -<head> - <meta charset="UTF-8"> - <title>Projects - Elias Haugsbakk</title> - <link rel="stylesheet" href="/css/common.css"> - <link rel="stylesheet" href="/css/projects.css"> -</head> -<body> +{% extends "templates/layout.html" %} +{% block content %} <main class="main-container"> <header> <h1>Projects</h1> @@ -64,24 +57,14 @@ <li> <strong>Other Project One</strong> - A short one-line description. <span class="tech-stack-inline">(Bash)</span> - <a href="#" class="small-link">GitHub</a> + <a href="#">GitHub</a> </li> <li> <strong>Other Project Two</strong> - A short one-line description. <span class="tech-stack-inline">(Python, PostgreSQL)</span> - <a href="#" class="small-link">GitHub</a> + <a href="#">GitHub</a> </li> </ul> </section> </main> - -<footer> - <p> - <span class="footer-left"><a href="/">eliashaugsbakk.xyz</a></span> - <span class="footer-separator">|</span> - <span class="footer-right"><a href="mailto:[email protected]">[email protected]</a></span> - </p> -</footer> - -</body> -</html> +{% endblock %} |
