Compare commits

..
2 Commits
5 changed files with 66 additions and 16 deletions

No files matched your search

+1
View File
@@ -5,3 +5,4 @@ build/*
\*Claude*
/resources/static/output.css
/node_modules/
/org/output/
+1 -1
View File
@@ -13,7 +13,7 @@ build:
clj -M:build
org: ./org/*
emacs -Q --script build-org.el
emacs -Q --script build-org.el 2>&1
watch: tailwind static build
+45
View File
@@ -0,0 +1,45 @@
#+title: ferano.io
#+options: toc:nil
Static portfolio site. No framework — just Clojure generating HTML.
* Stack
- *Clojure + Hiccup* — generates all HTML in ~src/ferano_io/main.clj~
- *EDN* — all site data (projects, games, experiments, links) lives in ~resources/data.edn~
- *Tailwind CSS* — compiled from ~resources/input.css~ to ~build/static/output.css~
- *Org-mode* — blog posts written in ~org/~, compiled to HTML fragments by Emacs via ~build-org.el~
* Build
#+begin_src sh
make watch # tailwind + static assets + clj build (local dev)
make publish # full build + rsync to VPS
#+end_src
Individual targets:
| ~make build~ | ~clj -M:build~ — generates ~build/index.html~ and ~build/blog/*.html~ |
| ~make org~ | runs Emacs headless to compile ~org/*.org~ → ~org/output/*.html~ |
| ~make tailwind~ | compiles Tailwind CSS |
| ~make static~ | rsyncs ~resources/static/~ → ~build/static/~ |
* Dev (nREPL)
#+begin_src sh
clj -M:dev
#+end_src
Starts a CIDER-compatible nREPL. Sets ~-Ddev=true~ so the page loads Tailwind from CDN instead of the compiled file.
* Blog
Write ~org/YYYY-MM-DD-slug.org~ files. ~make org~ (or ~make build~, which calls it) converts them to body-only HTML fragments, then ~build-website~ wraps each one in the site template and writes it to ~build/blog/~.
* Publish
#+begin_src sh
make publish
#+end_src
Rsyncs ~build/~ to ~joe-vps:/home/josephferano/websites/ferano.io/~.
+9 -8
View File
@@ -5,17 +5,18 @@
'(("org-files"
:recursive t
:base-directory "./org"
:publishing-directory "./build/blog/"
:publishing-directory "./org/output/"
:publishing-function org-html-publish-to-html
:body-only t
:with-author nil ;; Don't include author name
:with-creator nil ;; Include Emacs and Org versions in footer
:with-toc nil ;; Include a table of contents
:title "Joseph Ferano - Blog"
:with-title nil
:with-validation nil
:section-numbers nil ;; Don't include section numbers
:time-stamp-file nil)
;; :with-author nil ;; Don't include author name
;; :with-creator nil ;; Include Emacs and Org versions in footer
;; :with-toc nil ;; Include a table of contents
;; :with-title nil
;; :with-validation nil
;; :section-numbers nil ;; Don't include section numbers
;; :time-stamp-file nil
)
("static-files"
:base-directory "./content/"
:base-extension "css\\|js\\|png\\|jpg\\|gif\\|pdf\\|mp3\\|ogg\\|svg"
+10 -7
View File
@@ -1,6 +1,7 @@
(ns ferano-io.main
(:require [clojure.string :as str]
[clojure.java.io :as io]
[clojure.java.shell :refer [sh]]
[hiccup.core :as h]
[hiccup.page :as page]
[clojure.edn :as edn]))
@@ -142,29 +143,31 @@
[:style ".menu-toggle:checked + label + .mobile-menu { opacity: 1; visibility: visible; transform: translateY(0); } .menu-toggle { display: none; } .mobile-menu { opacity: 0; visibility: hidden; transform: translateY(-10px); transition: opacity 0.2s ease, visibility 0.2s ease, transform 0.2s ease; } .mobile-menu a { display: block; }"]]
[:body
[:div {:class "min-h-screen bg-gray-50"}
(header data)
body
(contact data)]]))
(defn main-page [data]
(page-template
data
(let [fns [header hero projects-grid games blog-summary]]
(let [fns [hero projects-grid games blog-summary]]
(map #(% data) fns))))
(defn blog-page [data blog-entry-path]
(let [path (str "org/" blog-entry-path)]
(println path)
(let [path (str "org/output/" blog-entry-path)]
(page-template data (slurp path))))
(defn build-website []
(println (:out (sh "make" "org")))
(let [data (edn/read-string (slurp "resources/data.edn"))
blog-entries (.list (io/file "org/"))
blog-entries (.list (io/file "org/output"))
data (assoc data :blog-entries blog-entries)]
(spit "build/index.html" (main-page data))
(println "Generated index.html")
(doseq [entry blog-entries]
(spit (str "build/blog/" (str/replace entry #"\.org$" ".html"))
(blog-page data entry)))))
(spit (str "build/blog/" entry) (blog-page data entry)))))
(defn -main [& args]
(build-website)
(println "Generated website!"))
(println "Generated website!")
(shutdown-agents))