diff --git a/.github/workflows/ewpratten-com-deploy.yml b/.github/workflows/deploy.yml
similarity index 91%
rename from .github/workflows/ewpratten-com-deploy.yml
rename to .github/workflows/deploy.yml
index 0f5e335..4f40f4f 100644
--- a/.github/workflows/ewpratten-com-deploy.yml
+++ b/.github/workflows/deploy.yml
@@ -24,7 +24,6 @@ jobs:
       - name: Build only 
         uses: shalzz/zola-deploy-action@v0.19.1
         env:
-          BUILD_DIR: sites/ewpratten.com
           BUILD_ONLY: true
           BUILD_FLAGS: --drafts
 
@@ -47,7 +46,6 @@ jobs:
       - name: Build only 
         uses: shalzz/zola-deploy-action@v0.19.1
         env:
-          BUILD_DIR: sites/ewpratten.com
           BUILD_ONLY: true
 
       - name: Publish to Cloudflare Pages
@@ -56,6 +54,6 @@ jobs:
           apiToken: ${{ secrets.CLOUDFLARE_API_TOKEN }}
           accountId: ${{ secrets.CLOUDFLARE_ACCOUNT_ID }}
           projectName: ewpratten
-          directory: sites/ewpratten.com/public
+          directory: public
           gitHubToken: ${{ secrets.GITHUB_TOKEN }}
           wranglerVersion: '2'
diff --git a/.vscode/tasks.json b/.vscode/tasks.json
index ebb7bc4..412fc1f 100644
--- a/.vscode/tasks.json
+++ b/.vscode/tasks.json
@@ -8,7 +8,7 @@
             "type": "shell",
             "command": "zola",
             "options": {
-                "cwd": "${workspaceFolder}/sites/ewpratten.com"
+                "cwd": "${workspaceFolder}"
             },
             "args": [
                 "serve",
diff --git a/_headers b/_headers
new file mode 120000
index 0000000..c73f6b0
--- /dev/null
+++ b/_headers
@@ -0,0 +1 @@
+./static/_headers
\ No newline at end of file
diff --git a/_redirects b/_redirects
new file mode 120000
index 0000000..12b15c0
--- /dev/null
+++ b/_redirects
@@ -0,0 +1 @@
+./static/_redirects
\ No newline at end of file
diff --git a/functions b/functions
new file mode 120000
index 0000000..910093e
--- /dev/null
+++ b/functions
@@ -0,0 +1 @@
+./static/functions
\ No newline at end of file
diff --git a/requirements.txt b/requirements.txt
new file mode 100644
index 0000000..c04e3b4
--- /dev/null
+++ b/requirements.txt
@@ -0,0 +1 @@
+python-frontmatter
\ No newline at end of file
diff --git a/scripts/find_external_assets.py b/scripts/find_external_assets.py
new file mode 100644
index 0000000..84401b2
--- /dev/null
+++ b/scripts/find_external_assets.py
@@ -0,0 +1,37 @@
+import re
+from pathlib import Path
+
+REPO_ROOT = Path(__file__).parent.parent
+
+# Find all MD and HTML files
+md_files = list(REPO_ROOT.rglob("*.md"))
+html_files = list(REPO_ROOT.rglob("*.html"))
+
+# Ignore any files in the `public` directory
+md_files = [f for f in md_files if "public" not in f.parts]
+html_files = [f for f in html_files if "public" not in f.parts]
+
+# Result storage
+external_assets = set()
+
+# Find Markdown images
+for file in md_files:
+    body = file.read_text()
+    for match in re.finditer(r"!\[.*?\]\((.*?)\)", body):
+        link = match.group(1)
+        if link.startswith("http"):
+            external_assets.add((file, link))
+
+# Search HTML
+for file in html_files:
+    body = file.read_text()
+    for match in re.finditer(r'src="(.*?)"', body):
+        link = match.group(1)
+        if link.startswith("http"):
+            external_assets.add((file, link))
+                
+# Print all external assets
+for file_path, link in external_assets:
+    # Strip the prefix off the file path
+    file_path = file_path.relative_to(REPO_ROOT)
+    print(f"{file_path}:\t{link}")
\ No newline at end of file
diff --git a/scripts/fix_md_file_aliases.py b/scripts/fix_md_file_aliases.py
new file mode 100644
index 0000000..b08eea1
--- /dev/null
+++ b/scripts/fix_md_file_aliases.py
@@ -0,0 +1,66 @@
+import argparse
+import sys
+import re
+import frontmatter
+import yaml
+from pathlib import Path
+
+BLOG_POST_RE = re.compile(r"^\d{4}-\d+-\d+-(.*)\.md$")
+
+
+def main() -> int:
+    # Handle program arguments
+    ap = argparse.ArgumentParser(
+        description="Fixes the `aliases` field in the front matter of markdown files"
+    )
+    ap.add_argument(
+        "--root",
+        type=Path,
+        default=Path(__file__).parent.parent / "content" / "blog",
+        help="The root directory to search for markdown files",
+    )
+    args = ap.parse_args()
+
+    # Find all markdown files
+    md_files = list(args.root.glob("**/*.md"))
+    print(f"Found {len(md_files)} markdown files")
+
+    # Handle each file
+    for file in md_files:
+        print(f"Processing: {file}")
+
+        # Determine what the alias path should be
+        title_matches = BLOG_POST_RE.match(file.name)
+        if not title_matches:
+            print("Skipping file, not a blog post")
+            continue
+
+        title = title_matches.group(1)
+        correct_alias = f"/blog/{title.lower()}"
+        print("Correct alias:", correct_alias)
+
+        # Load and parse the frontmatter
+        post = frontmatter.load(file)
+
+        # Get the list of aliases
+        aliases = post.metadata.get("aliases", [])
+
+        # If the alias is already correct, skip it
+        if correct_alias in aliases:
+            print("Found correct alias")
+            continue
+
+        # Otherwise, add the correct alias
+        aliases.append(correct_alias)
+
+        # Write out the new frontmatter
+        post.metadata["aliases"] = aliases
+        file_contents = frontmatter.dumps(post, sort_keys=False)
+        file_contents += "\n"
+        file.write_text(file_contents)
+
+    return 0
+
+
+if __name__ == "__main__":
+    sys.exit(main())