feat: Add a recipe book
Created a recipe section in the blog from existing markdown content.
This commit is contained in:
parent
5b25211618
commit
d2421d41f3
5 changed files with 172 additions and 71 deletions
38
blog.html
38
blog.html
|
|
@ -82,6 +82,44 @@
|
|||
</article>
|
||||
</div>
|
||||
</section>
|
||||
|
||||
<!-- Recipes Section -->
|
||||
<section class="content-section">
|
||||
<h2>Recipes</h2>
|
||||
<p class="section-description">Family recipes and culinary experiments.</p>
|
||||
<div class="blog-grid">
|
||||
<article class="blog-card">
|
||||
<h3><a href="/blog/public/recipe-book/st-patricks-day.html">St. Patrick's Day</a></h3>
|
||||
<p class="blog-meta">Holiday</p>
|
||||
<p>Traditional Irish recipes - corned beef, lamb stew, soda bread, and more.</p>
|
||||
</article>
|
||||
<article class="blog-card">
|
||||
<h3><a href="/blog/public/recipe-book/christmas.html">Christmas</a></h3>
|
||||
<p class="blog-meta">Holiday</p>
|
||||
<p>Holiday favorites including eggnog, gingerbread fruitcake, and meatloaf.</p>
|
||||
</article>
|
||||
<article class="blog-card">
|
||||
<h3><a href="/blog/public/recipe-book/earth-day.html">Earth Day</a></h3>
|
||||
<p class="blog-meta">Special Event</p>
|
||||
<p>Lamb stir fry and berry compote from April 2024.</p>
|
||||
</article>
|
||||
<article class="blog-card">
|
||||
<h3><a href="/blog/public/recipe-book/camping.html">Camping & Backpacking</a></h3>
|
||||
<p class="blog-meta">Outdoor</p>
|
||||
<p>Trail-ready recipes and energy bars for adventures.</p>
|
||||
</article>
|
||||
<article class="blog-card">
|
||||
<h3><a href="/blog/public/recipe-book/misc.html">Miscellaneous</a></h3>
|
||||
<p class="blog-meta">Various</p>
|
||||
<p>Drinks, snacks, sides, and external recipe links.</p>
|
||||
</article>
|
||||
<article class="blog-card">
|
||||
<h3><a href="/blog/public/recipe-book/">Full Recipe Book</a></h3>
|
||||
<p class="blog-meta">Index</p>
|
||||
<p>Browse all recipe collections in one place.</p>
|
||||
</article>
|
||||
</div>
|
||||
</section>
|
||||
</main>
|
||||
|
||||
<!--#include virtual="/includes/footer.html" -->
|
||||
|
|
|
|||
45
common.nginx.nix
Normal file
45
common.nginx.nix
Normal file
|
|
@ -0,0 +1,45 @@
|
|||
{ config, pkgs, lib, ... }:
|
||||
|
||||
{
|
||||
# Common configuration shared between staging and prod
|
||||
|
||||
# This file contains nginx settings that are identical across environments
|
||||
# Import this in both staging.nginx.nix and prod.nginx.nix
|
||||
|
||||
services.nginx = {
|
||||
# Recommended settings
|
||||
recommendedGzipSettings = true;
|
||||
recommendedOptimisation = true;
|
||||
recommendedProxySettings = true;
|
||||
};
|
||||
|
||||
# Common location configurations that can be reused
|
||||
# These are defined as library functions
|
||||
lib.nginxLocations = {
|
||||
# Standard root location with SSI support
|
||||
rootLocation = {
|
||||
index = "index.html";
|
||||
tryFiles = "$uri $uri/ =404";
|
||||
extraConfig = ''
|
||||
# Enable Server Side Includes for navbar/footer includes
|
||||
ssi on;
|
||||
'';
|
||||
};
|
||||
|
||||
# Private blog articles location with HTTP basic authentication
|
||||
privateLocation = {
|
||||
extraConfig = ''
|
||||
auth_basic "Private Articles";
|
||||
auth_basic_user_file /srv/nginx/.htpasswd;
|
||||
|
||||
# Enable Server Side Includes
|
||||
ssi on;
|
||||
'';
|
||||
};
|
||||
|
||||
# Common extraConfig for custom 404
|
||||
custom404 = ''
|
||||
error_page 404 /404.html;
|
||||
'';
|
||||
};
|
||||
}
|
||||
38
deploy.sh
38
deploy.sh
|
|
@ -2,6 +2,9 @@
|
|||
|
||||
set -e
|
||||
|
||||
# Common files to deploy (shared between staging and prod)
|
||||
DEPLOY_FILES="blog includes index.html blog.html resume.html style.css 404.html"
|
||||
|
||||
# Usage information
|
||||
usage() {
|
||||
printf "Usage: %s [staging|prod]\n\n staging - Deploy to local staging environment (/srv/www/stage.binning.net)\n prod - Deploy to production server via SSH (www.binning.net)\n\nExample:\n %s staging\n %s prod\n" "$0" "$0" "$0"
|
||||
|
|
@ -27,15 +30,7 @@ case $ENV in
|
|||
|
||||
# Deploy website files via rsync
|
||||
printf "Deploying website files...\n"
|
||||
sudo rsync -av --delete \
|
||||
blog \
|
||||
includes \
|
||||
index.html \
|
||||
blog.html \
|
||||
resume.html \
|
||||
style.css \
|
||||
404.html \
|
||||
${STAGING_PATH}/
|
||||
sudo rsync -av --delete ${DEPLOY_FILES} ${STAGING_PATH}/
|
||||
|
||||
# Set proper ownership
|
||||
sudo chown -R nginx:nginx ${STAGING_PATH}/
|
||||
|
|
@ -50,8 +45,8 @@ case $ENV in
|
|||
printf "Deploying to PRODUCTION environment...\n"
|
||||
|
||||
# SSH details
|
||||
REMOTE_HOST="binning.net"
|
||||
REMOTE_USER="matthew.binning"
|
||||
REMOTE_HOST="crossbox"
|
||||
REMOTE_USER="m3b"
|
||||
REMOTE_PATH="/srv/www/binning.net"
|
||||
REMOTE_NIXOS="/etc/nixos/"
|
||||
|
||||
|
|
@ -61,24 +56,21 @@ case $ENV in
|
|||
fi
|
||||
|
||||
# Deploy website files via rsync over SSH
|
||||
# Using just the host from SSH config without user@ prefix
|
||||
printf "Deploying website files...\n"
|
||||
rsync -avz --delete \
|
||||
-e ssh \
|
||||
blog \
|
||||
includes \
|
||||
index.html \
|
||||
blog.html \
|
||||
resume.html \
|
||||
style.css \
|
||||
404.html \
|
||||
${REMOTE_USER}@${REMOTE_HOST}:${REMOTE_PATH}/
|
||||
ssh ${REMOTE_HOST} "mkdir -p /tmp/${REMOTE_PATH}"
|
||||
rsync -avz --delete ${DEPLOY_FILES} ${REMOTE_HOST}:/tmp/${REMOTE_PATH}/
|
||||
# Set proper permissions and move config on remote server
|
||||
ssh ${REMOTE_HOST} "sudo mv /tmp/${REMOTE_PATH} ${REMOTE_PATH} && \
|
||||
sudo chown -R nginx:nginx ${REMOTE_PATH}/ && \
|
||||
printf 'Content deployed.\n'"
|
||||
|
||||
# Deploy nginx configuration
|
||||
printf "Deploying nginx configuration...\n"
|
||||
scp prod.nginx.nix ${REMOTE_USER}@${REMOTE_HOST}:/tmp/nginx.nix
|
||||
scp prod.nginx.nix ${REMOTE_HOST}:/tmp/nginx.nix
|
||||
|
||||
# Set proper permissions and move config on remote server
|
||||
ssh ${REMOTE_USER}@${REMOTE_HOST} "sudo mv /tmp/nginx.nix ${REMOTE_NIXOS}nginx.nix && \
|
||||
ssh ${REMOTE_HOST} "sudo mv /tmp/nginx.nix ${REMOTE_NIXOS}nginx.nix && \
|
||||
sudo chown -R nginx:nginx ${REMOTE_PATH}/ && \
|
||||
printf 'Configuration deployed. Run sudo nixos-rebuild switch to activate.\n'"
|
||||
|
||||
|
|
|
|||
|
|
@ -3,8 +3,8 @@
|
|||
<a href="/" class="nav-brand">Home</a>
|
||||
<ul class="nav-menu">
|
||||
<li><a href="/blog.html">Blog</a></li>
|
||||
<li><a href="https://forgejo.binning.net" target="_blank">Git</a></li>
|
||||
<li><a href="/resume.html">Resume</a></li>
|
||||
<li><a href="https://forgejo.binning.net" target="_blank">Forgejo</a></li>
|
||||
</ul>
|
||||
</div>
|
||||
</nav>
|
||||
|
|
|
|||
120
style.css
120
style.css
|
|
@ -6,19 +6,20 @@
|
|||
}
|
||||
|
||||
body {
|
||||
font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', 'Roboto', 'Oxygen', 'Ubuntu', 'Cantarell', 'Fira Sans', 'Droid Sans', 'Helvetica Neue', sans-serif;
|
||||
line-height: 1.6;
|
||||
color: #333;
|
||||
background-color: #f5f5f5;
|
||||
font-family: 'Courier New', 'Courier', 'Monaco', 'Lucida Console', monospace;
|
||||
line-height: 1.7;
|
||||
color: #3e2723;
|
||||
background-color: #f4ecd8;
|
||||
}
|
||||
|
||||
/* Navbar Styles */
|
||||
.navbar {
|
||||
background-color: #2c3e50;
|
||||
box-shadow: 0 2px 4px rgba(0,0,0,0.1);
|
||||
background-color: #5d4037;
|
||||
box-shadow: 0 2px 4px rgba(62, 39, 35, 0.3);
|
||||
position: sticky;
|
||||
top: 0;
|
||||
z-index: 1000;
|
||||
border-bottom: 2px solid #4e342e;
|
||||
}
|
||||
|
||||
.nav-container {
|
||||
|
|
@ -31,14 +32,14 @@ body {
|
|||
}
|
||||
|
||||
.nav-brand {
|
||||
color: #fff;
|
||||
color: #f4ecd8;
|
||||
text-decoration: none;
|
||||
font-size: 1.5rem;
|
||||
font-weight: bold;
|
||||
}
|
||||
|
||||
.nav-brand:hover {
|
||||
color: #3498db;
|
||||
color: #d7ccc8;
|
||||
}
|
||||
|
||||
.nav-menu {
|
||||
|
|
@ -48,14 +49,14 @@ body {
|
|||
}
|
||||
|
||||
.nav-menu a {
|
||||
color: #fff;
|
||||
color: #f4ecd8;
|
||||
text-decoration: none;
|
||||
font-size: 1rem;
|
||||
transition: color 0.3s ease;
|
||||
}
|
||||
|
||||
.nav-menu a:hover {
|
||||
color: #3498db;
|
||||
color: #d7ccc8;
|
||||
}
|
||||
|
||||
/* Main Container */
|
||||
|
|
@ -67,39 +68,41 @@ body {
|
|||
|
||||
/* Hero Section */
|
||||
.hero {
|
||||
background-color: #fff;
|
||||
background-color: #efebe9;
|
||||
padding: 3rem 2rem;
|
||||
border-radius: 8px;
|
||||
box-shadow: 0 2px 8px rgba(0,0,0,0.1);
|
||||
border-radius: 4px;
|
||||
box-shadow: 0 2px 8px rgba(62, 39, 35, 0.2);
|
||||
margin-bottom: 2rem;
|
||||
text-align: center;
|
||||
border: 1px solid #d7ccc8;
|
||||
}
|
||||
|
||||
.hero h1 {
|
||||
font-size: 2.5rem;
|
||||
color: #2c3e50;
|
||||
color: #4e342e;
|
||||
margin-bottom: 1rem;
|
||||
}
|
||||
|
||||
.hero p {
|
||||
font-size: 1.2rem;
|
||||
color: #555;
|
||||
color: #6d4c41;
|
||||
}
|
||||
|
||||
/* Content Section */
|
||||
.content-section {
|
||||
background-color: #fff;
|
||||
background-color: #efebe9;
|
||||
padding: 2rem;
|
||||
margin-bottom: 2rem;
|
||||
border-radius: 8px;
|
||||
box-shadow: 0 2px 8px rgba(0,0,0,0.1);
|
||||
border-radius: 4px;
|
||||
box-shadow: 0 2px 8px rgba(62, 39, 35, 0.2);
|
||||
border: 1px solid #d7ccc8;
|
||||
}
|
||||
|
||||
.content-section h2 {
|
||||
color: #2c3e50;
|
||||
color: #4e342e;
|
||||
font-size: 2rem;
|
||||
margin-bottom: 1.5rem;
|
||||
border-bottom: 3px solid #3498db;
|
||||
border-bottom: 3px solid #8d6e63;
|
||||
padding-bottom: 0.5rem;
|
||||
}
|
||||
|
||||
|
|
@ -107,20 +110,21 @@ body {
|
|||
.genealogy-blurb p {
|
||||
margin-bottom: 1rem;
|
||||
line-height: 1.8;
|
||||
color: #555;
|
||||
color: #5d4037;
|
||||
}
|
||||
|
||||
.contact-info strong {
|
||||
color: #2c3e50;
|
||||
color: #4e342e;
|
||||
}
|
||||
|
||||
/* Footer */
|
||||
.footer {
|
||||
background-color: #2c3e50;
|
||||
color: #fff;
|
||||
background-color: #5d4037;
|
||||
color: #f4ecd8;
|
||||
text-align: center;
|
||||
padding: 2rem;
|
||||
margin-top: 3rem;
|
||||
border-top: 2px solid #4e342e;
|
||||
}
|
||||
|
||||
.footer p {
|
||||
|
|
@ -129,7 +133,7 @@ body {
|
|||
|
||||
/* Blog Styles */
|
||||
.section-description {
|
||||
color: #666;
|
||||
color: #6d4c41;
|
||||
font-style: italic;
|
||||
margin-bottom: 1.5rem;
|
||||
}
|
||||
|
|
@ -142,55 +146,55 @@ body {
|
|||
}
|
||||
|
||||
.blog-card {
|
||||
background-color: #f9f9f9;
|
||||
border: 1px solid #e0e0e0;
|
||||
border-radius: 8px;
|
||||
background-color: #faf8f3;
|
||||
border: 1px solid #d7ccc8;
|
||||
border-radius: 4px;
|
||||
padding: 1.5rem;
|
||||
transition: transform 0.2s ease, box-shadow 0.2s ease;
|
||||
position: relative;
|
||||
}
|
||||
|
||||
.blog-card:hover {
|
||||
transform: translateY(-4px);
|
||||
box-shadow: 0 4px 12px rgba(0,0,0,0.15);
|
||||
transform: translateY(-2px);
|
||||
box-shadow: 0 4px 12px rgba(62, 39, 35, 0.25);
|
||||
}
|
||||
|
||||
.blog-card h3 {
|
||||
color: #2c3e50;
|
||||
color: #4e342e;
|
||||
margin-bottom: 0.5rem;
|
||||
font-size: 1.3rem;
|
||||
}
|
||||
|
||||
.blog-card h3 a {
|
||||
color: #2c3e50;
|
||||
color: #4e342e;
|
||||
text-decoration: none;
|
||||
transition: color 0.3s ease;
|
||||
}
|
||||
|
||||
.blog-card h3 a:hover {
|
||||
color: #3498db;
|
||||
color: #6d4c41;
|
||||
}
|
||||
|
||||
.blog-meta {
|
||||
color: #999;
|
||||
color: #8d6e63;
|
||||
font-size: 0.9rem;
|
||||
margin-bottom: 0.75rem;
|
||||
}
|
||||
|
||||
.blog-card p {
|
||||
color: #555;
|
||||
color: #5d4037;
|
||||
line-height: 1.6;
|
||||
}
|
||||
|
||||
.blog-card.private {
|
||||
border-color: #f39c12;
|
||||
background-color: #fff9f0;
|
||||
border-color: #a1887f;
|
||||
background-color: #f5f5f0;
|
||||
}
|
||||
|
||||
.private-badge {
|
||||
display: inline-block;
|
||||
background-color: #f39c12;
|
||||
color: #fff;
|
||||
background-color: #8d6e63;
|
||||
color: #f4ecd8;
|
||||
padding: 0.25rem 0.75rem;
|
||||
border-radius: 4px;
|
||||
font-size: 0.85rem;
|
||||
|
|
@ -206,10 +210,10 @@ body {
|
|||
}
|
||||
|
||||
.skill-category h3 {
|
||||
color: #2c3e50;
|
||||
color: #4e342e;
|
||||
margin-bottom: 1rem;
|
||||
font-size: 1.2rem;
|
||||
border-bottom: 2px solid #3498db;
|
||||
border-bottom: 2px solid #8d6e63;
|
||||
padding-bottom: 0.5rem;
|
||||
}
|
||||
|
||||
|
|
@ -220,7 +224,7 @@ body {
|
|||
|
||||
.skill-category li {
|
||||
padding: 0.5rem 0;
|
||||
color: #555;
|
||||
color: #5d4037;
|
||||
position: relative;
|
||||
padding-left: 1.5rem;
|
||||
}
|
||||
|
|
@ -229,7 +233,7 @@ body {
|
|||
content: "▸";
|
||||
position: absolute;
|
||||
left: 0;
|
||||
color: #3498db;
|
||||
color: #8d6e63;
|
||||
font-weight: bold;
|
||||
}
|
||||
|
||||
|
|
@ -242,13 +246,13 @@ body {
|
|||
}
|
||||
|
||||
.experience-item h3 {
|
||||
color: #2c3e50;
|
||||
color: #4e342e;
|
||||
font-size: 1.4rem;
|
||||
margin-bottom: 0.5rem;
|
||||
}
|
||||
|
||||
.job-meta {
|
||||
color: #999;
|
||||
color: #8d6e63;
|
||||
font-size: 0.95rem;
|
||||
margin-bottom: 1rem;
|
||||
font-style: italic;
|
||||
|
|
@ -260,16 +264,38 @@ body {
|
|||
}
|
||||
|
||||
.experience-item li {
|
||||
color: #555;
|
||||
color: #5d4037;
|
||||
margin-bottom: 0.5rem;
|
||||
line-height: 1.7;
|
||||
}
|
||||
|
||||
.experience-item p {
|
||||
color: #555;
|
||||
color: #5d4037;
|
||||
line-height: 1.7;
|
||||
}
|
||||
|
||||
/* Recipe Page Styles */
|
||||
.recipe-card {
|
||||
background-color: #faf8f3;
|
||||
border: 1px solid #d7ccc8;
|
||||
border-radius: 4px;
|
||||
padding: 1.5rem;
|
||||
margin-bottom: 1.5rem;
|
||||
}
|
||||
|
||||
.recipe-card h3 {
|
||||
color: #4e342e;
|
||||
border-bottom: 2px solid #8d6e63;
|
||||
padding-bottom: 0.5rem;
|
||||
margin-bottom: 1rem;
|
||||
}
|
||||
|
||||
.recipe-year {
|
||||
color: #8d6e63;
|
||||
font-style: italic;
|
||||
font-size: 0.9rem;
|
||||
}
|
||||
|
||||
/* Responsive Design */
|
||||
@media (max-width: 768px) {
|
||||
.nav-container {
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue