diff --git a/build_site.py b/build_site.py
index 3e428db5a641e7f32adda709d5e3b6623ff98b3a..d9556403684e2f145315c049d9d0fc8e8826d0ea 100644
--- a/build_site.py
+++ b/build_site.py
@@ -1,7 +1,44 @@
+import json
 import shutil
 import os
+from jinja2 import Environment, PackageLoader, select_autoescape
+
+# Jinja2 environment
+env = Environment(
+    loader=PackageLoader("build_site"),
+    autoescape=select_autoescape()
+)
+
+
+# Create directory
 if os.path.exists("public"):
     shutil.rmtree("public")
 os.mkdir("public")
-shutil.copyfile("templates/index.html", "public/index.html")
+
+# Copy static assets
 shutil.copytree("static", "public/", dirs_exist_ok=True)
+
+# Load projects
+projects = []
+for filename in os.listdir("templates/projects"):
+    filepath = os.path.join("templates", "projects", filename)
+    if os.path.isfile(filepath) and filepath.endswith(".json"):
+        # Load file
+        f = json.load(open(filepath, "r"))
+        project = {
+            "name": f.get("name", "Untitled"),
+            "description": f.get("description", ""),
+            "image": f.get("image", ""),
+            "badges": f.get("badges", []),
+            "buttons": f.get("buttons", []),
+            "buttons_use_group": len(f.get("buttons", [])) > 1
+        }
+        # Add to projects
+        projects.append(project)
+
+projects.reverse()  # Reverse items so newest is at the top
+
+# Format template
+template = env.get_template("index.html")
+with open("public/index.html", "w") as f:
+    f.write(template.render(projects=projects))
diff --git a/templates/index.html b/templates/index.html
index 4de5031028d27ef1b67617ac170c01184474db66..1ea2033031972baf91877ec6449b17bf55fd236c 100644
--- a/templates/index.html
+++ b/templates/index.html
@@ -41,39 +41,30 @@
             </div>
             <div class="row mx-auto p-2 text-center projects-row">
                 <h2>Projects</h2>
-                <div class="col-md-4">
-                    <div class="card proj-card">
-                        <img src="img/project/placeholder.png" class="card-img-top" alt="...">
-                        <div class="card-body">
-                            <h5 class="card-title">Project 1 <span class="badge text-bg-warning">In Progress</span></h5>
-                            <p class="card-text">Lorem ipsum, some sort of dolor sit amet description here.</p>
-                            <a href="https://example.com" class="btn btn-primary">View</a>
-                        </div>
-                    </div>
-                </div>
-                <div class="col-md-4">
-                    <div class="card proj-card">
-                        <img src="img/project/placeholder.png" class="card-img-top" alt="...">
-                        <div class="card-body">
-                            <h5 class="card-title">Project 2 <span class="badge text-bg-success">Finished</span></h5>
-                            <p class="card-text">Lorem ipsum, slightly different dolor sit amet description.</p>
-                            <div class="btn-group">
-                                <a href="https://example.com" class="btn btn-primary">Website</a>
-                                <a href="https://github.com" class="btn btn-secondary">Source Code</a>
+                {% for project in projects %}
+                    <div class="col-md-4">
+                        <div class="card proj-card">
+                            <img src="{{ project.image }}" class="card-img-top" alt="{{ project.name }}">
+                            <div class="card-body">
+                                <h5 class="card-title">
+                                    {{ project.name }}
+                                    {% for badge in project.badges %}
+                                        <span class="badge {{ badge.classes }}">{{ badge.text }}</span>
+                                    {% endfor %}
+                                </h5>
+                                <p class="card-text">
+                                    {{ project.description }}
+                                </p>
+
+                                {% if project.buttons_use_group %}<div class="btn-group">{% endif %}
+                                    {% for button in project.buttons %}
+                                        <a href="{{ button.url }}" class="btn {{ button.classes }}">{{ button.text }}</a>
+                                    {% endfor %}
+                                {% if project.buttons_use_group %}</div>{% endif %}
                             </div>
                         </div>
                     </div>
-                </div>
-                <div class="col-md-4">
-                    <div class="card proj-card">
-                        <img src="img/project/pizzapalace.png" class="card-img-top" alt="Pizza Palace">
-                        <div class="card-body">
-                            <h5 class="card-title">Pizza Palace <span class="badge text-bg-success">Finished</span></h5>
-                            <p class="card-text">I was tasked with a simple challenge and I overengineered it. Complete with admin UI and database.</p>
-                            <a href="https://example.com" class="btn btn-secondary">Source Code</a>
-                        </div>
-                    </div>
-                </div>
+                {% endfor %}
             </div>
         </div>
         <script src="https://cdn.jsdelivr.net/npm/bootstrap@5.3.3/dist/js/bootstrap.bundle.min.js" integrity="sha384-YvpcrYf0tY3lHB60NNkmXc5s9fDVZLESaAA55NDzOxhy9GkcIdslK1eN7N6jIeHz" crossorigin="anonymous"></script>
diff --git a/templates/projects/001-pizzapalace.json b/templates/projects/001-pizzapalace.json
index 1841fa7f3bb7ab0c5981405b3daf3dca9c861d21..a02543c301b59948d3aff131a3afa594aedbfbbe 100644
--- a/templates/projects/001-pizzapalace.json
+++ b/templates/projects/001-pizzapalace.json
@@ -1,7 +1,18 @@
 {
     "name": "Pizza Palace",
+    "image": "img/project/pizzapalace.png",
     "description": "I was tasked with a simple challenge and I overengineered it. Complete with admin UI and database.",
-    "badge_text": "Finished",
-    "badge_class": "text-bg-success",
-    "image": "img/project/pizzapalace.png"
+    "badges": [
+        {
+            "text": "Finished",
+            "classes": "text-bg-success"
+        }
+    ],
+    "buttons": [
+        {
+            "text": "Source Code",
+            "url": "https://git.rb9.xyz/TheJoeCoder/PizzaPalace",
+            "classes": "btn-secondary"
+        }
+    ]
 }
\ No newline at end of file